Author: cgutman
Date: Mon Jan 30 16:23:44 2012
New Revision: 55328
URL:
http://svn.reactos.org/svn/reactos?rev=55328&view=rev
Log:
[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
Modified:
branches/usb-bringup-trunk/boot/bootdata/hivesys_i386.inf
branches/usb-bringup-trunk/hal/halx86/acpi/halpnpdd.c
branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: branches/usb-bringup-trunk/boot/bootdata/hivesys_i386.inf
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/boot/bootdata…
==============================================================================
--- branches/usb-bringup-trunk/boot/bootdata/hivesys_i386.inf [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/boot/bootdata/hivesys_i386.inf [iso-8859-1] Mon Jan 30
16:23:44 2012
@@ -7,6 +7,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"
@@ -1413,10 +1451,61 @@
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
Modified: branches/usb-bringup-trunk/hal/halx86/acpi/halpnpdd.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/hal/halx86/ac…
==============================================================================
--- branches/usb-bringup-trunk/hal/halx86/acpi/halpnpdd.c [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/hal/halx86/acpi/halpnpdd.c [iso-8859-1] Mon Jan 30 16:23:44
2012
@@ -57,10 +57,61 @@
IN ULONG Count)
{
PFDO_EXTENSION FdoExtension = Context;
+
+ /* Invalidate device relations since we added a new device */
+ IoInvalidateDeviceRelations(FdoExtension->PhysicalDeviceObject, BusRelations);
+}
+
+NTSTATUS
+NTAPI
+HalpAddDevice(IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT TargetDevice)
+{
+ NTSTATUS Status;
+ PFDO_EXTENSION FdoExtension;
PPDO_EXTENSION PdoExtension;
+ PDEVICE_OBJECT DeviceObject, AttachedDevice;
PDEVICE_OBJECT PdoDeviceObject;
- NTSTATUS Status;
PDESCRIPTION_HEADER Wdrt;
+
+ DPRINT("HAL: PnP Driver ADD!\n");
+
+ /* Create the FDO */
+ Status = IoCreateDevice(DriverObject,
+ sizeof(FDO_EXTENSION),
+ NULL,
+ FILE_DEVICE_BUS_EXTENDER,
+ 0,
+ FALSE,
+ &DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Should not happen */
+ DbgBreakPoint();
+ return Status;
+ }
+
+ /* Setup the FDO extension */
+ FdoExtension = DeviceObject->DeviceExtension;
+ FdoExtension->ExtensionType = FdoExtensionType;
+ FdoExtension->PhysicalDeviceObject = TargetDevice;
+ FdoExtension->FunctionalDeviceObject = DeviceObject;
+ FdoExtension->ChildPdoList = NULL;
+
+ /* FDO is done initializing */
+ DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ /* Attach to the physical device object (the bus) */
+ AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject, TargetDevice);
+ if (!AttachedDevice)
+ {
+ /* Failed, undo everything */
+ IoDeleteDevice(DeviceObject);
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+ /* Save the attachment */
+ FdoExtension->AttachedDeviceObject = AttachedDevice;
/* Create the PDO */
Status = IoCreateDevice(DriverObject,
@@ -74,7 +125,7 @@
{
/* Fail */
DPRINT1("HAL: Could not create ACPI device object status=0x%08x\n",
Status);
- return;
+ return Status;
}
/* Setup the PDO device extension */
@@ -87,7 +138,7 @@
/* Add the PDO to the head of the list */
PdoExtension->Next = FdoExtension->ChildPdoList;
FdoExtension->ChildPdoList = PdoExtension;
-
+
/* Initialization is finished */
PdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
@@ -99,61 +150,10 @@
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);
-}
-
-NTSTATUS
-NTAPI
-HalpAddDevice(IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT TargetDevice)
-{
- NTSTATUS Status;
- PFDO_EXTENSION FdoExtension;
- PDEVICE_OBJECT DeviceObject, AttachedDevice;
- DPRINT("HAL: PnP Driver ADD!\n");
-
- /* Create the FDO */
- Status = IoCreateDevice(DriverObject,
- sizeof(FDO_EXTENSION),
- NULL,
- FILE_DEVICE_BUS_EXTENDER,
- 0,
- FALSE,
- &DeviceObject);
- if (!NT_SUCCESS(Status))
- {
- /* Should not happen */
- DbgBreakPoint();
- return Status;
- }
-
- /* Setup the FDO extension */
- FdoExtension = DeviceObject->DeviceExtension;
- FdoExtension->ExtensionType = FdoExtensionType;
- FdoExtension->PhysicalDeviceObject = TargetDevice;
- FdoExtension->FunctionalDeviceObject = DeviceObject;
- FdoExtension->ChildPdoList = NULL;
-
- /* FDO is done initializing */
- DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
- /* Attach to the physical device object (the bus) */
- AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject, TargetDevice);
- if (!AttachedDevice)
- {
- /* Failed, undo everything */
- IoDeleteDevice(DeviceObject);
- return STATUS_NO_SUCH_DEVICE;
- }
-
- /* Save the attachment */
- FdoExtension->AttachedDeviceObject = AttachedDevice;
-
/* Register for reinitialization to report devices later */
- IoRegisterDriverReinitialization(DriverObject,
- HalpReportDetectedDevices,
- FdoExtension);
+ IoRegisterBootDriverReinitialization(DriverObject,
+ HalpReportDetectedDevices,
+ FdoExtension);
/* Return status */
DPRINT("Device added %lx\n", Status);
Modified: branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/ntoskrnl/io/p…
==============================================================================
--- branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Mon Jan 30
16:23:44 2012
@@ -55,6 +55,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
@@ -1869,6 +2233,8 @@
&DeviceNode->InstancePath);
}
+ DeviceNode->Flags &= ~DNF_NEED_TO_ENUM;
+
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
@@ -2052,6 +2418,9 @@
{
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);
@@ -2184,7 +2553,25 @@
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)
{