ReactOS 0.4.16-dev-1308-gbf734eb
database.c File Reference
#include "services.h"
#include <winbase_undoc.h>
#include <userenv.h>
#include <strsafe.h>
#include <debug.h>
Include dependency graph for database.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static BOOL ScmIsSecurityService (_In_ PSERVICE_IMAGE pServiceImage)
 
static DWORD ScmCreateNewControlPipe (_In_ PSERVICE_IMAGE pServiceImage, _In_ BOOL bSecurityServiceProcess)
 
static PSERVICE_IMAGE ScmGetServiceImageByImagePath (LPWSTR lpImagePath)
 
DWORD ScmGetServiceNameFromTag (IN PTAG_INFO_NAME_FROM_TAG_IN_PARAMS InParams, OUT PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS *OutParams)
 
static BOOL ScmIsSameServiceAccount (_In_ PCWSTR pszAccountName1, _In_ PCWSTR pszAccountName2)
 
static BOOL ScmIsLocalSystemAccount (_In_ PCWSTR pszAccountName)
 
static BOOL ScmEnableBackupRestorePrivileges (_In_ HANDLE hToken, _In_ BOOL bEnable)
 
static DWORD ScmLogonService (IN PSERVICE pService, IN PSERVICE_IMAGE pImage)
 
static DWORD ScmCreateOrReferenceServiceImage (PSERVICE pService)
 
VOID ScmRemoveServiceImage (PSERVICE_IMAGE pServiceImage)
 
PSERVICE ScmGetServiceEntryByName (LPCWSTR lpServiceName)
 
PSERVICE ScmGetServiceEntryByDisplayName (LPCWSTR lpDisplayName)
 
PSERVICE ScmGetServiceEntryByResumeCount (DWORD dwResumeCount)
 
DWORD ScmGenerateServiceTag (PSERVICE lpServiceRecord)
 
DWORD ScmCreateNewServiceRecord (LPCWSTR lpServiceName, PSERVICE *lpServiceRecord, DWORD dwServiceType, DWORD dwStartType)
 
VOID ScmDeleteServiceRecord (PSERVICE lpService)
 
