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

Go to the source code of this file.

Classes

struct  _SCMGR_HANDLE
 
struct  _MANAGER_HANDLE
 
struct  _SERVICE_HANDLE
 

Macros

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

Typedefs

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

Functions

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

Definition at line 60 of file rpcserver.c.

◆ SC_MANAGER_READ

#define SC_MANAGER_READ
Value:
SC_MANAGER_QUERY_LOCK_STATUS | \
SC_MANAGER_ENUMERATE_SERVICE)
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65

Definition at line 50 of file rpcserver.c.

◆ SC_MANAGER_WRITE

#define SC_MANAGER_WRITE
Value:
SC_MANAGER_MODIFY_BOOT_CONFIG | \
SC_MANAGER_CREATE_SERVICE)
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66

Definition at line 55 of file rpcserver.c.

◆ SERVICE_EXECUTE

#define SERVICE_EXECUTE
Value:
SERVICE_USER_DEFINED_CONTROL | \
SERVICE_PAUSE_CONTINUE | \
SERVICE_STOP | \
SERVICE_START)
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67

Definition at line 79 of file rpcserver.c.

◆ SERVICE_READ

#define SERVICE_READ
Value:
SERVICE_INTERROGATE | \
SERVICE_ENUMERATE_DEPENDENTS | \
SERVICE_QUERY_STATUS | \
SERVICE_QUERY_CONFIG)
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65

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:
SERVICE_CHANGE_CONFIG)
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66

Definition at line 75 of file rpcserver.c.

◆ TAG_ARRAY_SIZE

#define TAG_ARRAY_SIZE   32

Definition at line 86 of file rpcserver.c.

Typedef Documentation

◆ MANAGER_HANDLE

◆ PMANAGER_HANDLE

◆ PSERVICE_HANDLE

◆ SCMGR_HANDLE

◆ SERVICE_HANDLE

Function Documentation

◆ Int_EnumDependentServicesW()

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

Definition at line 783 of file rpcserver.c.

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

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

◆ midl_user_allocate()

void __RPC_FAR* __RPC_USER midl_user_allocate ( SIZE_T  len)

Definition at line 6744 of file rpcserver.c.

6745 {
6747 }
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
GLenum GLsizei len
Definition: glext.h:6722
#define HEAP_ZERO_MEMORY
Definition: compat.h:134

◆ midl_user_free()

void __RPC_USER midl_user_free ( void __RPC_FAR ptr)

Definition at line 6750 of file rpcserver.c.

6751 {
6752  HeapFree(GetProcessHeap(), 0, ptr);
6753 }
static PVOID ptr
Definition: dispmode.c:27
#define GetProcessHeap()
Definition: compat.h:595
#define HeapFree(x, y, z)
Definition: compat.h:594

◆ RChangeServiceConfig2A()

DWORD WINAPI RChangeServiceConfig2A ( SC_RPC_HANDLE  hService,
SC_RPC_CONFIG_INFOA  Info 
)

Definition at line 5019 of file rpcserver.c.

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

Referenced by ChangeServiceConfig2A().

◆ RChangeServiceConfig2W()

DWORD WINAPI RChangeServiceConfig2W ( SC_RPC_HANDLE  hService,
SC_RPC_CONFIG_INFOW  Info 
)

Definition at line 5420 of file rpcserver.c.

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

Referenced by ChangeServiceConfig2W(), and RChangeServiceConfig2A().

◆ RChangeServiceConfigA()

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

Definition at line 3461 of file rpcserver.c.

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

Referenced by ChangeServiceConfigA().

◆ RChangeServiceConfigW()

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

Definition at line 1920 of file rpcserver.c.

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

Referenced by ChangeServiceConfigW(), and RChangeServiceConfigA().

◆ RCloseNotifyHandle()

DWORD WINAPI RCloseNotifyHandle ( LPSC_NOTIFY_RPC_HANDLE  phNotify,
PBOOL  pfApcFired 
)

Definition at line 6665 of file rpcserver.c.

