Just enough to make ie6 setup work.
I'm not receiving list mail, please CC me when replying.
Johan
diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in
index cdbab2e..3be7e22 100644
--- a/programs/wineboot/Makefile.in
+++ b/programs/wineboot/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = wineboot.exe
APPMODE = -mconsole
-IMPORTS = uuid advapi32 kernel32 ntdll
+IMPORTS = uuid advapi32 ole32 kernel32 ntdll
DELAYIMPORTS = setupapi shell32 shlwapi version user32
C_SRCS = \
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 717a175..4a91c37 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -86,6 +86,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(wineboot);
#define MAX_LINE_LENGTH (2*MAX_PATH+2)
+typedef HRESULT (*DLLREGISTER) (void);
+typedef HRESULT (*DLLINSTALL) (BOOL,LPCWSTR);
+
extern BOOL shutdown_close_windows( BOOL force );
extern void kill_processes( BOOL kill_desktop );
@@ -157,6 +160,65 @@ done:
return ret;
}
+static VOID *LoadProc(WCHAR* strDllW, const char* procName, HMODULE* DllHandle)
+{
+ VOID* (*proc)(void);
+
+ *DllHandle = LoadLibraryExW(strDllW, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+ if(!*DllHandle)
+ {
+ WINE_TRACE("LoadLibraryEx failed %s\n",
+ wine_dbgstr_w(strDllW));
+ return NULL;
+ }
+ proc = (VOID *) GetProcAddress(*DllHandle, procName);
+ if (!proc)
+ {
+ WINE_TRACE("GetProcAddress failed (%s -> %s)\n",
+ wine_dbgstr_w(strDllW), procName);
+ FreeLibrary(*DllHandle);
+ return NULL;
+ }
+ return proc;
+}
+
+static int RunDllRegisterServer(WCHAR* strDll)
+{
+ DLLREGISTER pfRegister = NULL;
+ HRESULT hr;
+ HMODULE DllHandle = NULL;
+
+ pfRegister = LoadProc(strDll, "DllRegisterServer", &DllHandle);
+
+ if (!pfRegister)
+ return -1;
+
+ hr = pfRegister();
+
+ if(DllHandle)
+ FreeLibrary(DllHandle);
+
+ return hr;
+}
+
+static HRESULT RunDllInstall(WCHAR *strDll, BOOL install, WCHAR *command_line)
+{
+ DLLINSTALL pfInstall = NULL;
+ HRESULT hr;
+ HMODULE DllHandle = NULL;
+
+ pfInstall = LoadProc(strDll, "DllInstall", &DllHandle);
+
+ if (!pfInstall)
+ return -1;
+
+ hr = pfInstall(install, command_line);
+
+ if(DllHandle)
+ FreeLibrary(DllHandle);
+ return hr;
+}
+
/* Performs the rename operations dictated in %SystemRoot%\Wininit.ini.
* Returns FALSE if there was an error, or otherwise if all is ok.
*/
@@ -526,6 +588,197 @@ end:
return res==ERROR_SUCCESS;
}
+static BOOL ProcessRunOnceExKey(HKEY hkRunEntry)
+{
+ DWORD i;
+ DWORD res;
+ DWORD nMaxCmdLine=0, nMaxValue=0;
+ WCHAR *szCmdLine=NULL;
+ WCHAR *szValue=NULL;
+ static const WCHAR KEY_DLLREGISTERSERVER[]={
+ 'D','l','l','R','e','g','i','s','t','e','r','S','e','r','v','e','r',0};
+ static const WCHAR KEY_DLLINSTALL[]={
+ 'D','l','l','I','n','s','t','a','l','l',0};
+
+ if( (res=RegQueryInfoKeyW( hkRunEntry, NULL, NULL, NULL, NULL, NULL, NULL, &i, &nMaxValue,
+ &nMaxCmdLine, NULL, NULL ))!=ERROR_SUCCESS )
+ goto end;
+
+
+ if( (szCmdLine=HeapAlloc(GetProcessHeap(),0,nMaxCmdLine))==NULL )
+ {
+ WINE_ERR("Couldn't allocate memory for the commands to be executed\n");
+
+ res=ERROR_NOT_ENOUGH_MEMORY;
+ goto end;
+ }
+
+ if( (szValue=HeapAlloc(GetProcessHeap(),0,(++nMaxValue)*sizeof(*szValue)))==NULL )
+ {
+ WINE_ERR("Couldn't allocate memory for the value names\n");
+
+ res=ERROR_NOT_ENOUGH_MEMORY;
+ goto end;
+ }
+
+ while( i>0 )
+ {
+ DWORD nValLength=nMaxValue, nDataLength=nMaxCmdLine;
+ DWORD type;
+ WCHAR *first, *second, *third; /* | separated parts of the entry */
+ WCHAR pipe[] = {'|',0};
+ i--;
+
+ if( (res=RegEnumValueW( hkRunEntry, i, szValue, &nValLength, 0, &type,
+ (LPBYTE)szCmdLine, &nDataLength ))!=ERROR_SUCCESS )
+ {
+ WINE_ERR("Couldn't read in value %d - %d\n", i, res );
+ break;
+ }
+
+ if (strlenW(szValue) == 0)
+ {
+ WINE_TRACE("Processing %s entries\n", wine_dbgstr_w( szCmdLine ));
+ continue;
+ }
+
+ if( type!=REG_SZ )
+ {
+ WINE_ERR("Incorrect type of value #%d (%d)\n", i, type );
+ continue;
+ }
+
+ if( (res=RegDeleteValueW( hkRunEntry, szValue ))!=ERROR_SUCCESS )
+ {
+ WINE_ERR("Couldn't delete value - %d, %d. Running command anyways.\n", i, res );
+ }
+
+ if ((first = strstrW(szCmdLine, pipe)) != NULL)
+ {
+ WCHAR *value = first + strlenW(pipe);
+ HRESULT retval;
+ if (strncmpW(value, KEY_DLLREGISTERSERVER,
+ strlenW(KEY_DLLREGISTERSERVER)) == 0)
+ {
+ DWORD len;
+ WCHAR *cmd;
+ len = strlenW(szCmdLine) - strlenW(first) + strlenW(pipe);
+ cmd = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * len);
+ if (cmd == NULL)
+ goto end;
+
+ if (lstrcpynW(cmd, szCmdLine, len))
+ {
+ WINE_TRACE("DllRegisterServer %s\n", wine_dbgstr_w(cmd));
+ retval = RunDllRegisterServer(cmd);
+ WINE_TRACE("DllRegisterServer returned %d\n", retval);
+ }
+ HeapFree(GetProcessHeap(), 0, cmd);
+ }
+ else if (strncmpW(value, KEY_DLLINSTALL,
+ strlenW(KEY_DLLINSTALL)) == 0)
+ {
+ WCHAR *filename, *arg = NULL;
+ WCHAR install = FALSE;
+ HRESULT retval;
+ DWORD filenameLength, argLength;
+
+ /* filename|DllInstall
+ * filename|DllInstall|i,arg
+ * filename|DllInstall|I,arg
+ * FIXME: is i=FALSE,I=TRUE or the reverse?
+ */
+ second = strstrW(first + strlenW(pipe), pipe);
+ if (second == NULL)
+ filenameLength = strlenW(szCmdLine) - strlenW(first) + strlenW(pipe);
+ else if ((third = strstrW(second, pipe)) != NULL)
+ {
+ filenameLength = strlenW(szCmdLine) - strlenW(first) + strlenW(pipe);
+ install = *(second + strlenW(pipe));
+
+ argLength = strlenW(third) - strlenW(pipe) - 1;
+ filename = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * argLength);
+ lstrcpynW(arg, third + strlenW(pipe) + 2, argLength);
+ }
+
+ filename = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * filenameLength);
+ lstrcpynW(filename, szCmdLine, filenameLength);
+
+ WINE_TRACE("DllInstall (%s, %d, %s)\n",
+ wine_dbgstr_w(filename),
+ install == 'i',
+ wine_dbgstr_w(arg));
+ retval = RunDllInstall(filename, install == 'i', arg);
+ WINE_TRACE("DllInstall returned %d\n", retval);
+ HeapFree( GetProcessHeap(), 0, filename );
+ if (arg)
+ HeapFree( GetProcessHeap(), 0, arg );
+ }
+ } else {
+ if( (res=runCmd(szCmdLine, NULL, TRUE, FALSE ))==INVALID_RUNCMD_RETURN )
+ {
+ WINE_ERR("Error running cmd #%d (%d)\n", i, GetLastError() );
+ }
+ }
+ }
+ end:
+ HeapFree( GetProcessHeap(), 0, szValue );
+ HeapFree( GetProcessHeap(), 0, szCmdLine );
+
+ return res;
+}
+
+static BOOL ProcessRunOnceEx( HKEY hkRoot )
+{
+ static const WCHAR WINKEY_NAME[]={'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
+ 'C','u','r','r','e','n','t','V','e','r','s','i','o','n', '\\',
+ 'R','u','n','O','n','c','e','E','x',0};
+ HKEY hkRunOnceEx, hkRunEntry;
+ DWORD res;
+ DWORD i;
+
+ WINE_TRACE("processing RunOnceEx entries under %s\n", hkRoot==HKEY_LOCAL_MACHINE ? "HKLM" : "HKCU");
+
+ if (RegOpenKeyExW( hkRoot, WINKEY_NAME, 0, KEY_ALL_ACCESS, &hkRunOnceEx ) != ERROR_SUCCESS)
+ return TRUE;
+
+ i = 0;
+ while( 1 )
+ {
+ WCHAR szKeyName[2048];
+
+ res = RegEnumKeyW( hkRunOnceEx, i, szKeyName, 2048);
+ if ( res==ERROR_NO_MORE_ITEMS )
+ break;
+ else if( res!=ERROR_SUCCESS )
+ {
+ WINE_ERR("Couldn't read in value %d - %d\n", i, res );
+ break;
+ }
+ i++;
+
+ if (RegOpenKeyExW( hkRunOnceEx, szKeyName, 0, KEY_ALL_ACCESS, &hkRunEntry ) != ERROR_SUCCESS)
+ return TRUE;
+
+ ProcessRunOnceExKey( hkRunEntry );
+
+ RegCloseKey( hkRunEntry );
+
+ if( (res=RegDeleteKeyW( hkRunOnceEx, szKeyName ))!=ERROR_SUCCESS )
+ {
+ WINE_ERR("Couldn't delete key - %s, %d. Running command anyways.\n",
+ wine_dbgstr_w( szKeyName ), res );
+ }
+ }
+ if( hkRunOnceEx!=NULL )
+ RegCloseKey( hkRunOnceEx );
+
+ WINE_TRACE("done\n");
+
+ return res==ERROR_SUCCESS;
+}
+
/*
* WFP is Windows File Protection, in NT5 and Windows 2000 it maintains a cache
* of known good dlls and scans through and replaces corrupted DLLs with these
@@ -824,6 +1077,8 @@ int main( int argc, char *argv[] )
HANDLE event;
SECURITY_ATTRIBUTES sa;
+ OleInitialize(NULL);
+
GetWindowsDirectoryW( windowsdir, MAX_PATH );
if( !SetCurrentDirectoryW( windowsdir ) )
WINE_ERR("Cannot set the dir to %s (%d)\n", wine_dbgstr_w(windowsdir), GetLastError() );
@@ -875,6 +1130,8 @@ int main( int argc, char *argv[] )
ProcessRunKeys( HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNONCE], TRUE, TRUE );
+ ProcessRunOnceEx( HKEY_LOCAL_MACHINE );
+
if (!init && !restart)
{
ProcessRunKeys( HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUN], FALSE, FALSE );