2012年3月11日 星期日

Event Shared Between Kernel and User Modes

要避免應用程式沒效率地監看驅動程式的事件, 我們會很直覺地想到使用 event, 但一般只有在 user mode 或是 kernel mode 各別使用, 如果要在 user mode 及 kernel mode 使用同一個 event, 要怎麼做呢?

Kernel Driver
  1. 實作一個 IOCTL 處理函式
  2. 從 input buffer 取得 user mode app 傳來的 event handle
    PVOID ptr;
    HANDLE hEvent;
    WdfRequestRetrieveInputBuffer(req, sizeof(HANDLE), &ptr, NULL);
    hEvent = *(HANDLE *)ptr;
    
  3. 呼叫 ObReferenceObjectByHandle() 將 event handle 與 KEVENT 做關聯
    KEVENT kEvent;
    ObReferenceObjectByHandle(hEvent, EVENT_MODIFY_STATE, *ExEventObjectType,
        UserMode, &kEvent, NULL);
    
  4. 呼叫 KeSetEvent() 通知 user mode app 有事件發生
  5. 在 driver/device cleanup 時呼叫 ObDereferenceObject() 切斷與 event handle 的關聯

User Mode App
  1. 在 user mode app 中呼叫 CreateEvent() 建立一個 event
  2. 將此 event handle 透過 DeviceIoControl 傳入 kernel driver
    DeviceIoControl(hDevice, dwIoControlCode, &hEvent, sizeof(HANDLE),
        lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
    
  3. 呼叫 WaitForSignalObject() 等待事件
  4. 程式離開前呼叫 CloseEvent() 將 event handle 關閉


更多資訊:
Sharing Is Caring - Sharing Events Between Kernel-User Mode
Communication between GUI Application and Device Driver

沒有留言:

張貼留言