Windows下USB驱动基础知识
+ -

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

2021-08-30 509 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   

0 篇笔记 写笔记

Windows驱动中获取设备PDO的属性信息
Windows驱动开发过程中,关于设备DEVICE_OBJECT有一堆的属信息,如硬件ID,兼容ID之类的,这些属性信息大部分在应用层是可以根据Setup系列函数获取到的。但在驱动层怎么获取PNP上报的物理设备PDO的这些属性信息呢?常见的属性信息有: wdm.h:33601typedef en......
打印IRP_MJ_PNP所有子功能设备
PCHARPnPMinorFunctionString( UCHAR MinorFunction){ static char str[256]; switch (MinorFunction) { case IRP_MN_START_DEVICE: ......
USBIP 创建FDO设备和子设备PDO
设备创建由add_vdev函数实现,具体过程为:使用vdev_create创建FDO设备建立自己的设备链表将创建的FDO和PDO使用IoAttachDeviceToDeviceStack函数关联最后根据设备类型进行初始化设备层级及设备成员指针链表如下:static PAGEABLE NTST......
USBIP FDO和PDO设备类型及结构体大小
设备类型typedef enum { VDEV_ROOT,//虚拟根设备FDO VDEV_CPDO,//虚拟USB控制器PDO VDEV_VHCI,//USB控制器FDO VDEV_HPDO,//USB根HUB PDO VDEV_VHUB, //USB根HUB......
USBIP 虚拟控制器设备(VDEV_CPDO)PDO的初始化过程
IRP_MN_QUERY_ID/BusQueryDeviceIDPAGEABLE NTSTATUSpnp_query_id(pvdev_t vdev, PIRP irp, PIO_STACK_LOCATION irpstack){ NTSTATUS status = STATUS_......
USBIP 集线器PDO(VDEV_HPDO)的初始化过程
USB集线器其实也是USB设备的一类,其设备分类分类为0x09。和USBIP虚拟的控制器(VDEV_CPDO)类似,USB控制器创建了其PDO之后,会通过IRP_MN_QUERY_DEVICE_RELATIONS返回USB集线器HUB的PDO设备列表。PNP管理器收到有新的设备之后,会开始收集这个P......
USBIP 应用层初始化PDO设备
这里只是简单的介绍一下当有一个新的PDO设备需要创建时的执行流程。其功能函为usbip.exe工程中的attach_device函数。其大概原理如下:1.通过usbip_net_tcp_connect函数连接到远程设备的应用层。2.执行query_import_device,创建设备句柄并与双方进行......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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