- Fill Level field in DEVICE_NODE structure
[reactos.git] / reactos / ntoskrnl / io / pnproot.c
index 43b0065..d4c24fd 100644 (file)
@@ -1,10 +1,9 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/pnproot.c
  * PURPOSE:         PnP manager root device
- * 
+ *
  * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
  */
 
@@ -34,6 +33,8 @@ typedef struct _PNPROOT_DEVICE
   UNICODE_STRING InstanceID;
   // Device description
   UNICODE_STRING DeviceDescription;
+  // Resource requirement list
+  PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
 } PNPROOT_DEVICE, *PPNPROOT_DEVICE;
 
 typedef enum
@@ -70,6 +71,8 @@ typedef struct _PNPROOT_PDO_DEVICE_EXTENSION
   UNICODE_STRING DeviceID;
   // Instance ID
   UNICODE_STRING InstanceID;
+  // Resource requirement list
+  PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
 } PNPROOT_PDO_DEVICE_EXTENSION, *PPNPROOT_PDO_DEVICE_EXTENSION;
 
 
@@ -119,7 +122,7 @@ PnpRootCreateDevice(
 
   DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension;
 
-  Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE));
+  Device = (PPNPROOT_DEVICE)ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
   if (!Device)
     return STATUS_INSUFFICIENT_RESOURCES;
 
