ReactOS  0.4.13-dev-79-gcd489d8
rpcserver.c File Reference
#include "services.h"
#include <winnls.h>
#include <strsafe.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 25 of file rpcserver.c.

◆ MANAGER_TAG

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

Definition at line 23 of file rpcserver.c.

◆ NDEBUG

#define NDEBUG

Definition at line 18 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 58 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 48 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 53 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 77 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 66 of file rpcserver.c.

◆ SERVICE_TAG

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

Definition at line 24 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 73 of file rpcserver.c.

◆ TAG_ARRAY_SIZE

#define TAG_ARRAY_SIZE   32

Definition at line 84 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 781 of file rpcserver.c.

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

6739 {
6741 }
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
GLenum GLsizei len
Definition: glext.h:6722
#define HEAP_ZERO_MEMORY
Definition: compat.h:123

◆ midl_user_free()

void __RPC_USER midl_user_free ( void __RPC_FAR ptr)

Definition at line 6744 of file rpcserver.c.

6745 {
6746  HeapFree(GetProcessHeap(), 0, ptr);
6747 }
static PVOID ptr
Definition: dispmode.c:27
#define GetProcessHeap()
Definition: compat.h:395
#define HeapFree(x, y, z)
Definition: compat.h:394

◆ RChangeServiceConfig2A()

DWORD WINAPI RChangeServiceConfig2A ( SC_RPC_HANDLE  hService,
SC_RPC_CONFIG_INFOA  Info 
)

Definition at line 5013 of file rpcserver.c.

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

Referenced by ChangeServiceConfig2A().

◆ RChangeServiceConfig2W()

DWORD WINAPI RChangeServiceConfig2W ( SC_RPC_HANDLE  hService,
SC_RPC_CONFIG_INFOW  Info 
)

Definition at line 5414 of file rpcserver.c.

