Passing [in] and [unique] to RQueryServiceonfigW is not a solution
either. It was a quick and dirty hack to get things working.
I'm working on a proper solution right now, unless you already have
something in your hat :-)
Le 13/08/2011 12:53, ekohl(a)svn.reactos.org a écrit :
Author: ekohl
Date: Sat Aug 13 10:53:15 2011
New Revision: 53201
URL:
http://svn.reactos.org/svn/reactos?rev=53201&view=rev
Log:
[ADVAPI32]
Fix EnumServicesStatusEx[A/W]:
- If lpServices is NULL or cbBufSize is less than sizeof(ENUM_SERVICE_STATUS_PROCESS)
pass a pointer to an internal status buffer to REnumServicesStatusExA/W. Adding
'in' and 'unique' attributes in the idl file is NOT an option because this
is not compatible with Windows.
- Check the InfoLevel.
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 13 10:53:15 2011
@@ -1150,7 +1150,9 @@
LPDWORD lpResumeHandle,
LPCSTR pszGroupName)
{
+ ENUM_SERVICE_STATUS_PROCESSA ServiceStatus;
LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr;
+ DWORD dwBufferSize;
DWORD dwError;
DWORD dwCount;
@@ -1166,6 +1168,18 @@
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
+ }
+
+ if (lpServices == NULL ||
+ cbBufSize< sizeof(ENUM_SERVICE_STATUS_PROCESSA))
+ {
+ lpStatusPtr =&ServiceStatus;
+ dwBufferSize = sizeof(ENUM_SERVICE_STATUS_PROCESSA);
+ }
+ else
+ {
+ lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
+ dwBufferSize = cbBufSize;
}
RpcTryExcept
@@ -1174,8 +1188,8 @@
InfoLevel,
dwServiceType,
dwServiceState,
- (LPBYTE)lpServices,
- cbBufSize,
+ (LPBYTE)lpStatusPtr,
+ dwBufferSize,
pcbBytesNeeded,
lpServicesReturned,
lpResumeHandle,
@@ -1189,18 +1203,20 @@
if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
{
- lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
- for (dwCount = 0; dwCount< *lpServicesReturned; dwCount++)
+ if (InfoLevel == SC_ENUM_PROCESS_INFO)
{
- if (lpStatusPtr->lpServiceName)
- lpStatusPtr->lpServiceName =
- (LPSTR)((ULONG_PTR)lpServices +
(ULONG_PTR)lpStatusPtr->lpServiceName);
-
- if (lpStatusPtr->lpDisplayName)
- lpStatusPtr->lpDisplayName =
- (LPSTR)((ULONG_PTR)lpServices +
(ULONG_PTR)lpStatusPtr->lpDisplayName);
-
- lpStatusPtr++;
+ for (dwCount = 0; dwCount< *lpServicesReturned; dwCount++)
+ {
+ if (lpStatusPtr->lpServiceName)
+ lpStatusPtr->lpServiceName =
+ (LPSTR)((ULONG_PTR)lpServices +
(ULONG_PTR)lpStatusPtr->lpServiceName);
+
+ if (lpStatusPtr->lpDisplayName)
+ lpStatusPtr->lpDisplayName =
+ (LPSTR)((ULONG_PTR)lpServices +
(ULONG_PTR)lpStatusPtr->lpDisplayName);
+
+ lpStatusPtr++;
+ }
}
}
@@ -1234,11 +1250,31 @@
LPDWORD lpResumeHandle,
LPCWSTR pszGroupName)
{
+ ENUM_SERVICE_STATUS_PROCESSW ServiceStatus;
LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
+ DWORD dwBufferSize;
DWORD dwError;
DWORD dwCount;
TRACE("EnumServicesStatusExW() called\n");
+
+ if (InfoLevel != SC_ENUM_PROCESS_INFO)
+ {
+ SetLastError(ERROR_INVALID_LEVEL);
+ return FALSE;
+ }
+
+ if (lpServices == NULL ||
+ cbBufSize< sizeof(ENUM_SERVICE_STATUS_PROCESSW))
+ {
+ lpStatusPtr =&ServiceStatus;
+ dwBufferSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW);
+ }
+ else
+ {
+ lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
+ dwBufferSize = cbBufSize;
+ }
RpcTryExcept
{
@@ -1246,8 +1282,8 @@
InfoLevel,
dwServiceType,
dwServiceState,
- (LPBYTE)lpServices,
- cbBufSize,
+ (LPBYTE)lpStatusPtr,
+ dwBufferSize,
pcbBytesNeeded,
lpServicesReturned,
lpResumeHandle,
@@ -1261,18 +1297,20 @@
if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
{
- lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
- for (dwCount = 0; dwCount< *lpServicesReturned; dwCount++)
+ if (InfoLevel == SC_ENUM_PROCESS_INFO)
{
- if (lpStatusPtr->lpServiceName)
- lpStatusPtr->lpServiceName =
- (LPWSTR)((ULONG_PTR)lpServices +
(ULONG_PTR)lpStatusPtr->lpServiceName);
-
- if (lpStatusPtr->lpDisplayName)
- lpStatusPtr->lpDisplayName =
- (LPWSTR)((ULONG_PTR)lpServices +
(ULONG_PTR)lpStatusPtr->lpDisplayName);
-
- lpStatusPtr++;
+ for (dwCount = 0; dwCount< *lpServicesReturned; dwCount++)
+ {
+ if (lpStatusPtr->lpServiceName)
+ lpStatusPtr->lpServiceName =
+ (LPWSTR)((ULONG_PTR)lpServices +
(ULONG_PTR)lpStatusPtr->lpServiceName);
+
+ if (lpStatusPtr->lpDisplayName)
+ lpStatusPtr->lpDisplayName =
+ (LPWSTR)((ULONG_PTR)lpServices +
(ULONG_PTR)lpStatusPtr->lpDisplayName);
+
+ lpStatusPtr++;
+ }
}
}