DWORD Int_EnumDependentServicesW (HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
 
DWORD ScmDeleteService (PSERVICE lpService)
 
DWORD ScmReferenceService (PSERVICE lpService)
 
DWORD ScmDereferenceService (PSERVICE lpService)
 
static DWORD CreateServiceListEntry (LPCWSTR lpServiceName, HKEY hServiceKey)
 
VOID ScmDeleteMarkedServices (VOID)
 
static VOID ScmGetNoInteractiveServicesValue (VOID)
 
DWORD ScmCreateServiceDatabase (VOID)
 
VOID ScmShutdownServiceDatabase (VOID)
 
static NTSTATUS ScmCheckDriver (PSERVICE Service)
 
VOID ScmGetBootAndSystemDriverState (VOID)
 
DWORD ScmSendControlPacket (_In_ HANDLE hControlPipe, _In_ PCWSTR pServiceName, _In_ DWORD dwControl, _In_ DWORD dwControlPacketSize, _In_ PVOID pControlPacket)
 
DWORD ScmControlServiceEx (_In_ HANDLE hControlPipe, _In_ PCWSTR pServiceName, _In_ DWORD dwControl, _In_ SERVICE_STATUS_HANDLE hServiceStatus, _In_opt_ DWORD dwServiceTag, _In_opt_ DWORD argc, _In_reads_opt_(argc) const PCWSTR *argv)
 
DWORD ScmControlService (_In_ HANDLE hControlPipe, _In_ PCWSTR pServiceName, _In_ DWORD dwControl, _In_ SERVICE_STATUS_HANDLE hServiceStatus)
 
static DWORD ScmWaitForServiceConnect (PSERVICE Service)
 
static DWORD ScmStartUserModeService (PSERVICE Service, DWORD argc, const PCWSTR *argv)
 
static DWORD ScmLoadService (PSERVICE Service, DWORD argc, const PCWSTR *argv)
 
DWORD ScmStartService (PSERVICE Service, DWORD argc, const PCWSTR *argv)
 
VOID ScmAutoStartServices (VOID)
 
VOID ScmAutoShutdownServices (VOID)
 
BOOL ScmLockDatabaseExclusive (VOID)
 
BOOL ScmLockDatabaseShared (VOID)
 
VOID ScmUnlockDatabase (VOID)
 
VOID ScmInitNamedPipeCriticalSection (VOID)
 
VOID ScmDeleteNamedPipeCriticalSection (VOID)
 

Variables

LIST_ENTRY ImageListHead
 
LIST_ENTRY ServiceListHead
 
static RTL_RESOURCE DatabaseLock
 
static DWORD ResumeCount = 1
 
static DWORD NoInteractiveServices = 0
 
static DWORD ServiceTag = 0
 
static CRITICAL_SECTION ControlServiceCriticalSection
 
static DWORD PipeTimeout = 30000
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 21 of file database.c.

Function Documentation

◆ CreateServiceListEntry()

static DWORD CreateServiceListEntry ( LPCWSTR  lpServiceName,
HKEY  hServiceKey 
)
static

Definition at line 955 of file database.c.

957{
958 PSERVICE lpService = NULL;
960 LPWSTR lpGroup = NULL;
962 DWORD dwError;
963 DWORD dwServiceType;
964 DWORD dwStartType;
965 DWORD dwErrorControl;
966 DWORD dwTagId;
967
968 DPRINT("Service: '%S'\n", lpServiceName);
969 if (*lpServiceName == L'{')
970 return ERROR_SUCCESS;
971
972 dwSize = sizeof(DWORD);
973 dwError = RegQueryValueExW(hServiceKey,
974 L"Type",
975 NULL,
976 NULL,
977 (LPBYTE)&dwServiceType,
978 &dwSize);
979 if (dwError != ERROR_SUCCESS)
980 return ERROR_SUCCESS;
981
982 if (((dwServiceType & ~SERVICE_INTERACTIVE_PROCESS) != SERVICE_WIN32_OWN_PROCESS) &&
984 (dwServiceType != SERVICE_KERNEL_DRIVER) &&
985 (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER))
986 return ERROR_SUCCESS;
987
988 DPRINT("Service type: %lx\n", dwServiceType);
989
990 dwSize = sizeof(DWORD);
991 dwError = RegQueryValueExW(hServiceKey,
992 L"Start",
993 NULL,
994 NULL,
995 (LPBYTE)&dwStartType,
996 &dwSize);
997 if (dwError != ERROR_SUCCESS)
998 return ERROR_SUCCESS;
999
1000 DPRINT("Start type: %lx\n", dwStartType);
1001
1002 dwSize = sizeof(DWORD);
1003 dwError = RegQueryValueExW(hServiceKey,
1004 L"ErrorControl",
1005 NULL,
1006 NULL,
1007 (LPBYTE)&dwErrorControl,
1008 &dwSize);
1009 if (dwError != ERROR_SUCCESS)
1010 return ERROR_SUCCESS;
1011
1012 DPRINT("Error control: %lx\n", dwErrorControl);
1013
1014 dwError = RegQueryValueExW(hServiceKey,
1015 L"Tag",
1016 NULL,
1017 NULL,
1018 (LPBYTE)&dwTagId,
1019 &dwSize);
1020 if (dwError != ERROR_SUCCESS)
1021 dwTagId = 0;
1022
1023 DPRINT("Tag: %lx\n", dwTagId);
1024
1025 dwError = ScmReadString(hServiceKey,
1026 L"Group",
1027 &lpGroup);
1028 if (dwError != ERROR_SUCCESS)
1029 lpGroup = NULL;
1030
1031 DPRINT("Group: %S\n", lpGroup);
1032
1033 dwError = ScmReadString(hServiceKey,
1034 L"DisplayName",
1035 &lpDisplayName);
1036 if (dwError != ERROR_SUCCESS)
1038
1039 DPRINT("Display name: %S\n", lpDisplayName);
1040
1041 dwError = ScmCreateNewServiceRecord(lpServiceName,
1042 &lpService,
1043 dwServiceType,
1044 dwStartType);
1045 if (dwError != ERROR_SUCCESS)
1046 goto done;
1047
1048 lpService->dwErrorControl = dwErrorControl;
1049 lpService->dwTag = dwTagId;
1050
1051 if (lpGroup != NULL)
1052 {
1053 dwError = ScmSetServiceGroup(lpService, lpGroup);
1054 if (dwError != ERROR_SUCCESS)
1055 goto done;
1056 }
1057
1058 if (lpDisplayName != NULL)
1059 {
1060 lpService->lpDisplayName = lpDisplayName;
1062 }
1063
1064 DPRINT("ServiceName: '%S'\n", lpService->lpServiceName);
1065 if (lpService->lpGroup != NULL)
1066 {
1067 DPRINT("Group: '%S'\n", lpService->lpGroup->lpGroupName);
1068 }
1069 DPRINT("Start %lx Type %lx Tag %lx ErrorControl %lx\n",
1070 lpService->dwStartType,
1071 lpService->Status.dwServiceType,
1072 lpService->dwTag,
1073 lpService->dwErrorControl);
1074
1075 if (ScmIsDeleteFlagSet(hServiceKey))
1076 lpService->bDeleted = TRUE;
1077 else
1078 ScmGenerateServiceTag(lpService);
1079
1080 if (lpService->Status.dwServiceType & SERVICE_WIN32)
1081 {
1082 dwError = ScmReadSecurityDescriptor(hServiceKey,
1083 &lpService->pSecurityDescriptor);
1084 if (dwError != ERROR_SUCCESS)
1085 goto done;
1086
1087 /* Assing the default security descriptor if the security descriptor cannot be read */
1088 if (lpService->pSecurityDescriptor == NULL)
1089 {
1090 DPRINT("No security descriptor found! Assign default security descriptor\n");
1091 dwError = ScmCreateDefaultServiceSD(&lpService->pSecurityDescriptor);
1092 if (dwError != ERROR_SUCCESS)
1093 goto done;
1094
1095 dwError = ScmWriteSecurityDescriptor(hServiceKey,
1096 lpService->pSecurityDescriptor);
1097 if (dwError != ERROR_SUCCESS)
1098 goto done;
1099 }
1100 }
1101
1102done:
1103 if (lpGroup != NULL)
1104 HeapFree(GetProcessHeap(), 0, lpGroup);
1105
1106 if (lpDisplayName != NULL)
1108
1109 if (lpService != NULL)
1110 {
1111 ASSERT(lpService->lpImage == NULL);
1112 }
1113
1114 return dwError;
1115}
DWORD ScmReadString(HKEY hServiceKey, LPCWSTR lpValueName, LPWSTR *lpValue)
Definition: config.c:270
BOOL ScmIsDeleteFlagSet(HKEY hServiceKey)
Definition: config.c:251
DWORD ScmWriteSecurityDescriptor(_In_ HKEY hServiceKey, _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor)
Definition: config.c:530
DWORD ScmReadSecurityDescriptor(_In_ HKEY hServiceKey, _Out_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
Definition: config.c:566
DWORD ScmGenerateServiceTag(PSERVICE lpServiceRecord)
Definition: database.c:743
DWORD ScmCreateNewServiceRecord(LPCWSTR lpServiceName, PSERVICE *lpServiceRecord, DWORD dwServiceType, DWORD dwStartType)
Definition: database.c:766
DWORD ScmCreateDefaultServiceSD(PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
Definition: security.c:320
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define GetProcessHeap()
Definition: compat.h:736
#define HeapFree(x, y, z)
Definition: compat.h:735
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD ScmSetServiceGroup(PSERVICE lpService, LPCWSTR lpGroupName)
Definition: groupdb.c:61
#define ASSERT(a)
Definition: mode.c:44
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
#define DPRINT
Definition: sndvol32.h:73
LPWSTR lpGroupName
Definition: services.h:35
DWORD dwServiceType
Definition: winsvc.h:99
BOOL bDeleted
Definition: services.h:68
PSERVICE_GROUP lpGroup
Definition: services.h:66
PSECURITY_DESCRIPTOR pSecurityDescriptor
Definition: services.h:82
DWORD dwErrorControl
Definition: services.h:74
LPWSTR lpDisplayName
Definition: services.h:65
SERVICE_STATUS Status
Definition: services.h:72
DWORD dwStartType
Definition: services.h:73
DWORD dwTag
Definition: services.h:75
PSERVICE_IMAGE lpImage
Definition: services.h:67
LPWSTR lpServiceName
Definition: services.h:64
unsigned char * LPBYTE
Definition: typedefs.h:53
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2831
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:953
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:963
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:967
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:954
#define SERVICE_WIN32
Definition: cmtypes.h:964
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by ScmCreateServiceDatabase().

◆ Int_EnumDependentServicesW()

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

Definition at line 782 of file rpcserver.c.

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

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

◆ ScmAutoShutdownServices()

VOID ScmAutoShutdownServices ( VOID  )

Definition at line 2332 of file database.c.

2333{
2334 PLIST_ENTRY ServiceEntry;
2335 PSERVICE CurrentService;
2336
2337 DPRINT("ScmAutoShutdownServices() called\n");
2338
2339 /* Lock the service database exclusively */
2341
2342 ServiceEntry = ServiceListHead.Flink;
2343 while (ServiceEntry != &ServiceListHead)
2344 {
2345 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2346
2347 if ((CurrentService->Status.dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN) &&
2348 (CurrentService->Status.dwCurrentState == SERVICE_RUNNING ||
2349 CurrentService->Status.dwCurrentState == SERVICE_START_PENDING))
2350 {
2351 /* Send the shutdown notification */
2352 DPRINT("Shutdown service: %S\n", CurrentService->lpServiceName);
2353 ScmControlService(CurrentService->lpImage->hControlPipe,
2354 CurrentService->lpServiceName,
2356 (SERVICE_STATUS_HANDLE)CurrentService);
2357 }
2358
2359 ServiceEntry = ServiceEntry->Flink;
2360 }
2361
2362 /* Unlock the service database */
2364
2365 DPRINT("ScmAutoShutdownServices() done\n");
2366}
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
DWORD ScmControlService(_In_ HANDLE hControlPipe, _In_ PCWSTR pServiceName, _In_ DWORD dwControl, _In_ SERVICE_STATUS_HANDLE hServiceStatus)
Definition: database.c:1592
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2384
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2370
LIST_ENTRY ServiceListHead
Definition: database.c:28
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
HANDLE hControlPipe
Definition: services.h:53
DWORD dwControlsAccepted
Definition: winsvc.h:101
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30

Referenced by ShutdownHandlerRoutine().

◆ ScmAutoStartServices()

VOID ScmAutoStartServices ( VOID  )

Definition at line 2121 of file database.c.

2122{
2123 DWORD dwError;
2124 PLIST_ENTRY GroupEntry;
2125 PLIST_ENTRY ServiceEntry;
2126 PSERVICE_GROUP CurrentGroup;
2127 PSERVICE CurrentService;
2128 WCHAR szSafeBootServicePath[MAX_PATH];
2129 DWORD SafeBootEnabled;
2130 HKEY hKey;
2131 DWORD dwKeySize;
2132 ULONG i;
2133
2134 /*
2135 * This function MUST be called ONLY at initialization time.
2136 * Therefore, no need to acquire the user service start lock.
2137 */
2139
2140 /* Retrieve the SafeBoot parameter */
2142 L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option",
2143 0,
2144 KEY_READ,
2145 &hKey);
2146 if (dwError == ERROR_SUCCESS)
2147 {
2148 dwKeySize = sizeof(SafeBootEnabled);
2149 dwError = RegQueryValueExW(hKey,
2150 L"OptionValue",
2151 0,
2152 NULL,
2153 (LPBYTE)&SafeBootEnabled,
2154 &dwKeySize);
2156 }
2157
2158 /* Default to Normal boot if the value doesn't exist */
2159 if (dwError != ERROR_SUCCESS)
2160 SafeBootEnabled = 0;
2161
2162 /* Acquire the service control critical section, to synchronize starts */
2164
2165 /* Clear 'ServiceVisited' flag (or set if not to start in Safe Mode) */
2166 ServiceEntry = ServiceListHead.Flink;
2167 while (ServiceEntry != &ServiceListHead)
2168 {
2169 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2170
2171 /* Build the safe boot path */
2172 StringCchCopyW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2173 L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot");
2174
2175 switch (SafeBootEnabled)
2176 {
2177 /* NOTE: Assumes MINIMAL (1) and DSREPAIR (3) load same items */
2178 case 1:
2179 case 3:
2180 StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2181 L"\\Minimal\\");
2182 break;
2183
2184 case 2:
2185 StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2186 L"\\Network\\");
2187 break;
2188 }
2189
2190 if (SafeBootEnabled != 0)
2191 {
2192 /* If key does not exist then do not assume safe mode */
2194 szSafeBootServicePath,
2195 0,
2196 KEY_READ,
2197 &hKey);
2198 if (dwError == ERROR_SUCCESS)
2199 {
2201
2202 /* Finish Safe Boot path off */
2203 StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2204 CurrentService->lpServiceName);
2205
2206 /* Check that the key is in the Safe Boot path */
2208 szSafeBootServicePath,
2209 0,
2210 KEY_READ,
2211 &hKey);
2212 if (dwError != ERROR_SUCCESS)
2213 {
2214 /* Mark service as visited so it is not auto-started */
2215 CurrentService->ServiceVisited = TRUE;
2216 }
2217 else
2218 {
2219 /* Must be auto-started in safe mode - mark as unvisited */
2221 CurrentService->ServiceVisited = FALSE;
2222 }
2223 }
2224 else
2225 {
2226 DPRINT1("WARNING: Could not open the associated Safe Boot key\n");
2227 CurrentService->ServiceVisited = FALSE;
2228 }
2229 }
2230
2231 ServiceEntry = ServiceEntry->Flink;
2232 }
2233
2234 /* Start all services which are members of an existing group */
2235 GroupEntry = GroupListHead.Flink;
2236 while (GroupEntry != &GroupListHead)
2237 {
2238 CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
2239
2240 DPRINT("Group '%S'\n", CurrentGroup->lpGroupName);
2241
2242 /* Start all services witch have a valid tag */
2243 for (i = 0; i < CurrentGroup->TagCount; i++)
2244 {
2245 ServiceEntry = ServiceListHead.Flink;
2246 while (ServiceEntry != &ServiceListHead)
2247 {
2248 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2249
2250 if ((CurrentService->lpGroup == CurrentGroup) &&
2251 (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2252 (CurrentService->ServiceVisited == FALSE) &&
2253 (CurrentService->dwTag == CurrentGroup->TagArray[i]))
2254 {
2255 CurrentService->ServiceVisited = TRUE;
2256 ScmLoadService(CurrentService, 0, NULL);
2257 }
2258
2259 ServiceEntry = ServiceEntry->Flink;
2260 }
2261 }
2262
2263 /* Start all services which have an invalid tag or which do not have a tag */
2264 ServiceEntry = ServiceListHead.Flink;
2265 while (ServiceEntry != &ServiceListHead)
2266 {
2267 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2268
2269 if ((CurrentService->lpGroup == CurrentGroup) &&
2270 (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2271 (CurrentService->ServiceVisited == FALSE))
2272 {
2273 CurrentService->ServiceVisited = TRUE;
2274 ScmLoadService(CurrentService, 0, NULL);
2275 }
2276
2277 ServiceEntry = ServiceEntry->Flink;
2278 }
2279
2280 GroupEntry = GroupEntry->Flink;
2281 }
2282
2283 /* Start all services which are members of any non-existing group */
2284 ServiceEntry = ServiceListHead.Flink;
2285 while (ServiceEntry != &ServiceListHead)
2286 {
2287 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2288
2289 if ((CurrentService->lpGroup != NULL) &&
2290 (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2291 (CurrentService->ServiceVisited == FALSE))
2292 {
2293 CurrentService->ServiceVisited = TRUE;
2294 ScmLoadService(CurrentService, 0, NULL);
2295 }
2296
2297 ServiceEntry = ServiceEntry->Flink;
2298 }
2299
2300 /* Start all services which are not a member of any group */
2301 ServiceEntry = ServiceListHead.Flink;
2302 while (ServiceEntry != &ServiceListHead)
2303 {
2304 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2305
2306 if ((CurrentService->lpGroup == NULL) &&
2307 (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2308 (CurrentService->ServiceVisited == FALSE))
2309 {
2310 CurrentService->ServiceVisited = TRUE;
2311 ScmLoadService(CurrentService, 0, NULL);
2312 }
2313
2314 ServiceEntry = ServiceEntry->Flink;
2315 }
2316
2317 /* Clear 'ServiceVisited' flag again */
2318 ServiceEntry = ServiceListHead.Flink;
2319 while (ServiceEntry != &ServiceListHead)
2320 {
2321 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2322 CurrentService->ServiceVisited = FALSE;
2323 ServiceEntry = ServiceEntry->Flink;
2324 }
2325
2326 /* Release the critical section */
2328}
#define DPRINT1
Definition: precomp.h:8
static DWORD ScmLoadService(PSERVICE Service, DWORD argc, const PCWSTR *argv)
Definition: database.c:1967
static CRITICAL_SECTION ControlServiceCriticalSection
Definition: database.c:36
BOOL ScmInitialize
Definition: services.c:28
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
FxAutoRegKey hKey
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LIST_ENTRY GroupListHead
Definition: groupdb.c:19
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
PULONG TagArray
Definition: services.h:40
ULONG TagCount
Definition: services.h:39
BOOLEAN ServiceVisited
Definition: services.h:84
uint32_t ULONG
Definition: typedefs.h:59
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define SERVICE_AUTO_START
Definition: cmtypes.h:977

Referenced by wWinMain().

◆ ScmCheckDriver()

static NTSTATUS ScmCheckDriver ( PSERVICE  Service)
static

Definition at line 1285 of file database.c.

1286{
1289 HANDLE DirHandle;
1294 ULONG Index;
1295
1296 DPRINT("ScmCheckDriver(%S) called\n", Service->lpServiceName);
1297
1298 if (Service->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
1299 {
1300 RtlInitUnicodeString(&DirName, L"\\Driver");
1301 }
1302 else // if (Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
1303 {
1304 ASSERT(Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER);
1305 RtlInitUnicodeString(&DirName, L"\\FileSystem");
1306 }
1307
1309 &DirName,
1310 0,
1311 NULL,
1312 NULL);
1313
1314 Status = NtOpenDirectoryObject(&DirHandle,
1317 if (!NT_SUCCESS(Status))
1318 {
1319 return Status;
1320 }
1321
1323 2 * MAX_PATH * sizeof(WCHAR);
1324 DirInfo = HeapAlloc(GetProcessHeap(),
1326 BufferLength);
1327
1328 Index = 0;
1329 while (TRUE)
1330 {
1331 Status = NtQueryDirectoryObject(DirHandle,
1332 DirInfo,
1334 TRUE,
1335 FALSE,
1336 &Index,
1337 &DataLength);
1339 {
1340 /* FIXME: Add current service to 'failed service' list */
1341 DPRINT("Service '%S' failed\n", Service->lpServiceName);
1342 break;
1343 }
1344
1345 if (!NT_SUCCESS(Status))
1346 break;
1347
1348 DPRINT("Comparing: '%S' '%wZ'\n", Service->lpServiceName, &DirInfo->Name);
1349
1350 if (_wcsicmp(Service->lpServiceName, DirInfo->Name.Buffer) == 0)
1351 {
1352 DPRINT("Found: '%S' '%wZ'\n",
1353 Service->lpServiceName, &DirInfo->Name);
1354
1355 /* Mark service as 'running' */
1356 Service->Status.dwCurrentState = SERVICE_RUNNING;
1357 Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
1358 Service->Status.dwWin32ExitCode = ERROR_SUCCESS;
1359 Service->Status.dwServiceSpecificExitCode = 0;
1360 Service->Status.dwCheckPoint = 0;
1361 Service->Status.dwWaitHint = 0;
1362
1363 /* Mark the service group as 'running' */
1364 if (Service->lpGroup != NULL)
1365 {
1366 Service->lpGroup->ServicesRunning = TRUE;
1367 }
1368
1369 break;
1370 }
1371 }
1372
1374 0,
1375 DirInfo);
1376 NtClose(DirHandle);
1377
1378 return STATUS_SUCCESS;
1379}
LONG NTSTATUS
Definition: precomp.h:26
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:737
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define HeapAlloc
Definition: compat.h:733
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
Status
Definition: gdiplustypes.h:25
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
@ Service
Definition: ntsecapi.h:292
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:393
NTSTATUS NTAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PVOID Buffer, IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan, IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
Definition: obdir.c:490
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28

Referenced by ScmGetBootAndSystemDriverState().

◆ ScmControlService()

DWORD ScmControlService ( _In_ HANDLE  hControlPipe,
_In_ PCWSTR  pServiceName,
_In_ DWORD  dwControl,
_In_ SERVICE_STATUS_HANDLE  hServiceStatus 
)

Definition at line 1592 of file database.c.

1597{
1598 DWORD dwError = ERROR_SUCCESS;
1599 PSCM_CONTROL_PACKET ControlPacket;
1601 PWSTR Ptr;
1602
1603 DPRINT("ScmControlService(%S, %d) called\n", pServiceName, dwControl);
1604
1605 /* Calculate the total size of the control packet:
1606 * initial structure, the start command line, and the argument vector */
1608 PacketSize += (DWORD)((wcslen(pServiceName) + 1) * sizeof(WCHAR));
1609
1610 /* Allocate the control packet */
1612 if (!ControlPacket)
1614
1615 ControlPacket->dwSize = PacketSize;
1616 ControlPacket->dwControl = dwControl;
1617 ControlPacket->hServiceStatus = hServiceStatus;
1618
1619 /* Copy the service name */
1620 ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
1621 Ptr = (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset);
1622 wcscpy(Ptr, pServiceName);
1623
1624 /* Send the control packet */
1625 dwError = ScmSendControlPacket(hControlPipe,
1626 pServiceName,
1627 dwControl,
1628 PacketSize,
1629 ControlPacket);
1630
1631 /* Free the control packet */
1632 HeapFree(GetProcessHeap(), 0, ControlPacket);
1633
1634 DPRINT("ScmControlService(%S, %d) done (Error %lu)\n", pServiceName, dwControl, dwError);
1635 return dwError;
1636}
DWORD ScmSendControlPacket(_In_ HANDLE hControlPipe, _In_ PCWSTR pServiceName, _In_ DWORD dwControl, _In_ DWORD dwControlPacketSize, _In_ PVOID pControlPacket)
Definition: database.c:1416
wcscpy
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
struct _SCM_CONTROL_PACKET SCM_CONTROL_PACKET
DWORD dwServiceNameOffset
Definition: services.h:35
SERVICE_STATUS_HANDLE hServiceStatus
Definition: services.h:34
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65
SERVICE_STATUS_HANDLE hServiceStatus
Definition: main.c:10
_In_ USHORT PacketSize
Definition: iofuncs.h:1058

Referenced by RControlService(), ScmAutoShutdownServices(), and ScmStopThread().

◆ ScmControlServiceEx()

DWORD ScmControlServiceEx ( _In_ HANDLE  hControlPipe,
_In_ PCWSTR  pServiceName,
_In_ DWORD  dwControl,
_In_ SERVICE_STATUS_HANDLE  hServiceStatus,
_In_opt_ DWORD  dwServiceTag,
_In_opt_ DWORD  argc,
_In_reads_opt_(argc) const PCWSTR argv 
)

Definition at line 1492 of file database.c.

1500{
1501 DWORD dwError = ERROR_SUCCESS;
1502 PSCM_CONTROL_PACKET ControlPacket;
1504 DWORD i;
1505 PWSTR Ptr;
1506
1507 DPRINT("ScmControlServiceEx(%S, %d) called\n", pServiceName, dwControl);
1508
1509 /* Calculate the total size of the control packet:
1510 * initial structure, the start command line, and the argument vector */
1512 PacketSize += (DWORD)((wcslen(pServiceName) + 1) * sizeof(WCHAR));
1513
1514 /*
1515 * Calculate the required packet size for the start argument vector 'argv',
1516 * composed of the pointer offsets list, followed by UNICODE strings.
1517 * The strings are stored successively after the offsets vector, with
1518 * the offsets being relative to the beginning of the vector, as in the
1519 * following layout (with N == argc):
1520 * [argOff(0)]...[argOff(N-1)][str(0)]...[str(N-1)] .
1521 */
1522 if (argc > 0 && argv != NULL)
1523 {
1525 PacketSize += (argc * sizeof(PWSTR));
1526
1527 DPRINT("Argc: %lu\n", argc);
1528 for (i = 0; i < argc; i++)
1529 {
1530 DPRINT("Argv[%lu]: %S\n", i, argv[i]);
1531 PacketSize += (DWORD)((wcslen(argv[i]) + 1) * sizeof(WCHAR));
1532 }
1533 }
1534
1535 /* Allocate the control packet */
1537 if (!ControlPacket)
1539
1540 ControlPacket->dwSize = PacketSize;
1541 ControlPacket->dwControl = dwControl;
1542 ControlPacket->hServiceStatus = hServiceStatus;
1543 ControlPacket->dwServiceTag = dwServiceTag;
1544
1545 /* Copy the start command line */
1546 ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
1547 Ptr = (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset);
1548 wcscpy(Ptr, pServiceName);
1549
1550 ControlPacket->dwArgumentsCount = 0;
1551 ControlPacket->dwArgumentsOffset = 0;
1552
1553 /* Copy the argument vector */
1554 if (argc > 0 && argv != NULL)
1555 {
1556 PWSTR *pOffPtr, pArgPtr;
1557
1558 Ptr += wcslen(pServiceName) + 1;
1559 pOffPtr = (PWSTR*)ALIGN_UP_POINTER(Ptr, PWSTR);
1560 pArgPtr = (PWSTR)((ULONG_PTR)pOffPtr + argc * sizeof(PWSTR));
1561
1562 ControlPacket->dwArgumentsCount = argc;
1563 ControlPacket->dwArgumentsOffset = (DWORD)((ULONG_PTR)pOffPtr - (ULONG_PTR)ControlPacket);
1564
1565 DPRINT("dwArgumentsCount: %lu\n", ControlPacket->dwArgumentsCount);
1566 DPRINT("dwArgumentsOffset: %lu\n", ControlPacket->dwArgumentsOffset);
1567
1568 for (i = 0; i < argc; i++)
1569 {
1570 wcscpy(pArgPtr, argv[i]);
1571 pOffPtr[i] = (PWSTR)((ULONG_PTR)pArgPtr - (ULONG_PTR)pOffPtr);
1572 DPRINT("offset[%lu]: %p\n", i, pOffPtr[i]);
1573 pArgPtr += wcslen(argv[i]) + 1;
1574 }
1575 }
1576
1577 dwError = ScmSendControlPacket(hControlPipe,
1578 pServiceName,
1579 dwControl,
1580 PacketSize,
1581 ControlPacket);
1582
1583 /* Free the control packet */
1584 HeapFree(GetProcessHeap(), 0, ControlPacket);
1585
1586 DPRINT("ScmControlServiceEx(%S, %d) done (Error %lu)\n", pServiceName, dwControl, dwError);
1587 return dwError;
1588}
static int argc
Definition: ServiceArgs.c:12
#define ULONG_PTR
Definition: config.h:101
#define argv
Definition: mplay32.c:18
DWORD dwArgumentsOffset
Definition: services.h:36
DWORD dwArgumentsCount
Definition: services.h:32
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
#define ALIGN_UP_POINTER(ptr, type)
Definition: umtypes.h:97

Referenced by ScmStartUserModeService().

◆ ScmCreateNewControlPipe()

static DWORD ScmCreateNewControlPipe ( _In_ PSERVICE_IMAGE  pServiceImage,
_In_ BOOL  bSecurityServiceProcess 
)
static

Definition at line 52 of file database.c.

55{
56 WCHAR szControlPipeName[MAX_PATH + 1];
57 SECURITY_ATTRIBUTES SecurityAttributes;
58 HKEY hServiceCurrentKey = INVALID_HANDLE_VALUE;
59 DWORD dwServiceCurrent = 1;
60 DWORD dwKeyDisposition;
61 DWORD dwKeySize;
62 DWORD dwError;
63
64 /* Get the service number */
66 {
67 /* TODO: Create registry entry with correct write access */
69 L"SYSTEM\\CurrentControlSet\\Control\\ServiceCurrent",
70 0,
71 NULL,
74 NULL,
75 &hServiceCurrentKey,
76 &dwKeyDisposition);
77 if (dwError != ERROR_SUCCESS)
78 {
79 DPRINT1("RegCreateKeyEx() failed with error %lu\n", dwError);
80 return dwError;
81 }
82
83 if (dwKeyDisposition == REG_OPENED_EXISTING_KEY)
84 {
85 dwKeySize = sizeof(DWORD);
86 dwError = RegQueryValueExW(hServiceCurrentKey,
87 L"",
88 0,
89 NULL,
90 (BYTE*)&dwServiceCurrent,
91 &dwKeySize);
92 if (dwError != ERROR_SUCCESS)
93 {
94 RegCloseKey(hServiceCurrentKey);
95 DPRINT1("RegQueryValueEx() failed with error %lu\n", dwError);
96 return dwError;
97 }
98
99 dwServiceCurrent++;
100 }
101
102 dwError = RegSetValueExW(hServiceCurrentKey,
103 L"",
104 0,
105 REG_DWORD,
106 (BYTE*)&dwServiceCurrent,
107 sizeof(dwServiceCurrent));
108
109 RegCloseKey(hServiceCurrentKey);
110
111 if (dwError != ERROR_SUCCESS)
112 {
113 DPRINT1("RegSetValueExW() failed (Error %lu)\n", dwError);
114 return dwError;
115 }
116 }
117 else
118 {
119 dwServiceCurrent = 0;
120 }
121
122 /* Create '\\.\pipe\net\NtControlPipeXXX' instance */
123 StringCchPrintfW(szControlPipeName, ARRAYSIZE(szControlPipeName),
124 L"\\\\.\\pipe\\net\\NtControlPipe%lu", dwServiceCurrent);
125
126 DPRINT("PipeName: %S\n", szControlPipeName);
127
128 SecurityAttributes.nLength = sizeof(SecurityAttributes);
129 SecurityAttributes.lpSecurityDescriptor = pPipeSD;
130 SecurityAttributes.bInheritHandle = FALSE;
131
132 pServiceImage->hControlPipe = CreateNamedPipeW(szControlPipeName,
135 100,
136 8000,
137 4,
139 &SecurityAttributes);
140 DPRINT("CreateNamedPipeW(%S) done\n", szControlPipeName);
141 if (pServiceImage->hControlPipe == INVALID_HANDLE_VALUE)
142 {
143 DPRINT1("Failed to create control pipe\n");
144 return GetLastError();
145 }
146
147 return ERROR_SUCCESS;
148}
static DWORD PipeTimeout
Definition: database.c:37
PSECURITY_DESCRIPTOR pPipeSD
Definition: security.c:27
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:246
#define KEY_WRITE
Definition: nt_native.h:1031
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
static BOOL bSecurityServiceProcess
Definition: sctrl.c:63
#define REG_DWORD
Definition: sdbapi.c:596
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
LPVOID lpSecurityDescriptor
Definition: compat.h:193
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:172
#define PIPE_WAIT
Definition: winbase.h:179
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:178
#define PIPE_TYPE_MESSAGE
Definition: winbase.h:176
unsigned char BYTE
Definition: xxhash.c:193

Referenced by ScmCreateOrReferenceServiceImage().

◆ ScmCreateNewServiceRecord()

DWORD ScmCreateNewServiceRecord ( LPCWSTR  lpServiceName,
PSERVICE lpServiceRecord,
DWORD  dwServiceType,
DWORD  dwStartType 
)

Definition at line 766 of file database.c.

770{
771 PSERVICE lpService = NULL;
772
773 DPRINT("Service: '%S'\n", lpServiceName);
774
775 /* Allocate service entry */
776 lpService = HeapAlloc(GetProcessHeap(),
778 FIELD_OFFSET(SERVICE, szServiceName[wcslen(lpServiceName) + 1]));
779 if (lpService == NULL)
781
782 *lpServiceRecord = lpService;
783
784 /* Copy service name */
785 wcscpy(lpService->szServiceName, lpServiceName);
786 lpService->lpServiceName = lpService->szServiceName;
787 lpService->lpDisplayName = lpService->lpServiceName;
788
789 /* Set the start type */
790 lpService->dwStartType = dwStartType;
791
792 /* Set the resume count */
793 lpService->dwResumeCount = ResumeCount++;
794
795 /* Append service record */
797 &lpService->ServiceListEntry);
798
799 /* Initialize the service status */
800 lpService->Status.dwServiceType = dwServiceType;
802 lpService->Status.dwControlsAccepted = 0;
803 lpService->Status.dwWin32ExitCode =
805 lpService->Status.dwServiceSpecificExitCode = 0;
806 lpService->Status.dwCheckPoint = 0;
807 lpService->Status.dwWaitHint =
808 (dwServiceType & SERVICE_DRIVER) ? 0 : 2000; /* 2 seconds */
809
810 return ERROR_SUCCESS;
811}
static DWORD ResumeCount
Definition: database.c:31
#define InsertTailList(ListHead, Entry)
DWORD dwWin32ExitCode
Definition: winsvc.h:102
DWORD dwWaitHint
Definition: winsvc.h:105
DWORD dwCheckPoint
Definition: winsvc.h:104
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
LIST_ENTRY ServiceListEntry
Definition: services.h:63
DWORD dwResumeCount
Definition: services.h:69
WCHAR szServiceName[1]
Definition: services.h:86
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define ERROR_SERVICE_NEVER_STARTED
Definition: winerror.h:628
#define ERROR_SERVICE_DISABLED
Definition: winerror.h:609
#define SERVICE_DISABLED
Definition: cmtypes.h:979
#define SERVICE_DRIVER
Definition: cmtypes.h:958

Referenced by CreateServiceListEntry(), and RCreateServiceW().

◆ ScmCreateOrReferenceServiceImage()

static DWORD ScmCreateOrReferenceServiceImage ( PSERVICE  pService)
static

Definition at line 457 of file database.c.

458{
460 UNICODE_STRING ImagePath;
462 PSERVICE_IMAGE pServiceImage = NULL;
464 DWORD dwError = ERROR_SUCCESS;
465 DWORD dwRecordSize;
467 BOOL bSecurityService;
468
469 DPRINT("ScmCreateOrReferenceServiceImage(%p)\n", pService);
470
471 RtlInitUnicodeString(&ImagePath, NULL);
473
474 /* Get service data */
476 sizeof(QueryTable));
477
478 QueryTable[0].Name = L"ImagePath";
480 QueryTable[0].EntryContext = &ImagePath;
481 QueryTable[1].Name = L"ObjectName";
484
486 pService->lpServiceName,
488 NULL,
489 NULL);
490 if (!NT_SUCCESS(Status))
491 {
492 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
494 }
495
496 DPRINT("ImagePath: '%wZ'\n", &ImagePath);
497 DPRINT("ObjectName: '%wZ'\n", &ObjectName);
498
499 pServiceImage = ScmGetServiceImageByImagePath(ImagePath.Buffer);
500 if (pServiceImage == NULL)
501 {
502 dwRecordSize = sizeof(SERVICE_IMAGE) +
503 ImagePath.Length + sizeof(WCHAR) +
504 ((ObjectName.Length != 0) ? (ObjectName.Length + sizeof(WCHAR)) : 0);
505
506 /* Create a new service image */
507 pServiceImage = HeapAlloc(GetProcessHeap(),
509 dwRecordSize);
510 if (pServiceImage == NULL)
511 {
512 dwError = ERROR_NOT_ENOUGH_MEMORY;
513 goto done;
514 }
515
516 pServiceImage->dwImageRunCount = 1;
517 pServiceImage->hControlPipe = INVALID_HANDLE_VALUE;
518 pServiceImage->hProcess = INVALID_HANDLE_VALUE;
519
520 pString = (PWSTR)((INT_PTR)pServiceImage + sizeof(SERVICE_IMAGE));
521
522 /* Set the image path */
523 pServiceImage->pszImagePath = pString;
524 wcscpy(pServiceImage->pszImagePath,
525 ImagePath.Buffer);
526
527 /* Set the account name */
528 if (ObjectName.Length > 0)
529 {
530 pString = pString + wcslen(pString) + 1;
531
532 pServiceImage->pszAccountName = pString;
533 wcscpy(pServiceImage->pszAccountName,
534 ObjectName.Buffer);
535 }
536
537 /* Service logon */
538 dwError = ScmLogonService(pService, pServiceImage);
539 if (dwError != ERROR_SUCCESS)
540 {
541 DPRINT1("ScmLogonService() failed (Error %lu)\n", dwError);
542
543 /* Release the service image */
544 HeapFree(GetProcessHeap(), 0, pServiceImage);
545
546 goto done;
547 }
548
549 bSecurityService = ScmIsSecurityService(pServiceImage);
550
551 /* Create the control pipe */
552 dwError = ScmCreateNewControlPipe(pServiceImage,
553 bSecurityService);
554 if (dwError != ERROR_SUCCESS)
555 {
556 DPRINT1("ScmCreateNewControlPipe() failed (Error %lu)\n", dwError);
557
558 /* Unload the user profile */
559 if (pServiceImage->hProfile != NULL)
560 {
562 UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile);
564 }
565
566 /* Close the logon token */
567 if (pServiceImage->hToken != NULL)
568 CloseHandle(pServiceImage->hToken);
569
570 /* Release the service image */
571 HeapFree(GetProcessHeap(), 0, pServiceImage);
572
573 goto done;
574 }
575
576 if (bSecurityService)
577 {
579 }
580
581 /* FIXME: Add more initialization code here */
582
583
584 /* Append service record */
586 &pServiceImage->ImageListEntry);
587 }
588 else
589 {
590// if ((lpService->Status.dwServiceType & SERVICE_WIN32_SHARE_PROCESS) == 0)
591
592 /* Fail if services in an image use different accounts */
593 if (!ScmIsSameServiceAccount(pServiceImage->pszAccountName, ObjectName.Buffer))
594 {
596 goto done;
597 }
598
599 /* Increment the run counter */
600 pServiceImage->dwImageRunCount++;
601 }
602
603 DPRINT("pServiceImage->pszImagePath: %S\n", pServiceImage->pszImagePath);
604 DPRINT("pServiceImage->pszAccountName: %S\n", pServiceImage->pszAccountName);
605 DPRINT("pServiceImage->dwImageRunCount: %lu\n", pServiceImage->dwImageRunCount);
606
607 /* Link the service image to the service */
608 pService->lpImage = pServiceImage;
609
610done:
612 RtlFreeUnicodeString(&ImagePath);
613
614 DPRINT("ScmCreateOrReferenceServiceImage() done (Error: %lu)\n", dwError);
615
616 return dwError;
617}
static BOOL ScmEnableBackupRestorePrivileges(_In_ HANDLE hToken, _In_ BOOL bEnable)
Definition: database.c:311
static PSERVICE_IMAGE ScmGetServiceImageByImagePath(LPWSTR lpImagePath)
Definition: database.c:152
LIST_ENTRY ImageListHead
Definition: database.c:27
static BOOL ScmIsSecurityService(_In_ PSERVICE_IMAGE pServiceImage)
Definition: database.c:44
static DWORD ScmLogonService(IN PSERVICE pService, IN PSERVICE_IMAGE pImage)
Definition: database.c:358
static BOOL ScmIsSameServiceAccount(_In_ PCWSTR pszAccountName1, _In_ PCWSTR pszAccountName2)
Definition: database.c:269
static DWORD ScmCreateNewControlPipe(_In_ PSERVICE_IMAGE pServiceImage, _In_ BOOL bSecurityServiceProcess)
Definition: database.c:52
DWORD SetSecurityServicesEvent(VOID)
Definition: services.c:142
struct _SERVICE_IMAGE SERVICE_IMAGE
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2184
unsigned int BOOL
Definition: ntddk_ex.h:94
FxString * pString
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4203
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define RTL_REGISTRY_SERVICES
Definition: nt_native.h:162
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
LPWSTR pszImagePath
Definition: services.h:49
LIST_ENTRY ImageListEntry
Definition: services.h:48
HANDLE hProfile
Definition: services.h:57
LPWSTR pszAccountName
Definition: services.h:50
HANDLE hToken
Definition: services.h:56
DWORD dwImageRunCount
Definition: services.h:51
HANDLE hProcess
Definition: services.h:54
int32_t INT_PTR
Definition: typedefs.h:64
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ERROR_DIFFERENT_SERVICE_ACCOUNT
Definition: winerror.h:630
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64

