Introduced service thread

Alexander Yaworsky yaworsky at migusoft.ru
Tue Sep 21 02:09:27 CDT 2004


Hello

ChangeLog:

- introduced service thread
- removed duplicate code from StartServiceCtrlDispatcherA/W into helper function
- signal StartService that service has been started

Index: dlls/advapi32/service.c
===================================================================
RCS file: /home/wine/wine/dlls/advapi32/service.c,v
retrieving revision 1.58
diff -u -r1.58 service.c
--- dlls/advapi32/service.c 21 Sep 2004 00:23:32 -0000 1.58
+++ dlls/advapi32/service.c 21 Sep 2004 06:30:35 -0000
@@ -39,12 +39,21 @@
       'S','e','r','v','i','c','e','s','\\',0 };
 static const WCHAR  szSCMLock[] = {'A','D','V','A','P','I','_','S','C','M',
                                    'L','O','C','K',0};
+static const WCHAR  szWaitServiceStartW[]  = {'A','D','V','A','P','I','_','W',
+                                              'a','i','t','S','e','r','v','i',
+                                              'c','e','S','t','a','r','t',0};
 static const WCHAR  szServiceShmemNameFmtW[] = {'A','D','V','A','P','I','_',
                                                 'S','E','B','_','%','s',0};
 
 struct SEB              /* service environment block */
 {                       /*   resides in service's shared memory object */
     DWORD argc;
+    union               /* argument vectors */
+    {
+        LPSTR *A;
+        LPWSTR *W;
+    } argv;
+    LPSERVICE_MAIN_FUNCTIONW service_main;
     /* variable part of SEB contains service arguments */
 };
 
