ReactOS 0.4.15-dev-8245-gd24675b
rpcserver.c File Reference
#include "services.h"
#include <winnls.h>
#include <strsafe.h>
#include <pseh/pseh2.h>
#include <debug.h>
Include dependency graph for rpcserver.c:

Go to the source code of this file.

Classes

struct  _SCMGR_HANDLE
 
struct  _MANAGER_HANDLE
 
struct  _SERVICE_HANDLE
 

Macros

#define NDEBUG
 
#define MANAGER_TAG   0x72674D68 /* 'hMgr' */
 
#define SERVICE_TAG   0x63765368 /* 'hSvc' */
 
#define INVALID_TAG   0xAABBCCDD
 
#define SC_MANAGER_READ
 
#define SC_MANAGER_WRITE
 
#define SC_MANAGER_EXECUTE
 
#define SERVICE_READ
 
#define SERVICE_WRITE
 
#define SERVICE_EXECUTE
 
#define TAG_ARRAY_SIZE   32
 

Typedefs

typedef struct _SCMGR_HANDLE SCMGR_HANDLE
 
typedef struct _MANAGER_HANDLE MANAGER_HANDLE
 
typedef struct _MANAGER_HANDLEPMANAGER_HANDLE
 
typedef struct _SERVICE_HANDLE SERVICE_HANDLE
 
typedef struct _SERVICE_HANDLEPSERVICE_HANDLE
 

Functions

VOID ScmStartRpcServer (VOID)
 
static DWORD ScmCreateManagerHandle (LPWSTR lpDatabaseName, SC_HANDLE *Handle)
 
static DWORD ScmCreateServiceHandle (PSERVICE lpServiceEntry, SC_HANDLE *Handle)
 
static PMANAGER_HANDLE ScmGetServiceManagerFromHandle (SC_RPC_HANDLE Handle)
 
static PSERVICE_HANDLE ScmGetServiceFromHandle (SC_RPC_HANDLE Handle)
 
static DWORD ScmCheckAccess (SC_HANDLE Handle, DWORD dwDesiredAccess)
 
DWORD ScmAssignNewTag (PSERVICE lpService)
 
DWORD ScmConvertToBootPathName (wchar_t *CanonName, wchar_t **RelativeName)
 
DWORD ScmCanonDriverImagePath (DWORD dwStartType, const wchar_t *lpServiceName, wchar_t **lpCanonName)
 
