X-Git-Url: http://git.iain.cx/?a=blobdiff_plain;f=registry.cpp;h=48783f136b47c4cf22ea8716d9d321fc84c6e7b5;hb=70c205435a839d0378035071777e8c8384008337;hp=b8aab781ec6ba1e24f9006c89696eab4fb3cf491;hpb=04056eb6ead840b893772711f5a8db10f8ba76c1;p=nssm.git diff --git a/registry.cpp b/registry.cpp index b8aab78..48783f1 100644 --- a/registry.cpp +++ b/registry.cpp @@ -67,6 +67,14 @@ int create_messages() { return 0; } +long enumerate_registry_values(HKEY key, unsigned long *index, TCHAR *name, unsigned long namelen) { + unsigned long type; + unsigned long datalen = namelen; + long error = RegEnumValue(key, *index, name, &datalen, 0, &type, 0, 0); + if (error == ERROR_SUCCESS) ++*index; + return error; +} + int create_parameters(nssm_service_t *service, bool editing) { /* Try to open the registry */ HKEY key = open_registry(service->name, KEY_WRITE); @@ -158,6 +166,8 @@ int create_parameters(nssm_service_t *service, bool editing) { if (service->stderr_copy_and_truncate) set_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_COPY_AND_TRUNCATE, 1); else if (editing) delete_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_COPY_AND_TRUNCATE); } + if (service->hook_share_output_handles) set_number(key, NSSM_REG_HOOK_SHARE_OUTPUT_HANDLES, 1); + else if (editing) RegDeleteValue(key, NSSM_REG_HOOK_SHARE_OUTPUT_HANDLES); if (service->rotate_files) set_number(key, NSSM_REG_ROTATE, 1); else if (editing) RegDeleteValue(key, NSSM_REG_ROTATE); if (service->rotate_stdout_online) set_number(key, NSSM_REG_ROTATE_ONLINE, 1); @@ -230,48 +240,50 @@ int create_exit_action(TCHAR *service_name, const TCHAR *action_string, bool edi int get_environment(TCHAR *service_name, HKEY key, TCHAR *value, TCHAR **env, unsigned long *envlen) { unsigned long type = REG_MULTI_SZ; + unsigned long envsize; + + *envlen = 0; /* Dummy test to find buffer size */ - unsigned long ret = RegQueryValueEx(key, value, 0, &type, NULL, envlen); + unsigned long ret = RegQueryValueEx(key, value, 0, &type, NULL, &envsize); if (ret != ERROR_SUCCESS) { *env = 0; - *envlen = 0; /* The service probably doesn't have any environment configured */ if (ret == ERROR_FILE_NOT_FOUND) return 0; - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(GetLastError()), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(ret), 0); return 1; } if (type != REG_MULTI_SZ) { - *env = 0; - *envlen = 0; log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_INVALID_ENVIRONMENT_STRING_TYPE, value, service_name, 0); + *env = 0; return 2; } /* Probably not possible */ - if (! *envlen) return 0; + if (! envsize) return 0; /* Previously initialised? */ if (*env) HeapFree(GetProcessHeap(), 0, *env); - *env = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, *envlen); + *env = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, envsize); if (! *env) { - *envlen = 0; log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, value, _T("get_environment()"), 0); return 3; } - /* Actually get the strings */ - ret = RegQueryValueEx(key, value, 0, &type, (unsigned char *) *env, envlen); + /* Actually get the strings. */ + ret = RegQueryValueEx(key, value, 0, &type, (unsigned char *) *env, &envsize); if (ret != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(GetLastError()), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(ret), 0); HeapFree(GetProcessHeap(), 0, *env); *env = 0; - *envlen = 0; return 4; } + /* Value retrieved by RegQueryValueEx() is SIZE not COUNT. */ + *envlen = (unsigned long) environment_length(env); + return 0; } @@ -290,14 +302,13 @@ int get_string(HKEY key, TCHAR *value, TCHAR *data, unsigned long datalen, bool unsigned long ret = RegQueryValueEx(key, value, 0, &type, (unsigned char *) buffer, &buflen); if (ret != ERROR_SUCCESS) { - unsigned long error = GetLastError(); HeapFree(GetProcessHeap(), 0, buffer); if (ret == ERROR_FILE_NOT_FOUND) { if (! must_exist) return 0; } - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(error), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(ret), 0); return 2; } @@ -353,12 +364,10 @@ int set_string(HKEY key, TCHAR *value, TCHAR *string, bool expand) { int set_string(HKEY key, TCHAR *value, TCHAR *string) { return set_string(key, value, string, false); - return 1; } int set_expand_string(HKEY key, TCHAR *value, TCHAR *string) { return set_string(key, value, string, true); - return 1; } /* @@ -390,7 +399,7 @@ int get_number(HKEY key, TCHAR *value, unsigned long *number, bool must_exist) { if (! must_exist) return 0; } - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(GetLastError()), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(ret), 0); if (ret == ERROR_FILE_NOT_FOUND) return -1; return -2; @@ -492,7 +501,7 @@ void override_milliseconds(TCHAR *service_name, HKEY key, TCHAR *value, unsigned _sntprintf_s(milliseconds, _countof(milliseconds), _TRUNCATE, _T("%lu"), default_value); log_event(EVENTLOG_WARNING_TYPE, event, service_name, value, milliseconds, 0); } - else log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(GetLastError()), 0); + else log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(ret), 0); } } else ok = true; @@ -640,6 +649,13 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) { else log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_BOGUS_PRIORITY, service->name, NSSM_REG_PRIORITY, 0); } + /* Try to get hook I/O sharing - may fail. */ + unsigned long hook_share_output_handles; + if (get_number(key, NSSM_REG_HOOK_SHARE_OUTPUT_HANDLES, &hook_share_output_handles, false) == 1) { + if (hook_share_output_handles) service->hook_share_output_handles = true; + else service->hook_share_output_handles = false; + } + else hook_share_output_handles = false; /* Try to get file rotation settings - may fail. */ unsigned long rotate_files; if (get_number(key, NSSM_REG_ROTATE, &rotate_files, false) == 1) { @@ -652,6 +668,9 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) { else service->rotate_stdout_online = service->rotate_stderr_online = false; } else service->rotate_stdout_online = service->rotate_stderr_online = false; + /* Hook I/O sharing and online rotation need a pipe. */ + service->use_stdout_pipe = service->rotate_stdout_online || hook_share_output_handles; + service->use_stderr_pipe = service->rotate_stderr_online || hook_share_output_handles; if (get_number(key, NSSM_REG_ROTATE_SECONDS, &service->rotate_seconds, false) != 1) service->rotate_seconds = 0; if (get_number(key, NSSM_REG_ROTATE_BYTES_LOW, &service->rotate_bytes_low, false) != 1) service->rotate_bytes_low = 0; if (get_number(key, NSSM_REG_ROTATE_BYTES_HIGH, &service->rotate_bytes_high, false) != 1) service->rotate_bytes_high = 0; @@ -693,7 +712,7 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) { if (type != REG_DWORD) { log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_BOGUS_STOP_METHOD_SKIP, service->name, NSSM_REG_STOP_METHOD_SKIP, NSSM, 0); } - else log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, NSSM_REG_STOP_METHOD_SKIP, error_string(GetLastError()), 0); + else log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, NSSM_REG_STOP_METHOD_SKIP, error_string(ret), 0); } } else stop_ok = true;