有3种常用方式:method_buffered method_in_direct method_out_direct
还有method_neither,《windows设备驱动wdf开发》描述为:源自win 9x的vxd的模式,不建议读者掌握。这个就不管了。
method_buffered:无论读和写都对应同一缓冲区
method_in_direct\ method_out_direct:输入缓冲区可作为附加输出缓冲区,输出缓冲区可作为附加输入缓冲区,两者区别只在dma读写要分清,详见《windows设备驱动wdf开发》的dma_sample
举简例:
应用层deviceiocontrol传两个unchar数(2 和 4)的地址给驱动。
驱动读取地址提取数值,两数相加完成请求返还给应用层。
以上过程分别以:method_buffered method_in_direct method_out_direct 各执行一次

驱动层evtdeviceiocontrol例程读取处理部分:
#define iosample_ioctl_buffered ctl_code(file_device_unknown, 0x800, method_buffered, file_any_access)
#define iosample_ioctl_in_direct ctl_code(file_device_unknown, 0x801, method_in_direct, file_any_access)
#define iosample_ioctl_out_direct ctl_code(file_device_unknown, 0x802, method_out_direct, file_any_access)
switch(iocontrolcode)
{
case iosample_ioctl_buffered:
case iosample_ioctl_in_direct:
case iosample_ioctl_out_direct:
if (inputbufferlength == 0 || outputbufferlength == 0)
{ //检查输入、输出参数有效性
wdfrequestcomplete(request, status_invalid_parameter);
}
else
{
//method_buffered,method_out_direct,method_in_direct三种方式,
//输入缓冲区地址可通过调用wdfrequestretrieveinputbuffer函数获得
//输出缓冲区地址可通过调用wdfrequestretrieveoutputbuffer函数获得
//获取输入缓冲区地址buffer
status = wdfrequestretrieveinputbuffer(request, 1, &buffer, null);
if (!nt_success(status))
wdfrequestcomplete(request, status_unsuccessful);
break;
//buffer表示输入缓冲区地址
//输入x1=应用程序传给驱动程序的数字
x1 = *(uchar *)buffer;
//获取输出缓冲区地址buffer
status = wdfrequestretrieveoutputbuffer(request, 1, &buffer, null);
if (!nt_success(status))
break;
//输入x2=应用程序通过输出缓冲区传给驱动程序的数字
x2 = *(uchar *)buffer;
*(uchar *)buffer=x1+x2;
//完成i/o请求,驱动程序传给应用程序的数据长度为1字节
wdfrequestcompletewithinformation(request, status_success, 1);
default :
status = status_invalid_device_request;
wdfrequestcompletewithinformation(request, status, 0);
}
分析:对于method_buffered:
驱动层输入输出缓冲区对应应用层的输入缓冲区和输出缓冲区,wdfrequestretrieveinputbuffer和wdfrequestretrieveoutputbuffer都读取同一位置,所以2+2=4。那个6的地址在驱动层是不可读的,他只是应用层接受来自驱动的输出结果
对于method_out_direct,method_in_direct:
驱动层输入缓冲区,驱动层输出缓冲区分别于应用层对应。所以那个6的地址对于驱动层是可读的,实际上这就是所谓“输出缓冲区可作为附加的输入缓冲区”