WDF 提供了两个方法来 complete io request(实际上 有三个):
1. WdfRequestComplete;
2.WdfRequestCompleteWithInformation(,,)
IO MEthod 有三种方式:
METHOD_BUFFERED;
METHOD_DIRECT;
METHOD_NEITHER;
这里只讨论前面两种,METHOD_BUFFERED;METHOD_DIRECT; 情况下如何使用正确的IO complete function。
如果使用自定义的IOCTL code, 如下:
#define IOCTL_UIHGWB_MALLOC_MEMO \
CTL_CODE(FILE_DEVICE_UIHGWB, 0x804,\
METHOD_BUFFERED, FILE_READ_DATA|FILE_WRITE_DATA)
使用此IOCTL 的接口是windows的API DeviceIOControl; 其原型:
前面说的三种IO Method, 其实只是针对Outbuff 来讲的, 使用Outbuffer一般是需要读取数据,此参数也可是NULL;
如果User使用DeviceIOcontrol的时候希望device 往outbuffer里写入数据,也就是user希望通过outbuffer 获取一些数据,
那么在WDF的驱动设计时候, VOID UIHGwb_EvtIoDeviceControl(IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
);
函数需要注意request的 返回方式;
- 如果IOCTL code定义的是METHOD_BUFFERED, 那么需要使用WDFRequestCompleteWithInformation()接口,buffer的内容才会更新到User 的outbuffer;
使用WDFRequestComplete()接口返回的话, outbuffer的内容并不会更新;关于Method_buffered的工作原理,读者可以参考MSDN手册;
但是,不管哪个接口,如果返回的status不是 STATUS_SUCCESS,比如WdfRequestComplete(Request, STATUS_STATUS_INVALID_PARAMETER);或者WdfRequestCompleteWithInformation(Request, STATUS_STATUS_INVALID_PARAMETER, sizeof(ULONG64));
那么outbuffer 都不会更新;!! - 如果IOCTL dode的定义的是METHOD_INDIRECT或者METHOD_OUTDIRECT,那么驱动只要更新了outbuffer的值,就是直接操作了user space的 outbuffer。参考MSDN资料;
所以, 为了保险起见, 直接使用DIRECT的方式,比较方便。