[ros-diffs] [ion] 22968: - Separate functions that deal with driver-related registry code, grouping, tagging, indexing, sorting into drvrlist.c... this code should eventually become part of Cm instead.

ion at svn.reactos.org ion at svn.reactos.org
Sun Jul 9 04:34:33 CEST 2006


Author: ion
Date: Sun Jul  9 06:34:32 2006
New Revision: 22968

URL: http://svn.reactos.org/svn/reactos?rev=22968&view=rev
Log:
- Separate functions that deal with driver-related registry code, grouping, tagging, indexing, sorting into drvrlist.c... this code should eventually become part of Cm instead.

Added:
    trunk/reactos/ntoskrnl/io/iomgr/drvrlist.c
Modified:
    trunk/reactos/ntoskrnl/io/iomgr/driver.c
    trunk/reactos/ntoskrnl/ntoskrnl.rbuild

Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c?rev=22968&r1=22967&r2=22968&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/driver.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/driver.c Sun Jul  9 06:34:32 2006
@@ -1,7 +1,7 @@
 /*
  * PROJECT:         ReactOS Kernel
  * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            ntoskrnl/io/driver.c
+ * FILE:            ntoskrnl/io/iomgr/driver.c
  * PURPOSE:         Driver Object Management
  * PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
  *                  Filip Navara (navaraf at reactos.org)
@@ -14,90 +14,38 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-/* ke/main.c */
+/* GLOBALS ********************************************************************/
+
+LIST_ENTRY DriverReinitListHead;
+KSPIN_LOCK DriverReinitListLock;
+PLIST_ENTRY DriverReinitTailEntry;
+
+PLIST_ENTRY DriverBootReinitTailEntry;
+LIST_ENTRY DriverBootReinitListHead;
+KSPIN_LOCK DriverBootReinitListLock;
+
+UNICODE_STRING IopHardwareDatabaseKey =
+   RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
+
+POBJECT_TYPE IoDriverObjectType = NULL;
+
 extern BOOLEAN SetupMode;
 extern BOOLEAN NoGuiBoot;
 
-typedef struct _SERVICE_GROUP
-{
-  LIST_ENTRY GroupListEntry;
-  UNICODE_STRING GroupName;
-  BOOLEAN ServicesRunning;
-  ULONG TagCount;
-  PULONG TagArray;
-} SERVICE_GROUP, *PSERVICE_GROUP;
-
-typedef struct _SERVICE
-{
-  LIST_ENTRY ServiceListEntry;
-  UNICODE_STRING ServiceName;
-  UNICODE_STRING RegistryPath;
-  UNICODE_STRING ServiceGroup;
-  UNICODE_STRING ImagePath;
-
-  ULONG Start;
-  ULONG Type;
-  ULONG ErrorControl;
-  ULONG Tag;
-
-/*  BOOLEAN ServiceRunning;*/	// needed ??
-} SERVICE, *PSERVICE;
-
-/* GLOBALS ********************************************************************/
-
-static LIST_ENTRY DriverReinitListHead;
-static KSPIN_LOCK DriverReinitListLock;
-static PLIST_ENTRY DriverReinitTailEntry;
-
-static PLIST_ENTRY DriverBootReinitTailEntry;
-static LIST_ENTRY DriverBootReinitListHead;
-static KSPIN_LOCK DriverBootReinitListLock;
-
-static LIST_ENTRY GroupListHead = {NULL, NULL};
-static LIST_ENTRY ServiceListHead  = {NULL, NULL};
-
-static UNICODE_STRING IopHardwareDatabaseKey =
-   RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
-
-POBJECT_TYPE IoDriverObjectType = NULL;
-
 /* DECLARATIONS ***************************************************************/
 
-VOID STDCALL
-IopDeleteDriver(PVOID ObjectBody);
-
 NTSTATUS
-LdrProcessModule(PVOID ModuleLoadBase,
-		 PUNICODE_STRING ModuleName,
-		 PLDR_DATA_TABLE_ENTRY *ModuleObject);
-
-static VOID
-FASTCALL
-INIT_FUNCTION
-IopDisplayLoadingMessage(PVOID ServiceName, 
-                         BOOLEAN Unicode);
-
-static VOID INIT_FUNCTION
-MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length);
-
-NTSTATUS FASTCALL INIT_FUNCTION
-IopInitializeBuiltinDriver(
-   PDEVICE_NODE ModuleDeviceNode,
-   PVOID ModuleLoadBase,
-   PCHAR FileName,
-   ULONG ModuleLength);
-
-static INIT_FUNCTION NTSTATUS
-IopLoadDriver(PSERVICE Service);
+LdrProcessModule(
+    PVOID ModuleLoadBase,
+    PUNICODE_STRING ModuleName,
+    PLDR_DATA_TABLE_ENTRY *ModuleObject
+);
 
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, IopInitDriverImplementation)
 #pragma alloc_text(INIT, IopDisplayLoadingMessage)
