Report service status to the service manager.
authorEric Kohl <eric.kohl@reactos.org>
Sat, 27 Feb 2010 17:15:49 +0000 (17:15 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 27 Feb 2010 17:15:49 +0000 (17:15 +0000)
Patch is partially based on code by Dmitry Gorbachev.

svn path=/trunk/; revision=45706

reactos/base/services/umpnpmgr/umpnpmgr.c

index 8dc8a16..2352efe 100644 (file)
 
 /* 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");
 }