ReactOS 0.4.16-dev-602-ge302bac
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)
 
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)
 
static DWORD WINAPI ScmStopThread (PVOID pParam)
 
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()

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

Definition at line 782 of file rpcserver.c.

788{
789 DWORD dwError = ERROR_SUCCESS;
790 WCHAR szNameBuf[MAX_PATH];
791 WCHAR szValueBuf[MAX_PATH];
792 WCHAR *lpszNameBuf = szNameBuf;
793 WCHAR *lpszValueBuf = szValueBuf;
795 DWORD dwNumSubKeys;
796 DWORD dwIteration;
797 PSERVICE lpCurrentService;
798 HKEY hServiceEnumKey;
799 DWORD dwCurrentServiceState = SERVICE_ACTIVE;
800 DWORD dwDependServiceStrPtr = 0;
801 DWORD dwRequiredSize = 0;
802
803 /* Get the number of service keys */
805 NULL,
806 NULL,
807 NULL,
808 &dwNumSubKeys,
809 NULL,
810 NULL,
811 NULL,
812 NULL,
813 NULL,
814 NULL,
815 NULL);
816 if (dwError != ERROR_SUCCESS)
817 {
818 DPRINT("ERROR! Unable to get number of services keys\n");
819 return dwError;
820 }
821
822 /* Iterate the service keys to see if another service depends on the this service */
823 for (dwIteration = 0; dwIteration < dwNumSubKeys; dwIteration++)
824 {
826 dwError = RegEnumKeyExW(hServicesKey,
827 dwIteration,
828 lpszNameBuf,
829 &dwSize,
830 NULL,
831 NULL,
832 NULL,
833 NULL);
834 if (dwError != ERROR_SUCCESS)
835 return dwError;
836
837 /* Open the Service key */
838 dwError = RegOpenKeyExW(hServicesKey,
839 lpszNameBuf,
840 0,
841 KEY_READ,
842 &hServiceEnumKey);
843 if (dwError != ERROR_SUCCESS)
844 return dwError;
845
846 dwSize = MAX_PATH * sizeof(WCHAR);
847
848 /* Check for the DependOnService Value */
849 dwError = RegQueryValueExW(hServiceEnumKey,
850 L"DependOnService",
851 NULL,
852 NULL,
853 (LPBYTE)lpszValueBuf,
854 &dwSize);
855
856 /* FIXME: Handle load order. */
857
858 /* If the service found has a DependOnService value */
859 if (dwError == ERROR_SUCCESS)
860 {
861 dwDependServiceStrPtr = 0;
862
863 /* Can be more than one Dependencies in the DependOnService string */
864 while (wcslen(lpszValueBuf + dwDependServiceStrPtr) > 0)
865 {
866 if (_wcsicmp(lpszValueBuf + dwDependServiceStrPtr, lpService->lpServiceName) == 0)
867 {
868 /* Get the current enumed service pointer */
869 lpCurrentService = ScmGetServiceEntryByName(lpszNameBuf);
870
871 /* Check for valid Service */
872 if (!lpCurrentService)
873 {
874 /* This should never happen! */
875 DPRINT("This should not happen at this point, report to Developer\n");
876 return ERROR_NOT_FOUND;
877 }
878
879 /* Determine state the service is in */
880 if (lpCurrentService->Status.dwCurrentState == SERVICE_STOPPED)
881 dwCurrentServiceState = SERVICE_INACTIVE;
882
883 /* If the ServiceState matches that requested or searching for SERVICE_STATE_ALL */
884 if ((dwCurrentServiceState == dwServiceState) ||
885 (dwServiceState == SERVICE_STATE_ALL))
886 {
887 /* Calculate the required size */
888 dwRequiredSize += sizeof(SERVICE_STATUS);
889 dwRequiredSize += (DWORD)((wcslen(lpCurrentService->lpServiceName) + 1) * sizeof(WCHAR));
890 dwRequiredSize += (DWORD)((wcslen(lpCurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
891
892 /* Add the size for service name and display name pointers */
893 dwRequiredSize += (2 * sizeof(PVOID));
894
895 /* increase the BytesNeeded size */
896 *pcbBytesNeeded = *pcbBytesNeeded + dwRequiredSize;
897
898 /* Don't fill callers buffer yet, as MSDN read that the last service with dependency
899 comes first */
900
901 /* Recursive call to check for its dependencies */
903 lpCurrentService,
904 dwServiceState,
905 lpServices,
907 lpServicesReturned);
908
909 /* If the lpServices is valid set the service pointer */
910 if (lpServices)
911 lpServices[*lpServicesReturned] = lpCurrentService;
912
913 *lpServicesReturned = *lpServicesReturned + 1;
914 }
915 }
916
917 dwDependServiceStrPtr += (DWORD)(wcslen(lpszValueBuf + dwDependServiceStrPtr) + 1);
918 }
919 }
920 else if (*pcbBytesNeeded)
921 {
922 dwError = ERROR_SUCCESS;
923 }
924
925 RegCloseKey(hServiceEnumKey);
926 }
927
928 return dwError;
929}
static HANDLE hServicesKey
Definition: devinst.c:21
PSERVICE ScmGetServiceEntryByName(LPCWSTR lpServiceName)
Definition: database.c:657
DWORD Int_EnumDependentServicesW(HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: rpcserver.c:782
#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:65
SERVICE_STATUS Status
Definition: services.h:72
LPWSTR lpServiceName
Definition: services.h:64
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(), RControlService(), REnumDependentServicesA(), REnumDependentServicesW(), and ScmDeleteService().

◆ midl_user_allocate()

void __RPC_FAR *__RPC_USER midl_user_allocate ( SIZE_T  len)

Definition at line 6790 of file rpcserver.c.

6791{
6793}
#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 6796 of file rpcserver.c.

6797{
6799}
#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 5034 of file rpcserver.c.

5037{
5038 SC_RPC_CONFIG_INFOW InfoW = { 0 };
5039 DWORD dwRet, dwLength;
5040 PVOID ptr = NULL;
5041
5042 DPRINT("RChangeServiceConfig2A() called\n");
5043 DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
5044
5045 if ((Info.dwInfoLevel < SERVICE_CONFIG_DESCRIPTION) ||
5046 (Info.dwInfoLevel > SERVICE_CONFIG_FAILURE_ACTIONS))
5047 {
5048 return ERROR_INVALID_LEVEL;
5049 }
5050
5051 InfoW.dwInfoLevel = Info.dwInfoLevel;
5052
5054 {
5055 LPSERVICE_DESCRIPTIONW lpServiceDescriptionW;
5056 LPSERVICE_DESCRIPTIONA lpServiceDescriptionA;
5057
5058 lpServiceDescriptionA = Info.psd;
5059
5060 if (lpServiceDescriptionA &&
5061 lpServiceDescriptionA->lpDescription)
5062 {
5063 dwLength = (DWORD)((strlen(lpServiceDescriptionA->lpDescription) + 1) * sizeof(WCHAR));
5064
5065 lpServiceDescriptionW = HeapAlloc(GetProcessHeap(),
5067 dwLength + sizeof(SERVICE_DESCRIPTIONW));
5068 if (!lpServiceDescriptionW)
5069 {
5071 }
5072
5073 lpServiceDescriptionW->lpDescription = (LPWSTR)(lpServiceDescriptionW + 1);
5074
5076 0,
5077 lpServiceDescriptionA->lpDescription,
5078 -1,
5079 lpServiceDescriptionW->lpDescription,
5080 dwLength);
5081
5082 ptr = lpServiceDescriptionW;
5083 InfoW.psd = lpServiceDescriptionW;
5084 }
5085 }
5086 else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5087 {
5088 LPSERVICE_FAILURE_ACTIONSW lpServiceFailureActionsW;
5089 LPSERVICE_FAILURE_ACTIONSA lpServiceFailureActionsA;
5090 DWORD dwRebootLen = 0;
5091 DWORD dwCommandLen = 0;
5092 DWORD dwActionArrayLen = 0;
5093 LPWSTR lpStr = NULL;
5094
5095 lpServiceFailureActionsA = Info.psfa;
5096
5097 if (lpServiceFailureActionsA)
5098 {
5099 /*
5100 * The following code is inspired by the
5101 * SERVICE_CONFIG_FAILURE_ACTIONS case of
5102 * the RQueryServiceConfig2W function.
5103 */
5104
5105 /* Retrieve the needed length for the two data strings */
5106 if (lpServiceFailureActionsA->lpRebootMsg)
5107 {
5108 dwRebootLen = (DWORD)((strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR));
5109 }
5110 if (lpServiceFailureActionsA->lpCommand)
5111 {
5112 dwCommandLen = (DWORD)((strlen(lpServiceFailureActionsA->lpCommand) + 1) * sizeof(WCHAR));
5113 }
5114
5115 /*
5116 * Retrieve the size of the lpsaActions array if needed.
5117 * We will copy the lpsaActions array only if there is at
5118 * least one action AND that the original array is valid.
5119 */
5120 if (lpServiceFailureActionsA->cActions > 0 && lpServiceFailureActionsA->lpsaActions)
5121 {
5122 dwActionArrayLen = lpServiceFailureActionsA->cActions * sizeof(SC_ACTION);
5123 }
5124
5125 /* Compute the total length for the UNICODE structure, including data */
5127 dwActionArrayLen + dwRebootLen + dwCommandLen;
5128
5129 /* Allocate the structure */
5130 lpServiceFailureActionsW = HeapAlloc(GetProcessHeap(),
5132 dwLength);
5133 if (!lpServiceFailureActionsW)
5134 {
5136 }
5137
5138 /* Copy the members */
5139 lpServiceFailureActionsW->dwResetPeriod = lpServiceFailureActionsA->dwResetPeriod;
5140 lpServiceFailureActionsW->cActions = lpServiceFailureActionsA->cActions;
5141
5142 /* Copy the lpsaActions array if needed */
5143 if (dwActionArrayLen > 0)
5144 {
5145 /* The storage zone is just after the end of the SERVICE_FAILURE_ACTIONSW structure */
5146 lpServiceFailureActionsW->lpsaActions = (LPSC_ACTION)((ULONG_PTR)(lpServiceFailureActionsW + 1));
5147
5148 /* dwActionArrayLen == lpServiceFailureActionsW->cActions * sizeof(SC_ACTION) */
5149 RtlCopyMemory(lpServiceFailureActionsW->lpsaActions,
5150 lpServiceFailureActionsA->lpsaActions,
5151 dwActionArrayLen);
5152 }
5153 else
5154 {
5155 /* No lpsaActions array */
5156 lpServiceFailureActionsW->lpsaActions = NULL;
5157 }
5158 /* The data strings are stored just after the lpsaActions array */
5159 lpStr = (LPWSTR)((ULONG_PTR)(lpServiceFailureActionsW + 1) + dwActionArrayLen);
5160
5161 /*
5162 * Convert the data strings to UNICODE
5163 */
5164
5165 lpServiceFailureActionsW->lpRebootMsg = NULL;
5166 lpServiceFailureActionsW->lpCommand = NULL;
5167
5168 if (dwRebootLen)
5169 {
5170 /* lpRebootMsg points just after the lpsaActions array */
5171 lpServiceFailureActionsW->lpRebootMsg = lpStr;
5172
5174 0,
5175 lpServiceFailureActionsA->lpRebootMsg,
5176 -1,
5177 lpServiceFailureActionsW->lpRebootMsg,
5178 dwRebootLen);
5179
5180 lpStr += dwRebootLen / sizeof(WCHAR);
5181 }
5182
5183 if (dwCommandLen)
5184 {
5185 /* lpRebootMsg points just after the lpRebootMsg data string */
5186 lpServiceFailureActionsW->lpCommand = lpStr;
5187
5189 0,
5190 lpServiceFailureActionsA->lpCommand,
5191 -1,
5192 lpServiceFailureActionsW->lpCommand,
5193 dwCommandLen);
5194 }
5195
5196 /* Set the pointers */
5197 ptr = lpServiceFailureActionsW;
5198 InfoW.psfa = lpServiceFailureActionsW;
5199 }
5200 }
5201
5202 dwRet = RChangeServiceConfig2W(hService, InfoW);
5203
5205
5206 return dwRet;
5207}
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:5435
#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 5435 of file rpcserver.c.

