Windows驱动开发WDM (5)- DeviceIoControl(直接方式交互"输出buffer")

这篇博客探讨了Windows驱动开发中DeviceIoControl函数的使用,它允许用户模式程序与内核模式驱动进行交互。文章重点介绍了控制码的构成,包括DeviceType、Function和TransferType,并提及了数据传输的三种方式:METHOD_BUFFERED、METHOD_IN_DIRECT和METHOD_OUT_DIRECT。内容还引用了MSDN的官方解释,解释了不同TransferType对输入输出缓冲的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

除了ReadFile和WriteFile外,还有一个函数可以让用户模式程序访问内核模式驱动:DeviceIoControl。这是经常用的一个API, 原型如下:

BOOL WINAPI DeviceIoControl(
  _In_         HANDLE hDevice,//已经打开的设备
  _In_         DWORD dwIoControlCode,控制码
  _In_opt_     LPVOID lpInBuffer,//输入缓冲区
  _In_         DWORD nInBufferSize,//输入缓冲区大小
  _Out_opt_    LPVOID lpOutBuffer,//输出缓冲区
  _In_         DWORD nOutBufferSize,//输出缓冲区大小
  _Out_opt_    LPDWORD lpBytesReturned,//返回驱动操作的字节数
  _Inout_opt_  LPOVERLAPPED lpOverlapped//用于Overlapped操作
);

其他参数都好理解,除了控制码需要讲一下。MSDN解释(http://msdn.microsoft.com/en-us/library/windows/hardware/ff543023(v=vs.85).aspx)。

 

控制码

其实控制码只是一个32位长度的DWORD,只是这32位内容里面不同的位对应了不同的意思,见上图。DDK提供了一个宏来生成这个控制码,

#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)

DeviceType:对应创建FDO(IoCreateDevice)时候指定的设备类型。

Function:是控制码的一个标志,其中0 - 0x7FFF已经保留给微软用了,我们可以使用>=0x8000的值。比如0x8000表示驱动加密功能,0x8001表示驱动解密功能。

TransferType:定义系统如何在驱动和用户模式的caller之间传递数据。就像ReadFile,WriteFile的内存操作一样。创建设备对象的时候,DEVICE_OBJECT->Flags需要指定一个内存操作方式,比如DO_BUFFERED_O或者DO_DIRECT_IO。注意DEVICE_OBJECT->Flags指定的内存方式只对ReadFile和WriteFile起作用。DeviceIoControl需要在控制码里面指定,也就是这里的TransferType。这里有三种方式:METHOD_BUFFERED,METHOD_IN_DIRECT or METHOD_OUT_DIRECT和METHOD_NEITHER(参见:http://msdn.microsoft.com/en-us/library/windows/hardware/ff543023(v=vs.85).aspx)。METHOD_BUFFERED比较简单,就是输入输出都是用缓冲区方式。METHOD_IN_DIRECT/METHOD_OUT_DIRECT比较让人困惑。首先对于METHOD_IN_DIRECT/METHOD_OUT_DIRECT,输入都是使用的缓冲区方式(通过Irp->AssociatedIrp.SystemBuffer获得内核模式下的缓冲),困惑在于输出缓冲(METHOD_IN_DIRECT/METHOD_OUT_DIRECT只对输出缓冲起作用)。MSDN上面是这么解释的(

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值