Move group-list related code to a separate file and keep the group name in the group record because it never changes.
Modified: trunk/reactos/subsys/system/services/config.c
Modified: trunk/reactos/subsys/system/services/database.c
Added: trunk/reactos/subsys/system/services/groupdb.c
Modified: trunk/reactos/subsys/system/services/services.h
Modified: trunk/reactos/subsys/system/services/services.xml

Modified: trunk/reactos/subsys/system/services/config.c
--- trunk/reactos/subsys/system/services/config.c	2005-12-31 18:36:39 UTC (rev 20490)
+++ trunk/reactos/subsys/system/services/config.c	2005-12-31 18:56:34 UTC (rev 20491)
@@ -233,7 +233,7 @@
     DWORD dwType;
     DWORD dwSizeNeeded;
     LPWSTR expanded = NULL;
-    LPBYTE ptr = NULL;
+    LPWSTR ptr = NULL;
 
     *lpValue = NULL;
 
@@ -255,7 +255,7 @@
                                lpValueName,
                                0,
                                &dwType,
-                               ptr,
+                               (LPBYTE)ptr,
                                &dwSize);
     if (dwError != ERROR_SUCCESS)
         goto done;
@@ -281,7 +281,7 @@
     }
     else
     {
-        *lpValue = (LPWSTR)ptr;
+        *lpValue = ptr;
     }
 
 done:;

Modified: trunk/reactos/subsys/system/services/database.c
--- trunk/reactos/subsys/system/services/database.c	2005-12-31 18:36:39 UTC (rev 20490)
+++ trunk/reactos/subsys/system/services/database.c	2005-12-31 18:56:34 UTC (rev 20491)
@@ -31,23 +31,8 @@
 #include <debug.h>
 
 
-/* TYPES *********************************************************************/
-
-typedef struct _SERVICE_GROUP
-{
-  LIST_ENTRY GroupListEntry;
-  UNICODE_STRING GroupName;
-
-  BOOLEAN ServicesRunning;
-  ULONG TagCount;
-  PULONG TagArray;
-
-} SERVICE_GROUP, *PSERVICE_GROUP;
-
-
 /* GLOBALS *******************************************************************/
 
-LIST_ENTRY GroupListHead;
 LIST_ENTRY ServiceListHead;
 
 static RTL_RESOURCE DatabaseLock;
@@ -143,104 +128,6 @@
 }
 
 
-static NTSTATUS STDCALL
-CreateGroupOrderListRoutine(PWSTR ValueName,
-                            ULONG ValueType,
-                            PVOID ValueData,
-                            ULONG ValueLength,
-                            PVOID Context,
-                            PVOID EntryContext)
-{
-    PSERVICE_GROUP Group;
-
-    DPRINT("CreateGroupOrderListRoutine(%S, %x, %x, %x, %x, %x)\n",
-           ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
-
-    if (ValueType == REG_BINARY &&
-        ValueData != NULL &&
-        ValueLength >= sizeof(DWORD) &&
-        ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
-    {
-        Group = (PSERVICE_GROUP)Context;
-        Group->TagCount = ((PULONG)ValueData)[0];
-        if (Group->TagCount > 0)
-        {
-            if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
-            {
-                Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),
-                                                    HEAP_ZERO_MEMORY,
-                                                    Group->TagCount * sizeof(DWORD));
-                if (Group->TagArray == NULL)
-                {
-                    Group->TagCount = 0;
-                    return STATUS_INSUFFICIENT_RESOURCES;
-                }
-
-                RtlCopyMemory(Group->TagArray,
-                              (PULONG)ValueData + 1,
-                              Group->TagCount * sizeof(DWORD));
-            }
-            else
-            {
-                Group->TagCount = 0;
-                return STATUS_UNSUCCESSFUL;
-            }
-        }
-    }
-
-    return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS STDCALL
-CreateGroupListRoutine(PWSTR ValueName,
-                       ULONG ValueType,
-                       PVOID ValueData,
-                       ULONG ValueLength,
-                       PVOID Context,
-                       PVOID EntryContext)
-{
-    PSERVICE_GROUP Group;
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-    NTSTATUS Status;
-
-    if (ValueType == REG_SZ)
-    {
-        DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
-
-        Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
-                                          HEAP_ZERO_MEMORY,
-                                          sizeof(SERVICE_GROUP));
-        if (Group == NULL)
-        {
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
-
-        if (!RtlCreateUnicodeString(&Group->GroupName,
-                                    (PWSTR)ValueData))
-        {
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
-
-        RtlZeroMemory(&QueryTable, sizeof(QueryTable));
-        QueryTable[0].Name = (PWSTR)ValueData;
-        QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine;
-
-        Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
-                                        L"GroupOrderList",
-                                        QueryTable,
-                                        (PVOID)Group,
-                                        NULL);
-        DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
-
-        InsertTailList(&GroupListHead,
-                       &Group->GroupListEntry);
-    }
-
-    return STATUS_SUCCESS;
-}
-
-
 DWORD
 ScmCreateNewServiceRecord(LPWSTR lpServiceName,
                           PSERVICE *lpServiceRecord)
@@ -412,31 +299,6 @@
 }
 
 