Referenced by ScmLoadService().

◆ ScmCreateServiceDatabase()

DWORD ScmCreateServiceDatabase ( VOID  )

Definition at line 1186 of file database.c.

1187{
1188 WCHAR szSubKey[MAX_PATH];
1190 HKEY hServiceKey;
1191 DWORD dwSubKey;
1192 DWORD dwSubKeyLength;
1193 FILETIME ftLastChanged;
1194 DWORD dwError;
1195
1196 DPRINT("ScmCreateServiceDatabase() called\n");
1197
1198 /* Retrieve the NoInteractiveServies value */
1200
1201 /* Create the service group list */
1202 dwError = ScmCreateGroupList();
1203 if (dwError != ERROR_SUCCESS)
1204 return dwError;
1205
1206 /* Initialize image and service lists */
1209
1210 /* Initialize the database lock */
1212
1214 L"System\\CurrentControlSet\\Services",
1215 0,
1216 KEY_READ,
1217 &hServicesKey);
1218 if (dwError != ERROR_SUCCESS)
1219 return dwError;
1220
1221 dwSubKey = 0;
1222 for (;;)
1223 {
1224 dwSubKeyLength = MAX_PATH;
1225 dwError = RegEnumKeyExW(hServicesKey,
1226 dwSubKey,
1227 szSubKey,
1228 &dwSubKeyLength,
1229 NULL,
1230 NULL,
1231 NULL,
1232 &ftLastChanged);
1233 if (dwError == ERROR_SUCCESS &&
1234 szSubKey[0] != L'{')
1235 {
1236 DPRINT("SubKeyName: '%S'\n", szSubKey);
1237
1238 dwError = RegOpenKeyExW(hServicesKey,
1239 szSubKey,
1240 0,
1241 KEY_READ,
1242 &hServiceKey);
1243 if (dwError == ERROR_SUCCESS)
1244 {
1245 dwError = CreateServiceListEntry(szSubKey,
1246 hServiceKey);
1247
1248 RegCloseKey(hServiceKey);
1249 }
1250 }
1251
1252 if (dwError != ERROR_SUCCESS)
1253 break;
1254
1255 dwSubKey++;
1256 }
1257
1259
1260 /* Wait for the LSA server */
1261 ScmWaitForLsa();
1262
1263 /* Delete services that are marked for delete */
1265
1266 DPRINT("ScmCreateServiceDatabase() done\n");
1267
1268 return ERROR_SUCCESS;
1269}
static DWORD CreateServiceListEntry(LPCWSTR lpServiceName, HKEY hServiceKey)
Definition: database.c:955
static RTL_RESOURCE DatabaseLock
Definition: database.c:30
static VOID ScmGetNoInteractiveServicesValue(VOID)
Definition: database.c:1160
VOID ScmDeleteMarkedServices(VOID)
Definition: database.c:1119
VOID ScmWaitForLsa(VOID)
Definition: services.c:207
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DWORD ScmCreateGroupList(VOID)
Definition: groupdb.c:235
NTSYSAPI VOID NTAPI RtlInitializeResource(_In_ PRTL_RESOURCE Resource)