static DWORD Int_EnumDependentServicesW (HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
 
DWORD WINAPI RCloseServiceHandle (LPSC_RPC_HANDLE hSCObject)
 
DWORD WINAPI RControlService (SC_RPC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
 
DWORD WINAPI RDeleteService (SC_RPC_HANDLE hService)
 
DWORD WINAPI RLockServiceDatabase (SC_RPC_HANDLE hSCManager, LPSC_RPC_LOCK lpLock)
 
DWORD WINAPI RQueryServiceObjectSecurity (SC_RPC_HANDLE hService, SECURITY_INFORMATION dwSecurityInformation, LPBYTE lpSecurityDescriptor, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded)
 
DWORD WINAPI RSetServiceObjectSecurity (SC_RPC_HANDLE hService, DWORD dwSecurityInformation, LPBYTE lpSecurityDescriptor, DWORD dwSecurityDescriptorSize)
 
DWORD WINAPI RQueryServiceStatus (SC_RPC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
 
static BOOL ScmIsValidServiceState (DWORD dwCurrentState)
 
DWORD WINAPI RSetServiceStatus (RPC_SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
 
DWORD WINAPI RUnlockServiceDatabase (LPSC_RPC_LOCK Lock)
 
DWORD WINAPI RNotifyBootConfigStatus (SVCCTL_HANDLEW lpMachineName, DWORD BootAcceptable)
 
DWORD WINAPI RI_ScSetServiceBitsW (RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, wchar_t *lpString)
 
DWORD WINAPI RChangeServiceConfigW (SC_RPC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPWSTR lpBinaryPathName, LPWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPWSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPWSTR lpDisplayName)
 
DWORD WINAPI RCreateServiceW (SC_RPC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPCWSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle)
 
DWORD WINAPI REnumDependentServicesW (SC_RPC_HANDLE hService, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned)
 
DWORD WINAPI REnumServicesStatusW (SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD dwBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeHandle)
 
DWORD WINAPI ROpenSCManagerW (LPWSTR lpMachineName, LPWSTR lpDatabaseName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpScHandle)
 
DWORD WINAPI ROpenServiceW (SC_RPC_HANDLE hSCManager, LPWSTR lpServiceName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpServiceHandle)
 
DWORD WINAPI RQueryServiceConfigW (SC_RPC_HANDLE hService, LPBYTE lpBuf, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
 
DWORD WINAPI RQueryServiceLockStatusW (SC_RPC_HANDLE hSCManager, LPBYTE lpBuf, DWORD cbBufSize, LPBOUNDED_DWORD_4K pcbBytesNeeded)
 
DWORD WINAPI RStartServiceW (SC_RPC_HANDLE hService, DWORD argc, LPSTRING_PTRSW argv)
 
DWORD WINAPI RGetServiceDisplayNameW (SC_RPC_HANDLE hSCManager, LPCWSTR lpServiceName, LPWSTR lpDisplayName, DWORD *lpcchBuffer)
 
DWORD WINAPI RGetServiceKeyNameW (SC_RPC_HANDLE hSCManager, LPCWSTR lpDisplayName, LPWSTR lpServiceName, DWORD *lpcchBuffer)
 
DWORD WINAPI RI_ScSetServiceBitsA (RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, char *lpString)
 
DWORD WINAPI RChangeServiceConfigA (SC_RPC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPSTR lpBinaryPathName, LPSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSTR lpDisplayName)
 
DWORD WINAPI RCreateServiceA (SC_RPC_HANDLE hSCManager, LPSTR lpServiceName, LPSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPSTR lpBinaryPathName, LPSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle)
 
DWORD WINAPI REnumDependentServicesA (SC_RPC_HANDLE hService, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned)
 
DWORD WINAPI REnumServicesStatusA (SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD dwBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeHandle)
 
DWORD WINAPI ROpenSCManagerA (LPSTR lpMachineName, LPSTR lpDatabaseName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpScHandle)
 
DWORD WINAPI ROpenServiceA (SC_RPC_HANDLE hSCManager, LPSTR lpServiceName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpServiceHandle)
 
DWORD WINAPI RQueryServiceConfigA (SC_RPC_HANDLE hService, LPBYTE lpBuf, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
 
DWORD WINAPI RQueryServiceLockStatusA (SC_RPC_HANDLE hSCManager, LPBYTE lpBuf, DWORD cbBufSize, LPBOUNDED_DWORD_4K pcbBytesNeeded)
 
DWORD WINAPI RStartServiceA (SC_RPC_HANDLE hService, DWORD argc, LPSTRING_PTRSA argv)
 
DWORD WINAPI RGetServiceDisplayNameA (SC_RPC_HANDLE hSCManager, LPCSTR lpServiceName, LPSTR lpDisplayName, LPBOUNDED_DWORD_4K lpcchBuffer)
 
DWORD WINAPI RGetServiceKeyNameA (SC_RPC_HANDLE hSCManager, LPCSTR lpDisplayName, LPSTR lpServiceName, LPBOUNDED_DWORD_4K lpcchBuffer)
 
DWORD WINAPI RI_ScGetCurrentGroupStateW (SC_RPC_HANDLE hSCManager, LPWSTR lpLoadOrderGroup, LPDWORD lpState)
 
DWORD WINAPI REnumServiceGroupW (SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCWSTR pszGroupName)
 
DWORD WINAPI RChangeServiceConfig2A (SC_RPC_HANDLE hService, SC_RPC_CONFIG_INFOA Info)
 
static DWORD ScmSetFailureActions (HKEY hServiceKey, LPSERVICE_FAILURE_ACTIONSW lpFailureActions)
 
DWORD WINAPI RChangeServiceConfig2W (SC_RPC_HANDLE hService, SC_RPC_CONFIG_INFOW Info)
 
DWORD WINAPI RQueryServiceConfig2A (SC_RPC_HANDLE hService, DWORD dwInfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
 
DWORD WINAPI RQueryServiceConfig2W (SC_RPC_HANDLE hService, DWORD dwInfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
 
DWORD WINAPI RQueryServiceStatusEx (SC_RPC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
 
DWORD WINAPI REnumServicesStatusExA (SC_RPC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCSTR pszGroupName)
 
DWORD WINAPI REnumServicesStatusExW (SC_RPC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCWSTR pszGroupName)
 
DWORD WINAPI RSendTSMessage (handle_t BindingHandle)
 
DWORD WINAPI RCreateServiceWOW64A (handle_t BindingHandle, LPSTR lpServiceName, LPSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPSTR lpBinaryPathName, LPSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle)
 
DWORD WINAPI RCreateServiceWOW64W (handle_t BindingHandle, LPWSTR lpServiceName, LPWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPWSTR lpBinaryPathName, LPWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPWSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle)
 
DWORD WINAPI RI_ScQueryServiceTagInfo (SC_RPC_HANDLE hSCManager, TAG_INFO_LEVEL dwInfoLevel, PTAG_INFO_NAME_FROM_TAG_IN_PARAMS *lpInParams, PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS *lpOutParams)
 
DWORD WINAPI RNotifyServiceStatusChange (SC_RPC_HANDLE hService, SC_RPC_NOTIFY_PARAMS NotifyParams, GUID *pClientProcessGuid, GUID *pSCMProcessGuid, PBOOL pfCreateRemoteQueue, LPSC_NOTIFY_RPC_HANDLE phNotify)
 
DWORD WINAPI RGetNotifyResults (SC_NOTIFY_RPC_HANDLE hNotify, PSC_RPC_NOTIFY_PARAMS_LIST *ppNotifyParams)
 
DWORD WINAPI RCloseNotifyHandle (LPSC_NOTIFY_RPC_HANDLE phNotify, PBOOL pfApcFired)
 
DWORD WINAPI RControlServiceExA (SC_RPC_HANDLE hService, DWORD dwControl, DWORD dwInfoLevel)
 
DWORD WINAPI RControlServiceExW (SC_RPC_HANDLE hService, DWORD dwControl, DWORD dwInfoLevel)
 
DWORD WINAPI RSendPnPMessage (handle_t BindingHandle)
 
DWORD WINAPI RI_ScValidatePnPService (_In_ SC_RPC_HANDLE hSCManager, _In_ LPWSTR pszServiceName, _Out_ RPC_SERVICE_STATUS_HANDLE *phServiceStatus)
 
DWORD WINAPI ROpenServiceStatusHandle (handle_t BindingHandle)
 
DWORD WINAPI RFunction55 (handle_t BindingHandle)
 
void __RPC_FAR *__RPC_USER midl_user_allocate (SIZE_T len)
 
void __RPC_USER midl_user_free (void __RPC_FAR *ptr)
 
void __RPC_USER SC_RPC_HANDLE_rundown (SC_RPC_HANDLE hSCObject)
 
void __RPC_USER SC_RPC_LOCK_rundown (SC_RPC_LOCK Lock)
 
void __RPC_USER SC_NOTIFY_RPC_HANDLE_rundown (SC_NOTIFY_RPC_HANDLE hNotify)
 

Variables

static GENERIC_MAPPING ScmManagerMapping
 
static GENERIC_MAPPING ScmServiceMapping
 
DWORD g_dwServiceBits = 0
 

Macro Definition Documentation

◆ INVALID_TAG

#define INVALID_TAG   0xAABBCCDD

Definition at line 27 of file rpcserver.c.

◆ MANAGER_TAG

#define MANAGER_TAG   0x72674D68 /* 'hMgr' */

Definition at line 25 of file rpcserver.c.

◆ NDEBUG

#define NDEBUG

Definition at line 20 of file rpcserver.c.

◆ SC_MANAGER_EXECUTE

#define SC_MANAGER_EXECUTE
Value:
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67
#define SC_MANAGER_LOCK
Definition: winsvc.h:17
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14

Definition at line 60 of file rpcserver.c.

◆ SC_MANAGER_READ

#define SC_MANAGER_READ
Value:
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define SC_MANAGER_QUERY_LOCK_STATUS
Definition: winsvc.h:18

Definition at line 50 of file rpcserver.c.

◆ SC_MANAGER_WRITE

#define SC_MANAGER_WRITE
Value:
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define SC_MANAGER_MODIFY_BOOT_CONFIG
Definition: winsvc.h:19

Definition at line 55 of file rpcserver.c.

◆ SERVICE_EXECUTE

#define SERVICE_EXECUTE
Value:
#define SERVICE_START
Definition: winsvc.h:57
#define SERVICE_USER_DEFINED_CONTROL
Definition: winsvc.h:61
#define SERVICE_PAUSE_CONTINUE
Definition: winsvc.h:59
#define SERVICE_STOP
Definition: winsvc.h:58

Definition at line 79 of file rpcserver.c.

◆ SERVICE_READ

#define SERVICE_READ
Value:
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
#define SERVICE_INTERROGATE
Definition: winsvc.h:60
#define SERVICE_ENUMERATE_DEPENDENTS
Definition: winsvc.h:56
#define SERVICE_QUERY_CONFIG
Definition: winsvc.h:53

Definition at line 68 of file rpcserver.c.

◆ SERVICE_TAG

#define SERVICE_TAG   0x63765368 /* 'hSvc' */

Definition at line 26 of file rpcserver.c.

◆ SERVICE_WRITE

#define SERVICE_WRITE
Value:
#define SERVICE_CHANGE_CONFIG
Definition: winsvc.h:54

Definition at line 75 of file rpcserver.c.

◆ TAG_ARRAY_SIZE

#define TAG_ARRAY_SIZE   32

Definition at line 86 of file rpcserver.c.

Typedef Documentation

◆ MANAGER_HANDLE

◆ PMANAGER_HANDLE

◆ PSERVICE_HANDLE

◆ SCMGR_HANDLE

◆ SERVICE_HANDLE

Function Documentation

◆ Int_EnumDependentServicesW()

static DWORD Int_EnumDependentServicesW ( HKEY  hServicesKey,
PSERVICE  lpService,
DWORD  dwServiceState,
PSERVICE lpServices,
LPDWORD  pcbBytesNeeded,
LPDWORD  lpServicesReturned 
)
static

Definition at line 783 of file rpcserver.c.

789{
790 DWORD dwError = ERROR_SUCCESS;
791 WCHAR szNameBuf[MAX_PATH];
792 WCHAR szValueBuf[MAX_PATH];
793 WCHAR *lpszNameBuf = szNameBuf;
794 WCHAR *lpszValueBuf = szValueBuf;
796 DWORD dwNumSubKeys;
797 DWORD dwIteration;
798 PSERVICE lpCurrentService;
799 HKEY hServiceEnumKey;
800 DWORD dwCurrentServiceState = SERVICE_ACTIVE;
801 DWORD dwDependServiceStrPtr = 0;
802 DWORD dwRequiredSize = 0;
803
804 /* Get the number of service keys */
806 NULL,
807 NULL,
808 NULL,
809 &dwNumSubKeys,
810 NULL,
811 NULL,
812 NULL,
813 NULL,
814 NULL,
815 NULL,
816 NULL);
817 if (dwError != ERROR_SUCCESS)
818 {
819 DPRINT("ERROR! Unable to get number of services keys\n");
820 return dwError;
821 }
822
823 /* Iterate the service keys to see if another service depends on the this service */
824 for (dwIteration = 0; dwIteration < dwNumSubKeys; dwIteration++)
825 {
827 dwError = RegEnumKeyExW(hServicesKey,
828 dwIteration,
829 lpszNameBuf,
830 &dwSize,
831 NULL,
832 NULL,
833 NULL,
834 NULL);
835 if (dwError != ERROR_SUCCESS)
836 return dwError;
837
838 /* Open the Service key */
839 dwError = RegOpenKeyExW(hServicesKey,
840 lpszNameBuf,
841 0,
842 KEY_READ,
843 &hServiceEnumKey);
844 if (dwError != ERROR_SUCCESS)
845 return dwError;
846
847 dwSize = MAX_PATH * sizeof(WCHAR);
848
849 /* Check for the DependOnService Value */
850 dwError = RegQueryValueExW(hServiceEnumKey,
851 L"DependOnService",
852 NULL,
853 NULL,
854 (LPBYTE)lpszValueBuf,
855 &dwSize);
856
857 /* FIXME: Handle load order. */
858
859 /* If the service found has a DependOnService value */
860 if (dwError == ERROR_SUCCESS)
861 {
862 dwDependServiceStrPtr = 0;
863
864 /* Can be more than one Dependencies in the DependOnService string */
865 while (wcslen(lpszValueBuf + dwDependServiceStrPtr) > 0)
866 {
867 if (_wcsicmp(lpszValueBuf + dwDependServiceStrPtr, lpService->lpServiceName) == 0)
868 {
869 /* Get the current enumed service pointer */
870 lpCurrentService = ScmGetServiceEntryByName(lpszNameBuf);
871
872 /* Check for valid Service */
873 if (!lpCurrentService)
874 {
875 /* This should never happen! */
876 DPRINT("This should not happen at this point, report to Developer\n");
877 return ERROR_NOT_FOUND;
878 }
879
880 /* Determine state the service is in */
881 if (lpCurrentService->Status.dwCurrentState == SERVICE_STOPPED)
882 dwCurrentServiceState = SERVICE_INACTIVE;
883
884 /* If the ServiceState matches that requested or searching for SERVICE_STATE_ALL */
885 if ((dwCurrentServiceState == dwServiceState) ||
886 (dwServiceState == SERVICE_STATE_ALL))
887 {
888 /* Calculate the required size */
889 dwRequiredSize += sizeof(SERVICE_STATUS);
890 dwRequiredSize += (DWORD)((wcslen(lpCurrentService->lpServiceName) + 1) * sizeof(WCHAR));
891 dwRequiredSize += (DWORD)((wcslen(lpCurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
892
893 /* Add the size for service name and display name pointers */
894 dwRequiredSize += (2 * sizeof(PVOID));
895
896 /* increase the BytesNeeded size */
897 *pcbBytesNeeded = *pcbBytesNeeded + dwRequiredSize;
898
899 /* Don't fill callers buffer yet, as MSDN read that the last service with dependency
900 comes first */
901
902 /* Recursive call to check for its dependencies */
904 lpCurrentService,
905 dwServiceState,
906 lpServices,
908 lpServicesReturned);
909
910 /* If the lpServices is valid set the service pointer */
911 if (lpServices)
912 lpServices[*lpServicesReturned] = lpCurrentService;
913
914 *lpServicesReturned = *lpServicesReturned + 1;
915 }
916 }
917
918 dwDependServiceStrPtr += (DWORD)(wcslen(lpszValueBuf + dwDependServiceStrPtr) + 1);
919 }
920 }
921 else if (*pcbBytesNeeded)
922 {
923 dwError = ERROR_SUCCESS;
924 }
925
926 RegCloseKey(hServiceEnumKey);
927 }
928
929 return dwError;
930}
static HANDLE hServicesKey
Definition: devinst.c:21
PSERVICE ScmGetServiceEntryByName(LPCWSTR lpServiceName)
Definition: database.c:657
static DWORD Int_EnumDependentServicesW(HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: rpcserver.c:783
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define KEY_READ
Definition: nt_native.h:1023
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define DPRINT
Definition: sndvol32.h:73
DWORD dwCurrentState
Definition: winsvc.h:100
LPWSTR lpDisplayName
Definition: services.h:63
SERVICE_STATUS Status
Definition: services.h:70
LPWSTR lpServiceName
Definition: services.h:62
unsigned char * LPBYTE
Definition: typedefs.h:53
void * PVOID
Definition: typedefs.h:50
#define ERROR_NOT_FOUND
Definition: winerror.h:690
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define SERVICE_STATE_ALL
Definition: winsvc.h:52
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:425
#define SERVICE_ACTIVE
Definition: winsvc.h:50
struct _SERVICE_STATUS SERVICE_STATUS
#define SERVICE_INACTIVE
Definition: winsvc.h:51
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by Int_EnumDependentServicesW(), RCloseServiceHandle(), RControlService(), REnumDependentServicesA(), and REnumDependentServicesW().

◆ midl_user_allocate()

void __RPC_FAR *__RPC_USER midl_user_allocate ( SIZE_T  len)

Definition at line 6775 of file rpcserver.c.

6776{
6778}
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
GLenum GLsizei len
Definition: glext.h:6722

◆ midl_user_free()

void __RPC_USER midl_user_free ( void __RPC_FAR ptr)

Definition at line 6781 of file rpcserver.c.

6782{
6784}
#define HeapFree(x, y, z)
Definition: compat.h:735
static PVOID ptr
Definition: dispmode.c:27

◆ RChangeServiceConfig2A()

DWORD WINAPI RChangeServiceConfig2A ( SC_RPC_HANDLE  hService,
SC_RPC_CONFIG_INFOA  Info 
)

Definition at line 5019 of file rpcserver.c.

5022{
5023 SC_RPC_CONFIG_INFOW InfoW = { 0 };
5024 DWORD dwRet, dwLength;
5025 PVOID ptr = NULL;
5026
5027 DPRINT("RChangeServiceConfig2A() called\n");
5028 DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
5029
5030 if ((Info.dwInfoLevel < SERVICE_CONFIG_DESCRIPTION) ||
5031 (Info.dwInfoLevel > SERVICE_CONFIG_FAILURE_ACTIONS))
5032 {
5033 return ERROR_INVALID_LEVEL;
5034 }
5035
5036 InfoW.dwInfoLevel = Info.dwInfoLevel;
5037
5039 {
5040 LPSERVICE_DESCRIPTIONW lpServiceDescriptionW;
5041 LPSERVICE_DESCRIPTIONA lpServiceDescriptionA;
5042
5043 lpServiceDescriptionA = Info.psd;
5044
5045 if (lpServiceDescriptionA &&
5046 lpServiceDescriptionA->lpDescription)
5047 {
5048 dwLength = (DWORD)((strlen(lpServiceDescriptionA->lpDescription) + 1) * sizeof(WCHAR));
5049
5050 lpServiceDescriptionW = HeapAlloc(GetProcessHeap(),
5052 dwLength + sizeof(SERVICE_DESCRIPTIONW));
5053 if (!lpServiceDescriptionW)
5054 {
5056 }
5057
5058 lpServiceDescriptionW->lpDescription = (LPWSTR)(lpServiceDescriptionW + 1);
5059
5061 0,
5062 lpServiceDescriptionA->lpDescription,
5063 -1,
5064 lpServiceDescriptionW->lpDescription,
5065 dwLength);
5066
5067 ptr = lpServiceDescriptionW;
5068 InfoW.psd = lpServiceDescriptionW;
5069 }
5070 }
5071 else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5072 {
5073 LPSERVICE_FAILURE_ACTIONSW lpServiceFailureActionsW;
5074 LPSERVICE_FAILURE_ACTIONSA lpServiceFailureActionsA;
5075 DWORD dwRebootLen = 0;
5076 DWORD dwCommandLen = 0;
5077 DWORD dwActionArrayLen = 0;
5078 LPWSTR lpStr = NULL;
5079
5080 lpServiceFailureActionsA = Info.psfa;
5081
5082 if (lpServiceFailureActionsA)
5083 {
5084 /*
5085 * The following code is inspired by the
5086 * SERVICE_CONFIG_FAILURE_ACTIONS case of
5087 * the RQueryServiceConfig2W function.
5088 */
5089
5090 /* Retrieve the needed length for the two data strings */
5091 if (lpServiceFailureActionsA->lpRebootMsg)
5092 {
5093 dwRebootLen = (DWORD)((strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR));
5094 }
5095 if (lpServiceFailureActionsA->lpCommand)
5096 {
5097 dwCommandLen = (DWORD)((strlen(lpServiceFailureActionsA->lpCommand) + 1) * sizeof(WCHAR));
5098 }
5099
5100 /*
5101 * Retrieve the size of the lpsaActions array if needed.
5102 * We will copy the lpsaActions array only if there is at
5103 * least one action AND that the original array is valid.
5104 */
5105 if (lpServiceFailureActionsA->cActions > 0 && lpServiceFailureActionsA->lpsaActions)
5106 {
5107 dwActionArrayLen = lpServiceFailureActionsA->cActions * sizeof(SC_ACTION);
5108 }
5109
5110 /* Compute the total length for the UNICODE structure, including data */
5112 dwActionArrayLen + dwRebootLen + dwCommandLen;
5113
5114 /* Allocate the structure */
5115 lpServiceFailureActionsW = HeapAlloc(GetProcessHeap(),
5117 dwLength);
5118 if (!lpServiceFailureActionsW)
5119 {
5121 }
5122
5123 /* Copy the members */
5124 lpServiceFailureActionsW->dwResetPeriod = lpServiceFailureActionsA->dwResetPeriod;
5125 lpServiceFailureActionsW->cActions = lpServiceFailureActionsA->cActions;
5126
5127 /* Copy the lpsaActions array if needed */
5128 if (dwActionArrayLen > 0)
5129 {
5130 /* The storage zone is just after the end of the SERVICE_FAILURE_ACTIONSW structure */
5131 lpServiceFailureActionsW->lpsaActions = (LPSC_ACTION)((ULONG_PTR)(lpServiceFailureActionsW + 1));
5132
5133 /* dwActionArrayLen == lpServiceFailureActionsW->cActions * sizeof(SC_ACTION) */
5134 RtlCopyMemory(lpServiceFailureActionsW->lpsaActions,
5135 lpServiceFailureActionsA->lpsaActions,
5136 dwActionArrayLen);
5137 }
5138 else
5139 {
5140 /* No lpsaActions array */
5141 lpServiceFailureActionsW->lpsaActions = NULL;
5142 }
5143 /* The data strings are stored just after the lpsaActions array */
5144 lpStr = (LPWSTR)((ULONG_PTR)(lpServiceFailureActionsW + 1) + dwActionArrayLen);
5145
5146 /*
5147 * Convert the data strings to UNICODE
5148 */
5149
5150 lpServiceFailureActionsW->lpRebootMsg = NULL;
5151 lpServiceFailureActionsW->lpCommand = NULL;
5152
5153 if (dwRebootLen)
5154 {
5155 /* lpRebootMsg points just after the lpsaActions array */
5156 lpServiceFailureActionsW->lpRebootMsg = lpStr;
5157
5159 0,
5160 lpServiceFailureActionsA->lpRebootMsg,
5161 -1,
5162 lpServiceFailureActionsW->lpRebootMsg,
5163 dwRebootLen);
5164
5165 lpStr += dwRebootLen / sizeof(WCHAR);
5166 }
5167
5168 if (dwCommandLen)
5169 {
5170 /* lpRebootMsg points just after the lpRebootMsg data string */
5171 lpServiceFailureActionsW->lpCommand = lpStr;
5172
5174 0,
5175 lpServiceFailureActionsA->lpCommand,
5176 -1,
5177 lpServiceFailureActionsW->lpCommand,
5178 dwCommandLen);
5179 }
5180
5181 /* Set the pointers */
5182 ptr = lpServiceFailureActionsW;
5183 InfoW.psfa = lpServiceFailureActionsW;
5184 }
5185 }
5186
5187 dwRet = RChangeServiceConfig2W(hService, InfoW);
5188
5190
5191 return dwRet;
5192}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DWORD WINAPI RChangeServiceConfig2W(SC_RPC_HANDLE hService, SC_RPC_CONFIG_INFOW Info)
Definition: rpcserver.c:5420
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
static DWORD DWORD * dwLength
Definition: fusion.c:86
LPSERVICE_DESCRIPTIONW psd
Definition: svcctl.idl:200
LPSERVICE_FAILURE_ACTIONSW psfa
Definition: svcctl.idl:201
LPWSTR lpDescription
Definition: winsvc.h:196
SC_ACTION * lpsaActions
Definition: winsvc.h:213
SC_ACTION * lpsaActions
Definition: winsvc.h:220
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
struct _SERVICE_FAILURE_ACTIONSW SERVICE_FAILURE_ACTIONSW
#define SERVICE_CONFIG_DESCRIPTION
Definition: winsvc.h:65
struct _SC_ACTION SC_ACTION
struct _SC_ACTION * LPSC_ACTION
#define SERVICE_CONFIG_FAILURE_ACTIONS
Definition: winsvc.h:66
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by ChangeServiceConfig2A().

◆ RChangeServiceConfig2W()

DWORD WINAPI RChangeServiceConfig2W ( SC_RPC_HANDLE  hService,
SC_RPC_CONFIG_INFOW  Info 
)

Definition at line 5420 of file rpcserver.c.

5423{
5424 DWORD dwError = ERROR_SUCCESS;
5425 PSERVICE_HANDLE hSvc;
5426 PSERVICE lpService = NULL;
5427 HKEY hServiceKey = NULL;
5429
5430 DPRINT("RChangeServiceConfig2W() called\n");
5431 DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
5432
5433 if (ScmShutdown)
5435
5436 if ((Info.dwInfoLevel < SERVICE_CONFIG_DESCRIPTION) ||
5437 (Info.dwInfoLevel > SERVICE_CONFIG_FAILURE_ACTIONS))
5438 {
5439 return ERROR_INVALID_LEVEL;
5440 }
5441
5442 hSvc = ScmGetServiceFromHandle(hService);
5443 if (hSvc == NULL)
5444 {
5445 DPRINT("Invalid service handle\n");
5446 return ERROR_INVALID_HANDLE;
5447 }
5448
5449 if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5451
5452 /* Check the access rights */
5455 {
5456 DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
5457 return ERROR_ACCESS_DENIED;
5458 }
5459
5460 if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5461 {
5462 /* FIXME: Check if the caller has the SE_SHUTDOWN_NAME privilege */
5463
5464 }
5465
5466 lpService = hSvc->ServiceEntry;
5467 if (lpService == NULL)
5468 {
5469 DPRINT("lpService == NULL\n");
5470 return ERROR_INVALID_HANDLE;
5471 }
5472
5473 /* Failure actions can only be set for Win32 services, not for drivers */
5474 if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5475 {
5476 if (lpService->Status.dwServiceType & SERVICE_DRIVER)
5478 }
5479
5480 /* Lock the service database exclusively */
5482
5483 if (lpService->bDeleted)
5484 {
5485 DPRINT("Service has already been marked for delete\n");
5487 goto done;
5488 }
5489
5490 /* Open the service key */
5491 dwError = ScmOpenServiceKey(lpService->szServiceName,
5493 &hServiceKey);
5494 if (dwError != ERROR_SUCCESS)
5495 goto done;
5496
5497 if (Info.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
5498 {
5499 LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd;
5500
5501 /* Modify the service description, if specified */
5502 if (lpServiceDescription != NULL &&
5503 lpServiceDescription->lpDescription != NULL)
5504 {
5505 /* If the description is "" then we delete it */
5506 if (*lpServiceDescription->lpDescription == 0)
5507 {
5508 DPRINT("Delete service description\n");
5509 dwError = RegDeleteValueW(hServiceKey, L"Description");
5510
5511 if (dwError == ERROR_FILE_NOT_FOUND)
5512 dwError = ERROR_SUCCESS;
5513 }
5514 else
5515 {
5516 DPRINT("Setting service description value %S\n", lpServiceDescription->lpDescription);
5517 dwError = RegSetValueExW(hServiceKey,
5518 L"Description",
5519 0,
5520 REG_SZ,
5521 (LPBYTE)lpServiceDescription->lpDescription,
5522 (DWORD)((wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR)));
5523 }
5524 }
5525 else
5526 {
5527 dwError = ERROR_SUCCESS;
5528 }
5529 }
5530 else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5531 {
5532 dwError = ScmSetFailureActions(hServiceKey,
5534 }
5535
5536done:
5537 if (hServiceKey != NULL)
5538 RegCloseKey(hServiceKey);
5539
5540 /* Unlock the service database */
5542
5543 DPRINT("RChangeServiceConfig2W() done (Error %lu)\n", dwError);
5544
5545 return dwError;
5546}
DWORD ScmOpenServiceKey(LPWSTR lpServiceName, REGSAM samDesired, PHKEY phKey)
Definition: config.c:42
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2434
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2420
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:222
static DWORD ScmSetFailureActions(HKEY hServiceKey, LPSERVICE_FAILURE_ACTIONSW lpFailureActions)
Definition: rpcserver.c:5196
BOOL ScmShutdown
Definition: services.c:29
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define REG_SZ
Definition: layer.c:22
if(dx< 0)
Definition: linetemp.h:194
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define KEY_SET_VALUE
Definition: nt_native.h:1017
DWORD DesiredAccess
Definition: rpcserver.c:32
SCMGR_HANDLE Handle
Definition: rpcserver.c:45
PSERVICE ServiceEntry
Definition: rpcserver.c:46
DWORD dwServiceType
Definition: winsvc.h:99
BOOL bDeleted
Definition: services.h:66
WCHAR szServiceName[1]
Definition: services.h:84
#define ERROR_SERVICE_MARKED_FOR_DELETE
Definition: winerror.h:623
#define ERROR_CANNOT_DETECT_DRIVER_FAILURE
Definition: winerror.h:631
#define ERROR_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:651
struct _SERVICE_DESCRIPTIONW * LPSERVICE_DESCRIPTIONW
#define SERVICE_DRIVER
Definition: cmtypes.h:958
_In_ ULONG RequiredAccess
Definition: iofuncs.h:2223

Referenced by ChangeServiceConfig2W(), and RChangeServiceConfig2A().

◆ RChangeServiceConfigA()

DWORD WINAPI RChangeServiceConfigA ( SC_RPC_HANDLE  hService,
DWORD  dwServiceType,
DWORD  dwStartType,
DWORD  dwErrorControl,
LPSTR  lpBinaryPathName,
LPSTR  lpLoadOrderGroup,
LPDWORD  lpdwTagId,
LPBYTE  lpDependencies,
DWORD  dwDependSize,
LPSTR  lpServiceStartName,
LPBYTE  lpPassword,
DWORD  dwPwSize,
LPSTR  lpDisplayName 
)

Definition at line 3461 of file rpcserver.c.

3475{
3476 DWORD dwError = ERROR_SUCCESS;
3477 LPWSTR lpBinaryPathNameW = NULL;
3478 LPWSTR lpLoadOrderGroupW = NULL;
3479 LPWSTR lpDependenciesW = NULL;
3480 LPWSTR lpServiceStartNameW = NULL;
3481 LPWSTR lpDisplayNameW = NULL;
3482 DWORD dwDependenciesLength = 0;
3483 SIZE_T cchLength;
3484 int len;
3485 LPCSTR lpStr;
3486
3487 if (lpBinaryPathName)
3488 {
3489 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
3490 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3491 if (!lpBinaryPathNameW)
3492 {
3494 goto cleanup;
3495 }
3496 MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
3497 }
3498
3499 if (lpLoadOrderGroup)
3500 {
3501 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
3502 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3503 if (!lpLoadOrderGroupW)
3504 {
3506 goto cleanup;
3507 }
3508 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
3509 }
3510
3511 if (lpDependencies)
3512 {
3513 lpStr = (LPCSTR)lpDependencies;
3514 while (*lpStr)
3515 {
3516 cchLength = strlen(lpStr) + 1;
3517 dwDependenciesLength += (DWORD)cchLength;
3518 lpStr = lpStr + cchLength;
3519 }
3520 dwDependenciesLength++;
3521
3522 lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
3523 if (!lpDependenciesW)
3524 {
3526 goto cleanup;
3527 }
3528 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
3529 }
3530
3531 if (lpServiceStartName)
3532 {
3533 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
3534 lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3535 if (!lpServiceStartNameW)
3536 {
3538 goto cleanup;
3539 }
3540 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
3541 }
3542
3543 if (lpDisplayName)
3544 {
3546 lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3547 if (!lpDisplayNameW)
3548 {
3550 goto cleanup;
3551 }
3552 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
3553 }
3554
3555 dwError = RChangeServiceConfigW(hService,
3556 dwServiceType,
3557 dwStartType,
3558 dwErrorControl,
3559 lpBinaryPathNameW,
3560 lpLoadOrderGroupW,
3561 lpdwTagId,
3562 (LPBYTE)lpDependenciesW,
3563 dwDependenciesLength,
3564 lpServiceStartNameW,
3565 lpPassword,
3566 dwPwSize,
3567 lpDisplayNameW);
3568
3569cleanup:
3570 if (lpBinaryPathNameW != NULL)
3571 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
3572
3573 if (lpLoadOrderGroupW != NULL)
3574 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
3575
3576 if (lpDependenciesW != NULL)
3577 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
3578
3579 if (lpServiceStartNameW != NULL)
3580 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
3581
3582 if (lpDisplayNameW != NULL)
3583 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
3584
3585 return dwError;
3586}
DWORD WINAPI RChangeServiceConfigW(SC_RPC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPWSTR lpBinaryPathName, LPWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPWSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPWSTR lpDisplayName)
Definition: rpcserver.c:1920
#define SetLastError(x)
Definition: compat.h:752
static void cleanup(void)
Definition: main.c:1335
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2790
const char * LPCSTR
Definition: xmlstorage.h:183

Referenced by ChangeServiceConfigA().

◆ RChangeServiceConfigW()

DWORD WINAPI RChangeServiceConfigW ( SC_RPC_HANDLE  hService,
DWORD  dwServiceType,
DWORD  dwStartType,
DWORD  dwErrorControl,
LPWSTR  lpBinaryPathName,
LPWSTR  lpLoadOrderGroup,
LPDWORD  lpdwTagId,
LPBYTE  lpDependencies,
DWORD  dwDependSize,
LPWSTR  lpServiceStartName,
LPBYTE  lpPassword,
DWORD  dwPwSize,
LPWSTR  lpDisplayName 
)

Definition at line 1920 of file rpcserver.c.

1934{
1935 DWORD dwError = ERROR_SUCCESS;
1936 PSERVICE_HANDLE hSvc;
1937 PSERVICE lpService = NULL;
1938 HKEY hServiceKey = NULL;
1939 LPWSTR lpDisplayNameW = NULL;
1940 LPWSTR lpImagePathW = NULL;
1941 LPWSTR lpClearTextPassword = NULL;
1942
1943 DPRINT("RChangeServiceConfigW() called\n");
1944 DPRINT("dwServiceType = 0x%lx\n", dwServiceType);
1945 DPRINT("dwStartType = %lu\n", dwStartType);
1946 DPRINT("dwErrorControl = %lu\n", dwErrorControl);
1947 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
1948 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
1949 DPRINT("lpServiceStartName = %S\n", lpServiceStartName);
1950 DPRINT("lpPassword = %p\n", lpPassword);
1951 DPRINT("dwPwSite = %lu\n", dwPwSize);
1952 DPRINT("lpDisplayName = %S\n", lpDisplayName);
1953
1954 if (ScmShutdown)
1956
1957 hSvc = ScmGetServiceFromHandle(hService);
1958 if (hSvc == NULL)
1959 {
1960 DPRINT1("Invalid service handle\n");
1961 return ERROR_INVALID_HANDLE;
1962 }
1963
1966 {
1967 DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
1968 return ERROR_ACCESS_DENIED;
1969 }
1970
1971 /* Check for invalid service type value */
1972 if ((dwServiceType != SERVICE_NO_CHANGE) &&
1973 (dwServiceType != SERVICE_KERNEL_DRIVER) &&
1974 (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER) &&
1977 {
1979 }
1980
1981 /* Check for invalid start type value */
1982 if ((dwStartType != SERVICE_NO_CHANGE) &&
1983 (dwStartType != SERVICE_BOOT_START) &&
1984 (dwStartType != SERVICE_SYSTEM_START) &&
1985 (dwStartType != SERVICE_AUTO_START) &&
1986 (dwStartType != SERVICE_DEMAND_START) &&
1987 (dwStartType != SERVICE_DISABLED))
1988 {
1990 }
1991
1992 /* Only drivers can be boot start or system start services */
1993 if ((dwStartType == SERVICE_BOOT_START) ||
1994 (dwStartType == SERVICE_SYSTEM_START))
1995 {
1996 if ((dwServiceType != SERVICE_KERNEL_DRIVER) &&
1997 (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER))
1999 }
2000
2001 /* Check for invalid error control value */
2002 if ((dwErrorControl != SERVICE_NO_CHANGE) &&
2003 (dwErrorControl != SERVICE_ERROR_IGNORE) &&
2004 (dwErrorControl != SERVICE_ERROR_NORMAL) &&
2005 (dwErrorControl != SERVICE_ERROR_SEVERE) &&
2006 (dwErrorControl != SERVICE_ERROR_CRITICAL))
2007 {
2009 }
2010
2011 if (lpdwTagId && (!lpLoadOrderGroup || !*lpLoadOrderGroup))
2012 {
2014 }
2015
2016 lpService = hSvc->ServiceEntry;
2017 if (lpService == NULL)
2018 {
2019 DPRINT("lpService == NULL\n");
2020 return ERROR_INVALID_HANDLE;
2021 }
2022
2023 /* Lock the service database exclusively */
2025
2026 if (lpService->bDeleted)
2027 {
2028 DPRINT("Service has already been marked for delete\n");
2030 goto done;
2031 }
2032
2033 /* Open the service key */
2034 dwError = ScmOpenServiceKey(lpService->szServiceName,
2036 &hServiceKey);
2037 if (dwError != ERROR_SUCCESS)
2038 goto done;
2039
2040 /* Write service data to the registry */
2041
2042 /* Set the display name */
2043 if (lpDisplayName != NULL && *lpDisplayName != 0)
2044 {
2045 RegSetValueExW(hServiceKey,
2046 L"DisplayName",
2047 0,
2048 REG_SZ,
2050 (DWORD)((wcslen(lpDisplayName) + 1) * sizeof(WCHAR)));
2051
2052 /* Update the display name */
2053 lpDisplayNameW = HeapAlloc(GetProcessHeap(),
2055 (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
2056 if (lpDisplayNameW == NULL)
2057 {
2058 dwError = ERROR_NOT_ENOUGH_MEMORY;
2059 goto done;
2060 }
2061
2062 wcscpy(lpDisplayNameW, lpDisplayName);
2063 if (lpService->lpDisplayName != lpService->lpServiceName)
2064 HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
2065
2066 lpService->lpDisplayName = lpDisplayNameW;
2067 }
2068
2069 if (dwServiceType != SERVICE_NO_CHANGE)
2070 {
2071 /* Set the service type */
2072 dwError = RegSetValueExW(hServiceKey,
2073 L"Type",
2074 0,
2075 REG_DWORD,
2076 (LPBYTE)&dwServiceType,
2077 sizeof(DWORD));
2078 if (dwError != ERROR_SUCCESS)
2079 goto done;
2080
2081 lpService->Status.dwServiceType = dwServiceType;
2082 }
2083
2084 if (dwStartType != SERVICE_NO_CHANGE)
2085 {
2086 /* Set the start value */
2087 dwError = RegSetValueExW(hServiceKey,
2088 L"Start",
2089 0,
2090 REG_DWORD,
2091 (LPBYTE)&dwStartType,
2092 sizeof(DWORD));
2093 if (dwError != ERROR_SUCCESS)
2094 goto done;
2095
2096 lpService->dwStartType = dwStartType;
2097 }
2098
2099 if (dwErrorControl != SERVICE_NO_CHANGE)
2100 {
2101 /* Set the error control value */
2102 dwError = RegSetValueExW(hServiceKey,
2103 L"ErrorControl",
2104 0,
2105 REG_DWORD,
2106 (LPBYTE)&dwErrorControl,
2107 sizeof(DWORD));
2108 if (dwError != ERROR_SUCCESS)
2109 goto done;
2110
2111 lpService->dwErrorControl = dwErrorControl;
2112 }
2113
2114 if (lpBinaryPathName != NULL && *lpBinaryPathName != 0)
2115 {
2116 /* Set the image path */
2117 lpImagePathW = lpBinaryPathName;
2118
2119 if (lpService->Status.dwServiceType & SERVICE_DRIVER)
2120 {
2121 dwError = ScmCanonDriverImagePath(lpService->dwStartType,
2122 lpBinaryPathName,
2123 &lpImagePathW);
2124
2125 if (dwError != ERROR_SUCCESS)
2126 goto done;
2127 }
2128
2129 dwError = RegSetValueExW(hServiceKey,
2130 L"ImagePath",
2131 0,
2133 (LPBYTE)lpImagePathW,
2134 (DWORD)((wcslen(lpImagePathW) + 1) * sizeof(WCHAR)));
2135
2136 if (lpImagePathW != lpBinaryPathName)
2137 HeapFree(GetProcessHeap(), 0, lpImagePathW);
2138
2139 if (dwError != ERROR_SUCCESS)
2140 goto done;
2141 }
2142
2143 /* Set the group name */
2144 if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
2145 {
2146 dwError = RegSetValueExW(hServiceKey,
2147 L"Group",
2148 0,
2149 REG_SZ,
2150 (LPBYTE)lpLoadOrderGroup,
2151 (DWORD)((wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)));
2152 if (dwError != ERROR_SUCCESS)
2153 goto done;
2154
2155 dwError = ScmSetServiceGroup(lpService,
2156 lpLoadOrderGroup);
2157 if (dwError != ERROR_SUCCESS)
2158 goto done;
2159 }
2160
2161 /* Set the tag */
2162 if (lpdwTagId != NULL)
2163 {
2164 dwError = ScmAssignNewTag(lpService);
2165 if (dwError != ERROR_SUCCESS)
2166 goto done;
2167
2168 dwError = RegSetValueExW(hServiceKey,
2169 L"Tag",
2170 0,
2171 REG_DWORD,
2172 (LPBYTE)&lpService->dwTag,
2173 sizeof(DWORD));
2174 if (dwError != ERROR_SUCCESS)
2175 goto done;
2176
2177 *lpdwTagId = lpService->dwTag;
2178 }
2179
2180 /* Write dependencies */
2181 if (lpDependencies != NULL && *lpDependencies != 0)
2182 {
2183 dwError = ScmWriteDependencies(hServiceKey,
2184 (LPWSTR)lpDependencies,
2185 dwDependSize);
2186 if (dwError != ERROR_SUCCESS)
2187 goto done;
2188 }
2189
2190 /* Start name and password are only used by Win32 services */
2191 if (lpService->Status.dwServiceType & SERVICE_WIN32)
2192 {
2193 /* Write service start name */
2194 if (lpServiceStartName != NULL && *lpServiceStartName != 0)
2195 {
2196 dwError = RegSetValueExW(hServiceKey,
2197 L"ObjectName",
2198 0,
2199 REG_SZ,
2200 (LPBYTE)lpServiceStartName,
2201 (DWORD)((wcslen(lpServiceStartName) + 1) * sizeof(WCHAR)));
2202 if (dwError != ERROR_SUCCESS)
2203 goto done;
2204 }
2205
2206 if (lpPassword != NULL)
2207 {
2208 if (*(LPWSTR)lpPassword != 0)
2209 {
2210 /* Decrypt the password */
2211 dwError = ScmDecryptPassword(hService,
2212 lpPassword,
2213 dwPwSize,
2214 &lpClearTextPassword);
2215 if (dwError != ERROR_SUCCESS)
2216 {
2217 DPRINT1("ScmDecryptPassword failed (Error %lu)\n", dwError);
2218 goto done;
2219 }
2220 DPRINT1("Clear text password: %S\n", lpClearTextPassword);
2221
2222 /* Write the password */
2223 dwError = ScmSetServicePassword(lpService->szServiceName,
2224 lpClearTextPassword);
2225 if (dwError != ERROR_SUCCESS)
2226 {
2227 DPRINT1("ScmSetServicePassword failed (Error %lu)\n", dwError);
2228 goto done;
2229 }
2230 }
2231 else
2232 {
2233 /* Delete the password */
2234 dwError = ScmSetServicePassword(lpService->szServiceName,
2235 NULL);
2236 if (dwError == ERROR_FILE_NOT_FOUND)
2237 dwError = ERROR_SUCCESS;
2238
2239 if (dwError != ERROR_SUCCESS)
2240 {
2241 DPRINT1("ScmSetServicePassword failed (Error %lu)\n", dwError);
2242 goto done;
2243 }
2244 }
2245 }
2246 }
2247
2248done:
2249 if (lpClearTextPassword != NULL)
2250 {
2251 /* Wipe and release the password buffer */
2252 SecureZeroMemory(lpClearTextPassword,
2253 (wcslen(lpClearTextPassword) + 1) * sizeof(WCHAR));
2254 HeapFree(GetProcessHeap(), 0, lpClearTextPassword);
2255 }
2256
2257 if (hServiceKey != NULL)
2258 RegCloseKey(hServiceKey);
2259
2260 /* Unlock the service database */
2262
2263 DPRINT("RChangeServiceConfigW() done (Error %lu)\n", dwError);
2264
2265 return dwError;
2266}
#define DPRINT1
Definition: precomp.h:8
DWORD ScmDecryptPassword(_In_ PVOID ContextHandle, _In_ PBYTE pPassword, _In_ DWORD dwPasswordSize, _Out_ PWSTR *pClearTextPassword)
Definition: config.c:708
DWORD ScmSetServicePassword(IN PCWSTR pszServiceName, IN PCWSTR pszPassword)
Definition: config.c:469
DWORD ScmWriteDependencies(HKEY hServiceKey, LPCWSTR lpDependencies, DWORD dwDependenciesLength)
Definition: config.c:117
DWORD ScmCanonDriverImagePath(DWORD dwStartType, const wchar_t *lpServiceName, wchar_t **lpCanonName)
Definition: rpcserver.c:642
DWORD ScmAssignNewTag(PSERVICE lpService)
Definition: rpcserver.c:272
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
DWORD ScmSetServiceGroup(PSERVICE lpService, LPCWSTR lpGroupName)
Definition: groupdb.c:61
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define REG_DWORD
Definition: sdbapi.c:596
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
DWORD dwErrorControl
Definition: services.h:72
DWORD dwStartType
Definition: services.h:71
DWORD dwTag
Definition: services.h:73
#define SecureZeroMemory
Definition: winbase.h:1713
#define SERVICE_NO_CHANGE
Definition: winsvc.h:20
#define SERVICE_DEMAND_START
Definition: cmtypes.h:978
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:953
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:963
#define SERVICE_ERROR_SEVERE
Definition: cmtypes.h:983
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:967
#define SERVICE_DISABLED
Definition: cmtypes.h:979
#define SERVICE_AUTO_START
Definition: cmtypes.h:977
#define SERVICE_BOOT_START
Definition: cmtypes.h:975
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:984
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:976
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:954
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:981
#define SERVICE_WIN32
Definition: cmtypes.h:964
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:982

Referenced by ChangeServiceConfigW(), and RChangeServiceConfigA().

◆ RCloseNotifyHandle()

DWORD WINAPI RCloseNotifyHandle ( LPSC_NOTIFY_RPC_HANDLE  phNotify,
PBOOL  pfApcFired 
)

Definition at line 6665 of file rpcserver.c.

6668{
6671}
#define UNIMPLEMENTED
Definition: debug.h:118
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102

◆ RCloseServiceHandle()

DWORD WINAPI RCloseServiceHandle ( LPSC_RPC_HANDLE  hSCObject)

Definition at line 936 of file rpcserver.c.

938{
939 PMANAGER_HANDLE hManager;
940 PSERVICE_HANDLE hService;
941 PSERVICE lpService;
943 DWORD dwError;
945 DWORD dwServicesReturned = 0;
946
947 DPRINT("RCloseServiceHandle() called\n");
948
949 DPRINT("hSCObject = %p\n", *hSCObject);
950
951 if (*hSCObject == 0)
953
954 hManager = ScmGetServiceManagerFromHandle(*hSCObject);
955 hService = ScmGetServiceFromHandle(*hSCObject);
956
957 if (hManager != NULL)
958 {
959 DPRINT("Found manager handle\n");
960
961 /* Make sure we don't access stale memory if someone tries to use this handle again. */
962 hManager->Handle.Tag = INVALID_TAG;
963
964 HeapFree(GetProcessHeap(), 0, hManager);
965 hManager = NULL;
966
967 *hSCObject = NULL;
968
969 DPRINT("RCloseServiceHandle() done\n");
970 return ERROR_SUCCESS;
971 }
972 else if (hService != NULL)
973 {
974 DPRINT("Found service handle\n");
975
976 /* Lock the service database exclusively */
978
979 /* Get the pointer to the service record */
980 lpService = hService->ServiceEntry;
981
982 /* Make sure we don't access stale memory if someone tries to use this handle again. */
983 hService->Handle.Tag = INVALID_TAG;
984
985 /* Free the handle */
986 HeapFree(GetProcessHeap(), 0, hService);
987 hService = NULL;
988
989 ASSERT(lpService->dwRefCount > 0);
990
991 lpService->dwRefCount--;
992 DPRINT("CloseServiceHandle - lpService->dwRefCount %u\n",
993 lpService->dwRefCount);
994
995 if (lpService->dwRefCount == 0)
996 {
997 /* If this service has been marked for deletion */
998 if (lpService->bDeleted &&
1000 {
1001 /* Open the Services Reg key */
1003 L"System\\CurrentControlSet\\Services",
1004 0,
1006 &hServicesKey);
1007 if (dwError != ERROR_SUCCESS)
1008 {
1009 DPRINT("Failed to open services key\n");
1011 return dwError;
1012 }
1013
1014 /* Call the internal function with NULL, just to get bytes we need */
1016 lpService,
1018 NULL,
1020 &dwServicesReturned);
1021
1022 /* If pcbBytesNeeded returned a value then there are services running that are dependent on this service */
1023 if (pcbBytesNeeded)
1024 {
1025 DPRINT("Deletion failed due to running dependencies\n");
1028 return ERROR_SUCCESS;
1029 }
1030
1031 /* There are no references and no running dependencies,
1032 it is now safe to delete the service */
1033
1034 /* Delete the Service Key */
1035 dwError = ScmDeleteRegKey(hServicesKey,
1036 lpService->lpServiceName);
1037
1039
1040 if (dwError != ERROR_SUCCESS)
1041 {
1042 DPRINT("Failed to Delete the Service Registry key\n");
1044 return dwError;
1045 }
1046
1047 /* Delete the Service */
1048 ScmDeleteServiceRecord(lpService);
1049 }
1050 }
1051
1053
1054 *hSCObject = NULL;
1055
1056 DPRINT("RCloseServiceHandle() done\n");
1057 return ERROR_SUCCESS;
1058 }
1059
1060 DPRINT("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
1061
1062 return ERROR_INVALID_HANDLE;
1063}
DWORD ScmDeleteRegKey(_In_ HKEY hKey, _In_ PCWSTR pszSubKey)
Definition: config.c:646
VOID ScmDeleteServiceRecord(PSERVICE lpService)
Definition: database.c:816
#define INVALID_TAG
Definition: rpcserver.c:27
static PMANAGER_HANDLE ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:202
#define ASSERT(a)
Definition: mode.c:44
SCMGR_HANDLE Handle
Definition: rpcserver.c:38
DWORD dwRefCount
Definition: services.h:68
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by CloseServiceHandle(), and SC_RPC_HANDLE_rundown().

◆ RControlService()

DWORD WINAPI RControlService ( SC_RPC_HANDLE  hService,
DWORD  dwControl,
LPSERVICE_STATUS  lpServiceStatus 
)

Definition at line 1069 of file rpcserver.c.

1073{
1074 PSERVICE_HANDLE hSvc;
1075 PSERVICE lpService;
1077 DWORD dwError = ERROR_SUCCESS;
1079 DWORD dwServicesReturned = 0;
1080 DWORD dwControlsAccepted;
1081 DWORD dwCurrentState;
1083 LPCWSTR lpLogStrings[2];
1084 WCHAR szLogBuffer[80];
1085 UINT uID;
1086
1087 DPRINT("RControlService() called\n");
1088
1089 if (ScmShutdown)
1091
1092 /* Check the service handle */
1093 hSvc = ScmGetServiceFromHandle(hService);
1094 if (hSvc == NULL)
1095 {
1096 DPRINT1("Invalid service handle\n");
1097 return ERROR_INVALID_HANDLE;
1098 }
1099
1100 /* Check the service entry point */
1101 lpService = hSvc->ServiceEntry;
1102 if (lpService == NULL)
1103 {
1104 DPRINT1("lpService == NULL\n");
1105 return ERROR_INVALID_HANDLE;
1106 }
1107
1108 /* Check access rights */
1109 switch (dwControl)
1110 {
1113 break;
1114
1123 break;
1124
1127 break;
1128
1129 default:
1130 if (dwControl >= 128 && dwControl <= 255)
1132 else
1134 break;
1135 }
1136
1139 return ERROR_ACCESS_DENIED;
1140
1141 /* Return the current service status information */
1142 RtlCopyMemory(lpServiceStatus,
1143 &lpService->Status,
1144 sizeof(SERVICE_STATUS));
1145
1146 if (dwControl == SERVICE_CONTROL_STOP)
1147 {
1148 /* Check if the service has dependencies running as windows
1149 doesn't stop a service that does */
1150
1151 /* Open the Services Reg key */
1153 L"System\\CurrentControlSet\\Services",
1154 0,
1155 KEY_READ,
1156 &hServicesKey);
1157 if (dwError != ERROR_SUCCESS)
1158 {
1159 DPRINT("Failed to open services key\n");
1160 return dwError;
1161 }
1162
1163 /* Call the internal function with NULL, just to get bytes we need */
1165 lpService,
1167 NULL,
1169 &dwServicesReturned);
1170
1172
1173 /* If pcbBytesNeeded is not zero then there are services running that
1174 are dependent on this service */
1175 if (pcbBytesNeeded != 0)
1176 {
1177 DPRINT("Service has running dependencies. Failed to stop service\n");
1179 }
1180 }
1181
1182 if (lpService->Status.dwServiceType & SERVICE_DRIVER)
1183 {
1184 /* Send control code to the driver */
1185 dwError = ScmControlDriver(lpService,
1186 dwControl,
1187 lpServiceStatus);
1188 }
1189 else
1190 {
1191 dwControlsAccepted = lpService->Status.dwControlsAccepted;
1192 dwCurrentState = lpService->Status.dwCurrentState;
1193
1194 /* Return ERROR_SERVICE_NOT_ACTIVE if the service has not been started */
1195 if (lpService->lpImage == NULL || dwCurrentState == SERVICE_STOPPED)
1197
1198 /* Check the current state before sending a control request */
1199 switch (dwCurrentState)
1200 {
1202 case SERVICE_STOPPED:
1204
1206 switch (dwControl)
1207 {
1209 break;
1210
1212 RtlCopyMemory(lpServiceStatus,
1213 &lpService->Status,
1214 sizeof(SERVICE_STATUS));
1215 return ERROR_SUCCESS;
1216
1217 default:
1219 }
1220 break;
1221 }
1222
1223 /* Check if the control code is acceptable to the service */
1224 switch (dwControl)
1225 {
1227 if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0)
1229 break;
1230
1233 if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0)
1235 break;
1236
1238 if ((dwControlsAccepted & SERVICE_ACCEPT_PARAMCHANGE) == 0)
1240 break;
1241
1246 if ((dwControlsAccepted & SERVICE_ACCEPT_NETBINDCHANGE) == 0)
1248 break;
1249 }
1250
1251 /* Send control code to the service */
1252 dwError = ScmControlService(lpService->lpImage->hControlPipe,
1253 lpService->lpServiceName,
1254 (SERVICE_STATUS_HANDLE)lpService,
1255 dwControl);
1256
1257 /* Return service status information */
1258 RtlCopyMemory(lpServiceStatus,
1259 &lpService->Status,
1260 sizeof(SERVICE_STATUS));
1261 }
1262
1263 if (dwError == ERROR_SUCCESS)
1264 {
1265 if (dwControl == SERVICE_CONTROL_STOP ||
1266 dwControl == SERVICE_CONTROL_PAUSE ||
1267 dwControl == SERVICE_CONTROL_CONTINUE)
1268 {
1269 /* Log a successful send control */
1270
1271 switch (dwControl)
1272 {
1274 uID = IDS_SERVICE_STOP;
1275 break;
1276
1278 uID = IDS_SERVICE_PAUSE;
1279 break;
1280
1282 uID = IDS_SERVICE_RESUME;
1283 break;
1284 }
1285 LoadStringW(GetModuleHandle(NULL), uID, szLogBuffer, ARRAYSIZE(szLogBuffer));
1286
1287 lpLogStrings[0] = lpService->lpDisplayName;
1288 lpLogStrings[1] = szLogBuffer;
1289
1292 2,
1293 lpLogStrings);
1294 }
1295 }
1296
1297 return dwError;
1298}
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
DWORD ScmControlService(HANDLE hControlPipe, PWSTR pServiceName, SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwControl)
Definition: database.c:1314
DWORD ScmControlDriver(PSERVICE lpService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: driver.c:335
#define IDS_SERVICE_PAUSE
Definition: resource.h:5
#define IDS_SERVICE_STOP
Definition: resource.h:4
#define IDS_SERVICE_RESUME
Definition: resource.h:6
VOID ScmLogEvent(DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings)
Definition: services.c:174
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
unsigned int UINT
Definition: ndis.h:50
#define EVENT_SERVICE_CONTROL_SUCCESS
Definition: netevent.h:432
HANDLE hControlPipe
Definition: services.h:51
DWORD dwControlsAccepted
Definition: winsvc.h:101
PSERVICE_IMAGE lpImage
Definition: services.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
#define GetModuleHandle
Definition: winbase.h:3827
#define ERROR_SERVICE_NOT_ACTIVE
Definition: winerror.h:613
#define ERROR_DEPENDENT_SERVICES_RUNNING
Definition: winerror.h:602
#define ERROR_INVALID_SERVICE_CONTROL
Definition: winerror.h:603
#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL
Definition: winerror.h:612
#define EVENTLOG_INFORMATION_TYPE
Definition: winnt_old.h:2836
#define SERVICE_ACCEPT_PARAMCHANGE
Definition: winsvc.h:31
#define SERVICE_CONTROL_PARAMCHANGE
Definition: winsvc.h:41
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
#define SERVICE_CONTROL_NETBINDREMOVE
Definition: winsvc.h:43
#define SERVICE_CONTROL_NETBINDADD
Definition: winsvc.h:42
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_CONTROL_NETBINDDISABLE
Definition: winsvc.h:45
#define SERVICE_CONTROL_NETBINDENABLE
Definition: winsvc.h:44
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
#define SERVICE_ACCEPT_PAUSE_CONTINUE
Definition: winsvc.h:29
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_ACCEPT_NETBINDCHANGE
Definition: winsvc.h:32
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by ControlService().

◆ RControlServiceExA()

DWORD WINAPI RControlServiceExA ( SC_RPC_HANDLE  hService,
DWORD  dwControl,
DWORD  dwInfoLevel 
)

Definition at line 6677 of file rpcserver.c.

6681{
6684}

◆ RControlServiceExW()

DWORD WINAPI RControlServiceExW ( SC_RPC_HANDLE  hService,
DWORD  dwControl,
DWORD  dwInfoLevel 
)

Definition at line 6690 of file rpcserver.c.

6694{
6697}

◆ RCreateServiceA()

DWORD WINAPI RCreateServiceA ( SC_RPC_HANDLE  hSCManager,
LPSTR  lpServiceName,
LPSTR  lpDisplayName,
DWORD  dwDesiredAccess,
DWORD  dwServiceType,
DWORD  dwStartType,
DWORD  dwErrorControl,
LPSTR  lpBinaryPathName,
LPSTR  lpLoadOrderGroup,
LPDWORD  lpdwTagId,
LPBYTE  lpDependencies,
DWORD  dwDependSize,
LPSTR  lpServiceStartName,
LPBYTE  lpPassword,
DWORD  dwPwSize,
LPSC_RPC_HANDLE  lpServiceHandle 
)

Definition at line 3592 of file rpcserver.c.

3609{
3610 DWORD dwError = ERROR_SUCCESS;
3611 LPWSTR lpServiceNameW = NULL;
3612 LPWSTR lpDisplayNameW = NULL;
3613 LPWSTR lpBinaryPathNameW = NULL;
3614 LPWSTR lpLoadOrderGroupW = NULL;
3615 LPWSTR lpDependenciesW = NULL;
3616 LPWSTR lpServiceStartNameW = NULL;
3617 DWORD dwDependenciesLength = 0;
3618 SIZE_T cchLength;
3619 int len;
3620 LPCSTR lpStr;
3621
3622 if (lpServiceName)
3623 {
3624 len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
3625 lpServiceNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3626 if (!lpServiceNameW)
3627 {
3629 goto cleanup;
3630 }
3631 MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
3632 }
3633
3634 if (lpDisplayName)
3635 {
3637 lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3638 if (!lpDisplayNameW)
3639 {
3641 goto cleanup;
3642 }
3643 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
3644 }
3645
3646 if (lpBinaryPathName)
3647 {
3648 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
3649 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3650 if (!lpBinaryPathNameW)
3651 {
3653 goto cleanup;
3654 }
3655 MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
3656 }
3657
3658 if (lpLoadOrderGroup)
3659 {
3660 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
3661 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3662 if (!lpLoadOrderGroupW)
3663 {
3665 goto cleanup;
3666 }
3667 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
3668 }
3669
3670 if (lpDependencies)
3671 {
3672 lpStr = (LPCSTR)lpDependencies;
3673 while (*lpStr)
3674 {
3675 cchLength = strlen(lpStr) + 1;
3676 dwDependenciesLength += (DWORD)cchLength;
3677 lpStr = lpStr + cchLength;
3678 }
3679 dwDependenciesLength++;
3680
3681 lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
3682 if (!lpDependenciesW)
3683 {
3685 goto cleanup;
3686 }
3687 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
3688 }
3689
3690 if (lpServiceStartName)
3691 {
3692 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
3693 lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3694 if (!lpServiceStartNameW)
3695 {
3697 goto cleanup;
3698 }
3699 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
3700 }
3701
3702 dwError = RCreateServiceW(hSCManager,
3703 lpServiceNameW,
3704 lpDisplayNameW,
3705 dwDesiredAccess,
3706 dwServiceType,
3707 dwStartType,
3708 dwErrorControl,
3709 lpBinaryPathNameW,
3710 lpLoadOrderGroupW,
3711 lpdwTagId,
3712 (LPBYTE)lpDependenciesW,
3713 dwDependenciesLength,
3714 lpServiceStartNameW,
3715 lpPassword,
3716 dwPwSize,
3717 lpServiceHandle);
3718
3719cleanup:
3720 if (lpServiceNameW !=NULL)
3721 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
3722
3723 if (lpDisplayNameW != NULL)
3724 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
3725
3726 if (lpBinaryPathNameW != NULL)
3727 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
3728
3729 if (lpLoadOrderGroupW != NULL)
3730 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
3731
3732 if (lpDependenciesW != NULL)
3733 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
3734
3735 if (lpServiceStartNameW != NULL)
3736 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
3737
3738 return dwError;
3739}
DWORD WINAPI RCreateServiceW(SC_RPC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPCWSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle)
Definition: rpcserver.c:2272
SC_HANDLE hSCManager
Definition: sc.c:12

Referenced by CreateServiceA().

◆ RCreateServiceW()

DWORD WINAPI RCreateServiceW ( SC_RPC_HANDLE  hSCManager,
LPCWSTR  lpServiceName,
LPCWSTR  lpDisplayName,
DWORD  dwDesiredAccess,
DWORD  dwServiceType,
DWORD  dwStartType,
DWORD  dwErrorControl,
LPCWSTR  lpBinaryPathName,
LPCWSTR  lpLoadOrderGroup,
LPDWORD  lpdwTagId,
LPBYTE  lpDependencies,
DWORD  dwDependSize,
LPCWSTR  lpServiceStartName,
LPBYTE  lpPassword,
DWORD  dwPwSize,
LPSC_RPC_HANDLE  lpServiceHandle 
)

Definition at line 2272 of file rpcserver.c.

2289{
2290 PMANAGER_HANDLE hManager;
2291 DWORD dwError = ERROR_SUCCESS;
2292 PSERVICE lpService = NULL;
2293 SC_HANDLE hServiceHandle = NULL;
2294 LPWSTR lpImagePath = NULL;
2295 LPWSTR lpClearTextPassword = NULL;
2296 HKEY hServiceKey = NULL;
2297 LPWSTR lpObjectName;
2298
2299 DPRINT("RCreateServiceW() called\n");
2300 DPRINT("lpServiceName = %S\n", lpServiceName);
2301 DPRINT("lpDisplayName = %S\n", lpDisplayName);
2302 DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess);
2303 DPRINT("dwServiceType = 0x%lx\n", dwServiceType);
2304 DPRINT("dwStartType = %lu\n", dwStartType);
2305 DPRINT("dwErrorControl = %lu\n", dwErrorControl);
2306 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
2307 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
2308 DPRINT("lpdwTagId = %p\n", lpdwTagId);
2309
2310 if (ScmShutdown)
2312
2314 if (hManager == NULL)
2315 {
2316 DPRINT1("Invalid service manager handle\n");
2317 return ERROR_INVALID_HANDLE;
2318 }
2319
2320 /* Check access rights */
2323 {
2324 DPRINT("Insufficient access rights! 0x%lx\n",
2325 hManager->Handle.DesiredAccess);
2326 return ERROR_ACCESS_DENIED;
2327 }
2328
2329 if (*lpServiceName == 0)
2330 return ERROR_INVALID_NAME;
2331
2332 if (*lpBinaryPathName == 0)
2334
2335 /* Check for invalid service type value */
2336 if ((dwServiceType != SERVICE_KERNEL_DRIVER) &&
2337 (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER) &&
2340 {
2342 }
2343
2344 /* Check for invalid start type value */
2345 if ((dwStartType != SERVICE_BOOT_START) &&
2346 (dwStartType != SERVICE_SYSTEM_START) &&
2347 (dwStartType != SERVICE_AUTO_START) &&
2348 (dwStartType != SERVICE_DEMAND_START) &&
2349 (dwStartType != SERVICE_DISABLED))
2350 {
2352 }
2353
2354 /* Only drivers can be boot start or system start services */
2355 if ((dwStartType == SERVICE_BOOT_START) ||
2356 (dwStartType == SERVICE_SYSTEM_START))
2357 {
2358 if ((dwServiceType != SERVICE_KERNEL_DRIVER) &&
2359 (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER))
2360 {
2362 }
2363 }
2364
2365 /* Check for invalid error control value */
2366 if ((dwErrorControl != SERVICE_ERROR_IGNORE) &&
2367 (dwErrorControl != SERVICE_ERROR_NORMAL) &&
2368 (dwErrorControl != SERVICE_ERROR_SEVERE) &&
2369 (dwErrorControl != SERVICE_ERROR_CRITICAL))
2370 {
2372 }
2373
2374 if ((dwServiceType == (SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS)) &&
2375 (lpServiceStartName))
2376 {
2377 /* We allow LocalSystem to run interactive. */
2378 if (wcsicmp(lpServiceStartName, L"LocalSystem"))
2379 {
2381 }
2382 }
2383
2384 if (lpdwTagId && (!lpLoadOrderGroup || !*lpLoadOrderGroup))
2385 {
2387 }
2388
2389 /* Lock the service database exclusively */
2391
2392 lpService = ScmGetServiceEntryByName(lpServiceName);
2393 if (lpService)
2394 {
2395 /* Unlock the service database */
2397
2398 /* Check if it is marked for deletion */
2399 if (lpService->bDeleted)
2401
2402 /* Return service-exists error */
2403 return ERROR_SERVICE_EXISTS;
2404 }
2405
2406 if (lpDisplayName != NULL &&
2408 {
2409 /* Unlock the service database */
2411
2413 }
2414
2415 if (dwServiceType & SERVICE_DRIVER)
2416 {
2417 dwError = ScmCanonDriverImagePath(dwStartType,
2418 lpBinaryPathName,
2419 &lpImagePath);
2420 if (dwError != ERROR_SUCCESS)
2421 goto done;
2422 }
2423 else
2424 {
2425 if (dwStartType == SERVICE_BOOT_START ||
2426 dwStartType == SERVICE_SYSTEM_START)
2427 {
2428 /* Unlock the service database */
2430
2432 }
2433 }
2434
2435 /* Allocate a new service entry */
2436 dwError = ScmCreateNewServiceRecord(lpServiceName,
2437 &lpService,
2438 dwServiceType,
2439 dwStartType);
2440 if (dwError != ERROR_SUCCESS)
2441 goto done;
2442
2443 /* Fill the new service entry */
2444 lpService->dwErrorControl = dwErrorControl;
2445
2446 /* Fill the display name */
2447 if (lpDisplayName != NULL &&
2448 *lpDisplayName != 0 &&
2449 _wcsicmp(lpService->lpDisplayName, lpDisplayName) != 0)
2450 {
2451 lpService->lpDisplayName = HeapAlloc(GetProcessHeap(),
2453 (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
2454 if (lpService->lpDisplayName == NULL)
2455 {
2456 dwError = ERROR_NOT_ENOUGH_MEMORY;
2457 goto done;
2458 }
2459 wcscpy(lpService->lpDisplayName, lpDisplayName);
2460 }
2461
2462 /* Assign the service to a group */
2463 if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
2464 {
2465 dwError = ScmSetServiceGroup(lpService,
2466 lpLoadOrderGroup);
2467 if (dwError != ERROR_SUCCESS)
2468 goto done;
2469 }
2470
2471 /* Assign a new tag */
2472 if (lpdwTagId != NULL)
2473 {
2474 dwError = ScmAssignNewTag(lpService);
2475 if (dwError != ERROR_SUCCESS)
2476 goto done;
2477 }
2478
2479 /* Assign the default security descriptor */
2480 if (dwServiceType & SERVICE_WIN32)
2481 {
2482 dwError = ScmCreateDefaultServiceSD(&lpService->pSecurityDescriptor);
2483 if (dwError != ERROR_SUCCESS)
2484 goto done;
2485 }
2486
2487 /* Write service data to the registry */
2488 /* Create the service key */
2489 dwError = ScmCreateServiceKey(lpServiceName,
2490 KEY_WRITE,
2491 &hServiceKey);
2492 if (dwError != ERROR_SUCCESS)
2493 goto done;
2494
2495 /* Set the display name */
2496 if (lpDisplayName != NULL && *lpDisplayName != 0)
2497 {
2498 RegSetValueExW(hServiceKey,
2499 L"DisplayName",
2500 0,
2501 REG_SZ,
2503 (DWORD)((wcslen(lpDisplayName) + 1) * sizeof(WCHAR)));
2504 }
2505
2506 /* Set the service type */
2507 dwError = RegSetValueExW(hServiceKey,
2508 L"Type",
2509 0,
2510 REG_DWORD,
2511 (LPBYTE)&dwServiceType,
2512 sizeof(DWORD));
2513 if (dwError != ERROR_SUCCESS)
2514 goto done;
2515
2516 /* Set the start value */
2517 dwError = RegSetValueExW(hServiceKey,
2518 L"Start",
2519 0,
2520 REG_DWORD,
2521 (LPBYTE)&dwStartType,
2522 sizeof(DWORD));
2523 if (dwError != ERROR_SUCCESS)
2524 goto done;
2525
2526 /* Set the error control value */
2527 dwError = RegSetValueExW(hServiceKey,
2528 L"ErrorControl",
2529 0,
2530 REG_DWORD,
2531 (LPBYTE)&dwErrorControl,
2532 sizeof(DWORD));
2533 if (dwError != ERROR_SUCCESS)
2534 goto done;
2535
2536 /* Set the image path */
2537 if (dwServiceType & SERVICE_WIN32)
2538 {
2539 dwError = RegSetValueExW(hServiceKey,
2540 L"ImagePath",
2541 0,
2543 (LPBYTE)lpBinaryPathName,
2544 (DWORD)((wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR)));
2545 if (dwError != ERROR_SUCCESS)
2546 goto done;
2547 }
2548 else if (dwServiceType & SERVICE_DRIVER)
2549 {
2550 dwError = RegSetValueExW(hServiceKey,
2551 L"ImagePath",
2552 0,
2554 (LPBYTE)lpImagePath,
2555 (DWORD)((wcslen(lpImagePath) + 1) * sizeof(WCHAR)));
2556 if (dwError != ERROR_SUCCESS)
2557 goto done;
2558 }
2559
2560 /* Set the group name */
2561 if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
2562 {
2563 dwError = RegSetValueExW(hServiceKey,
2564 L"Group",
2565 0,
2566 REG_SZ,
2567 (LPBYTE)lpLoadOrderGroup,
2568 (DWORD)((wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)));
2569 if (dwError != ERROR_SUCCESS)
2570 goto done;
2571 }
2572
2573 /* Set the service tag */
2574 if (lpdwTagId != NULL)
2575 {
2576 dwError = RegSetValueExW(hServiceKey,
2577 L"Tag",
2578 0,
2579 REG_DWORD,
2580 (LPBYTE)&lpService->dwTag,
2581 sizeof(DWORD));
2582 if (dwError != ERROR_SUCCESS)
2583 goto done;
2584 }
2585
2586 /* Write dependencies */
2587 if (lpDependencies != NULL && *lpDependencies != 0)
2588 {
2589 dwError = ScmWriteDependencies(hServiceKey,
2590 (LPCWSTR)lpDependencies,
2591 dwDependSize);
2592 if (dwError != ERROR_SUCCESS)
2593 goto done;
2594 }
2595
2596 /* Start name and password are only used by Win32 services */
2597 if (dwServiceType & SERVICE_WIN32)
2598 {
2599 /* Write service start name */
2600 lpObjectName = (lpServiceStartName != NULL) ? (LPWSTR)lpServiceStartName : L"LocalSystem";
2601 dwError = RegSetValueExW(hServiceKey,
2602 L"ObjectName",
2603 0,
2604 REG_SZ,
2605 (LPBYTE)lpObjectName,
2606 (DWORD)((wcslen(lpObjectName) + 1) * sizeof(WCHAR)));
2607 if (dwError != ERROR_SUCCESS)
2608 goto done;
2609
2610 if (lpPassword != NULL && *(LPWSTR)lpPassword != 0)
2611 {
2612 /* Decrypt the password */
2614 lpPassword,
2615 dwPwSize,
2616 &lpClearTextPassword);
2617 if (dwError != ERROR_SUCCESS)
2618 goto done;
2619
2620 /* Write the password */
2621 dwError = ScmSetServicePassword(lpServiceName,
2622 lpClearTextPassword);
2623 if (dwError != ERROR_SUCCESS)
2624 goto done;
2625 }
2626
2627 /* Write the security descriptor */
2628 dwError = ScmWriteSecurityDescriptor(hServiceKey,
2629 lpService->pSecurityDescriptor);
2630 if (dwError != ERROR_SUCCESS)
2631 goto done;
2632 }
2633
2634 dwError = ScmCreateServiceHandle(lpService,
2635 &hServiceHandle);
2636 if (dwError != ERROR_SUCCESS)
2637 goto done;
2638
2639 dwError = ScmCheckAccess(hServiceHandle,
2640 dwDesiredAccess);
2641 if (dwError != ERROR_SUCCESS)
2642 goto done;
2643
2644 lpService->dwRefCount = 1;
2645
2646 /* Get the service tag (if Win32) */
2647 ScmGenerateServiceTag(lpService);
2648
2649 DPRINT("CreateService - lpService->dwRefCount %u\n", lpService->dwRefCount);
2650
2651done:
2652 /* Unlock the service database */
2654
2655 if (hServiceKey != NULL)
2656 RegCloseKey(hServiceKey);
2657
2658 if (lpClearTextPassword != NULL)
2659 {
2660 /* Wipe and release the password buffer */
2661 SecureZeroMemory(lpClearTextPassword,
2662 (wcslen(lpClearTextPassword) + 1) * sizeof(WCHAR));
2663 HeapFree(GetProcessHeap(), 0, lpClearTextPassword);
2664 }
2665
2666 if (dwError == ERROR_SUCCESS)
2667 {
2668 DPRINT("hService %p\n", hServiceHandle);
2669 *lpServiceHandle = (SC_RPC_HANDLE)hServiceHandle;
2670
2671 if (lpdwTagId != NULL)
2672 *lpdwTagId = lpService->dwTag;
2673 }
2674 else
2675 {
2676 if (lpService != NULL &&
2677 lpService->lpServiceName != NULL)
2678 {
2679 /* Release the display name buffer */
2680 HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
2681 }
2682
2683 if (hServiceHandle)
2684 {
2685 /* Remove the service handle */
2686 HeapFree(GetProcessHeap(), 0, hServiceHandle);
2687 }
2688
2689 if (lpService != NULL)
2690 {
2691 /* FIXME: remove the service entry */
2692 }
2693 }
2694
2695 if (lpImagePath != NULL)
2696 HeapFree(GetProcessHeap(), 0, lpImagePath);
2697
2698 DPRINT("RCreateServiceW() done (Error %lu)\n", dwError);
2699
2700 return dwError;
2701}
DWORD ScmWriteSecurityDescriptor(_In_ HKEY hServiceKey, _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor)
Definition: config.c:530
DWORD ScmCreateServiceKey(LPCWSTR lpServiceName, REGSAM samDesired, PHKEY phKey)
Definition: config.c:72
DWORD ScmGenerateServiceTag(PSERVICE lpServiceRecord)
Definition: database.c:744
DWORD ScmCreateNewServiceRecord(LPCWSTR lpServiceName, PSERVICE *lpServiceRecord, DWORD dwServiceType, DWORD dwStartType)
Definition: database.c:767
PSERVICE ScmGetServiceEntryByDisplayName(LPCWSTR lpDisplayName)
Definition: database.c:686
static DWORD ScmCreateServiceHandle(PSERVICE lpServiceEntry, SC_HANDLE *Handle)
Definition: rpcserver.c:180
static DWORD ScmCheckAccess(SC_HANDLE Handle, DWORD dwDesiredAccess)
Definition: rpcserver.c:242
DWORD ScmCreateDefaultServiceSD(PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
Definition: security.c:320
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define wcsicmp
Definition: compat.h:15
#define KEY_WRITE
Definition: nt_native.h:1031
PSECURITY_DESCRIPTOR pSecurityDescriptor
Definition: services.h:80
PVOID SC_RPC_HANDLE
Definition: svcctl.idl:21
#define ERROR_DUPLICATE_SERVICE_NAME
Definition: winerror.h:629
#define ERROR_SERVICE_EXISTS
Definition: winerror.h:624

Referenced by CreateServiceW(), and RCreateServiceA().

◆ RCreateServiceWOW64A()

DWORD WINAPI RCreateServiceWOW64A ( handle_t  BindingHandle,
LPSTR  lpServiceName,
LPSTR  lpDisplayName,
DWORD  dwDesiredAccess,
DWORD  dwServiceType,
DWORD  dwStartType,
DWORD  dwErrorControl,
LPSTR  lpBinaryPathName,
LPSTR  lpLoadOrderGroup,
LPDWORD  lpdwTagId,
LPBYTE  lpDependencies,
DWORD  dwDependSize,
LPSTR  lpServiceStartName,
LPBYTE  lpPassword,
DWORD  dwPwSize,
LPSC_RPC_HANDLE  lpServiceHandle 
)

Definition at line 6541 of file rpcserver.c.

6558{
6561}

◆ RCreateServiceWOW64W()

DWORD WINAPI RCreateServiceWOW64W ( handle_t  BindingHandle,
LPWSTR  lpServiceName,
LPWSTR  lpDisplayName,
DWORD  dwDesiredAccess,
DWORD  dwServiceType,
DWORD  dwStartType,
DWORD  dwErrorControl,
LPWSTR  lpBinaryPathName,
LPWSTR  lpLoadOrderGroup,
LPDWORD  lpdwTagId,
LPBYTE  lpDependencies,
DWORD  dwDependSize,
LPWSTR  lpServiceStartName,
LPBYTE  lpPassword,
DWORD  dwPwSize,
LPSC_RPC_HANDLE  lpServiceHandle 
)

Definition at line 6567 of file rpcserver.c.

6584{
6587}

◆ RDeleteService()

DWORD WINAPI RDeleteService ( SC_RPC_HANDLE  hService)

Definition at line 1304 of file rpcserver.c.

1306{
1307 PSERVICE_HANDLE hSvc;
1308 PSERVICE lpService;
1309 DWORD dwError;
1310
1311 DPRINT("RDeleteService() called\n");
1312
1313 if (ScmShutdown)
1315
1316 hSvc = ScmGetServiceFromHandle(hService);
1317 if (hSvc == NULL)
1318 {
1319 DPRINT1("Invalid service handle\n");
1320 return ERROR_INVALID_HANDLE;
1321 }
1322
1324 DELETE))
1325 return ERROR_ACCESS_DENIED;
1326
1327 lpService = hSvc->ServiceEntry;
1328 if (lpService == NULL)
1329 {
1330 DPRINT("lpService == NULL\n");
1331 return ERROR_INVALID_HANDLE;
1332 }
1333
1334 /* Lock the service database exclusively */
1336
1337 if (lpService->bDeleted)
1338 {
1339 DPRINT("Service has already been marked for delete\n");
1341 goto Done;
1342 }
1343
1344 /* Mark service for delete */
1345 lpService->bDeleted = TRUE;
1346
1347 dwError = ScmMarkServiceForDelete(lpService);
1348
1349Done:
1350 /* Unlock the service database */
1352
1353 DPRINT("RDeleteService() done\n");
1354
1355 return dwError;
1356}
DWORD ScmMarkServiceForDelete(PSERVICE pService)
Definition: config.c:223
#define TRUE
Definition: types.h:120
#define DELETE
Definition: nt_native.h:57

Referenced by DeleteService().

◆ REnumDependentServicesA()

DWORD WINAPI REnumDependentServicesA ( SC_RPC_HANDLE  hService,
DWORD  dwServiceState,
LPBYTE  lpServices,
DWORD  cbBufSize,
LPBOUNDED_DWORD_256K  pcbBytesNeeded,
LPBOUNDED_DWORD_256K  lpServicesReturned 
)

Definition at line 3745 of file rpcserver.c.

3752{
3753 DWORD dwError = ERROR_SUCCESS;
3754 DWORD dwServicesReturned = 0;
3755 DWORD dwServiceCount;
3757 PSERVICE_HANDLE hSvc;
3758 PSERVICE lpService = NULL;
3759 PSERVICE *lpServicesArray = NULL;
3760 LPENUM_SERVICE_STATUSA lpServicesPtr = NULL;
3761 LPSTR lpStr;
3762
3763 *pcbBytesNeeded = 0;
3764 *lpServicesReturned = 0;
3765
3766 DPRINT("REnumDependentServicesA() called\n");
3767
3768 hSvc = ScmGetServiceFromHandle(hService);
3769 if (hSvc == NULL)
3770 {
3771 DPRINT1("Invalid service handle\n");
3772 return ERROR_INVALID_HANDLE;
3773 }
3774
3775 lpService = hSvc->ServiceEntry;
3776
3777 /* Check access rights */
3780 {
3781 DPRINT("Insufficient access rights! 0x%lx\n",
3782 hSvc->Handle.DesiredAccess);
3783 return ERROR_ACCESS_DENIED;
3784 }
3785
3786 /* Open the Services Reg key */
3788 L"System\\CurrentControlSet\\Services",
3789 0,
3790 KEY_READ,
3791 &hServicesKey);
3792
3793 if (dwError != ERROR_SUCCESS)
3794 return dwError;
3795
3796 /* NOTE: Windows calculates the pcbBytesNeeded based on WCHAR strings for
3797 both EnumDependentServicesA and EnumDependentServicesW. So returned pcbBytesNeeded
3798 are the same for both. Verified in WINXP. */
3799
3800 /* First determine the bytes needed and get the number of dependent services*/
3802 lpService,
3803 dwServiceState,
3804 NULL,
3806 &dwServicesReturned);
3807 if (dwError != ERROR_SUCCESS)
3808 goto Done;
3809
3810 /* If buffer size is less than the bytes needed or pointer is null*/
3811 if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
3812 {
3813 dwError = ERROR_MORE_DATA;
3814 goto Done;
3815 }
3816
3817 /* Allocate memory for array of service pointers */
3818 lpServicesArray = HeapAlloc(GetProcessHeap(),
3820 (dwServicesReturned + 1) * sizeof(PSERVICE));
3821 if (!lpServicesArray)
3822 {
3823 DPRINT("Could not allocate buffer\n");
3824 dwError = ERROR_NOT_ENOUGH_MEMORY;
3825 goto Done;
3826 }
3827
3828 dwServicesReturned = 0;
3829 *pcbBytesNeeded = 0;
3830
3832 lpService,
3833 dwServiceState,
3834 lpServicesArray,
3836 &dwServicesReturned);
3837 if (dwError != ERROR_SUCCESS)
3838 {
3839 goto Done;
3840 }
3841
3842 lpServicesPtr = (LPENUM_SERVICE_STATUSA)lpServices;
3843 lpStr = (LPSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSA)));
3844
3845 /* Copy EnumDepenedentService to Buffer */
3846 for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
3847 {
3848 lpService = lpServicesArray[dwServiceCount];
3849
3850 /* Copy the status info */
3851 memcpy(&lpServicesPtr->ServiceStatus,
3852 &lpService->Status,
3853 sizeof(SERVICE_STATUS));
3854
3855 /* Copy display name */
3857 0,
3858 lpService->lpDisplayName,
3859 -1,
3860 lpStr,
3861 (int)wcslen(lpService->lpDisplayName),
3862 0,
3863 0);
3864 lpServicesPtr->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
3865 lpStr += strlen(lpStr) + 1;
3866
3867 /* Copy service name */
3869 0,
3870 lpService->lpServiceName,
3871 -1,
3872 lpStr,
3873 (int)wcslen(lpService->lpServiceName),
3874 0,
3875 0);
3876 lpServicesPtr->lpServiceName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
3877 lpStr += strlen(lpStr) + 1;
3878
3879 lpServicesPtr++;
3880 }
3881
3882 *lpServicesReturned = dwServicesReturned;
3883
3884Done:
3885 if (lpServicesArray)
3886 HeapFree(GetProcessHeap(), 0, lpServicesArray);
3887
3889
3890 DPRINT("REnumDependentServicesA() done (Error %lu)\n", dwError);
3891
3892 return dwError;
3893}
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define WideCharToMultiByte
Definition: compat.h:111
#define ULONG_PTR
Definition: config.h:101
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
SERVICE_STATUS ServiceStatus
Definition: winsvc.h:127
_In_ DWORD _In_ DWORD cbBufSize
Definition: winsvc.h:424
struct _ENUM_SERVICE_STATUSA * LPENUM_SERVICE_STATUSA
char * LPSTR
Definition: xmlstorage.h:182

Referenced by EnumDependentServicesA().

◆ REnumDependentServicesW()

DWORD WINAPI REnumDependentServicesW ( SC_RPC_HANDLE  hService,
DWORD  dwServiceState,
LPBYTE  lpServices,
DWORD  cbBufSize,
LPBOUNDED_DWORD_256K  pcbBytesNeeded,
LPBOUNDED_DWORD_256K  lpServicesReturned 
)

Definition at line 2707 of file rpcserver.c.

2714{
2715 DWORD dwError = ERROR_SUCCESS;
2716 DWORD dwServicesReturned = 0;
2717 DWORD dwServiceCount;
2719 PSERVICE_HANDLE hSvc;
2720 PSERVICE lpService = NULL;
2721 PSERVICE *lpServicesArray = NULL;
2722 LPENUM_SERVICE_STATUSW lpServicesPtr = NULL;
2723 LPWSTR lpStr;
2724
2725 *pcbBytesNeeded = 0;
2726 *lpServicesReturned = 0;
2727
2728 DPRINT("REnumDependentServicesW() called\n");
2729
2730 hSvc = ScmGetServiceFromHandle(hService);
2731 if (hSvc == NULL)
2732 {
2733 DPRINT1("Invalid service handle\n");
2734 return ERROR_INVALID_HANDLE;
2735 }
2736
2737 lpService = hSvc->ServiceEntry;
2738
2739 /* Check access rights */
2742 {
2743 DPRINT("Insufficient access rights! 0x%lx\n",
2744 hSvc->Handle.DesiredAccess);
2745 return ERROR_ACCESS_DENIED;
2746 }
2747
2748 /* Open the Services Reg key */
2750 L"System\\CurrentControlSet\\Services",
2751 0,
2752 KEY_READ,
2753 &hServicesKey);
2754 if (dwError != ERROR_SUCCESS)
2755 return dwError;
2756
2757 /* First determine the bytes needed and get the number of dependent services */
2759 lpService,
2760 dwServiceState,
2761 NULL,
2763 &dwServicesReturned);
2764 if (dwError != ERROR_SUCCESS)
2765 goto Done;
2766
2767 /* If buffer size is less than the bytes needed or pointer is null */
2768 if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
2769 {
2770 dwError = ERROR_MORE_DATA;
2771 goto Done;
2772 }
2773
2774 /* Allocate memory for array of service pointers */
2775 lpServicesArray = HeapAlloc(GetProcessHeap(),
2777 (dwServicesReturned + 1) * sizeof(PSERVICE));
2778 if (!lpServicesArray)
2779 {
2780 DPRINT1("Could not allocate buffer\n");
2781 dwError = ERROR_NOT_ENOUGH_MEMORY;
2782 goto Done;
2783 }
2784
2785 dwServicesReturned = 0;
2786 *pcbBytesNeeded = 0;
2787
2789 lpService,
2790 dwServiceState,
2791 lpServicesArray,
2793 &dwServicesReturned);
2794 if (dwError != ERROR_SUCCESS)
2795 {
2796 goto Done;
2797 }
2798
2799 lpServicesPtr = (LPENUM_SERVICE_STATUSW)lpServices;
2800 lpStr = (LPWSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSW)));
2801
2802 /* Copy EnumDepenedentService to Buffer */
2803 for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
2804 {
2805 lpService = lpServicesArray[dwServiceCount];
2806
2807 /* Copy status info */
2808 memcpy(&lpServicesPtr->ServiceStatus,
2809 &lpService->Status,
2810 sizeof(SERVICE_STATUS));
2811
2812 /* Copy display name */
2813 wcscpy(lpStr, lpService->lpDisplayName);
2814 lpServicesPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
2815 lpStr += (wcslen(lpService->lpDisplayName) + 1);
2816
2817 /* Copy service name */
2818 wcscpy(lpStr, lpService->lpServiceName);
2819 lpServicesPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
2820 lpStr += (wcslen(lpService->lpServiceName) + 1);
2821
2822 lpServicesPtr++;
2823 }
2824
2825 *lpServicesReturned = dwServicesReturned;
2826
2827Done:
2828 if (lpServicesArray != NULL)
2829 HeapFree(GetProcessHeap(), 0, lpServicesArray);
2830
2832
2833 DPRINT("REnumDependentServicesW() done (Error %lu)\n", dwError);
2834
2835 return dwError;
2836}
SERVICE_STATUS ServiceStatus
Definition: winsvc.h:132
LPWSTR lpDisplayName
Definition: winsvc.h:131
LPWSTR lpServiceName
Definition: winsvc.h:130
struct _ENUM_SERVICE_STATUSW * LPENUM_SERVICE_STATUSW

