Author: sir_richard
Date: Sat Apr 3 09:44:38 2010
New Revision: 46693
URL:
http://svn.reactos.org/svn/reactos?rev=46693&view=rev
Log:
[NTOS]: Implement Configuration Manager routines for building a driver list, sorting it,
detecting circular dependencies and ordering, combining groups, tags, group orders and tag
orders, etc. Replaces the "drvrlist" I/O interface currently in ReactOS.
[NTOS]: Use the new Cm interface in IopInitializeSystemDrivers to parse the ordered list
of system drivers to load. Make it use ZwLoadDriver directly instead of having a hacked
IopLoadDriver function.
[NTOS]: Drivers should not show up loading n times a reboot now (some drivers seemed to do
this in the past when they failed to load).
[NTOS]: The system driver code could be further improved by checknig if the driver has
already been loaded, or attempted and failed to load, but it is already much better now
than in the past.
[PERF]: Boot-time improvement since the new system driver loading code uses low-level Cm
interfaces (portability side-effect: can be shared with FreeLDR) instead of the complex
parse-based object-manager-based system-calls.
Removed:
trunk/reactos/ntoskrnl/io/iomgr/drvrlist.c
Modified:
trunk/reactos/ntoskrnl/config/cmboot.c
trunk/reactos/ntoskrnl/config/cmsysini.c
trunk/reactos/ntoskrnl/include/internal/cm.h
trunk/reactos/ntoskrnl/io/iomgr/driver.c
trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
Modified: trunk/reactos/ntoskrnl/config/cmboot.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmboot.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmboot.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmboot.c [iso-8859-1] Sat Apr 3 09:44:38 2010
@@ -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(a)reactos.org)
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ * Alex Ionescu (alex.ionescu(a)reactos.org)
*/
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
-
-/* GLOBALS *******************************************************************/
-
-/* FUNCTIONS *****************************************************************/
+
+/* FUNCTIONS ******************************************************************/
HCELL_INDEX
NTAPI
@@ -124,3 +123,559 @@
/* 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 */
Modified: trunk/reactos/ntoskrnl/config/cmsysini.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] Sat Apr 3 09:44:38 2010
@@ -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(a)reactos.org)
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ * Alex Ionescu (alex.ionescu(a)reactos.org)
*/
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
@@ -33,7 +34,7 @@
extern LONG CmpFlushStarveWriters;
extern BOOLEAN CmFirstTime;
-/* FUNCTIONS *****************************************************************/
+/* FUNCTIONS ******************************************************************/
VOID
NTAPI
@@ -1576,6 +1577,162 @@
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)
{
/* Enter a critical region and lock the registry */
@@ -1771,3 +1928,5 @@
if (!CmFirstTime) CmpShutdownWorkers();
CmpDoFlushAll(TRUE);
}
+
+/* EOF */
Modified: trunk/reactos/ntoskrnl/include/internal/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/cm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/cm.h [iso-8859-1] Sat Apr 3 09:44:38 2010
@@ -1520,6 +1520,40 @@
NTAPI
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
);
//
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 [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] Sat Apr 3 09:44:38 2010
@@ -200,6 +200,7 @@
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 @@
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
*
@@ -1790,6 +1823,8 @@
}
cur--;
}
+
+ IopDisplayLoadingMessage(&ServiceName);
/*
* Get service type.
Removed: 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 [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/drvrlist.c (removed)
@@ -1,561 +1,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: <UNKNOWN>
- */
-
-/* INCLUDES *******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <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;
-
-#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");
-}
Modified: trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iomgr.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] Sat Apr 3 09:44:38 2010
@@ -493,9 +493,6 @@
/* 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 @@
IopInitializeSystemDrivers();
PnpSystemInit = TRUE;
- /* Destroy the group driver list */
- IoDestroyDriverList();
-
/* Reinitialize drivers that requested it */
IopReinitializeDrivers();
Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Sat Apr 3 09:44:38 2010
@@ -244,7 +244,6 @@
<file>device.c</file>
<file>deviface.c</file>
<file>driver.c</file>
- <file>drvrlist.c</file>
<file>error.c</file>
<file>file.c</file>
<file>iocomp.c</file>