Pass argv[0] (service name) to the service program.

This commit is contained in:
Alexander Yaworsky 2004-09-16 20:27:31 +00:00 committed by Alexandre Julliard
parent 530e789d7e
commit 6a36f28f2a
1 changed files with 81 additions and 47 deletions

View File

@ -34,12 +34,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(advapi); WINE_DEFAULT_DEBUG_CHANNEL(advapi);
static DWORD start_dwNumServiceArgs;
static LPWSTR *start_lpServiceArgVectors;
static const WCHAR _ServiceStartDataW[] = {'A','D','V','A','P','I','_','S',
'e','r','v','i','c','e','S','t',
'a','r','t','D','a','t','a',0};
static const WCHAR szServiceManagerKey[] = { 'S','y','s','t','e','m','\\', static const WCHAR szServiceManagerKey[] = { 'S','y','s','t','e','m','\\',
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
'S','e','r','v','i','c','e','s','\\',0 }; 'S','e','r','v','i','c','e','s','\\',0 };
@ -183,6 +177,38 @@ EnumServicesStatusW( SC_HANDLE hSCManager, DWORD dwServiceType,
return FALSE; return FALSE;
} }
/******************************************************************************
* read_scm_lock_data
*
* helper function for StartServiceCtrlDispatcherA/W
*
* SCM database is locked by StartService;
* open global SCM lock object and read service name
*/
static BOOL read_scm_lock_data( LPWSTR buffer )
{
HANDLE hLock;
LPWSTR argptr;
hLock = OpenFileMappingW( FILE_MAP_ALL_ACCESS, FALSE, szSCMLock );
if( NULL == hLock )
{
SetLastError( ERROR_FAILED_SERVICE_CONTROLLER_CONNECT );
return FALSE;
}
argptr = MapViewOfFile( hLock, FILE_MAP_ALL_ACCESS,
0, 0, MAX_SERVICE_NAME * sizeof(WCHAR) );
if( NULL == argptr )
{
CloseHandle( hLock );
return FALSE;
}
strcpyW( buffer, argptr );
UnmapViewOfFile( argptr );
CloseHandle( hLock );
return TRUE;
}
/****************************************************************************** /******************************************************************************
* StartServiceCtrlDispatcherA [ADVAPI32.@] * StartServiceCtrlDispatcherA [ADVAPI32.@]
*/ */
@ -190,24 +216,32 @@ BOOL WINAPI
StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent ) StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
{ {
LPSERVICE_MAIN_FUNCTIONA fpMain; LPSERVICE_MAIN_FUNCTIONA fpMain;
HANDLE wait; WCHAR service_name[ MAX_SERVICE_NAME ];
LPWSTR argv0;
DWORD dwNumServiceArgs ; DWORD dwNumServiceArgs ;
LPWSTR *lpArgVecW; LPWSTR *lpArgVecW;
LPSTR *lpArgVecA; LPSTR *lpArgVecA;
unsigned int i; unsigned int i;
TRACE("(%p)\n", servent); TRACE("(%p)\n", servent);
wait = CreateSemaphoreW(NULL,1,1,_ServiceStartDataW);
if (!wait) if( ! read_scm_lock_data( service_name ) )
{ {
ERR("Couldn't create data semaphore\n"); /* FIXME: Instead of exiting we fall through and allow
return FALSE; 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;
} }
dwNumServiceArgs = start_dwNumServiceArgs; /* FIXME: other args */
lpArgVecW = start_lpServiceArgVectors; dwNumServiceArgs = 1;
argv0 = service_name;
ReleaseSemaphore(wait, 1, NULL); lpArgVecW = &argv0;
/* Convert the Unicode arg vectors back to ASCII */ /* Convert the Unicode arg vectors back to ASCII */
if(dwNumServiceArgs) if(dwNumServiceArgs)
@ -219,6 +253,7 @@ StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
for(i=0; i<dwNumServiceArgs; i++) for(i=0; i<dwNumServiceArgs; i++)
lpArgVecA[i]=HEAP_strdupWtoA(GetProcessHeap(), 0, lpArgVecW[i]); lpArgVecA[i]=HEAP_strdupWtoA(GetProcessHeap(), 0, lpArgVecW[i]);
run_service:
/* FIXME: should we blindly start all services? */ /* FIXME: should we blindly start all services? */
while (servent->lpServiceName) { while (servent->lpServiceName) {
TRACE("%s at %p)\n", debugstr_a(servent->lpServiceName),servent); TRACE("%s at %p)\n", debugstr_a(servent->lpServiceName),servent);
@ -251,23 +286,20 @@ BOOL WINAPI
StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent ) StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent )
{ {
LPSERVICE_MAIN_FUNCTIONW fpMain; LPSERVICE_MAIN_FUNCTIONW fpMain;
HANDLE wait; LPWSTR argv0;
WCHAR service_name[ MAX_SERVICE_NAME ];
DWORD dwNumServiceArgs ; DWORD dwNumServiceArgs ;
LPWSTR *lpServiceArgVectors ; LPWSTR *lpServiceArgVectors ;
TRACE("(%p)\n", servent); TRACE("(%p)\n", servent);
wait = OpenSemaphoreW(SEMAPHORE_ALL_ACCESS, FALSE, _ServiceStartDataW);
if(wait == 0) if( ! read_scm_lock_data( service_name ) )
{
ERR("Couldn't find wait semaphore\n");
ERR("perhaps you need to start services using StartService\n");
return FALSE; return FALSE;
}
dwNumServiceArgs = start_dwNumServiceArgs; /* FIXME: other args */
lpServiceArgVectors = start_lpServiceArgVectors; dwNumServiceArgs = 1;
argv0 = service_name;
ReleaseSemaphore(wait, 1, NULL); lpServiceArgVectors = &argv0;
/* FIXME: should we blindly start all services? */ /* FIXME: should we blindly start all services? */
while (servent->lpServiceName) { while (servent->lpServiceName) {
@ -873,7 +905,9 @@ StartServiceW( SC_HANDLE hService, DWORD dwNumServiceArgs,
WCHAR path[MAX_PATH],str[MAX_PATH]; WCHAR path[MAX_PATH],str[MAX_PATH];
DWORD type,size; DWORD type,size;
long r; long r;
HANDLE data,wait; HANDLE hLock;
HANDLE wait = NULL;
LPWSTR shmem_lock = NULL;
PROCESS_INFORMATION procinfo; PROCESS_INFORMATION procinfo;
STARTUPINFOW startupinfo; STARTUPINFOW startupinfo;
BOOL ret = FALSE; BOOL ret = FALSE;
@ -889,36 +923,36 @@ StartServiceW( SC_HANDLE hService, DWORD dwNumServiceArgs,
TRACE("Starting service %s\n", debugstr_w(path) ); TRACE("Starting service %s\n", debugstr_w(path) );
data = CreateSemaphoreW(NULL,1,1,_ServiceStartDataW); hLock = LockServiceDatabase( hsvc->u.service.sc_manager );
if (!data) if( NULL == hLock )
{
ERR("Couldn't create data semaphore\n");
return FALSE; return FALSE;
/*
* FIXME: start dependent services
*/
/* pass argv[0] (service name) to the service via global SCM lock object */
shmem_lock = MapViewOfFile( hLock, FILE_MAP_ALL_ACCESS,
0, 0, MAX_SERVICE_NAME * sizeof(WCHAR) );
if( NULL == shmem_lock )
{
ERR("Couldn't map shared memory\n");
goto done;
} }
strcpyW( shmem_lock, hsvc->u.service.name );
wait = CreateSemaphoreW(NULL,0,1,_WaitServiceStartW); wait = CreateSemaphoreW(NULL,0,1,_WaitServiceStartW);
if (!wait) if (!wait)
{ {
ERR("Couldn't create wait semaphore\n"); ERR("Couldn't create wait semaphore\n");
return FALSE; goto done;
} }
/* /*
* FIXME: lpServiceArgsVectors need to be stored and returned to * FIXME: lpServiceArgsVectors need to be stored and returned to
* the service when it calls StartServiceCtrlDispatcher * the service when it calls StartServiceCtrlDispatcher
*
* Chuck these in a global (yuk) so we can pass them to
* another process - address space separation will break this.
*/ */
r = WaitForSingleObject(data,INFINITE);
if( r == WAIT_FAILED)
return FALSE;
FIXME("problematic because of address space separation.\n");
start_dwNumServiceArgs = dwNumServiceArgs;
start_lpServiceArgVectors = (LPWSTR *)lpServiceArgVectors;
ZeroMemory(&startupinfo,sizeof(STARTUPINFOW)); ZeroMemory(&startupinfo,sizeof(STARTUPINFOW));
startupinfo.cb = sizeof(STARTUPINFOW); startupinfo.cb = sizeof(STARTUPINFOW);
@ -953,9 +987,9 @@ StartServiceW( SC_HANDLE hService, DWORD dwNumServiceArgs,
ret = TRUE; ret = TRUE;
done: done:
CloseHandle( wait ); if( wait ) CloseHandle( wait );
ReleaseSemaphore(data, 1, NULL); if( shmem_lock != NULL ) UnmapViewOfFile( shmem_lock );
CloseHandle( data ); UnlockServiceDatabase( hLock );
return ret; return ret;
} }