ReactOS  0.4.13-dev-73-gcfe54aa
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 DWORD ScmCreateNewControlPipe (PSERVICE_IMAGE pServiceImage)
 
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 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 756 of file database.c.

758 {
759  PSERVICE lpService = NULL;
761  LPWSTR lpGroup = NULL;
762  DWORD dwSize;
763  DWORD dwError;
764  DWORD dwServiceType;
765  DWORD dwStartType;
766  DWORD dwErrorControl;
767  DWORD dwTagId;
768 
769  DPRINT("Service: '%S'\n", lpServiceName);
770  if (*lpServiceName == L'{')
771  return ERROR_SUCCESS;
772 
773  dwSize = sizeof(DWORD);
774  dwError = RegQueryValueExW(hServiceKey,
775  L"Type",
776  NULL,
777  NULL,
778  (LPBYTE)&dwServiceType,
779  &dwSize);
780  if (dwError != ERROR_SUCCESS)
781  return ERROR_SUCCESS;
782 
783  if (((dwServiceType & ~SERVICE_INTERACTIVE_PROCESS) != SERVICE_WIN32_OWN_PROCESS) &&
785  (dwServiceType != SERVICE_KERNEL_DRIVER) &&
786  (dwServiceType != SERVICE_FILE_SYSTEM_DRIVER))
787  return ERROR_SUCCESS;
788 
789  DPRINT("Service type: %lx\n", dwServiceType);
790 
791  dwSize = sizeof(DWORD);
792  dwError = RegQueryValueExW(hServiceKey,
793  L"Start",
794  NULL,
795  NULL,
796  (LPBYTE)&dwStartType,
797  &dwSize);
798  if (dwError != ERROR_SUCCESS)
799  return ERROR_SUCCESS;
800 
801  DPRINT("Start type: %lx\n", dwStartType);
802 
803  dwSize = sizeof(DWORD);
804  dwError = RegQueryValueExW(hServiceKey,
805  L"ErrorControl",
806  NULL,
807  NULL,
808  (LPBYTE)&dwErrorControl,
809  &dwSize);
810  if (dwError != ERROR_SUCCESS)
811  return ERROR_SUCCESS;
812 
813  DPRINT("Error control: %lx\n", dwErrorControl);
814 
815  dwError = RegQueryValueExW(hServiceKey,
816  L"Tag",
817  NULL,
818  NULL,
819  (LPBYTE)&dwTagId,
820  &dwSize);
821  if (dwError != ERROR_SUCCESS)
822  dwTagId = 0;
823 
824  DPRINT("Tag: %lx\n", dwTagId);
825 
826  dwError = ScmReadString(hServiceKey,
827  L"Group",
828  &lpGroup);
829  if (dwError != ERROR_SUCCESS)
830  lpGroup = NULL;
831 
832  DPRINT("Group: %S\n", lpGroup);
833 
834  dwError = ScmReadString(hServiceKey,
835  L"DisplayName",
836  &lpDisplayName);
837  if (dwError != ERROR_SUCCESS)
839 
840  DPRINT("Display name: %S\n", lpDisplayName);
841 
842  dwError = ScmCreateNewServiceRecord(lpServiceName,
843  &lpService,
844  dwServiceType,
845  dwStartType);
846  if (dwError != ERROR_SUCCESS)
847  goto done;
848 
849  lpService->dwErrorControl = dwErrorControl;
850  lpService->dwTag = dwTagId;
851 
852  if (lpGroup != NULL)
853  {
854  dwError = ScmSetServiceGroup(lpService, lpGroup);
855  if (dwError != ERROR_SUCCESS)
856  goto done;
857  }
858 
859  if (lpDisplayName != NULL)
860  {
861  lpService->lpDisplayName = lpDisplayName;
863  }
864 
865  DPRINT("ServiceName: '%S'\n", lpService->lpServiceName);
866  if (lpService->lpGroup != NULL)
867  {
868  DPRINT("Group: '%S'\n", lpService->lpGroup->lpGroupName);
869  }
870  DPRINT("Start %lx Type %lx Tag %lx ErrorControl %lx\n",
871  lpService->dwStartType,
872  lpService->Status.dwServiceType,
873  lpService->dwTag,
874  lpService->dwErrorControl);
875 
876  if (ScmIsDeleteFlagSet(hServiceKey))
877  lpService->bDeleted = TRUE;
878  else
879  ScmGenerateServiceTag(lpService);
880 
881  if (lpService->Status.dwServiceType & SERVICE_WIN32)
882  {
883  dwError = ScmReadSecurityDescriptor(hServiceKey,
884  &lpService->pSecurityDescriptor);
885  if (dwError != ERROR_SUCCESS)
886  goto done;
887 
888  /* Assing the default security descriptor if the security descriptor cannot be read */
889  if (lpService->pSecurityDescriptor == NULL)
890  {
891  DPRINT("No security descriptor found! Assign default security descriptor!\n");
892  dwError = ScmCreateDefaultServiceSD(&lpService->pSecurityDescriptor);
893  if (dwError != ERROR_SUCCESS)
894  goto done;
895 
896  dwError = ScmWriteSecurityDescriptor(hServiceKey,
897  lpService->pSecurityDescriptor);
898  if (dwError != ERROR_SUCCESS)
899  goto done;
900  }
901  }
902 
903 done:
904  if (lpGroup != NULL)
905  HeapFree(GetProcessHeap(), 0, lpGroup);
906 
907  if (lpDisplayName != NULL)
909 
910  if (lpService != NULL)
911  {
912  ASSERT(lpService->lpImage == NULL);
913  }
914 
915  return dwError;
916 }
SERVICE_STATUS Status
Definition: services.h:69
#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:32
PSERVICE_GROUP lpGroup
Definition: services.h:63
LPWSTR lpDisplayName
Definition: services.h:62
#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:4134
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:61
DWORD ScmReadString(HKEY hServiceKey, LPCWSTR lpValueName, LPWSTR *lpValue)
Definition: config.c:270
PSECURITY_DESCRIPTOR pSecurityDescriptor
Definition: services.h:78
DWORD dwStartType
Definition: services.h:70
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:666
#define SERVICE_WIN32
Definition: cmtypes.h:962
DWORD dwTag
Definition: services.h:72
DWORD dwErrorControl
Definition: services.h:71
BOOL bDeleted
Definition: services.h:65
DWORD ScmCreateDefaultServiceSD(PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
Definition: security.c:235
WCHAR * LPWSTR
Definition: xmlstorage.h:184
PSERVICE_IMAGE lpImage
Definition: services.h:64
DWORD ScmGenerateServiceTag(PSERVICE lpServiceRecord)
Definition: database.c:643
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:2730
#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 2272 of file database.c.

2273 {
2274  PLIST_ENTRY ServiceEntry;
2275  PSERVICE CurrentService;
2276 
2277  DPRINT("ScmAutoShutdownServices() called\n");
2278 
2279  /* Lock the service database exclusively */
2281 
2282  ServiceEntry = ServiceListHead.Flink;
2283  while (ServiceEntry != &ServiceListHead)
2284  {
2285  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2286 
2287  if ((CurrentService->Status.dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN) &&
2288  (CurrentService->Status.dwCurrentState == SERVICE_RUNNING ||
2289  CurrentService->Status.dwCurrentState == SERVICE_START_PENDING))
2290  {
2291  /* Send the shutdown notification */
2292  DPRINT("Shutdown service: %S\n", CurrentService->lpServiceName);
2293  ScmControlService(CurrentService->lpImage->hControlPipe,
2294  CurrentService->lpServiceName,
2295  (SERVICE_STATUS_HANDLE)CurrentService,
2297  }
2298 
2299  ServiceEntry = ServiceEntry->Flink;
2300  }
2301 
2302  /* Unlock the service database */
2304 
2305  DPRINT("ScmAutoShutdownServices() done\n");
2306 }
SERVICE_STATUS Status
Definition: services.h:69
DWORD dwCurrentState
Definition: winsvc.h:100
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2310
#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:61
Definition: typedefs.h:117
DWORD dwControlsAccepted
Definition: winsvc.h:101
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2324
PSERVICE_IMAGE lpImage
Definition: services.h:64
DWORD ScmControlService(HANDLE hControlPipe, PWSTR pServiceName, SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwControl)
Definition: database.c:1213
HANDLE hControlPipe
Definition: services.h:50
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40

Referenced by ShutdownHandlerRoutine().

◆ ScmAutoStartServices()

VOID ScmAutoStartServices ( VOID  )

Definition at line 2061 of file database.c.

2062 {
2063  DWORD dwError;
2064  PLIST_ENTRY GroupEntry;
2065  PLIST_ENTRY ServiceEntry;
2066  PSERVICE_GROUP CurrentGroup;
2067  PSERVICE CurrentService;
2068  WCHAR szSafeBootServicePath[MAX_PATH];
2069  DWORD SafeBootEnabled;
2070  HKEY hKey;
2071  DWORD dwKeySize;
2072  ULONG i;
2073 
2074  /*
2075  * This function MUST be called ONLY at initialization time.
2076  * Therefore, no need to acquire the user service start lock.
2077  */
2079 
2080  /* Retrieve the SafeBoot parameter */
2082  L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option",
2083  0,
2084  KEY_READ,
2085  &hKey);
2086  if (dwError == ERROR_SUCCESS)
2087  {
2088  dwKeySize = sizeof(SafeBootEnabled);
2089  dwError = RegQueryValueExW(hKey,
2090  L"OptionValue",
2091  0,
2092  NULL,
2093  (LPBYTE)&SafeBootEnabled,
2094  &dwKeySize);
2095  RegCloseKey(hKey);
2096  }
2097 
2098  /* Default to Normal boot if the value doesn't exist */
2099  if (dwError != ERROR_SUCCESS)
2100  SafeBootEnabled = 0;
2101 
2102  /* Acquire the service control critical section, to synchronize starts */
2104 
2105  /* Clear 'ServiceVisited' flag (or set if not to start in Safe Mode) */
2106  ServiceEntry = ServiceListHead.Flink;
2107  while (ServiceEntry != &ServiceListHead)
2108  {
2109  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2110 
2111  /* Build the safe boot path */
2112  StringCchCopyW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2113  L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot");
2114 
2115  switch (SafeBootEnabled)
2116  {
2117  /* NOTE: Assumes MINIMAL (1) and DSREPAIR (3) load same items */
2118  case 1:
2119  case 3:
2120  StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2121  L"\\Minimal\\");
2122  break;
2123 
2124  case 2:
2125  StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2126  L"\\Network\\");
2127  break;
2128  }
2129 
2130  if (SafeBootEnabled != 0)
2131  {
2132  /* If key does not exist then do not assume safe mode */
2134  szSafeBootServicePath,
2135  0,
2136  KEY_READ,
2137  &hKey);
2138  if (dwError == ERROR_SUCCESS)
2139  {
2140  RegCloseKey(hKey);
2141 
2142  /* Finish Safe Boot path off */
2143  StringCchCatW(szSafeBootServicePath, ARRAYSIZE(szSafeBootServicePath),
2144  CurrentService->lpServiceName);
2145 
2146  /* Check that the key is in the Safe Boot path */
2148  szSafeBootServicePath,
2149  0,
2150  KEY_READ,
2151  &hKey);
2152  if (dwError != ERROR_SUCCESS)
2153  {
2154  /* Mark service as visited so it is not auto-started */
2155  CurrentService->ServiceVisited = TRUE;
2156  }
2157  else
2158  {
2159  /* Must be auto-started in safe mode - mark as unvisited */
2160  RegCloseKey(hKey);
2161  CurrentService->ServiceVisited = FALSE;
2162  }
2163  }
2164  else
2165  {
2166  DPRINT1("WARNING: Could not open the associated Safe Boot key!");
2167  CurrentService->ServiceVisited = FALSE;
2168  }
2169  }
2170 
2171  ServiceEntry = ServiceEntry->Flink;
2172  }
2173 
2174  /* Start all services which are members of an existing group */
2175  GroupEntry = GroupListHead.Flink;
2176  while (GroupEntry != &GroupListHead)
2177  {
2178  CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
2179 
2180  DPRINT("Group '%S'\n", CurrentGroup->lpGroupName);
2181 
2182  /* Start all services witch have a valid tag */
2183  for (i = 0; i < CurrentGroup->TagCount; i++)
2184  {
2185  ServiceEntry = ServiceListHead.Flink;
2186  while (ServiceEntry != &ServiceListHead)
2187  {
2188  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2189 
2190  if ((CurrentService->lpGroup == CurrentGroup) &&
2191  (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2192  (CurrentService->ServiceVisited == FALSE) &&
2193  (CurrentService->dwTag == CurrentGroup->TagArray[i]))
2194  {
2195  CurrentService->ServiceVisited = TRUE;
2196  ScmLoadService(CurrentService, 0, NULL);
2197  }
2198 
2199  ServiceEntry = ServiceEntry->Flink;
2200  }
2201  }
2202 
2203  /* Start all services which have an invalid tag or which do not have a tag */
2204  ServiceEntry = ServiceListHead.Flink;
2205  while (ServiceEntry != &ServiceListHead)
2206  {
2207  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2208 
2209  if ((CurrentService->lpGroup == CurrentGroup) &&
2210  (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2211  (CurrentService->ServiceVisited == FALSE))
2212  {
2213  CurrentService->ServiceVisited = TRUE;
2214  ScmLoadService(CurrentService, 0, NULL);
2215  }
2216 
2217  ServiceEntry = ServiceEntry->Flink;
2218  }
2219 
2220  GroupEntry = GroupEntry->Flink;
2221  }
2222 
2223  /* Start all services which are members of any non-existing group */
2224  ServiceEntry = ServiceListHead.Flink;
2225  while (ServiceEntry != &ServiceListHead)
2226  {
2227  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2228 
2229  if ((CurrentService->lpGroup != NULL) &&
2230  (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2231  (CurrentService->ServiceVisited == FALSE))
2232  {
2233  CurrentService->ServiceVisited = TRUE;
2234  ScmLoadService(CurrentService, 0, NULL);
2235  }
2236 
2237  ServiceEntry = ServiceEntry->Flink;
2238  }
2239 
2240  /* Start all services which are not a member of any group */
2241  ServiceEntry = ServiceListHead.Flink;
2242  while (ServiceEntry != &ServiceListHead)
2243  {
2244  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2245 
2246  if ((CurrentService->lpGroup == NULL) &&
2247  (CurrentService->dwStartType == SERVICE_AUTO_START) &&
2248  (CurrentService->ServiceVisited == FALSE))
2249  {
2250  CurrentService->ServiceVisited = TRUE;
2251  ScmLoadService(CurrentService, 0, NULL);
2252  }
2253 
2254  ServiceEntry = ServiceEntry->Flink;
2255  }
2256 
2257  /* Clear 'ServiceVisited' flag again */
2258  ServiceEntry = ServiceListHead.Flink;
2259  while (ServiceEntry != &ServiceListHead)
2260  {
2261  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
2262  CurrentService->ServiceVisited = FALSE;
2263  ServiceEntry = ServiceEntry->Flink;
2264  }
2265 
2266  /* Release the critical section */
2268 }
#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:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
PSERVICE_GROUP lpGroup
Definition: services.h:63
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:1909
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define 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:80
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR lpServiceName
Definition: services.h:61
Definition: typedefs.h:117
PULONG TagArray
Definition: services.h:37
DWORD dwStartType
Definition: services.h:70
ULONG TagCount
Definition: services.h:36
#define DPRINT1
Definition: precomp.h:8
DWORD dwTag
Definition: services.h:72
#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:3381
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 1086 of file database.c.

1087 {
1090  HANDLE DirHandle;
1091  NTSTATUS Status;
1094  ULONG DataLength;
1095  ULONG Index;
1096 
1097  DPRINT("ScmCheckDriver(%S) called\n", Service->lpServiceName);
1098 
1099  if (Service->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
1100  {
1101  RtlInitUnicodeString(&DirName, L"\\Driver");
1102  }
1103  else // if (Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
1104  {
1105  ASSERT(Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER);
1106  RtlInitUnicodeString(&DirName, L"\\FileSystem");
1107  }
1108 
1110  &DirName,
1111  0,
1112  NULL,
1113  NULL);
1114 
1115  Status = NtOpenDirectoryObject(&DirHandle,
1117  &ObjectAttributes);
1118  if (!NT_SUCCESS(Status))
1119  {
1120  return Status;
1121  }
1122 
1124  2 * MAX_PATH * sizeof(WCHAR);
1125  DirInfo = HeapAlloc(GetProcessHeap(),
1127  BufferLength);
1128 
1129  Index = 0;
1130  while (TRUE)
1131  {
1132  Status = NtQueryDirectoryObject(DirHandle,
1133  DirInfo,
1134  BufferLength,
1135  TRUE,
1136  FALSE,
1137  &Index,
1138  &DataLength);
1140  {
1141  /* FIXME: Add current service to 'failed service' list */
1142  DPRINT("Service '%S' failed\n", Service->lpServiceName);
1143  break;
1144  }
1145 
1146  if (!NT_SUCCESS(Status))
1147  break;
1148 
1149  DPRINT("Comparing: '%S' '%wZ'\n", Service->lpServiceName, &DirInfo->Name);
1150 
1151  if (_wcsicmp(Service->lpServiceName, DirInfo->Name.Buffer) == 0)
1152  {
1153  DPRINT("Found: '%S' '%wZ'\n",
1154  Service->lpServiceName, &DirInfo->Name);
1155 
1156  /* Mark service as 'running' */
1157  Service->Status.dwCurrentState = SERVICE_RUNNING;
1158  Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
1159  Service->Status.dwWin32ExitCode = ERROR_SUCCESS;
1160  Service->Status.dwServiceSpecificExitCode = 0;
1161  Service->Status.dwCheckPoint = 0;
1162  Service->Status.dwWaitHint = 0;
1163 
1164  /* Mark the service group as 'running' */
1165  if (Service->lpGroup != NULL)
1166  {
1167  Service->lpGroup->ServicesRunning = TRUE;
1168  }
1169 
1170  break;
1171  }
1172  }
1173 
1175  0,
1176  DirInfo);
1177  NtClose(DirHandle);
1178 
1179  return STATUS_SUCCESS;
1180 }
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:359
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:456
_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:2725
#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 1213 of file database.c.

1217 {
1218  PSCM_CONTROL_PACKET ControlPacket;
1219  SCM_REPLY_PACKET ReplyPacket;
1220 
1221  DWORD dwWriteCount = 0;
1222  DWORD dwReadCount = 0;
1223  DWORD PacketSize;
1224  PWSTR Ptr;
1225  DWORD dwError = ERROR_SUCCESS;
1226  BOOL bResult;
1227  OVERLAPPED Overlapped = {0};
1228 
1229  DPRINT("ScmControlService() called\n");
1230 
1231  /* Acquire the service control critical section, to synchronize requests */
1233 
1234  /* Calculate the total length of the start command line */
1235  PacketSize = sizeof(SCM_CONTROL_PACKET);
1236  PacketSize += (DWORD)((wcslen(pServiceName) + 1) * sizeof(WCHAR));
1237 
1238  ControlPacket = HeapAlloc(GetProcessHeap(),
1240  PacketSize);
1241  if (ControlPacket == NULL)
1242  {
1244  return ERROR_NOT_ENOUGH_MEMORY;
1245  }
1246 
1247  ControlPacket->dwSize = PacketSize;
1248  ControlPacket->dwControl = dwControl;
1249  ControlPacket->hServiceStatus = hServiceStatus;
1250 
1251  ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
1252 
1253  Ptr = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
1254  wcscpy(Ptr, pServiceName);
1255 
1256  ControlPacket->dwArgumentsCount = 0;
1257  ControlPacket->dwArgumentsOffset = 0;
1258 
1259  bResult = WriteFile(hControlPipe,
1260  ControlPacket,
1261  PacketSize,
1262  &dwWriteCount,
1263  &Overlapped);
1264  if (bResult == FALSE)
1265  {
1266  DPRINT("WriteFile() returned FALSE\n");
1267 
1268  dwError = GetLastError();
1269  if (dwError == ERROR_IO_PENDING)
1270  {
1271  DPRINT("dwError: ERROR_IO_PENDING\n");
1272 
1273  dwError = WaitForSingleObject(hControlPipe,
1274  PipeTimeout);
1275  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1276 
1277  if (dwError == WAIT_TIMEOUT)
1278  {
1279  bResult = CancelIo(hControlPipe);
1280  if (bResult == FALSE)
1281  {
1282  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1283  }
1284 
1286  goto Done;
1287  }
1288  else if (dwError == WAIT_OBJECT_0)
1289  {
1290  bResult = GetOverlappedResult(hControlPipe,
1291  &Overlapped,
1292  &dwWriteCount,
1293  TRUE);
1294  if (bResult == FALSE)
1295  {
1296  dwError = GetLastError();
1297  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1298 
1299  goto Done;
1300  }
1301  }
1302  }
1303  else
1304  {
1305  DPRINT1("WriteFile() failed (Error %lu)\n", dwError);
1306  goto Done;
1307  }
1308  }
1309 
1310  /* Read the reply */
1311  Overlapped.hEvent = (HANDLE) NULL;
1312 
1313  bResult = ReadFile(hControlPipe,
1314  &ReplyPacket,
1315  sizeof(SCM_REPLY_PACKET),
1316  &dwReadCount,
1317  &Overlapped);
1318  if (bResult == FALSE)
1319  {
1320  DPRINT("ReadFile() returned FALSE\n");
1321 
1322  dwError = GetLastError();
1323  if (dwError == ERROR_IO_PENDING)
1324  {
1325  DPRINT("dwError: ERROR_IO_PENDING\n");
1326 
1327  dwError = WaitForSingleObject(hControlPipe,
1328  PipeTimeout);
1329  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1330 
1331  if (dwError == WAIT_TIMEOUT)
1332  {
1333  bResult = CancelIo(hControlPipe);
1334  if (bResult == FALSE)
1335  {
1336  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1337  }
1338 
1340  goto Done;
1341  }
1342  else if (dwError == WAIT_OBJECT_0)
1343  {
1344  bResult = GetOverlappedResult(hControlPipe,
1345  &Overlapped,
1346  &dwReadCount,
1347  TRUE);
1348  if (bResult == FALSE)
1349  {
1350  dwError = GetLastError();
1351  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1352 
1353  goto Done;
1354  }
1355  }
1356  }
1357  else
1358  {
1359  DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
1360  goto Done;
1361  }
1362  }
1363 
1364 Done:
1365  /* Release the control packet */
1367  0,
1368  ControlPacket);
1369 
1370  if (dwReadCount == sizeof(SCM_REPLY_PACKET))
1371  {
1372  dwError = ReplyPacket.dwError;
1373  }
1374 
1376 
1377  DPRINT("ScmControlService() done\n");
1378 
1379  return dwError;
1380 }
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 ( PSERVICE_IMAGE  pServiceImage)
static

