[NTOS:IO] Fix IopGetBusTypeGuidIndex

- Use a global structure instead of pointer
- Allocate only the GUID buffer
- Keep track of allocated size and number of GUIDs
- Grow in steps of 8 GUIDs
- Use ExAllocatePoolWithTag instead of ExAllocatePool
- Use IsEqualGUID

See CORE-12791
This commit is contained in:
Timo Kreuzer
2026-05-07 11:12:02 +03:00
parent 1ed6179ea8
commit a7f658e322
4 changed files with 49 additions and 38 deletions

View File

@@ -414,11 +414,11 @@ typedef struct _DRIVER_INFORMATION
//
typedef struct _IO_BUS_TYPE_GUID_LIST
{
ULONG GuidCount;
FAST_MUTEX Lock;
GUID Guids[1];
ULONG AllocatedCount;
ULONG GuidCount;
PGUID Guids;
} IO_BUS_TYPE_GUID_LIST, *PIO_BUS_TYPE_GUID_LIST;
extern PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList;
//
// Shutdown entry for registed devices
@@ -1445,7 +1445,7 @@ extern LIST_ENTRY IopErrorLogListHead;
extern ULONG IopAutoReboot;
extern ULONG IopNumTriageDumpDataBlocks;
extern PVOID IopTriageDumpDataBlocks[64];
extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
extern IO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
extern PDRIVER_OBJECT IopRootDriverObject;
extern KSPIN_LOCK IopDeviceActionLock;
extern LIST_ENTRY IopDeviceActionRequestList;

View File

@@ -89,6 +89,7 @@
#define TAG_IO_DEVNODE 'donD'
#define TAG_PNP_NOTIFY 'NPnP'
#define TAG_PNP_ROOT 'RPnP'
#define TAG_PNP_GUIDS 'GPnP'
#define TAG_IO_RESOURCE 'CRSR'
#define TAG_IO_TIMER 'MTOI'
#define TAG_VPB ' BPV'

View File

@@ -444,10 +444,19 @@ IopInitializePlugPlayServices(VOID)
if (!NT_SUCCESS(Status)) return Status;
/* Initialize the Bus Type GUID List */
PnpBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
RtlZeroMemory(PnpBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
ExInitializeFastMutex(&PnpBusTypeGuidList->Lock);
ExInitializeFastMutex(&PnpBusTypeGuidList.Lock);
PnpBusTypeGuidList.AllocatedCount = 8;
PnpBusTypeGuidList.GuidCount = 0;
PnpBusTypeGuidList.Guids = ExAllocatePoolWithTag(PagedPool,
PnpBusTypeGuidList.AllocatedCount * sizeof(GUID),
TAG_PNP_GUIDS);
if (PnpBusTypeGuidList.Guids == NULL)
{
DPRINT1("Failed to allocate PnP GUID buffer!\n");
KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0);
}
RtlZeroMemory(PnpBusTypeGuidList.Guids, PnpBusTypeGuidList.AllocatedCount * sizeof(GUID));
/* Initialize PnP root relations (this is a syncronous operation) */
PiQueueDeviceAction(Pdo, PiActionEnumRootDevices, NULL, NULL);

View File