Referenced by EnumDependentServicesW().

◆ REnumServiceGroupW()

DWORD WINAPI REnumServiceGroupW ( SC_RPC_HANDLE  hSCManager,
DWORD  dwServiceType,
DWORD  dwServiceState,
LPBYTE  lpBuffer,
DWORD  cbBufSize,
LPBOUNDED_DWORD_256K  pcbBytesNeeded,
LPBOUNDED_DWORD_256K  lpServicesReturned,
LPBOUNDED_DWORD_256K  lpResumeIndex,
LPCWSTR  pszGroupName 
)

Definition at line 4753 of file rpcserver.c.

4763{
4764 PMANAGER_HANDLE hManager;
4765 PSERVICE lpService;
4766 DWORD dwError = ERROR_SUCCESS;
4767 PLIST_ENTRY ServiceEntry;
4768 PSERVICE CurrentService;
4769 DWORD dwState;
4770 DWORD dwRequiredSize;
4771 DWORD dwServiceCount;
4772 DWORD dwSize;
4773 DWORD dwLastResumeCount = 0;
4774 LPENUM_SERVICE_STATUSW lpStatusPtr;
4775 LPWSTR lpStringPtr;
4776
4777 DPRINT("REnumServiceGroupW() called\n");
4778
4779 if (ScmShutdown)
4781
4783 if (hManager == NULL)
4784 {
4785 DPRINT1("Invalid service manager handle\n");
4786 return ERROR_INVALID_HANDLE;
4787 }
4788
4789 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
4790 {
4791 return ERROR_INVALID_ADDRESS;
4792 }
4793
4794 *pcbBytesNeeded = 0;
4795 *lpServicesReturned = 0;
4796
4797 if ((dwServiceType == 0) ||
4798 ((dwServiceType & ~SERVICE_TYPE_ALL) != 0))
4799 {
4800 DPRINT("Invalid Service Type\n");
4802 }
4803
4804 if ((dwServiceState == 0) ||
4805 ((dwServiceState & ~SERVICE_STATE_ALL) != 0))
4806 {
4807 DPRINT("Invalid Service State\n");
4809 }
4810
4811 /* Check access rights */
4814 {
4815 DPRINT("Insufficient access rights! 0x%lx\n",
4816 hManager->Handle.DesiredAccess);
4817 return ERROR_ACCESS_DENIED;
4818 }
4819
4820 if (lpResumeIndex)
4821 dwLastResumeCount = *lpResumeIndex;
4822
4823 /* Lock the service database shared */
4825
4826 lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
4827 if (lpService == NULL)
4828 {
4829 dwError = ERROR_SUCCESS;
4830 goto Done;
4831 }
4832
4833 dwRequiredSize = 0;
4834 dwServiceCount = 0;
4835
4836 for (ServiceEntry = &lpService->ServiceListEntry;
4837 ServiceEntry != &ServiceListHead;
4838 ServiceEntry = ServiceEntry->Flink)
4839 {
4840 CurrentService = CONTAINING_RECORD(ServiceEntry,
4841 SERVICE,
4842 ServiceListEntry);
4843
4844 if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4845 continue;
4846
4847 dwState = SERVICE_ACTIVE;
4848 if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4849 dwState = SERVICE_INACTIVE;
4850
4851 if ((dwState & dwServiceState) == 0)
4852 continue;
4853
4854 if (pszGroupName)
4855 {
4856 if (*pszGroupName == 0)
4857 {
4858 if (CurrentService->lpGroup != NULL)
4859 continue;
4860 }
4861 else
4862 {
4863 if ((CurrentService->lpGroup == NULL) ||
4864 _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4865 continue;
4866 }
4867 }
4868
4869 dwSize = sizeof(ENUM_SERVICE_STATUSW) +
4870 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4871 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
4872
4873 if (dwRequiredSize + dwSize > cbBufSize)
4874 {
4875 DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
4876 break;
4877 }
4878
4879 DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
4880 dwRequiredSize += dwSize;
4881 dwServiceCount++;
4882 dwLastResumeCount = CurrentService->dwResumeCount;
4883 }
4884
4885 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
4886 DPRINT("dwServiceCount: %lu\n", dwServiceCount);
4887
4888 for (;
4889 ServiceEntry != &ServiceListHead;
4890 ServiceEntry = ServiceEntry->Flink)
4891 {
4892 CurrentService = CONTAINING_RECORD(ServiceEntry,
4893 SERVICE,
4894 ServiceListEntry);
4895
4896 if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4897 continue;
4898
4899 dwState = SERVICE_ACTIVE;
4900 if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4901 dwState = SERVICE_INACTIVE;
4902
4903 if ((dwState & dwServiceState) == 0)
4904 continue;
4905
4906 if (pszGroupName)
4907 {
4908 if (*pszGroupName == 0)
4909 {
4910 if (CurrentService->lpGroup != NULL)
4911 continue;
4912 }
4913 else
4914 {
4915 if ((CurrentService->lpGroup == NULL) ||
4916 _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4917 continue;
4918 }
4919 }
4920
4921 dwRequiredSize += (sizeof(ENUM_SERVICE_STATUSW) +
4922 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4923 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
4924
4925 dwError = ERROR_MORE_DATA;
4926 }
4927
4928 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
4929
4930 if (lpResumeIndex)
4931 *lpResumeIndex = dwLastResumeCount;
4932
4933 *lpServicesReturned = dwServiceCount;
4934 *pcbBytesNeeded = dwRequiredSize;
4935
4936 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpBuffer;
4937 lpStringPtr = (LPWSTR)((ULONG_PTR)lpBuffer +
4938 dwServiceCount * sizeof(ENUM_SERVICE_STATUSW));
4939
4940 dwRequiredSize = 0;
4941 for (ServiceEntry = &lpService->ServiceListEntry;
4942 ServiceEntry != &ServiceListHead;
4943 ServiceEntry = ServiceEntry->Flink)
4944 {
4945 CurrentService = CONTAINING_RECORD(ServiceEntry,
4946 SERVICE,
4947 ServiceListEntry);
4948
4949 if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4950 continue;
4951
4952 dwState = SERVICE_ACTIVE;
4953 if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4954 dwState = SERVICE_INACTIVE;
4955
4956 if ((dwState & dwServiceState) == 0)
4957 continue;
4958
4959 if (pszGroupName)
4960 {
4961 if (*pszGroupName == 0)
4962 {
4963 if (CurrentService->lpGroup != NULL)
4964 continue;
4965 }
4966 else
4967 {
4968 if ((CurrentService->lpGroup == NULL) ||
4969 _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4970 continue;
4971 }
4972 }
4973
4974 dwSize = sizeof(ENUM_SERVICE_STATUSW) +
4975 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4976 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
4977
4978 if (dwRequiredSize + dwSize > cbBufSize)
4979 break;
4980
4981 /* Copy the service name */
4982 wcscpy(lpStringPtr, CurrentService->lpServiceName);
4983 lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
4984 lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
4985
4986 /* Copy the display name */
4987 wcscpy(lpStringPtr, CurrentService->lpDisplayName);
4988 lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
4989 lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
4990
4991 /* Copy the status information */
4992 memcpy(&lpStatusPtr->ServiceStatus,
4993 &CurrentService->Status,
4994 sizeof(SERVICE_STATUS));
4995
4996 lpStatusPtr++;
4997 dwRequiredSize += dwSize;
4998 }
4999
5000 if (dwError == ERROR_SUCCESS)
5001 {
5002 *pcbBytesNeeded = 0;
5003 if (lpResumeIndex) *lpResumeIndex = 0;
5004 }
5005
5006Done:
5007 /* Unlock the service database */
5009
5010 DPRINT("REnumServiceGroupW() done (Error %lu)\n", dwError);
5011
5012 return dwError;
5013}
PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
Definition: database.c:715
BOOL ScmLockDatabaseShared(VOID)
Definition: database.c:2427
LIST_ENTRY ServiceListHead
Definition: database.c:29
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LPWSTR lpGroupName
Definition: services.h:33
PSERVICE_GROUP lpGroup
Definition: services.h:64
LIST_ENTRY ServiceListEntry
Definition: services.h:61
DWORD dwResumeCount
Definition: services.h:67
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
struct _ENUM_SERVICE_STATUSW ENUM_SERVICE_STATUSW
#define SERVICE_TYPE_ALL
Definition: cmtypes.h:969

Referenced by EnumServiceGroupW(), and REnumServicesStatusW().

◆ REnumServicesStatusA()

DWORD WINAPI REnumServicesStatusA ( SC_RPC_HANDLE  hSCManager,
DWORD  dwServiceType,
DWORD  dwServiceState,
LPBYTE  lpBuffer,
DWORD  dwBufSize,
LPBOUNDED_DWORD_256K  pcbBytesNeeded,
LPBOUNDED_DWORD_256K  lpServicesReturned,
LPBOUNDED_DWORD_256K  lpResumeHandle 
)

Definition at line 3899 of file rpcserver.c.

3908{
3909 LPENUM_SERVICE_STATUSW lpStatusPtrW = NULL;
3910 LPENUM_SERVICE_STATUSW lpStatusPtrIncrW;
3911 LPENUM_SERVICE_STATUSA lpStatusPtrA = NULL;
3912 LPWSTR lpStringPtrW;
3913 LPSTR lpStringPtrA;
3914 DWORD dwError;
3915 DWORD dwServiceCount;
3916
3917 DPRINT("REnumServicesStatusA() called\n");
3918
3919 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
3920 {
3921 return ERROR_INVALID_ADDRESS;
3922 }
3923
3924 if ((dwBufSize > 0) && (lpBuffer))
3925 {
3926 lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
3927 if (!lpStatusPtrW)
3928 {
3929 DPRINT("Failed to allocate buffer\n");
3931 }
3932 }
3933
3935 dwServiceType,
3936 dwServiceState,
3937 (LPBYTE)lpStatusPtrW,
3938 dwBufSize,
3940 lpServicesReturned,
3941 lpResumeHandle);
3942
3943 /* if no services were returned then we are Done */
3944 if (*lpServicesReturned == 0)
3945 goto Done;
3946
3947 lpStatusPtrIncrW = lpStatusPtrW;
3948 lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
3949 lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
3950 *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSA));
3951 lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
3952 *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSW));
3953
3954 for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
3955 {
3956 /* Copy the service name */
3958 0,
3959 lpStringPtrW,
3960 -1,
3961 lpStringPtrA,
3962 (int)wcslen(lpStringPtrW),
3963 0,
3964 0);
3965
3966 lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
3967 lpStringPtrA += wcslen(lpStringPtrW) + 1;
3968 lpStringPtrW += wcslen(lpStringPtrW) + 1;
3969
3970 /* Copy the display name */
3972 0,
3973 lpStringPtrW,
3974 -1,
3975 lpStringPtrA,
3976 (int)wcslen(lpStringPtrW),
3977 0,
3978 0);
3979
3980 lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
3981 lpStringPtrA += wcslen(lpStringPtrW) + 1;
3982 lpStringPtrW += wcslen(lpStringPtrW) + 1;
3983
3984 /* Copy the status information */
3985 memcpy(&lpStatusPtrA->ServiceStatus,
3986 &lpStatusPtrIncrW->ServiceStatus,
3987 sizeof(SERVICE_STATUS));
3988
3989 lpStatusPtrIncrW++;
3990 lpStatusPtrA++;
3991 }
3992
3993Done:
3994 if (lpStatusPtrW)
3995 HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
3996
3997 DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
3998
3999 return dwError;
4000}
DWORD WINAPI REnumServicesStatusW(SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD dwBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeHandle)
Definition: rpcserver.c:2842
struct _ENUM_SERVICE_STATUSA ENUM_SERVICE_STATUSA