Definition at line 44 of file database.c.

45 {
46  WCHAR szControlPipeName[MAX_PATH + 1];
47  HKEY hServiceCurrentKey = INVALID_HANDLE_VALUE;
48  DWORD ServiceCurrent = 0;
49  DWORD KeyDisposition;
50  DWORD dwKeySize;
51  DWORD dwError;
52 
53  /* Get the service number */
54  /* TODO: Create registry entry with correct write access */
56  L"SYSTEM\\CurrentControlSet\\Control\\ServiceCurrent", 0, NULL,
59  NULL,
60  &hServiceCurrentKey,
61  &KeyDisposition);
62  if (dwError != ERROR_SUCCESS)
63  {
64  DPRINT1("RegCreateKeyEx() failed with error %lu\n", dwError);
65  return dwError;
66  }
67 
68  if (KeyDisposition == REG_OPENED_EXISTING_KEY)
69  {
70  dwKeySize = sizeof(DWORD);
71  dwError = RegQueryValueExW(hServiceCurrentKey,
72  L"", 0, NULL, (BYTE*)&ServiceCurrent, &dwKeySize);
73 
74  if (dwError != ERROR_SUCCESS)
75  {
76  RegCloseKey(hServiceCurrentKey);
77  DPRINT1("RegQueryValueEx() failed with error %lu\n", dwError);
78  return dwError;
79  }
80 
81  ServiceCurrent++;
82  }
83 
84  dwError = RegSetValueExW(hServiceCurrentKey, L"", 0, REG_DWORD, (BYTE*)&ServiceCurrent, sizeof(ServiceCurrent));
85 
86  RegCloseKey(hServiceCurrentKey);
87 
88  if (dwError != ERROR_SUCCESS)
89  {
90  DPRINT1("RegSetValueExW() failed (Error %lu)\n", dwError);
91  return dwError;
92  }
93 
94  /* Create '\\.\pipe\net\NtControlPipeXXX' instance */
95  StringCchPrintfW(szControlPipeName, ARRAYSIZE(szControlPipeName),
96  L"\\\\.\\pipe\\net\\NtControlPipe%lu", ServiceCurrent);
97 
98  DPRINT("PipeName: %S\n", szControlPipeName);
99 
100  pServiceImage->hControlPipe = CreateNamedPipeW(szControlPipeName,
103  100,
104  8000,
105  4,
106  PipeTimeout,
107  NULL);
108  DPRINT("CreateNamedPipeW(%S) done\n", szControlPipeName);
109  if (pServiceImage->hControlPipe == INVALID_HANDLE_VALUE)
110  {
111  DPRINT1("Failed to create control pipe!\n");
112  return GetLastError();
113  }
114 
115  return ERROR_SUCCESS;
116 }
#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:1094
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:4917
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define 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
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define DPRINT1
Definition: precomp.h:8
#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
HANDLE hControlPipe
Definition: services.h:50
#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 666 of file database.c.

