X-Git-Url: http://git.iain.cx/?a=blobdiff_plain;f=service.cpp;h=a94e6984d41e0b8a79a003ae2898cf1b87b9bf2b;hb=de47d8ddf95aeddbdcaf0d9ecf2d126aae9a5df7;hp=164fbc0c2fddab5238e7f2f26baeb40b81b04ed2;hpb=6adc886e1fa296f67aacef0c01994e302e8caf86;p=nssm.git diff --git a/service.cpp b/service.cpp index 164fbc0..a94e698 100644 --- a/service.cpp +++ b/service.cpp @@ -429,6 +429,56 @@ QUERY_SERVICE_CONFIG *query_service_config(const TCHAR *service_name, SC_HANDLE return qsc; } +/* WILL NOT allocate a new string if the identifier is already present. */ +int prepend_service_group_identifier(TCHAR *group, TCHAR **canon) { + if (! group || ! group[0] || group[0] == SC_GROUP_IDENTIFIER) { + *canon = group; + return 0; + } + + size_t len = _tcslen(group) + 1; + *canon = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR)); + if (! *canon) { + print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("canon"), _T("prepend_service_group_identifier()")); + return 1; + } + + TCHAR *s = *canon; + *s++ = SC_GROUP_IDENTIFIER; + memmove(s, group, len * sizeof(TCHAR)); + (*canon)[len] = _T('\0'); + + return 0; +} + +int append_to_dependencies(TCHAR *dependencies, unsigned long dependencieslen, TCHAR *string, TCHAR **newdependencies, unsigned long *newlen, int type) { + *newlen = 0; + + TCHAR *canon = 0; + if (type == DEPENDENCY_GROUPS) { + if (prepend_service_group_identifier(string, &canon)) return 1; + } + else canon = string; + int ret = append_to_double_null(dependencies, dependencieslen, newdependencies, newlen, canon, 0, false); + if (canon && canon != string) HeapFree(GetProcessHeap(), 0, canon); + + return ret; +} + +int remove_from_dependencies(TCHAR *dependencies, unsigned long dependencieslen, TCHAR *string, TCHAR **newdependencies, unsigned long *newlen, int type) { + *newlen = 0; + + TCHAR *canon = 0; + if (type == DEPENDENCY_GROUPS) { + if (prepend_service_group_identifier(string, &canon)) return 1; + } + else canon = string; + int ret = remove_from_double_null(dependencies, dependencieslen, newdependencies, newlen, canon, 0, false); + if (canon && canon != string) HeapFree(GetProcessHeap(), 0, canon); + + return ret; +} + int set_service_dependencies(const TCHAR *service_name, SC_HANDLE service_handle, TCHAR *buffer) { TCHAR *dependencies = _T(""); unsigned long num_dependencies = 0; @@ -562,8 +612,10 @@ int get_service_dependencies(const TCHAR *service_name, SC_HANDLE service_handle QUERY_SERVICE_CONFIG *qsc = query_service_config(service_name, service_handle); if (! qsc) return 3; - if (! qsc->lpDependencies) return 0; - if (! qsc->lpDependencies[0]) return 0; + if (! qsc->lpDependencies || ! qsc->lpDependencies[0]) { + HeapFree(GetProcessHeap(), 0, qsc); + return 0; + } /* lpDependencies is doubly NULL terminated. */ while (qsc->lpDependencies[*bufsize]) { @@ -577,6 +629,7 @@ int get_service_dependencies(const TCHAR *service_name, SC_HANDLE service_handle if (! *buffer) { *bufsize = 0; print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("lpDependencies"), _T("get_service_dependencies()")); + HeapFree(GetProcessHeap(), 0, qsc); return 4; } @@ -601,6 +654,12 @@ int get_service_dependencies(const TCHAR *service_name, SC_HANDLE service_handle HeapFree(GetProcessHeap(), 0, qsc); + if (! *buffer[0]) { + HeapFree(GetProcessHeap(), 0, *buffer); + *buffer = 0; + *bufsize = 0; + } + return 0; } @@ -1072,7 +1131,7 @@ int pre_edit_service(int argc, TCHAR **argv) { } if (! service->native) { - key = open_registry(service->name, KEY_WRITE); + key = open_registry(service->name, KEY_READ | KEY_WRITE); if (! key) { if (value.string) HeapFree(GetProcessHeap(), 0, value.string); return 4;