https://git.reactos.org/?p=reactos.git;a=commitdiff;h=76ec8411a44bd44a0c5559fefc5e1b4dd3fed66b

commit 76ec8411a44bd44a0c5559fefc5e1b4dd3fed66b
Author:     Dmitry Borisov <di.s...@protonmail.com>
AuthorDate: Fri May 3 20:39:26 2024 +0600
Commit:     Dmitry Borisov <di.s...@protonmail.com>
CommitDate: Sat Aug 3 17:08:43 2024 +0600

    [ISAPNP] Fix parsing of complex resource data
    
    - Properly handle the case when the dependent function is placed
      after fixed resources
    - Initialize the version and revision fields of resource lists
    - Improve validation of resource data
    - Add more debug prints
    
    CORE-18562
---
 drivers/bus/isapnp/hardware.c  | 381 ++++++++-----------
 drivers/bus/isapnp/isapnp.c    | 819 ++++++++++++++++-------------------------
 drivers/bus/isapnp/isapnp.h    |  13 +-
 drivers/bus/isapnp/isapnpres.h |  97 ++---
 drivers/bus/isapnp/pdo.c       |  24 +-
 5 files changed, 530 insertions(+), 804 deletions(-)

diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index 135ab574a16..937923959a3 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -20,13 +20,6 @@
 
 #endif /* UNIT_TEST */
 
-typedef enum
-{
-    dfNotStarted,
-    dfStarted,
-    dfDone
-} DEPEDENT_FUNCTION_STATE;
-
 static
 inline
 VOID
@@ -390,24 +383,6 @@ Peek(
     }
 }
 
-static
-CODE_SEG("PAGE")
-VOID
-PeekCached(
-    _In_reads_bytes_(Length) PUCHAR ResourceData,
-    _Out_writes_bytes_all_(Length) PVOID Buffer,
-    _In_ USHORT Length)
-{
-    PUCHAR Dest = Buffer;
-
-    PAGED_CODE();
-
-    while (Length--)
-    {
-        *Dest++ = *ResourceData++;
-    }
-}
-
 static
 CODE_SEG("PAGE")
 UCHAR
