diff --git a/reactos/ntoskrnl/config/cmboot.c b/reactos/ntoskrnl/config/cmboot.c index f1dcc347a20..50c6815866f 100644 --- a/reactos/ntoskrnl/config/cmboot.c +++ b/reactos/ntoskrnl/config/cmboot.c @@ -1,20 +1,19 @@ /* * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: ntoskrnl/config/cmboot.c * PURPOSE: Configuration Manager - Boot Initialization - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * PROGRAMMERS: ReactOS Portable Systems Group + * Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include "ntoskrnl.h" #define NDEBUG #include "debug.h" - -/* GLOBALS *******************************************************************/ - -/* FUNCTIONS *****************************************************************/ + +/* FUNCTIONS ******************************************************************/ HCELL_INDEX NTAPI @@ -124,3 +123,559 @@ CmpFindControlSet(IN PHHIVE SystemHive, /* Return the CCS Cell */ return ControlSetCell; } + +ULONG +NTAPI +CmpFindTagIndex(IN PHHIVE Hive, + IN HCELL_INDEX TagCell, + IN HCELL_INDEX GroupOrderCell, + IN PUNICODE_STRING GroupName) +{ + PCM_KEY_VALUE TagValue, Value; + HCELL_INDEX OrderCell; + PULONG TagOrder, DriverTag; + ULONG CurrentTag, Length; + PCM_KEY_NODE Node; + BOOLEAN BufferAllocated; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Get the tag */ + Value = HvGetCell(Hive, TagCell); + ASSERT(Value); + DriverTag = (PULONG)CmpValueToData(Hive, Value, &Length); + ASSERT(DriverTag); + + /* Get the order array */ + Node = HvGetCell(Hive, GroupOrderCell); + ASSERT(Node); + OrderCell = CmpFindValueByName(Hive, Node, GroupName); + if (OrderCell == HCELL_NIL) return -2; + + /* And read it */ + TagValue = HvGetCell(Hive, OrderCell); + CmpGetValueData(Hive, TagValue, &Length, (PVOID*)&TagOrder, &BufferAllocated, &OrderCell); + ASSERT(TagOrder); + + /* Parse each tag */ + for (CurrentTag = 1; CurrentTag <= TagOrder[0]; CurrentTag++) + { + /* Find a match */ + if (TagOrder[CurrentTag] == *DriverTag) + { + /* Found it -- return the tag */ + if (BufferAllocated) ExFreePool(TagOrder); + return CurrentTag; + } + } + + /* No matches, so assume next to last ordering */ + if (BufferAllocated) ExFreePool(TagOrder); + return -2; +} + +BOOLEAN +NTAPI +CmpAddDriverToList(IN PHHIVE Hive, + IN HCELL_INDEX DriverCell, + IN HCELL_INDEX GroupOrderCell, + IN PUNICODE_STRING RegistryPath, + IN PLIST_ENTRY BootDriverListHead) +{ + PBOOT_DRIVER_NODE DriverNode; + PBOOT_DRIVER_LIST_ENTRY DriverEntry; + PCM_KEY_NODE Node; + ULONG NameLength, Length; + HCELL_INDEX ValueCell, TagCell; + PCM_KEY_VALUE Value; + PUNICODE_STRING FileName, RegistryString; + UNICODE_STRING UnicodeString; + PULONG ErrorControl; + PWCHAR Buffer; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Allocate a driver node and initialize it */ + DriverNode = CmpAllocate(sizeof(BOOT_DRIVER_NODE), FALSE, TAG_CM); + if (!DriverNode) return FALSE; + DriverEntry = &DriverNode->ListEntry; + DriverEntry->RegistryPath.Buffer = NULL; + DriverEntry->FilePath.Buffer = NULL; + + /* Get the driver cell */ + Node = HvGetCell(Hive, DriverCell); + ASSERT(Node); + + /* Get the name from the cell */ + DriverNode->Name.Length = Node->Flags & KEY_COMP_NAME ? + CmpCompressedNameSize(Node->Name, Node->NameLength) : + Node->NameLength; + DriverNode->Name.MaximumLength = DriverNode->Name.Length; + NameLength = DriverNode->Name.Length; + + /* Now allocate the buffer for it and copy the name */ + DriverNode->Name.Buffer = CmpAllocate(NameLength, FALSE, TAG_CM); + if (!DriverNode->Name.Buffer) return FALSE; + if (Node->Flags & KEY_COMP_NAME) + { + /* Compressed name */ + CmpCopyCompressedName(DriverNode->Name.Buffer, + DriverNode->Name.Length, + Node->Name, + Node->NameLength); + } + else + { + /* Normal name */ + RtlCopyMemory(DriverNode->Name.Buffer, Node->Name, Node->NameLength); + } + + /* Now find the image path */ + RtlInitUnicodeString(&UnicodeString, L"ImagePath"); + ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString); + if (ValueCell == HCELL_NIL) + { + /* Couldn't find it, so assume the drivers path */ + Length = sizeof(L"System32\\Drivers\\") + NameLength + sizeof(L".sys"); + + /* Allocate the path name */ + FileName = &DriverEntry->FilePath; + FileName->Length = 0; + FileName->MaximumLength = Length; + FileName->Buffer = CmpAllocate(Length, FALSE,TAG_CM); + if (!FileName->Buffer) return FALSE; + + /* Write the path name */ + RtlAppendUnicodeToString(FileName, L"System32\\Drivers\\"); + RtlAppendUnicodeStringToString(FileName, &DriverNode->Name); + RtlAppendUnicodeToString(FileName, L".sys"); + } + else + { + /* Path name exists, so grab it */ + Value = HvGetCell(Hive, ValueCell); + ASSERT(Value); + + /* Allocate and setup the path name */ + FileName = &DriverEntry->FilePath; + Buffer = (PWCHAR)CmpValueToData(Hive, Value, &Length); + FileName->MaximumLength = FileName->Length = Length; + FileName->Buffer = CmpAllocate(Length, FALSE, TAG_CM); + + /* Transfer the data */ + if (!(FileName->Buffer) || !(Buffer)) return FALSE; + RtlCopyMemory(FileName->Buffer, Buffer, Length); + } + + /* Now build the registry path */ + RegistryString = &DriverEntry->RegistryPath; + RegistryString->Length = 0; + RegistryString->MaximumLength = RegistryPath->Length + NameLength; + RegistryString->Buffer = CmpAllocate(RegistryString->MaximumLength, FALSE, TAG_CM); + if (!RegistryString->Buffer) return FALSE; + + /* Add the driver name to it */ + RtlAppendUnicodeStringToString(RegistryString, RegistryPath); + RtlAppendUnicodeStringToString(RegistryString, &DriverNode->Name); + + /* The entry is done, add it */ + InsertHeadList(BootDriverListHead, &DriverEntry->Link); + + /* Now find error control settings */ + RtlInitUnicodeString(&UnicodeString, L"ErrorControl"); + ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString); + if (ValueCell == HCELL_NIL) + { + /* Couldn't find it, so assume default */ + DriverNode->ErrorControl = NormalError; + } + else + { + /* Otherwise, read whatever the data says */ + Value = HvGetCell(Hive, ValueCell); + ASSERT(Value); + ErrorControl = (PULONG)CmpValueToData(Hive, Value, &Length); + ASSERT(ErrorControl); + DriverNode->ErrorControl = *ErrorControl; + } + + /* Next, get the group cell */ + RtlInitUnicodeString(&UnicodeString, L"group"); + ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString); + if (ValueCell == HCELL_NIL) + { + /* Couldn't find, so set an empty string */ + RtlInitEmptyUnicodeString(&DriverNode->Group, NULL, 0); + } + else + { + /* Found it, read the group value */ + Value = HvGetCell(Hive, ValueCell); + ASSERT(Value); + + /* Copy it into the node */ + DriverNode->Group.Buffer = (PWCHAR)CmpValueToData(Hive, Value, &Length); + if (!DriverNode->Group.Buffer) return FALSE; + DriverNode->Group.Length = Length - sizeof(UNICODE_NULL); + DriverNode->Group.MaximumLength = DriverNode->Group.Length; + } + + /* Finally, find the tag */ + RtlInitUnicodeString(&UnicodeString, L"Tag"); + TagCell = CmpFindValueByName(Hive, Node, &UnicodeString); + if (TagCell == HCELL_NIL) + { + /* No tag, so load last */ + DriverNode->Tag = -1; + } + else + { + /* Otherwise, decode it based on tag order */ + DriverNode->Tag = CmpFindTagIndex(Hive, + TagCell, + GroupOrderCell, + &DriverNode->Group); + } + + /* All done! */ + return TRUE; +} + +BOOLEAN +NTAPI +CmpIsLoadType(IN PHHIVE Hive, + IN HCELL_INDEX Cell, + IN SERVICE_LOAD_TYPE LoadType) +{ + PCM_KEY_NODE Node; + HCELL_INDEX ValueCell; + UNICODE_STRING ValueString = RTL_CONSTANT_STRING(L"Start"); + PCM_KEY_VALUE Value; + ULONG Length; + PLONG Data; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Open the start cell */ + Node = HvGetCell(Hive, Cell); + ASSERT(Node); + ValueCell = CmpFindValueByName(Hive, Node, &ValueString); + if (ValueCell == HCELL_NIL) return FALSE; + + /* Read the start value */ + Value = HvGetCell(Hive, ValueCell); + ASSERT(Value); + Data = (PLONG)CmpValueToData(Hive, Value, &Length); + ASSERT(Data); + + /* Return if the type matches */ + return (*Data == LoadType); +} + +BOOLEAN +NTAPI +CmpFindDrivers(IN PHHIVE Hive, + IN HCELL_INDEX ControlSet, + IN SERVICE_LOAD_TYPE LoadType, + IN PWCHAR BootFileSystem OPTIONAL, + IN PLIST_ENTRY DriverListHead) +{ + HCELL_INDEX ServicesCell, ControlCell, GroupOrderCell, DriverCell; + UNICODE_STRING Name; + ULONG i; + WCHAR Buffer[128]; + UNICODE_STRING UnicodeString, KeyPath; + PBOOT_DRIVER_NODE FsNode; + PCM_KEY_NODE ControlNode, ServicesNode, Node; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Open the control set key */ + ControlNode = HvGetCell(Hive, ControlSet); + ASSERT(ControlNode); + + /* Get services cell */ + RtlInitUnicodeString(&Name, L"Services"); + ServicesCell = CmpFindSubKeyByName(Hive, ControlNode, &Name); + if (ServicesCell == HCELL_NIL) return FALSE; + + /* Open services key */ + ServicesNode = HvGetCell(Hive, ServicesCell); + ASSERT(ServicesNode); + + /* Get control cell */ + RtlInitUnicodeString(&Name, L"Control"); + ControlCell = CmpFindSubKeyByName(Hive, ControlNode, &Name); + if (ControlCell == HCELL_NIL) return FALSE; + + /* Get the group order cell and read it */ + RtlInitUnicodeString(&Name, L"GroupOrderList"); + Node = HvGetCell(Hive, ControlCell); + ASSERT(Node); + GroupOrderCell = CmpFindSubKeyByName(Hive, Node, &Name); + if (GroupOrderCell == HCELL_NIL) return FALSE; + + /* Build the root registry path */ + RtlInitEmptyUnicodeString(&KeyPath, Buffer, sizeof(Buffer)); + RtlAppendUnicodeToString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"); + + /* Find the first subkey (ie: the first driver or service) */ + i = 0; + DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, i); + while (DriverCell != HCELL_NIL) + { + /* Make sure it's a driver of this start type */ + if (CmpIsLoadType(Hive, DriverCell, LoadType)) + { + /* Add it to the list */ + CmpAddDriverToList(Hive, + DriverCell, + GroupOrderCell, + &KeyPath, + DriverListHead); + + } + + /* Try the next subkey */ + DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, ++i); + } + + /* Check if we have a boot file system */ + if (BootFileSystem) + { + /* Find it */ + RtlInitUnicodeString(&UnicodeString, BootFileSystem); + DriverCell = CmpFindSubKeyByName(Hive, ServicesNode, &UnicodeString); + if (DriverCell != HCELL_NIL) + { + /* Always add it to the list */ + CmpAddDriverToList(Hive, + DriverCell, + GroupOrderCell, + &KeyPath, + DriverListHead); + + /* Mark it as critical so it always loads */ + FsNode = CONTAINING_RECORD(DriverListHead->Flink, + BOOT_DRIVER_NODE, + ListEntry.Link); + FsNode->ErrorControl = SERVICE_ERROR_CRITICAL; + } + } + + /* We're done! */ + return TRUE; +} + +BOOLEAN +NTAPI +CmpDoSort(IN PLIST_ENTRY DriverListHead, + IN PUNICODE_STRING OrderList) +{ + PWCHAR Current, End = NULL; + PLIST_ENTRY NextEntry; + UNICODE_STRING GroupName; + PBOOT_DRIVER_NODE CurrentNode; + + /* We're going from end to start, so get to the last group and keep going */ + Current = &OrderList->Buffer[OrderList->Length / sizeof(WCHAR)]; + while (Current > OrderList->Buffer) + { + /* Scan the current string */ + do + { + if (*Current == UNICODE_NULL) End = Current; + } while ((*(--Current - 1) != UNICODE_NULL) && (Current != OrderList->Buffer)); + + /* This is our cleaned up string for this specific group */ + ASSERT(End != NULL); + GroupName.Length = (End - Current) * sizeof(WCHAR); + GroupName.MaximumLength = GroupName.Length; + GroupName.Buffer = Current; + + /* Now loop the driver list */ + NextEntry = DriverListHead->Flink; + while (NextEntry != DriverListHead) + { + /* Get this node */ + CurrentNode = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + + /* Get the next entry now since we'll do a relink */ + NextEntry = CurrentNode->ListEntry.Link.Flink; + + /* Is there a group name and does it match the current group? */ + if ((CurrentNode->Group.Buffer) && + (RtlEqualUnicodeString(&GroupName, &CurrentNode->Group, TRUE))) + { + /* Remove from this location and re-link in the new one */ + RemoveEntryList(&CurrentNode->ListEntry.Link); + InsertHeadList(DriverListHead, &CurrentNode->ListEntry.Link); + } + } + + /* Move on */ + Current--; + } + + /* All done */ + return TRUE; +} + +BOOLEAN +NTAPI +CmpSortDriverList(IN PHHIVE Hive, + IN HCELL_INDEX ControlSet, + IN PLIST_ENTRY DriverListHead) +{ + HCELL_INDEX Controls, GroupOrder, ListCell; + UNICODE_STRING Name, DependList; + PCM_KEY_VALUE ListNode; + ULONG Length; + PCM_KEY_NODE Node; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Open the control key */ + Node = HvGetCell(Hive, ControlSet); + ASSERT(Node); + RtlInitUnicodeString(&Name, L"Control"); + Controls = CmpFindSubKeyByName(Hive, Node, &Name); + if (Controls == HCELL_NIL) return FALSE; + + /* Open the service group order */ + Node = HvGetCell(Hive, Controls); + ASSERT(Node); + RtlInitUnicodeString(&Name, L"ServiceGroupOrder"); + GroupOrder = CmpFindSubKeyByName(Hive, Node, &Name); + if (GroupOrder == HCELL_NIL) return FALSE; + + /* Open the list key */ + Node = HvGetCell(Hive, GroupOrder); + ASSERT(Node); + RtlInitUnicodeString(&Name, L"list"); + ListCell = CmpFindValueByName(Hive, Node, &Name); + if (ListCell == HCELL_NIL) return FALSE; + + /* Now read the actual list */ + ListNode = HvGetCell(Hive, ListCell); + ASSERT(ListNode); + if (ListNode->Type != REG_MULTI_SZ) return FALSE; + + /* Copy it into a buffer */ + DependList.Buffer = (PWCHAR)CmpValueToData(Hive, ListNode, &Length); + if (!DependList.Buffer) return FALSE; + DependList.Length = DependList.MaximumLength = Length - sizeof(UNICODE_NULL); + + /* And start the recurive sort algorithm */ + return CmpDoSort(DriverListHead, &DependList); +} + +BOOLEAN +NTAPI +CmpOrderGroup(IN PBOOT_DRIVER_NODE StartNode, + IN PBOOT_DRIVER_NODE EndNode) +{ + PBOOT_DRIVER_NODE CurrentNode, PreviousNode; + PLIST_ENTRY ListEntry; + + /* Base case, nothing to do */ + if (StartNode == EndNode) return TRUE; + + /* Loop the nodes */ + CurrentNode = StartNode; + do + { + /* Save this as the previous node */ + PreviousNode = CurrentNode; + + /* And move to the next one */ + ListEntry = CurrentNode->ListEntry.Link.Flink; + CurrentNode = CONTAINING_RECORD(ListEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + + /* Check if the previous driver had a bigger tag */ + if (PreviousNode->Tag > CurrentNode->Tag) + { + /* Check if we need to update the tail */ + if (CurrentNode == EndNode) + { + /* Update the tail */ + ListEntry = CurrentNode->ListEntry.Link.Blink; + EndNode = CONTAINING_RECORD(ListEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + } + + /* Remove this driver since we need to move it */ + RemoveEntryList(&CurrentNode->ListEntry.Link); + + /* Keep looping until we find a driver with a lower tag than ours */ + while ((PreviousNode->Tag > CurrentNode->Tag) && (PreviousNode != StartNode)) + { + /* We'll be re-inserted at this spot */ + ListEntry = PreviousNode->ListEntry.Link.Blink; + PreviousNode = CONTAINING_RECORD(ListEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + } + + /* Do the insert in the new location */ + InsertTailList(&PreviousNode->ListEntry.Link, &CurrentNode->ListEntry.Link); + + /* Update the head, if needed */ + if (PreviousNode == StartNode) StartNode = CurrentNode; + } + } while (CurrentNode != EndNode); + + /* All done */ + return TRUE; +} + +BOOLEAN +NTAPI +CmpResolveDriverDependencies(IN PLIST_ENTRY DriverListHead) +{ + PLIST_ENTRY NextEntry; + PBOOT_DRIVER_NODE StartNode, EndNode, CurrentNode; + + /* Loop the list */ + NextEntry = DriverListHead->Flink; + while (NextEntry != DriverListHead) + { + /* Find the first entry */ + StartNode = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + do + { + /* Find the last entry */ + EndNode = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + + /* Get the next entry */ + NextEntry = NextEntry->Flink; + CurrentNode = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + + /* If the next entry is back to the top, break out */ + if (NextEntry == DriverListHead) break; + + /* Otherwise, check if this entry is equal */ + if (!RtlEqualUnicodeString(&StartNode->Group, + &CurrentNode->Group, + TRUE)) + { + /* It is, so we've detected a cycle, break out */ + break; + } + } while (NextEntry != DriverListHead); + + /* Now we have the correct start and end pointers, so do the sort */ + CmpOrderGroup(StartNode, EndNode); + } + + /* We're done */ + return TRUE; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/config/cmsysini.c b/reactos/ntoskrnl/config/cmsysini.c index 0326e88e619..3587efe7326 100644 --- a/reactos/ntoskrnl/config/cmsysini.c +++ b/reactos/ntoskrnl/config/cmsysini.c @@ -1,12 +1,13 @@ /* * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: ntoskrnl/config/cmsysini.c * PURPOSE: Configuration Manager - System Initialization Code - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * PROGRAMMERS: ReactOS Portable Systems Group + * Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include "ntoskrnl.h" #define NDEBUG @@ -33,7 +34,7 @@ ULONG CmpTraceLevel = 0; extern LONG CmpFlushStarveWriters; extern BOOLEAN CmFirstTime; -/* FUNCTIONS *****************************************************************/ +/* FUNCTIONS ******************************************************************/ VOID NTAPI @@ -1574,6 +1575,162 @@ CmInitSystem1(VOID) return TRUE; } +VOID +NTAPI +CmpFreeDriverList(IN PHHIVE Hive, + IN PLIST_ENTRY DriverList) +{ + PLIST_ENTRY NextEntry, OldEntry; + PBOOT_DRIVER_NODE DriverNode; + PAGED_CODE(); + + /* Parse the current list */ + NextEntry = DriverList->Flink; + while (NextEntry != DriverList) + { + /* Get the driver node */ + DriverNode = CONTAINING_RECORD(NextEntry, BOOT_DRIVER_NODE, ListEntry.Link); + + /* Get the next entry now, since we're going to free it later */ + OldEntry = NextEntry; + NextEntry = NextEntry->Flink; + + /* Was there a name? */ + if (DriverNode->Name.Buffer) + { + /* Free it */ + CmpFree(DriverNode->Name.Buffer, DriverNode->Name.Length); + } + + /* Was there a registry path? */ + if (DriverNode->ListEntry.RegistryPath.Buffer) + { + /* Free it */ + CmpFree(DriverNode->ListEntry.RegistryPath.Buffer, + DriverNode->ListEntry.RegistryPath.MaximumLength); + } + + /* Was there a file path? */ + if (DriverNode->ListEntry.FilePath.Buffer) + { + /* Free it */ + CmpFree(DriverNode->ListEntry.FilePath.Buffer, + DriverNode->ListEntry.FilePath.MaximumLength); + } + + /* Now free the node, and move on */ + CmpFree(OldEntry, sizeof(BOOT_DRIVER_NODE)); + } +} + +PUNICODE_STRING* +NTAPI +CmGetSystemDriverList(VOID) +{ + LIST_ENTRY DriverList; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + PCM_KEY_BODY KeyBody; + PHHIVE Hive; + HCELL_INDEX RootCell, ControlCell; + HANDLE KeyHandle; + UNICODE_STRING KeyName; + PLIST_ENTRY NextEntry; + ULONG i; + PUNICODE_STRING* ServicePath = NULL; + BOOLEAN Success, AutoSelect; + PBOOT_DRIVER_LIST_ENTRY DriverEntry; + PAGED_CODE(); + + /* Initialize the driver list */ + InitializeListHead(&DriverList); + + /* Open the system hive key */ + RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); + if (!NT_SUCCESS(Status)) return NULL; + + /* Reference the key object to get the root hive/cell to access directly */ + Status = ObReferenceObjectByHandle(KeyHandle, + KEY_QUERY_VALUE, + CmpKeyObjectType, + KernelMode, + (PVOID*)&KeyBody, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + NtClose(KeyHandle); + return NULL; + } + + /* Do all this under the registry lock */ + CmpLockRegistryExclusive(); + + /* Get the hive and key cell */ + Hive = KeyBody->KeyControlBlock->KeyHive; + RootCell = KeyBody->KeyControlBlock->KeyCell; + + /* Open the current control set key */ + RtlInitUnicodeString(&KeyName, L"Current"); + ControlCell = CmpFindControlSet(Hive, RootCell, &KeyName, &AutoSelect); + if (ControlCell == HCELL_NIL) goto EndPath; + + /* Find all system drivers */ + Success = CmpFindDrivers(Hive, ControlCell, SystemLoad, NULL, &DriverList); + if (!Success) goto EndPath; + + /* Sort by group/tag */ + if (!CmpSortDriverList(Hive, ControlCell, &DriverList)) goto EndPath; + + /* Remove circular dependencies (cycles) and sort */ + if (!CmpResolveDriverDependencies(&DriverList)) goto EndPath; + + /* Loop the list to count drivers */ + for (i = 0, NextEntry = DriverList.Flink; + NextEntry != &DriverList; + i++, NextEntry = NextEntry->Flink); + + /* Allocate the array */ + ServicePath = ExAllocatePool(NonPagedPool, (i + 1) * sizeof(PUNICODE_STRING)); + if (!ServicePath) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0); + + /* Loop the driver list */ + for (i = 0, NextEntry = DriverList.Flink; + NextEntry != &DriverList; + i++, NextEntry = NextEntry->Flink) + { + /* Get the entry */ + DriverEntry = CONTAINING_RECORD(NextEntry, BOOT_DRIVER_LIST_ENTRY, Link); + + /* Allocate the path for the caller and duplicate the registry path */ + ServicePath[i] = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING)); + RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + &DriverEntry->RegistryPath, + ServicePath[i]); + } + + /* Terminate the list */ + ServicePath[i] = NULL; + +EndPath: + /* Free the driver list if we had one */ + if (!IsListEmpty(&DriverList)) CmpFreeDriverList(Hive, &DriverList); + + /* Unlock the registry */ + CmpUnlockRegistry(); + + /* Close the key handle and dereference the object, then return the path */ + ObDereferenceObject(KeyBody); + NtClose(KeyHandle); + return ServicePath; +} + VOID NTAPI CmpLockRegistryExclusive(VOID) @@ -1771,3 +1928,5 @@ CmShutdownSystem(VOID) if (!CmFirstTime) CmpShutdownWorkers(); CmpDoFlushAll(TRUE); } + +/* EOF */ diff --git a/reactos/ntoskrnl/include/internal/cm.h b/reactos/ntoskrnl/include/internal/cm.h index 4880dc08026..62f4010f20b 100644 --- a/reactos/ntoskrnl/include/internal/cm.h +++ b/reactos/ntoskrnl/include/internal/cm.h @@ -1522,6 +1522,40 @@ CmSetLazyFlushState( IN BOOLEAN Enable ); +// +// Driver List Routines +// +PUNICODE_STRING* +NTAPI +CmGetSystemDriverList( + VOID +); + +BOOLEAN +NTAPI +CmpFindDrivers( + IN PHHIVE Hive, + IN HCELL_INDEX ControlSet, + IN SERVICE_LOAD_TYPE LoadType, + IN PWSTR BootFileSystem OPTIONAL, + IN PLIST_ENTRY DriverListHead +); + + +BOOLEAN +NTAPI +CmpSortDriverList( + IN PHHIVE Hive, + IN HCELL_INDEX ControlSet, + IN PLIST_ENTRY DriverListHead +); + +BOOLEAN +NTAPI +CmpResolveDriverDependencies( + IN PLIST_ENTRY DriverListHead +); + // // Global variables accessible from all of Cm // diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index f00a87d0e09..18202bfd5e4 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -200,6 +200,7 @@ IopDisplayLoadingMessage(PUNICODE_STRING ServiceName) UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS"); if (ExpInTextModeSetup) return; + if (!KeLoaderBlock) return; RtlUpcaseUnicodeString(ServiceName, ServiceName, FALSE); snprintf(TextBuffer, sizeof(TextBuffer), "%s%sSystem32\\Drivers\\%wZ%s\n", @@ -1070,6 +1071,38 @@ IopInitializeBootDrivers(VOID) InitializeListHead(&KeLoaderBlock->LoadOrderListHead); } +VOID +FASTCALL +IopInitializeSystemDrivers(VOID) +{ + PUNICODE_STRING *DriverList, *SavedList; + + /* No system drivers on the boot cd */ + if (KeLoaderBlock->SetupLdrBlock) return; + + /* Get the driver list */ + SavedList = DriverList = CmGetSystemDriverList(); + ASSERT(DriverList); + + /* Loop it */ + while (*DriverList) + { + /* Load the driver */ + ZwLoadDriver(*DriverList); + + /* Free the entry */ + RtlFreeUnicodeString(*DriverList); + ExFreePool(*DriverList); + + /* Next entry */ + InbvIndicateProgress(); + DriverList++; + } + + /* Free the list */ + ExFreePool(SavedList); +} + /* * IopUnloadDriver * @@ -1791,6 +1824,8 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) cur--; } + IopDisplayLoadingMessage(&ServiceName); + /* * Get service type. */ diff --git a/reactos/ntoskrnl/io/iomgr/drvrlist.c b/reactos/ntoskrnl/io/iomgr/drvrlist.c deleted file mode 100644 index e15aab2a2cd..00000000000 --- a/reactos/ntoskrnl/io/iomgr/drvrlist.c +++ /dev/null @@ -1,561 +0,0 @@ -/* - * 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: - */ - -/* INCLUDES *******************************************************************/ - -#include -#define NDEBUG -#include - -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; - -#define TAG_RTLREGISTRY 'vrqR' - -/* GLOBALS ********************************************************************/ - -LIST_ENTRY GroupListHead = {NULL, NULL}; -LIST_ENTRY ServiceListHead = {NULL, NULL}; -extern BOOLEAN NoGuiBoot; - -VOID -FASTCALL -INIT_FUNCTION -IopDisplayLoadingMessage(PUNICODE_STRING ServiceName); - -/* PRIVATE FUNCTIONS **********************************************************/ - -static NTSTATUS NTAPI -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(ULONG) && - ValueLength >= (*(PULONG)ValueData + 1) * sizeof(ULONG)) - { - Group = (PSERVICE_GROUP)Context; - Group->TagCount = ((PULONG)ValueData)[0]; - if (Group->TagCount > 0) - { - if (ValueLength >= (Group->TagCount + 1) * sizeof(ULONG)) - { - Group->TagArray = ExAllocatePool(NonPagedPool, Group->TagCount * sizeof(ULONG)); - if (Group->TagArray == NULL) - { - Group->TagCount = 0; - return STATUS_INSUFFICIENT_RESOURCES; - } - memcpy(Group->TagArray, (PULONG)ValueData + 1, Group->TagCount * sizeof(ULONG)); - } - else - { - Group->TagCount = 0; - return STATUS_UNSUCCESSFUL; - } - } - } - return STATUS_SUCCESS; -} - -static NTSTATUS NTAPI -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 NTAPI -IopCreateServiceListEntry(PUNICODE_STRING ServiceName) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[7]; - PSERVICE Service; - NTSTATUS Status; - ULONG DefaultTag = MAXULONG; - - 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; - QueryTable[5].DefaultData = &DefaultTag; - QueryTable[5].DefaultType = REG_DWORD; - QueryTable[5].DefaultLength = sizeof(DefaultTag); - - 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) - { - ExFreePoolWithTag(Service->ServiceGroup.Buffer, TAG_RTLREGISTRY); - } - if (Service->ImagePath.Buffer) - { - ExFreePoolWithTag(Service->ImagePath.Buffer, TAG_RTLREGISTRY); - } - 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 = (USHORT)KeyInfo->NameLength; - SubKeyName.MaximumLength = (USHORT)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; - PSERVICE CurrentService; - PLIST_ENTRY NextEntry, TempEntry; - - DPRINT("IoDestroyDriverList() called\n"); - - /* Destroy the Group List */ - for (NextEntry = GroupListHead.Flink, TempEntry = NextEntry->Flink; - NextEntry != &GroupListHead; - NextEntry = TempEntry, TempEntry = NextEntry->Flink) - { - /* Get the entry */ - CurrentGroup = CONTAINING_RECORD(NextEntry, - SERVICE_GROUP, - GroupListEntry); - - /* Remove it from the list */ - RemoveEntryList(&CurrentGroup->GroupListEntry); - - /* Free buffers */ - ExFreePool(CurrentGroup->GroupName.Buffer); - if (CurrentGroup->TagArray) - ExFreePool(CurrentGroup->TagArray); - ExFreePool(CurrentGroup); - } - - /* Destroy the Service List */ - for (NextEntry = ServiceListHead.Flink, TempEntry = NextEntry->Flink; - NextEntry != &ServiceListHead; - NextEntry = TempEntry, TempEntry = NextEntry->Flink) - { - /* Get the entry */ - CurrentService = CONTAINING_RECORD(NextEntry, - SERVICE, - ServiceListEntry); - - /* Remove it from the list */ - RemoveEntryList(&CurrentService->ServiceListEntry); - - /* Free buffers */ - ExFreePool(CurrentService->ServiceName.Buffer); - ExFreePool(CurrentService->RegistryPath.Buffer); - if (CurrentService->ServiceGroup.Buffer) - ExFreePool(CurrentService->ServiceGroup.Buffer); - if (CurrentService->ImagePath.Buffer) - ExFreePool(CurrentService->ImagePath.Buffer); - ExFreePool(CurrentService); - } - - DPRINT("IoDestroyDriverList() done\n"); - - /* Return success */ - return STATUS_SUCCESS; -} - -static INIT_FUNCTION NTSTATUS -IopLoadDriver(PSERVICE Service) -{ - NTSTATUS Status = STATUS_UNSUCCESSFUL; - PUNICODE_STRING ImagePath = &Service->ImagePath; - PWCHAR ImageName; - UNICODE_STRING ImageNameU; - - ImageName = wcsrchr(ImagePath->Buffer, L'\\'); - if (!ImageName) - ImageName = ImagePath->Buffer; - else - ImageName++; - - RtlInitUnicodeString(&ImageNameU, ImageName); - - IopDisplayLoadingMessage(&ImageNameU); - - 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; - PLIST_ENTRY NextGroupEntry, NextServiceEntry; - - DPRINT("IopInitializeSystemDrivers()\n"); - - /* Start looping */ - for (NextGroupEntry = GroupListHead.Flink; - NextGroupEntry != &GroupListHead; - NextGroupEntry = NextGroupEntry->Flink) - { - /* Get the entry */ - CurrentGroup = CONTAINING_RECORD(NextGroupEntry, - SERVICE_GROUP, - GroupListEntry); - - DPRINT("Group: %wZ\n", &CurrentGroup->GroupName); - - /* Load all drivers with a valid tag */ - for (i = 0; i < CurrentGroup->TagCount; i++) - { - /* Start looping */ - for (NextServiceEntry = ServiceListHead.Flink; - NextServiceEntry != &ServiceListHead; - NextServiceEntry = NextServiceEntry->Flink) - { - /* Get the entry */ - CurrentService = CONTAINING_RECORD(NextServiceEntry, - SERVICE, - ServiceListEntry); - - if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName, - &CurrentService->ServiceGroup, - TRUE)) && - (CurrentService->Start == SERVICE_SYSTEM_START) && - (CurrentService->Tag == CurrentGroup->TagArray[i])) - - { - DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath); - Status = IopLoadDriver(CurrentService); - InbvIndicateProgress(); - } - } - } - - /* Load all drivers without a tag or with an invalid tag */ - for (NextServiceEntry = ServiceListHead.Flink; - NextServiceEntry != &ServiceListHead; - NextServiceEntry = NextServiceEntry->Flink) - { - /* Get the entry */ - CurrentService = CONTAINING_RECORD(NextServiceEntry, - SERVICE, - ServiceListEntry); - - if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName, - &CurrentService->ServiceGroup, - TRUE)) && - (CurrentService->Start == 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); - InbvIndicateProgress(); - } - - } - } - } - - DPRINT("IopInitializeSystemDrivers() done\n"); -} diff --git a/reactos/ntoskrnl/io/iomgr/iomgr.c b/reactos/ntoskrnl/io/iomgr/iomgr.c index c7999660a61..e52f2fe54ab 100644 --- a/reactos/ntoskrnl/io/iomgr/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr/iomgr.c @@ -493,9 +493,6 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Setup the group cache */ if (!NT_SUCCESS(PiInitCacheGroupInformation())) return FALSE; - /* Create the group driver list */ - IoCreateDriverList(); - /* Load boot start drivers */ IopInitializeBootDrivers(); @@ -533,9 +530,6 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) IopInitializeSystemDrivers(); PnpSystemInit = TRUE; - /* Destroy the group driver list */ - IoDestroyDriverList(); - /* Reinitialize drivers that requested it */ IopReinitializeDrivers(); diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild index b6ed1824217..a349f887312 100644 --- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild +++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild @@ -244,7 +244,6 @@ device.c deviface.c driver.c - drvrlist.c error.c file.c iocomp.c