Parcourir la source

Log that we received control messages.

Send a message to the event log when we receive a service control.

Use a fake message for starting a service so we can reuse code.
No SERVICE_CONTROL_START control is defined or used by the Windows
API.

French translations by François-Régis Tardy.
Iain Patterson il y a 12 ans
Parent
commit
5078d2360f
3 fichiers modifiés avec 80 ajouts et 0 suppressions
  1. 30 0
      messages.mc
  2. 48 0
      service.cpp
  3. 2 0
      service.h

+ 30 - 0
messages.mc

@@ -465,3 +465,33 @@ Language = French
 La déclaration de l'environnement %1 pour le service %2 n'est pas du type REG_MULTI_SZ.  Cette déclaration sera ignorée.
 .
 
+MessageId = +1
+SymbolicName = NSSM_EVENT_SERVICE_CONTROL_HANDLED
+Severity = Informational
+Language = English
+Service %1 received %2 control, which will be handled.
+.
+Language = French
+Le service %1 a reçu le code de contrôle %2, qui sera pris en compte.
+.
+
+MessageId = +1
+SymbolicName = NSSM_EVENT_SERVICE_CONTROL_NOT_HANDLED
+Severity = Informational
+Language = English
+Service %1 received unsupported %2 control, which will not be handled.
+.
+Language = French
+Le service %1 a reçu le code de contrôle %2, qui n'est pas géré.  Aucune action ne sera entreprise en réponse à cette demande.
+.
+
+MessageId = +1
+SymbolicName = NSSM_EVENT_SERVICE_CONTROL_UNKNOWN
+Severity = Informational
+Language = English
+Service %1 received unknown service control message %2, which will be ignored.
+.
+Language = French
+Le service %1 a reçu le code de contrôle inconnu %2, qui sera donc ignoré.
+.
+

+ 48 - 0
service.cpp

@@ -198,6 +198,8 @@ void WINAPI service_main(unsigned long argc, char **argv) {
     return;
   }
 
+  log_service_control(service_name, 0, true);
+
   service_status.dwCurrentState = SERVICE_START_PENDING;
   service_status.dwWaitHint = throttle_delay + NSSM_WAITHINT_MARGIN;
   SetServiceStatus(service_handle, &service_status);
@@ -252,15 +254,59 @@ int monitor_service() {
   return 0;
 }
 
+char *service_control_text(unsigned long control) {
+  switch (control) {
+    /* HACK: there is no SERVICE_CONTROL_START constant */
+    case 0: return "START";
+    case SERVICE_CONTROL_STOP: return "STOP";
+    case SERVICE_CONTROL_SHUTDOWN: return "SHUTDOWN";
+    case SERVICE_CONTROL_PAUSE: return "PAUSE";
+    case SERVICE_CONTROL_CONTINUE: return "CONTINUE";
+    case SERVICE_CONTROL_INTERROGATE: return "INTERROGATE";
+    default: return 0;
+  }
+}
+
+void log_service_control(char *service_name, unsigned long control, bool handled) {
+  char *text = service_control_text(control);
+  unsigned long event;
+
+  if (! text) {
+    /* "0x" + 8 x hex + NULL */
+    text = (char *) HeapAlloc(GetProcessHeap(), 0, 11);
+    if (! text) {
+      log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, "control code", "log_service_control", 0);
+      return;
+    }
+    if (_snprintf(text, 11, "0x%08x", control) < 0) {
+      log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, "control code", "log_service_control", 0);
+      HeapFree(GetProcessHeap(), 0, text);
+      return;
+    }
+
+    event = NSSM_EVENT_SERVICE_CONTROL_UNKNOWN;
+  }
+  else if (handled) event = NSSM_EVENT_SERVICE_CONTROL_HANDLED;
+  else event = NSSM_EVENT_SERVICE_CONTROL_NOT_HANDLED;
+
+  log_event(EVENTLOG_INFORMATION_TYPE, event, service_name, text, 0);
+
+  if (event == NSSM_EVENT_SERVICE_CONTROL_UNKNOWN) {
+    HeapFree(GetProcessHeap(), 0, text);
+  }
+}
+
 /* Service control handler */
 unsigned long WINAPI service_control_handler(unsigned long control, unsigned long event, void *data, void *context) {
   switch (control) {
     case SERVICE_CONTROL_SHUTDOWN:
     case SERVICE_CONTROL_STOP:
+      log_service_control(service_name, control, true);
       stop_service(0, true, true);
       return NO_ERROR;
 
     case SERVICE_CONTROL_CONTINUE:
+      log_service_control(service_name, control, true);
       if (! throttle_timer) return ERROR_CALL_NOT_IMPLEMENTED;
       throttle = 0;
       ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));
@@ -276,10 +322,12 @@ unsigned long WINAPI service_control_handler(unsigned long control, unsigned lon
         We don't accept pause messages but it isn't possible to register
         only for continue messages so we have to handle this case.
       */
+      log_service_control(service_name, control, false);
       return ERROR_CALL_NOT_IMPLEMENTED;
   }
 
   /* Unknown control */
+  log_service_control(service_name, control, false);
   return ERROR_CALL_NOT_IMPLEMENTED;
 }
 

+ 2 - 0
service.h

@@ -4,6 +4,8 @@
 #define ACTION_LEN 16
 
 void WINAPI service_main(unsigned long, char **);
+char *service_control_text(unsigned long);
+void log_service_control(char *, unsigned long, bool);
 unsigned long WINAPI service_control_handler(unsigned long, unsigned long, void *, void *);
 
 SC_HANDLE open_service_manager();