Windows下USB驱动获取USB设备各种描述符代码函数封装

12 0 2021-06-29 本文地址:http://www.usbzh.com/fun/detail-32.html

USB设备的一个种要的概念就是各种描述符,如设备描述符,配置描述符,字符串描述符等等。
在设备驱动驱动开发中,通过读取这些描述符可以知道该USB设备的相关信息。
这里我们对在Windows驱动开发过程的获取USB设备的描述符进行代码封装成函数GetDescriptor。

NTSTATUS GetDescriptor(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR DescriptorType,
    IN ULONG DescriptorLength,
    IN UCHAR DescriptorIndex,
    IN LANGID LanguageId,
    OUT PVOID* OutDescriptor)
{
    PURB Urb;
    NTSTATUS Status;
    PVOID Descriptor;

    ASSERT(DeviceObject != NULL);
    ASSERT(OutDescriptor != NULL);
    ASSERT(DescriptorLength != 0);   

    Descriptor = ExAllocatePool(NonPagedPool, DescriptorLength);
    if (!Descriptor)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlZeroMemory(Descriptor, DescriptorLength);

    Urb = (PURB)ExAllocatePool(NonPagedPool, sizeof(URB));
    if (Urb == NULL)
    {
        ExFreePool(Descriptor);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    UsbBuildGetDescriptorRequest(Urb,
        sizeof(Urb->UrbControlDescriptorRequest),
        DescriptorType,
        DescriptorIndex,
        LanguageId,
        Descriptor,
        NULL,
        DescriptorLength,
        NULL);


    Status = SyncUrbRequest(DeviceObject, Urb);
    ExFreePool(Urb);
    if (NT_SUCCESS(Status))
    {
#pragma warning(disable:6011)
        *OutDescriptor = (PVOID)Descriptor;
#pragma warning(default:6011)
    }

    return Status;
}

可以看到,该函数使用了我们前面封装的通用URB转IRP请求函数SyncUrbRequest,其相关代码见:http://www.usbzh.com/fun/detail-31.html

GetDescriptor函数的参数不多,第一个为下层设备对象,其次为设备的描述符类型,长度,后面的DescriptorIndex和LanguageId仅对字符串有效,最后输出的是该描述符的指针。

测试代码

这里我们通过GetAllDescriptor获取USB设备的设备描述符和配置描述符。

设备描述符是通过2次获取的。


NTSTATUS GetAllDescriptor(
    IN PDEVICE_OBJECT DeviceObject
)
{
    NTSTATUS Status;
    PFDO_DEVICE_EXTENSION DeviceExtension;
    USHORT DescriptorLength;

    DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    //
    // 1.0 first get device descriptor
    //
    Status = GetDescriptor(DeviceExtension->NextDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
    if (!NT_SUCCESS(Status))
    {
        //
        // failed to get device descriptor
        //
        DeviceExtension->DeviceDescriptor = NULL;
        return Status;
    }

    //
    // 2.0 now get basic configuration descriptor
    //
    Status = GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
    if (!NT_SUCCESS(Status))
    {
        ExFreePool(DeviceExtension->DeviceDescriptor);
        DeviceExtension->DeviceDescriptor = NULL;
        return Status;
    }

    DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;

    //
    // release basic descriptor
    //
    ExFreePool(DeviceExtension->ConfigurationDescriptor);
    DeviceExtension->ConfigurationDescriptor = NULL;

    /* 2.1 allocate full descriptor */
    Status = GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
    if (!NT_SUCCESS(Status))
    {
        ExFreePool(DeviceExtension->DeviceDescriptor);
        DeviceExtension->DeviceDescriptor = NULL;
        return Status;
    }

    return Status;
}
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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