mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:23:01 +00:00
Report to registry hardware found by Freeloader.
See issue #645 for more details. svn path=/trunk/; revision=24124
This commit is contained in:
parent
eccbefcccb
commit
7ac40876f4
1 changed files with 348 additions and 1 deletions
|
@ -32,6 +32,8 @@ IopSetRootDeviceInstanceData(PDEVICE_NODE DeviceNode);
|
||||||
#pragma alloc_text(INIT, IopSetRootDeviceInstanceData)
|
#pragma alloc_text(INIT, IopSetRootDeviceInstanceData)
|
||||||
#pragma alloc_text(INIT, PnpInit)
|
#pragma alloc_text(INIT, PnpInit)
|
||||||
#pragma alloc_text(INIT, PnpInit2)
|
#pragma alloc_text(INIT, PnpInit2)
|
||||||
|
#pragma alloc_text(INIT, IopUpdateRootKey)
|
||||||
|
#pragma alloc_text(INIT, IopEnumerateDetectedDevices)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,6 +177,25 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
||||||
&Stack);
|
&Stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _INVALIDATE_DEVICE_RELATION_DATA
|
||||||
|
{
|
||||||
|
DEVICE_RELATION_TYPE Type;
|
||||||
|
PIO_WORKITEM WorkItem;
|
||||||
|
} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
NTAPI
|
||||||
|
IoInvalidateDeviceRelationsWorker(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
PINVALIDATE_DEVICE_RELATION_DATA Data = Context;
|
||||||
|
|
||||||
|
IopInvalidateDeviceRelations(IopGetDeviceNode(DeviceObject), Data->Type);
|
||||||
|
IoFreeWorkItem(Data->WorkItem);
|
||||||
|
ExFreePool(Data);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -183,7 +204,27 @@ STDCALL
|
||||||
IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
|
IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN DEVICE_RELATION_TYPE Type)
|
IN DEVICE_RELATION_TYPE Type)
|
||||||
{
|
{
|
||||||
IopInvalidateDeviceRelations(IopGetDeviceNode(DeviceObject), Type);
|
PIO_WORKITEM WorkItem;
|
||||||
|
PINVALIDATE_DEVICE_RELATION_DATA Data;
|
||||||
|
|
||||||
|
Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
|
||||||
|
if (!Data)
|
||||||
|
return;
|
||||||
|
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||||
|
if (!WorkItem)
|
||||||
|
{
|
||||||
|
ExFreePool(Data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data->Type = Type;
|
||||||
|
Data->WorkItem = WorkItem;
|
||||||
|
|
||||||
|
IoQueueWorkItem(
|
||||||
|
WorkItem,
|
||||||
|
IoInvalidateDeviceRelationsWorker,
|
||||||
|
DelayedWorkQueue,
|
||||||
|
Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2549,12 +2590,318 @@ PnpInit(VOID)
|
||||||
IopRootDeviceNode->PhysicalDeviceObject);
|
IopRootDeviceNode->PhysicalDeviceObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS INIT_FUNCTION
|
||||||
|
IopEnumerateDetectedDevices(
|
||||||
|
IN HANDLE hBaseKey,
|
||||||
|
IN PUNICODE_STRING RelativePath,
|
||||||
|
IN HANDLE hRootKey,
|
||||||
|
IN BOOLEAN EnumerateSubKeys)
|
||||||
|
{
|
||||||
|
UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
|
||||||
|
UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc");
|
||||||
|
UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE hDevicesKey = NULL;
|
||||||
|
HANDLE hDeviceKey = NULL;
|
||||||
|
HANDLE hLevel1Key, hLevel2Key = NULL;
|
||||||
|
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;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS");
|
||||||
|
UNICODE_STRING HardwareIdPci = RTL_CONSTANT_STRING(L"*PNP0A03");
|
||||||
|
static ULONG DeviceIndexPci = 0;
|
||||||
|
const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController");
|
||||||
|
UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501");
|
||||||
|
static ULONG DeviceIndexSerial = 0;
|
||||||
|
const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardPeripheral");
|
||||||
|
UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303");
|
||||||
|
static ULONG DeviceIndexKeyboard = 0;
|
||||||
|
const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerPeripheral");
|
||||||
|
UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13");
|
||||||
|
static ULONG DeviceIndexMouse = 0;
|
||||||
|
PUNICODE_STRING pHardwareId;
|
||||||
|
ULONG DeviceIndex = 0;
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, RelativePath, OBJ_KERNEL_HANDLE, hBaseKey, NULL);
|
||||||
|
Status = ZwOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 = pDeviceInformation->NameLength;
|
||||||
|
DeviceName.Buffer = pDeviceInformation->Name;
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_KERNEL_HANDLE, hDevicesKey, NULL);
|
||||||
|
Status = ZwOpenKey(
|
||||||
|
&hDeviceKey,
|
||||||
|
KEY_QUERY_VALUE + EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 = pDeviceInformation->NameLength;
|
||||||
|
DeviceName.Buffer = pDeviceInformation->Name;
|
||||||
|
|
||||||
|
Status = IopEnumerateDetectedDevices(hDeviceKey, &DeviceName, hRootKey, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read identifier */
|
||||||
|
Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
|
||||||
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
else if (pValueInformation->Type != REG_SZ)
|
||||||
|
{
|
||||||
|
DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign hardware id to this device */
|
||||||
|
ValueName.Length = ValueName.MaximumLength = 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 (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0)
|
||||||
|
{
|
||||||
|
pHardwareId = &HardwareIdPci;
|
||||||
|
DeviceIndex = DeviceIndexPci++;
|
||||||
|
}
|
||||||
|
else if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
|
||||||
|
{
|
||||||
|
pHardwareId = &HardwareIdSerial;
|
||||||
|
DeviceIndex = DeviceIndexSerial++;
|
||||||
|
}
|
||||||
|
else if (RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
|
||||||
|
{
|
||||||
|
pHardwareId = &HardwareIdKeyboard;
|
||||||
|
DeviceIndex = DeviceIndexKeyboard++;
|
||||||
|
}
|
||||||
|
else if (RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
|
||||||
|
{
|
||||||
|
pHardwareId = &HardwareIdMouse;
|
||||||
|
DeviceIndex = DeviceIndexMouse++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Unknown device */
|
||||||
|
DPRINT("Unknown device %wZ in %wZ\n", &ValueName, RelativePath);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the detected device to Root key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, pHardwareId, OBJ_KERNEL_HANDLE, hRootKey, NULL);
|
||||||
|
Status = ZwCreateKey(
|
||||||
|
&hLevel1Key,
|
||||||
|
KEY_CREATE_SUB_KEY,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_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,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_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, pHardwareId);
|
||||||
|
Status = ZwSetValueKey(hLevel2Key, &DeviceDescU, 0, REG_SZ, ValueName.Buffer, ValueName.MaximumLength);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
|
||||||
|
ZwDeleteKey(hLevel2Key);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
|
||||||
|
ZwDeleteKey(hLevel2Key);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextdevice:
|
||||||
|
if (hLevel2Key)
|
||||||
|
{
|
||||||
|
ZwClose(hLevel2Key);
|
||||||
|
hLevel2Key = NULL;
|
||||||
|
}
|
||||||
|
if (hDeviceKey)
|
||||||
|
{
|
||||||
|
ZwClose(hDeviceKey);
|
||||||
|
hDeviceKey = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hDevicesKey)
|
||||||
|
ZwClose(hDevicesKey);
|
||||||
|
if (hDeviceKey)
|
||||||
|
ZwClose(hDeviceKey);
|
||||||
|
if (pDeviceInformation)
|
||||||
|
ExFreePool(pDeviceInformation);
|
||||||
|
if (pValueInformation)
|
||||||
|
ExFreePool(pValueInformation);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS INIT_FUNCTION
|
||||||
|
IopUpdateRootKey(VOID)
|
||||||
|
{
|
||||||
|
UNICODE_STRING RootPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum\\Root");
|
||||||
|
UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE hRoot;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &RootPathU, OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||||
|
Status = ZwOpenKey(&hRoot, KEY_CREATE_SUB_KEY, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
Status = IopEnumerateDetectedDevices(
|
||||||
|
NULL,
|
||||||
|
&MultiKeyPathU,
|
||||||
|
hRoot,
|
||||||
|
TRUE);
|
||||||
|
ZwClose(hRoot);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
VOID INIT_FUNCTION
|
VOID INIT_FUNCTION
|
||||||
PnpInit2(VOID)
|
PnpInit2(VOID)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */
|
||||||
|
/* FIXME: this should be done only when ACPI is disabled or not present! */
|
||||||
|
Status = IopUpdateRootKey();
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
CPRINT("IopUpdateRootKey() failed\n");
|
||||||
|
KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set root device instance data */
|
/* Set root device instance data */
|
||||||
Status = IopSetRootDeviceInstanceData(IopRootDeviceNode);
|
Status = IopSetRootDeviceInstanceData(IopRootDeviceNode);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue