mirror of
https://github.com/reactos/reactos.git
synced 2024-10-07 09:54:40 +00:00
- REnumServicesStatusA/REnumServicesStatusExA: Call REnumServicesStatusW/REnumServicesStatusExW to do the work eliminating duplicate code.
- lpResumeIndex and lpResumeHandle are set to 0 on success. svn path=/trunk/; revision=36751
This commit is contained in:
parent
d9a416da9f
commit
da1d359b70
|
@ -2371,7 +2371,7 @@ DWORD REnumServicesStatusW(
|
||||||
dwRequiredSize += dwSize;
|
dwRequiredSize += dwSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwError != ERROR_MORE_DATA)
|
if (dwError == 0)
|
||||||
{
|
{
|
||||||
*pcbBytesNeeded = 0;
|
*pcbBytesNeeded = 0;
|
||||||
if (lpResumeHandle) *lpResumeHandle = 0;
|
if (lpResumeHandle) *lpResumeHandle = 0;
|
||||||
|
@ -3375,208 +3375,84 @@ DWORD REnumServicesStatusA(
|
||||||
LPBOUNDED_DWORD_256K lpServicesReturned,
|
LPBOUNDED_DWORD_256K lpServicesReturned,
|
||||||
LPBOUNDED_DWORD_256K lpResumeHandle)
|
LPBOUNDED_DWORD_256K lpResumeHandle)
|
||||||
{
|
{
|
||||||
PMANAGER_HANDLE hManager;
|
LPENUM_SERVICE_STATUSW lpStatusPtrW = NULL;
|
||||||
PSERVICE lpService;
|
LPENUM_SERVICE_STATUSA lpStatusPtrA = NULL;
|
||||||
DWORD dwError = ERROR_SUCCESS;
|
LPWSTR lpStringPtrW;
|
||||||
PLIST_ENTRY ServiceEntry;
|
LPSTR lpStringPtrA;
|
||||||
PSERVICE CurrentService;
|
DWORD dwError;
|
||||||
DWORD dwState;
|
|
||||||
DWORD dwRequiredSize;
|
|
||||||
DWORD dwServiceCount;
|
DWORD dwServiceCount;
|
||||||
DWORD dwSize;
|
|
||||||
DWORD dwLastResumeCount = 0;
|
|
||||||
LPENUM_SERVICE_STATUSA lpStatusPtr;
|
|
||||||
LPSTR lpStringPtr;
|
|
||||||
|
|
||||||
DPRINT("REnumServicesStatusA() called\n");
|
DPRINT("REnumServicesStatusA() called\n");
|
||||||
|
|
||||||
if (ScmShutdown)
|
if ((dwBufSize > 0) && (lpBuffer))
|
||||||
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
||||||
|
|
||||||
hManager = (PMANAGER_HANDLE)hSCManager;
|
|
||||||
if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
|
|
||||||
{
|
{
|
||||||
DPRINT1("Invalid manager handle!\n");
|
lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
|
||||||
return ERROR_INVALID_HANDLE;
|
if (!lpStatusPtrW)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to allocate buffer!\n");
|
||||||
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*pcbBytesNeeded = 0;
|
dwError = REnumServicesStatusW(BindingHandle,
|
||||||
*lpServicesReturned = 0;
|
hSCManager,
|
||||||
|
dwServiceType,
|
||||||
|
dwServiceState,
|
||||||
|
(LPBYTE)lpStatusPtrW,
|
||||||
|
dwBufSize,
|
||||||
|
pcbBytesNeeded,
|
||||||
|
lpServicesReturned,
|
||||||
|
lpResumeHandle);
|
||||||
|
|
||||||
if ((dwServiceType!=SERVICE_DRIVER) && (dwServiceType!=SERVICE_WIN32))
|
/* if no services were returned then we are Done */
|
||||||
|
if (*lpServicesReturned == 0) goto Done;
|
||||||
|
|
||||||
|
lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
|
||||||
|
lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
|
||||||
|
*lpServicesReturned * sizeof(ENUM_SERVICE_STATUSA));
|
||||||
|
lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
|
||||||
|
*lpServicesReturned * sizeof(ENUM_SERVICE_STATUSW));
|
||||||
|
|
||||||
|
for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
|
||||||
{
|
{
|
||||||
DPRINT1("Not a valid Service Type!\n");
|
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dwServiceState<SERVICE_ACTIVE) || (dwServiceState>SERVICE_STATE_ALL))
|
|
||||||
{
|
|
||||||
DPRINT1("Not a valid Service State!\n");
|
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpResumeHandle) dwLastResumeCount = *lpResumeHandle;
|
|
||||||
|
|
||||||
/* FIXME: 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;
|
|
||||||
|
|
||||||
dwSize = sizeof(ENUM_SERVICE_STATUSA) +
|
|
||||||
wcslen(CurrentService->lpServiceName) + 1 +
|
|
||||||
wcslen(CurrentService->lpDisplayName) + 1;
|
|
||||||
|
|
||||||
if (dwRequiredSize + dwSize > dwBufSize)
|
|
||||||
{
|
|
||||||
DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
|
|
||||||
dwRequiredSize += dwSize;
|
|
||||||
dwServiceCount++;
|
|
||||||
dwLastResumeCount = CurrentService->dwResumeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
dwRequiredSize += sizeof(ENUM_SERVICE_STATUSA) +
|
|
||||||
wcslen(CurrentService->lpServiceName) + 1 +
|
|
||||||
wcslen(CurrentService->lpDisplayName) + 1;
|
|
||||||
|
|
||||||
dwError = ERROR_MORE_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
|
|
||||||
|
|
||||||
if (lpResumeHandle) *lpResumeHandle = dwLastResumeCount;
|
|
||||||
*lpServicesReturned = dwServiceCount;
|
|
||||||
*pcbBytesNeeded = dwRequiredSize;
|
|
||||||
|
|
||||||
lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpBuffer;
|
|
||||||
lpStringPtr = (LPSTR)((ULONG_PTR)lpBuffer +
|
|
||||||
dwServiceCount * sizeof(ENUM_SERVICE_STATUSA));
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
dwSize = sizeof(ENUM_SERVICE_STATUSA) +
|
|
||||||
wcslen(CurrentService->lpServiceName) + 1 +
|
|
||||||
wcslen(CurrentService->lpDisplayName) + 1;
|
|
||||||
|
|
||||||
if (dwRequiredSize + dwSize > dwBufSize)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Copy the service name */
|
/* Copy the service name */
|
||||||
WideCharToMultiByte(CP_ACP,
|
WideCharToMultiByte(CP_ACP,
|
||||||
0,
|
0,
|
||||||
CurrentService->lpServiceName,
|
lpStringPtrW,
|
||||||
-1,
|
-1,
|
||||||
lpStringPtr,
|
lpStringPtrA,
|
||||||
wcslen(CurrentService->lpServiceName),
|
wcslen(lpStringPtrW),
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
lpStatusPtr->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
|
|
||||||
lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
|
lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
|
||||||
|
lpStringPtrA += wcslen(lpStringPtrW) + 1;
|
||||||
|
lpStringPtrW += wcslen(lpStringPtrW) + 1;
|
||||||
|
|
||||||
/* Copy the display name */
|
/* Copy the display name */
|
||||||
WideCharToMultiByte(CP_ACP,
|
WideCharToMultiByte(CP_ACP,
|
||||||
0,
|
0,
|
||||||
CurrentService->lpDisplayName,
|
lpStringPtrW,
|
||||||
-1,
|
-1,
|
||||||
lpStringPtr,
|
lpStringPtrA,
|
||||||
wcslen(CurrentService->lpDisplayName),
|
wcslen(lpStringPtrW),
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
lpStatusPtr->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
|
|
||||||
lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
|
lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
|
||||||
|
lpStringPtrA += wcslen(lpStringPtrW) + 1;
|
||||||
|
lpStringPtrW += wcslen(lpStringPtrW) + 1;
|
||||||
|
|
||||||
/* Copy the status information */
|
/* Copy the status information */
|
||||||
memcpy(&lpStatusPtr->ServiceStatus,
|
memcpy(&lpStatusPtrA->ServiceStatus,
|
||||||
&CurrentService->Status,
|
&lpStatusPtrW->ServiceStatus,
|
||||||
sizeof(SERVICE_STATUS));
|
sizeof(SERVICE_STATUS));
|
||||||
|
|
||||||
lpStatusPtr++;
|
lpStatusPtrA++;
|
||||||
dwRequiredSize += dwSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwError != ERROR_MORE_DATA)
|
|
||||||
{
|
|
||||||
*pcbBytesNeeded = 0;
|
|
||||||
if (lpResumeHandle) *lpResumeHandle = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Done:;
|
Done:;
|
||||||
/* FIXME: Unlock the service list */
|
if (lpStatusPtrW) HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
|
||||||
|
|
||||||
DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
|
DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
|
||||||
|
|
||||||
|
@ -4521,73 +4397,16 @@ DWORD REnumServicesStatusExA(
|
||||||
LPBOUNDED_DWORD_256K lpResumeIndex,
|
LPBOUNDED_DWORD_256K lpResumeIndex,
|
||||||
LPCSTR pszGroupName)
|
LPCSTR pszGroupName)
|
||||||
{
|
{
|
||||||
PMANAGER_HANDLE hManager;
|
LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrW = NULL;
|
||||||
PSERVICE lpService;
|
LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtrA = NULL;
|
||||||
DWORD dwError = ERROR_SUCCESS;
|
LPWSTR lpStringPtrW;
|
||||||
PLIST_ENTRY ServiceEntry;
|
LPSTR lpStringPtrA;
|
||||||
PSERVICE CurrentService;
|
|
||||||
DWORD dwState;
|
|
||||||
DWORD dwRequiredSize;
|
|
||||||
DWORD dwServiceCount;
|
|
||||||
DWORD dwSize;
|
|
||||||
DWORD dwLastResumeCount = 0;
|
|
||||||
LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr;
|
|
||||||
LPSTR lpStringPtr;
|
|
||||||
LPWSTR pszGroupNameW = NULL;
|
LPWSTR pszGroupNameW = NULL;
|
||||||
|
DWORD dwError;
|
||||||
|
DWORD dwServiceCount;
|
||||||
|
|
||||||
DPRINT("REnumServicesStatusExA() called\n");
|
DPRINT("REnumServicesStatusExA() 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 || hManager->Handle.Tag != MANAGER_TAG)
|
|
||||||
{
|
|
||||||
DPRINT1("Invalid manager handle!\n");
|
|
||||||
return ERROR_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pcbBytesNeeded = 0;
|
|
||||||
*lpServicesReturned = 0;
|
|
||||||
|
|
||||||
if ((dwServiceType!=SERVICE_DRIVER) && (dwServiceType!=SERVICE_WIN32))
|
|
||||||
{
|
|
||||||
DPRINT1("Not a valid Service Type!\n");
|
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dwServiceState<SERVICE_ACTIVE) || (dwServiceState>SERVICE_STATE_ALL))
|
|
||||||
{
|
|
||||||
DPRINT1("Not a valid Service State!\n");
|
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpResumeIndex) dwLastResumeCount = *lpResumeIndex;
|
|
||||||
|
|
||||||
/* FIXME: Lock the service list shared */
|
|
||||||
|
|
||||||
lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
|
|
||||||
if (lpService == NULL)
|
|
||||||
{
|
|
||||||
dwError = ERROR_SUCCESS;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
dwRequiredSize = 0;
|
|
||||||
dwServiceCount = 0;
|
|
||||||
|
|
||||||
if (pszGroupName)
|
if (pszGroupName)
|
||||||
{
|
{
|
||||||
pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
|
pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
|
||||||
|
@ -4604,209 +4423,82 @@ DWORD REnumServicesStatusExA(
|
||||||
strlen(pszGroupName) + 1);
|
strlen(pszGroupName) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ServiceEntry = &lpService->ServiceListEntry;
|
if ((cbBufSize > 0) && (lpBuffer))
|
||||||
ServiceEntry != &ServiceListHead;
|
|
||||||
ServiceEntry = ServiceEntry->Flink)
|
|
||||||
{
|
{
|
||||||
CurrentService = CONTAINING_RECORD(ServiceEntry,
|
lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbBufSize);
|
||||||
SERVICE,
|
if (!lpStatusPtrW)
|
||||||
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 (pszGroupNameW)
|
|
||||||
{
|
{
|
||||||
if (*pszGroupNameW == 0)
|
DPRINT1("Failed to allocate buffer!\n");
|
||||||
{
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
if (CurrentService->lpGroup != NULL)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((CurrentService->lpGroup == NULL) ||
|
|
||||||
_wcsicmp(pszGroupNameW, CurrentService->lpGroup->lpGroupName))
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
|
dwError = REnumServicesStatusExW(BindingHandle,
|
||||||
(wcslen(CurrentService->lpServiceName) + 1) +
|
hSCManager,
|
||||||
(wcslen(CurrentService->lpDisplayName) + 1);
|
InfoLevel,
|
||||||
|
dwServiceType,
|
||||||
|
dwServiceState,
|
||||||
|
(LPBYTE)lpStatusPtrW,
|
||||||
|
cbBufSize,
|
||||||
|
pcbBytesNeeded,
|
||||||
|
lpServicesReturned,
|
||||||
|
lpResumeIndex,
|
||||||
|
pszGroupNameW);
|
||||||
|
|
||||||
if (dwRequiredSize + dwSize <= cbBufSize)
|
/* if no services were returned then we are Done */
|
||||||
{
|
if (*lpServicesReturned == 0) goto Done;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
lpStatusPtrA = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer;
|
||||||
|
lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
|
||||||
|
*lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
|
||||||
|
lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
|
||||||
|
*lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
|
||||||
|
|
||||||
DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
|
for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
|
||||||
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 (pszGroupNameW)
|
|
||||||
{
|
|
||||||
if (*pszGroupNameW == 0)
|
|
||||||
{
|
|
||||||
if (CurrentService->lpGroup != NULL)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((CurrentService->lpGroup == NULL) ||
|
|
||||||
_wcsicmp(pszGroupNameW, CurrentService->lpGroup->lpGroupName))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dwRequiredSize += (sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
|
|
||||||
(wcslen(CurrentService->lpServiceName) + 1) +
|
|
||||||
(wcslen(CurrentService->lpDisplayName) + 1));
|
|
||||||
|
|
||||||
dwError = ERROR_MORE_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
|
|
||||||
|
|
||||||
if (lpResumeIndex) *lpResumeIndex = dwLastResumeCount;
|
|
||||||
*lpServicesReturned = dwServiceCount;
|
|
||||||
*pcbBytesNeeded = dwRequiredSize;
|
|
||||||
|
|
||||||
/* If there was no services that matched */
|
|
||||||
if (!dwServiceCount)
|
|
||||||
{
|
|
||||||
dwError = ERROR_SERVICE_DOES_NOT_EXIST;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer;
|
|
||||||
lpStringPtr = (LPSTR)((ULONG_PTR)lpBuffer +
|
|
||||||
dwServiceCount * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
|
|
||||||
|
|
||||||
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 (pszGroupNameW)
|
|
||||||
{
|
|
||||||
if (*pszGroupNameW == 0)
|
|
||||||
{
|
|
||||||
if (CurrentService->lpGroup != NULL)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((CurrentService->lpGroup == NULL) ||
|
|
||||||
_wcsicmp(pszGroupNameW, CurrentService->lpGroup->lpGroupName))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
|
|
||||||
((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
|
|
||||||
((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
|
|
||||||
|
|
||||||
if (dwRequiredSize + dwSize <= cbBufSize)
|
|
||||||
{
|
{
|
||||||
/* Copy the service name */
|
/* Copy the service name */
|
||||||
WideCharToMultiByte(CP_ACP,
|
WideCharToMultiByte(CP_ACP,
|
||||||
0,
|
0,
|
||||||
CurrentService->lpServiceName,
|
lpStringPtrW,
|
||||||
-1,
|
-1,
|
||||||
lpStringPtr,
|
lpStringPtrA,
|
||||||
wcslen(CurrentService->lpServiceName),
|
wcslen(lpStringPtrW),
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
lpStatusPtr->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
|
|
||||||
lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
|
lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
|
||||||
|
lpStringPtrA += wcslen(lpStringPtrW) + 1;
|
||||||
|
lpStringPtrW += wcslen(lpStringPtrW) + 1;
|
||||||
|
|
||||||
/* Copy the display name */
|
/* Copy the display name */
|
||||||
WideCharToMultiByte(CP_ACP,
|
WideCharToMultiByte(CP_ACP,
|
||||||
0,
|
0,
|
||||||
CurrentService->lpDisplayName,
|
lpStringPtrW,
|
||||||
-1,
|
-1,
|
||||||
lpStringPtr,
|
lpStringPtrA,
|
||||||
wcslen(CurrentService->lpDisplayName),
|
wcslen(lpStringPtrW),
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
lpStatusPtr->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
|
|
||||||
lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
|
lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
|
||||||
|
lpStringPtrA += wcslen(lpStringPtrW) + 1;
|
||||||
|
lpStringPtrW += wcslen(lpStringPtrW) + 1;
|
||||||
|
|
||||||
/* Copy the status information */
|
/* Copy the status information */
|
||||||
memcpy(&lpStatusPtr->ServiceStatusProcess,
|
memcpy(&lpStatusPtrA->ServiceStatusProcess,
|
||||||
&CurrentService->Status,
|
&lpStatusPtrW->ServiceStatusProcess,
|
||||||
sizeof(SERVICE_STATUS));
|
sizeof(SERVICE_STATUS));
|
||||||
lpStatusPtr->ServiceStatusProcess.dwProcessId = CurrentService->ProcessId; /* FIXME */
|
|
||||||
lpStatusPtr->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
|
|
||||||
|
|
||||||
lpStatusPtr++;
|
lpStatusPtrA->ServiceStatusProcess.dwProcessId = lpStatusPtrW->ServiceStatusProcess.dwProcessId; /* FIXME */
|
||||||
dwRequiredSize += dwSize;
|
lpStatusPtrA->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
|
||||||
}
|
lpStatusPtrA++;
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwError != ERROR_MORE_DATA)
|
|
||||||
{
|
|
||||||
*pcbBytesNeeded = 0;
|
|
||||||
if (lpResumeIndex) *lpResumeIndex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Done:;
|
Done:;
|
||||||
/* Unlock the service list */
|
|
||||||
|
|
||||||
if (pszGroupNameW) HeapFree(GetProcessHeap(), 0, pszGroupNameW);
|
if (pszGroupNameW) HeapFree(GetProcessHeap(), 0, pszGroupNameW);
|
||||||
|
|
||||||
|
if (lpStatusPtrW) HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
|
||||||
|
|
||||||
DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError);
|
DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError);
|
||||||
|
|
||||||
return dwError;
|
return dwError;
|
||||||
|
@ -5073,7 +4765,7 @@ DWORD REnumServicesStatusExW(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwError != ERROR_MORE_DATA)
|
if (dwError == 0)
|
||||||
{
|
{
|
||||||
*pcbBytesNeeded = 0;
|
*pcbBytesNeeded = 0;
|
||||||
if (lpResumeIndex) *lpResumeIndex = 0;
|
if (lpResumeIndex) *lpResumeIndex = 0;
|
||||||
|
|
Loading…
Reference in a new issue