Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

613 lines
17 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. dataman.h
  5. Abstract:
  6. Contains data structures and function prototypes for the Service
  7. Controller Database Manager and the Group List Database Manager.
  8. (Dataman.c & Groupman.c)
  9. Author:
  10. Dan Lafferty (danl) 22-Oct-1993
  11. Environment:
  12. User Mode -Win32
  13. Revision History:
  14. 04-Dec-1996 AnirudhS
  15. Added CCrashRecord.
  16. 17-Aug-1995 AnirudhS
  17. Removed State field from LOAD_ORDER_GROUP, since it is recomputed
  18. every time it is read.
  19. 26-Jun-1995 AnirudhS
  20. Added ScNotifyServiceObject.
  21. 12-Apr-1995 AnirudhS
  22. Added AccountName field to image record.
  23. 06-Oct-1993 danl
  24. Re-arranged comments so that structures are easier to read.
  25. 19-Jan-1992 danl
  26. Modified for use with the "real" service controller
  27. 20-Mar-1991 danl
  28. created
  29. --*/
  30. #ifndef SCDATAMAN_INCLUDED
  31. #define SCDATAMAN_INCLUDED
  32. #define USE_GROUPS
  33. //
  34. // ImageFlag definitions
  35. //
  36. #define CANSHARE_FLAG 0x00000001 // service can run in a shared process
  37. #define IS_SYSTEM_SERVICE 0x00000002 // service runs in this exe or the security process
  38. //
  39. // StatusFlag definitions
  40. //
  41. #define DELETE_FLAG 0x00000001 // service is marked for delete
  42. #define UPDATE_FLAG 0x00000002 //
  43. #define CURRENTSTART_FLAG 0x00000004 //
  44. //
  45. // StatusFlag Macros. SR = ServiceRecord
  46. //
  47. #define SET_DELETE_FLAG(SR) (((SR)->StatusFlag) |= DELETE_FLAG)
  48. #define CLEAR_DELETE_FLAG(SR) (((SR)->StatusFlag) &= (~DELETE_FLAG))
  49. #define DELETE_FLAG_IS_SET(SR) (((SR)->StatusFlag) & DELETE_FLAG)
  50. #define SET_UPDATE_FLAG(SR) (((SR)->StatusFlag) |= UPDATE_FLAG)
  51. #define CLEAR_UPDATE_FLAG(SR) (((SR)->StatusFlag) &= (~UPDATE_FLAG))
  52. #define UPDATE_FLAG_IS_SET(SR) (((SR)->StatusFlag) & UPDATE_FLAG)
  53. //
  54. // To get a demand start service to be started correctly in group
  55. // order specified by the ServiceGroupOrder list, we need an additional
  56. // flag to indicate that this service must be included in the same start
  57. // request.
  58. //
  59. #define SET_CURRENTSTART_FLAG(SR) (((SR)->StatusFlag) |= CURRENTSTART_FLAG)
  60. #define CLEAR_CURRENTSTART_FLAG(SR) (((SR)->StatusFlag) &= (~CURRENTSTART_FLAG))
  61. #define CURRENTSTART_FLAG_IS_SET(SR) (((SR)->StatusFlag) & CURRENTSTART_FLAG)
  62. //
  63. // Data Structures
  64. //
  65. //
  66. //==================
  67. // LOAD_ORDER_GROUP
  68. //==================
  69. // NOTE: This is an ordered linked list. The Next group is loaded after
  70. // this group.
  71. //
  72. // Reference count which indicates the number of members in this
  73. // group plus any dependency pointer that points to this group.
  74. // This field is only used for standalone groups so that we know
  75. // when to delete the group entry. This value is always set to
  76. // 0xffffffff if this entry represents an order group.
  77. //
  78. typedef struct _LOAD_ORDER_GROUP {
  79. struct _LOAD_ORDER_GROUP *Next;
  80. struct _LOAD_ORDER_GROUP *Prev;
  81. LPWSTR GroupName;
  82. DWORD RefCount;
  83. } LOAD_ORDER_GROUP, *PLOAD_ORDER_GROUP, *LPLOAD_ORDER_GROUP;
  84. //================
  85. // IMAGE_RECORD
  86. //================
  87. typedef struct _IMAGE_RECORD {
  88. struct _IMAGE_RECORD *Prev; // linked list
  89. struct _IMAGE_RECORD *Next; // linked list
  90. LPWSTR ImageName; // fully qualified .exe name
  91. DWORD Pid; // Process ID
  92. DWORD ServiceCount; // Num services running in process
  93. HANDLE PipeHandle; // Handle to Service
  94. HANDLE ProcessHandle; // Handle for process
  95. HANDLE ObjectWaitHandle; // Handle for waiting on the process
  96. HANDLE TokenHandle; // Logon token handle
  97. LUID AccountLuid; // Unique LUID for this logon session
  98. HANDLE ProfileHandle; // User profile handle
  99. LPWSTR AccountName; // Account process was started under
  100. DWORD ImageFlags; // Flags for the IMAGE_RECORD
  101. }IMAGE_RECORD, *PIMAGE_RECORD, *LPIMAGE_RECORD;
  102. typedef enum _DEPEND_TYPE {
  103. TypeNone = 0,
  104. TypeDependOnService = 128,
  105. TypeDependOnGroup,
  106. TypeDependOnUnresolved // only for service
  107. } DEPEND_TYPE, *PDEPEND_TYPE, *LPDEPEND_TYPE;
  108. //================
  109. // DEPEND_RECORD
  110. //================
  111. // A service record has a pointer to this structure if the service
  112. // must be started after some services, or must be stopped after some
  113. // services.
  114. // NOTE: This is an ordered linked list. This service depends on the
  115. // "Next" service. Question: Does this service depend on all the services
  116. // in the Next chain?
  117. //
  118. // Depend union:
  119. // Based on the DependType field, this pointer may point to a
  120. // service or a group which the service depends on, or an
  121. // unresolved dependency structure.
  122. //
  123. typedef struct _DEPEND_RECORD {
  124. struct _DEPEND_RECORD *Next;
  125. DEPEND_TYPE DependType;
  126. union {
  127. struct _SERVICE_RECORD * DependService;
  128. struct _LOAD_ORDER_GROUP * DependGroup;
  129. struct _UNRESOLVED_DEPEND * DependUnresolved;
  130. LPVOID Depend; // used when type doesn't matter
  131. };
  132. } DEPEND_RECORD, *PDEPEND_RECORD, *LPDEPEND_RECORD;
  133. //================
  134. // CCrashRecord
  135. //================
  136. // This structure counts a service's crashes and remembers the time of the
  137. // last crash. It is allocated only for services that crash.
  138. //
  139. class CCrashRecord
  140. {
  141. public:
  142. CCrashRecord() :
  143. _LastCrashTime(0),
  144. _Count(0)
  145. { }
  146. DWORD IncrementCount(DWORD ResetSeconds);
  147. private:
  148. __int64 _LastCrashTime; // FILETIME = __int64
  149. DWORD _Count;
  150. };
  151. //================
  152. // SERVICE_RECORD
  153. //================
  154. // Dependency information:
  155. // StartDepend is a linked list of services and groups that must be
  156. // started first before this service can start.
  157. // StopDepend is a linked list of services and groups that must be
  158. // stopped first before this service can stop.
  159. // Dependencies is a string read in from the registry. Deleted when
  160. // the info has been converted to a StartDepend list.
  161. //
  162. // StartError:
  163. // Error encountered by service controller when starting a service.
  164. // This is distinguished from error posted by the service itself in
  165. // the exitcode field.
  166. //
  167. // StartState:
  168. // SC managed service state which is distinguished from the service
  169. // current state to enable correct handling of start dependencies.
  170. //
  171. // Load order group information:
  172. //
  173. // MemberOfGroup is a pointer to a load order group which this service
  174. // is currently a member of. This value is set to NULL if this
  175. // service does not belong to a group. A non-NULL pointer could
  176. // point to a group entry in either the order group or standalone
  177. // group list.
  178. //
  179. // RegistryGroup is a pointer to a group which we have recorded in the
  180. // registry as the group this service belongs to. This is not the
  181. // same as MemberOfGroup whenever the service is running and the
  182. // load order group of the service has been changed
  183. //
  184. typedef struct _SERVICE_RECORD {
  185. struct _SERVICE_RECORD *Prev; // linked list
  186. struct _SERVICE_RECORD *Next; // linked list
  187. LPWSTR ServiceName; // points to service name
  188. LPWSTR DisplayName; // points to display name
  189. DWORD ResumeNum; // Ordered number for this rec
  190. DWORD ServerAnnounce; // Server announcement bit flags
  191. DWORD Signature; // Identifies this as a service record.
  192. DWORD UseCount; // How many open handles to service
  193. DWORD StatusFlag; // status(delete,update...)
  194. union {
  195. LPIMAGE_RECORD ImageRecord; // Points to image record
  196. LPWSTR ObjectName; // Points to driver object name
  197. };
  198. SERVICE_STATUS ServiceStatus; // see winsvc.h
  199. DWORD StartType; // AUTO, DEMAND, etc.
  200. DWORD ErrorControl; // NORMAL, SEVERE, etc.
  201. DWORD Tag; // DWORD Id for the service,0=none.
  202. LPDEPEND_RECORD StartDepend;
  203. LPDEPEND_RECORD StopDepend;
  204. LPWSTR Dependencies;
  205. PSECURITY_DESCRIPTOR ServiceSd;
  206. DWORD StartError;
  207. DWORD StartState;
  208. LPLOAD_ORDER_GROUP MemberOfGroup;
  209. LPLOAD_ORDER_GROUP RegistryGroup;
  210. CCrashRecord * CrashRecord;
  211. }
  212. SERVICE_RECORD, *PSERVICE_RECORD, *LPSERVICE_RECORD;
  213. //===================
  214. // UNRESOLVED_DEPEND
  215. //===================
  216. // Unresolved dependency record structure
  217. //
  218. // Unresolved dependency entries are linked together so that when a
  219. // new service or group is created (installed) we can look it up in this
  220. // list to see if the service or group is already depended on by some
  221. // other service.
  222. //
  223. typedef struct _UNRESOLVED_DEPEND {
  224. struct _UNRESOLVED_DEPEND *Next;
  225. struct _UNRESOLVED_DEPEND *Prev;
  226. LPWSTR Name; // Service or group name
  227. DWORD RefCount;
  228. } UNRESOLVED_DEPEND, *PUNRESOLVED_DEPEND, *LPUNRESOLVED_DEPEND;
  229. //
  230. // Macros & Constants
  231. //
  232. //
  233. // for every service record in the database...
  234. //
  235. #define FOR_ALL_SERVICES(SR) \
  236. SC_ASSERT(ScServiceListLock.Have()); \
  237. for (LPSERVICE_RECORD SR = ScGetServiceDatabase(); \
  238. SR != NULL; \
  239. SR = SR->Next)
  240. //
  241. // for every service record in the database that meets this condition...
  242. //
  243. #define FOR_SERVICES_THAT(SR, condition) \
  244. FOR_ALL_SERVICES(SR) \
  245. if (!(condition)) \
  246. continue; \
  247. else
  248. #define FIND_END_OF_LIST(record) while((record)->Next != NULL) { \
  249. (record)=(record)->Next; \
  250. }
  251. #define REMOVE_FROM_LIST(record) (record)->Prev->Next = (record)->Next; \
  252. if ((record)->Next != NULL) { \
  253. (record)->Next->Prev = (record)->Prev; \
  254. }
  255. #define ADD_TO_LIST(record, newRec) FIND_END_OF_LIST((record)) \
  256. (record)->Next = (newRec); \
  257. (newRec)->Prev = (record); \
  258. (newRec)->Next = NULL;
  259. //
  260. // Service controller maintains the state of a service when
  261. // starting up a service and its dependencies in the StartState
  262. // field of the service record.
  263. //
  264. #define SC_NEVER_STARTED 0x00000000
  265. #define SC_START_NOW 0x00000001
  266. #define SC_START_PENDING 0x00000002
  267. #define SC_START_SUCCESS 0x00000003
  268. #define SC_START_FAIL 0x00000004
  269. #define TERMINATE_TIMEOUT 20000 // wait response to terminate req.
  270. //
  271. // External Globals
  272. //
  273. extern LPLOAD_ORDER_GROUP ScGlobalTDIGroup;
  274. extern LPLOAD_ORDER_GROUP ScGlobalPNP_TDIGroup;
  275. //
  276. // Function Prototypes
  277. //
  278. LPLOAD_ORDER_GROUP
  279. ScGetOrderGroupList(
  280. VOID
  281. );
  282. LPLOAD_ORDER_GROUP
  283. ScGetStandaloneGroupList(
  284. VOID
  285. );
  286. LPSERVICE_RECORD
  287. ScGetServiceDatabase(
  288. VOID
  289. );
  290. LPUNRESOLVED_DEPEND
  291. ScGetUnresolvedDependList(
  292. VOID
  293. );
  294. BOOL
  295. ScInitDatabase(
  296. VOID
  297. );
  298. VOID
  299. ScInitGroupDatabase(VOID);
  300. VOID
  301. ScEndGroupDatabase(VOID);
  302. DWORD
  303. ScCreateDependRecord(
  304. IN BOOL IsStartList,
  305. IN OUT PSERVICE_RECORD ServiceRecord,
  306. OUT PDEPEND_RECORD *DependRecord
  307. );
  308. DWORD
  309. ScCreateImageRecord (
  310. OUT LPIMAGE_RECORD *ImageRecordPtr,
  311. IN LPWSTR ImageName,
  312. IN LPWSTR AccountName,
  313. IN DWORD Pid,
  314. IN HANDLE PipeHandle,
  315. IN HANDLE ProcessHandle,
  316. IN HANDLE TokenHandle,
  317. IN HANDLE ProfileHandle,
  318. IN DWORD ImageFlags
  319. );
  320. DWORD
  321. ScCreateServiceRecord(
  322. IN LPWSTR ServiceName,
  323. OUT LPSERVICE_RECORD *ServiceRecord
  324. );
  325. VOID
  326. ScFreeServiceRecord(
  327. IN LPSERVICE_RECORD ServiceRecord
  328. );
  329. VOID
  330. ScDecrementUseCountAndDelete(
  331. LPSERVICE_RECORD ServiceRecord
  332. );
  333. BOOL
  334. ScFindEnumStart(
  335. IN DWORD ResumeIndex,
  336. OUT LPSERVICE_RECORD *ServiceRecordPtr
  337. );
  338. BOOL
  339. ScGetNamedImageRecord (
  340. IN LPWSTR ImageName,
  341. OUT LPIMAGE_RECORD *ImageRecordPtr
  342. );
  343. DWORD
  344. ScGetNamedServiceRecord (
  345. IN LPWSTR ServiceName,
  346. OUT LPSERVICE_RECORD *ServiceRecordPtr
  347. );
  348. LPLOAD_ORDER_GROUP
  349. ScGetNamedGroupRecord(
  350. IN LPCWSTR GroupName
  351. );
  352. DWORD
  353. ScGetDisplayNamedServiceRecord (
  354. IN LPWSTR ServiceDisplayName,
  355. OUT LPSERVICE_RECORD *ServiceRecordPtr
  356. );
  357. DWORD
  358. ScGetTotalNumberOfRecords(
  359. VOID
  360. );
  361. VOID
  362. ScProcessCleanup(
  363. HANDLE ProcessHandle
  364. );
  365. VOID
  366. ScQueueRecoveryAction(
  367. IN LPSERVICE_RECORD ServiceRecord
  368. );
  369. VOID
  370. ScDeleteMarkedServices(
  371. VOID
  372. );
  373. DWORD
  374. ScUpdateServiceRecord (
  375. IN LPSERVICE_STATUS ServiceStatus,
  376. IN LPSERVICE_RECORD ServiceRecord
  377. );
  378. DWORD
  379. ScRemoveService (
  380. IN LPSERVICE_RECORD ServiceRecord
  381. );
  382. DWORD
  383. ScTerminateServiceProcess (
  384. IN PIMAGE_RECORD ImageRecord
  385. );
  386. VOID
  387. ScDeleteImageRecord (
  388. IN LPIMAGE_RECORD ImageRecord
  389. );
  390. VOID
  391. ScActivateServiceRecord (
  392. IN LPSERVICE_RECORD ServiceRecord,
  393. IN LPIMAGE_RECORD ImageRecord
  394. );
  395. DWORD
  396. ScDeactivateServiceRecord (
  397. IN LPSERVICE_RECORD ServiceRecord
  398. );
  399. DWORD
  400. ScCreateOrderGroupEntry(
  401. IN LPWSTR GroupName
  402. );
  403. DWORD
  404. ScAddConfigInfoServiceRecord(
  405. IN LPSERVICE_RECORD ServiceRecord,
  406. IN DWORD ServiceType,
  407. IN DWORD StartType,
  408. IN DWORD ErrorControl,
  409. IN LPWSTR Group OPTIONAL,
  410. IN DWORD Tag,
  411. IN LPWSTR Dependencies OPTIONAL,
  412. IN LPWSTR DisplayName OPTIONAL,
  413. IN PSECURITY_DESCRIPTOR Sd OPTIONAL
  414. );
  415. VOID
  416. ScGenerateDependencies(
  417. VOID
  418. );
  419. DWORD
  420. ScSetDependencyPointers(
  421. LPSERVICE_RECORD Service
  422. );
  423. DWORD
  424. ScResolveDependencyToService(
  425. LPSERVICE_RECORD Service
  426. );
  427. VOID
  428. ScUnresolveDependencyToService(
  429. LPSERVICE_RECORD Service
  430. );
  431. DWORD
  432. ScCreateDependencies(
  433. OUT PSERVICE_RECORD ServiceRecord,
  434. IN LPWSTR Dependencies OPTIONAL
  435. );
  436. VOID
  437. ScDeleteStartDependencies(
  438. IN PSERVICE_RECORD ServiceRecord
  439. );
  440. VOID
  441. ScDeleteStopDependencies(
  442. IN PSERVICE_RECORD ServiceToBeDeleted
  443. );
  444. DWORD
  445. ScCreateGroupMembership(
  446. OUT PSERVICE_RECORD ServiceRecord,
  447. IN LPWSTR Group OPTIONAL
  448. );
  449. VOID
  450. ScDeleteGroupMembership(
  451. IN OUT PSERVICE_RECORD ServiceRecord
  452. );
  453. DWORD
  454. ScCreateRegistryGroupPointer(
  455. OUT PSERVICE_RECORD ServiceRecord,
  456. IN LPWSTR Group OPTIONAL
  457. );
  458. VOID
  459. ScDeleteRegistryGroupPointer(
  460. IN OUT PSERVICE_RECORD ServiceRecord
  461. );
  462. VOID
  463. ScGetUniqueTag(
  464. IN LPWSTR GroupName,
  465. OUT LPDWORD Tag
  466. );
  467. DWORD
  468. ScUpdateServiceRecordConfig(
  469. LPSERVICE_RECORD ServiceRecord,
  470. DWORD dwServiceType,
  471. DWORD dwStartType,
  472. DWORD dwErrorControl,
  473. LPWSTR lpLoadOrderGroup,
  474. LPBYTE lpDependencies
  475. );
  476. VOID
  477. ScGetDependencySize(
  478. LPSERVICE_RECORD ServiceRecord,
  479. LPDWORD DependSize,
  480. LPDWORD MaxDependSize
  481. );
  482. DWORD
  483. ScGetDependencyString(
  484. LPSERVICE_RECORD ServiceRecord,
  485. DWORD MaxDependSize,
  486. DWORD DependSize,
  487. LPWSTR lpDependencies
  488. );
  489. BOOL
  490. ScAllocateSRHeap(
  491. DWORD HeapSize
  492. );
  493. #if DBG
  494. VOID
  495. ScDumpGroups(
  496. VOID
  497. );
  498. VOID
  499. ScDumpServiceDependencies(
  500. VOID
  501. );
  502. #endif // if DBG
  503. #endif // ifndef SCDATAMAN_INCLUDED