6668 {
6669  UNIMPLEMENTED;
6671 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define UNIMPLEMENTED
Definition: debug.h:115

◆ RCloseServiceHandle()

DWORD WINAPI RCloseServiceHandle ( LPSC_RPC_HANDLE  hSCObject)

Definition at line 936 of file rpcserver.c.

938 {
939  PMANAGER_HANDLE hManager;
940  PSERVICE_HANDLE hService;
941  PSERVICE lpService;
943  DWORD dwError;
944  DWORD pcbBytesNeeded = 0;
945  DWORD dwServicesReturned = 0;
946 
947  DPRINT("RCloseServiceHandle() called\n");
948 
949  DPRINT("hSCObject = %p\n", *hSCObject);
950 
951  if (*hSCObject == 0)
952  return ERROR_INVALID_HANDLE;
953 
954  hManager = ScmGetServiceManagerFromHandle(*hSCObject);
955  hService = ScmGetServiceFromHandle(*hSCObject);
956 
957  if (hManager != NULL)
958  {
959  DPRINT("Found manager handle\n");
960 
961  /* Make sure we don't access stale memory if someone tries to use this handle again. */
962  hManager->Handle.Tag = INVALID_TAG;
963 
964  HeapFree(GetProcessHeap(), 0, hManager);
965  hManager = NULL;
966 
967  *hSCObject = NULL;
968 
969  DPRINT("RCloseServiceHandle() done\n");
970  return ERROR_SUCCESS;
971  }
972  else if (hService != NULL)
973  {
974  DPRINT("Found service handle\n");
975 
976  /* Lock the service database exclusively */
978 
979  /* Get the pointer to the service record */
980  lpService = hService->ServiceEntry;
981 
982  /* Make sure we don't access stale memory if someone tries to use this handle again. */
983  hService->Handle.Tag = INVALID_TAG;
984 
985  /* Free the handle */
986  HeapFree(GetProcessHeap(), 0, hService);
987  hService = NULL;
988 
989  ASSERT(lpService->dwRefCount > 0);
990 
991  lpService->dwRefCount--;
992  DPRINT("CloseServiceHandle - lpService->dwRefCount %u\n",
993  lpService->dwRefCount);
994 
995  if (lpService->dwRefCount == 0)
996  {
997  /* If this service has been marked for deletion */
998  if (lpService->bDeleted &&
999  lpService->Status.dwCurrentState == SERVICE_STOPPED)
1000  {
1001  /* Open the Services Reg key */
1003  L"System\\CurrentControlSet\\Services",
1004  0,
1006  &hServicesKey);
1007  if (dwError != ERROR_SUCCESS)
1008  {
1009  DPRINT("Failed to open services key\n");
1011  return dwError;
1012  }
1013 
1014  /* Call the internal function with NULL, just to get bytes we need */
1016  lpService,
1018  NULL,
1019  &pcbBytesNeeded,
1020  &dwServicesReturned);
1021 
1022  /* If pcbBytesNeeded returned a value then there are services running that are dependent on this service */
1023  if (pcbBytesNeeded)
1024  {
1025  DPRINT("Deletion failed due to running dependencies.\n");
1028  return ERROR_SUCCESS;
1029  }
1030 
1031  /* There are no references and no running dependencies,
1032  it is now safe to delete the service */
1033 
1034  /* Delete the Service Key */
1035  dwError = ScmDeleteRegKey(hServicesKey,
1036  lpService->lpServiceName);
1037 
1039 
1040  if (dwError != ERROR_SUCCESS)
1041  {
1042  DPRINT("Failed to Delete the Service Registry key\n");
1044  return dwError;
1045  }
1046 
1047  /* Delete the Service */
1048  ScmDeleteServiceRecord(lpService);
1049  }
1050  }
1051 
1053 
1054  *hSCObject = NULL;
1055 
1056  DPRINT("RCloseServiceHandle() done\n");
1057  return ERROR_SUCCESS;
1058  }
1059 
1060  DPRINT("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
1061 
1062  return ERROR_INVALID_HANDLE;
1063 }
SERVICE_STATUS Status
Definition: services.h:70
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
static PMANAGER_HANDLE ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:202
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:222
DWORD ScmDeleteRegKey(_In_ HKEY hKey, _In_ PCWSTR pszSubKey)
Definition: config.c:646
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD dwCurrentState
Definition: winsvc.h:100
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define KEY_READ
Definition: nt_native.h:1023
SCMGR_HANDLE Handle
Definition: rpcserver.c:45
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2420
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define SERVICE_STOPPED
Definition: winsvc.h:21
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
DWORD dwRefCount
Definition: services.h:68
static HANDLE hServicesKey
Definition: devinst.c:21
#define GetProcessHeap()
Definition: compat.h:595
#define ASSERT(a)
Definition: mode.c:44
PSERVICE ServiceEntry
Definition: rpcserver.c:46
#define SERVICE_ACTIVE
Definition: winsvc.h:50
static DWORD Int_EnumDependentServicesW(HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: rpcserver.c:783
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:62
SCMGR_HANDLE Handle
Definition: rpcserver.c:38
#define NULL
Definition: types.h:112
VOID ScmDeleteServiceRecord(PSERVICE lpService)
Definition: database.c:816
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2434
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
BOOL bDeleted
Definition: services.h:66
#define DPRINT
Definition: sndvol32.h:71
#define INVALID_TAG
Definition: rpcserver.c:27
#define HeapFree(x, y, z)
Definition: compat.h:594
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by CloseServiceHandle(), and SC_RPC_HANDLE_rundown().

◆ RControlService()

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

Definition at line 1069 of file rpcserver.c.

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

Referenced by ControlService().

◆ RControlServiceExA()

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

Definition at line 6677 of file rpcserver.c.

6681 {
6682  UNIMPLEMENTED;
6684 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define UNIMPLEMENTED
Definition: debug.h:115

◆ RControlServiceExW()

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

Definition at line 6690 of file rpcserver.c.

6694 {
6695  UNIMPLEMENTED;
6697 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define UNIMPLEMENTED
Definition: debug.h:115

◆ RCreateServiceA()

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

Definition at line 3592 of file rpcserver.c.

3609 {
3610  DWORD dwError = ERROR_SUCCESS;
3611  LPWSTR lpServiceNameW = NULL;
3612  LPWSTR lpDisplayNameW = NULL;
3613  LPWSTR lpBinaryPathNameW = NULL;
3614  LPWSTR lpLoadOrderGroupW = NULL;
3615  LPWSTR lpDependenciesW = NULL;
3616  LPWSTR lpServiceStartNameW = NULL;
3617  DWORD dwDependenciesLength = 0;
3618  SIZE_T cchLength;
3619  int len;
3620  LPCSTR lpStr;
3621 
3622  if (lpServiceName)
3623  {
3624  len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
3625  lpServiceNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3626  if (!lpServiceNameW)
3627  {
3629  goto cleanup;
3630  }
3631  MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
3632  }
3633 
3634  if (lpDisplayName)
3635  {
3637  lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3638  if (!lpDisplayNameW)
3639  {
3641  goto cleanup;
3642  }
3643  MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
3644  }
3645 
3646  if (lpBinaryPathName)
3647  {
3648  len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
3649  lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3650  if (!lpBinaryPathNameW)
3651  {
3653  goto cleanup;
3654  }
3655  MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
3656  }
3657 
3658  if (lpLoadOrderGroup)
3659  {
3660  len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
3661  lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3662  if (!lpLoadOrderGroupW)
3663  {
3665  goto cleanup;
3666  }
3667  MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
3668  }
3669 
3670  if (lpDependencies)
3671  {
3672  lpStr = (LPCSTR)lpDependencies;
3673  while (*lpStr)
3674  {
3675  cchLength = strlen(lpStr) + 1;
3676  dwDependenciesLength += (DWORD)cchLength;
3677  lpStr = lpStr + cchLength;
3678  }
3679  dwDependenciesLength++;
3680 
3681  lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
3682  if (!lpDependenciesW)
3683  {
3685  goto cleanup;
3686  }
3687  MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
3688  }
3689 
3690  if (lpServiceStartName)
3691  {
3692  len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
3693  lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3694  if (!lpServiceStartNameW)
3695  {
3697  goto cleanup;
3698  }
3699  MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
3700  }
3701 
3702  dwError = RCreateServiceW(hSCManager,
3703  lpServiceNameW,
3704  lpDisplayNameW,
3705  dwDesiredAccess,
3706  dwServiceType,
3707  dwStartType,
3708  dwErrorControl,
3709  lpBinaryPathNameW,
3710  lpLoadOrderGroupW,
3711  lpdwTagId,
3712  (LPBYTE)lpDependenciesW,
3713  dwDependenciesLength,
3714  lpServiceStartNameW,
3715  lpPassword,
3716  dwPwSize,
3717  lpServiceHandle);
3718 
3719 cleanup:
3720  if (lpServiceNameW !=NULL)
3721  HeapFree(GetProcessHeap(), 0, lpServiceNameW);
3722 
3723  if (lpDisplayNameW != NULL)
3724  HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
3725 
3726  if (lpBinaryPathNameW != NULL)
3727  HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
3728 
3729  if (lpLoadOrderGroupW != NULL)
3730  HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
3731 
3732  if (lpDependenciesW != NULL)
3733  HeapFree(GetProcessHeap(), 0, lpDependenciesW);
3734 
3735  if (lpServiceStartNameW != NULL)
3736  HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
3737 
3738  return dwError;
3739 }
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD WINAPI RCreateServiceW(SC_RPC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPCWSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle)
Definition: rpcserver.c:2272
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_ACP
Definition: compat.h:109
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define DWORD
Definition: nt_native.h:44
unsigned char * LPBYTE
Definition: typedefs.h:53
const char * LPCSTR
Definition: xmlstorage.h:183
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
GLenum GLsizei len
Definition: glext.h:6722
SC_HANDLE hSCManager
Definition: sc.c:12
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define MultiByteToWideChar
Definition: compat.h:110
char * cleanup(char *str)
Definition: wpickclick.c:99
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2769
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by CreateServiceA().

◆ RCreateServiceW()

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

Definition at line 2272 of file rpcserver.c.

2289 {
2290  PMANAGER_HANDLE hManager;
2291  DWORD dwError = ERROR_SUCCESS;
2292  PSERVICE lpService = NULL;
2293  SC_HANDLE hServiceHandle = NULL;
2294  LPWSTR lpImagePath = NULL;
2295  LPWSTR lpClearTextPassword = NULL;
2296  HKEY hServiceKey = NULL;
2297  LPWSTR lpObjectName;
2298 
2299  DPRINT("RCreateServiceW() called\n");
2300  DPRINT("lpServiceName = %S\n", lpServiceName);
2301  DPRINT("lpDisplayName = %S\n", lpDisplayName);
2302  DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess);
2303  DPRINT("dwServiceType = 0x%lx\n", dwServiceType);
2304  DPRINT("dwStartType = %lu\n", dwStartType);
2305  DPRINT("dwErrorControl = %lu\n", dwErrorControl);
2306  DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
2307  DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
2308  DPRINT("lpdwTagId = %p\n", lpdwTagId);
2309 
2310  if (ScmShutdown)
2312 
2314  if (hManager == NULL)
2315  {
2316  DPRINT1("Invalid service manager handle!\n");
2317  return ERROR_INVALID_HANDLE;
2318  }
2319 
2320  /* Check access rights */
2323  {
2324  DPRINT("Insufficient access rights! 0x%lx\n",
2325  hManager->Handle.DesiredAccess);
2326  return ERROR_ACCESS_DENIED;
2327  }
2328 
2329  if (*lpServiceName == 0)
2330  return ERROR_INVALID_NAME;
2331 
2332  if (*lpBinaryPathName == 0)
2333  return ERROR_INVALID_PARAMETER;
2334 
2335  /* Check for invalid service type value */
2336  if ((dwServiceType != SERVICE_KERNEL_DRIVER) &&
2337  (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER) &&
2338  ((dwServiceType & ~SERVICE_INTERACTIVE_PROCESS) != SERVICE_WIN32_OWN_PROCESS) &&
2340  {
2341  return ERROR_INVALID_PARAMETER;
2342  }
2343 
2344  /* Check for invalid start type value */
2345  if ((dwStartType != SERVICE_BOOT_START) &&
2346  (dwStartType != SERVICE_SYSTEM_START) &&
2347  (dwStartType != SERVICE_AUTO_START) &&
2348  (dwStartType != SERVICE_DEMAND_START) &&
2349  (dwStartType != SERVICE_DISABLED))
2350  {
2351  return ERROR_INVALID_PARAMETER;
2352  }
2353 
2354  /* Only drivers can be boot start or system start services */
2355  if ((dwStartType == SERVICE_BOOT_START) ||
2356  (dwStartType == SERVICE_SYSTEM_START))
2357  {
2358  if ((dwServiceType != SERVICE_KERNEL_DRIVER) &&
2359  (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER))
2360  {
2361  return ERROR_INVALID_PARAMETER;
2362  }
2363  }
2364 
2365  /* Check for invalid error control value */
2366  if ((dwErrorControl != SERVICE_ERROR_IGNORE) &&
2367  (dwErrorControl != SERVICE_ERROR_NORMAL) &&
2368  (dwErrorControl != SERVICE_ERROR_SEVERE) &&
2369  (dwErrorControl != SERVICE_ERROR_CRITICAL))
2370  {
2371  return ERROR_INVALID_PARAMETER;
2372  }
2373 
2374  if ((dwServiceType == (SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS)) &&
2375  (lpServiceStartName))
2376  {
2377  /* We allow LocalSystem to run interactive. */
2378  if (wcsicmp(lpServiceStartName, L"LocalSystem"))
2379  {
2380  return ERROR_INVALID_PARAMETER;
2381  }
2382  }
2383 
2384  if (lpdwTagId && (!lpLoadOrderGroup || !*lpLoadOrderGroup))
2385  {
2386  return ERROR_INVALID_PARAMETER;
2387  }
2388 
2389  /* Lock the service database exclusively */
2391 
2392  lpService = ScmGetServiceEntryByName(lpServiceName);
2393  if (lpService)
2394  {
2395  /* Unlock the service database */
2397 
2398  /* Check if it is marked for deletion */
2399  if (lpService->bDeleted)
2401 
2402  /* Return service-exists error */
2403  return ERROR_SERVICE_EXISTS;
2404  }
2405 
2406  if (lpDisplayName != NULL &&
2408  {
2409  /* Unlock the service database */
2411 
2413  }
2414 
2415  if (dwServiceType & SERVICE_DRIVER)
2416  {
2417  dwError = ScmCanonDriverImagePath(dwStartType,
2418  lpBinaryPathName,
2419  &lpImagePath);
2420  if (dwError != ERROR_SUCCESS)
2421  goto done;
2422  }
2423  else
2424  {
2425  if (dwStartType == SERVICE_BOOT_START ||
2426  dwStartType == SERVICE_SYSTEM_START)
2427  {
2428  /* Unlock the service database */
2430 
2431  return ERROR_INVALID_PARAMETER;
2432  }
2433  }
2434 
2435  /* Allocate a new service entry */
2436  dwError = ScmCreateNewServiceRecord(lpServiceName,
2437  &lpService,
2438  dwServiceType,
2439  dwStartType);
2440  if (dwError != ERROR_SUCCESS)
2441  goto done;
2442 
2443  /* Fill the new service entry */
2444  lpService->dwErrorControl = dwErrorControl;
2445 
2446  /* Fill the display name */
2447  if (lpDisplayName != NULL &&
2448  *lpDisplayName != 0 &&
2449  _wcsicmp(lpService->lpDisplayName, lpDisplayName) != 0)
2450  {
2451  lpService->lpDisplayName = HeapAlloc(GetProcessHeap(),
2453  (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
2454  if (lpService->lpDisplayName == NULL)
2455  {
2456  dwError = ERROR_NOT_ENOUGH_MEMORY;
2457  goto done;
2458  }
2459  wcscpy(lpService->lpDisplayName, lpDisplayName);
2460  }
2461 
2462  /* Assign the service to a group */
2463  if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
2464  {
2465  dwError = ScmSetServiceGroup(lpService,
2466  lpLoadOrderGroup);
2467  if (dwError != ERROR_SUCCESS)
2468  goto done;
2469  }
2470 
2471  /* Assign a new tag */
2472  if (lpdwTagId != NULL)
2473  {
2474  dwError = ScmAssignNewTag(lpService);
2475  if (dwError != ERROR_SUCCESS)
2476  goto done;
2477  }
2478 
2479  /* Assign the default security descriptor */
2480  if (dwServiceType & SERVICE_WIN32)
2481  {
2482  dwError = ScmCreateDefaultServiceSD(&lpService->pSecurityDescriptor);
2483  if (dwError != ERROR_SUCCESS)
2484  goto done;
2485  }
2486 
2487  /* Write service data to the registry */
2488  /* Create the service key */
2489  dwError = ScmCreateServiceKey(lpServiceName,
2490  KEY_WRITE,
2491  &hServiceKey);
2492  if (dwError != ERROR_SUCCESS)
2493  goto done;
2494 
2495  /* Set the display name */
2496  if (lpDisplayName != NULL && *lpDisplayName != 0)
2497  {
2498  RegSetValueExW(hServiceKey,
2499  L"DisplayName",
2500  0,
2501  REG_SZ,
2503  (DWORD)((wcslen(lpDisplayName) + 1) * sizeof(WCHAR)));
2504  }
2505 
2506  /* Set the service type */
2507  dwError = RegSetValueExW(hServiceKey,
2508  L"Type",
2509  0,
2510  REG_DWORD,
2511  (LPBYTE)&dwServiceType,
2512  sizeof(DWORD));
2513  if (dwError != ERROR_SUCCESS)
2514  goto done;
2515 
2516  /* Set the start value */
2517  dwError = RegSetValueExW(hServiceKey,
2518  L"Start",
2519  0,
2520  REG_DWORD,
2521  (LPBYTE)&dwStartType,
2522  sizeof(DWORD));
2523  if (dwError != ERROR_SUCCESS)
2524  goto done;
2525 
2526  /* Set the error control value */
2527  dwError = RegSetValueExW(hServiceKey,
2528  L"ErrorControl",
2529  0,
2530  REG_DWORD,
2531  (LPBYTE)&dwErrorControl,
2532  sizeof(DWORD));
2533  if (dwError != ERROR_SUCCESS)
2534  goto done;
2535 
2536  /* Set the image path */
2537  if (dwServiceType & SERVICE_WIN32)
2538  {
2539  dwError = RegSetValueExW(hServiceKey,
2540  L"ImagePath",
2541  0,
2542  REG_EXPAND_SZ,
2543  (LPBYTE)lpBinaryPathName,
2544  (DWORD)((wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR)));
2545  if (dwError != ERROR_SUCCESS)
2546  goto done;
2547  }
2548  else if (dwServiceType & SERVICE_DRIVER)
2549  {
2550  dwError = RegSetValueExW(hServiceKey,
2551  L"ImagePath",
2552  0,
2553  REG_EXPAND_SZ,
2554  (LPBYTE)lpImagePath,
2555  (DWORD)((wcslen(lpImagePath) + 1) * sizeof(WCHAR)));
2556  if (dwError != ERROR_SUCCESS)
2557  goto done;
2558  }
2559 
2560  /* Set the group name */
2561  if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
2562  {
2563  dwError = RegSetValueExW(hServiceKey,
2564  L"Group",
2565  0,
2566  REG_SZ,
2567  (LPBYTE)lpLoadOrderGroup,
2568  (DWORD)((wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)));
2569  if (dwError != ERROR_SUCCESS)
2570  goto done;
2571  }
2572 
2573  /* Set the service tag */
2574  if (lpdwTagId != NULL)
2575  {
2576  dwError = RegSetValueExW(hServiceKey,
2577  L"Tag",
2578  0,
2579  REG_DWORD,
2580  (LPBYTE)&lpService->dwTag,
2581  sizeof(DWORD));
2582  if (dwError != ERROR_SUCCESS)
2583  goto done;
2584  }
2585 
2586  /* Write dependencies */
2587  if (lpDependencies != NULL && *lpDependencies != 0)
2588  {
2589  dwError = ScmWriteDependencies(hServiceKey,
2590  (LPCWSTR)lpDependencies,
2591  dwDependSize);
2592  if (dwError != ERROR_SUCCESS)
2593  goto done;
2594  }
2595 
2596  /* Start name and password are only used by Win32 services */
2597  if (dwServiceType & SERVICE_WIN32)
2598  {
2599  /* Write service start name */
2600  lpObjectName = (lpServiceStartName != NULL) ? (LPWSTR)lpServiceStartName : L"LocalSystem";
2601  dwError = RegSetValueExW(hServiceKey,
2602  L"ObjectName",
2603  0,
2604  REG_SZ,
2605  (LPBYTE)lpObjectName,
2606  (DWORD)((wcslen(lpObjectName) + 1) * sizeof(WCHAR)));
2607  if (dwError != ERROR_SUCCESS)
2608  goto done;
2609 
2610  if (lpPassword != NULL && *(LPWSTR)lpPassword != 0)
2611  {
2612  /* Decrypt the password */
2613  dwError = ScmDecryptPassword(hSCManager,
2614  lpPassword,
2615  dwPwSize,
2616  &lpClearTextPassword);
2617  if (dwError != ERROR_SUCCESS)
2618  goto done;
2619 
2620  /* Write the password */
2621  dwError = ScmSetServicePassword(lpServiceName,
2622  lpClearTextPassword);
2623  if (dwError != ERROR_SUCCESS)
2624  goto done;
2625  }
2626 
2627  /* Write the security descriptor */
2628  dwError = ScmWriteSecurityDescriptor(hServiceKey,
2629  lpService->pSecurityDescriptor);
2630  if (dwError != ERROR_SUCCESS)
2631  goto done;
2632  }
2633 
2634  dwError = ScmCreateServiceHandle(lpService,
2635  &hServiceHandle);
2636  if (dwError != ERROR_SUCCESS)
2637  goto done;
2638 
2639  dwError = ScmCheckAccess(hServiceHandle,
2640  dwDesiredAccess);
2641  if (dwError != ERROR_SUCCESS)
2642  goto done;
2643 
2644  lpService->dwRefCount = 1;
2645 
2646  /* Get the service tag (if Win32) */
2647  ScmGenerateServiceTag(lpService);
2648 
2649  DPRINT("CreateService - lpService->dwRefCount %u\n", lpService->dwRefCount);
2650 
2651 done:
2652  /* Unlock the service database */
2654 
2655  if (hServiceKey != NULL)
2656  RegCloseKey(hServiceKey);
2657 
2658  if (lpClearTextPassword != NULL)
2659  {
2660  /* Wipe and release the password buffer */
2661  SecureZeroMemory(lpClearTextPassword,
2662  (wcslen(lpClearTextPassword) + 1) * sizeof(WCHAR));
2663  HeapFree(GetProcessHeap(), 0, lpClearTextPassword);
2664  }
2665 
2666  if (dwError == ERROR_SUCCESS)
2667  {
2668  DPRINT("hService %p\n", hServiceHandle);
2669  *lpServiceHandle = (SC_RPC_HANDLE)hServiceHandle;
2670 
2671  if (lpdwTagId != NULL)
2672  *lpdwTagId = lpService->dwTag;
2673  }
2674  else
2675  {
2676  if (lpService != NULL &&
2677  lpService->lpServiceName != NULL)
2678  {
2679  /* Release the display name buffer */
2680  HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
2681  }
2682 
2683  if (hServiceHandle)
2684  {
2685  /* Remove the service handle */
2686  HeapFree(GetProcessHeap(), 0, hServiceHandle);
2687  }
2688 
2689  if (lpService != NULL)
2690  {
2691  /* FIXME: remove the service entry */
2692  }
2693  }
2694 
2695  if (lpImagePath != NULL)
2696  HeapFree(GetProcessHeap(), 0, lpImagePath);
2697 
2698  DPRINT("RCreateServiceW() done (Error %lu)\n", dwError);
2699 
2700  return dwError;
2701 }
DWORD ScmCanonDriverImagePath(DWORD dwStartType, const wchar_t *lpServiceName, wchar_t **lpCanonName)
Definition: rpcserver.c:642
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:981
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:976
static PMANAGER_HANDLE ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:202
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:982
PSERVICE ScmGetServiceEntryByName(LPCWSTR lpServiceName)
Definition: database.c:657
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2420
#define SecureZeroMemory
Definition: winbase.h:1665
DWORD ScmDecryptPassword(_In_ PVOID ContextHandle, _In_ PBYTE pPassword, _In_ DWORD dwPasswordSize, _Out_ PWSTR *pClearTextPassword)
Definition: config.c:708
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:967
#define ERROR_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:651
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
LPWSTR lpDisplayName
Definition: services.h:63
DWORD ScmWriteDependencies(HKEY hServiceKey, LPCWSTR lpDependencies, DWORD dwDependenciesLength)
Definition: config.c:117
#define SERVICE_DISABLED
Definition: cmtypes.h:979
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
DWORD dwRefCount
Definition: services.h:68
DWORD ScmCreateServiceKey(LPCWSTR lpServiceName, REGSAM samDesired, PHKEY phKey)
Definition: config.c:72
DWORD ScmSetServiceGroup(PSERVICE lpService, LPCWSTR lpGroupName)
Definition: groupdb.c:61
#define SERVICE_BOOT_START
Definition: cmtypes.h:975
#define ERROR_SERVICE_MARKED_FOR_DELETE
Definition: winerror.h:623
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:954
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
#define KEY_WRITE
Definition: nt_native.h:1031
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:4899
PSERVICE ScmGetServiceEntryByDisplayName(LPCWSTR lpDisplayName)
Definition: database.c:686
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL ScmShutdown
Definition: services.c:29
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ERROR_DUPLICATE_SERVICE_NAME
Definition: winerror.h:629
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:963
#define wcsicmp
Definition: compat.h:15
#define ERROR_SERVICE_EXISTS
Definition: winerror.h:624
DWORD ScmSetServicePassword(IN PCWSTR pszServiceName, IN PCWSTR pszPassword)
Definition: config.c:469
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
DWORD ScmAssignNewTag(PSERVICE lpService)
Definition: rpcserver.c:272
LPWSTR lpServiceName
Definition: services.h:62
PSECURITY_DESCRIPTOR pSecurityDescriptor
Definition: services.h:79
SC_HANDLE hSCManager
Definition: sc.c:12
DWORD ScmWriteSecurityDescriptor(_In_ HKEY hServiceKey, _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor)
Definition: config.c:530
SCMGR_HANDLE Handle
Definition: rpcserver.c:38
DWORD ScmCreateNewServiceRecord(LPCWSTR lpServiceName, PSERVICE *lpServiceRecord, DWORD dwServiceType, DWORD dwStartType)
Definition: database.c:767
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define SERVICE_WIN32
Definition: cmtypes.h:964
#define SERVICE_ERROR_SEVERE
Definition: cmtypes.h:983
#define NULL
Definition: types.h:112
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static DWORD ScmCreateServiceHandle(PSERVICE lpServiceEntry, SC_HANDLE *Handle)
Definition: rpcserver.c:180
PVOID SC_RPC_HANDLE
Definition: svcctl.idl:21
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
DWORD dwTag
Definition: services.h:73
#define SERVICE_AUTO_START
Definition: cmtypes.h:977
DWORD dwErrorControl
Definition: services.h:72
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2434
static DWORD ScmCheckAccess(SC_HANDLE Handle, DWORD dwDesiredAccess)
Definition: rpcserver.c:242
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:984
BOOL bDeleted
Definition: services.h:66
DWORD ScmCreateDefaultServiceSD(PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
Definition: security.c:319
#define SERVICE_DRIVER
Definition: cmtypes.h:958
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define SERVICE_DEMAND_START
Definition: cmtypes.h:978
#define REG_DWORD
Definition: sdbapi.c:596
DWORD ScmGenerateServiceTag(PSERVICE lpServiceRecord)
Definition: database.c:744
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2769
#define HeapFree(x, y, z)
Definition: compat.h:594
DWORD DesiredAccess
Definition: rpcserver.c:32
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:953
#define REG_SZ
Definition: layer.c:22

Referenced by CreateServiceW(), and RCreateServiceA().

◆ RCreateServiceWOW64A()

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

Definition at line 6541 of file rpcserver.c.

6558 {
6559  UNIMPLEMENTED;
6561 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define UNIMPLEMENTED
Definition: debug.h:115

◆ RCreateServiceWOW64W()

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

Definition at line 6567 of file rpcserver.c.

6584 {
6585  UNIMPLEMENTED;
6587 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define UNIMPLEMENTED
Definition: debug.h:115

◆ RDeleteService()

DWORD WINAPI RDeleteService ( SC_RPC_HANDLE  hService)

Definition at line 1304 of file rpcserver.c.

1306 {
1307  PSERVICE_HANDLE hSvc;
1308  PSERVICE lpService;
1309  DWORD dwError;
1310 
1311  DPRINT("RDeleteService() called\n");
1312 
1313  if (ScmShutdown)
1315 
1316  hSvc = ScmGetServiceFromHandle(hService);
1317  if (hSvc == NULL)
1318  {
1319  DPRINT1("Invalid service handle!\n");
1320  return ERROR_INVALID_HANDLE;
1321  }
1322 
1324  DELETE))
1325  return ERROR_ACCESS_DENIED;
1326 
1327  lpService = hSvc->ServiceEntry;
1328  if (lpService == NULL)
1329  {
1330  DPRINT("lpService == NULL!\n");
1331  return ERROR_INVALID_HANDLE;
1332  }
1333 
1334  /* Lock the service database exclusively */
1336 
1337  if (lpService->bDeleted)
1338  {
1339  DPRINT("The service has already been marked for delete!\n");
1341  goto Done;
1342  }
1343 
1344  /* Mark service for delete */
1345  lpService->bDeleted = TRUE;
1346 
1347  dwError = ScmMarkServiceForDelete(lpService);
1348 
1349 Done:
1350  /* Unlock the service database */
1352 
1353  DPRINT("RDeleteService() done\n");
1354 
1355  return dwError;
1356 }
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:222
#define TRUE
Definition: types.h:120
SCMGR_HANDLE Handle
Definition: rpcserver.c:45
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2420
#define ERROR_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:651
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define ERROR_SERVICE_MARKED_FOR_DELETE
Definition: winerror.h:623
BOOL ScmShutdown
Definition: services.c:29
PSERVICE ServiceEntry
Definition: rpcserver.c:46
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD ScmMarkServiceForDelete(PSERVICE pService)
Definition: config.c:223
#define NULL
Definition: types.h:112
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
#define DPRINT1
Definition: precomp.h:8
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2434
BOOL bDeleted
Definition: services.h:66
#define DPRINT
Definition: sndvol32.h:71
DWORD DesiredAccess
Definition: rpcserver.c:32
#define DELETE
Definition: nt_native.h:57

Referenced by DeleteService().

◆ REnumDependentServicesA()

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

Definition at line 3745 of file rpcserver.c.

3752 {
3753  DWORD dwError = ERROR_SUCCESS;
3754  DWORD dwServicesReturned = 0;
3755  DWORD dwServiceCount;
3757  PSERVICE_HANDLE hSvc;
3758  PSERVICE lpService = NULL;
3759  PSERVICE *lpServicesArray = NULL;
3760  LPENUM_SERVICE_STATUSA lpServicesPtr = NULL;
3761  LPSTR lpStr;
3762 
3763  *pcbBytesNeeded = 0;
3764  *lpServicesReturned = 0;
3765 
3766  DPRINT("REnumDependentServicesA() called\n");
3767 
3768  hSvc = ScmGetServiceFromHandle(hService);
3769  if (hSvc == NULL)
3770  {
3771  DPRINT1("Invalid service handle!\n");
3772  return ERROR_INVALID_HANDLE;
3773  }
3774 
3775  lpService = hSvc->ServiceEntry;
3776 
3777  /* Check access rights */
3780  {
3781  DPRINT("Insufficient access rights! 0x%lx\n",
3782  hSvc->Handle.DesiredAccess);
3783  return ERROR_ACCESS_DENIED;
3784  }
3785 
3786  /* Open the Services Reg key */
3788  L"System\\CurrentControlSet\\Services",
3789  0,
3790  KEY_READ,
3791  &hServicesKey);
3792 
3793  if (dwError != ERROR_SUCCESS)
3794  return dwError;
3795 
3796  /* NOTE: Windows calculates the pcbBytesNeeded based on WCHAR strings for
3797  both EnumDependentServicesA and EnumDependentServicesW. So returned pcbBytesNeeded
3798  are the same for both. Verified in WINXP. */
3799 
3800  /* First determine the bytes needed and get the number of dependent services*/
3802  lpService,
3803  dwServiceState,
3804  NULL,
3806  &dwServicesReturned);
3807  if (dwError != ERROR_SUCCESS)
3808  goto Done;
3809 
3810  /* If buffer size is less than the bytes needed or pointer is null*/
3811  if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
3812  {
3813  dwError = ERROR_MORE_DATA;
3814  goto Done;
3815  }
3816 
3817  /* Allocate memory for array of service pointers */
3818  lpServicesArray = HeapAlloc(GetProcessHeap(),
3820  (dwServicesReturned + 1) * sizeof(PSERVICE));
3821  if (!lpServicesArray)
3822  {
3823  DPRINT("Could not allocate a buffer!!\n");
3824  dwError = ERROR_NOT_ENOUGH_MEMORY;
3825  goto Done;
3826  }
3827 
3828  dwServicesReturned = 0;
3829  *pcbBytesNeeded = 0;
3830 
3832  lpService,
3833  dwServiceState,
3834  lpServicesArray,
3836  &dwServicesReturned);
3837  if (dwError != ERROR_SUCCESS)
3838  {
3839  goto Done;
3840  }
3841 
3842  lpServicesPtr = (LPENUM_SERVICE_STATUSA)lpServices;
3843  lpStr = (LPSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSA)));
3844 
3845  /* Copy EnumDepenedentService to Buffer */
3846  for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
3847  {
3848  lpService = lpServicesArray[dwServiceCount];
3849 
3850  /* Copy the status info */
3851  memcpy(&lpServicesPtr->ServiceStatus,
3852  &lpService->Status,
3853  sizeof(SERVICE_STATUS));
3854 
3855  /* Copy display name */
3857  0,
3858  lpService->lpDisplayName,
3859  -1,
3860  lpStr,
3861  (int)wcslen(lpService->lpDisplayName),
3862  0,
3863  0);
3864  lpServicesPtr->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
3865  lpStr += strlen(lpStr) + 1;
3866 
3867  /* Copy service name */
3869  0,
3870  lpService->lpServiceName,
3871  -1,
3872  lpStr,
3873  (int)wcslen(lpService->lpServiceName),
3874  0,
3875  0);
3876  lpServicesPtr->lpServiceName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
3877  lpStr += strlen(lpStr) + 1;
3878 
3879  lpServicesPtr++;
3880  }
3881 
3882  *lpServicesReturned = dwServicesReturned;
3883 
3884 Done:
3885  if (lpServicesArray)
3886  HeapFree(GetProcessHeap(), 0, lpServicesArray);
3887 
3889 
3890  DPRINT("REnumDependentServicesA() done (Error %lu)\n", dwError);
3891 
3892  return dwError;
3893 }
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
SERVICE_STATUS Status
Definition: services.h:70
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:222
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:111
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define KEY_READ
Definition: nt_native.h:1023
SCMGR_HANDLE Handle
Definition: rpcserver.c:45
#define CP_ACP
Definition: compat.h:109
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
SERVICE_STATUS ServiceStatus
Definition: winsvc.h:127
LPWSTR lpDisplayName
Definition: services.h:63
char * LPSTR
Definition: xmlstorage.h:182
uint32_t ULONG_PTR
Definition: typedefs.h:65
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
static HANDLE hServicesKey
Definition: devinst.c:21
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
PSERVICE ServiceEntry
Definition: rpcserver.c:46
static DWORD Int_EnumDependentServicesW(HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: rpcserver.c:783
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ DWORD _In_ DWORD cbBufSize
Definition: winsvc.h:424
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:62
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_MORE_DATA
Definition: dderror.h:13
struct _ENUM_SERVICE_STATUSA * LPENUM_SERVICE_STATUSA
#define NULL
Definition: types.h:112
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
#define ULONG_PTR
Definition: config.h:101
#define DPRINT
Definition: sndvol32.h:71
#define HeapFree(x, y, z)
Definition: compat.h:594
DWORD DesiredAccess
Definition: rpcserver.c:32
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by EnumDependentServicesA().

◆ REnumDependentServicesW()

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

Definition at line 2707 of file rpcserver.c.

2714 {
2715  DWORD dwError = ERROR_SUCCESS;
2716  DWORD dwServicesReturned = 0;
2717  DWORD dwServiceCount;
2719  PSERVICE_HANDLE hSvc;
2720  PSERVICE lpService = NULL;
2721  PSERVICE *lpServicesArray = NULL;
2722  LPENUM_SERVICE_STATUSW lpServicesPtr = NULL;
2723  LPWSTR lpStr;
2724 
2725  *pcbBytesNeeded = 0;
2726  *lpServicesReturned = 0;
2727 
2728  DPRINT("REnumDependentServicesW() called\n");
2729 
2730  hSvc = ScmGetServiceFromHandle(hService);
2731  if (hSvc == NULL)
2732  {
2733  DPRINT1("Invalid service handle!\n");
2734  return ERROR_INVALID_HANDLE;
2735  }
2736 
2737  lpService = hSvc->ServiceEntry;
2738 
2739  /* Check access rights */
2742  {
2743  DPRINT("Insufficient access rights! 0x%lx\n",
2744  hSvc->Handle.DesiredAccess);
2745  return ERROR_ACCESS_DENIED;
2746  }
2747 
2748  /* Open the Services Reg key */
2750  L"System\\CurrentControlSet\\Services",
2751  0,
2752  KEY_READ,
2753  &hServicesKey);
2754  if (dwError != ERROR_SUCCESS)
2755  return dwError;
2756 
2757  /* First determine the bytes needed and get the number of dependent services */
2759  lpService,
2760  dwServiceState,
2761  NULL,
2763  &dwServicesReturned);
2764  if (dwError != ERROR_SUCCESS)
2765  goto Done;
2766 
2767  /* If buffer size is less than the bytes needed or pointer is null */
2768  if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
2769  {
2770  dwError = ERROR_MORE_DATA;
2771  goto Done;
2772  }
2773 
2774  /* Allocate memory for array of service pointers */
2775  lpServicesArray = HeapAlloc(GetProcessHeap(),
2777  (dwServicesReturned + 1) * sizeof(PSERVICE));
2778  if (!lpServicesArray)
2779  {
2780  DPRINT1("Could not allocate a buffer!!\n");
2781  dwError = ERROR_NOT_ENOUGH_MEMORY;
2782  goto Done;
2783  }
2784 
2785  dwServicesReturned = 0;
2786  *pcbBytesNeeded = 0;
2787 
2789  lpService,
2790  dwServiceState,
2791  lpServicesArray,
2793  &dwServicesReturned);
2794  if (dwError != ERROR_SUCCESS)
2795  {
2796  goto Done;
2797  }
2798 
2799  lpServicesPtr = (LPENUM_SERVICE_STATUSW)lpServices;
2800  lpStr = (LPWSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSW)));
2801 
2802  /* Copy EnumDepenedentService to Buffer */
2803  for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
2804  {
2805  lpService = lpServicesArray[dwServiceCount];
2806 
2807  /* Copy status info */
2808  memcpy(&lpServicesPtr->ServiceStatus,
2809  &lpService->Status,
2810  sizeof(SERVICE_STATUS));
2811 
2812  /* Copy display name */
2813  wcscpy(lpStr, lpService->lpDisplayName);
2814  lpServicesPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
2815  lpStr += (wcslen(lpService->lpDisplayName) + 1);
2816 
2817  /* Copy service name */
2818  wcscpy(lpStr, lpService->lpServiceName);
2819  lpServicesPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
2820  lpStr += (wcslen(lpService->lpServiceName) + 1);
2821 
2822  lpServicesPtr++;
2823  }
2824 
2825  *lpServicesReturned = dwServicesReturned;
2826 
2827 Done:
2828  if (lpServicesArray != NULL)
2829  HeapFree(GetProcessHeap(), 0, lpServicesArray);
2830 
2832 
2833  DPRINT("REnumDependentServicesW() done (Error %lu)\n", dwError);
2834 
2835  return dwError;
2836 }
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
SERVICE_STATUS Status
Definition: services.h:70
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:222
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
SCMGR_HANDLE Handle
Definition: rpcserver.c:45
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
LPWSTR lpDisplayName
Definition: services.h:63
uint32_t ULONG_PTR
Definition: typedefs.h:65
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
struct _ENUM_SERVICE_STATUSW * LPENUM_SERVICE_STATUSW
static HANDLE hServicesKey
Definition: devinst.c:21
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
PSERVICE ServiceEntry
Definition: rpcserver.c:46
static DWORD Int_EnumDependentServicesW(HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: rpcserver.c:783
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ DWORD _In_ DWORD cbBufSize
Definition: winsvc.h:424
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:62
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
SERVICE_STATUS ServiceStatus
Definition: winsvc.h:132
#define ERROR_MORE_DATA
Definition: dderror.h:13
LPWSTR lpServiceName
Definition: winsvc.h:130
LPWSTR lpDisplayName
Definition: winsvc.h:131
#define NULL
Definition: types.h:112
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
#define ULONG_PTR
Definition: config.h:101
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define HeapFree(x, y, z)
Definition: compat.h:594
DWORD DesiredAccess
Definition: rpcserver.c:32
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by EnumDependentServicesW().

◆ REnumServiceGroupW()

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

Definition at line 4753 of file rpcserver.c.

4763 {
4764  PMANAGER_HANDLE hManager;
4765  PSERVICE lpService;
4766  DWORD dwError = ERROR_SUCCESS;
4767  PLIST_ENTRY ServiceEntry;
4768  PSERVICE CurrentService;
4769  DWORD dwState;
4770  DWORD dwRequiredSize;
4771  DWORD dwServiceCount;
4772  DWORD dwSize;
4773  DWORD dwLastResumeCount = 0;
4774  LPENUM_SERVICE_STATUSW lpStatusPtr;
4775  LPWSTR lpStringPtr;
4776 
4777  DPRINT("REnumServiceGroupW() called\n");
4778 
4779  if (ScmShutdown)
4781 
4783  if (hManager == NULL)
4784  {
4785  DPRINT1("Invalid service manager handle!\n");
4786  return ERROR_INVALID_HANDLE;
4787  }
4788 
4789  if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
4790  {
4791  return ERROR_INVALID_ADDRESS;
4792  }
4793 
4794  *pcbBytesNeeded = 0;
4795  *lpServicesReturned = 0;
4796 
4797  if ((dwServiceType == 0) ||
4798  ((dwServiceType & ~SERVICE_TYPE_ALL) != 0))
4799  {
4800  DPRINT("Not a valid Service Type!\n");
4801  return ERROR_INVALID_PARAMETER;
4802  }
4803 
4804  if ((dwServiceState == 0) ||
4805  ((dwServiceState & ~SERVICE_STATE_ALL) != 0))
4806  {
4807  DPRINT("Not a valid Service State!\n");
4808  return ERROR_INVALID_PARAMETER;
4809  }
4810 
4811  /* Check access rights */
4814  {
4815  DPRINT("Insufficient access rights! 0x%lx\n",
4816  hManager->Handle.DesiredAccess);
4817  return ERROR_ACCESS_DENIED;
4818  }
4819 
4820  if (lpResumeIndex)
4821  dwLastResumeCount = *lpResumeIndex;
4822 
4823  /* Lock the service database shared */
4825 
4826  lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
4827  if (lpService == NULL)
4828  {
4829  dwError = ERROR_SUCCESS;
4830  goto Done;
4831  }
4832 
4833  dwRequiredSize = 0;
4834  dwServiceCount = 0;
4835 
4836  for (ServiceEntry = &lpService->ServiceListEntry;
4837  ServiceEntry != &ServiceListHead;
4838  ServiceEntry = ServiceEntry->Flink)
4839  {
4840  CurrentService = CONTAINING_RECORD(ServiceEntry,
4841  SERVICE,
4842  ServiceListEntry);
4843 
4844  if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4845  continue;
4846 
4847  dwState = SERVICE_ACTIVE;
4848  if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4849  dwState = SERVICE_INACTIVE;
4850 
4851  if ((dwState & dwServiceState) == 0)
4852  continue;
4853 
4854  if (pszGroupName)
4855  {
4856  if (*pszGroupName == 0)
4857  {
4858  if (CurrentService->lpGroup != NULL)
4859  continue;
4860  }
4861  else
4862  {
4863  if ((CurrentService->lpGroup == NULL) ||
4864  _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4865  continue;
4866  }
4867  }
4868 
4869  dwSize = sizeof(ENUM_SERVICE_STATUSW) +
4870  (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4871  (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
4872 
4873  if (dwRequiredSize + dwSize > cbBufSize)
4874  {
4875  DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
4876  break;
4877  }
4878 
4879  DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
4880  dwRequiredSize += dwSize;
4881  dwServiceCount++;
4882  dwLastResumeCount = CurrentService->dwResumeCount;
4883  }
4884 
4885  DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
4886  DPRINT("dwServiceCount: %lu\n", dwServiceCount);
4887 
4888  for (;
4889  ServiceEntry != &ServiceListHead;
4890  ServiceEntry = ServiceEntry->Flink)
4891  {
4892  CurrentService = CONTAINING_RECORD(ServiceEntry,
4893  SERVICE,
4894  ServiceListEntry);
4895 
4896  if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4897  continue;
4898 
4899  dwState = SERVICE_ACTIVE;
4900  if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4901  dwState = SERVICE_INACTIVE;
4902 
4903  if ((dwState & dwServiceState) == 0)
4904  continue;
4905 
4906  if (pszGroupName)
4907  {
4908  if (*pszGroupName == 0)
4909  {
4910  if (CurrentService->lpGroup != NULL)
4911  continue;
4912  }
4913  else
4914  {
4915  if ((CurrentService->lpGroup == NULL) ||
4916  _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4917  continue;
4918  }
4919  }
4920 
4921  dwRequiredSize += (sizeof(ENUM_SERVICE_STATUSW) +
4922  (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4923  (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
4924 
4925  dwError = ERROR_MORE_DATA;
4926  }
4927 
4928  DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
4929 
4930  if (lpResumeIndex)
4931  *lpResumeIndex = dwLastResumeCount;
4932 
4933  *lpServicesReturned = dwServiceCount;
4934  *pcbBytesNeeded = dwRequiredSize;
4935 
4936  lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpBuffer;
4937  lpStringPtr = (LPWSTR)((ULONG_PTR)lpBuffer +
4938  dwServiceCount * sizeof(ENUM_SERVICE_STATUSW));
4939 
4940  dwRequiredSize = 0;
4941  for (ServiceEntry = &lpService->ServiceListEntry;
4942  ServiceEntry != &ServiceListHead;
4943  ServiceEntry = ServiceEntry->Flink)
4944  {
4945  CurrentService = CONTAINING_RECORD(ServiceEntry,
4946  SERVICE,
4947  ServiceListEntry);
4948 
4949  if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4950  continue;
4951 
4952  dwState = SERVICE_ACTIVE;
4953  if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4954  dwState = SERVICE_INACTIVE;
4955 
4956  if ((dwState & dwServiceState) == 0)
4957  continue;
4958 
4959  if (pszGroupName)
4960  {
4961  if (*pszGroupName == 0)
4962  {
4963  if (CurrentService->lpGroup != NULL)
4964  continue;
4965  }
4966  else
4967  {
4968  if ((CurrentService->lpGroup == NULL) ||
4969  _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4970  continue;
4971  }
4972  }
4973 
4974  dwSize = sizeof(ENUM_SERVICE_STATUSW) +
4975  (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4976  (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
4977 
4978  if (dwRequiredSize + dwSize > cbBufSize)
4979  break;
4980 
4981  /* Copy the service name */
4982  wcscpy(lpStringPtr, CurrentService->lpServiceName);
4983  lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
4984  lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
4985 
4986  /* Copy the display name */
4987  wcscpy(lpStringPtr, CurrentService->lpDisplayName);
4988  lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
4989  lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
4990 
4991  /* Copy the status information */
4992  memcpy(&lpStatusPtr->ServiceStatus,
4993  &CurrentService->Status,
4994  sizeof(SERVICE_STATUS));
4995 
4996  lpStatusPtr++;
4997  dwRequiredSize += dwSize;
4998  }
4999 
5000  if (dwError == ERROR_SUCCESS)
5001  {
5002  *pcbBytesNeeded = 0;
5003  if (lpResumeIndex) *lpResumeIndex = 0;
5004  }
5005 
5006 Done:
5007  /* Unlock the service database */
5009 
5010  DPRINT("REnumServiceGroupW() done (Error %lu)\n", dwError);
5011 
5012  return dwError;
5013 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
SERVICE_STATUS Status
Definition: services.h:70
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
static PMANAGER_HANDLE ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:202
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD dwCurrentState
Definition: winsvc.h:100
#define SERVICE_INACTIVE
Definition: winsvc.h:51
#define ERROR_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:651
BOOL ScmLockDatabaseShared(VOID)
Definition: database.c:2427
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
LPWSTR lpGroupName
Definition: services.h:33
#define SERVICE_STATE_ALL
Definition: winsvc.h:52
PSERVICE_GROUP lpGroup
Definition: services.h:64
LPWSTR lpDisplayName
Definition: services.h:63
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
struct _ENUM_SERVICE_STATUSW * LPENUM_SERVICE_STATUSW
#define SERVICE_TYPE_ALL
Definition: cmtypes.h:969
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY ServiceListEntry
Definition: services.h:61
BOOL ScmShutdown
Definition: services.c:29
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SERVICE_ACTIVE
Definition: winsvc.h:50
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ DWORD _In_ DWORD cbBufSize
Definition: winsvc.h:424
DWORD dwServiceType
Definition: winsvc.h:99
LIST_ENTRY ServiceListHead
Definition: database.c:29
struct _ENUM_SERVICE_STATUSW ENUM_SERVICE_STATUSW
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
DWORD dwResumeCount
Definition: services.h:67
LPWSTR lpServiceName
Definition: services.h:62
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
SERVICE_STATUS ServiceStatus
Definition: winsvc.h:132
Definition: typedefs.h:119
SC_HANDLE hSCManager
Definition: sc.c:12
#define ERROR_MORE_DATA
Definition: dderror.h:13
PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
Definition: database.c:715
SCMGR_HANDLE Handle
Definition: rpcserver.c:38
LPWSTR lpServiceName
Definition: winsvc.h:130
LPWSTR lpDisplayName
Definition: winsvc.h:131
#define NULL
Definition: types.h:112
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2434
#define ULONG_PTR
Definition: config.h:101
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
DWORD DesiredAccess
Definition: rpcserver.c:32
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

Referenced by EnumServiceGroupW(), and REnumServicesStatusW().

◆ REnumServicesStatusA()

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

Definition at line 3899 of file rpcserver.c.

3908 {
3909  LPENUM_SERVICE_STATUSW lpStatusPtrW = NULL;
3910  LPENUM_SERVICE_STATUSW lpStatusPtrIncrW;
3911  LPENUM_SERVICE_STATUSA lpStatusPtrA = NULL;
3912  LPWSTR lpStringPtrW;
3913  LPSTR lpStringPtrA;
3914  DWORD dwError;
3915  DWORD dwServiceCount;
3916 
3917  DPRINT("REnumServicesStatusA() called\n");
3918 
3919  if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
3920  {
3921  return ERROR_INVALID_ADDRESS;
3922  }
3923 
3924  if ((dwBufSize > 0) && (lpBuffer))
3925  {
3926  lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
3927  if (!lpStatusPtrW)
3928  {
3929  DPRINT("Failed to allocate buffer!\n");
3930  return ERROR_NOT_ENOUGH_MEMORY;
3931  }
3932  }
3933 
3934  dwError = REnumServicesStatusW(hSCManager,
3935  dwServiceType,
3936  dwServiceState,
3937  (LPBYTE)lpStatusPtrW,
3938  dwBufSize,
3940  lpServicesReturned,
3941  lpResumeHandle);
3942 
3943  /* if no services were returned then we are Done */
3944  if (*lpServicesReturned == 0)
3945  goto Done;
3946 
3947  lpStatusPtrIncrW = lpStatusPtrW;
3948  lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
3949  lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
3950  *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSA));
3951  lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
3952  *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSW));
3953 
3954  for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
3955  {
3956  /* Copy the service name */
3958  0,
3959  lpStringPtrW,
3960  -1,
3961  lpStringPtrA,
3962  (int)wcslen(lpStringPtrW),
3963  0,
3964  0);
3965 
3966  lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
3967  lpStringPtrA += wcslen(lpStringPtrW) + 1;
3968  lpStringPtrW += wcslen(lpStringPtrW) + 1;
3969 
3970  /* Copy the display name */
3972  0,
3973  lpStringPtrW,
3974  -1,
3975  lpStringPtrA,
3976  (int)wcslen(lpStringPtrW),
3977  0,
3978  0);
3979 
3980  lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
3981  lpStringPtrA += wcslen(lpStringPtrW) + 1;
3982  lpStringPtrW += wcslen(lpStringPtrW) + 1;
3983 
3984  /* Copy the status information */
3985  memcpy(&lpStatusPtrA->ServiceStatus,
3986  &lpStatusPtrIncrW->ServiceStatus,
3987  sizeof(SERVICE_STATUS));
3988 
3989  lpStatusPtrIncrW++;
3990  lpStatusPtrA++;
3991  }
3992 
3993 Done:
3994  if (lpStatusPtrW)
3995  HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
3996 
3997  DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
3998 
3999  return dwError;
4000 }
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
#define WideCharToMultiByte
Definition: compat.h:111
#define CP_ACP
Definition: compat.h:109
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
SERVICE_STATUS ServiceStatus
Definition: winsvc.h:127
char * LPSTR
Definition: xmlstorage.h:182
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _ENUM_SERVICE_STATUSW ENUM_SERVICE_STATUSW
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
SERVICE_STATUS ServiceStatus
Definition: winsvc.h:132
SC_HANDLE hSCManager
Definition: sc.c:12
DWORD WINAPI REnumServicesStatusW(SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD dwBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeHandle)
Definition: rpcserver.c:2842
struct _ENUM_SERVICE_STATUSA * LPENUM_SERVICE_STATUSA
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ULONG_PTR
Definition: config.h:101
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _ENUM_SERVICE_STATUSA ENUM_SERVICE_STATUSA
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by EnumServicesStatusA().

◆ REnumServicesStatusExA()

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

Definition at line 6096 of file rpcserver.c.

6107 {
6108  LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrW = NULL;
6109  LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrIncrW;
6110  LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtrA = NULL;
6111  LPWSTR lpStringPtrW;
6112  LPSTR lpStringPtrA;
6113  LPWSTR pszGroupNameW = NULL;
6114  DWORD dwError;
6115  DWORD dwServiceCount;
6116 
6117  DPRINT("REnumServicesStatusExA() called\n");
6118 
6119  if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
6120  {
6121  return ERROR_INVALID_ADDRESS;
6122  }
6123 
6124  if (pszGroupName)
6125  {
6126  pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
6127  if (!pszGroupNameW)
6128  {
6129  DPRINT("Failed to allocate buffer!\n");
6130  dwError = ERROR_NOT_ENOUGH_MEMORY;
6131  goto Done;
6132  }
6133 
6135  0,
6136  pszGroupName,
6137  -1,
6138  pszGroupNameW,
6139  (int)(strlen(pszGroupName) + 1));
6140  }
6141 
6142  if ((cbBufSize > 0) && (lpBuffer))
6143  {
6144  lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbBufSize);
6145  if (!lpStatusPtrW)
6146  {
6147  DPRINT("Failed to allocate buffer!\n");
6148  dwError = ERROR_NOT_ENOUGH_MEMORY;
6149  goto Done;
6150  }
6151  }
6152 
6154  InfoLevel,
6155  dwServiceType,
6156  dwServiceState,
6157  (LPBYTE)lpStatusPtrW,
6158  cbBufSize,
6160  lpServicesReturned,
6161  lpResumeIndex,
6162  pszGroupNameW);
6163 
6164  /* if no services were returned then we are Done */
6165  if (*lpServicesReturned == 0)
6166  goto Done;
6167 
6168  lpStatusPtrIncrW = lpStatusPtrW;
6169  lpStatusPtrA = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer;
6170  lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
6171  *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
6172  lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
6173  *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
6174 
6175  for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
6176  {
6177  /* Copy the service name */
6179  0,
6180  lpStringPtrW,
6181  -1,
6182  lpStringPtrA,
6183  (int)wcslen(lpStringPtrW),
6184  0,
6185  0);
6186 
6187  lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
6188  lpStringPtrA += wcslen(lpStringPtrW) + 1;
6189  lpStringPtrW += wcslen(lpStringPtrW) + 1;
6190 
6191  /* Copy the display name */
6193  0,
6194  lpStringPtrW,
6195  -1,
6196  lpStringPtrA,
6197  (int)wcslen(lpStringPtrW),
6198  0,
6199  0);
6200 
6201  lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
6202  lpStringPtrA += wcslen(lpStringPtrW) + 1;
6203  lpStringPtrW += wcslen(lpStringPtrW) + 1;
6204 
6205  /* Copy the status information */
6206  memcpy(&lpStatusPtrA->ServiceStatusProcess,
6207  &lpStatusPtrIncrW->ServiceStatusProcess,
6208  sizeof(SERVICE_STATUS));
6209 
6210  /* Copy the service process ID */
6211  lpStatusPtrA->ServiceStatusProcess.dwProcessId = lpStatusPtrIncrW->ServiceStatusProcess.dwProcessId;
6212 
6213  lpStatusPtrA->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
6214 
6215  lpStatusPtrIncrW++;
6216  lpStatusPtrA++;
6217  }
6218 
6219 Done:
6220  if (pszGroupNameW)
6221  HeapFree(GetProcessHeap(), 0, pszGroupNameW);
6222 
6223  if (lpStatusPtrW)
6224  HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
6225 
6226  DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError);
6227 
6228  return dwError;
6229 }
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
#define WideCharToMultiByte
Definition: compat.h:111
DWORD WINAPI REnumServicesStatusExW(SC_RPC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCWSTR pszGroupName)
Definition: rpcserver.c:6235
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_ACP
Definition: compat.h:109
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
char * LPSTR
Definition: xmlstorage.h:182
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
struct _ENUM_SERVICE_STATUS_PROCESSA ENUM_SERVICE_STATUS_PROCESSA
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
struct _ENUM_SERVICE_STATUS_PROCESSA * LPENUM_SERVICE_STATUS_PROCESSA
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ DWORD _In_ DWORD cbBufSize
Definition: winsvc.h:424
SERVICE_STATUS_PROCESS ServiceStatusProcess
Definition: winsvc.h:142
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
SC_HANDLE hSCManager
Definition: sc.c:12
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define MultiByteToWideChar
Definition: compat.h:110
struct _ENUM_SERVICE_STATUS_PROCESSW ENUM_SERVICE_STATUS_PROCESSW
#define ULONG_PTR
Definition: config.h:101
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
SERVICE_STATUS_PROCESS ServiceStatusProcess
Definition: winsvc.h:137
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by EnumServicesStatusExA().

◆ REnumServicesStatusExW()

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

Definition at line 6235 of file rpcserver.c.

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