Referenced by wWinMain().

◆ ScmDeleteMarkedServices()

VOID ScmDeleteMarkedServices ( VOID  )

Definition at line 1119 of file database.c.

1120{
1121 PLIST_ENTRY ServiceEntry;
1122 PSERVICE CurrentService;
1124 DWORD dwError;
1125
1126 ServiceEntry = ServiceListHead.Flink;
1127 while (ServiceEntry != &ServiceListHead)
1128 {
1129 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
1130
1131 ServiceEntry = ServiceEntry->Flink;
1132
1133 if (CurrentService->bDeleted != FALSE)
1134 {
1136 L"System\\CurrentControlSet\\Services",
1137 0,
1138 DELETE,
1139 &hServicesKey);
1140 if (dwError == ERROR_SUCCESS)
1141 {
1142 dwError = ScmDeleteRegKey(hServicesKey, CurrentService->lpServiceName);
1144 if (dwError == ERROR_SUCCESS)
1145 {
1146 RemoveEntryList(&CurrentService->ServiceListEntry);
1147 HeapFree(GetProcessHeap(), 0, CurrentService);
1148 }
1149 }
1150
1151 if (dwError != ERROR_SUCCESS)
1152 DPRINT1("Delete service failed: %S\n", CurrentService->lpServiceName);
1153 }
1154 }
1155}
DWORD ScmDeleteRegKey(_In_ HKEY hKey, _In_ PCWSTR pszSubKey)
Definition: config.c:646
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define DELETE
Definition: nt_native.h:57

