Pass argv[0] (service name) to the service program.
This commit is contained in:
parent
530e789d7e
commit
6a36f28f2a
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue