Introduced service thread.
authorAlexander Yaworsky <yaworsky@migusoft.ru>
Wed, 1 Dec 2004 15:31:34 +0000 (15:31 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Wed, 1 Dec 2004 15:31:34 +0000 (15:31 +0000)
dlls/advapi32/service.c

index 0193b2463a0b83ff428242015bdf70204a6634e4..57c539134797f7598cead07d733b337847c42c31 100644 (file)
@@ -305,6 +305,26 @@ static LPWSTR* build_arg_vectors( struct SEB* seb )
     return ret;
 }
 
+/******************************************************************************
+ * service thread
+ */
+struct service_thread_data
+{
+    WCHAR service_name[ MAX_SERVICE_NAME ];
+    CHAR service_nameA[ MAX_SERVICE_NAME ];
+    LPSERVICE_MAIN_FUNCTIONW service_main;
+    DWORD argc;
+    LPWSTR *argv;
+};
+
+static DWORD WINAPI service_thread( LPVOID arg )
+{
+    struct service_thread_data *data = arg;
+
+    data->service_main( data->argc, data->argv );
+    return 0;
+}
+
 /******************************************************************************
  * service_ctrl_dispatcher
  *
@@ -312,15 +332,17 @@ static LPWSTR* build_arg_vectors( struct SEB* seb )
  */
 static BOOL service_ctrl_dispatcher( LPSERVICE_TABLE_ENTRYW servent, BOOL ascii )
 {
-    WCHAR service_name[ MAX_SERVICE_NAME ];
     HANDLE hServiceShmem = NULL;
     struct SEB *seb = NULL;
-    DWORD  dwNumServiceArgs;
-    LPWSTR *lpArgVecW = NULL;
+    struct service_thread_data *thread_data;
     unsigned int i;
-    BOOL ret = FALSE;
+    HANDLE thread;
+
+    thread_data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct service_thread_data) );
+    if( NULL == thread_data )
+        return FALSE;
 
-    if( ! read_scm_lock_data( service_name ) )
+    if( ! read_scm_lock_data( thread_data->service_name ) )
     {
         /* FIXME: Instead of exiting we allow
            service to be executed as ordinary program.
@@ -329,44 +351,65 @@ static BOOL service_ctrl_dispatcher( LPSERVICE_TABLE_ENTRYW servent, BOOL ascii
          */
         FIXME("should fail with ERROR_FAILED_SERVICE_CONTROLLER_CONNECT\n");
         servent->lpServiceProc( 0, NULL );
+        HeapFree( GetProcessHeap(), 0, thread_data );
         return TRUE;
     }
 
-    seb = open_seb_shmem( service_name, &hServiceShmem );
+    seb = open_seb_shmem( thread_data->service_name, &hServiceShmem );
     if( NULL == seb )
-        return FALSE;
+        goto error;
 
-    lpArgVecW = build_arg_vectors( seb );
-    if( NULL == lpArgVecW )
-        goto done;
+    thread_data->argv = build_arg_vectors( seb );
+    if( NULL == thread_data->argv )
+        goto error;
 
-    lpArgVecW[0] = service_name;
-    dwNumServiceArgs = seb->argc + 1;
+    thread_data->argv[0] = thread_data->service_name;
+    thread_data->argc = seb->argc + 1;
 
     if( ascii )
-        /* Convert the Unicode arg vectors back to ASCII */
-        for(i=0; i<dwNumServiceArgs; i++)
+    {
+        /* Convert the Unicode arg vectors back to ASCII;
+         * but we'll need unicode service name (argv[0]) for object names */
+        WideCharToMultiByte( CP_ACP, 0, thread_data->argv[0], -1,
+                             thread_data->service_nameA, MAX_SERVICE_NAME, NULL, NULL );
+        thread_data->argv[0] = (LPWSTR) thread_data->service_nameA;
+
+        for(i=1; i<thread_data->argc; i++)
         {
-            LPWSTR src = lpArgVecW[i];
+            LPWSTR src = thread_data->argv[i];
             int len = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL );
             LPSTR dest = HeapAlloc( GetProcessHeap(), 0, len );
             if( NULL == dest )
-                goto done;
+                goto error;
             WideCharToMultiByte( CP_ACP, 0, src, -1, dest, len, NULL, NULL );
             /* copy converted string back  */
             memcpy( src, dest, len );
             HeapFree( GetProcessHeap(), 0, dest );
         }
+    }
 
-    /* try to start the service */
-    servent->lpServiceProc( dwNumServiceArgs, lpArgVecW);
-    ret = TRUE;
+    /* start the service thread */
+    thread_data->service_main = servent->lpServiceProc;
+    thread = CreateThread( NULL, 0, service_thread, thread_data, 0, NULL );
+    if( NULL == thread )
+        goto error;
 
-done:
-    if( lpArgVecW ) HeapFree( GetProcessHeap(), 0, lpArgVecW );
+    /* FIXME: dispatch control requests */
+    WaitForSingleObject( thread, INFINITE );
+    CloseHandle( thread );
+
+    HeapFree( GetProcessHeap(), 0, thread_data->argv );
+    HeapFree( GetProcessHeap(), 0, thread_data );
+    UnmapViewOfFile( seb );
+    CloseHandle( hServiceShmem );
+    return TRUE;
+
+error:
+    if( thread_data->argv ) HeapFree( GetProcessHeap(), 0, thread_data->argv );
     if( seb ) UnmapViewOfFile( seb );
     if( hServiceShmem ) CloseHandle( hServiceShmem );
-    return ret;
+    HeapFree( GetProcessHeap(), 0, thread_data );
+    return FALSE;
 }
 
 /******************************************************************************