Referenced by EnumServicesStatusA().

◆ REnumServicesStatusExA()

DWORD WINAPI REnumServicesStatusExA ( SC_RPC_HANDLE  hSCManager,
SC_ENUM_TYPE  InfoLevel,
DWORD  dwServiceType,
DWORD  dwServiceState,
LPBYTE  lpBuffer,
DWORD  cbBufSize,
LPBOUNDED_DWORD_256K  pcbBytesNeeded,
LPBOUNDED_DWORD_256K  lpServicesReturned,
LPBOUNDED_DWORD_256K  lpResumeIndex,
LPCSTR  pszGroupName 
)

Definition at line 6096 of file rpcserver.c.

6107{
6108 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrW = NULL;
6109 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrIncrW;
6110 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtrA = NULL;
6111 LPWSTR lpStringPtrW;
6112 LPSTR lpStringPtrA;
6113 LPWSTR pszGroupNameW = NULL;
6114 DWORD dwError;
6115 DWORD dwServiceCount;
6116
6117 DPRINT("REnumServicesStatusExA() called\n");
6118
6119 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
6120 {
6121 return ERROR_INVALID_ADDRESS;
6122 }
6123
6124 if (pszGroupName)
6125 {
6126 pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
6127 if (!pszGroupNameW)
6128 {
6129 DPRINT("Failed to allocate buffer\n");
6130 dwError = ERROR_NOT_ENOUGH_MEMORY;
6131 goto Done;
6132 }
6133
6135 0,
6136 pszGroupName,
6137 -1,
6138 pszGroupNameW,
6139 (int)(strlen(pszGroupName) + 1));
6140 }
6141
6142 if ((cbBufSize > 0) && (lpBuffer))
6143 {
6145 if (!lpStatusPtrW)
6146 {
6147 DPRINT("Failed to allocate buffer\n");
6148 dwError = ERROR_NOT_ENOUGH_MEMORY;
6149 goto Done;
6150 }
6151 }
6152
6154 InfoLevel,
6155 dwServiceType,
6156 dwServiceState,
6157 (LPBYTE)lpStatusPtrW,
6158 cbBufSize,
6160 lpServicesReturned,
6161 lpResumeIndex,
6162 pszGroupNameW);
6163
6164 /* if no services were returned then we are Done */
6165 if (*lpServicesReturned == 0)
6166 goto Done;
6167
6168 lpStatusPtrIncrW = lpStatusPtrW;
6170 lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
6171 *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
6172 lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
6173 *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
6174
6175 for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
6176 {
6177 /* Copy the service name */
6179 0,
6180 lpStringPtrW,
6181 -1,
6182 lpStringPtrA,
6183 (int)wcslen(lpStringPtrW),
6184 0,
6185 0);
6186
6187 lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
6188 lpStringPtrA += wcslen(lpStringPtrW) + 1;
6189 lpStringPtrW += wcslen(lpStringPtrW) + 1;
6190
6191 /* Copy the display name */
6193 0,
6194 lpStringPtrW,
6195 -1,
6196 lpStringPtrA,
6197 (int)wcslen(lpStringPtrW),
6198 0,
6199 0);
6200
6201 lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
6202 lpStringPtrA += wcslen(lpStringPtrW) + 1;
6203 lpStringPtrW += wcslen(lpStringPtrW) + 1;
6204
6205 /* Copy the status information */
6206 memcpy(&lpStatusPtrA->ServiceStatusProcess,
6207 &lpStatusPtrIncrW->ServiceStatusProcess,
6208 sizeof(SERVICE_STATUS));
6209
6210 /* Copy the service process ID */
6211 lpStatusPtrA->ServiceStatusProcess.dwProcessId = lpStatusPtrIncrW->ServiceStatusProcess.dwProcessId;
6212
6213 lpStatusPtrA->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
6214
6215 lpStatusPtrIncrW++;
6216 lpStatusPtrA++;
6217 }
6218
6219Done:
6220 if (pszGroupNameW)
6221 HeapFree(GetProcessHeap(), 0, pszGroupNameW);
6222
6223 if (lpStatusPtrW)
6224 HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
6225
6226 DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError);
6227
6228 return dwError;
6229}
DWORD WINAPI REnumServicesStatusExW(SC_RPC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCWSTR pszGroupName)
Definition: rpcserver.c:6235
SERVICE_STATUS_PROCESS ServiceStatusProcess
Definition: winsvc.h:137
SERVICE_STATUS_PROCESS ServiceStatusProcess
Definition: winsvc.h:142
struct _ENUM_SERVICE_STATUS_PROCESSA ENUM_SERVICE_STATUS_PROCESSA
struct _ENUM_SERVICE_STATUS_PROCESSA * LPENUM_SERVICE_STATUS_PROCESSA
struct _ENUM_SERVICE_STATUS_PROCESSW ENUM_SERVICE_STATUS_PROCESSW

