Windows驱动中获取设备PDO的属性信息

41 0 2021-06-24 本文地址:http://www.usbzh.com/fun/detail-30.html

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);
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!