Resend: advapi32/service.c; patch 2/7: Merge Unicode and ASCII versions of StartServiceCtrlDispatcher

Alexander Yaworsky yaworsky at migusoft.ru
Mon Nov 29 21:10:28 CST 2004


ChangeLog:

Merge Unicode and ASCII versions of StartServiceCtrlDispatcher.
Implement StartServiceCtrlDispatcherA on the top of StartServiceCtrlDispatcherW.
Get rid of HEAP_strdupWtoA.

Index: dlls/advapi32/service.c
===================================================================
RCS file: /home/wine/wine/dlls/advapi32/service.c,v
retrieving revision 1.65
diff -u -r1.65 service.c
--- dlls/advapi32/service.c	21 Nov 2004 15:50:08 -0000	1.65
+++ dlls/advapi32/service.c	30 Nov 2004 03:54:36 -0000
@@ -28,7 +28,6 @@
 #include "winerror.h"
 #include "winreg.h"
 #include "wine/unicode.h"
-#include "heap.h"
 #include "wine/debug.h"
 #include "winternl.h"
 
@@ -225,7 +224,7 @@
 /******************************************************************************
  * read_scm_lock_data
  *
- * helper function for StartServiceCtrlDispatcherA/W
+ * helper function for service control dispatcher
  *
  * SCM database is locked by StartService;
  * open global SCM lock object and read service name
@@ -257,7 +256,7 @@
 /******************************************************************************
  * open_seb_shmem
  *
- * helper function for StartServiceCtrlDispatcherA/W
+ * helper function for service control dispatcher
  */
 static struct SEB* open_seb_shmem( LPWSTR service_name, HANDLE* hServiceShmem )
 {
@@ -281,7 +280,7 @@
 /******************************************************************************
  * build_arg_vectors
  *
- * helper function for StartServiceCtrlDispatcherA/W
+ * helper function for service control dispatcher
  *
  * Allocate and initialize array of LPWSTRs to arguments in variable part
  * of service environment block.
@@ -307,23 +306,20 @@
 }
 
 /******************************************************************************
- * StartServiceCtrlDispatcherA [ADVAPI32.@]
+ * service_ctrl_dispatcher
+ *
+ * helper function for StartServiceCtrlDispatcherA/W
  */
-BOOL WINAPI
-StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
+static BOOL service_ctrl_dispatcher( LPSERVICE_TABLE_ENTRYW servent, BOOL ascii )
 {
-    LPSERVICE_MAIN_FUNCTIONA fpMain;
     WCHAR service_name[ MAX_SERVICE_NAME ];
     HANDLE hServiceShmem = NULL;
     struct SEB *seb = NULL;
-    DWORD  dwNumServiceArgs = 0;
+    DWORD  dwNumServiceArgs;
     LPWSTR *lpArgVecW = NULL;
-    LPSTR  *lpArgVecA = NULL;
     unsigned int i;
     BOOL ret = FALSE;
 
-    TRACE("(%p)\n", servent);
-
     if( ! read_scm_lock_data( service_name ) )
     {
         /* FIXME: Instead of exiting we allow
@@ -347,28 +343,26 @@
     lpArgVecW[0] = service_name;
     dwNumServiceArgs = seb->argc + 1;
 
-    /* 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]);
-
-    /* FIXME: find service entry by name if SERVICE_WIN32_SHARE_PROCESS */
-    TRACE("%s at %p)\n", debugstr_a(servent->lpServiceName),servent);
-    fpMain = servent->lpServiceProc;
+    if( ascii )
+        /* Convert the Unicode arg vectors back to ASCII */
+        for(i=0; i<dwNumServiceArgs; i++)
+        {
+            LPWSTR src = lpArgVecW[i];
+            int len = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL );
+            LPSTR dest = HeapAlloc( GetProcessHeap(), 0, len );
+            if( NULL == dest )
+                goto done;
+            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 */
-    fpMain( dwNumServiceArgs, lpArgVecA);
+    servent->lpServiceProc( dwNumServiceArgs, lpArgVecW);
+    ret = TRUE;
 
 done:
-    if(dwNumServiceArgs)
-    {
-        /* free arg strings */
-        for(i=0; i<dwNumServiceArgs; i++)
-            HeapFree(GetProcessHeap(), 0, lpArgVecA[i]);
-        HeapFree(GetProcessHeap(), 0, lpArgVecA);
-    }
-
     if( lpArgVecW ) HeapFree( GetProcessHeap(), 0, lpArgVecW );
     if( seb ) UnmapViewOfFile( seb );
     if( hServiceShmem ) CloseHandle( hServiceShmem );
@@ -376,51 +370,53 @@
 }
 
 /******************************************************************************
- * StartServiceCtrlDispatcherW [ADVAPI32.@]
- *
- * PARAMS
- *   servent []
+ * StartServiceCtrlDispatcherA [ADVAPI32.@]
  */
 BOOL WINAPI
-StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent )
+StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
 {
-    LPSERVICE_MAIN_FUNCTIONW fpMain;
-    WCHAR service_name[ MAX_SERVICE_NAME ];
-    HANDLE hServiceShmem = NULL;
-    struct SEB *seb;
-    DWORD  dwNumServiceArgs ;
-    LPWSTR *lpServiceArgVectors ;
+    int count, i;
+    LPSERVICE_TABLE_ENTRYW ServiceTableW;
+    BOOL ret;
 
     TRACE("(%p)\n", servent);
 
-    if( ! read_scm_lock_data( service_name ) )
-        return FALSE;
-
-    seb = open_seb_shmem( service_name, &hServiceShmem );
-    if( NULL == seb )
+    /* convert service table to unicode */
+    for( count = 0; servent[ count ].lpServiceName; )
+        count++;
+    ServiceTableW = HeapAlloc( GetProcessHeap(), 0, (count + 1) * sizeof(SERVICE_TABLE_ENTRYW) );
+    if( NULL == ServiceTableW )
         return FALSE;
 
-    lpServiceArgVectors = build_arg_vectors( seb );
-    if( NULL == lpServiceArgVectors )
+    for( i = 0; i < count; i++ )
     {
-        UnmapViewOfFile( seb );
-        CloseHandle( hServiceShmem );
-        return FALSE;
+        ServiceTableW[ i ].lpServiceName = SERV_dup( servent[ i ].lpServiceName );
+        ServiceTableW[ i ].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONW) servent[ i ].lpServiceProc;
     }
-    lpServiceArgVectors[0] = service_name;
-    dwNumServiceArgs = seb->argc + 1;
+    ServiceTableW[ count ].lpServiceName = NULL;
+    ServiceTableW[ count ].lpServiceProc = NULL;
 
-    /* FIXME: find service entry by name if SERVICE_WIN32_SHARE_PROCESS */
-    TRACE("%s at %p)\n", debugstr_w(servent->lpServiceName),servent);
-    fpMain = servent->lpServiceProc;
+    /* start dispatcher */
+    ret = service_ctrl_dispatcher( ServiceTableW, TRUE );
 
-    /* try to start the service */
-    fpMain( dwNumServiceArgs, lpServiceArgVectors);
+    /* free service table */
+    for( i = 0; i < count; i++ )
+        SERV_free( ServiceTableW[ i ].lpServiceName );
+    HeapFree( GetProcessHeap(), 0, ServiceTableW );
+    return ret;
+}
 
-    HeapFree( GetProcessHeap(), 0, lpServiceArgVectors );
-    UnmapViewOfFile( seb );
-    CloseHandle( hServiceShmem );
-    return TRUE;
+/******************************************************************************
+ * StartServiceCtrlDispatcherW [ADVAPI32.@]
+ *
+ * PARAMS
+ *   servent []
+ */
+BOOL WINAPI
+StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent )
+{
+    TRACE("(%p)\n", servent);
+    return service_ctrl_dispatcher( servent, FALSE );
 }
 
 /******************************************************************************



More information about the wine-patches mailing list