From: Iain Patterson Date: Mon, 19 Apr 2010 22:17:55 +0000 (+0100) Subject: Compile messages. X-Git-Tag: v2.3~3 X-Git-Url: http://git.iain.cx/?a=commitdiff_plain;h=06a62a665e152850d082607eced4fa4654f1bf70;p=nssm.git Compile messages. Don't spam the event log with warnings about not finding application messages. Every message currently uses the default event ID 1. --- diff --git a/event.cpp b/event.cpp index 7f2b9f4..2a9bbf2 100644 --- a/event.cpp +++ b/event.cpp @@ -2,13 +2,13 @@ /* Convert error code to error string - must call LocalFree() on return value */ char *error_string(unsigned long error) { - char *message; - if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &message, 0, 0)) return 0; + static char message[65535]; + if (! FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, 0, NSSM_MESSAGE_DEFAULT, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), message, sizeof(message), 0)) return 0; return message; } /* Log a message to the Event Log */ -void eventprintf(unsigned short type, char *format, ...) { +void eventprintf(unsigned short type, unsigned long id, char *format, ...) { char message[4096]; char *strings[2]; int n, size; @@ -32,7 +32,7 @@ void eventprintf(unsigned short type, char *format, ...) { if (! handle) return; /* Log it */ - if (! ReportEvent(handle, type, 0, 0, 0, 1, 0, (const char **) strings, 0)) { + if (! ReportEvent(handle, type, 0, id, 0, 1, 0, (const char **) strings, 0)) { printf("ReportEvent(): %s\n", error_string(GetLastError())); } diff --git a/event.h b/event.h index 8bc7777..d6fb7ed 100644 --- a/event.h +++ b/event.h @@ -2,6 +2,6 @@ #define EVENT_H char *error_string(unsigned long); -void eventprintf(unsigned short, char *, ...); +void eventprintf(unsigned short, unsigned long, char *, ...); #endif diff --git a/nssm.cpp b/nssm.cpp index f412579..85add5f 100644 --- a/nssm.cpp +++ b/nssm.cpp @@ -39,11 +39,14 @@ int main(int argc, char **argv) { /* Undocumented: "run" is used to actually do service stuff */ if (! str_equiv(argv[1], NSSM_RUN)) exit(usage(2)); + /* Register messages */ + create_messages(); + /* Start service magic */ SERVICE_TABLE_ENTRY table[] = { { NSSM, service_main }, { 0, 0 } }; if (! StartServiceCtrlDispatcher(table)) { char *message = error_string(GetLastError()); - eventprintf(EVENTLOG_ERROR_TYPE, "StartServiceCtrlDispatcher() failed: %s", message); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "StartServiceCtrlDispatcher() failed: %s", message); if (message) LocalFree(message); return 100; } diff --git a/nssm.h b/nssm.h index 9b8c7cd..6f0a762 100644 --- a/nssm.h +++ b/nssm.h @@ -6,6 +6,7 @@ #include #include #include "event.h" +#include "messages.h" #include "registry.h" #include "service.h" #include "gui.h" diff --git a/nssm.rc b/nssm.rc index aa1134d..ff9a524 100644 --- a/nssm.rc +++ b/nssm.rc @@ -1,4 +1,4 @@ -//Microsoft Developer Studio generated resource script. +// Microsoft Visual C++ generated resource script. // #include "resource.h" @@ -27,21 +27,19 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK // TEXTINCLUDE // -1 TEXTINCLUDE DISCARDABLE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE DISCARDABLE +2 TEXTINCLUDE BEGIN - "#include ""afxres.h""\r\n" - "\0" + "#include ""afxres.h""\r\0" END -3 TEXTINCLUDE DISCARDABLE +3 TEXTINCLUDE BEGIN - "\r\n" - "\0" + "#include ""messages.rc\0" END #endif // APSTUDIO_INVOKED @@ -54,15 +52,15 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_NSSM ICON DISCARDABLE "nssm.ico" +IDI_NSSM ICON "nssm.ico" ///////////////////////////////////////////////////////////////////////////// // // Dialog // -IDD_INSTALL DIALOG DISCARDABLE 0, 0, 220, 90 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_INSTALL DIALOG 0, 0, 220, 90 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "NSSM service installer" FONT 8, "MS Sans Serif" BEGIN @@ -77,8 +75,8 @@ BEGIN LTEXT "Application:",IDC_STATIC,7,9,38,8 END -IDD_REMOVE DIALOG DISCARDABLE 0, 0, 223, 28 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_REMOVE DIALOG 0, 0, 223, 28 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "NSSM service remover" FONT 8, "MS Sans Serif" BEGIN @@ -94,7 +92,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE +GUIDELINES DESIGNINFO BEGIN IDD_INSTALL, DIALOG BEGIN @@ -118,8 +116,7 @@ END // // Generated from the TEXTINCLUDE 3 resource. // - - +#include "messages.rc" ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED diff --git a/nssm.vcproj b/nssm.vcproj index 4bd08c5..f8300fb 100644 --- a/nssm.vcproj +++ b/nssm.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + diff --git a/registry.cpp b/registry.cpp index d1080ae..eca8e78 100644 --- a/registry.cpp +++ b/registry.cpp @@ -1,35 +1,61 @@ #include "nssm.h" +int create_messages() { + HKEY key; + + char registry[MAX_PATH]; + if (_snprintf(registry, sizeof(registry), "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s", NSSM) < 0) { + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Out of memory for eventlog registry()!"); + return 1; + } + + if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, 0) != ERROR_SUCCESS) { + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't open eventlog registry!", NSSM_REGISTRY); + return 2; + } + + /* Get path of this program */ + char path[MAX_PATH]; + GetModuleFileName(0, path, MAX_PATH); + + /* Try to register the module but don't worry so much on failure */ + RegSetValueEx(key, "EventMessageFile", 0, REG_SZ, (const unsigned char *) path, strlen(path) + 1); + unsigned long types = EVENTLOG_INFORMATION_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_ERROR_TYPE; + RegSetValueEx(key, "TypesSupported", 0, REG_DWORD, /*XXX*/(PBYTE) &types, sizeof(types)); + + return 0; +} + int create_parameters(char *service_name, char *exe, char *flags, char *dir) { /* Get registry */ char registry[MAX_PATH]; if (_snprintf(registry, sizeof(registry), NSSM_REGISTRY, service_name) < 0) { - eventprintf(EVENTLOG_ERROR_TYPE, "Out of memory for NSSM_REGISTRY in create_parameters()!"); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Out of memory for NSSM_REGISTRY in create_parameters()!"); return 1; } /* Try to open the registry */ HKEY key; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, 0) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't open service registry settings!", NSSM_REGISTRY); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't open service registry settings!", NSSM_REGISTRY); return 2; } /* Try to create the parameters */ if (RegSetValueEx(key, NSSM_REG_EXE, 0, REG_SZ, (const unsigned char *) exe, strlen(exe) + 1) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't add registry value %s: %s", NSSM_REG_EXE, error_string(GetLastError())); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't add registry value %s: %s", NSSM_REG_EXE, error_string(GetLastError())); RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY); RegCloseKey(key); return 3; } if (RegSetValueEx(key, NSSM_REG_FLAGS, 0, REG_SZ, (const unsigned char *) flags, strlen(flags) + 1) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't add registry value %s: %s", NSSM_REG_FLAGS, error_string(GetLastError())); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't add registry value %s: %s", NSSM_REG_FLAGS, error_string(GetLastError())); RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY); RegCloseKey(key); return 4; } if (RegSetValueEx(key, NSSM_REG_DIR, 0, REG_SZ, (const unsigned char *) dir, strlen(dir) + 1) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't add registry value %s: %s", NSSM_REG_DIR, error_string(GetLastError())); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't add registry value %s: %s", NSSM_REG_DIR, error_string(GetLastError())); RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY); RegCloseKey(key); return 5; @@ -45,7 +71,7 @@ int create_exit_action(char *service_name, const char *action_string) { /* Get registry */ char registry[MAX_PATH]; if (_snprintf(registry, sizeof(registry), NSSM_REGISTRY "\\%s", service_name, NSSM_REG_EXIT) < 0) { - eventprintf(EVENTLOG_ERROR_TYPE, "Out of memory for NSSM_REG_EXIT in create_exit_action()!"); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Out of memory for NSSM_REG_EXIT in create_exit_action()!"); return 1; } @@ -53,7 +79,7 @@ int create_exit_action(char *service_name, const char *action_string) { HKEY key; unsigned long disposition; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, &disposition) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't open service exit action registry settings!"); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't open service exit action registry settings!"); return 2; } @@ -65,7 +91,7 @@ int create_exit_action(char *service_name, const char *action_string) { /* Create the default value */ if (RegSetValueEx(key, 0, 0, REG_SZ, (const unsigned char *) action_string, strlen(action_string) + 1) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't add default registry value %s: %s", NSSM_REG_EXIT, error_string(GetLastError())); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't add default registry value %s: %s", NSSM_REG_EXIT, error_string(GetLastError())); RegCloseKey(key); return 3; } @@ -80,14 +106,14 @@ int get_parameters(char *service_name, char *exe, int exelen, char *flags, int f /* Get registry */ char registry[MAX_PATH]; if (_snprintf(registry, sizeof(registry), NSSM_REGISTRY, service_name) < 0) { - eventprintf(EVENTLOG_ERROR_TYPE, "Out of memory for NSSM_REGISTRY in get_parameters()!"); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Out of memory for NSSM_REGISTRY in get_parameters()!"); return 1; } /* Try to open the registry */ HKEY key; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, registry, 0, KEY_READ, &key) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't open service registry settings!", NSSM_REGISTRY); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't open service registry settings!", NSSM_REGISTRY); return 2; } @@ -95,21 +121,21 @@ int get_parameters(char *service_name, char *exe, int exelen, char *flags, int f /* Try to get executable file - MUST succeed */ if (RegQueryValueEx(key, NSSM_REG_EXE, 0, &type, (unsigned char *) exe, (unsigned long *) &exelen) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't get application path (registry value %s): %s", NSSM_REG_EXE, error_string(GetLastError())); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't get application path (registry value %s): %s", NSSM_REG_EXE, error_string(GetLastError())); RegCloseKey(key); return 3; } /* Try to get flags - may fail */ if (RegQueryValueEx(key, NSSM_REG_FLAGS, 0, &type, (unsigned char *) flags, (unsigned long *) &flagslen) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_WARNING_TYPE, "Can't get application flags (registry value %s): %s", NSSM_REG_FLAGS, error_string(GetLastError())); + eventprintf(EVENTLOG_WARNING_TYPE, NSSM_MESSAGE_DEFAULT, "Can't get application flags (registry value %s): %s", NSSM_REG_FLAGS, error_string(GetLastError())); RegCloseKey(key); return 4; } /* Try to get startup directory - may fail */ if (RegQueryValueEx(key, NSSM_REG_DIR, 0, &type, (unsigned char *) dir, (unsigned long *) &dirlen) != ERROR_SUCCESS) { - eventprintf(EVENTLOG_WARNING_TYPE, "Can't get application startup directory (registry value %s): %s", NSSM_REG_DIR, error_string(GetLastError())); + eventprintf(EVENTLOG_WARNING_TYPE, NSSM_MESSAGE_DEFAULT, "Can't get application startup directory (registry value %s): %s", NSSM_REG_DIR, error_string(GetLastError())); RegCloseKey(key); return 5; } @@ -124,7 +150,7 @@ int get_exit_action(char *service_name, unsigned long *ret, unsigned char *actio /* Get registry */ char registry[MAX_PATH]; if (_snprintf(registry, sizeof(registry), NSSM_REGISTRY "\\%s", service_name, NSSM_REG_EXIT) < 0) { - eventprintf(EVENTLOG_ERROR_TYPE, "Out of memory for NSSM_REG_EXIT in get_exit_action()!"); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Out of memory for NSSM_REG_EXIT in get_exit_action()!"); return 1; } @@ -132,7 +158,7 @@ int get_exit_action(char *service_name, unsigned long *ret, unsigned char *actio HKEY key; long error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, registry, 0, KEY_READ, &key); if (error != ERROR_SUCCESS && error != ERROR_FILE_NOT_FOUND) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't open registry %s!", registry); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't open registry %s!", registry); return 2; } diff --git a/registry.h b/registry.h index 3ad673f..2f45f99 100644 --- a/registry.h +++ b/registry.h @@ -7,6 +7,7 @@ #define NSSM_REG_DIR "AppDirectory" #define NSSM_REG_EXIT "AppExit" +int create_messages(); int create_parameters(char *, char *, char *, char *); int create_exit_action(char *, const char *); int get_parameters(char *, char *, int, char *, int, char *, int); diff --git a/service.cpp b/service.cpp index 4dc6fa2..ad5f2c2 100644 --- a/service.cpp +++ b/service.cpp @@ -16,7 +16,7 @@ static const char *exit_action_strings[] = { "Restart", "Ignore", "Exit", 0 }; SC_HANDLE open_service_manager() { SC_HANDLE ret = OpenSCManager(0, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); if (! ret) { - eventprintf(EVENTLOG_ERROR_TYPE, "Unable to connect to service manager!\nPerhaps you need to be an administrator..."); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Unable to connect to service manager!\nPerhaps you need to be an administrator..."); return 0; } @@ -139,7 +139,7 @@ int remove_service(char *name) { /* Service initialisation */ void WINAPI service_main(unsigned long argc, char **argv) { if (_snprintf(service_name, sizeof(service_name), "%s", argv[0]) < 0) { - eventprintf(EVENTLOG_ERROR_TYPE, "service_main(): Out of memory for service_name!"); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "service_main(): Out of memory for service_name!"); return; } @@ -159,14 +159,14 @@ void WINAPI service_main(unsigned long argc, char **argv) { /* Get startup parameters */ int ret = get_parameters(argv[0], exe, sizeof(exe), flags, sizeof(flags), dir, sizeof(dir)); if (ret) { - eventprintf(EVENTLOG_ERROR_TYPE, "service_main(): Can't get startup parameters: error %d", ret); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "service_main(): Can't get startup parameters: error %d", ret); return; } /* Register control handler */ service_handle = RegisterServiceCtrlHandlerEx(NSSM, service_control_handler, 0); if (! service_handle) { - eventprintf(EVENTLOG_ERROR_TYPE, "service_main(): RegisterServiceCtrlHandlerEx() failed: %s", error_string(GetLastError())); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "service_main(): RegisterServiceCtrlHandlerEx() failed: %s", error_string(GetLastError())); return; } @@ -180,14 +180,14 @@ int monitor_service() { /* Set service status to started */ int ret = start_service(); if (ret) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't start service %s: error code %d", service_name, ret); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't start service %s: error code %d", service_name, ret); return ret; } - eventprintf(EVENTLOG_INFORMATION_TYPE, "Started process %s %s in %s for service %s", exe, flags, dir, service_name); + eventprintf(EVENTLOG_INFORMATION_TYPE, NSSM_MESSAGE_DEFAULT, "Started process %s %s in %s for service %s", exe, flags, dir, service_name); /* Monitor service service */ if (! RegisterWaitForSingleObject(&wait_handle, pid, end_service, 0, INFINITE, WT_EXECUTEONLYONCE | WT_EXECUTELONGFUNCTION)) { - eventprintf(EVENTLOG_WARNING_TYPE, "RegisterWaitForSingleObject() returned %s - service may claim to be still running when %s exits ", error_string(GetLastError()), exe); + eventprintf(EVENTLOG_WARNING_TYPE, NSSM_MESSAGE_DEFAULT, "RegisterWaitForSingleObject() returned %s - service may claim to be still running when %s exits ", error_string(GetLastError()), exe); } return 0; @@ -222,11 +222,11 @@ int start_service() { /* Launch executable with arguments */ char cmd[MAX_PATH]; if (_snprintf(cmd, sizeof(cmd), "%s %s", exe, flags) < 0) { - eventprintf(EVENTLOG_ERROR_TYPE, "Error constructing command line"); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Error constructing command line"); return stop_service(2); } if (! CreateProcess(0, cmd, 0, 0, 0, 0, 0, dir, &si, &pi)) { - eventprintf(EVENTLOG_ERROR_TYPE, "Can't launch %s. CreateProcess() returned %s", exe, error_string(GetLastError())); + eventprintf(EVENTLOG_ERROR_TYPE, NSSM_MESSAGE_DEFAULT, "Can't launch %s. CreateProcess() returned %s", exe, error_string(GetLastError())); return stop_service(3); } pid = pi.hProcess; @@ -272,7 +272,7 @@ void CALLBACK end_service(void *arg, unsigned char why) { unsigned long ret = 0; GetExitCodeProcess(pid, &ret); - eventprintf(EVENTLOG_INFORMATION_TYPE, "Process %s for service %s exited with return code %u", exe, service_name, ret); + eventprintf(EVENTLOG_INFORMATION_TYPE, NSSM_MESSAGE_DEFAULT, "Process %s for service %s exited with return code %u", exe, service_name, ret); /* What action should we take? */ int action = NSSM_EXIT_RESTART; @@ -290,22 +290,22 @@ void CALLBACK end_service(void *arg, unsigned char why) { switch (action) { /* Try to restart the service or return failure code to service manager */ case NSSM_EXIT_RESTART: - eventprintf(EVENTLOG_INFORMATION_TYPE, "Action for exit code %lu is %s: Attempting to restart %s for service %s", ret, exit_action_strings[action], exe, service_name); + eventprintf(EVENTLOG_INFORMATION_TYPE, NSSM_MESSAGE_DEFAULT, "Action for exit code %lu is %s: Attempting to restart %s for service %s", ret, exit_action_strings[action], exe, service_name); while (monitor_service()) { - eventprintf(EVENTLOG_INFORMATION_TYPE, "Failed to restart %s - sleeping ", exe, ret); + eventprintf(EVENTLOG_INFORMATION_TYPE, NSSM_MESSAGE_DEFAULT, "Failed to restart %s - sleeping ", exe, ret); Sleep(30000); } break; /* Do nothing, just like srvany would */ case NSSM_EXIT_IGNORE: - eventprintf(EVENTLOG_INFORMATION_TYPE, "Action for exit code %lu is %s: Not attempting to restart %s for service %s", ret, exit_action_strings[action], exe, service_name); + eventprintf(EVENTLOG_INFORMATION_TYPE, NSSM_MESSAGE_DEFAULT, "Action for exit code %lu is %s: Not attempting to restart %s for service %s", ret, exit_action_strings[action], exe, service_name); Sleep(INFINITE); break; /* Tell the service manager we are finished */ case NSSM_EXIT_REALLY: - eventprintf(EVENTLOG_INFORMATION_TYPE, "Action for exit code %lu is %s: Stopping service %s", ret, exit_action_strings[action], service_name); + eventprintf(EVENTLOG_INFORMATION_TYPE, NSSM_MESSAGE_DEFAULT, "Action for exit code %lu is %s: Stopping service %s", ret, exit_action_strings[action], service_name); stop_service(ret); break; }