- Service list entries use a pointer to a group list entry instead of the goup name.
- New group list entries are created in the unknown-group-list for services of unknown groups.
Modified: trunk/reactos/subsys/system/services/database.c
Modified: trunk/reactos/subsys/system/services/groupdb.c
Modified: trunk/reactos/subsys/system/services/rpcserver.c
Modified: trunk/reactos/subsys/system/services/services.h

Modified: trunk/reactos/subsys/system/services/database.c
--- trunk/reactos/subsys/system/services/database.c	2005-12-31 21:37:52 UTC (rev 20495)
+++ trunk/reactos/subsys/system/services/database.c	2005-12-31 22:42:41 UTC (rev 20496)
@@ -267,8 +267,9 @@
 
     if (lpGroup != NULL)
     {
-        lpService->lpServiceGroup = lpGroup;
-        lpGroup = NULL;
+        dwError = ScmSetServiceGroup(lpService, lpGroup);
+        if (dwError != ERROR_SUCCESS)
+            goto done;
     }
 
     if (lpDisplayName != NULL)
@@ -278,7 +279,7 @@
     }
 
     DPRINT("ServiceName: '%S'\n", lpService->lpServiceName);
-    DPRINT("Group: '%S'\n", lpService->lpServiceGroup);
+    DPRINT("Group: '%S'\n", lpService->lpGroup->lpGroupName);
     DPRINT("Start %lx  Type %lx  Tag %lx  ErrorControl %lx\n",
            lpService->dwStartType,
            lpService->Status.dwServiceType,
@@ -415,8 +416,6 @@
     ULONG BufferLength;
     ULONG DataLength;
     ULONG Index;
-    PLIST_ENTRY GroupEntry;
-    PSERVICE_GROUP CurrentGroup;
 
     DPRINT("ScmCheckDriver(%S) called\n", Service->lpServiceName);
 
@@ -481,24 +480,12 @@
             /* Mark service as 'running' */
             Service->Status.dwCurrentState = SERVICE_RUNNING;
 
-            /* Find the driver's group and mark it as 'running' */
-            if (Service->lpServiceGroup != NULL)
+            /* Mark the service group as 'running' */
+            if (Service->lpGroup != NULL)
             {
-                GroupEntry = GroupListHead.Flink;
-                while (GroupEntry != &GroupListHead)
-                {
-                    CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
-
-                    DPRINT("Checking group '%S'\n", &CurrentGroup->lpGroupName);
-                    if (Service->lpServiceGroup != NULL &&
-                        _wcsicmp(Service->lpServiceGroup, CurrentGroup->lpGroupName) == 0)
-                    {
-                        CurrentGroup->ServicesRunning = TRUE;
-                    }
-
-                    GroupEntry = GroupEntry->Flink;
-                }
+                Service->lpGroup->ServicesRunning = TRUE;
             }
+
             break;
         }
     }