5438{
5439 DWORD dwError = ERROR_SUCCESS;
5440 PSERVICE_HANDLE hSvc;
5441 PSERVICE lpService = NULL;
5442 HKEY hServiceKey = NULL;
5444
5445 DPRINT("RChangeServiceConfig2W() called\n");
5446 DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
5447
5448 if (ScmShutdown)
5450
5451 if ((Info.dwInfoLevel < SERVICE_CONFIG_DESCRIPTION) ||
5452 (Info.dwInfoLevel > SERVICE_CONFIG_FAILURE_ACTIONS))
5453 {
5454 return ERROR_INVALID_LEVEL;
5455 }
5456
5457 hSvc = ScmGetServiceFromHandle(hService);
5458 if (hSvc == NULL)
5459 {
5460 DPRINT("Invalid service handle\n");
5461 return ERROR_INVALID_HANDLE;
5462 }
5463
5464 if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5466
5467 /* Check the access rights */
5470 {
5471 DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
5472 return ERROR_ACCESS_DENIED;
5473 }
5474
5475 if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5476 {
5477 /* FIXME: Check if the caller has the SE_SHUTDOWN_NAME privilege */
5478
5479 }
5480
5481 lpService = hSvc->ServiceEntry;
5482 if (lpService == NULL)
5483 {
5484 DPRINT("lpService == NULL\n");
5485 return ERROR_INVALID_HANDLE;
5486 }
5487
5488 /* Failure actions can only be set for Win32 services, not for drivers */
5489 if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5490 {
5491 if (lpService->Status.dwServiceType & SERVICE_DRIVER)
5493 }
5494
5495 /* Lock the service database exclusively */
5497
5498 if (lpService->bDeleted)
5499 {
5500 DPRINT("Service has already been marked for delete\n");
5502 goto done;
5503 }
5504
5505 /* Open the service key */
5506 dwError = ScmOpenServiceKey(lpService->szServiceName,
5508 &hServiceKey);
5509 if (dwError != ERROR_SUCCESS)
5510 goto done;
5511
5512 if (Info.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
5513 {
5514 LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd;
5515
5516 /* Modify the service description, if specified */
5517 if (lpServiceDescription != NULL &&
5518 lpServiceDescription->lpDescription != NULL)
5519 {
5520 /* If the description is "" then we delete it */
5521 if (*lpServiceDescription->lpDescription == 0)
5522 {
5523 DPRINT("Delete service description\n");
5524 dwError = RegDeleteValueW(hServiceKey, L"Description");
5525
5526 if (dwError == ERROR_FILE_NOT_FOUND)
5527 dwError = ERROR_SUCCESS;
5528 }
5529 else
5530 {
5531 DPRINT("Setting service description value %S\n", lpServiceDescription->lpDescription);
5532 dwError = RegSetValueExW(hServiceKey,
5533 L"Description",
5534 0,
5535 REG_SZ,
5536 (LPBYTE)lpServiceDescription->lpDescription,
5537 (DWORD)((wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR)));
5538 }
5539 }
5540 else
5541 {
5542 dwError = ERROR_SUCCESS;
5543 }
5544 }
5545 else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5546 {
5547 dwError = ScmSetFailureActions(hServiceKey,
5549 }
5550
5551done:
5552 if (hServiceKey != NULL)
5553 RegCloseKey(hServiceKey);
5554
5555 /* Unlock the service database */
5557
5558 DPRINT("RChangeServiceConfig2W() done (Error %lu)\n", dwError);
5559
5560 return dwError;
5561}
DWORD ScmOpenServiceKey(LPWSTR lpServiceName, REGSAM samDesired, PHKEY phKey)
Definition: config.c:42
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2328
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2314
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:222
static DWORD ScmSetFailureActions(HKEY hServiceKey, LPSERVICE_FAILURE_ACTIONSW lpFailureActions)
Definition: rpcserver.c:5211
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:68
WCHAR szServiceName[1]
Definition: services.h:86
#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 3476 of file rpcserver.c.

3490{
3491 DWORD dwError = ERROR_SUCCESS;
3492 LPWSTR lpBinaryPathNameW = NULL;
3493 LPWSTR lpLoadOrderGroupW = NULL;
3494 LPWSTR lpDependenciesW = NULL;
3495 LPWSTR lpServiceStartNameW = NULL;
3496 LPWSTR lpDisplayNameW = NULL;
3497 DWORD dwDependenciesLength = 0;
3498 SIZE_T cchLength;
3499 int len;
3500 LPCSTR lpStr;
3501
3502 if (lpBinaryPathName)
3503 {
3504 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
3505 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3506 if (!lpBinaryPathNameW)
3507 {
3509 goto cleanup;
3510 }
3511 MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
3512 }
3513
3514 if (lpLoadOrderGroup)
3515 {
3516 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
3517 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3518 if (!lpLoadOrderGroupW)
3519 {
3521 goto cleanup;
3522 }
3523 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
3524 }
3525
3526 if (lpDependencies)
3527 {
3528 lpStr = (LPCSTR)lpDependencies;
3529 while (*lpStr)
3530 {
3531 cchLength = strlen(lpStr) + 1;
3532 dwDependenciesLength += (DWORD)cchLength;
3533 lpStr = lpStr + cchLength;
3534 }
3535 dwDependenciesLength++;
3536
3537 lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
3538 if (!lpDependenciesW)
3539 {
3541 goto cleanup;
3542 }
3543 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
3544 }
3545
3546 if (lpServiceStartName)
3547 {
3548 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
3549 lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3550 if (!lpServiceStartNameW)
3551 {
3553 goto cleanup;
3554 }
3555 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
3556 }
3557
3558 if (lpDisplayName)
3559 {
3561 lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3562 if (!lpDisplayNameW)
3563 {
3565 goto cleanup;
3566 }
3567 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
3568 }
3569
3570 dwError = RChangeServiceConfigW(hService,
3571 dwServiceType,
3572 dwStartType,
3573 dwErrorControl,
3574 lpBinaryPathNameW,
3575 lpLoadOrderGroupW,
3576 lpdwTagId,
3577 (LPBYTE)lpDependenciesW,
3578 dwDependenciesLength,
3579 lpServiceStartNameW,
3580 lpPassword,
3581 dwPwSize,
3582 lpDisplayNameW);
3583
3584cleanup:
3585 if (lpBinaryPathNameW != NULL)
3586 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
3587
3588 if (lpLoadOrderGroupW != NULL)
3589 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
3590
3591 if (lpDependenciesW != NULL)
3592 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
3593
3594 if (lpServiceStartNameW != NULL)
3595 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
3596
3597 if (lpDisplayNameW != NULL)
3598 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
3599
3600 return dwError;
3601}
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:1935
#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:2815
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 1935 of file rpcserver.c.

1949{
1950 DWORD dwError = ERROR_SUCCESS;
1951 PSERVICE_HANDLE hSvc;
1952 PSERVICE lpService = NULL;
1953 HKEY hServiceKey = NULL;
1954 LPWSTR lpDisplayNameW = NULL;
1955 LPWSTR lpImagePathW = NULL;
1956 LPWSTR lpClearTextPassword = NULL;
1957
1958 DPRINT("RChangeServiceConfigW() called\n");
1959 DPRINT("dwServiceType = 0x%lx\n", dwServiceType);
1960 DPRINT("dwStartType = %lu\n", dwStartType);
1961 DPRINT("dwErrorControl = %lu\n", dwErrorControl);
1962 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
1963 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
1964 DPRINT("lpServiceStartName = %S\n", lpServiceStartName);
1965 DPRINT("lpPassword = %p\n", lpPassword);
1966 DPRINT("dwPwSite = %lu\n", dwPwSize);
1967 DPRINT("lpDisplayName = %S\n", lpDisplayName);
1968
1969 if (ScmShutdown)
1971
1972 hSvc = ScmGetServiceFromHandle(hService);
1973 if (hSvc == NULL)
1974 {
1975 DPRINT1("Invalid service handle\n");
1976 return ERROR_INVALID_HANDLE;
1977 }
1978
1981 {
1982 DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
1983 return ERROR_ACCESS_DENIED;
1984 }
1985
1986 /* Check for invalid service type value */
1987 if ((dwServiceType != SERVICE_NO_CHANGE) &&
1988 (dwServiceType != SERVICE_KERNEL_DRIVER) &&
1989 (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER) &&
1992 {
1994 }
1995
1996 /* Check for invalid start type value */
1997 if ((dwStartType != SERVICE_NO_CHANGE) &&
1998 (dwStartType != SERVICE_BOOT_START) &&
1999 (dwStartType != SERVICE_SYSTEM_START) &&
2000 (dwStartType != SERVICE_AUTO_START) &&
2001 (dwStartType != SERVICE_DEMAND_START) &&
2002 (dwStartType != SERVICE_DISABLED))
2003 {
2005 }
2006
2007 /* Only drivers can be boot start or system start services */
2008 if ((dwStartType == SERVICE_BOOT_START) ||
2009 (dwStartType == SERVICE_SYSTEM_START))
2010 {
2011 if ((dwServiceType != SERVICE_KERNEL_DRIVER) &&
2012 (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER))
2014 }
2015
2016 /* Check for invalid error control value */
2017 if ((dwErrorControl != SERVICE_NO_CHANGE) &&
2018 (dwErrorControl != SERVICE_ERROR_IGNORE) &&
2019 (dwErrorControl != SERVICE_ERROR_NORMAL) &&
2020 (dwErrorControl != SERVICE_ERROR_SEVERE) &&
2021 (dwErrorControl != SERVICE_ERROR_CRITICAL))
2022 {
2024 }
2025
2026 if (lpdwTagId && (!lpLoadOrderGroup || !*lpLoadOrderGroup))
2027 {
2029 }
2030
2031 lpService = hSvc->ServiceEntry;
2032 if (lpService == NULL)
2033 {
2034 DPRINT("lpService == NULL\n");
2035 return ERROR_INVALID_HANDLE;
2036 }
2037
2038 /* Lock the service database exclusively */
2040
2041 if (lpService->bDeleted)
2042 {
2043 DPRINT("Service has already been marked for delete\n");
2045 goto done;
2046 }
2047
2048 /* Open the service key */
2049 dwError = ScmOpenServiceKey(lpService->szServiceName,
2051 &hServiceKey);
2052 if (dwError != ERROR_SUCCESS)
2053 goto done;
2054
2055 /* Write service data to the registry */
2056
2057 /* Set the display name */
2058 if (lpDisplayName != NULL && *lpDisplayName != 0)
2059 {
2060 RegSetValueExW(hServiceKey,
2061 L"DisplayName",
2062 0,
2063 REG_SZ,
2065 (DWORD)((wcslen(lpDisplayName) + 1) * sizeof(WCHAR)));
2066
2067 /* Update the display name */
2068 lpDisplayNameW = HeapAlloc(GetProcessHeap(),
2070 (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
2071 if (lpDisplayNameW == NULL)
2072 {
2073 dwError = ERROR_NOT_ENOUGH_MEMORY;
2074 goto done;
2075 }
2076
2077 wcscpy(lpDisplayNameW, lpDisplayName);
2078 if (lpService->lpDisplayName != lpService->lpServiceName)
2079 HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
2080
2081 lpService->lpDisplayName = lpDisplayNameW;
2082 }
2083
2084 if (dwServiceType != SERVICE_NO_CHANGE)
2085 {
2086 /* Set the service type */
2087 dwError = RegSetValueExW(hServiceKey,
2088 L"Type",
2089 0,
2090 REG_DWORD,
2091 (LPBYTE)&dwServiceType,
2092 sizeof(DWORD));
2093 if (dwError != ERROR_SUCCESS)
2094 goto done;
2095
2096 lpService->Status.dwServiceType = dwServiceType;
2097 }
2098
2099 if (dwStartType != SERVICE_NO_CHANGE)
2100 {
2101 /* Set the start value */
2102 dwError = RegSetValueExW(hServiceKey,
2103 L"Start",
2104 0,
2105 REG_DWORD,
2106 (LPBYTE)&dwStartType,
2107 sizeof(DWORD));
2108 if (dwError != ERROR_SUCCESS)
2109 goto done;
2110
2111 lpService->dwStartType = dwStartType;
2112 }
2113
2114 if (dwErrorControl != SERVICE_NO_CHANGE)
2115 {
2116 /* Set the error control value */
2117 dwError = RegSetValueExW(hServiceKey,
2118 L"ErrorControl",
2119 0,
2120 REG_DWORD,
2121 (LPBYTE)&dwErrorControl,
2122 sizeof(DWORD));
2123 if (dwError != ERROR_SUCCESS)
2124 goto done;
2125
2126 lpService->dwErrorControl = dwErrorControl;
2127 }
2128
2129 if (lpBinaryPathName != NULL && *lpBinaryPathName != 0)
2130 {
2131 /* Set the image path */
2132 lpImagePathW = lpBinaryPathName;
2133
2134 if (lpService->Status.dwServiceType & SERVICE_DRIVER)
2135 {
2136 dwError = ScmCanonDriverImagePath(lpService->dwStartType,
2137 lpBinaryPathName,
2138 &lpImagePathW);
2139
2140 if (dwError != ERROR_SUCCESS)
2141 goto done;
2142 }
2143
2144 dwError = RegSetValueExW(hServiceKey,
2145 L"ImagePath",
2146 0,
2148 (LPBYTE)lpImagePathW,
2149 (DWORD)((wcslen(lpImagePathW) + 1) * sizeof(WCHAR)));
2150
2151 if (lpImagePathW != lpBinaryPathName)
2152 HeapFree(GetProcessHeap(), 0, lpImagePathW);
2153
2154 if (dwError != ERROR_SUCCESS)
2155 goto done;
2156 }
2157
2158 /* Set the group name */
2159 if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
2160 {
2161 dwError = RegSetValueExW(hServiceKey,
2162 L"Group",
2163 0,
2164 REG_SZ,
2165 (LPBYTE)lpLoadOrderGroup,
2166 (DWORD)((wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)));
2167 if (dwError != ERROR_SUCCESS)
2168 goto done;
2169
2170 dwError = ScmSetServiceGroup(lpService,
2171 lpLoadOrderGroup);
2172 if (dwError != ERROR_SUCCESS)
2173 goto done;
2174 }
2175
2176 /* Set the tag */
2177 if (lpdwTagId != NULL)
2178 {
2179 dwError = ScmAssignNewTag(lpService);
2180 if (dwError != ERROR_SUCCESS)
2181 goto done;
2182
2183 dwError = RegSetValueExW(hServiceKey,
2184 L"Tag",
2185 0,
2186 REG_DWORD,
2187 (LPBYTE)&lpService->dwTag,
2188 sizeof(DWORD));
2189 if (dwError != ERROR_SUCCESS)
2190 goto done;
2191
2192 *lpdwTagId = lpService->dwTag;
2193 }
2194
2195 /* Write dependencies */
2196 if (lpDependencies != NULL && *lpDependencies != 0)
2197 {
2198 dwError = ScmWriteDependencies(hServiceKey,
2199 (LPWSTR)lpDependencies,
2200 dwDependSize);
2201 if (dwError != ERROR_SUCCESS)
2202 goto done;
2203 }
2204
2205 /* Start name and password are only used by Win32 services */
2206 if (lpService->Status.dwServiceType & SERVICE_WIN32)
2207 {
2208 /* Write service start name */
2209 if (lpServiceStartName != NULL && *lpServiceStartName != 0)
2210 {
2211 dwError = RegSetValueExW(hServiceKey,
2212 L"ObjectName",
2213 0,
2214 REG_SZ,
2215 (LPBYTE)lpServiceStartName,
2216 (DWORD)((wcslen(lpServiceStartName) + 1) * sizeof(WCHAR)));
2217 if (dwError != ERROR_SUCCESS)
2218 goto done;
2219 }
2220
2221 if (lpPassword != NULL)
2222 {
2223 if (*(LPWSTR)lpPassword != 0)
2224 {
2225 /* Decrypt the password */
2226 dwError = ScmDecryptPassword(hService,
2227 lpPassword,
2228 dwPwSize,
2229 &lpClearTextPassword);
2230 if (dwError != ERROR_SUCCESS)
2231 {
2232 DPRINT1("ScmDecryptPassword failed (Error %lu)\n", dwError);
2233 goto done;
2234 }
2235 DPRINT("Clear text password: %S\n", lpClearTextPassword);
2236
2237 /* Write the password */
2238 dwError = ScmSetServicePassword(lpService->szServiceName,
2239 lpClearTextPassword);
2240 if (dwError != ERROR_SUCCESS)
2241 {
2242 DPRINT1("ScmSetServicePassword failed (Error %lu)\n", dwError);
2243 goto done;
2244 }
2245 }
2246 else
2247 {
2248 /* Delete the password */
2249 dwError = ScmSetServicePassword(lpService->szServiceName,
2250 NULL);
2251 if (dwError == ERROR_FILE_NOT_FOUND)
2252 dwError = ERROR_SUCCESS;
2253
2254 if (dwError != ERROR_SUCCESS)
2255 {
2256 DPRINT1("ScmSetServicePassword failed (Error %lu)\n", dwError);
2257 goto done;
2258 }
2259 }
2260 }
2261 }
2262
2263done:
2264 if (lpClearTextPassword != NULL)
2265 {
2266 /* Wipe and release the password buffer */
2267 SecureZeroMemory(lpClearTextPassword,
2268 (wcslen(lpClearTextPassword) + 1) * sizeof(WCHAR));
2269 HeapFree(GetProcessHeap(), 0, lpClearTextPassword);
2270 }
2271
2272 if (hServiceKey != NULL)
2273 RegCloseKey(hServiceKey);
2274
2275 /* Unlock the service database */
2277
2278 DPRINT("RChangeServiceConfigW() done (Error %lu)\n", dwError);
2279
2280 return dwError;
2281}
#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
wcscpy
#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
DWORD dwErrorControl
Definition: services.h:74
DWORD dwStartType
Definition: services.h:73
DWORD dwTag
Definition: services.h:75
#define SecureZeroMemory
Definition: winbase.h:1738
#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 6680 of file rpcserver.c.

6683{
6686}
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102

◆ RCloseServiceHandle()

DWORD WINAPI RCloseServiceHandle ( LPSC_RPC_HANDLE  hSCObject)

Definition at line 935 of file rpcserver.c.

937{
938 PMANAGER_HANDLE hManager;
939 PSERVICE_HANDLE hService;
940 PSERVICE lpService;
941
942 DPRINT("RCloseServiceHandle() called\n");
943
944 DPRINT("hSCObject = %p\n", *hSCObject);
945
946 if (*hSCObject == 0)
948
949 hManager = ScmGetServiceManagerFromHandle(*hSCObject);
950 hService = ScmGetServiceFromHandle(*hSCObject);
951
952 if (hManager != NULL)
953 {
954 DPRINT("Found manager handle\n");
955
956 /* Make sure we don't access stale memory if someone tries to use this handle again. */
957 hManager->Handle.Tag = INVALID_TAG;
958
959 HeapFree(GetProcessHeap(), 0, hManager);
960 hManager = NULL;
961
962 *hSCObject = NULL;
963
964 DPRINT("RCloseServiceHandle() done\n");
965 return ERROR_SUCCESS;
966 }
967 else if (hService != NULL)
968 {
969 DPRINT("Found service handle\n");
970
971 /* Lock the service database exclusively */
973
974 /* Get the pointer to the service record */
975 lpService = hService->ServiceEntry;
976
977 /* Make sure we don't access stale memory if someone tries to use this handle again. */
978 hService->Handle.Tag = INVALID_TAG;
979
980 /* Free the handle */
981 HeapFree(GetProcessHeap(), 0, hService);
982 hService = NULL;
983
984
985 DPRINT("Closing service %S with %d references\n", lpService->lpServiceName, lpService->RefCount);
986 ScmDereferenceService(lpService);
987
989
990 *hSCObject = NULL;
991
992 DPRINT("RCloseServiceHandle() done\n");
993 return ERROR_SUCCESS;
994 }
995
996 DPRINT("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
997
999}
DWORD ScmDereferenceService(PSERVICE lpService)
Definition: database.c:939
#define INVALID_TAG
Definition: rpcserver.c:27
static PMANAGER_HANDLE ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:202
SCMGR_HANDLE Handle
Definition: rpcserver.c:38
LONG RefCount
Definition: services.h:70

Referenced by CloseServiceHandle(), and SC_RPC_HANDLE_rundown().

◆ RControlService()

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

Definition at line 1005 of file rpcserver.c.

1009{
1010 PSERVICE_HANDLE hSvc;
1011 PSERVICE lpService;
1013 DWORD dwError = ERROR_SUCCESS;
1015 DWORD dwServicesReturned = 0;
1016 DWORD dwControlsAccepted;
1017 DWORD dwCurrentState;
1019 LPCWSTR lpLogStrings[2];
1020 WCHAR szLogBuffer[80];
1021 UINT uID;
1022
1023 DPRINT("RControlService() called\n");
1024
1025 if (ScmShutdown)
1027
1028 /* Check the service handle */
1029 hSvc = ScmGetServiceFromHandle(hService);
1030 if (hSvc == NULL)
1031 {
1032 DPRINT1("Invalid service handle\n");
1033 return ERROR_INVALID_HANDLE;
1034 }
1035
1036 /* Check the service entry point */
1037 lpService = hSvc->ServiceEntry;
1038 if (lpService == NULL)
1039 {
1040 DPRINT1("lpService == NULL\n");
1041 return ERROR_INVALID_HANDLE;
1042 }
1043
1044 /* Check access rights */
1045 switch (dwControl)
1046 {
1049 break;
1050
1059 break;
1060
1063 break;
1064
1065 default:
1066 if (dwControl >= 128 && dwControl <= 255)
1068 else
1070 break;
1071 }
1072
1075 return ERROR_ACCESS_DENIED;
1076
1077 /* Return the current service status information */
1078 RtlCopyMemory(lpServiceStatus,
1079 &lpService->Status,
1080 sizeof(SERVICE_STATUS));
1081
1082 if (dwControl == SERVICE_CONTROL_STOP)
1083 {
1084 /* Check if the service has dependencies running as windows
1085 doesn't stop a service that does */
1086
1087 /* Open the Services Reg key */
1089 L"System\\CurrentControlSet\\Services",
1090 0,
1091 KEY_READ,
1092 &hServicesKey);
1093 if (dwError != ERROR_SUCCESS)
1094 {
1095 DPRINT("Failed to open services key\n");
1096 return dwError;
1097 }
1098
1099 /* Call the internal function with NULL, just to get bytes we need */
1101 lpService,
1103 NULL,
1105 &dwServicesReturned);
1106
1108
1109 /* If pcbBytesNeeded is not zero then there are services running that
1110 are dependent on this service */
1111 if (pcbBytesNeeded != 0)
1112 {
1113 DPRINT("Service has running dependencies. Failed to stop service\n");
1115 }
1116 }
1117
1118 if (lpService->Status.dwServiceType & SERVICE_DRIVER)
1119 {
1120 /* Send control code to the driver */
1121 dwError = ScmControlDriver(lpService,
1122 dwControl,
1123 lpServiceStatus);
1124 }
1125 else
1126 {
1127 dwControlsAccepted = lpService->Status.dwControlsAccepted;
1128 dwCurrentState = lpService->Status.dwCurrentState;
1129
1130 /* Return ERROR_SERVICE_NOT_ACTIVE if the service has not been started */
1131 if (lpService->lpImage == NULL || dwCurrentState == SERVICE_STOPPED)
1133
1134 /* Check the current state before sending a control request */
1135 switch (dwCurrentState)
1136 {
1138 case SERVICE_STOPPED:
1140
1142 switch (dwControl)
1143 {
1145 break;
1146
1148 RtlCopyMemory(lpServiceStatus,
1149 &lpService->Status,
1150 sizeof(SERVICE_STATUS));
1151 return ERROR_SUCCESS;
1152
1153 default:
1155 }
1156 break;
1157 }
1158
1159 /* Check if the control code is acceptable to the service */
1160 switch (dwControl)
1161 {
1163 if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0)
1165 break;
1166
1169 if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0)
1171 break;
1172
1174 if ((dwControlsAccepted & SERVICE_ACCEPT_PARAMCHANGE) == 0)
1176 break;
1177
1182 if ((dwControlsAccepted & SERVICE_ACCEPT_NETBINDCHANGE) == 0)
1184 break;
1185 }
1186
1187 /* Send control code to the service */
1188 dwError = ScmControlService(lpService->lpImage->hControlPipe,
1189 lpService->lpServiceName,
1190 dwControl,
1191 (SERVICE_STATUS_HANDLE)lpService);
1192
1193 /* Return service status information */
1194 RtlCopyMemory(lpServiceStatus,
1195 &lpService->Status,
1196 sizeof(SERVICE_STATUS));
1197 }
1198
1199 if (dwError == ERROR_SUCCESS)
1200 {
1201 if (dwControl == SERVICE_CONTROL_STOP ||
1202 dwControl == SERVICE_CONTROL_PAUSE ||
1203 dwControl == SERVICE_CONTROL_CONTINUE)
1204 {
1205 /* Log a successful send control */
1206
1207 switch (dwControl)
1208 {
1210 uID = IDS_SERVICE_STOP;
1211 break;
1212
1214 uID = IDS_SERVICE_PAUSE;
1215 break;
1216
1218 uID = IDS_SERVICE_RESUME;
1219 break;
1220 }
1221 LoadStringW(GetModuleHandle(NULL), uID, szLogBuffer, ARRAYSIZE(szLogBuffer));
1222
1223 lpLogStrings[0] = lpService->lpDisplayName;
1224 lpLogStrings[1] = szLogBuffer;
1225
1228 2,
1229 lpLogStrings);
1230 }
1231 }
1232
1233 return dwError;
1234}
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
DWORD ScmControlService(_In_ HANDLE hControlPipe, _In_ PCWSTR pServiceName, _In_ DWORD dwControl, _In_ SERVICE_STATUS_HANDLE hServiceStatus)
Definition: database.c:1569
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:53
DWORD dwControlsAccepted
Definition: winsvc.h:101
PSERVICE_IMAGE lpImage
Definition: services.h:67
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
#define GetModuleHandle
Definition: winbase.h:3852
#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:2865
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#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 6692 of file rpcserver.c.

6696{
6699}

◆ RControlServiceExW()

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

Definition at line 6705 of file rpcserver.c.

6709{
6712}

◆ 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 3607 of file rpcserver.c.

3624{
3625 DWORD dwError = ERROR_SUCCESS;
3626 LPWSTR lpServiceNameW = NULL;
3627 LPWSTR lpDisplayNameW = NULL;
3628 LPWSTR lpBinaryPathNameW = NULL;
3629 LPWSTR lpLoadOrderGroupW = NULL;
3630 LPWSTR lpDependenciesW = NULL;
3631 LPWSTR lpServiceStartNameW = NULL;
3632 DWORD dwDependenciesLength = 0;
3633 SIZE_T cchLength;
3634 int len;
3635 LPCSTR lpStr;
3636
3637 if (lpServiceName)
3638 {
3639 len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
3640 lpServiceNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3641 if (!lpServiceNameW)
3642 {
3644 goto cleanup;
3645 }
3646 MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
3647 }
3648
3649 if (lpDisplayName)
3650 {
3652 lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3653 if (!lpDisplayNameW)
3654 {
3656 goto cleanup;
3657 }
3658 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
3659 }
3660
3661 if (lpBinaryPathName)
3662 {
3663 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
3664 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3665 if (!lpBinaryPathNameW)
3666 {
3668 goto cleanup;
3669 }
3670 MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
3671 }
3672
3673 if (lpLoadOrderGroup)
3674 {
3675 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
3676 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3677 if (!lpLoadOrderGroupW)
3678 {
3680 goto cleanup;
3681 }
3682 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
3683 }
3684
3685 if (lpDependencies)
3686 {
3687 lpStr = (LPCSTR)lpDependencies;
3688 while (*lpStr)
3689 {
3690 cchLength = strlen(lpStr) + 1;
3691 dwDependenciesLength += (DWORD)cchLength;
3692 lpStr = lpStr + cchLength;
3693 }
3694 dwDependenciesLength++;
3695
3696 lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
3697 if (!lpDependenciesW)
3698 {
3700 goto cleanup;
3701 }
3702 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
3703 }
3704
3705 if (lpServiceStartName)
3706 {
3707 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
3708 lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3709 if (!lpServiceStartNameW)
3710 {
3712 goto cleanup;
3713 }
3714 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
3715 }
3716
3717 dwError = RCreateServiceW(hSCManager,
3718 lpServiceNameW,
3719 lpDisplayNameW,
3720 dwDesiredAccess,
3721 dwServiceType,
3722 dwStartType,
3723 dwErrorControl,
3724 lpBinaryPathNameW,
3725 lpLoadOrderGroupW,
3726 lpdwTagId,
3727 (LPBYTE)lpDependenciesW,
3728 dwDependenciesLength,
3729 lpServiceStartNameW,
3730 lpPassword,
3731 dwPwSize,
3732 lpServiceHandle);
3733
3734cleanup:
3735 if (lpServiceNameW !=NULL)
3736 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
3737
3738 if (lpDisplayNameW != NULL)
3739 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
3740
3741 if (lpBinaryPathNameW != NULL)
3742 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
3743
3744 if (lpLoadOrderGroupW != NULL)
3745 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
3746
3747 if (lpDependenciesW != NULL)
3748 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
3749
3750 if (lpServiceStartNameW != NULL)
3751 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
3752
3753 return dwError;
3754}
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:2287
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 2287 of file rpcserver.c.

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

6573{
6576}

◆ 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 6582 of file rpcserver.c.

6599{
6602}

◆ RDeleteService()

DWORD WINAPI RDeleteService ( SC_RPC_HANDLE  hService)

Definition at line 1240 of file rpcserver.c.

1242{
1243 PSERVICE_HANDLE hSvc;
1244 PSERVICE lpService;
1245 DWORD dwError;
1246
1247 DPRINT("RDeleteService() called\n");
1248
1249 if (ScmShutdown)
1251
1252 hSvc = ScmGetServiceFromHandle(hService);
1253 if (hSvc == NULL)
1254 {
1255 DPRINT1("Invalid service handle\n");
1256 return ERROR_INVALID_HANDLE;
1257 }
1258
1260 DELETE))
1261 return ERROR_ACCESS_DENIED;
1262
1263 lpService = hSvc->ServiceEntry;
1264 if (lpService == NULL)
1265 {
1266 DPRINT("lpService == NULL\n");
1267 return ERROR_INVALID_HANDLE;
1268 }
1269
1270 /* Lock the service database exclusively */
1272
1273 if (lpService->bDeleted)
1274 {
1275 DPRINT("Service has already been marked for delete\n");
1277 goto Done;
1278 }
1279
1280 /* Mark service for delete */
1281 lpService->bDeleted = TRUE;
1282
1283 dwError = ScmMarkServiceForDelete(lpService);
1284
1285Done:
1286 /* Unlock the service database */
1288
1289 DPRINT("RDeleteService() done\n");
1290
1291 return dwError;
1292}
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 3760 of file rpcserver.c.

