ReactOS  0.4.14-dev-98-gb0d4763
database.c File Reference
#include "services.h"
#include <userenv.h>
#include <strsafe.h>
#include <reactos/undocuser.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)
 
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 ScmControlService (HANDLE hControlPipe, PWSTR pServiceName, SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwControl)
 
static DWORD ScmSendStartCommand (PSERVICE Service, DWORD argc, LPWSTR *argv)
 
static DWORD ScmWaitForServiceConnect (PSERVICE Service)
 
static DWORD ScmStartUserModeService (PSERVICE Service, DWORD argc, LPWSTR *argv)
 
static DWORD ScmLoadService (PSERVICE Service, DWORD argc, LPWSTR *argv)
 
DWORD ScmStartService (PSERVICE Service, DWORD argc, LPWSTR *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 22 of file database.c.

Function Documentation

◆ CreateServiceListEntry()

static DWORD CreateServiceListEntry ( LPCWSTR  lpServiceName,
HKEY  hServiceKey 
)
static

Definition at line 857 of file database.c.

859 {
860  PSERVICE lpService = NULL;
862  LPWSTR lpGroup = NULL;
863  DWORD dwSize;
864  DWORD dwError;
865  DWORD dwServiceType;
866  DWORD dwStartType;
867  DWORD dwErrorControl;
868  DWORD dwTagId;
869 
870  DPRINT("Service: '%S'\n", lpServiceName);
871  if (*lpServiceName == L'{')
872  return ERROR_SUCCESS;
873 
874  dwSize = sizeof(DWORD);
875  dwError = RegQueryValueExW(hServiceKey,
876  L"Type",
877  NULL,
878  NULL,
879  (LPBYTE)&dwServiceType,
880  &dwSize);
881  if (dwError != ERROR_SUCCESS)
882  return ERROR_SUCCESS;
883 
884  if (((dwServiceType & ~SERVICE_INTERACTIVE_PROCESS) != SERVICE_WIN32_OWN_PROCESS) &&
886  (dwServiceType != SERVICE_KERNEL_DRIVER) &&
887  (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER))
888  return ERROR_SUCCESS;
889 
890  DPRINT("Service type: %lx\n", dwServiceType);
891 
892  dwSize = sizeof(DWORD);
893  dwError = RegQueryValueExW(hServiceKey,
894  L"Start",
895  NULL,
896  NULL,
897  (LPBYTE)&dwStartType,
898  &dwSize);
899  if (dwError != ERROR_SUCCESS)
900  return ERROR_SUCCESS;
901 
902  DPRINT("Start type: %lx\n", dwStartType);
903 
904  dwSize = sizeof(DWORD);
905  dwError = RegQueryValueExW(hServiceKey,
906  L"ErrorControl",
907  NULL,
908  NULL,
909  (LPBYTE)&dwErrorControl,
910  &dwSize);
911  if (dwError != ERROR_SUCCESS)
912  return ERROR_SUCCESS;
913 
914  DPRINT("Error control: %lx\n", dwErrorControl);
915 
916  dwError = RegQueryValueExW(hServiceKey,
917  L"Tag",
918  NULL,
919  NULL,
920  (LPBYTE)&dwTagId,
921  &dwSize);
922  if (dwError != ERROR_SUCCESS)
923  dwTagId = 0;
924 
925  DPRINT("Tag: %lx\n", dwTagId);
926 
927  dwError = ScmReadString(hServiceKey,
928  L"Group",
929  &lpGroup);
930  if (dwError != ERROR_SUCCESS)
931  lpGroup = NULL;
932 
933  DPRINT("Group: %S\n", lpGroup);
934 
935  dwError = ScmReadString(hServiceKey,
936  L"DisplayName",
937  &lpDisplayName);
938  if (dwError != ERROR_SUCCESS)
940 
941  DPRINT("Display name: %S\n", lpDisplayName);
942 
943  dwError = ScmCreateNewServiceRecord(lpServiceName,
944  &lpService,
945  dwServiceType,
946  dwStartType);
947  if (dwError != ERROR_SUCCESS)
948  goto done;
949 
950  lpService->dwErrorControl = dwErrorControl;
951  lpService->dwTag = dwTagId;
952 
953  if (lpGroup != NULL)
954  {
955  dwError = ScmSetServiceGroup(lpService, lpGroup);
956  if (dwError != ERROR_SUCCESS)
957  goto done;
958  }
959 
960  if (lpDisplayName != NULL)
961  {
962  lpService->lpDisplayName = lpDisplayName;
964  }
965 
966  DPRINT("ServiceName: '%S'\n", lpService->lpServiceName);
967  if (lpService->lpGroup != NULL)
968  {
969  DPRINT("Group: '%S'\n", lpService->lpGroup->lpGroupName);
970  }
971  DPRINT("Start %lx Type %lx Tag %lx ErrorControl %lx\n",
972  lpService->dwStartType,
973  lpService->Status.dwServiceType,
974  lpService->dwTag,
975  lpService->dwErrorControl);
976 
977  if (ScmIsDeleteFlagSet(hServiceKey))
978  lpService->bDeleted = TRUE;
979  else
980  ScmGenerateServiceTag(lpService);
981 
982  if (lpService->Status.dwServiceType & SERVICE_WIN32)
983  {
984  dwError = ScmReadSecurityDescriptor(hServiceKey,
985  &lpService->pSecurityDescriptor);
986  if (dwError != ERROR_SUCCESS)
987  goto done;
988 
989  /* Assing the default security descriptor if the security descriptor cannot be read */
990  if (lpService->pSecurityDescriptor == NULL)
991  {
992  DPRINT("No security descriptor found! Assign default security descriptor!\n");
993  dwError = ScmCreateDefaultServiceSD(&lpService->pSecurityDescriptor);
994  if (dwError != ERROR_SUCCESS)
995  goto done;
996 
997  dwError = ScmWriteSecurityDescriptor(hServiceKey,
998  lpService->pSecurityDescriptor);
999  if (dwError != ERROR_SUCCESS)
1000  goto done;
1001  }
1002  }
1003 
1004 done:
1005  if (lpGroup != NULL)
1006  HeapFree(GetProcessHeap(), 0, lpGroup);
1007 
1008  if (lpDisplayName != NULL)
1010 
1011  if (lpService != NULL)
1012  {
1013  ASSERT(lpService->lpImage == NULL);
1014  }
1015 
1016  return dwError;
1017 }
SERVICE_STATUS Status
Definition: services.h:70
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:965
LPWSTR lpGroupName
Definition: services.h:33
PSERVICE_GROUP lpGroup
Definition: services.h:64
LPWSTR lpDisplayName
Definition: services.h:63
#define DWORD
Definition: nt_native.h:44
unsigned char * LPBYTE
Definition: typedefs.h:52
smooth NULL
Definition: ftsmooth.c:416
DWORD ScmSetServiceGroup(PSERVICE lpService, LPCWSTR lpGroupName)
Definition: groupdb.c:61
void DPRINT(...)
Definition: polytest.cpp:61
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:952
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:960
#define GetProcessHeap()
Definition: compat.h:395
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD dwServiceType
Definition: winsvc.h:99
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:961
static const WCHAR L[]
Definition: oid.c:1250
BOOL ScmIsDeleteFlagSet(HKEY hServiceKey)
Definition: config.c:251
LPWSTR lpServiceName
Definition: services.h:62
DWORD ScmReadString(HKEY hServiceKey, LPCWSTR lpValueName, LPWSTR *lpValue)
Definition: config.c:270
PSECURITY_DESCRIPTOR pSecurityDescriptor
Definition: services.h:79
DWORD dwStartType
Definition: services.h:71
DWORD ScmWriteSecurityDescriptor(_In_ HKEY hServiceKey, _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor)
Definition: config.c:523
DWORD ScmCreateNewServiceRecord(LPCWSTR lpServiceName, PSERVICE *lpServiceRecord, DWORD dwServiceType, DWORD dwStartType)
Definition: database.c:767
#define SERVICE_WIN32
Definition: cmtypes.h:962
DWORD dwTag
Definition: services.h:73
DWORD dwErrorControl
Definition: services.h:72
BOOL bDeleted
Definition: services.h:66
DWORD ScmCreateDefaultServiceSD(PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
Definition: security.c:319
WCHAR * LPWSTR
Definition: xmlstorage.h:184
PSERVICE_IMAGE lpImage
Definition: services.h:65
DWORD ScmGenerateServiceTag(PSERVICE lpServiceRecord)
Definition: database.c:744
DWORD ScmReadSecurityDescriptor(_In_ HKEY hServiceKey, _Out_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
Definition: config.c:559
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2737
#define HeapFree(x, y, z)
Definition: compat.h:394
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:951

Referenced by ScmCreateServiceDatabase().

◆ ScmAutoShutdownServices()

VOID ScmAutoShutdownServices ( VOID  )

Definition at line 2382 of file database.c.

2383 {
2384  PLIST_ENTRY ServiceEntry;
2385  PSERVICE CurrentService;
2386 
2387  DPRINT("ScmAutoShutdownServices() called\n");
2388 
2389  /* Lock the service database exclusively */
2391 
2392  ServiceEntry = ServiceListHead.Flink;
2393  while (ServiceEntry != &ServiceListHead)
2394  {
2395  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2396 
2397  if ((CurrentService->Status.dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN) &&
2398  (CurrentService->Status.dwCurrentState == SERVICE_RUNNING ||
2399  CurrentService->Status.dwCurrentState == SERVICE_START_PENDING))
2400  {
2401  /* Send the shutdown notification */
2402  DPRINT("Shutdown service: %S\n", CurrentService->lpServiceName);
2403  ScmControlService(CurrentService->lpImage->hControlPipe,
2404  CurrentService->lpServiceName,
2405  (SERVICE_STATUS_HANDLE)CurrentService,
2407  }
2408 
2409  ServiceEntry = ServiceEntry->Flink;
2410  }
2411 
2412  /* Unlock the service database */
2414 
2415  DPRINT("ScmAutoShutdownServices() done\n");
2416 }
SERVICE_STATUS Status
Definition: services.h:70
DWORD dwCurrentState
Definition: winsvc.h:100
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2420
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define SERVICE_RUNNING
Definition: winsvc.h:24
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
LIST_ENTRY ServiceListHead
Definition: database.c:29
LPWSTR lpServiceName
Definition: services.h:62
Definition: typedefs.h:117
DWORD dwControlsAccepted
Definition: winsvc.h:101
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2434
PSERVICE_IMAGE lpImage
Definition: services.h:65
DWORD ScmControlService(HANDLE hControlPipe, PWSTR pServiceName, SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwControl)
Definition: database.c:1314
HANDLE hControlPipe
Definition: services.h:51
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40

Referenced by ShutdownHandlerRoutine().

◆ ScmAutoStartServices()

VOID ScmAutoStartServices ( VOID  )

Definition at line 2171 of file database.c.

2172 {
2173  DWORD dwError;
2174  PLIST_ENTRY GroupEntry;
2175  PLIST_ENTRY ServiceEntry;
2176  PSERVICE_GROUP CurrentGroup;
2177  PSERVICE CurrentService;
2178  WCHAR szSafeBootServicePath[MAX_PATH];
2179  DWORD SafeBootEnabled;
2180  HKEY hKey;
2181  DWORD dwKeySize;
2182  ULONG i;
2183 
2184  /*
2185  * This function MUST be called ONLY at initialization time.
2186  * Therefore, no need to acquire the user service start lock.
2187  */
2189 
2190  /* Retrieve the SafeBoot parameter */
2192  L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option",
2193  0,
2194  KEY_READ,
2195  &hKey);
2196  if (dwError == ERROR_SUCCESS)
2197  {
2198  dwKeySize = sizeof(SafeBootEnabled);
2199  dwError = RegQueryValueExW(hKey,
2200  L"OptionValue",
2201  0,
2202  NULL,
2203  (LPBYTE)&SafeBootEnabled,
2204  &dwKeySize);
2205  RegCloseKey(hKey);
2206  }
2207 
2208  /* Default to Normal boot if the value doesn't exist */
2209  if (dwError != ERROR_SUCCESS)
2210  SafeBootEnabled = 0;
2211 
2212  /* Acquire the service control critical section, to synchronize starts */
2214 
2215  /* Clear 'ServiceVisited' flag (or set if not to start in Safe Mode) */
2216  ServiceEntry = ServiceListHead.Flink;
2217  while (ServiceEntry != &ServiceListHead)
2218  {
2219  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2220 
2221  /* Build the safe boot path */
2222  StringCchCopyW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2223  L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot");
2224 
2225  switch (SafeBootEnabled)
2226  {
2227  /* NOTE: Assumes MINIMAL (1) and DSREPAIR (3) load same items */
2228  case 1:
2229  case 3:
2230  StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2231  L"\\Minimal\\");
2232  break;
2233 
2234  case 2:
2235  StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2236  L"\\Network\\");
2237  break;
2238  }
2239 
2240  if (SafeBootEnabled != 0)
2241  {
2242  /* If key does not exist then do not assume safe mode */
2244  szSafeBootServicePath,
2245  0,
2246  KEY_READ,
2247  &hKey);
2248  if (dwError == ERROR_SUCCESS)
2249  {
2250  RegCloseKey(hKey);
2251 
2252  /* Finish Safe Boot path off */
2253  StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2254  CurrentService->lpServiceName);
2255 
2256  /* Check that the key is in the Safe Boot path */
2258  szSafeBootServicePath,
2259  0,
2260  KEY_READ,
2261  &hKey);
2262  if (dwError != ERROR_SUCCESS)
2263  {
2264  /* Mark service as visited so it is not auto-started */
2265  CurrentService->ServiceVisited = TRUE;
2266  }
2267  else
2268  {
2269  /* Must be auto-started in safe mode - mark as unvisited */
2270  RegCloseKey(hKey);
2271  CurrentService->ServiceVisited = FALSE;
2272  }
2273  }
2274  else
2275  {
2276  DPRINT1("WARNING: Could not open the associated Safe Boot key!");
2277  CurrentService->ServiceVisited = FALSE;
2278  }
2279  }
2280 
2281  ServiceEntry = ServiceEntry->Flink;
2282  }
2283 
2284  /* Start all services which are members of an existing group */
2285  GroupEntry = GroupListHead.Flink;
2286  while (GroupEntry != &GroupListHead)
2287  {
2288  CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
2289 
2290  DPRINT("Group '%S'\n", CurrentGroup->lpGroupName);
2291 
2292  /* Start all services witch have a valid tag */
2293  for (i = 0; i < CurrentGroup->TagCount; i++)
2294  {
2295  ServiceEntry = ServiceListHead.Flink;
2296  while (ServiceEntry != &ServiceListHead)
2297  {
2298  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2299 
2300  if ((CurrentService->lpGroup == CurrentGroup) &&
2301  (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2302  (CurrentService->ServiceVisited == FALSE) &&
2303  (CurrentService->dwTag == CurrentGroup->TagArray[i]))
2304  {
2305  CurrentService->ServiceVisited = TRUE;
2306  ScmLoadService(CurrentService, 0, NULL);
2307  }
2308 
2309  ServiceEntry = ServiceEntry->Flink;
2310  }
2311  }
2312 
2313  /* Start all services which have an invalid tag or which do not have a tag */
2314  ServiceEntry = ServiceListHead.Flink;
2315  while (ServiceEntry != &ServiceListHead)
2316  {
2317  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2318 
2319  if ((CurrentService->lpGroup == CurrentGroup) &&
2320  (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2321  (CurrentService->ServiceVisited == FALSE))
2322  {
2323  CurrentService->ServiceVisited = TRUE;
2324  ScmLoadService(CurrentService, 0, NULL);
2325  }
2326 
2327  ServiceEntry = ServiceEntry->Flink;
2328  }
2329 
2330  GroupEntry = GroupEntry->Flink;
2331  }
2332 
2333  /* Start all services which are members of any non-existing group */
2334  ServiceEntry = ServiceListHead.Flink;
2335  while (ServiceEntry != &ServiceListHead)
2336  {
2337  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2338 
2339  if ((CurrentService->lpGroup != NULL) &&
2340  (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2341  (CurrentService->ServiceVisited == FALSE))
2342  {
2343  CurrentService->ServiceVisited = TRUE;
2344  ScmLoadService(CurrentService, 0, NULL);
2345  }
2346 
2347  ServiceEntry = ServiceEntry->Flink;
2348  }
2349 
2350  /* Start all services which are not a member of any group */
2351  ServiceEntry = ServiceListHead.Flink;
2352  while (ServiceEntry != &ServiceListHead)
2353  {
2354  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2355 
2356  if ((CurrentService->lpGroup == NULL) &&
2357  (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2358  (CurrentService->ServiceVisited == FALSE))
2359  {
2360  CurrentService->ServiceVisited = TRUE;
2361  ScmLoadService(CurrentService, 0, NULL);
2362  }
2363 
2364  ServiceEntry = ServiceEntry->Flink;
2365  }
2366 
2367  /* Clear 'ServiceVisited' flag again */
2368  ServiceEntry = ServiceListHead.Flink;
2369  while (ServiceEntry != &ServiceListHead)
2370  {
2371  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2372  CurrentService->ServiceVisited = FALSE;
2373  ServiceEntry = ServiceEntry->Flink;
2374  }
2375 
2376  /* Release the critical section */
2378 }
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
LIST_ENTRY GroupListHead
Definition: groupdb.c:19
#define KEY_READ
Definition: nt_native.h:1023
BOOL ScmInitialize
Definition: services.c:28
LPWSTR lpGroupName
Definition: services.h:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
PSERVICE_GROUP lpGroup
Definition: services.h:64
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
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
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
static CRITICAL_SECTION ControlServiceCriticalSection
Definition: database.c:37
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
static DWORD ScmLoadService(PSERVICE Service, DWORD argc, LPWSTR *argv)
Definition: database.c:2019
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
LIST_ENTRY ServiceListHead
Definition: database.c:29
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN ServiceVisited
Definition: services.h:81
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:62
Definition: typedefs.h:117
PULONG TagArray
Definition: services.h:38
DWORD dwStartType
Definition: services.h:71
ULONG TagCount
Definition: services.h:37
#define DPRINT1
Definition: precomp.h:8
DWORD dwTag
Definition: services.h:73
#define SERVICE_AUTO_START
Definition: cmtypes.h:975
unsigned int ULONG
Definition: retypes.h:1
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by wWinMain().

◆ ScmCheckDriver()

static NTSTATUS ScmCheckDriver ( PSERVICE  Service)
static

Definition at line 1187 of file database.c.

1188 {
1191  HANDLE DirHandle;
1192  NTSTATUS Status;
1195  ULONG DataLength;
1196  ULONG Index;
1197 
1198  DPRINT("ScmCheckDriver(%S) called\n", Service->lpServiceName);
1199 
1200  if (Service->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
1201  {
1202  RtlInitUnicodeString(&DirName, L"\\Driver");
1203  }
1204  else // if (Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
1205  {
1206  ASSERT(Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER);
1207  RtlInitUnicodeString(&DirName, L"\\FileSystem");
1208  }
1209 
1211  &DirName,
1212  0,
1213  NULL,
1214  NULL);
1215 
1216  Status = NtOpenDirectoryObject(&DirHandle,
1218  &ObjectAttributes);
1219  if (!NT_SUCCESS(Status))
1220  {
1221  return Status;
1222  }
1223 
1225  2 * MAX_PATH * sizeof(WCHAR);
1226  DirInfo = HeapAlloc(GetProcessHeap(),
1228  BufferLength);
1229 
1230  Index = 0;
1231  while (TRUE)
1232  {
1233  Status = NtQueryDirectoryObject(DirHandle,
1234  DirInfo,
1235  BufferLength,
1236  TRUE,
1237  FALSE,
1238  &Index,
1239  &DataLength);
1241  {
1242  /* FIXME: Add current service to 'failed service' list */
1243  DPRINT("Service '%S' failed\n", Service->lpServiceName);
1244  break;
1245  }
1246 
1247  if (!NT_SUCCESS(Status))
1248  break;
1249 
1250  DPRINT("Comparing: '%S' '%wZ'\n", Service->lpServiceName, &DirInfo->Name);
1251 
1252  if (_wcsicmp(Service->lpServiceName, DirInfo->Name.Buffer) == 0)
1253  {
1254  DPRINT("Found: '%S' '%wZ'\n",
1255  Service->lpServiceName, &DirInfo->Name);
1256 
1257  /* Mark service as 'running' */
1258  Service->Status.dwCurrentState = SERVICE_RUNNING;
1259  Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
1260  Service->Status.dwWin32ExitCode = ERROR_SUCCESS;
1261  Service->Status.dwServiceSpecificExitCode = 0;
1262  Service->Status.dwCheckPoint = 0;
1263  Service->Status.dwWaitHint = 0;
1264 
1265  /* Mark the service group as 'running' */
1266  if (Service->lpGroup != NULL)
1267  {
1268  Service->lpGroup->ServicesRunning = TRUE;
1269  }
1270 
1271  break;
1272  }
1273  }
1274 
1276  0,
1277  DirInfo);
1278  NtClose(DirHandle);
1279 
1280  return STATUS_SUCCESS;
1281 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define TRUE
Definition: types.h:120
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
#define ERROR_SUCCESS
Definition: deptool.c:10
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:401
LONG NTSTATUS
Definition: precomp.h:26
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
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:498
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define SERVICE_RUNNING
Definition: winsvc.h:24
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:952
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
Status
Definition: gdiplustypes.h:24
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
unsigned int ULONG
Definition: retypes.h:1
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:741
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define HeapFree(x, y, z)
Definition: compat.h:394
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:951

Referenced by ScmGetBootAndSystemDriverState().

◆ ScmControlService()

DWORD ScmControlService ( HANDLE  hControlPipe,
PWSTR  pServiceName,
SERVICE_STATUS_HANDLE  hServiceStatus,
DWORD  dwControl 
)

Definition at line 1314 of file database.c.

1318 {
1319  PSCM_CONTROL_PACKET ControlPacket;
1320  SCM_REPLY_PACKET ReplyPacket;
1321 
1322  DWORD dwWriteCount = 0;
1323  DWORD dwReadCount = 0;
1324  DWORD PacketSize;
1325  PWSTR Ptr;
1326  DWORD dwError = ERROR_SUCCESS;
1327  BOOL bResult;
1328  OVERLAPPED Overlapped = {0};
1329 
1330  DPRINT("ScmControlService() called\n");
1331 
1332  /* Acquire the service control critical section, to synchronize requests */
1334 
1335  /* Calculate the total length of the start command line */
1336  PacketSize = sizeof(SCM_CONTROL_PACKET);
1337  PacketSize += (DWORD)((wcslen(pServiceName) + 1) * sizeof(WCHAR));
1338 
1339  ControlPacket = HeapAlloc(GetProcessHeap(),
1341  PacketSize);
1342  if (ControlPacket == NULL)
1343  {
1345  return ERROR_NOT_ENOUGH_MEMORY;
1346  }
1347 
1348  ControlPacket->dwSize = PacketSize;
1349  ControlPacket->dwControl = dwControl;
1350  ControlPacket->hServiceStatus = hServiceStatus;
1351 
1352  ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
1353 
1354  Ptr = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
1355  wcscpy(Ptr, pServiceName);
1356 
1357  ControlPacket->dwArgumentsCount = 0;
1358  ControlPacket->dwArgumentsOffset = 0;
1359 
1360  bResult = WriteFile(hControlPipe,
1361  ControlPacket,
1362  PacketSize,
1363  &dwWriteCount,
1364  &Overlapped);
1365  if (bResult == FALSE)
1366  {
1367  DPRINT("WriteFile() returned FALSE\n");
1368 
1369  dwError = GetLastError();
1370  if (dwError == ERROR_IO_PENDING)
1371  {
1372  DPRINT("dwError: ERROR_IO_PENDING\n");
1373 
1374  dwError = WaitForSingleObject(hControlPipe,
1375  PipeTimeout);
1376  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1377 
1378  if (dwError == WAIT_TIMEOUT)
1379  {
1380  bResult = CancelIo(hControlPipe);
1381  if (bResult == FALSE)
1382  {
1383  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1384  }
1385 
1387  goto Done;
1388  }
1389  else if (dwError == WAIT_OBJECT_0)
1390  {
1391  bResult = GetOverlappedResult(hControlPipe,
1392  &Overlapped,
1393  &dwWriteCount,
1394  TRUE);
1395  if (bResult == FALSE)
1396  {
1397  dwError = GetLastError();
1398  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1399 
1400  goto Done;
1401  }
1402  }
1403  }
1404  else
1405  {
1406  DPRINT1("WriteFile() failed (Error %lu)\n", dwError);
1407  goto Done;
1408  }
1409  }
1410 
1411  /* Read the reply */
1412  Overlapped.hEvent = (HANDLE) NULL;
1413 
1414  bResult = ReadFile(hControlPipe,
1415  &ReplyPacket,
1416  sizeof(SCM_REPLY_PACKET),
1417  &dwReadCount,
1418  &Overlapped);
1419  if (bResult == FALSE)
1420  {
1421  DPRINT("ReadFile() returned FALSE\n");
1422 
1423  dwError = GetLastError();
1424  if (dwError == ERROR_IO_PENDING)
1425  {
1426  DPRINT("dwError: ERROR_IO_PENDING\n");
1427 
1428  dwError = WaitForSingleObject(hControlPipe,
1429  PipeTimeout);
1430  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1431 
1432  if (dwError == WAIT_TIMEOUT)
1433  {
1434  bResult = CancelIo(hControlPipe);
1435  if (bResult == FALSE)
1436  {
1437  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1438  }
1439 
1441  goto Done;
1442  }
1443  else if (dwError == WAIT_OBJECT_0)
1444  {
1445  bResult = GetOverlappedResult(hControlPipe,
1446  &Overlapped,
1447  &dwReadCount,
1448  TRUE);
1449  if (bResult == FALSE)
1450  {
1451  dwError = GetLastError();
1452  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1453 
1454  goto Done;
1455  }
1456  }
1457  }
1458  else
1459  {
1460  DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
1461  goto Done;
1462  }
1463  }
1464 
1465 Done:
1466  /* Release the control packet */
1468  0,
1469  ControlPacket);
1470 
1471  if (dwReadCount == sizeof(SCM_REPLY_PACKET))
1472  {
1473  dwError = ReplyPacket.dwError;
1474  }
1475 
1477 
1478  DPRINT("ScmControlService() done\n");
1479 
1480  return dwError;
1481 }
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD dwServiceNameOffset
Definition: services.h:35
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
SERVICE_STATUS_HANDLE hServiceStatus
Definition: services.h:34
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
uint16_t * PWSTR
Definition: typedefs.h:54
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define ERROR_SERVICE_REQUEST_TIMEOUT
Definition: winerror.h:604
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define DWORD
Definition: nt_native.h:44
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
unsigned int BOOL
Definition: ntddk_ex.h:94
HANDLE hEvent
Definition: winbase.h:792
BOOL WINAPI CancelIo(IN HANDLE hFile)
Definition: deviceio.c:290
static CRITICAL_SECTION ControlServiceCriticalSection
Definition: database.c:37
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
DWORD dwArgumentsCount
Definition: services.h:32
#define WAIT_OBJECT_0
Definition: winbase.h:387
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
PVOID HANDLE
Definition: typedefs.h:71
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_TIMEOUT
Definition: dderror.h:14
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
SERVICE_STATUS_HANDLE hServiceStatus
Definition: main.c:10
static DWORD PipeTimeout
Definition: database.c:38
DWORD dwArgumentsOffset
Definition: services.h:36
_In_ USHORT PacketSize
Definition: iofuncs.h:1056
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
struct _SCM_CONTROL_PACKET SCM_CONTROL_PACKET
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
BYTE * PBYTE
Definition: pedump.c:66
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394

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

◆ ScmCreateNewControlPipe()

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

Definition at line 53 of file database.c.

56 {
57  WCHAR szControlPipeName[MAX_PATH + 1];
58  SECURITY_ATTRIBUTES SecurityAttributes;
59  HKEY hServiceCurrentKey = INVALID_HANDLE_VALUE;
60  DWORD dwServiceCurrent = 1;
61  DWORD dwKeyDisposition;
62  DWORD dwKeySize;
63  DWORD dwError;
64 
65  /* Get the service number */
67  {
68  /* TODO: Create registry entry with correct write access */
70  L"SYSTEM\\CurrentControlSet\\Control\\ServiceCurrent",
71  0,
72  NULL,
75  NULL,
76  &hServiceCurrentKey,
77  &dwKeyDisposition);
78  if (dwError != ERROR_SUCCESS)
79  {
80  DPRINT1("RegCreateKeyEx() failed with error %lu\n", dwError);
81  return dwError;
82  }
83 
84  if (dwKeyDisposition == REG_OPENED_EXISTING_KEY)
85  {
86  dwKeySize = sizeof(DWORD);
87  dwError = RegQueryValueExW(hServiceCurrentKey,
88  L"",
89  0,
90  NULL,
91  (BYTE*)&dwServiceCurrent,
92  &dwKeySize);
93  if (dwError != ERROR_SUCCESS)
94  {
95  RegCloseKey(hServiceCurrentKey);
96  DPRINT1("RegQueryValueEx() failed with error %lu\n", dwError);
97  return dwError;
98  }
99 
100  dwServiceCurrent++;
101  }
102 
103  dwError = RegSetValueExW(hServiceCurrentKey,
104  L"",
105  0,
106  REG_DWORD,
107  (BYTE*)&dwServiceCurrent,
108  sizeof(dwServiceCurrent));
109 
110  RegCloseKey(hServiceCurrentKey);
111 
112  if (dwError != ERROR_SUCCESS)
113  {
114  DPRINT1("RegSetValueExW() failed (Error %lu)\n", dwError);
115  return dwError;
116  }
117  }
118  else
119  {
120  dwServiceCurrent = 0;
121  }
122 
123  /* Create '\\.\pipe\net\NtControlPipeXXX' instance */
124  StringCchPrintfW(szControlPipeName, ARRAYSIZE(szControlPipeName),
125  L"\\\\.\\pipe\\net\\NtControlPipe%lu", dwServiceCurrent);
126 
127  DPRINT("PipeName: %S\n", szControlPipeName);
128 
129  SecurityAttributes.nLength = sizeof(SecurityAttributes);
130  SecurityAttributes.lpSecurityDescriptor = pPipeSD;
131  SecurityAttributes.bInheritHandle = FALSE;
132 
133  pServiceImage->hControlPipe = CreateNamedPipeW(szControlPipeName,
136  100,
137  8000,
138  4,
139  PipeTimeout,
140  &SecurityAttributes);
141  DPRINT("CreateNamedPipeW(%S) done\n", szControlPipeName);
142  if (pServiceImage->hControlPipe == INVALID_HANDLE_VALUE)
143  {
144  DPRINT1("Failed to create control pipe!\n");
145  return GetLastError();
146  }
147 
148  return ERROR_SUCCESS;
149 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define PIPE_TYPE_MESSAGE
Definition: winbase.h:168
#define KEY_READ
Definition: nt_native.h:1023
#define PIPE_WAIT
Definition: winbase.h:171
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define DWORD
Definition: nt_native.h:44
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:1091
static BOOL bSecurityServiceProcess
Definition: sctrl.c:61
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define KEY_WRITE
Definition: nt_native.h:1031
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:164
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
unsigned char BYTE
Definition: mem.h:68
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:170
static DWORD PipeTimeout
Definition: database.c:38
LPVOID lpSecurityDescriptor
Definition: compat.h:181
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define DPRINT1
Definition: precomp.h:8
PSECURITY_DESCRIPTOR pPipeSD
Definition: security.c:27
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
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 FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define REG_DWORD
Definition: sdbapi.c:596
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by ScmCreateOrReferenceServiceImage().

◆ ScmCreateNewServiceRecord()

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

Definition at line 767 of file database.c.

771 {
772  PSERVICE lpService = NULL;
773 
774  DPRINT("Service: '%S'\n", lpServiceName);
775 
776  /* Allocate service entry */
777  lpService = HeapAlloc(GetProcessHeap(),
779  FIELD_OFFSET(SERVICE, szServiceName[wcslen(lpServiceName) + 1]));
780  if (lpService == NULL)
782 
783  *lpServiceRecord = lpService;
784 
785  /* Copy service name */
786  wcscpy(lpService->szServiceName, lpServiceName);
787  lpService->lpServiceName = lpService->szServiceName;
788  lpService->lpDisplayName = lpService->lpServiceName;
789 
790  /* Set the start type */
791  lpService->dwStartType = dwStartType;
792 
793  /* Set the resume count */
794  lpService->dwResumeCount = ResumeCount++;
795 
796  /* Append service record */
798  &lpService->ServiceListEntry);
799 
800  /* Initialize the service status */
801  lpService->Status.dwServiceType = dwServiceType;
803  lpService->Status.dwControlsAccepted = 0;
804  lpService->Status.dwWin32ExitCode =
806  lpService->Status.dwServiceSpecificExitCode = 0;
807  lpService->Status.dwCheckPoint = 0;
808  lpService->Status.dwWaitHint =
809  (dwServiceType & SERVICE_DRIVER) ? 0 : 2000; /* 2 seconds */
810 
811  return ERROR_SUCCESS;
812 }
SERVICE_STATUS Status
Definition: services.h:70
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD dwCurrentState
Definition: winsvc.h:100
#define ERROR_SERVICE_DISABLED
Definition: winerror.h:609
static DWORD ResumeCount
Definition: database.c:32
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
LPWSTR lpDisplayName
Definition: services.h:63
#define InsertTailList(ListHead, Entry)
#define ERROR_SERVICE_NEVER_STARTED
Definition: winerror.h:628
#define SERVICE_DISABLED
Definition: cmtypes.h:977
DWORD dwCheckPoint
Definition: winsvc.h:104
#define SERVICE_STOPPED
Definition: winsvc.h:21
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
LIST_ENTRY ServiceListEntry
Definition: services.h:61
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD dwWaitHint
Definition: winsvc.h:105
DWORD dwWin32ExitCode
Definition: winsvc.h:102
DWORD dwServiceType
Definition: winsvc.h:99
LIST_ENTRY ServiceListHead
Definition: database.c:29
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
DWORD dwResumeCount
Definition: services.h:67
LPWSTR lpServiceName
Definition: services.h:62
DWORD dwStartType
Definition: services.h:71
DWORD dwControlsAccepted
Definition: winsvc.h:101
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define SERVICE_DRIVER
Definition: cmtypes.h:956
WCHAR szServiceName[1]
Definition: services.h:83
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)

