[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.
This commit is contained in:
Eric Kohl 2023-12-31 15:33:19 +01:00
parent 10bb50b456
commit f5346cbc1b
4 changed files with 93 additions and 7 deletions

View file

@ -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@reactos.org>
* Copyright 2006-2007 Hervé Poussineau <hpoussin@reactos.org>
* Copyright 2007 Ged Murphy <gedmurphy@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;
}

View file

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

View file

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

View file

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