在上面的两篇博文中,介绍了IRP与派遣函数,以及我们通过了一个例子“磁盘设备的绝对读写”来演示了在应用程序中是如何向一个设备发出I/O请求的。这篇博文将演示在驱动程序中处理一个非常简单的I/O请求——由DeviceIoControl这个Win32API经过一系列的调用,在内核中由I/O管理器构造生成的IRP_MJ_DEVICE_CONTROL这个IRP。
我们先来看看DeviceIoControl这个函数的原型,此函数向某个打开的设备所在驱动程序的派遣函数中发送IRP:IRP_MJ_DEVICE_CONTROL。函数原型:
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
);
hDevice:操作是要执行的设备句柄。使用 CreateFile 函数打开。
dwIoControlCode:操作的控制代码。
需要注意的是,这个控制码不是随便定的,为了方便定义控制码,微软提供了一个CTL_CODE宏。控制码的结构如下:
本例中博主定义了这样的一个ioctl控制码:
#define IOCTL1 CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
来看看这个宏的使用方法:
首先是这个宏的定义:
#define CTL_CODE(DeviceType, Function, Method, Access) ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
DeviceType:设备类型,IoCreateDevice使用的设备类型,具体参加我之前的博文”NT驱动的基本结构“
Function:定义设