[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / io / pnpmgr / pnproot.c
index 717c0d9..7a62ed2 100644 (file)
@@ -1,18 +1,17 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/pnproot.c
+ * PROJECT:         ReactOS Kernel
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnproot.c
  * PURPOSE:         PnP manager root device
- *
  * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
- *                  Copyright 2007 Hervé Poussineau (hpoussin@reactos.org)
+ *                  Copyright 2007 Herv? Poussineau (hpoussin@reactos.org)
  */
 
 /* INCLUDES ******************************************************************/
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
 
 /* GLOBALS *******************************************************************/
 
@@ -34,7 +33,6 @@ typedef struct _PNPROOT_DEVICE
     UNICODE_STRING DeviceDescription;
     // Resource requirement list
     PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
-    ULONG ResourceRequirementsListSize;
     // Associated resource list
     PCM_RESOURCE_LIST ResourceList;
     ULONG ResourceListSize;
@@ -83,7 +81,7 @@ typedef struct _PNPROOT_FDO_DEVICE_EXTENSION
 
 typedef struct _BUFFER
 {
-    PVOID *Buffer;
+    PVOID *Data;
     PULONG Length;
 } BUFFER, *PBUFFER;
 
@@ -100,20 +98,31 @@ LocateChildDevice(
 {
     PPNPROOT_DEVICE Device;
     UNICODE_STRING DeviceIdU, InstanceIdU;
+    PLIST_ENTRY NextEntry;
 
+    /* Initialize the strings to compare  */
     RtlInitUnicodeString(&DeviceIdU, DeviceId);
     RtlInitUnicodeString(&InstanceIdU, InstanceId);
 
-    LIST_FOR_EACH(Device, &DeviceExtension->DeviceListHead, PNPROOT_DEVICE, ListEntry)
+    /* Start looping */
+    for (NextEntry = DeviceExtension->DeviceListHead.Flink;
+         NextEntry != &DeviceExtension->DeviceListHead;
+         NextEntry = NextEntry->Flink)
     {
-        if (RtlEqualUnicodeString(&DeviceIdU, &Device->DeviceID, TRUE)
-         && RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
+        /* Get the entry */
+        Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
+
+        /* See if the strings match */
+        if (RtlEqualUnicodeString(&DeviceIdU, &Device->DeviceID, TRUE) &&
+            RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
         {
+            /* They do, so set the pointer and return success */
             *ChildDevice = Device;
             return STATUS_SUCCESS;
         }
     }
 
+    /* No device found */
     return STATUS_NO_SUCH_DEVICE;
 }
 
@@ -121,43 +130,28 @@ LocateChildDevice(
 NTSTATUS
 PnpRootCreateDevice(
     IN PUNICODE_STRING ServiceName,
-    IN PDEVICE_OBJECT *PhysicalDeviceObject)
+    OUT PDEVICE_OBJECT *PhysicalDeviceObject,
+    OUT OPTIONAL PUNICODE_STRING FullInstancePath)
 {
     PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
-    UNICODE_STRING UnknownServiceName = RTL_CONSTANT_STRING(L"UNKNOWN");
-    PUNICODE_STRING LocalServiceName;
     PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
     WCHAR DevicePath[MAX_PATH + 1];
     WCHAR InstancePath[5];
     PPNPROOT_DEVICE Device = NULL;
     NTSTATUS Status;
-    ULONG i;
+    UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\");
+    ULONG NextInstance;
+    UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM);
+    HANDLE EnumHandle, DeviceKeyHandle = INVALID_HANDLE_VALUE;
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    OBJECT_ATTRIBUTES ObjectAttributes;
 
     DeviceExtension = PnpRootDeviceObject->DeviceExtension;
     KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
 
-    if (ServiceName)
-        LocalServiceName = ServiceName;
-    else
-        LocalServiceName = &UnknownServiceName;
+    DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
 
-    DPRINT("Creating a PnP root device for service '%wZ'\n", LocalServiceName);
-
-    /* Search for a free instance ID */
-    _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\LEGACY_%wZ", REGSTR_KEY_ROOTENUM, LocalServiceName);
-    for (i = 0; i < 9999; i++)
-    {
-        _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", i);
-        Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
-        if (Status == STATUS_NO_SUCH_DEVICE)
-            break;
-    }
-    if (i > 9999)
-    {
-        DPRINT1("Too much legacy devices reported for service '%wZ'\n", &LocalServiceName);
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto cleanup;
-    }
+    _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, ServiceName);
 
     /* Initialize a PNPROOT_DEVICE structure */
     Device = ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
@@ -173,12 +167,96 @@ PnpRootCreateDevice(
         Status = STATUS_NO_MEMORY;
         goto cleanup;
     }
+
+    Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ);
+    if (NT_SUCCESS(Status))
+    {
+        InitializeObjectAttributes(&ObjectAttributes, &Device->DeviceID, OBJ_CASE_INSENSITIVE, EnumHandle, NULL);
+        Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, 0, NULL);
+        ZwClose(EnumHandle);
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open registry key\n");
+        goto cleanup;
+    }
+
+tryagain:
+    RtlZeroMemory(QueryTable, sizeof(QueryTable));
+    QueryTable[0].Name = L"NextInstance";
+    QueryTable[0].EntryContext = &NextInstance;
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+                                    (PWSTR)DeviceKeyHandle,
+                                    QueryTable,
+                                    NULL,
+                                    NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
+        {
+             _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
+             Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
+             if (Status == STATUS_NO_SUCH_DEVICE)
+                 break;
+        }
+
+        if (NextInstance > 9999)
+        {
+            DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto cleanup;
+        }
+    }
+
+    _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
+    Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
+    if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
+    {
+        DPRINT1("NextInstance value is corrupt! (%d)\n", NextInstance);
+        RtlDeleteRegistryValue(RTL_REGISTRY_HANDLE,
+                               (PWSTR)DeviceKeyHandle,
+                               L"NextInstance");
+        goto tryagain;
+    }
+
+    NextInstance++;
+    Status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE,
+                                   (PWSTR)DeviceKeyHandle,
+                                   L"NextInstance",
+                                   REG_DWORD,
+                                   &NextInstance,
+                                   sizeof(NextInstance));
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status);
+        goto cleanup;
+    }
+
     if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
     {
         Status = STATUS_NO_MEMORY;
         goto cleanup;
     }
 