@@ -454,19 +429,28 @@ ReadTags(
     _In_ PUCHAR ReadDataPort,
     _Out_writes_(ISAPNP_MAX_RESOURCEDATA) PUCHAR Buffer,
     _In_ ULONG MaxLength,
-    _Out_ PUSHORT MaxLogDev)
+    _Out_ PUSHORT MaxLogDev,
+    _Out_ PULONG MaxTagsPerDevice)
 {
+    ULONG TagCount = 0;
+
     PAGED_CODE();
 
     *MaxLogDev = 0;
+    *MaxTagsPerDevice = 0;
 
     while (TRUE)
     {
         UCHAR Tag;
         USHORT TagLen;
 
+        ++TagCount;
+
         if (MaxLength < 1)
+        {
+            DPRINT("Too small tag\n");
             return STATUS_BUFFER_OVERFLOW;
+        }
 
         Tag = PeekByte(ReadDataPort);
         if (Tag == 0)
@@ -487,7 +471,10 @@ ReadTags(
             UCHAR Temp[2];
 
             if (MaxLength < sizeof(Temp))
+            {
+                DPRINT("Too small tag\n");
                 return STATUS_BUFFER_OVERFLOW;
+            }
 
             Peek(ReadDataPort, &Temp, sizeof(Temp));
             *Buffer++ = Temp[0];
@@ -505,17 +492,28 @@ ReadTags(
         }
 
         if (TagLen > MaxLength)
+        {
+            DPRINT("Too large resource data structure\n");
             return STATUS_BUFFER_OVERFLOW;
+        }
 
         Peek(ReadDataPort, Buffer, TagLen);
         MaxLength -= TagLen;
         Buffer += TagLen;
 
         if (Tag == ISAPNP_TAG_LOGDEVID)
-            (*MaxLogDev)++;
+        {
+            /* Attempt to guess the allocation size based on the tags 
available */
+            *MaxTagsPerDevice = max(*MaxTagsPerDevice, TagCount);
+            TagCount = 0;
 
-        if (Tag == ISAPNP_TAG_END)
+            (*MaxLogDev)++;
+        }
+        else if (Tag == ISAPNP_TAG_END)
+        {
+            *MaxTagsPerDevice = max(*MaxTagsPerDevice, TagCount);
             break;
+        }
     }
 
     return STATUS_SUCCESS;
@@ -534,8 +532,8 @@ FreeLogicalDevice(
     if (LogDevice->FriendlyName)
         ExFreePoolWithTag(LogDevice->FriendlyName, TAG_ISAPNP);
 
-    if (LogDevice->Alternatives)
-        ExFreePoolWithTag(LogDevice->Alternatives, TAG_ISAPNP);
+    if (LogDevice->Resources)
+        ExFreePoolWithTag(LogDevice->Resources, TAG_ISAPNP);
 
     Entry = LogDevice->CompatibleIdList.Flink;
     while (Entry != &LogDevice->CompatibleIdList)
@@ -562,15 +560,10 @@ ParseTags(
     _Inout_ PISAPNP_LOGICAL_DEVICE LogDevice)
 {
     USHORT LogDev;
-    DEPEDENT_FUNCTION_STATE DfState = dfNotStarted;
+    ISAPNP_DEPENDENT_FUNCTION_STATE DfState = dfNotStarted;
+    PISAPNP_RESOURCE Resource = LogDevice->Resources;
     PUCHAR IdStrPos = NULL;
     USHORT IdStrLen = 0;
-    UCHAR NumberOfIo = 0,
-          NumberOfIrq = 0,
-          NumberOfDma = 0,
-          NumberOfMemRange = 0,
-          NumberOfMemRange32 = 0,
-          NumberOfDepedentSet = 0;
 
     PAGED_CODE();
 
@@ -613,7 +606,7 @@ ParseTags(
                     goto SkipTag;
                 }
 
-                PeekCached(ResourceData, &Temp, TagLen);
+                RtlCopyMemory(&Temp, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 DPRINT("Found tag 0x%X (len %u)\n"
@@ -643,7 +636,7 @@ ParseTags(
                 if (!CompatibleId)
                     return STATUS_INSUFFICIENT_RESOURCES;
 
-                PeekCached(ResourceData, &Temp, TagLen);
+                RtlCopyMemory(&Temp, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 DPRINT("Found tag 0x%X (len %u)\n"
@@ -665,30 +658,21 @@ ParseTags(
             {
                 PISAPNP_IRQ_DESCRIPTION Description;
 
-                if (LogDev != 0 ||
-                    (TagLen > sizeof(ISAPNP_IRQ_DESCRIPTION) ||
-                     TagLen < (sizeof(ISAPNP_IRQ_DESCRIPTION) - 1)) ||
-                    NumberOfIrq >= RTL_NUMBER_OF(LogDevice->Irq))
-                {
+                if (LogDev != 0)
                     goto SkipTag;
-                }
 
-                if (DfState == dfStarted)
+                if (TagLen > sizeof(ISAPNP_IRQ_DESCRIPTION) ||
+                    TagLen < (sizeof(ISAPNP_IRQ_DESCRIPTION) - 1))
                 {
-                    if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
-                        goto SkipTag;
-
-                    Description = 
&LogDevice->Alternatives->Irq[NumberOfDepedentSet];
+                    DPRINT1("Invalid tag %x\n", ISAPNP_TAG_IRQ);
+                    return STATUS_UNSUCCESSFUL;
                 }
-                else
-                {
-                    Description = &LogDevice->Irq[NumberOfIrq].Description;
 
-                    LogDevice->Irq[NumberOfIrq].Index = NumberOfIrq;
-                    ++NumberOfIrq;
-                }
+                Resource->Type = ISAPNP_RESOURCE_TYPE_IRQ;
+                Description = &Resource->IrqDescription;
+                ++Resource;
 
-                PeekCached(ResourceData, Description, TagLen);
+                RtlCopyMemory(Description, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 if (TagLen == (sizeof(ISAPNP_IRQ_DESCRIPTION) - 1))
@@ -708,28 +692,20 @@ ParseTags(
             {
                 PISAPNP_DMA_DESCRIPTION Description;
 
-                if (LogDev != 0 || TagLen != sizeof(ISAPNP_DMA_DESCRIPTION) ||
-                    NumberOfDma >= RTL_NUMBER_OF(LogDevice->Dma))
-                {
+                if (LogDev != 0)
                     goto SkipTag;
-                }
 
-                if (DfState == dfStarted)
+                if (TagLen != sizeof(ISAPNP_DMA_DESCRIPTION))
                 {
-                    if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
-                        goto SkipTag;
-
-                    Description = 
&LogDevice->Alternatives->Dma[NumberOfDepedentSet];
+                    DPRINT1("Invalid tag %x\n", ISAPNP_TAG_DMA);
+                    return STATUS_UNSUCCESSFUL;
                 }
-                else
-                {
-                    Description = &LogDevice->Dma[NumberOfDma].Description;
 
-                    LogDevice->Dma[NumberOfDma].Index = NumberOfDma;
-                    ++NumberOfDma;
-                }
+                Resource->Type = ISAPNP_RESOURCE_TYPE_DMA;
+                Description = &Resource->DmaDescription;
+                ++Resource;
 
-                PeekCached(ResourceData, Description, TagLen);
+                RtlCopyMemory(Description, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 DPRINT("Found tag 0x%X (len %u)\n"
@@ -744,48 +720,39 @@ ParseTags(
 
             case ISAPNP_TAG_STARTDEP:
             {
-                if (LogDev != 0 || TagLen > 1 ||
-                    NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
-                {
+                if (LogDev != 0)
                     goto SkipTag;
+
+                if (TagLen > 1)
+                {
+                    DPRINT1("Invalid tag %x\n", ISAPNP_TAG_STARTDEP);
+                    return STATUS_UNSUCCESSFUL;
                 }
 
                 if (DfState == dfNotStarted)
                 {
-                    LogDevice->Alternatives = ExAllocatePoolZero(PagedPool,
-                                                                 
sizeof(ISAPNP_ALTERNATIVES),
-                                                                 TAG_ISAPNP);
-                    if (!LogDevice->Alternatives)
-                        return STATUS_INSUFFICIENT_RESOURCES;
-
                     DfState = dfStarted;
                 }
-                else if (DfState == dfStarted)
-                {
-                    ++NumberOfDepedentSet;
-                }
-                else
+                else if (DfState != dfStarted)
                 {
                     goto SkipTag;
                 }
 
-                ++LogDevice->Alternatives->Count;
+                Resource->Type = ISAPNP_RESOURCE_TYPE_START_DEPENDENT;
+                ++Resource;
 
                 if (TagLen != 1)
                 {
-                    LogDevice->Alternatives->Priority[NumberOfDepedentSet] = 1;
+                    Resource->Priority = 1;
                 }
                 else
                 {
-                    PeekCached(ResourceData,
-                               
&LogDevice->Alternatives->Priority[NumberOfDepedentSet],
-                               TagLen);
+                    RtlCopyMemory(&Resource->Priority, ResourceData, TagLen);
                     ResourceData += TagLen;
                 }
 
-                DPRINT("*** Start depedent set %u, priority %u ***\n",
-                       NumberOfDepedentSet,
-                       LogDevice->Alternatives->Priority[NumberOfDepedentSet]);
+                DPRINT("*** Start dependent set, priority %u ***\n",
+                       Resource->Priority);
 
                 break;
             }
@@ -795,22 +762,14 @@ ParseTags(
                 if (LogDev != 0 || DfState != dfStarted)
                     goto SkipTag;
 
+                Resource->Type = ISAPNP_RESOURCE_TYPE_END_DEPENDENT;
+                ++Resource;
+
                 DfState = dfDone;
 
                 ResourceData += TagLen;
 
-                if (HasIoAlternatives(LogDevice->Alternatives))
-                    LogDevice->Alternatives->IoIndex = NumberOfIo++;
-                if (HasIrqAlternatives(LogDevice->Alternatives))
-                    LogDevice->Alternatives->IrqIndex = NumberOfIrq++;
-                if (HasDmaAlternatives(LogDevice->Alternatives))
-                    LogDevice->Alternatives->DmaIndex = NumberOfDma++;
-                if (HasMemoryAlternatives(LogDevice->Alternatives))
-                    LogDevice->Alternatives->MemRangeIndex = 
NumberOfMemRange++;
-                if (HasMemory32Alternatives(LogDevice->Alternatives))
-                    LogDevice->Alternatives->MemRange32Index = 
NumberOfMemRange32++;
-
-                DPRINT("*** End of depedent set ***\n");
+                DPRINT("*** End of dependent set ***\n");
 
                 break;
             }
@@ -819,28 +778,20 @@ ParseTags(
             {
                 PISAPNP_IO_DESCRIPTION Description;
 
-                if (LogDev != 0 || TagLen != sizeof(ISAPNP_IO_DESCRIPTION) ||
-                    NumberOfIo >= RTL_NUMBER_OF(LogDevice->Io))
-                {
+                if (LogDev != 0)
                     goto SkipTag;
-                }
 
-                if (DfState == dfStarted)
+                if (TagLen != sizeof(ISAPNP_IO_DESCRIPTION))
                 {
-                    if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
-                        goto SkipTag;
-
-                    Description = 
&LogDevice->Alternatives->Io[NumberOfDepedentSet];
+                    DPRINT1("Invalid tag %x\n", ISAPNP_TAG_IOPORT);
+                    return STATUS_UNSUCCESSFUL;
                 }
-                else
-                {
-                    Description = &LogDevice->Io[NumberOfIo].Description;
 
-                    LogDevice->Io[NumberOfIo].Index = NumberOfIo;
-                    ++NumberOfIo;
-                }
+                Resource->Type = ISAPNP_RESOURCE_TYPE_IO;
+                Description = &Resource->IoDescription;
+                ++Resource;
 
-                PeekCached(ResourceData, Description, TagLen);
+                RtlCopyMemory(Description, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 DPRINT("Found tag 0x%X (len %u)\n"
@@ -864,28 +815,20 @@ ParseTags(
                 ISAPNP_FIXED_IO_DESCRIPTION Temp;
                 PISAPNP_IO_DESCRIPTION Description;
 
-                if (LogDev != 0 || TagLen != 
sizeof(ISAPNP_FIXED_IO_DESCRIPTION) ||
-                    NumberOfIo >= RTL_NUMBER_OF(LogDevice->Io))
-                {
+                if (LogDev != 0)
                     goto SkipTag;
-                }
 
-                if (DfState == dfStarted)
+                if (TagLen != sizeof(ISAPNP_FIXED_IO_DESCRIPTION))
                 {
-                    if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
-                        goto SkipTag;
-
-                    Description = 
&LogDevice->Alternatives->Io[NumberOfDepedentSet];
+                    DPRINT1("Invalid tag %x\n", ISAPNP_TAG_FIXEDIO);
+                    return STATUS_UNSUCCESSFUL;
                 }
-                else
-                {
-                    Description = &LogDevice->Io[NumberOfIo].Description;
 
-                    LogDevice->Io[NumberOfIo].Index = NumberOfIo;
-                    ++NumberOfIo;
-                }
+                Resource->Type = ISAPNP_RESOURCE_TYPE_IO;
+                Description = &Resource->IoDescription;
+                ++Resource;
 
-                PeekCached(ResourceData, &Temp, TagLen);
+                RtlCopyMemory(&Temp, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 /* Save the address bits [0:9] */
@@ -919,7 +862,7 @@ ParseTags(
                     if (!LogDevice->FriendlyName)
                         return STATUS_INSUFFICIENT_RESOURCES;
 
-                    PeekCached(IdStrPos, LogDevice->FriendlyName, IdStrLen);
+                    RtlCopyMemory(LogDevice->FriendlyName, IdStrPos, IdStrLen);
 
                     End = LogDevice->FriendlyName + IdStrLen - 1;
                     while (End > LogDevice->FriendlyName && *End == ' ')
@@ -929,6 +872,8 @@ ParseTags(
                     *++End = ANSI_NULL;
                 }
 
+                Resource->Type = ISAPNP_RESOURCE_TYPE_END;
+
                 return STATUS_SUCCESS;
             }
 
@@ -936,28 +881,23 @@ ParseTags(
             {
                 PISAPNP_MEMRANGE_DESCRIPTION Description;
 
-                if (LogDev != 0 || TagLen != 
sizeof(ISAPNP_MEMRANGE_DESCRIPTION) ||
-                    NumberOfMemRange >= RTL_NUMBER_OF(LogDevice->MemRange))
-                {
+                if (LogDev != 0)
                     goto SkipTag;
-                }
 
-                if (DfState == dfStarted)
+                if (TagLen != sizeof(ISAPNP_MEMRANGE_DESCRIPTION))
                 {
-                    if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
-                        goto SkipTag;
-
-                    Description = 
&LogDevice->Alternatives->MemRange[NumberOfDepedentSet];
+                    DPRINT1("Invalid tag %x\n", ISAPNP_TAG_MEMRANGE);
+                    return STATUS_UNSUCCESSFUL;
                 }
-                else
-                {
-                    Description = 
&LogDevice->MemRange[NumberOfMemRange].Description;
 
-                    LogDevice->MemRange[NumberOfMemRange].Index = 
NumberOfMemRange;
-                    ++NumberOfMemRange;
-                }
+                LogDevice->Flags |= ISAPNP_HAS_MEM24_DECODER;
+                ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM32_DECODER));
 
-                PeekCached(ResourceData, Description, TagLen);
+                Resource->Type = ISAPNP_RESOURCE_TYPE_MEMRANGE;
+                Description = &Resource->MemRangeDescription;
+                ++Resource;
+
+                RtlCopyMemory(Description, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 DPRINT("Found tag 0x%X (len %u)\n"
@@ -1004,28 +944,23 @@ ParseTags(
             {
                 PISAPNP_MEMRANGE32_DESCRIPTION Description;
 
-                if (LogDev != 0 || TagLen != 
sizeof(ISAPNP_MEMRANGE32_DESCRIPTION) ||
-                    NumberOfMemRange32 >= RTL_NUMBER_OF(LogDevice->MemRange32))
-                {
+                if (LogDev != 0)
                     goto SkipTag;
-                }
 
-                if (DfState == dfStarted)
+                if (TagLen != sizeof(ISAPNP_MEMRANGE32_DESCRIPTION))
                 {
-                    if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
-                        goto SkipTag;
-
-                    Description = 
&LogDevice->Alternatives->MemRange32[NumberOfDepedentSet];
+                    DPRINT1("Invalid tag %x\n", ISAPNP_TAG_MEM32RANGE);
+                    return STATUS_UNSUCCESSFUL;
                 }
-                else
-                {
-                    Description = 
&LogDevice->MemRange32[NumberOfMemRange32].Description;
 
-                    LogDevice->MemRange32[NumberOfMemRange32].Index = 
NumberOfMemRange32;
-                    ++NumberOfMemRange32;
-                }
+                LogDevice->Flags |= ISAPNP_HAS_MEM32_DECODER;
+                ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM24_DECODER));
+
+                Resource->Type = ISAPNP_RESOURCE_TYPE_MEMRANGE32;
+                Description = &Resource->MemRange32Description;
+                ++Resource;
 
-                PeekCached(ResourceData, Description, TagLen);
+                RtlCopyMemory(Description, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 DPRINT("Found tag 0x%X (len %u)\n"
@@ -1049,28 +984,23 @@ ParseTags(
                 ISAPNP_FIXEDMEMRANGE_DESCRIPTION Temp;
                 PISAPNP_MEMRANGE32_DESCRIPTION Description;
 
-                if (LogDev != 0 || TagLen != 
sizeof(ISAPNP_FIXEDMEMRANGE_DESCRIPTION) ||
-                    NumberOfMemRange32 >= RTL_NUMBER_OF(LogDevice->MemRange32))
-                {
+                if (LogDev != 0)
                     goto SkipTag;
-                }
 
-                if (DfState == dfStarted)
+                if (TagLen != sizeof(ISAPNP_FIXEDMEMRANGE_DESCRIPTION))
                 {
-                    if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
-                        goto SkipTag;
-
-                    Description = 
&LogDevice->Alternatives->MemRange32[NumberOfDepedentSet];
+                    DPRINT1("Invalid tag %x\n", ISAPNP_TAG_FIXEDMEM32RANGE);
+                    return STATUS_UNSUCCESSFUL;
                 }
-                else
-                {
-                    Description = 
&LogDevice->MemRange32[NumberOfMemRange32].Description;
 
-                    LogDevice->MemRange32[NumberOfMemRange32].Index = 
NumberOfMemRange32;
-                    ++NumberOfMemRange32;
-                }
+                LogDevice->Flags |= ISAPNP_HAS_MEM32_DECODER;
+                ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM24_DECODER));
+
+                Resource->Type = ISAPNP_RESOURCE_TYPE_MEMRANGE32;
+                Description = &Resource->MemRange32Description;
+                ++Resource;
 
-                PeekCached(ResourceData, &Temp, TagLen);
+                RtlCopyMemory(&Temp, ResourceData, TagLen);
                 ResourceData += TagLen;
 
                 Description->Information = Temp.Information;
@@ -1121,7 +1051,7 @@ ReadCurrentResources(
 
     WriteLogicalDeviceNumber(LogDevice->LDN);
 
-    /* If the device is not activated by BIOS we just report a NULL resource 
list */
+    /* If the device is not activated by BIOS then the device has no boot 
resources */
     if (!(ReadByte(ReadDataPort, ISAPNP_ACTIVATE) & 1))
     {
         LogDevice->Flags &= ~ISAPNP_HAS_RESOURCES;
@@ -1217,7 +1147,6 @@ WriteResources(
     for (i = 0; i < PartialResourceList->Count; i++)
     {
         PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor = 
&PartialResourceList->PartialDescriptors[i];
-        UCHAR Index;
 
         switch (Descriptor->Type)
         {
@@ -1229,10 +1158,9 @@ WriteResources(
                                        Descriptor->u.Port.Start.LowPart +
                                        Descriptor->u.Port.Length - 1,
                                        NULL,
-                                       NULL,
-                                       &Index);
+                                       NULL);
 
-                WriteWord(ISAPNP_IOBASE(Index), 
(USHORT)Descriptor->u.Port.Start.LowPart);
+                WriteWord(ISAPNP_IOBASE(NumberOfIo), 
(USHORT)Descriptor->u.Port.Start.LowPart);
 
                 ++NumberOfIo;
                 break;
@@ -1240,10 +1168,10 @@ WriteResources(
 
             case CmResourceTypeInterrupt:
             {
-                (VOID)FindIrqDescriptor(LogDevice, 
Descriptor->u.Interrupt.Level, &Index);
+                (VOID)FindIrqDescriptor(LogDevice, 
Descriptor->u.Interrupt.Level);
 
-                WriteByte(ISAPNP_IRQNO(Index), 
(UCHAR)Descriptor->u.Interrupt.Level);
-                WriteByte(ISAPNP_IRQTYPE(Index),
+                WriteByte(ISAPNP_IRQNO(NumberOfIrq), 
(UCHAR)Descriptor->u.Interrupt.Level);
+                WriteByte(ISAPNP_IRQTYPE(NumberOfIrq),
                           Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED
                           ? IRQTYPE_HIGH_EDGE : IRQTYPE_LOW_LEVEL);
 
@@ -1253,9 +1181,9 @@ WriteResources(
 
             case CmResourceTypeDma:
             {
-                (VOID)FindDmaDescriptor(LogDevice, Descriptor->u.Dma.Channel, 
&Index);
+                (VOID)FindDmaDescriptor(LogDevice, Descriptor->u.Dma.Channel);
 
-                WriteByte(ISAPNP_DMACHANNEL(Index), 
(UCHAR)Descriptor->u.Dma.Channel);
+                WriteByte(ISAPNP_DMACHANNEL(NumberOfDma), 
(UCHAR)Descriptor->u.Dma.Channel);
 
                 ++NumberOfDma;
                 break;
@@ -1263,7 +1191,6 @@ WriteResources(
 
             case CmResourceTypeMemory:
             {
-                BOOLEAN Memory32;
                 UCHAR Information;
                 UCHAR MemoryControl = MEMORY_USE_8_BIT_DECODER;
 
@@ -1271,30 +1198,28 @@ WriteResources(
                                            Descriptor->u.Memory.Start.LowPart,
                                            Descriptor->u.Memory.Start.LowPart +
                                            Descriptor->u.Memory.Length - 1,
-                                           &Memory32,
-                                           &Information,
-                                           &Index);
+                                           &Information);
 
-                if (!Memory32)
+                if (LogicalDevice->Flags & ISAPNP_HAS_MEM24_DECODER)
                 {
                     if (Information & MEMRANGE_16_BIT_MEMORY_MASK)
                         MemoryControl = MEMORY_USE_16_BIT_DECODER;
 
-                    WriteWord(ISAPNP_MEMBASE(Index),
+                    WriteWord(ISAPNP_MEMBASE(NumberOfMemory),
                               (USHORT)(Descriptor->u.Memory.Start.LowPart >> 
8));
 
-                    if (ReadMemoryControl(ReadDataPort, Index) & 
MEMORY_UPPER_LIMIT)
+                    if (ReadMemoryControl(ReadDataPort, NumberOfMemory) & 
MEMORY_UPPER_LIMIT)
                     {
-                        WriteByte(ISAPNP_MEMCONTROL(Index),
+                        WriteByte(ISAPNP_MEMCONTROL(NumberOfMemory),
                                   MemoryControl | MEMORY_UPPER_LIMIT);
-                        WriteWord(ISAPNP_MEMLIMIT(Index),
+                        WriteWord(ISAPNP_MEMLIMIT(NumberOfMemory),
                                   (USHORT)((Descriptor->u.Memory.Start.LowPart 
+
                                             Descriptor->u.Memory.Length) >> 
8));
                     }
                     else
                     {
-                        WriteByte(ISAPNP_MEMCONTROL(Index), MemoryControl);
-                        WriteWord(ISAPNP_MEMLIMIT(Index),
+                        WriteByte(ISAPNP_MEMCONTROL(NumberOfMemory), 
MemoryControl);
+                        WriteWord(ISAPNP_MEMLIMIT(NumberOfMemory),
                                   (USHORT)(LENGTH_TO_RANGE_LENGTH(Descriptor->
                                                                   
u.Memory.Length) >> 8));
                     }
@@ -1303,7 +1228,7 @@ WriteResources(
                 }
                 else
                 {
-                    WriteDoubleWord(ISAPNP_MEMBASE32(Index),
+                    WriteDoubleWord(ISAPNP_MEMBASE32(NumberOfMemory32),
                                     Descriptor->u.Memory.Start.LowPart);
 
                     if ((Information & MEMRANGE_16_BIT_MEMORY_MASK) == 
MEMRANGE_32_BIT_MEMORY_ONLY)
@@ -1311,18 +1236,18 @@ WriteResources(
                     else if (Information & MEMRANGE_16_BIT_MEMORY_MASK)
                         MemoryControl = MEMORY_USE_16_BIT_DECODER;
 
-                    if (ReadMemoryControl32(ReadDataPort, Index) & 
MEMORY_UPPER_LIMIT)
+                    if (ReadMemoryControl32(ReadDataPort, NumberOfMemory32) & 
MEMORY_UPPER_LIMIT)
                     {
-                        WriteByte(ISAPNP_MEMCONTROL32(Index),
+                        WriteByte(ISAPNP_MEMCONTROL32(NumberOfMemory32),
                                   MemoryControl | MEMORY_UPPER_LIMIT);
-                        WriteDoubleWord(ISAPNP_MEMLIMIT32(Index),
+                        WriteDoubleWord(ISAPNP_MEMLIMIT32(NumberOfMemory32),
                                         Descriptor->u.Memory.Start.LowPart +
                                         Descriptor->u.Memory.Length);
                     }
                     else
                     {
-                        WriteByte(ISAPNP_MEMCONTROL32(Index), MemoryControl);
-                        WriteDoubleWord(ISAPNP_MEMLIMIT32(Index),
+                        WriteByte(ISAPNP_MEMCONTROL32(NumberOfMemory32), 
MemoryControl);
+                        WriteDoubleWord(ISAPNP_MEMLIMIT32(NumberOfMemory32),
                                         
LENGTH_TO_RANGE_LENGTH(Descriptor->u.Memory.Length));
                     }
 
@@ -1501,6 +1426,7 @@ IsaHwFillDeviceList(
         NTSTATUS Status;
         UCHAR TempId[3], LogDev;
         ISAPNP_IDENTIFIER Identifier;
+        ULONG MaxTagsPerDevice;
         USHORT MaxLogDev;
 
         Wake(Csn);
@@ -1510,7 +1436,11 @@ IsaHwFillDeviceList(
         IsaPnpExtractAscii(TempId, Identifier.VendorId);
         Identifier.ProdId = RtlUshortByteSwap(Identifier.ProdId);
 
-        Status = ReadTags(FdoExt->ReadDataPort, ResourceData, 
ISAPNP_MAX_RESOURCEDATA, &MaxLogDev);
+        Status = ReadTags(FdoExt->ReadDataPort,
+                          ResourceData,
+                          ISAPNP_MAX_RESOURCEDATA,
+                          &MaxLogDev,
+                          &MaxTagsPerDevice);
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to read tags with status 0x%08lx, CSN %u\n", 
Status, Csn);
@@ -1572,6 +1502,16 @@ IsaHwFillDeviceList(
             LogDevice->CSN = Csn;
             LogDevice->LDN = LogDev;
 
+            LogDevice->Resources = ExAllocatePoolWithTag(PagedPool,
+                                                         MaxTagsPerDevice * 
sizeof(ISAPNP_RESOURCE),
+                                                         TAG_ISAPNP);
+            if (!LogDevice->Resources)
+            {
+                DPRINT1("Failed to allocate the resources array\n");
+                FreeLogicalDevice(LogDevice);
+                goto Deactivate;
+            }
+
             Status = ParseTags(ResourceData, LogDev, LogDevice);
             if (!NT_SUCCESS(Status))
             {
@@ -1644,7 +1584,6 @@ IsaHwConfigureDevice(
                                       Descriptor->u.Port.Start.LowPart +
                                       Descriptor->u.Port.Length - 1,
                                       NULL,
-                                      NULL,
                                       NULL))
                 {
                     return STATUS_RESOURCE_DATA_NOT_FOUND;
@@ -1658,7 +1597,7 @@ IsaHwConfigureDevice(
                 if (++NumberOfIrq > RTL_NUMBER_OF(LogicalDevice->Irq))
                     return STATUS_INVALID_PARAMETER_2;
 
-                if (!FindIrqDescriptor(LogicalDevice, 
Descriptor->u.Interrupt.Level, NULL))
+                if (!FindIrqDescriptor(LogicalDevice, 
Descriptor->u.Interrupt.Level))
                     return STATUS_RESOURCE_DATA_NOT_FOUND;
 
                 break;
@@ -1669,7 +1608,7 @@ IsaHwConfigureDevice(
                 if (++NumberOfDma > RTL_NUMBER_OF(LogicalDevice->Dma))
                     return STATUS_INVALID_PARAMETER_3;
 
-                if (!FindDmaDescriptor(LogicalDevice, 
Descriptor->u.Dma.Channel, NULL))
+                if (!FindDmaDescriptor(LogicalDevice, 
Descriptor->u.Dma.Channel))
                     return STATUS_RESOURCE_DATA_NOT_FOUND;
 
                 break;
@@ -1686,14 +1625,12 @@ IsaHwConfigureDevice(
                                           Descriptor->u.Memory.Start.LowPart,
                                           Descriptor->u.Memory.Start.LowPart +
                                           Descriptor->u.Memory.Length - 1,
-                                          &Memory32,
-                                          NULL,
                                           NULL))
                 {
                     return STATUS_RESOURCE_DATA_NOT_FOUND;
                 }
 
-                if (!Memory32 && (Descriptor->u.Memory.Start.LowPart & 0xFF))
+                if ((LogicalDevice->Flags & ISAPNP_HAS_MEM24_DECODER) && 
(Descriptor->u.Memory.Start.LowPart & 0xFF))
                     return STATUS_INVALID_PARAMETER;
 
                 break;
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index 7126166b092..bf5b6cde8c8 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -10,12 +10,8 @@
 /* INCLUDES 
*******************************************************************/
 
 #ifndef UNIT_TEST
-#include "isapnp.h"
-#endif /* UNIT_TEST */
 
-#include <search.h>
-
-#ifndef UNIT_TEST
+#include "isapnp.h"
 
 #define NDEBUG
 #include <debug.h>
@@ -32,46 +28,8 @@ LIST_ENTRY BusListHead;
 
 #endif /* UNIT_TEST */
 
-static PUCHAR Priority;
-
 /* FUNCTIONS 
******************************************************************/
 
-static
-CODE_SEG("PAGE")
-int
-__cdecl
-IsaComparePriority(
-    const void *A,
-    const void *B)
-{
-    PAGED_CODE();
-
-    return Priority[*(PUCHAR)A] - Priority[*(PUCHAR)B];
-}
-
-static
-CODE_SEG("PAGE")
-VOID
-IsaDetermineBestConfig(
-    _Out_writes_all_(ISAPNP_MAX_ALTERNATIVES) PUCHAR BestConfig,
-    _In_ PISAPNP_ALTERNATIVES Alternatives)
-{
-    UCHAR i;
-
-    PAGED_CODE();
-
-    for (i = 0; i < ISAPNP_MAX_ALTERNATIVES; i++)
-    {
-        BestConfig[i] = i;
-    }
-
-    Priority = Alternatives->Priority;
-    qsort(BestConfig,
-          Alternatives->Count,
-          sizeof(*BestConfig),
-          IsaComparePriority);
-}
-
 static
 CODE_SEG("PAGE")
 VOID
@@ -194,323 +152,298 @@ IsaConvertMemRange32Requirement(
                                                   Description->Length - 1;
 }
 
+/*
+ * For example, the PnP ROM
+ * 0x15, 0x04, ...                                 // Logical device ID
+ * 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x04, 0x04, // IO 330, len 4, align 4
+ * 0x30,                                           // **** Start DF ****
+ * 0x22, 0x04, 0x00,                               // IRQ 2
+ * 0x31, 0x02,                                     // **** Start DF ****
+ * 0x22, 0xC0, 0x00,                               // IRQ 6 or 7
+ * 0x38,                                           // **** End DF ******
+ * 0x2A, 0x20, 0x3A,                               // DMA 5
+ * 0x22, 0x00, 0x08,                               // IRQ 12
+ * 0x79, 0x00,                                     // END
+ *
+ * becomes the following resource requirements list:
+ * Interface 1 Bus 0 Slot 0 AlternativeLists 2
+ *
+ * AltList #0, AltList->Count 4
+ * [Option 0, ShareDisposition 1, Flags 11] IO: Min 0:330, Max 0:333, Align 4 
Len 4
+ * [Option 0, ShareDisposition 1, Flags 1]  INT: Min 2 Max 2
+ * [Option 0, ShareDisposition 0, Flags 0]  DMA: Min 5 Max 5
+ * [Option 0, ShareDisposition 1, Flags 1]  INT: Min B Max B
+ *
+ * AltList #1, AltList->Count 5
+ * [Option 0, ShareDisposition 1, Flags 11] IO: Min 0:330, Max 0:333, Align 4 
Len 4
+ * [Option 0, ShareDisposition 1, Flags 1]  INT: Min 6 Max 6
+ * [Option 8, ShareDisposition 1, Flags 1]  INT: Min 7 Max 7
+ * [Option 0, ShareDisposition 0, Flags 0]  DMA: Min 5 Max 5
+ * [Option 0, ShareDisposition 1, Flags 1]  INT: Min B Max B
+ */
 static
 CODE_SEG("PAGE")
 NTSTATUS
 IsaPnpCreateLogicalDeviceRequirements(
     _In_ PISAPNP_PDO_EXTENSION PdoExt)
 {
-    PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
-    RTL_BITMAP TempBitmap;
-    ULONG TempBuffer;
-    ULONG ResourceCount = 0, AltCount = 0, AltOptionalCount = 0;
-    ULONG ListSize, i, j;
-    BOOLEAN FirstDescriptor;
     PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
     PIO_RESOURCE_DESCRIPTOR Descriptor;
-    PISAPNP_ALTERNATIVES Alternatives = LogDev->Alternatives;
+    ISAPNP_DEPENDENT_FUNCTION_STATE DfState;
+    ULONG FirstFixedDescriptors, LastFixedDescriptors;
+    ULONG ResourceCount, AltListCount, ListSize, i;
+    BOOLEAN IsFirstAltList, IsFirstDescriptor;
+    PIO_RESOURCE_LIST AltList;
+    PISAPNP_RESOURCE Resource;
 
     PAGED_CODE();
 
-    /* Count number of requirements */
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->Io); i++)
+    /* Count the number of requirements */
+    DfState = dfNotStarted;
+    FirstFixedDescriptors = 0;
+    LastFixedDescriptors = 0;
+    ResourceCount = 0;
+    AltListCount = 1;
+    Resource = PdoExt->IsaPnpDevice->Resources;
+    while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
     {
-        /*
-         * Use the continue statement to count the number of requirements.
-         * We handle a possible gap because depedent function can appear at
-         * any position in the logical device's requirements list.
-         */
-        if (!LogDev->Io[i].Description.Length)
-            continue;
+        switch (Resource->Type)
+        {
+            case ISAPNP_RESOURCE_TYPE_START_DEPENDENT:
+            {
+                if (DfState == dfStarted)
+                    ++AltListCount;
 
-        ResourceCount++;
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->Irq); i++)
-    {
-        if (!LogDev->Irq[i].Description.Mask)
-            continue;
-
-        TempBuffer = LogDev->Irq[i].Description.Mask;
-        RtlInitializeBitMap(&TempBitmap,
-                            &TempBuffer,
-                            RTL_BITS_OF(LogDev->Irq[i].Description.Mask));
-        ResourceCount += RtlNumberOfSetBits(&TempBitmap);
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
-    {
-        if (!LogDev->Dma[i].Description.Mask)
-            continue;
-
-        TempBuffer = LogDev->Dma[i].Description.Mask;
-        RtlInitializeBitMap(&TempBitmap,
-                            &TempBuffer,
-                            RTL_BITS_OF(LogDev->Dma[i].Description.Mask));
-        ResourceCount += RtlNumberOfSetBits(&TempBitmap);
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange); i++)
-    {
-        if (!LogDev->MemRange[i].Description.Length)
-            continue;
+                DfState = dfStarted;
+                break;
+            }
 
-        ResourceCount++;
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++)
-    {
-        if (!LogDev->MemRange32[i].Description.Length)
-            continue;
+            case ISAPNP_RESOURCE_TYPE_END_DEPENDENT:
+            {
+                DfState = dfDone;
+                break;
+            }
 
-        ResourceCount++;
-    }
-    if (Alternatives)
-    {
-        ULONG BitCount;
-
-        if (HasIoAlternatives(Alternatives))
-            AltCount++;
-        if (HasIrqAlternatives(Alternatives))
-            AltCount++;
-        if (HasDmaAlternatives(Alternatives))
-            AltCount++;
-        if (HasMemoryAlternatives(Alternatives))
-            AltCount++;
-        if (HasMemory32Alternatives(Alternatives))
-            AltCount++;
-        ResourceCount += AltCount;
-
-        if (HasIrqAlternatives(Alternatives))
-        {
-            for (i = 0; i < Alternatives->Count; i++)
+            case ISAPNP_RESOURCE_TYPE_IRQ:
+            case ISAPNP_RESOURCE_TYPE_DMA:
             {
-                TempBuffer = Alternatives->Irq[i].Mask;
-                RtlInitializeBitMap(&TempBitmap,
-                                    &TempBuffer,
-                                    RTL_BITS_OF(Alternatives->Irq[i].Mask));
-                BitCount = RtlNumberOfSetBits(&TempBitmap);
-
-                if (BitCount > 1)
-                    AltOptionalCount += BitCount - 1;
+                RTL_BITMAP ResourceBitmap;
+                ULONG BitmapSize, BitmapBuffer, BitCount;
+
+                if (Resource->Type == ISAPNP_RESOURCE_TYPE_IRQ)
+                {
+                    BitmapSize = RTL_BITS_OF(Resource->IrqDescription.Mask);
+                    BitmapBuffer = Resource->IrqDescription.Mask;
+                }
+                else
+                {
+                    BitmapSize = RTL_BITS_OF(Resource->DmaDescription.Mask);
+                    BitmapBuffer = Resource->DmaDescription.Mask;
+                }
+                RtlInitializeBitMap(&ResourceBitmap, &BitmapBuffer, 
BitmapSize);
+
+                BitCount = RtlNumberOfSetBits(&ResourceBitmap);
+                switch (DfState)
+                {
+                    case dfNotStarted:
+                        FirstFixedDescriptors += BitCount;
+                        break;
+
+                    case dfStarted:
+                        ResourceCount += BitCount;
+                        break;
+
+                    case dfDone:
+                        LastFixedDescriptors += BitCount;
+                        break;
+
+                    DEFAULT_UNREACHABLE;
+                }
+
+                break;
             }
-        }
-        if (HasDmaAlternatives(Alternatives))
-        {
-            for (i = 0; i < Alternatives->Count; i++)
+
+            case ISAPNP_RESOURCE_TYPE_IO:
+            case ISAPNP_RESOURCE_TYPE_MEMRANGE:
+            case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
             {
-                TempBuffer = Alternatives->Dma[i].Mask;
-                RtlInitializeBitMap(&TempBitmap,
-                                    &TempBuffer,
-                                    RTL_BITS_OF(Alternatives->Dma[i].Mask));
-                BitCount = RtlNumberOfSetBits(&TempBitmap);
-
-                if (BitCount > 1)
-                    AltOptionalCount += BitCount - 1;
+                switch (DfState)
+                {
+                    case dfNotStarted:
+                        ++FirstFixedDescriptors;
+                        break;
+
+                    case dfStarted:
+                        ++ResourceCount;
+                        break;
+
+                    case dfDone:
+                        ++LastFixedDescriptors;
+                        break;
+
+                    DEFAULT_UNREACHABLE;
+                }
+                break;
             }
+
+            default:
+                ASSERT(FALSE);
+                UNREACHABLE;
+                break;
         }
+
+        ++Resource;
     }
-    if (ResourceCount == 0)
+
+    /* This logical device has no resource requirements */
+    if ((ResourceCount == 0) && (FirstFixedDescriptors == 0) && 
(LastFixedDescriptors == 0))
         return STATUS_SUCCESS;
 
     /* Allocate memory to store requirements */
-    ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
-    if (Alternatives)
-    {
-        ListSize += sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1) * 
Alternatives->Count
-                    + sizeof(IO_RESOURCE_LIST) * (Alternatives->Count - 1)
-                    + sizeof(IO_RESOURCE_DESCRIPTOR) * AltOptionalCount;
-    }
-    else
-    {
-        ListSize += sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1);
-    }
+    ListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
+               FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) * AltListCount +
+               sizeof(IO_RESOURCE_DESCRIPTOR) * ResourceCount +
+               sizeof(IO_RESOURCE_DESCRIPTOR) * AltListCount *
+               (FirstFixedDescriptors + LastFixedDescriptors);
     RequirementsList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
     if (!RequirementsList)
         return STATUS_NO_MEMORY;
 
     RequirementsList->ListSize = ListSize;
     RequirementsList->InterfaceType = Isa;
-    RequirementsList->AlternativeLists = Alternatives ? Alternatives->Count : 
1;
+    RequirementsList->AlternativeLists = AltListCount;
 
     RequirementsList->List[0].Version = 1;
     RequirementsList->List[0].Revision = 1;
-    RequirementsList->List[0].Count = ResourceCount;
 
     /* Store requirements */
-    Descriptor = RequirementsList->List[0].Descriptors;
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->Io); i++)
-    {
-        if (!LogDev->Io[i].Description.Length)
-            break;
-
-        IsaConvertIoRequirement(Descriptor++, &LogDev->Io[i].Description);
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->Irq); i++)
-    {
-        if (!LogDev->Irq[i].Description.Mask)
-            continue;
-
-        FirstDescriptor = TRUE;
-
-        for (j = 0; j < RTL_BITS_OF(LogDev->Irq[i].Description.Mask); j++)
-        {
-            if (!(LogDev->Irq[i].Description.Mask & (1 << j)))
-                continue;
-
-            IsaConvertIrqRequirement(Descriptor++,
-                                     &LogDev->Irq[i].Description,
-                                     j,
-                                     FirstDescriptor);
-
-            if (FirstDescriptor)
-                FirstDescriptor = FALSE;
-        }
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
+    IsFirstAltList = TRUE;
+    AltList = &RequirementsList->List[0];
+    Descriptor = &RequirementsList->List[0].Descriptors[0];
+    Resource = PdoExt->IsaPnpDevice->Resources;
+    while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
     {
-        if (!LogDev->Dma[i].Description.Mask)
-            continue;
-
-        FirstDescriptor = TRUE;
-
-        for (j = 0; j < RTL_BITS_OF(LogDev->Dma[i].Description.Mask); j++)
+        switch (Resource->Type)
         {
-            if (!(LogDev->Dma[i].Description.Mask & (1 << j)))
-                continue;
-
-            IsaConvertDmaRequirement(Descriptor++,
-                                     &LogDev->Dma[i].Description,
-                                     j,
-                                     FirstDescriptor);
-
-            if (FirstDescriptor)
-                FirstDescriptor = FALSE;
-        }
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange); i++)
-    {
-        if (!LogDev->MemRange[i].Description.Length)
-            continue;
+            case ISAPNP_RESOURCE_TYPE_START_DEPENDENT:
+            {
+                if (!IsFirstAltList)
+                {
+                    /* Add room for the fixed descriptors */
+                    AltList->Count += LastFixedDescriptors;
 
-        IsaConvertMemRangeRequirement(Descriptor++,
-                                      &LogDev->MemRange[i].Description);
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++)
-    {
-        if (!LogDev->MemRange32[i].Description.Length)
-            continue;
+                    /* Move on to the next list */
+                    AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + 
AltList->Count);
+                    AltList->Version = 1;
+                    AltList->Revision = 1;
 
-        IsaConvertMemRange32Requirement(Descriptor++,
-                                        &LogDev->MemRange32[i].Description);
-    }
-    if (Alternatives)
-    {
-        UCHAR BestConfig[ISAPNP_MAX_ALTERNATIVES];
-        PIO_RESOURCE_LIST AltList = &RequirementsList->List[0];
-        PIO_RESOURCE_LIST NextList = AltList;
+                    /* Propagate the fixed resources to our new list */
+                    RtlCopyMemory(&AltList->Descriptors,
+                                  RequirementsList->List[0].Descriptors,
+                                  sizeof(IO_RESOURCE_DESCRIPTOR) * 
FirstFixedDescriptors);
+                    AltList->Count += FirstFixedDescriptors;
 
-        IsaDetermineBestConfig(BestConfig, Alternatives);
+                    Descriptor = &AltList->Descriptors[FirstFixedDescriptors];
+                }
 
-        for (i = 0; i < RequirementsList->AlternativeLists; i++)
-        {
-            RtlMoveMemory(NextList, AltList, sizeof(IO_RESOURCE_LIST));
-
-            /* Just because the 'NextList->Count++' correction */
-            NextList->Count = ResourceCount;
-            /*
-             * For example, the ROM
-             * 0x15, ...        // Logical device ID
-             * 0x30,            // Start DF
-             * 0x22, 0x04, 0x00 // IRQ
-             * 0x30,            // Start DF
-             * 0x22, 0xC0, 0x00 // IRQ
-             * 0x38,            // End DF
-             * 0x2A, 0x20, 0x3A // DMA
-             * 0x22, 0x00, 0x08 // IRQ
-             * 0x79, 0x00       // END
-             *
-             * will be represented as the following resource requirements list:
-             * Interface 1 Bus 0 Slot 0 AlternativeLists 2
-             * AltList 1, AltList->Count 3
-             * [Option 0, ShareDisposition 1, Flags 1] INT: Min B Max B
-             * [Option 0, ShareDisposition 0, Flags 0] DMA: Min 5 Max 5
-             * [Option 0, ShareDisposition 1, Flags 1] INT: Min 2 Max 2
-             * End Descriptors
-             * AltList 2, AltList->Count 4
-             * [Option 0, ShareDisposition 1, Flags 1] INT: Min B Max B
-             * [Option 0, ShareDisposition 0, Flags 0] DMA: Min 5 Max 5
-             * [Option 0, ShareDisposition 1, Flags 1] INT: Min 6 Max 6
-             * [Option 8, ShareDisposition 1, Flags 1] INT: Min 7 Max 7
-             * End Descriptors
-             */
-
-            /* Propagate the fixed resources to our new list */
-            for (j = 0; j < AltList->Count - AltCount; j++)
-            {
-                RtlMoveMemory(&NextList->Descriptors[j],
-                              &AltList->Descriptors[j],
-                              sizeof(IO_RESOURCE_DESCRIPTOR));
+                IsFirstAltList = FALSE;
+                break;
             }
 
-            Descriptor = &NextList->Descriptors[NextList->Count - AltCount];
+            case ISAPNP_RESOURCE_TYPE_END_DEPENDENT:
+                break;
 
-            /*
-             * Append alternatives.
-             * NOTE: To keep it simple, we append these to the end of the list.
-             */
-            if (HasIoAlternatives(Alternatives))
+            case ISAPNP_RESOURCE_TYPE_IO:
             {
-                IsaConvertIoRequirement(Descriptor++,
-                                        &Alternatives->Io[BestConfig[i]]);
+                IsaConvertIoRequirement(Descriptor++, 
&Resource->IoDescription);
+
+                ++AltList->Count;
+                break;
             }
-            if (HasIrqAlternatives(Alternatives))
+
+            case ISAPNP_RESOURCE_TYPE_IRQ:
             {
-                FirstDescriptor = TRUE;
+                IsFirstDescriptor = TRUE;
 
-                for (j = 0; j < 
RTL_BITS_OF(Alternatives->Irq[BestConfig[i]].Mask); j++)
+                for (i = 0; i < RTL_BITS_OF(Resource->IrqDescription.Mask); 
i++)
                 {
-                    if (!(Alternatives->Irq[BestConfig[i]].Mask & (1 << j)))
+                    if (!(Resource->IrqDescription.Mask & (1 << i)))
                         continue;
 
                     IsaConvertIrqRequirement(Descriptor++,
-                                             &Alternatives->Irq[BestConfig[i]],
-                                             j,
-                                             FirstDescriptor);
-
-                    if (FirstDescriptor)
-                        FirstDescriptor = FALSE;
-                    else
-                        NextList->Count++;
+                                             &Resource->IrqDescription,
+                                             i,
+                                             IsFirstDescriptor);
+                    ++AltList->Count;
+
+                    IsFirstDescriptor = FALSE;
                 }
+
+                break;
             }
-            if (HasDmaAlternatives(Alternatives))
+
+            case ISAPNP_RESOURCE_TYPE_DMA:
             {
-                FirstDescriptor = TRUE;
+                IsFirstDescriptor = TRUE;
 
-                for (j = 0; j < 
RTL_BITS_OF(Alternatives->Dma[BestConfig[i]].Mask); j++)
+                for (i = 0; i < RTL_BITS_OF(Resource->DmaDescription.Mask); 
i++)
                 {
-                    if (!(Alternatives->Dma[BestConfig[i]].Mask & (1 << j)))
+                    if (!(Resource->DmaDescription.Mask & (1 << i)))
                         continue;
 
                     IsaConvertDmaRequirement(Descriptor++,
-                                             &Alternatives->Dma[BestConfig[i]],
-                                             j,
-                                             FirstDescriptor);
-
-                    if (FirstDescriptor)
-                        FirstDescriptor = FALSE;
-                    else
-                        NextList->Count++;
+                                             &Resource->DmaDescription,
+                                             i,
+                                             IsFirstDescriptor);
+                    ++AltList->Count;
+
+                    IsFirstDescriptor = FALSE;
                 }
+
+                break;
             }
-            if (HasMemoryAlternatives(Alternatives))
+
+            case ISAPNP_RESOURCE_TYPE_MEMRANGE:
             {
-                IsaConvertMemRangeRequirement(Descriptor++,
-                                              
&Alternatives->MemRange[BestConfig[i]]);
+                IsaConvertMemRangeRequirement(Descriptor++, 
&Resource->MemRangeDescription);
+
+                ++AltList->Count;
+                break;
             }
-            if (HasMemory32Alternatives(Alternatives))
+
+            case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
             {
-                IsaConvertMemRange32Requirement(Descriptor++,
-                                                
&Alternatives->MemRange32[BestConfig[i]]);
+                IsaConvertMemRange32Requirement(Descriptor++, 
&Resource->MemRange32Description);
+
+                ++AltList->Count;
+                break;
             }
 
+            default:
+                ASSERT(FALSE);
+                UNREACHABLE;
+                break;
+        }
+
+        ++Resource;
+    }
+
+    /* Append the fixed resources */
+    if (LastFixedDescriptors)
+    {
+        PIO_RESOURCE_LIST NextList = &RequirementsList->List[0];
+
+        /* Make the descriptor point to the fixed resources */
+        Descriptor -= LastFixedDescriptors;
+
+        /* Propagate the fixed resources onto previous lists */
+        AltListCount = RequirementsList->AlternativeLists - 1;
+        for (i = 0; i < AltListCount; i++)
+        {
+            RtlCopyMemory(&NextList->Descriptors[NextList->Count - 
LastFixedDescriptors],
+                          Descriptor,
+                          sizeof(IO_RESOURCE_DESCRIPTOR) * 
LastFixedDescriptors);
+
             NextList = (PIO_RESOURCE_LIST)(NextList->Descriptors + 
NextList->Count);
         }
     }
@@ -527,58 +460,42 @@ FindIoDescriptor(
     _In_ ULONG RangeStart,
     _In_ ULONG RangeEnd,
     _Out_opt_ PUCHAR Information,
-    _Out_opt_ PULONG Length,
-    _Out_opt_ PUCHAR WriteOrder)
+    _Out_opt_ PULONG Length)
 {
-    ULONG i;
-    BOOLEAN Match;
-    PISAPNP_IO_DESCRIPTION Description;
+    PISAPNP_RESOURCE Resource;
 
     PAGED_CODE();
 
-    for (i = 0; i < RTL_NUMBER_OF(LogDevice->Io); i++)
+    Resource = LogDevice->Resources;
+    while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
     {
-        Description = &LogDevice->Io[i].Description;
-
-        Match = Base ? (Base >= Description->Minimum) && (Base <= 
Description->Maximum)
-                     : (RangeStart >= Description->Minimum) &&
-                       (RangeEnd <= (ULONG)(Description->Maximum + 
Description->Length - 1));
-
-        if (Match)
+        if (Resource->Type == ISAPNP_RESOURCE_TYPE_IO)
         {
-            if (Information)
-                *Information = Description->Information;
-            if (Length)
-                *Length = Description->Length;
-            if (WriteOrder)
-                *WriteOrder = LogDevice->Io[i].Index;
-
-            return TRUE;
-        }
-    }
-
-    if (!LogDevice->Alternatives)
-        return FALSE;
+            PISAPNP_IO_DESCRIPTION Description = &Resource->IoDescription;
+            BOOLEAN Match;
 
-    for (i = 0; i < LogDevice->Alternatives->Count; i++)
-    {
-        Description = &LogDevice->Alternatives->Io[i];
+            if (Base)
+            {
+                Match = (Base >= Description->Minimum) && (Base <= 
Description->Maximum);
+            }
+            else
+            {
+                Match = (RangeStart >= Description->Minimum) &&
+                        (RangeEnd <= (ULONG)(Description->Maximum + 
Description->Length - 1));
+            }
 
-        Match = Base ? (Base >= Description->Minimum) && (Base <= 
Description->Maximum)
-                     : (RangeStart >= Description->Minimum) &&
-                       (RangeEnd <= (ULONG)(Description->Maximum + 
Description->Length - 1));
+            if (Match)
+            {
+                if (Information)
+                    *Information = Description->Information;
+                if (Length)
+                    *Length = Description->Length;
 
-        if (Match)
-        {
-            if (Information)
-                *Information = Description->Information;
-            if (Length)
-                *Length = Description->Length;
-            if (WriteOrder)
-                *WriteOrder = LogDevice->Alternatives->IoIndex;
-
-            return TRUE;
+                return TRUE;
+            }
         }
+
+        ++Resource;
     }
 
     return FALSE;
@@ -588,53 +505,24 @@ CODE_SEG("PAGE")
 BOOLEAN
 FindIrqDescriptor(
     _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
-    _In_ ULONG Vector,
-    _Out_opt_ PUCHAR WriteOrder)
+    _In_ ULONG Vector)
 {
-    ULONG i, j;
-    PISAPNP_IRQ_DESCRIPTION Description;
+    PISAPNP_RESOURCE Resource;
 
     PAGED_CODE();
 
-    for (i = 0; i < RTL_NUMBER_OF(LogDevice->Irq); i++)
+    Resource = LogDevice->Resources;
+    while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
     {
-        Description = &LogDevice->Irq[i].Description;
-
-        for (j = 0; j < RTL_BITS_OF(Description->Mask); j++)
+        if (Resource->Type == ISAPNP_RESOURCE_TYPE_IRQ)
         {
-            if (Description->Mask & (1 << j))
-            {
-                if (j == Vector)
-                {
-                    if (WriteOrder)
-                        *WriteOrder = LogDevice->Irq[i].Index;
+            PISAPNP_IRQ_DESCRIPTION Description = &Resource->IrqDescription;
 
-                    return TRUE;
-                }
-            }
+            if (Description->Mask & (1 << Vector))
+                return TRUE;
         }
-    }
-
-    if (!LogDevice->Alternatives)
-        return FALSE;
-
-    for (i = 0; i < LogDevice->Alternatives->Count; i++)
-    {
-        Description = &LogDevice->Alternatives->Irq[i];
-
-        for (j = 0; j < RTL_BITS_OF(Description->Mask); j++)
-        {
-            if (Description->Mask & (1 << j))
-            {
-                if (j == Vector)
-                {
-                    if (WriteOrder)
-                        *WriteOrder = LogDevice->Alternatives->IrqIndex;
 
-                    return TRUE;
-                }
-            }
-        }
+        ++Resource;
     }
 
     return FALSE;
@@ -644,53 +532,24 @@ CODE_SEG("PAGE")
 BOOLEAN
 FindDmaDescriptor(
     _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
-    _In_ ULONG Channel,
-    _Out_opt_ PUCHAR WriteOrder)
+    _In_ ULONG Channel)
 {
-    ULONG i, j;
-    PISAPNP_DMA_DESCRIPTION Description;
+    PISAPNP_RESOURCE Resource;
 
     PAGED_CODE();
 
-    for (i = 0; i < RTL_NUMBER_OF(LogDevice->Dma); i++)
+    Resource = LogDevice->Resources;
+    while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
     {
-        Description = &LogDevice->Dma[i].Description;
-
-        for (j = 0; j < RTL_BITS_OF(Description->Mask); j++)
+        if (Resource->Type == ISAPNP_RESOURCE_TYPE_DMA)
         {
-            if (Description->Mask & (1 << j))
-            {
-                if (j == Channel)
-                {
-                    if (WriteOrder)
-                        *WriteOrder = LogDevice->Dma[i].Index;
+            PISAPNP_DMA_DESCRIPTION Description = &Resource->DmaDescription;
 
-                    return TRUE;
-                }
-            }
+            if (Description->Mask & (1 << Channel))
+                return TRUE;
         }
-    }
-
-    if (!LogDevice->Alternatives)
-        return FALSE;
-
-    for (i = 0; i < LogDevice->Alternatives->Count; i++)
-    {
-        Description = &LogDevice->Alternatives->Dma[i];
-
-        for (j = 0; j < RTL_BITS_OF(Description->Mask); j++)
-        {
-            if (Description->Mask & (1 << j))
-            {
-                if (j == Channel)
-                {
-                    if (WriteOrder)
-                        *WriteOrder = LogDevice->Alternatives->DmaIndex;
 
-                    return TRUE;
-                }
-            }
-        }
+        ++Resource;
     }
 
     return FALSE;
@@ -702,87 +561,57 @@ FindMemoryDescriptor(
     _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
     _In_ ULONG RangeStart,
     _In_ ULONG RangeEnd,
-    _Out_opt_ PBOOLEAN Memory32,
-    _Out_opt_ PUCHAR Information,
-    _Out_opt_ PUCHAR WriteOrder)
+    _Out_opt_ PUCHAR Information)
 {
-    ULONG i;
-    PISAPNP_MEMRANGE_DESCRIPTION Description;
-    PISAPNP_MEMRANGE32_DESCRIPTION Description32;
+    PISAPNP_RESOURCE Resource;
 
     PAGED_CODE();
 
-    for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange); i++)
+    Resource = LogDevice->Resources;
+    while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
     {
-        Description = &LogDevice->MemRange[i].Description;
-
-        if ((RangeStart >= (ULONG)(Description->Minimum << 8)) &&
-            (RangeEnd <= (ULONG)((Description->Maximum << 8) + 
(Description->Length << 8) - 1)))
+        switch (Resource->Type)
         {
-            if (Memory32)
-                *Memory32 = FALSE;
-            if (Information)
-                *Information = Description->Information;
-            if (WriteOrder)
-                *WriteOrder = LogDevice->MemRange[i].Index;
-
-            return TRUE;
-        }
-    }
-    for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange32); i++)
-    {
-        Description32 = &LogDevice->MemRange32[i].Description;
+            case ISAPNP_RESOURCE_TYPE_MEMRANGE:
+            {
+                PISAPNP_MEMRANGE_DESCRIPTION Description;
 
-        if ((RangeStart >= Description32->Minimum) &&
-            (RangeEnd <= (Description32->Maximum + Description32->Length - 1)))
-        {
-            if (Memory32)
-                *Memory32 = TRUE;
-            if (Information)
-                *Information = Description32->Information;
-            if (WriteOrder)
-                *WriteOrder = LogDevice->MemRange32[i].Index;
-
-            return TRUE;
-        }
-    }
+                Description = &Resource->MemRangeDescription;
 
-    if (!LogDevice->Alternatives)
-        return FALSE;
+                if ((RangeStart >= (ULONG)(Description->Minimum << 8)) &&
+                    (RangeEnd <= (ULONG)((Description->Maximum << 8) +
+                                         (Description->Length << 8) - 1)))
+                {
+                    if (Information)
+                        *Information = Description->Information;
 
-    for (i = 0; i < LogDevice->Alternatives->Count; i++)
-    {
-        Description = &LogDevice->Alternatives->MemRange[i];
+                    return TRUE;
+                }
+                break;
+            }
 
-        if ((RangeStart >= (ULONG)(Description->Minimum << 8)) &&
-            (RangeEnd <= (ULONG)((Description->Maximum << 8) + 
(Description->Length << 8) - 1)))
-        {
-            if (Memory32)
-                *Memory32 = FALSE;
-            if (Information)
-                *Information = Description->Information;
-            if (WriteOrder)
-                *WriteOrder = LogDevice->Alternatives->MemRangeIndex;
-
-            return TRUE;
-        }
-    }
-    for (i = 0; i < LogDevice->Alternatives->Count; i++)
-    {
-        Description32 = &LogDevice->Alternatives->MemRange32[i];
+            case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
+            {
+                PISAPNP_MEMRANGE32_DESCRIPTION Description32;
 
-        if ((RangeStart >= Description32->Minimum) &&
-            (RangeEnd <= (Description32->Maximum + Description32->Length - 1)))
-        {
-            if (Memory32)
-                *Memory32 = TRUE;
-            if (Information)
-                *Information = Description32->Information;
-            if (WriteOrder)
-                *WriteOrder = LogDevice->Alternatives->MemRange32Index;
-
-            return TRUE;
+                Description32 = &Resource->MemRange32Description;
+
+                if ((RangeStart >= Description32->Minimum) &&
+                    (RangeEnd <= (Description32->Maximum + 
Description32->Length - 1)))
+                {
+                    if (Information)
+                        *Information = Description32->Information;
+
+                    return TRUE;
+                }
+                break;
+            }
+
+            default:
+                break;
         }
+
+        ++Resource;
     }
 
     return FALSE;
@@ -872,9 +701,9 @@ IsaPnpCreateLogicalDeviceResources(
                               0,
                               0,
                               &Information,
-                              &CurrentLength,
-                              NULL))
+                              &CurrentLength))
         {
+            DPRINT1("I/O entry #%lu %x not found\n", i, 
LogDev->Io[i].CurrentBase);
             goto InvalidBiosResources;
         }
 
@@ -894,9 +723,6 @@ IsaPnpCreateLogicalDeviceResources(
         if (!LogDev->Irq[i].CurrentNo)
             break;
 
-        if (!FindIrqDescriptor(LogDev, LogDev->Irq[i].CurrentNo, NULL))
-            goto InvalidBiosResources;
-
         Descriptor = 
&ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
         Descriptor->Type = CmResourceTypeInterrupt;
         Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
@@ -906,16 +732,13 @@ IsaPnpCreateLogicalDeviceResources(
             Descriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
         Descriptor->u.Interrupt.Level = LogDev->Irq[i].CurrentNo;
         Descriptor->u.Interrupt.Vector = LogDev->Irq[i].CurrentNo;
-        Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+        Descriptor->u.Interrupt.Affinity = (KAFFINITY)-1;
     }
     for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
     {
         if (LogDev->Dma[i].CurrentChannel == 4)
             break;
 
-        if (!FindDmaDescriptor(LogDev, LogDev->Dma[i].CurrentChannel, NULL))
-            goto InvalidBiosResources;
-
         Descriptor = 
&ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
         Descriptor->Type = CmResourceTypeDma;
         Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
@@ -930,10 +753,12 @@ IsaPnpCreateLogicalDeviceResources(
         if (!FindMemoryDescriptor(LogDev,
                                   LogDev->MemRange[i].CurrentBase,
                                   LogDev->MemRange[i].CurrentLength,
-                                  NULL,
-                                  &Information,
-                                  NULL))
+                                  &Information))
         {
+            DPRINT1("MEM entry #%lu %lx %lx not found\n",
+                    i,
+                    LogDev->MemRange[i].CurrentBase,
+                    LogDev->MemRange[i].CurrentLength);
             goto InvalidBiosResources;
         }
 
@@ -956,10 +781,12 @@ IsaPnpCreateLogicalDeviceResources(
         if (!FindMemoryDescriptor(LogDev,
                                   LogDev->MemRange32[i].CurrentBase,
                                   LogDev->MemRange32[i].CurrentLength,
-                                  NULL,
-                                  &Information,
-                                  NULL))
+                                  &Information))
         {
+            DPRINT1("MEM32 entry #%lu %lx %lx not found\n",
+                    i,
+                    LogDev->MemRange32[i].CurrentBase,
+                    LogDev->MemRange32[i].CurrentLength);
             goto InvalidBiosResources;
         }
 
@@ -980,7 +807,7 @@ IsaPnpCreateLogicalDeviceResources(
     return STATUS_SUCCESS;
 
 InvalidBiosResources:
-    DPRINT("Invalid boot resources! (CSN %u, LDN %u)\n", LogDev->CSN, 
LogDev->LDN);
+    DPRINT1("Invalid boot resources! (CSN %u, LDN %u)\n", LogDev->CSN, 
LogDev->LDN);
 
     LogDev->Flags &= ~ISAPNP_HAS_RESOURCES;
     ExFreePoolWithTag(ResourceList, TAG_ISAPNP);
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index 17945dbe06a..998c7e766f0 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -151,22 +151,19 @@ FindIoDescriptor(
     _In_ ULONG RangeStart,
     _In_ ULONG RangeEnd,
     _Out_opt_ PUCHAR Information,
-    _Out_opt_ PULONG Length,
-    _Out_opt_ PUCHAR WriteOrder);
+    _Out_opt_ PULONG Length);
 
 CODE_SEG("PAGE")
 BOOLEAN
 FindIrqDescriptor(
     _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
-    _In_ ULONG Vector,
-    _Out_opt_ PUCHAR WriteOrder);
+    _In_ ULONG Vector);
 
 CODE_SEG("PAGE")
 BOOLEAN
 FindDmaDescriptor(
     _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
-    _In_ ULONG Channel,
-    _Out_opt_ PUCHAR WriteOrder);
+    _In_ ULONG Channel);
 
 CODE_SEG("PAGE")
 BOOLEAN
@@ -174,9 +171,7 @@ FindMemoryDescriptor(
     _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
     _In_ ULONG RangeStart,
     _In_ ULONG RangeEnd,
-    _Out_opt_ PBOOLEAN Memory32,
-    _Out_opt_ PUCHAR Information,
-    _Out_opt_ PUCHAR WriteOrder);
+    _Out_opt_ PUCHAR Information);
 
 CODE_SEG("PAGE")
 PIO_RESOURCE_REQUIREMENTS_LIST
diff --git a/drivers/bus/isapnp/isapnpres.h b/drivers/bus/isapnp/isapnpres.h
index 16c21646a0f..a21299a1710 100644
--- a/drivers/bus/isapnp/isapnpres.h
+++ b/drivers/bus/isapnp/isapnpres.h
@@ -9,10 +9,7 @@
 #pragma once
 
 /** @brief Maximum size of resource data structure supported by the driver. */
-#define ISAPNP_MAX_RESOURCEDATA 0x1000
-
-/** @brief Maximum number of Start DF tags supported by the driver. */
-#define ISAPNP_MAX_ALTERNATIVES 8
+#define ISAPNP_MAX_RESOURCEDATA   0x1000
 
 typedef struct _ISAPNP_IO
 {
@@ -59,23 +56,35 @@ typedef struct _ISAPNP_COMPATIBLE_ID_ENTRY
     LIST_ENTRY IdLink;
 } ISAPNP_COMPATIBLE_ID_ENTRY, *PISAPNP_COMPATIBLE_ID_ENTRY;
 
-typedef struct _ISAPNP_ALTERNATIVES
+typedef enum
+{
+    dfNotStarted,
+    dfStarted,
+    dfDone
+} ISAPNP_DEPENDENT_FUNCTION_STATE;
+
+typedef struct _ISAPNP_RESOURCE
 {
-    ISAPNP_IO_DESCRIPTION Io[ISAPNP_MAX_ALTERNATIVES];
-    ISAPNP_IRQ_DESCRIPTION Irq[ISAPNP_MAX_ALTERNATIVES];
-    ISAPNP_DMA_DESCRIPTION Dma[ISAPNP_MAX_ALTERNATIVES];
-    ISAPNP_MEMRANGE_DESCRIPTION MemRange[ISAPNP_MAX_ALTERNATIVES];
-    ISAPNP_MEMRANGE32_DESCRIPTION MemRange32[ISAPNP_MAX_ALTERNATIVES];
-    UCHAR Priority[ISAPNP_MAX_ALTERNATIVES];
-    UCHAR IoIndex;
-    UCHAR IrqIndex;
-    UCHAR DmaIndex;
-    UCHAR MemRangeIndex;
-    UCHAR MemRange32Index;
-
-    _Field_range_(0, ISAPNP_MAX_ALTERNATIVES)
-    UCHAR Count;
-} ISAPNP_ALTERNATIVES, *PISAPNP_ALTERNATIVES;
+    UCHAR Type;
+#define ISAPNP_RESOURCE_TYPE_END               0
+#define ISAPNP_RESOURCE_TYPE_IO                1
+#define ISAPNP_RESOURCE_TYPE_IRQ               2
+#define ISAPNP_RESOURCE_TYPE_DMA               3
+#define ISAPNP_RESOURCE_TYPE_MEMRANGE          4
+#define ISAPNP_RESOURCE_TYPE_MEMRANGE32        5
+#define ISAPNP_RESOURCE_TYPE_START_DEPENDENT   6
+#define ISAPNP_RESOURCE_TYPE_END_DEPENDENT     7
+
+    union
+    {
+        ISAPNP_IO_DESCRIPTION IoDescription;
+        ISAPNP_IRQ_DESCRIPTION IrqDescription;
+        ISAPNP_DMA_DESCRIPTION DmaDescription;
+        ISAPNP_MEMRANGE_DESCRIPTION MemRangeDescription;
+        ISAPNP_MEMRANGE32_DESCRIPTION MemRange32Description;
+        UCHAR Priority;
+    };
+} ISAPNP_RESOURCE, *PISAPNP_RESOURCE;
 
 typedef struct _ISAPNP_LOGICAL_DEVICE
 {
@@ -92,6 +101,12 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
 /** Cleared when the device has no boot resources */
 #define ISAPNP_HAS_RESOURCES        0x00000004
 
+/** The card implements 24-bit memory decoder */
+#define ISAPNP_HAS_MEM24_DECODER    0x00000008
+
+/** The card implements 32-bit memory decoder */
+#define ISAPNP_HAS_MEM32_DECODER    0x00000010
+
     /**
      * @name The card data.
      * @{
@@ -109,7 +124,7 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
     UCHAR LDN;
     UCHAR LogVendorId[3];
     USHORT LogProdId;
-    PISAPNP_ALTERNATIVES Alternatives;
+    PISAPNP_RESOURCE Resources;
     PSTR FriendlyName;
     LIST_ENTRY CompatibleIdList;
 
@@ -120,43 +135,3 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
     ISAPNP_MEMRANGE32 MemRange32[4];
     /**@}*/
 } ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
-
-FORCEINLINE
-BOOLEAN
-HasIoAlternatives(
-    _In_ PISAPNP_ALTERNATIVES Alternatives)
-{
-    return (Alternatives->Io[0].Length != 0);
-}
-
-FORCEINLINE
-BOOLEAN
-HasIrqAlternatives(
-    _In_ PISAPNP_ALTERNATIVES Alternatives)
-{
-    return (Alternatives->Irq[0].Mask != 0);
-}
-
-FORCEINLINE
-BOOLEAN
-HasDmaAlternatives(
-    _In_ PISAPNP_ALTERNATIVES Alternatives)
-{
-    return (Alternatives->Dma[0].Mask != 0);
-}
-
-FORCEINLINE
-BOOLEAN
-HasMemoryAlternatives(
-    _In_ PISAPNP_ALTERNATIVES Alternatives)
-{
-    return (Alternatives->MemRange[0].Length != 0);
-}
-
-FORCEINLINE
-BOOLEAN
-HasMemory32Alternatives(
-    _In_ PISAPNP_ALTERNATIVES Alternatives)
-{
-    return (Alternatives->MemRange32[0].Length != 0);
-}
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 5e8979ad274..26d4cfc8a94 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -488,12 +488,6 @@ IsaPdoQueryResources(
         return STATUS_SUCCESS;
     }
 
-    if (!(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES))
-    {
-        Irp->IoStatus.Information = 0;
-        return STATUS_SUCCESS;
-    }
-
     if (!PdoExt->ResourceList)
         return Irp->IoStatus.Status;
 
@@ -847,8 +841,8 @@ IsaPnpRemoveLogicalDeviceDO(
     if (LogDev->FriendlyName)
         ExFreePoolWithTag(LogDev->FriendlyName, TAG_ISAPNP);
 
-    if (LogDev->Alternatives)
-        ExFreePoolWithTag(LogDev->Alternatives, TAG_ISAPNP);
+    if (LogDev->Resources)
+        ExFreePoolWithTag(LogDev->Resources, TAG_ISAPNP);
 
     Entry = LogDev->CompatibleIdList.Flink;
     while (Entry != &LogDev->CompatibleIdList)
@@ -983,18 +977,16 @@ IsaPdoPnp(
             break;
 
         case IRP_MN_SURPRISE_REMOVAL:
-            if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
-                Status = IsaPdoRemoveDevice(PdoExt, FALSE);
-            else
-                Status = IsaReadPortRemoveDevice(PdoExt, FALSE);
-            break;
-
         case IRP_MN_REMOVE_DEVICE:
+        {
+            BOOLEAN FinalRemove = (IrpSp->MinorFunction == 
IRP_MN_REMOVE_DEVICE);
+
             if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
-                Status = IsaPdoRemoveDevice(PdoExt, TRUE);
+                Status = IsaPdoRemoveDevice(PdoExt, FinalRemove);
             else
-                Status = IsaReadPortRemoveDevice(PdoExt, TRUE);
+                Status = IsaReadPortRemoveDevice(PdoExt, FinalRemove);
             break;
+        }
 
         case IRP_MN_QUERY_PNP_DEVICE_STATE:
             Status = IsaPdoQueryPnpDeviceState(PdoExt, Irp);

Reply via email to