5417 {
5418  DWORD dwError = ERROR_SUCCESS;
5419  PSERVICE_HANDLE hSvc;
5420  PSERVICE lpService = NULL;
5421  HKEY hServiceKey = NULL;
5423 
5424  DPRINT("RChangeServiceConfig2W() called\n");
5425  DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
5426 
5427  if (ScmShutdown)
5429 
5430  if ((Info.dwInfoLevel < SERVICE_CONFIG_DESCRIPTION) ||
5431  (Info.dwInfoLevel > SERVICE_CONFIG_FAILURE_ACTIONS))
5432  {
5433  return ERROR_INVALID_LEVEL;
5434  }
5435 
5436  hSvc = ScmGetServiceFromHandle(hService);
5437  if (hSvc == NULL)
5438  {
5439  DPRINT("Invalid service handle!\n");
5440  return ERROR_INVALID_HANDLE;
5441  }
5442 
5443  if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5445 
5446  /* Check the access rights */
5448  RequiredAccess))
5449  {
5450  DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
5451  return ERROR_ACCESS_DENIED;
5452  }
5453 
5454  if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5455  {
5456  /* FIXME: Check if the caller has the SE_SHUTDOWN_NAME privilege */
5457 
5458  }
5459 
5460  lpService = hSvc->ServiceEntry;
5461  if (lpService == NULL)
5462  {
5463  DPRINT("lpService == NULL!\n");
5464  return ERROR_INVALID_HANDLE;
5465  }
5466 
5467  /* Failure actions can only be set for Win32 services, not for drivers */
5468  if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5469  {
5470  if (lpService->Status.dwServiceType & SERVICE_DRIVER)
5472  }
5473 
5474  /* Lock the service database exclusively */
5476 
5477  if (lpService->bDeleted)
5478  {
5479  DPRINT("The service has already been marked for delete!\n");
5481  goto done;
5482  }
5483 
5484  /* Open the service key */
5485  dwError = ScmOpenServiceKey(lpService->szServiceName,
5487  &hServiceKey);
5488  if (dwError != ERROR_SUCCESS)
5489  goto done;
5490 
5491  if (Info.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
5492  {
5493  LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd;
5494 
5495  /* Modify the service description, if specified */
5496  if (lpServiceDescription != NULL &&
5497  lpServiceDescription->lpDescription != NULL)
5498  {
5499  /* If the description is "" then we delete it */
5500  if (*lpServiceDescription->lpDescription == 0)
5501  {
5502  DPRINT("Delete service description\n");
5503  dwError = RegDeleteValueW(hServiceKey, L"Description");
5504 
5505  if (dwError == ERROR_FILE_NOT_FOUND)
5506  dwError = ERROR_SUCCESS;
5507  }
5508  else
5509  {
5510  DPRINT("Setting service description value %S\n", lpServiceDescription->lpDescription);
5511  dwError = RegSetValueExW(hServiceKey,
5512  L"Description",
5513  0,
5514  REG_SZ,
5515  (LPBYTE)lpServiceDescription->lpDescription,
5516  (DWORD)((wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR)));
5517  }
5518  }
5519  else
5520  {
5521  dwError = ERROR_SUCCESS;
5522  }
5523  }
5524  else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5525  {
5526  dwError = ScmSetFailureActions(hServiceKey,
5528  }
5529 
5530 done:
5531  if (hServiceKey != NULL)
5532  RegCloseKey(hServiceKey);
5533 
5534  /* Unlock the service database */
5536 
5537  DPRINT("RChangeServiceConfig2W() done (Error %lu)\n", dwError);
5538 
5539  return dwError;
5540 }
SERVICE_STATUS Status
Definition: services.h:69
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:220
#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:43
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2310
#define ERROR_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:651
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
#define SERVICE_CONFIG_DESCRIPTION
Definition: winsvc.h:65
struct TraceInfo Info
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#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:4917
static DWORD ScmSetFailureActions(HKEY hServiceKey, LPSERVICE_FAILURE_ACTIONSW lpFailureActions)
Definition: rpcserver.c:5190
struct _SERVICE_DESCRIPTIONW * LPSERVICE_DESCRIPTIONW
if(!(yy_init))
Definition: macro.lex.yy.c:714
BOOL ScmShutdown
Definition: services.c:29
PSERVICE ServiceEntry
Definition: rpcserver.c:44
__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:2219
#define SERVICE_START
Definition: winsvc.h:57
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2368
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
DWORD ScmOpenServiceKey(LPWSTR lpServiceName, REGSAM samDesired, PHKEY phKey)
Definition: config.c:42
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2324
BOOL bDeleted
Definition: services.h:65
#define SERVICE_DRIVER
Definition: cmtypes.h:956
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
#define ERROR_CANNOT_DETECT_DRIVER_FAILURE
Definition: winerror.h:631
WCHAR szServiceName[1]
Definition: services.h:82
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG ACCESS_MASK
Definition: nt_native.h:40
DWORD DesiredAccess
Definition: rpcserver.c:30
#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 3455 of file rpcserver.c.

3469 {
3470  DWORD dwError = ERROR_SUCCESS;
3471  LPWSTR lpBinaryPathNameW = NULL;
3472  LPWSTR lpLoadOrderGroupW = NULL;
3473  LPWSTR lpDependenciesW = NULL;
3474  LPWSTR lpServiceStartNameW = NULL;
3475  LPWSTR lpDisplayNameW = NULL;
3476  DWORD dwDependenciesLength = 0;
3477  SIZE_T cchLength;
3478  int len;
3479  LPCSTR lpStr;
3480 
3481  if (lpBinaryPathName)
3482  {
3483  len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
3484  lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3485  if (!lpBinaryPathNameW)
3486  {
3488  goto cleanup;
3489  }
3490  MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
3491  }
3492 
3493  if (lpLoadOrderGroup)
3494  {
3495  len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
3496  lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3497  if (!lpLoadOrderGroupW)
3498  {
3500  goto cleanup;
3501  }
3502  MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
3503  }
3504 
3505  if (lpDependencies)
3506  {
3507  lpStr = (LPCSTR)lpDependencies;
3508  while (*lpStr)
3509  {
3510  cchLength = strlen(lpStr) + 1;
3511  dwDependenciesLength += (DWORD)cchLength;
3512  lpStr = lpStr + cchLength;
3513  }
3514  dwDependenciesLength++;
3515 
3516  lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
3517  if (!lpDependenciesW)
3518  {
3520  goto cleanup;
3521  }
3522  MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
3523  }
3524 
3525  if (lpServiceStartName)
3526  {
3527  len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
3528  lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3529  if (!lpServiceStartNameW)
3530  {
3532  goto cleanup;
3533  }
3534  MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
3535  }
3536 
3537  if (lpDisplayName)
3538  {
3540  lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3541  if (!lpDisplayNameW)
3542  {
3544  goto cleanup;
3545  }
3546  MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
3547  }
3548 
3549  dwError = RChangeServiceConfigW(hService,
3550  dwServiceType,
3551  dwStartType,
3552  dwErrorControl,
3553  lpBinaryPathNameW,
3554  lpLoadOrderGroupW,
3555  lpdwTagId,
3556  (LPBYTE)lpDependenciesW,
3557  dwDependenciesLength,
3558  lpServiceStartNameW,
3559  lpPassword,
3560  dwPwSize,
3561  lpDisplayNameW);
3562 
3563 cleanup:
3564  if (lpBinaryPathNameW != NULL)
3565  HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
3566 
3567  if (lpLoadOrderGroupW != NULL)
3568  HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
3569 
3570  if (lpDependenciesW != NULL)
3571  HeapFree(GetProcessHeap(), 0, lpDependenciesW);
3572 
3573  if (lpServiceStartNameW != NULL)
3574  HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
3575 
3576  if (lpDisplayNameW != NULL)
3577  HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
3578 
3579  return dwError;
3580 }
#define ERROR_SUCCESS
Definition: deptool.c:10
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_ACP
Definition: compat.h:99
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define DWORD
Definition: nt_native.h:44
unsigned char * LPBYTE
Definition: typedefs.h:52
smooth NULL
Definition: ftsmooth.c:416
const char * LPCSTR
Definition: xmlstorage.h:183
#define GetProcessHeap()
Definition: compat.h:395
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:409
GLenum GLsizei len
Definition: glext.h:6722
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define MultiByteToWideChar
Definition: compat.h:100
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:2730
#define HeapFree(x, y, z)
Definition: compat.h:394
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:1916

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

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

6662 {
6663  UNIMPLEMENTED;
6665 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
#define UNIMPLEMENTED
Definition: debug.h:114

◆ RCloseServiceHandle()

DWORD WINAPI RCloseServiceHandle ( LPSC_RPC_HANDLE  hSCObject)

Definition at line 934 of file rpcserver.c.

936 {
937  PMANAGER_HANDLE hManager;
938  PSERVICE_HANDLE hService;
939  PSERVICE lpService;
941  DWORD dwError;
942  DWORD pcbBytesNeeded = 0;
943  DWORD dwServicesReturned = 0;
944 
945  DPRINT("RCloseServiceHandle() called\n");
946 
947  DPRINT("hSCObject = %p\n", *hSCObject);
948 
949  if (*hSCObject == 0)
950  return ERROR_INVALID_HANDLE;
951 
952  hManager = ScmGetServiceManagerFromHandle(*hSCObject);
953  hService = ScmGetServiceFromHandle(*hSCObject);
954 
955  if (hManager != NULL)
956  {
957  DPRINT("Found manager handle\n");
958 
959  /* Make sure we don't access stale memory if someone tries to use this handle again. */
960  hManager->Handle.Tag = INVALID_TAG;
961 
962  HeapFree(GetProcessHeap(), 0, hManager);
963  hManager = NULL;
964 
965  *hSCObject = NULL;
966 
967  DPRINT("RCloseServiceHandle() done\n");
968  return ERROR_SUCCESS;
969  }
970  else if (hService != NULL)
971  {
972  DPRINT("Found service handle\n");
973 
974  /* Lock the service database exclusively */
976 
977  /* Get the pointer to the service record */
978  lpService = hService->ServiceEntry;
979 
980  /* Make sure we don't access stale memory if someone tries to use this handle again. */
981  hService->Handle.Tag = INVALID_TAG;
982 
983  /* Free the handle */
984  HeapFree(GetProcessHeap(), 0, hService);
985  hService = NULL;
986 
987  ASSERT(lpService->dwRefCount > 0);
988 
989  lpService->dwRefCount--;
990  DPRINT("CloseServiceHandle - lpService->dwRefCount %u\n",
991  lpService->dwRefCount);
992 
993  if (lpService->dwRefCount == 0)
994  {
995  /* If this service has been marked for deletion */
996  if (lpService->bDeleted &&
997  lpService->Status.dwCurrentState == SERVICE_STOPPED)
998  {
999  /* Open the Services Reg key */
1001  L"System\\CurrentControlSet\\Services",
1002  0,
1004  &hServicesKey);
1005  if (dwError != ERROR_SUCCESS)
1006  {
1007  DPRINT("Failed to open services key\n");
1009  return dwError;
1010  }
1011 
1012  /* Call the internal function with NULL, just to get bytes we need */
1014  lpService,
1016  NULL,
1017  &pcbBytesNeeded,
1018  &dwServicesReturned);
1019 
1020  /* If pcbBytesNeeded returned a value then there are services running that are dependent on this service */
1021  if (pcbBytesNeeded)
1022  {
1023  DPRINT("Deletion failed due to running dependencies.\n");
1026  return ERROR_SUCCESS;
1027  }
1028 
1029  /* There are no references and no running dependencies,
1030  it is now safe to delete the service */
1031 
1032  /* Delete the Service Key */
1033  dwError = ScmDeleteRegKey(hServicesKey,
1034  lpService->lpServiceName);
1035 
1037 
1038  if (dwError != ERROR_SUCCESS)
1039  {
1040  DPRINT("Failed to Delete the Service Registry key\n");
1042  return dwError;
1043  }
1044 
1045  /* Delete the Service */
1046  ScmDeleteServiceRecord(lpService);
1047  }
1048  }
1049 
1051 
1052  *hSCObject = NULL;
1053 
1054  DPRINT("RCloseServiceHandle() done\n");
1055  return ERROR_SUCCESS;
1056  }
1057 
1058  DPRINT("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
1059 
1060  return ERROR_INVALID_HANDLE;
1061 }
SERVICE_STATUS Status
Definition: services.h:69
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
static PMANAGER_HANDLE ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:200
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:220
DWORD ScmDeleteRegKey(_In_ HKEY hKey, _In_ PCWSTR pszSubKey)
Definition: config.c:639
#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:43
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2310
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
#define SERVICE_STOPPED
Definition: winsvc.h:21
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
DWORD dwRefCount
Definition: services.h:67
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static HANDLE hServicesKey
Definition: devinst.c:21
#define GetProcessHeap()
Definition: compat.h:395
PSERVICE ServiceEntry
Definition: rpcserver.c:44
#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:781
unsigned long DWORD
Definition: ntddk_ex.h:95
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:61
SCMGR_HANDLE Handle
Definition: rpcserver.c:36
VOID ScmDeleteServiceRecord(PSERVICE lpService)
Definition: database.c:715
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2324
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
BOOL bDeleted
Definition: services.h:65
#define INVALID_TAG
Definition: rpcserver.c:25
#define HeapFree(x, y, z)
Definition: compat.h:394
#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 1067 of file rpcserver.c.

1071 {
1072  PSERVICE_HANDLE hSvc;
1073  PSERVICE lpService;
1075  DWORD dwError = ERROR_SUCCESS;
1076  DWORD pcbBytesNeeded = 0;
1077  DWORD dwServicesReturned = 0;
1078  DWORD dwControlsAccepted;
1079  DWORD dwCurrentState;
1081  LPCWSTR lpLogStrings[2];
1082  WCHAR szLogBuffer[80];
1083  UINT uID;
1084 
1085  DPRINT("RControlService() called\n");
1086 
1087  if (ScmShutdown)
1089 
1090  /* Check the service handle */
1091  hSvc = ScmGetServiceFromHandle(hService);
1092  if (hSvc == NULL)
1093  {
1094  DPRINT1("Invalid service handle!\n");
1095  return ERROR_INVALID_HANDLE;
1096  }
1097 
1098  /* Check the service entry point */
1099  lpService = hSvc->ServiceEntry;
1100  if (lpService == NULL)
1101  {
1102  DPRINT1("lpService == NULL!\n");
1103  return ERROR_INVALID_HANDLE;
1104  }
1105 
1106  /* Check access rights */
1107  switch (dwControl)
1108  {
1109  case SERVICE_CONTROL_STOP:
1111  break;
1112 
1113  case SERVICE_CONTROL_PAUSE:
1121  break;
1122 
1125  break;
1126 
1127  default:
1128  if (dwControl >= 128 && dwControl <= 255)
1130  else
1131  return ERROR_INVALID_PARAMETER;
1132  break;
1133  }
1134 
1136  DesiredAccess))
1137  return ERROR_ACCESS_DENIED;
1138 
1139  /* Return the current service status information */
1140  RtlCopyMemory(lpServiceStatus,
1141  &lpService->Status,
1142  sizeof(SERVICE_STATUS));
1143 
1144  if (dwControl == SERVICE_CONTROL_STOP)
1145  {
1146  /* Check if the service has dependencies running as windows
1147  doesn't stop a service that does */
1148 
1149  /* Open the Services Reg key */
1151  L"System\\CurrentControlSet\\Services",
1152  0,
1153  KEY_READ,
1154  &hServicesKey);
1155  if (dwError != ERROR_SUCCESS)
1156  {
1157  DPRINT("Failed to open services key\n");
1158  return dwError;
1159  }
1160 
1161  /* Call the internal function with NULL, just to get bytes we need */
1163  lpService,
1165  NULL,
1166  &pcbBytesNeeded,
1167  &dwServicesReturned);
1168 
1170 
1171  /* If pcbBytesNeeded is not zero then there are services running that
1172  are dependent on this service */
1173  if (pcbBytesNeeded != 0)
1174  {
1175  DPRINT("Service has running dependencies. Failed to stop service.\n");
1177  }
1178  }
1179 
1180  if (lpService->Status.dwServiceType & SERVICE_DRIVER)
1181  {
1182  /* Send control code to the driver */
1183  dwError = ScmControlDriver(lpService,
1184  dwControl,
1185  lpServiceStatus);
1186  }
1187  else
1188  {
1189  dwControlsAccepted = lpService->Status.dwControlsAccepted;
1190  dwCurrentState = lpService->Status.dwCurrentState;
1191 
1192  /* Return ERROR_SERVICE_NOT_ACTIVE if the service has not been started */
1193  if (lpService->lpImage == NULL || dwCurrentState == SERVICE_STOPPED)
1194  return ERROR_SERVICE_NOT_ACTIVE;
1195 
1196  /* Check the current state before sending a control request */
1197  switch (dwCurrentState)
1198  {
1199  case SERVICE_STOP_PENDING:
1200  case SERVICE_STOPPED:
1202 
1203  case SERVICE_START_PENDING:
1204  switch (dwControl)
1205  {
1206  case SERVICE_CONTROL_STOP:
1207  break;
1208 
1210  RtlCopyMemory(lpServiceStatus,
1211  &lpService->Status,
1212  sizeof(SERVICE_STATUS));
1213  return ERROR_SUCCESS;
1214 
1215  default:
1217  }
1218  break;
1219  }
1220 
1221  /* Check if the control code is acceptable to the service */
1222  switch (dwControl)
1223  {
1224  case SERVICE_CONTROL_STOP:
1225  if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0)
1227  break;
1228 
1229  case SERVICE_CONTROL_PAUSE:
1231  if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0)
1233  break;
1234 
1236  if ((dwControlsAccepted & SERVICE_ACCEPT_PARAMCHANGE) == 0)
1238  break;
1239 
1244  if ((dwControlsAccepted & SERVICE_ACCEPT_NETBINDCHANGE) == 0)
1246  break;
1247  }
1248 
1249  /* Send control code to the service */
1250  dwError = ScmControlService(lpService->lpImage->hControlPipe,
1251  lpService->lpServiceName,
1252  (SERVICE_STATUS_HANDLE)lpService,
1253  dwControl);
1254 
1255  /* Return service status information */
1256  RtlCopyMemory(lpServiceStatus,
1257  &lpService->Status,
1258  sizeof(SERVICE_STATUS));
1259  }
1260 
1261  if (dwError == ERROR_SUCCESS)
1262  {
1263  if (dwControl == SERVICE_CONTROL_STOP ||
1264  dwControl == SERVICE_CONTROL_PAUSE ||
1265  dwControl == SERVICE_CONTROL_CONTINUE)
1266  {
1267  /* Log a successful send control */
1268 
1269  switch (dwControl)
1270  {
1271  case SERVICE_CONTROL_STOP:
1272  uID = IDS_SERVICE_STOP;
1273  break;
1274 
1275  case SERVICE_CONTROL_PAUSE:
1276  uID = IDS_SERVICE_PAUSE;
1277  break;
1278 
1280  uID = IDS_SERVICE_RESUME;
1281  break;
1282  }
1283  LoadStringW(GetModuleHandle(NULL), uID, szLogBuffer, ARRAYSIZE(szLogBuffer));
1284 
1285  lpLogStrings[0] = lpService->lpDisplayName;
1286  lpLogStrings[1] = szLogBuffer;
1287 
1290  2,
1291  lpLogStrings);
1292  }
1293  }
1294 
1295  return dwError;
1296 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#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:69
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:220
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:43
#define SERVICE_ACCEPT_NETBINDCHANGE
Definition: winsvc.h:32
#define ERROR_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:651
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
#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:62
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:87
#define SERVICE_CONTROL_PARAMCHANGE
Definition: winsvc.h:41
#define ERROR_INVALID_SERVICE_CONTROL
Definition: winerror.h:603
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#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:52
#define EVENTLOG_INFORMATION_TYPE
Definition: winnt_old.h:2632
BOOL ScmShutdown
Definition: services.c:29
PSERVICE ServiceEntry
Definition: rpcserver.c:44
__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:781
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:61
#define ERROR_DEPENDENT_SERVICES_RUNNING
Definition: winerror.h:602
DWORD dwControlsAccepted
Definition: winsvc.h:101
#define GetModuleHandle
Definition: winbase.h:3641
#define SERVICE_STOP
Definition: winsvc.h:58
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
#define SERVICE_CONTROL_NETBINDENABLE
Definition: winsvc.h:44
unsigned int UINT
Definition: ndis.h:50
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:3381
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_DRIVER
Definition: cmtypes.h:956
PSERVICE_IMAGE lpImage
Definition: services.h:64
DWORD ScmControlService(HANDLE hControlPipe, PWSTR pServiceName, SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwControl)
Definition: database.c:1213
#define SERVICE_CONTROL_NETBINDDISABLE
Definition: winsvc.h:45
#define SERVICE_CONTROL_NETBINDREMOVE
Definition: winsvc.h:43
HANDLE hControlPipe
Definition: services.h:50
#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:30
#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 6671 of file rpcserver.c.

