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 lpService
->lpGroup
->dwRefCount
--;
38 /* FIXME: What do we have to do when dwRefCount is 0? */
41 GroupEntry
= GroupListHead
.Flink
;
42 while (GroupEntry
!= &GroupListHead
)
44 lpGroup
= CONTAINING_RECORD(GroupEntry
, SERVICE_GROUP
, GroupListEntry
);
46 if (!_wcsicmp(lpGroup
->lpGroupName
, lpGroupName
))
48 lpService
->lpGroup
= lpGroup
;
52 GroupEntry
= GroupEntry
->Flink
;
55 GroupEntry
= UnknownGroupListHead
.Flink
;
56 while (GroupEntry
!= &UnknownGroupListHead
)
58 lpGroup
= CONTAINING_RECORD(GroupEntry
, SERVICE_GROUP
, GroupListEntry
);
60 if (!_wcsicmp(lpGroup
->lpGroupName
, lpGroupName
))
62 lpGroup
->dwRefCount
++;
63 lpService
->lpGroup
= lpGroup
;
67 GroupEntry
= GroupEntry
->Flink
;
70 lpGroup
= (PSERVICE_GROUP
)HeapAlloc(GetProcessHeap(),
72 sizeof(SERVICE_GROUP
) + ((wcslen(lpGroupName
) + 1)* sizeof(WCHAR
)));
74 return ERROR_NOT_ENOUGH_MEMORY
;
76 wcscpy(lpGroup
->szGroupName
, lpGroupName
);
77 lpGroup
->lpGroupName
= lpGroup
->szGroupName
;
78 lpGroup
->dwRefCount
= 1;
79 lpService
->lpGroup
= lpGroup
;
81 InsertTailList(&UnknownGroupListHead
,
82 &lpGroup
->GroupListEntry
);
88 static NTSTATUS WINAPI
89 CreateGroupOrderListRoutine(PWSTR ValueName
,
98 DPRINT("CreateGroupOrderListRoutine(%S, %x, %p, %x, %p, %p)\n",
99 ValueName
, ValueType
, ValueData
, ValueLength
, Context
, EntryContext
);
101 if (ValueType
== REG_BINARY
&&
103 ValueLength
>= sizeof(DWORD
) &&
104 ValueLength
>= (*(PULONG
)ValueData
+ 1) * sizeof(DWORD
))
106 Group
= (PSERVICE_GROUP
)Context
;
107 Group
->TagCount
= ((PULONG
)ValueData
)[0];
108 if (Group
->TagCount
> 0)
110 if (ValueLength
>= (Group
->TagCount
+ 1) * sizeof(DWORD
))
112 Group
->TagArray
= (PULONG
)HeapAlloc(GetProcessHeap(),
114 Group
->TagCount
* sizeof(DWORD
));
115 if (Group
->TagArray
== NULL
)
118 return STATUS_INSUFFICIENT_RESOURCES
;
121 RtlCopyMemory(Group
->TagArray
,
122 (PULONG
)ValueData
+ 1,
123 Group
->TagCount
* sizeof(DWORD
));
128 return STATUS_UNSUCCESSFUL
;
133 return STATUS_SUCCESS
;
137 static NTSTATUS WINAPI
138 CreateGroupListRoutine(PWSTR ValueName
,
145 PSERVICE_GROUP Group
;
146 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
149 if (ValueType
== REG_SZ
)
151 DPRINT("Data: '%S'\n", (PWCHAR
)ValueData
);
153 Group
= (PSERVICE_GROUP
)HeapAlloc(GetProcessHeap(),
155 sizeof(SERVICE_GROUP
) + ((wcslen((const wchar_t*) ValueData
) + 1) * sizeof(WCHAR
)));
158 return STATUS_INSUFFICIENT_RESOURCES
;
161 wcscpy(Group
->szGroupName
, (const wchar_t*) ValueData
);
162 Group
->lpGroupName
= Group
->szGroupName
;
163 Group
->dwRefCount
= (DWORD
)-1;
165 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
166 QueryTable
[0].Name
= (PWSTR
)ValueData
;
167 QueryTable
[0].QueryRoutine
= CreateGroupOrderListRoutine
;
169 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
174 DPRINT("%x %lu %S\n", Status
, Group
->TagCount
, (PWSTR
)ValueData
);
176 InsertTailList(&GroupListHead
,
177 &Group
->GroupListEntry
);
180 return STATUS_SUCCESS
;
185 ScmCreateGroupList(VOID
)
187 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
190 InitializeListHead(&GroupListHead
);
191 InitializeListHead(&UnknownGroupListHead
);
193 /* Build group order list */
194 RtlZeroMemory(&QueryTable
,
197 QueryTable
[0].Name
= L
"List";
198 QueryTable
[0].QueryRoutine
= CreateGroupListRoutine
;
200 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
201 L
"ServiceGroupOrder",
206 return RtlNtStatusToDosError(Status
);