Referenced by CreateServiceListEntry(), and RCreateServiceW().

◆ ScmCreateOrReferenceServiceImage()

static DWORD ScmCreateOrReferenceServiceImage ( PSERVICE  pService)
static

Definition at line 458 of file database.c.

459 {
461  UNICODE_STRING ImagePath;
463  PSERVICE_IMAGE pServiceImage = NULL;
465  DWORD dwError = ERROR_SUCCESS;
466  DWORD dwRecordSize;
467  LPWSTR pString;
468  BOOL bSecurityService;
469 
470  DPRINT("ScmCreateOrReferenceServiceImage(%p)\n", pService);
471 
472  RtlInitUnicodeString(&ImagePath, NULL);
474 
475  /* Get service data */
477  sizeof(QueryTable));
478 
479  QueryTable[0].Name = L"ImagePath";
481  QueryTable[0].EntryContext = &ImagePath;
482  QueryTable[1].Name = L"ObjectName";
485 
487  pService->lpServiceName,
488  QueryTable,
489  NULL,
490  NULL);
491  if (!NT_SUCCESS(Status))
492  {
493  DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
495  }
496 
497  DPRINT("ImagePath: '%wZ'\n", &ImagePath);
498  DPRINT("ObjectName: '%wZ'\n", &ObjectName);
499 
500  pServiceImage = ScmGetServiceImageByImagePath(ImagePath.Buffer);
501  if (pServiceImage == NULL)
502  {
503  dwRecordSize = sizeof(SERVICE_IMAGE) +
504  ImagePath.Length + sizeof(WCHAR) +
505  ((ObjectName.Length != 0) ? (ObjectName.Length + sizeof(WCHAR)) : 0);
506 
507  /* Create a new service image */
508  pServiceImage = HeapAlloc(GetProcessHeap(),
510  dwRecordSize);
511  if (pServiceImage == NULL)
512  {
513  dwError = ERROR_NOT_ENOUGH_MEMORY;
514  goto done;
515  }
516 
517  pServiceImage->dwImageRunCount = 1;
518  pServiceImage->hControlPipe = INVALID_HANDLE_VALUE;
519  pServiceImage->hProcess = INVALID_HANDLE_VALUE;
520 
521  pString = (PWSTR)((INT_PTR)pServiceImage + sizeof(SERVICE_IMAGE));
522 
523  /* Set the image path */
524  pServiceImage->pszImagePath = pString;
525  wcscpy(pServiceImage->pszImagePath,
526  ImagePath.Buffer);
527 
528  /* Set the account name */
529  if (ObjectName.Length > 0)
530  {
531  pString = pString + wcslen(pString) + 1;
532 
533  pServiceImage->pszAccountName = pString;
534  wcscpy(pServiceImage->pszAccountName,
535  ObjectName.Buffer);
536  }
537 
538  /* Service logon */
539  dwError = ScmLogonService(pService, pServiceImage);
540  if (dwError != ERROR_SUCCESS)
541  {
542  DPRINT1("ScmLogonService() failed (Error %lu)\n", dwError);
543 
544  /* Release the service image */
545  HeapFree(GetProcessHeap(), 0, pServiceImage);
546 
547  goto done;
548  }
549 
550  bSecurityService = ScmIsSecurityService(pServiceImage);
551 
552  /* Create the control pipe */
553  dwError = ScmCreateNewControlPipe(pServiceImage,
554  bSecurityService);
555  if (dwError != ERROR_SUCCESS)
556  {
557  DPRINT1("ScmCreateNewControlPipe() failed (Error %lu)\n", dwError);
558 
559  /* Unload the user profile */
560  if (pServiceImage->hProfile != NULL)
561  {
563  UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile);
565  }
566 
567  /* Close the logon token */
568  if (pServiceImage->hToken != NULL)
569  CloseHandle(pServiceImage->hToken);
570 
571  /* Release the service image */
572  HeapFree(GetProcessHeap(), 0, pServiceImage);
573 
574  goto done;
575  }
576 
577  if (bSecurityService)
578  {
580  }
581 
582  /* FIXME: Add more initialization code here */
583 
584 
585  /* Append service record */
587  &pServiceImage->ImageListEntry);
588  }
589  else
590  {
591 // if ((lpService->Status.dwServiceType & SERVICE_WIN32_SHARE_PROCESS) == 0)
592 
593  /* Fail if services in an image use different accounts */
594  if (!ScmIsSameServiceAccount(pServiceImage->pszAccountName, ObjectName.Buffer))
595  {
597  goto done;
598  }
599 
600  /* Increment the run counter */
601  pServiceImage->dwImageRunCount++;
602  }
603 
604  DPRINT("pServiceImage->pszImagePath: %S\n", pServiceImage->pszImagePath);
605  DPRINT("pServiceImage->pszAccountName: %S\n", pServiceImage->pszAccountName);
606  DPRINT("pServiceImage->dwImageRunCount: %lu\n", pServiceImage->dwImageRunCount);
607 
608  /* Link the service image to the service */
609  pService->lpImage = pServiceImage;
610 
611 done:
613  RtlFreeUnicodeString(&ImagePath);
614 
615  DPRINT("ScmCreateOrReferenceServiceImage() done (Error: %lu)\n", dwError);
616 
617  return dwError;
618 }
static PSERVICE_IMAGE ScmGetServiceImageByImagePath(LPWSTR lpImagePath)
Definition: database.c:153
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
LPWSTR pszAccountName
Definition: services.h:48
HANDLE hToken
Definition: services.h:54
#define ERROR_SUCCESS
Definition: deptool.c:10
LIST_ENTRY ImageListEntry
Definition: services.h:46
LIST_ENTRY ImageListHead
Definition: database.c:28
uint16_t * PWSTR
Definition: typedefs.h:54
static BOOL ScmEnableBackupRestorePrivileges(_In_ HANDLE hToken, _In_ BOOL bEnable)
Definition: database.c:312
LONG NTSTATUS
Definition: precomp.h:26
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD SetSecurityServicesEvent(VOID)
Definition: services.c:53
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
int32_t INT_PTR
Definition: typedefs.h:62
#define InsertTailList(ListHead, Entry)
#define RTL_REGISTRY_SERVICES
Definition: nt_native.h:162
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2101
static DWORD ScmLogonService(IN PSERVICE pService, IN PSERVICE_IMAGE pImage)
Definition: database.c:359
struct _SERVICE_IMAGE SERVICE_IMAGE
DWORD dwImageRunCount
Definition: services.h:49
#define ERROR_DIFFERENT_SERVICE_ACCOUNT
Definition: winerror.h:630
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static DWORD ScmCreateNewControlPipe(_In_ PSERVICE_IMAGE pServiceImage, _In_ BOOL bSecurityServiceProcess)
Definition: database.c:53
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HANDLE hProfile
Definition: services.h:55
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:62
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
LPWSTR pszImagePath
Definition: services.h:47
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
static BOOL ScmIsSameServiceAccount(_In_ PCWSTR pszAccountName1, _In_ PCWSTR pszAccountName2)
Definition: database.c:270
WCHAR * LPWSTR
Definition: xmlstorage.h:184
PSERVICE_IMAGE lpImage
Definition: services.h:65
HANDLE hProcess
Definition: services.h:52
HANDLE hControlPipe
Definition: services.h:51
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
static BOOL ScmIsSecurityService(_In_ PSERVICE_IMAGE pServiceImage)
Definition: database.c:45

