Windows驱动中获取设备PDO的属性信息
2021-08-30
604
0
Windows驱动开发过程中,关于设备DEVICE_OBJECT有一堆的属信息,如硬件ID,兼容ID之类的,这些属性信息大部分在应用层是可以根据Setup系列函数获取到的。但在驱动层怎么获取PNP上报的物理设备PDO的这些属性信息呢?
常见的属性信息有: wdm.h:33601
typedef enum {
DevicePropertyDeviceDescription = 0x0 | __string_type,
DevicePropertyHardwareID = 0x1 | __multiString_type,
DevicePropertyCompatibleIDs = 0x2 | __multiString_type,
DevicePropertyBootConfiguration = 0x3,
DevicePropertyBootConfigurationTranslated = 0x4,
DevicePropertyClassName = 0x5 | __string_type,
DevicePropertyClassGuid = 0x6 | __string_type,
DevicePropertyDriverKeyName = 0x7 | __string_type,
DevicePropertyManufacturer = 0x8 | __string_type,
DevicePropertyFriendlyName = 0x9 | __string_type,
DevicePropertyLocationInformation = 0xa | __string_type,
DevicePropertyPhysicalDeviceObjectName = 0xb | __string_type,
DevicePropertyBusTypeGuid = 0xc | __guid_type,
DevicePropertyLegacyBusType = 0xd,
DevicePropertyBusNumber = 0xe,
DevicePropertyEnumeratorName = 0xf | __string_type,
DevicePropertyAddress = 0x10,
DevicePropertyUINumber = 0x11,
DevicePropertyInstallState = 0x12,
DevicePropertyRemovalPolicy = 0x13,
DevicePropertyResourceRequirements = 0x14,
DevicePropertyAllocatedResources = 0x15,
DevicePropertyContainerID = 0x16 | __string_type
} DEVICE_REGISTRY_PROPERTY;
这其可以根据wdm提供的IoGetDeviceProperty函数来实现。我们对其进行封装:
static char *
reg_get_property(PDEVICE_OBJECT pdo, int property)
{
UNICODE_STRING prop_uni;
ANSI_STRING prop_ansi;
char *prop;
PWCHAR buf;
ULONG len;
NTSTATUS status;
if (pdo == NULL)
return NULL;
status = IoGetDeviceProperty(pdo, property, 0, NULL, &len);
if (status != STATUS_BUFFER_TOO_SMALL) {
DBGE(DBG_GENERAL, "reg_get_property: IoGetDeviceProperty failed to get size: status: %x\n", status);
return NULL;
}
buf = ExAllocatePoolWithTag(PagedPool, len + sizeof(WCHAR), USBIP_STUB_POOL_TAG);
if (buf == NULL) {
DBGE(DBG_GENERAL, "reg_get_property: out of memory\n");
return NULL;
}
status = IoGetDeviceProperty(pdo, property, len, buf, &len);
if (NT_ERROR(status)) {
DBGE(DBG_GENERAL, "reg_get_property: IoGetDeviceProperty failed: status: %x\n", status);
ExFreePool(buf);
return NULL;
}
buf[len / sizeof(WCHAR)] = L'\0';
RtlInitUnicodeString(&prop_uni, buf);
status = RtlUnicodeStringToAnsiString(&prop_ansi, &prop_uni, TRUE);
ExFreePool(buf);
if (NT_ERROR(status)) {
DBGE(DBG_GENERAL, "reg_get_property: failed to convert unicode string: status: %x\n", status);
return NULL;
}
prop = ExAllocatePoolWithTag(PagedPool, prop_ansi.Length + 1, USBIP_STUB_POOL_TAG);
if (prop == NULL) {
DBGE(DBG_GENERAL, "reg_get_property: out of memory\n");
RtlFreeAnsiString(&prop_ansi);
return NULL;
}
RtlCopyMemory(prop, prop_ansi.Buffer, prop_ansi.Length);
prop[prop_ansi.Length] = '\0';
RtlFreeAnsiString(&prop_ansi);
return prop;
}
测试代码:
//获取设备的硬件ID
reg_get_property(pdo, DevicePropertyHardwareID);
//获取设备的兼容ID
reg_get_property(pdo, DevicePropertyCompatibleIDs);
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936