Alexandre Julliard : kernel32: Launch wineboot on first startup of a wine process.

Alexandre Julliard julliard at winehq.org
Fri Jan 4 07:12:47 CST 2008


Module: wine
Branch: master
Commit: d55b2de5747da90666065b5ed2fdeb8049282419
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d55b2de5747da90666065b5ed2fdeb8049282419

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Jan  4 12:51:04 2008 +0100

kernel32: Launch wineboot on first startup of a wine process.

---

 dlls/kernel32/process.c       |   47 +++++++++++++++++++++++++++++++++++++++++
 programs/wineboot/Makefile.in |    2 +-
 programs/wineboot/wineboot.c  |   13 +++++++++++
 3 files changed, 61 insertions(+), 1 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 84291c3..39e3665 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -774,6 +774,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
  *
  * Allocate the stack of new process.
@@ -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 1f751ce..8d69026 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 99ba1b4..1552330 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;
 }




More information about the wine-cvs mailing list