Referenced by ScmLoadService().

◆ ScmCreateServiceDatabase()

DWORD ScmCreateServiceDatabase ( VOID  )

Definition at line 1088 of file database.c.

1089 {
1090  WCHAR szSubKey[MAX_PATH];
1092  HKEY hServiceKey;
1093  DWORD dwSubKey;
1094  DWORD dwSubKeyLength;
1095  FILETIME ftLastChanged;
1096  DWORD dwError;
1097 
1098  DPRINT("ScmCreateServiceDatabase() called\n");
1099 
1100  /* Retrieve the NoInteractiveServies value */
1102 
1103  /* Create the service group list */
1104  dwError = ScmCreateGroupList();
1105  if (dwError != ERROR_SUCCESS)
1106  return dwError;
1107 
1108  /* Initialize image and service lists */
1111 
1112  /* Initialize the database lock */
1114 
1116  L"System\\CurrentControlSet\\Services",
1117  0,
1118  KEY_READ,
1119  &hServicesKey);
1120  if (dwError != ERROR_SUCCESS)
1121  return dwError;
1122 
1123  dwSubKey = 0;
1124  for (;;)
1125  {
1126  dwSubKeyLength = MAX_PATH;
1127  dwError = RegEnumKeyExW(hServicesKey,
1128  dwSubKey,
1129  szSubKey,
1130  &dwSubKeyLength,
1131  NULL,
1132  NULL,
1133  NULL,
1134  &ftLastChanged);
1135  if (dwError == ERROR_SUCCESS &&
1136  szSubKey[0] != L'{')
1137  {
1138  DPRINT("SubKeyName: '%S'\n", szSubKey);
1139 
1140  dwError = RegOpenKeyExW(hServicesKey,
1141  szSubKey,
1142  0,
1143  KEY_READ,
1144  &hServiceKey);
1145  if (dwError == ERROR_SUCCESS)
1146  {
1147  dwError = CreateServiceListEntry(szSubKey,
1148  hServiceKey);
1149 
1150  RegCloseKey(hServiceKey);
1151  }
1152  }
1153 
1154  if (dwError != ERROR_SUCCESS)
1155  break;
1156 
1157  dwSubKey++;
1158  }
1159 
1161 
1162  /* Wait for the LSA server */
1163  ScmWaitForLsa();
1164 
1165  /* Delete services that are marked for delete */
1167 
1168  DPRINT("ScmCreateServiceDatabase() done\n");
1169 
1170  return ERROR_SUCCESS;
1171 }
#define ERROR_SUCCESS
Definition: deptool.c:10
LIST_ENTRY ImageListHead
Definition: database.c:28
#define KEY_READ
Definition: nt_native.h:1023
static RTL_RESOURCE DatabaseLock
Definition: database.c:31
VOID ScmWaitForLsa(VOID)
Definition: services.c:118
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
static DWORD CreateServiceListEntry(LPCWSTR lpServiceName, HKEY hServiceKey)
Definition: database.c:857
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static HANDLE hServicesKey
Definition: devinst.c:21
NTSYSAPI VOID NTAPI RtlInitializeResource(_In_ PRTL_RESOURCE Resource)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
LIST_ENTRY ServiceListHead
Definition: database.c:29
static const WCHAR L[]
Definition: oid.c:1250
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
static VOID ScmGetNoInteractiveServicesValue(VOID)
Definition: database.c:1062
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
DWORD ScmCreateGroupList(VOID)
Definition: groupdb.c:235
VOID ScmDeleteMarkedServices(VOID)
Definition: database.c:1021
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by wWinMain().