@@ -24,7 +24,7 @@ extern ULONG ExpInitializationPhase;
/* DATA **********************************************************************/
PDRIVER_OBJECT IopRootDriverObject;
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL;
IO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
/* FUNCTIONS *****************************************************************/
@@ -410,66 +410,67 @@ USHORT
NTAPI
IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
{
USHORT i = 0, FoundIndex = 0xFFFF;
ULONG NewSize;
PVOID NewList;
USHORT i, FoundIndex = 0xFFFF;
ULONG NewAllocatedCount;
PGUID NewList;
/* Acquire the lock */
ExAcquireFastMutex(&PnpBusTypeGuidList->Lock);
ExAcquireFastMutex(&PnpBusTypeGuidList.Lock);
/* Loop all entries */
while (i < PnpBusTypeGuidList->GuidCount)
for (i = 0; i < PnpBusTypeGuidList.GuidCount; i++)
{
/* Try to find a match */
if (RtlCompareMemory(BusTypeGuid,
&PnpBusTypeGuidList->Guids[i],
sizeof(GUID)) == sizeof(GUID))
if (IsEqualGUID(BusTypeGuid, &PnpBusTypeGuidList.Guids[i]))
{
/* Found it */
FoundIndex = i;
goto Quickie;
}
i++;
}
/* Check if we have to grow the list */
if (PnpBusTypeGuidList->GuidCount)
ASSERT(PnpBusTypeGuidList.GuidCount <= PnpBusTypeGuidList.AllocatedCount);
if (PnpBusTypeGuidList.GuidCount == PnpBusTypeGuidList.AllocatedCount)
{
/* Calculate the new size */
NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
(sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
NewAllocatedCount = PnpBusTypeGuidList.AllocatedCount + 8;
/* Allocate the new copy */
NewList = ExAllocatePool(PagedPool, NewSize);
NewList = ExAllocatePoolWithTag(PagedPool,
NewAllocatedCount * sizeof(GUID),
TAG_PNP_GUIDS);
if (!NewList)
{
/* Fail */
goto Quickie;
}
/* Now copy them, decrease the size too */
NewSize -= sizeof(GUID);
RtlCopyMemory(NewList, PnpBusTypeGuidList, NewSize);
/* Copy the existing GUIDs to the new list and zero the rest */
RtlCopyMemory(NewList,
PnpBusTypeGuidList.Guids,
PnpBusTypeGuidList.GuidCount * sizeof(GUID));
RtlZeroMemory(&NewList[PnpBusTypeGuidList.GuidCount],
(NewAllocatedCount - PnpBusTypeGuidList.GuidCount) * sizeof(GUID));
/* Free the old list */
ExFreePool(PnpBusTypeGuidList);
ExFreePool(PnpBusTypeGuidList.Guids);
/* Use the new buffer */
PnpBusTypeGuidList = NewList;
PnpBusTypeGuidList.Guids = NewList;
PnpBusTypeGuidList.AllocatedCount = NewAllocatedCount;
}
/* Copy the new GUID */
RtlCopyMemory(&PnpBusTypeGuidList->Guids[PnpBusTypeGuidList->GuidCount],
BusTypeGuid,
sizeof(GUID));
PnpBusTypeGuidList.Guids[PnpBusTypeGuidList.GuidCount] = *BusTypeGuid;
/* The new entry is the index */
FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
PnpBusTypeGuidList->GuidCount++;
ASSERT(PnpBusTypeGuidList.GuidCount < MAXUSHORT);
FoundIndex = (USHORT)PnpBusTypeGuidList.GuidCount;
PnpBusTypeGuidList.GuidCount++;
Quickie:
ExReleaseFastMutex(&PnpBusTypeGuidList->Lock);
ExReleaseFastMutex(&PnpBusTypeGuidList.Lock);
return FoundIndex;
}
@@ -1172,13 +1173,13 @@ PnpBusTypeGuidGet(IN USHORT Index,
NTSTATUS Status = STATUS_SUCCESS;
/* Acquire the lock */
ExAcquireFastMutex(&PnpBusTypeGuidList->Lock);
ExAcquireFastMutex(&PnpBusTypeGuidList.Lock);
/* Validate size */
if (Index < PnpBusTypeGuidList->GuidCount)
if (Index < PnpBusTypeGuidList.GuidCount)
{
/* Copy the data */
RtlCopyMemory(BusTypeGuid, &PnpBusTypeGuidList->Guids[Index], sizeof(GUID));
RtlCopyMemory(BusTypeGuid, &PnpBusTypeGuidList.Guids[Index], sizeof(GUID));
}
else
{
@@ -1187,7 +1188,7 @@ PnpBusTypeGuidGet(IN USHORT Index,
}
/* Release lock and return status */
ExReleaseFastMutex(&PnpBusTypeGuidList->Lock);
ExReleaseFastMutex(&PnpBusTypeGuidList.Lock);
return Status;
}