@@ -155,23 +158,21 @@ PnpRootCreateDevice(
 
   PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
 
-  if (!IopCreateUnicodeString(
+  if (!RtlCreateUnicodeString(
     &PdoDeviceExtension->DeviceID,
     ENUM_NAME_ROOT \
-    L"\\LEGACY_UNKNOWN",
-    PagedPool))
+    L"\\LEGACY_UNKNOWN"))
   {
     /* FIXME: */
-    DPRINT("IopCreateUnicodeString() failed\n");
+    DPRINT("RtlCreateUnicodeString() failed\n");
   }
 
-  if (!IopCreateUnicodeString(
+  if (!RtlCreateUnicodeString(
     &PdoDeviceExtension->InstanceID,
-    L"0000",
-    PagedPool))
+    L"0000"))
   {
     /* FIXME: */
-    DPRINT("IopCreateUnicodeString() failed\n");
+    DPRINT("RtlCreateUnicodeString() failed\n");
   }
 
   ExInterlockedInsertTailList(
@@ -209,12 +210,11 @@ PdoQueryId(
 
   switch (IrpSp->Parameters.QueryId.IdType) {
     case BusQueryDeviceID:
-      Status = IopCreateUnicodeString(
-        &String,
-        DeviceExtension->DeviceID.Buffer,
-        PagedPool);
+      Status = RtlDuplicateUnicodeString(TRUE,
+                                         &DeviceExtension->DeviceID,
+                                         &String);
 
-      DPRINT("DeviceID: %S\n", String.Buffer);
+      DPRINT("DeviceID: %wZ\n", &String);
 
       Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
       break;
@@ -225,10 +225,9 @@ PdoQueryId(
       break;
 
     case BusQueryInstanceID:
-      Status = IopCreateUnicodeString(
-        &String,
-        DeviceExtension->InstanceID.Buffer,
-        PagedPool);
+      Status = RtlDuplicateUnicodeString(TRUE,
+                                         &DeviceExtension->InstanceID,
+                                         &String);
 
       DPRINT("InstanceID: %S\n", String.Buffer);
 
@@ -271,17 +270,63 @@ PdoQueryResourceRequirements(
   IN PIRP Irp,
   PIO_STACK_LOCATION IrpSp)
 {
+  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
   PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
   ULONG ResourceListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List);
 
-  ResourceList = ExAllocatePool(PagedPool, ResourceListSize);
-  if (ResourceList == NULL)
-    return STATUS_INSUFFICIENT_RESOURCES;
+  DPRINT("Called\n");
 
-  RtlZeroMemory(ResourceList, ResourceListSize);
-  ResourceList->ListSize = ResourceListSize;
+  DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+  
+  if (DeviceExtension->ResourceRequirementsList == NULL)
+  {
+    /* Create an empty resource list */
+    ResourceList = ExAllocatePool(PagedPool, ResourceListSize);
+    if (ResourceList == NULL)
+      return STATUS_INSUFFICIENT_RESOURCES;
 
-  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+    RtlZeroMemory(ResourceList, ResourceListSize);
+    ResourceList->ListSize = ResourceListSize;
+
+    Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+  }
+  else
+  {
+    /* Copy existing resource requirement list */
+    ResourceList = ExAllocatePool(PagedPool, DeviceExtension->ResourceRequirementsList->ListSize);
+    if (ResourceList == NULL)
+      return STATUS_INSUFFICIENT_RESOURCES;
+
+    RtlCopyMemory(
+      ResourceList,
+      DeviceExtension->ResourceRequirementsList,
+      DeviceExtension->ResourceRequirementsList->ListSize);
+    Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+  }
+
+  return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+PnpRootPdoQueryCapabilities(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp,
+  PIO_STACK_LOCATION IrpSp)
+{
+  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
+  PDEVICE_CAPABILITIES DeviceCapabilities;
+
+  DPRINT("Called\n");
+
+  DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+  DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
+
+  if (DeviceCapabilities->Version != 1)
+    return STATUS_UNSUCCESSFUL;
+
+  DeviceCapabilities->UniqueID = TRUE;
+  /* FIXME: Fill other fields */
 
   return STATUS_SUCCESS;
 }
@@ -304,7 +349,7 @@ PnpRootPdoPnpControl(
   NTSTATUS Status;
 
   DPRINT("Called\n");
-               
+
   Status = Irp->IoStatus.Status;
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
@@ -331,6 +376,10 @@ PnpRootPdoPnpControl(
     Status = PdoQueryResources(DeviceObject, Irp, IrpSp);
     break;
 
+  case IRP_MN_QUERY_CAPABILITIES:
+    Status = PnpRootPdoQueryCapabilities(DeviceObject, Irp, IrpSp);
+    break;
+
   case IRP_MN_START_DEVICE:
   case IRP_MN_QUERY_STOP_DEVICE:
   case IRP_MN_CANCEL_STOP_DEVICE:
@@ -396,6 +445,96 @@ PnpRootPdoPowerControl(
 
 /* Functional Device Object routines */
 
+static NTSTATUS
+PnpRootReadRegistryBinary(
+  IN PWSTR KeyName,
+  IN PWSTR ValueKeyName,
+  OUT PVOID* Buffer)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  UNICODE_STRING KeyNameU;
+  UNICODE_STRING ValueKeyNameU;
+  KEY_VALUE_PARTIAL_INFORMATION Size;
+  PKEY_VALUE_PARTIAL_INFORMATION Data = NULL;
+  ULONG DataSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION);
+  HANDLE KeyHandle;
+  NTSTATUS Status;
+  
+  DPRINT("Called\n");
+  
+  RtlInitUnicodeString(&KeyNameU, KeyName);
+  RtlInitUnicodeString(&ValueKeyNameU, ValueKeyName);
+  
+  InitializeObjectAttributes(
+    &ObjectAttributes,
+    &KeyNameU,
+    OBJ_CASE_INSENSITIVE,
+    NULL, /* Root dir */
+    NULL); /* Security descriptor */
+  Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
+  if (!NT_SUCCESS(Status))
+  {
+    DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status);
+    return Status;
+  }
+  
+  Status = ZwQueryValueKey(
+    KeyHandle,
+    &ValueKeyNameU,
+    KeyValuePartialInformation,
+    &Size, DataSize,
+    &DataSize);
+  if (Status != STATUS_BUFFER_OVERFLOW)
+  {
+    DPRINT("ZwQueryValueKey() failed (Status 0x%08lx)\n", Status);
+    ZwClose(KeyHandle);
+    return Status;
+  }
+  
+  while (Status == STATUS_BUFFER_OVERFLOW)
+  {
+    if (Data)
+      ExFreePoolWithTag(Data, TAG_PNP_ROOT);
+    Data = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, DataSize, TAG_PNP_ROOT);
+    if (!Data)
+    {
+      DPRINT("ExAllocatePoolWithTag() failed\n", Status);
+      ZwClose(KeyHandle);
+      return Status;
+    }
+    
+    Status = ZwQueryValueKey(
+      KeyHandle,
+      &ValueKeyNameU,
+      KeyValuePartialInformation,
+      Data, DataSize,
+      &DataSize);
+    if (NT_SUCCESS(Status))
+    {
+      *Buffer = ExAllocatePoolWithTag(PagedPool, Data->DataLength, TAG_PNP_ROOT);
+      if (!*Buffer)
+      {
+        DPRINT("ExAllocatePoolWithTag() failed\n", Status);
+        ExFreePoolWithTag(Data, TAG_PNP_ROOT);
+        ZwClose(KeyHandle);
+        return Status;
+      }
+      
+      RtlCopyMemory(
+        *Buffer,
+        Data->Data,
+        Data->DataLength);
+      break;
+    }
+  }
+  
+  if (Data)
+    ExFreePoolWithTag(Data, TAG_PNP_ROOT);
+  ZwClose(KeyHandle);
+  
+  return Status;
+}
+
 NTSTATUS
 PnpRootFdoReadDeviceInfo(
   PPNPROOT_DEVICE Device)
@@ -420,6 +559,7 @@ PnpRootFdoReadDeviceInfo(
 
   DPRINT("KeyName %S\n", KeyName);
 
+  /* 1. Read informations in instance key */
   RtlZeroMemory(QueryTable, sizeof(QueryTable));
 
   RtlInitUnicodeString(DeviceDesc, NULL);
@@ -429,13 +569,13 @@ PnpRootFdoReadDeviceInfo(
   QueryTable[0].EntryContext = DeviceDesc;
 
   Status = RtlQueryRegistryValues(
-    RTL_REGISTRY_ABSOLUTE,
+    RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
     KeyName,
     QueryTable,
     NULL,
     NULL);
 
-  DPRINT("RtlQueryRegistryValues() returned status %x\n", Status);
+  DPRINT("RtlQueryRegistryValues() returned status 0x%08lx\n", Status);
 
   if (!NT_SUCCESS(Status))
   {
@@ -444,6 +584,22 @@ PnpRootFdoReadDeviceInfo(
 
   DPRINT("Got device description: %S\n", DeviceDesc->Buffer);
 
+  /* 2. Read informations in instance key, LogConf subkey */
+  RtlZeroMemory(QueryTable, sizeof(QueryTable));
+  wcscat(KeyName, L"\\LogConf");
+  
+  Status = PnpRootReadRegistryBinary(
+    KeyName,
+    L"BasicConfigVector",
+    (PVOID*)&Device->ResourceRequirementsList);
+
+  DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status);
+
+  if (!NT_SUCCESS(Status))
+  {
+    /* FIXME: */
+  }
+
   return STATUS_SUCCESS;
 }
 
@@ -453,32 +609,34 @@ PnpRootFdoEnumerateDevices(
   PDEVICE_OBJECT DeviceObject)
 {
   PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  PKEY_BASIC_INFORMATION KeyInfo;
-  UNICODE_STRING KeyName;
+  OBJECT_ATTRIBUTES ObjectAttributes, SubKeyAttributes;
+  PKEY_BASIC_INFORMATION KeyInfo, SubKeyInfo;
+  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" ENUM_NAME_ROOT);
+  UNICODE_STRING SubKeyName;
   PPNPROOT_DEVICE Device;
   WCHAR Buffer[MAX_PATH];
-  HANDLE KeyHandle;
+  HANDLE KeyHandle, SubKeyHandle;
   ULONG BufferSize;
   ULONG ResultSize;
   NTSTATUS Status;
-  ULONG Index;
+  ULONG Index1, Index2;
 
   DPRINT("Called\n");
 
   DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
   BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH+1) * sizeof(WCHAR);
-  KeyInfo = ExAllocatePool(PagedPool, BufferSize);
+  KeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT);
   if (!KeyInfo)
   {
     return STATUS_INSUFFICIENT_RESOURCES;
   }
-
-  RtlRosInitUnicodeStringFromLiteral(
-    &KeyName,
-    L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" \
-    ENUM_NAME_ROOT);
+  SubKeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT);
+  if (!SubKeyInfo)
+  {
+    ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
+    return STATUS_INSUFFICIENT_RESOURCES;
+  }
 
   InitializeObjectAttributes(
     &ObjectAttributes,
@@ -487,95 +645,140 @@ PnpRootFdoEnumerateDevices(
                NULL,
                NULL);
 
-  Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
+  Status = ZwOpenKey(&KeyHandle, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes);
   if (!NT_SUCCESS(Status))
   {
-    DPRINT("ZwOpenKey() failed (Status %x)\n", Status);
-    ExFreePool(KeyInfo);
+    DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status);
+    ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
+    ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
     return Status;
   }
 
   /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
-            there are more entries in the list than found in the registry as some 
+            there are more entries in the list than found in the registry as some
             drivers are passed on the command line */
 //  DeviceExtension->DeviceListCount = 0;
 
-  Index = 0;
-  do {
+  /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
+   * KeyHandle. We'll first do a first enumeration to have first level keys,
+   * and an inner one to have the real devices list.
+   */
+  Index1 = 0;
+  
+  while (TRUE)
+  {
     Status = ZwEnumerateKey(
       KeyHandle,
-      Index,
+      Index1,
       KeyBasicInformation,
       KeyInfo,
       BufferSize,
       &ResultSize);
     if (!NT_SUCCESS(Status))
     {
-      DPRINT("ZwEnumerateKey() (Status %x)\n", Status);
+      DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status);
       break;
     }
 
     /* Terminate the string */
     KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
-
-    Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE));
-    if (!Device)
+    
+    /* Open the key */
+    RtlInitUnicodeString(&SubKeyName, KeyInfo->Name);
+    InitializeObjectAttributes(
+      &SubKeyAttributes,
+      &SubKeyName,
+      0, /* Attributes */
+      KeyHandle,
+      NULL); /* Security descriptor */
+    Status = ZwOpenKey(&SubKeyHandle, KEY_ENUMERATE_SUB_KEYS, &SubKeyAttributes);
+    if (!NT_SUCCESS(Status))
     {
-      /* FIXME: */
+      DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status);
       break;
     }
-
-    RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));
-
-    if (!IopCreateUnicodeString(&Device->ServiceName, KeyInfo->Name, PagedPool))
+    
+    /* Enumerate the sub-keys */
+    Index2 = 0;
+    while (TRUE)
     {
-      /* FIXME: */
-      DPRINT("IopCreateUnicodeString() failed\n");
-    }
+      Status = ZwEnumerateKey(
+        SubKeyHandle,
+        Index2,
+        KeyBasicInformation,
+        SubKeyInfo,
+        BufferSize,
+        &ResultSize);
+      if (!NT_SUCCESS(Status))
+      {
+        DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status);
+        break;
+      }
+      
+      /* Terminate the string */
+      SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0;
+      
+      Device = (PPNPROOT_DEVICE)ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
+      if (!Device)
+      {
+        /* FIXME: */
+        DPRINT("ExAllocatePoolWithTag() failed\n");
+        break;
+      }
 