3767{
3768 DWORD dwError = ERROR_SUCCESS;
3769 DWORD dwServicesReturned = 0;
3770 DWORD dwServiceCount;
3772 PSERVICE_HANDLE hSvc;
3773 PSERVICE lpService = NULL;
3774 PSERVICE *lpServicesArray = NULL;
3775 LPENUM_SERVICE_STATUSA lpServicesPtr = NULL;
3776 LPSTR lpStr;
3777
3778 *pcbBytesNeeded = 0;
3779 *lpServicesReturned = 0;
3780
3781 DPRINT("REnumDependentServicesA() called\n");
3782
3783 hSvc = ScmGetServiceFromHandle(hService);
3784 if (hSvc == NULL)
3785 {
3786 DPRINT1("Invalid service handle\n");
3787 return ERROR_INVALID_HANDLE;
3788 }
3789
3790 lpService = hSvc->ServiceEntry;
3791
3792 /* Check access rights */
3795 {
3796 DPRINT("Insufficient access rights! 0x%lx\n",
3797 hSvc->Handle.DesiredAccess);
3798 return ERROR_ACCESS_DENIED;
3799 }
3800
3801 /* Open the Services Reg key */
3803 L"System\\CurrentControlSet\\Services",
3804 0,
3805 KEY_READ,
3806 &hServicesKey);
3807
3808 if (dwError != ERROR_SUCCESS)
3809 return dwError;
3810
3811 /* NOTE: Windows calculates the pcbBytesNeeded based on WCHAR strings for
3812 both EnumDependentServicesA and EnumDependentServicesW. So returned pcbBytesNeeded
3813 are the same for both. Verified in WINXP. */
3814
3815 /* First determine the bytes needed and get the number of dependent services*/
3817 lpService,
3818 dwServiceState,
3819 NULL,
3821 &dwServicesReturned);
3822 if (dwError != ERROR_SUCCESS)
3823 goto Done;
3824
3825 /* If buffer size is less than the bytes needed or pointer is null*/
3826 if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
3827 {
3828 dwError = ERROR_MORE_DATA;
3829 goto Done;
3830 }
3831
3832 /* Allocate memory for array of service pointers */
3833 lpServicesArray = HeapAlloc(GetProcessHeap(),
3835 (dwServicesReturned + 1) * sizeof(PSERVICE));
3836 if (!lpServicesArray)
3837 {
3838 DPRINT("Could not allocate buffer\n");
3839 dwError = ERROR_NOT_ENOUGH_MEMORY;
3840 goto Done;
3841 }
3842
3843 dwServicesReturned = 0;
3844 *pcbBytesNeeded = 0;
3845
3847 lpService,
3848 dwServiceState,
3849 lpServicesArray,
3851 &dwServicesReturned);
3852 if (dwError != ERROR_SUCCESS)
3853 {
3854 goto Done;
3855 }
3856
3857 lpServicesPtr = (LPENUM_SERVICE_STATUSA)lpServices;
3858 lpStr = (LPSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSA)));
3859
3860 /* Copy EnumDepenedentService to Buffer */
3861 for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
3862 {
3863 lpService = lpServicesArray[dwServiceCount];
3864
3865 /* Copy the status info */
3866 memcpy(&lpServicesPtr->ServiceStatus,
3867 &lpService->Status,
3868 sizeof(SERVICE_STATUS));
3869
3870 /* Copy display name */
3872 0,
3873 lpService->lpDisplayName,
3874 -1,
3875 lpStr,
3876 (int)wcslen(lpService->lpDisplayName),
3877 0,
3878 0);
3879 lpServicesPtr->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
3880 lpStr += strlen(lpStr) + 1;
3881
3882 /* Copy service name */
3884 0,
3885 lpService->lpServiceName,
3886 -1,
3887 lpStr,
3888 (int)wcslen(lpService->lpServiceName),
3889 0,
3890 0);
3891 lpServicesPtr->lpServiceName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
3892 lpStr += strlen(lpStr) + 1;
3893
3894 lpServicesPtr++;
3895 }
3896
3897 *lpServicesReturned = dwServicesReturned;
3898
3899Done:
3900 if (lpServicesArray)
3901 HeapFree(GetProcessHeap(), 0, lpServicesArray);
3902
3904
3905 DPRINT("REnumDependentServicesA() done (Error %lu)\n", dwError);
3906
3907 return dwError;
3908}
#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 2722 of file rpcserver.c.

