ReactOS 0.4.16-dev-1223-gddcd5f7
services.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include <windef.h>
#include <winbase.h>
#include <winsvc.h>
#include <winreg.h>
#include <winuser.h>
#include <netevent.h>
#include <ndk/setypes.h>
#include <ndk/obfuncs.h>
#include <ndk/rtlfuncs.h>
#include <services/services.h>
#include <svcctl_s.h>
#include "resource.h"
Include dependency graph for services.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _SERVICE_GROUP
 
struct  _SERVICE_IMAGE
 
struct  _SERVICE
 
struct  _START_LOCK
 

Macros

#define WIN32_NO_STATUS
 
#define _INC_WINDOWS
 
#define COM_NO_WINDOWS_H
 
#define NTOS_MODE_USER
 
#define LOCK_TAG   0x4C697041 /* 'ApiL' */
 

Typedefs

typedef struct _SERVICE_GROUP SERVICE_GROUP
 
typedef struct _SERVICE_GROUPPSERVICE_GROUP
 
typedef struct _SERVICE_IMAGE SERVICE_IMAGE
 
typedef struct _SERVICE_IMAGEPSERVICE_IMAGE
 
typedef struct _SERVICE SERVICE
 
typedef struct _SERVICEPSERVICE
 
typedef struct _START_LOCK START_LOCK
 
typedef struct _START_LOCKPSTART_LOCK
 

Functions

DWORD ScmOpenServiceKey (LPWSTR lpServiceName, REGSAM samDesired, PHKEY phKey)
 
DWORD ScmCreateServiceKey (LPCWSTR lpServiceName, REGSAM samDesired, PHKEY phKey)
 
DWORD ScmWriteDependencies (HKEY hServiceKey, LPCWSTR lpDependencies, DWORD dwDependenciesLength)
 
DWORD ScmMarkServiceForDelete (PSERVICE pService)
 
BOOL ScmIsDeleteFlagSet (HKEY hServiceKey)
 
DWORD ScmReadString (HKEY hServiceKey, LPCWSTR lpValueName, LPWSTR *lpValue)
 
DWORD ScmReadDependencies (HKEY hServiceKey, LPWSTR *lpDependencies, DWORD *lpdwDependenciesLength)
 
DWORD ScmSetServicePassword (_In_ PCWSTR pszServiceName, _In_ PCWSTR pszPassword)
 
DWORD ScmWriteSecurityDescriptor (_In_ HKEY hServiceKey, _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor)
 
DWORD ScmReadSecurityDescriptor (_In_ HKEY hServiceKey, _Out_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
 
DWORD ScmDeleteRegKey (_In_ HKEY hKey, _In_ PCWSTR pszSubKey)
 
DWORD ScmDecryptPassword (_In_ PVOID ContextHandle, _In_ PBYTE pPassword, _In_ DWORD dwPasswordSize, _Out_ PWSTR *pDecryptedPassword)
 
DWORD ScmCreateLastKnownGoodControlSet (VOID)
 
DWORD ScmAcceptBoot (VOID)
 
DWORD ScmRunLastKnownGood (VOID)
 
DWORD ScmCreateServiceDatabase (VOID)
 
VOID ScmShutdownServiceDatabase (VOID)
 
VOID ScmGetBootAndSystemDriverState (VOID)
 
VOID ScmAutoStartServices (VOID)
 
VOID ScmAutoShutdownServices (VOID)
 
DWORD ScmStartService (PSERVICE Service, DWORD argc, const PCWSTR *argv)
 
DWORD ScmReferenceService (PSERVICE lpService)
 
DWORD ScmDereferenceService (PSERVICE lpService)
 
VOID ScmRemoveServiceImage (PSERVICE_IMAGE pServiceImage)
 
PSERVICE ScmGetServiceEntryByName (LPCWSTR lpServiceName)
 
PSERVICE ScmGetServiceEntryByDisplayName (LPCWSTR lpDisplayName)
 
PSERVICE ScmGetServiceEntryByResumeCount (DWORD dwResumeCount)
 
DWORD ScmCreateNewServiceRecord (LPCWSTR lpServiceName, PSERVICE *lpServiceRecord, DWORD dwServiceType, DWORD dwStartType)
 
VOID ScmDeleteServiceRecord (PSERVICE lpService)
 
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)
 
BOOL ScmLockDatabaseExclusive (VOID)
 
BOOL ScmLockDatabaseShared (VOID)
 
VOID ScmUnlockDatabase (VOID)
 
VOID ScmInitNamedPipeCriticalSection (VOID)
 
VOID ScmDeleteNamedPipeCriticalSection (VOID)
 
DWORD ScmGetServiceNameFromTag (PTAG_INFO_NAME_FROM_TAG_IN_PARAMS InParams, PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS *OutParams)
 
DWORD ScmGenerateServiceTag (PSERVICE lpServiceRecord)
 
DWORD ScmStartDriver (PSERVICE lpService)
 