670 {
671  PSERVICE lpService = NULL;
672 
673  DPRINT("Service: '%S'\n", lpServiceName);
674 
675  /* Allocate service entry */
676  lpService = HeapAlloc(GetProcessHeap(),
678  FIELD_OFFSET(SERVICE, szServiceName[wcslen(lpServiceName) + 1]));
679  if (lpService == NULL)
681 
682  *lpServiceRecord = lpService;
683 
684  /* Copy service name */
685  wcscpy(lpService->szServiceName, lpServiceName);
686  lpService->lpServiceName = lpService->szServiceName;
687  lpService->lpDisplayName = lpService->lpServiceName;
688 
689  /* Set the start type */
690  lpService->dwStartType = dwStartType;
691 
692  /* Set the resume count */
693  lpService->dwResumeCount = ResumeCount++;
694 
695  /* Append service record */
697  &lpService->ServiceListEntry);
698 
699  /* Initialize the service status */
700  lpService->Status.dwServiceType = dwServiceType;
702  lpService->Status.dwControlsAccepted = 0;
703  lpService->Status.dwWin32ExitCode =
705  lpService->Status.dwServiceSpecificExitCode = 0;
706  lpService->Status.dwCheckPoint = 0;
707  lpService->Status.dwWaitHint =
708  (dwServiceType & SERVICE_DRIVER) ? 0 : 2000; /* 2 seconds */
709 
710  return ERROR_SUCCESS;
711 }
SERVICE_STATUS Status
Definition: services.h:69
#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:62
#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:60
#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:66
LPWSTR lpServiceName
Definition: services.h:61
DWORD dwStartType
Definition: services.h:70
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:82
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 374 of file database.c.