-#pragma alloc_text(INIT, IoCreateDriverList)
-#pragma alloc_text(INIT, IoDestroyDriverList)
 #pragma alloc_text(INIT, MiFreeBootDriverMemory)
 #pragma alloc_text(INIT, IopInitializeBuiltinDriver)
-#pragma alloc_text(INIT, IopLoadDriver)
 #endif
 
 
@@ -839,338 +787,6 @@
    }
 
    return STATUS_SUCCESS;
-}
-
-static NTSTATUS STDCALL
-IopGetGroupOrderList(PWSTR ValueName,
-		     ULONG ValueType,
-		     PVOID ValueData,
-		     ULONG ValueLength,
-		     PVOID Context,
-		     PVOID EntryContext)
-{
-  PSERVICE_GROUP Group;
-
-  DPRINT("IopGetGroupOrderList(%S, %x, 0x%p, %x, 0x%p, 0x%p)\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 = ExAllocatePool(NonPagedPool, Group->TagCount * sizeof(DWORD));
-	      if (Group->TagArray == NULL)
-	        {
-		  Group->TagCount = 0;
-	          return STATUS_INSUFFICIENT_RESOURCES;
-		}
-	      memcpy(Group->TagArray, (PULONG)ValueData + 1, Group->TagCount * sizeof(DWORD));
-	    }
-	  else
-	    {
-	      Group->TagCount = 0;
-	      return STATUS_UNSUCCESSFUL;
-	    }
-	}
-    }
-  return STATUS_SUCCESS;
-}
-
-static NTSTATUS STDCALL
-IopCreateGroupListEntry(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("GroupName: '%S'\n", (PWCHAR)ValueData);
-
-      Group = ExAllocatePool(NonPagedPool,
-			     sizeof(SERVICE_GROUP));
-      if (Group == NULL)
-	{
-	  return(STATUS_INSUFFICIENT_RESOURCES);
-	}
-
-      RtlZeroMemory(Group, sizeof(SERVICE_GROUP));
-
-      if (!RtlCreateUnicodeString(&Group->GroupName, (PWSTR)ValueData))
-	{
-	  ExFreePool(Group);
-	  return(STATUS_INSUFFICIENT_RESOURCES);
-	}
-
-      RtlZeroMemory(&QueryTable, sizeof(QueryTable));
-      QueryTable[0].Name = (PWSTR)ValueData;
-      QueryTable[0].QueryRoutine = IopGetGroupOrderList;
-
-      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);
-}
-
-
-static NTSTATUS STDCALL
-IopCreateServiceListEntry(PUNICODE_STRING ServiceName)
-{
-  RTL_QUERY_REGISTRY_TABLE QueryTable[7];
-  PSERVICE Service;
-  NTSTATUS Status;
-
-  DPRINT("ServiceName: '%wZ'\n", ServiceName);
-
-  /* Allocate service entry */
-  Service = (PSERVICE)ExAllocatePool(NonPagedPool, sizeof(SERVICE));
-  if (Service == NULL)
-    {
-      DPRINT1("ExAllocatePool() failed\n");
-      return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-  RtlZeroMemory(Service, sizeof(SERVICE));
-
-  /* Get service data */
-  RtlZeroMemory(&QueryTable,
-		sizeof(QueryTable));
-
-  QueryTable[0].Name = L"Start";
-  QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-  QueryTable[0].EntryContext = &Service->Start;
-
-  QueryTable[1].Name = L"Type";
-  QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-  QueryTable[1].EntryContext = &Service->Type;
-
-  QueryTable[2].Name = L"ErrorControl";
-  QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-  QueryTable[2].EntryContext = &Service->ErrorControl;
-
-  QueryTable[3].Name = L"Group";
-  QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
-  QueryTable[3].EntryContext = &Service->ServiceGroup;
-
-  QueryTable[4].Name = L"ImagePath";
-  QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
-  QueryTable[4].EntryContext = &Service->ImagePath;
-
-  QueryTable[5].Name = L"Tag";
-  QueryTable[5].Flags = RTL_QUERY_REGISTRY_DIRECT;
-  QueryTable[5].EntryContext = &Service->Tag;
-
-  Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
-				  ServiceName->Buffer,
-				  QueryTable,
-				  NULL,
-				  NULL);
-  if (!NT_SUCCESS(Status) || Service->Start > 1)
-    {
-      /*
-       * If something goes wrong during RtlQueryRegistryValues
-       * it'll just drop everything on the floor and return,
-       * so you have to check if the buffers were filled.
-       * Luckily we zerofilled the Service.
-       */
-      if (Service->ServiceGroup.Buffer)
-        {
-          ExFreePool(Service->ServiceGroup.Buffer);
-        }
-      if (Service->ImagePath.Buffer)
-        {
-          ExFreePool(Service->ImagePath.Buffer);
-        }
-      ExFreePool(Service);
-      return(Status);
-    }
-
-  /* Copy service name */
-  Service->ServiceName.Length = ServiceName->Length;
-  Service->ServiceName.MaximumLength = ServiceName->Length + sizeof(WCHAR);
-  Service->ServiceName.Buffer = ExAllocatePool(NonPagedPool,
-					       Service->ServiceName.MaximumLength);
-  RtlCopyMemory(Service->ServiceName.Buffer,
-		ServiceName->Buffer,
-		ServiceName->Length);
-  Service->ServiceName.Buffer[ServiceName->Length / sizeof(WCHAR)] = 0;
-
-  /* Build registry path */
-  Service->RegistryPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
-  Service->RegistryPath.Buffer = ExAllocatePool(NonPagedPool,
-						MAX_PATH * sizeof(WCHAR));
-  wcscpy(Service->RegistryPath.Buffer,
-	 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
-  wcscat(Service->RegistryPath.Buffer,
-	 Service->ServiceName.Buffer);
-  Service->RegistryPath.Length = wcslen(Service->RegistryPath.Buffer) * sizeof(WCHAR);
-
-  DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
-  DPRINT("RegistryPath: '%wZ'\n", &Service->RegistryPath);
-  DPRINT("ServiceGroup: '%wZ'\n", &Service->ServiceGroup);
-  DPRINT("ImagePath: '%wZ'\n", &Service->ImagePath);
-  DPRINT("Start %lx  Type %lx  Tag %lx ErrorControl %lx\n",
-	 Service->Start, Service->Type, Service->Tag, Service->ErrorControl);
-
-  /* Append service entry */
-  InsertTailList(&ServiceListHead,
-		 &Service->ServiceListEntry);
-
-  return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS INIT_FUNCTION
-IoCreateDriverList(VOID)
-{
-  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-  PKEY_BASIC_INFORMATION KeyInfo = NULL;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
-  UNICODE_STRING SubKeyName;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  ULONG Index;
-
-  ULONG KeyInfoLength = 0;
-  ULONG ReturnedLength;
-
-  DPRINT("IoCreateDriverList() called\n");
-
-  /* Initialize basic variables */
-  InitializeListHead(&GroupListHead);
-  InitializeListHead(&ServiceListHead);
-
-  /* Build group order list */
-  RtlZeroMemory(&QueryTable,
-		sizeof(QueryTable));
-
-  QueryTable[0].Name = L"List";
-  QueryTable[0].QueryRoutine = IopCreateGroupListEntry;
-
-  Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
-				  L"ServiceGroupOrder",
-				  QueryTable,
-				  NULL,
-				  NULL);
-  if (!NT_SUCCESS(Status))
-    return(Status);
-
-  /* Enumerate services and create the service list */
-  InitializeObjectAttributes(&ObjectAttributes,
-			     &ServicesKeyName,
-			     OBJ_CASE_INSENSITIVE,
-			     NULL,
-			     NULL);
-
-  Status = ZwOpenKey(&KeyHandle,
-		     KEY_ENUMERATE_SUB_KEYS,
-		     &ObjectAttributes);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
-
-  KeyInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_PATH * sizeof(WCHAR);
-  KeyInfo = ExAllocatePool(NonPagedPool, KeyInfoLength);
-  if (KeyInfo == NULL)
-    {
-      ZwClose(KeyHandle);
-      return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-
-  Index = 0;
-  while (TRUE)
-    {
-      Status = ZwEnumerateKey(KeyHandle,
-			      Index,
-			      KeyBasicInformation,
-			      KeyInfo,
-			      KeyInfoLength,
-			      &ReturnedLength);
-      if (NT_SUCCESS(Status))
-	{
-	  if (KeyInfo->NameLength < MAX_PATH * sizeof(WCHAR))
-	    {
-
-	      SubKeyName.Length = KeyInfo->NameLength;
-	      SubKeyName.MaximumLength = KeyInfo->NameLength + sizeof(WCHAR);
-	      SubKeyName.Buffer = KeyInfo->Name;
-	      SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
-
-	      DPRINT("KeyName: '%wZ'\n", &SubKeyName);
-	      IopCreateServiceListEntry(&SubKeyName);
-	    }
-	}
-
-      if (!NT_SUCCESS(Status))
-	break;
-
-      Index++;
-    }
-
-  ExFreePool(KeyInfo);
-  ZwClose(KeyHandle);
-
-  DPRINT("IoCreateDriverList() done\n");
-
-  return(STATUS_SUCCESS);
-}
-
-NTSTATUS INIT_FUNCTION
-IoDestroyDriverList(VOID)
-{
-  PSERVICE_GROUP CurrentGroup, tmp1;
-  PSERVICE CurrentService, tmp2;
-
-  DPRINT("IoDestroyDriverList() called\n");
-
-  /* Destroy group list */
-  LIST_FOR_EACH_SAFE(CurrentGroup, tmp1, &GroupListHead, SERVICE_GROUP, GroupListEntry)
-    {
-      ExFreePool(CurrentGroup->GroupName.Buffer);
-      RemoveEntryList(&CurrentGroup->GroupListEntry);
-      if (CurrentGroup->TagArray)
-        {
-	  ExFreePool(CurrentGroup->TagArray);
-	}
-      ExFreePool(CurrentGroup);
-    }
-
-  /* Destroy service list */
-  LIST_FOR_EACH_SAFE(CurrentService, tmp2, &ServiceListHead, SERVICE, ServiceListEntry)
-    {
-      ExFreePool(CurrentService->ServiceName.Buffer);
-      ExFreePool(CurrentService->RegistryPath.Buffer);
-      ExFreePool(CurrentService->ServiceGroup.Buffer);
-      ExFreePool(CurrentService->ImagePath.Buffer);
-      RemoveEntryList(&CurrentService->ServiceListEntry);
-      ExFreePool(CurrentService);
-    }
-
-  DPRINT("IoDestroyDriverList() done\n");
-
-  return(STATUS_SUCCESS);
 }
 
 static VOID INIT_FUNCTION
@@ -1378,115 +994,6 @@
    }
 }
 