Referenced by ScmCreateServiceDatabase(), and ScmShutdownServiceDatabase().

◆ ScmDeleteNamedPipeCriticalSection()

VOID ScmDeleteNamedPipeCriticalSection ( VOID  )

Definition at line 2419 of file database.c.

2420{
2422}
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

Referenced by wWinMain().

◆ ScmDeleteService()

DWORD ScmDeleteService ( PSERVICE  lpService)

Definition at line 862 of file database.c.

863{
864 DWORD dwError;
866 DWORD dwServicesReturned = 0;
868
869 ASSERT(lpService->RefCount == 0);
870
871 /* Open the Services Reg key */
873 L"System\\CurrentControlSet\\Services",
874 0,
876 &hServicesKey);
877 if (dwError != ERROR_SUCCESS)
878 {
879 DPRINT1("Failed to open services key\n");
880 return dwError;
881 }
882
883 /* Call the function with NULL, just to get bytes we need */
885 lpService,
887 NULL,
889 &dwServicesReturned);
890
891 /* If pcbBytesNeeded returned a value then there are services running that are dependent on this service */
892 if (pcbBytesNeeded)
893 {
894 DPRINT1("Deletion failed due to running dependencies\n");
897 }
898
899 /* There are no references and no running dependencies,
900 it is now safe to delete the service */
901
902 /* Delete the Service Key */
903 dwError = ScmDeleteRegKey(hServicesKey, lpService->lpServiceName);
904
906
907 if (dwError != ERROR_SUCCESS)
908 {
909 DPRINT1("Failed to delete the Service Registry key\n");
910 return dwError;
911 }
912
913 /* Delete the Service */
914 ScmDeleteServiceRecord(lpService);
915
916 return ERROR_SUCCESS;
917}
VOID ScmDeleteServiceRecord(PSERVICE lpService)
Definition: database.c:815
DWORD Int_EnumDependentServicesW(HKEY hServicesKey, PSERVICE lpService, DWORD dwServiceState, PSERVICE *lpServices, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: rpcserver.c:782
#define KEY_SET_VALUE
Definition: nt_native.h:1017
LONG RefCount
Definition: services.h:70
#define ERROR_DEPENDENT_SERVICES_RUNNING
Definition: winerror.h:602

Referenced by ScmDereferenceService().

◆ ScmDeleteServiceRecord()

VOID ScmDeleteServiceRecord ( PSERVICE  lpService)

Definition at line 815 of file database.c.

816{
817 DPRINT("Deleting Service %S\n", lpService->lpServiceName);
818
819 /* Delete the display name */
820 if (lpService->lpDisplayName != NULL &&
821 lpService->lpDisplayName != lpService->lpServiceName)
822 HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
823
824 /* Dereference the service image */
825 if (lpService->lpImage)
826 {
827 lpService->lpImage->dwImageRunCount--;
828
829 if (lpService->lpImage->dwImageRunCount == 0)
830 {
831 ScmRemoveServiceImage(lpService->lpImage);
832 lpService->lpImage = NULL;
833 }
834 }
835
836 /* Decrement the group reference counter */
837 ScmSetServiceGroup(lpService, NULL);
838
839 /* Release the SecurityDescriptor */
840 if (lpService->pSecurityDescriptor != NULL)
842
843 /* Remove the Service from the List */
845
846 DPRINT("Deleted Service %S\n", lpService->lpServiceName);
847
848 /* Delete the service record */
849 HeapFree(GetProcessHeap(), 0, lpService);
850
851 DPRINT("Done\n");
852}
VOID ScmRemoveServiceImage(PSERVICE_IMAGE pServiceImage)
Definition: database.c:621

Referenced by ScmDeleteService().

◆ ScmDereferenceService()

DWORD ScmDereferenceService ( PSERVICE  lpService)

Definition at line 938 of file database.c.

939{
940 DWORD ref;
941
942 ASSERT(lpService->RefCount > 0);
943
944 ref = InterlockedDecrement(&lpService->RefCount);
945
946 if (ref == 0 && lpService->bDeleted &&
948 {
949 ScmDeleteService(lpService);
950 }
951 return ref;
952}
#define InterlockedDecrement
Definition: armddk.h:52
DWORD ScmDeleteService(PSERVICE lpService)
Definition: database.c:862
Definition: send.c:48

Referenced by RCloseServiceHandle(), RSetServiceStatus(), and ScmStopThread().

◆ ScmEnableBackupRestorePrivileges()

static BOOL ScmEnableBackupRestorePrivileges ( _In_ HANDLE  hToken,
_In_ BOOL  bEnable 
)
static

Definition at line 311 of file database.c.

314{
315 PTOKEN_PRIVILEGES pTokenPrivileges = NULL;
317 BOOL bRet = FALSE;
318
319 DPRINT("ScmEnableBackupRestorePrivileges(%p %d)\n", hToken, bEnable);
320
321 dwSize = sizeof(TOKEN_PRIVILEGES) + 2 * sizeof(LUID_AND_ATTRIBUTES);
322 pTokenPrivileges = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
323 if (pTokenPrivileges == NULL)
324 {
325 DPRINT1("Failed to allocate privilege buffer\n");
326 goto done;
327 }
328
329 pTokenPrivileges->PrivilegeCount = 2;
330 pTokenPrivileges->Privileges[0].Luid.LowPart = SE_BACKUP_PRIVILEGE;
331 pTokenPrivileges->Privileges[0].Luid.HighPart = 0;
332 pTokenPrivileges->Privileges[0].Attributes = (bEnable ? SE_PRIVILEGE_ENABLED : 0);
333 pTokenPrivileges->Privileges[1].Luid.LowPart = SE_RESTORE_PRIVILEGE;
334 pTokenPrivileges->Privileges[1].Luid.HighPart = 0;
335 pTokenPrivileges->Privileges[1].Attributes = (bEnable ? SE_PRIVILEGE_ENABLED : 0);
336
337 bRet = AdjustTokenPrivileges(hToken, FALSE, pTokenPrivileges, 0, NULL, NULL);
338 if (!bRet)
339 {
340 DPRINT1("AdjustTokenPrivileges() failed with error %lu\n", GetLastError());
341 }
343 {
344 DPRINT1("AdjustTokenPrivileges() succeeded, but with not all privileges assigned\n");
345 bRet = FALSE;
346 }
347
348done:
349 if (pTokenPrivileges != NULL)
350 HeapFree(GetProcessHeap(), 0, pTokenPrivileges);
351
352 return bRet;
353}
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:374
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
LONG HighPart
DWORD LowPart
$ULONG PrivilegeCount
Definition: setypes.h:1035
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:1036
_In_ BOOL bEnable
Definition: winddi.h:3426
#define ERROR_NOT_ALL_ASSIGNED
Definition: winerror.h:782
struct _TOKEN_PRIVILEGES TOKEN_PRIVILEGES
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63

Referenced by ScmCreateOrReferenceServiceImage(), ScmLogonService(), and ScmRemoveServiceImage().

◆ ScmGenerateServiceTag()

DWORD ScmGenerateServiceTag ( PSERVICE  lpServiceRecord)

Definition at line 743 of file database.c.

744{
745 /* Check for an overflow */
746 if (ServiceTag == -1)
747 {
748 return ERROR_INVALID_DATA;
749 }
750
751 /* This is only valid for Win32 services */
752 if (!(lpServiceRecord->Status.dwServiceType & SERVICE_WIN32))
753 {
755 }
756
757 /* Increment the tag counter and set it */
758 ServiceTag = ServiceTag % 0xFFFFFFFF + 1;
759 lpServiceRecord->dwServiceTag = ServiceTag;
760
761 return ERROR_SUCCESS;
762}
static DWORD ServiceTag
Definition: database.c:33
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
DWORD dwServiceTag
Definition: services.h:78
#define ERROR_INVALID_DATA
Definition: winerror.h:116

Referenced by CreateServiceListEntry(), and RCreateServiceW().

◆ ScmGetBootAndSystemDriverState()

VOID ScmGetBootAndSystemDriverState ( VOID  )

Definition at line 1383 of file database.c.

1384{
1385 PLIST_ENTRY ServiceEntry;
1386 PSERVICE CurrentService;
1387
1388 DPRINT("ScmGetBootAndSystemDriverState() called\n");
1389
1390 ServiceEntry = ServiceListHead.Flink;
1391 while (ServiceEntry != &ServiceListHead)
1392 {
1393 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
1394
1395 if (CurrentService->dwStartType == SERVICE_BOOT_START ||
1396 CurrentService->dwStartType == SERVICE_SYSTEM_START)
1397 {
1398 /* Check driver */
1399 DPRINT(" Checking service: %S\n", CurrentService->lpServiceName);
1400
1401 ScmCheckDriver(CurrentService);
1402 }
1403
1404 ServiceEntry = ServiceEntry->Flink;
1405 }
1406
1407 DPRINT("ScmGetBootAndSystemDriverState() done\n");
1408}
static NTSTATUS ScmCheckDriver(PSERVICE Service)
Definition: database.c:1285
#define SERVICE_BOOT_START
Definition: cmtypes.h:975
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:976

Referenced by wWinMain().

◆ ScmGetNoInteractiveServicesValue()

static VOID ScmGetNoInteractiveServicesValue ( VOID  )
static

Definition at line 1160 of file database.c.

1161{
1162 HKEY hKey;
1163 DWORD dwKeySize;
1164 LONG lError;
1165
1167 L"SYSTEM\\CurrentControlSet\\Control\\Windows",
1168 0,
1169 KEY_READ,
1170 &hKey);
1171 if (lError == ERROR_SUCCESS)
1172 {
1173 dwKeySize = sizeof(NoInteractiveServices);
1174 lError = RegQueryValueExW(hKey,
1175 L"NoInteractiveServices",
1176 0,
1177 NULL,
1179 &dwKeySize);
1181 }
1182}
static DWORD NoInteractiveServices
Definition: database.c:32
long LONG
Definition: pedump.c:60

Referenced by ScmCreateServiceDatabase().

◆ ScmGetServiceEntryByDisplayName()

PSERVICE ScmGetServiceEntryByDisplayName ( LPCWSTR  lpDisplayName)

Definition at line 685 of file database.c.

686{
687 PLIST_ENTRY ServiceEntry;
688 PSERVICE CurrentService;
689
690 DPRINT("ScmGetServiceEntryByDisplayName() called\n");
691
692 ServiceEntry = ServiceListHead.Flink;
693 while (ServiceEntry != &ServiceListHead)
694 {
695 CurrentService = CONTAINING_RECORD(ServiceEntry,
696 SERVICE,
697 ServiceListEntry);
698 if (_wcsicmp(CurrentService->lpDisplayName, lpDisplayName) == 0)
699 {
700 DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
701 return CurrentService;
702 }
703
704 ServiceEntry = ServiceEntry->Flink;
705 }
706
707 DPRINT("Couldn't find a matching service\n");
708
709 return NULL;
710}

Referenced by RCreateServiceW(), RGetServiceKeyNameA(), and RGetServiceKeyNameW().

◆ ScmGetServiceEntryByName()

PSERVICE ScmGetServiceEntryByName ( LPCWSTR  lpServiceName)

Definition at line 656 of file database.c.

657{
658 PLIST_ENTRY ServiceEntry;
659 PSERVICE CurrentService;
660
661 DPRINT("ScmGetServiceEntryByName() called\n");
662
663 ServiceEntry = ServiceListHead.Flink;
664 while (ServiceEntry != &ServiceListHead)
665 {
666 CurrentService = CONTAINING_RECORD(ServiceEntry,
667 SERVICE,
668 ServiceListEntry);
669 if (_wcsicmp(CurrentService->lpServiceName, lpServiceName) == 0)
670 {
671 DPRINT("Found service: '%S'\n", CurrentService->lpServiceName);
672 return CurrentService;
673 }
674
675 ServiceEntry = ServiceEntry->Flink;
676 }
677
678 DPRINT("Couldn't find a matching service\n");
679
680 return NULL;
681}

Referenced by Int_EnumDependentServicesW(), RCreateServiceW(), RGetServiceDisplayNameA(), RGetServiceDisplayNameW(), RI_ScValidatePnPService(), and ROpenServiceW().

◆ ScmGetServiceEntryByResumeCount()

PSERVICE ScmGetServiceEntryByResumeCount ( DWORD  dwResumeCount)

Definition at line 714 of file database.c.

715{
716 PLIST_ENTRY ServiceEntry;
717 PSERVICE CurrentService;
718
719 DPRINT("ScmGetServiceEntryByResumeCount() called\n");
720
721 ServiceEntry = ServiceListHead.Flink;
722 while (ServiceEntry != &ServiceListHead)
723 {
724 CurrentService = CONTAINING_RECORD(ServiceEntry,
725 SERVICE,
726 ServiceListEntry);
727 if (CurrentService->dwResumeCount > dwResumeCount)
728 {
729 DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
730 return CurrentService;
731 }
732
733 ServiceEntry = ServiceEntry->Flink;
734 }
735
736 DPRINT("Couldn't find a matching service\n");
737
738 return NULL;
739}

Referenced by REnumServiceGroupW(), and REnumServicesStatusExW().

◆ ScmGetServiceImageByImagePath()

static PSERVICE_IMAGE ScmGetServiceImageByImagePath ( LPWSTR  lpImagePath)
static

Definition at line 152 of file database.c.

153{
154 PLIST_ENTRY ImageEntry;
155 PSERVICE_IMAGE CurrentImage;
156
157 DPRINT("ScmGetServiceImageByImagePath(%S) called\n", lpImagePath);
158
159 ImageEntry = ImageListHead.Flink;
160 while (ImageEntry != &ImageListHead)
161 {
162 CurrentImage = CONTAINING_RECORD(ImageEntry,
164 ImageListEntry);
165 if (_wcsicmp(CurrentImage->pszImagePath, lpImagePath) == 0)
166 {
167 DPRINT("Found image: '%S'\n", CurrentImage->pszImagePath);
168 return CurrentImage;
169 }
170
171 ImageEntry = ImageEntry->Flink;
172 }
173
174 DPRINT("Couldn't find a matching image\n");
175
176 return NULL;
177
178}

Referenced by ScmCreateOrReferenceServiceImage().

◆ ScmGetServiceNameFromTag()

DWORD ScmGetServiceNameFromTag ( IN PTAG_INFO_NAME_FROM_TAG_IN_PARAMS  InParams,
OUT PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS OutParams 
)

Definition at line 182 of file database.c.

184{
185 PLIST_ENTRY ServiceEntry;
186 PSERVICE CurrentService;
187 PSERVICE_IMAGE CurrentImage;
189 DWORD dwError;
190
191 /* Lock the database */
193
194 /* Find the matching service */
195 ServiceEntry = ServiceListHead.Flink;
196 while (ServiceEntry != &ServiceListHead)
197 {
198 CurrentService = CONTAINING_RECORD(ServiceEntry,
199 SERVICE,
200 ServiceListEntry);
201
202 /* We must match the tag */
203 if (CurrentService->dwServiceTag == InParams->dwTag &&
204 CurrentService->lpImage != NULL)
205 {
206 CurrentImage = CurrentService->lpImage;
207 /* And matching the PID */
208 if (CurrentImage->dwProcessId == InParams->dwPid)
209 {
210 break;
211 }
212 }
213
214 ServiceEntry = ServiceEntry->Flink;
215 }
216
217 /* No match! */
218 if (ServiceEntry == &ServiceListHead)
219 {
220 dwError = ERROR_RETRY;
221 goto Cleanup;
222 }
223
224 /* Allocate the output buffer */
226 if (OutBuffer == NULL)
227 {
228 dwError = ERROR_NOT_ENOUGH_MEMORY;
229 goto Cleanup;
230 }
231
232 /* And the buffer for the name */
233 OutBuffer->pszName = MIDL_user_allocate(wcslen(CurrentService->lpServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
234 if (OutBuffer->pszName == NULL)
235 {
236 dwError = ERROR_NOT_ENOUGH_MEMORY;
237 goto Cleanup;
238 }
239
240 /* Fill in output data */
241 wcscpy(OutBuffer->pszName, CurrentService->lpServiceName);
242 OutBuffer->TagType = TagTypeService;
243
244 /* And return */
245 *OutParams = OutBuffer;
246 dwError = ERROR_SUCCESS;
247
248Cleanup:
249
250 /* Unlock database */
252
253 /* If failure, free allocated memory */
254 if (dwError != ERROR_SUCCESS)
255 {
256 if (OutBuffer != NULL)
257 {
259 }
260 }
261
262 /* Return error/success */
263 return dwError;
264}
static const WCHAR Cleanup[]
Definition: register.c:80
void *__RPC_USER MIDL_user_allocate(SIZE_T size)
Definition: irotp.c:371
void __RPC_USER MIDL_user_free(void *p)
Definition: irotp.c:376
#define UNICODE_NULL
_In_ UCHAR _In_ ULONG _Out_ PUCHAR _Outptr_result_bytebuffer_ OutBufferLength PVOID * OutBuffer
Definition: scsi.h:4071
DWORD dwProcessId
Definition: services.h:55
@ TagTypeService
Definition: svcctl.idl:304
#define ERROR_RETRY
Definition: winerror.h:740

Referenced by RI_ScQueryServiceTagInfo().

◆ ScmInitNamedPipeCriticalSection()

VOID ScmInitNamedPipeCriticalSection ( VOID  )

Definition at line 2391 of file database.c.

2392{
2393 HKEY hKey;
2394 DWORD dwKeySize;
2395 DWORD dwError;
2396
2398
2400 L"SYSTEM\\CurrentControlSet\\Control",
2401 0,
2402 KEY_READ,
2403 &hKey);
2404 if (dwError == ERROR_SUCCESS)
2405 {
2406 dwKeySize = sizeof(PipeTimeout);
2408 L"ServicesPipeTimeout",
2409 0,
2410 NULL,
2412 &dwKeySize);
2414 }
2415}
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751

Referenced by wWinMain().

◆ ScmIsLocalSystemAccount()

static BOOL ScmIsLocalSystemAccount ( _In_ PCWSTR  pszAccountName)
static

Definition at line 298 of file database.c.

300{
301 if (pszAccountName == NULL ||
302 _wcsicmp(pszAccountName, L"LocalSystem") == 0)
303 return TRUE;
304
305 return FALSE;
306}

Referenced by ScmLogonService().

◆ ScmIsSameServiceAccount()

static BOOL ScmIsSameServiceAccount ( _In_ PCWSTR  pszAccountName1,
_In_ PCWSTR  pszAccountName2 
)
static

Definition at line 269 of file database.c.

272{
273 if (pszAccountName1 == NULL &&
274 pszAccountName2 == NULL)
275 return TRUE;
276
277 if (pszAccountName1 == NULL &&
278 pszAccountName2 != NULL &&
279 _wcsicmp(pszAccountName2, L"LocalSystem") == 0)
280 return TRUE;
281
282 if (pszAccountName1 != NULL &&
283 pszAccountName2 == NULL &&
284 _wcsicmp(pszAccountName1, L"LocalSystem") == 0)
285 return TRUE;
286
287 if (pszAccountName1 != NULL &&
288 pszAccountName2 != NULL &&
289 _wcsicmp(pszAccountName1, pszAccountName2) == 0)
290 return TRUE;
291
292 return FALSE;
293}

Referenced by ScmCreateOrReferenceServiceImage().

◆ ScmIsSecurityService()

static BOOL ScmIsSecurityService ( _In_ PSERVICE_IMAGE  pServiceImage)
static

Definition at line 44 of file database.c.

46{
47 return (wcsstr(pServiceImage->pszImagePath, L"\\system32\\lsass.exe") != NULL);
48}
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)

