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 );
"Johan Dahlin" jdahlin@gmail.com wrote:
+typedef HRESULT (*DLLREGISTER) (void); +typedef HRESULT (*DLLINSTALL) (BOOL,LPCWSTR);
Wrong calling convention.
+static int RunDllRegisterServer(WCHAR* strDll) +{
- DLLREGISTER pfRegister = NULL;
- HRESULT hr;
- HMODULE DllHandle = NULL;
- pfRegister = LoadProc(strDll, "DllRegisterServer", &DllHandle);
- if (!pfRegister)
return -1;
If you've decided to return an HRESULT then use something more appropriate here instead of -1.
- hr = pfRegister();
- if(DllHandle)
FreeLibrary(DllHandle);
'if(DllHandle)' check above is redundant.
- return hr;
+}
If you are returning an HRESULT then use an appropriate return type for the function.
+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;
Same as above.
- hr = pfInstall(install, command_line);
- if(DllHandle)
FreeLibrary(DllHandle);
Same as above.
+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;
Why not 'return' isntead of 'goto'?
- 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;
- }
Same here.
- 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;
+}
You are returning 'res' while using 'retval' in some code paths.
Dmitry Timoshkov wrote:
"Johan Dahlin" jdahlin@gmail.com wrote:
+typedef HRESULT (*DLLREGISTER) (void); +typedef HRESULT (*DLLINSTALL) (BOOL,LPCWSTR);
Wrong calling convention.
I'm not sure I follow here. (This is all quite of new to me) Are you telling me that I should add WINAPI after HRESULT?
- hr = pfRegister();
- if(DllHandle)
FreeLibrary(DllHandle);
'if(DllHandle)' check above is redundant.
Will fix.
- return hr;
+}
If you are returning an HRESULT then use an appropriate return type for the function.
I wanted to propagate the return value from the called function, but perhaps I should just refactor a bit and do the logging in there instead.
+static BOOL ProcessRunOnceExKey(HKEY hkRunEntry) +{
[..]
Why not 'return' isntead of 'goto'?
To avoid duplicating a couple of HeapFree() calls. Besides, I'm conforming to the style of the file, the same construct is used at other places in the same file.
You are returning 'res' while using 'retval' in some code paths.
Well, they are used for different things. But sure, I'll try to avoid it and thus make it a bit clearer.
Johan