◆ ScmDeleteMarkedServices()

VOID ScmDeleteMarkedServices ( VOID  )

Definition at line 1021 of file database.c.

1022 {
1023  PLIST_ENTRY ServiceEntry;
1024  PSERVICE CurrentService;
1026  DWORD dwError;
1027 
1028  ServiceEntry = ServiceListHead.Flink;
1029  while (ServiceEntry != &ServiceListHead)
1030  {
1031  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
1032 
1033  ServiceEntry = ServiceEntry->Flink;
1034 
1035  if (CurrentService->bDeleted != FALSE)
1036  {
1038  L"System\\CurrentControlSet\\Services",
1039  0,
1040  DELETE,
1041  &hServicesKey);
1042  if (dwError == ERROR_SUCCESS)
1043  {
1044  dwError = ScmDeleteRegKey(hServicesKey, CurrentService->lpServiceName);
1046  if (dwError == ERROR_SUCCESS)
1047  {
1048  RemoveEntryList(&CurrentService->ServiceListEntry);
1049  HeapFree(GetProcessHeap(), 0, CurrentService);
1050  }
1051  }
1052 
1053  if (dwError != ERROR_SUCCESS)
1054  DPRINT1("Delete service failed: %S\n", CurrentService->lpServiceName);
1055  }
1056  }
1057 }
DWORD ScmDeleteRegKey(_In_ HKEY hKey, _In_ PCWSTR pszSubKey)
Definition: config.c:639
#define ERROR_SUCCESS
Definition: deptool.c:10
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static HANDLE hServicesKey
Definition: devinst.c:21
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY ServiceListEntry
Definition: services.h:61
#define GetProcessHeap()
Definition: compat.h:395
unsigned long DWORD
Definition: ntddk_ex.h:95
LIST_ENTRY ServiceListHead
Definition: database.c:29
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:62
Definition: typedefs.h:117
#define DPRINT1
Definition: precomp.h:8
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
BOOL bDeleted
Definition: services.h:66
#define HeapFree(x, y, z)
Definition: compat.h:394
#define DELETE
Definition: nt_native.h:57
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by ScmCreateServiceDatabase(), and ScmShutdownServiceDatabase().

◆ ScmDeleteNamedPipeCriticalSection()

VOID ScmDeleteNamedPipeCriticalSection ( VOID  )

Definition at line 2469 of file database.c.

2470 {
2472 }
static CRITICAL_SECTION ControlServiceCriticalSection
Definition: database.c:37
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

Referenced by wWinMain().

◆ ScmDeleteServiceRecord()

VOID ScmDeleteServiceRecord ( PSERVICE  lpService)

Definition at line 816 of file database.c.

817 {
818  DPRINT("Deleting Service %S\n", lpService->lpServiceName);
819 
820  /* Delete the display name */
821  if (lpService->lpDisplayName != NULL &&
822  lpService->lpDisplayName != lpService->lpServiceName)
823  HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
824 
825  /* Dereference the service image */
826  if (lpService->lpImage)
827  {
828  lpService->lpImage->dwImageRunCount--;
829 
830  if (lpService->lpImage->dwImageRunCount == 0)
831  {
832  ScmRemoveServiceImage(lpService->lpImage);
833  lpService->lpImage = NULL;
834  }
835  }
836 
837  /* Decrement the group reference counter */
838  ScmSetServiceGroup(lpService, NULL);
839 
840  /* Release the SecurityDescriptor */
841  if (lpService->pSecurityDescriptor != NULL)
842  HeapFree(GetProcessHeap(), 0, lpService->pSecurityDescriptor);
843 
844  /* Remove the Service from the List */
845  RemoveEntryList(&lpService->ServiceListEntry);
846 
847  DPRINT("Deleted Service %S\n", lpService->lpServiceName);
848 
849  /* Delete the service record */
850  HeapFree(GetProcessHeap(), 0, lpService);
851 
852  DPRINT("Done\n");
853 }
LPWSTR lpDisplayName
Definition: services.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
DWORD dwImageRunCount
Definition: services.h:49
smooth NULL
Definition: ftsmooth.c:416
DWORD ScmSetServiceGroup(PSERVICE lpService, LPCWSTR lpGroupName)
Definition: groupdb.c:61
void DPRINT(...)
Definition: polytest.cpp:61
LIST_ENTRY ServiceListEntry
Definition: services.h:61
#define GetProcessHeap()
Definition: compat.h:395
LPWSTR lpServiceName
Definition: services.h:62
PSECURITY_DESCRIPTOR pSecurityDescriptor
Definition: services.h:79
PSERVICE_IMAGE lpImage
Definition: services.h:65
#define HeapFree(x, y, z)
Definition: compat.h:394
VOID ScmRemoveServiceImage(PSERVICE_IMAGE pServiceImage)
Definition: database.c:622

Referenced by RCloseServiceHandle().

◆ ScmEnableBackupRestorePrivileges()

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

Definition at line 312 of file database.c.

315 {
316  PTOKEN_PRIVILEGES pTokenPrivileges = NULL;
317  DWORD dwSize;
318  BOOL bRet = FALSE;
319 
320  DPRINT("ScmEnableBackupRestorePrivileges(%p %d)\n", hToken, bEnable);
321 
322  dwSize = sizeof(TOKEN_PRIVILEGES) + 2 * sizeof(LUID_AND_ATTRIBUTES);
323  pTokenPrivileges = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
324  if (pTokenPrivileges == NULL)
325  {
326  DPRINT1("Failed to allocate the privilege buffer!\n");
327  goto done;
328  }
329 
330  pTokenPrivileges->PrivilegeCount = 2;
331  pTokenPrivileges->Privileges[0].Luid.LowPart = SE_BACKUP_PRIVILEGE;
332  pTokenPrivileges->Privileges[0].Luid.HighPart = 0;
333  pTokenPrivileges->Privileges[0].Attributes = (bEnable ? SE_PRIVILEGE_ENABLED : 0);
334  pTokenPrivileges->Privileges[1].Luid.LowPart = SE_RESTORE_PRIVILEGE;
335  pTokenPrivileges->Privileges[1].Luid.HighPart = 0;
336  pTokenPrivileges->Privileges[1].Attributes = (bEnable ? SE_PRIVILEGE_ENABLED : 0);
337 
338  bRet = AdjustTokenPrivileges(hToken, FALSE, pTokenPrivileges, 0, NULL, NULL);
339  if (!bRet)
340  {
341  DPRINT1("AdjustTokenPrivileges() failed with error %lu\n", GetLastError());
342  }
343  else if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
344  {
345  DPRINT1("AdjustTokenPrivileges() succeeded, but with not all privileges assigned\n");
346  bRet = FALSE;
347  }
348 
349 done:
350  if (pTokenPrivileges != NULL)
351  HeapFree(GetProcessHeap(), 0, pTokenPrivileges);
352 
353  return bRet;
354 }
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
$ULONG PrivilegeCount
Definition: setypes.h:969
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
unsigned int BOOL
Definition: ntddk_ex.h:94
struct _TOKEN_PRIVILEGES TOKEN_PRIVILEGES
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD LowPart
unsigned long DWORD
Definition: ntddk_ex.h:95
LONG HighPart
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:376
_In_ BOOL bEnable
Definition: winddi.h:3426
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:970
#define DPRINT1
Definition: precomp.h:8
#define ERROR_NOT_ALL_ASSIGNED
Definition: winerror.h:782
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
#define HeapFree(x, y, z)
Definition: compat.h:394
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54

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