Referenced by ScmCreateOrReferenceServiceImage(), ScmStartUserModeService(), and ScmWaitForServiceConnect().

◆ ScmLoadService()

static DWORD ScmLoadService ( PSERVICE  Service,
DWORD  argc,
const PCWSTR argv 
)
static

Definition at line 1967 of file database.c.

1970{
1971 PSERVICE_GROUP Group = Service->lpGroup;
1972 DWORD dwError = ERROR_SUCCESS;
1973 LPCWSTR lpLogStrings[2];
1974 WCHAR szLogBuffer[80];
1975
1976 DPRINT("ScmLoadService() called\n");
1977 DPRINT("Start Service %p (%S)\n", Service, Service->lpServiceName);
1978
1979 if (Service->Status.dwCurrentState != SERVICE_STOPPED)
1980 {
1981 DPRINT("Service %S is already running\n", Service->lpServiceName);
1983 }
1984
1985 DPRINT("Service->Type: %lu\n", Service->Status.dwServiceType);
1986
1987 if (Service->Status.dwServiceType & SERVICE_DRIVER)
1988 {
1989 /* Start the driver */
1990 dwError = ScmStartDriver(Service);
1991 }
1992 else // if (Service->Status.dwServiceType & (SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS))
1993 {
1994 /* Start user-mode service */
1996 if (dwError == ERROR_SUCCESS)
1997 {
1999 if (dwError == ERROR_SUCCESS)
2000 {
2001 Service->Status.dwCurrentState = SERVICE_START_PENDING;
2002 Service->Status.dwControlsAccepted = 0;
2004 }
2005 else
2006 {
2007 Service->lpImage->dwImageRunCount--;
2008 if (Service->lpImage->dwImageRunCount == 0)
2009 {
2011 Service->lpImage = NULL;
2012 }
2013 }
2014 }
2015 }
2016
2017 DPRINT("ScmLoadService() done (Error %lu)\n", dwError);
2018
2019 if (dwError == ERROR_SUCCESS)
2020 {
2021 if (Group != NULL)
2022 {
2023 Group->ServicesRunning = TRUE;
2024 }
2025
2026 /* Log a successful service start */
2028 lpLogStrings[0] = Service->lpDisplayName;
2029 lpLogStrings[1] = szLogBuffer;
2030
2033 2,
2034 lpLogStrings);
2035 }
2036 else
2037 {
2038 if (Service->dwErrorControl != SERVICE_ERROR_IGNORE)
2039 {
2040 /* Log a failed service start */
2041 StringCchPrintfW(szLogBuffer, ARRAYSIZE(szLogBuffer),
2042 L"%lu", dwError);
2043 lpLogStrings[0] = Service->lpServiceName;
2044 lpLogStrings[1] = szLogBuffer;
2047 2,
2048 lpLogStrings);
2049 }
2050
2051#if 0
2052 switch (Service->dwErrorControl)
2053 {
2055 if (IsLastKnownGood == FALSE)
2056 {
2057 /* FIXME: Boot last known good configuration */
2058 }
2059 break;
2060
2062 if (IsLastKnownGood == FALSE)
2063 {
2064 /* FIXME: Boot last known good configuration */
2065 }
2066 else
2067 {
2068 /* FIXME: BSOD! */
2069 }
2070 break;
2071 }
2072#endif
2073 }
2074
2075 return dwError;
2076}
static DWORD ScmStartUserModeService(PSERVICE Service, DWORD argc, const PCWSTR *argv)
Definition: database.c:1817
DWORD ScmReferenceService(PSERVICE lpService)
Definition: database.c:930
static DWORD ScmCreateOrReferenceServiceImage(PSERVICE pService)
Definition: database.c:457
DWORD ScmStartDriver(PSERVICE pService)
Definition: driver.c:314
#define IDS_SERVICE_START
Definition: resource.h:3
VOID ScmLogEvent(DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings)
Definition: services.c:174
INT WINAPI DECLSPEC_HOTPATCH LoadStringW(HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen)
Definition: string.c:1220
_In_opt_ PSID Group
Definition: rtlfuncs.h:1670
#define EVENT_SERVICE_CONTROL_SUCCESS
Definition: netevent.h:432
#define EVENT_SERVICE_START_FAILED
Definition: netevent.h:444
#define GetModuleHandle
Definition: winbase.h:3868
#define ERROR_SERVICE_ALREADY_RUNNING
Definition: winerror.h:607
#define EVENTLOG_ERROR_TYPE
Definition: winnt_old.h:2876
#define EVENTLOG_INFORMATION_TYPE
Definition: winnt_old.h:2878
#define SERVICE_ERROR_SEVERE
Definition: cmtypes.h:983
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:984
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:981
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by ScmAutoStartServices(), and ScmStartService().

◆ ScmLockDatabaseExclusive()

◆ ScmLockDatabaseShared()

◆ ScmLogonService()

static DWORD ScmLogonService ( IN PSERVICE  pService,
IN PSERVICE_IMAGE  pImage 
)
static

Definition at line 358 of file database.c.