DWORD ScmControlDriver (PSERVICE lpService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
 
PSERVICE_GROUP ScmGetServiceGroupByName (_In_ LPCWSTR lpGroupName)
 
DWORD ScmCreateGroupList (VOID)
 
DWORD ScmSetServiceGroup (PSERVICE lpService, LPCWSTR lpGroupName)
 
DWORD ScmAcquireServiceStartLock (IN BOOL IsServiceController, OUT LPSC_RPC_LOCK lpLock)
 
DWORD ScmReleaseServiceStartLock (IN OUT LPSC_RPC_LOCK lpLock)
 
VOID ScmQueryServiceLockStatusW (OUT LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus)
 
VOID ScmQueryServiceLockStatusA (OUT LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus)
 
VOID ScmStartRpcServer (VOID)
 
DWORD ScmInitializeSecurity (VOID)
 
VOID ScmShutdownSecurity (VOID)
 
DWORD ScmCreateDefaultServiceSD (PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
 
VOID PrintString (LPCSTR fmt,...)
 
DWORD SetSecurityServicesEvent (VOID)
 
VOID ScmLogEvent (DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings)
 
VOID ScmWaitForLsa (VOID)
 

Variables

LIST_ENTRY ServiceListHead
 
LIST_ENTRY GroupListHead
 
LIST_ENTRY ImageListHead
 
BOOL ScmInitialize
 
BOOL ScmShutdown
 
BOOL ScmLiveSetup
 
BOOL ScmSetupInProgress
 
PSECURITY_DESCRIPTOR pPipeSD
 

Macro Definition Documentation

◆ _INC_WINDOWS

#define _INC_WINDOWS

Definition at line 12 of file services.h.

◆ COM_NO_WINDOWS_H

#define COM_NO_WINDOWS_H

Definition at line 13 of file services.h.

◆ LOCK_TAG

#define LOCK_TAG   0x4C697041 /* 'ApiL' */

Definition at line 90 of file services.h.

◆ NTOS_MODE_USER

#define NTOS_MODE_USER

Definition at line 22 of file services.h.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 11 of file services.h.

Typedef Documentation

◆ PSERVICE

◆ PSERVICE_GROUP

◆ PSERVICE_IMAGE

◆ PSTART_LOCK

◆ SERVICE

◆ SERVICE_GROUP

◆ SERVICE_IMAGE

◆ START_LOCK

Function Documentation

◆ PrintString()

VOID PrintString ( LPCSTR  fmt,
  ... 
)

Definition at line 39 of file services.c.

40{
41#if DBG
42 CHAR buffer[512];
43 va_list ap;
44
45 va_start(ap, fmt);
47 va_end(ap);
48
50#endif
51}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
GLuint buffer
Definition: glext.h:5915
void WINAPI SHIM_OBJ_NAME() OutputDebugStringA(LPCSTR lpOutputString)
Definition: ignoredbgout.c:18
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
Definition: dsound.c:943
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
char CHAR
Definition: xmlstorage.h:175

◆ ScmAcceptBoot()

DWORD ScmAcceptBoot ( VOID  )

Definition at line 336 of file controlset.c.

337{
338 DWORD dwCurrentControlSet, dwDefaultControlSet;
339 DWORD dwFailedControlSet, dwLastKnownGoodControlSet;
340 DWORD dwNewControlSet;
341 DWORD dwError;
342
343 DPRINT("ScmAcceptBoot()\n");
344
345 if (bBootAccepted)
346 {
347 DPRINT1("Boot has already been accepted\n");
349 }
350
351 /* Get the control set values */
352 dwError = ScmGetControlSetValues(&dwCurrentControlSet,
353 &dwDefaultControlSet,
354 &dwFailedControlSet,
355 &dwLastKnownGoodControlSet);
356 if (dwError != ERROR_SUCCESS)
357 return dwError;
358
359 /* Search for a new control set number */
360 for (dwNewControlSet = 1; dwNewControlSet < 1000; dwNewControlSet++)
361 {
362 if ((dwNewControlSet != dwCurrentControlSet) &&
363 (dwNewControlSet != dwDefaultControlSet) &&
364 (dwNewControlSet != dwFailedControlSet) &&
365 (dwNewControlSet != dwLastKnownGoodControlSet))
366 break;
367 }
368
369 /* Fail if we did not find an unused control set!*/
370 if (dwNewControlSet >= 1000)
371 {
372 DPRINT1("Too many control sets\n");
373 return ERROR_NO_MORE_ITEMS;
374 }
375
376 /* Copy the current control set */
377 dwError = ScmCopyControlSet(dwCurrentControlSet,
378 dwNewControlSet);
379 if (dwError != ERROR_SUCCESS)
380 return dwError;
381
382 /* Delete the current last known good contol set, if it is not used anywhere else */
383 if ((dwLastKnownGoodControlSet != dwCurrentControlSet) &&
384 (dwLastKnownGoodControlSet != dwDefaultControlSet) &&
385 (dwLastKnownGoodControlSet != dwFailedControlSet))
386 {
387 ScmDeleteControlSet(dwLastKnownGoodControlSet);
388 }
389
390 /* Set the new 'LastKnownGood' control set */
391 dwError = ScmSetLastKnownGoodControlSet(dwNewControlSet);
392 if (dwError != ERROR_SUCCESS)
393 return dwError;
394
396
397 return ERROR_SUCCESS;
398}
#define DPRINT1
Definition: precomp.h:8
static DWORD ScmSetLastKnownGoodControlSet(DWORD dwControlSet)
Definition: controlset.c:112
static DWORD ScmDeleteControlSet(DWORD dwControlSet)
Definition: controlset.c:241
static DWORD ScmGetControlSetValues(PDWORD pdwCurrentControlSet, PDWORD pdwDefaultControlSet, PDWORD pdwFailedControlSet, PDWORD pdwLastKnownGoodControlSet)
Definition: controlset.c:29
static DWORD ScmCopyControlSet(DWORD dwSourceControlSet, DWORD dwDestinationControlSet)
Definition: controlset.c:178
static BOOL bBootAccepted
Definition: controlset.c:22
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DPRINT
Definition: sndvol32.h:73
#define ERROR_BOOT_ALREADY_ACCEPTED
Definition: winerror.h:627

Referenced by RNotifyBootConfigStatus().

◆ ScmAcquireServiceStartLock()

DWORD ScmAcquireServiceStartLock ( IN BOOL  IsServiceController,
OUT LPSC_RPC_LOCK  lpLock 
)

Definition at line 31 of file lock.c.

33{
34 DWORD dwRequiredSize;
35 DWORD dwError = ERROR_SUCCESS;
36
37 *lpLock = NULL;
38
39 /* Lock the service database exclusively */
41
43 {
45 goto done;
46 }
47
48 /* Allocate a new lock for the database */
49 dwRequiredSize = sizeof(START_LOCK);
50
51 if (!IsServiceController)
52 {
53 /* FIXME: dwRequiredSize += RtlLengthSid(UserSid <-- to be retrieved); */
54 }
55
58 dwRequiredSize);
60 {
62 goto done;
63 }
64
67
68 /* FIXME: Retrieve the owner SID. Use IsServiceController. */
70
72
73done:
74 /* Unlock the service database */
76
77 return dwError;
78}
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2384
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2370
static PSTART_LOCK pServiceStartLock
Definition: lock.c:21
#define LOCK_TAG
Definition: services.h:90
struct _START_LOCK START_LOCK
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
__u16 time
Definition: mkdosfs.c:8
struct _SID * PSID
Definition: eventlog.c:35
#define DWORD
Definition: nt_native.h:44
DWORD TimeWhenLocked
Definition: services.h:95
DWORD Tag
Definition: services.h:94
PSID LockOwnerSid
Definition: services.h:96
SC_RPC_LOCK * LPSC_RPC_LOCK
Definition: svcctl.idl:24
#define ERROR_SERVICE_DATABASE_LOCKED
Definition: winerror.h:606

Referenced by RLockServiceDatabase(), ScmStartService(), and wWinMain().

◆ 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
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
DWORD dwCurrentState
Definition: winsvc.h:100
SERVICE_STATUS Status
Definition: services.h:72
PSERVICE_IMAGE lpImage
Definition: services.h:67
LPWSTR lpServiceName
Definition: services.h:64
#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}
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 RegCloseKey(hKey)
Definition: registry.h:49
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define MAX_PATH
Definition: compat.h:34
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
#define ASSERT(a)
Definition: mode.c:44
#define KEY_READ
Definition: nt_native.h:1023
#define L(x)
Definition: ntvdm.h:50
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
LPWSTR lpGroupName
Definition: services.h:35
PSERVICE_GROUP lpGroup
Definition: services.h:66
BOOLEAN ServiceVisited
Definition: services.h:84
DWORD dwStartType
Definition: services.h:73
DWORD dwTag
Definition: services.h:75
unsigned char * LPBYTE
Definition: typedefs.h:53
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
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by wWinMain().

◆ ScmControlDriver()

DWORD ScmControlDriver ( PSERVICE  lpService,
DWORD  dwControl,
LPSERVICE_STATUS  lpServiceStatus 
)

Definition at line 335 of file driver.c.

338{
339 DWORD dwError;
340
341 DPRINT("ScmControlDriver() called\n");
342
343 switch (dwControl)
344 {
346 /* Check the drivers status */
347 dwError = ScmGetDriverStatus(lpService,
348 lpServiceStatus);
349 if (dwError != ERROR_SUCCESS)
350 goto done;
351
352 /* Fail, if it is not running */
353 if (lpService->Status.dwCurrentState != SERVICE_RUNNING)
354 {
356 goto done;
357 }
358
359 /* Unload the driver */
360 dwError = ScmUnloadDriver(lpService);
361 if (dwError == ERROR_INVALID_SERVICE_CONTROL)
362 {
363 /* The driver cannot be stopped, mark it non-stoppable */
364 lpService->Status.dwControlsAccepted = 0;
365 goto done;
366 }
367
368 /* Make the driver 'stop pending' */
370
371 /* Check the drivers status again */
372 dwError = ScmGetDriverStatus(lpService,
373 lpServiceStatus);
374 break;
375
377 dwError = ScmGetDriverStatus(lpService,
378 lpServiceStatus);
379 break;
380
381 default:
383 }
384
385done:
386 DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError);
387
388 return dwError;
389}
static DWORD ScmGetDriverStatus(PSERVICE lpService, LPSERVICE_STATUS lpServiceStatus)
Definition: driver.c:136
static DWORD ScmUnloadDriver(PSERVICE lpService)
Definition: driver.c:77
#define ERROR_INVALID_SERVICE_CONTROL
Definition: winerror.h:603
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39

