USB(Universal Serial Bus)总线支持类
包括三个类:KUsbLowerDevice类、KUsbInterface类和KUsbPipe类,这三个类都只能在WDM模式下使用。
本文只做概要性介绍,以后三篇文章将分别介绍这三个类的封装结构。
【Overview】
DriverWorks支持USB客户端驱动开发,比如需要通过USB向某个设备发送请求的驱动程序。
从客户端驱动的开发者角度来看,任何USB设备概念上都是由三个类组件组成的:Logical Device,Interfaces和Endpoints。
以下分别讲述:
(1)Logical Device
这 是一个逻辑组件,USB总线驱动通过这个组件对设备进行配置和控制。它相当于USB规格说明书中描述的默认控制管道(the default control pipe)或"endpoint 0"。所有的USB设备都支持一个函数集合,这些函数通过向USB协议栈的逻辑设备层发送命令的方式完成自己的功能。这些功能包括控制设备描述符和设置配 置空间。
类KUsbLowerDevice抽象了这个函数集合。通过实例化这个类,一个设备驱动创建了一个系统USB总线驱动的上层接口。
(2)Interfaces
所 有USB设备都有一个或多个接口。一个接口就是一组提供特殊功能的设备端点(这个在概念上和COM接口相似,因为接口就象征着一个特殊的,定义良好的操作 集合)。一个设备的每个接口呈现了设备功能的不同子集。假如设备驱动不使用相同的端点,那么他们就可以使能一个设备的多个接口。
USB规格说明书 中提出了如下的例子作为对接口功能的说明:一个ISDN设备(综合业务数字网络设备)可以配置两个接口,每个接口提供64KB/s的数据通道,在主机上他 们有分离的数据源或者接收方。另一个配置可以使ISDN设备呈现为单个接口,事实上是把两个通道结合成了一个128KB/s双向通道。
类KUsbInterface抽象了这个函数集合。一个驱动为每个接口创建了一个此类的实例,用它进行相互作用(interact)。
(3)Endpoints
端 点是物理设备上个别的数据提供者和使用者。从物理上将,这可以将IO寄存器映射到设备上。端点和驱动间的联系被成为pipe。USB规格说明书定义了四种 类型的管道:Control,Interrupt,Bulk和Isochronous。设备驱动程序管理的每个数据传输都利用了一个特殊的管道。
类KUsbPipe抽象了这个函数集合。一个驱动为每个管道(pipe)创建这个类实例,需要通过它进行数据传输。然而,驱动不会为默认控制管道(endpoint 0)创建实例。KUsbLowerDevice抽象了这个管道。
class KUsbLowerDevice
【Overview】
KUsbLowerDevice类是实现一个USB客户端驱动的 核心类。它使驱动能够控制一个USB设备的默认控制管道(the default control pipe),能够配置设备,并且能够向设备传递各种控制请求和状态请求。这个类相当于USB协议栈的逻辑设备层(logical device layer),为USB和设备端点(device endpoints)之间的路由通信负责。
KUsbLowerDevice类是KPnpLowerDevice类的子类,因此继承了它的成员函数。这个基类提供了对底层物理设备属性的控制。
一个KUsbLowerDevice类实例(或者是它的子类)就象征着endpoint 0(控制管道the control pipe)。所以你不用为endpoint 0实例化一个KUsbPipe类。
当系统检测到一个USB设备,它会创建一个设备对象来表示系统中的这个物理设备。这个设备对象被称为物理设备对象(PDO)。系统决定了为设备负责的驱动程序,并且调用那个驱动的AddDevice 入口函数,传递一个指向PDO的指针作为参数。
一般来说,AddDevice 创建一个功能设备对象(FDO),就相当于传进来的PDO。FDO的角色只是使应用程序和更高层的驱动程序能够通过客户端驱动发送IO请求(I/O requests)。FDO是一个KPnpDevice派生类的实例。
要 创建FDO和PDO之间的连接(biding),FDO嵌入一个KUsbLowerDevice类型的数据成员。在construction 函数或者Initialize函数中,FDO和PDO联系起来,因此FDO把自己插入驱动程序栈里并开始为PDO操作IRPs(IO请求包I/O request packets)。
对于怎样使用KUsbLowerDevice的成员函数进行USB设备的配置,参见下面的【Configuring a USB Device】部分,这在DriverWorks里是以链接方式给出的一个专题。
【Configuring a USB Device】
下面是构造一个能够控制USB设备的驱动程序的几个要点说明(keys):
(1)USB 驱动必须是WDM驱动程序。这意味着你在继承KDriver的类里需要一个AddDevice函数。你的function.h文件必须有宏定 义#define DRIVER_FUNCTION_ADD_DEVICE,DRIVER_FUNCTION_PNP和DRIVER_FUNCTION_POWER。
(2)USB 设备通常是支持即插即用的。从KPnpDevice派生一个类。这个类必须有一个KUsbLowerDevice类型的数据成员。而且对于每种配置的每个 接口,都要声明一个KUsbInterface类型的数据成员。对每个USB端点(endpoint),要声明一个KUsbPipe类型的数据成员。
(3)你的设备类必须重写,至少重写OnStartDevice 和 OnStopDevice函数。可能还有其他你需要重写的成员函数,但是系统需要的很多PnP(即插即用)和Power(电源管理)功能是由它的基类KPnpDevice实现了的。
(4) 在设备构造函数里,你必须首先通过调用KUsbLowerDevice类的Initialize函数对它进行初始化。然后调用每个 KUsbInterface类的Initialize对它们分别进行初始化。要保证调用这些函数的新形式(new forms)。遗留的形式之所以存在仅仅是为了保持对老式设备驱动的兼容。然后调用SetLowerDevice, SetPnpPolicy和SetPowerPolicy三个函数。
(5)在你的设备类的OnStartDevice函数里,调用 KUsbLowerDevice::ActivateConfiguration来配置设备。这个函数将建立KUsbPipe、 KUsbInterface对象和当前USB管道(pipes)、接口之间的联系(biding)。
(6)在OnStopDevice函数里,调用KUsbLowerDevice::DeActivateConfiguration函数。
具体请参考安装目录../DriverWorks/examples/wdm下的示例程序USBTHERM,或者使用DriverWizard生成一个定制的USB客户端驱动程序。
【Member Functions】
1、KUsbLowerDevice - Constructor (2 forms)构造函数。运行于PASSIVE_LEVEL中断级别上。
FORM 1:
KUsbLowerDevice(
KDevice* AttachingDevice,
PDEVICE_OBJECT PhysicalDeviceObject,
NTSTATUS* pStatus
);
FORM 2:
KUsbLowerDevice(void);
FORM 3:
KUsbLowerDevice(
PDEVICE_OBJECT TopOfStackDevice,
PDEVICE_OBJECT PhysicalDeviceObject,
NTSTATUS* pStatus
);
如果用Form2,就必须提前调用Initialize函数。
2、Initialize - Initialization初始化一个类实例,只有使用默认构造函数(不带参数)进行构造时用这个函数初始化。运行于PASSIVE_LEVEL中断级别上。
FORM 1:
NTSTATUS Initialize(
KDevice* AttachingDevice,
PDEVICE_OBJECT PhysicalDeviceObject
);
FORM 2:
NTSTATUS Initialize(
PDEVICE_OBJECT TopOfStackDeviceObject,
PDEVICE_OBJECT PhysicalDeviceObject
);
3、GetDeviceDescriptor - Retrieve device descriptor从设备取得设备描述符,这个函数和SubmitUrb函数同步调用。运行于PASSIVE_LEVEL中断级别上。
函数原型:
NTSTATUS GetDeviceDescriptor( PUSB_DEVICE_DESCRIPTOR pDevDesc );
设备描述符的数据结构定义:
typedef struct _USB_DEVICE_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT bcdUSB;
UCHAR bDeviceClass;
UCHAR bDeviceSubClass;
UCHAR bDeviceProtocol;
UCHAR bMaxPacketSize0;
USHORT idVendor;
USHORT idProduct;
USHORT bcdDevice;
UCHAR iManufacturer;
UCHAR iProduct;
UCHAR iSerialNumber;
UCHAR bNumConfigurations;
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
4、GetStringDescriptor - Retrieve string descriptor获取一个串描述符。运行于PASSIVE_LEVEL中断级别上。
函数原型:
NTSTATUS GetStringDescriptor(
UCHAR Index,
PSTR pStr,
LONG MaxLen,
SHORT LangId
);
串描述符数据结构定义:
typedef struct _USB_STRING_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
WCHAR bString[1];
} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
5、GetCurrentFrameNumber - Retrieves the current USB frame number from the system USB bus driver从系统的USB总线驱动获得当前USB驱动程序的USB帧编号。
函数原型:
ULONG GetCurrentFrameNumber( VOID);
6、ActivateConfiguration - Activate a particular configuration of the device激活指定的配置。FORM1打开驱动中实例化的KUsbInterface和KUsbPipe对象。当对象已经打开时,函数也会向这个对象所 抽象的设备上的端点(endpoint)或接口(interface)提交请求。
FORM 1: (Preferred推荐)
AC_STATUS ActivateConfiguration(
USHAR ConfigurationValue,
ULONG MaxConfigSize=1024
);
FORM 2: (Legacy保留,不推荐)
AC_STATUS ActivateConfiguration(
UCHAR ConfigurationValue,
ULONG nEndpointsDescribed,
USB_ENDPOINT* Endpoints,
USB_ENDPOINT** ppProblem=NULL,
ULONG MaxConfigSize=1024
);
7、DeActivateConfiguration - Set the device to the unconfigured state. (Works like UnConfigure, but also cleans up internal objects.)通知USB总线驱动程序将设备置于非配置状态,关闭ActivateConfiguration打开的KUsbInterface和 KUsbPipe对象。这个函数只有当ActivateConfiguration 使用FORM1时使用,FORM2时没有相应的De-函数。运行于PASSIVE_LEVEL中断级别上。
函数原型:
NTSTATUS DeActivateConfiguration(
PIO_COMPLETION_ROUTINE pfnCompletionRoutine=NULL,
PVOID pContext=NULL
);
8、Preconfigure - Prepare for configuration by retrieving a configuration descriptor.获取一个配置描述符。配置一个USB设备的第一步。如果调用成功(返回STATUS_SUCCESS),就可以使用 m_config数据成员进行配置描述符的存取了。运行于PASSIVE_LEVEL中断级别上。
函数原型:
NTSTATUS Preconfigure(
UCHAR ConfigIndex=0,
ULONG MaxConfigSize=DEFAULT_CONFIG_SIZE
);
9、LocateInterface - Retrieve a pointer to a qualified interface descriptor.在当前已指定特征的配置描述符中找到一个接口。返回这个接口描述符的指针,没找到的话就返回NULL。调用者必须处于IRQL < DISPATCH_LEVEL中断级别上。
函数原型:
PUSB_INTERFACE_DESCRIPTOR LocateInterface(
PVOID* pStart,
PUSB_ENDPOINT_DESCRIPTOR* ppEndpoints,
LONG InterfaceNumber = -1,
LONG AlternateSetting = -1,
LONG InterfaceClass = -1,
LONG InterfaceSubClass = -1,
LONG InterfaceProtocol = -1
);
10、PreconfigureInterface - Add a specified interface to the set to be configured.设置一个接口和相关的管道等待被配置。调用Preconfigure函数后,驱动为每个接口调用这个函数,简单的存储信息直到 Configure函数被调用(Configure用来设置配置信息)。
函数原型:
NTSTATUS PreconfigureInterface( PUSB_INTERFACE_DESCRIPTOR pInterfaceDesc );
11、Configure - Set the current configuration.设置物理设备的当前配置信息。调用者处于IRQL < DISPATCH_LEVEL中断级别上。
函数原型:
NTSTATUS Configure(void);
12、Unconfigure - Unconfigure the device将设备置为未配置状态(unconfigured state)。调用者处于PASSIVE_LEVEL中断级别上。
函数原型:
NTSTATUS Unconfigure(
PIO_COMPLETION_ROUTINE CompletionRoutine=NULL,
PVOID Context=NULL
);
13、GetStatus - Get the device status获得设备状态。运行于PASSIVE_LEVEL中断级别上。
函数原型:
NTSTATUS GetStatus(
PUSHORT pStatus,
PIO_COMPLETION_ROUTINE CompletionRoutine=NULL,
PVOID Context=NULL
);
14、SetFeature - Set a device feature设置(使能)一个设备特性,申请URB失败的话返回STATUS_INSUFFICIENT_RESOURCES。运行于PASSIVE_LEVEL中断级别上。
函数原型:
NTSTATUS SetFeature(
USHORT Feature,
PIO_COMPLETION_ROUTINE CompletionRoutine=NULL,
PVOID Context=NULL
);
15、ClearFeature - Clear a device feature清除一个设备特征,申请URB失败的话返回STATUS_INSUFFICIENT_RESOURCES。运行于PASSIVE_LEVEL中断级别上。
函数原型:
NTSTATUS ClearFeature(
USHORT Feature,
PIO_COMPLETION_ROUTINE CompletionRoutine=NULL,
PVOID Context=NULL
);
16、BuildClassRequest - Build an URB for a class request为类请求构造一个URB,申请内存(非分页内存),并/或 为逻辑设备初始化一个_URB_CONTROL_VENDOR_OR_CLASS_REQUEST结构。调用者处于IRQL <= DISPATCH_LEVEL中断级别上。
FORM 1:
PURB BuildClassRequest(
PUCHAR TransferBuffer,
ULONG TransferBufferLength,
UCHAR RequestTypeReservedBits,
UCHAR Request,
USHORT Value,
BOOLEAN bIn=FALSE,
BOOLEAN bShortOk=FALSE,
PURB Link=NULL,
UCHAR Index=0,
USHORT Function=URB_FUNCTION_CLASS_DEVICE,
PURB pUrb=NULL
);
FORM 2:
PURB BuildClassRequest(
KMemory& TransferBufferMDL,
ULONG TransferBufferLength,
UCHAR RequestTypeReservedBits,
UCHAR Request,
USHORT Value,
BOOLEAN bIn=FALSE,
BOOLEAN bShortOk=FALSE,
PURB Link=NULL,
UCHAR Index=0,
USHORT Function=URB_FUNCTION_CLASS_DEVICE,
PURB pUrb=NULL
);
17、BuildVendorRequest - Build an URB for a vendor request为供应商请求构造一个URB,申请内存(非分页内存),并/或 为逻辑设备初始化一个_URB_CONTROL_VENDOR_OR_CLASS_REQUEST结构。调用者处于IRQL <= DISPATCH_LEVEL中断级别上。
PURB BuildVendorRequest(
PUCHAR TransferBuffer,
ULONG TransferBufferLength,
UCHAR RequestTypeReservedBits,
UCHAR Request,
USHORT Value,
BOOLEAN bIn=FALSE,
BOOLEAN bShortOk=FALSE,
PURB Link=NULL
UCHAR Index=0,
USHORT Function=URB_FUNCTION_VENDOR_DEVICE,
PURB pUrb=NULL
);
FORM 2:
PURB BuildVendorRequest(
KMemory& TransferBufferMDL,
ULONG TransferBufferLength,
UCHAR RequestTypeReservedBits,
UCHAR Request,
USHORT Value,
BOOLEAN bIn=FALSE,
BOOLEAN bShortOk=FALSE,
PURB Link=NULL
UCHAR Index=0,
USHORT Function=URB_FUNCTION_VENDOR_DEVICE
PURB pUrb=NULL
);
18、ReleaseResources - Releases all of the dynamic resources for the object释放所有的动态资源。
函数原型:
void ReleaseResources(void);
19、SubmitUrb - Submits an URB (USB Request Block) to the system USB bus driver for processing提交一个URB(USB Request Block)给系统USB总线驱动程序去处理。调用者处于IRQL <= DISPATCH_LEVEL中断级别上。
FORM 1:
NTSTATUS SubmitUrb(
PURB pUrb,
PIO_COMPLETION_ROUTINE CompletionRoutine=NULL,
PVOID CompletionContext=NULL,
ULONG mSecTimeOut=0
);
FORM 2:
NTSTATUS SubmitUrb(
KIrp I,
PURB pUrb,
PIO_COMPLETION_ROUTINE CompletionRoutine=NULL,
PVOID CompletionContext=NULL,
ULONG mSecTimeOut=0
);
KUsbInterface类
【Overview】
KUsbInterface 类抽象了一个USB接口,这个接口在USB规格说明书的第5章和第9章作了说明。一个接口是一个端点(endpoints)集合,这里的端点指的是数据的 发送源和接收方。换句话说,一个接口是一个USB设备产生数据或使用数据的组件的子集(或子类)。一个给定的设备可以有若干个接口 (interfaces)。包含相同端点的接口不能同时被配置。
一个驱动使用KUsbInterface类实例来管理一个设备管道的读写访问。 KUsbPipe和KUsbInterface两个类的关系类似与KUsbInterface和KUsbLowerDevice两个类的关系。比如说,一 个KUsbInterface类实例必须在KUsbPipe对象之前被初始化。因此这个类的存在更多的是结构上的需要而非功能上的需要。实际上几乎没有那 个成员真正的和物理设备产生了交互。但是,这个类为驱动提供了一种控制接口和它的管道之间信息(information)的方法。
KUsbInterface 对象的初始化发生在构造函数里或者Initialize函数里。初始化要求一个一个KUsbLowerDevice类实例的参数,这个实例将是把 KUsbInterface对象注册到其上的实例。在KUsbLowerDevice被初始化之前,KUsbInterface实例不可能被驱动初始化。 这意味着驱动必须在初始化KUsbInterface类之前对KUsbLowerDevice类的构造函数或initialize函数进行一次成功的调用 (call)。
【Legacy Note】
使用USBENDPOINT结构来描述他们的USB设备的设备驱动程序应该遵循另一套初始化 KUsbInterface对象的规则。这些对象必须在物理设备被配置以后才能进行初始化。这意味着在初始化任何KUsbInterface对象之前,必 须对KUsbLowerDevice::Configure作一次成功的调用。
【Member Functions】
1、KUsbInterface - Constructor (2 forms)构造函数
调用中断级 IRQL <= DISPATCH_LEVEL。
2、Initialize - Initialization初始化函数
调用中断级 IRQL <= DISPATCH_LEVEL。
3、Open - Opens a KUsbInterface object, which establishes a binding between the object and an active USB interface打开一个KUsbInterface对象,这个对象建立了一个对象和一个激活的USB接口之间的连接(binding)。
4、IsOpen - Tests if the KUsbInterface object has been opened测试KUsbInterface对象是否已经打开。
5、Close - Closes an open KUsbInterface object关闭一个打开的KUsbInterface对象。
6、SelectAlternate - Change the device’s setting for the current interface给设备发送一个URB来为设备使能所选定的设置。
7、InterfaceNumber - Accessor for interface number从对象获取接口序号。
任意中断级调用
8、AlternateSetting - Accessor for alternate setting从对象获取指定的设置。
任意中断级调用
9、Class - Accessor for USB class从对象获取接口类。
任意中断级调用
10、Subclass - Accessor for USB subclass从对象获取接口子类。
任意中断级调用
11、Protocol - Accessor for protocol attribute从对象获取协议属性。
任意中断级调用
12、NumberOfPipes - Accessor for number of pipes in interface获取构成接口的管道数量。
任意中断级调用
13、Pipes - Accessor for pipe information structs从接口对象获取管道信息结构的数组,参数为索引号(index)。
任意中断级调用
14、GetStatus - Get status of interface from device获取接口状态。
调用中断级必须在PASSIVE_LEVEL。
15、SetFeature - Set interface feature设置设备特征值。如果无法分配URB的空间就返回STATUS_INSUFFICIENT_RESOURCES ,否则就返回对USB系统驱动调用所返回的状态值。
调用中断级必须在PASSIVE_LEVEL。
16、ClearFeature - Clear interface feature清除接口特征值。
17、BuildClassRequest - Build an URB for a class request为类请求构造一个URB,申请内存(非分页内存),并/或 为逻辑设备初始化
一个_URB_CONTROL_VENDOR_OR_CLASS_REQUEST结构。
调用者处于IRQL <= DISPATCH_LEVEL中断级别上。
18、BuildVendorRequest - Build an URB for a vendor request为供应商请求构造一个URB,申请内存(非分页内存),并/或 为逻辑设备初始化一个_URB_CONTROL_VENDOR_OR_CLASS_REQUEST结构。
调用者处于IRQL <= DISPATCH_LEVEL中断级别上。
19、SubmitUrb - Submits an URB (USB Request Block) to the system USB bus driver for processing提交一个URB(USB Request Block)给系统USB总线驱动程序去处理。
如果驱动程序提供了一个非空(non-NULL)的完成例程,那么两种FORM之一的调用者处于IRQL <= DISPATCH_LEVEL中断级别上。否则中断级别必须在PASSIVE_LEVEL。
KUsbPipe类
【Overview】
KUsbPipe类抽象了一个USB管道(pipe),这种机制在USB规格说明书的第5 章和第9章有描述。一个管道是一个主机和端点(endpoint)之间的连接。每个端点是互相独立的可寻址的数据使用者或数据提供者。因此一个管道为主机 和设备之间的信息交换描绘了一个独特的逻辑上下文(a logically distinct context)。在设备给定的配置下,每个管道都和一个特定的接口联系在一起。
KUsbPipe对象的初始化发生在构造函数或 Initialize函数里。初始化要求一个KUsbLowerDevice类实例的参数,这个实例将是把KUsbPipe对象注册到其上的实例。在 KUsbLowerDevice被初始化之前,KUsbPipe实例不可能被驱动初始化。
USB规格说明书定义了四种类型的管 道:Control,Bulk,Interrupt和Isochronous。每种管道的特征都在USB规格说明书中有详细的说明。KUsbPipe类包 含有为每一种传输创建URBs(USB Request Blocks)的成员函数。对于一个给定的管道对象,只有为管道创建合适类型的URB的那个成员函数可以被调用。每当驱动程序为管道创建一个URB,它将 调用基类的SubmitUrb函数,将请求传递给USB系统总线驱动程序。
【Member Functions】
1、KUsbPipe - Constructor构造函数(三种Forms)
调用中断级IRQL <= DISPATCH_LEVEL。
2、Type - Accessor to pipe type获取管道类型,返回m_Information->PipeType。
任何中断级上调用。
3、Open - Opens a KUsbPipe object打开一个KUsbPipe对象(这个对象建立对象和激活的USB管道之间的连接binding)。
4、IsOpen - Tests if the KUsbPipe object has been opened测试KUsbPipe对象是否被KUsbLowerDevice::ActivateConfiguration或 KUsbInterface::SelectAlternate正确的初始化。
5、Close - Closes an open KUsbPipe object关闭一个KUsbPipe对象,删除对象和激活的USB管道之间的连接(biding)。
6、MaximumPacketSize - Accessor to maximum packet size获取管道有效负载的最大数据大小(B为单位)。返回m_Information->MaximumPacketSize。
任何中断级上调用。
7、EndpointAddress - Accessor to endpoint address获取管道的端点地址。返回m_Information->EndpointAddress。
任何中断级上调用。
8、PollInterval - Accessor to polling period获取轮询间隔时间(以ms为单位)。返回m_Information->Interval。
任何中断级上调用。
9、Handle - Accessor to handle assigned by bus driver获取管道句柄,返回m_Information->PipeHandle。
任何中断级上调用。
10、MaximumTransferSize - Accessor to maximum transfer size获取端点可以进行传输的最大数据量,返回m_Information->MaximumTransferSize。
任何中断级上调用。
11、SetMaximumTransferSize - Sets maximum transfer size of the pipe指定管道可以传输的最大数据量(以B为单位)。
12、Initialize - Initialization初始化,使用不带参数的构造函数时要用此函数进行初始化。
调用中断级IRQL <= DISPATCH_LEVEL。
13、Reset - Reset the pipe重置管道,返回从USB系统总线驱动返回的状态值。
任何中断级上调用。
14、Abort - Abort all outstanding requests强制取消所有未完成的请求。
任何中断级上调用。
15、BuildInterruptTransfer - Build an interrupt transfer URB构造一个interrupt类型的传输URB请求。
16、BuildControlTransfer - Build a control transfer URB构造一个control类型的传输URB请求。
17、BuildIsochronousTransfer - Build an isochronous transfer URB构造一个isochronous类型的传输URB请求。
18、BuildBulkTransfer - Build a bulk transfer URB构造一个bulk类型的传输URB请求。
19、GetStatus - Get status of pipe获取管道状态。
调用中断级必须在PASSIVE_LEVEL。
20、SetFeature - Set pipe feature设置管道特征值。如果无法分配URB的空间就返回STATUS_INSUFFICIENT_RESOURCES ,否则就返回对USB系统驱动调用所返回的状态值。
调用中断级必须在PASSIVE_LEVEL。
21、ClearFeature - Clear pipe feature清除管道特征值。
如果CompletionRoutine参数为NULL,调用中断级必须在PASSIVE_LEVEL。
22、BuildClassRequest - Build an URB for a class request为类请求构造一个URB,申请内存(非分页内存),并/或 为逻辑设备初始化一个_URB_CONTROL_VENDOR_OR_CLASS_REQUEST结构。
调用者处于IRQL <= DISPATCH_LEVEL中断级别上。
23、BuildVendorRequest - Build an URB for a vendor request为供应商请求构造一个URB,申请内存(非分页内存),并/或 为逻辑设备初始化一个_URB_CONTROL_VENDOR_OR_CLASS_REQUEST结构。
调用者处于IRQL <= DISPATCH_LEVEL中断级别上。
24、SubmitUrb - Submits an URB (USB Request Block) to the system USB bus driver for processing提交一个URB(USB Request Block)给系统USB总线驱动程序去处理。
如果驱动程序提供了一个非空(non-NULL)的完成例程,那么两种FORM之一的调用者处于IRQL <= DISPATCH_LEVEL中断级别上。否则中断级别必须在PASSIVE_LEVEL。 DISPATCH_LEVEL中断级别上。