-    wcscpy(Buffer, ENUM_NAME_ROOT);
-    wcscat(Buffer, L"\\");
-    wcscat(Buffer, KeyInfo->Name);
+      RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));
 
-    if (!IopCreateUnicodeString(&Device->DeviceID, Buffer, PagedPool))
-    {
-      /* FIXME: */
-      DPRINT("IopCreateUnicodeString() failed\n");
-    }
+      if (!RtlCreateUnicodeString(&Device->ServiceName, KeyInfo->Name))
+      {
+        /* FIXME: */
+        DPRINT("RtlCreateUnicodeString() failed\n");
+      }
 
-    DPRINT("Got entry: %S\n", Device->DeviceID.Buffer);
+      wcscpy(Buffer, ENUM_NAME_ROOT);
+      wcscat(Buffer, L"\\");
+      wcscat(Buffer, KeyInfo->Name);
 
-    if (!IopCreateUnicodeString(
-      &Device->InstanceID,
-      L"0000",
-      PagedPool))
-    {
-      /* FIXME: */
-      DPRINT("IopCreateUnicodeString() failed\n");
-    }
+      if (!RtlCreateUnicodeString(&Device->DeviceID, Buffer))
+      {
+        /* FIXME: */
+        DPRINT("RtlCreateUnicodeString() failed\n");
+      }
 