Referenced by RControlService().

◆ 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 HeapFree(x, y, z)
Definition: compat.h:735
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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().

◆ ScmCreateDefaultServiceSD()

DWORD ScmCreateDefaultServiceSD ( PSECURITY_DESCRIPTOR ppSecurityDescriptor)

Definition at line 320 of file security.c.

322{
323 PSECURITY_DESCRIPTOR pRelativeSD = NULL;
324 DWORD dwBufferLength = 0;
326 DWORD dwError = ERROR_SUCCESS;
327
328 /* Convert the absolute SD to a self-relative SD */
330 NULL,
331 &dwBufferLength);
333 {
334 dwError = RtlNtStatusToDosError(Status);
335 goto done;
336 }
337
338 DPRINT("BufferLength %lu\n", dwBufferLength);
339
340 pRelativeSD = RtlAllocateHeap(RtlGetProcessHeap(),
342 dwBufferLength);
343 if (pRelativeSD == NULL)
344 {
345 dwError = ERROR_OUTOFMEMORY;
346 goto done;
347 }
348 DPRINT("pRelativeSD %p\n", pRelativeSD);
349
351 pRelativeSD,
352 &dwBufferLength);
353 if (!NT_SUCCESS(Status))
354 {
355 dwError = RtlNtStatusToDosError(Status);
356 goto done;
357 }
358
359 *ppSecurityDescriptor = pRelativeSD;
360
361done:
362 if (dwError != ERROR_SUCCESS)
363 {
364 if (pRelativeSD != NULL)
365 RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD);
366 }
367
368 return dwError;
369}
LONG NTSTATUS
Definition: precomp.h:26
static PSECURITY_DESCRIPTOR pDefaultSD
Definition: security.c:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
NTSYSAPI NTSTATUS NTAPI RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN PULONG BufferLength)
Definition: sd.c:626
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69

Referenced by CreateServiceListEntry(), and RCreateServiceW().

◆ ScmCreateGroupList()

DWORD ScmCreateGroupList ( VOID  )

Definition at line 235 of file groupdb.c.

236{
239
242
243 /* Build group order list */
245 sizeof(QueryTable));
246
247 QueryTable[0].Name = L"List";
249
251 L"ServiceGroupOrder",
253 NULL,
254 NULL);
255
257}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LIST_ENTRY UnknownGroupListHead
Definition: groupdb.c:20
static NTSTATUS WINAPI CreateGroupListRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: groupdb.c:188
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4203
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by ScmCreateServiceDatabase().

◆ ScmCreateLastKnownGoodControlSet()

DWORD ScmCreateLastKnownGoodControlSet ( VOID  )

Definition at line 275 of file controlset.c.

276{
277 DWORD dwCurrentControlSet, dwDefaultControlSet;
278 DWORD dwFailedControlSet, dwLastKnownGoodControlSet;
279 DWORD dwNewControlSet;
280 DWORD dwError;
281
282 /* Get the control set values */
283 dwError = ScmGetControlSetValues(&dwCurrentControlSet,
284 &dwDefaultControlSet,
285 &dwFailedControlSet,
286 &dwLastKnownGoodControlSet);
287 if (dwError != ERROR_SUCCESS)
288 return dwError;
289
290 /* First boot after setup? */
291 if ((ScmGetSetupInProgress() == 0) &&
292 (dwCurrentControlSet == dwLastKnownGoodControlSet))
293 {
294 DPRINT("First boot after setup\n");
295
296 /* Search for a new control set number */
297 for (dwNewControlSet = 1; dwNewControlSet < 1000; dwNewControlSet++)
298 {
299 if ((dwNewControlSet != dwCurrentControlSet) &&
300 (dwNewControlSet != dwDefaultControlSet) &&
301 (dwNewControlSet != dwFailedControlSet) &&
302 (dwNewControlSet != dwLastKnownGoodControlSet))
303 break;
304 }
305
306 /* Fail if we did not find an unused control set!*/
307 if (dwNewControlSet >= 1000)
308 {
309 DPRINT1("Too many control sets\n");
310 return ERROR_NO_MORE_ITEMS;
311 }
312
313 /* Copy the current control set */
314 dwError = ScmCopyControlSet(dwCurrentControlSet,
315 dwNewControlSet);
316 if (dwError != ERROR_SUCCESS)
317 return dwError;
318
319 /* Set the new 'LastKnownGood' control set */
320 dwError = ScmSetLastKnownGoodControlSet(dwNewControlSet);
321 if (dwError == ERROR_SUCCESS)
322 {
323 /*
324 * Accept the boot here in order to prevent the creation of
325 * another control set when a user is going to get logged on
326 */
328 }
329 }
330
331 return dwError;
332}
static DWORD ScmGetSetupInProgress(VOID)
Definition: controlset.c:142

Referenced by wWinMain().

◆ 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 dwServiceType
Definition: winsvc.h:99
DWORD dwWin32ExitCode
Definition: winsvc.h:102
DWORD dwWaitHint
Definition: winsvc.h:105
DWORD dwCheckPoint
Definition: winsvc.h:104
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
LPWSTR lpDisplayName
Definition: services.h:65
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_STOPPED
Definition: winsvc.h:21
#define SERVICE_DISABLED
Definition: cmtypes.h:979
#define SERVICE_DRIVER
Definition: cmtypes.h:958

Referenced by CreateServiceListEntry(), and RCreateServiceW().

◆ 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 HANDLE hServicesKey
Definition: devinst.c:21
static DWORD CreateServiceListEntry(LPCWSTR lpServiceName, HKEY hServiceKey)
Definition: database.c:955
LIST_ENTRY ImageListHead
Definition: database.c:27
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
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
DWORD ScmCreateGroupList(VOID)
Definition: groupdb.c:235
NTSYSAPI VOID NTAPI RtlInitializeResource(_In_ PRTL_RESOURCE Resource)

Referenced by wWinMain().

◆ ScmCreateServiceKey()

DWORD ScmCreateServiceKey ( LPCWSTR  lpServiceName,
REGSAM  samDesired,
PHKEY  phKey 
)

Definition at line 72 of file config.c.

75{
77 DWORD dwDisposition;
78 DWORD dwError;
79
80 *phKey = NULL;
81
83 L"System\\CurrentControlSet\\Services",
84 0,
87 if (dwError != ERROR_SUCCESS)
88 return dwError;
89
91 lpServiceName,
92 0,
93 NULL,
95 samDesired,
96 NULL,
97 phKey,
98 &dwDisposition);
99#if 0
100 if ((dwError == ERROR_SUCCESS) &&
101 (dwDisposition == REG_OPENED_EXISTING_KEY))
102 {
103 RegCloseKey(*phKey);
104 *phKey = NULL;
105 dwError = ERROR_SERVICE_EXISTS;
106 }
107#endif
108
110
111 return dwError;
112}
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
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define ERROR_SERVICE_EXISTS
Definition: winerror.h:624

Referenced by RCreateServiceW().

◆ ScmDecryptPassword()

DWORD ScmDecryptPassword ( _In_ PVOID  ContextHandle,
_In_ PBYTE  pPassword,
_In_ DWORD  dwPasswordSize,
_Out_ PWSTR pDecryptedPassword 
)

Definition at line 708 of file config.c.

