[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
This commit is contained in:
Eric Kohl 2011-08-13 14:26:55 +00:00
parent 33e3cab77d
commit b4fdd97d15
2 changed files with 79 additions and 52 deletions

View file

@ -1835,17 +1835,32 @@ QueryServiceConfigA(SC_HANDLE hService,
DWORD cbBufSize, DWORD cbBufSize,
LPDWORD pcbBytesNeeded) LPDWORD pcbBytesNeeded)
{ {
QUERY_SERVICE_CONFIGA ServiceConfig;
LPQUERY_SERVICE_CONFIGA lpConfigPtr;
DWORD dwBufferSize;
DWORD dwError; DWORD dwError;
TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n", TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
hService, lpServiceConfig, cbBufSize, pcbBytesNeeded); 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 RpcTryExcept
{ {
/* Call to services.exe using RPC */ /* Call to services.exe using RPC */
dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService, dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService,
(LPBYTE)lpServiceConfig, (LPBYTE)lpConfigPtr,
cbBufSize, dwBufferSize,
pcbBytesNeeded); pcbBytesNeeded);
} }
RpcExcept(EXCEPTION_EXECUTE_HANDLER) RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@ -1862,30 +1877,30 @@ QueryServiceConfigA(SC_HANDLE hService,
} }
/* Adjust the pointers */ /* Adjust the pointers */
if (lpServiceConfig->lpBinaryPathName) if (lpConfigPtr->lpBinaryPathName)
lpServiceConfig->lpBinaryPathName = lpConfigPtr->lpBinaryPathName =
(LPSTR)((ULONG_PTR)lpServiceConfig + (LPSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpBinaryPathName); (ULONG_PTR)lpConfigPtr->lpBinaryPathName);
if (lpServiceConfig->lpLoadOrderGroup) if (lpConfigPtr->lpLoadOrderGroup)
lpServiceConfig->lpLoadOrderGroup = lpConfigPtr->lpLoadOrderGroup =
(LPSTR)((ULONG_PTR)lpServiceConfig + (LPSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpLoadOrderGroup); (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup);
if (lpServiceConfig->lpDependencies) if (lpConfigPtr->lpDependencies)
lpServiceConfig->lpDependencies = lpConfigPtr->lpDependencies =
(LPSTR)((ULONG_PTR)lpServiceConfig + (LPSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpDependencies); (ULONG_PTR)lpConfigPtr->lpDependencies);
if (lpServiceConfig->lpServiceStartName) if (lpConfigPtr->lpServiceStartName)
lpServiceConfig->lpServiceStartName = lpConfigPtr->lpServiceStartName =
(LPSTR)((ULONG_PTR)lpServiceConfig + (LPSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpServiceStartName); (ULONG_PTR)lpConfigPtr->lpServiceStartName);
if (lpServiceConfig->lpDisplayName) if (lpConfigPtr->lpDisplayName)
lpServiceConfig->lpDisplayName = lpConfigPtr->lpDisplayName =
(LPSTR)((ULONG_PTR)lpServiceConfig + (LPSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpDisplayName); (ULONG_PTR)lpConfigPtr->lpDisplayName);
TRACE("QueryServiceConfigA() done\n"); TRACE("QueryServiceConfigA() done\n");
@ -1904,20 +1919,32 @@ QueryServiceConfigW(SC_HANDLE hService,
DWORD cbBufSize, DWORD cbBufSize,
LPDWORD pcbBytesNeeded) LPDWORD pcbBytesNeeded)
{ {
QUERY_SERVICE_CONFIGW ServiceConfig;
LPQUERY_SERVICE_CONFIGW lpConfigPtr;
DWORD dwBufferSize;
DWORD dwError; DWORD dwError;
TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n", TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
hService, lpServiceConfig, cbBufSize, pcbBytesNeeded); hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
if(pcbBytesNeeded) if (lpServiceConfig == NULL ||
*pcbBytesNeeded = 0; cbBufSize < sizeof(QUERY_SERVICE_CONFIGW))
{
lpConfigPtr = &ServiceConfig;
dwBufferSize = sizeof(QUERY_SERVICE_CONFIGW);
}
else
{
lpConfigPtr = lpServiceConfig;
dwBufferSize = cbBufSize;
}
RpcTryExcept RpcTryExcept
{ {
/* Call to services.exe using RPC */ /* Call to services.exe using RPC */
dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService, dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService,
(LPBYTE)lpServiceConfig, (LPBYTE)lpConfigPtr,
cbBufSize, dwBufferSize,
pcbBytesNeeded); pcbBytesNeeded);
} }
RpcExcept(EXCEPTION_EXECUTE_HANDLER) RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@ -1934,30 +1961,30 @@ QueryServiceConfigW(SC_HANDLE hService,
} }
/* Adjust the pointers */ /* Adjust the pointers */
if (lpServiceConfig->lpBinaryPathName) if (lpConfigPtr->lpBinaryPathName)
lpServiceConfig->lpBinaryPathName = lpConfigPtr->lpBinaryPathName =
(LPWSTR)((ULONG_PTR)lpServiceConfig + (LPWSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpBinaryPathName); (ULONG_PTR)lpConfigPtr->lpBinaryPathName);
if (lpServiceConfig->lpLoadOrderGroup) if (lpConfigPtr->lpLoadOrderGroup)
lpServiceConfig->lpLoadOrderGroup = lpConfigPtr->lpLoadOrderGroup =
(LPWSTR)((ULONG_PTR)lpServiceConfig + (LPWSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpLoadOrderGroup); (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup);
if (lpServiceConfig->lpDependencies) if (lpConfigPtr->lpDependencies)
lpServiceConfig->lpDependencies = lpConfigPtr->lpDependencies =
(LPWSTR)((ULONG_PTR)lpServiceConfig + (LPWSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpDependencies); (ULONG_PTR)lpConfigPtr->lpDependencies);
if (lpServiceConfig->lpServiceStartName) if (lpConfigPtr->lpServiceStartName)
lpServiceConfig->lpServiceStartName = lpConfigPtr->lpServiceStartName =
(LPWSTR)((ULONG_PTR)lpServiceConfig + (LPWSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpServiceStartName); (ULONG_PTR)lpConfigPtr->lpServiceStartName);
if (lpServiceConfig->lpDisplayName) if (lpConfigPtr->lpDisplayName)
lpServiceConfig->lpDisplayName = lpConfigPtr->lpDisplayName =
(LPWSTR)((ULONG_PTR)lpServiceConfig + (LPWSTR)((ULONG_PTR)lpConfigPtr +
(ULONG_PTR)lpServiceConfig->lpDisplayName); (ULONG_PTR)lpConfigPtr->lpDisplayName);
TRACE("QueryServiceConfigW() done\n"); TRACE("QueryServiceConfigW() done\n");

View file

@ -435,10 +435,10 @@ interface svcctl
/* Function 17 */ /* Function 17 */
DWORD RQueryServiceConfigW( DWORD RQueryServiceConfigW(
[in] SC_RPC_HANDLE hService, [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, */ /* FIXME: should be [out] LPQUERY_SERVICE_CONFIGW lpServiceConfig, */
[in, range(0, 1024*8)] DWORD cbBufSize, [in, range(0, 1024*8)] DWORD cbBufSize,
[in, out, unique] LPBOUNDED_DWORD_8K pcbBytesNeeded); [out] LPBOUNDED_DWORD_8K pcbBytesNeeded);
/* Function 18 */ /* Function 18 */
DWORD RQueryServiceLockStatusW( DWORD RQueryServiceLockStatusW(
@ -547,10 +547,10 @@ interface svcctl
/* Function 29 */ /* Function 29 */
DWORD RQueryServiceConfigA( DWORD RQueryServiceConfigA(
[in] SC_RPC_HANDLE hService, [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, */ /* FIXME: should be [out] LPQUERY_SERVICE_CONFIGA lpServiceConfig, */
[in, range(0, 1024*8)] DWORD cbBufSize, [in, range(0, 1024*8)] DWORD cbBufSize,
[in, out, unique] LPBOUNDED_DWORD_8K pcbBytesNeeded); [out] LPBOUNDED_DWORD_8K pcbBytesNeeded);
/* Function 30 */ /* Function 30 */
DWORD RQueryServiceLockStatusA( DWORD RQueryServiceLockStatusA(