+    if (FullInstancePath)
+    {
+        FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length;
+        FullInstancePath->Length = 0;
+        FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength);
+        if (!FullInstancePath->Buffer)
+        {
+            Status = STATUS_NO_MEMORY;
+            goto cleanup;
+        }
+
+        RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID);
+        RtlAppendUnicodeStringToString(FullInstancePath, &PathSep);
+        RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID);
+    }
+
     /* Initialize a device object */
     Status = IoCreateDevice(
         PnpRootDeviceObject->DriverObject,
@@ -223,51 +301,11 @@ cleanup:
         RtlFreeUnicodeString(&Device->InstanceID);
         ExFreePoolWithTag(Device, TAG_PNP_ROOT);
     }
+    if (DeviceKeyHandle != INVALID_HANDLE_VALUE)
+        ZwClose(DeviceKeyHandle);
     return Status;
 }
 
-static NTSTATUS STDCALL
-ForwardIrpAndWaitCompletion(
-       IN PDEVICE_OBJECT DeviceObject,
-       IN PIRP Irp,
-       IN PVOID Context)
-{
-       if (Irp->PendingReturned)
-               KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
-       return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-static NTSTATUS
-ForwardIrpAndWait(
-       IN PDEVICE_OBJECT DeviceObject,
-       IN PIRP Irp)
-{
-       PDEVICE_OBJECT LowerDevice;
-       KEVENT Event;
-       NTSTATUS Status;
-
-       ASSERT(((PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO);
-       LowerDevice = ((PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Ldo;
-
-       ASSERT(LowerDevice);
-
-       KeInitializeEvent(&Event, NotificationEvent, FALSE);
-       IoCopyCurrentIrpStackLocationToNext(Irp);
-
-       DPRINT("Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
-       IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
-
-       Status = IoCallDriver(LowerDevice, Irp);
-       if (Status == STATUS_PENDING)
-       {
-               Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
-               if (NT_SUCCESS(Status))
-                       Status = Irp->IoStatus.Status;
-       }
-
-       return Status;
-}
-
 static NTSTATUS NTAPI
 QueryStringCallback(
     IN PWSTR ValueName,
@@ -277,19 +315,17 @@ QueryStringCallback(
     IN PVOID Context,
     IN PVOID EntryContext)
 {
-    PUNICODE_STRING String = (PUNICODE_STRING)EntryContext;
+    PUNICODE_STRING Destination = (PUNICODE_STRING)EntryContext;
+    UNICODE_STRING Source;
 
     if (ValueType != REG_SZ || ValueLength == 0 || ValueLength % sizeof(WCHAR) != 0)
         return STATUS_SUCCESS;
 
-    String->Buffer = ExAllocatePoolWithTag(PagedPool, ValueLength, TAG_PNP_ROOT);
-    if (String->Buffer == NULL)
-        return STATUS_NO_MEMORY;
-    String->Length = String->MaximumLength = (USHORT)ValueLength;
-    RtlCopyMemory(String->Buffer, ValueData, ValueLength);
-    if (ValueLength > 0 && String->Buffer[ValueLength / sizeof(WCHAR) - 1] == L'\0')
-        String->Length -= sizeof(WCHAR);
-    return STATUS_SUCCESS;
+    Source.MaximumLength = Source.Length = ValueLength;
+    Source.Buffer = ValueData;
+    if (Source.Length > 0 && Source.Buffer[Source.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
+        Source.Length -= sizeof(WCHAR);
+    return RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, &Source, Destination);
 }
 
 static NTSTATUS NTAPI
@@ -306,7 +342,7 @@ QueryBinaryValueCallback(
 
     if (ValueLength == 0)
     {
-        *Buffer->Buffer = NULL;
+        *Buffer->Data = NULL;
         return STATUS_SUCCESS;
     }
 
@@ -314,7 +350,7 @@ QueryBinaryValueCallback(
     if (BinaryValue == NULL)
         return STATUS_NO_MEMORY;
     RtlCopyMemory(BinaryValue, ValueData, ValueLength);
-    *Buffer->Buffer = BinaryValue;
+    *Buffer->Data = BinaryValue;
     if (Buffer->Length) *Buffer->Length = ValueLength;
     return STATUS_SUCCESS;
 }
@@ -324,7 +360,6 @@ EnumerateDevices(
     IN PDEVICE_OBJECT DeviceObject)
 {
     PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
-    OBJECT_ATTRIBUTES ObjectAttributes;
     PKEY_BASIC_INFORMATION KeyInfo = NULL, SubKeyInfo = NULL;
     UNICODE_STRING LegacyU = RTL_CONSTANT_STRING(L"LEGACY_");
     UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM L"\\" REGSTR_KEY_ROOTENUM);
@@ -362,17 +397,10 @@ EnumerateDevices(
         goto cleanup;
     }
 
-    InitializeObjectAttributes(
-        &ObjectAttributes,
-        &KeyName,
-        OBJ_CASE_INSENSITIVE,
-        NULL,
-        NULL);
-
-    Status = ZwOpenKey(&KeyHandle, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes);
+    Status = IopOpenRegistryKeyEx(&KeyHandle, NULL, &KeyName, KEY_ENUMERATE_SUB_KEYS);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT("ZwOpenKey(%wZ) failed with status 0x%08lx\n", &KeyName, Status);
+        DPRINT("IopOpenRegistryKeyEx(%wZ) failed with status 0x%08lx\n", &KeyName, Status);
         goto cleanup;
     }
 
@@ -414,16 +442,10 @@ EnumerateDevices(
         }
 
         /* Open the key */
-        InitializeObjectAttributes(
-            &ObjectAttributes,
-            &SubKeyName,
-            0, /* Attributes */
-            KeyHandle,
-            NULL); /* Security descriptor */
-        Status = ZwOpenKey(&SubKeyHandle, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes);
+        Status = IopOpenRegistryKeyEx(&SubKeyHandle, KeyHandle, &SubKeyName, KEY_ENUMERATE_SUB_KEYS);
         if (!NT_SUCCESS(Status))
         {
-            DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
+            DPRINT("IopOpenRegistryKeyEx() failed with status 0x%08lx\n", Status);
             break;
         }
 
@@ -482,23 +504,17 @@ EnumerateDevices(
                 }
 
                 /* Open registry key to fill other informations */
-                InitializeObjectAttributes(
-                    &ObjectAttributes,
-                    &Device->InstanceID,
-                    0, /* Attributes */
-                    SubKeyHandle,
-                    NULL); /* Security descriptor */
-                Status = ZwOpenKey(&DeviceKeyHandle, KEY_READ, &ObjectAttributes);
+                Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, SubKeyHandle, &Device->InstanceID, KEY_READ);
                 if (!NT_SUCCESS(Status))
                 {
-                    DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
+                    DPRINT("IopOpenRegistryKeyEx() failed with status 0x%08lx\n", Status);
                     break;
                 }
 
                 /* Fill other informations */
-                Buffer1.Buffer = (PVOID *)&Device->ResourceRequirementsList;
+                Buffer1.Data = (PVOID *)&Device->ResourceRequirementsList;
                 Buffer1.Length = NULL;
-                Buffer2.Buffer = (PVOID *)&Device->ResourceList;
+                Buffer2.Data = (PVOID *)&Device->ResourceList;
                 Buffer2.Length = &Device->ResourceListSize;
                 RtlZeroMemory(QueryTable, sizeof(QueryTable));
                 QueryTable[0].QueryRoutine = QueryStringCallback;
@@ -557,8 +573,10 @@ cleanup:
         ZwClose(SubKeyHandle);
     if (KeyHandle != INVALID_HANDLE_VALUE)
         ZwClose(KeyHandle);
-    ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
-    ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
+    if (KeyInfo)
+        ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
+    if (SubKeyInfo)
+        ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
     KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
     return Status;
 }
@@ -581,6 +599,7 @@ PnpRootQueryDeviceRelations(
     PPNPROOT_DEVICE Device = NULL;
     ULONG Size;
     NTSTATUS Status;
+    PLIST_ENTRY NextEntry;
 
     DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
 
@@ -616,8 +635,15 @@ PnpRootQueryDeviceRelations(
     }
 
     KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
-    LIST_FOR_EACH(Device, &DeviceExtension->DeviceListHead, PNPROOT_DEVICE, ListEntry)
+
+    /* Start looping */
+    for (NextEntry = DeviceExtension->DeviceListHead.Flink;
+         NextEntry != &DeviceExtension->DeviceListHead;
+         NextEntry = NextEntry->Flink)
     {
+        /* Get the entry */
+        Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
+    
         if (!Device->Pdo)
         {
             /* Create a physical device object for the
@@ -702,28 +728,35 @@ PnpRootFdoPnpControl(
 
         case IRP_MN_START_DEVICE:
             DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
-            Status = ForwardIrpAndWait(DeviceObject, Irp);
-            if (NT_SUCCESS(Status))
-                DeviceExtension->State = dsStarted;
-            Status = STATUS_SUCCESS;
-            break;
+            if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp))
+                Status = STATUS_UNSUCCESSFUL;
+            else
+            {
+                Status = Irp->IoStatus.Status;
+                if (NT_SUCCESS(Status))
+                    DeviceExtension->State = dsStarted;
+            }
+
+            Irp->IoStatus.Status = Status;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
 
          case IRP_MN_STOP_DEVICE:
              DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
              /* Root device cannot be stopped */
-             Status = STATUS_NOT_SUPPORTED;
-             break;
+             Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
+             IoCompleteRequest(Irp, IO_NO_INCREMENT);
+             return Status;
 
         default:
             DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
-            Status = STATUS_NOT_IMPLEMENTED;
             break;
     }
 
     if (Status != STATUS_PENDING)
     {
-        Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
     }
 
     return Status;
@@ -736,51 +769,25 @@ PdoQueryDeviceRelations(
     IN PIO_STACK_LOCATION IrpSp)
 {
     PDEVICE_RELATIONS Relations;
-    DEVICE_RELATION_TYPE RelationType;
     NTSTATUS Status = Irp->IoStatus.Status;
 
-    RelationType = IrpSp->Parameters.QueryDeviceRelations.Type;
+    if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
+        return Status;
 
-    switch (RelationType)
+    DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
+    Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
+    if (!Relations)
     {
-        /* FIXME: remove */
-        case BusRelations:
-        {
-            if (IoGetAttachedDevice(DeviceObject) != DeviceObject)
-            {
-                /* We're not alone in the stack */
-                PDEVICE_NODE DeviceNode;
-                DeviceNode = IopGetDeviceNode(IopGetDeviceNode(DeviceObject)->PhysicalDeviceObject);
-                DPRINT1("Device stack for '%wZ' (%wZ) is misbehaving ; shouldn't receive IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n",
-                    &DeviceNode->InstancePath, &DeviceNode->ServiceName);
-            }
-            break;
-        }
-
-        case TargetDeviceRelation:
-        {
-            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
-            Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
-            if (!Relations)
-            {
-                DPRINT("ExAllocatePoolWithTag() failed\n");
-                Status = STATUS_NO_MEMORY;
-            }
-            else
-            {
-                ObReferenceObject(DeviceObject);
-                Relations->Count = 1;
-                Relations->Objects[0] = DeviceObject;
-                Status = STATUS_SUCCESS;
-                Irp->IoStatus.Information = (ULONG_PTR)Relations;
-            }
-            break;
-        }
-
-        default:
-        {
-            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / unknown relation type 0x%lx\n", RelationType);
-        }
+        DPRINT("ExAllocatePoolWithTag() failed\n");
+        Status = STATUS_NO_MEMORY;
+    }
+    else
+    {
+        ObReferenceObject(DeviceObject);
+        Relations->Count = 1;
+        Relations->Objects[0] = DeviceObject;
+        Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = (ULONG_PTR)Relations;
     }
 
     return Status;
@@ -818,35 +825,29 @@ PdoQueryResources(
 
     DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-    if (DeviceExtension->DeviceInfo->ResourceList == NULL)
-    {
-        /* Create an empty resource list */
-        ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
-        if (!ResourceList)
-            return STATUS_NO_MEMORY;
-
-        ResourceList->Count = 0;
-
-        Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
-    }
-    else
+    if (DeviceExtension->DeviceInfo->ResourceList)
     {
         /* Copy existing resource requirement list */
         ResourceList = ExAllocatePool(
             PagedPool,
-            FIELD_OFFSET(CM_RESOURCE_LIST, List) + DeviceExtension->DeviceInfo->ResourceListSize);
+            DeviceExtension->DeviceInfo->ResourceListSize);
         if (!ResourceList)
             return STATUS_NO_MEMORY;
 
-        ResourceList->Count = 1;
         RtlCopyMemory(
-            &ResourceList->List,
+            ResourceList,
             DeviceExtension->DeviceInfo->ResourceList,
             DeviceExtension->DeviceInfo->ResourceListSize);
-            Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
-    }
 
-    return STATUS_SUCCESS;
+        Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+
+        return STATUS_SUCCESS;
+    }
+    else
+    {
+        /* No resources so just return without changing the status */
+        return Irp->IoStatus.Status;
+    }
 }
 
 static NTSTATUS
@@ -857,23 +858,10 @@ PdoQueryResourceRequirements(
 {
     PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
     PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
-    ULONG ResourceListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List);
 
     DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-    if (DeviceExtension->DeviceInfo->ResourceRequirementsList == NULL)
-    {
-        /* Create an empty resource list */
-        ResourceList = ExAllocatePool(PagedPool, ResourceListSize);
-        if (!ResourceList)
-            return STATUS_NO_MEMORY;
-
-        RtlZeroMemory(ResourceList, ResourceListSize);
-        ResourceList->ListSize = ResourceListSize;
-
-        Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
-    }
-    else
+    if (DeviceExtension->DeviceInfo->ResourceRequirementsList)
     {
         /* Copy existing resource requirement list */
         ResourceList = ExAllocatePool(PagedPool, DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
@@ -884,10 +872,16 @@ PdoQueryResourceRequirements(
             ResourceList,
             DeviceExtension->DeviceInfo->ResourceRequirementsList,
             DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
-            Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
-    }
 
-    return STATUS_SUCCESS;
+        Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+
+        return STATUS_SUCCESS;
+    }
+    else
+    {
+        /* No resource requirements so just return without changing the status */
+        return Irp->IoStatus.Status;
+    }
 }
 
 static NTSTATUS
@@ -1126,7 +1120,7 @@ PnpRootPnpControl(
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 PnpRootAddDevice(
     IN PDRIVER_OBJECT DriverObject,
     IN PDEVICE_OBJECT PhysicalDeviceObject)
@@ -1140,7 +1134,7 @@ PnpRootAddDevice(
     {
         DPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
         Status = STATUS_INSUFFICIENT_RESOURCES;
-        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
     }
 
     Status = IoCreateDevice(
@@ -1154,7 +1148,7 @@ PnpRootAddDevice(
     if (!NT_SUCCESS(Status))
     {
         DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
-        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
     }
     DPRINT("Created FDO %p\n", PnpRootDeviceObject);
 
@@ -1174,7 +1168,7 @@ PnpRootAddDevice(
     if (!NT_SUCCESS(Status))
     {
         DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
-        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
     }
 
     PnpRootDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
@@ -1198,5 +1192,3 @@ PnpRootDriverEntry(
 
     return STATUS_SUCCESS;
 }
-
-/* EOF */