ReactOS  0.4.14-dev-98-gb0d4763
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:70
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:424
PSERVICE ScmGetServiceEntryByName(LPCWSTR lpServiceName)
Definition: database.c:657
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD dwCurrentState
Definition: winsvc.h:100
#define SERVICE_INACTIVE
Definition: winsvc.h:51
#define KEY_READ
Definition: nt_native.h:1023
#define SERVICE_STATE_ALL
Definition: winsvc.h:52
LPWSTR lpDisplayName
Definition: services.h:63
#define DWORD
Definition: nt_native.h:44
#define SERVICE_STOPPED
Definition: winsvc.h:21
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h: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:4116
__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:3686
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:62
#define ERROR_NOT_FOUND
Definition: winerror.h:690
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
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 6740 of file rpcserver.c.

6741 {
6743 }
#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 6746 of file rpcserver.c.

6747 {
6748  HeapFree(GetProcessHeap(), 0, ptr);
6749 }
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 5015 of file rpcserver.c.

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

5419 {
5420  DWORD dwError = ERROR_SUCCESS;
5421  PSERVICE_HANDLE hSvc;
5422  PSERVICE lpService = NULL;
5423  HKEY hServiceKey = NULL;
5425 
5426  DPRINT("RChangeServiceConfig2W() called\n");
5427  DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
5428 
5429  if (ScmShutdown)
5431 
5432  if ((Info.dwInfoLevel < SERVICE_CONFIG_DESCRIPTION) ||
5433  (Info.dwInfoLevel > SERVICE_CONFIG_FAILURE_ACTIONS))
5434  {
5435  return ERROR_INVALID_LEVEL;
5436  }
5437 
5438  hSvc = ScmGetServiceFromHandle(hService);
5439  if (hSvc == NULL)
5440  {
5441  DPRINT("Invalid service handle!\n");
5442  return ERROR_INVALID_HANDLE;
5443  }
5444 
5445  if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5447 
5448  /* Check the access rights */
5450  RequiredAccess))
5451  {
5452  DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
5453  return ERROR_ACCESS_DENIED;
5454  }
5455 
5456  if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5457  {
5458  /* FIXME: Check if the caller has the SE_SHUTDOWN_NAME privilege */
5459 
5460  }
5461 
5462  lpService = hSvc->ServiceEntry;
5463  if (lpService == NULL)
5464  {
5465  DPRINT("lpService == NULL!\n");
5466  return ERROR_INVALID_HANDLE;
5467  }
5468 
5469  /* Failure actions can only be set for Win32 services, not for drivers */
5470  if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5471  {
5472  if (lpService->Status.dwServiceType & SERVICE_DRIVER)
5474  }
5475 
5476  /* Lock the service database exclusively */
5478 
5479  if (lpService->bDeleted)
5480  {
5481  DPRINT("The service has already been marked for delete!\n");
5483  goto done;
5484  }
5485 
5486  /* Open the service key */
5487  dwError = ScmOpenServiceKey(lpService->szServiceName,
5489  &hServiceKey);
5490  if (dwError != ERROR_SUCCESS)
5491  goto done;
5492 
5493  if (Info.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
5494  {
5495  LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd;
5496 
5497  /* Modify the service description, if specified */
5498  if (lpServiceDescription != NULL &&
5499  lpServiceDescription->lpDescription != NULL)
5500  {
5501  /* If the description is "" then we delete it */
5502  if (*lpServiceDescription->lpDescription == 0)
5503  {
5504  DPRINT("Delete service description\n");
5505  dwError = RegDeleteValueW(hServiceKey, L"Description");
5506 
5507  if (dwError == ERROR_FILE_NOT_FOUND)
5508  dwError = ERROR_SUCCESS;
5509  }
5510  else
5511  {
5512  DPRINT("Setting service description value %S\n", lpServiceDescription->lpDescription);
5513  dwError = RegSetValueExW(hServiceKey,
5514  L"Description",
5515  0,
5516  REG_SZ,
5517  (LPBYTE)lpServiceDescription->lpDescription,
5518  (DWORD)((wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR)));
5519  }
5520  }
5521  else
5522  {
5523  dwError = ERROR_SUCCESS;
5524  }
5525  }
5526  else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
5527  {
5528  dwError = ScmSetFailureActions(hServiceKey,
5530  }
5531 
5532 done:
5533  if (hServiceKey != NULL)
5534  RegCloseKey(hServiceKey);
5535 
5536  /* Unlock the service database */
5538 
5539  DPRINT("RChangeServiceConfig2W() done (Error %lu)\n", dwError);
5540 
5541  return dwError;
5542 }
SERVICE_STATUS Status
Definition: services.h:70
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:2420
#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:4895
static DWORD ScmSetFailureActions(HKEY hServiceKey, LPSERVICE_FAILURE_ACTIONSW lpFailureActions)
Definition: rpcserver.c:5192
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:2355
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:2434
BOOL bDeleted
Definition: services.h:66
#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:83
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 3457 of file rpcserver.c.

3471 {
3472  DWORD dwError = ERROR_SUCCESS;
3473  LPWSTR lpBinaryPathNameW = NULL;
3474  LPWSTR lpLoadOrderGroupW = NULL;
3475  LPWSTR lpDependenciesW = NULL;
3476  LPWSTR lpServiceStartNameW = NULL;
3477  LPWSTR lpDisplayNameW = NULL;
3478  DWORD dwDependenciesLength = 0;
3479  SIZE_T cchLength;
3480  int len;
3481  LPCSTR lpStr;
3482 
3483  if (lpBinaryPathName)
3484  {
3485  len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
3486  lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3487  if (!lpBinaryPathNameW)
3488  {
3490  goto cleanup;
3491  }
3492  MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
3493  }
3494 
3495  if (lpLoadOrderGroup)
3496  {
3497  len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
3498  lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3499  if (!lpLoadOrderGroupW)
3500  {
3502  goto cleanup;
3503  }
3504  MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
3505  }
3506 
3507  if (lpDependencies)
3508  {
3509  lpStr = (LPCSTR)lpDependencies;
3510  while (*lpStr)
3511  {
3512  cchLength = strlen(lpStr) + 1;
3513  dwDependenciesLength += (DWORD)cchLength;
3514  lpStr = lpStr + cchLength;
3515  }
3516  dwDependenciesLength++;
3517 
3518  lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
3519  if (!lpDependenciesW)
3520  {
3522  goto cleanup;
3523  }
3524  MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
3525  }
3526 
3527  if (lpServiceStartName)
3528  {
3529  len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
3530  lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3531  if (!lpServiceStartNameW)
3532  {
3534  goto cleanup;
3535  }
3536  MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
3537  }
3538 
3539  if (lpDisplayName)
3540  {
3542  lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
3543  if (!lpDisplayNameW)
3544  {
3546  goto cleanup;
3547  }
3548  MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
3549  }
3550 
3551  dwError = RChangeServiceConfigW(hService,
3552  dwServiceType,
3553  dwStartType,
3554  dwErrorControl,
3555  lpBinaryPathNameW,
3556  lpLoadOrderGroupW,
3557  lpdwTagId,
3558  (LPBYTE)lpDependenciesW,
3559  dwDependenciesLength,
3560  lpServiceStartNameW,
3561  lpPassword,
3562  dwPwSize,
3563  lpDisplayNameW);
3564 
3565 cleanup:
3566  if (lpBinaryPathNameW != NULL)
3567  HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
3568 
3569  if (lpLoadOrderGroupW != NULL)
3570  HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
3571 
3572  if (lpDependenciesW != NULL)
3573  HeapFree(GetProcessHeap(), 0, lpDependenciesW);
3574 
3575  if (lpServiceStartNameW != NULL)
3576  HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
3577 
3578  if (lpDisplayNameW != NULL)
3579  HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
3580 
3581  return dwError;
3582 }
#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:2737
#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:1918

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

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

6664 {
6665  UNIMPLEMENTED;
6667 }
#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:70
_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:2420
#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:68
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:62
SCMGR_HANDLE Handle
Definition: rpcserver.c:36
VOID ScmDeleteServiceRecord(PSERVICE lpService)
Definition: database.c:816
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2434
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
BOOL bDeleted
Definition: services.h:66
#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:70
_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:63
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define ERROR_SERVICE_NOT_ACTIVE
Definition: winerror.h:613
#define SERVICE_STOPPED
Definition: winsvc.h:21
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define ERROR_ACCESS_DENIED
Definition: compat.h: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:85
#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:62
#define ERROR_DEPENDENT_SERVICES_RUNNING
Definition: winerror.h:602
DWORD dwControlsAccepted
Definition: winsvc.h:101
#define GetModuleHandle
Definition: winbase.h:3651
#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:3366
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_DRIVER
Definition: cmtypes.h:956
PSERVICE_IMAGE lpImage
Definition: services.h:65
DWORD ScmControlService(HANDLE hControlPipe, PWSTR pServiceName, SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwControl)
Definition: database.c:1314
#define SERVICE_CONTROL_NETBINDDISABLE
Definition: winsvc.h:45
#define SERVICE_CONTROL_NETBINDREMOVE
Definition: winsvc.h:43
HANDLE hControlPipe
Definition: services.h:51
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_PAUSE_CONTINUE
Definition: winsvc.h:59
ULONG ACCESS_MASK
Definition: nt_native.h:40
DWORD DesiredAccess
Definition: rpcserver.c: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 6673 of file rpcserver.c.

6677 {
6678  UNIMPLEMENTED;
6680 }
#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 6686 of file rpcserver.c.

6690 {
6691  UNIMPLEMENTED;
6693 }
#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 3588 of file rpcserver.c.

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

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

6554 {
6555  UNIMPLEMENTED;
6557 }
#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 6563 of file rpcserver.c.

6580 {
6581  UNIMPLEMENTED;
6583 }
#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:2420
#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:2434
BOOL bDeleted
Definition: services.h:66
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 3741 of file rpcserver.c.

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

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

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

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

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

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