2729{
2730 DWORD dwError = ERROR_SUCCESS;
2731 DWORD dwServicesReturned = 0;
2732 DWORD dwServiceCount;
2734 PSERVICE_HANDLE hSvc;
2735 PSERVICE lpService = NULL;
2736 PSERVICE *lpServicesArray = NULL;
2737 LPENUM_SERVICE_STATUSW lpServicesPtr = NULL;
2738 LPWSTR lpStr;
2739
2740 *pcbBytesNeeded = 0;
2741 *lpServicesReturned = 0;
2742
2743 DPRINT("REnumDependentServicesW() called\n");
2744
2745 hSvc = ScmGetServiceFromHandle(hService);
2746 if (hSvc == NULL)
2747 {
2748 DPRINT1("Invalid service handle\n");
2749 return ERROR_INVALID_HANDLE;
2750 }
2751
2752 lpService = hSvc->ServiceEntry;
2753
2754 /* Check access rights */
2757 {
2758 DPRINT("Insufficient access rights! 0x%lx\n",
2759 hSvc->Handle.DesiredAccess);
2760 return ERROR_ACCESS_DENIED;
2761 }
2762
2763 /* Open the Services Reg key */
2765 L"System\\CurrentControlSet\\Services",
2766 0,
2767 KEY_READ,
2768 &hServicesKey);
2769 if (dwError != ERROR_SUCCESS)
2770 return dwError;
2771
2772 /* First determine the bytes needed and get the number of dependent services */
2774 lpService,
2775 dwServiceState,
2776 NULL,
2778 &dwServicesReturned);
2779 if (dwError != ERROR_SUCCESS)
2780 goto Done;
2781
2782 /* If buffer size is less than the bytes needed or pointer is null */
2783 if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
2784 {
2785 dwError = ERROR_MORE_DATA;
2786 goto Done;
2787 }
2788
2789 /* Allocate memory for array of service pointers */
2790 lpServicesArray = HeapAlloc(GetProcessHeap(),
2792 (dwServicesReturned + 1) * sizeof(PSERVICE));
2793 if (!lpServicesArray)
2794 {
2795 DPRINT1("Could not allocate buffer\n");
2796 dwError = ERROR_NOT_ENOUGH_MEMORY;
2797 goto Done;
2798 }
2799
2800 dwServicesReturned = 0;
2801 *pcbBytesNeeded = 0;
2802
2804 lpService,
2805 dwServiceState,
2806 lpServicesArray,
2808 &dwServicesReturned);
2809 if (dwError != ERROR_SUCCESS)
2810 {
2811 goto Done;
2812 }
2813
2814 lpServicesPtr = (LPENUM_SERVICE_STATUSW)lpServices;
2815 lpStr = (LPWSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSW)));
2816
2817 /* Copy EnumDepenedentService to Buffer */
2818 for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
2819 {
2820 lpService = lpServicesArray[dwServiceCount];
2821
2822 /* Copy status info */
2823 memcpy(&lpServicesPtr->ServiceStatus,
2824 &lpService->Status,
2825 sizeof(SERVICE_STATUS));
2826
2827 /* Copy display name */
2828 wcscpy(lpStr, lpService->lpDisplayName);
2829 lpServicesPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
2830 lpStr += (wcslen(lpService->lpDisplayName) + 1);
2831
2832 /* Copy service name */
2833 wcscpy(lpStr, lpService->lpServiceName);
2834 lpServicesPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
2835 lpStr += (wcslen(lpService->lpServiceName) + 1);
2836
2837 lpServicesPtr++;
2838 }
2839
2840 *lpServicesReturned = dwServicesReturned;
2841
2842Done:
2843 if (lpServicesArray != NULL)
2844 HeapFree(GetProcessHeap(), 0, lpServicesArray);
2845
2847
2848 DPRINT("REnumDependentServicesW() done (Error %lu)\n", dwError);
2849
2850 return dwError;
2851}
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 4768 of file rpcserver.c.

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

