[ADVAPI32]
authorEric Kohl <eric.kohl@reactos.org>
Sat, 13 Aug 2011 14:26:55 +0000 (14:26 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 13 Aug 2011 14:26:55 +0000 (14:26 +0000)
Fix QueryServiceConfigEx[A/W]:
- If lpServiceConfig is NULL or cbBufSize is less than sizeof(QUERY_SERVICE_CONFIGA/W) pass a pointer to an internal status buffer to RQueryServiceConfigA/W.
- Revert r53153 and r53154. Adding 'in' and 'unique' attributes is NOT an option because this is not compatible with Windows.

svn path=/trunk/; revision=53202

reactos/dll/win32/advapi32/service/scm.c
reactos/include/reactos/idl/svcctl.idl

index 3ce9907..ff2496c 100644 (file)
@@ -1835,17 +1835,32 @@ QueryServiceConfigA(SC_HANDLE hService,
                     DWORD cbBufSize,
                     LPDWORD pcbBytesNeeded)
 {
                     DWORD cbBufSize,
                     LPDWORD pcbBytesNeeded)
 {
+    QUERY_SERVICE_CONFIGA ServiceConfig;
+    LPQUERY_SERVICE_CONFIGA lpConfigPtr;
+    DWORD dwBufferSize;
     DWORD dwError;
 
     TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
            hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
 
     DWORD dwError;
 
     TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
            hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
 
+    if (lpServiceConfig == NULL ||
+        cbBufSize < sizeof(QUERY_SERVICE_CONFIGA))
+    {
+        lpConfigPtr = &ServiceConfig;
+        dwBufferSize = sizeof(QUERY_SERVICE_CONFIGA);
+    }
+    else
+    {
+        lpConfigPtr = lpServiceConfig;
+        dwBufferSize = cbBufSize;
+    }
+
     RpcTryExcept
     {
         /* Call to services.exe using RPC */
         dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService,
     RpcTryExcept
     {
         /* Call to services.exe using RPC */
         dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService,
-                                       (LPBYTE)lpServiceConfig,
-                                       cbBufSize,
+                                       (LPBYTE)lpConfigPtr,
+                                       dwBufferSize,
                                        pcbBytesNeeded);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
                                        pcbBytesNeeded);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -1862,30 +1877,30 @@ QueryServiceConfigA(SC_HANDLE hService,
     }
 
     /* Adjust the pointers */
     }
 
     /* Adjust the pointers */
-    if (lpServiceConfig->lpBinaryPathName)
-        lpServiceConfig->lpBinaryPathName =
-            (LPSTR)((ULONG_PTR)lpServiceConfig +
-                    (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
-
-    if (lpServiceConfig->lpLoadOrderGroup)
-        lpServiceConfig->lpLoadOrderGroup =
-            (LPSTR)((ULONG_PTR)lpServiceConfig +
-                    (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
-
-    if (lpServiceConfig->lpDependencies)
-        lpServiceConfig->lpDependencies =
-            (LPSTR)((ULONG_PTR)lpServiceConfig +
-                    (ULONG_PTR)lpServiceConfig->lpDependencies);
-
-    if (lpServiceConfig->lpServiceStartName)
-        lpServiceConfig->lpServiceStartName =
-            (LPSTR)((ULONG_PTR)lpServiceConfig +
-                    (ULONG_PTR)lpServiceConfig->lpServiceStartName);
-
-    if (lpServiceConfig->lpDisplayName)
-        lpServiceConfig->lpDisplayName =
-           (LPSTR)((ULONG_PTR)lpServiceConfig +
-                   (ULONG_PTR)lpServiceConfig->lpDisplayName);
+    if (lpConfigPtr->lpBinaryPathName)
+        lpConfigPtr->lpBinaryPathName =
+            (LPSTR)((ULONG_PTR)lpConfigPtr +
+                    (ULONG_PTR)lpConfigPtr->lpBinaryPathName);
+
+    if (lpConfigPtr->lpLoadOrderGroup)
+        lpConfigPtr->lpLoadOrderGroup =
+            (LPSTR)((ULONG_PTR)lpConfigPtr +
+                    (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup);
+
+    if (lpConfigPtr->lpDependencies)
+        lpConfigPtr->lpDependencies =
+            (LPSTR)((ULONG_PTR)lpConfigPtr +
+                    (ULONG_PTR)lpConfigPtr->lpDependencies);
+
+    if (lpConfigPtr->lpServiceStartName)
+        lpConfigPtr->lpServiceStartName =
+            (LPSTR)((ULONG_PTR)lpConfigPtr +
+                    (ULONG_PTR)lpConfigPtr->lpServiceStartName);
+
+    if (lpConfigPtr->lpDisplayName)
+        lpConfigPtr->lpDisplayName =
+           (LPSTR)((ULONG_PTR)lpConfigPtr +
+                   (ULONG_PTR)lpConfigPtr->lpDisplayName);
 
     TRACE("QueryServiceConfigA() done\n");
 
 
     TRACE("QueryServiceConfigA() done\n");
 
@@ -1904,20 +1919,32 @@ QueryServiceConfigW(SC_HANDLE hService,
                     DWORD cbBufSize,
                     LPDWORD pcbBytesNeeded)
 {
                     DWORD cbBufSize,
                     LPDWORD pcbBytesNeeded)
 {
+    QUERY_SERVICE_CONFIGW ServiceConfig;
+    LPQUERY_SERVICE_CONFIGW lpConfigPtr;
+    DWORD dwBufferSize;
     DWORD dwError;
 
     TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
            hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
     DWORD dwError;
 
     TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
            hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
-           
-    if(pcbBytesNeeded)
-        *pcbBytesNeeded = 0;
-    
+
+    if (lpServiceConfig == NULL ||
+        cbBufSize < sizeof(QUERY_SERVICE_CONFIGW))
+    {
+        lpConfigPtr = &ServiceConfig;
+        dwBufferSize = sizeof(QUERY_SERVICE_CONFIGW);
+    }
+    else
+    {
+        lpConfigPtr = lpServiceConfig;
+        dwBufferSize = cbBufSize;
+    }
+
     RpcTryExcept
     {
         /* Call to services.exe using RPC */
         dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService,
     RpcTryExcept
     {
         /* Call to services.exe using RPC */
         dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService,
-                                       (LPBYTE)lpServiceConfig,
-                                       cbBufSize,
+                                       (LPBYTE)lpConfigPtr,
+                                       dwBufferSize,
                                        pcbBytesNeeded);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
                                        pcbBytesNeeded);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -1934,30 +1961,30 @@ QueryServiceConfigW(SC_HANDLE hService,
     }
 
     /* Adjust the pointers */
     }
 
     /* Adjust the pointers */
-    if (lpServiceConfig->lpBinaryPathName)
-        lpServiceConfig->lpBinaryPathName =
-            (LPWSTR)((ULONG_PTR)lpServiceConfig +
-                     (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
-
-    if (lpServiceConfig->lpLoadOrderGroup)
-        lpServiceConfig->lpLoadOrderGroup =
-            (LPWSTR)((ULONG_PTR)lpServiceConfig +
-                     (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
-
-    if (lpServiceConfig->lpDependencies)
-        lpServiceConfig->lpDependencies =
-            (LPWSTR)((ULONG_PTR)lpServiceConfig +
-                     (ULONG_PTR)lpServiceConfig->lpDependencies);
-
-    if (lpServiceConfig->lpServiceStartName)
-        lpServiceConfig->lpServiceStartName =
-            (LPWSTR)((ULONG_PTR)lpServiceConfig +
-                     (ULONG_PTR)lpServiceConfig->lpServiceStartName);
-
-    if (lpServiceConfig->lpDisplayName)
-        lpServiceConfig->lpDisplayName =
-           (LPWSTR)((ULONG_PTR)lpServiceConfig +
-                    (ULONG_PTR)lpServiceConfig->lpDisplayName);
+    if (lpConfigPtr->lpBinaryPathName)
+        lpConfigPtr->lpBinaryPathName =
+            (LPWSTR)((ULONG_PTR)lpConfigPtr +
+                     (ULONG_PTR)lpConfigPtr->lpBinaryPathName);
+
+    if (lpConfigPtr->lpLoadOrderGroup)
+        lpConfigPtr->lpLoadOrderGroup =
+            (LPWSTR)((ULONG_PTR)lpConfigPtr +
+                     (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup);
+
+    if (lpConfigPtr->lpDependencies)
+        lpConfigPtr->lpDependencies =
+            (LPWSTR)((ULONG_PTR)lpConfigPtr +
+                     (ULONG_PTR)lpConfigPtr->lpDependencies);
+
+    if (lpConfigPtr->lpServiceStartName)
+        lpConfigPtr->lpServiceStartName =
+            (LPWSTR)((ULONG_PTR)lpConfigPtr +
+                     (ULONG_PTR)lpConfigPtr->lpServiceStartName);
+
+    if (lpConfigPtr->lpDisplayName)
+        lpConfigPtr->lpDisplayName =
+           (LPWSTR)((ULONG_PTR)lpConfigPtr +
+                    (ULONG_PTR)lpConfigPtr->lpDisplayName);
 
     TRACE("QueryServiceConfigW() done\n");
 
 
     TRACE("QueryServiceConfigW() done\n");
 
index f272c26..2febd67 100644 (file)
@@ -435,10 +435,10 @@ interface svcctl
     /* Function 17 */
     DWORD RQueryServiceConfigW(
         [in] SC_RPC_HANDLE hService,
     /* Function 17 */
     DWORD RQueryServiceConfigW(
         [in] SC_RPC_HANDLE hService,
-        [in, out, size_is(cbBufSize), unique] LPBYTE lpServiceConfig,
+        [out, size_is(cbBufSize)] LPBYTE lpServiceConfig,
         /* FIXME: should be [out] LPQUERY_SERVICE_CONFIGW lpServiceConfig, */
         [in, range(0, 1024*8)] DWORD cbBufSize,
         /* FIXME: should be [out] LPQUERY_SERVICE_CONFIGW lpServiceConfig, */
         [in, range(0, 1024*8)] DWORD cbBufSize,
-        [in, out, unique] LPBOUNDED_DWORD_8K pcbBytesNeeded);
+        [out] LPBOUNDED_DWORD_8K pcbBytesNeeded);
 
     /* Function 18 */
     DWORD RQueryServiceLockStatusW(
 
     /* Function 18 */
     DWORD RQueryServiceLockStatusW(
@@ -547,10 +547,10 @@ interface svcctl
     /* Function 29 */
     DWORD RQueryServiceConfigA(
         [in] SC_RPC_HANDLE hService,
     /* Function 29 */
     DWORD RQueryServiceConfigA(
         [in] SC_RPC_HANDLE hService,
-        [in, out, size_is(cbBufSize), unique] LPBYTE lpServiceConfig,
+        [out, size_is(cbBufSize)] LPBYTE lpServiceConfig,
         /* FIXME: should be [out] LPQUERY_SERVICE_CONFIGA lpServiceConfig, */
         [in, range(0, 1024*8)] DWORD cbBufSize,
         /* FIXME: should be [out] LPQUERY_SERVICE_CONFIGA lpServiceConfig, */
         [in, range(0, 1024*8)] DWORD cbBufSize,
-        [in, out, unique] LPBOUNDED_DWORD_8K pcbBytesNeeded);
+        [out] LPBOUNDED_DWORD_8K pcbBytesNeeded);
 
     /* Function 30 */
     DWORD RQueryServiceLockStatusA(
 
     /* Function 30 */
     DWORD RQueryServiceLockStatusA(