- 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:
Michael Martin 2008-10-14 17:55:44 +00:00
parent d9a416da9f
commit da1d359b70

View file

@ -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;