USB通用驱动源码分析
+ -

USBCCGP 分发函数

2021-09-15 378 0

通过上一节知道,USBCCGAP将所有的IRP都会发到USBCCGP_Dispatch函数中。
其代码如下:

usbccgp.c

NTSTATUS
NTAPI
USBCCGP_Dispatch(
    PDEVICE_OBJECT DeviceObject, 
    PIRP Irp)
{
    PCOMMON_DEVICE_EXTENSION DeviceExtension;
    PIO_STACK_LOCATION IoStack;

    /* Get common device extension */
    DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    /* Get current stack location */
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    if (IoStack->MajorFunction == IRP_MJ_CREATE || IoStack->MajorFunction == IRP_MJ_CLOSE)
    {
        /* Dispatch to default handler */
        return USBCCGP_CreateClose(DeviceObject, Irp);
    }

    if (DeviceExtension->IsFDO)
    {
        /* Handle request for FDO */
        return FDO_Dispatch(DeviceObject, Irp);
    }
    else
    {
        /* Handle request for PDO */
        return PDO_Dispatch(DeviceObject, Irp);
    }
}

从代码可以看到,这里分三种情况进行重新分发。

第一种IRP_MJ_CREATEIRP_MJ_CLOSE,用于总线驱动被打开和关闭时的回调函数。

子设备的FDO也有其对应的IRP_MJ_CREATEIRP_MJ_CLOSE,其一般不向总线驱动下发。

第二种当设备为FDO时,调用FDO_Dispatch

第三种当设备为 PDO时,调用PDO_Dispatch

USBCCGP总能驱动设备的打开与关闭

usbccgp.c

NTSTATUS
NTAPI
USBCCGP_CreateClose(
    PDEVICE_OBJECT DeviceObject, 
    PIRP Irp)
{
    PCOMMON_DEVICE_EXTENSION DeviceExtension;
    PFDO_DEVICE_EXTENSION FDODeviceExtension;

    /* Get common device extension */
    DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    /* Is it a fdo */
    if (DeviceExtension->IsFDO)
    {
        /* Forward and forget */
        IoSkipCurrentIrpStackLocation(Irp);

        /* Get fdo */
        FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

        /* Call lower driver */
        return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
    }
    else
    {
        /* Pdo not supported */
        Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_NOT_SUPPORTED;
    }
}

从代码来看,仅支持FDO也即总线驱动设备的打开,并不支持PDO,即子设备的FDO IoCallDriver调用总线驱动。

公共的DEVICE_EXTENSION结构体头

无论是总线驱动设备的扩展结构体,还是子设备驱动的扩展结构体,都具有一个公共的结构体头COMMON_DEVICE_EXTENSION,其也只包括一个变量IsFDO,用于标识该设备的类型。

后面我们在看创建设备(IoCreateDevice)后,会看到这个变量的初始化。

usbccgp.h

typedef struct
{
    BOOLEAN IsFDO;                                           // is device a FDO or PDO
}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;

typedef struct
{
    COMMON_DEVICE_EXTENSION Common;                          // shared with PDO
    PDRIVER_OBJECT DriverObject;                             // driver object
    PDEVICE_OBJECT PhysicalDeviceObject;                     // physical device object
    PDEVICE_OBJECT NextDeviceObject;                         // lower device object
    PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;                 // usb device descriptor
    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;   // usb configuration descriptor
    DEVICE_CAPABILITIES Capabilities;                        // device capabilities
    PUSBD_INTERFACE_LIST_ENTRY InterfaceList;                // interface list
    ULONG InterfaceListCount;                                // interface list count
    USBD_CONFIGURATION_HANDLE ConfigurationHandle;           // configuration handle
    USBC_DEVICE_CONFIGURATION_INTERFACE_V1 BusInterface;     // bus custom enumeration interface
    PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor;            // usb function descriptor
    ULONG FunctionDescriptorCount;                           // number of function descriptor
    PDEVICE_OBJECT * ChildPDO;                               // child pdos
    LIST_ENTRY ResetPortListHead;                            // reset port list head
    LIST_ENTRY CyclePortListHead;                            // cycle port list head
    UCHAR ResetPortActive;                                   // reset port active
    UCHAR CyclePortActive;                                   // cycle port active
    KSPIN_LOCK Lock;                                         // reset / cycle port list lock
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;

#define USBCCPG_TAG 'cbsu'

typedef struct
{
    COMMON_DEVICE_EXTENSION Common;                          // shared with FDO
    PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor;            // function descriptor
    PDEVICE_OBJECT NextDeviceObject;                         // next device object
    DEVICE_CAPABILITIES Capabilities;                        // device capabilities
    ULONG FunctionIndex;                                     // function index
    USB_DEVICE_DESCRIPTOR DeviceDescriptor;                  // usb device descriptor
    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;   // usb configuration descriptor
    USBD_CONFIGURATION_HANDLE ConfigurationHandle;           // configuration handle
    PUSBD_INTERFACE_LIST_ENTRY InterfaceList;                // interface list
    ULONG InterfaceListCount;                                // interface list count
    PFDO_DEVICE_EXTENSION FDODeviceExtension;                // pointer to fdo's pdo list
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
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 篇笔记 写笔记

USBCCGP 分发函数
通过上一节知道,USBCCGAP将所有的IRP都会发到USBCCGP_Dispatch函数中。其代码如下:usbccgp.cNTSTATUSNTAPIUSBCCGP_Dispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp){ ......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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