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…
==============================================================================
--- 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(a)reactos.org)
* Filip Navara (navaraf(a)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…
==============================================================================
--- 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?r…
==============================================================================
--- 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>