diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 84291c3922b..39e3665f7d5 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -773,6 +773,45 @@ static BOOL process_init(void) } +/*********************************************************************** + * start_wineboot + * + * Start the wineboot process if necessary. Return the event to wait on. + */ +static HANDLE start_wineboot(void) +{ + static const WCHAR wineboot_eventW[] = {'_','_','w','i','n','e','b','o','o','t','_','e','v','e','n','t',0}; + HANDLE event; + + if (!(event = CreateEventW( NULL, TRUE, FALSE, wineboot_eventW ))) + { + ERR( "failed to create wineboot event, expect trouble\n" ); + return 0; + } + if (GetLastError() != ERROR_ALREADY_EXISTS) /* we created it */ + { + static const WCHAR command_line[] = {'\\','w','i','n','e','b','o','o','t','.','e','x','e',0}; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + WCHAR cmdline[MAX_PATH + sizeof(command_line)/sizeof(WCHAR)]; + + memset( &si, 0, sizeof(si) ); + si.cb = sizeof(si); + GetSystemDirectoryW( cmdline, MAX_PATH ); + lstrcatW( cmdline, command_line ); + if (CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi )) + { + TRACE( "started wineboot pid %04x tid %04x\n", pi.dwProcessId, pi.dwThreadId ); + CloseHandle( pi.hThread ); + CloseHandle( pi.hProcess ); + + } + else ERR( "failed to start wineboot, err %u\n", GetLastError() ); + } + return event; +} + + /*********************************************************************** * init_stack * @@ -894,6 +933,7 @@ void __wine_kernel_init(void) WCHAR *p, main_exe_name[MAX_PATH+1]; PEB *peb = NtCurrentTeb()->Peb; + HANDLE boot_event = 0; /* Initialize everything */ if (!process_init()) exit(1); @@ -913,6 +953,7 @@ void __wine_kernel_init(void) ExitProcess( GetLastError() ); } if (!build_command_line( __wine_main_wargv )) goto error; + boot_event = start_wineboot(); } /* if there's no extension, append a dot to prevent LoadLibrary from appending .dll */ @@ -944,6 +985,12 @@ void __wine_kernel_init(void) ExitProcess( error ); } + if (boot_event) + { + if (WaitForSingleObject( boot_event, 30000 )) WARN( "boot event wait timed out\n" ); + CloseHandle( boot_event ); + } + /* switch to the new stack */ wine_switch_to_stack( start_process, NULL, init_stack() ); diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in index 1f751ce950b..8d69026c340 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 = shell32 shlwapi version user32 advapi32 kernel32 +IMPORTS = shell32 shlwapi version user32 advapi32 kernel32 ntdll EXTRALIBS = -luuid C_SRCS = \ diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c index 99ba1b4cede..1552330e273 100644 --- a/programs/wineboot/wineboot.c +++ b/programs/wineboot/wineboot.c @@ -716,9 +716,13 @@ static const struct option long_options[] = int main( int argc, char *argv[] ) { + extern HANDLE __wine_make_process_system(void); + static const WCHAR wineboot_eventW[] = {'_','_','w','i','n','e','b','o','o','t','_','e','v','e','n','t',0}; + /* First, set the current directory to SystemRoot */ int optc; int end_session = 0, force = 0, kill = 0, restart = 0, shutdown = 0; + HANDLE event; GetWindowsDirectoryW( windowsdir, MAX_PATH ); if( !SetCurrentDirectoryW( windowsdir ) ) @@ -750,6 +754,9 @@ int main( int argc, char *argv[] ) if (shutdown) return 0; + event = CreateEventW( NULL, TRUE, FALSE, wineboot_eventW ); + ResetEvent( event ); /* in case this is a restart */ + wininit(); pendingRename(); @@ -769,5 +776,11 @@ int main( int argc, char *argv[] ) } WINE_TRACE("Operation done\n"); + + SetEvent( event ); + + /* FIXME: the wait is needed to keep services running */ + /* it should be removed once we have a proper services.exe */ + WaitForSingleObject( __wine_make_process_system(), INFINITE ); return 0; }