◆ ScmGenerateServiceTag()

DWORD ScmGenerateServiceTag ( PSERVICE  lpServiceRecord)

Definition at line 744 of file database.c.

745 {
746  /* Check for an overflow */
747  if (ServiceTag == -1)
748  {
749  return ERROR_INVALID_DATA;
750  }
751 
752  /* This is only valid for Win32 services */
753  if (!(lpServiceRecord->Status.dwServiceType & SERVICE_WIN32))
754  {
756  }
757 
758  /* Increment the tag counter and set it */
759  ServiceTag = ServiceTag % 0xFFFFFFFF + 1;
760  lpServiceRecord->dwTag = ServiceTag;
761 
762  return ERROR_SUCCESS;
763 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
SERVICE_STATUS Status
Definition: services.h:70
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD dwServiceType
Definition: winsvc.h:99
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define SERVICE_WIN32
Definition: cmtypes.h:962
DWORD dwTag
Definition: services.h:73
static DWORD ServiceTag
Definition: database.c:34

Referenced by CreateServiceListEntry(), and RCreateServiceW().

◆ ScmGetBootAndSystemDriverState()

VOID ScmGetBootAndSystemDriverState ( VOID  )

Definition at line 1285 of file database.c.

1286 {
1287  PLIST_ENTRY ServiceEntry;
1288  PSERVICE CurrentService;
1289 
1290  DPRINT("ScmGetBootAndSystemDriverState() called\n");
1291 
1292  ServiceEntry = ServiceListHead.Flink;
1293  while (ServiceEntry != &ServiceListHead)
1294  {
1295  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
1296 
1297  if (CurrentService->dwStartType == SERVICE_BOOT_START ||
1298  CurrentService->dwStartType == SERVICE_SYSTEM_START)
1299  {
1300  /* Check driver */
1301  DPRINT(" Checking service: %S\n", CurrentService->lpServiceName);
1302 
1303  ScmCheckDriver(CurrentService);
1304  }
1305 
1306  ServiceEntry = ServiceEntry->Flink;
1307  }
1308 
1309  DPRINT("ScmGetBootAndSystemDriverState() done\n");
1310 }
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:974
static NTSTATUS ScmCheckDriver(PSERVICE Service)
Definition: database.c:1187
void DPRINT(...)
Definition: polytest.cpp:61
#define SERVICE_BOOT_START
Definition: cmtypes.h:973
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY ServiceListHead
Definition: database.c:29
LPWSTR lpServiceName
Definition: services.h:62
Definition: typedefs.h:117
DWORD dwStartType
Definition: services.h:71

Referenced by wWinMain().

◆ ScmGetNoInteractiveServicesValue()

static VOID ScmGetNoInteractiveServicesValue ( VOID  )
static

Definition at line 1062 of file database.c.

1063 {
1064  HKEY hKey;
1065  DWORD dwKeySize;
1066  LONG lError;
1067 
1069  L"SYSTEM\\CurrentControlSet\\Control\\Windows",
1070  0,
1071  KEY_READ,
1072  &hKey);
1073  if (lError == ERROR_SUCCESS)
1074  {
1075  dwKeySize = sizeof(NoInteractiveServices);
1076  lError = RegQueryValueExW(hKey,
1077  L"NoInteractiveServices",
1078  0,
1079  NULL,
1081  &dwKeySize);
1082  RegCloseKey(hKey);
1083  }
1084 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
static DWORD NoInteractiveServices
Definition: database.c:33

Referenced by ScmCreateServiceDatabase().

◆ ScmGetServiceEntryByDisplayName()

PSERVICE ScmGetServiceEntryByDisplayName ( LPCWSTR  lpDisplayName)

Definition at line 686 of file database.c.

687 {
688  PLIST_ENTRY ServiceEntry;
689  PSERVICE CurrentService;
690 
691  DPRINT("ScmGetServiceEntryByDisplayName() called\n");
692 
693  ServiceEntry = ServiceListHead.Flink;
694  while (ServiceEntry != &ServiceListHead)
695  {
696  CurrentService = CONTAINING_RECORD(ServiceEntry,
697  SERVICE,
698  ServiceListEntry);
699  if (_wcsicmp(CurrentService->lpDisplayName, lpDisplayName) == 0)
700  {
701  DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
702  return CurrentService;
703  }
704 
705  ServiceEntry = ServiceEntry->Flink;
706  }
707 
708  DPRINT("Couldn't find a matching service\n");
709 
710  return NULL;
711 }
LPWSTR lpDisplayName
Definition: services.h:63
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY ServiceListHead
Definition: database.c:29
Definition: typedefs.h:117
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2737
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

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

◆ ScmGetServiceEntryByName()

PSERVICE ScmGetServiceEntryByName ( LPCWSTR  lpServiceName)

Definition at line 657 of file database.c.

658 {
659  PLIST_ENTRY ServiceEntry;
660  PSERVICE CurrentService;
661 
662  DPRINT("ScmGetServiceEntryByName() called\n");
663 
664  ServiceEntry = ServiceListHead.Flink;
665  while (ServiceEntry != &ServiceListHead)
666  {
667  CurrentService = CONTAINING_RECORD(ServiceEntry,
668  SERVICE,
669  ServiceListEntry);
670  if (_wcsicmp(CurrentService->lpServiceName, lpServiceName) == 0)
671  {
672  DPRINT("Found service: '%S'\n", CurrentService->lpServiceName);
673  return CurrentService;
674  }
675 
676  ServiceEntry = ServiceEntry->Flink;
677  }
678 
679  DPRINT("Couldn't find a matching service\n");
680 
681  return NULL;
682 }
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY ServiceListHead
Definition: database.c:29
LPWSTR lpServiceName
Definition: services.h:62
Definition: typedefs.h:117
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

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

◆ ScmGetServiceEntryByResumeCount()

PSERVICE ScmGetServiceEntryByResumeCount ( DWORD  dwResumeCount)

Definition at line 715 of file database.c.

716 {
717  PLIST_ENTRY ServiceEntry;
718  PSERVICE CurrentService;
719 
720  DPRINT("ScmGetServiceEntryByResumeCount() called\n");
721 
722  ServiceEntry = ServiceListHead.Flink;
723  while (ServiceEntry != &ServiceListHead)
724  {
725  CurrentService = CONTAINING_RECORD(ServiceEntry,
726  SERVICE,
727  ServiceListEntry);
728  if (CurrentService->dwResumeCount > dwResumeCount)
729  {
730  DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
731  return CurrentService;
732  }
733 
734  ServiceEntry = ServiceEntry->Flink;
735  }
736 
737  DPRINT("Couldn't find a matching service\n");
738 
739  return NULL;
740 }
LPWSTR lpDisplayName
Definition: services.h:63
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY ServiceListHead
Definition: database.c:29
DWORD dwResumeCount
Definition: services.h:67
Definition: typedefs.h:117

Referenced by REnumServiceGroupW(), and REnumServicesStatusExW().

◆ ScmGetServiceImageByImagePath()

static PSERVICE_IMAGE ScmGetServiceImageByImagePath ( LPWSTR  lpImagePath)
static

Definition at line 153 of file database.c.

154 {
155  PLIST_ENTRY ImageEntry;
156  PSERVICE_IMAGE CurrentImage;
157 
158  DPRINT("ScmGetServiceImageByImagePath(%S) called\n", lpImagePath);
159 
160  ImageEntry = ImageListHead.Flink;
161  while (ImageEntry != &ImageListHead)
162  {
163  CurrentImage = CONTAINING_RECORD(ImageEntry,
165  ImageListEntry);
166  if (_wcsicmp(CurrentImage->pszImagePath, lpImagePath) == 0)
167  {
168  DPRINT("Found image: '%S'\n", CurrentImage->pszImagePath);
169  return CurrentImage;
170  }
171 
172  ImageEntry = ImageEntry->Flink;
173  }
174 
175  DPRINT("Couldn't find a matching image\n");
176 
177  return NULL;
178 
179 }
LIST_ENTRY ImageListHead
Definition: database.c:28
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
Definition: typedefs.h:117
LPWSTR pszImagePath
Definition: services.h:47
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

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 183 of file database.c.

185 {
186  PLIST_ENTRY ServiceEntry;
187  PSERVICE CurrentService;
188  PSERVICE_IMAGE CurrentImage;
190  DWORD dwError;
191 
192  /* Lock the database */
194 
195  /* Find the matching service */
196  ServiceEntry = ServiceListHead.Flink;
197  while (ServiceEntry != &ServiceListHead)
198  {
199  CurrentService = CONTAINING_RECORD(ServiceEntry,
200  SERVICE,
201  ServiceListEntry);
202 
203  /* We must match the tag */
204  if (CurrentService->dwTag == InParams->dwTag &&
205  CurrentService->lpImage != NULL)
206  {
207  CurrentImage = CurrentService->lpImage;
208  /* And matching the PID */
209  if (CurrentImage->dwProcessId == InParams->dwPid)
210  {
211  break;
212  }
213  }
214 
215  ServiceEntry = ServiceEntry->Flink;
216  }
217 
218  /* No match! */
219  if (ServiceEntry == &ServiceListHead)
220  {
221  dwError = ERROR_RETRY;
222  goto Cleanup;
223  }
224 
225  /* Allocate the output buffer */
227  if (OutBuffer == NULL)
228  {
229  dwError = ERROR_NOT_ENOUGH_MEMORY;
230  goto Cleanup;
231  }
232 
233  /* And the buffer for the name */
234  OutBuffer->pszName = MIDL_user_allocate(wcslen(CurrentService->lpServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
235  if (OutBuffer->pszName == NULL)
236  {
237  dwError = ERROR_NOT_ENOUGH_MEMORY;
238  goto Cleanup;
239  }
240 
241  /* Fill in output data */
242  wcscpy(OutBuffer->pszName, CurrentService->lpServiceName);
243  OutBuffer->TagType = TagTypeService;
244 
245  /* And return */
246  *OutParams = OutBuffer;
247  dwError = ERROR_SUCCESS;
248 
249 Cleanup:
250 
251  /* Unlock database */
253 
254  /* If failure, free allocated memory */
255  if (dwError != ERROR_SUCCESS)
256  {
257  if (OutBuffer != NULL)
258  {
259  MIDL_user_free(OutBuffer);
260  }
261  }
262 
263  /* Return error/success */
264  return dwError;
265 }
DWORD dwProcessId
Definition: services.h:53
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2420
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
LIST_ENTRY ServiceListHead
Definition: database.c:29
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
LPWSTR lpServiceName
Definition: services.h:62
Definition: typedefs.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERROR_RETRY
Definition: winerror.h:740
DWORD dwTag
Definition: services.h:73
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2434
void *__RPC_USER MIDL_user_allocate(SIZE_T size)
Definition: irotp.c:371
PSERVICE_IMAGE lpImage
Definition: services.h:65
void __RPC_USER MIDL_user_free(void *p)
Definition: irotp.c:376
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)

Referenced by RI_ScQueryServiceTagInfo().

◆ ScmInitNamedPipeCriticalSection()

VOID ScmInitNamedPipeCriticalSection ( VOID  )

Definition at line 2441 of file database.c.

2442 {
2443  HKEY hKey;
2444  DWORD dwKeySize;
2445  DWORD dwError;
2446 
2448 
2450  L"SYSTEM\\CurrentControlSet\\Control",
2451  0,
2452  KEY_READ,
2453  &hKey);
2454  if (dwError == ERROR_SUCCESS)
2455  {
2456  dwKeySize = sizeof(PipeTimeout);
2457  RegQueryValueExW(hKey,
2458  L"ServicesPipeTimeout",
2459  0,
2460  NULL,
2461  (LPBYTE)&PipeTimeout,
2462  &dwKeySize);
2463  RegCloseKey(hKey);
2464  }
2465 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
static CRITICAL_SECTION ControlServiceCriticalSection
Definition: database.c:37
smooth NULL
Definition: ftsmooth.c:416
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
static DWORD PipeTimeout
Definition: database.c:38
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by wWinMain().

◆ ScmIsLocalSystemAccount()

static BOOL ScmIsLocalSystemAccount ( _In_ PCWSTR  pszAccountName)
static

Definition at line 299 of file database.c.

301 {
302  if (pszAccountName == NULL ||
303  _wcsicmp(pszAccountName, L"LocalSystem") == 0)
304  return TRUE;
305 
306  return FALSE;
307 }
#define TRUE
Definition: types.h:120
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR L[]
Definition: oid.c:1250
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

Referenced by ScmLogonService().

◆ ScmIsSameServiceAccount()

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

Definition at line 270 of file database.c.

273 {
274  if (pszAccountName1 == NULL &&
275  pszAccountName2 == NULL)
276  return TRUE;
277 
278  if (pszAccountName1 == NULL &&
279  pszAccountName2 != NULL &&
280  _wcsicmp(pszAccountName2, L"LocalSystem") == 0)
281  return TRUE;
282 
283  if (pszAccountName1 != NULL &&
284  pszAccountName2 == NULL &&
285  _wcsicmp(pszAccountName1, L"LocalSystem") == 0)
286  return TRUE;
287 
288  if (pszAccountName1 != NULL &&
289  pszAccountName2 != NULL &&
290  _wcsicmp(pszAccountName1, pszAccountName2) == 0)
291  return TRUE;
292 
293  return FALSE;
294 }
#define TRUE
Definition: types.h:120
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR L[]
Definition: oid.c:1250
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

Referenced by ScmCreateOrReferenceServiceImage().

◆ ScmIsSecurityService()

static BOOL ScmIsSecurityService ( _In_ PSERVICE_IMAGE  pServiceImage)
static

Definition at line 45 of file database.c.

47 {
48  return (wcsstr(pServiceImage->pszImagePath, L"\\system32\\lsass.exe") != NULL);
49 }
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR L[]
Definition: oid.c:1250

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

◆ ScmLoadService()

static DWORD ScmLoadService ( PSERVICE  Service,
DWORD  argc,
LPWSTR argv 
)
static

Definition at line 2019 of file database.c.

2022 {
2023  PSERVICE_GROUP Group = Service->lpGroup;
2024  DWORD dwError = ERROR_SUCCESS;
2025  LPCWSTR lpLogStrings[2];
2026  WCHAR szLogBuffer[80];
2027 
2028  DPRINT("ScmLoadService() called\n");
2029  DPRINT("Start Service %p (%S)\n", Service, Service->lpServiceName);
2030 
2031  if (Service->Status.dwCurrentState != SERVICE_STOPPED)
2032  {
2033  DPRINT("Service %S is already running!\n", Service->lpServiceName);
2035  }
2036 
2037  DPRINT("Service->Type: %lu\n", Service->Status.dwServiceType);
2038 
2039  if (Service->Status.dwServiceType & SERVICE_DRIVER)
2040  {
2041  /* Start the driver */
2042  dwError = ScmStartDriver(Service);
2043  }
2044  else // if (Service->Status.dwServiceType & (SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS))
2045  {
2046  /* Start user-mode service */
2048  if (dwError == ERROR_SUCCESS)
2049  {
2051  if (dwError == ERROR_SUCCESS)
2052  {
2053  Service->Status.dwCurrentState = SERVICE_START_PENDING;
2054  Service->Status.dwControlsAccepted = 0;
2055  }
2056  else
2057  {
2058  Service->lpImage->dwImageRunCount--;
2059  if (Service->lpImage->dwImageRunCount == 0)
2060  {
2061  ScmRemoveServiceImage(Service->lpImage);
2062  Service->lpImage = NULL;
2063  }
2064  }
2065  }
2066  }
2067 
2068  DPRINT("ScmLoadService() done (Error %lu)\n", dwError);
2069 
2070  if (dwError == ERROR_SUCCESS)
2071  {
2072  if (Group != NULL)
2073  {
2074  Group->ServicesRunning = TRUE;
2075  }
2076 
2077  /* Log a successful service start */
2078  LoadStringW(GetModuleHandle(NULL), IDS_SERVICE_START, szLogBuffer, 80);
2079  lpLogStrings[0] = Service->lpDisplayName;
2080  lpLogStrings[1] = szLogBuffer;
2081 
2084  2,
2085  lpLogStrings);
2086  }
2087  else
2088  {
2089  if (Service->dwErrorControl != SERVICE_ERROR_IGNORE)
2090  {
2091  /* Log a failed service start */
2092  StringCchPrintfW(szLogBuffer, ARRAYSIZE(szLogBuffer),
2093  L"%lu", dwError);
2094  lpLogStrings[0] = Service->lpServiceName;
2095  lpLogStrings[1] = szLogBuffer;
2098  2,
2099  lpLogStrings);
2100  }
2101 
2102 #if 0
2103  switch (Service->dwErrorControl)
2104  {
2105  case SERVICE_ERROR_SEVERE:
2106  if (IsLastKnownGood == FALSE)
2107  {
2108  /* FIXME: Boot last known good configuration */
2109  }
2110  break;
2111 
2113  if (IsLastKnownGood == FALSE)
2114  {
2115  /* FIXME: Boot last known good configuration */
2116  }
2117  else
2118  {
2119  /* FIXME: BSOD! */
2120  }
2121  break;
2122  }
2123 #endif
2124  }
2125 
2126  return dwError;
2127 }
static int argc
Definition: ServiceArgs.c:12
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:979
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
_In_opt_ PSID Group
Definition: rtlfuncs.h:1606
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define argv
Definition: mplay32.c:18
DWORD ScmStartDriver(PSERVICE pService)
Definition: driver.c:314
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define IDS_SERVICE_START
Definition: resource.h:3
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define EVENTLOG_ERROR_TYPE
Definition: winnt_old.h:2630
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define EVENT_SERVICE_START_FAILED
Definition: netevent.h:444
VOID ScmLogEvent(DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings)
Definition: services.c:85
#define EVENTLOG_INFORMATION_TYPE
Definition: winnt_old.h:2632
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define EVENT_SERVICE_CONTROL_SUCCESS
Definition: netevent.h:432
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
#define GetModuleHandle
Definition: winbase.h:3651
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define SERVICE_ERROR_SEVERE
Definition: cmtypes.h:981
static DWORD ScmCreateOrReferenceServiceImage(PSERVICE pService)
Definition: database.c:458
static DWORD ScmStartUserModeService(PSERVICE Service, DWORD argc, LPWSTR *argv)
Definition: database.c:1873
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:982
#define SERVICE_DRIVER
Definition: cmtypes.h:956
#define ERROR_SERVICE_ALREADY_RUNNING
Definition: winerror.h:607
VOID ScmRemoveServiceImage(PSERVICE_IMAGE pServiceImage)
Definition: database.c:622