-    Status = PnpRootFdoReadDeviceInfo(Device);
-    if (!NT_SUCCESS(Status))
-    {
-      DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status);
-      /* FIXME: */      
-    }
+      DPRINT("Got entry: %S\n", Device->DeviceID.Buffer);
 
-    ExInterlockedInsertTailList(
-      &DeviceExtension->DeviceListHead,
-      &Device->ListEntry,
-      &DeviceExtension->DeviceListLock);
+      if (!RtlCreateUnicodeString(
+        &Device->InstanceID,
+        SubKeyInfo->Name))
+      {
+        /* FIXME: */
+        DPRINT("RtlCreateUnicodeString() failed\n");
+      }
 
-    DeviceExtension->DeviceListCount++;
+      Status = PnpRootFdoReadDeviceInfo(Device);
+      if (!NT_SUCCESS(Status))
+      {
+        /* FIXME */
+        DPRINT("PnpRootFdoReadDeviceInfo() failed with status 0x%08lx\n", Status);
+      }
 
-    Index++;
-  } while (TRUE);
+      ExInterlockedInsertTailList(
+        &DeviceExtension->DeviceListHead,
+        &Device->ListEntry,
+        &DeviceExtension->DeviceListLock);
 
-  DPRINT("Entries found: %d\n", Index);
+      DeviceExtension->DeviceListCount++;
+      
+      Index2++;
+    }
+    
+    ZwClose(SubKeyHandle);
+    Index1++;
+  }
 
   ZwClose(KeyHandle);
 
