From 78b64795d77e6d2d753d908520fd99b79d4c3b46 Mon Sep 17 00:00:00 2001 From: Alexander Yaworsky Date: Wed, 1 Dec 2004 15:31:34 +0000 Subject: [PATCH] Introduced service thread. --- dlls/advapi32/service.c | 87 ++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 0193b2463a0..57c53913479 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -305,6 +305,26 @@ static LPWSTR* build_arg_vectors( struct SEB* seb ) return ret; } +/****************************************************************************** + * service thread + */ +struct service_thread_data +{ + WCHAR service_name[ MAX_SERVICE_NAME ]; + CHAR service_nameA[ MAX_SERVICE_NAME ]; + LPSERVICE_MAIN_FUNCTIONW service_main; + DWORD argc; + LPWSTR *argv; +}; + +static DWORD WINAPI service_thread( LPVOID arg ) +{ + struct service_thread_data *data = arg; + + data->service_main( data->argc, data->argv ); + return 0; +} + /****************************************************************************** * service_ctrl_dispatcher * @@ -312,15 +332,17 @@ static LPWSTR* build_arg_vectors( struct SEB* seb ) */ static BOOL service_ctrl_dispatcher( LPSERVICE_TABLE_ENTRYW servent, BOOL ascii ) { - WCHAR service_name[ MAX_SERVICE_NAME ]; HANDLE hServiceShmem = NULL; struct SEB *seb = NULL; - DWORD dwNumServiceArgs; - LPWSTR *lpArgVecW = NULL; + struct service_thread_data *thread_data; unsigned int i; - BOOL ret = FALSE; + HANDLE thread; - if( ! read_scm_lock_data( service_name ) ) + thread_data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct service_thread_data) ); + if( NULL == thread_data ) + return FALSE; + + if( ! read_scm_lock_data( thread_data->service_name ) ) { /* FIXME: Instead of exiting we allow service to be executed as ordinary program. @@ -329,44 +351,65 @@ static BOOL service_ctrl_dispatcher( LPSERVICE_TABLE_ENTRYW servent, BOOL ascii */ FIXME("should fail with ERROR_FAILED_SERVICE_CONTROLLER_CONNECT\n"); servent->lpServiceProc( 0, NULL ); + HeapFree( GetProcessHeap(), 0, thread_data ); return TRUE; } - seb = open_seb_shmem( service_name, &hServiceShmem ); + seb = open_seb_shmem( thread_data->service_name, &hServiceShmem ); if( NULL == seb ) - return FALSE; + goto error; - lpArgVecW = build_arg_vectors( seb ); - if( NULL == lpArgVecW ) - goto done; + thread_data->argv = build_arg_vectors( seb ); + if( NULL == thread_data->argv ) + goto error; - lpArgVecW[0] = service_name; - dwNumServiceArgs = seb->argc + 1; + thread_data->argv[0] = thread_data->service_name; + thread_data->argc = seb->argc + 1; if( ascii ) - /* Convert the Unicode arg vectors back to ASCII */ - for(i=0; iargv[0], -1, + thread_data->service_nameA, MAX_SERVICE_NAME, NULL, NULL ); + thread_data->argv[0] = (LPWSTR) thread_data->service_nameA; + + for(i=1; iargc; i++) { - LPWSTR src = lpArgVecW[i]; + LPWSTR src = thread_data->argv[i]; int len = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL ); LPSTR dest = HeapAlloc( GetProcessHeap(), 0, len ); if( NULL == dest ) - goto done; + goto error; 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 */ - servent->lpServiceProc( dwNumServiceArgs, lpArgVecW); - ret = TRUE; + /* start the service thread */ + thread_data->service_main = servent->lpServiceProc; + thread = CreateThread( NULL, 0, service_thread, thread_data, 0, NULL ); + if( NULL == thread ) + goto error; -done: - if( lpArgVecW ) HeapFree( GetProcessHeap(), 0, lpArgVecW ); + /* FIXME: dispatch control requests */ + WaitForSingleObject( thread, INFINITE ); + CloseHandle( thread ); + + HeapFree( GetProcessHeap(), 0, thread_data->argv ); + HeapFree( GetProcessHeap(), 0, thread_data ); + UnmapViewOfFile( seb ); + CloseHandle( hServiceShmem ); + return TRUE; + +error: + if( thread_data->argv ) HeapFree( GetProcessHeap(), 0, thread_data->argv ); if( seb ) UnmapViewOfFile( seb ); if( hServiceShmem ) CloseHandle( hServiceShmem ); - return ret; + HeapFree( GetProcessHeap(), 0, thread_data ); + return FALSE; } /******************************************************************************