Referenced by EnumServicesStatusExA().

◆ REnumServicesStatusExW()

DWORD WINAPI REnumServicesStatusExW ( SC_RPC_HANDLE  hSCManager,
SC_ENUM_TYPE  InfoLevel,
DWORD  dwServiceType,
DWORD  dwServiceState,
LPBYTE  lpBuffer,
DWORD  cbBufSize,
LPBOUNDED_DWORD_256K  pcbBytesNeeded,
LPBOUNDED_DWORD_256K  lpServicesReturned,
LPBOUNDED_DWORD_256K  lpResumeIndex,
LPCWSTR  pszGroupName 
)

Definition at line 6235 of file rpcserver.c.

6246{
6247 PMANAGER_HANDLE hManager;
6248 PSERVICE lpService;
6249 DWORD dwError = ERROR_SUCCESS;
6250 PLIST_ENTRY ServiceEntry;
6251 PSERVICE CurrentService;
6252 DWORD dwState;
6253 DWORD dwRequiredSize;
6254 DWORD dwServiceCount;
6255 DWORD dwSize;
6256 DWORD dwLastResumeCount = 0;
6258 LPWSTR lpStringPtr;
6259
6260 DPRINT("REnumServicesStatusExW() called\n");
6261
6262 if (ScmShutdown)
6264
6265 if (InfoLevel != SC_ENUM_PROCESS_INFO)
6266 return ERROR_INVALID_LEVEL;
6267
6269 if (hManager == NULL)
6270 {
6271 DPRINT1("Invalid service manager handle\n");
6272 return ERROR_INVALID_HANDLE;
6273 }
6274
6275 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
6276 {
6277 return ERROR_INVALID_ADDRESS;
6278 }
6279
6280 *pcbBytesNeeded = 0;
6281 *lpServicesReturned = 0;
6282
6283 if ((dwServiceType == 0) ||
6284 ((dwServiceType & ~SERVICE_TYPE_ALL) != 0))
6285 {
6286 DPRINT("Invalid Service Type\n");
6288 }
6289
6290 if ((dwServiceState == 0) ||
6291 ((dwServiceState & ~SERVICE_STATE_ALL) != 0))
6292 {
6293 DPRINT("Invalid Service State\n");
6295 }
6296
6297 /* Check access rights */
6300 {
6301 DPRINT("Insufficient access rights 0x%lx\n",
6302 hManager->Handle.DesiredAccess);
6303 return ERROR_ACCESS_DENIED;
6304 }
6305
6306 if (lpResumeIndex)
6307 dwLastResumeCount = *lpResumeIndex;
6308
6309 /* Lock the service database shared */
6311
6312 lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
6313 if (lpService == NULL)
6314 {
6315 dwError = ERROR_SUCCESS;
6316 goto Done;
6317 }
6318
6319 dwRequiredSize = 0;
6320 dwServiceCount = 0;
6321
6322 for (ServiceEntry = &lpService->ServiceListEntry;
6323 ServiceEntry != &ServiceListHead;
6324 ServiceEntry = ServiceEntry->Flink)
6325 {
6326 CurrentService = CONTAINING_RECORD(ServiceEntry,
6327 SERVICE,
6328 ServiceListEntry);
6329
6330 if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
6331 continue;
6332
6333 dwState = SERVICE_ACTIVE;
6334 if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
6335 dwState = SERVICE_INACTIVE;
6336
6337 if ((dwState & dwServiceState) == 0)
6338 continue;
6339
6340 if (pszGroupName)
6341 {
6342 if (*pszGroupName == 0)
6343 {
6344 if (CurrentService->lpGroup != NULL)
6345 continue;
6346 }
6347 else
6348 {
6349 if ((CurrentService->lpGroup == NULL) ||
6350 _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
6351 continue;
6352 }
6353 }
6354
6356 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
6357 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
6358
6359 if (dwRequiredSize + dwSize <= cbBufSize)
6360 {
6361 DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
6362 dwRequiredSize += dwSize;
6363 dwServiceCount++;
6364 dwLastResumeCount = CurrentService->dwResumeCount;
6365 }
6366 else
6367 {
6368 DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
6369 break;
6370 }
6371
6372 }
6373
6374 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
6375 DPRINT("dwServiceCount: %lu\n", dwServiceCount);
6376
6377 for (;
6378 ServiceEntry != &ServiceListHead;
6379 ServiceEntry = ServiceEntry->Flink)
6380 {
6381 CurrentService = CONTAINING_RECORD(ServiceEntry,
6382 SERVICE,
6383 ServiceListEntry);
6384
6385 if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
6386 continue;
6387
6388 dwState = SERVICE_ACTIVE;
6389 if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
6390 dwState = SERVICE_INACTIVE;
6391
6392 if ((dwState & dwServiceState) == 0)
6393 continue;
6394
6395 if (pszGroupName)
6396 {
6397 if (*pszGroupName == 0)
6398 {
6399 if (CurrentService->lpGroup != NULL)
6400 continue;
6401 }
6402 else
6403 {
6404 if ((CurrentService->lpGroup == NULL) ||
6405 _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
6406 continue;
6407 }
6408 }
6409
6410 dwRequiredSize += (sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
6411 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
6412 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
6413
6414 dwError = ERROR_MORE_DATA;
6415 }
6416
6417 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
6418
6419 if (lpResumeIndex)
6420 *lpResumeIndex = dwLastResumeCount;
6421
6422 *lpServicesReturned = dwServiceCount;
6423 *pcbBytesNeeded = dwRequiredSize;
6424
6425 /* If there was no services that matched */
6426 if ((!dwServiceCount) && (dwError != ERROR_MORE_DATA))
6427 {
6429 goto Done;
6430 }
6431
6433 lpStringPtr = (LPWSTR)((ULONG_PTR)lpBuffer +
6434 dwServiceCount * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
6435
6436 dwRequiredSize = 0;
6437 for (ServiceEntry = &lpService->ServiceListEntry;
6438 ServiceEntry != &ServiceListHead;
6439 ServiceEntry = ServiceEntry->Flink)
6440 {
6441 CurrentService = CONTAINING_RECORD(ServiceEntry,
6442 SERVICE,
6443 ServiceListEntry);
6444
6445 if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
6446 continue;
6447
6448 dwState = SERVICE_ACTIVE;
6449 if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
6450 dwState = SERVICE_INACTIVE;
6451
6452 if ((dwState & dwServiceState) == 0)
6453 continue;
6454
6455 if (pszGroupName)
6456 {
6457 if (*pszGroupName == 0)
6458 {
6459 if (CurrentService->lpGroup != NULL)
6460 continue;
6461 }
6462 else
6463 {
6464 if ((CurrentService->lpGroup == NULL) ||
6465 _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
6466 continue;
6467 }
6468 }
6469
6471 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
6472 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
6473
6474 if (dwRequiredSize + dwSize <= cbBufSize)
6475 {
6476 /* Copy the service name */
6477 wcscpy(lpStringPtr,
6478 CurrentService->lpServiceName);
6479 lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
6480 lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
6481
6482 /* Copy the display name */
6483 wcscpy(lpStringPtr,
6484 CurrentService->lpDisplayName);
6485 lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
6486 lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
6487
6488 /* Copy the status information */
6489 memcpy(&lpStatusPtr->ServiceStatusProcess,
6490 &CurrentService->Status,
6491 sizeof(SERVICE_STATUS));
6492
6493 /* Copy the service process ID */
6494 if ((CurrentService->Status.dwCurrentState == SERVICE_STOPPED) || (CurrentService->lpImage == NULL))
6495 lpStatusPtr->ServiceStatusProcess.dwProcessId = 0;
6496 else
6497 lpStatusPtr->ServiceStatusProcess.dwProcessId = CurrentService->lpImage->dwProcessId;
6498
6499 lpStatusPtr->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
6500
6501 lpStatusPtr++;
6502 dwRequiredSize += dwSize;
6503 }
6504 else
6505 {
6506 break;
6507 }
6508 }
6509
6510 if (dwError == 0)
6511 {
6512 *pcbBytesNeeded = 0;
6513 if (lpResumeIndex)
6514 *lpResumeIndex = 0;
6515 }
6516
6517Done:
6518 /* Unlock the service database */
6520
6521 DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError);
6522
6523 return dwError;
6524}
DWORD dwProcessId
Definition: services.h:53
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:611
struct _ENUM_SERVICE_STATUS_PROCESSW * LPENUM_SERVICE_STATUS_PROCESSW
@ SC_ENUM_PROCESS_INFO
Definition: winsvc.h:122

Referenced by EnumServicesStatusExW(), and REnumServicesStatusExA().

◆ REnumServicesStatusW()

DWORD WINAPI REnumServicesStatusW ( SC_RPC_HANDLE  hSCManager,
DWORD  dwServiceType,
DWORD  dwServiceState,
LPBYTE  lpBuffer,
DWORD  dwBufSize,
LPBOUNDED_DWORD_256K  pcbBytesNeeded,
LPBOUNDED_DWORD_256K  lpServicesReturned,
LPBOUNDED_DWORD_256K  lpResumeHandle 
)

Definition at line 2842 of file rpcserver.c.

2851{
2852 /* Enumerate all the services, not regarding of their group */
2854 dwServiceType,
2855 dwServiceState,
2856 lpBuffer,
2857 dwBufSize,
2859 lpServicesReturned,
2860 lpResumeHandle,
2861 NULL);
2862}
DWORD WINAPI REnumServiceGroupW(SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCWSTR pszGroupName)
Definition: rpcserver.c:4753

Referenced by EnumServiceGroupW(), EnumServicesStatusW(), and REnumServicesStatusA().

◆ RFunction55()

DWORD WINAPI RFunction55 ( handle_t  BindingHandle)

Definition at line 6767 of file rpcserver.c.

6769{
6772}

◆ RGetNotifyResults()

DWORD WINAPI RGetNotifyResults ( SC_NOTIFY_RPC_HANDLE  hNotify,
PSC_RPC_NOTIFY_PARAMS_LIST ppNotifyParams 
)

Definition at line 6653 of file rpcserver.c.

6656{
6659}

◆ RGetServiceDisplayNameA()

DWORD WINAPI RGetServiceDisplayNameA ( SC_RPC_HANDLE  hSCManager,
LPCSTR  lpServiceName,
LPSTR  lpDisplayName,
LPBOUNDED_DWORD_4K  lpcchBuffer 
)

Definition at line 4460 of file rpcserver.c.

4465{
4466 // PMANAGER_HANDLE hManager;
4467 PSERVICE lpService = NULL;
4468 LPCWSTR lpSvcDisplayName;
4469 LPWSTR lpServiceNameW;
4471
4472 DPRINT("RGetServiceDisplayNameA() called\n");
4473 DPRINT("hSCManager = %p\n", hSCManager);
4474 DPRINT("lpServiceName: %s\n", lpServiceName);
4475 DPRINT("lpDisplayName: %p\n", lpDisplayName);
4476 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
4477
4478#if 0
4479 hManager = (PMANAGER_HANDLE)hSCManager;
4480 if (hManager->Handle.Tag != MANAGER_TAG)
4481 {
4482 DPRINT("Invalid manager handle\n");
4483 return ERROR_INVALID_HANDLE;
4484 }
4485#endif
4486
4487 /* Get service database entry */
4488 if (lpServiceName != NULL)
4489 {
4490 dwLength = (DWORD)(strlen(lpServiceName) + 1);
4491 lpServiceNameW = HeapAlloc(GetProcessHeap(),
4493 dwLength * sizeof(WCHAR));
4494 if (!lpServiceNameW)
4496
4498 0,
4499 lpServiceName,
4500 -1,
4501 lpServiceNameW,
4502 dwLength);
4503
4504 lpService = ScmGetServiceEntryByName(lpServiceNameW);
4505
4506 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
4507 }
4508
4509 if (lpService == NULL)
4510 {
4511 DPRINT("Could not find service\n");
4513 }
4514
4515 if (lpService->lpDisplayName)
4516 lpSvcDisplayName = lpService->lpDisplayName;
4517 else
4518 lpSvcDisplayName = lpService->lpServiceName;
4519
4520 /*
4521 * NOTE: On Windows the comparison on *lpcchBuffer is made against
4522 * the number of (wide) characters of the UNICODE display name, and
4523 * not against the number of bytes needed to store the ANSI string.
4524 */
4525 dwLength = (DWORD)wcslen(lpSvcDisplayName);
4526
4527 if (*lpcchBuffer > dwLength)
4528 {
4529 if (lpDisplayName != NULL &&
4531 0,
4532 lpSvcDisplayName,
4533 -1,
4535 (int)*lpcchBuffer,
4536 NULL,
4537 NULL) == 0)
4538 {
4539 /*
4540 * But then, if *lpcchBuffer was greater than the number of
4541 * (wide) characters of the UNICODE display name, yet smaller
4542 * than the number of bytes needed due to the possible presence
4543 * of DBCS characters, the *exact* number of bytes is returned
4544 * (without the NULL terminator).
4545 */
4547 0,
4548 lpSvcDisplayName,
4549 (int)dwLength,
4550 NULL,
4551 0,
4552 NULL,
4553 NULL);
4554 *lpDisplayName = 0;
4555 *lpcchBuffer = dwLength;
4557 }
4558
4559 /*
4560 * NOTE: On Windows, RGetServiceDisplayNameA() does not update
4561 * *lpcchBuffer on success, contrary to RGetServiceDisplayNameW().
4562 */
4563 return ERROR_SUCCESS;
4564 }
4565 else
4566 {
4567 /*
4568 * NOTE: On Windows, if *lpcchBuffer is smaller than the number of
4569 * (wide) characters of the UNICODE display name, only an upper
4570 * estimation is returned by doubling the string length, to account
4571 * for the presence of any possible DBCS characters.
4572 */
4573 *lpcchBuffer = dwLength * sizeof(WCHAR);
4575 }
4576}
struct _MANAGER_HANDLE * PMANAGER_HANDLE
#define MANAGER_TAG
Definition: rpcserver.c:25
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by GetServiceDisplayNameA().

