From b4fdd97d15a58005ea788a0ec16b0f598dd0c1c0 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 13 Aug 2011 14:26:55 +0000 Subject: [PATCH] [ADVAPI32] 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 | 139 ++++++++++++++--------- reactos/include/reactos/idl/svcctl.idl | 8 +- 2 files changed, 87 insertions(+), 60 deletions(-) diff --git a/reactos/dll/win32/advapi32/service/scm.c b/reactos/dll/win32/advapi32/service/scm.c index 3ce9907ad0f..ff2496c970f 100644 --- a/reactos/dll/win32/advapi32/service/scm.c +++ b/reactos/dll/win32/advapi32/service/scm.c @@ -1835,17 +1835,32 @@ QueryServiceConfigA(SC_HANDLE hService, 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); + 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, - (LPBYTE)lpServiceConfig, - cbBufSize, + (LPBYTE)lpConfigPtr, + dwBufferSize, pcbBytesNeeded); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) @@ -1862,30 +1877,30 @@ QueryServiceConfigA(SC_HANDLE hService, } /* 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"); @@ -1904,20 +1919,32 @@ QueryServiceConfigW(SC_HANDLE hService, 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); - - 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, - (LPBYTE)lpServiceConfig, - cbBufSize, + (LPBYTE)lpConfigPtr, + dwBufferSize, pcbBytesNeeded); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) @@ -1934,30 +1961,30 @@ QueryServiceConfigW(SC_HANDLE hService, } /* 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"); diff --git a/reactos/include/reactos/idl/svcctl.idl b/reactos/include/reactos/idl/svcctl.idl index f272c26ebbe..2febd675415 100644 --- a/reactos/include/reactos/idl/svcctl.idl +++ b/reactos/include/reactos/idl/svcctl.idl @@ -435,10 +435,10 @@ interface svcctl /* 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, - [in, out, unique] LPBOUNDED_DWORD_8K pcbBytesNeeded); + [out] LPBOUNDED_DWORD_8K pcbBytesNeeded); /* Function 18 */ DWORD RQueryServiceLockStatusW( @@ -547,10 +547,10 @@ interface svcctl /* 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, - [in, out, unique] LPBOUNDED_DWORD_8K pcbBytesNeeded); + [out] LPBOUNDED_DWORD_8K pcbBytesNeeded); /* Function 30 */ DWORD RQueryServiceLockStatusA( -- 2.17.1