[NTOS:IO] Fix some bugs in the IoQueryDeviceDescription helpers (#5320)

- Add missing ExAllocatePool NULL checks.

- Fix order of KeBugCheckEx parameters for PNP_DETECTED_FATAL_ERROR.

- The Controller and Peripheral numbers are zero-based, so if the caller
  wants to inspect controller (or peripheral) zero, let it be so!
  The original code was treating controller number zero for enumerating
  controllers of a given class within the different buses, which is
  wrong. See the diff'ed trace below.
  Tested with Windows' videoprt.sys VideoPortGetDeviceData().

```diff
 IoQueryDeviceDescription()
     BusType:          0xB093C224 (0)
     BusNumber:        0xB093C228 (0)
     ControllerType:   0xF9D01030 (19)
     ControllerNumber: 0xF9D01038 (0)
     PeripheralType:   0x00000000 (4294967295)
     PeripheralNumber: 0x00000000 (4294967295)
     CalloutRoutine:   0xF9CF74E4
     Context:          0xF9D5A340
 --> Query: 0xF9D5A22C

 IopQueryBusDescription(Query: 0xF9D5A22C)
     RootKey: '\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM'
     RootKeyHandle: 0x00000598
     KeyIsRoot: TRUE
     Bus: 0xF9D5A290 (4294967295)
     Seen: 'CentralProcessor'
     Seen: 'FloatingPointProcessor'
     Seen: 'MultifunctionAdapter'
     SubRootRegName: '\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MultifunctionAdapter'

 IopQueryBusDescription(Query: 0xF9D5A22C)
     RootKey: '\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MultifunctionAdapter'
     RootKeyHandle: 0x00000590
     KeyIsRoot: FALSE
     Bus: 0xF9D5A290 (4294967295)
     Seen: '0'
     SubRootRegName: '\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MultifunctionAdapter\0'
     Getting bus value: 'Identifier'
     Getting bus value: 'Configuration Data'
     Getting bus value: 'Component Information'
     --> Getting device on Bus #0 : '\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MultifunctionAdapter\0'

 IopQueryDeviceDescription(Query: 0xF9D5A22C)
     RootKey: '\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MultifunctionAdapter\0'
     RootKeyHandle: 0x00000590
     Bus: 0
-    Enumerating controllers in '\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MultifunctionAdapter\0\DisplayController'...
+    Getting controller #0
+    Retrieving controller '\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MultifunctionAdapter\0\DisplayController\0'
```
This commit is contained in:
Hermès Bélusca-Maïto 2023-05-27 22:55:40 +02:00
parent 318b2e786d
commit 84b4a80beb
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -170,18 +170,16 @@ IopQueryDeviceDescription(
Bus); Bus);
/* Temporary string */ /* Temporary string */
TempString.MaximumLength = sizeof(TempBuffer); RtlInitEmptyUnicodeString(&TempString, TempBuffer, sizeof(TempBuffer));
TempString.Length = 0;
TempString.Buffer = TempBuffer;
/* Append controller name to string */ /* Append controller name to string */
RtlAppendUnicodeToString(&ControllerRootRegName, L"\\"); RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->ControllerType]); RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->ControllerType]);
/* Set the controller number if specified */ /* Set the controller number if specified */
if (Query->ControllerNumber && *(Query->ControllerNumber)) if (Query->ControllerNumber)
{ {
ControllerNumber = *Query->ControllerNumber; ControllerNumber = *(Query->ControllerNumber);
MaximumControllerNumber = ControllerNumber + 1; MaximumControllerNumber = ControllerNumber + 1;
IORSRCTRACE(" Getting controller #%lu\n", ControllerNumber); IORSRCTRACE(" Getting controller #%lu\n", ControllerNumber);
} }
@ -208,6 +206,11 @@ IopQueryDeviceDescription(
/* Allocate it */ /* Allocate it */
ControllerFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE); ControllerFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);
if (!ControllerFullInformation)
{
ZwClose(ControllerKeyHandle);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Get the information */ /* Get the information */
Status = ZwQueryKey(ControllerKeyHandle, Status = ZwQueryKey(ControllerKeyHandle,
@ -222,7 +225,7 @@ IopQueryDeviceDescription(
/* No controller was found, bail out */ /* No controller was found, bail out */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (ControllerFullInformation != NULL) if (ControllerFullInformation)
ExFreePoolWithTag(ControllerFullInformation, TAG_IO_RESOURCE); ExFreePoolWithTag(ControllerFullInformation, TAG_IO_RESOURCE);
return Status; return Status;
} }
@ -286,11 +289,17 @@ IopQueryDeviceDescription(
(Status != STATUS_BUFFER_TOO_SMALL) && (Status != STATUS_BUFFER_TOO_SMALL) &&
(Status != STATUS_BUFFER_OVERFLOW)) (Status != STATUS_BUFFER_OVERFLOW))
{ {
ControllerInformation[ControllerLoop] = NULL;
continue; continue;
} }
/* Allocate it */ /* Allocate it */
ControllerInformation[ControllerLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE); ControllerInformation[ControllerLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);
if (!ControllerInformation[ControllerLoop])
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
/* Get the information */ /* Get the information */
Status = ZwQueryValueKey(ControllerKeyHandle, Status = ZwQueryValueKey(ControllerKeyHandle,
@ -339,9 +348,9 @@ IopQueryDeviceDescription(
goto EndLoop; goto EndLoop;
/* Set the peripheral number if specified */ /* Set the peripheral number if specified */
if (Query->PeripheralNumber && *Query->PeripheralNumber) if (Query->PeripheralNumber)
{ {
PeripheralNumber = *Query->PeripheralNumber; PeripheralNumber = *(Query->PeripheralNumber);
MaximumPeripheralNumber = PeripheralNumber + 1; MaximumPeripheralNumber = PeripheralNumber + 1;
IORSRCTRACE(" Getting peripheral #%lu\n", PeripheralNumber); IORSRCTRACE(" Getting peripheral #%lu\n", PeripheralNumber);
} }
@ -368,6 +377,12 @@ IopQueryDeviceDescription(
/* Allocate it */ /* Allocate it */
PeripheralFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE); PeripheralFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);
if (!PeripheralFullInformation)
{
ZwClose(PeripheralKeyHandle);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto EndLoop;
}
/* Get the information */ /* Get the information */
Status = ZwQueryKey(PeripheralKeyHandle, Status = ZwQueryKey(PeripheralKeyHandle,
@ -450,6 +465,11 @@ IopQueryDeviceDescription(
/* Allocate it */ /* Allocate it */
PeripheralInformation[PeripheralLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE); PeripheralInformation[PeripheralLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);
if (!PeripheralInformation[PeripheralLoop])
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
/* Get the information */ /* Get the information */
Status = ZwQueryValueKey(PeripheralKeyHandle, Status = ZwQueryValueKey(PeripheralKeyHandle,
@ -591,9 +611,8 @@ IopQueryBusDescription(
/* Allocate it */ /* Allocate it */
FullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE); FullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);
if (!FullInformation) if (!FullInformation)
return STATUS_NO_MEMORY; return STATUS_INSUFFICIENT_RESOURCES;
/* Get the information */ /* Get the information */
Status = ZwQueryKey(RootKeyHandle, Status = ZwQueryKey(RootKeyHandle,
@ -608,6 +627,11 @@ IopQueryBusDescription(
/* Allocate it */ /* Allocate it */
BasicInformation = ExAllocatePoolWithTag(PagedPool, LenBasicInformation, TAG_IO_RESOURCE); BasicInformation = ExAllocatePoolWithTag(PagedPool, LenBasicInformation, TAG_IO_RESOURCE);
if (!BasicInformation)
{
ExFreePoolWithTag(FullInformation, TAG_IO_RESOURCE);
return STATUS_INSUFFICIENT_RESOURCES;
}
} }
/* Deallocate the old buffer */ /* Deallocate the old buffer */
@ -691,6 +715,11 @@ IopQueryBusDescription(
/* Allocate it */ /* Allocate it */
BusInformation[SubBusLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE); BusInformation[SubBusLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);
if (!BusInformation[SubBusLoop])
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
/* Get the information */ /* Get the information */
Status = ZwQueryValueKey(SubRootKeyHandle, Status = ZwQueryValueKey(SubRootKeyHandle,
@ -774,7 +803,8 @@ IopQueryBusDescription(
Status = IopQueryBusDescription(Query, SubRootRegName, SubRootKeyHandle, Bus, !KeyIsRoot); Status = IopQueryBusDescription(Query, SubRootRegName, SubRootKeyHandle, Bus, !KeyIsRoot);
/* Everything enumerated */ /* Everything enumerated */
if (Status == STATUS_NO_MORE_ENTRIES) Status = STATUS_SUCCESS; if (Status == STATUS_NO_MORE_ENTRIES)
Status = STATUS_SUCCESS;
ZwClose(SubRootKeyHandle); ZwClose(SubRootKeyHandle);
SubRootKeyHandle = NULL; SubRootKeyHandle = NULL;
@ -860,11 +890,10 @@ IopStoreSystemPartitionInformation(
return; return;
} }
/* Prepare the string that will receive where symbolic link points to */ /* Prepare the string that will receive where symbolic link points to.
LinkTarget.Length = 0; * We will zero the end of the string after having received it */
/* We will zero the end of the string after having received it */ RtlInitEmptyUnicodeString(&LinkTarget, LinkTargetBuffer,
LinkTarget.MaximumLength = sizeof(LinkTargetBuffer) - sizeof(UNICODE_NULL); sizeof(LinkTargetBuffer) - sizeof(UNICODE_NULL));
LinkTarget.Buffer = LinkTargetBuffer;
/* Query target */ /* Query target */
Status = ZwQuerySymbolicLinkObject(LinkHandle, &LinkTarget, NULL); Status = ZwQuerySymbolicLinkObject(LinkHandle, &LinkTarget, NULL);
@ -1124,10 +1153,10 @@ IoAssignResources(
{ {
/* New drivers should not call this API */ /* New drivers should not call this API */
KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
0, 0x2,
0,
(ULONG_PTR)DeviceObject, (ULONG_PTR)DeviceObject,
(ULONG_PTR)DriverObject); (ULONG_PTR)DriverObject,
0);
} }
} }
@ -1217,10 +1246,16 @@ IoQueryDeviceDescription(
CalloutRoutine, Context, CalloutRoutine, Context,
&Query); &Query);
if (!BusType)
return STATUS_NOT_IMPLEMENTED;
/* Set up the string */ /* Set up the string */
RootRegKey.Length = 0; RootRegKey.Length = 0;
RootRegKey.MaximumLength = 2048; RootRegKey.MaximumLength = 2048;
RootRegKey.Buffer = ExAllocatePoolWithTag(PagedPool, RootRegKey.MaximumLength, TAG_IO_RESOURCE); RootRegKey.Buffer = ExAllocatePoolWithTag(PagedPool, RootRegKey.MaximumLength, TAG_IO_RESOURCE);
if (!RootRegKey.Buffer)
return STATUS_INSUFFICIENT_RESOURCES;
RtlAppendUnicodeToString(&RootRegKey, L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM"); RtlAppendUnicodeToString(&RootRegKey, L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
/* Open a handle to the Root Registry Key */ /* Open a handle to the Root Registry Key */