-Implement EnumServicesStatusExW.

-Add missing [unique] Attributes to svcctrl.idl.

svn path=/trunk/; revision=20335
This commit is contained in:
Eric Kohl
2005-12-26 15:06:46 +00:00
parent 5caea08853
commit 5531d9e68d
3 changed files with 313 additions and 32 deletions
+33 -12
View File
@@ -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 @@ cpp_quote("#endif")
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 @@ cpp_quote("#endif")
[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 @@ cpp_quote("#endif")
/* 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 @@ cpp_quote("#endif")
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 @@ cpp_quote("#endif")
[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 @@ cpp_quote("#endif")
/* 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 @@ cpp_quote("#endif")
// 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 @@ cpp_quote("#endif")
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 */
+57 -17
View File
@@ -708,24 +708,64 @@ EnumServicesStatusExA(SC_HANDLE hSCManager,
/**********************************************************************
* 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 @@ QueryServiceStatusEx(SC_HANDLE hService,
pcbBytesNeeded);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
+223 -3
View File
@@ -1393,9 +1393,9 @@ ScmrEnumServicesStatusW(handle_t BindingHandle,
*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,7 +2138,227 @@ ScmrQueryServiceStatusEx(handle_t BindingHandle,
/* 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 */