https://git.reactos.org/?p=reactos.git;a=commitdiff;h=484c26d99fea3ee24796a2...
commit 484c26d99fea3ee24796a27aa0b49c0c37dd3024 Author: Stanislav Motylkov x86corez@gmail.com AuthorDate: Mon May 8 15:49:46 2023 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Mon May 8 16:07:01 2023 +0200
[NTOS:PNP] Move Firmware Mapper functions into new file CORE-18962 --- ntoskrnl/io/pnpmgr/pnpmap.c | 585 ++++++++++++++++++++++++++++++++++++++++++++ ntoskrnl/io/pnpmgr/pnpmgr.c | 570 ------------------------------------------ ntoskrnl/ntos.cmake | 1 + 3 files changed, 586 insertions(+), 570 deletions(-)
diff --git a/ntoskrnl/io/pnpmgr/pnpmap.c b/ntoskrnl/io/pnpmgr/pnpmap.c new file mode 100644 index 00000000000..795e4a3c2ce --- /dev/null +++ b/ntoskrnl/io/pnpmgr/pnpmap.c @@ -0,0 +1,585 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: PnP manager Firmware Mapper functions + * COPYRIGHT: Copyright 2006-2007 Hervé Poussineau hpoussin@reactos.org + * Copyright 2008-2011 Cameron Gutman cameron.gutman@reactos.org + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* FUNCTIONS *****************************************************************/ + +static +CODE_SEG("INIT") +NTSTATUS +IopEnumerateDetectedDevices( + IN HANDLE hBaseKey, + IN PUNICODE_STRING RelativePath OPTIONAL, + IN HANDLE hRootKey, + IN BOOLEAN EnumerateSubKeys, + 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; + 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) + { + Status = IopOpenRegistryKeyEx(&hDevicesKey, hBaseKey, RelativePath, KEY_ENUMERATE_SUB_KEYS); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + } + else + hDevicesKey = hBaseKey; + + pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength); + if (!pDeviceInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + while (TRUE) + { + Status = ZwEnumerateKey(hDevicesKey, IndexDevice, 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(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + IndexDevice++; + + /* Open device key */ + DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength; + DeviceName.Buffer = pDeviceInformation->Name; + + Status = IopOpenRegistryKeyEx(&hDeviceKey, hDevicesKey, &DeviceName, + KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + /* Read boot resources, and add then to parent ones */ + Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + ExFreePool(pValueInformation); + ValueInfoLength = RequiredSize; + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + ZwDeleteKey(hLevel2Key); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + } + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + BootResources = ParentBootResources; + BootResourcesLength = ParentBootResourcesLength; + } + else if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR) + { + DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR); + goto nextdevice; + } + else + { + static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors); + + /* Concatenate current resources and parent ones */ + if (ParentBootResourcesLength == 0) + BootResourcesLength = pValueInformation->DataLength; + else + BootResourcesLength = ParentBootResourcesLength + + pValueInformation->DataLength + - Header; + BootResources = ExAllocatePool(PagedPool, BootResourcesLength); + if (!BootResources) + { + DPRINT("ExAllocatePool() failed\n"); + goto nextdevice; + } + if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) + { + RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); + } + else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific) + { + RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength), + (PVOID)((ULONG_PTR)ParentBootResources + Header), + ParentBootResourcesLength - Header); + BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count; + } + else + { + RtlCopyMemory(BootResources, pValueInformation->Data, Header); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + Header), + (PVOID)((ULONG_PTR)ParentBootResources + Header), + ParentBootResourcesLength - Header); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength), + pValueInformation->Data + Header, + pValueInformation->DataLength - Header); + BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count; + } + } + + if (EnumerateSubKeys) + { + IndexSubKey = 0; + 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; + } + } + + /* Read identifier */ + Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + ExFreePool(pValueInformation); + ValueInfoLength = RequiredSize; + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + if (Status != STATUS_OBJECT_NAME_NOT_FOUND) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + ValueName.Length = ValueName.MaximumLength = 0; + } + else if (pValueInformation->Type != REG_SZ) + { + DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); + goto nextdevice; + } + else + { + /* Assign hardware id to this device */ + ValueName.Length = ValueName.MaximumLength = (USHORT)pValueInformation->DataLength; + ValueName.Buffer = (PWCHAR)pValueInformation->Data; + if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) + 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 + { + /* Unknown key path */ + DPRINT("Unknown key path '%wZ'\n", RelativePath); + goto nextdevice; + } + + /* Prepare hardware id key (hardware id value without final \0) */ + HardwareIdKey = *pHardwareId; + HardwareIdKey.Length -= sizeof(UNICODE_NULL); + + /* Add the detected device to Root key */ + InitializeObjectAttributes(&ObjectAttributes, &HardwareIdKey, OBJ_KERNEL_HANDLE, hRootKey, NULL); + Status = ZwCreateKey( + &hLevel1Key, + KEY_CREATE_SUB_KEY, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + swprintf(Level2Name, L"%04lu", DeviceIndex); + RtlInitUnicodeString(&Level2NameU, Level2Name); + InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL); + Status = ZwCreateKey( + &hLevel2Key, + KEY_SET_VALUE | KEY_CREATE_SUB_KEY, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + NULL); + ZwClose(hLevel1Key); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey); + Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + /* Create 'LogConf' subkey */ + InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL); + Status = ZwCreateKey( + &hLogConf, + KEY_SET_VALUE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) + { + CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG)); + if (!CmResourceList) + { + ZwClose(hLogConf); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + + /* Add the list count (1st member of CM_RESOURCE_LIST) */ + ListCount = 1; + RtlCopyMemory(CmResourceList, + &ListCount, + sizeof(ULONG)); + + /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */ + RtlCopyMemory(CmResourceList + sizeof(ULONG), + BootResources, + BootResourcesLength); + + /* Save boot resources to 'LogConf\BootConfig' */ + Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); + ZwClose(hLogConf); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + } + ZwClose(hLogConf); + +nextdevice: + if (BootResources && BootResources != ParentBootResources) + { + ExFreePool(BootResources); + BootResources = NULL; + } + if (hLevel2Key) + { + ZwClose(hLevel2Key); + hLevel2Key = NULL; + } + if (hDeviceKey) + { + ZwClose(hDeviceKey); + hDeviceKey = NULL; + } + } + + Status = STATUS_SUCCESS; + +cleanup: + if (hDevicesKey && hDevicesKey != hBaseKey) + ZwClose(hDevicesKey); + if (hDeviceKey) + ZwClose(hDeviceKey); + if (pDeviceInformation) + ExFreePool(pDeviceInformation); + if (pValueInformation) + ExFreePool(pValueInformation); + return Status; +} + +static +CODE_SEG("INIT") +BOOLEAN +IopIsFirmwareMapperDisabled(VOID) +{ + UNICODE_STRING KeyPathU = RTL_CONSTANT_STRING(L"\Registry\Machine\SYSTEM\CURRENTCONTROLSET\Control\Pnp"); + UNICODE_STRING KeyNameU = RTL_CONSTANT_STRING(L"DisableFirmwareMapper"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hPnpKey; + PKEY_VALUE_PARTIAL_INFORMATION KeyInformation; + ULONG DesiredLength, Length; + ULONG KeyValue = 0; + NTSTATUS Status; + + InitializeObjectAttributes(&ObjectAttributes, &KeyPathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); + Status = ZwOpenKey(&hPnpKey, KEY_QUERY_VALUE, &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + Status = ZwQueryValueKey(hPnpKey, + &KeyNameU, + KeyValuePartialInformation, + NULL, + 0, + &DesiredLength); + if ((Status == STATUS_BUFFER_TOO_SMALL) || + (Status == STATUS_BUFFER_OVERFLOW)) + { + Length = DesiredLength; + KeyInformation = ExAllocatePool(PagedPool, Length); + if (KeyInformation) + { + Status = ZwQueryValueKey(hPnpKey, + &KeyNameU, + KeyValuePartialInformation, + KeyInformation, + Length, + &DesiredLength); + if (NT_SUCCESS(Status) && KeyInformation->DataLength == sizeof(ULONG)) + { + KeyValue = (ULONG)(*KeyInformation->Data); + } + else + { + DPRINT1("ZwQueryValueKey(%wZ%wZ) failed\n", &KeyPathU, &KeyNameU); + } + + ExFreePool(KeyInformation); + } + else + { + DPRINT1("Failed to allocate memory for registry query\n"); + } + } + else + { + DPRINT1("ZwQueryValueKey(%wZ%wZ) failed with status 0x%08lx\n", &KeyPathU, &KeyNameU, Status); + } + + ZwClose(hPnpKey); + } + else + { + DPRINT1("ZwOpenKey(%wZ) failed with status 0x%08lx\n", &KeyPathU, Status); + } + + DPRINT("Firmware mapper is %s\n", KeyValue != 0 ? "disabled" : "enabled"); + + return (KeyValue != 0) ? TRUE : FALSE; +} + +CODE_SEG("INIT") +NTSTATUS +NTAPI +IopUpdateRootKey(VOID) +{ + UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\Registry\Machine\SYSTEM\CurrentControlSet\Enum"); + UNICODE_STRING RootPathU = RTL_CONSTANT_STRING(L"Root"); + UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\Registry\Machine\HARDWARE\DESCRIPTION\System\MultifunctionAdapter"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hEnum, hRoot; + NTSTATUS Status; + + InitializeObjectAttributes(&ObjectAttributes, &EnumU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); + Status = ZwCreateKey(&hEnum, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwCreateKey() failed with status 0x%08lx\n", Status); + return Status; + } + + InitializeObjectAttributes(&ObjectAttributes, &RootPathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hEnum, NULL); + Status = ZwCreateKey(&hRoot, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); + ZwClose(hEnum); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status); + return Status; + } + + if (!IopIsFirmwareMapperDisabled()) + { + Status = IopOpenRegistryKeyEx(&hEnum, NULL, &MultiKeyPathU, KEY_ENUMERATE_SUB_KEYS); + if (!NT_SUCCESS(Status)) + { + /* Nothing to do, don't return with an error status */ + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + ZwClose(hRoot); + return STATUS_SUCCESS; + } + Status = IopEnumerateDetectedDevices( + hEnum, + NULL, + hRoot, + TRUE, + NULL, + 0); + ZwClose(hEnum); + } + else + { + /* Enumeration is disabled */ + Status = STATUS_SUCCESS; + } + + ZwClose(hRoot); + + return Status; +} diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 87bf857e9fc..2b92983a9a0 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -880,576 +880,6 @@ cleanup: return Status; }
-static -CODE_SEG("INIT") -NTSTATUS -IopEnumerateDetectedDevices( - IN HANDLE hBaseKey, - IN PUNICODE_STRING RelativePath OPTIONAL, - IN HANDLE hRootKey, - IN BOOLEAN EnumerateSubKeys, - 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; - 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) - { - Status = IopOpenRegistryKeyEx(&hDevicesKey, hBaseKey, RelativePath, KEY_ENUMERATE_SUB_KEYS); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - } - else - hDevicesKey = hBaseKey; - - pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength); - if (!pDeviceInformation) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_NO_MEMORY; - goto cleanup; - } - - pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); - if (!pValueInformation) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_NO_MEMORY; - goto cleanup; - } - - while (TRUE) - { - Status = ZwEnumerateKey(hDevicesKey, IndexDevice, 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(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); - } - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - IndexDevice++; - - /* Open device key */ - DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength; - DeviceName.Buffer = pDeviceInformation->Name; - - Status = IopOpenRegistryKeyEx(&hDeviceKey, hDevicesKey, &DeviceName, - KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0)); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - /* Read boot resources, and add then to parent ones */ - Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); - if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) - { - ExFreePool(pValueInformation); - ValueInfoLength = RequiredSize; - pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); - if (!pValueInformation) - { - DPRINT("ExAllocatePool() failed\n"); - ZwDeleteKey(hLevel2Key); - Status = STATUS_NO_MEMORY; - goto cleanup; - } - Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); - } - if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - { - BootResources = ParentBootResources; - BootResourcesLength = ParentBootResourcesLength; - } - else if (!NT_SUCCESS(Status)) - { - DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); - goto nextdevice; - } - else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR) - { - DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR); - goto nextdevice; - } - else - { - static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors); - - /* Concatenate current resources and parent ones */ - if (ParentBootResourcesLength == 0) - BootResourcesLength = pValueInformation->DataLength; - else - BootResourcesLength = ParentBootResourcesLength - + pValueInformation->DataLength - - Header; - BootResources = ExAllocatePool(PagedPool, BootResourcesLength); - if (!BootResources) - { - DPRINT("ExAllocatePool() failed\n"); - goto nextdevice; - } - if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) - { - RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); - } - else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific) - { - RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); - RtlCopyMemory( - (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength), - (PVOID)((ULONG_PTR)ParentBootResources + Header), - ParentBootResourcesLength - Header); - BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count; - } - else - { - RtlCopyMemory(BootResources, pValueInformation->Data, Header); - RtlCopyMemory( - (PVOID)((ULONG_PTR)BootResources + Header), - (PVOID)((ULONG_PTR)ParentBootResources + Header), - ParentBootResourcesLength - Header); - RtlCopyMemory( - (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength), - pValueInformation->Data + Header, - pValueInformation->DataLength - Header); - BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count; - } - } - - if (EnumerateSubKeys) - { - IndexSubKey = 0; - 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; - } - } - - /* Read identifier */ - Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); - if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) - { - ExFreePool(pValueInformation); - ValueInfoLength = RequiredSize; - pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); - if (!pValueInformation) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_NO_MEMORY; - goto cleanup; - } - Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); - } - if (!NT_SUCCESS(Status)) - { - if (Status != STATUS_OBJECT_NAME_NOT_FOUND) - { - DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); - goto nextdevice; - } - ValueName.Length = ValueName.MaximumLength = 0; - } - else if (pValueInformation->Type != REG_SZ) - { - DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); - goto nextdevice; - } - else - { - /* Assign hardware id to this device */ - ValueName.Length = ValueName.MaximumLength = (USHORT)pValueInformation->DataLength; - ValueName.Buffer = (PWCHAR)pValueInformation->Data; - if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) - 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 - { - /* Unknown key path */ - DPRINT("Unknown key path '%wZ'\n", RelativePath); - goto nextdevice; - } - - /* Prepare hardware id key (hardware id value without final \0) */ - HardwareIdKey = *pHardwareId; - HardwareIdKey.Length -= sizeof(UNICODE_NULL); - - /* Add the detected device to Root key */ - InitializeObjectAttributes(&ObjectAttributes, &HardwareIdKey, OBJ_KERNEL_HANDLE, hRootKey, NULL); - Status = ZwCreateKey( - &hLevel1Key, - KEY_CREATE_SUB_KEY, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); - goto nextdevice; - } - swprintf(Level2Name, L"%04lu", DeviceIndex); - RtlInitUnicodeString(&Level2NameU, Level2Name); - InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL); - Status = ZwCreateKey( - &hLevel2Key, - KEY_SET_VALUE | KEY_CREATE_SUB_KEY, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); - ZwClose(hLevel1Key); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); - goto nextdevice; - } - DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey); - Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - /* Create 'LogConf' subkey */ - InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL); - Status = ZwCreateKey( - &hLogConf, - KEY_SET_VALUE, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) - { - CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG)); - if (!CmResourceList) - { - ZwClose(hLogConf); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - - /* Add the list count (1st member of CM_RESOURCE_LIST) */ - ListCount = 1; - RtlCopyMemory(CmResourceList, - &ListCount, - sizeof(ULONG)); - - /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */ - RtlCopyMemory(CmResourceList + sizeof(ULONG), - BootResources, - BootResourcesLength); - - /* Save boot resources to 'LogConf\BootConfig' */ - Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG)); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); - ZwClose(hLogConf); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - } - ZwClose(hLogConf); - -nextdevice: - if (BootResources && BootResources != ParentBootResources) - { - ExFreePool(BootResources); - BootResources = NULL; - } - if (hLevel2Key) - { - ZwClose(hLevel2Key); - hLevel2Key = NULL; - } - if (hDeviceKey) - { - ZwClose(hDeviceKey); - hDeviceKey = NULL; - } - } - - Status = STATUS_SUCCESS; - -cleanup: - if (hDevicesKey && hDevicesKey != hBaseKey) - ZwClose(hDevicesKey); - if (hDeviceKey) - ZwClose(hDeviceKey); - if (pDeviceInformation) - ExFreePool(pDeviceInformation); - if (pValueInformation) - ExFreePool(pValueInformation); - return Status; -} - -static -CODE_SEG("INIT") -BOOLEAN -IopIsFirmwareMapperDisabled(VOID) -{ - UNICODE_STRING KeyPathU = RTL_CONSTANT_STRING(L"\Registry\Machine\SYSTEM\CURRENTCONTROLSET\Control\Pnp"); - UNICODE_STRING KeyNameU = RTL_CONSTANT_STRING(L"DisableFirmwareMapper"); - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hPnpKey; - PKEY_VALUE_PARTIAL_INFORMATION KeyInformation; - ULONG DesiredLength, Length; - ULONG KeyValue = 0; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, &KeyPathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwOpenKey(&hPnpKey, KEY_QUERY_VALUE, &ObjectAttributes); - if (NT_SUCCESS(Status)) - { - Status = ZwQueryValueKey(hPnpKey, - &KeyNameU, - KeyValuePartialInformation, - NULL, - 0, - &DesiredLength); - if ((Status == STATUS_BUFFER_TOO_SMALL) || - (Status == STATUS_BUFFER_OVERFLOW)) - { - Length = DesiredLength; - KeyInformation = ExAllocatePool(PagedPool, Length); - if (KeyInformation) - { - Status = ZwQueryValueKey(hPnpKey, - &KeyNameU, - KeyValuePartialInformation, - KeyInformation, - Length, - &DesiredLength); - if (NT_SUCCESS(Status) && KeyInformation->DataLength == sizeof(ULONG)) - { - KeyValue = (ULONG)(*KeyInformation->Data); - } - else - { - DPRINT1("ZwQueryValueKey(%wZ%wZ) failed\n", &KeyPathU, &KeyNameU); - } - - ExFreePool(KeyInformation); - } - else - { - DPRINT1("Failed to allocate memory for registry query\n"); - } - } - else - { - DPRINT1("ZwQueryValueKey(%wZ%wZ) failed with status 0x%08lx\n", &KeyPathU, &KeyNameU, Status); - } - - ZwClose(hPnpKey); - } - else - { - DPRINT1("ZwOpenKey(%wZ) failed with status 0x%08lx\n", &KeyPathU, Status); - } - - DPRINT("Firmware mapper is %s\n", KeyValue != 0 ? "disabled" : "enabled"); - - return (KeyValue != 0) ? TRUE : FALSE; -} - -CODE_SEG("INIT") -NTSTATUS -NTAPI -IopUpdateRootKey(VOID) -{ - UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\Registry\Machine\SYSTEM\CurrentControlSet\Enum"); - UNICODE_STRING RootPathU = RTL_CONSTANT_STRING(L"Root"); - UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\Registry\Machine\HARDWARE\DESCRIPTION\System\MultifunctionAdapter"); - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hEnum, hRoot; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, &EnumU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwCreateKey(&hEnum, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ZwCreateKey() failed with status 0x%08lx\n", Status); - return Status; - } - - InitializeObjectAttributes(&ObjectAttributes, &RootPathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hEnum, NULL); - Status = ZwCreateKey(&hRoot, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); - ZwClose(hEnum); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status); - return Status; - } - - if (!IopIsFirmwareMapperDisabled()) - { - Status = IopOpenRegistryKeyEx(&hEnum, NULL, &MultiKeyPathU, KEY_ENUMERATE_SUB_KEYS); - if (!NT_SUCCESS(Status)) - { - /* Nothing to do, don't return with an error status */ - DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); - ZwClose(hRoot); - return STATUS_SUCCESS; - } - Status = IopEnumerateDetectedDevices( - hEnum, - NULL, - hRoot, - TRUE, - NULL, - 0); - ZwClose(hEnum); - } - else - { - /* Enumeration is disabled */ - Status = STATUS_SUCCESS; - } - - ZwClose(hRoot); - - return Status; -} - NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake index 60d4436a438..dddb6cae4ab 100644 --- a/ntoskrnl/ntos.cmake +++ b/ntoskrnl/ntos.cmake @@ -157,6 +157,7 @@ list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpdma.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpinit.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpirp.c + ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpmap.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpmgr.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpnotify.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpreport.c