From 295ea36f9e8e70fd219ed9eaf8dc25e536db82a9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 25 Feb 2018 23:35:35 +0100 Subject: [PATCH] [ADVAPI32] Few improvements for Services. - Set some last errors. - Fix error code returned by ScLookupServiceByServiceName(). - Check the validity of the handler proc in RegisterServiceCtrlHandler(Ex)W(). - Improve some traces; comment some code. --- dll/win32/advapi32/service/sctrl.c | 135 ++++++++++++++++++----------- 1 file changed, 84 insertions(+), 51 deletions(-) diff --git a/dll/win32/advapi32/service/sctrl.c b/dll/win32/advapi32/service/sctrl.c index 30903ffeb44..f0de114f405 100644 --- a/dll/win32/advapi32/service/sctrl.c +++ b/dll/win32/advapi32/service/sctrl.c @@ -135,15 +135,19 @@ ScDestroyStatusBinding(VOID) } -static PACTIVE_SERVICE -ScLookupServiceByServiceName(LPCWSTR lpServiceName) +static DWORD +ScLookupServiceByServiceName(IN LPCWSTR lpServiceName, + OUT PACTIVE_SERVICE* pService) { DWORD i; TRACE("ScLookupServiceByServiceName(%S) called\n", lpServiceName); if (lpActiveServices[0].bOwnProcess) - return &lpActiveServices[0]; + { + *pService = &lpActiveServices[0]; + return ERROR_SUCCESS; + } for (i = 0; i < dwActiveServiceCount; i++) { @@ -151,15 +155,14 @@ ScLookupServiceByServiceName(LPCWSTR lpServiceName) if (_wcsicmp(lpActiveServices[i].ServiceName.Buffer, lpServiceName) == 0) { TRACE("Found!\n"); - return &lpActiveServices[i]; + *pService = &lpActiveServices[i]; + return ERROR_SUCCESS; } } TRACE("No service found!\n"); - - SetLastError(ERROR_SERVICE_DOES_NOT_EXIST); - - return NULL; + *pService = NULL; + return ERROR_SERVICE_NOT_IN_EXE; } @@ -268,7 +271,7 @@ ScConnectControlPipe(HANDLE *hPipe) dwProcessId = GetCurrentProcessId(); WriteFile(*hPipe, &dwProcessId, - sizeof(DWORD), + sizeof(dwProcessId), &dwBytesWritten, NULL); @@ -588,8 +591,8 @@ ScServiceDispatcher(HANDLE hPipe, if (ControlPacket->dwControl == SERVICE_CONTROL_START_OWN) lpActiveServices[0].bOwnProcess = TRUE; - lpService = ScLookupServiceByServiceName(lpServiceName); - if (lpService != NULL) + dwError = ScLookupServiceByServiceName(lpServiceName, &lpService); + if ((dwError == ERROR_SUCCESS) && (lpService != NULL)) { /* Execute command */ switch (ControlPacket->dwControl) @@ -611,10 +614,6 @@ ScServiceDispatcher(HANDLE hPipe, break; } } - else - { - dwError = ERROR_SERVICE_DOES_NOT_EXIST; - } } ReplyPacket.dwError = dwError; @@ -647,21 +646,21 @@ RegisterServiceCtrlHandlerA(LPCSTR lpServiceName, { ANSI_STRING ServiceNameA; UNICODE_STRING ServiceNameU; - SERVICE_STATUS_HANDLE SHandle; + SERVICE_STATUS_HANDLE hServiceStatus; - RtlInitAnsiString(&ServiceNameA, (LPSTR)lpServiceName); + RtlInitAnsiString(&ServiceNameA, lpServiceName); if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE))) { - SetLastError(ERROR_OUTOFMEMORY); - return (SERVICE_STATUS_HANDLE)0; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; } - SHandle = RegisterServiceCtrlHandlerW(ServiceNameU.Buffer, - lpHandlerProc); + hServiceStatus = RegisterServiceCtrlHandlerW(ServiceNameU.Buffer, + lpHandlerProc); RtlFreeUnicodeString(&ServiceNameU); - return SHandle; + return hServiceStatus; } @@ -674,18 +673,26 @@ SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc) { + DWORD dwError; PACTIVE_SERVICE Service; - Service = ScLookupServiceByServiceName((LPWSTR)lpServiceName); - if (Service == NULL) + dwError = ScLookupServiceByServiceName(lpServiceName, &Service); + if ((dwError != ERROR_SUCCESS) || (Service == NULL)) + { + SetLastError(dwError); + return NULL; + } + + if (!lpHandlerProc) { - return (SERVICE_STATUS_HANDLE)NULL; + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; } - Service->HandlerFunction = lpHandlerProc; + Service->HandlerFunction = lpHandlerProc; Service->HandlerFunctionEx = NULL; - TRACE("RegisterServiceCtrlHandler returning %lu\n", Service->hServiceStatus); + TRACE("RegisterServiceCtrlHandler returning 0x%p\n", Service->hServiceStatus); return Service->hServiceStatus; } @@ -703,22 +710,22 @@ RegisterServiceCtrlHandlerExA(LPCSTR lpServiceName, { ANSI_STRING ServiceNameA; UNICODE_STRING ServiceNameU; - SERVICE_STATUS_HANDLE SHandle; + SERVICE_STATUS_HANDLE hServiceStatus; - RtlInitAnsiString(&ServiceNameA, (LPSTR)lpServiceName); + RtlInitAnsiString(&ServiceNameA, lpServiceName); if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE))) { - SetLastError(ERROR_OUTOFMEMORY); - return (SERVICE_STATUS_HANDLE)0; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; } - SHandle = RegisterServiceCtrlHandlerExW(ServiceNameU.Buffer, - lpHandlerProc, - lpContext); + hServiceStatus = RegisterServiceCtrlHandlerExW(ServiceNameU.Buffer, + lpHandlerProc, + lpContext); RtlFreeUnicodeString(&ServiceNameU); - return SHandle; + return hServiceStatus; } @@ -732,19 +739,27 @@ RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext) { + DWORD dwError; PACTIVE_SERVICE Service; - Service = ScLookupServiceByServiceName(lpServiceName); - if (Service == NULL) + dwError = ScLookupServiceByServiceName(lpServiceName, &Service); + if ((dwError != ERROR_SUCCESS) || (Service == NULL)) { - return (SERVICE_STATUS_HANDLE)NULL; + SetLastError(dwError); + return NULL; } - Service->HandlerFunction = NULL; + if (!lpHandlerProc) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + Service->HandlerFunction = NULL; Service->HandlerFunctionEx = lpHandlerProc; - Service->HandlerContext = lpContext; + Service->HandlerContext = lpContext; - TRACE("RegisterServiceCtrlHandlerEx returning %lu\n", Service->hServiceStatus); + TRACE("RegisterServiceCtrlHandlerEx returning 0x%p\n", Service->hServiceStatus); return Service->hServiceStatus; } @@ -942,11 +957,14 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable) } dwActiveServiceCount = i; + + /* Initialize the service table */ lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwActiveServiceCount * sizeof(ACTIVE_SERVICE)); if (lpActiveServices == NULL) { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } @@ -956,16 +974,18 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable) RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName, lpServiceStartTable[i].lpServiceName); lpActiveServices[i].ServiceMain.A = lpServiceStartTable[i].lpServiceProc; - lpActiveServices[i].hServiceStatus = 0; + lpActiveServices[i].hServiceStatus = NULL; lpActiveServices[i].bUnicode = FALSE; lpActiveServices[i].bOwnProcess = FALSE; } + /* Initialize the connection to the SCM */ + dwError = ScConnectControlPipe(&hPipe); if (dwError != ERROR_SUCCESS) { bRet = FALSE; - goto done; + goto Done; } dwBufSize = sizeof(SCM_CONTROL_PACKET) + @@ -976,22 +996,24 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable) dwBufSize); if (ControlPacket == NULL) { + dwError = ERROR_NOT_ENOUGH_MEMORY; bRet = FALSE; - goto done; + goto Done; } ScCreateStatusBinding(); + /* Start the dispatcher loop */ ScServiceDispatcher(hPipe, ControlPacket, dwBufSize); + /* Close the connection */ ScDestroyStatusBinding(); - CloseHandle(hPipe); /* Free the control packet */ RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket); -done: +Done: /* Free the service table */ for (i = 0; i < dwActiveServiceCount; i++) { @@ -1001,6 +1023,8 @@ done: lpActiveServices = NULL; dwActiveServiceCount = 0; + if (!bRet) SetLastError(dwError); + return bRet; } @@ -1029,11 +1053,14 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable) } dwActiveServiceCount = i; + + /* Initialize the service table */ lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwActiveServiceCount * sizeof(ACTIVE_SERVICE)); if (lpActiveServices == NULL) { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } @@ -1043,16 +1070,18 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable) RtlCreateUnicodeString(&lpActiveServices[i].ServiceName, lpServiceStartTable[i].lpServiceName); lpActiveServices[i].ServiceMain.W = lpServiceStartTable[i].lpServiceProc; - lpActiveServices[i].hServiceStatus = 0; + lpActiveServices[i].hServiceStatus = NULL; lpActiveServices[i].bUnicode = TRUE; lpActiveServices[i].bOwnProcess = FALSE; } + /* Initialize the connection to the SCM */ + dwError = ScConnectControlPipe(&hPipe); if (dwError != ERROR_SUCCESS) { bRet = FALSE; - goto done; + goto Done; } dwBufSize = sizeof(SCM_CONTROL_PACKET) + @@ -1063,22 +1092,24 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable) dwBufSize); if (ControlPacket == NULL) { + dwError = ERROR_NOT_ENOUGH_MEMORY; bRet = FALSE; - goto done; + goto Done; } ScCreateStatusBinding(); + /* Start the dispatcher loop */ ScServiceDispatcher(hPipe, ControlPacket, dwBufSize); + /* Close the connection */ ScDestroyStatusBinding(); - CloseHandle(hPipe); /* Free the control packet */ RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket); -done: +Done: /* Free the service table */ for (i = 0; i < dwActiveServiceCount; i++) { @@ -1088,6 +1119,8 @@ done: lpActiveServices = NULL; dwActiveServiceCount = 0; + if (!bRet) SetLastError(dwError); + return bRet; } -- 2.17.1