Referenced by ScmAutoStartServices(), and ScmStartService().

◆ ScmLockDatabaseExclusive()

BOOL ScmLockDatabaseExclusive ( VOID  )

Definition at line 2420 of file database.c.

2421 {
2423 }
#define TRUE
Definition: types.h:120
static RTL_RESOURCE DatabaseLock
Definition: database.c:31
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)

Referenced by RChangeServiceConfig2W(), RChangeServiceConfigW(), RCloseServiceHandle(), RCreateServiceW(), RDeleteService(), ROpenServiceW(), RSetServiceObjectSecurity(), RSetServiceStatus(), ScmAcquireServiceStartLock(), ScmAutoShutdownServices(), ScmGetServiceNameFromTag(), and ScmReleaseServiceStartLock().

◆ ScmLockDatabaseShared()

BOOL ScmLockDatabaseShared ( VOID  )

Definition at line 2427 of file database.c.

2428 {
2430 }
#define TRUE
Definition: types.h:120
static RTL_RESOURCE DatabaseLock
Definition: database.c:31
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceShared(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)

Referenced by REnumServiceGroupW(), REnumServicesStatusExW(), RI_ScGetCurrentGroupStateW(), RQueryServiceConfig2A(), RQueryServiceConfig2W(), RQueryServiceConfigA(), RQueryServiceConfigW(), RQueryServiceObjectSecurity(), RQueryServiceStatus(), RQueryServiceStatusEx(), ScmQueryServiceLockStatusA(), and ScmQueryServiceLockStatusW().

◆ ScmLogonService()

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

Definition at line 359 of file database.c.

362 {
363  PROFILEINFOW ProfileInfo;
364  PWSTR pszUserName = NULL;
365  PWSTR pszDomainName = NULL;
366  PWSTR pszPassword = NULL;
367  PWSTR ptr;
368  DWORD dwError = ERROR_SUCCESS;
369 
370  DPRINT("ScmLogonService(%p %p)\n", pService, pImage);
371  DPRINT("Service %S\n", pService->lpServiceName);
372 
373  if (ScmIsLocalSystemAccount(pImage->pszAccountName))
374  return ERROR_SUCCESS;
375 
376  /* Get the user and domain names */
377  ptr = wcschr(pImage->pszAccountName, L'\\');
378  if (ptr != NULL)
379  {
380  *ptr = L'\0';
381  pszUserName = ptr + 1;
382  pszDomainName = pImage->pszAccountName;
383  }
384  else
385  {
386  // ERROR_INVALID_SERVICE_ACCOUNT
387  pszUserName = pImage->pszAccountName;
388  pszDomainName = NULL;
389  }
390 
391  /* Build the service 'password' */
392  pszPassword = HeapAlloc(GetProcessHeap(),
394  (wcslen(pService->lpServiceName) + 5) * sizeof(WCHAR));
395  if (pszPassword == NULL)
396  {
397  dwError = ERROR_NOT_ENOUGH_MEMORY;
398  goto done;
399  }
400 
401  wcscpy(pszPassword, L"_SC_");
402  wcscat(pszPassword, pService->lpServiceName);
403 
404  DPRINT("Domain: %S User: %S Password: %S\n", pszDomainName, pszUserName, pszPassword);
405 
406  /* Do the service logon */
407  if (!LogonUserW(pszUserName,
408  pszDomainName,
409  pszPassword,
412  &pImage->hToken))
413  {
414  dwError = GetLastError();
415  DPRINT1("LogonUserW() failed (Error %lu)\n", dwError);
416 
417  /* Normalize the returned error */
418  dwError = ERROR_SERVICE_LOGON_FAILED;
419  goto done;
420  }
421 
422  /* Load the user profile; the per-user environment variables are thus correctly initialized */
423  ZeroMemory(&ProfileInfo, sizeof(ProfileInfo));
424  ProfileInfo.dwSize = sizeof(ProfileInfo);
425  ProfileInfo.dwFlags = PI_NOUI;
426  ProfileInfo.lpUserName = pszUserName;
427  // ProfileInfo.lpProfilePath = NULL;
428  // ProfileInfo.lpDefaultPath = NULL;
429  // ProfileInfo.lpServerName = NULL;
430  // ProfileInfo.lpPolicyPath = NULL;
431  // ProfileInfo.hProfile = NULL;
432 
433  ScmEnableBackupRestorePrivileges(pImage->hToken, TRUE);
434  if (!LoadUserProfileW(pImage->hToken, &ProfileInfo))
435  dwError = GetLastError();
436  ScmEnableBackupRestorePrivileges(pImage->hToken, FALSE);
437 
438  if (dwError != ERROR_SUCCESS)
439  {
440  DPRINT1("LoadUserProfileW() failed (Error %lu)\n", dwError);
441  goto done;
442  }
443 
444  pImage->hProfile = ProfileInfo.hProfile;
445 
446 done:
447  if (pszPassword != NULL)
448  HeapFree(GetProcessHeap(), 0, pszPassword);
449 
450  if (ptr != NULL)
451  *ptr = L'\\';
452 
453  return dwError;
454 }
#define TRUE
Definition: types.h:120
HANDLE hProfile
Definition: userenv.h:43
#define ERROR_SUCCESS
Definition: deptool.c:10
uint16_t * PWSTR
Definition: typedefs.h:54
static BOOL ScmEnableBackupRestorePrivileges(_In_ HANDLE hToken, _In_ BOOL bEnable)
Definition: database.c:312
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
LPWSTR lpUserName
Definition: userenv.h:38
static BOOL ScmIsLocalSystemAccount(_In_ PCWSTR pszAccountName)
Definition: database.c:299
static PVOID ptr
Definition: dispmode.c:27
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:423
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define LOGON32_LOGON_SERVICE
Definition: winbase.h:375
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD dwSize
Definition: userenv.h:36
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
DWORD dwFlags
Definition: userenv.h:37
#define ERROR_SERVICE_LOGON_FAILED
Definition: winerror.h:620
#define PI_NOUI
Definition: userenv.h:8
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
BOOL WINAPI LoadUserProfileW(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOW lpProfileInfo)
Definition: profile.c:1922
#define LOGON32_PROVIDER_DEFAULT
Definition: winbase.h:368
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by ScmCreateOrReferenceServiceImage().

◆ ScmRemoveServiceImage()

VOID ScmRemoveServiceImage ( PSERVICE_IMAGE  pServiceImage)

Definition at line 622 of file database.c.

