From d816c7617cb3f7f3ac72cb33184bc8a07b49e6d2 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 27 Feb 2010 17:15:49 +0000 Subject: [PATCH] Report service status to the service manager. Patch is partially based on code by Dmitry Gorbachev. svn path=/trunk/; revision=45706 --- reactos/base/services/umpnpmgr/umpnpmgr.c | 91 +++++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/reactos/base/services/umpnpmgr/umpnpmgr.c b/reactos/base/services/umpnpmgr/umpnpmgr.c index 8dc8a16e031..2352efe703f 100644 --- a/reactos/base/services/umpnpmgr/umpnpmgr.c +++ b/reactos/base/services/umpnpmgr/umpnpmgr.c @@ -51,15 +51,17 @@ /* GLOBALS ******************************************************************/ -static VOID CALLBACK -ServiceMain(DWORD argc, LPTSTR *argv); - -static SERVICE_TABLE_ENTRY ServiceTable[2] = +static VOID CALLBACK ServiceMain(DWORD argc, LPWSTR *argv); +static WCHAR ServiceName[] = L"PlugPlay"; +static SERVICE_TABLE_ENTRYW ServiceTable[] = { - {TEXT("PlugPlay"), ServiceMain}, + {ServiceName, ServiceMain}, {NULL, NULL} }; +static SERVICE_STATUS_HANDLE ServiceStatusHandle; +static SERVICE_STATUS ServiceStatus; + static WCHAR szRootDeviceId[] = L"HTREE\\ROOT\\0"; static HKEY hEnumKey = NULL; @@ -2446,6 +2448,72 @@ PnpEventThread(LPVOID lpParameter) } +static VOID +UpdateServiceStatus(DWORD dwState) +{ + ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ServiceStatus.dwCurrentState = dwState; + ServiceStatus.dwControlsAccepted = 0; + ServiceStatus.dwWin32ExitCode = 0; + ServiceStatus.dwServiceSpecificExitCode = 0; + ServiceStatus.dwCheckPoint = 0; + + if (dwState == SERVICE_START_PENDING || + dwState == SERVICE_STOP_PENDING || + dwState == SERVICE_PAUSE_PENDING || + dwState == SERVICE_CONTINUE_PENDING) + ServiceStatus.dwWaitHint = 10000; + else + ServiceStatus.dwWaitHint = 0; + + SetServiceStatus(ServiceStatusHandle, + &ServiceStatus); +} + + +static DWORD WINAPI +ServiceControlHandler(DWORD dwControl, + DWORD dwEventType, + LPVOID lpEventData, + LPVOID lpContext) +{ + DPRINT1("ServiceControlHandler() called\n"); + + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + DPRINT1(" SERVICE_CONTROL_STOP received\n"); + UpdateServiceStatus(SERVICE_STOPPED); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_PAUSE: + DPRINT1(" SERVICE_CONTROL_PAUSE received\n"); + UpdateServiceStatus(SERVICE_PAUSED); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_CONTINUE: + DPRINT1(" SERVICE_CONTROL_CONTINUE received\n"); + UpdateServiceStatus(SERVICE_RUNNING); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_INTERROGATE: + DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n"); + SetServiceStatus(ServiceStatusHandle, + &ServiceStatus); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_SHUTDOWN: + DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n"); + UpdateServiceStatus(SERVICE_STOPPED); + return ERROR_SUCCESS; + + default : + DPRINT1(" Control %lu received\n"); + return ERROR_CALL_NOT_IMPLEMENTED; + } +} + + static VOID CALLBACK ServiceMain(DWORD argc, LPTSTR *argv) { @@ -2457,6 +2525,17 @@ ServiceMain(DWORD argc, LPTSTR *argv) DPRINT("ServiceMain() called\n"); + ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, + ServiceControlHandler, + NULL); + if (!ServiceStatusHandle) + { + DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError()); + return; + } + + UpdateServiceStatus(SERVICE_START_PENDING); + hThread = CreateThread(NULL, 0, PnpEventThread, @@ -2484,6 +2563,8 @@ ServiceMain(DWORD argc, LPTSTR *argv) if (hThread != NULL) CloseHandle(hThread); + UpdateServiceStatus(SERVICE_RUNNING); + DPRINT("ServiceMain() done\n"); }