713{
714 struct ustring inData, keyData, outData;
715 BYTE SessionKey[16];
718
719 /* Get the session key */
720 Status = SystemFunction028(ContextHandle,
721 SessionKey);
722 if (!NT_SUCCESS(Status))
723 {
724 DPRINT1("SystemFunction028 failed (Status 0x%08lx)\n", Status);
726 }
727
728 inData.Length = dwPasswordSize;
729 inData.MaximumLength = inData.Length;
730 inData.Buffer = pPassword;
731
732 keyData.Length = sizeof(SessionKey);
733 keyData.MaximumLength = keyData.Length;
734 keyData.Buffer = SessionKey;
735
736 outData.Length = 0;
737 outData.MaximumLength = 0;
738 outData.Buffer = NULL;
739
740 /* Get the required buffer size */
741 Status = SystemFunction005(&inData,
742 &keyData,
743 &outData);
745 {
746 DPRINT1("SystemFunction005 failed (Status 0x%08lx)\n", Status);
748 }
749
750 /* Allocate a buffer for the clear text password */
751 pBuffer = HeapAlloc(GetProcessHeap(), 0, outData.Length);
752 if (pBuffer == NULL)
753 return ERROR_OUTOFMEMORY;
754
755 outData.MaximumLength = outData.Length;
756 outData.Buffer = (unsigned char *)pBuffer;
757
758 /* Decrypt the password */
759 Status = SystemFunction005(&inData,
760 &keyData,
761 &outData);
762 if (!NT_SUCCESS(Status))
763 {
764 DPRINT1("SystemFunction005 failed (Status 0x%08lx)\n", Status);
767 }
768
769 *pClearTextPassword = pBuffer;
770
771 return ERROR_SUCCESS;
772}
NTSTATUS WINAPI SystemFunction028(IN PVOID ContextHandle, OUT LPBYTE SessionKey)
NTSTATUS WINAPI SystemFunction005(const struct ustring *in, const struct ustring *key, struct ustring *out)
Definition: sysfunc.c:182
PVOID pBuffer
Definition: config.c:19
unsigned char BYTE
Definition: xxhash.c:193

Referenced by RChangeServiceConfigW(), and RCreateServiceW().

◆ ScmDeleteNamedPipeCriticalSection()

VOID ScmDeleteNamedPipeCriticalSection ( VOID  )

Definition at line 2419 of file database.c.

2420{
2422}
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

Referenced by wWinMain().

◆ ScmDeleteRegKey()

DWORD ScmDeleteRegKey ( _In_ HKEY  hKey,
_In_ PCWSTR  pszSubKey 
)

Definition at line 646 of file config.c.

649{
650 DWORD dwMaxSubkeyLen, dwMaxValueLen;
651 DWORD dwMaxLen, dwSize;
652 PWSTR pszName = NULL;
653 HKEY hSubKey;
654 DWORD dwError;
655
656 dwError = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_READ, &hSubKey);
657 if (dwError != ERROR_SUCCESS)
658 return dwError;
659
660 /* Get maximum length of key and value names */
661 dwError = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
662 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
663 if (dwError != ERROR_SUCCESS)
664 goto done;
665
666 dwMaxSubkeyLen++;
667 dwMaxValueLen++;
668 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
669
670 /* Allocate the name buffer */
671 pszName = HeapAlloc(GetProcessHeap(), 0, dwMaxLen * sizeof(WCHAR));
672 if (pszName == NULL)
673 {
674 dwError = ERROR_NOT_ENOUGH_MEMORY;
675 goto done;
676 }
677
678 /* Recursively delete all the subkeys */
679 while (TRUE)
680 {
681 dwSize = dwMaxLen;
682 if (RegEnumKeyExW(hSubKey, 0, pszName, &dwSize,
684 {
685 break;
686 }
687
688 dwError = ScmDeleteRegKey(hSubKey, pszName);
689 if (dwError != ERROR_SUCCESS)
690 goto done;
691 }
692
693done:
694 if (pszName != NULL)
695 HeapFree(GetProcessHeap(), 0, pszName);
696
697 RegCloseKey(hSubKey);
698
699 /* Finally delete the key */
700 if (dwError == ERROR_SUCCESS)
701 dwError = RegDeleteKeyW(hKey, pszSubKey);
702
703 return dwError;
704}
DWORD ScmDeleteRegKey(_In_ HKEY hKey, _In_ PCWSTR pszSubKey)
Definition: config.c:646
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
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
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define max(a, b)
Definition: svc.c:63

Referenced by ScmDeleteMarkedServices(), ScmDeleteRegKey(), and ScmDeleteService().

◆ 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
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
DWORD ScmSetServiceGroup(PSERVICE lpService, LPCWSTR lpGroupName)
Definition: groupdb.c:61
DWORD dwImageRunCount
Definition: services.h:51
PSECURITY_DESCRIPTOR pSecurityDescriptor
Definition: services.h:82

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
BOOL bDeleted
Definition: services.h:68
LONG RefCount
Definition: services.h:70
Definition: send.c:48

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

◆ 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
#define SERVICE_WIN32
Definition: cmtypes.h:964

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().

◆ 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}
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2831

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().

◆ ScmGetServiceGroupByName()

PSERVICE_GROUP ScmGetServiceGroupByName ( _In_ LPCWSTR  lpGroupName)

Definition at line 26 of file groupdb.c.

28{
29 PLIST_ENTRY GroupEntry;
30 PSERVICE_GROUP lpGroup;
31
32 DPRINT("ScmGetServiceGroupByName(%S)\n", lpGroupName);
33
34 GroupEntry = GroupListHead.Flink;
35 while (GroupEntry != &GroupListHead)
36 {
37 lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
38
39 if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
40 return lpGroup;
41
42 GroupEntry = GroupEntry->Flink;
43 }
44
45 GroupEntry = UnknownGroupListHead.Flink;
46 while (GroupEntry != &UnknownGroupListHead)
47 {
48 lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
49
50 if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
51 return lpGroup;
52
53 GroupEntry = GroupEntry->Flink;
54 }
55
56 return NULL;
57}

Referenced by RI_ScGetCurrentGroupStateW().

◆ ScmGetServiceNameFromTag()

DWORD ScmGetServiceNameFromTag ( PTAG_INFO_NAME_FROM_TAG_IN_PARAMS  InParams,
PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS OutParams 
)

◆ ScmInitializeSecurity()

DWORD ScmInitializeSecurity ( VOID  )

Definition at line 373 of file security.c.

374{
375 DWORD dwError;
376
377 dwError = ScmCreateSids();
378 if (dwError != ERROR_SUCCESS)
379 return dwError;
380
381 dwError = ScmCreateAcls();
382 if (dwError != ERROR_SUCCESS)
383 return dwError;
384
385 dwError = ScmCreateDefaultSD();
386 if (dwError != ERROR_SUCCESS)
387 return dwError;
388
389 dwError = ScmCreatePipeSD();
390 if (dwError != ERROR_SUCCESS)
391 return dwError;
392
393 return ERROR_SUCCESS;
394}
static DWORD ScmCreatePipeSD(VOID)
Definition: security.c:271
static DWORD ScmCreateSids(VOID)
Definition: security.c:55
static DWORD ScmCreateAcls(VOID)
Definition: security.c:127
static DWORD ScmCreateDefaultSD(VOID)
Definition: security.c:214

Referenced by wWinMain().

◆ 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}
static DWORD PipeTimeout
Definition: database.c:37
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751

Referenced by wWinMain().

◆ ScmIsDeleteFlagSet()

BOOL ScmIsDeleteFlagSet ( HKEY  hServiceKey)

Definition at line 251 of file config.c.

