Author: ekohl
Date: Sat Aug 20 19:08:21 2011
New Revision: 53344
URL:
http://svn.reactos.org/svn/reactos?rev=53344&view=rev
Log:
[ADVAPI32]
QueryServiceConfig2A/W: Handle small or null buffer properly.
Modified:
trunk/reactos/dll/win32/advapi32/service/scm.c
Modified: trunk/reactos/dll/win32/advapi32/service/scm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/service…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/service/scm.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/service/scm.c [iso-8859-1] Sat Aug 20 19:08:21 2011
@@ -2076,23 +2076,43 @@
DWORD cbBufSize,
LPDWORD pcbBytesNeeded)
{
+ SERVICE_DESCRIPTIONA ServiceDescription;
+ SERVICE_FAILURE_ACTIONSA ServiceFailureActions;
+ LPBYTE lpTempBuffer;
+ BOOL bUseTempBuffer = FALSE;
+ DWORD dwBufferSize;
DWORD dwError;
TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize
%lu, pcbBytesNeeded %p)\n",
hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
- if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
- dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
- {
- SetLastError(ERROR_INVALID_LEVEL);
- return FALSE;
- }
-
- if ((lpBuffer == NULL && cbBufSize != 0) ||
- pcbBytesNeeded == NULL)
- {
- SetLastError(ERROR_INVALID_ADDRESS);
- return FALSE;
+ lpTempBuffer = lpBuffer;
+ dwBufferSize = cbBufSize;
+
+ switch (dwInfoLevel)
+ {
+ case SERVICE_CONFIG_DESCRIPTION:
+ if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_DESCRIPTIONA)))
+ {
+ lpTempBuffer = (LPBYTE)&ServiceDescription;
+ dwBufferSize = sizeof(SERVICE_DESCRIPTIONA);
+ bUseTempBuffer = TRUE;
+ }
+ break;
+
+ case SERVICE_CONFIG_FAILURE_ACTIONS:
+ if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_FAILURE_ACTIONSA)))
+ {
+ lpTempBuffer = (LPBYTE)&ServiceFailureActions;
+ dwBufferSize = sizeof(SERVICE_FAILURE_ACTIONSA);
+ bUseTempBuffer = TRUE;
+ }
+ break;
+
+ default:
+ WARN("Unknown info level 0x%lx\n", dwInfoLevel);
+ SetLastError(ERROR_INVALID_LEVEL);
+ return FALSE;
}
RpcTryExcept
@@ -2100,8 +2120,8 @@
/* Call to services.exe using RPC */
dwError = RQueryServiceConfig2A((SC_RPC_HANDLE)hService,
dwInfoLevel,
- lpBuffer,
- cbBufSize,
+ lpTempBuffer,
+ dwBufferSize,
pcbBytesNeeded);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -2114,6 +2134,13 @@
{
TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
SetLastError(dwError);
+ return FALSE;
+ }
+
+ if (bUseTempBuffer == TRUE)
+ {
+ TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
@@ -2121,7 +2148,7 @@
{
case SERVICE_CONFIG_DESCRIPTION:
{
- LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpBuffer;
+ LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpTempBuffer;
if (lpPtr->lpDescription != NULL)
lpPtr->lpDescription =
@@ -2131,7 +2158,7 @@
case SERVICE_CONFIG_FAILURE_ACTIONS:
{
- LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
+ LPSERVICE_FAILURE_ACTIONSA lpPtr =
(LPSERVICE_FAILURE_ACTIONSA)lpTempBuffer;
if (lpPtr->lpRebootMsg != NULL)
lpPtr->lpRebootMsg =
@@ -2146,11 +2173,6 @@
(SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
}
break;
-
- default:
- ERR("Unknown info level 0x%lx\n", dwInfoLevel);
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
}
TRACE("QueryServiceConfig2A() done\n");
@@ -2171,23 +2193,43 @@
DWORD cbBufSize,
LPDWORD pcbBytesNeeded)
{
+ SERVICE_DESCRIPTIONW ServiceDescription;
+ SERVICE_FAILURE_ACTIONSW ServiceFailureActions;
+ LPBYTE lpTempBuffer;
+ BOOL bUseTempBuffer = FALSE;
+ DWORD dwBufferSize;
DWORD dwError;
TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
- if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
- dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
- {
- SetLastError(ERROR_INVALID_LEVEL);
- return FALSE;
- }
-
- if ((lpBuffer == NULL && cbBufSize != 0) ||
- pcbBytesNeeded == NULL)
- {
- SetLastError(ERROR_INVALID_ADDRESS);
- return FALSE;
+ lpTempBuffer = lpBuffer;
+ dwBufferSize = cbBufSize;
+
+ switch (dwInfoLevel)
+ {
+ case SERVICE_CONFIG_DESCRIPTION:
+ if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_DESCRIPTIONW)))
+ {
+ lpTempBuffer = (LPBYTE)&ServiceDescription;
+ dwBufferSize = sizeof(SERVICE_DESCRIPTIONW);
+ bUseTempBuffer = TRUE;
+ }
+ break;
+
+ case SERVICE_CONFIG_FAILURE_ACTIONS:
+ if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_FAILURE_ACTIONSW)))
+ {
+ lpTempBuffer = (LPBYTE)&ServiceFailureActions;
+ dwBufferSize = sizeof(SERVICE_FAILURE_ACTIONSW);
+ bUseTempBuffer = TRUE;
+ }
+ break;
+
+ default:
+ WARN("Unknown info level 0x%lx\n", dwInfoLevel);
+ SetLastError(ERROR_INVALID_LEVEL);
+ return FALSE;
}
RpcTryExcept
@@ -2195,8 +2237,8 @@
/* Call to services.exe using RPC */
dwError = RQueryServiceConfig2W((SC_RPC_HANDLE)hService,
dwInfoLevel,
- lpBuffer,
- cbBufSize,
+ lpTempBuffer,
+ dwBufferSize,
pcbBytesNeeded);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -2209,6 +2251,13 @@
{
TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
SetLastError(dwError);
+ return FALSE;
+ }
+
+ if (bUseTempBuffer == TRUE)
+ {
+ TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
@@ -2216,7 +2265,7 @@
{
case SERVICE_CONFIG_DESCRIPTION:
{
- LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpBuffer;
+ LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpTempBuffer;
if (lpPtr->lpDescription != NULL)
lpPtr->lpDescription =
@@ -2226,7 +2275,7 @@
case SERVICE_CONFIG_FAILURE_ACTIONS:
{
- LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
+ LPSERVICE_FAILURE_ACTIONSW lpPtr =
(LPSERVICE_FAILURE_ACTIONSW)lpTempBuffer;
if (lpPtr->lpRebootMsg != NULL)
lpPtr->lpRebootMsg =
@@ -2241,11 +2290,6 @@
(SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
}
break;
-
- default:
- WARN("Unknown info level 0x%lx\n", dwInfoLevel);
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
}
TRACE("QueryServiceConfig2W() done\n");