https://git.reactos.org/?p=reactos.git;a=commitdiff;h=85ca8afb6038d15de75f7…
commit 85ca8afb6038d15de75f7af00a7f9d9035d520e1
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Wed May 10 20:31:10 2023 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat May 27 12:22:57 2023 +0200
[NTOS:PNP] IopEnumerateDetectedDevices(): General refactoring
CORE-18962
- Deduplicate a while-loop by adding one more recursive call.
- Add IopMapDetectedDeviceId() helper function with a structure
in order to reduce hardcoded constants and checks.
---
ntoskrnl/io/pnpmgr/pnpmap.c | 285 ++++++++++++++++++++++----------------------
1 file changed, 140 insertions(+), 145 deletions(-)
diff --git a/ntoskrnl/io/pnpmgr/pnpmap.c b/ntoskrnl/io/pnpmgr/pnpmap.c
index 613e95a20c6..36a7f5bbedf 100644
--- a/ntoskrnl/io/pnpmgr/pnpmap.c
+++ b/ntoskrnl/io/pnpmgr/pnpmap.c
@@ -12,8 +12,72 @@
#define NDEBUG
#include <debug.h>
+/* TYPES *********************************************************************/
+
+typedef struct _PNP_DETECT_IDENTIFIER_MAP
+{
+ PWSTR DetectId;
+ PWSTR PnPId;
+ ULONG Counter;
+} PNP_DETECT_IDENTIFIER_MAP;
+
+/* DATA **********************************************************************/
+
+static UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
+static UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
+static UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration
Data");
+static UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig");
+static UNICODE_STRING LogConfU = RTL_CONSTANT_STRING(L"LogConf");
+
+/* FIXME: There should be two sets of hardcoded PnP identifiers
+ * for the keyboard and pointer peripherals (see CORE-18963).
+ * They also can be parsed from a LegacyXlate sections of driver INF files.
+ */
+
+static
+PNP_DETECT_IDENTIFIER_MAP PnPMap[] =
+{
+ { L"SerialController", L"*PNP0501\0", 0 },
+ { L"KeyboardController", L"*PNP0303\0", 0 },
+#if defined(SARCH_PC98)
+ { L"PointerController", L"*nEC1F00\0", 0 },
+#else
+ { L"PointerController", L"*PNP0F13\0", 0 },
+#endif
+ { L"ParallelController", L"*PNP0400\0", 0 },
+ { L"FloppyDiskPeripheral", L"*PNP0700\0", 0 },
+ { NULL, NULL, 0 }
+};
+
/* FUNCTIONS *****************************************************************/
+static
+CODE_SEG("INIT")
+PWSTR
+IopMapDetectedDeviceId(
+ _In_ PUNICODE_STRING DetectId,
+ _Out_ PULONG DeviceIndex)
+{
+ ULONG i;
+ UNICODE_STRING CmpId;
+
+ if (!DetectId)
+ return NULL;
+
+ for (i = 0; PnPMap[i].DetectId; i++)
+ {
+ RtlInitUnicodeString(&CmpId, PnPMap[i].DetectId);
+
+ if (RtlCompareUnicodeString(DetectId, &CmpId, FALSE) == 0)
+ {
+ *DeviceIndex = PnPMap[i].Counter++;
+ break;
+ }
+ }
+
+ return PnPMap[i].PnPId;
+}
+
static
CODE_SEG("INIT")
NTSTATUS
@@ -22,62 +86,18 @@ IopEnumerateDetectedDevices(
_In_opt_ PUNICODE_STRING RelativePath,
_In_ HANDLE hRootKey,
_In_ BOOLEAN EnumerateSubKeys,
+ _In_opt_ PCM_FULL_RESOURCE_DESCRIPTOR BootResources,
+ _In_opt_ ULONG BootResourcesLength,
_In_ PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources,
_In_ ULONG ParentBootResourcesLength)
{
- UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
- UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
- UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration
Data");
- UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig");
- UNICODE_STRING LogConfU = RTL_CONSTANT_STRING(L"LogConf");
- OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hDevicesKey = NULL;
- HANDLE hDeviceKey = NULL;
- HANDLE hLevel1Key, hLevel2Key = NULL, hLogConf;
- UNICODE_STRING Level2NameU;
- WCHAR Level2Name[5];
- ULONG IndexDevice = 0;
- ULONG IndexSubKey;
+ ULONG KeyIndex = 0;
PKEY_BASIC_INFORMATION pDeviceInformation = NULL;
ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR);
- PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
- ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
- UNICODE_STRING DeviceName, ValueName;
- ULONG RequiredSize;
- PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL;
- ULONG BootResourcesLength;
NTSTATUS Status;
- const UNICODE_STRING IdentifierSerial =
RTL_CONSTANT_STRING(L"SerialController");
- UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0");
- static ULONG DeviceIndexSerial = 0;
- const UNICODE_STRING IdentifierKeyboard =
RTL_CONSTANT_STRING(L"KeyboardController");
- UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0");
- static ULONG DeviceIndexKeyboard = 0;
- const UNICODE_STRING IdentifierMouse =
RTL_CONSTANT_STRING(L"PointerController");
- /* FIXME: IopEnumerateDetectedDevices() should be rewritten.
- * The PnP identifiers can either be hardcoded or parsed from a LegacyXlate
- * sections of driver INF files.
- */
-#if defined(SARCH_PC98)
- UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*nEC1F00\0");
-#else
- UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
-#endif
- static ULONG DeviceIndexMouse = 0;
- const UNICODE_STRING IdentifierParallel =
RTL_CONSTANT_STRING(L"ParallelController");
- UNICODE_STRING HardwareIdParallel = RTL_CONSTANT_STRING(L"*PNP0400\0");
- static ULONG DeviceIndexParallel = 0;
- const UNICODE_STRING IdentifierFloppy =
RTL_CONSTANT_STRING(L"FloppyDiskPeripheral");
- UNICODE_STRING HardwareIdFloppy = RTL_CONSTANT_STRING(L"*PNP0700\0");
- static ULONG DeviceIndexFloppy = 0;
- UNICODE_STRING HardwareIdKey;
- PUNICODE_STRING pHardwareId;
- ULONG DeviceIndex = 0;
- PUCHAR CmResourceList;
- ULONG ListCount;
-
- if (RelativePath)
+ if (!BootResources && RelativePath)
{
Status = IopOpenRegistryKeyEx(&hDevicesKey, hBaseKey, RelativePath,
KEY_ENUMERATE_SUB_KEYS);
@@ -98,18 +118,24 @@ IopEnumerateDetectedDevices(
goto cleanup;
}
- pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
- if (!pValueInformation)
- {
- DPRINT("ExAllocatePool() failed\n");
- Status = STATUS_NO_MEMORY;
- goto cleanup;
- }
-
while (TRUE)
{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hDeviceKey = NULL;
+ HANDLE hLevel1Key, hLevel2Key = NULL, hLogConf;
+ UNICODE_STRING Level2NameU;
+ WCHAR Level2Name[5];
+ PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
+ ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 *
sizeof(WCHAR);
+ UNICODE_STRING DeviceName, ValueName;
+ ULONG RequiredSize;
+
+ UNICODE_STRING HardwareIdKey;
+ PWSTR pHardwareId;
+ ULONG DeviceIndex = 0;
+
Status = ZwEnumerateKey(hDevicesKey,
- IndexDevice,
+ KeyIndex,
KeyBasicInformation,
pDeviceInformation,
DeviceInfoLength,
@@ -130,7 +156,12 @@ IopEnumerateDetectedDevices(
goto cleanup;
}
- Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation,
pDeviceInformation, DeviceInfoLength, &RequiredSize);
+ Status = ZwEnumerateKey(hDevicesKey,
+ KeyIndex,
+ KeyBasicInformation,
+ pDeviceInformation,
+ DeviceInfoLength,
+ &RequiredSize);
}
if (!NT_SUCCESS(Status))
@@ -138,12 +169,38 @@ IopEnumerateDetectedDevices(
DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
goto cleanup;
}
- IndexDevice++;
+ KeyIndex++;
/* Open device key */
DeviceName.Length = DeviceName.MaximumLength =
(USHORT)pDeviceInformation->NameLength;
DeviceName.Buffer = pDeviceInformation->Name;
+ if (BootResources)
+ {
+ Status = IopEnumerateDetectedDevices(
+ hDevicesKey,
+ &DeviceName,
+ hRootKey,
+ TRUE,
+ NULL,
+ 0,
+ BootResources,
+ BootResourcesLength);
+
+ if (!NT_SUCCESS(Status))
+ goto cleanup;
+
+ continue;
+ }
+
+ pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
+ if (!pValueInformation)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+
Status = IopOpenRegistryKeyEx(&hDeviceKey, hDevicesKey, &DeviceName,
KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0));
@@ -247,60 +304,18 @@ IopEnumerateDetectedDevices(
if (EnumerateSubKeys)
{
- IndexSubKey = 0;
+ Status = IopEnumerateDetectedDevices(
+ hDeviceKey,
+ RelativePath,
+ hRootKey,
+ TRUE,
+ BootResources,
+ BootResourcesLength,
+ ParentBootResources,
+ ParentBootResourcesLength);
- while (TRUE)
- {
- Status = ZwEnumerateKey(hDeviceKey,
- IndexSubKey,
- KeyBasicInformation,
- pDeviceInformation,
- DeviceInfoLength,
- &RequiredSize);
-
- if (Status == STATUS_NO_MORE_ENTRIES)
- break;
- else if (Status == STATUS_BUFFER_OVERFLOW || Status ==
STATUS_BUFFER_TOO_SMALL)
- {
- ExFreePool(pDeviceInformation);
- DeviceInfoLength = RequiredSize;
- pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
-
- if (!pDeviceInformation)
- {
- DPRINT("ExAllocatePool() failed\n");
- Status = STATUS_NO_MEMORY;
- goto cleanup;
- }
-
- Status = ZwEnumerateKey(hDeviceKey,
- IndexSubKey,
- KeyBasicInformation,
- pDeviceInformation,
- DeviceInfoLength,
- &RequiredSize);
- }
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n",
Status);
- goto cleanup;
- }
- IndexSubKey++;
- DeviceName.Length = DeviceName.MaximumLength =
(USHORT)pDeviceInformation->NameLength;
- DeviceName.Buffer = pDeviceInformation->Name;
-
- Status = IopEnumerateDetectedDevices(
- hDeviceKey,
- &DeviceName,
- hRootKey,
- TRUE,
- BootResources,
- BootResourcesLength);
-
- if (!NT_SUCCESS(Status))
- goto cleanup;
- }
+ if (!NT_SUCCESS(Status))
+ goto cleanup;
}
/* Read identifier */
@@ -355,32 +370,8 @@ IopEnumerateDetectedDevices(
ValueName.Length -= sizeof(WCHAR);
}
- if (RelativePath && RtlCompareUnicodeString(RelativePath,
&IdentifierSerial, FALSE) == 0)
- {
- pHardwareId = &HardwareIdSerial;
- DeviceIndex = DeviceIndexSerial++;
- }
- else if (RelativePath && RtlCompareUnicodeString(RelativePath,
&IdentifierKeyboard, FALSE) == 0)
- {
- pHardwareId = &HardwareIdKeyboard;
- DeviceIndex = DeviceIndexKeyboard++;
- }
- else if (RelativePath && RtlCompareUnicodeString(RelativePath,
&IdentifierMouse, FALSE) == 0)
- {
- pHardwareId = &HardwareIdMouse;
- DeviceIndex = DeviceIndexMouse++;
- }
- else if (RelativePath && RtlCompareUnicodeString(RelativePath,
&IdentifierParallel, FALSE) == 0)
- {
- pHardwareId = &HardwareIdParallel;
- DeviceIndex = DeviceIndexParallel++;
- }
- else if (RelativePath && RtlCompareUnicodeString(RelativePath,
&IdentifierFloppy, FALSE) == 0)
- {
- pHardwareId = &HardwareIdFloppy;
- DeviceIndex = DeviceIndexFloppy++;
- }
- else
+ pHardwareId = IopMapDetectedDeviceId(RelativePath, &DeviceIndex);
+ if (!pHardwareId)
{
/* Unknown key path */
DPRINT("Unknown key path '%wZ'\n", RelativePath);
@@ -388,8 +379,9 @@ IopEnumerateDetectedDevices(
}
/* Prepare hardware id key (hardware id value without final \0) */
- HardwareIdKey = *pHardwareId;
- HardwareIdKey.Length -= sizeof(UNICODE_NULL);
+ HardwareIdKey.Length = wcslen(pHardwareId) * sizeof(WCHAR);
+ HardwareIdKey.MaximumLength = HardwareIdKey.Length + sizeof(UNICODE_NULL) * 2;
+ HardwareIdKey.Buffer = pHardwareId;
/* Add the detected device to Root key */
InitializeObjectAttributes(&ObjectAttributes, &HardwareIdKey,
OBJ_KERNEL_HANDLE, hRootKey, NULL);
@@ -430,7 +422,7 @@ IopEnumerateDetectedDevices(
}
DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex,
&HardwareIdKey);
- Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ,
pHardwareId->Buffer, pHardwareId->MaximumLength);
+ Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ,
HardwareIdKey.Buffer, HardwareIdKey.MaximumLength);
if (!NT_SUCCESS(Status))
{
@@ -460,6 +452,9 @@ IopEnumerateDetectedDevices(
if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
{
+ PUCHAR CmResourceList;
+ ULONG ListCount;
+
CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength +
sizeof(ULONG));
if (!CmResourceList)
{
@@ -515,6 +510,8 @@ nextdevice:
ZwClose(hDeviceKey);
hDeviceKey = NULL;
}
+ if (pValueInformation)
+ ExFreePool(pValueInformation);
}
Status = STATUS_SUCCESS;
@@ -522,12 +519,8 @@ nextdevice:
cleanup:
if (hDevicesKey && hDevicesKey != hBaseKey)
ZwClose(hDevicesKey);
- if (hDeviceKey)
- ZwClose(hDeviceKey);
if (pDeviceInformation)
ExFreePool(pDeviceInformation);
- if (pValueInformation)
- ExFreePool(pValueInformation);
return Status;
}
@@ -647,6 +640,8 @@ IopUpdateRootKey(VOID)
hRoot,
TRUE,
NULL,
+ 0,
+ NULL,
0);
ZwClose(hEnum);
}