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@reactos.org) * Filip Navara (navaraf@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?re... ============================================================================== --- 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>