3923{
3924 LPENUM_SERVICE_STATUSW lpStatusPtrW = NULL;
3925 LPENUM_SERVICE_STATUSW lpStatusPtrIncrW;
3926 LPENUM_SERVICE_STATUSA lpStatusPtrA = NULL;
3927 LPWSTR lpStringPtrW;
3928 LPSTR lpStringPtrA;
3929 DWORD dwError;
3930 DWORD dwServiceCount;
3931
3932 DPRINT("REnumServicesStatusA() called\n");
3933
3934 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
3935 {
3936 return ERROR_INVALID_ADDRESS;
3937 }
3938
3939 if ((dwBufSize > 0) && (lpBuffer))
3940 {
3941 lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
3942 if (!lpStatusPtrW)
3943 {
3944 DPRINT("Failed to allocate buffer\n");
3946 }
3947 }
3948
3950 dwServiceType,
3951 dwServiceState,
3952 (LPBYTE)lpStatusPtrW,
3953 dwBufSize,
3955 lpServicesReturned,
3956 lpResumeHandle);
3957
3958 /* if no services were returned then we are Done */
3959 if (*lpServicesReturned == 0)
3960 goto Done;
3961
3962 lpStatusPtrIncrW = lpStatusPtrW;
3963 lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
3964 lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
3965 *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSA));
3966 lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
3967 *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSW));
3968
3969 for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
3970 {
3971 /* Copy the service name */
3973 0,
3974 lpStringPtrW,
3975 -1,
3976 lpStringPtrA,
3977 (int)wcslen(lpStringPtrW),
3978 0,
3979 0);
3980
3981 lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
3982 lpStringPtrA += wcslen(lpStringPtrW) + 1;
3983 lpStringPtrW += wcslen(lpStringPtrW) + 1;
3984
3985 /* Copy the display name */
3987 0,
3988 lpStringPtrW,
3989 -1,
3990 lpStringPtrA,
3991 (int)wcslen(lpStringPtrW),
3992 0,
3993 0);
3994
3995 lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
3996 lpStringPtrA += wcslen(lpStringPtrW) + 1;
3997 lpStringPtrW += wcslen(lpStringPtrW) + 1;
3998
3999 /* Copy the status information */
4000 memcpy(&lpStatusPtrA->ServiceStatus,
4001 &lpStatusPtrIncrW->ServiceStatus,
4002 sizeof(SERVICE_STATUS));
4003
4004 lpStatusPtrIncrW++;
4005 lpStatusPtrA++;
4006 }
4007
4008Done:
4009 if (lpStatusPtrW)
4010 HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
4011
4012 DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
4013
4014 return dwError;
4015}
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:2857
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 6111 of file rpcserver.c.

