Introduced service thread.

This commit is contained in:
Alexander Yaworsky 2004-12-01 15:31:34 +00:00 committed by Alexandre Julliard
parent 60cd092c68
commit 78b64795d7
1 changed files with 65 additions and 22 deletions

View File

@ -305,6 +305,26 @@ static LPWSTR* build_arg_vectors( struct SEB* seb )
return ret; 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 * 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 ) static BOOL service_ctrl_dispatcher( LPSERVICE_TABLE_ENTRYW servent, BOOL ascii )
{ {
WCHAR service_name[ MAX_SERVICE_NAME ];
HANDLE hServiceShmem = NULL; HANDLE hServiceShmem = NULL;
struct SEB *seb = NULL; struct SEB *seb = NULL;
DWORD dwNumServiceArgs; struct service_thread_data *thread_data;
LPWSTR *lpArgVecW = NULL;
unsigned int i; 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 /* FIXME: Instead of exiting we allow
service to be executed as ordinary program. 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"); FIXME("should fail with ERROR_FAILED_SERVICE_CONTROLLER_CONNECT\n");
servent->lpServiceProc( 0, NULL ); servent->lpServiceProc( 0, NULL );
HeapFree( GetProcessHeap(), 0, thread_data );
return TRUE; return TRUE;
} }
seb = open_seb_shmem( service_name, &hServiceShmem ); seb = open_seb_shmem( thread_data->service_name, &hServiceShmem );
if( NULL == seb ) if( NULL == seb )
return FALSE; goto error;
lpArgVecW = build_arg_vectors( seb ); thread_data->argv = build_arg_vectors( seb );
if( NULL == lpArgVecW ) if( NULL == thread_data->argv )
goto done; goto error;
lpArgVecW[0] = service_name; thread_data->argv[0] = thread_data->service_name;
dwNumServiceArgs = seb->argc + 1; thread_data->argc = seb->argc + 1;
if( ascii ) if( ascii )
/* Convert the Unicode arg vectors back to ASCII */ {
for(i=0; i<dwNumServiceArgs; i++) /* Convert the Unicode arg vectors back to ASCII;
* but we'll need unicode service name (argv[0]) for object names */
WideCharToMultiByte( CP_ACP, 0, thread_data->argv[0], -1,
thread_data->service_nameA, MAX_SERVICE_NAME, NULL, NULL );
thread_data->argv[0] = (LPWSTR) thread_data->service_nameA;
for(i=1; i<thread_data->argc; i++)
{ {
LPWSTR src = lpArgVecW[i]; LPWSTR src = thread_data->argv[i];
int len = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL ); int len = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL );
LPSTR dest = HeapAlloc( GetProcessHeap(), 0, len ); LPSTR dest = HeapAlloc( GetProcessHeap(), 0, len );
if( NULL == dest ) if( NULL == dest )
goto done; goto error;
WideCharToMultiByte( CP_ACP, 0, src, -1, dest, len, NULL, NULL ); WideCharToMultiByte( CP_ACP, 0, src, -1, dest, len, NULL, NULL );
/* copy converted string back */ /* copy converted string back */
memcpy( src, dest, len ); memcpy( src, dest, len );
HeapFree( GetProcessHeap(), 0, dest ); HeapFree( GetProcessHeap(), 0, dest );
} }
}
/* try to start the service */ /* start the service thread */
servent->lpServiceProc( dwNumServiceArgs, lpArgVecW); thread_data->service_main = servent->lpServiceProc;
ret = TRUE; thread = CreateThread( NULL, 0, service_thread, thread_data, 0, NULL );
if( NULL == thread )
goto error;
done: /* FIXME: dispatch control requests */
if( lpArgVecW ) HeapFree( GetProcessHeap(), 0, lpArgVecW ); 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( seb ) UnmapViewOfFile( seb );
if( hServiceShmem ) CloseHandle( hServiceShmem ); if( hServiceShmem ) CloseHandle( hServiceShmem );
return ret; HeapFree( GetProcessHeap(), 0, thread_data );
return FALSE;
} }
/****************************************************************************** /******************************************************************************