252{
253 DWORD dwError;
254 DWORD dwType;
255 DWORD dwFlag;
256 DWORD dwSize = sizeof(DWORD);
257
258 dwError = RegQueryValueExW(hServiceKey,
259 L"DeleteFlag",
260 0,
261 &dwType,
262 (LPBYTE)&dwFlag,
263 &dwSize);
264
265 return (dwError == ERROR_SUCCESS);
266}

Referenced by CreateServiceListEntry().

◆ ScmLockDatabaseExclusive()

◆ ScmLockDatabaseShared()

◆ ScmLogEvent()

VOID ScmLogEvent ( DWORD  dwEventId,
WORD  wType,
WORD  wStrings,
LPCWSTR lpStrings 
)

Definition at line 174 of file services.c.

178{
179 HANDLE hLog;
180
182 L"Service Control Manager");
183 if (hLog == NULL)
184 {
185 DPRINT1("ScmLogEvent: RegisterEventSourceW failed %lu\n", GetLastError());
186 return;
187 }
188
189 if (!ReportEventW(hLog,
190 wType,
191 0,
192 dwEventId,
193 NULL,
194 wStrings,
195 0,
196 lpStrings,
197 NULL))
198 {
199 DPRINT1("ScmLogEvent: ReportEventW failed %lu\n", GetLastError());
200 }
201
203}
static HANDLE hLog
Definition: misc.cpp:13
BOOL WINAPI ReportEventW(IN HANDLE hEventLog, IN WORD wType, IN WORD wCategory, IN DWORD dwEventID, IN PSID lpUserSid, IN WORD wNumStrings, IN DWORD dwDataSize, IN LPCWSTR *lpStrings, IN LPVOID lpRawData)
Definition: eventlog.c:1516
BOOL WINAPI DeregisterEventSource(IN HANDLE hEventLog)
Definition: eventlog.c:473
HANDLE WINAPI RegisterEventSourceW(IN LPCWSTR lpUNCServerName, IN LPCWSTR lpSourceName)
Definition: eventlog.c:1295
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by RControlService(), RSetServiceStatus(), ScmLoadService(), ScmStopThread(), and ScmWaitForServiceConnect().

◆ ScmMarkServiceForDelete()

DWORD ScmMarkServiceForDelete ( PSERVICE  pService)

Definition at line 223 of file config.c.

224{
225 HKEY hServiceKey = NULL;
226 DWORD dwValue = 1;
227 DWORD dwError;
228
229 DPRINT("ScmMarkServiceForDelete() called\n");
230
231 dwError = ScmOpenServiceKey(pService->lpServiceName,
232 KEY_WRITE,
233 &hServiceKey);
234 if (dwError != ERROR_SUCCESS)
235 return dwError;
236
237 dwError = RegSetValueExW(hServiceKey,
238 L"DeleteFlag",
239 0,
240 REG_DWORD,
241 (LPBYTE)&dwValue,
242 sizeof(DWORD));
243
244 RegCloseKey(hServiceKey);
245
246 return dwError;
247}
DWORD ScmOpenServiceKey(LPWSTR lpServiceName, REGSAM samDesired, PHKEY phKey)
Definition: config.c:42
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 KEY_WRITE
Definition: nt_native.h:1031
#define REG_DWORD
Definition: sdbapi.c:596

Referenced by RDeleteService().

◆ ScmOpenServiceKey()

DWORD ScmOpenServiceKey ( LPWSTR  lpServiceName,
REGSAM  samDesired,
PHKEY  phKey 
)

Definition at line 42 of file config.c.

45{
47 DWORD dwError;
48
49 *phKey = NULL;
50
52 L"System\\CurrentControlSet\\Services",
53 0,
56 if (dwError != ERROR_SUCCESS)
57 return dwError;
58
60 lpServiceName,
61 0,
62 samDesired,
63 phKey);
64
66
67 return dwError;
68}

Referenced by RChangeServiceConfig2W(), RChangeServiceConfigW(), RQueryServiceConfig2A(), RQueryServiceConfig2W(), RQueryServiceConfigA(), RQueryServiceConfigW(), RSetServiceObjectSecurity(), and ScmMarkServiceForDelete().

◆ ScmQueryServiceLockStatusA()

VOID ScmQueryServiceLockStatusA ( OUT LPQUERY_SERVICE_LOCK_STATUSA  lpLockStatus)

Definition at line 159 of file lock.c.

160{
161 /* Lock the service database shared */
163
164 if (pServiceStartLock != NULL)
165 {
166 lpLockStatus->fIsLocked = TRUE;
167
168 /* FIXME: Retrieve the owner name. */
169 lpLockStatus->lpLockOwner = NULL;
170
171 lpLockStatus->dwLockDuration = (DWORD)time(NULL) - pServiceStartLock->TimeWhenLocked;
172 }
173 else
174 {
175 lpLockStatus->fIsLocked = FALSE;
176
177 strcpy((LPSTR)(lpLockStatus + 1), "");
178 lpLockStatus->lpLockOwner = (LPSTR)(ULONG_PTR)sizeof(QUERY_SERVICE_LOCK_STATUSA);
179
180 lpLockStatus->dwLockDuration = 0;
181 }
182
183 /* Unlock the service database */
185
186 return;
187}
BOOL ScmLockDatabaseShared(VOID)
Definition: database.c:2377
strcpy
Definition: string.h:131
struct _QUERY_SERVICE_LOCK_STATUSA QUERY_SERVICE_LOCK_STATUSA
char * LPSTR
Definition: xmlstorage.h:182

Referenced by RQueryServiceLockStatusA().

◆ ScmQueryServiceLockStatusW()

VOID ScmQueryServiceLockStatusW ( OUT LPQUERY_SERVICE_LOCK_STATUSW  lpLockStatus)

Definition at line 127 of file lock.c.

128{
129 /* Lock the service database shared */
131
132 if (pServiceStartLock != NULL)
133 {
134 lpLockStatus->fIsLocked = TRUE;
135
136 /* FIXME: Retrieve the owner name. */
137 lpLockStatus->lpLockOwner = NULL;
138
139 lpLockStatus->dwLockDuration = (DWORD)time(NULL) - pServiceStartLock->TimeWhenLocked;
140 }
141 else
142 {
143 lpLockStatus->fIsLocked = FALSE;
144
145 wcscpy((LPWSTR)(lpLockStatus + 1), L"");
146 lpLockStatus->lpLockOwner = (LPWSTR)(ULONG_PTR)sizeof(QUERY_SERVICE_LOCK_STATUSW);
147
148 lpLockStatus->dwLockDuration = 0;
149 }
150
151 /* Unlock the service database */
153
154 return;
155}
struct _QUERY_SERVICE_LOCK_STATUSW QUERY_SERVICE_LOCK_STATUSW
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by RQueryServiceLockStatusW().

◆ ScmReadDependencies()

DWORD ScmReadDependencies ( HKEY  hServiceKey,
LPWSTR lpDependencies,
DWORD lpdwDependenciesLength 
)

Definition at line 349 of file config.c.