6122{
6123 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrW = NULL;
6124 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrIncrW;
6125 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtrA = NULL;
6126 LPWSTR lpStringPtrW;
6127 LPSTR lpStringPtrA;
6128 LPWSTR pszGroupNameW = NULL;
6129 DWORD dwError;
6130 DWORD dwServiceCount;
6131
6132 DPRINT("REnumServicesStatusExA() called\n");
6133
6134 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
6135 {
6136 return ERROR_INVALID_ADDRESS;
6137 }
6138
6139 if (pszGroupName)
6140 {
6141 pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
6142 if (!pszGroupNameW)
6143 {
6144 DPRINT("Failed to allocate buffer\n");
6145 dwError = ERROR_NOT_ENOUGH_MEMORY;
6146 goto Done;
6147 }
6148
6150 0,
6151 pszGroupName,
6152 -1,
6153 pszGroupNameW,
6154 (int)(strlen(pszGroupName) + 1));
6155 }
6156
6157 if ((cbBufSize > 0) && (lpBuffer))
6158 {
6160 if (!lpStatusPtrW)
6161 {
6162 DPRINT("Failed to allocate buffer\n");
6163 dwError = ERROR_NOT_ENOUGH_MEMORY;
6164 goto Done;
6165 }
6166 }
6167
6169 InfoLevel,
6170 dwServiceType,
6171 dwServiceState,
6172 (LPBYTE)lpStatusPtrW,
6173 cbBufSize,
6175 lpServicesReturned,
6176 lpResumeIndex,
6177 pszGroupNameW);
6178
6179 /* if no services were returned then we are Done */
6180 if (*lpServicesReturned == 0)
6181 goto Done;
6182
6183 lpStatusPtrIncrW = lpStatusPtrW;
6185 lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
6186 *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
6187 lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
6188 *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
6189
6190 for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
6191 {
6192 /* Copy the service name */
6194 0,
6195 lpStringPtrW,
6196 -1,
6197 lpStringPtrA,
6198 (int)wcslen(lpStringPtrW),
6199 0,
6200 0);
6201
6202 lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
6203 lpStringPtrA += wcslen(lpStringPtrW) + 1;
6204 lpStringPtrW += wcslen(lpStringPtrW) + 1;
6205
6206 /* Copy the display name */
6208 0,
6209 lpStringPtrW,
6210 -1,
6211 lpStringPtrA,
6212 (int)wcslen(lpStringPtrW),
6213 0,
6214 0);
6215
6216 lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
6217 lpStringPtrA += wcslen(lpStringPtrW) + 1;
6218 lpStringPtrW += wcslen(lpStringPtrW) + 1;
6219
6220 /* Copy the status information */
6221 memcpy(&lpStatusPtrA->ServiceStatusProcess,
6222 &lpStatusPtrIncrW->ServiceStatusProcess,
6223 sizeof(SERVICE_STATUS));
6224
6225 /* Copy the service process ID */
6226 lpStatusPtrA->ServiceStatusProcess.dwProcessId = lpStatusPtrIncrW->ServiceStatusProcess.dwProcessId;
6227
6228 lpStatusPtrA->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
6229
6230 lpStatusPtrIncrW++;
6231 lpStatusPtrA++;
6232 }
6233
6234Done:
6235 if (pszGroupNameW)
6236 HeapFree(GetProcessHeap(), 0, pszGroupNameW);
6237
6238 if (lpStatusPtrW)
6239 HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
6240
6241 DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError);
6242
6243 return dwError;
6244}
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:6250
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 6250 of file rpcserver.c.

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

2866{
2867 /* Enumerate all the services, not regarding of their group */
2869 dwServiceType,
2870 dwServiceState,
2871 lpBuffer,
2872 dwBufSize,
2874 lpServicesReturned,
2875 lpResumeHandle,
2876 NULL);
2877}
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:4768

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

◆ RFunction55()

DWORD WINAPI RFunction55 ( handle_t  BindingHandle)

Definition at line 6782 of file rpcserver.c.

6784{
6787}

◆ RGetNotifyResults()

DWORD WINAPI RGetNotifyResults ( SC_NOTIFY_RPC_HANDLE  hNotify,
PSC_RPC_NOTIFY_PARAMS_LIST ppNotifyParams 
)

Definition at line 6668 of file rpcserver.c.

6671{
6674}

◆ RGetServiceDisplayNameA()

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

Definition at line 4475 of file rpcserver.c.

4480{
4481 // PMANAGER_HANDLE hManager;
4482 PSERVICE lpService = NULL;
4483 LPCWSTR lpSvcDisplayName;
4484 LPWSTR lpServiceNameW;
4486
4487 DPRINT("RGetServiceDisplayNameA() called\n");
4488 DPRINT("hSCManager = %p\n", hSCManager);
4489 DPRINT("lpServiceName: %s\n", lpServiceName);
4490 DPRINT("lpDisplayName: %p\n", lpDisplayName);
4491 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
4492
4493#if 0
4494 hManager = (PMANAGER_HANDLE)hSCManager;
4495 if (hManager->Handle.Tag != MANAGER_TAG)
4496 {
4497 DPRINT("Invalid manager handle\n");
4498 return ERROR_INVALID_HANDLE;
4499 }
4500#endif
4501
4502 /* Get service database entry */
4503 if (lpServiceName != NULL)
4504 {
4505 dwLength = (DWORD)(strlen(lpServiceName) + 1);
4506 lpServiceNameW = HeapAlloc(GetProcessHeap(),
4508 dwLength * sizeof(WCHAR));
4509 if (!lpServiceNameW)
4511
4513 0,
4514 lpServiceName,
4515 -1,
4516 lpServiceNameW,
4517 dwLength);
4518
4519 lpService = ScmGetServiceEntryByName(lpServiceNameW);
4520
4521 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
4522 }
4523
4524 if (lpService == NULL)
4525 {
4526 DPRINT("Could not find service\n");
4528 }
4529
4530 if (lpService->lpDisplayName)
4531 lpSvcDisplayName = lpService->lpDisplayName;
4532 else
4533 lpSvcDisplayName = lpService->lpServiceName;
4534
4535 /*
4536 * NOTE: On Windows the comparison on *lpcchBuffer is made against
4537 * the number of (wide) characters of the UNICODE display name, and
4538 * not against the number of bytes needed to store the ANSI string.
4539 */
4540 dwLength = (DWORD)wcslen(lpSvcDisplayName);
4541
4542 if (*lpcchBuffer > dwLength)
4543 {
4544 if (lpDisplayName != NULL &&
4546 0,
4547 lpSvcDisplayName,
4548 -1,
4550 (int)*lpcchBuffer,
4551 NULL,
4552 NULL) == 0)
4553 {
4554 /*
4555 * But then, if *lpcchBuffer was greater than the number of
4556 * (wide) characters of the UNICODE display name, yet smaller
4557 * than the number of bytes needed due to the possible presence
4558 * of DBCS characters, the *exact* number of bytes is returned
4559 * (without the NULL terminator).
4560 */
4562 0,
4563 lpSvcDisplayName,
4564 (int)dwLength,
4565 NULL,
4566 0,
4567 NULL,
4568 NULL);
4569 *lpDisplayName = 0;
4570 *lpcchBuffer = dwLength;
4572 }
4573
4574 /*
4575 * NOTE: On Windows, RGetServiceDisplayNameA() does not update
4576 * *lpcchBuffer on success, contrary to RGetServiceDisplayNameW().
4577 */
4578 return ERROR_SUCCESS;
4579 }
4580 else
4581 {
4582 /*
4583 * NOTE: On Windows, if *lpcchBuffer is smaller than the number of
4584 * (wide) characters of the UNICODE display name, only an upper
4585 * estimation is returned by doubling the string length, to account
4586 * for the presence of any possible DBCS characters.
4587 */
4588 *lpcchBuffer = dwLength * sizeof(WCHAR);
4590 }
4591}
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 3332 of file rpcserver.c.

3337{
3338 // PMANAGER_HANDLE hManager;
3339 PSERVICE lpService;
3340 LPCWSTR lpSvcDisplayName;
3342 DWORD dwError;
3343
3344 DPRINT("RGetServiceDisplayNameW() called\n");
3345 DPRINT("hSCManager = %p\n", hSCManager);
3346 DPRINT("lpServiceName: %S\n", lpServiceName);
3347 DPRINT("lpDisplayName: %p\n", lpDisplayName);
3348 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
3349
3350#if 0
3351 hManager = (PMANAGER_HANDLE)hSCManager;
3352 if (hManager->Handle.Tag != MANAGER_TAG)
3353 {
3354 DPRINT("Invalid manager handle\n");
3355 return ERROR_INVALID_HANDLE;
3356 }
3357#endif
3358
3359 /* Get service database entry */
3360 lpService = ScmGetServiceEntryByName(lpServiceName);
3361 if (lpService == NULL)
3362 {
3363 DPRINT("Could not find service\n");
3365 }
3366
3367 if (lpService->lpDisplayName)
3368 lpSvcDisplayName = lpService->lpDisplayName;
3369 else
3370 lpSvcDisplayName = lpService->lpServiceName;
3371
3372 dwLength = (DWORD)wcslen(lpSvcDisplayName);
3373
3374 if (*lpcchBuffer > dwLength)
3375 {
3376 if (lpDisplayName != NULL)
3377 wcscpy(lpDisplayName, lpSvcDisplayName);
3378
3379 dwError = ERROR_SUCCESS;
3380 }
3381 else
3382 {
3383 dwError = ERROR_INSUFFICIENT_BUFFER;
3384 }
3385
3386 *lpcchBuffer = dwLength;
3387
3388 return dwError;
3389}

Referenced by GetServiceDisplayNameW().

◆ RGetServiceKeyNameA()

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

Definition at line 4597 of file rpcserver.c.

4602{
4603 // PMANAGER_HANDLE hManager;
4604 PSERVICE lpService;
4605 LPWSTR lpDisplayNameW;
4607
4608 DPRINT("RGetServiceKeyNameA() called\n");
4609 DPRINT("hSCManager = %p\n", hSCManager);
4610 DPRINT("lpDisplayName: %s\n", lpDisplayName);
4611 DPRINT("lpServiceName: %p\n", lpServiceName);
4612 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
4613
4614#if 0
4615 hManager = (PMANAGER_HANDLE)hSCManager;
4616 if (hManager->Handle.Tag != MANAGER_TAG)
4617 {
4618 DPRINT("Invalid manager handle\n");
4619 return ERROR_INVALID_HANDLE;
4620 }
4621#endif
4622
4623 /* Get service database entry */
4624
4626 lpDisplayNameW = HeapAlloc(GetProcessHeap(),
4628 dwLength * sizeof(WCHAR));
4629 if (!lpDisplayNameW)
4631
4633 0,
4635 -1,
4636 lpDisplayNameW,
4637 dwLength);
4638
4639 lpService = ScmGetServiceEntryByDisplayName(lpDisplayNameW);
4640
4641 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
4642
4643 if (lpService == NULL)
4644 {
4645 DPRINT("Could not find service\n");
4647 }
4648
4649 /*
4650 * NOTE: On Windows the comparison on *lpcchBuffer is made against
4651 * the number of (wide) characters of the UNICODE service name, and
4652 * not against the number of bytes needed to store the ANSI string.
4653 */
4654 dwLength = (DWORD)wcslen(lpService->lpServiceName);
4655
4656 if (*lpcchBuffer > dwLength)
4657 {
4658 if (lpServiceName != NULL &&
4660 0,
4661 lpService->lpServiceName,
4662 -1,
4663 lpServiceName,
4664 (int)*lpcchBuffer,
4665 NULL,
4666 NULL) == 0)
4667 {
4668 /*
4669 * But then, if *lpcchBuffer was greater than the number of
4670 * (wide) characters of the UNICODE service name, yet smaller
4671 * than the number of bytes needed due to the possible presence
4672 * of DBCS characters, the *exact* number of bytes is returned
4673 * (without the NULL terminator).
4674 */
4676 0,
4677 lpService->lpServiceName,
4678 (int)dwLength,
4679 NULL,
4680 0,
4681 NULL,
4682 NULL);
4683 *lpServiceName = 0;
4684 *lpcchBuffer = dwLength;
4686 }
4687
4688 /*
4689 * NOTE: On Windows, RGetServiceKeyNameA() does not update
4690 * *lpcchBuffer on success, contrary to RGetServiceKeyNameW().
4691 */
4692 return ERROR_SUCCESS;
4693 }
4694 else
4695 {
4696 /*
4697 * NOTE: On Windows, if *lpcchBuffer is smaller than the number of
4698 * (wide) characters of the UNICODE service name, only an upper
4699 * estimation is returned by doubling the string length, to account
4700 * for the presence of any possible DBCS characters.
4701 */
4702 *lpcchBuffer = dwLength * sizeof(WCHAR);
4704 }
4705}

