创建IO请求

创建IO请求


目前框架只对5中IRP请求进行WDFREQUEST对象封装,但实际上WDFREQUEST对象可以封装任何一种IRP请求,WDF驱动程序除了使用框架通过时间回调传递的WDFREQUEST对象外,还可以自己新建任何类型的WDFREQUEST对象。
两种方法:
1、创建空对象,然后调用格式化函数,将对象格式化为指定类型的命令。有4种(5个)函数可用,这种方法只能创建4种WDFREQUEST对象。
2、直接通过一个指定的IRP创建,使用此方法可以创建任何类型的WDFREQUEST对象,根据IRP类型而定。
调用 WdfRequestCreate 创建一个空对象
 NTSTATUS WdfRequestCreate(IN OPTIONAL PWDF_OBJECT_ATTRIBUTES RequestAttributes,

    IN OPTIONAL WDFIOTARGET IoTarget,

    OUT WDFREQUEST* Request);
参数RequestAttribtues用来配置将被创建的框架对象,这个类型的参数并不是仅针对于WDFREQUEST对象,所有继承自WDFOBJECT的框架对象都使用WDF_OBJECT_ATTRIBUTES结构体进行对象配置。

IoTarget是一个可选参数,仅用来做验证,不会被保存,如果不为NULL,则WdfRequestCreate函数将验证新建的对象,是否可以被发送到此IO目标对象,如果不能,则创建失败,返回STATUS_REQUEST_NOT_ACCEPTED,表面系统资源不足。

创建成功,就会返回一个WDFREQUEST对象句柄,而在使用之前,要对它进行格式化,有如下4种(5个)函数

WdfIoTargetFormatRequestForIoctl

WdfIoTargetFormatRequestForInternalIoctl

WdfIoTargetFormatRequestForInternalIoctlothers

WdfIoTargetFormatRequestForRead

WdfIoTargetFormatRequestForWrite
第一个函数将WDFREQUEST对象格式化为IRP_MJ_DEVICE_CONTROL命令;第二第三个函数将WDFREQUEST对象格式化为IRP_MJ_INTERNAL_DEVICE_CONTROL命令,这两个函数使用了不同的参数;第四个函数将WDFREQUEST对象格式化为IRP_MJ_READ命令;第五个函数将WDFREQUEST对象格式化为IRP_MJ_WRITE命令
NTSTATUS WdfIoTargetFormatRequestForRead(IN WDFIOTARGET IoTarget,

     IN OUT WDFREQUEST Request,

     IN OPTIONAL WDFMEMORY OutputBuffer,

     IN OPTIONAL PWDFMEMORY_OFFSET OutputBufferOffset,

     IN OPTIONAL PLONGLONG DeviceOffset);

参数IoTarget指明发送到的IO目标,WDFIOTARGET对象是对DEVICE_OBJECT对象的封装,最终使用的也恰恰是这个设备对象指针;参数Request传入一个前面创建的WDFREQUEST对象句柄,当函数调用成功后,这个对象的内部将焕然一新。


第二种创建WDFREQUEST对象的方法是调用WdfRequestCreateFromIrp,选择直接从一个已有的IRP结构体进行封装
NTSTATUS WdfRequestCreateFromIrp(IN OPTIONAL PWDF_OBJECT_ATTRIBUTES RequestAttributes,

    IN PIRP Irp,

    IN BOOLEAN RequestFreesIrp,

    OUT WDFREQUEST* Request);
!! 参数RequestFreesIrp为TRUE时,则WDFREQUEST对象被删除时,将负责调用IoFreeIrp释放irp,否则用户必须手动释放他

WDF驱动创建的WDFREQUEST对象,必须最后调用WdfObjectDelete方法进行删除。但如果对象是由框架通过参数传递给WDF驱动的,则不可调用WdfObjectDelete方法删除,这个权利应当让给框架在其内部进行

最后提一提发送请求。调用框架接口函数WdfRequestSend将一个请求发送到指定的IO目标对象
BOOLEAN WdfRequestSend(IN WDFREQUEST Request,

   IN WDFIOTARGET Target,

   IN OPTIONAL PWDF_REQUEST_SEND_OPTIONS RequestOptions);
重点是 RequestOptions
typedef struct _WDF_REQUEST_SEND_OPTIONS{

 IN ULONG Size;

 IN ULONG Flags;

 IN LONGLONG Timeout;

}WDF_REQUEST_SEND_OPTIONS,*PWDF_REQUEST_SEND_OPTIONS;
Flags是标志值,其实重要的两个是:
WDF_REQUEST_SEND_OPTION_SYNCHRONOUS:同步标志。设置同步标志后,直到所有发送的请求被完成,WdfRequestSend函数才会返回。请求被完成前,调用者一直处于阻塞状态;如果不设置此标志,则采用相反的异步方式发送请求,WdfRequestSend被调用后立即返回,而请求完成时,指定的完成函数将被调用。

WDF_REQUEST_SEND_OPTION_TIMEOUT:超时标志。设置超时标志后,框架把WDF_REQUEST_SEND_OPTIONS结构体中的Timeout值作为超时值计算超时。

参考
io请求  谷歌
io请求   数据结构      谷歌
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值