361{
362 PROFILEINFOW ProfileInfo;
363 PWSTR pszUserName = NULL;
364 PWSTR pszDomainName = NULL;
365 PWSTR pszPassword = NULL;
366 PWSTR ptr;
367 DWORD dwError = ERROR_SUCCESS;
368
369 DPRINT("ScmLogonService(%p %p)\n", pService, pImage);
370 DPRINT("Service %S\n", pService->lpServiceName);
371
372 if (ScmIsLocalSystemAccount(pImage->pszAccountName) || ScmLiveSetup || ScmSetupInProgress)
373 return ERROR_SUCCESS;
374
375 /* Get the user and domain names */
376 ptr = wcschr(pImage->pszAccountName, L'\\');
377 if (ptr != NULL)
378 {
379 *ptr = L'\0';
380 pszUserName = ptr + 1;
381 pszDomainName = pImage->pszAccountName;
382 }
383 else
384 {
385 // ERROR_INVALID_SERVICE_ACCOUNT
386 pszUserName = pImage->pszAccountName;
387 pszDomainName = NULL;
388 }
389
390 /* Build the service 'password' */
391 pszPassword = HeapAlloc(GetProcessHeap(),
393 (wcslen(pService->lpServiceName) + 5) * sizeof(WCHAR));
394 if (pszPassword == NULL)
395 {
396 dwError = ERROR_NOT_ENOUGH_MEMORY;
397 goto done;
398 }
399
400 wcscpy(pszPassword, L"_SC_");
401 wcscat(pszPassword, pService->lpServiceName);
402
403 DPRINT("Domain: %S User: %S Password: %S\n", pszDomainName, pszUserName, pszPassword);
404
405 /* Do the service logon */
406 if (!LogonUserW(pszUserName,
407 pszDomainName,
408 pszPassword,
411 &pImage->hToken))
412 {
413 dwError = GetLastError();
414 DPRINT1("LogonUserW() failed (Error %lu)\n", dwError);
415
416 /* Normalize the returned error */
418 goto done;
419 }
420
421 /* Load the user profile; the per-user environment variables are thus correctly initialized */
422 ZeroMemory(&ProfileInfo, sizeof(ProfileInfo));
423 ProfileInfo.dwSize = sizeof(ProfileInfo);
424 ProfileInfo.dwFlags = PI_NOUI;
425 ProfileInfo.lpUserName = pszUserName;
426 // ProfileInfo.lpProfilePath = NULL;
427 // ProfileInfo.lpDefaultPath = NULL;
428 // ProfileInfo.lpServerName = NULL;
429 // ProfileInfo.lpPolicyPath = NULL;
430 // ProfileInfo.hProfile = NULL;
431
432 ScmEnableBackupRestorePrivileges(pImage->hToken, TRUE);
433 if (!LoadUserProfileW(pImage->hToken, &ProfileInfo))
434 dwError = GetLastError();
436
437 if (dwError != ERROR_SUCCESS)
438 {
439 DPRINT1("LoadUserProfileW() failed (Error %lu)\n", dwError);
440 goto done;
441 }
442
443 pImage->hProfile = ProfileInfo.hProfile;
444
445done:
446 if (pszPassword != NULL)
447 HeapFree(GetProcessHeap(), 0, pszPassword);
448
449 if (ptr != NULL)
450 *ptr = L'\\';
451
452 return dwError;
453}
static BOOL ScmIsLocalSystemAccount(_In_ PCWSTR pszAccountName)
Definition: database.c:298
BOOL ScmLiveSetup
Definition: services.c:30
BOOL ScmSetupInProgress
Definition: services.c:31
wcscat
BOOL WINAPI LogonUserW(_In_ LPWSTR lpszUsername, _In_opt_ LPWSTR lpszDomain, _In_opt_ LPWSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _Out_opt_ PHANDLE phToken)
Definition: logon.c:1137
#define wcschr
Definition: compat.h:17
BOOL WINAPI LoadUserProfileW(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOW lpProfileInfo)
Definition: profile.c:2005
static PVOID ptr
Definition: dispmode.c:27
DWORD dwFlags
Definition: userenv.h:37
DWORD dwSize
Definition: userenv.h:36
HANDLE hProfile
Definition: userenv.h:43
LPWSTR lpUserName
Definition: userenv.h:38
#define PI_NOUI
Definition: userenv.h:8
#define ZeroMemory
Definition: winbase.h:1753
#define LOGON32_LOGON_SERVICE
Definition: winbase.h:427
#define LOGON32_PROVIDER_DEFAULT
Definition: winbase.h:420
#define ERROR_SERVICE_LOGON_FAILED
Definition: winerror.h:620

Referenced by ScmCreateOrReferenceServiceImage().

◆ ScmReferenceService()

DWORD ScmReferenceService ( PSERVICE  lpService)

Definition at line 930 of file database.c.

931{
932 return InterlockedIncrement(&lpService->RefCount);
933}
#define InterlockedIncrement
Definition: armddk.h:53

Referenced by RCreateServiceW(), ROpenServiceW(), RSetServiceStatus(), and ScmLoadService().

◆ ScmRemoveServiceImage()

VOID ScmRemoveServiceImage ( PSERVICE_IMAGE  pServiceImage)

Definition at line 621 of file database.c.

622{
623 DPRINT1("ScmRemoveServiceImage() called\n");
624
625 /* FIXME: Terminate the process */
626
627 /* Remove the service image from the list */
628 RemoveEntryList(&pServiceImage->ImageListEntry);
629
630 /* Close the process handle */
631 if (pServiceImage->hProcess != INVALID_HANDLE_VALUE)
632 CloseHandle(pServiceImage->hProcess);
633
634 /* Close the control pipe */
635 if (pServiceImage->hControlPipe != INVALID_HANDLE_VALUE)
636 CloseHandle(pServiceImage->hControlPipe);
637
638 /* Unload the user profile */
639 if (pServiceImage->hProfile != NULL)
640 {
642 UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile);
644 }
645
646 /* Close the logon token */
647 if (pServiceImage->hToken != NULL)
648 CloseHandle(pServiceImage->hToken);
649
650 /* Release the service image */
651 HeapFree(GetProcessHeap(), 0, pServiceImage);
652}

Referenced by ScmDeleteServiceRecord(), ScmLoadService(), and ScmStopThread().

◆ ScmSendControlPacket()

DWORD ScmSendControlPacket ( _In_ HANDLE  hControlPipe,
_In_ PCWSTR  pServiceName,
_In_ DWORD  dwControl,
_In_ DWORD  dwControlPacketSize,
_In_ PVOID  pControlPacket 
)

Definition at line 1416 of file database.c.

