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 *****************************************************************/
18 /* GLOBALS *******************************************************************/
20 LIST_ENTRY GroupListHead
;
21 LIST_ENTRY UnknownGroupListHead
;
24 /* FUNCTIONS *****************************************************************/
27 ScmSetServiceGroup(PSERVICE lpService
,
30 PLIST_ENTRY GroupEntry
;
31 PSERVICE_GROUP lpGroup
;
33 DPRINT("ScmSetServiceGroup(%S)\n", lpGroupName
);
35 if (lpService
->lpGroup
!= NULL
)
37 lpService
->lpGroup
->dwRefCount
--;
39 /* FIXME: What do we have to do when dwRefCount is 0? */
42 GroupEntry
= GroupListHead
.Flink
;
43 while (GroupEntry
!= &GroupListHead
)
45 lpGroup
= CONTAINING_RECORD(GroupEntry
, SERVICE_GROUP
, GroupListEntry
);
47 if (!_wcsicmp(lpGroup
->lpGroupName
, lpGroupName
))
49 lpService
->lpGroup
= lpGroup
;
53 GroupEntry
= GroupEntry
->Flink
;
56 GroupEntry
= UnknownGroupListHead
.Flink
;
57 while (GroupEntry
!= &UnknownGroupListHead
)
59 lpGroup
= CONTAINING_RECORD(GroupEntry
, SERVICE_GROUP
, GroupListEntry
);
61 if (!_wcsicmp(lpGroup
->lpGroupName
, lpGroupName
))
63 lpGroup
->dwRefCount
++;
64 lpService
->lpGroup
= lpGroup
;
68 GroupEntry
= GroupEntry
->Flink
;
71 lpGroup
= (PSERVICE_GROUP
)HeapAlloc(GetProcessHeap(),
73 sizeof(SERVICE_GROUP
) + ((wcslen(lpGroupName
) + 1)* sizeof(WCHAR
)));
75 return ERROR_NOT_ENOUGH_MEMORY
;
77 wcscpy(lpGroup
->szGroupName
, lpGroupName
);
78 lpGroup
->lpGroupName
= lpGroup
->szGroupName
;
79 lpGroup
->dwRefCount
= 1;
80 lpService
->lpGroup
= lpGroup
;
82 InsertTailList(&UnknownGroupListHead
,
83 &lpGroup
->GroupListEntry
);
89 static NTSTATUS WINAPI
90 CreateGroupOrderListRoutine(PWSTR ValueName
,
99 DPRINT("CreateGroupOrderListRoutine(%S, %x, %x, %x, %x, %x)\n",
100 ValueName
, ValueType
, ValueData
, ValueLength
, Context
, EntryContext
);
102 if (ValueType
== REG_BINARY
&&
104 ValueLength
>= sizeof(DWORD
) &&
105 ValueLength
>= (*(PULONG
)ValueData
+ 1) * sizeof(DWORD
))
107 Group
= (PSERVICE_GROUP
)Context
;
108 Group
->TagCount
= ((PULONG
)ValueData
)[0];
109 if (Group
->TagCount
> 0)
111 if (ValueLength
>= (Group
->TagCount
+ 1) * sizeof(DWORD
))
113 Group
->TagArray
= (PULONG
)HeapAlloc(GetProcessHeap(),
115 Group
->TagCount
* sizeof(DWORD
));
116 if (Group
->TagArray
== NULL
)
119 return STATUS_INSUFFICIENT_RESOURCES
;
122 RtlCopyMemory(Group
->TagArray
,
123 (PULONG
)ValueData
+ 1,
124 Group
->TagCount
* sizeof(DWORD
));
129 return STATUS_UNSUCCESSFUL
;
134 return STATUS_SUCCESS
;
138 static NTSTATUS WINAPI
139 CreateGroupListRoutine(PWSTR ValueName
,
146 PSERVICE_GROUP Group
;
147 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
150 if (ValueType
== REG_SZ
)
152 DPRINT("Data: '%S'\n", (PWCHAR
)ValueData
);
154 Group
= (PSERVICE_GROUP
)HeapAlloc(GetProcessHeap(),
156 sizeof(SERVICE_GROUP
) + ((wcslen((const wchar_t*) ValueData
) + 1) * sizeof(WCHAR
)));
159 return STATUS_INSUFFICIENT_RESOURCES
;
162 wcscpy(Group
->szGroupName
, (const wchar_t*) ValueData
);
163 Group
->lpGroupName
= Group
->szGroupName
;
164 Group
->dwRefCount
= (DWORD
)-1;
166 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
167 QueryTable
[0].Name
= (PWSTR
)ValueData
;
168 QueryTable
[0].QueryRoutine
= CreateGroupOrderListRoutine
;
170 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
175 DPRINT("%x %d %S\n", Status
, Group
->TagCount
, (PWSTR
)ValueData
);
177 InsertTailList(&GroupListHead
,
178 &Group
->GroupListEntry
);
181 return STATUS_SUCCESS
;
186 ScmCreateGroupList(VOID
)
188 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
191 InitializeListHead(&GroupListHead
);
192 InitializeListHead(&UnknownGroupListHead
);
194 /* Build group order list */
195 RtlZeroMemory(&QueryTable
,
198 QueryTable
[0].Name
= L
"List";
199 QueryTable
[0].QueryRoutine
= CreateGroupListRoutine
;
201 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
202 L
"ServiceGroupOrder",
207 return RtlNtStatusToDosError(Status
);