向Windows核心驅動傳遞使用者層定義的事件Event,並響應核心層的通知

來源:互聯網
上載者:User

標籤:bre   kernel   out   adp   建立線程   模式   content   etc   get   

完整的程式在下載:http://download.csdn.net/detail/dijkstar/7913249

 

使用者層建立的事件Event是一個Handle控制代碼,和核心中的建立的核心模式下的KEVENT是一個東西。因此,在應用程式層建立的事件,可以在核心層獲得並使用。這一部分的原理,見張帆編著的《Windows驅動技術詳解》章節8.5.4,P237頁;

程式是來自於《Windows驅動技術詳解》章節8.5.4(驅動程式和應用程式互動事件對象)和章節10.2.1(DPC定時器)。

 

首先,在應用程式層建立一個等待事件Event,建立監控這個等待事件的線程,並把等待事件Event傳遞給核心:

 

  1.  //
  2.  //1. 建立使用者層的等待事件,傳入核心
  3.  //2. 建立線程,用於監測核心事件的到來
  4.  //
  5.  HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  6.  HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, Thread1, &hEvent, 0, NULL);
  7.   
  8.  //先將使用者層的等待Event傳入核心
  9.  DeviceIoControl(hDevice, IOCTL_SET_EVENT, &hEvent, sizeof(hEvent), NULL, 0, &dwOutput, NULL);

監控線程的內容:(裡面用了查詢指令周期數,可以測試每次等待WaitFor××的時間)

 

 

  1.  UINT WINAPI Thread1(LPVOID para)
  2.  {
  3.  HANDLE *phEvent = (HANDLE *)para;
  4.  while(1)
  5.  {
  6.  //獲得初始值
  7.  QueryPerformanceCounter(&litmp);
  8.  qt1=litmp.QuadPart;
  9.   
  10.  //等待
  11.  WaitForSingleObject(*phEvent, INFINITE);
  12.   
  13.   
  14.  //獲得終止值
  15.  QueryPerformanceCounter(&litmp);
  16.  qt2=litmp.QuadPart;
  17.  //獲得對應的時間值,轉到毫秒單位上
  18.  dfm=(double)(qt2-qt1);
  19.  dft=dfm/dff;
  20.   
  21.   
  22.  printf("本次等待用時: %.3f 毫秒\n", dft*1000.0);
  23.  }
  24.  }

使用者層還通知驅動核心啟動一個DPC定時器,用於每次來觸發應用程式層的等待事件Event:

 

 

  1.  DWORD dwMircoSeconds = 1000 * 50;//單位微秒
  2.  DeviceIoControl(hDevice, IOCTL_START_TIMER, &dwMircoSeconds, sizeof(DWORD), NULL, 0, &dwOutput, NULL);

在驅動程式中,首先取出來應用程式層傳遞進來的事件,並把它轉化為核心對象:

 

 

  1.  case IOCTL_SET_EVENT:
  2.  {
  3.  //把傳遞進來的使用者層等待事件取出來
  4.  HANDLE hUserEvent = *(HANDLE *)pIrp->AssociatedIrp.SystemBuffer;
  5.   
  6.  //將使用者層事件轉化為核心等待對象
  7.  status = ObReferenceObjectByHandle(hUserEvent, EVENT_MODIFY_STATE,
  8.  *ExEventObjectType, KernelMode, (PVOID*)&pDevExt->pEvent, NULL);
  9.   
  10.  KdPrint(("status = %d\n", status));//status應該為0才對
  11.   
  12.  ObDereferenceObject(pDevExt->pEvent);
  13.  break;
  14.  }

在核心的每次定時器到來時,啟用等待事件,等於觸發啟用應用程式層的WaitFor××函數向下繼續執行:

 

 

  1.  #pragma LOCKEDCODE
  2.  VOID PollingTimerDpc( IN PKDPC pDpc,
  3.   IN PVOID pContext,
  4.   IN PVOID SysArg1,
  5.   IN PVOID SysArg2 )
  6.  {
  7.  PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)pContext;
  8.  PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
  9.  KeSetTimer(
  10.  &pdx->pollingTimer,
  11.  pdx->pollingInterval,
  12.  &pdx->pollingDPC );
  13.  KdPrint(("PollingTimerDpc\n"));
  14.   
  15.  //定時器到來,通知使用者層
  16.  if(pdx->pEvent)
  17.  KeSetEvent(pdx->pEvent, IO_NO_INCREMENT, FALSE);
  18.   
  19.   
  20.  /*
  21.  //檢驗是運行在任意線程上下文
  22.   PEPROCESS pEProcess = IoGetCurrentProcess();
  23.   PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);
  24.   KdPrint(("%s\n",ProcessName));
  25.  */
  26.  }

程式中其他部分見源碼解釋,這個程式還有兩個問題,一是應用程式層必須正常退出,否則驅動核心層因不能正常關閉DPC定時器,而繼續執行已經找不到的等待事件,引起藍屏崩潰;二是雖然在核心裡,DPC定時器的觸發精度為1個100ns層級,但當觸發周期設定為20ms以下時,在應用程式層監控WaitFor,都是十幾個毫秒的分辨精度,再向下設定已經沒有意義。

 

 

 

jpg 改 rar 

 

 

 

 

向Windows核心驅動傳遞使用者層定義的事件Event,並響應核心層的通知

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.