-DWORD
-ScmReadGroupList(VOID)
-{
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-    NTSTATUS Status;
-
-    InitializeListHead(&GroupListHead);
-
-    /* Build group order list */
-    RtlZeroMemory(&QueryTable,
-                  sizeof(QueryTable));
-
-    QueryTable[0].Name = L"List";
-    QueryTable[0].QueryRoutine = CreateGroupListRoutine;
-
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
-                                    L"ServiceGroupOrder",
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
-
-    return RtlNtStatusToDosError(Status);
-}
-
-
 VOID
 ScmDeleteMarkedServices(VOID)
 {
@@ -476,7 +338,7 @@
 
     DPRINT("ScmCreateServiceDatabase() called\n");
 
-    dwError = ScmReadGroupList();
+    dwError = ScmCreateGroupList();
     if (dwError != ERROR_SUCCESS)
         return dwError;
 
@@ -627,9 +489,9 @@
                 {
                     CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
 
-                    DPRINT("Checking group '%wZ'\n", &CurrentGroup->GroupName);
+                    DPRINT("Checking group '%S'\n", &CurrentGroup->lpGroupName);
                     if (Service->lpServiceGroup != NULL &&
-                        _wcsicmp(Service->lpServiceGroup, CurrentGroup->GroupName.Buffer) == 0)
+                        _wcsicmp(Service->lpServiceGroup, CurrentGroup->lpGroupName) == 0)
                     {
                         CurrentGroup->ServicesRunning = TRUE;
                     }
@@ -984,7 +846,7 @@
     {
         CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
 
-        DPRINT("Group '%wZ'\n", &CurrentGroup->GroupName);
+        DPRINT("Group '%S'\n", CurrentGroup->lpGroupName);
 
         /* Start all services witch have a valid tag */
         for (i = 0; i < CurrentGroup->TagCount; i++)
@@ -995,7 +857,7 @@
                 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
 
                 if ((CurrentService->lpServiceGroup != NULL) &&
-                    (_wcsicmp(CurrentGroup->GroupName.Buffer, CurrentService->lpServiceGroup) == 0) &&
+                    (_wcsicmp(CurrentGroup->lpGroupName, CurrentService->lpServiceGroup) == 0) &&
                     (CurrentService->dwStartType == SERVICE_AUTO_START) &&
                     (CurrentService->ServiceVisited == FALSE) &&
                     (CurrentService->dwTag == CurrentGroup->TagArray[i]))
@@ -1016,7 +878,7 @@
             CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
 
             if ((CurrentService->lpServiceGroup != NULL) &&
-                (_wcsicmp(CurrentGroup->GroupName.Buffer, CurrentService->lpServiceGroup) == 0) &&
+                (_wcsicmp(CurrentGroup->lpGroupName, CurrentService->lpServiceGroup) == 0) &&
                 (CurrentService->dwStartType == SERVICE_AUTO_START) &&
                 (CurrentService->ServiceVisited == FALSE))
             {

Added: trunk/reactos/subsys/system/services/groupdb.c
--- trunk/reactos/subsys/system/services/groupdb.c	2005-12-31 18:36:39 UTC (rev 20490)
+++ trunk/reactos/subsys/system/services/groupdb.c	2005-12-31 18:56:34 UTC (rev 20491)
@@ -0,0 +1,140 @@
+/*
+ * groupdb.c
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "services.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+/* GLOBALS *******************************************************************/
+
+LIST_ENTRY GroupListHead;
+
+
+/* FUNCTIONS *****************************************************************/
+
+static NTSTATUS STDCALL
+CreateGroupOrderListRoutine(PWSTR ValueName,
+                            ULONG ValueType,
+                            PVOID ValueData,
+                            ULONG ValueLength,
+                            PVOID Context,
+                            PVOID EntryContext)
+{
+    PSERVICE_GROUP Group;
+
+    DPRINT("CreateGroupOrderListRoutine(%S, %x, %x, %x, %x, %x)\n",
+           ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
+
+    if (ValueType == REG_BINARY &&
+        ValueData != NULL &&
+        ValueLength >= sizeof(DWORD) &&
+        ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
+    {
+        Group = (PSERVICE_GROUP)Context;
+        Group->TagCount = ((PULONG)ValueData)[0];
+        if (Group->TagCount > 0)
+        {
+            if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
+            {
+                Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),
+                                                    HEAP_ZERO_MEMORY,
+                                                    Group->TagCount * sizeof(DWORD));
+                if (Group->TagArray == NULL)
+                {
+                    Group->TagCount = 0;
+                    return STATUS_INSUFFICIENT_RESOURCES;
+                }
+
+                RtlCopyMemory(Group->TagArray,
+                              (PULONG)ValueData + 1,
+                              Group->TagCount * sizeof(DWORD));
+            }
+            else
+            {
+                Group->TagCount = 0;
+                return STATUS_UNSUCCESSFUL;
+            }
+        }
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS STDCALL
+CreateGroupListRoutine(PWSTR ValueName,
+                       ULONG ValueType,
+                       PVOID ValueData,
+                       ULONG ValueLength,
+                       PVOID Context,
+                       PVOID EntryContext)
+{
+    PSERVICE_GROUP Group;
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    NTSTATUS Status;
+
+    if (ValueType == REG_SZ)
+    {
+        DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
+
+        Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
+                                          HEAP_ZERO_MEMORY,
+                                          sizeof(SERVICE_GROUP) + (wcslen(ValueData) * sizeof(WCHAR)));
+        if (Group == NULL)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        wcscpy(Group->szGroupName, ValueData);
+        Group->lpGroupName = Group->szGroupName;
+        Group->dwRefCount = (DWORD)-1;
+
+        RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+        QueryTable[0].Name = (PWSTR)ValueData;
+        QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine;
+
+        Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+                                        L"GroupOrderList",
+                                        QueryTable,
+                                        (PVOID)Group,
+                                        NULL);
+        DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
+
+        InsertTailList(&GroupListHead,
+                       &Group->GroupListEntry);
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
+DWORD
+ScmCreateGroupList(VOID)
+{
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    NTSTATUS Status;
+
+    InitializeListHead(&GroupListHead);
+
+    /* Build group order list */
+    RtlZeroMemory(&QueryTable,
+                  sizeof(QueryTable));
+
+    QueryTable[0].Name = L"List";
+    QueryTable[0].QueryRoutine = CreateGroupListRoutine;
+
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+                                    L"ServiceGroupOrder",
+                                    QueryTable,
+                                    NULL,
+                                    NULL);
+
+    return RtlNtStatusToDosError(Status);
+}
+
+/* EOF */

Modified: trunk/reactos/subsys/system/services/services.h
--- trunk/reactos/subsys/system/services/services.h	2005-12-31 18:36:39 UTC (rev 20490)
+++ trunk/reactos/subsys/system/services/services.h	2005-12-31 18:56:34 UTC (rev 20491)
@@ -9,6 +9,21 @@
 #include <ndk/ntndk.h>
 #include <services/services.h>
 
+
+typedef struct _SERVICE_GROUP
+{
+    LIST_ENTRY GroupListEntry;
+    LPWSTR lpGroupName;
+
+    DWORD dwRefCount;
+    BOOLEAN ServicesRunning;
+    ULONG TagCount;
+    PULONG TagArray;
+
+    WCHAR szGroupName[1];
+} SERVICE_GROUP, *PSERVICE_GROUP;
+
+
 typedef struct _SERVICE
 {
     LIST_ENTRY ServiceListEntry;
@@ -40,6 +55,7 @@
 /* VARIABLES ***************************************************************/
 
 extern LIST_ENTRY ServiceListHead;
+extern LIST_ENTRY GroupListHead;
 extern BOOL ScmShutdown;
 
 
@@ -90,6 +106,11 @@
                        LPSERVICE_STATUS lpServiceStatus);
 
 
+/* groupdb.c */
+
+DWORD ScmCreateGroupList(VOID);
+
+
 /* rpcserver.c */
 
 VOID ScmStartRpcServer(VOID);

Modified: trunk/reactos/subsys/system/services/services.xml
--- trunk/reactos/subsys/system/services/services.xml	2005-12-31 18:36:39 UTC (rev 20490)
+++ trunk/reactos/subsys/system/services/services.xml	2005-12-31 18:56:34 UTC (rev 20491)
@@ -13,6 +13,7 @@
 	<file>config.c</file>
 	<file>database.c</file>
 	<file>driver.c</file>
+	<file>groupdb.c</file>
 	<file>rpcserver.c</file>
 	<file>services.c</file>
 	<file>services.rc</file>