375 {
377  UNICODE_STRING ImagePath;
379  PSERVICE_IMAGE pServiceImage = NULL;
381  DWORD dwError = ERROR_SUCCESS;
382  DWORD dwRecordSize;
383  LPWSTR pString;
384 
385  DPRINT("ScmCreateOrReferenceServiceImage(%p)\n", pService);
386 
387  RtlInitUnicodeString(&ImagePath, NULL);
389 
390  /* Get service data */
392  sizeof(QueryTable));
393 
394  QueryTable[0].Name = L"ImagePath";
396  QueryTable[0].EntryContext = &ImagePath;
397  QueryTable[1].Name = L"ObjectName";
400 
402  pService->lpServiceName,
403  QueryTable,
404  NULL,
405  NULL);
406  if (!NT_SUCCESS(Status))
407  {
408  DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
410  }
411 
412  DPRINT("ImagePath: '%wZ'\n", &ImagePath);
413  DPRINT("ObjectName: '%wZ'\n", &ObjectName);
414 
415  pServiceImage = ScmGetServiceImageByImagePath(ImagePath.Buffer);
416  if (pServiceImage == NULL)
417  {
418  dwRecordSize = sizeof(SERVICE_IMAGE) +
419  ImagePath.Length + sizeof(WCHAR) +
420  ((ObjectName.Length != 0) ? (ObjectName.Length + sizeof(WCHAR)) : 0);
421 
422  /* Create a new service image */
423  pServiceImage = HeapAlloc(GetProcessHeap(),
425  dwRecordSize);
426  if (pServiceImage == NULL)
427  {
428  dwError = ERROR_NOT_ENOUGH_MEMORY;
429  goto done;
430  }
431 
432  pServiceImage->dwImageRunCount = 1;
433  pServiceImage->hControlPipe = INVALID_HANDLE_VALUE;
434  pServiceImage->hProcess = INVALID_HANDLE_VALUE;
435 
436  pString = (PWSTR)((INT_PTR)pServiceImage + sizeof(SERVICE_IMAGE));
437 
438  /* Set the image path */
439  pServiceImage->pszImagePath = pString;
440  wcscpy(pServiceImage->pszImagePath,
441  ImagePath.Buffer);
442 
443  /* Set the account name */
444  if (ObjectName.Length > 0)
445  {
446  pString = pString + wcslen(pString) + 1;
447 
448  pServiceImage->pszAccountName = pString;
449  wcscpy(pServiceImage->pszAccountName,
450  ObjectName.Buffer);
451  }
452 
453  /* Service logon */
454  dwError = ScmLogonService(pService, pServiceImage);
455  if (dwError != ERROR_SUCCESS)
456  {
457  DPRINT1("ScmLogonService() failed (Error %lu)\n", dwError);
458 
459  /* Release the service image */
460  HeapFree(GetProcessHeap(), 0, pServiceImage);
461 
462  goto done;
463  }
464 
465  /* Create the control pipe */
466  dwError = ScmCreateNewControlPipe(pServiceImage);
467  if (dwError != ERROR_SUCCESS)
468  {
469  DPRINT1("ScmCreateNewControlPipe() failed (Error %lu)\n", dwError);
470 
471  /* Unload the user profile */
472  if (pServiceImage->hProfile != NULL)
473  UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile);
474 
475  /* Close the logon token */
476  if (pServiceImage->hToken != NULL)
477  CloseHandle(pServiceImage->hToken);
478 
479  /* Release the service image */
480  HeapFree(GetProcessHeap(), 0, pServiceImage);
481 
482  goto done;
483  }
484 
485  /* FIXME: Add more initialization code here */
486 
487 
488  /* Append service record */
490  &pServiceImage->ImageListEntry);
491  }
492  else
493  {
494 // if ((lpService->Status.dwServiceType & SERVICE_WIN32_SHARE_PROCESS) == 0)
495 
496  /* Fail if services in an image use different accounts */
497  if (!ScmIsSameServiceAccount(pServiceImage->pszAccountName, ObjectName.Buffer))
498  {
500  goto done;
501  }
502 
503  /* Increment the run counter */
504  pServiceImage->dwImageRunCount++;
505  }
506 
507  DPRINT("pServiceImage->pszImagePath: %S\n", pServiceImage->pszImagePath);
508  DPRINT("pServiceImage->pszAccountName: %S\n", pServiceImage->pszAccountName);
509  DPRINT("pServiceImage->dwImageRunCount: %lu\n", pServiceImage->dwImageRunCount);
510 
511  /* Link the service image to the service */
512  pService->lpImage = pServiceImage;
513 
514 done:
516  RtlFreeUnicodeString(&ImagePath);
517 
518  DPRINT("ScmCreateOrReferenceServiceImage() done (Error: %lu)\n", dwError);
519 
520  return dwError;
521 }
static PSERVICE_IMAGE ScmGetServiceImageByImagePath(LPWSTR lpImagePath)
Definition: database.c:120
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
#define CloseHandle
Definition: compat.h:398
LPWSTR pszAccountName
Definition: services.h:47
HANDLE hToken
Definition: services.h:53
#define ERROR_SUCCESS
Definition: deptool.c:10
LIST_ENTRY ImageListEntry
Definition: services.h:45
LIST_ENTRY ImageListHead
Definition: database.c:28
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
_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:279
struct _SERVICE_IMAGE SERVICE_IMAGE
DWORD dwImageRunCount
Definition: services.h:48
#define ERROR_DIFFERENT_SERVICE_ACCOUNT
Definition: winerror.h:630
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static DWORD ScmCreateNewControlPipe(PSERVICE_IMAGE pServiceImage)
Definition: database.c:44
#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:54
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:61
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
LPWSTR pszImagePath
Definition: services.h:46
#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:237
WCHAR * LPWSTR
Definition: xmlstorage.h:184
PSERVICE_IMAGE lpImage
Definition: services.h:64
HANDLE hProcess
Definition: services.h:51
HANDLE hControlPipe
Definition: services.h:50
#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

Referenced by ScmLoadService().

◆ ScmCreateServiceDatabase()

DWORD ScmCreateServiceDatabase ( VOID  )

Definition at line 987 of file database.c.

988 {
989  WCHAR szSubKey[MAX_PATH];
991  HKEY hServiceKey;
992  DWORD dwSubKey;
993  DWORD dwSubKeyLength;
994  FILETIME ftLastChanged;
995  DWORD dwError;
996 
997  DPRINT("ScmCreateServiceDatabase() called\n");
998 
999  /* Retrieve the NoInteractiveServies value */
1001 
1002  /* Create the service group list */
1003  dwError = ScmCreateGroupList();
1004  if (dwError != ERROR_SUCCESS)
1005  return dwError;
1006 
1007  /* Initialize image and service lists */
1010 
1011  /* Initialize the database lock */
1013 
1015  L"System\\CurrentControlSet\\Services",
1016  0,
1017  KEY_READ,
1018  &hServicesKey);
1019  if (dwError != ERROR_SUCCESS)
1020  return dwError;
1021 
1022  dwSubKey = 0;
1023  for (;;)
1024  {
1025  dwSubKeyLength = MAX_PATH;
1026  dwError = RegEnumKeyExW(hServicesKey,
1027  dwSubKey,
1028  szSubKey,
1029  &dwSubKeyLength,
1030  NULL,
1031  NULL,
1032  NULL,
1033  &ftLastChanged);
1034  if (dwError == ERROR_SUCCESS &&
1035  szSubKey[0] != L'{')
1036  {
1037  DPRINT("SubKeyName: '%S'\n", szSubKey);
1038 
1039  dwError = RegOpenKeyExW(hServicesKey,
1040  szSubKey,
1041  0,
1042  KEY_READ,
1043  &hServiceKey);
1044  if (dwError == ERROR_SUCCESS)
1045  {
1046  dwError = CreateServiceListEntry(szSubKey,
1047  hServiceKey);
1048 
1049  RegCloseKey(hServiceKey);
1050  }
1051  }
1052 
1053  if (dwError != ERROR_SUCCESS)
1054  break;
1055 
1056  dwSubKey++;
1057  }
1058 
1060 
1061  /* Wait for the LSA server */
1062  ScmWaitForLsa();
1063 
1064  /* Delete services that are marked for delete */
1066 
1067  DPRINT("ScmCreateServiceDatabase() done\n");
1068 
1069  return ERROR_SUCCESS;
1070 }
#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:85
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
static DWORD CreateServiceListEntry(LPCWSTR lpServiceName, HKEY hServiceKey)
Definition: database.c:756
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:3381
static VOID ScmGetNoInteractiveServicesValue(VOID)
Definition: database.c:961
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2541
DWORD ScmCreateGroupList(VOID)
Definition: groupdb.c:235
VOID ScmDeleteMarkedServices(VOID)
Definition: database.c:920
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by wWinMain().

◆ ScmDeleteMarkedServices()

VOID ScmDeleteMarkedServices ( VOID  )

Definition at line 920 of file database.c.

921 {
922  PLIST_ENTRY ServiceEntry;
923  PSERVICE CurrentService;
925  DWORD dwError;
926 
927  ServiceEntry = ServiceListHead.Flink;
928  while (ServiceEntry != &ServiceListHead)
929  {
930  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
931 
932  ServiceEntry = ServiceEntry->Flink;
933 
934  if (CurrentService->bDeleted != FALSE)
935  {
937  L"System\\CurrentControlSet\\Services",
938  0,
939  DELETE,
940  &hServicesKey);
941  if (dwError == ERROR_SUCCESS)
942  {
943  dwError = ScmDeleteRegKey(hServicesKey, CurrentService->lpServiceName);
945  if (dwError == ERROR_SUCCESS)
946  {
947  RemoveEntryList(&CurrentService->ServiceListEntry);
948  HeapFree(GetProcessHeap(), 0, CurrentService);
949  }
950  }
951 
952  if (dwError != ERROR_SUCCESS)
953  DPRINT1("Delete service failed: %S\n", CurrentService->lpServiceName);
954  }
955  }
956 }
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:60
#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:61
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:3381
BOOL bDeleted
Definition: services.h:65
#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 2359 of file database.c.

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

Referenced by wWinMain().

◆ ScmDeleteServiceRecord()

VOID ScmDeleteServiceRecord ( PSERVICE  lpService)

Definition at line 715 of file database.c.

716 {
717  DPRINT("Deleting Service %S\n", lpService->lpServiceName);
718 
719  /* Delete the display name */
720  if (lpService->lpDisplayName != NULL &&
721  lpService->lpDisplayName != lpService->lpServiceName)
722  HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
723 
724  /* Dereference the service image */
725  if (lpService->lpImage)
726  {
727  lpService->lpImage->dwImageRunCount--;
728 
729  if (lpService->lpImage->dwImageRunCount == 0)
730  {
731  ScmRemoveServiceImage(lpService->lpImage);
732  lpService->lpImage = NULL;
733  }
734  }
735 
736  /* Decrement the group reference counter */
737  ScmSetServiceGroup(lpService, NULL);
738 
739  /* Release the SecurityDescriptor */
740  if (lpService->pSecurityDescriptor != NULL)
741  HeapFree(GetProcessHeap(), 0, lpService->pSecurityDescriptor);
742 
743  /* Remove the Service from the List */
744  RemoveEntryList(&lpService->ServiceListEntry);
745 
746  DPRINT("Deleted Service %S\n", lpService->lpServiceName);
747 
748  /* Delete the service record */
749  HeapFree(GetProcessHeap(), 0, lpService);
750 
751  DPRINT("Done\n");
752 }
LPWSTR lpDisplayName
Definition: services.h:62
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
DWORD dwImageRunCount
Definition: services.h:48
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:60
#define GetProcessHeap()
Definition: compat.h:395
LPWSTR lpServiceName
Definition: services.h:61
PSECURITY_DESCRIPTOR pSecurityDescriptor
Definition: services.h:78
PSERVICE_IMAGE lpImage
Definition: services.h:64
#define HeapFree(x, y, z)
Definition: compat.h:394
VOID ScmRemoveServiceImage(PSERVICE_IMAGE pServiceImage)
Definition: database.c:525