6675 {
6676  UNIMPLEMENTED;
6678 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
#define UNIMPLEMENTED
Definition: debug.h:114

◆ RControlServiceExW()

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

Definition at line 6684 of file rpcserver.c.

6688 {
6689  UNIMPLEMENTED;
6691 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
#define UNIMPLEMENTED
Definition: debug.h:114

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

3603 {
3604  DWORD dwError = ERROR_SUCCESS;
3605  LPWSTR lpServiceNameW = NULL;
3606  LPWSTR lpDisplayNameW = NULL;
3607  LPWSTR lpBinaryPathNameW = NULL;
3608  LPWSTR lpLoadOrderGroupW = NULL;
3609  LPWSTR lpDependenciesW = NULL;
3610  LPWSTR lpServiceStartNameW = NULL;
3611  DWORD dwDependenciesLength = 0;
3612  SIZE_T cchLength;
3613  int len;
3614  LPCSTR lpStr;
3615 
3616  if (lpServiceName)
3617  {
3618  len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
3619  lpServiceNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3620  if (!lpServiceNameW)
3621  {
3623  goto cleanup;
3624  }
3625  MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
3626  }
3627 
3628  if (lpDisplayName)
3629  {
3631  lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3632  if (!lpDisplayNameW)
3633  {
3635  goto cleanup;
3636  }
3637  MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
3638  }
3639 
3640  if (lpBinaryPathName)
3641  {
3642  len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
3643  lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3644  if (!lpBinaryPathNameW)
3645  {
3647  goto cleanup;
3648  }
3649  MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
3650  }
3651 
3652  if (lpLoadOrderGroup)
3653  {
3654  len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
3655  lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3656  if (!lpLoadOrderGroupW)
3657  {
3659  goto cleanup;
3660  }
3661  MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
3662  }
3663 
3664  if (lpDependencies)
3665  {
3666  lpStr = (LPCSTR)lpDependencies;
3667  while (*lpStr)
3668  {
3669  cchLength = strlen(lpStr) + 1;
3670  dwDependenciesLength += (DWORD)cchLength;
3671  lpStr = lpStr + cchLength;
3672  }
3673  dwDependenciesLength++;
3674 
3675  lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
3676  if (!lpDependenciesW)
3677  {
3679  goto cleanup;
3680  }
3681  MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
3682  }
3683 
3684  if (lpServiceStartName)
3685  {
3686  len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
3687  lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3688  if (!lpServiceStartNameW)
3689  {
3691  goto cleanup;
3692  }
3693  MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
3694  }
3695 
3696  dwError = RCreateServiceW(hSCManager,
3697  lpServiceNameW,
3698  lpDisplayNameW,
3699  dwDesiredAccess,
3700  dwServiceType,
3701  dwStartType,
3702  dwErrorControl,
3703  lpBinaryPathNameW,
3704  lpLoadOrderGroupW,
3705  lpdwTagId,
3706  (LPBYTE)lpDependenciesW,
3707  dwDependenciesLength,
3708  lpServiceStartNameW,
3709  lpPassword,
3710  dwPwSize,
3711  lpServiceHandle);
3712 
3713 cleanup:
3714  if (lpServiceNameW !=NULL)
3715  HeapFree(GetProcessHeap(), 0, lpServiceNameW);
3716 
3717  if (lpDisplayNameW != NULL)
3718  HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
3719 
3720  if (lpBinaryPathNameW != NULL)
3721  HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
3722 
3723  if (lpLoadOrderGroupW != NULL)
3724  HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
3725 
3726  if (lpDependenciesW != NULL)
3727  HeapFree(GetProcessHeap(), 0, lpDependenciesW);
3728 
3729  if (lpServiceStartNameW != NULL)
3730  HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
3731 
3732  return dwError;
3733 }
#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:2267
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_ACP
Definition: compat.h:99
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define DWORD
Definition: nt_native.h:44
unsigned char * LPBYTE
Definition: typedefs.h:52
smooth NULL
Definition: ftsmooth.c:416
const char * LPCSTR
Definition: xmlstorage.h:183
#define GetProcessHeap()
Definition: compat.h:395
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:409
GLenum GLsizei len
Definition: glext.h:6722
SC_HANDLE hSCManager
Definition: sc.c:12
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define MultiByteToWideChar
Definition: compat.h:100
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:2730
#define HeapFree(x, y, z)
Definition: compat.h:394

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

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

6552 {
6553  UNIMPLEMENTED;
6555 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
#define UNIMPLEMENTED
Definition: debug.h:114

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

6578 {
6579  UNIMPLEMENTED;
6581 }
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
#define UNIMPLEMENTED
Definition: debug.h:114

◆ RDeleteService()

DWORD WINAPI RDeleteService ( SC_RPC_HANDLE  hService)

Definition at line 1302 of file rpcserver.c.

1304 {
1305  PSERVICE_HANDLE hSvc;
1306  PSERVICE lpService;
1307  DWORD dwError;
1308 
1309  DPRINT("RDeleteService() called\n");
1310 
1311  if (ScmShutdown)
1313 
1314  hSvc = ScmGetServiceFromHandle(hService);
1315  if (hSvc == NULL)
1316  {
1317  DPRINT1("Invalid service handle!\n");
1318  return ERROR_INVALID_HANDLE;
1319  }
1320 
1322  DELETE))
1323  return ERROR_ACCESS_DENIED;
1324 
1325  lpService = hSvc->ServiceEntry;
1326  if (lpService == NULL)
1327  {
1328  DPRINT("lpService == NULL!\n");
1329  return ERROR_INVALID_HANDLE;
1330  }
1331 
1332  /* Lock the service database exclusively */
1334 
1335  if (lpService->bDeleted)
1336  {
1337  DPRINT("The service has already been marked for delete!\n");
1339  goto Done;
1340  }
1341 
1342  /* Mark service for delete */
1343  lpService->bDeleted = TRUE;
1344 
1345  dwError = ScmMarkServiceForDelete(lpService);
1346 
1347 Done:
1348  /* Unlock the service database */
1350 
1351  DPRINT("RDeleteService() done\n");
1352 
1353  return dwError;
1354 }
#define TRUE
Definition: types.h:120
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:220
SCMGR_HANDLE Handle
Definition: rpcserver.c:43
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2310
#define ERROR_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:651
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define ERROR_SERVICE_MARKED_FOR_DELETE
Definition: winerror.h:623
BOOL ScmShutdown
Definition: services.c:29
PSERVICE ServiceEntry
Definition: rpcserver.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD ScmMarkServiceForDelete(PSERVICE pService)
Definition: config.c:223
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
#define DPRINT1
Definition: precomp.h:8
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2324
BOOL bDeleted
Definition: services.h:65
DWORD DesiredAccess
Definition: rpcserver.c:30
#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 3739 of file rpcserver.c.

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

2708 {
2709  DWORD dwError = ERROR_SUCCESS;
2710  DWORD dwServicesReturned = 0;
2711  DWORD dwServiceCount;
2713  PSERVICE_HANDLE hSvc;
2714  PSERVICE lpService = NULL;
2715  PSERVICE *lpServicesArray = NULL;
2716  LPENUM_SERVICE_STATUSW lpServicesPtr = NULL;
2717  LPWSTR lpStr;
2718 
2719  *pcbBytesNeeded = 0;
2720  *lpServicesReturned = 0;
2721 
2722  DPRINT("REnumDependentServicesW() called\n");
2723 
2724  hSvc = ScmGetServiceFromHandle(hService);
2725  if (hSvc == NULL)
2726  {
2727  DPRINT1("Invalid service handle!\n");
2728  return ERROR_INVALID_HANDLE;
2729  }
2730 
2731  lpService = hSvc->ServiceEntry;
2732 
2733  /* Check access rights */
2736  {
2737  DPRINT("Insufficient access rights! 0x%lx\n",
2738  hSvc->Handle.DesiredAccess);
2739  return ERROR_ACCESS_DENIED;
2740  }
2741 
2742  /* Open the Services Reg key */
2744  L"System\\CurrentControlSet\\Services",
2745  0,
2746  KEY_READ,
2747  &hServicesKey);
2748  if (dwError != ERROR_SUCCESS)
2749  return dwError;
2750 
2751  /* First determine the bytes needed and get the number of dependent services */
2753  lpService,
2754  dwServiceState,
2755  NULL,
2757  &dwServicesReturned);
2758  if (dwError != ERROR_SUCCESS)
2759  goto Done;
2760 
2761  /* If buffer size is less than the bytes needed or pointer is null */
2762  if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
2763  {
2764  dwError = ERROR_MORE_DATA;
2765  goto Done;
2766  }
2767 
2768  /* Allocate memory for array of service pointers */
2769  lpServicesArray = HeapAlloc(GetProcessHeap(),
2771  (dwServicesReturned + 1) * sizeof(PSERVICE));
2772  if (!lpServicesArray)
2773  {
2774  DPRINT1("Could not allocate a buffer!!\n");
2775  dwError = ERROR_NOT_ENOUGH_MEMORY;
2776  goto Done;
2777  }
2778 
2779  dwServicesReturned = 0;
2780  *pcbBytesNeeded = 0;
2781 
2783  lpService,
2784  dwServiceState,
2785  lpServicesArray,
2787  &dwServicesReturned);
2788  if (dwError != ERROR_SUCCESS)
2789  {
2790  goto Done;
2791  }
2792 
2793  lpServicesPtr = (LPENUM_SERVICE_STATUSW)lpServices;
2794  lpStr = (LPWSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSW)));
2795 
2796  /* Copy EnumDepenedentService to Buffer */
2797  for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
2798  {
2799  lpService = lpServicesArray[dwServiceCount];
2800 
2801  /* Copy status info */
2802  memcpy(&lpServicesPtr->ServiceStatus,
2803  &lpService->Status,
2804  sizeof(SERVICE_STATUS));
2805 
2806  /* Copy display name */
2807  wcscpy(lpStr, lpService->lpDisplayName);
2808  lpServicesPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
2809  lpStr += (wcslen(lpService->lpDisplayName) + 1);
2810 
2811  /* Copy service name */
2812  wcscpy(lpStr, lpService->lpServiceName);
2813  lpServicesPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
2814  lpStr += (wcslen(lpService->lpServiceName) + 1);
2815 
2816  lpServicesPtr++;
2817  }
2818 
2819  *lpServicesReturned = dwServicesReturned;
2820 
2821 Done:
2822  if (lpServicesArray != NULL)
2823  HeapFree(GetProcessHeap(), 0, lpServicesArray);
2824 
2826 
2827  DPRINT("REnumDependentServicesW() done (Error %lu)\n", dwError);
2828 
2829  return dwError;
2830 }
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
SERVICE_STATUS Status
Definition: services.h:69
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
static PSERVICE_HANDLE ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:220
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
SCMGR_HANDLE Handle
Definition: rpcserver.c:43
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
LPWSTR lpDisplayName
Definition: services.h:62
uint32_t ULONG_PTR
Definition: typedefs.h:63
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
smooth NULL
Definition: ftsmooth.c:416
struct _ENUM_SERVICE_STATUSW * LPENUM_SERVICE_STATUSW
void DPRINT(...)
Definition: polytest.cpp:61
static HANDLE hServicesKey
Definition: devinst.c:21
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
PSERVICE ServiceEntry
Definition: rpcserver.c:44
static DWORD Int_EnumDependentServicesW(HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: rpcserver.c:781
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:61
#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
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
#define ULONG_PTR
Definition: config.h:101
WCHAR * LPWSTR
Definition: xmlstorage.h:184
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
DWORD DesiredAccess
Definition: rpcserver.c:30
#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 4747 of file rpcserver.c.

4757 {
4758  PMANAGER_HANDLE hManager;
4759  PSERVICE lpService;
4760  DWORD dwError = ERROR_SUCCESS;
4761  PLIST_ENTRY ServiceEntry;
4762  PSERVICE CurrentService;
4763  DWORD dwState;
4764  DWORD dwRequiredSize;
4765  DWORD dwServiceCount;
4766  DWORD dwSize;
4767  DWORD dwLastResumeCount = 0;
4768  LPENUM_SERVICE_STATUSW lpStatusPtr;
4769  LPWSTR lpStringPtr;
4770 
4771  DPRINT("REnumServiceGroupW() called\n");
4772 
4773  if (ScmShutdown)
4775 
4777  if (hManager == NULL)
4778  {
4779  DPRINT1("Invalid service manager handle!\n");
4780  return ERROR_INVALID_HANDLE;
4781  }
4782 
4783  if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
4784  {
4785  return ERROR_INVALID_ADDRESS;
4786  }
4787 
4788  *pcbBytesNeeded = 0;
4789  *lpServicesReturned = 0;
4790 
4791  if ((dwServiceType == 0) ||
4792  ((dwServiceType & ~SERVICE_TYPE_ALL) != 0))
4793  {
4794  DPRINT("Not a valid Service Type!\n");
4795  return ERROR_INVALID_PARAMETER;
4796  }
4797 
4798  if ((dwServiceState == 0) ||
4799  ((dwServiceState & ~SERVICE_STATE_ALL) != 0))
4800  {
4801  DPRINT("Not a valid Service State!\n");
4802  return ERROR_INVALID_PARAMETER;
4803  }
4804 
4805  /* Check access rights */
4808  {
4809  DPRINT("Insufficient access rights! 0x%lx\n",
4810  hManager->Handle.DesiredAccess);
4811  return ERROR_ACCESS_DENIED;
4812  }
4813 
4814  if (lpResumeIndex)
4815  dwLastResumeCount = *lpResumeIndex;
4816 
4817  /* Lock the service database shared */
4819 
4820  lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
4821  if (lpService == NULL)
4822  {
4823  dwError = ERROR_SUCCESS;
4824  goto Done;
4825  }
4826 
4827  dwRequiredSize = 0;
4828  dwServiceCount = 0;
4829 
4830  for (ServiceEntry = &lpService->ServiceListEntry;
4831  ServiceEntry != &ServiceListHead;
4832  ServiceEntry = ServiceEntry->Flink)
4833  {
4834  CurrentService = CONTAINING_RECORD(ServiceEntry,
4835  SERVICE,
4836  ServiceListEntry);
4837 
4838  if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4839  continue;
4840 
4841  dwState = SERVICE_ACTIVE;
4842  if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4843  dwState = SERVICE_INACTIVE;
4844 
4845  if ((dwState & dwServiceState) == 0)
4846  continue;
4847 
4848  if (pszGroupName)
4849  {
4850  if (*pszGroupName == 0)
4851  {
4852  if (CurrentService->lpGroup != NULL)
4853  continue;
4854  }
4855  else
4856  {
4857  if ((CurrentService->lpGroup == NULL) ||
4858  _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4859  continue;
4860  }
4861  }
4862 
4863  dwSize = sizeof(ENUM_SERVICE_STATUSW) +
4864  (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4865  (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
4866 
4867  if (dwRequiredSize + dwSize > cbBufSize)
4868  {
4869  DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
4870  break;
4871  }
4872 
4873  DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
4874  dwRequiredSize += dwSize;
4875  dwServiceCount++;
4876  dwLastResumeCount = CurrentService->dwResumeCount;
4877  }
4878 
4879  DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
4880  DPRINT("dwServiceCount: %lu\n", dwServiceCount);
4881 
4882  for (;
4883  ServiceEntry != &ServiceListHead;
4884  ServiceEntry = ServiceEntry->Flink)
4885  {
4886  CurrentService = CONTAINING_RECORD(ServiceEntry,
4887  SERVICE,
4888  ServiceListEntry);
4889 
4890  if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4891  continue;
4892 
4893  dwState = SERVICE_ACTIVE;
4894  if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4895  dwState = SERVICE_INACTIVE;
4896 
4897  if ((dwState & dwServiceState) == 0)
4898  continue;
4899 
4900  if (pszGroupName)
4901  {
4902  if (*pszGroupName == 0)
4903  {
4904  if (CurrentService->lpGroup != NULL)
4905  continue;
4906  }
4907  else
4908  {
4909  if ((CurrentService->lpGroup == NULL) ||
4910  _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4911  continue;
4912  }
4913  }
4914 
4915  dwRequiredSize += (sizeof(ENUM_SERVICE_STATUSW) +
4916  (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4917  (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
4918 
4919  dwError = ERROR_MORE_DATA;
4920  }
4921 
4922  DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
4923 
4924  if (lpResumeIndex)
4925  *lpResumeIndex = dwLastResumeCount;
4926 
4927  *lpServicesReturned = dwServiceCount;
4928  *pcbBytesNeeded = dwRequiredSize;
4929 
4930  lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpBuffer;
4931  lpStringPtr = (LPWSTR)((ULONG_PTR)lpBuffer +
4932  dwServiceCount * sizeof(ENUM_SERVICE_STATUSW));
4933 
4934  dwRequiredSize = 0;
4935  for (ServiceEntry = &lpService->ServiceListEntry;
4936  ServiceEntry != &ServiceListHead;
4937  ServiceEntry = ServiceEntry->Flink)
4938  {
4939  CurrentService = CONTAINING_RECORD(ServiceEntry,
4940  SERVICE,
4941  ServiceListEntry);
4942 
4943  if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
4944  continue;
4945 
4946  dwState = SERVICE_ACTIVE;
4947  if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
4948  dwState = SERVICE_INACTIVE;
4949 
4950  if ((dwState & dwServiceState) == 0)
4951  continue;
4952 
4953  if (pszGroupName)
4954  {
4955  if (*pszGroupName == 0)
4956  {
4957  if (CurrentService->lpGroup != NULL)
4958  continue;
4959  }
4960  else
4961  {
4962  if ((CurrentService->lpGroup == NULL) ||
4963  _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName) != 0)
4964  continue;
4965  }
4966  }
4967 
4968  dwSize = sizeof(ENUM_SERVICE_STATUSW) +
4969  (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
4970  (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
4971 
4972  if (dwRequiredSize + dwSize > cbBufSize)
4973  break;
4974 
4975  /* Copy the service name */
4976  wcscpy(lpStringPtr, CurrentService->lpServiceName);
4977  lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
4978  lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
4979 
4980  /* Copy the display name */
4981  wcscpy(lpStringPtr, CurrentService->lpDisplayName);
4982  lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
4983  lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
4984 
4985  /* Copy the status information */
4986  memcpy(&lpStatusPtr->ServiceStatus,
4987  &CurrentService->Status,
4988  sizeof(SERVICE_STATUS));
4989 
4990  lpStatusPtr++;
4991  dwRequiredSize += dwSize;
4992  }
4993 
4994  if (dwError == ERROR_SUCCESS)
4995  {
4996  *pcbBytesNeeded = 0;
4997  if (lpResumeIndex) *lpResumeIndex = 0;
4998  }
4999 
5000 Done:
5001  /* Unlock the service database */
5003 
5004  DPRINT("REnumServiceGroupW() done (Error %lu)\n", dwError);
5005 
5006  return dwError;
5007 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
SERVICE_STATUS Status
Definition: services.h:69
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
static PMANAGER_HANDLE ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
Definition: rpcserver.c:200
#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:2317
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
LPWSTR lpGroupName
Definition: services.h:32
#define SERVICE_STATE_ALL
Definition: winsvc.h:52
PSERVICE_GROUP lpGroup
Definition: services.h:63
LPWSTR lpDisplayName
Definition: services.h:62
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
smooth NULL
Definition: ftsmooth.c:416
struct _ENUM_SERVICE_STATUSW * LPENUM_SERVICE_STATUSW
void DPRINT(...)
Definition: polytest.cpp:61
#define SERVICE_TYPE_ALL
Definition: cmtypes.h:967
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:119
LIST_ENTRY ServiceListEntry
Definition: services.h:60
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:96
_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:66
LPWSTR lpServiceName
Definition: services.h:61
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
SERVICE_STATUS ServiceStatus
Definition: winsvc.h:132
Definition: typedefs.h:117
SC_HANDLE hSCManager
Definition: sc.c:12
#define ERROR_MORE_DATA
Definition: dderror.h:13
PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
Definition: database.c:614
SCMGR_HANDLE Handle
Definition: rpcserver.c:36
LPWSTR lpServiceName
Definition: winsvc.h:130
LPWSTR lpDisplayName
Definition: winsvc.h:131
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
#define DPRINT1
Definition: precomp.h:8
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2324
#define ULONG_PTR
Definition: config.h:101
WCHAR * LPWSTR
Definition: xmlstorage.h:184
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
DWORD DesiredAccess
Definition: rpcserver.c:30
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
_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 3893 of file rpcserver.c.

3902 {
3903  LPENUM_SERVICE_STATUSW lpStatusPtrW = NULL;
3904  LPENUM_SERVICE_STATUSW lpStatusPtrIncrW;
3905  LPENUM_SERVICE_STATUSA lpStatusPtrA = NULL;
3906  LPWSTR lpStringPtrW;
3907  LPSTR lpStringPtrA;
3908  DWORD dwError;
3909  DWORD dwServiceCount;
3910 
3911  DPRINT("REnumServicesStatusA() called\n");
3912 
3913  if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
3914  {
3915  return ERROR_INVALID_ADDRESS;
3916  }
3917 
3918  if ((dwBufSize > 0) && (lpBuffer))
3919  {
3920  lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
3921  if (!lpStatusPtrW)
3922  {
3923  DPRINT("Failed to allocate buffer!\n");
3924  return ERROR_NOT_ENOUGH_MEMORY;
3925  }
3926  }
3927 
3928  dwError = REnumServicesStatusW(hSCManager,
3929  dwServiceType,
3930  dwServiceState,
3931  (LPBYTE)lpStatusPtrW,
3932  dwBufSize,
3934  lpServicesReturned,
3935  lpResumeHandle);
3936 
3937  /* if no services were returned then we are Done */
3938  if (*lpServicesReturned == 0)
3939  goto Done;
3940 
3941  lpStatusPtrIncrW = lpStatusPtrW;
3942  lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
3943  lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
3944  *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSA));
3945  lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
3946  *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSW));
3947 
3948  for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
3949  {
3950  /* Copy the service name */
3952  0,
3953  lpStringPtrW,
3954  -1,
3955  lpStringPtrA,
3956  (int)wcslen(lpStringPtrW),
3957  0,
3958  0);
3959 
3960  lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
3961  lpStringPtrA += wcslen(lpStringPtrW) + 1;
3962  lpStringPtrW += wcslen(lpStringPtrW) + 1;
3963 
3964  /* Copy the display name */
3966  0,
3967  lpStringPtrW,
3968  -1,
3969  lpStringPtrA,
3970  (int)wcslen(lpStringPtrW),
3971  0,
3972  0);
3973 
3974  lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
3975  lpStringPtrA += wcslen(lpStringPtrW) + 1;
3976  lpStringPtrW += wcslen(lpStringPtrW) + 1;
3977 
3978  /* Copy the status information */
3979  memcpy(&lpStatusPtrA->ServiceStatus,
3980  &lpStatusPtrIncrW->ServiceStatus,
3981  sizeof(SERVICE_STATUS));
3982 
3983  lpStatusPtrIncrW++;
3984  lpStatusPtrA++;
3985  }
3986 
3987 Done:
3988  if (lpStatusPtrW)
3989  HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
3990 
3991  DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
3992 
3993  return dwError;
3994 }
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
#define WideCharToMultiByte
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:99
#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:63
unsigned char * LPBYTE
Definition: typedefs.h:52
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define GetProcessHeap()
Definition: compat.h:395
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:96
#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:2836
struct _ENUM_SERVICE_STATUSA * LPENUM_SERVICE_STATUSA
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define ULONG_PTR
Definition: config.h:101
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _ENUM_SERVICE_STATUSA ENUM_SERVICE_STATUSA
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394

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

6101 {
6102  LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrW = NULL;
6103  LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrIncrW;
6104  LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtrA = NULL;
6105  LPWSTR lpStringPtrW;
6106  LPSTR lpStringPtrA;
6107  LPWSTR pszGroupNameW = NULL;
6108  DWORD dwError;
6109  DWORD dwServiceCount;
6110 
6111  DPRINT("REnumServicesStatusExA() called\n");
6112 
6113  if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
6114  {
6115  return ERROR_INVALID_ADDRESS;
6116  }
6117 
6118  if (pszGroupName)
6119  {
6120  pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
6121  if (!pszGroupNameW)
6122  {
6123  DPRINT("Failed to allocate buffer!\n");
6124  dwError = ERROR_NOT_ENOUGH_MEMORY;
6125  goto Done;
6126  }
6127 
6129  0,
6130  pszGroupName,
6131  -1,
6132  pszGroupNameW,
6133  (int)(strlen(pszGroupName) + 1));
6134  }
6135 
6136  if ((cbBufSize > 0) && (lpBuffer))
6137  {
6138  lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbBufSize);
6139  if (!lpStatusPtrW)
6140  {
6141  DPRINT("Failed to allocate buffer!\n");
6142  dwError = ERROR_NOT_ENOUGH_MEMORY;
6143  goto Done;
6144  }
6145  }
6146 
6148  InfoLevel,
6149  dwServiceType,
6150  dwServiceState,
6151  (LPBYTE)lpStatusPtrW,
6152  cbBufSize,
6154  lpServicesReturned,
6155  lpResumeIndex,
6156  pszGroupNameW);
6157 
6158  /* if no services were returned then we are Done */
6159  if (*lpServicesReturned == 0)
6160  goto Done;
6161 
6162  lpStatusPtrIncrW = lpStatusPtrW;
6163  lpStatusPtrA = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer;
6164  lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
6165  *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
6166  lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
6167  *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
6168 
6169  for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
6170  {
6171  /* Copy the service name */
6173  0,
6174  lpStringPtrW,
6175  -1,
6176  lpStringPtrA,
6177  (int)wcslen(lpStringPtrW),
6178  0,
6179  0);
6180 
6181  lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
6182  lpStringPtrA += wcslen(lpStringPtrW) + 1;
6183  lpStringPtrW += wcslen(lpStringPtrW) + 1;
6184 
6185  /* Copy the display name */
6187  0,
6188  lpStringPtrW,
6189  -1,
6190  lpStringPtrA,
6191  (int)wcslen(lpStringPtrW),
6192  0,
6193  0);
6194 
6195  lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
6196  lpStringPtrA += wcslen(lpStringPtrW) + 1;
6197  lpStringPtrW += wcslen(lpStringPtrW) + 1;
6198 
6199  /* Copy the status information */
6200  memcpy(&lpStatusPtrA->ServiceStatusProcess,
6201  &lpStatusPtrIncrW->ServiceStatusProcess,
6202  sizeof(SERVICE_STATUS));
6203 
6204  /* Copy the service process ID */
6205  lpStatusPtrA->ServiceStatusProcess.dwProcessId = lpStatusPtrIncrW->ServiceStatusProcess.dwProcessId;
6206 
6207  lpStatusPtrA->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
6208 
6209  lpStatusPtrIncrW++;
6210  lpStatusPtrA++;
6211  }
6212 
6213 Done:
6214  if (pszGroupNameW)
6215  HeapFree(GetProcessHeap(), 0, pszGroupNameW);
6216 
6217  if (lpStatusPtrW)
6218  HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
6219 
6220  DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError);
6221 
6222  return dwError;
6223 }
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
#define WideCharToMultiByte
Definition: compat.h:101
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:6229
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_ACP
Definition: compat.h:99
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
char * LPSTR
Definition: xmlstorage.h:182
uint32_t ULONG_PTR
Definition: typedefs.h:63
unsigned char * LPBYTE
Definition: typedefs.h:52
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
struct _ENUM_SERVICE_STATUS_PROCESSA ENUM_SERVICE_STATUS_PROCESSA
#define GetProcessHeap()
Definition: compat.h:395
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:96
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
SC_HANDLE hSCManager
Definition: sc.c:12
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define MultiByteToWideChar
Definition: compat.h:100
struct _ENUM_SERVICE_STATUS_PROCESSW ENUM_SERVICE_STATUS_PROCESSW
#define ULONG_PTR
Definition: config.h:101
WCHAR * LPWSTR
Definition: xmlstorage.h:184
SERVICE_STATUS_PROCESS ServiceStatusProcess
Definition: winsvc.h:137
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394

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

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