1422{
1423 DWORD dwError = ERROR_SUCCESS;
1424 BOOL bResult;
1425 SCM_REPLY_PACKET ReplyPacket;
1426 DWORD dwReadCount = 0;
1427 OVERLAPPED Overlapped = {0};
1428
1429 DPRINT("ScmSendControlPacket(%p, %lu, %p) called\n",
1430 hControlPipe, dwControlPacketSize, pControlPacket);
1431
1432 /* Acquire the service control critical section, to synchronize requests */
1434
1435 bResult = TransactNamedPipe(hControlPipe,
1436 pControlPacket,
1437 dwControlPacketSize,
1438 &ReplyPacket,
1439 sizeof(ReplyPacket),
1440 &dwReadCount,
1441 &Overlapped);
1442 if (!bResult)
1443 {
1444 /* Fail for any error other than pending IO */
1445 dwError = GetLastError();
1446 if (dwError != ERROR_IO_PENDING)
1447 {
1448 DPRINT1("TransactNamedPipe(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, dwError);
1449 goto Done;
1450 }
1451
1452 DPRINT("TransactNamedPipe(%S, %d) returned ERROR_IO_PENDING\n", pServiceName, dwControl);
1453
1454 dwError = WaitForSingleObject(hControlPipe, PipeTimeout);
1455 DPRINT("WaitForSingleObject(%S, %d) returned %lu\n", pServiceName, dwControl, dwError);
1456
1457 if (dwError == WAIT_TIMEOUT)
1458 {
1459 DPRINT1("WaitForSingleObject(%S, %d) timed out\n", pServiceName, dwControl);
1460 bResult = CancelIo(hControlPipe);
1461 if (!bResult)
1462 DPRINT1("CancelIo(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, GetLastError());
1463
1465 }
1466 else if (dwError == WAIT_OBJECT_0)
1467 {
1468 bResult = GetOverlappedResult(hControlPipe,
1469 &Overlapped,
1470 &dwReadCount,
1471 TRUE);
1472 if (!bResult)
1473 {
1474 dwError = GetLastError();
1475 DPRINT1("GetOverlappedResult(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, dwError);
1476 }
1477 }
1478 }
1479
1480Done:
1481 /* Release the service control critical section */
1483
1484 if (dwReadCount == sizeof(ReplyPacket))
1485 dwError = ReplyPacket.dwError;
1486
1487 return dwError;
1488}
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_IO_PENDING
Definition: dderror.h:15
BOOL WINAPI CancelIo(IN HANDLE hFile)
Definition: deviceio.c:290
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:221
BOOL WINAPI TransactNamedPipe(IN HANDLE hNamedPipe, IN LPVOID lpInBuffer, IN DWORD nInBufferSize, OUT LPVOID lpOutBuffer, IN DWORD nOutBufferSize, OUT LPDWORD lpBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: npipe.c:1315
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define WAIT_OBJECT_0
Definition: winbase.h:439
#define ERROR_SERVICE_REQUEST_TIMEOUT
Definition: winerror.h:604

Referenced by RI_ScSendPnPMessage(), ScmControlService(), and ScmControlServiceEx().

◆ ScmShutdownServiceDatabase()

VOID ScmShutdownServiceDatabase ( VOID  )

Definition at line 1273 of file database.c.

1274{
1275 DPRINT("ScmShutdownServiceDatabase() called\n");
1276
1279
1280 DPRINT("ScmShutdownServiceDatabase() done\n");
1281}
NTSYSAPI VOID NTAPI RtlDeleteResource(_In_ PRTL_RESOURCE Resource)

Referenced by ShutdownHandlerRoutine().

◆ ScmStartService()

DWORD ScmStartService ( PSERVICE  Service,
DWORD  argc,
const PCWSTR argv 
)

Definition at line 2080 of file database.c.

2083{
2084 DWORD dwError = ERROR_SUCCESS;
2086
2087 DPRINT("ScmStartService() called\n");
2088 DPRINT("Start Service %p (%S)\n", Service, Service->lpServiceName);
2089
2090 /* Acquire the service control critical section, to synchronize starts */
2092
2093 /*
2094 * Acquire the user service start lock while the service is starting, if
2095 * needed (i.e. if we are not starting it during the initialization phase).
2096 * If we don't success, bail out.
2097 */
2098 if (!ScmInitialize)
2099 {
2101 if (dwError != ERROR_SUCCESS)
2102 goto done;
2103 }
2104
2105 /* Really start the service */
2106 dwError = ScmLoadService(Service, argc, argv);
2107
2108 /* Release the service start lock, if needed, and the critical section */
2110
2111done:
2113
2114 DPRINT("ScmStartService() done (Error %lu)\n", dwError);
2115
2116 return dwError;
2117}
DWORD ScmAcquireServiceStartLock(IN BOOL IsServiceController, OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:31
DWORD ScmReleaseServiceStartLock(IN OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:82
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127

Referenced by RStartServiceA(), and RStartServiceW().

◆ ScmStartUserModeService()

static DWORD ScmStartUserModeService ( PSERVICE  Service,
DWORD  argc,
const PCWSTR argv 
)
static

Definition at line 1817 of file database.c.

1820{
1821 PROCESS_INFORMATION ProcessInformation;
1822 STARTUPINFOW StartupInfo;
1823 LPVOID lpEnvironment;
1824 BOOL Result;
1825 DWORD dwError = ERROR_SUCCESS;
1826
1827 DPRINT("ScmStartUserModeService(%p)\n", Service);
1828
1829 /* If the image is already running, just send a start command */
1830 if (Service->lpImage->dwImageRunCount > 1)
1831 goto Quit;
1832
1833 /* Otherwise start its process */
1834 ZeroMemory(&StartupInfo, sizeof(StartupInfo));
1835 StartupInfo.cb = sizeof(StartupInfo);
1836 ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
1837
1838 if (Service->lpImage->hToken)
1839 {
1840 /* User token: Run the service under the user account */
1841
1842 if (!CreateEnvironmentBlock(&lpEnvironment, Service->lpImage->hToken, FALSE))
1843 {
1844 /* We failed, run the service with the current environment */
1845 DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with current environment\n",
1846 GetLastError(), Service->lpServiceName);
1847 lpEnvironment = NULL;
1848 }
1849
1850 /* Impersonate the new user */
1851 Result = ImpersonateLoggedOnUser(Service->lpImage->hToken);
1852 if (Result)
1853 {
1854 /* Launch the process in the user's logon session */
1855 Result = CreateProcessAsUserW(Service->lpImage->hToken,
1856 NULL,
1857 Service->lpImage->pszImagePath,
1858 NULL,
1859 NULL,
1860 FALSE,
1862 lpEnvironment,
1863 NULL,
1864 &StartupInfo,
1865 &ProcessInformation);
1866 if (!Result)
1867 dwError = GetLastError();
1868
1869 /* Revert the impersonation */
1870 RevertToSelf();
1871 }
1872 else
1873 {
1874 dwError = GetLastError();
1875 DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", dwError);
1876 }
1877 }
1878 else
1879 {
1880 /* No user token: Run the service under the LocalSystem account */
1881
1882 if (!CreateEnvironmentBlock(&lpEnvironment, NULL, TRUE))
1883 {
1884 /* We failed, run the service with the current environment */
1885 DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with current environment\n",
1886 GetLastError(), Service->lpServiceName);
1887 lpEnvironment = NULL;
1888 }
1889
1890 /* Use the interactive desktop if the service is interactive */
1891 if ((NoInteractiveServices == 0) &&
1892 (Service->Status.dwServiceType & SERVICE_INTERACTIVE_PROCESS))
1893 {
1894 StartupInfo.dwFlags |= STARTF_INHERITDESKTOP;
1895 StartupInfo.lpDesktop = L"WinSta0\\Default";
1896 }
1897
1898 if (!ScmIsSecurityService(Service->lpImage))
1899 {
1901 Service->lpImage->pszImagePath,
1902 NULL,
1903 NULL,
1904 FALSE,
1906 lpEnvironment,
1907 NULL,
1908 &StartupInfo,
1909 &ProcessInformation);
1910 if (!Result)
1911 dwError = GetLastError();
1912 }
1913 else
1914 {
1915 Result = TRUE;
1916 dwError = ERROR_SUCCESS;
1917 }
1918 }
1919
1920 if (lpEnvironment)
1921 DestroyEnvironmentBlock(lpEnvironment);
1922
1923 if (!Result)
1924 {
1925 DPRINT1("Starting '%S' failed with error %d\n",
1926 Service->lpServiceName, dwError);
1927 return dwError;
1928 }
1929
1930 DPRINT("Process Id: %lu Handle %p\n",
1931 ProcessInformation.dwProcessId,
1932 ProcessInformation.hProcess);
1933 DPRINT("Thread Id: %lu Handle %p\n",
1934 ProcessInformation.dwThreadId,
1935 ProcessInformation.hThread);
1936
1937 /* Get the process handle and ID */
1938 Service->lpImage->hProcess = ProcessInformation.hProcess;
1939 Service->lpImage->dwProcessId = ProcessInformation.dwProcessId;
1940
1941 /* Resume the main thread and close its handle */
1942 ResumeThread(ProcessInformation.hThread);
1943 CloseHandle(ProcessInformation.hThread);
1944
1945 /* Connect control pipe */
1947 if (dwError != ERROR_SUCCESS)
1948 {
1949 DPRINT1("Connecting control pipe failed! (Error %lu)\n", dwError);
1950 Service->lpImage->dwProcessId = 0;
1951 return dwError;
1952 }
1953
1954Quit:
1955 /* Send the start command and return */
1956 return ScmControlServiceEx(Service->lpImage->hControlPipe,
1957 Service->lpServiceName,
1958 (Service->Status.dwServiceType & SERVICE_WIN32_OWN_PROCESS)
1961 Service->dwServiceTag,
1962 argc, argv);
1963}
DWORD ScmControlServiceEx(_In_ HANDLE hControlPipe, _In_ PCWSTR pServiceName, _In_ DWORD dwControl, _In_ SERVICE_STATUS_HANDLE hServiceStatus, _In_opt_ DWORD dwServiceTag, _In_opt_ DWORD argc, _In_reads_opt_(argc) const PCWSTR *argv)
Definition: database.c:1492
static DWORD ScmWaitForServiceConnect(PSERVICE Service)
Definition: database.c:1640
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW(_In_opt_ HANDLE hToken, _In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation)
Definition: logon.c:993
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
Definition: misc.c:152
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4598
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
BOOL WINAPI RevertToSelf(void)
Definition: security.c:855
BOOL WINAPI DestroyEnvironmentBlock(IN LPVOID lpEnvironment)
Definition: environment.c:725
BOOL WINAPI CreateEnvironmentBlock(OUT LPVOID *lpEnvironment, IN HANDLE hToken, IN BOOL bInherit)
Definition: environment.c:503
#define SERVICE_CONTROL_START_OWN
Definition: services.h:20
#define SERVICE_CONTROL_START_SHARE
Definition: services.h:18
LPWSTR lpDesktop
Definition: winbase.h:889
DWORD cb
Definition: winbase.h:887
DWORD dwFlags
Definition: winbase.h:898
#define STARTF_INHERITDESKTOP
Definition: undocuser.h:166
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:196
#define CREATE_SUSPENDED
Definition: winbase.h:188
#define DETACHED_PROCESS
Definition: winbase.h:189
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by ScmLoadService().

◆ ScmUnlockDatabase()

◆ ScmWaitForServiceConnect()

static DWORD ScmWaitForServiceConnect ( PSERVICE  Service)
static

Definition at line 1640 of file database.c.

1641{
1642 DWORD dwRead = 0;
1643 DWORD dwProcessId = 0;
1644 DWORD dwError = ERROR_SUCCESS;
1645 BOOL bResult;
1646 OVERLAPPED Overlapped = {0};
1647#if 0
1648 LPCWSTR lpLogStrings[3];
1649 WCHAR szBuffer1[20];
1650 WCHAR szBuffer2[20];
1651#endif
1652
1653 DPRINT("ScmWaitForServiceConnect()\n");
1654
1655 bResult = ConnectNamedPipe(Service->lpImage->hControlPipe,
1656 &Overlapped);
1657 if (bResult == FALSE)
1658 {
1659 DPRINT("ConnectNamedPipe() returned FALSE\n");
1660
1661 dwError = GetLastError();
1662 if (dwError == ERROR_IO_PENDING)
1663 {
1664 DPRINT("dwError: ERROR_IO_PENDING\n");
1665
1666 dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1667 PipeTimeout);
1668 DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1669
1670 if (dwError == WAIT_TIMEOUT)
1671 {
1672 DPRINT("WaitForSingleObject() returned WAIT_TIMEOUT\n");
1673
1674 bResult = CancelIo(Service->lpImage->hControlPipe);
1675 if (bResult == FALSE)
1676 {
1677 DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1678 }
1679
1680#if 0
1681 _ultow(PipeTimeout, szBuffer1, 10);
1682 lpLogStrings[0] = Service->lpDisplayName;
1683 lpLogStrings[1] = szBuffer1;
1684
1687 2,
1688 lpLogStrings);
1689#endif
1690 DPRINT1("Log EVENT_CONNECTION_TIMEOUT by %S\n", Service->lpDisplayName);
1691
1693 }
1694 else if (dwError == WAIT_OBJECT_0)
1695 {
1696 bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1697 &Overlapped,
1698 &dwRead,
1699 TRUE);
1700 if (bResult == FALSE)
1701 {
1702 dwError = GetLastError();
1703 DPRINT1("GetOverlappedResult failed (Error %lu)\n", dwError);
1704
1705 return dwError;
1706 }
1707 }
1708 }
1709 else if (dwError != ERROR_PIPE_CONNECTED)
1710 {
1711 DPRINT1("ConnectNamedPipe failed (Error %lu)\n", dwError);
1712 return dwError;
1713 }
1714 }
1715
1716 DPRINT("Control pipe connected\n");
1717
1718 Overlapped.hEvent = NULL;
1719
1720 /* Read the process id from pipe */
1721 bResult = ReadFile(Service->lpImage->hControlPipe,
1722 (LPVOID)&dwProcessId,
1723 sizeof(DWORD),
1724 &dwRead,
1725 &Overlapped);
1726 if (bResult == FALSE)
1727 {
1728 DPRINT("ReadFile() returned FALSE\n");
1729
1730 dwError = GetLastError();
1731 if (dwError == ERROR_IO_PENDING)
1732 {
1733 DPRINT("dwError: ERROR_IO_PENDING\n");
1734
1735 dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1736 PipeTimeout);
1737 if (dwError == WAIT_TIMEOUT)
1738 {
1739 DPRINT("WaitForSingleObject() returned WAIT_TIMEOUT\n");
1740
1741 bResult = CancelIo(Service->lpImage->hControlPipe);
1742 if (bResult == FALSE)
1743 {
1744 DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1745 }
1746
1747#if 0
1748 _ultow(PipeTimeout, szBuffer1, 10);
1749 lpLogStrings[0] = szBuffer1;
1750
1753 1,
1754 lpLogStrings);
1755#endif
1756 DPRINT1("Log EVENT_READFILE_TIMEOUT by %S\n", Service->lpDisplayName);
1757
1759 }
1760 else if (dwError == WAIT_OBJECT_0)
1761 {
1762 DPRINT("WaitForSingleObject() returned WAIT_OBJECT_0\n");
1763
1764 DPRINT("Process Id: %lu\n", dwProcessId);
1765
1766 bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1767 &Overlapped,
1768 &dwRead,
1769 TRUE);
1770 if (bResult == FALSE)
1771 {
1772 dwError = GetLastError();
1773 DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1774
1775 return dwError;
1776 }
1777 }
1778 else
1779 {
1780 DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
1781 }
1782 }
1783 else
1784 {
1785 DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
1786 return dwError;
1787 }
1788 }
1789
1790 if ((ScmIsSecurityService(Service->lpImage) == FALSE)&&
1791 (dwProcessId != Service->lpImage->dwProcessId))
1792 {
1793#if 0
1794 _ultow(Service->lpImage->dwProcessId, szBuffer1, 10);
1795 _ultow(dwProcessId, szBuffer2, 10);
1796
1797 lpLogStrings[0] = Service->lpDisplayName;
1798 lpLogStrings[1] = szBuffer1;
1799 lpLogStrings[2] = szBuffer2;
1800
1803 3,
1804 lpLogStrings);
1805#endif
1806
1807 DPRINT1("Log EVENT_SERVICE_DIFFERENT_PID_CONNECTED by %S\n", Service->lpDisplayName);
1808 }
1809
1810 DPRINT("ScmWaitForServiceConnect() done\n");
1811
1812 return ERROR_SUCCESS;
1813}
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
_CRTIMP wchar_t *__cdecl _ultow(_In_ unsigned long _Value, _Pre_notnull_ _Post_z_ wchar_t *_Dest, _In_ int _Radix)
#define EVENT_SERVICE_DIFFERENT_PID_CONNECTED
Definition: netevent.h:435
#define EVENT_CONNECTION_TIMEOUT
Definition: netevent.h:143
#define EVENT_READFILE_TIMEOUT
Definition: netevent.h:413
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
HANDLE hEvent
Definition: winbase.h:855
#define ERROR_PIPE_CONNECTED
Definition: winerror.h:352
#define EVENTLOG_WARNING_TYPE
Definition: winnt_old.h:2877

Referenced by ScmStartUserModeService().

Variable Documentation

◆ ControlServiceCriticalSection

◆ DatabaseLock

◆ ImageListHead

◆ NoInteractiveServices

DWORD NoInteractiveServices = 0
static

Definition at line 32 of file database.c.

Referenced by ScmGetNoInteractiveServicesValue(), and ScmStartUserModeService().

◆ PipeTimeout

DWORD PipeTimeout = 30000
static

◆ ResumeCount

DWORD ResumeCount = 1
static

Definition at line 31 of file database.c.

Referenced by CreateProcessInternalW(), and ScmCreateNewServiceRecord().

◆ ServiceListHead

◆ ServiceTag

DWORD ServiceTag = 0
static

Definition at line 33 of file database.c.

Referenced by GetOwnerModuleFromTagEntry(), ScmGenerateServiceTag(), and service_main().