[ros-diffs] [ekohl] 53344: [ADVAPI32] QueryServiceConfig2A/W: Handle small or null buffer properly.

ekohl at svn.reactos.org ekohl at svn.reactos.org
Sat Aug 20 19:08:22 UTC 2011


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/scm.c?rev=53344&r1=53343&r2=53344&view=diff
==============================================================================
--- 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");




More information about the Ros-diffs mailing list