-  ExFreePool(KeyInfo);
+  ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
+  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
 
   return STATUS_SUCCESS;
 }
@@ -590,7 +793,6 @@ PnpRootQueryBusRelations(
   PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
   PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
   PDEVICE_RELATIONS Relations;
-  PLIST_ENTRY CurrentEntry;
   PPNPROOT_DEVICE Device;
   NTSTATUS Status;
   ULONG Size;
@@ -606,12 +808,12 @@ PnpRootQueryBusRelations(
 
   if (Irp->IoStatus.Information)
   {
-    /* FIXME: Another bus driver has already created a DEVICE_RELATIONS 
+    /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
               structure so we must merge this structure with our own */
   }
 
   Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
-    (DeviceExtension->DeviceListCount - 1);  
+    (DeviceExtension->DeviceListCount - 1);
 
   Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
   if (!Relations)
@@ -620,11 +822,8 @@ PnpRootQueryBusRelations(
   Relations->Count = DeviceExtension->DeviceListCount;
 
   i = 0;
-  CurrentEntry = DeviceExtension->DeviceListHead.Flink;
-  while (CurrentEntry != &DeviceExtension->DeviceListHead)
+  LIST_FOR_EACH(Device,&DeviceExtension->DeviceListHead,PNPROOT_DEVICE, ListEntry) 
   {
-    Device = CONTAINING_RECORD(CurrentEntry, PNPROOT_DEVICE, ListEntry);
-
     if (!Device->Pdo)
     {
       /* Create a physical device object for the
@@ -644,7 +843,7 @@ PnpRootQueryBusRelations(
         return Status;
       }
 
-      DPRINT("Created PDO %x\n", Device->Pdo);
+      DPRINT("Created PDO 0x%p\n", Device->Pdo);
 
       Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
 
@@ -662,31 +861,53 @@ PnpRootQueryBusRelations(
 
       PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
 
-      if (!IopCreateUnicodeString(
+      if (!RtlCreateUnicodeString(
         &PdoDeviceExtension->DeviceID,
-        Device->DeviceID.Buffer,
-        PagedPool))
+        Device->DeviceID.Buffer))
       {
         DPRINT("Insufficient resources\n");
         /* FIXME: */
       }
 
-      DPRINT1("DeviceID: %wZ  PDO %p\n",
+      DPRINT("DeviceID: %wZ  PDO %p\n",
         &PdoDeviceExtension->DeviceID,
         Device->Pdo);
 
-      if (!IopCreateUnicodeString(
+      if (!RtlCreateUnicodeString(
         &PdoDeviceExtension->InstanceID,
-        Device->InstanceID.Buffer,
-        PagedPool))
+        Device->InstanceID.Buffer))
       {
         DPRINT("Insufficient resources\n");
         /* FIXME: */
       }
 
-      DPRINT1("InstanceID: %wZ  PDO %p\n",
+      DPRINT("InstanceID: %wZ  PDO %p\n",
         &PdoDeviceExtension->InstanceID,
         Device->Pdo);
+
+      if (Device->ResourceRequirementsList != NULL)
+      {
+        PdoDeviceExtension->ResourceRequirementsList = ExAllocatePoolWithTag(
+          PagedPool,
+          Device->ResourceRequirementsList->ListSize,
+          TAG_PNP_ROOT);
+        if (PdoDeviceExtension->ResourceRequirementsList)
+        {
+          RtlCopyMemory(
+            PdoDeviceExtension->ResourceRequirementsList,
+            Device->ResourceRequirementsList,
+            Device->ResourceRequirementsList->ListSize);
+        }
+        else
+        {
+          /* FIXME */
+          DPRINT("ExAllocatePoolWithTag() failed\n");
+        }
+      }
+
+      DPRINT("ResourceRequirementsList: %p  PDO %p\n",
+        PdoDeviceExtension->ResourceRequirementsList,
+        Device->Pdo);
     }
 
     /* Reference the physical device object. The PnP manager
@@ -696,8 +917,6 @@ PnpRootQueryBusRelations(
     Relations->Objects[i] = Device->Pdo;
 
     i++;
-
-    CurrentEntry = CurrentEntry->Flink;
   }
 
   if (NT_SUCCESS(Status))
@@ -852,7 +1071,7 @@ PnpRootPnpControl(
 
   DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-  DPRINT("DeviceObject %x  DeviceExtension %x  IsFDO %d\n",
+  DPRINT("DeviceObject 0x%p  DeviceExtension 0x%p  IsFDO %d\n",
     DeviceObject,
     DeviceExtension,
     DeviceExtension->IsFDO);
@@ -932,12 +1151,12 @@ PnpRootAddDevice(
     PhysicalDeviceObject);
 
   if (!PnpRootDeviceObject) {
-    CPRINT("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject);
+    CPRINT("PnpRootDeviceObject 0x%p\n", PnpRootDeviceObject);
     KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
   }
 
   if (!PhysicalDeviceObject) {
-    CPRINT("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject);
+    CPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
     KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
   }