From 3aff101683b4eec875f6b58654c863a73552f309 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 30 Jan 2012 16:23:44 +0000 Subject: [PATCH] [HALACPI] - Create PDO earlier so ACPI can be loaded earlier in boot [HIVESYS] - Create critical device database with required devices for USB boot [NTOSKRNL] - Read the CDDB and install devices that are critical for boot - This implementation won't be 100% correct until a PnP manager rewrite but it should work well enough for our needs - Not complete and disabled atm svn path=/branches/usb-bringup-trunk/; revision=55328 --- boot/bootdata/hivesys_i386.inf | 91 +++++++- hal/halx86/acpi/halpnpdd.c | 88 ++++---- ntoskrnl/io/pnpmgr/pnpmgr.c | 387 +++++++++++++++++++++++++++++++++ 3 files changed, 521 insertions(+), 45 deletions(-) diff --git a/boot/bootdata/hivesys_i386.inf b/boot/bootdata/hivesys_i386.inf index c1262865491..e82d5d3c9fb 100644 --- a/boot/bootdata/hivesys_i386.inf +++ b/boot/bootdata/hivesys_i386.inf @@ -8,6 +8,44 @@ HKLM,"SYSTEM\CurrentControlSet\Control","WaitToKillServiceTimeout",2,"20000" HKLM,"SYSTEM\CurrentControlSet\Control\Biosinfo","InfName",2,"biosinfo.inf" HKLM,"SYSTEM\CurrentControlSet\Control\PnP",,0x00000012 +; Critical Device Database + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\acpipic_up","ClassGUID",0x00000000,"{4D36E966-E325-11CE-BFC1-08002BE10318}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\*PNP0A03","Service",0x00000000,"pci" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\*PNP0A03","ClassGUID",0x00000000,"{4D36E97D-E325-11CE-BFC1-08002BE10318}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\*PNP0C08","Service",0x00000000,"acpi" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\*PNP0C08","ClassGUID",0x00000000,"{4D36E97D-E325-11CE-BFC1-08002BE10318}" + +;HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\PCI#CC_0C0300","Service",0x00000000,"usbuhci" +;HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\PCI#CC_0C0300","ClassGUID",0x00000000,"{36FC9E60-C465-11CF-8056-444553540000}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\PCI#CC_0C0310","Service",0x00000000,"usbohci" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\PCI#CC_0C0310","ClassGUID",0x00000000,"{36FC9E60-C465-11CF-8056-444553540000}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\PCI#CC_0C0320","Service",0x00000000,"usbehci" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\PCI#CC_0C0320","ClassGUID",0x00000000,"{36FC9E60-C465-11CF-8056-444553540000}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#Class_08&SubClass_06&Prot_50","Service",0x00000000,"usbstor" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#Class_08&SubClass_06&Prot_50","ClassGUID",0x00000000,"{36FC9E60-C465-11CF-8056-444553540000}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#COMPOSITE","Service",0x00000000,"usbccgp" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#COMPOSITE","ClassGUID",0x00000000,"{36FC9E60-C465-11CF-8056-444553540000}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#CLASS_09","Service",0x00000000,"usbhub" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#CLASS_09","ClassGUID",0x00000000,"{36FC9E60-C465-11CF-8056-444553540000}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#ROOT_HUB","Service",0x00000000,"usbhub" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#ROOT_HUB","ClassGUID",0x00000000,"{36FC9E60-C465-11CF-8056-444553540000}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#ROOT_HUB20","Service",0x00000000,"usbhub" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#ROOT_HUB20","ClassGUID",0x00000000,"{36FC9E60-C465-11CF-8056-444553540000}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\GenDisk","Service",0x00000000,"disk" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\GenDisk","ClassGUID",0x00000000,"{4D36E967-E325-11CE-BFC1-08002BE10318}" + + HKLM,"SYSTEM\CurrentControlSet\Control\SafeBoot","AlternateShell",2,"cmd.exe" ; Safe Boot drivers @@ -1413,10 +1451,61 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ImagePath",0x00020000,"system32 HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Start",0x00010001,0x00000004 HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Type",0x00010001,0x00000001 +; USB hub driver +HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","Group",0x00000000,"Boot Bus" +HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","ImagePath",0x00020000,"system32\drivers\usbhub.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","Start",0x00010001,0x00000000 + +; EHCI controller driver +HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","Group",0x00000000,"Boot Bus" +HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","ImagePath",0x00020000,"system32\drivers\usbehci.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","Start",0x00010001,0x00000000 + +; OHCI controller driver +HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","Group",0x00000000,"Boot Bus" +HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","ImagePath",0x00020000,"system32\drivers\usbohci.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","Start",0x00010001,0x00000000 + +; UHCI controller driver +HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","Group",0x00000000,"Boot Bus" +HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","ImagePath",0x00020000,"system32\drivers\usbuhci.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","Start",0x00010001,0x00000000 + +; USB storage driver +HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","Group",0x00000000,"Primary Disk" +HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","ImagePath",0x00020000,"system32\drivers\usbstor.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","Start",0x00010001,0x00000000 + +; USB composite generic parent +HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","Group",0x00000000,"Boot Bus" +HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","ImagePath",0x00020000,"system32\drivers\usbccgp.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","Start",0x00010001,0x00000000 + +; ACPI driver +HKLM,"SYSTEM\CurrentControlSet\Services\acpi","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\acpi","Group",0x00000000,"Boot Bus" +HKLM,"SYSTEM\CurrentControlSet\Services\acpi","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\acpi","ImagePath",0x00020000,"system32\drivers\acpi.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\acpi","Start",0x00010001,0x00000000 + ; PCI Bus driver HKLM,"SYSTEM\CurrentControlSet\Services\Pci","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Group",0x00000000,"Boot Bus " +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Group",0x00000000,"Boot Bus" HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","ImagePath",0x00020000,"system32\drivers\pci.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Pci\Parameters","1045C621",0x00030003,04,00,00,00,00,00,00,00 HKLM,"SYSTEM\CurrentControlSet\Services\Pci\Parameters","10950640",0x00030003,04,00,00,00,00,00,00,00 HKLM,"SYSTEM\CurrentControlSet\Services\Pci\Parameters","80861230",0x00030003,04,00,00,00,00,00,00,00 diff --git a/hal/halx86/acpi/halpnpdd.c b/hal/halx86/acpi/halpnpdd.c index 8ca5dd3b029..926ef20294b 100644 --- a/hal/halx86/acpi/halpnpdd.c +++ b/hal/halx86/acpi/halpnpdd.c @@ -57,47 +57,6 @@ HalpReportDetectedDevices(IN PDRIVER_OBJECT DriverObject, IN ULONG Count) { PFDO_EXTENSION FdoExtension = Context; - PPDO_EXTENSION PdoExtension; - PDEVICE_OBJECT PdoDeviceObject; - NTSTATUS Status; - PDESCRIPTION_HEADER Wdrt; - - /* Create the PDO */ - Status = IoCreateDevice(DriverObject, - sizeof(PDO_EXTENSION), - NULL, - FILE_DEVICE_BUS_EXTENDER, - FILE_AUTOGENERATED_DEVICE_NAME, - FALSE, - &PdoDeviceObject); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - DPRINT1("HAL: Could not create ACPI device object status=0x%08x\n", Status); - return; - } - - /* Setup the PDO device extension */ - PdoExtension = PdoDeviceObject->DeviceExtension; - PdoExtension->ExtensionType = PdoExtensionType; - PdoExtension->PhysicalDeviceObject = PdoDeviceObject; - PdoExtension->ParentFdoExtension = FdoExtension; - PdoExtension->PdoType = AcpiPdo; - - /* Add the PDO to the head of the list */ - PdoExtension->Next = FdoExtension->ChildPdoList; - FdoExtension->ChildPdoList = PdoExtension; - - /* Initialization is finished */ - PdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - - /* Find the ACPI watchdog table */ - Wdrt = HalAcpiGetTable(0, 'TRDW'); - if (Wdrt) - { - /* FIXME: TODO */ - DPRINT1("You have an ACPI Watchdog. That's great! You should be proud ;-)\n"); - } /* Invalidate device relations since we added a new device */ IoInvalidateDeviceRelations(FdoExtension->PhysicalDeviceObject, BusRelations); @@ -110,7 +69,11 @@ HalpAddDevice(IN PDRIVER_OBJECT DriverObject, { NTSTATUS Status; PFDO_EXTENSION FdoExtension; + PPDO_EXTENSION PdoExtension; PDEVICE_OBJECT DeviceObject, AttachedDevice; + PDEVICE_OBJECT PdoDeviceObject; + PDESCRIPTION_HEADER Wdrt; + DPRINT("HAL: PnP Driver ADD!\n"); /* Create the FDO */ @@ -150,10 +113,47 @@ HalpAddDevice(IN PDRIVER_OBJECT DriverObject, /* Save the attachment */ FdoExtension->AttachedDeviceObject = AttachedDevice; + /* Create the PDO */ + Status = IoCreateDevice(DriverObject, + sizeof(PDO_EXTENSION), + NULL, + FILE_DEVICE_BUS_EXTENDER, + FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, + &PdoDeviceObject); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + DPRINT1("HAL: Could not create ACPI device object status=0x%08x\n", Status); + return Status; + } + + /* Setup the PDO device extension */ + PdoExtension = PdoDeviceObject->DeviceExtension; + PdoExtension->ExtensionType = PdoExtensionType; + PdoExtension->PhysicalDeviceObject = PdoDeviceObject; + PdoExtension->ParentFdoExtension = FdoExtension; + PdoExtension->PdoType = AcpiPdo; + + /* Add the PDO to the head of the list */ + PdoExtension->Next = FdoExtension->ChildPdoList; + FdoExtension->ChildPdoList = PdoExtension; + + /* Initialization is finished */ + PdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + + /* Find the ACPI watchdog table */ + Wdrt = HalAcpiGetTable(0, 'TRDW'); + if (Wdrt) + { + /* FIXME: TODO */ + DPRINT1("You have an ACPI Watchdog. That's great! You should be proud ;-)\n"); + } + /* Register for reinitialization to report devices later */ - IoRegisterDriverReinitialization(DriverObject, - HalpReportDetectedDevices, - FdoExtension); + IoRegisterBootDriverReinitialization(DriverObject, + HalpReportDetectedDevices, + FdoExtension); /* Return status */ DPRINT("Device added %lx\n", Status); diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 9d20b971ff0..c92deeb6904 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -57,6 +57,370 @@ IopGetDeviceNode(PDEVICE_OBJECT DeviceObject) return ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode; } +VOID +IopFixupDeviceId(PWCHAR String) +{ + ULONG Length = wcslen(String), i; + + for (i = 0; i < Length; i++) + { + if (String[i] == L'\\') + String[i] = L'#'; + } +} + +VOID +NTAPI +IopInstallCriticalDevice(PDEVICE_NODE DeviceNode) +{ + NTSTATUS Status; + HANDLE CriticalDeviceKey, InstanceKey; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING CriticalDeviceKeyU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\CriticalDeviceDatabase"); + UNICODE_STRING CompatibleIdU = RTL_CONSTANT_STRING(L"CompatibleIDs"); + UNICODE_STRING HardwareIdU = RTL_CONSTANT_STRING(L"HardwareID"); + UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service"); + UNICODE_STRING ClassGuidU = RTL_CONSTANT_STRING(L"ClassGUID"); + PKEY_VALUE_PARTIAL_INFORMATION PartialInfo; + ULONG HidLength = 0, CidLength = 0, BufferLength; + PWCHAR IdBuffer, OriginalIdBuffer; + + /* Open the device instance key */ + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey); + if (Status != STATUS_SUCCESS) + return; + + Status = ZwQueryValueKey(InstanceKey, + &HardwareIdU, + KeyValuePartialInformation, + NULL, + 0, + &HidLength); + if (Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL) + { + ZwClose(InstanceKey); + return; + } + + Status = ZwQueryValueKey(InstanceKey, + &CompatibleIdU, + KeyValuePartialInformation, + NULL, + 0, + &CidLength); + if (Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL) + { + CidLength = 0; + } + + BufferLength = HidLength + CidLength; + BufferLength -= (((CidLength != 0) ? 2 : 1) * FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)); + + /* Allocate a buffer to hold data from both */ + OriginalIdBuffer = IdBuffer = ExAllocatePool(PagedPool, BufferLength); + if (!IdBuffer) + { + ZwClose(InstanceKey); + return; + } + + /* Compute the buffer size */ + if (HidLength > CidLength) + BufferLength = HidLength; + else + BufferLength = CidLength; + + PartialInfo = ExAllocatePool(PagedPool, BufferLength); + if (!PartialInfo) + { + ZwClose(InstanceKey); + ExFreePool(OriginalIdBuffer); + return; + } + + Status = ZwQueryValueKey(InstanceKey, + &HardwareIdU, + KeyValuePartialInformation, + PartialInfo, + HidLength, + &HidLength); + if (Status != STATUS_SUCCESS) + { + ExFreePool(PartialInfo); + ExFreePool(OriginalIdBuffer); + ZwClose(InstanceKey); + return; + } + + /* Copy in HID info first (without 2nd terminating NULL if CID is present) */ + HidLength = PartialInfo->DataLength - ((CidLength != 0) ? sizeof(WCHAR) : 0); + RtlCopyMemory(IdBuffer, PartialInfo->Data, HidLength); + + if (CidLength != 0) + { + Status = ZwQueryValueKey(InstanceKey, + &CompatibleIdU, + KeyValuePartialInformation, + PartialInfo, + CidLength, + &CidLength); + if (Status != STATUS_SUCCESS) + { + ExFreePool(PartialInfo); + ExFreePool(OriginalIdBuffer); + ZwClose(InstanceKey); + return; + } + + /* Copy CID next */ + CidLength = PartialInfo->DataLength; + RtlCopyMemory(((PUCHAR)IdBuffer) + HidLength, PartialInfo->Data, CidLength); + } + + /* Free our temp buffer */ + ExFreePool(PartialInfo); + + InitializeObjectAttributes(&ObjectAttributes, + &CriticalDeviceKeyU, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenKey(&CriticalDeviceKey, + KEY_ENUMERATE_SUB_KEYS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + /* The critical device database doesn't exist because + * we're probably in 1st stage setup, but it's ok */ + ExFreePool(OriginalIdBuffer); + ZwClose(InstanceKey); + return; + } + + while (*IdBuffer) + { + ULONG StringLength = (ULONG)wcslen(IdBuffer) + 1, Index; + + IopFixupDeviceId(IdBuffer); + + /* Look through all subkeys for a match */ + for (Index = 0; TRUE; Index++) + { + ULONG NeededLength; + PKEY_BASIC_INFORMATION BasicInfo; + + Status = ZwEnumerateKey(CriticalDeviceKey, + Index, + KeyBasicInformation, + NULL, + 0, + &NeededLength); + if (Status == STATUS_NO_MORE_ENTRIES) + break; + else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + UNICODE_STRING ChildIdNameU, RegKeyNameU; + + BasicInfo = ExAllocatePool(PagedPool, NeededLength); + if (!BasicInfo) + { + /* No memory */ + ExFreePool(OriginalIdBuffer); + ZwClose(CriticalDeviceKey); + ZwClose(InstanceKey); + return; + } + + Status = ZwEnumerateKey(CriticalDeviceKey, + Index, + KeyBasicInformation, + BasicInfo, + NeededLength, + &NeededLength); + if (Status != STATUS_SUCCESS) + { + /* This shouldn't happen */ + ExFreePool(BasicInfo); + continue; + } + + ChildIdNameU.Buffer = IdBuffer; + ChildIdNameU.MaximumLength = ChildIdNameU.Length = (StringLength - 1) * sizeof(WCHAR); + RegKeyNameU.Buffer = BasicInfo->Name; + RegKeyNameU.MaximumLength = RegKeyNameU.Length = BasicInfo->NameLength; + + if (RtlEqualUnicodeString(&ChildIdNameU, &RegKeyNameU, TRUE)) + { + HANDLE ChildKeyHandle; + + InitializeObjectAttributes(&ObjectAttributes, + &ChildIdNameU, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + CriticalDeviceKey, + NULL); + + Status = ZwOpenKey(&ChildKeyHandle, + KEY_QUERY_VALUE, + &ObjectAttributes); + if (Status != STATUS_SUCCESS) + { + ExFreePool(BasicInfo); + continue; + } + + /* Check if there's already a driver installed */ + Status = ZwQueryValueKey(InstanceKey, + &ClassGuidU, + KeyValuePartialInformation, + NULL, + 0, + &NeededLength); + if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + ExFreePool(BasicInfo); + continue; + } + + Status = ZwQueryValueKey(ChildKeyHandle, + &ClassGuidU, + KeyValuePartialInformation, + NULL, + 0, + &NeededLength); + if (Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL) + { + ExFreePool(BasicInfo); + continue; + } + + PartialInfo = ExAllocatePool(PagedPool, NeededLength); + if (!PartialInfo) + { + ExFreePool(OriginalIdBuffer); + ExFreePool(BasicInfo); + ZwClose(InstanceKey); + ZwClose(ChildKeyHandle); + ZwClose(CriticalDeviceKey); + return; + } + + /* Read ClassGUID entry in the CDDB */ + Status = ZwQueryValueKey(ChildKeyHandle, + &ClassGuidU, + KeyValuePartialInformation, + PartialInfo, + NeededLength, + &NeededLength); + if (Status != STATUS_SUCCESS) + { + ExFreePool(BasicInfo); + continue; + } + + /* Write it to the ENUM key */ + Status = ZwSetValueKey(InstanceKey, + &ClassGuidU, + 0, + REG_SZ, + PartialInfo->Data, + PartialInfo->DataLength); + if (Status != STATUS_SUCCESS) + { + ExFreePool(BasicInfo); + ExFreePool(PartialInfo); + ZwClose(ChildKeyHandle); + continue; + } + + Status = ZwQueryValueKey(ChildKeyHandle, + &ServiceU, + KeyValuePartialInformation, + NULL, + 0, + &NeededLength); + if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + ExFreePool(PartialInfo); + PartialInfo = ExAllocatePool(PagedPool, NeededLength); + if (!PartialInfo) + { + ExFreePool(OriginalIdBuffer); + ExFreePool(BasicInfo); + ZwClose(InstanceKey); + ZwClose(ChildKeyHandle); + ZwClose(CriticalDeviceKey); + return; + } + + /* Read the service entry from the CDDB */ + Status = ZwQueryValueKey(ChildKeyHandle, + &ServiceU, + KeyValuePartialInformation, + PartialInfo, + NeededLength, + &NeededLength); + if (Status != STATUS_SUCCESS) + { + ExFreePool(BasicInfo); + ExFreePool(PartialInfo); + ZwClose(ChildKeyHandle); + continue; + } + + /* Write it to the ENUM key */ + Status = ZwSetValueKey(InstanceKey, + &ServiceU, + 0, + REG_SZ, + PartialInfo->Data, + PartialInfo->DataLength); + if (Status != STATUS_SUCCESS) + { + ExFreePool(BasicInfo); + ExFreePool(PartialInfo); + ZwClose(ChildKeyHandle); + continue; + } + + DPRINT1("Installed service '%S' for critical device '%wZ'\n", PartialInfo->Data, &ChildIdNameU); + } + else + { + DPRINT1("Installed NULL service for critical device '%wZ'\n", &ChildIdNameU); + } + + /* We need to enumerate children */ + DeviceNode->Flags |= DNF_NEED_TO_ENUM; + + ExFreePool(OriginalIdBuffer); + ExFreePool(PartialInfo); + ExFreePool(BasicInfo); + ZwClose(InstanceKey); + ZwClose(ChildKeyHandle); + ZwClose(CriticalDeviceKey); + + /* That's it */ + return; + } + + ExFreePool(BasicInfo); + } + else + { + /* Umm, not sure what happened here */ + continue; + } + } + + /* Advance to the next ID */ + IdBuffer += StringLength; + } + + ExFreePool(OriginalIdBuffer); + ZwClose(InstanceKey); + ZwClose(CriticalDeviceKey); +} + NTSTATUS FASTCALL IopInitializeDevice(PDEVICE_NODE DeviceNode, @@ -1869,6 +2233,8 @@ IopEnumerateDevice( &DeviceNode->InstancePath); } + DeviceNode->Flags &= ~DNF_NEED_TO_ENUM; + DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); Stack.Parameters.QueryDeviceRelations.Type = BusRelations; @@ -2053,6 +2419,9 @@ IopActionConfigureChildServices(PDEVICE_NODE DeviceNode, WCHAR RegKeyBuffer[MAX_PATH]; UNICODE_STRING RegKey; + /* Install the service for this if it's in the CDDB */ + //IopInstallCriticalDevice(DeviceNode); + RegKey.Length = 0; RegKey.MaximumLength = sizeof(RegKeyBuffer); RegKey.Buffer = RegKeyBuffer; @@ -2184,7 +2553,25 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, if (IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED) || IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) || IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED)) + { + if (DeviceNode->Flags & DNF_NEED_TO_ENUM) + { + Status = IopInitializeDevice(DeviceNode, NULL); + if (NT_SUCCESS(Status)) + { + /* HACK */ + DeviceNode->Flags &= ~DNF_STARTED; + Status = IopStartDevice(DeviceNode); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n", + &DeviceNode->InstancePath, Status); + } + } + DeviceNode->Flags &= ~DNF_NEED_TO_ENUM; + } return STATUS_SUCCESS; + } if (DeviceNode->ServiceName.Buffer == NULL) {