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;