Referenced by RCloseServiceHandle().

◆ ScmGenerateServiceTag()

DWORD ScmGenerateServiceTag ( PSERVICE  lpServiceRecord)

Definition at line 643 of file database.c.

644 {
645  /* Check for an overflow */
646  if (ServiceTag == -1)
647  {
648  return ERROR_INVALID_DATA;
649  }
650 
651  /* This is only valid for Win32 services */
652  if (!(lpServiceRecord->Status.dwServiceType & SERVICE_WIN32))
653  {
655  }
656 
657  /* Increment the tag counter and set it */
658  ServiceTag = ServiceTag % 0xFFFFFFFF + 1;
659  lpServiceRecord->dwTag = ServiceTag;
660 
661  return ERROR_SUCCESS;
662 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
SERVICE_STATUS Status
Definition: services.h:69
#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:72
static DWORD ServiceTag
Definition: database.c:34

Referenced by CreateServiceListEntry(), and RCreateServiceW().

◆ ScmGetBootAndSystemDriverState()

VOID ScmGetBootAndSystemDriverState ( VOID  )

Definition at line 1184 of file database.c.

1185 {
1186  PLIST_ENTRY ServiceEntry;
1187  PSERVICE CurrentService;
1188 
1189  DPRINT("ScmGetBootAndSystemDriverState() called\n");
1190 
1191  ServiceEntry = ServiceListHead.Flink;
1192  while (ServiceEntry != &ServiceListHead)
1193  {
1194  CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
1195 
1196  if (CurrentService->dwStartType == SERVICE_BOOT_START ||
1197  CurrentService->dwStartType == SERVICE_SYSTEM_START)
1198  {
1199  /* Check driver */
1200  DPRINT(" Checking service: %S\n", CurrentService->lpServiceName);
1201 
1202  ScmCheckDriver(CurrentService);
1203  }
1204 
1205  ServiceEntry = ServiceEntry->Flink;
1206  }
1207 
1208  DPRINT("ScmGetBootAndSystemDriverState() done\n");
1209 }
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:974
static NTSTATUS ScmCheckDriver(PSERVICE Service)
Definition: database.c:1086
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:61
Definition: typedefs.h:117
DWORD dwStartType
Definition: services.h:70

Referenced by wWinMain().

◆ ScmGetNoInteractiveServicesValue()

static VOID ScmGetNoInteractiveServicesValue ( VOID  )
static

Definition at line 961 of file database.c.

962 {
963  HKEY hKey;
964  DWORD dwKeySize;
965  LONG lError;
966 
968  L"SYSTEM\\CurrentControlSet\\Control\\Windows",
969  0,
970  KEY_READ,
971  &hKey);
972  if (lError == ERROR_SUCCESS)
973  {
974  dwKeySize = sizeof(NoInteractiveServices);
975  lError = RegQueryValueExW(hKey,
976  L"NoInteractiveServices",
977  0,
978  NULL,
980  &dwKeySize);
981  RegCloseKey(hKey);
982  }
983 }
#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:4134
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:3381
#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 585 of file database.c.

586 {
587  PLIST_ENTRY ServiceEntry;
588  PSERVICE CurrentService;
589 
590  DPRINT("ScmGetServiceEntryByDisplayName() called\n");
591 
592  ServiceEntry = ServiceListHead.Flink;
593  while (ServiceEntry != &ServiceListHead)
594  {
595  CurrentService = CONTAINING_RECORD(ServiceEntry,
596  SERVICE,
597  ServiceListEntry);
598  if (_wcsicmp(CurrentService->lpDisplayName, lpDisplayName) == 0)
599  {
600  DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
601  return CurrentService;
602  }
603 
604  ServiceEntry = ServiceEntry->Flink;
605  }
606 
607  DPRINT("Couldn't find a matching service\n");
608 
609  return NULL;
610 }
LPWSTR lpDisplayName
Definition: services.h:62
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:2730
_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 556 of file database.c.

557 {
558  PLIST_ENTRY ServiceEntry;
559  PSERVICE CurrentService;
560 
561  DPRINT("ScmGetServiceEntryByName() called\n");
562 
563  ServiceEntry = ServiceListHead.Flink;
564  while (ServiceEntry != &ServiceListHead)
565  {
566  CurrentService = CONTAINING_RECORD(ServiceEntry,
567  SERVICE,
568  ServiceListEntry);
569  if (_wcsicmp(CurrentService->lpServiceName, lpServiceName) == 0)
570  {
571  DPRINT("Found service: '%S'\n", CurrentService->lpServiceName);
572  return CurrentService;
573  }
574 
575  ServiceEntry = ServiceEntry->Flink;
576  }
577 
578  DPRINT("Couldn't find a matching service\n");
579 
580  return NULL;
581 }
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:61
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 614 of file database.c.

615 {
616  PLIST_ENTRY ServiceEntry;
617  PSERVICE CurrentService;
618 
619  DPRINT("ScmGetServiceEntryByResumeCount() called\n");
620 
621  ServiceEntry = ServiceListHead.Flink;
622  while (ServiceEntry != &ServiceListHead)
623  {
624  CurrentService = CONTAINING_RECORD(ServiceEntry,
625  SERVICE,
626  ServiceListEntry);
627  if (CurrentService->dwResumeCount > dwResumeCount)
628  {
629  DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
630  return CurrentService;
631  }
632 
633  ServiceEntry = ServiceEntry->Flink;
634  }
635 
636  DPRINT("Couldn't find a matching service\n");
637 
638  return NULL;
639 }
LPWSTR lpDisplayName
Definition: services.h:62
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:66
Definition: typedefs.h:117

Referenced by REnumServiceGroupW(), and REnumServicesStatusExW().

◆ ScmGetServiceImageByImagePath()

static PSERVICE_IMAGE ScmGetServiceImageByImagePath ( LPWSTR  lpImagePath)
static

Definition at line 120 of file database.c.

121 {
122  PLIST_ENTRY ImageEntry;
123  PSERVICE_IMAGE CurrentImage;
124 
125  DPRINT("ScmGetServiceImageByImagePath(%S) called\n", lpImagePath);
126 
127  ImageEntry = ImageListHead.Flink;
128  while (ImageEntry != &ImageListHead)
129  {
130  CurrentImage = CONTAINING_RECORD(ImageEntry,
132  ImageListEntry);
133  if (_wcsicmp(CurrentImage->pszImagePath, lpImagePath) == 0)
134  {
135  DPRINT("Found image: '%S'\n", CurrentImage->pszImagePath);
136  return CurrentImage;
137  }
138 
139  ImageEntry = ImageEntry->Flink;
140  }
141 
142  DPRINT("Couldn't find a matching image\n");
143 
144  return NULL;
145 
146 }
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:46
_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 150 of file database.c.