@@ -856,8 +843,7 @@
             {
                 CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
 
-                if ((CurrentService->lpServiceGroup != NULL) &&
-                    (_wcsicmp(CurrentGroup->lpGroupName, CurrentService->lpServiceGroup) == 0) &&
+                if ((CurrentService->lpGroup == CurrentGroup) &&
                     (CurrentService->dwStartType == SERVICE_AUTO_START) &&
                     (CurrentService->ServiceVisited == FALSE) &&
                     (CurrentService->dwTag == CurrentGroup->TagArray[i]))
@@ -877,8 +863,7 @@
         {
             CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
 
-            if ((CurrentService->lpServiceGroup != NULL) &&
-                (_wcsicmp(CurrentGroup->lpGroupName, CurrentService->lpServiceGroup) == 0) &&
+            if ((CurrentService->lpGroup == CurrentGroup) &&
                 (CurrentService->dwStartType == SERVICE_AUTO_START) &&
                 (CurrentService->ServiceVisited == FALSE))
             {
@@ -899,7 +884,7 @@
     {
         CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
 
-        if ((CurrentService->lpServiceGroup != NULL) &&
+        if ((CurrentService->lpGroup != NULL) &&
             (CurrentService->dwStartType == SERVICE_AUTO_START) &&
             (CurrentService->ServiceVisited == FALSE))
         {
@@ -917,7 +902,7 @@
     {
         CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
 
-        if ((CurrentService->lpServiceGroup == NULL) &&
+        if ((CurrentService->lpGroup == NULL) &&
             (CurrentService->dwStartType == SERVICE_AUTO_START) &&
             (CurrentService->ServiceVisited == FALSE))
         {

Modified: trunk/reactos/subsys/system/services/groupdb.c
--- trunk/reactos/subsys/system/services/groupdb.c	2005-12-31 21:37:52 UTC (rev 20495)
+++ trunk/reactos/subsys/system/services/groupdb.c	2005-12-31 22:42:41 UTC (rev 20496)
@@ -13,10 +13,64 @@
 /* GLOBALS *******************************************************************/
 
 LIST_ENTRY GroupListHead;
+LIST_ENTRY UnknownGroupListHead;
 
 
 /* FUNCTIONS *****************************************************************/
 
+DWORD
+ScmSetServiceGroup(PSERVICE lpService,
+                   LPWSTR lpGroupName)
+{
+    PLIST_ENTRY GroupEntry;
+    PSERVICE_GROUP lpGroup;
+
+    GroupEntry = GroupListHead.Flink;
+    while (GroupEntry != &GroupListHead)
+    {
+        lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
+
+        if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
+        {
+            lpService->lpGroup = lpGroup;
+            return ERROR_SUCCESS;
+        }
+
+        GroupEntry = GroupEntry->Flink;
+    }
+
+    GroupEntry = UnknownGroupListHead.Flink;
+    while (GroupEntry != &UnknownGroupListHead)
+    {
+        lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
+
+        if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
+        {
+            lpGroup->dwRefCount++;
+            lpService->lpGroup = lpGroup;
+            return ERROR_SUCCESS;
+        }
+
+        GroupEntry = GroupEntry->Flink;
+    }
+
+    lpGroup = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
+                                        HEAP_ZERO_MEMORY,
+                                        sizeof(SERVICE_GROUP) + (wcslen(lpGroupName) * sizeof(WCHAR)));
+    if (lpGroup == NULL)
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    wcscpy(lpGroup->szGroupName, lpGroupName);
+    lpGroup->lpGroupName = lpGroup->szGroupName;
+    lpGroup->dwRefCount = 1;
+
+    InsertTailList(&UnknownGroupListHead,
+                   &lpGroup->GroupListEntry);
+
+    return ERROR_SUCCESS;
+}
+
+
 static NTSTATUS STDCALL
 CreateGroupOrderListRoutine(PWSTR ValueName,
                             ULONG ValueType,
@@ -120,6 +174,7 @@
     NTSTATUS Status;
 
     InitializeListHead(&GroupListHead);
+    InitializeListHead(&UnknownGroupListHead);
 
     /* Build group order list */
     RtlZeroMemory(&QueryTable,

Modified: trunk/reactos/subsys/system/services/rpcserver.c
--- trunk/reactos/subsys/system/services/rpcserver.c	2005-12-31 21:37:52 UTC (rev 20495)
+++ trunk/reactos/subsys/system/services/rpcserver.c	2005-12-31 22:42:41 UTC (rev 20496)
@@ -927,7 +927,7 @@
 
     if (lpdwTagId != NULL)
     {
-        dwError = ScmAssignNewTag(lpService->lpServiceGroup,
+        dwError = ScmAssignNewTag(lpService->lpGroup->lpGroupName,
                                   &lpService->dwTag);
         if (dwError != ERROR_SUCCESS)
             goto done;
@@ -1161,7 +1161,7 @@
 
     if (lpdwTagId != NULL)
     {
-        dwError = ScmAssignNewTag(lpService->lpServiceGroup,
+        dwError = ScmAssignNewTag(lpService->lpGroup->lpGroupName,
                                   &lpService->dwTag);
         if (dwError != ERROR_SUCCESS)
             goto done;
@@ -1635,8 +1635,8 @@
     if (lpImagePath != NULL)
         dwRequiredSize += ((wcslen(lpImagePath) + 1) * sizeof(WCHAR));
 
-    if (lpService->lpServiceGroup  != NULL)
-        dwRequiredSize += ((wcslen(lpService->lpServiceGroup) + 1) * sizeof(WCHAR));
+    if (lpService->lpGroup != NULL)
+        dwRequiredSize += ((wcslen(lpService->lpGroup->lpGroupName) + 1) * sizeof(WCHAR));
 
     /* FIXME: Add Dependencies length*/
 
@@ -1670,11 +1670,11 @@
             lpConfig->lpBinaryPathName = NULL;
         }
 
-        if (lpService->lpServiceGroup != NULL)
+        if (lpService->lpGroup != NULL)
         {
-            wcscpy(lpStr, lpService->lpServiceGroup);
+            wcscpy(lpStr, lpService->lpGroup->lpGroupName);
             lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
-            lpStr += (wcslen(lpService->lpServiceGroup) + 1);
+            lpStr += (wcslen(lpService->lpGroup->lpGroupName) + 1);
         }
         else
         {
@@ -2290,7 +2290,8 @@
 
         if (pszGroupName)
         {
-            if (_wcsicmp(pszGroupName, CurrentService->lpServiceGroup))
+            if ((CurrentService->lpGroup == NULL) ||
+                _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName))
                 continue;
         }
 
@@ -2336,7 +2337,8 @@
 
         if (pszGroupName)
         {
-            if (_wcsicmp(pszGroupName, CurrentService->lpServiceGroup))
+            if ((CurrentService->lpGroup == NULL) ||
+                _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName))
                 continue;
         }
 
@@ -2378,7 +2380,8 @@
 
         if (pszGroupName)
         {
-            if (_wcsicmp(pszGroupName, CurrentService->lpServiceGroup))
+            if ((CurrentService->lpGroup == NULL) ||
+                _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName))
                 continue;
         }
 

Modified: trunk/reactos/subsys/system/services/services.h
--- trunk/reactos/subsys/system/services/services.h	2005-12-31 21:37:52 UTC (rev 20495)
+++ trunk/reactos/subsys/system/services/services.h	2005-12-31 22:42:41 UTC (rev 20496)
@@ -29,7 +29,7 @@
     LIST_ENTRY ServiceListEntry;
     LPWSTR lpServiceName;
     LPWSTR lpDisplayName;
-    LPWSTR lpServiceGroup;
+    PSERVICE_GROUP lpGroup;
     BOOL bDeleted;
     DWORD dwResumeCount;
 
@@ -109,6 +109,8 @@
 /* groupdb.c */
 
 DWORD ScmCreateGroupList(VOID);
+DWORD ScmSetServiceGroup(PSERVICE lpService,
+                         LPWSTR lpGroupName);
 
 
 /* rpcserver.c */