Referenced by GetServiceKeyNameA().

◆ RGetServiceKeyNameW()

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

Definition at line 3395 of file rpcserver.c.

3400{
3401 // PMANAGER_HANDLE hManager;
3402 PSERVICE lpService;
3404 DWORD dwError;
3405
3406 DPRINT("RGetServiceKeyNameW() called\n");
3407 DPRINT("hSCManager = %p\n", hSCManager);
3408 DPRINT("lpDisplayName: %S\n", lpDisplayName);
3409 DPRINT("lpServiceName: %p\n", lpServiceName);
3410 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
3411
3412#if 0
3413 hManager = (PMANAGER_HANDLE)hSCManager;
3414 if (hManager->Handle.Tag != MANAGER_TAG)
3415 {
3416 DPRINT("Invalid manager handle\n");
3417 return ERROR_INVALID_HANDLE;
3418 }
3419#endif
3420
3421 /* Get service database entry */
3423 if (lpService == NULL)
3424 {
3425 DPRINT("Could not find service\n");
3427 }
3428
3429 dwLength = (DWORD)wcslen(lpService->lpServiceName);
3430
3431 if (*lpcchBuffer > dwLength)
3432 {
3433 if (lpServiceName != NULL)
3434 wcscpy(lpServiceName, lpService->lpServiceName);
3435
3436 dwError = ERROR_SUCCESS;
3437 }
3438 else
3439 {
3440 dwError = ERROR_INSUFFICIENT_BUFFER;
3441 }
3442
3443 *lpcchBuffer = dwLength;
3444
3445 return dwError;
3446}

Referenced by GetServiceKeyNameW().

◆ RI_ScGetCurrentGroupStateW()

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

Definition at line 4711 of file rpcserver.c.

4715{
4716 PMANAGER_HANDLE hManager;
4717 PSERVICE_GROUP pServiceGroup;
4718 DWORD dwError = ERROR_SUCCESS;
4719
4720 DPRINT("RI_ScGetCurrentGroupStateW() called\n");
4721
4722 if (ScmShutdown)
4724
4726 if (hManager == NULL)
4727 {
4728 DPRINT1("Invalid service manager handle\n");
4729 return ERROR_INVALID_HANDLE;
4730 }
4731
4732 /* Check for SC_MANAGER_ENUMERATE_SERVICE access right */
4735 {
4736 DPRINT("Insufficient access rights! 0x%lx\n",
4737 hManager->Handle.DesiredAccess);
4738 return ERROR_ACCESS_DENIED;
4739 }
4740
4741 /* Lock the service database shared */
4743
4744 /* Get the group list entry */
4745 pServiceGroup = ScmGetServiceGroupByName(lpLoadOrderGroup);
4746 if (pServiceGroup == NULL)
4747 {
4749 goto done;
4750 }
4751
4752 /* FIXME: Return the group state */
4753 *lpState = 0;
4754
4755done:
4756 /* Unlock the service database */
4758
4759 DPRINT("RI_ScGetCurrentGroupStateW() done (Error %lu)\n", dwError);
4760
4761 return dwError;
4762}
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 6608 of file rpcserver.c.

6613{
6614 PMANAGER_HANDLE hManager;
6615
6616 /* Validate handle */
6618 if (hManager == NULL)
6619 {
6620 return ERROR_INVALID_HANDLE;
6621 }
6622
6623 /* FIXME: should check whether client is local */
6624
6625 /* Check access rights */
6628 {
6629 return ERROR_ACCESS_DENIED;
6630 }
6631
6632 /* Check parameters */
6633 if (lpInParams == NULL || lpOutParams == NULL)
6634 {
6636 }
6637
6638 /* Check info level */
6640 {
6641 return ERROR_RETRY;
6642 }
6643
6644 /* Call internal helper */
6645 return ScmGetServiceNameFromTag(*lpInParams, lpOutParams);
6646}
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 3452 of file rpcserver.c.

3458{
3459 if (ScmShutdown)
3461
3462 if (lpString != NULL)
3464
3467 bSetBitsOn,
3468 bUpdateImmediately,
3469 NULL);
3470}
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:1881
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 1881 of file rpcserver.c.

1887{
1888 PSERVICE pService;
1889
1890 DPRINT("RI_ScSetServiceBitsW(%p %lx %d %d %S)\n",
1891 hServiceStatus, dwServiceBits, bSetBitsOn,
1892 bUpdateImmediately, lpString);
1893
1894 if (ScmShutdown)
1896
1897 if (lpString != NULL)
1899
1900 if (hServiceStatus == 0)
1901 {
1902 DPRINT("hServiceStatus == NULL\n");
1903 return ERROR_INVALID_HANDLE;
1904 }
1905
1906 // FIXME: Validate the status handle
1907 pService = (PSERVICE)hServiceStatus;
1908
1909 if (bSetBitsOn)
1910 {
1911 DPRINT("Old service bits: %08lx\n", pService->dwServiceBits);
1912 DPRINT("Old global service bits: %08lx\n", g_dwServiceBits);
1913 pService->dwServiceBits |= dwServiceBits;
1915 DPRINT("New service bits: %08lx\n", pService->dwServiceBits);
1916 DPRINT("New global service bits: %08lx\n", g_dwServiceBits);
1917 }
1918 else
1919 {
1920 DPRINT("Old service bits: %08lx\n", pService->dwServiceBits);
1921 DPRINT("Old global service bits: %08lx\n", g_dwServiceBits);
1922 pService->dwServiceBits &= ~dwServiceBits;
1923 g_dwServiceBits &= ~dwServiceBits;
1924 DPRINT("New service bits: %08lx\n", pService->dwServiceBits);
1925 DPRINT("New global service bits: %08lx\n", g_dwServiceBits);
1926 }
1927
1928 return ERROR_SUCCESS;
1929}
DWORD g_dwServiceBits
Definition: rpcserver.c:102
struct _SERVICE * PSERVICE
DWORD dwServiceBits
Definition: services.h:77

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 6729 of file rpcserver.c.

6733{
6734 PMANAGER_HANDLE hManager;
6735 PSERVICE pService;
6736
6737 DPRINT("RI_ScValidatePnPService(%p %S %p)\n", hSCManager, pszServiceName, phServiceStatus);
6738
6739 /* Validate handle */
6741 if (hManager == NULL)
6742 {
6743 DPRINT1("Invalid handle\n");
6744 return ERROR_INVALID_HANDLE;
6745 }
6746
6747 /* FIXME: should check whether client is local */
6748
6749 /* Check access rights */
6752 {
6753 DPRINT1("No SC_MANAGER_CONNECT access\n");
6754 return ERROR_ACCESS_DENIED;
6755 }
6756
6757 pService = ScmGetServiceEntryByName(pszServiceName);
6758 DPRINT("pService: %p\n", pService);
6759 if (pService == NULL)
6761
6762 *phServiceStatus = (RPC_SERVICE_STATUS_HANDLE)pService;
6763
6764 return ERROR_SUCCESS;
6765}
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 1298 of file rpcserver.c.

1301{
1302 PMANAGER_HANDLE hMgr;
1303
1304 DPRINT("RLockServiceDatabase() called\n");
1305
1306 *lpLock = NULL;
1307
1309 if (hMgr == NULL)
1310 {
1311 DPRINT1("Invalid service manager handle\n");
1312 return ERROR_INVALID_HANDLE;
1313 }
1314
1317 return ERROR_ACCESS_DENIED;
1318
1319 return ScmAcquireServiceStartLock(FALSE, lpLock);
1320}
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 1864 of file rpcserver.c.

1867{
1868 DPRINT("RNotifyBootConfigStatus(%p %lu)\n",
1869 lpMachineName, BootAcceptable);
1870
1871 if (BootAcceptable)
1872 return ScmAcceptBoot();
1873
1874 return ScmRunLastKnownGood();
1875}
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 6652 of file rpcserver.c.

6659{
6662}

◆ ROpenSCManagerA()

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

Definition at line 4021 of file rpcserver.c.

4026{
4028 UNICODE_STRING DatabaseName;
4029 DWORD dwError;
4030
4031 DPRINT("ROpenSCManagerA() called\n");
4032
4033 if (lpMachineName)
4035 lpMachineName);
4036
4037 if (lpDatabaseName)
4039 lpDatabaseName);
4040
4041 dwError = ROpenSCManagerW(lpMachineName ? MachineName.Buffer : NULL,
4042 lpDatabaseName ? DatabaseName.Buffer : NULL,
4043 dwDesiredAccess,
4044 lpScHandle);
4045
4046 if (lpMachineName)
4048
4049 if (lpDatabaseName)
4050 RtlFreeUnicodeString(&DatabaseName);
4051
4052 return dwError;
4053}
DWORD WINAPI ROpenSCManagerW(LPWSTR lpMachineName, LPWSTR lpDatabaseName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpScHandle)
Definition: rpcserver.c:2883
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:1294

Referenced by OpenSCManagerA().

◆ ROpenSCManagerW()

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

Definition at line 2883 of file rpcserver.c.

2888{
2889 DWORD dwError;
2890 SC_HANDLE hHandle;
2891
2892 DPRINT("ROpenSCManagerW() called\n");
2893 DPRINT("lpMachineName = %p\n", lpMachineName);
2894 DPRINT("lpMachineName: %S\n", lpMachineName);
2895 DPRINT("lpDataBaseName = %p\n", lpDatabaseName);
2896 DPRINT("lpDataBaseName: %S\n", lpDatabaseName);
2897 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
2898
2899 if (ScmShutdown)
2901
2902 if (!lpScHandle)
2904
2905 dwError = ScmCreateManagerHandle(lpDatabaseName,
2906 &hHandle);
2907 if (dwError != ERROR_SUCCESS)
2908 {
2909 DPRINT("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
2910 return dwError;
2911 }
2912
2913 /* Check the desired access */
2914 dwError = ScmCheckAccess(hHandle,
2915 dwDesiredAccess | SC_MANAGER_CONNECT);
2916 if (dwError != ERROR_SUCCESS)
2917 {
2918 DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
2919 HeapFree(GetProcessHeap(), 0, hHandle);
2920 return dwError;
2921 }
2922
2923 *lpScHandle = (SC_RPC_HANDLE)hHandle;
2924 DPRINT("*hScm = %p\n", *lpScHandle);
2925
2926 DPRINT("ROpenSCManagerW() done\n");
2927
2928 return ERROR_SUCCESS;
2929}
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 4059 of file rpcserver.c.

4064{
4066 DWORD dwError;
4067
4068 DPRINT("ROpenServiceA() called\n");
4069
4070 if (lpServiceName)
4072 lpServiceName);
4073
4074 dwError = ROpenServiceW(hSCManager,
4075 lpServiceName ? ServiceName.Buffer : NULL,
4076 dwDesiredAccess,
4077 lpServiceHandle);
4078
4079 if (lpServiceName)
4081
4082 return dwError;
4083}
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:2935