623 {
624  DPRINT1("ScmRemoveServiceImage() called\n");
625 
626  /* FIXME: Terminate the process */
627 
628  /* Remove the service image from the list */
629  RemoveEntryList(&pServiceImage->ImageListEntry);
630 
631  /* Close the process handle */
632  if (pServiceImage->hProcess != INVALID_HANDLE_VALUE)
633  CloseHandle(pServiceImage->hProcess);
634 
635  /* Close the control pipe */
636  if (pServiceImage->hControlPipe != INVALID_HANDLE_VALUE)
637  CloseHandle(pServiceImage->hControlPipe);
638 
639  /* Unload the user profile */
640  if (pServiceImage->hProfile != NULL)
641  {
643  UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile);
645  }
646 
647  /* Close the logon token */
648  if (pServiceImage->hToken != NULL)
649  CloseHandle(pServiceImage->hToken);
650 
651  /* Release the service image */
652  HeapFree(GetProcessHeap(), 0, pServiceImage);
653 }
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
HANDLE hToken
Definition: services.h:54
LIST_ENTRY ImageListEntry
Definition: services.h:46
static BOOL ScmEnableBackupRestorePrivileges(_In_ HANDLE hToken, _In_ BOOL bEnable)
Definition: database.c:312
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2101
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:395
HANDLE hProfile
Definition: services.h:55
#define DPRINT1
Definition: precomp.h:8
HANDLE hProcess
Definition: services.h:52
HANDLE hControlPipe
Definition: services.h:51
#define HeapFree(x, y, z)
Definition: compat.h:394

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

◆ ScmSendStartCommand()

static DWORD ScmSendStartCommand ( PSERVICE  Service,
DWORD  argc,
LPWSTR argv 
)
static

Definition at line 1485 of file database.c.

1488 {
1489  DWORD dwError = ERROR_SUCCESS;
1490  PSCM_CONTROL_PACKET ControlPacket;
1491  SCM_REPLY_PACKET ReplyPacket;
1492  DWORD PacketSize;
1493  DWORD i;
1494  PWSTR Ptr;
1495  PWSTR *pOffPtr;
1496  PWSTR pArgPtr;
1497  BOOL bResult;
1498  DWORD dwWriteCount = 0;
1499  DWORD dwReadCount = 0;
1500  OVERLAPPED Overlapped = {0};
1501 
1502  DPRINT("ScmSendStartCommand() called\n");
1503 
1504  /* Calculate the total length of the start command line */
1505  PacketSize = sizeof(SCM_CONTROL_PACKET);
1506  PacketSize += (DWORD)((wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR));
1507 
1508  /*
1509  * Calculate the required packet size for the start argument vector 'argv',
1510  * composed of the list of pointer offsets, followed by UNICODE strings.
1511  * The strings are stored continuously after the vector of offsets, with
1512  * the offsets being relative to the beginning of the vector, as in the
1513  * following layout (with N == argc):
1514  * [argOff(0)]...[argOff(N-1)][str(0)]...[str(N-1)] .
1515  */
1516  if (argc > 0 && argv != NULL)
1517  {
1519  PacketSize += (argc * sizeof(PWSTR));
1520 
1521  DPRINT("Argc: %lu\n", argc);
1522  for (i = 0; i < argc; i++)
1523  {
1524  DPRINT("Argv[%lu]: %S\n", i, argv[i]);
1525  PacketSize += (DWORD)((wcslen(argv[i]) + 1) * sizeof(WCHAR));
1526  }
1527  }
1528 
1529  /* Allocate a control packet */
1530  ControlPacket = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PacketSize);
1531  if (ControlPacket == NULL)
1532  return ERROR_NOT_ENOUGH_MEMORY;
1533 
1534  ControlPacket->dwSize = PacketSize;
1535  ControlPacket->dwControl = (Service->Status.dwServiceType & SERVICE_WIN32_OWN_PROCESS)
1538  ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
1539  ControlPacket->dwServiceTag = Service->dwTag;
1540 
1541  /* Copy the start command line */
1542  ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
1543  Ptr = (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset);
1544  wcscpy(Ptr, Service->lpServiceName);
1545 
1546  ControlPacket->dwArgumentsCount = 0;
1547  ControlPacket->dwArgumentsOffset = 0;
1548 
1549  /* Copy the argument vector */
1550  if (argc > 0 && argv != NULL)
1551  {
1552  Ptr += wcslen(Service->lpServiceName) + 1;
1553  pOffPtr = (PWSTR*)ALIGN_UP_POINTER(Ptr, PWSTR);
1554  pArgPtr = (PWSTR)((ULONG_PTR)pOffPtr + argc * sizeof(PWSTR));
1555 
1556  ControlPacket->dwArgumentsCount = argc;
1557  ControlPacket->dwArgumentsOffset = (DWORD)((ULONG_PTR)pOffPtr - (ULONG_PTR)ControlPacket);
1558 
1559  DPRINT("dwArgumentsCount: %lu\n", ControlPacket->dwArgumentsCount);
1560  DPRINT("dwArgumentsOffset: %lu\n", ControlPacket->dwArgumentsOffset);
1561 
1562  for (i = 0; i < argc; i++)
1563  {
1564  wcscpy(pArgPtr, argv[i]);
1565  pOffPtr[i] = (PWSTR)((ULONG_PTR)pArgPtr - (ULONG_PTR)pOffPtr);
1566  DPRINT("offset[%lu]: %p\n", i, pOffPtr[i]);
1567  pArgPtr += wcslen(argv[i]) + 1;
1568  }
1569  }
1570 
1571  bResult = WriteFile(Service->lpImage->hControlPipe,
1572  ControlPacket,
1573  PacketSize,
1574  &dwWriteCount,
1575  &Overlapped);
1576  if (bResult == FALSE)
1577  {
1578  DPRINT("WriteFile() returned FALSE\n");
1579 
1580  dwError = GetLastError();
1581  if (dwError == ERROR_IO_PENDING)
1582  {
1583  DPRINT("dwError: ERROR_IO_PENDING\n");
1584 
1585  dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1586  PipeTimeout);
1587  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1588 
1589  if (dwError == WAIT_TIMEOUT)
1590  {
1591  bResult = CancelIo(Service->lpImage->hControlPipe);
1592  if (bResult == FALSE)
1593  {
1594  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1595  }
1596 
1598  goto Done;
1599  }
1600  else if (dwError == WAIT_OBJECT_0)
1601  {
1602  bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1603  &Overlapped,
1604  &dwWriteCount,
1605  TRUE);
1606  if (bResult == FALSE)
1607  {
1608  dwError = GetLastError();
1609  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1610 
1611  goto Done;
1612  }
1613  }
1614  }
1615  else
1616  {
1617  DPRINT1("WriteFile() failed (Error %lu)\n", dwError);
1618  goto Done;
1619  }
1620  }
1621 
1622  /* Read the reply */
1623  Overlapped.hEvent = (HANDLE) NULL;
1624 
1625  bResult = ReadFile(Service->lpImage->hControlPipe,
1626  &ReplyPacket,
1627  sizeof(SCM_REPLY_PACKET),
1628  &dwReadCount,
1629  &Overlapped);
1630  if (bResult == FALSE)
1631  {
1632  DPRINT("ReadFile() returned FALSE\n");
1633 
1634  dwError = GetLastError();
1635  if (dwError == ERROR_IO_PENDING)
1636  {
1637  DPRINT("dwError: ERROR_IO_PENDING\n");
1638 
1639  dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1640  PipeTimeout);
1641  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1642 
1643  if (dwError == WAIT_TIMEOUT)
1644  {
1645  bResult = CancelIo(Service->lpImage->hControlPipe);
1646  if (bResult == FALSE)
1647  {
1648  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1649  }
1650 
1652  goto Done;
1653  }
1654  else if (dwError == WAIT_OBJECT_0)
1655  {
1656  bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1657  &Overlapped,
1658  &dwReadCount,
1659  TRUE);
1660  if (bResult == FALSE)
1661  {
1662  dwError = GetLastError();
1663  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1664 
1665  goto Done;
1666  }
1667  }
1668  }
1669  else
1670  {
1671  DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
1672  goto Done;
1673  }
1674  }
1675 
1676 Done:
1677  /* Release the control packet */
1679  0,
1680  ControlPacket);
1681 
1682  if (dwReadCount == sizeof(SCM_REPLY_PACKET))
1683  {
1684  dwError = ReplyPacket.dwError;
1685  }
1686 
1687  DPRINT("ScmSendStartCommand() done\n");
1688 
1689  return dwError;
1690 }
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static int argc
Definition: ServiceArgs.c:12
DWORD dwServiceNameOffset
Definition: services.h:35
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
SERVICE_STATUS_HANDLE hServiceStatus
Definition: services.h:34
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
uint16_t * PWSTR
Definition: typedefs.h:54
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define ERROR_SERVICE_REQUEST_TIMEOUT
Definition: winerror.h:604
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define SERVICE_CONTROL_START_SHARE
Definition: services.h:18
#define argv
Definition: mplay32.c:18
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define DWORD
Definition: nt_native.h:44
uint32_t ULONG_PTR
Definition: typedefs.h:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
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
unsigned int BOOL
Definition: ntddk_ex.h:94
HANDLE hEvent
Definition: winbase.h:792
BOOL WINAPI CancelIo(IN HANDLE hFile)
Definition: deviceio.c:290
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
DWORD dwArgumentsCount
Definition: services.h:32
#define SERVICE_CONTROL_START_OWN
Definition: services.h:20
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:960
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
#define WAIT_OBJECT_0
Definition: winbase.h:387
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
PVOID HANDLE
Definition: typedefs.h:71
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_TIMEOUT
Definition: dderror.h:14
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static DWORD PipeTimeout
Definition: database.c:38
DWORD dwArgumentsOffset
Definition: services.h:36
_In_ USHORT PacketSize
Definition: iofuncs.h:1056
#define ALIGN_UP_POINTER(ptr, type)
Definition: umtypes.h:97
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
#define ULONG_PTR
Definition: config.h:101
struct _SCM_CONTROL_PACKET SCM_CONTROL_PACKET
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by ScmStartUserModeService().

◆ ScmShutdownServiceDatabase()

VOID ScmShutdownServiceDatabase ( VOID  )

Definition at line 1175 of file database.c.

1176 {
1177  DPRINT("ScmShutdownServiceDatabase() called\n");
1178 
1181 
1182  DPRINT("ScmShutdownServiceDatabase() done\n");
1183 }
NTSYSAPI VOID NTAPI RtlDeleteResource(_In_ PRTL_RESOURCE Resource)
static RTL_RESOURCE DatabaseLock
Definition: database.c:31
void DPRINT(...)
Definition: polytest.cpp:61
VOID ScmDeleteMarkedServices(VOID)
Definition: database.c:1021

Referenced by ShutdownHandlerRoutine().

◆ ScmStartService()

DWORD ScmStartService ( PSERVICE  Service,
DWORD  argc,
LPWSTR argv 
)

Definition at line 2131 of file database.c.