152 {
153  PLIST_ENTRY ServiceEntry;
154  PSERVICE CurrentService;
155  PSERVICE_IMAGE CurrentImage;
157  DWORD dwError;
158 
159  /* Lock the database */
161 
162  /* Find the matching service */
163  ServiceEntry = ServiceListHead.Flink;
164  while (ServiceEntry != &ServiceListHead)
165  {
166  CurrentService = CONTAINING_RECORD(ServiceEntry,
167  SERVICE,
168  ServiceListEntry);
169 
170  /* We must match the tag */
171  if (CurrentService->dwTag == InParams->dwTag &&
172  CurrentService->lpImage != NULL)
173  {
174  CurrentImage = CurrentService->lpImage;
175  /* And matching the PID */
176  if (CurrentImage->dwProcessId == InParams->dwPid)
177  {
178  break;
179  }
180  }
181 
182  ServiceEntry = ServiceEntry->Flink;
183  }
184 
185  /* No match! */
186  if (ServiceEntry == &ServiceListHead)
187  {
188  dwError = ERROR_RETRY;
189  goto Cleanup;
190  }
191 
192  /* Allocate the output buffer */
194  if (OutBuffer == NULL)
195  {
196  dwError = ERROR_NOT_ENOUGH_MEMORY;
197  goto Cleanup;
198  }
199 
200  /* And the buffer for the name */
201  OutBuffer->pszName = MIDL_user_allocate(wcslen(CurrentService->lpServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
202  if (OutBuffer->pszName == NULL)
203  {
204  dwError = ERROR_NOT_ENOUGH_MEMORY;
205  goto Cleanup;
206  }
207 
208  /* Fill in output data */
209  wcscpy(OutBuffer->pszName, CurrentService->lpServiceName);
210  OutBuffer->TagType = TagTypeService;
211 
212  /* And return */
213  *OutParams = OutBuffer;
214  dwError = ERROR_SUCCESS;
215 
216 Cleanup:
217 
218  /* Unlock database */
220 
221  /* If failure, free allocated memory */
222  if (dwError != ERROR_SUCCESS)
223  {
224  if (OutBuffer != NULL)
225  {
226  MIDL_user_free(OutBuffer);
227  }
228  }
229 
230  /* Return error/success */
231  return dwError;
232 }
DWORD dwProcessId
Definition: services.h:52
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2310
#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:61
Definition: typedefs.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERROR_RETRY
Definition: winerror.h:740
DWORD dwTag
Definition: services.h:72
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2324
void *__RPC_USER MIDL_user_allocate(SIZE_T size)
Definition: irotp.c:371
PSERVICE_IMAGE lpImage
Definition: services.h:64
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 2331 of file database.c.

2332 {
2333  HKEY hKey;
2334  DWORD dwKeySize;
2335  DWORD dwError;
2336 
2338 
2340  L"SYSTEM\\CurrentControlSet\\Control",
2341  0,
2342  KEY_READ,
2343  &hKey);
2344  if (dwError == ERROR_SUCCESS)
2345  {
2346  dwKeySize = sizeof(PipeTimeout);
2347  RegQueryValueExW(hKey,
2348  L"ServicesPipeTimeout",
2349  0,
2350  NULL,
2351  (LPBYTE)&PipeTimeout,
2352  &dwKeySize);
2353  RegCloseKey(hKey);
2354  }
2355 }
#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:697
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:4134
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:3381
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by wWinMain().

◆ ScmIsLocalSystemAccount()

static BOOL ScmIsLocalSystemAccount ( _In_ PCWSTR  pszAccountName)
static

Definition at line 266 of file database.c.

268 {
269  if (pszAccountName == NULL ||
270  _wcsicmp(pszAccountName, L"LocalSystem") == 0)
271  return TRUE;
272 
273  return FALSE;
274 }
#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 237 of file database.c.

240 {
241  if (pszAccountName1 == NULL &&
242  pszAccountName2 == NULL)
243  return TRUE;
244 
245  if (pszAccountName1 == NULL &&
246  pszAccountName2 != NULL &&
247  _wcsicmp(pszAccountName2, L"LocalSystem") == 0)
248  return TRUE;
249 
250  if (pszAccountName1 != NULL &&
251  pszAccountName2 == NULL &&
252  _wcsicmp(pszAccountName1, L"LocalSystem") == 0)
253  return TRUE;
254 
255  if (pszAccountName1 != NULL &&
256  pszAccountName2 != NULL &&
257  _wcsicmp(pszAccountName1, pszAccountName2) == 0)
258  return TRUE;
259 
260  return FALSE;
261 }
#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().

◆ ScmLoadService()

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

Definition at line 1909 of file database.c.

1912 {
1913  PSERVICE_GROUP Group = Service->lpGroup;
1914  DWORD dwError = ERROR_SUCCESS;
1915  LPCWSTR lpLogStrings[2];
1916  WCHAR szLogBuffer[80];
1917 
1918  DPRINT("ScmLoadService() called\n");
1919  DPRINT("Start Service %p (%S)\n", Service, Service->lpServiceName);
1920 
1921  if (Service->Status.dwCurrentState != SERVICE_STOPPED)
1922  {
1923  DPRINT("Service %S is already running!\n", Service->lpServiceName);
1925  }
1926 
1927  DPRINT("Service->Type: %lu\n", Service->Status.dwServiceType);
1928 
1929  if (Service->Status.dwServiceType & SERVICE_DRIVER)
1930  {
1931  /* Start the driver */
1932  dwError = ScmStartDriver(Service);
1933  }
1934  else // if (Service->Status.dwServiceType & (SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS))
1935  {
1936  /* Start user-mode service */
1938  if (dwError == ERROR_SUCCESS)
1939  {
1941  if (dwError == ERROR_SUCCESS)
1942  {
1943  Service->Status.dwCurrentState = SERVICE_START_PENDING;
1944  Service->Status.dwControlsAccepted = 0;
1945  }
1946  else
1947  {
1948  Service->lpImage->dwImageRunCount--;
1949  if (Service->lpImage->dwImageRunCount == 0)
1950  {
1951  ScmRemoveServiceImage(Service->lpImage);
1952  Service->lpImage = NULL;
1953  }
1954  }
1955  }
1956  }
1957 
1958  DPRINT("ScmLoadService() done (Error %lu)\n", dwError);
1959 
1960  if (dwError == ERROR_SUCCESS)
1961  {
1962  if (Group != NULL)
1963  {
1964  Group->ServicesRunning = TRUE;
1965  }
1966 
1967  /* Log a successful service start */
1968  LoadStringW(GetModuleHandle(NULL), IDS_SERVICE_START, szLogBuffer, 80);
1969  lpLogStrings[0] = Service->lpDisplayName;
1970  lpLogStrings[1] = szLogBuffer;
1971 
1974  2,
1975  lpLogStrings);
1976  }
1977  else
1978  {
1979  if (Service->dwErrorControl != SERVICE_ERROR_IGNORE)
1980  {
1981  /* Log a failed service start */
1982  StringCchPrintfW(szLogBuffer, ARRAYSIZE(szLogBuffer),
1983  L"%lu", dwError);
1984  lpLogStrings[0] = Service->lpServiceName;
1985  lpLogStrings[1] = szLogBuffer;
1988  2,
1989  lpLogStrings);
1990  }
1991 
1992 #if 0
1993  switch (Service->dwErrorControl)
1994  {
1995  case SERVICE_ERROR_SEVERE:
1996  if (IsLastKnownGood == FALSE)
1997  {
1998  /* FIXME: Boot last known good configuration */
1999  }
2000  break;
2001 
2003  if (IsLastKnownGood == FALSE)
2004  {
2005  /* FIXME: Boot last known good configuration */
2006  }
2007  else
2008  {
2009  /* FIXME: BSOD! */
2010  }
2011  break;
2012  }
2013 #endif
2014  }
2015 
2016  return dwError;
2017 }
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:52
#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:3641
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:374
static DWORD ScmStartUserModeService(PSERVICE Service, DWORD argc, LPWSTR *argv)
Definition: database.c:1771
#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:525

Referenced by ScmAutoStartServices(), and ScmStartService().

◆ ScmLockDatabaseExclusive()

BOOL ScmLockDatabaseExclusive ( VOID  )

Definition at line 2310 of file database.c.

2311 {
2313 }
#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 2317 of file database.c.

2318 {
2320 }
#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 279 of file database.c.

282 {
283  DWORD dwError = ERROR_SUCCESS;
284  PROFILEINFOW ProfileInfo;
285  PWSTR pszUserName = NULL;
286  PWSTR pszDomainName = NULL;
287  PWSTR pszPassword = NULL;
288  PWSTR ptr;
289 
290  DPRINT("ScmLogonService(%p %p)\n", pService, pImage);
291  DPRINT("Service %S\n", pService->lpServiceName);
292 
293  if (ScmIsLocalSystemAccount(pImage->pszAccountName))
294  return ERROR_SUCCESS;
295 
296  /* Get the user and domain names */
297  ptr = wcschr(pImage->pszAccountName, L'\\');
298  if (ptr != NULL)
299  {
300  *ptr = L'\0';
301  pszUserName = ptr + 1;
302  pszDomainName = pImage->pszAccountName;
303  }
304  else
305  {
306  // ERROR_INVALID_SERVICE_ACCOUNT
307  pszUserName = pImage->pszAccountName;
308  pszDomainName = NULL;
309  }
310 
311  /* Build the service 'password' */
312  pszPassword = HeapAlloc(GetProcessHeap(),
314  (wcslen(pService->lpServiceName) + 5) * sizeof(WCHAR));
315  if (pszPassword == NULL)
316  {
317  dwError = ERROR_NOT_ENOUGH_MEMORY;
318  goto done;
319  }
320 
321  wcscpy(pszPassword, L"_SC_");
322  wcscat(pszPassword, pService->lpServiceName);
323 
324  DPRINT("Domain: %S User: %S Password: %S\n", pszDomainName, pszUserName, pszPassword);
325 
326  /* Do the service logon */
327  if (!LogonUserW(pszUserName,
328  pszDomainName,
329  pszPassword,
332  &pImage->hToken))
333  {
334  dwError = GetLastError();
335  DPRINT1("LogonUserW() failed (Error %lu)\n", dwError);
336 
337  /* Normalize the returned error */
338  dwError = ERROR_SERVICE_LOGON_FAILED;
339  goto done;
340  }
341 
342  /* Load the user profile; the per-user environment variables are thus correctly initialized */
343  ZeroMemory(&ProfileInfo, sizeof(ProfileInfo));
344  ProfileInfo.dwSize = sizeof(ProfileInfo);
345  ProfileInfo.dwFlags = PI_NOUI;
346  ProfileInfo.lpUserName = pszUserName;
347  // ProfileInfo.lpProfilePath = NULL;
348  // ProfileInfo.lpDefaultPath = NULL;
349  // ProfileInfo.lpServerName = NULL;
350  // ProfileInfo.lpPolicyPath = NULL;
351  // ProfileInfo.hProfile = NULL;
352 
353  if (!LoadUserProfileW(pImage->hToken, &ProfileInfo))
354  {
355  dwError = GetLastError();
356  DPRINT1("LoadUserProfileW() failed (Error %lu)\n", dwError);
357  goto done;
358  }
359 
360  pImage->hProfile = ProfileInfo.hProfile;
361 
362 done:
363  if (pszPassword != NULL)
364  HeapFree(GetProcessHeap(), 0, pszPassword);
365 
366  if (ptr != NULL)
367  *ptr = L'\\';
368 
369  return dwError;
370 }
HANDLE hProfile
Definition: userenv.h:43
#define ERROR_SUCCESS
Definition: deptool.c:10
uint16_t * PWSTR
Definition: typedefs.h:54
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
LPWSTR lpUserName
Definition: userenv.h:38
static BOOL ScmIsLocalSystemAccount(_In_ PCWSTR pszAccountName)
Definition: database.c:266
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:420
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 525 of file database.c.