◆ RGetServiceDisplayNameW()

DWORD WINAPI RGetServiceDisplayNameW ( SC_RPC_HANDLE  hSCManager,
LPCWSTR  lpServiceName,
LPWSTR  lpDisplayName,
DWORD lpcchBuffer 
)

Definition at line 3317 of file rpcserver.c.

3322{
3323 // PMANAGER_HANDLE hManager;
3324 PSERVICE lpService;
3325 LPCWSTR lpSvcDisplayName;
3327 DWORD dwError;
3328
3329 DPRINT("RGetServiceDisplayNameW() called\n");
3330 DPRINT("hSCManager = %p\n", hSCManager);
3331 DPRINT("lpServiceName: %S\n", lpServiceName);
3332 DPRINT("lpDisplayName: %p\n", lpDisplayName);
3333 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
3334
3335#if 0
3336 hManager = (PMANAGER_HANDLE)hSCManager;
3337 if (hManager->Handle.Tag != MANAGER_TAG)
3338 {
3339 DPRINT("Invalid manager handle\n");
3340 return ERROR_INVALID_HANDLE;
3341 }
3342#endif
3343
3344 /* Get service database entry */
3345 lpService = ScmGetServiceEntryByName(lpServiceName);
3346 if (lpService == NULL)
3347 {
3348 DPRINT("Could not find service\n");
3350 }
3351
3352 if (lpService->lpDisplayName)
3353 lpSvcDisplayName = lpService->lpDisplayName;
3354 else
3355 lpSvcDisplayName = lpService->lpServiceName;
3356
3357 dwLength = (DWORD)wcslen(lpSvcDisplayName);
3358
3359 if (*lpcchBuffer > dwLength)
3360 {
3361 if (lpDisplayName != NULL)
3362 wcscpy(lpDisplayName, lpSvcDisplayName);
3363
3364 dwError = ERROR_SUCCESS;
3365 }
3366 else
3367 {
3368 dwError = ERROR_INSUFFICIENT_BUFFER;
3369 }
3370
3371 *lpcchBuffer = dwLength;
3372
3373 return dwError;
3374}