2134 {
2135  DWORD dwError = ERROR_SUCCESS;
2136  SC_RPC_LOCK Lock = NULL;
2137 
2138  DPRINT("ScmStartService() called\n");
2139  DPRINT("Start Service %p (%S)\n", Service, Service->lpServiceName);
2140 
2141  /* Acquire the service control critical section, to synchronize starts */
2143 
2144  /*
2145  * Acquire the user service start lock while the service is starting, if
2146  * needed (i.e. if we are not starting it during the initialization phase).
2147  * If we don't success, bail out.
2148  */
2149  if (!ScmInitialize)
2150  {
2151  dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
2152  if (dwError != ERROR_SUCCESS) goto done;
2153  }
2154 
2155  /* Really start the service */
2156  dwError = ScmLoadService(Service, argc, argv);
2157 
2158  /* Release the service start lock, if needed, and the critical section */
2160 
2161 done:
2163 
2164  DPRINT("ScmStartService() done (Error %lu)\n", dwError);
2165 
2166  return dwError;
2167 }
static int argc
Definition: ServiceArgs.c:12
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL ScmInitialize
Definition: services.c:28
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define argv
Definition: mplay32.c:18
DWORD ScmAcquireServiceStartLock(IN BOOL IsServiceController, OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:31
static CRITICAL_SECTION ControlServiceCriticalSection
Definition: database.c:37
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static DWORD ScmLoadService(PSERVICE Service, DWORD argc, LPWSTR *argv)
Definition: database.c:2019
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD ScmReleaseServiceStartLock(IN OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:82
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

Referenced by RStartServiceA(), and RStartServiceW().

◆ ScmStartUserModeService()

static DWORD ScmStartUserModeService ( PSERVICE  Service,
DWORD  argc,
LPWSTR argv 
)
static

Definition at line 1873 of file database.c.

1876 {
1877  PROCESS_INFORMATION ProcessInformation;
1878  STARTUPINFOW StartupInfo;
1879  LPVOID lpEnvironment;
1880  BOOL Result;
1881  DWORD dwError = ERROR_SUCCESS;
1882 
1883  DPRINT("ScmStartUserModeService(%p)\n", Service);
1884 
1885  /* If the image is already running ... */
1886  if (Service->lpImage->dwImageRunCount > 1)
1887  {
1888  /* ... just send a start command */
1890  }
1891 
1892  /* Otherwise start its process */
1893  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
1894  StartupInfo.cb = sizeof(StartupInfo);
1895  ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
1896 
1897  if (Service->lpImage->hToken)
1898  {
1899  /* User token: Run the service under the user account */
1900 
1901  if (!CreateEnvironmentBlock(&lpEnvironment, Service->lpImage->hToken, FALSE))
1902  {
1903  /* We failed, run the service with the current environment */
1904  DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with the current environment.\n",
1905  GetLastError(), Service->lpServiceName);
1906  lpEnvironment = NULL;
1907  }
1908 
1909  /* Impersonate the new user */
1910  Result = ImpersonateLoggedOnUser(Service->lpImage->hToken);
1911  if (Result)
1912  {
1913  /* Launch the process in the user's logon session */
1914  Result = CreateProcessAsUserW(Service->lpImage->hToken,
1915  NULL,
1916  Service->lpImage->pszImagePath,
1917  NULL,
1918  NULL,
1919  FALSE,
1921  lpEnvironment,
1922  NULL,
1923  &StartupInfo,
1924  &ProcessInformation);
1925  if (!Result)
1926  dwError = GetLastError();
1927 
1928  /* Revert the impersonation */
1929  RevertToSelf();
1930  }
1931  else
1932  {
1933  dwError = GetLastError();
1934  DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", dwError);
1935  }
1936  }
1937  else
1938  {
1939  /* No user token: Run the service under the LocalSystem account */
1940 
1941  if (!CreateEnvironmentBlock(&lpEnvironment, NULL, TRUE))
1942  {
1943  /* We failed, run the service with the current environment */
1944  DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with the current environment.\n",
1945  GetLastError(), Service->lpServiceName);
1946  lpEnvironment = NULL;
1947  }
1948 
1949  /* Use the interactive desktop if the service is interactive */
1950  if ((NoInteractiveServices == 0) &&
1951  (Service->Status.dwServiceType & SERVICE_INTERACTIVE_PROCESS))
1952  {
1953  StartupInfo.dwFlags |= STARTF_INHERITDESKTOP;
1954  StartupInfo.lpDesktop = L"WinSta0\\Default";
1955  }
1956 
1957  if (!ScmIsSecurityService(Service->lpImage))
1958  {
1960  Service->lpImage->pszImagePath,
1961  NULL,
1962  NULL,
1963  FALSE,
1965  lpEnvironment,
1966  NULL,
1967  &StartupInfo,
1968  &ProcessInformation);
1969  if (!Result)
1970  dwError = GetLastError();
1971  }
1972  else
1973  {
1974  Result = TRUE;
1975  dwError = ERROR_SUCCESS;
1976  }
1977  }
1978 
1979  if (lpEnvironment)
1980  DestroyEnvironmentBlock(lpEnvironment);
1981 
1982  if (!Result)
1983  {
1984  DPRINT1("Starting '%S' failed with error %d\n",
1985  Service->lpServiceName, dwError);
1986  return dwError;
1987  }
1988 
1989  DPRINT("Process Id: %lu Handle %p\n",
1990  ProcessInformation.dwProcessId,
1991  ProcessInformation.hProcess);
1992  DPRINT("Thread Id: %lu Handle %p\n",
1993  ProcessInformation.dwThreadId,
1994  ProcessInformation.hThread);
1995 
1996  /* Get the process handle and ID */
1997  Service->lpImage->hProcess = ProcessInformation.hProcess;
1998  Service->lpImage->dwProcessId = ProcessInformation.dwProcessId;
1999 
2000  /* Resume the main thread and close its handle */
2001  ResumeThread(ProcessInformation.hThread);
2002  CloseHandle(ProcessInformation.hThread);
2003 
2004  /* Connect control pipe */
2005  dwError = ScmWaitForServiceConnect(Service);
2006  if (dwError != ERROR_SUCCESS)
2007  {
2008  DPRINT1("Connecting control pipe failed! (Error %lu)\n", dwError);
2009  Service->lpImage->dwProcessId = 0;
2010  return dwError;
2011  }
2012 
2013  /* Send the start command */
2015 }
static int argc
Definition: ServiceArgs.c:12
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define ERROR_SUCCESS
Definition: deptool.c:10
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:186
BOOL WINAPI RevertToSelf(VOID)
Definition: security.c:1487
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:965
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
BOOL WINAPI CreateEnvironmentBlock(OUT LPVOID *lpEnvironment, IN HANDLE hToken, IN BOOL bInherit)
Definition: environment.c:505
#define argv
Definition: mplay32.c:18
#define CREATE_SUSPENDED
Definition: winbase.h:178
unsigned int BOOL
Definition: ntddk_ex.h:94
LPWSTR lpDesktop
Definition: winbase.h:826
#define STARTF_INHERITDESKTOP
Definition: undocuser.h:162
smooth NULL
Definition: ftsmooth.c:416
_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:426
void DPRINT(...)
Definition: polytest.cpp:61
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:4593
DWORD cb
Definition: winbase.h:824
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
BOOL WINAPI DestroyEnvironmentBlock(IN LPVOID lpEnvironment)
Definition: environment.c:727
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:281
static DWORD ScmSendStartCommand(PSERVICE Service, DWORD argc, LPWSTR *argv)
Definition: database.c:1485
#define DETACHED_PROCESS
Definition: winbase.h:179
#define DPRINT1
Definition: precomp.h:8
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:566
DWORD dwFlags
Definition: winbase.h:835
static DWORD ScmWaitForServiceConnect(PSERVICE Service)
Definition: database.c:1694
static DWORD NoInteractiveServices
Definition: database.c:33
static BOOL ScmIsSecurityService(_In_ PSERVICE_IMAGE pServiceImage)
Definition: database.c:45

Referenced by ScmLoadService().

◆ ScmUnlockDatabase()

◆ ScmWaitForServiceConnect()

static DWORD ScmWaitForServiceConnect ( PSERVICE  Service)
static

Definition at line 1694 of file database.c.

1695 {
1696  DWORD dwRead = 0;
1697  DWORD dwProcessId = 0;
1698  DWORD dwError = ERROR_SUCCESS;
1699  BOOL bResult;
1700  OVERLAPPED Overlapped = {0};
1701 #if 0
1702  LPCWSTR lpLogStrings[3];
1703  WCHAR szBuffer1[20];
1704  WCHAR szBuffer2[20];
1705 #endif
1706 
1707  DPRINT("ScmWaitForServiceConnect()\n");
1708 
1709  Overlapped.hEvent = (HANDLE)NULL;
1710 
1711  bResult = ConnectNamedPipe(Service->lpImage->hControlPipe,
1712  &Overlapped);
1713  if (bResult == FALSE)
1714  {
1715  DPRINT("ConnectNamedPipe() returned FALSE\n");
1716 
1717  dwError = GetLastError();
1718  if (dwError == ERROR_IO_PENDING)
1719  {
1720  DPRINT("dwError: ERROR_IO_PENDING\n");
1721 
1722  dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1723  PipeTimeout);
1724  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1725 
1726  if (dwError == WAIT_TIMEOUT)
1727  {
1728  DPRINT("WaitForSingleObject() returned WAIT_TIMEOUT\n");
1729 
1730  bResult = CancelIo(Service->lpImage->hControlPipe);
1731  if (bResult == FALSE)
1732  {
1733  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1734  }
1735 
1736 #if 0
1737  _ultow(PipeTimeout, szBuffer1, 10);
1738  lpLogStrings[0] = Service->lpDisplayName;
1739  lpLogStrings[1] = szBuffer1;
1740 
1743  2,
1744  lpLogStrings);
1745 #endif
1746  DPRINT1("Log EVENT_CONNECTION_TIMEOUT by %S\n", Service->lpDisplayName);
1747 
1749  }
1750  else if (dwError == WAIT_OBJECT_0)
1751  {
1752  bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1753  &Overlapped,
1754  &dwRead,
1755  TRUE);
1756  if (bResult == FALSE)
1757  {
1758  dwError = GetLastError();
1759  DPRINT1("GetOverlappedResult failed (Error %lu)\n", dwError);
1760 
1761  return dwError;
1762  }
1763  }
1764  }
1765  else if (dwError != ERROR_PIPE_CONNECTED)
1766  {
1767  DPRINT1("ConnectNamedPipe failed (Error %lu)\n", dwError);
1768  return dwError;
1769  }
1770  }
1771 
1772  DPRINT("Control pipe connected!\n");
1773 
1774  Overlapped.hEvent = (HANDLE) NULL;
1775 
1776  /* Read the process id from pipe */
1777  bResult = ReadFile(Service->lpImage->hControlPipe,
1778  (LPVOID)&dwProcessId,
1779  sizeof(DWORD),
1780  &dwRead,
1781  &Overlapped);
1782  if (bResult == FALSE)
1783  {
1784  DPRINT("ReadFile() returned FALSE\n");
1785 
1786  dwError = GetLastError();
1787  if (dwError == ERROR_IO_PENDING)
1788  {
1789  DPRINT("dwError: ERROR_IO_PENDING\n");
1790 
1791  dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1792  PipeTimeout);
1793  if (dwError == WAIT_TIMEOUT)
1794  {
1795  DPRINT("WaitForSingleObject() returned WAIT_TIMEOUT\n");
1796 
1797  bResult = CancelIo(Service->lpImage->hControlPipe);
1798  if (bResult == FALSE)
1799  {
1800  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1801  }
1802 
1803 #if 0
1804  _ultow(PipeTimeout, szBuffer1, 10);
1805  lpLogStrings[0] = szBuffer1;
1806 
1809  1,
1810  lpLogStrings);
1811 #endif
1812  DPRINT1("Log EVENT_READFILE_TIMEOUT by %S\n", Service->lpDisplayName);
1813 
1815  }
1816  else if (dwError == WAIT_OBJECT_0)
1817  {
1818  DPRINT("WaitForSingleObject() returned WAIT_OBJECT_0\n");
1819 
1820  DPRINT("Process Id: %lu\n", dwProcessId);
1821 
1822  bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1823  &Overlapped,
1824  &dwRead,
1825  TRUE);
1826  if (bResult == FALSE)
1827  {
1828  dwError = GetLastError();
1829  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1830 
1831  return dwError;
1832  }
1833  }
1834  else
1835  {
1836  DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
1837  }
1838  }
1839  else
1840  {
1841  DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
1842  return dwError;
1843  }
1844  }
1845 
1846  if ((ScmIsSecurityService(Service->lpImage) == FALSE)&&
1847  (dwProcessId != Service->lpImage->dwProcessId))
1848  {
1849 #if 0
1850  _ultow(Service->lpImage->dwProcessId, szBuffer1, 10);
1851  _ultow(dwProcessId, szBuffer2, 10);
1852 
1853  lpLogStrings[0] = Service->lpDisplayName;
1854  lpLogStrings[1] = szBuffer1;
1855  lpLogStrings[2] = szBuffer2;
1856 
1859  3,
1860  lpLogStrings);
1861 #endif
1862 
1863  DPRINT1("Log EVENT_SERVICE_DIFFERENT_PID_CONNECTED by %S\n", Service->lpDisplayName);
1864  }
1865 
1866  DPRINT("ScmWaitForServiceConnect() done\n");
1867 
1868  return ERROR_SUCCESS;
1869 }
_CRTIMP wchar_t *__cdecl _ultow(_In_ unsigned long _Value, _Pre_notnull_ _Post_z_ wchar_t *_Dest, _In_ int _Radix)
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
#define ERROR_SERVICE_REQUEST_TIMEOUT
Definition: winerror.h:604
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ERROR_IO_PENDING
Definition: dderror.h:15
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define EVENTLOG_ERROR_TYPE
Definition: winnt_old.h:2630
unsigned int BOOL
Definition: ntddk_ex.h:94
HANDLE hEvent
Definition: winbase.h:792
BOOL WINAPI CancelIo(IN HANDLE hFile)
Definition: deviceio.c:290
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define EVENT_READFILE_TIMEOUT
Definition: netevent.h:413
#define WAIT_OBJECT_0
Definition: winbase.h:387
VOID ScmLogEvent(DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings)
Definition: services.c:85
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define EVENTLOG_WARNING_TYPE
Definition: winnt_old.h:2631
PVOID HANDLE
Definition: typedefs.h:71
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_PIPE_CONNECTED
Definition: winerror.h:352
static DWORD PipeTimeout
Definition: database.c:38
#define EVENT_CONNECTION_TIMEOUT
Definition: netevent.h:143
#define DPRINT1
Definition: precomp.h:8
#define EVENT_SERVICE_DIFFERENT_PID_CONNECTED
Definition: netevent.h:435
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
static BOOL ScmIsSecurityService(_In_ PSERVICE_IMAGE pServiceImage)
Definition: database.c:45

Referenced by ScmStartUserModeService().

Variable Documentation

◆ ControlServiceCriticalSection

◆ DatabaseLock

◆ ImageListHead

◆ NoInteractiveServices

DWORD NoInteractiveServices = 0
static

Definition at line 33 of file database.c.

Referenced by ScmGetNoInteractiveServicesValue(), and ScmStartUserModeService().

◆ PipeTimeout

◆ ResumeCount

DWORD ResumeCount = 1
static

Definition at line 32 of file database.c.

Referenced by CreateProcessInternalW(), and ScmCreateNewServiceRecord().

◆ ServiceListHead

◆ ServiceTag

DWORD ServiceTag = 0
static

Definition at line 34 of file database.c.

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