526 {
527  DPRINT1("ScmRemoveServiceImage() called\n");
528 
529  /* FIXME: Terminate the process */
530 
531  /* Remove the service image from the list */
532  RemoveEntryList(&pServiceImage->ImageListEntry);
533 
534  /* Close the process handle */
535  if (pServiceImage->hProcess != INVALID_HANDLE_VALUE)
536  CloseHandle(pServiceImage->hProcess);
537 
538  /* Close the control pipe */
539  if (pServiceImage->hControlPipe != INVALID_HANDLE_VALUE)
540  CloseHandle(pServiceImage->hControlPipe);
541 
542  /* Unload the user profile */
543  if (pServiceImage->hProfile != NULL)
544  UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile);
545 
546  /* Close the logon token */
547  if (pServiceImage->hToken != NULL)
548  CloseHandle(pServiceImage->hToken);
549 
550  /* Release the service image */
551  HeapFree(GetProcessHeap(), 0, pServiceImage);
552 }
#define CloseHandle
Definition: compat.h:398
HANDLE hToken
Definition: services.h:53
LIST_ENTRY ImageListEntry
Definition: services.h:45
#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:54
#define DPRINT1
Definition: precomp.h:8
HANDLE hProcess
Definition: services.h:51
HANDLE hControlPipe
Definition: services.h:50
#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 1384 of file database.c.

1387 {
1388  DWORD dwError = ERROR_SUCCESS;
1389  PSCM_CONTROL_PACKET ControlPacket;
1390  SCM_REPLY_PACKET ReplyPacket;
1391  DWORD PacketSize;
1392  DWORD i;
1393  PWSTR Ptr;
1394  PWSTR *pOffPtr;
1395  PWSTR pArgPtr;
1396  BOOL bResult;
1397  DWORD dwWriteCount = 0;
1398  DWORD dwReadCount = 0;
1399  OVERLAPPED Overlapped = {0};
1400 
1401  DPRINT("ScmSendStartCommand() called\n");
1402 
1403  /* Calculate the total length of the start command line */
1404  PacketSize = sizeof(SCM_CONTROL_PACKET);
1405  PacketSize += (DWORD)((wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR));
1406 
1407  /*
1408  * Calculate the required packet size for the start argument vector 'argv',
1409  * composed of the list of pointer offsets, followed by UNICODE strings.
1410  * The strings are stored continuously after the vector of offsets, with
1411  * the offsets being relative to the beginning of the vector, as in the
1412  * following layout (with N == argc):
1413  * [argOff(0)]...[argOff(N-1)][str(0)]...[str(N-1)] .
1414  */
1415  if (argc > 0 && argv != NULL)
1416  {
1418  PacketSize += (argc * sizeof(PWSTR));
1419 
1420  DPRINT("Argc: %lu\n", argc);
1421  for (i = 0; i < argc; i++)
1422  {
1423  DPRINT("Argv[%lu]: %S\n", i, argv[i]);
1424  PacketSize += (DWORD)((wcslen(argv[i]) + 1) * sizeof(WCHAR));
1425  }
1426  }
1427 
1428  /* Allocate a control packet */
1429  ControlPacket = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PacketSize);
1430  if (ControlPacket == NULL)
1431  return ERROR_NOT_ENOUGH_MEMORY;
1432 
1433  ControlPacket->dwSize = PacketSize;
1434  ControlPacket->dwControl = (Service->Status.dwServiceType & SERVICE_WIN32_OWN_PROCESS)
1437  ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
1438  ControlPacket->dwServiceTag = Service->dwTag;
1439 
1440  /* Copy the start command line */
1441  ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
1442  Ptr = (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset);
1443  wcscpy(Ptr, Service->lpServiceName);
1444 
1445  ControlPacket->dwArgumentsCount = 0;
1446  ControlPacket->dwArgumentsOffset = 0;
1447 
1448  /* Copy the argument vector */
1449  if (argc > 0 && argv != NULL)
1450  {
1451  Ptr += wcslen(Service->lpServiceName) + 1;
1452  pOffPtr = (PWSTR*)ALIGN_UP_POINTER(Ptr, PWSTR);
1453  pArgPtr = (PWSTR)((ULONG_PTR)pOffPtr + argc * sizeof(PWSTR));
1454 
1455  ControlPacket->dwArgumentsCount = argc;
1456  ControlPacket->dwArgumentsOffset = (DWORD)((ULONG_PTR)pOffPtr - (ULONG_PTR)ControlPacket);
1457 
1458  DPRINT("dwArgumentsCount: %lu\n", ControlPacket->dwArgumentsCount);
1459  DPRINT("dwArgumentsOffset: %lu\n", ControlPacket->dwArgumentsOffset);
1460 
1461  for (i = 0; i < argc; i++)
1462  {
1463  wcscpy(pArgPtr, argv[i]);
1464  pOffPtr[i] = (PWSTR)((ULONG_PTR)pArgPtr - (ULONG_PTR)pOffPtr);
1465  DPRINT("offset[%lu]: %p\n", i, pOffPtr[i]);
1466  pArgPtr += wcslen(argv[i]) + 1;
1467  }
1468  }
1469 
1470  bResult = WriteFile(Service->lpImage->hControlPipe,
1471  ControlPacket,
1472  PacketSize,
1473  &dwWriteCount,
1474  &Overlapped);
1475  if (bResult == FALSE)
1476  {
1477  DPRINT("WriteFile() returned FALSE\n");
1478 
1479  dwError = GetLastError();
1480  if (dwError == ERROR_IO_PENDING)
1481  {
1482  DPRINT("dwError: ERROR_IO_PENDING\n");
1483 
1484  dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1485  PipeTimeout);
1486  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1487 
1488  if (dwError == WAIT_TIMEOUT)
1489  {
1490  bResult = CancelIo(Service->lpImage->hControlPipe);
1491  if (bResult == FALSE)
1492  {
1493  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1494  }
1495 
1497  goto Done;
1498  }
1499  else if (dwError == WAIT_OBJECT_0)
1500  {
1501  bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1502  &Overlapped,
1503  &dwWriteCount,
1504  TRUE);
1505  if (bResult == FALSE)
1506  {
1507  dwError = GetLastError();
1508  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1509 
1510  goto Done;
1511  }
1512  }
1513  }
1514  else
1515  {
1516  DPRINT1("WriteFile() failed (Error %lu)\n", dwError);
1517  goto Done;
1518  }
1519  }
1520 
1521  /* Read the reply */
1522  Overlapped.hEvent = (HANDLE) NULL;
1523 
1524  bResult = ReadFile(Service->lpImage->hControlPipe,
1525  &ReplyPacket,
1526  sizeof(SCM_REPLY_PACKET),
1527  &dwReadCount,
1528  &Overlapped);
1529  if (bResult == FALSE)
1530  {
1531  DPRINT("ReadFile() returned FALSE\n");
1532 
1533  dwError = GetLastError();
1534  if (dwError == ERROR_IO_PENDING)
1535  {
1536  DPRINT("dwError: ERROR_IO_PENDING\n");
1537 
1538  dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1539  PipeTimeout);
1540  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1541 
1542  if (dwError == WAIT_TIMEOUT)
1543  {
1544  bResult = CancelIo(Service->lpImage->hControlPipe);
1545  if (bResult == FALSE)
1546  {
1547  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1548  }
1549 
1551  goto Done;
1552  }
1553  else if (dwError == WAIT_OBJECT_0)
1554  {
1555  bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1556  &Overlapped,
1557  &dwReadCount,
1558  TRUE);
1559  if (bResult == FALSE)
1560  {
1561  dwError = GetLastError();
1562  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1563 
1564  goto Done;
1565  }
1566  }
1567  }
1568  else
1569  {
1570  DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
1571  goto Done;
1572  }
1573  }
1574 
1575 Done:
1576  /* Release the control packet */
1578  0,
1579  ControlPacket);
1580 
1581  if (dwReadCount == sizeof(SCM_REPLY_PACKET))
1582  {
1583  dwError = ReplyPacket.dwError;
1584  }
1585 
1586  DPRINT("ScmSendStartCommand() done\n");
1587 
1588  return dwError;
1589 }
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 1074 of file database.c.

1075 {
1076  DPRINT("ScmShutdownServiceDatabase() called\n");
1077 
1080 
1081  DPRINT("ScmShutdownServiceDatabase() done\n");
1082 }
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:920

Referenced by ShutdownHandlerRoutine().

◆ ScmStartService()

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

Definition at line 2021 of file database.c.

2024 {
2025  DWORD dwError = ERROR_SUCCESS;
2026  SC_RPC_LOCK Lock = NULL;
2027 
2028  DPRINT("ScmStartService() called\n");
2029  DPRINT("Start Service %p (%S)\n", Service, Service->lpServiceName);
2030 
2031  /* Acquire the service control critical section, to synchronize starts */
2033 
2034  /*
2035  * Acquire the user service start lock while the service is starting, if
2036  * needed (i.e. if we are not starting it during the initialization phase).
2037  * If we don't success, bail out.
2038  */
2039  if (!ScmInitialize)
2040  {
2041  dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
2042  if (dwError != ERROR_SUCCESS) goto done;
2043  }
2044 
2045  /* Really start the service */
2046  dwError = ScmLoadService(Service, argc, argv);
2047 
2048  /* Release the service start lock, if needed, and the critical section */
2050 
2051 done:
2053 
2054  DPRINT("ScmStartService() done (Error %lu)\n", dwError);
2055 
2056  return dwError;
2057 }
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:1909
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 1771 of file database.c.

