https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f5346cbc1b0c08559b77d…
commit f5346cbc1b0c08559b77ded0ef76a27a484c20fa
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Dec 31 15:33:19 2023 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Dec 31 15:33:19 2023 +0100
[ADVAPI32][IDL][SERVICES] Implement I_ScValidatePnPService
This is actually a Vista+ function, but we need it enable umpnpmgr.dll to notify
services of device events. Up until WinXP it was possible to make direct calls to the
service manager by umpnpmgr.dll because umpnpmgr.dll was loaded into the service manager
process. From Vista onwards umpnpmgr.dll is run as a separate service host process. And
since ReactOS always ran umpnpmgr.dll as a separate process, we have to use the Vista RPC
functions to notify services.
---
base/system/services/rpcserver.c | 41 ++++++++++++++++++++++++++----
dll/win32/advapi32/advapi32.spec | 1 +
dll/win32/advapi32/service/scm.c | 52 ++++++++++++++++++++++++++++++++++++++
sdk/include/reactos/idl/svcctl.idl | 6 +++--
4 files changed, 93 insertions(+), 7 deletions(-)
diff --git a/base/system/services/rpcserver.c b/base/system/services/rpcserver.c
index cad1f3b0487..c84b67e6b24 100644
--- a/base/system/services/rpcserver.c
+++ b/base/system/services/rpcserver.c
@@ -4,7 +4,7 @@
* FILE: base/system/services/rpcserver.c
* PURPOSE: RPC server interface for the advapi32 calls
* COPYRIGHT: Copyright 2005-2006 Eric Kohl
- * Copyright 2006-2007 Herv� Poussineau <hpoussin(a)reactos.org>
+ * Copyright 2006-2007 Hervé Poussineau <hpoussin(a)reactos.org>
* Copyright 2007 Ged Murphy <gedmurphy(a)reactos.org>
*/
@@ -6711,11 +6711,42 @@ RSendPnPMessage(
/* Function 53 */
DWORD
WINAPI
-RValidatePnPService(
- handle_t BindingHandle) /* FIXME */
+RI_ScValidatePnPService(
+ _In_ SC_RPC_HANDLE hSCManager,
+ _In_ LPWSTR pszServiceName,
+ _Out_ RPC_SERVICE_STATUS_HANDLE *phServiceStatus)
{
- UNIMPLEMENTED;
- return ERROR_CALL_NOT_IMPLEMENTED;
+ PMANAGER_HANDLE hManager;
+ PSERVICE pService;
+
+ DPRINT("RI_ScValidatePnPService(%p %S %p)\n", hSCManager, pszServiceName,
phServiceStatus);
+
+ /* Validate handle */
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
+ {
+ DPRINT1("Invalid handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: should check whether client is local */
+
+ /* Check access rights */
+ if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
+ SC_MANAGER_CONNECT))
+ {
+ DPRINT1("No SC_MANAGER_CONNECT access!\n");
+ return ERROR_ACCESS_DENIED;
+ }
+
+ pService = ScmGetServiceEntryByName(pszServiceName);
+ DPRINT("pService: %p\n", pService);
+ if (pService == NULL)
+ return ERROR_SERVICE_DOES_NOT_EXIST;
+
+ *phServiceStatus = (RPC_SERVICE_STATUS_HANDLE)pService;
+
+ return ERROR_SUCCESS;
}
diff --git a/dll/win32/advapi32/advapi32.spec b/dll/win32/advapi32/advapi32.spec
index 3a02c1362ab..e158d6a5c48 100644
--- a/dll/win32/advapi32/advapi32.spec
+++ b/dll/win32/advapi32/advapi32.spec
@@ -306,6 +306,7 @@
@ stub I_ScSendTSMessage
@ stdcall I_ScSetServiceBitsA(ptr long long long str)
@ stdcall I_ScSetServiceBitsW(ptr long long long wstr)
+@ stdcall I_ScValidatePnpService(wstr wstr ptr)
@ stub IdentifyCodeAuthzLevelW
@ stdcall ImpersonateAnonymousToken(ptr)
@ stdcall ImpersonateLoggedOnUser(long)
diff --git a/dll/win32/advapi32/service/scm.c b/dll/win32/advapi32/service/scm.c
index 621e5753247..aee23c5750d 100644
--- a/dll/win32/advapi32/service/scm.c
+++ b/dll/win32/advapi32/service/scm.c
@@ -1897,6 +1897,58 @@ I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager,
}
+/**********************************************************************
+ * I_ScValidatePnpService
+ *
+ * Undocumented
+ *
+ * @implemented
+ */
+DWORD
+WINAPI
+I_ScValidatePnpService(
+ _In_ LPCWSTR pszMachineName,
+ _In_ LPCWSTR pszServiceName,
+ _Out_ SERVICE_STATUS_HANDLE *phServiceStatus)
+{
+ SC_RPC_HANDLE hSCManager = NULL;
+ SERVICE_STATUS_HANDLE hServiceStatus = NULL;
+ DWORD dwError;
+
+ TRACE("I_ScValidatePnpService(%S %S %p)\n",
+ pszMachineName, pszServiceName, phServiceStatus);
+
+ hSCManager = OpenSCManagerW(pszMachineName,
+ SERVICES_ACTIVE_DATABASEW,
+ SC_MANAGER_CONNECT);
+ if (hSCManager == NULL)
+ {
+ dwError = GetLastError();
+ goto done;
+ }
+
+ RpcTryExcept
+ {
+ dwError = RI_ScValidatePnPService(hSCManager,
+ (LPWSTR)pszServiceName,
+ (RPC_SERVICE_STATUS_HANDLE
*)&hServiceStatus);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+ }
+ RpcEndExcept
+
+ *phServiceStatus = hServiceStatus;
+
+done:
+ if (hSCManager != NULL)
+ CloseServiceHandle(hSCManager);
+
+ return dwError;
+}
+
+
/**********************************************************************
* LockServiceDatabase
*
diff --git a/sdk/include/reactos/idl/svcctl.idl b/sdk/include/reactos/idl/svcctl.idl
index fccb3712896..c55eddf2aea 100644
--- a/sdk/include/reactos/idl/svcctl.idl
+++ b/sdk/include/reactos/idl/svcctl.idl
@@ -882,8 +882,10 @@ interface svcctl
/* Function 53 */
DWORD
__stdcall
- RValidatePnPService(
- [in] handle_t BindingHandle); /* FIXME */
+ RI_ScValidatePnPService(
+ [in] SC_RPC_HANDLE hService,
+ [in, string] LPWSTR pszServiceName,
+ [out] RPC_SERVICE_STATUS_HANDLE *phServiceStatus);
/* Function 54 */
DWORD