-static INIT_FUNCTION NTSTATUS
-IopLoadDriver(PSERVICE Service)
-{
-   NTSTATUS Status = STATUS_UNSUCCESSFUL;
-
-   IopDisplayLoadingMessage(Service->ServiceName.Buffer, TRUE);
-   Status = ZwLoadDriver(&Service->RegistryPath);
-   IopBootLog(&Service->ImagePath, NT_SUCCESS(Status) ? TRUE : FALSE);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("IopLoadDriver() failed (Status %lx)\n", Status);
-#if 0
-      if (Service->ErrorControl == 1)
-      {
-         /* Log error */
-      }
-      else if (Service->ErrorControl == 2)
-      {
-         if (IsLastKnownGood == FALSE)
-         {
-            /* Boot last known good configuration */
-         }
-      }
-      else if (Service->ErrorControl == 3)
-      {
-         if (IsLastKnownGood == FALSE)
-         {
-            /* Boot last known good configuration */
-         }
-         else
-         {
-            /* BSOD! */
-         }
-      }
-#endif
-   }
-   return Status;
-}
-
-
-/*
- * IopInitializeSystemDrivers
- *
- * Load drivers marked as system start.
- *
- * Parameters
- *    None
- *
- * Return Value
- *    None
- */
-
-VOID FASTCALL
-IopInitializeSystemDrivers(VOID)
-{
-   PSERVICE_GROUP CurrentGroup;
-   PSERVICE CurrentService;
-   NTSTATUS Status;
-   ULONG i;
-
-   DPRINT("IopInitializeSystemDrivers()\n");
-
-   LIST_FOR_EACH(CurrentGroup, &GroupListHead, SERVICE_GROUP, GroupListEntry)
-   {
-      DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);
-
-      /* Load all drivers with a valid tag */
-      for (i = 0; i < CurrentGroup->TagCount; i++)
-      {
-         LIST_FOR_EACH(CurrentService, &ServiceListHead, SERVICE, ServiceListEntry)
-         {
-            if ((RtlCompareUnicodeString(&CurrentGroup->GroupName,
-                                         &CurrentService->ServiceGroup, TRUE) == 0) &&
-	        (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/) &&
-		(CurrentService->Tag == CurrentGroup->TagArray[i]))
-	    {
-	       DPRINT("  Path: %wZ\n", &CurrentService->RegistryPath);
-               Status = IopLoadDriver(CurrentService);
- 	    }
-         }
-      }
-
-      /* Load all drivers without a tag or with an invalid tag */
-      LIST_FOR_EACH(CurrentService, &ServiceListHead, SERVICE, ServiceListEntry)
-      {
-         if ((RtlCompareUnicodeString(&CurrentGroup->GroupName,
-                                      &CurrentService->ServiceGroup, TRUE) == 0) &&
-	     (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/))
-	 {
-	    for (i = 0; i < CurrentGroup->TagCount; i++)
-	    {
-	       if (CurrentGroup->TagArray[i] == CurrentService->Tag)
-	       {
-	          break;
-	       }
-	    }
-	    if (i >= CurrentGroup->TagCount)
-	    {
-               DPRINT("  Path: %wZ\n", &CurrentService->RegistryPath);
-               Status = IopLoadDriver(CurrentService);
- 	    }
-	 }
-      }
-
-   }
-
-   DPRINT("IopInitializeSystemDrivers() done\n");
-}
-
 /*
  * IopUnloadDriver
  *

Added: trunk/reactos/ntoskrnl/io/iomgr/drvrlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/drvrlist.c?rev=22968&view=auto
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/drvrlist.c (added)
+++ trunk/reactos/ntoskrnl/io/iomgr/drvrlist.c Sun Jul  9 06:34:32 2006
@@ -1,0 +1,494 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/iomgr/drvrlist.c
+ * PURPOSE:         Driver List support for Grouping, Tagging, Sorting, etc.
+ * PROGRAMMERS:     <UNKNOWN>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+typedef struct _SERVICE_GROUP
+{
+  LIST_ENTRY GroupListEntry;
+  UNICODE_STRING GroupName;
+  BOOLEAN ServicesRunning;
+  ULONG TagCount;
+  PULONG TagArray;
+} SERVICE_GROUP, *PSERVICE_GROUP;
+
+typedef struct _SERVICE
+{
+  LIST_ENTRY ServiceListEntry;
+  UNICODE_STRING ServiceName;
+  UNICODE_STRING RegistryPath;
+  UNICODE_STRING ServiceGroup;
+  UNICODE_STRING ImagePath;
+
+  ULONG Start;
+  ULONG Type;
+  ULONG ErrorControl;
+  ULONG Tag;
+
+/*  BOOLEAN ServiceRunning;*/	// needed ??
+} SERVICE, *PSERVICE;
+
+/* GLOBALS ********************************************************************/
+
+LIST_ENTRY GroupListHead = {NULL, NULL};
+LIST_ENTRY ServiceListHead  = {NULL, NULL};
+extern BOOLEAN SetupMode;
+extern BOOLEAN NoGuiBoot;
+
+VOID 
+FASTCALL
+INIT_FUNCTION
+IopDisplayLoadingMessage(PVOID ServiceName,
+                         BOOLEAN Unicode);
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static NTSTATUS STDCALL
+IopGetGroupOrderList(PWSTR ValueName,
+		     ULONG ValueType,
+		     PVOID ValueData,
+		     ULONG ValueLength,
+		     PVOID Context,
+		     PVOID EntryContext)
+{
+  PSERVICE_GROUP Group;
+
+  DPRINT("IopGetGroupOrderList(%S, %x, 0x%p, %x, 0x%p, 0x%p)\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 = ExAllocatePool(NonPagedPool, Group->TagCount * sizeof(DWORD));
+	      if (Group->TagArray == NULL)
+	        {
+		  Group->TagCount = 0;
+	          return STATUS_INSUFFICIENT_RESOURCES;
+		}
+	      memcpy(Group->TagArray, (PULONG)ValueData + 1, Group->TagCount * sizeof(DWORD));
+	    }
+	  else
+	    {
+	      Group->TagCount = 0;
+	      return STATUS_UNSUCCESSFUL;
+	    }
+	}
+    }
+  return STATUS_SUCCESS;
+}
+
+static NTSTATUS STDCALL
+IopCreateGroupListEntry(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("GroupName: '%S'\n", (PWCHAR)ValueData);
+
+      Group = ExAllocatePool(NonPagedPool,
+			     sizeof(SERVICE_GROUP));
+      if (Group == NULL)
+	{
+	  return(STATUS_INSUFFICIENT_RESOURCES);
+	}
+
+      RtlZeroMemory(Group, sizeof(SERVICE_GROUP));
+
+      if (!RtlCreateUnicodeString(&Group->GroupName, (PWSTR)ValueData))
+	{
+	  ExFreePool(Group);
+	  return(STATUS_INSUFFICIENT_RESOURCES);
+	}
+
+      RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+      QueryTable[0].Name = (PWSTR)ValueData;
+      QueryTable[0].QueryRoutine = IopGetGroupOrderList;
+
+      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);
+}
+
+
+static NTSTATUS STDCALL
+IopCreateServiceListEntry(PUNICODE_STRING ServiceName)
+{
+  RTL_QUERY_REGISTRY_TABLE QueryTable[7];
+  PSERVICE Service;
+  NTSTATUS Status;
+
+  DPRINT("ServiceName: '%wZ'\n", ServiceName);
+
+  /* Allocate service entry */
+  Service = (PSERVICE)ExAllocatePool(NonPagedPool, sizeof(SERVICE));
+  if (Service == NULL)
+    {
+      DPRINT1("ExAllocatePool() failed\n");
+      return(STATUS_INSUFFICIENT_RESOURCES);
+    }
+  RtlZeroMemory(Service, sizeof(SERVICE));
+
+  /* Get service data */
+  RtlZeroMemory(&QueryTable,
+		sizeof(QueryTable));
+
+  QueryTable[0].Name = L"Start";
+  QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+  QueryTable[0].EntryContext = &Service->Start;
+
+  QueryTable[1].Name = L"Type";
+  QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+  QueryTable[1].EntryContext = &Service->Type;
+
+  QueryTable[2].Name = L"ErrorControl";
+  QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+  QueryTable[2].EntryContext = &Service->ErrorControl;
+
+  QueryTable[3].Name = L"Group";
+  QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
+  QueryTable[3].EntryContext = &Service->ServiceGroup;
+
+  QueryTable[4].Name = L"ImagePath";
+  QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
+  QueryTable[4].EntryContext = &Service->ImagePath;
+
+  QueryTable[5].Name = L"Tag";
+  QueryTable[5].Flags = RTL_QUERY_REGISTRY_DIRECT;
+  QueryTable[5].EntryContext = &Service->Tag;
+
+  Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
+				  ServiceName->Buffer,
+				  QueryTable,
+				  NULL,
+				  NULL);
+  if (!NT_SUCCESS(Status) || Service->Start > 1)
+    {
+      /*
+       * If something goes wrong during RtlQueryRegistryValues
+       * it'll just drop everything on the floor and return,
+       * so you have to check if the buffers were filled.
+       * Luckily we zerofilled the Service.
+       */
+      if (Service->ServiceGroup.Buffer)
+        {
+          ExFreePool(Service->ServiceGroup.Buffer);
+        }
+      if (Service->ImagePath.Buffer)
+        {
+          ExFreePool(Service->ImagePath.Buffer);
+        }
+      ExFreePool(Service);
+      return(Status);
+    }
+
+  /* Copy service name */
+  Service->ServiceName.Length = ServiceName->Length;
+  Service->ServiceName.MaximumLength = ServiceName->Length + sizeof(WCHAR);
+  Service->ServiceName.Buffer = ExAllocatePool(NonPagedPool,
+					       Service->ServiceName.MaximumLength);
+  RtlCopyMemory(Service->ServiceName.Buffer,
+		ServiceName->Buffer,
+		ServiceName->Length);
+  Service->ServiceName.Buffer[ServiceName->Length / sizeof(WCHAR)] = 0;
+
+  /* Build registry path */
+  Service->RegistryPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
+  Service->RegistryPath.Buffer = ExAllocatePool(NonPagedPool,
+						MAX_PATH * sizeof(WCHAR));
+  wcscpy(Service->RegistryPath.Buffer,
+	 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+  wcscat(Service->RegistryPath.Buffer,
+	 Service->ServiceName.Buffer);
+  Service->RegistryPath.Length = wcslen(Service->RegistryPath.Buffer) * sizeof(WCHAR);
+
+  DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
+  DPRINT("RegistryPath: '%wZ'\n", &Service->RegistryPath);
+  DPRINT("ServiceGroup: '%wZ'\n", &Service->ServiceGroup);
+  DPRINT("ImagePath: '%wZ'\n", &Service->ImagePath);
+  DPRINT("Start %lx  Type %lx  Tag %lx ErrorControl %lx\n",
+	 Service->Start, Service->Type, Service->Tag, Service->ErrorControl);
+
+  /* Append service entry */
+  InsertTailList(&ServiceListHead,
+		 &Service->ServiceListEntry);
+
+  return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS INIT_FUNCTION
+IoCreateDriverList(VOID)
+{
+  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+  PKEY_BASIC_INFORMATION KeyInfo = NULL;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
+  UNICODE_STRING SubKeyName;
+  HANDLE KeyHandle;
+  NTSTATUS Status;
+  ULONG Index;
+
+  ULONG KeyInfoLength = 0;
+  ULONG ReturnedLength;
+
+  DPRINT("IoCreateDriverList() called\n");
+
+  /* Initialize basic variables */
+  InitializeListHead(&GroupListHead);
+  InitializeListHead(&ServiceListHead);
+
+  /* Build group order list */
+  RtlZeroMemory(&QueryTable,
+		sizeof(QueryTable));
+
+  QueryTable[0].Name = L"List";
+  QueryTable[0].QueryRoutine = IopCreateGroupListEntry;
+
+  Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+				  L"ServiceGroupOrder",
+				  QueryTable,
+				  NULL,
+				  NULL);
+  if (!NT_SUCCESS(Status))
+    return(Status);
+
+  /* Enumerate services and create the service list */
+  InitializeObjectAttributes(&ObjectAttributes,
+			     &ServicesKeyName,
+			     OBJ_CASE_INSENSITIVE,
+			     NULL,
+			     NULL);
+
+  Status = ZwOpenKey(&KeyHandle,
+		     KEY_ENUMERATE_SUB_KEYS,
+		     &ObjectAttributes);
+  if (!NT_SUCCESS(Status))
+    {
+      return(Status);
+    }
+
+  KeyInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_PATH * sizeof(WCHAR);
+  KeyInfo = ExAllocatePool(NonPagedPool, KeyInfoLength);
+  if (KeyInfo == NULL)
+    {
+      ZwClose(KeyHandle);
+      return(STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  Index = 0;
+  while (TRUE)
+    {
+      Status = ZwEnumerateKey(KeyHandle,
+			      Index,
+			      KeyBasicInformation,
+			      KeyInfo,
+			      KeyInfoLength,
+			      &ReturnedLength);
+      if (NT_SUCCESS(Status))
+	{
+	  if (KeyInfo->NameLength < MAX_PATH * sizeof(WCHAR))
+	    {
+
+	      SubKeyName.Length = KeyInfo->NameLength;
+	      SubKeyName.MaximumLength = KeyInfo->NameLength + sizeof(WCHAR);
+	      SubKeyName.Buffer = KeyInfo->Name;
+	      SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
+
+	      DPRINT("KeyName: '%wZ'\n", &SubKeyName);
+	      IopCreateServiceListEntry(&SubKeyName);
+	    }
+	}
+
+      if (!NT_SUCCESS(Status))
+	break;
+
+      Index++;
+    }
+
+  ExFreePool(KeyInfo);
+  ZwClose(KeyHandle);
+
+  DPRINT("IoCreateDriverList() done\n");
+
+  return(STATUS_SUCCESS);
+}
+
+NTSTATUS INIT_FUNCTION
+IoDestroyDriverList(VOID)
+{
+  PSERVICE_GROUP CurrentGroup, tmp1;
+  PSERVICE CurrentService, tmp2;
+
+  DPRINT("IoDestroyDriverList() called\n");
+
+  /* Destroy group list */
+  LIST_FOR_EACH_SAFE(CurrentGroup, tmp1, &GroupListHead, SERVICE_GROUP, GroupListEntry)
+    {
+      ExFreePool(CurrentGroup->GroupName.Buffer);
+      RemoveEntryList(&CurrentGroup->GroupListEntry);
+      if (CurrentGroup->TagArray)
+        {
+	  ExFreePool(CurrentGroup->TagArray);
+	}
+      ExFreePool(CurrentGroup);
+    }
+
+  /* Destroy service list */
+  LIST_FOR_EACH_SAFE(CurrentService, tmp2, &ServiceListHead, SERVICE, ServiceListEntry)
+    {
+      ExFreePool(CurrentService->ServiceName.Buffer);
+      ExFreePool(CurrentService->RegistryPath.Buffer);
+      ExFreePool(CurrentService->ServiceGroup.Buffer);
+      ExFreePool(CurrentService->ImagePath.Buffer);
+      RemoveEntryList(&CurrentService->ServiceListEntry);
+      ExFreePool(CurrentService);
+    }
+
+  DPRINT("IoDestroyDriverList() done\n");
+
+  return(STATUS_SUCCESS);
+}
+
+static INIT_FUNCTION NTSTATUS
+IopLoadDriver(PSERVICE Service)
+{
+   NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+   IopDisplayLoadingMessage(Service->ServiceName.Buffer, TRUE);
+   Status = ZwLoadDriver(&Service->RegistryPath);
+   IopBootLog(&Service->ImagePath, NT_SUCCESS(Status) ? TRUE : FALSE);
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("IopLoadDriver() failed (Status %lx)\n", Status);
+#if 0
+      if (Service->ErrorControl == 1)
+      {
+         /* Log error */
+      }
+      else if (Service->ErrorControl == 2)
+      {
+         if (IsLastKnownGood == FALSE)
+         {
+            /* Boot last known good configuration */
+         }
+      }
+      else if (Service->ErrorControl == 3)
+      {
+         if (IsLastKnownGood == FALSE)
+         {
+            /* Boot last known good configuration */
+         }
+         else
+         {
+            /* BSOD! */
+         }
+      }
+#endif
+   }
+   return Status;
+}
+
+/*
+ * IopInitializeSystemDrivers
+ *
+ * Load drivers marked as system start.
+ *
+ * Parameters
+ *    None
+ *
+ * Return Value
+ *    None
+ */
+
+VOID FASTCALL
+IopInitializeSystemDrivers(VOID)
+{
+   PSERVICE_GROUP CurrentGroup;
+   PSERVICE CurrentService;
+   NTSTATUS Status;
+   ULONG i;
+
+   DPRINT("IopInitializeSystemDrivers()\n");
+
+   LIST_FOR_EACH(CurrentGroup, &GroupListHead, SERVICE_GROUP, GroupListEntry)
+   {
+      DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);
+
+      /* Load all drivers with a valid tag */
+      for (i = 0; i < CurrentGroup->TagCount; i++)
+      {
+         LIST_FOR_EACH(CurrentService, &ServiceListHead, SERVICE, ServiceListEntry)
+         {
+            if ((RtlCompareUnicodeString(&CurrentGroup->GroupName,
+                                         &CurrentService->ServiceGroup, TRUE) == 0) &&
+	        (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/) &&
+		(CurrentService->Tag == CurrentGroup->TagArray[i]))
+	    {
+	       DPRINT("  Path: %wZ\n", &CurrentService->RegistryPath);
+               Status = IopLoadDriver(CurrentService);
+ 	    }
+         }
+      }
+
+      /* Load all drivers without a tag or with an invalid tag */
+      LIST_FOR_EACH(CurrentService, &ServiceListHead, SERVICE, ServiceListEntry)
+      {
+         if ((RtlCompareUnicodeString(&CurrentGroup->GroupName,
+                                      &CurrentService->ServiceGroup, TRUE) == 0) &&
+	     (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/))
+	 {
+	    for (i = 0; i < CurrentGroup->TagCount; i++)
+	    {
+	       if (CurrentGroup->TagArray[i] == CurrentService->Tag)
+	       {
+	          break;
+	       }
+	    }
+	    if (i >= CurrentGroup->TagCount)
+	    {
+               DPRINT("  Path: %wZ\n", &CurrentService->RegistryPath);
+               Status = IopLoadDriver(CurrentService);
+ 	    }
+	 }
+      }
+
+   }
+
+   DPRINT("IopInitializeSystemDrivers() done\n");
+}
+/* EOF */

Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?rev=22968&r1=22967&r2=22968&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Sun Jul  9 06:34:32 2006
@@ -172,6 +172,7 @@
 			<file>deviface.c</file>
 			<file>disk.c</file>
 			<file>driver.c</file>
+			<file>drvrlist.c</file>
 			<file>error.c</file>
 			<file>event.c</file>
             <file>file.c</file>




More information about the Ros-diffs mailing list