@@ -218,6 +227,30 @@
 }
 
 /******************************************************************************
+ * open_seb_shmem
+ *
+ * helper function for StartServiceCtrlDispatcherA/W
+ */
+static struct SEB* open_seb_shmem( LPWSTR service_name, HANDLE* hServiceShmem )
+{
+    WCHAR object_name[ MAX_PATH ];
+    HANDLE hmem;
+    struct SEB *ret;
+
+    snprintfW( object_name, MAX_PATH, szServiceShmemNameFmtW, service_name );
+    hmem = OpenFileMappingW( FILE_MAP_ALL_ACCESS, FALSE, object_name );
+    if( NULL == hmem )
+        return NULL;
+
+    ret = MapViewOfFile( hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
+    if( NULL == ret )
+        CloseHandle( hmem );
+    else
+        *hServiceShmem = hmem;
+    return ret;
+}
+
+/******************************************************************************
  * build_arg_vectors
  *
  * helper function for StartServiceCtrlDispatcherA/W
@@ -246,88 +279,113 @@
 }
 
 /******************************************************************************
+ * service_thread
+ */
+static DWORD WINAPI service_thread( LPVOID lpParameter )
+{
+    struct SEB *seb = lpParameter;
+
+    seb->service_main( seb->argc, seb->argv.W );
+    return 0;
+}
+
+/******************************************************************************
+ * service_ctrl_dispatcher
+ *
+ * helper function for StartServiceCtrlDispatcherA/W
+ *
+ * FIXME: Create synchronization objects.
+ * Create service thread and signal that service has been started.
+ * FIXME: Accept control requests and call service control handler.
+ */
+static BOOL service_ctrl_dispatcher( struct SEB* seb )
+{
+    HANDLE hThread, wait;
+
+    hThread = CreateThread( NULL, 0, service_thread, seb, 0, NULL );
+    if( NULL == hThread )
+        return FALSE;
+
+    wait = OpenSemaphoreW(SEMAPHORE_MODIFY_STATE,FALSE,szWaitServiceStartW);
+    if (!wait)
+    {
+        ERR("Couldn't open wait semaphore\n");
+        /* return FALSE; */
+    }
+    else
+    {
+        ReleaseSemaphore( wait, 1, NULL );
+        CloseHandle( wait );
+    }
+
+    WaitForSingleObject( hThread, INFINITE );
+    CloseHandle( hThread );
+
+    return TRUE;
+}
+
+/******************************************************************************
  * StartServiceCtrlDispatcherA [ADVAPI32.@]
  */
 BOOL WINAPI
 StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
 {
-    LPSERVICE_MAIN_FUNCTIONA fpMain;
     WCHAR service_name[ MAX_SERVICE_NAME ];
-    WCHAR object_name[ MAX_PATH ];
     HANDLE hServiceShmem = NULL;
     struct SEB *seb = NULL;
-    DWORD  dwNumServiceArgs ;
     LPWSTR *lpArgVecW = NULL;
-    LPSTR  *lpArgVecA;
     unsigned int i;
+    BOOL ret = FALSE;
 
     TRACE("(%p)\n", servent);
 
     if( ! read_scm_lock_data( service_name ) )
     {
-        /* FIXME: Instead of exiting we fall through and allow
+        /* FIXME: Instead of exiting we allow
            service to be executed as ordinary program.
            This behaviour was specially introduced in the patch
            submitted against revision 1.45 and so preserved here.
          */
         FIXME("should fail with ERROR_FAILED_SERVICE_CONTROLLER_CONNECT\n");
-        dwNumServiceArgs = 0;
-        lpArgVecA = NULL;
-        goto run_service;
+        servent->lpServiceProc( 0, NULL );
+        return TRUE;
     }
 
-    snprintfW( object_name, MAX_PATH, szServiceShmemNameFmtW, service_name );
-    hServiceShmem = OpenFileMappingW( FILE_MAP_ALL_ACCESS, FALSE, object_name );
-    if( NULL == hServiceShmem )
-        return FALSE;
-
-    seb = MapViewOfFile( hServiceShmem, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
+    seb = open_seb_shmem( service_name, &hServiceShmem );
     if( NULL == seb )
-    {
-        CloseHandle( hServiceShmem );
         return FALSE;
-    }
 
     lpArgVecW = build_arg_vectors( seb );
     if( NULL == lpArgVecW )
-    {
-        UnmapViewOfFile( seb );
-        CloseHandle( hServiceShmem );
-        return FALSE;
-    }
+        goto done;
+
     lpArgVecW[0] = service_name;
-    dwNumServiceArgs = seb->argc + 1;
+    seb->argc++;
 
     /* Convert the Unicode arg vectors back to ASCII */
-    lpArgVecA = (LPSTR*) HeapAlloc( GetProcessHeap(), 0,
-                                    dwNumServiceArgs*sizeof(LPSTR) );
-    for(i=0; i<dwNumServiceArgs; i++)
-        lpArgVecA[i]=HEAP_strdupWtoA(GetProcessHeap(), 0, lpArgVecW[i]);
-
-run_service:
-    /* FIXME: should we blindly start all services? */
-    while (servent->lpServiceName) {
-        TRACE("%s at %p)\n", debugstr_a(servent->lpServiceName),servent);
-        fpMain = servent->lpServiceProc;
-
-        /* try to start the service */
-        fpMain( dwNumServiceArgs, lpArgVecA);
+    seb->argv.A = (LPSTR*) HeapAlloc( GetProcessHeap(), 0,
+                                      seb->argc*sizeof(LPSTR) );
+    for(i=0; i<seb->argc; i++)
+        seb->argv.A[i]=HEAP_strdupWtoA(GetProcessHeap(), 0, lpArgVecW[i]);
+
+    /* FIXME: find service entry by name if SERVICE_WIN32_SHARE_PROCESS */
+    TRACE("%s at %p)\n", debugstr_a(servent->lpServiceName),servent);
+    seb->service_main = (LPSERVICE_MAIN_FUNCTIONW) servent->lpServiceProc;
+    ret = service_ctrl_dispatcher( seb );
 
-        servent++;
-    }
-
-    if(dwNumServiceArgs)
+done:
+    if( seb->argv.A )
     {
         /* free arg strings */
-        for(i=0; i<dwNumServiceArgs; i++)
-            HeapFree(GetProcessHeap(), 0, lpArgVecA[i]);
-        HeapFree(GetProcessHeap(), 0, lpArgVecA);
+        for(i=0; i<seb->argc; i++)
+            HeapFree(GetProcessHeap(), 0, seb->argv.A[i]);
+        HeapFree(GetProcessHeap(), 0, seb->argv.A);
     }
 
     if( lpArgVecW ) HeapFree( GetProcessHeap(), 0, lpArgVecW );
     if( seb ) UnmapViewOfFile( seb );
     if( hServiceShmem ) CloseHandle( hServiceShmem );
-    return TRUE;
+    return ret;
 }
 
 /******************************************************************************
@@ -339,56 +397,40 @@
 BOOL WINAPI
 StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent )
 {
-    LPSERVICE_MAIN_FUNCTIONW fpMain;
     WCHAR service_name[ MAX_SERVICE_NAME ];
-    WCHAR object_name[ MAX_PATH ];
-    HANDLE hServiceShmem;
+    HANDLE hServiceShmem = NULL;
     struct SEB *seb;
-    DWORD  dwNumServiceArgs ;
-    LPWSTR *lpServiceArgVectors ;
+    BOOL ret;
 
     TRACE("(%p)\n", servent);
 
     if( ! read_scm_lock_data( service_name ) )
         return FALSE;
 
-    snprintfW( object_name, MAX_PATH, szServiceShmemNameFmtW, service_name );
-    hServiceShmem = OpenFileMappingW( FILE_MAP_ALL_ACCESS, FALSE, object_name );
-    if( NULL == hServiceShmem )
-        return FALSE;
-
-    seb = MapViewOfFile( hServiceShmem, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
+    seb = open_seb_shmem( service_name, &hServiceShmem );
     if( NULL == seb )
-    {
-        CloseHandle( hServiceShmem );
         return FALSE;
-    }
 
-    lpServiceArgVectors = build_arg_vectors( seb );
-    if( NULL == lpServiceArgVectors )
+    seb->argv.W = build_arg_vectors( seb );
+    if( NULL == seb->argv.W )
     {
         UnmapViewOfFile( seb );
         CloseHandle( hServiceShmem );
         return FALSE;
     }
-    lpServiceArgVectors[0] = service_name;
-    dwNumServiceArgs = seb->argc + 1;
-
-    /* FIXME: should we blindly start all services? */
-    while (servent->lpServiceName) {
-        TRACE("%s at %p)\n", debugstr_w(servent->lpServiceName),servent);
-        fpMain = servent->lpServiceProc;
 
-        /* try to start the service */
-        fpMain( dwNumServiceArgs, lpServiceArgVectors);
+    seb->argv.W[0] = service_name;
+    seb->argc++;
 
-        servent++;
-    }
+    /* FIXME: find service entry by name if SERVICE_WIN32_SHARE_PROCESS */
+    TRACE("%s at %p)\n", debugstr_w(servent->lpServiceName),servent);
+    seb->service_main = servent->lpServiceProc;
+    ret = service_ctrl_dispatcher( seb );
 
-    HeapFree( GetProcessHeap(), 0, lpServiceArgVectors );
+    HeapFree( GetProcessHeap(), 0, seb->argv.W );
     UnmapViewOfFile( seb );
     CloseHandle( hServiceShmem );
-    return TRUE;
+    return ret;
 }
 
 /******************************************************************************
@@ -972,9 +1014,6 @@
 StartServiceW( SC_HANDLE hService, DWORD dwNumServiceArgs,
                  LPCWSTR *lpServiceArgVectors )
 {
-    static const WCHAR  _WaitServiceStartW[]  = {'A','D','V','A','P','I','_','W',
-                                                'a','i','t','S','e','r','v','i',
-                                                'c','e','S','t','a','r','t',0};
     static const WCHAR  _ImagePathW[]  = {'I','m','a','g','e','P','a','t','h',0};
                                                 
     struct sc_handle *hsvc = hService;
@@ -1055,7 +1094,7 @@
         argptr += 1 + strlenW( argptr );
     }
 
-    wait = CreateSemaphoreW(NULL,0,1,_WaitServiceStartW);
+    wait = CreateSemaphoreW(NULL,0,1,szWaitServiceStartW);
     if (!wait)
     {
         ERR("Couldn't create wait semaphore\n");




More information about the wine-patches mailing list