352{
353 LPWSTR lpGroups = NULL;
354 LPWSTR lpServices = NULL;
355 SIZE_T cchGroupsLength = 0;
356 SIZE_T cchServicesLength = 0;
357 LPWSTR lpSrc;
358 LPWSTR lpDest;
359 SIZE_T cchLength;
360 SIZE_T cchTotalLength;
361
362 *lpDependencies = NULL;
363 *lpdwDependenciesLength = 0;
364
365 /* Read the dependency values */
366 ScmReadString(hServiceKey,
367 L"DependOnGroup",
368 &lpGroups);
369
370 ScmReadString(hServiceKey,
371 L"DependOnService",
372 &lpServices);
373
374 /* Leave, if there are no dependencies */
375 if (lpGroups == NULL && lpServices == NULL)
376 return ERROR_SUCCESS;
377
378 /* Determine the total buffer size for the dependencies */
379 if (lpGroups)
380 {
381 DPRINT("Groups:\n");
382 lpSrc = lpGroups;
383 while (*lpSrc != 0)
384 {
385 DPRINT(" %S\n", lpSrc);
386
387 cchLength = wcslen(lpSrc) + 1;
388 cchGroupsLength += cchLength + 1;
389
390 lpSrc = lpSrc + cchLength;
391 }
392 }
393
394 if (lpServices)
395 {
396 DPRINT("Services:\n");
397 lpSrc = lpServices;
398 while (*lpSrc != 0)
399 {
400 DPRINT(" %S\n", lpSrc);
401
402 cchLength = wcslen(lpSrc) + 1;
403 cchServicesLength += cchLength;
404
405 lpSrc = lpSrc + cchLength;
406 }
407 }
408
409 cchTotalLength = cchGroupsLength + cchServicesLength + 1;
410 DPRINT("cchTotalLength: %lu\n", cchTotalLength);
411
412 /* Allocate the common buffer for the dependencies */
413 *lpDependencies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cchTotalLength * sizeof(WCHAR));
414 if (*lpDependencies == NULL)
415 {
416 if (lpGroups)
417 HeapFree(GetProcessHeap(), 0, lpGroups);
418
419 if (lpServices)
420 HeapFree(GetProcessHeap(), 0, lpServices);
421
423 }
424
425 /* Return the allocated buffer length in characters */
426 *lpdwDependenciesLength = (DWORD)cchTotalLength;
427
428 /* Copy the service dependencies into the common buffer */
429 lpDest = *lpDependencies;
430 if (lpServices)
431 {
432 memcpy(lpDest,
433 lpServices,
434 cchServicesLength * sizeof(WCHAR));
435
436 lpDest = lpDest + cchServicesLength;
437 }
438
439 /* Copy the group dependencies into the common buffer */
440 if (lpGroups)
441 {
442 lpSrc = lpGroups;
443 while (*lpSrc != 0)
444 {
445 cchLength = wcslen(lpSrc) + 1;
446
447 *lpDest = SC_GROUP_IDENTIFIERW;
448 lpDest++;
449
450 wcscpy(lpDest, lpSrc);
451
452 lpDest = lpDest + cchLength;
453 lpSrc = lpSrc + cchLength;
454 }
455 }
456
457 /* Free the temporary buffers */
458 if (lpGroups)
459 HeapFree(GetProcessHeap(), 0, lpGroups);
460
461 if (lpServices)
462 HeapFree(GetProcessHeap(), 0, lpServices);
463
464 return ERROR_SUCCESS;
465}
DWORD ScmReadString(HKEY hServiceKey, LPCWSTR lpValueName, LPWSTR *lpValue)
Definition: config.c:270
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define SC_GROUP_IDENTIFIERW
Definition: winsvc.h:12

Referenced by RQueryServiceConfigA(), and RQueryServiceConfigW().

◆ ScmReadSecurityDescriptor()

DWORD ScmReadSecurityDescriptor ( _In_ HKEY  hServiceKey,
_Out_ PSECURITY_DESCRIPTOR ppSecurityDescriptor 
)

Definition at line 566 of file config.c.

569{
570 PSECURITY_DESCRIPTOR pRelativeSD = NULL;
571 HKEY hSecurityKey = NULL;
572 DWORD dwBufferLength = 0;
573 DWORD dwType;
574 DWORD dwError;
575
576 DPRINT("ScmReadSecurityDescriptor(%p %p)\n", hServiceKey, ppSecurityDescriptor);
577
578 *ppSecurityDescriptor = NULL;
579
580 dwError = RegOpenKeyExW(hServiceKey,
581 L"Security",
582 0,
584 &hSecurityKey);
585 if (dwError != ERROR_SUCCESS)
586 {
587 DPRINT("RegOpenKeyExW() failed (Error %lu)\n", dwError);
588
589 /* Do not fail if the Security key does not exist */
590 if (dwError == ERROR_FILE_NOT_FOUND)
591 dwError = ERROR_SUCCESS;
592 goto done;
593 }
594
595 dwError = RegQueryValueExW(hSecurityKey,
596 L"Security",
597 0,
598 &dwType,
599 NULL,
600 &dwBufferLength);
601 if (dwError != ERROR_SUCCESS)
602 {
603 DPRINT("RegQueryValueExW() failed (Error %lu)\n", dwError);
604
605 /* Do not fail if the Security value does not exist */
606 if (dwError == ERROR_FILE_NOT_FOUND)
607 dwError = ERROR_SUCCESS;
608 goto done;
609 }
610
611 DPRINT("dwBufferLength: %lu\n", dwBufferLength);
612 pRelativeSD = RtlAllocateHeap(RtlGetProcessHeap(),
614 dwBufferLength);
615 if (pRelativeSD == NULL)
616 {
617 return ERROR_OUTOFMEMORY;
618 }
619
620 DPRINT("pRelativeSD: %lu\n", pRelativeSD);
621 dwError = RegQueryValueExW(hSecurityKey,
622 L"Security",
623 0,
624 &dwType,
625 (LPBYTE)pRelativeSD,
626 &dwBufferLength);
627 if (dwError != ERROR_SUCCESS)
628 {
629 goto done;
630 }
631
632 *ppSecurityDescriptor = pRelativeSD;
633
634done:
635 if (dwError != ERROR_SUCCESS && pRelativeSD != NULL)
636 RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD);
637
638 if (hSecurityKey != NULL)
639 RegCloseKey(hSecurityKey);
640
641 return dwError;
642}
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016

Referenced by CreateServiceListEntry().

◆ ScmReadString()

DWORD ScmReadString ( HKEY  hServiceKey,
LPCWSTR  lpValueName,
LPWSTR lpValue 
)

Definition at line 270 of file config.c.

273{
274 DWORD dwError = 0;
275 DWORD dwSize = 0;
276 DWORD dwType = 0;
277 LPWSTR ptr = NULL;
278 LPWSTR expanded = NULL;
279
280 *lpValue = NULL;
281
282 dwError = RegQueryValueExW(hServiceKey,
283 lpValueName,
284 0,
285 &dwType,
286 NULL,
287 &dwSize);
288 if (dwError != ERROR_SUCCESS)
289 return dwError;
290
292 if (ptr == NULL)
294
295 dwError = RegQueryValueExW(hServiceKey,
296 lpValueName,
297 0,
298 &dwType,
299 (LPBYTE)ptr,
300 &dwSize);
301 if (dwError != ERROR_SUCCESS)
302 {
304 return dwError;
305 }
306
307 if (dwType == REG_EXPAND_SZ)
308 {
309 /* Expand the value... */
311 if (dwSize > 0)
312 {
313 expanded = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize * sizeof(WCHAR));
314 if (expanded)
315 {
316 if (dwSize == ExpandEnvironmentStringsW(ptr, expanded, dwSize))
317 {
318 *lpValue = expanded;
319 dwError = ERROR_SUCCESS;
320 }
321 else
322 {
323 dwError = GetLastError();
324 HeapFree(GetProcessHeap(), 0, expanded);
325 }
326 }
327 else
328 {
329 dwError = ERROR_NOT_ENOUGH_MEMORY;
330 }
331 }
332 else
333 {
334 dwError = GetLastError();
335 }
336
338 }
339 else
340 {
341 *lpValue = ptr;
342 }
343
344 return dwError;
345}
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
static PVOID ptr
Definition: dispmode.c:27
#define REG_EXPAND_SZ
Definition: nt_native.h:1494

