[ros-diffs] [cgutman] 55328: [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 i...

cgutman at svn.reactos.org cgutman at svn.reactos.org
Mon Jan 30 16:23:44 UTC 2012


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/hivesys_i386.inf?rev=55328&r1=55327&r2=55328&view=diff
==============================================================================
--- 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/acpi/halpnpdd.c?rev=55328&r1=55327&r2=55328&view=diff
==============================================================================
--- 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/pnpmgr/pnpmgr.c?rev=55328&r1=55327&r2=55328&view=diff
==============================================================================
--- 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)
    {




More information about the Ros-diffs mailing list