ReactOS  0.4.13-dev-651-g5dbc677
groupdb.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Service Control Manager
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: base/system/services/groupdb.c
5  * PURPOSE: Service group control interface
6  * COPYRIGHT: Copyright 2005 Eric Kohl
7  *
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "services.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* GLOBALS *******************************************************************/
18 
21 
22 
23 /* FUNCTIONS *****************************************************************/
24 
27  _In_ LPCWSTR lpGroupName)
28 {
29  PLIST_ENTRY GroupEntry;
30  PSERVICE_GROUP lpGroup;
31 
32  DPRINT("ScmGetServiceGroupByName(%S)\n", lpGroupName);
33 
34  GroupEntry = GroupListHead.Flink;
35  while (GroupEntry != &GroupListHead)
36  {
37  lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
38 
39  if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
40  return lpGroup;
41 
42  GroupEntry = GroupEntry->Flink;
43  }
44 
45  GroupEntry = UnknownGroupListHead.Flink;
46  while (GroupEntry != &UnknownGroupListHead)
47  {
48  lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
49 
50  if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
51  return lpGroup;
52 
53  GroupEntry = GroupEntry->Flink;
54  }
55 
56  return NULL;
57 }
58 
59 
60 DWORD
62  LPCWSTR lpGroupName)
63 {
64  PLIST_ENTRY GroupEntry;
65  PSERVICE_GROUP lpGroup;
66 
67  DPRINT("ScmSetServiceGroup(%S)\n", lpGroupName);
68 
69  if (lpService->lpGroup != NULL)
70  {
71  ASSERT(lpService->lpGroup->dwRefCount != 0);
72  ASSERT(lpService->lpGroup->dwRefCount == (DWORD)-1 ||
73  lpService->lpGroup->dwRefCount < 10000);
74  if (lpService->lpGroup->dwRefCount != (DWORD)-1)
75  {
76  lpService->lpGroup->dwRefCount--;
77  if (lpService->lpGroup->dwRefCount == 0)
78  {
79  ASSERT(lpService->lpGroup->TagCount == 0);
80  ASSERT(lpService->lpGroup->TagArray == NULL);
82  HeapFree(GetProcessHeap(), 0, lpService->lpGroup);
83  lpService->lpGroup = NULL;
84  }
85  }
86  }
87 
88  if (lpGroupName == NULL)
89  return ERROR_SUCCESS;
90 
91  GroupEntry = GroupListHead.Flink;
92  while (GroupEntry != &GroupListHead)
93  {
94  lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
95 
96  if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
97  {
98  lpService->lpGroup = lpGroup;
99  return ERROR_SUCCESS;
100  }
101 
102  GroupEntry = GroupEntry->Flink;
103  }
104 
105  GroupEntry = UnknownGroupListHead.Flink;
106  while (GroupEntry != &UnknownGroupListHead)
107  {
108  lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
109 
110  if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
111  {
112  lpGroup->dwRefCount++;
113  lpService->lpGroup = lpGroup;
114  return ERROR_SUCCESS;
115  }
116 
117  GroupEntry = GroupEntry->Flink;
118  }
119 
122  sizeof(SERVICE_GROUP) + ((wcslen(lpGroupName) + 1)* sizeof(WCHAR)));
123  if (lpGroup == NULL)
125 
126  wcscpy(lpGroup->szGroupName, lpGroupName);
127  lpGroup->lpGroupName = lpGroup->szGroupName;
128  lpGroup->dwRefCount = 1;
129  lpService->lpGroup = lpGroup;
130 
132  &lpGroup->GroupListEntry);
133 
134  return ERROR_SUCCESS;
135 }
136 
137 
138 static NTSTATUS WINAPI
143  PVOID Context,
145 {
147 
148  DPRINT("CreateGroupOrderListRoutine(%S, %x, %p, %x, %p, %p)\n",
150 
151  if (ValueType == REG_BINARY &&
152  ValueData != NULL &&
153  ValueLength >= sizeof(DWORD) &&
154  ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
155  {
157  Group->TagCount = ((PULONG)ValueData)[0];
158  if (Group->TagCount > 0)
159  {
160  if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
161  {
162  Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),
164  Group->TagCount * sizeof(DWORD));
165  if (Group->TagArray == NULL)
166  {
167  Group->TagCount = 0;
169  }
170 
171  RtlCopyMemory(Group->TagArray,
172  (PULONG)ValueData + 1,
173  Group->TagCount * sizeof(DWORD));
174  }
175  else
176  {
177  Group->TagCount = 0;
178  return STATUS_UNSUCCESSFUL;
179  }
180  }
181  }
182 
183  return STATUS_SUCCESS;
184 }
185 
186 
187 static NTSTATUS WINAPI
192  PVOID Context,
194 {
198 
199  if (ValueType == REG_SZ)
200  {
201  DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
202 
205  sizeof(SERVICE_GROUP) + ((wcslen((const wchar_t*) ValueData) + 1) * sizeof(WCHAR)));
206  if (Group == NULL)
207  {
209  }
210 
211  wcscpy(Group->szGroupName, (const wchar_t*) ValueData);
212  Group->lpGroupName = Group->szGroupName;
213  Group->dwRefCount = (DWORD)-1;
214 
218 
220  L"GroupOrderList",
221  QueryTable,
222  (PVOID)Group,
223  NULL);
224  DPRINT("%x %lu %S\n", Status, Group->TagCount, (PWSTR)ValueData);
225 
227  &Group->GroupListEntry);
228  }
229 
230  return STATUS_SUCCESS;
231 }
232 
233 
234 DWORD
236 {
239 
242 
243  /* Build group order list */
245  sizeof(QueryTable));
246 
247  QueryTable[0].Name = L"List";
249 
251  L"ServiceGroupOrder",
252  QueryTable,
253  NULL,
254  NULL);
255 
257 }
258 
259 /* EOF */
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ERROR_SUCCESS
Definition: deptool.c:10
LIST_ENTRY GroupListHead
Definition: groupdb.c:19
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define REG_BINARY
Definition: nt_native.h:1496
uint16_t * PWSTR
Definition: typedefs.h:54
_In_opt_ PSID Group
Definition: rtlfuncs.h:1606
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
LONG NTSTATUS
Definition: precomp.h:26
LPWSTR lpGroupName
Definition: services.h:32
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
PSERVICE_GROUP lpGroup
Definition: services.h:63
uint16_t * PWCHAR
Definition: typedefs.h:54
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
#define InsertTailList(ListHead, Entry)
#define DWORD
Definition: nt_native.h:44
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
WCHAR szGroupName[1]
Definition: services.h:39
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4004
smooth NULL
Definition: ftsmooth.c:416
DWORD ScmSetServiceGroup(PSERVICE lpService, LPCWSTR lpGroupName)
Definition: groupdb.c:61
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
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WINAPI
Definition: msvc.h:8
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_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
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
static NTSTATUS WINAPI CreateGroupOrderListRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: groupdb.c:139
struct _SERVICE_GROUP * PSERVICE_GROUP
Definition: typedefs.h:117
DWORD dwRefCount
Definition: services.h:34
LIST_ENTRY GroupListEntry
Definition: services.h:31
PULONG TagArray
Definition: services.h:37
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define _In_
Definition: no_sal2.h:204
LIST_ENTRY UnknownGroupListHead
Definition: groupdb.c:20
ULONG TagCount
Definition: services.h:36
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int * PULONG
Definition: retypes.h:1
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
static NTSTATUS WINAPI CreateGroupListRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: groupdb.c:188
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PSERVICE_GROUP ScmGetServiceGroupByName(_In_ LPCWSTR lpGroupName)
Definition: groupdb.c:26
struct _SERVICE_GROUP SERVICE_GROUP
return STATUS_SUCCESS
Definition: btrfs.c:2777
DWORD ScmCreateGroupList(VOID)
Definition: groupdb.c:235
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#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 REG_SZ
Definition: layer.c:22