1774 {
1775  PROCESS_INFORMATION ProcessInformation;
1776  STARTUPINFOW StartupInfo;
1777  LPVOID lpEnvironment;
1778  BOOL Result;
1779  DWORD dwError = ERROR_SUCCESS;
1780 
1781  DPRINT("ScmStartUserModeService(%p)\n", Service);
1782 
1783  /* If the image is already running ... */
1784  if (Service->lpImage->dwImageRunCount > 1)
1785  {
1786  /* ... just send a start command */
1788  }
1789 
1790  /* Otherwise start its process */
1791  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
1792  StartupInfo.cb = sizeof(StartupInfo);
1793  ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
1794 
1795  if (Service->lpImage->hToken)
1796  {
1797  /* User token: Run the service under the user account */
1798 
1799  if (!CreateEnvironmentBlock(&lpEnvironment, Service->lpImage->hToken, FALSE))
1800  {
1801  /* We failed, run the service with the current environment */
1802  DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with the current environment.\n",
1803  GetLastError(), Service->lpServiceName);
1804  lpEnvironment = NULL;
1805  }
1806 
1807  /* Impersonate the new user */
1808  Result = ImpersonateLoggedOnUser(Service->lpImage->hToken);
1809  if (Result)
1810  {
1811  /* Launch the process in the user's logon session */
1812  Result = CreateProcessAsUserW(Service->lpImage->hToken,
1813  NULL,
1814  Service->lpImage->pszImagePath,
1815  NULL,
1816  NULL,
1817  FALSE,
1819  lpEnvironment,
1820  NULL,
1821  &StartupInfo,
1822  &ProcessInformation);
1823  if (!Result)
1824  dwError = GetLastError();
1825 
1826  /* Revert the impersonation */
1827  RevertToSelf();
1828  }
1829  else
1830  {
1831  dwError = GetLastError();
1832  DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", dwError);
1833  }
1834  }
1835  else
1836  {
1837  /* No user token: Run the service under the LocalSystem account */
1838 
1839  if (!CreateEnvironmentBlock(&lpEnvironment, NULL, TRUE))
1840  {
1841  /* We failed, run the service with the current environment */
1842  DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with the current environment.\n",
1843  GetLastError(), Service->lpServiceName);
1844  lpEnvironment = NULL;
1845  }
1846 
1847  /* Use the interactive desktop if the service is interactive */
1848  if ((NoInteractiveServices == 0) &&
1849  (Service->Status.dwServiceType & SERVICE_INTERACTIVE_PROCESS))
1850  {
1851  StartupInfo.dwFlags |= STARTF_INHERITDESKTOP;
1852  StartupInfo.lpDesktop = L"WinSta0\\Default";
1853  }
1854 
1856  Service->lpImage->pszImagePath,
1857  NULL,
1858  NULL,
1859  FALSE,
1861  lpEnvironment,
1862  NULL,
1863  &StartupInfo,
1864  &ProcessInformation);
1865  if (!Result)
1866  dwError = GetLastError();
1867  }
1868 
1869  if (lpEnvironment)
1870  DestroyEnvironmentBlock(lpEnvironment);
1871 
1872  if (!Result)
1873  {
1874  DPRINT1("Starting '%S' failed with error %d\n",
1875  Service->lpServiceName, dwError);
1876  return dwError;
1877  }
1878 
1879  DPRINT("Process Id: %lu Handle %p\n",
1880  ProcessInformation.dwProcessId,
1881  ProcessInformation.hProcess);
1882  DPRINT("Thread Id: %lu Handle %p\n",
1883  ProcessInformation.dwThreadId,
1884  ProcessInformation.hThread);
1885 
1886  /* Get the process handle and ID */
1887  Service->lpImage->hProcess = ProcessInformation.hProcess;
1888  Service->lpImage->dwProcessId = ProcessInformation.dwProcessId;
1889 
1890  /* Resume the main thread and close its handle */
1891  ResumeThread(ProcessInformation.hThread);
1892  CloseHandle(ProcessInformation.hThread);
1893 
1894  /* Connect control pipe */
1895  dwError = ScmWaitForServiceConnect(Service);
1896  if (dwError != ERROR_SUCCESS)
1897  {
1898  DPRINT1("Connecting control pipe failed! (Error %lu)\n", dwError);
1899  Service->lpImage->dwProcessId = 0;
1900  return dwError;
1901  }
1902 
1903  /* Send the start command */
1905 }
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:1635
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:819
#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:4623
DWORD cb
Definition: winbase.h:817
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:278
static DWORD ScmSendStartCommand(PSERVICE Service, DWORD argc, LPWSTR *argv)
Definition: database.c:1384
#define DETACHED_PROCESS
Definition: winbase.h:179
#define DPRINT1
Definition: precomp.h:8
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:529
DWORD dwFlags
Definition: winbase.h:828
static DWORD ScmWaitForServiceConnect(PSERVICE Service)
Definition: database.c:1593
static DWORD NoInteractiveServices
Definition: database.c:33

Referenced by ScmLoadService().

◆ ScmUnlockDatabase()

◆ ScmWaitForServiceConnect()

static DWORD ScmWaitForServiceConnect ( PSERVICE  Service)
static

Definition at line 1593 of file database.c.

1594 {
1595  DWORD dwRead = 0;
1596  DWORD dwProcessId = 0;
1597  DWORD dwError = ERROR_SUCCESS;
1598  BOOL bResult;
1599  OVERLAPPED Overlapped = {0};
1600 #if 0
1601  LPCWSTR lpLogStrings[3];
1602  WCHAR szBuffer1[20];
1603  WCHAR szBuffer2[20];
1604 #endif
1605 
1606  DPRINT("ScmWaitForServiceConnect()\n");
1607 
1608  Overlapped.hEvent = (HANDLE)NULL;
1609 
1610  bResult = ConnectNamedPipe(Service->lpImage->hControlPipe,
1611  &Overlapped);
1612  if (bResult == FALSE)
1613  {
1614  DPRINT("ConnectNamedPipe() returned FALSE\n");
1615 
1616  dwError = GetLastError();
1617  if (dwError == ERROR_IO_PENDING)
1618  {
1619  DPRINT("dwError: ERROR_IO_PENDING\n");
1620 
1621  dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1622  PipeTimeout);
1623  DPRINT("WaitForSingleObject() returned %lu\n", dwError);
1624 
1625  if (dwError == WAIT_TIMEOUT)
1626  {
1627  DPRINT("WaitForSingleObject() returned WAIT_TIMEOUT\n");
1628 
1629  bResult = CancelIo(Service->lpImage->hControlPipe);
1630  if (bResult == FALSE)
1631  {
1632  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1633  }
1634 
1635 #if 0
1636  _ultow(PipeTimeout, szBuffer1, 10);
1637  lpLogStrings[0] = Service->lpDisplayName;
1638  lpLogStrings[1] = szBuffer1;
1639 
1642  2,
1643  lpLogStrings);
1644 #endif
1645  DPRINT1("Log EVENT_CONNECTION_TIMEOUT by %S\n", Service->lpDisplayName);
1646 
1648  }
1649  else if (dwError == WAIT_OBJECT_0)
1650  {
1651  bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1652  &Overlapped,
1653  &dwRead,
1654  TRUE);
1655  if (bResult == FALSE)
1656  {
1657  dwError = GetLastError();
1658  DPRINT1("GetOverlappedResult failed (Error %lu)\n", dwError);
1659 
1660  return dwError;
1661  }
1662  }
1663  }
1664  else if (dwError != ERROR_PIPE_CONNECTED)
1665  {
1666  DPRINT1("ConnectNamedPipe failed (Error %lu)\n", dwError);
1667  return dwError;
1668  }
1669  }
1670 
1671  DPRINT("Control pipe connected!\n");
1672 
1673  Overlapped.hEvent = (HANDLE) NULL;
1674 
1675  /* Read the process id from pipe */
1676  bResult = ReadFile(Service->lpImage->hControlPipe,
1677  (LPVOID)&dwProcessId,
1678  sizeof(DWORD),
1679  &dwRead,
1680  &Overlapped);
1681  if (bResult == FALSE)
1682  {
1683  DPRINT("ReadFile() returned FALSE\n");
1684 
1685  dwError = GetLastError();
1686  if (dwError == ERROR_IO_PENDING)
1687  {
1688  DPRINT("dwError: ERROR_IO_PENDING\n");
1689 
1690  dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
1691  PipeTimeout);
1692  if (dwError == WAIT_TIMEOUT)
1693  {
1694  DPRINT("WaitForSingleObject() returned WAIT_TIMEOUT\n");
1695 
1696  bResult = CancelIo(Service->lpImage->hControlPipe);
1697  if (bResult == FALSE)
1698  {
1699  DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
1700  }
1701 
1702 #if 0
1703  _ultow(PipeTimeout, szBuffer1, 10);
1704  lpLogStrings[0] = szBuffer1;
1705 
1708  1,
1709  lpLogStrings);
1710 #endif
1711  DPRINT1("Log EVENT_READFILE_TIMEOUT by %S\n", Service->lpDisplayName);
1712 
1714  }
1715  else if (dwError == WAIT_OBJECT_0)
1716  {
1717  DPRINT("WaitForSingleObject() returned WAIT_OBJECT_0\n");
1718 
1719  DPRINT("Process Id: %lu\n", dwProcessId);
1720 
1721  bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
1722  &Overlapped,
1723  &dwRead,
1724  TRUE);
1725  if (bResult == FALSE)
1726  {
1727  dwError = GetLastError();
1728  DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
1729 
1730  return dwError;
1731  }
1732  }
1733  else
1734  {
1735  DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
1736  }
1737  }
1738  else
1739  {
1740  DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
1741  return dwError;
1742  }
1743  }
1744 
1745  if (dwProcessId != Service->lpImage->dwProcessId)
1746  {
1747 #if 0
1748  _ultow(Service->lpImage->dwProcessId, szBuffer1, 10);
1749  _ultow(dwProcessId, szBuffer2, 10);
1750 
1751  lpLogStrings[0] = Service->lpDisplayName;
1752  lpLogStrings[1] = szBuffer1;
1753  lpLogStrings[2] = szBuffer2;
1754 
1757  3,
1758  lpLogStrings);
1759 #endif
1760 
1761  DPRINT1("Log EVENT_SERVICE_DIFFERENT_PID_CONNECTED by %S\n", Service->lpDisplayName);
1762  }
1763 
1764  DPRINT("ScmWaitForServiceConnect() done\n");
1765 
1766  return ERROR_SUCCESS;
1767 }
_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:52
__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

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