mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
-Implement EnumServicesStatusExW.
-Add missing [unique] Attributes to svcctrl.idl. svn path=/trunk/; revision=20335
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user