Referenced by OpenServiceA().

◆ ROpenServiceStatusHandle()

DWORD WINAPI ROpenServiceStatusHandle ( handle_t  BindingHandle)

Definition at line 6771 of file rpcserver.c.

6773{
6776}

◆ ROpenServiceW()

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

Definition at line 2935 of file rpcserver.c.

2940{
2941 PSERVICE lpService;
2942 PMANAGER_HANDLE hManager;
2943 SC_HANDLE hHandle;
2944 DWORD dwError = ERROR_SUCCESS;
2945
2946 DPRINT("ROpenServiceW() called\n");
2947 DPRINT("hSCManager = %p\n", hSCManager);
2948 DPRINT("lpServiceName = %p\n", lpServiceName);
2949 DPRINT("lpServiceName: %S\n", lpServiceName);
2950 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
2951
2952 if (ScmShutdown)
2954
2956 if (hManager == NULL)
2957 {
2958 DPRINT1("Invalid service manager handle\n");
2959 return ERROR_INVALID_HANDLE;
2960 }
2961
2962 if (!lpServiceHandle)
2964
2965 if (!lpServiceName)
2966 return ERROR_INVALID_ADDRESS;
2967
2968 /* Lock the service database exclusive */
2970
2971 /* Get service database entry */
2972 lpService = ScmGetServiceEntryByName(lpServiceName);
2973 if (lpService == NULL)
2974 {
2975 DPRINT("Could not find service\n");
2977 goto Done;
2978 }
2979
2980 /* Create a service handle */
2981 dwError = ScmCreateServiceHandle(lpService,
2982 &hHandle);
2983 if (dwError != ERROR_SUCCESS)
2984 {
2985 DPRINT("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
2986 goto Done;
2987 }
2988
2989 /* Check the desired access */
2990 dwError = ScmCheckAccess(hHandle,
2991 dwDesiredAccess);
2992 if (dwError != ERROR_SUCCESS)
2993 {
2994 DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
2995 HeapFree(GetProcessHeap(), 0, hHandle);
2996 goto Done;
2997 }
2998
2999 ScmReferenceService(lpService);
3000 DPRINT("OpenService %S - lpService->RefCount %u\n", lpService->lpServiceName, lpService->RefCount);
3001
3002 *lpServiceHandle = (SC_RPC_HANDLE)hHandle;
3003 DPRINT("*hService = %p\n", *lpServiceHandle);
3004
3005Done:
3006 /* Unlock the service database */
3008
3009 DPRINT("ROpenServiceW() done\n");
3010
3011 return dwError;
3012}

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 5567 of file rpcserver.c.

5573{
5574 DWORD dwError = ERROR_SUCCESS;
5575 PSERVICE_HANDLE hSvc;
5576 PSERVICE lpService = NULL;
5577 HKEY hServiceKey = NULL;
5578 DWORD dwRequiredSize = 0;
5579 DWORD dwType = 0;
5580 LPWSTR lpDescriptionW = NULL;
5581 LPWSTR lpRebootMessageW = NULL;
5582 LPWSTR lpFailureCommandW = NULL;
5583
5584 DPRINT("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",
5586
5587 if (!lpBuffer)
5588 return ERROR_INVALID_ADDRESS;
5589
5590 if (ScmShutdown)
5592
5595 {
5596 return ERROR_INVALID_LEVEL;
5597 }
5598
5599 hSvc = ScmGetServiceFromHandle(hService);
5600 if (hSvc == NULL)
5601 {
5602 DPRINT1("Invalid service handle\n");
5603 return ERROR_INVALID_HANDLE;
5604 }
5605
5608 {
5609 DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
5610 return ERROR_ACCESS_DENIED;
5611 }
5612
5613 lpService = hSvc->ServiceEntry;
5614 if (lpService == NULL)
5615 {
5616 DPRINT("lpService == NULL\n");
5617 return ERROR_INVALID_HANDLE;
5618 }
5619
5620 /* Lock the service database shared */
5622
5623 dwError = ScmOpenServiceKey(lpService->lpServiceName,
5624 KEY_READ,
5625 &hServiceKey);
5626 if (dwError != ERROR_SUCCESS)
5627 goto done;
5628
5630 {
5632 LPSTR lpStr;
5633
5634 dwError = ScmReadString(hServiceKey,
5635 L"Description",
5636 &lpDescriptionW);
5637 if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
5638 goto done;
5639
5641 if (dwError == ERROR_SUCCESS)
5642 *pcbBytesNeeded += (DWORD)((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
5643
5645 {
5646 dwError = ERROR_INSUFFICIENT_BUFFER;
5647 goto done;
5648 }
5649
5650 if (dwError == ERROR_SUCCESS)
5651 {
5652 lpStr = (LPSTR)(lpServiceDescription + 1);
5653
5655 0,
5656 lpDescriptionW,
5657 -1,
5658 lpStr,
5659 (int)wcslen(lpDescriptionW),
5660 NULL,
5661 NULL);
5662 lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
5663 }
5664 else
5665 {
5666 lpServiceDescription->lpDescription = NULL;
5667 dwError = ERROR_SUCCESS;
5668 }
5669 }
5671 {
5673 LPSTR lpStr = NULL;
5674
5675 /* Query value length */
5676 dwError = RegQueryValueExW(hServiceKey,
5677 L"FailureActions",
5678 NULL,
5679 &dwType,
5680 NULL,
5681 &dwRequiredSize);
5682 if (dwError != ERROR_SUCCESS &&
5683 dwError != ERROR_MORE_DATA &&
5684 dwError != ERROR_FILE_NOT_FOUND)
5685 {
5686 goto done;
5687 }
5688
5689 dwRequiredSize = (dwType == REG_BINARY) ? max(sizeof(SERVICE_FAILURE_ACTIONSA), dwRequiredSize)
5690 : sizeof(SERVICE_FAILURE_ACTIONSA);
5691
5692 /* Get the strings */
5693 ScmReadString(hServiceKey,
5694 L"FailureCommand",
5695 &lpFailureCommandW);
5696
5697 ScmReadString(hServiceKey,
5698 L"RebootMessage",
5699 &lpRebootMessageW);
5700
5701 if (lpRebootMessageW)
5702 dwRequiredSize += (DWORD)((wcslen(lpRebootMessageW) + 1) * sizeof(WCHAR));
5703
5704 if (lpFailureCommandW)
5705 dwRequiredSize += (DWORD)((wcslen(lpFailureCommandW) + 1) * sizeof(WCHAR));
5706
5707 if (cbBufSize < dwRequiredSize)
5708 {
5709 *pcbBytesNeeded = dwRequiredSize;
5710 dwError = ERROR_INSUFFICIENT_BUFFER;
5711 goto done;
5712 }
5713
5714 /* Now we can fill the buffer */
5715 if (dwError != ERROR_FILE_NOT_FOUND && dwType == REG_BINARY)
5716 {
5717 dwError = RegQueryValueExW(hServiceKey,
5718 L"FailureActions",
5719 NULL,
5720 NULL,
5721 (LPBYTE)lpFailureActions,
5722 &dwRequiredSize);
5723 if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
5724 goto done;
5725
5726 if (dwRequiredSize < sizeof(SERVICE_FAILURE_ACTIONSA))
5727 dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSA);
5728 }
5729 else
5730 {
5731 /*
5732 * The value of the error doesn't really matter, the only
5733 * important thing is that it must be != ERROR_SUCCESS .
5734 */
5735 dwError = ERROR_INVALID_DATA;
5736 }
5737
5738 if (dwError == ERROR_SUCCESS)
5739 {
5740 lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - sizeof(SERVICE_FAILURE_ACTIONSA)) / sizeof(SC_ACTION));
5741
5742 /* Here lpFailureActions->lpsaActions contains an offset. The conversion is done by the caller. */
5743 lpFailureActions->lpsaActions = (lpFailureActions->cActions > 0 ? (LPSC_ACTION)(ULONG_PTR)sizeof(SERVICE_FAILURE_ACTIONSA) : NULL);
5744
5745 lpStr = (LPSTR)((ULONG_PTR)(lpFailureActions + 1) + lpFailureActions->cActions * sizeof(SC_ACTION));
5746 }
5747 else
5748 {
5749 lpFailureActions->dwResetPeriod = 0;
5750 lpFailureActions->cActions = 0;
5751 lpFailureActions->lpsaActions = NULL;
5752 lpStr = (LPSTR)(lpFailureActions + 1);
5753 }
5754
5755 lpFailureActions->lpRebootMsg = NULL;
5756 lpFailureActions->lpCommand = NULL;
5757
5758 if (lpRebootMessageW)
5759 {
5761 0,
5762 lpRebootMessageW,
5763 -1,
5764 lpStr,
5765 (int)wcslen(lpRebootMessageW),
5766 NULL,
5767 NULL);
5768 lpFailureActions->lpRebootMsg = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureActions);
5769 lpStr += strlen(lpStr) + 1;
5770 }
5771
5772 if (lpFailureCommandW)
5773 {
5775 0,
5776 lpFailureCommandW,
5777 -1,
5778 lpStr,
5779 (int)wcslen(lpFailureCommandW),
5780 NULL,
5781 NULL);
5782 lpFailureActions->lpCommand = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureActions);
5783 /* lpStr += strlen(lpStr) + 1; */
5784 }
5785
5786 dwError = ERROR_SUCCESS;
5787 }
5788
5789done:
5790 /* Unlock the service database */
5792
5793 if (lpDescriptionW != NULL)
5794 HeapFree(GetProcessHeap(), 0, lpDescriptionW);
5795
5796 if (lpRebootMessageW != NULL)
5797 HeapFree(GetProcessHeap(), 0, lpRebootMessageW);
5798
5799 if (lpFailureCommandW != NULL)
5800 HeapFree(GetProcessHeap(), 0, lpFailureCommandW);
5801
5802 if (hServiceKey != NULL)
5803 RegCloseKey(hServiceKey);
5804
5805 DPRINT("RQueryServiceConfig2A() done (Error %lu)\n", dwError);
5806
5807 return dwError;
5808}
DWORD ScmReadString(HKEY hServiceKey, LPCWSTR lpValueName, LPWSTR *lpValue)
Definition: config.c:270
#define min(a, b)
Definition: monoChain.cc:55
#define REG_BINARY
Definition: nt_native.h:1496
#define max(a, b)
Definition: svc.c:63
#define ERROR_INVALID_DATA
Definition: winerror.h:116
struct _SERVICE_DESCRIPTIONA SERVICE_DESCRIPTIONA
struct _SERVICE_FAILURE_ACTIONSA * LPSERVICE_FAILURE_ACTIONSA
struct _SERVICE_DESCRIPTIONA * LPSERVICE_DESCRIPTIONA
struct _SERVICE_FAILURE_ACTIONSA SERVICE_FAILURE_ACTIONSA

Referenced by QueryServiceConfig2A().

◆ RQueryServiceConfig2W()

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

Definition at line 5814 of file rpcserver.c.

5820{
5821 DWORD dwError = ERROR_SUCCESS;
5822 PSERVICE_HANDLE hSvc;
5823 PSERVICE lpService = NULL;
5824 HKEY hServiceKey = NULL;
5825 DWORD dwRequiredSize = 0;