Referenced by GetServiceDisplayNameW().

◆ RGetServiceKeyNameA()

DWORD WINAPI RGetServiceKeyNameA ( SC_RPC_HANDLE  hSCManager,
LPCSTR  lpDisplayName,
LPSTR  lpServiceName,
LPBOUNDED_DWORD_4K  lpcchBuffer 
)

Definition at line 4582 of file rpcserver.c.

4587{
4588 // PMANAGER_HANDLE hManager;
4589 PSERVICE lpService;
4590 LPWSTR lpDisplayNameW;
4592
4593 DPRINT("RGetServiceKeyNameA() called\n");
4594 DPRINT("hSCManager = %p\n", hSCManager);
4595 DPRINT("lpDisplayName: %s\n", lpDisplayName);
4596 DPRINT("lpServiceName: %p\n", lpServiceName);
4597 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
4598
4599#if 0
4600 hManager = (PMANAGER_HANDLE)hSCManager;
4601 if (hManager->Handle.Tag != MANAGER_TAG)
4602 {
4603 DPRINT("Invalid manager handle\n");
4604 return ERROR_INVALID_HANDLE;
4605 }
4606#endif
4607
4608 /* Get service database entry */
4609
4611 lpDisplayNameW = HeapAlloc(GetProcessHeap(),
4613 dwLength * sizeof(WCHAR));
4614 if (!lpDisplayNameW)
4616
4618 0,
4620 -1,
4621 lpDisplayNameW,
4622 dwLength);
4623
4624 lpService = ScmGetServiceEntryByDisplayName(lpDisplayNameW);
4625
4626 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
4627
4628 if (lpService == NULL)
4629 {
4630 DPRINT("Could not find service\n");
4632 }
4633
4634 /*
4635 * NOTE: On Windows the comparison on *lpcchBuffer is made against
4636 * the number of (wide) characters of the UNICODE service name, and
4637 * not against the number of bytes needed to store the ANSI string.
4638 */
4639 dwLength = (DWORD)wcslen(lpService->lpServiceName);
4640
4641 if (*lpcchBuffer > dwLength)
4642 {
4643 if (lpServiceName != NULL &&
4645 0,
4646 lpService->lpServiceName,
4647 -1,
4648 lpServiceName,
4649 (int)*lpcchBuffer,
4650 NULL,
4651 NULL) == 0)
4652 {
4653 /*
4654 * But then, if *lpcchBuffer was greater than the number of
4655 * (wide) characters of the UNICODE service name, yet smaller
4656 * than the number of bytes needed due to the possible presence
4657 * of DBCS characters, the *exact* number of bytes is returned
4658 * (without the NULL terminator).
4659 */
4661 0,
4662 lpService->lpServiceName,
4663 (int)dwLength,
4664 NULL,
4665 0,
4666 NULL,
4667 NULL);
4668 *lpServiceName = 0;
4669 *lpcchBuffer = dwLength;
4671 }
4672
4673 /*
4674 * NOTE: On Windows, RGetServiceKeyNameA() does not update
4675 * *lpcchBuffer on success, contrary to RGetServiceKeyNameW().
4676 */
4677 return ERROR_SUCCESS;
4678 }
4679 else
4680 {
4681 /*
4682 * NOTE: On Windows, if *lpcchBuffer is smaller than the number of
4683 * (wide) characters of the UNICODE service name, only an upper
4684 * estimation is returned by doubling the string length, to account
4685 * for the presence of any possible DBCS characters.
4686 */
4687 *lpcchBuffer = dwLength * sizeof(WCHAR);
4689 }
4690}

Referenced by GetServiceKeyNameA().

◆ RGetServiceKeyNameW()

DWORD WINAPI RGetServiceKeyNameW ( SC_RPC_HANDLE  hSCManager,
LPCWSTR  lpDisplayName,
LPWSTR  lpServiceName,
DWORD lpcchBuffer 
)

Definition at line 3380 of file rpcserver.c.

3385{
3386 // PMANAGER_HANDLE hManager;
3387 PSERVICE lpService;
3389 DWORD dwError;
3390
3391 DPRINT("RGetServiceKeyNameW() called\n");
3392 DPRINT("hSCManager = %p\n", hSCManager);
3393 DPRINT("lpDisplayName: %S\n", lpDisplayName);
3394 DPRINT("lpServiceName: %p\n", lpServiceName);
3395 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
3396
3397#if 0
3398 hManager = (PMANAGER_HANDLE)hSCManager;
3399 if (hManager->Handle.Tag != MANAGER_TAG)
3400 {
3401 DPRINT("Invalid manager handle\n");
3402 return ERROR_INVALID_HANDLE;
3403 }
3404#endif
3405
3406 /* Get service database entry */
3408 if (lpService == NULL)
3409 {
3410 DPRINT("Could not find service\n");
3412 }
3413
3414 dwLength = (DWORD)wcslen(lpService->lpServiceName);
3415
3416 if (*lpcchBuffer > dwLength)
3417 {
3418 if (lpServiceName != NULL)
3419 wcscpy(lpServiceName, lpService->lpServiceName);
3420
3421 dwError = ERROR_SUCCESS;
3422 }
3423 else
3424 {
3425 dwError = ERROR_INSUFFICIENT_BUFFER;
3426 }
3427
3428 *lpcchBuffer = dwLength;
3429
3430 return dwError;
3431}

Referenced by GetServiceKeyNameW().

◆ RI_ScGetCurrentGroupStateW()

DWORD WINAPI RI_ScGetCurrentGroupStateW ( SC_RPC_HANDLE  hSCManager,
LPWSTR  lpLoadOrderGroup,
LPDWORD  lpState 
)

Definition at line 4696 of file rpcserver.c.

4700{
4701 PMANAGER_HANDLE hManager;
4702 PSERVICE_GROUP pServiceGroup;
4703 DWORD dwError = ERROR_SUCCESS;
4704
4705 DPRINT("RI_ScGetCurrentGroupStateW() called\n");
4706
4707 if (ScmShutdown)
4709
4711 if (hManager == NULL)
4712 {
4713 DPRINT1("Invalid service manager handle\n");
4714 return ERROR_INVALID_HANDLE;
4715 }
4716
4717 /* Check for SC_MANAGER_ENUMERATE_SERVICE access right */
4720 {
4721 DPRINT("Insufficient access rights! 0x%lx\n",
4722 hManager->Handle.DesiredAccess);
4723 return ERROR_ACCESS_DENIED;
4724 }
4725
4726 /* Lock the service database shared */
4728
4729 /* Get the group list entry */
4730 pServiceGroup = ScmGetServiceGroupByName(lpLoadOrderGroup);
4731 if (pServiceGroup == NULL)
4732 {
4734 goto done;
4735 }
4736
4737 /* FIXME: Return the group state */
4738 *lpState = 0;
4739
4740done:
4741 /* Unlock the service database */
4743
4744 DPRINT("RI_ScGetCurrentGroupStateW() done (Error %lu)\n", dwError);
4745
4746 return dwError;
4747}
PSERVICE_GROUP ScmGetServiceGroupByName(_In_ LPCWSTR lpGroupName)
Definition: groupdb.c:26

Referenced by I_ScGetCurrentGroupStateW().

◆ RI_ScQueryServiceTagInfo()

DWORD WINAPI RI_ScQueryServiceTagInfo ( SC_RPC_HANDLE  hSCManager,
TAG_INFO_LEVEL  dwInfoLevel,
PTAG_INFO_NAME_FROM_TAG_IN_PARAMS lpInParams,
PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS lpOutParams 
)

Definition at line 6593 of file rpcserver.c.

6598{
6599 PMANAGER_HANDLE hManager;
6600
6601 /* Validate handle */
6603 if (hManager == NULL)
6604 {
6605 return ERROR_INVALID_HANDLE;
6606 }
6607
6608 /* FIXME: should check whether client is local */
6609
6610 /* Check access rights */
6613 {
6614 return ERROR_ACCESS_DENIED;
6615 }
6616
6617 /* Check parameters */
6618 if (lpInParams == NULL || lpOutParams == NULL)
6619 {
6621 }
6622
6623 /* Check info level */
6625 {
6626 return ERROR_RETRY;
6627 }
6628
6629 /* Call internal helper */
6630 return ScmGetServiceNameFromTag(*lpInParams, lpOutParams);
6631}
DWORD ScmGetServiceNameFromTag(IN PTAG_INFO_NAME_FROM_TAG_IN_PARAMS InParams, OUT PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS *OutParams)
Definition: database.c:183
@ TagInfoLevelNameFromTag
Definition: svcctl.idl:300
#define ERROR_RETRY
Definition: winerror.h:740
_In_ DWORD dwInfoLevel
Definition: winsvc.h:422

Referenced by I_ScQueryServiceTagInfo().

◆ RI_ScSetServiceBitsA()

DWORD WINAPI RI_ScSetServiceBitsA ( RPC_SERVICE_STATUS_HANDLE  hServiceStatus,
DWORD  dwServiceBits,
int  bSetBitsOn,
int  bUpdateImmediately,
char lpString 
)

Definition at line 3437 of file rpcserver.c.

3443{
3444 if (ScmShutdown)
3446
3447 if (lpString != NULL)
3449
3452 bSetBitsOn,
3453 bUpdateImmediately,
3454 NULL);
3455}
DWORD dwServiceBits
Definition: srvsvc.c:40
DWORD WINAPI RI_ScSetServiceBitsW(RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, wchar_t *lpString)
Definition: rpcserver.c:1866
SERVICE_STATUS_HANDLE hServiceStatus
Definition: main.c:10

Referenced by I_ScSetServiceBitsA().

◆ RI_ScSetServiceBitsW()

