From 6e9b31dafd8db055a2770d344b95caf14e9faaf4 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 13 Aug 2011 19:57:32 +0000 Subject: [PATCH] [ADVAPI32] Fix EnumServiceGroupW and EnumServiceStatus[A/W]: - If lpServices is NULL or cbBufSize is less than sizeof(ENUM_SERVICE_STATUS/W) pass a pointer to an internal status buffer to REnumServiceGrouW or REnumServiceStatusA/W. svn path=/trunk/; revision=53210 --- reactos/dll/win32/advapi32/service/scm.c | 115 ++++++++++++++++------- 1 file changed, 80 insertions(+), 35 deletions(-) diff --git a/reactos/dll/win32/advapi32/service/scm.c b/reactos/dll/win32/advapi32/service/scm.c index ff2496c970f..490cf40a31f 100644 --- a/reactos/dll/win32/advapi32/service/scm.c +++ b/reactos/dll/win32/advapi32/service/scm.c @@ -875,7 +875,9 @@ EnumServiceGroupW(SC_HANDLE hSCManager, LPDWORD lpResumeHandle, LPCWSTR lpGroup) { + ENUM_SERVICE_STATUSW ServiceStatus; LPENUM_SERVICE_STATUSW lpStatusPtr; + DWORD dwBufferSize; DWORD dwError; DWORD dwCount; @@ -887,6 +889,17 @@ EnumServiceGroupW(SC_HANDLE hSCManager, return FALSE; } + if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) + { + lpStatusPtr = &ServiceStatus; + dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); + } + else + { + lpStatusPtr = lpServices; + dwBufferSize = cbBufSize; + } + RpcTryExcept { if (lpGroup == NULL) @@ -894,8 +907,8 @@ EnumServiceGroupW(SC_HANDLE hSCManager, dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager, dwServiceType, dwServiceState, - (LPBYTE)lpServices, - cbBufSize, + (LPBYTE)lpStatusPtr, + dwBufferSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle); @@ -905,8 +918,8 @@ EnumServiceGroupW(SC_HANDLE hSCManager, dwError = REnumServiceGroupW((SC_RPC_HANDLE)hSCManager, dwServiceType, dwServiceState, - (LPBYTE)lpServices, - cbBufSize, + (LPBYTE)lpStatusPtr, + dwBufferSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, @@ -921,18 +934,20 @@ EnumServiceGroupW(SC_HANDLE hSCManager, if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) { - lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices; - for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + if (*lpServicesReturned > 0) { - if (lpStatusPtr->lpServiceName) - lpStatusPtr->lpServiceName = - (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); + for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + { + if (lpStatusPtr->lpServiceName) + lpStatusPtr->lpServiceName = + (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); - if (lpStatusPtr->lpDisplayName) - lpStatusPtr->lpDisplayName = - (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); + if (lpStatusPtr->lpDisplayName) + lpStatusPtr->lpDisplayName = + (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); - lpStatusPtr++; + lpStatusPtr++; + } } } @@ -964,7 +979,9 @@ EnumServicesStatusA(SC_HANDLE hSCManager, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle) { + ENUM_SERVICE_STATUSA ServiceStatus; LPENUM_SERVICE_STATUSA lpStatusPtr; + DWORD dwBufferSize; DWORD dwError; DWORD dwCount; @@ -1012,13 +1029,24 @@ EnumServicesStatusA(SC_HANDLE hSCManager, return FALSE; } + if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) + { + lpStatusPtr = &ServiceStatus; + dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); + } + else + { + lpStatusPtr = lpServices; + dwBufferSize = cbBufSize; + } + RpcTryExcept { dwError = REnumServicesStatusA((SC_RPC_HANDLE)hSCManager, dwServiceType, dwServiceState, - (LPBYTE)lpServices, - cbBufSize, + (LPBYTE)lpStatusPtr, + dwBufferSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle); @@ -1031,18 +1059,20 @@ EnumServicesStatusA(SC_HANDLE hSCManager, if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) { - lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices; - for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + if (*lpServicesReturned > 0) { - if (lpStatusPtr->lpServiceName) - lpStatusPtr->lpServiceName = - (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); + for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + { + if (lpStatusPtr->lpServiceName) + lpStatusPtr->lpServiceName = + (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); - if (lpStatusPtr->lpDisplayName) - lpStatusPtr->lpDisplayName = - (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); + if (lpStatusPtr->lpDisplayName) + lpStatusPtr->lpDisplayName = + (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); - lpStatusPtr++; + lpStatusPtr++; + } } } @@ -1074,7 +1104,9 @@ EnumServicesStatusW(SC_HANDLE hSCManager, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle) { + ENUM_SERVICE_STATUSW ServiceStatus; LPENUM_SERVICE_STATUSW lpStatusPtr; + DWORD dwBufferSize; DWORD dwError; DWORD dwCount; @@ -1086,13 +1118,24 @@ EnumServicesStatusW(SC_HANDLE hSCManager, return FALSE; } + if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) + { + lpStatusPtr = &ServiceStatus; + dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); + } + else + { + lpStatusPtr = lpServices; + dwBufferSize = cbBufSize; + } + RpcTryExcept { dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager, dwServiceType, dwServiceState, - (LPBYTE)lpServices, - cbBufSize, + (LPBYTE)lpStatusPtr, + dwBufferSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle); @@ -1105,18 +1148,20 @@ EnumServicesStatusW(SC_HANDLE hSCManager, if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) { - lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices; - for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + if (*lpServicesReturned > 0) { - if (lpStatusPtr->lpServiceName) - lpStatusPtr->lpServiceName = - (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); + for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + { + if (lpStatusPtr->lpServiceName) + lpStatusPtr->lpServiceName = + (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); - if (lpStatusPtr->lpDisplayName) - lpStatusPtr->lpDisplayName = - (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); + if (lpStatusPtr->lpDisplayName) + lpStatusPtr->lpDisplayName = + (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); - lpStatusPtr++; + lpStatusPtr++; + } } } -- 2.17.1