--- trunk/reactos/include/idl/svcctl.idl 2005-12-26 02:45:49 UTC (rev 20334)
+++ trunk/reactos/include/idl/svcctl.idl 2005-12-26 15:06:46 UTC (rev 20335)
@@ -12,6 +12,7 @@
#define SC_LOCK unsigned int
#define SERVICE_STATUS_HANDLE unsigned long
#define SC_STATUS_TYPE unsigned long
+#define SC_ENUM_TYPE unsigned long
#define LPSTR char*
#define LPCSTR char*
#define LPWSTR wchar_t*
@@ -138,7 +139,7 @@
DWORD ScmrEnumDependentServicesW([in] handle_t BindingHandle,
[in] SC_HANDLE hService,
[in] DWORD dwServiceState,
- [out, size_is(cbBufSize)] LPBYTE lpServices,
+ [out, unique, size_is(cbBufSize)] LPBYTE lpServices,
[in] DWORD cbBufSize,
[out] LPDWORD pcbBytesNeeded,
[out] LPDWORD lpServicesReturned);
@@ -148,7 +149,7 @@
[in] SC_HANDLE hSCManager,
[in] DWORD dwServiceType,
[in] DWORD dwServiceState,
- [out, size_is(dwBufSize)] LPBYTE lpServices,
+ [out, unique, size_is(dwBufSize)] LPBYTE lpServices,
[in] DWORD dwBufSize,
[out] LPDWORD pcbBytesNeeded,
[out] LPDWORD lpServicesReturned,
@@ -178,7 +179,7 @@
/* Function 18 */
DWORD ScmrQueryServiceLockStatusW([in] handle_t BindingHandle,
[in] SC_HANDLE hSCManager,
- [out, size_is(cbBufSize), unique] LPBYTE lpLockStatus,
+ [out, unique, size_is(cbBufSize)] LPBYTE lpLockStatus,
[in] DWORD cbBufSize,
[out] LPDWORD pcbBytesNeeded);
@@ -249,7 +250,7 @@
DWORD ScmrEnumDependentServicesA([in] handle_t BindingHandle,
[in] SC_HANDLE hService,
[in] DWORD dwServiceState,
- [out, size_is(cbBufSize)] LPBYTE lpServices,
+ [out, unique, size_is(cbBufSize)] LPBYTE lpServices,
[in] DWORD cbBufSize,
[out] LPDWORD pcbBytesNeeded,
[out] LPDWORD lpServicesReturned);
@@ -259,7 +260,7 @@
[in] SC_HANDLE hSCManager,
[in] DWORD dwServiceType,
[in] DWORD dwServiceState,
- [out, size_is(dwBufSize)] LPBYTE lpServices,
+ [out, unique, size_is(dwBufSize)] LPBYTE lpServices,
[in] DWORD dwBufSize,
[out] LPDWORD pcbBytesNeeded,
[out] LPDWORD lpServicesReturned,
@@ -289,7 +290,7 @@
/* Function 30 */
// DWORD ScmrQueryServiceLockStatusA([in] handle_t BindingHandle,
// [in] SC_HANDLE hSCManager,
-// [out, size_is(cbBufSize), unique] LPBYTE lpLockStatus,
+// [out, unique, size_is(cbBufSize)] LPBYTE lpLockStatus,
// [in] DWORD cbBufSize,
// [out] LPDWORD pcbBytesNeeded);
@@ -297,20 +298,20 @@
// DWORD ScmrStartServiceA([in] handle_t BindingHandle,
// [in] SC_HANDLE hService,
// [in] DWORD dwNumServiceArgs,
-// [in, string, size_is(dwNumServiceArgs, ), unique] LPSTR *lpServiceArgVectors);
+// [in, unique, string, size_is(dwNumServiceArgs, )] LPSTR *lpServiceArgVectors);
/* Function 32 */
DWORD ScmrGetServiceDisplayNameA([in] handle_t BindingHandle,
[in] SC_HANDLE hSCManager,
[in, string, ref] LPCSTR lpServiceName,
- [out, size_is(*lpcchBuffer), unique] LPSTR lpDisplayName,
+ [out, unique, size_is(*lpcchBuffer)] LPSTR lpDisplayName,
[in, out, ref] LPDWORD lpcchBuffer);
/* Function 33 */
DWORD ScmrGetServiceKeyNameA([in] handle_t BindingHandle,
[in] SC_HANDLE hSCManager,
[in, string, ref] LPCSTR lpDisplayName,
- [out, size_is(*lpcchBuffer), unique] LPSTR lpServiceName,
+ [out, unique, size_is(*lpcchBuffer)] LPSTR lpServiceName,
[in, out, ref] LPDWORD lpcchBuffer);
/* Function 35 */
@@ -335,15 +336,35 @@
DWORD ScmrQueryServiceStatusEx([in] handle_t BindingHandle,
[in] SC_HANDLE hService,
[in] SC_STATUS_TYPE InfoLevel,
- [out, size_is(cbBufSize)] LPBYTE lpBuffer,
+ [out, unique, size_is(cbBufSize)] LPBYTE lpBuffer,
[in] DWORD cbBufSize,
[out] LPDWORD pcbBytesNeeded);
/* Function 41 */
- /* ScmrEnumServicesStatusExA */
+// DWORD ScmrEnumServicesStatusExA([in] handle_t BindingHandle,
+// [in] SC_HANDLE hService,
+// [in] SC_ENUM_TYPE InfoLevel,
+// [in] DWORD dwServiceType,
+// [in] DWORD dwServiceState,
+// [out, unique, size_is(cbBufSize)] LPBYTE lpServices,
+// [in] DWORD cbBufSize,
+// [out] LPDWORD pcbBytesNeeded,
+// [out] LPDWORD lpServicesReturned,
+// [in, out, unique] LPDWORD lpResumeHandle,
+// [in, string] LPCSTR pszGroupName);
/* Function 42 */
- /* ScmrEnumServicesStatusExW */
+ DWORD ScmrEnumServicesStatusExW([in] handle_t BindingHandle,
+ [in] SC_HANDLE hService,
+ [in] SC_ENUM_TYPE InfoLevel,
+ [in] DWORD dwServiceType,
+ [in] DWORD dwServiceState,
+ [out, unique, size_is(cbBufSize)] LPBYTE lpServices,
+ [in] DWORD cbBufSize,
+ [out] LPDWORD pcbBytesNeeded,
+ [out] LPDWORD lpServicesReturned,
+ [in, out, unique] LPDWORD lpResumeHandle,
+ [in, string] LPCWSTR pszGroupName);
/* Function 43 */
/* ScmrSendTSMessage */
--- trunk/reactos/lib/advapi32/service/scm.c 2005-12-26 02:45:49 UTC (rev 20334)
+++ trunk/reactos/lib/advapi32/service/scm.c 2005-12-26 15:06:46 UTC (rev 20335)
@@ -708,24 +708,64 @@
/**********************************************************************
* EnumServicesStatusExW
*
- * @unimplemented
+ * @implemented
*/
-BOOL
-STDCALL
-EnumServicesStatusExW(SC_HANDLE hSCManager,
- SC_ENUM_TYPE InfoLevel,
- DWORD dwServiceType,
- DWORD dwServiceState,
- LPBYTE lpServices,
- DWORD cbBufSize,
- LPDWORD pcbBytesNeeded,
- LPDWORD lpServicesReturned,
- LPDWORD lpResumeHandle,
- LPCWSTR pszGroupName)
+BOOL STDCALL
+EnumServicesStatusExW(SC_HANDLE hSCManager,
+ SC_ENUM_TYPE InfoLevel,
+ DWORD dwServiceType,
+ DWORD dwServiceState,
+ LPBYTE lpServices,
+ DWORD cbBufSize,
+ LPDWORD pcbBytesNeeded,
+ LPDWORD lpServicesReturned,
+ LPDWORD lpResumeHandle,
+ LPCWSTR pszGroupName)
{
- DPRINT1("EnumServicesStatusExW is unimplemented\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
+ DWORD dwError = ERROR_SUCCESS;
+ DWORD dwCount;
+
+ DPRINT1("EnumServicesStatusExW() called\n");
+
+ HandleBind();
+
+ dwError = ScmrEnumServicesStatusExW(BindingHandle,
+ (unsigned int)hSCManager,
+ (unsigned long)InfoLevel,
+ dwServiceType,
+ dwServiceState,
+ (unsigned char *)lpServices,
+ cbBufSize,
+ pcbBytesNeeded,
+ lpServicesReturned,
+ lpResumeHandle,
+ (wchar_t *)pszGroupName);
+
+ lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
+ 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++;
+ }
+
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("ScmrEnumServicesStatusExW() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+
+ DPRINT1("ScmrEnumServicesStatusExW() done\n");
+
+ return TRUE;
}
@@ -1390,7 +1430,7 @@
pcbBytesNeeded);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
+ DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
--- trunk/reactos/subsys/system/services/rpcserver.c 2005-12-26 02:45:49 UTC (rev 20334)
+++ trunk/reactos/subsys/system/services/rpcserver.c 2005-12-26 15:06:46 UTC (rev 20335)
@@ -1393,9 +1393,9 @@
*lpServicesReturned = dwServiceCount;
*pcbBytesNeeded = dwRequiredSize;
- lpStatusPtr = (LPENUM_SERVICE_STATUS)lpServices;
+ lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
lpStringPtr = (LPWSTR)((ULONG_PTR)lpServices +
- dwServiceCount * sizeof(ENUM_SERVICE_STATUS));
+ dwServiceCount * sizeof(ENUM_SERVICE_STATUSW));
dwRequiredSize = 0;
for (ServiceEntry = &lpService->ServiceListEntry;
@@ -2138,9 +2138,229 @@
/* Function 42 */
-/* ScmrEnumServicesStatusExW */
+unsigned long
+ScmrEnumServicesStatusExW(handle_t BindingHandle,
+ unsigned int hSCManager,
+ unsigned long InfoLevel,
+ unsigned long dwServiceType,
+ unsigned long dwServiceState,
+ unsigned char *lpServices,
+ unsigned long dwBufSize,
+ unsigned long *pcbBytesNeeded,
+ unsigned long *lpServicesReturned,
+ unsigned long *lpResumeHandle,
+ wchar_t *pszGroupName)
+{
+ PMANAGER_HANDLE hManager;
+ PSERVICE lpService;
+ DWORD dwError = ERROR_SUCCESS;
+ PLIST_ENTRY ServiceEntry;
+ PSERVICE CurrentService;
+ DWORD dwState;
+ DWORD dwRequiredSize;
+ DWORD dwServiceCount;
+ DWORD dwSize;
+ DWORD dwLastResumeCount;
+ LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
+ LPWSTR lpStringPtr;
+ DPRINT("ScmrEnumServicesStatusExW() called\n");
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ if (InfoLevel != SC_ENUM_PROCESS_INFO)
+ return ERROR_INVALID_LEVEL;
+
+ hManager = (PMANAGER_HANDLE)hSCManager;
+ if (hManager->Handle.Tag != MANAGER_TAG)
+ {
+ DPRINT1("Invalid manager handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* Check access rights */
+ if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
+ SC_MANAGER_ENUMERATE_SERVICE))
+ {
+ DPRINT1("Insufficient access rights! 0x%lx\n",
+ hManager->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ *pcbBytesNeeded = 0;
+ *lpServicesReturned = 0;
+
+ dwLastResumeCount = *lpResumeHandle;
+
+ /* Lock the service list shared */
+
+ lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
+ if (lpService == NULL)
+ {
+ dwError = ERROR_SUCCESS;
+ goto Done;
+ }
+
+ dwRequiredSize = 0;
+ dwServiceCount = 0;
+
+ for (ServiceEntry = &lpService->ServiceListEntry;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ if (pszGroupName)
+ {
+ if (_wcsicmp(pszGroupName, CurrentService->lpServiceGroup))
+ continue;
+ }
+
+ dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+ if (dwRequiredSize + dwSize <= dwBufSize)
+ {
+ DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
+ dwRequiredSize += dwSize;
+ dwServiceCount++;
+ dwLastResumeCount = CurrentService->dwResumeCount;
+ }
+ else
+ {
+ DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
+ break;
+ }
+
+ }
+
+ DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
+ DPRINT("dwServiceCount: %lu\n", dwServiceCount);
+
+ for (;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ if (pszGroupName)
+ {
+ if (_wcsicmp(pszGroupName, CurrentService->lpServiceGroup))
+ continue;
+ }
+
+ dwRequiredSize += (sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
+
+ dwError = ERROR_MORE_DATA;
+ }
+
+ DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
+
+ *lpResumeHandle = dwLastResumeCount;
+ *lpServicesReturned = dwServiceCount;
+ *pcbBytesNeeded = dwRequiredSize;
+
+ lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
+ lpStringPtr = (LPWSTR)((ULONG_PTR)lpServices +
+ dwServiceCount * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
+
+ dwRequiredSize = 0;
+ for (ServiceEntry = &lpService->ServiceListEntry;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ if (pszGroupName)
+ {
+ if (_wcsicmp(pszGroupName, CurrentService->lpServiceGroup))
+ continue;
+ }
+
+ dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+ if (dwRequiredSize + dwSize <= dwBufSize)
+ {
+ /* Copy the service name */
+ wcscpy(lpStringPtr,
+ CurrentService->lpServiceName);
+ lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
+ lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
+
+ /* Copy the display name */
+ wcscpy(lpStringPtr,
+ CurrentService->lpDisplayName);
+ lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
+ lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
+
+ /* Copy the status information */
+ memcpy(&lpStatusPtr->ServiceStatusProcess,
+ &CurrentService->Status,
+ sizeof(SERVICE_STATUS));
+ lpStatusPtr->ServiceStatusProcess.dwProcessId = CurrentService->ProcessId; /* FIXME */
+ lpStatusPtr->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
+
+ lpStatusPtr++;
+ dwRequiredSize += dwSize;
+ }
+ else
+ {
+ break;
+ }
+
+ }
+
+Done:;
+ /* Unlock the service list */
+
+ DPRINT("ScmrEnumServicesStatusExW() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
/* Function 43 */
/* ScmrSendTSMessage */