DWORD WINAPI RI_ScSetServiceBitsW ( RPC_SERVICE_STATUS_HANDLE  hServiceStatus,
DWORD  dwServiceBits,
int  bSetBitsOn,
int  bUpdateImmediately,
wchar_t lpString 
)

Definition at line 1866 of file rpcserver.c.

1872{
1873 PSERVICE pService;
1874
1875 DPRINT("RI_ScSetServiceBitsW(%p %lx %d %d %S)\n",
1876 hServiceStatus, dwServiceBits, bSetBitsOn,
1877 bUpdateImmediately, lpString);
1878
1879 if (ScmShutdown)
1881
1882 if (lpString != NULL)
1884
1885 if (hServiceStatus == 0)
1886 {
1887 DPRINT("hServiceStatus == NULL\n");
1888 return ERROR_INVALID_HANDLE;
1889 }
1890
1891 // FIXME: Validate the status handle
1892 pService = (PSERVICE)hServiceStatus;
1893
1894 if (bSetBitsOn)
1895 {
1896 DPRINT("Old service bits: %08lx\n", pService->dwServiceBits);
1897 DPRINT("Old global service bits: %08lx\n", g_dwServiceBits);
1898 pService->dwServiceBits |= dwServiceBits;
1900 DPRINT("New service bits: %08lx\n", pService->dwServiceBits);
1901 DPRINT("New global service bits: %08lx\n", g_dwServiceBits);
1902 }
1903 else
1904 {
1905 DPRINT("Old service bits: %08lx\n", pService->dwServiceBits);
1906 DPRINT("Old global service bits: %08lx\n", g_dwServiceBits);
1907 pService->dwServiceBits &= ~dwServiceBits;
1908 g_dwServiceBits &= ~dwServiceBits;
1909 DPRINT("New service bits: %08lx\n", pService->dwServiceBits);
1910 DPRINT("New global service bits: %08lx\n", g_dwServiceBits);
1911 }
1912
1913 return ERROR_SUCCESS;
1914}
DWORD g_dwServiceBits
Definition: rpcserver.c:102
struct _SERVICE * PSERVICE
DWORD dwServiceBits
Definition: services.h:75

Referenced by I_ScSetServiceBitsW(), and RI_ScSetServiceBitsA().

◆ RI_ScValidatePnPService()

DWORD WINAPI RI_ScValidatePnPService ( _In_ SC_RPC_HANDLE  hSCManager,
_In_ LPWSTR  pszServiceName,
_Out_ RPC_SERVICE_STATUS_HANDLE phServiceStatus 
)

Definition at line 6714 of file rpcserver.c.

6718{
6719 PMANAGER_HANDLE hManager;
6720 PSERVICE pService;
6721
6722 DPRINT("RI_ScValidatePnPService(%p %S %p)\n", hSCManager, pszServiceName, phServiceStatus);
6723
6724 /* Validate handle */
6726 if (hManager == NULL)
6727 {
6728 DPRINT1("Invalid handle!\n");
6729 return ERROR_INVALID_HANDLE;
6730 }
6731
6732 /* FIXME: should check whether client is local */
6733
6734 /* Check access rights */
6737 {
6738 DPRINT1("No SC_MANAGER_CONNECT access!\n");
6739 return ERROR_ACCESS_DENIED;
6740 }
6741
6742 pService = ScmGetServiceEntryByName(pszServiceName);
6743 DPRINT("pService: %p\n", pService);
6744 if (pService == NULL)
6746
6747 *phServiceStatus = (RPC_SERVICE_STATUS_HANDLE)pService;
6748
6749 return ERROR_SUCCESS;
6750}
ULONG_PTR RPC_SERVICE_STATUS_HANDLE
Definition: svcctl.idl:20

Referenced by I_ScValidatePnpService().

◆ RLockServiceDatabase()

DWORD WINAPI RLockServiceDatabase ( SC_RPC_HANDLE  hSCManager,
LPSC_RPC_LOCK  lpLock 
)

Definition at line 1362 of file rpcserver.c.

1365{
1366 PMANAGER_HANDLE hMgr;
1367
1368 DPRINT("RLockServiceDatabase() called\n");
1369
1370 *lpLock = NULL;
1371
1373 if (hMgr == NULL)
1374 {
1375 DPRINT1("Invalid service manager handle\n");
1376 return ERROR_INVALID_HANDLE;
1377 }
1378
1381 return ERROR_ACCESS_DENIED;
1382
1383 return ScmAcquireServiceStartLock(FALSE, lpLock);
1384}
DWORD ScmAcquireServiceStartLock(IN BOOL IsServiceController, OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:31
#define FALSE
Definition: types.h:117

Referenced by LockServiceDatabase().

◆ RNotifyBootConfigStatus()

DWORD WINAPI RNotifyBootConfigStatus ( SVCCTL_HANDLEW  lpMachineName,
DWORD  BootAcceptable 
)

Definition at line 1849 of file rpcserver.c.

1852{
1853 DPRINT("RNotifyBootConfigStatus(%p %lu)\n",
1854 lpMachineName, BootAcceptable);
1855
1856 if (BootAcceptable)
1857 return ScmAcceptBoot();
1858
1859 return ScmRunLastKnownGood();
1860}
DWORD ScmRunLastKnownGood(VOID)
Definition: controlset.c:402
DWORD ScmAcceptBoot(VOID)
Definition: controlset.c:336

Referenced by NotifyBootConfigStatus().

◆ RNotifyServiceStatusChange()

DWORD WINAPI RNotifyServiceStatusChange ( SC_RPC_HANDLE  hService,
SC_RPC_NOTIFY_PARAMS  NotifyParams,
GUID pClientProcessGuid,
GUID pSCMProcessGuid,
PBOOL  pfCreateRemoteQueue,
LPSC_NOTIFY_RPC_HANDLE  phNotify 
)

Definition at line 6637 of file rpcserver.c.

6644{
6647}

◆ ROpenSCManagerA()

DWORD WINAPI ROpenSCManagerA ( LPSTR  lpMachineName,
LPSTR  lpDatabaseName,
DWORD  dwDesiredAccess,
LPSC_RPC_HANDLE  lpScHandle 
)

Definition at line 4006 of file rpcserver.c.

4011{
4013 UNICODE_STRING DatabaseName;
4014 DWORD dwError;
4015
4016 DPRINT("ROpenSCManagerA() called\n");
4017
4018 if (lpMachineName)
4020 lpMachineName);
4021
4022 if (lpDatabaseName)
4024 lpDatabaseName);
4025
4026 dwError = ROpenSCManagerW(lpMachineName ? MachineName.Buffer : NULL,
4027 lpDatabaseName ? DatabaseName.Buffer : NULL,
4028 dwDesiredAccess,
4029 lpScHandle);
4030
4031 if (lpMachineName)
4033
4034 if (lpDatabaseName)
4035 RtlFreeUnicodeString(&DatabaseName);
4036
4037 return dwError;
4038}
DWORD WINAPI ROpenSCManagerW(LPWSTR lpMachineName, LPWSTR lpDatabaseName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpScHandle)
Definition: rpcserver.c:2868
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ DWORD _Out_ PDWORD _In_opt_ PCSTR MachineName
Definition: setupapi.h:1293

Referenced by OpenSCManagerA().

◆ ROpenSCManagerW()

DWORD WINAPI ROpenSCManagerW ( LPWSTR  lpMachineName,
LPWSTR  lpDatabaseName,
DWORD  dwDesiredAccess,
LPSC_RPC_HANDLE  lpScHandle 
)

Definition at line 2868 of file rpcserver.c.

2873{
2874 DWORD dwError;
2875 SC_HANDLE hHandle;
2876
2877 DPRINT("ROpenSCManagerW() called\n");
2878 DPRINT("lpMachineName = %p\n", lpMachineName);
2879 DPRINT("lpMachineName: %S\n", lpMachineName);
2880 DPRINT("lpDataBaseName = %p\n", lpDatabaseName);
2881 DPRINT("lpDataBaseName: %S\n", lpDatabaseName);
2882 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
2883
2884 if (ScmShutdown)
2886
2887 if (!lpScHandle)
2889
2890 dwError = ScmCreateManagerHandle(lpDatabaseName,
2891 &hHandle);
2892 if (dwError != ERROR_SUCCESS)
2893 {
2894 DPRINT("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
2895 return dwError;
2896 }
2897
2898 /* Check the desired access */
2899 dwError = ScmCheckAccess(hHandle,
2900 dwDesiredAccess | SC_MANAGER_CONNECT);
2901 if (dwError != ERROR_SUCCESS)
2902 {
2903 DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
2904 HeapFree(GetProcessHeap(), 0, hHandle);
2905 return dwError;
2906 }
2907
2908 *lpScHandle = (SC_RPC_HANDLE)hHandle;
2909 DPRINT("*hScm = %p\n", *lpScHandle);
2910
2911 DPRINT("ROpenSCManagerW() done\n");
2912
2913 return ERROR_SUCCESS;
2914}
static DWORD ScmCreateManagerHandle(LPWSTR lpDatabaseName, SC_HANDLE *Handle)
Definition: rpcserver.c:144

Referenced by OpenSCManagerW(), and ROpenSCManagerA().

◆ ROpenServiceA()

DWORD WINAPI ROpenServiceA ( SC_RPC_HANDLE  hSCManager,
LPSTR  lpServiceName,
DWORD  dwDesiredAccess,
LPSC_RPC_HANDLE  lpServiceHandle 
)

Definition at line 4044 of file rpcserver.c.

4049{
4051 DWORD dwError;
4052
4053 DPRINT("ROpenServiceA() called\n");
4054
4055 if (lpServiceName)
4057 lpServiceName);
4058
4059 dwError = ROpenServiceW(hSCManager,
4060 lpServiceName ? ServiceName.Buffer : NULL,
4061 dwDesiredAccess,
4062 lpServiceHandle);
4063
4064 if (lpServiceName)
4066
4067 return dwError;
4068}
static WCHAR ServiceName[]
Definition: browser.c:19
DWORD WINAPI ROpenServiceW(SC_RPC_HANDLE hSCManager, LPWSTR lpServiceName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpServiceHandle)
Definition: rpcserver.c:2920

Referenced by OpenServiceA().

◆ ROpenServiceStatusHandle()

DWORD WINAPI ROpenServiceStatusHandle ( handle_t  BindingHandle)

Definition at line 6756 of file rpcserver.c.

6758{
6761}

◆ ROpenServiceW()

DWORD WINAPI ROpenServiceW ( SC_RPC_HANDLE  hSCManager,
LPWSTR  lpServiceName,
DWORD  dwDesiredAccess,
LPSC_RPC_HANDLE  lpServiceHandle 
)

Definition at line 2920 of file rpcserver.c.

2925{
2926 PSERVICE lpService;
2927 PMANAGER_HANDLE hManager;
2928 SC_HANDLE hHandle;
2929 DWORD dwError = ERROR_SUCCESS;
2930
2931 DPRINT("ROpenServiceW() called\n");
2932 DPRINT("hSCManager = %p\n", hSCManager);
2933 DPRINT("lpServiceName = %p\n", lpServiceName);
2934 DPRINT("lpServiceName: %S\n", lpServiceName);
2935 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
2936
2937 if (ScmShutdown)
2939
2941 if (hManager == NULL)
2942 {
2943 DPRINT1("Invalid service manager handle\n");
2944 return ERROR_INVALID_HANDLE;
2945 }
2946
2947 if (!lpServiceHandle)
2949
2950 if (!lpServiceName)
2951 return ERROR_INVALID_ADDRESS;
2952
2953 /* Lock the service database exclusive */
2955
2956 /* Get service database entry */
2957 lpService = ScmGetServiceEntryByName(lpServiceName);
2958 if (lpService == NULL)
2959 {
2960 DPRINT("Could not find service\n");
2962 goto Done;
2963 }
2964
2965 /* Create a service handle */
2966 dwError = ScmCreateServiceHandle(lpService,
2967 &hHandle);
2968 if (dwError != ERROR_SUCCESS)
2969 {
2970 DPRINT("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
2971 goto Done;
2972 }
2973
2974 /* Check the desired access */
2975 dwError = ScmCheckAccess(hHandle,
2976 dwDesiredAccess);
2977 if (dwError != ERROR_SUCCESS)
2978 {
2979 DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
2980 HeapFree(GetProcessHeap(), 0, hHandle);
2981 goto Done;
2982 }
2983
2984 lpService->dwRefCount++;
2985 DPRINT("OpenService - lpService->dwRefCount %u\n",lpService->dwRefCount);
2986
2987 *lpServiceHandle = (SC_RPC_HANDLE)hHandle;
2988 DPRINT("*hService = %p\n", *lpServiceHandle);
2989
2990Done:
2991 /* Unlock the service database */
2993
2994 DPRINT("ROpenServiceW() done\n");
2995
2996 return dwError;
2997}

Referenced by OpenServiceW(), and ROpenServiceA().

◆ RQueryServiceConfig2A()

DWORD WINAPI RQueryServiceConfig2A ( SC_RPC_HANDLE  hService,
DWORD  dwInfoLevel,
LPBYTE  lpBuffer,
DWORD  cbBufSize,
LPBOUNDED_DWORD_8K  pcbBytesNeeded 
)

Definition at line 5552 of file rpcserver.c.

5558{
5559 DWORD dwError = ERROR_SUCCESS;
5560 PSERVICE_HANDLE hSvc;
5561 PSERVICE lpService = NULL;
5562 HKEY hServiceKey = NULL;
5563 DWORD dwRequiredSize = 0;
5564 DWORD dwType = 0;
5565 LPWSTR lpDescriptionW = NULL;
5566 LPWSTR lpRebootMessageW = NULL;
5567 LPWSTR lpFailureCommandW = NULL;
5568
5569 DPRINT("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",
5571
5572 if (!lpBuffer)
5573 return ERROR_INVALID_ADDRESS;
5574
5575 if (ScmShutdown)
5577
5580 {
5581 return ERROR_INVALID_LEVEL;
5582 }
5583
5584 hSvc = ScmGetServiceFromHandle(hService);
5585 if (hSvc == NULL)
5586 {
5587 DPRINT1("Invalid service handle\n");
5588 return ERROR_INVALID_HANDLE;
5589 }
5590
5593 {
5594 DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
5595 return ERROR_ACCESS_DENIED;
5596 }
5597
5598 lpService = hSvc->ServiceEntry;
5599 if (lpService == NULL)
5600 {
5601 DPRINT("lpService == NULL\n");
5602 return ERROR_INVALID_HANDLE;
5603 }
5604
5605 /* Lock the service database shared */
5607
5608 dwError = ScmOpenServiceKey(lpService->lpServiceName,
5609 KEY_READ,
5610 &hServiceKey);
5611 if (dwError != ERROR_SUCCESS)
5612 goto done;
5613
5615 {
5617 LPSTR lpStr;
5618
5619 dwError = ScmReadString(hServiceKey,
5620 L"Description",
5621 &lpDescriptionW);
5622 if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
5623 goto done;
5624
5626 if (dwError == ERROR_SUCCESS)
5627 *pcbBytesNeeded += (DWORD)((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
5628
5630 {
5631 dwError = ERROR_INSUFFICIENT_BUFFER;
5632 goto done;
5633 }
5634
5635 if (dwError == ERROR_SUCCESS)
5636 {
5637 lpStr = (LPSTR)(lpServiceDescription + 1);
5638
5640 0,
5641 lpDescriptionW,
5642 -1,
5643 lpStr,
5644 (int)wcslen(lpDescriptionW),
5645 NULL,
5646 NULL);
5647 lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
5648 }
5649 else
5650 {
5651 lpServiceDescription->lpDescription = NULL;
5652 dwError = ERROR_SUCCESS;
5653 }
5654 }
5656 {
5658 LPSTR lpStr = NULL;
5659
5660 /* Query value length */
5661 dwError = RegQueryValueExW(hServiceKey,
5662 L"FailureActions",
5663 NULL,
5664 &dwType,
5665 NULL,
5666 &dwRequiredSize);
5667 if (dwError != ERROR_SUCCESS &&
5668 dwError != ERROR_MORE_DATA &&
5669 dwError != ERROR_FILE_NOT_FOUND)
5670 {
5671 goto done;
5672 }
5673
5674 dwRequiredSize = (dwType == REG_BINARY) ? max(sizeof(SERVICE_FAILURE_ACTIONSA), dwRequiredSize)
5675 : sizeof(SERVICE_FAILURE_ACTIONSA);
5676
5677 /* Get the strings */
5678 ScmReadString(hServiceKey,
5679 L"FailureCommand",
5680 &lpFailureCommandW);
5681
5682 ScmReadString(hServiceKey,
5683 L"RebootMessage",
5684 &lpRebootMessageW);
5685
5686 if (lpRebootMessageW)
5687 dwRequiredSize += (DWORD)((wcslen(lpRebootMessageW) + 1) * sizeof(WCHAR));
5688
5689 if (lpFailureCommandW)
5690 dwRequiredSize += (DWORD)((wcslen(lpFailureCommandW) + 1) * sizeof(WCHAR));
5691
5692 if (cbBufSize < dwRequiredSize)
5693 {
5694 *pcbBytesNeeded = dwRequiredSize;
5695 dwError = ERROR_INSUFFICIENT_BUFFER;
5696 goto done;
5697 }
5698
5699 /* Now we can fill the buffer */
5700 if (dwError != ERROR_FILE_NOT_FOUND && dwType == REG_BINARY)
5701 {
5702 dwError = RegQueryValueExW(hServiceKey,
5703 L"FailureActions",
5704 NULL,
5705 NULL,
5706 (LPBYTE)lpFailureActions,
5707 &dwRequiredSize);
5708 if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
5709 goto done;
5710
5711 if (dwRequiredSize < sizeof(SERVICE_FAILURE_ACTIONSA))
5712 dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSA);
5713 }
5714 else
5715 {
5716 /*
5717 * The value of the error doesn't really matter, the only
5718 * important thing is that it must be != ERROR_SUCCESS .
5719 */
5720 dwError = ERROR_INVALID_DATA;
5721 }
5722
5723 if (dwError == ERROR_SUCCESS)
5724 {
5725 lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - sizeof(SERVICE_FAILURE_ACTIONSA)) / sizeof(SC_ACTION));
5726
5727 /* Here lpFailureActions->lpsaActions contains an offset. The conversion is done by the caller. */
5728 lpFailureActions->lpsaActions = (lpFailureActions->cActions > 0 ? (LPSC_ACTION)(ULONG_PTR)sizeof(SERVICE_FAILURE_ACTIONSA) : NULL);
5729
5730 lpStr = (LPSTR)((ULONG_PTR)(lpFailureActions + 1) + lpFailureActions->cActions * sizeof(SC_ACTION));
5731 }
5732 else
5733 {
5734 lpFailureActions->dwResetPeriod = 0;
5735 lpFailureActions->cActions = 0;
5736 lpFailureActions->lpsaActions = NULL;
5737 lpStr = (LPSTR)(lpFailureActions + 1);
5738 }
5739
5740 lpFailureActions->lpRebootMsg = NULL;
5741 lpFailureActions->lpCommand = NULL;
5742
5743 if (lpRebootMessageW)
5744 {
5746 0,
5747 lpRebootMessageW,
5748 -1,
5749 lpStr,
5750 (int)wcslen(lpRebootMessageW),
5751 NULL,
5752 NULL);
5753 lpFailureActions->lpRebootMsg = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureActions);
5754 lpStr += strlen(lpStr) + 1;
5755 }
5756
5757 if (lpFailureCommandW)
5758 {
5760 0,
5761 lpFailureCommandW,
5762 -1,
5763 lpStr,
5764 (int)wcslen(lpFailureCommandW),
5765 NULL,
5766 NULL);
5767 lpFailureActions->lpCommand = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureActions);
5768