Merge Unicode and ASCII versions of StartServiceCtrlDispatcher.

Implement StartServiceCtrlDispatcherA on the top of
StartServiceCtrlDispatcherW.
Get rid of HEAP_strdupWtoA.
This commit is contained in:
Alexander Yaworsky 2004-11-30 17:29:03 +00:00 committed by Alexandre Julliard
parent d7dd3e37c8
commit 8109cfd443
1 changed files with 62 additions and 66 deletions

View File

@ -28,7 +28,6 @@
#include "winerror.h" #include "winerror.h"
#include "winreg.h" #include "winreg.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "heap.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "winternl.h" #include "winternl.h"
@ -225,7 +224,7 @@ EnumServicesStatusW( SC_HANDLE hSCManager, DWORD dwServiceType,
/****************************************************************************** /******************************************************************************
* read_scm_lock_data * read_scm_lock_data
* *
* helper function for StartServiceCtrlDispatcherA/W * helper function for service control dispatcher
* *
* SCM database is locked by StartService; * SCM database is locked by StartService;
* open global SCM lock object and read service name * open global SCM lock object and read service name
@ -257,7 +256,7 @@ static BOOL read_scm_lock_data( LPWSTR buffer )
/****************************************************************************** /******************************************************************************
* open_seb_shmem * 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 ) static struct SEB* open_seb_shmem( LPWSTR service_name, HANDLE* hServiceShmem )
{ {
@ -281,7 +280,7 @@ static struct SEB* open_seb_shmem( LPWSTR service_name, HANDLE* hServiceShmem )
/****************************************************************************** /******************************************************************************
* build_arg_vectors * 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 * Allocate and initialize array of LPWSTRs to arguments in variable part
* of service environment block. * of service environment block.
@ -307,23 +306,20 @@ static LPWSTR* build_arg_vectors( struct SEB* seb )
} }
/****************************************************************************** /******************************************************************************
* StartServiceCtrlDispatcherA [ADVAPI32.@] * service_ctrl_dispatcher
*
* helper function for StartServiceCtrlDispatcherA/W
*/ */
BOOL WINAPI static BOOL service_ctrl_dispatcher( LPSERVICE_TABLE_ENTRYW servent, BOOL ascii )
StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
{ {
LPSERVICE_MAIN_FUNCTIONA fpMain;
WCHAR service_name[ MAX_SERVICE_NAME ]; WCHAR service_name[ MAX_SERVICE_NAME ];
HANDLE hServiceShmem = NULL; HANDLE hServiceShmem = NULL;
struct SEB *seb = NULL; struct SEB *seb = NULL;
DWORD dwNumServiceArgs = 0; DWORD dwNumServiceArgs;
LPWSTR *lpArgVecW = NULL; LPWSTR *lpArgVecW = NULL;
LPSTR *lpArgVecA = NULL;
unsigned int i; unsigned int i;
BOOL ret = FALSE; BOOL ret = FALSE;
TRACE("(%p)\n", servent);
if( ! read_scm_lock_data( service_name ) ) if( ! read_scm_lock_data( service_name ) )
{ {
/* FIXME: Instead of exiting we allow /* FIXME: Instead of exiting we allow
@ -347,34 +343,69 @@ StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
lpArgVecW[0] = service_name; lpArgVecW[0] = service_name;
dwNumServiceArgs = seb->argc + 1; dwNumServiceArgs = seb->argc + 1;
/* Convert the Unicode arg vectors back to ASCII */ if( ascii )
lpArgVecA = (LPSTR*) HeapAlloc( GetProcessHeap(), 0, /* Convert the Unicode arg vectors back to ASCII */
dwNumServiceArgs*sizeof(LPSTR) ); for(i=0; i<dwNumServiceArgs; i++)
for(i=0; i<dwNumServiceArgs; i++) {
lpArgVecA[i]=HEAP_strdupWtoA(GetProcessHeap(), 0, lpArgVecW[i]); LPWSTR src = lpArgVecW[i];
int len = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL );
/* FIXME: find service entry by name if SERVICE_WIN32_SHARE_PROCESS */ LPSTR dest = HeapAlloc( GetProcessHeap(), 0, len );
TRACE("%s at %p)\n", debugstr_a(servent->lpServiceName),servent); if( NULL == dest )
fpMain = servent->lpServiceProc; 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 */ /* try to start the service */
fpMain( dwNumServiceArgs, lpArgVecA); servent->lpServiceProc( dwNumServiceArgs, lpArgVecW);
ret = TRUE;
done: 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( lpArgVecW ) HeapFree( GetProcessHeap(), 0, lpArgVecW );
if( seb ) UnmapViewOfFile( seb ); if( seb ) UnmapViewOfFile( seb );
if( hServiceShmem ) CloseHandle( hServiceShmem ); if( hServiceShmem ) CloseHandle( hServiceShmem );
return ret; return ret;
} }
/******************************************************************************
* StartServiceCtrlDispatcherA [ADVAPI32.@]
*/
BOOL WINAPI
StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
{
int count, i;
LPSERVICE_TABLE_ENTRYW ServiceTableW;
BOOL ret;
TRACE("(%p)\n", servent);
/* 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;
for( i = 0; i < count; i++ )
{
ServiceTableW[ i ].lpServiceName = SERV_dup( servent[ i ].lpServiceName );
ServiceTableW[ i ].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONW) servent[ i ].lpServiceProc;
}
ServiceTableW[ count ].lpServiceName = NULL;
ServiceTableW[ count ].lpServiceProc = NULL;
/* start dispatcher */
ret = service_ctrl_dispatcher( ServiceTableW, TRUE );
/* free service table */
for( i = 0; i < count; i++ )
SERV_free( ServiceTableW[ i ].lpServiceName );
HeapFree( GetProcessHeap(), 0, ServiceTableW );
return ret;
}
/****************************************************************************** /******************************************************************************
* StartServiceCtrlDispatcherW [ADVAPI32.@] * StartServiceCtrlDispatcherW [ADVAPI32.@]
* *
@ -384,43 +415,8 @@ done:
BOOL WINAPI BOOL WINAPI
StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent ) StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent )
{ {
LPSERVICE_MAIN_FUNCTIONW fpMain;
WCHAR service_name[ MAX_SERVICE_NAME ];
HANDLE hServiceShmem = NULL;
struct SEB *seb;
DWORD dwNumServiceArgs ;
LPWSTR *lpServiceArgVectors ;
TRACE("(%p)\n", servent); TRACE("(%p)\n", servent);
return service_ctrl_dispatcher( servent, FALSE );
if( ! read_scm_lock_data( service_name ) )
return FALSE;
seb = open_seb_shmem( service_name, &hServiceShmem );
if( NULL == seb )
return FALSE;
lpServiceArgVectors = build_arg_vectors( seb );
if( NULL == lpServiceArgVectors )
{
UnmapViewOfFile( seb );
CloseHandle( hServiceShmem );
return FALSE;
}
lpServiceArgVectors[0] = service_name;
dwNumServiceArgs = seb->argc + 1;
/* FIXME: find service entry by name if SERVICE_WIN32_SHARE_PROCESS */
TRACE("%s at %p)\n", debugstr_w(servent->lpServiceName),servent);
fpMain = servent->lpServiceProc;
/* try to start the service */
fpMain( dwNumServiceArgs, lpServiceArgVectors);
HeapFree( GetProcessHeap(), 0, lpServiceArgVectors );
UnmapViewOfFile( seb );
CloseHandle( hServiceShmem );
return TRUE;
} }
/****************************************************************************** /******************************************************************************