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