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 + * Copyright 2006-2007 HervĂ© Poussineau * Copyright 2007 Ged Murphy */ @@ -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