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
10 /* INCLUDES *****************************************************************/
17 /* GLOBALS *******************************************************************/
19 LIST_ENTRY GroupListHead
;
20 LIST_ENTRY UnknownGroupListHead
;
23 /* FUNCTIONS *****************************************************************/
26 ScmSetServiceGroup(PSERVICE lpService
,
29 PLIST_ENTRY GroupEntry
;
30 PSERVICE_GROUP lpGroup
;
32 DPRINT("ScmSetServiceGroup(%S)\n", lpGroupName
);
34 if (lpService
->lpGroup
!= NULL
)
36 ASSERT(lpService
->lpGroup
->dwRefCount
!= 0);
37 ASSERT(lpService
->lpGroup
->dwRefCount
== (DWORD
)-1 ||
38 lpService
->lpGroup
->dwRefCount
< 10000);
39 if (lpService
->lpGroup
->dwRefCount
!= (DWORD
)-1)
41 lpService
->lpGroup
->dwRefCount
--;
42 if (lpService
->lpGroup
->dwRefCount
== 0)
44 ASSERT(lpService
->lpGroup
->TagCount
== 0);
45 ASSERT(lpService
->lpGroup
->TagArray
== NULL
);
46 RemoveEntryList(&lpService
->lpGroup
->GroupListEntry
);
47 HeapFree(GetProcessHeap(), 0, lpService
->lpGroup
);
48 lpService
->lpGroup
= NULL
;
53 if (lpGroupName
== NULL
)
56 GroupEntry
= GroupListHead
.Flink
;
57 while (GroupEntry
!= &GroupListHead
)
59 lpGroup
= CONTAINING_RECORD(GroupEntry
, SERVICE_GROUP
, GroupListEntry
);
61 if (!_wcsicmp(lpGroup
->lpGroupName
, lpGroupName
))
63 lpService
->lpGroup
= lpGroup
;
67 GroupEntry
= GroupEntry
->Flink
;
70 GroupEntry
= UnknownGroupListHead
.Flink
;
71 while (GroupEntry
!= &UnknownGroupListHead
)
73 lpGroup
= CONTAINING_RECORD(GroupEntry
, SERVICE_GROUP
, GroupListEntry
);
75 if (!_wcsicmp(lpGroup
->lpGroupName
, lpGroupName
))
77 lpGroup
->dwRefCount
++;
78 lpService
->lpGroup
= lpGroup
;
82 GroupEntry
= GroupEntry
->Flink
;
85 lpGroup
= (PSERVICE_GROUP
)HeapAlloc(GetProcessHeap(),
87 sizeof(SERVICE_GROUP
) + ((wcslen(lpGroupName
) + 1)* sizeof(WCHAR
)));
89 return ERROR_NOT_ENOUGH_MEMORY
;
91 wcscpy(lpGroup
->szGroupName
, lpGroupName
);
92 lpGroup
->lpGroupName
= lpGroup
->szGroupName
;
93 lpGroup
->dwRefCount
= 1;
94 lpService
->lpGroup
= lpGroup
;
96 InsertTailList(&UnknownGroupListHead
,
97 &lpGroup
->GroupListEntry
);
103 static NTSTATUS WINAPI
104 CreateGroupOrderListRoutine(PWSTR ValueName
,
111 PSERVICE_GROUP Group
;
113 DPRINT("CreateGroupOrderListRoutine(%S, %x, %p, %x, %p, %p)\n",
114 ValueName
, ValueType
, ValueData
, ValueLength
, Context
, EntryContext
);
116 if (ValueType
== REG_BINARY
&&
118 ValueLength
>= sizeof(DWORD
) &&
119 ValueLength
>= (*(PULONG
)ValueData
+ 1) * sizeof(DWORD
))
121 Group
= (PSERVICE_GROUP
)Context
;
122 Group
->TagCount
= ((PULONG
)ValueData
)[0];
123 if (Group
->TagCount
> 0)
125 if (ValueLength
>= (Group
->TagCount
+ 1) * sizeof(DWORD
))
127 Group
->TagArray
= (PULONG
)HeapAlloc(GetProcessHeap(),
129 Group
->TagCount
* sizeof(DWORD
));
130 if (Group
->TagArray
== NULL
)
133 return STATUS_INSUFFICIENT_RESOURCES
;
136 RtlCopyMemory(Group
->TagArray
,
137 (PULONG
)ValueData
+ 1,
138 Group
->TagCount
* sizeof(DWORD
));
143 return STATUS_UNSUCCESSFUL
;
148 return STATUS_SUCCESS
;
152 static NTSTATUS WINAPI
153 CreateGroupListRoutine(PWSTR ValueName
,
160 PSERVICE_GROUP Group
;
161 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
164 if (ValueType
== REG_SZ
)
166 DPRINT("Data: '%S'\n", (PWCHAR
)ValueData
);
168 Group
= (PSERVICE_GROUP
)HeapAlloc(GetProcessHeap(),
170 sizeof(SERVICE_GROUP
) + ((wcslen((const wchar_t*) ValueData
) + 1) * sizeof(WCHAR
)));
173 return STATUS_INSUFFICIENT_RESOURCES
;
176 wcscpy(Group
->szGroupName
, (const wchar_t*) ValueData
);
177 Group
->lpGroupName
= Group
->szGroupName
;
178 Group
->dwRefCount
= (DWORD
)-1;
180 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
181 QueryTable
[0].Name
= (PWSTR
)ValueData
;
182 QueryTable
[0].QueryRoutine
= CreateGroupOrderListRoutine
;
184 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
189 DPRINT("%x %lu %S\n", Status
, Group
->TagCount
, (PWSTR
)ValueData
);
191 InsertTailList(&GroupListHead
,
192 &Group
->GroupListEntry
);
195 return STATUS_SUCCESS
;
200 ScmCreateGroupList(VOID
)
202 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
205 InitializeListHead(&GroupListHead
);
206 InitializeListHead(&UnknownGroupListHead
);
208 /* Build group order list */
209 RtlZeroMemory(&QueryTable
,
212 QueryTable
[0].Name
= L
"List";
213 QueryTable
[0].QueryRoutine
= CreateGroupListRoutine
;
215 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
216 L
"ServiceGroupOrder",
221 return RtlNtStatusToDosError(Status
);