Hauled subsys/system items into base/system
[reactos.git] / reactos / base / system / services / groupdb.c
1 /*
2 * groupdb.c
3 */
4
5 /* INCLUDES *****************************************************************/
6
7 #include "services.h"
8
9 #define NDEBUG
10 #include <debug.h>
11
12
13 /* GLOBALS *******************************************************************/
14
15 LIST_ENTRY GroupListHead;
16 LIST_ENTRY UnknownGroupListHead;
17
18
19 /* FUNCTIONS *****************************************************************/
20
21 DWORD
22 ScmSetServiceGroup(PSERVICE lpService,
23 LPWSTR lpGroupName)
24 {
25 PLIST_ENTRY GroupEntry;
26 PSERVICE_GROUP lpGroup;
27
28 GroupEntry = GroupListHead.Flink;
29 while (GroupEntry != &GroupListHead)
30 {
31 lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
32
33 if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
34 {
35 lpService->lpGroup = lpGroup;
36 return ERROR_SUCCESS;
37 }
38
39 GroupEntry = GroupEntry->Flink;
40 }
41
42 GroupEntry = UnknownGroupListHead.Flink;
43 while (GroupEntry != &UnknownGroupListHead)
44 {
45 lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
46
47 if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
48 {
49 lpGroup->dwRefCount++;
50 lpService->lpGroup = lpGroup;
51 return ERROR_SUCCESS;
52 }
53
54 GroupEntry = GroupEntry->Flink;
55 }
56
57 lpGroup = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
58 HEAP_ZERO_MEMORY,
59 sizeof(SERVICE_GROUP) + (wcslen(lpGroupName) * sizeof(WCHAR)));
60 if (lpGroup == NULL)
61 return ERROR_NOT_ENOUGH_MEMORY;
62
63 wcscpy(lpGroup->szGroupName, lpGroupName);
64 lpGroup->lpGroupName = lpGroup->szGroupName;
65 lpGroup->dwRefCount = 1;
66
67 InsertTailList(&UnknownGroupListHead,
68 &lpGroup->GroupListEntry);
69
70 return ERROR_SUCCESS;
71 }
72
73
74 static NTSTATUS STDCALL
75 CreateGroupOrderListRoutine(PWSTR ValueName,
76 ULONG ValueType,
77 PVOID ValueData,
78 ULONG ValueLength,
79 PVOID Context,
80 PVOID EntryContext)
81 {
82 PSERVICE_GROUP Group;
83
84 DPRINT("CreateGroupOrderListRoutine(%S, %x, %x, %x, %x, %x)\n",
85 ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
86
87 if (ValueType == REG_BINARY &&
88 ValueData != NULL &&
89 ValueLength >= sizeof(DWORD) &&
90 ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
91 {
92 Group = (PSERVICE_GROUP)Context;
93 Group->TagCount = ((PULONG)ValueData)[0];
94 if (Group->TagCount > 0)
95 {
96 if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
97 {
98 Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),
99 HEAP_ZERO_MEMORY,
100 Group->TagCount * sizeof(DWORD));
101 if (Group->TagArray == NULL)
102 {
103 Group->TagCount = 0;
104 return STATUS_INSUFFICIENT_RESOURCES;
105 }
106
107 RtlCopyMemory(Group->TagArray,
108 (PULONG)ValueData + 1,
109 Group->TagCount * sizeof(DWORD));
110 }
111 else
112 {
113 Group->TagCount = 0;
114 return STATUS_UNSUCCESSFUL;
115 }
116 }
117 }
118
119 return STATUS_SUCCESS;
120 }
121
122
123 static NTSTATUS STDCALL
124 CreateGroupListRoutine(PWSTR ValueName,
125 ULONG ValueType,
126 PVOID ValueData,
127 ULONG ValueLength,
128 PVOID Context,
129 PVOID EntryContext)
130 {
131 PSERVICE_GROUP Group;
132 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
133 NTSTATUS Status;
134
135 if (ValueType == REG_SZ)
136 {
137 DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
138
139 Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
140 HEAP_ZERO_MEMORY,
141 sizeof(SERVICE_GROUP) + (wcslen(ValueData) * sizeof(WCHAR)));
142 if (Group == NULL)
143 {
144 return STATUS_INSUFFICIENT_RESOURCES;
145 }
146
147 wcscpy(Group->szGroupName, ValueData);
148 Group->lpGroupName = Group->szGroupName;
149 Group->dwRefCount = (DWORD)-1;
150
151 RtlZeroMemory(&QueryTable, sizeof(QueryTable));
152 QueryTable[0].Name = (PWSTR)ValueData;
153 QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine;
154
155 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
156 L"GroupOrderList",
157 QueryTable,
158 (PVOID)Group,
159 NULL);
160 DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
161
162 InsertTailList(&GroupListHead,
163 &Group->GroupListEntry);
164 }
165
166 return STATUS_SUCCESS;
167 }
168
169
170 DWORD
171 ScmCreateGroupList(VOID)
172 {
173 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
174 NTSTATUS Status;
175
176 InitializeListHead(&GroupListHead);
177 InitializeListHead(&UnknownGroupListHead);
178
179 /* Build group order list */
180 RtlZeroMemory(&QueryTable,
181 sizeof(QueryTable));
182
183 QueryTable[0].Name = L"List";
184 QueryTable[0].QueryRoutine = CreateGroupListRoutine;
185
186 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
187 L"ServiceGroupOrder",
188 QueryTable,
189 NULL,
190 NULL);
191
192 return RtlNtStatusToDosError(Status);
193 }
194
195 /* EOF */