Referenced by CreateServiceListEntry(), RQueryServiceConfig2A(), RQueryServiceConfig2W(), RQueryServiceConfigA(), RQueryServiceConfigW(), and ScmReadDependencies().

◆ 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().

◆ ScmReleaseServiceStartLock()

DWORD ScmReleaseServiceStartLock ( IN OUT LPSC_RPC_LOCK  lpLock)

Definition at line 82 of file lock.c.

83{
84 PSTART_LOCK pStartLock;
85 DWORD dwError = ERROR_SUCCESS;
86
87 if (lpLock == NULL)
89
90 pStartLock = (PSTART_LOCK)*lpLock;
91
92 if (pStartLock->Tag != LOCK_TAG)
94
95 /* Lock the service database exclusively */
97
98 /* Release the lock handle */
99 if ((pStartLock == pServiceStartLock) &&
101 {
104 *lpLock = NULL;
105
106 dwError = ERROR_SUCCESS;
107 }
108 else
109 {
111 }
112
113 /* Unlock the service database */
115
116 return dwError;
117}
struct _START_LOCK * PSTART_LOCK
#define ERROR_INVALID_SERVICE_LOCK
Definition: winerror.h:622

Referenced by RUnlockServiceDatabase(), ScmStartService(), and wWinMain().

◆ 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}
static BOOL ScmEnableBackupRestorePrivileges(_In_ HANDLE hToken, _In_ BOOL bEnable)
Definition: database.c:311
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2184
LIST_ENTRY ImageListEntry
Definition: services.h:48
HANDLE hProfile
Definition: services.h:57
HANDLE hToken
Definition: services.h:56
HANDLE hProcess
Definition: services.h:54

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

◆ ScmRunLastKnownGood()

DWORD ScmRunLastKnownGood ( VOID  )

Definition at line 402 of file controlset.c.

403{
404 DPRINT("ScmRunLastKnownGood()\n");
405
406 if (bBootAccepted)
407 {
408 DPRINT1("Boot has already been accepted\n");
410 }
411
412 /* FIXME */
413
414 return ERROR_SUCCESS;
415}

Referenced by RNotifyBootConfigStatus().

◆ 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
unsigned int BOOL
Definition: ntddk_ex.h:94
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().

◆ ScmSetServiceGroup()

DWORD ScmSetServiceGroup ( PSERVICE  lpService,
LPCWSTR  lpGroupName 
)

Definition at line 61 of file groupdb.c.

63{
64 PLIST_ENTRY GroupEntry;
65 PSERVICE_GROUP lpGroup;
66
67 DPRINT("ScmSetServiceGroup(%S)\n", lpGroupName);
68
69 if (lpService->lpGroup != NULL)
70 {
71 ASSERT(lpService->lpGroup->dwRefCount != 0);
72 ASSERT(lpService->lpGroup->dwRefCount == (DWORD)-1 ||
73 lpService->lpGroup->dwRefCount < 10000);
74 if (lpService->lpGroup->dwRefCount != (DWORD)-1)
75 {
76 lpService->lpGroup->dwRefCount--;
77 if (lpService->lpGroup->dwRefCount == 0)
78 {
79 ASSERT(lpService->lpGroup->TagCount == 0);
80 ASSERT(lpService->lpGroup->TagArray == NULL);
82 HeapFree(GetProcessHeap(), 0, lpService->lpGroup);
83 lpService->lpGroup = NULL;
84 }
85 }
86 }
87
88 if (lpGroupName == NULL)
89 return ERROR_SUCCESS;
90
91 GroupEntry = GroupListHead.Flink;
92 while (GroupEntry != &GroupListHead)
93 {
94 lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
95
96 if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
97 {
98 lpService->lpGroup = lpGroup;
99 return ERROR_SUCCESS;
100 }
101
102 GroupEntry = GroupEntry->Flink;
103 }
104
105 GroupEntry = UnknownGroupListHead.Flink;
106 while (GroupEntry != &UnknownGroupListHead)
107 {
108 lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
109
110 if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
111 {
112 lpGroup->dwRefCount++;
113 lpService->lpGroup = lpGroup;
114 return ERROR_SUCCESS;
115 }
116
117 GroupEntry = GroupEntry->Flink;
118 }
119
122 sizeof(SERVICE_GROUP) + ((wcslen(lpGroupName) + 1)* sizeof(WCHAR)));
123 if (lpGroup == NULL)
125
126 wcscpy(lpGroup->szGroupName, lpGroupName);
127 lpGroup->lpGroupName = lpGroup->szGroupName;
128 lpGroup->dwRefCount = 1;
129 lpService->lpGroup = lpGroup;
130
132 &lpGroup->GroupListEntry);
133
134 return ERROR_SUCCESS;
135}
struct _SERVICE_GROUP * PSERVICE_GROUP
struct _SERVICE_GROUP SERVICE_GROUP
DWORD dwRefCount
Definition: services.h:37
WCHAR szGroupName[1]
Definition: services.h:42
LIST_ENTRY GroupListEntry
Definition: services.h:34

Referenced by CreateServiceListEntry(), RChangeServiceConfigW(), RCreateServiceW(), and ScmDeleteServiceRecord().

◆ ScmSetServicePassword()

DWORD ScmSetServicePassword ( _In_ PCWSTR  pszServiceName,
_In_ PCWSTR  pszPassword 
)

◆ ScmShutdownSecurity()

VOID ScmShutdownSecurity ( VOID  )

Definition at line 398 of file security.c.

399{
402 ScmFreeAcls();
403 ScmFreeSids();
404}
static VOID ScmFreePipeSD(VOID)
Definition: security.c:312
static VOID ScmFreeAcls(VOID)
Definition: security.c:199
static VOID ScmFreeDefaultSD(VOID)
Definition: security.c:262
static VOID ScmFreeSids(VOID)
Definition: security.c:34

Referenced by wWinMain().

◆ 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().

◆ ScmStartDriver()

DWORD ScmStartDriver ( PSERVICE  lpService)

Definition at line 314 of file driver.c.

315{
316 DWORD dwError;
317
318 DPRINT("ScmStartDriver(%p)\n", pService);
319
320 dwError = ScmLoadDriver(pService);
321 if (dwError == ERROR_SUCCESS)
322 {
323 pService->Status.dwCurrentState = SERVICE_RUNNING;
324 pService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
325 pService->Status.dwWin32ExitCode = ERROR_SUCCESS;
326 }
327
328 DPRINT("ScmStartDriver returns %lu\n", dwError);
329
330 return dwError;
331}
static DWORD ScmLoadDriver(PSERVICE lpService)
Definition: driver.c:24
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28

Referenced by ScmLoadService().

◆ ScmStartRpcServer()

VOID ScmStartRpcServer ( VOID  )

Definition at line 107 of file rpcserver.c.

