DeviceIoControl
的同步和异步调用方式:
上层应该可以以同步或异步的方式.
在调用DeviceIoControl时,不指定FILE_FLAG_OVERLAPPED标志,表示以同步方式调用,调用线程将被阻塞直到控制操作完成.
当指定FILE_FLAG_OVERLAPPED标志调用DeviceIoControl,表示以异步方式调用,调用线程不立即阻塞,直到调用线程需要结果时,调用者调用事件等待函数,等待驱动发出事件.
在异步调用时,得使用事件(event)来通信.这里就用到了DeviceIoControl的最后一个OVERLAPPEND结构的参数:
OVERLAPPED
ov ;
ov.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL) ;
DeviceIoControl(……, &ov );
//执行其它操作.
//等待驱动事件
HANDLE
aEvents[2] ;
aEvents[0] = ov.hEvent ;
aEvents[1] = hStopEvent ;
DWORD nWaitResult = WaitForMultipleObjects (2, aEvents, FALSE, INFINITE) ;
这里使用WaitForMultipleObjects等待事件,为什么还有一个hStopEvent事件呢, WaitForMultipleObjects可能等待多个事件,只要有收到其中一个事件,就返回,这样当没有收到驱动发出的事件时又想停止等待时,就可以发别外一个事件来停止等待.
当收到事件后就可以使用
GetOverlappedResult读取驱动返回的数据.
驱动中获取上层数据:
MajorFunction[IRP_MJ_DEVICE_CONTROL]函数中,接收Irp,在Irp中:
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
//
输入缓冲区长度,DeviceIoControl的第四参数
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
//
输出缓冲区长度,DeviceIoControl的第六参数
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
//
控制代码,DeviceIoControl的第二个参数
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;