108{
110
111 DPRINT("ScmStartRpcServer() called\n");
112
113 Status = RpcServerUseProtseqEpW(L"ncacn_np",
114 10,
115 L"\\pipe\\ntsvcs",
116 NULL);
117 if (Status != RPC_S_OK)
118 {
119 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
120 return;
121 }
122
123 Status = RpcServerRegisterIf(svcctl_v2_0_s_ifspec,
124 NULL,
125 NULL);
126 if (Status != RPC_S_OK)
127 {
128 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
129 return;
130 }
131
132 Status = RpcServerListen(1, 20, TRUE);
133 if (Status != RPC_S_OK)
134 {
135 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
136 return;
137 }
138
139 DPRINT("ScmStartRpcServer() done\n");
140}
RPC_STATUS WINAPI RpcServerListen(UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait)
Definition: rpc_server.c:1520
RPC_STATUS WINAPI RpcServerRegisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv)
Definition: rpc_server.c:1116
RPC_STATUS WINAPI RpcServerUseProtseqEpW(RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:927
#define RPC_S_OK
Definition: rpcnterr.h:22
long RPC_STATUS
Definition: rpc.h:48

Referenced by wWinMain().

◆ 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
@ Service
Definition: ntsecapi.h:292
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127

Referenced by RStartServiceA(), and RStartServiceW().

◆ ScmUnlockDatabase()

◆ ScmWaitForLsa()

VOID ScmWaitForLsa ( VOID  )

Definition at line 207 of file services.c.

208{
209 HANDLE hEvent = CreateEventW(NULL, TRUE, FALSE, L"LSA_RPC_SERVER_ACTIVE");
210 if (hEvent == NULL)
211 {
212 DPRINT1("Failed to create or open the notification event (Error %lu)\n", GetLastError());
213 }
214 else
215 {
216 DPRINT("Wait for the LSA server\n");
218 DPRINT("LSA server running\n");
220 }
221
222 DPRINT("ScmWaitForLsa() done\n");
223}
#define INFINITE
Definition: serial.h:102
static HANDLE hEvent
Definition: comm.c:54
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651

Referenced by ScmCreateServiceDatabase().

◆ ScmWriteDependencies()

DWORD ScmWriteDependencies ( HKEY  hServiceKey,
LPCWSTR  lpDependencies,
DWORD  dwDependenciesLength 
)

Definition at line 117 of file config.c.

120{
121 DWORD dwError = ERROR_SUCCESS;
122 SIZE_T cchGroupLength = 0;
123 SIZE_T cchServiceLength = 0;
124 SIZE_T cchLength;
125 LPWSTR lpGroupDeps;
126 LPWSTR lpServiceDeps;
127 LPCWSTR lpSrc;
128 LPWSTR lpDst;
129
130 if (*lpDependencies == 0)
131 {
132 RegDeleteValueW(hServiceKey,
133 L"DependOnService");
134 RegDeleteValueW(hServiceKey,
135 L"DependOnGroup");
136 }
137 else
138 {
139 lpGroupDeps = HeapAlloc(GetProcessHeap(),
141 (dwDependenciesLength + 2) * sizeof(WCHAR));
142 if (lpGroupDeps == NULL)
144
145 lpSrc = lpDependencies;
146 lpDst = lpGroupDeps;
147 while (*lpSrc != 0)
148 {
149 cchLength = wcslen(lpSrc) + 1;
150 if (*lpSrc == SC_GROUP_IDENTIFIERW)
151 {
152 lpSrc++;
153 cchLength--;
154 cchGroupLength += cchLength;
155 wcscpy(lpDst, lpSrc);
156 lpDst = lpDst + cchLength;
157 }
158
159 lpSrc = lpSrc + cchLength;
160 }
161 *lpDst = 0;
162 lpDst++;
163 cchGroupLength++;
164
165 lpSrc = lpDependencies;
166 lpServiceDeps = lpDst;
167 while (*lpSrc != 0)
168 {
169 cchLength = wcslen(lpSrc) + 1;
170 if (*lpSrc != SC_GROUP_IDENTIFIERW)
171 {
172 cchServiceLength += cchLength;
173 wcscpy(lpDst, lpSrc);
174 lpDst = lpDst + cchLength;
175 }
176
177 lpSrc = lpSrc + cchLength;
178 }
179 *lpDst = 0;
180 cchServiceLength++;
181
182 if (cchGroupLength > 1)
183 {
184 dwError = RegSetValueExW(hServiceKey,
185 L"DependOnGroup",
186 0,
188 (LPBYTE)lpGroupDeps,
189 (DWORD)(cchGroupLength * sizeof(WCHAR)));
190 }
191 else
192 {
193 RegDeleteValueW(hServiceKey,
194 L"DependOnGroup");
195 }
196
197 if (dwError == ERROR_SUCCESS)
198 {
199 if (cchServiceLength > 1)
200 {
201 dwError = RegSetValueExW(hServiceKey,
202 L"DependOnService",
203 0,
205 (LPBYTE)lpServiceDeps,
206 (DWORD)(cchServiceLength * sizeof(WCHAR)));
207 }
208 else
209 {
210 RegDeleteValueW(hServiceKey,
211 L"DependOnService");
212 }
213 }
214
215 HeapFree(GetProcessHeap(), 0, lpGroupDeps);
216 }
217
218 return dwError;
219}
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
#define REG_MULTI_SZ
Definition: nt_native.h:1501
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by RChangeServiceConfigW(), and RCreateServiceW().

◆ ScmWriteSecurityDescriptor()

DWORD ScmWriteSecurityDescriptor ( _In_ HKEY  hServiceKey,
_In_ PSECURITY_DESCRIPTOR  pSecurityDescriptor 
)

Definition at line 530 of file config.c.

533{
534 HKEY hSecurityKey = NULL;
535 DWORD dwDisposition;
536 DWORD dwError;
537
538 DPRINT("ScmWriteSecurityDescriptor(%p %p)\n", hServiceKey, pSecurityDescriptor);
539
540 dwError = RegCreateKeyExW(hServiceKey,
541 L"Security",
542 0,
543 NULL,
546 NULL,
547 &hSecurityKey,
548 &dwDisposition);
549 if (dwError != ERROR_SUCCESS)
550 return dwError;
551
552 dwError = RegSetValueExW(hSecurityKey,
553 L"Security",
554 0,
556 (LPBYTE)pSecurityDescriptor,
557 RtlLengthSecurityDescriptor(pSecurityDescriptor));
558
559 RegCloseKey(hSecurityKey);
560
561 return dwError;
562}
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR)
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_SET_VALUE
Definition: nt_native.h:1017

Referenced by CreateServiceListEntry(), RCreateServiceW(), and RSetServiceObjectSecurity().

◆ SetSecurityServicesEvent()

DWORD SetSecurityServicesEvent ( VOID  )

Definition at line 142 of file services.c.

143{
144 DWORD dwError;
145
147 return ERROR_SUCCESS;
148
149 /* Create or open the SECURITY_SERVICES_STARTED event */
151 TRUE,
152 FALSE,
153 L"SECURITY_SERVICES_STARTED");
155 {
156 dwError = GetLastError();
157 if (dwError != ERROR_ALREADY_EXISTS)
158 return dwError;
159
161 FALSE,
162 L"SECURITY_SERVICES_STARTED");
164 return GetLastError();
165 }
166
168
169 return ERROR_SUCCESS;
170}
static HANDLE hScmSecurityServicesEvent
Definition: services.c:33
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define EVENT_MODIFY_STATE
Definition: winbase.h:171

Referenced by ScmCreateOrReferenceServiceImage().

Variable Documentation

◆ GroupListHead

◆ ImageListHead

LIST_ENTRY ImageListHead
extern

◆ pPipeSD

PSECURITY_DESCRIPTOR pPipeSD
extern

Definition at line 27 of file security.c.

Referenced by ScmCreateNewControlPipe(), ScmCreatePipeSD(), and ScmFreePipeSD().

◆ ScmInitialize

BOOL ScmInitialize
extern

Definition at line 28 of file services.c.

Referenced by ScmAutoStartServices(), ScmStartService(), and wWinMain().

◆ ScmLiveSetup

BOOL ScmLiveSetup
extern

Definition at line 30 of file services.c.

Referenced by CheckForLiveCD(), and ScmLogonService().

◆ ScmSetupInProgress

BOOL ScmSetupInProgress
extern

Definition at line 31 of file services.c.

Referenced by CheckForLiveCD(), and ScmLogonService().

◆ ScmShutdown

◆ ServiceListHead