2011年1月31日 星期一

[ Windows DDP ] 驅動程式的同步處理 : 核心模式下的同步物件 - 信號燈

前言 : 
在內核中還有另一種同步物件, 這就是信號燈. 和事件對向一樣, 信號燈在使用者模式下和核心模式下是完全統一的, 只不過操作方式不太一樣. 在使用者模式下, 信號燈物件用控制碼代表, 而在核心模式下, 信號燈物件用 KSEMAPHORE 資料結構表示. 

核心模式下的信號燈 : 
在使用信號燈物件前, 需要對信號燈物件進行初始化. 使用內核函式 KeInitializeSemaphore 對信號燈初始化, 其函式宣告如下 : 

- Syntax :
  1. VOID KeInitializeSemaphore(  
  2.   __out  PRKSEMAPHORE Semaphore,  
  3.   __in   LONG Count,  
  4.   __in   LONG Limit  
  5. );  

參數說明 : 
* 參數 Semaphore : 這個參數獲得內核信號燈物件指標
* 參數 Count : 這個參數式初始化時的信號燈計數.
* 參數 Limit : 這個參數指名信號燈計數的上限.

KeReadStateSemaphore 函式可以讀取信號燈當前的計數. 釋放信號燈會增加信號燈計數, 它對應的內核函式是 KeReleaseSemaphore. 程式設計師可以用這個函式指定增量值. 獲得信號燈可以使用 KeWaitXXX 系列函式. 如果能獲得, 就將計數減一, 否則陷入等待, 下面程式碼展示了如何在驅動程式中使用信號燈物件 : 
- Driver.cpp : 示範如何在核心模式下使用 信號燈
  1. VOID SemaphoreFun(IN PVOID pContext)  
  2. {  
  3.     // 得到信號燈  
  4.     PKSEMAPHORE pkSemaphore = (PKSEMAPHORE) pContext;  
  5.     KdPrint(("Enter SemaphoreFun\n"));  
  6.     KeReleaseSemaphore(pkSemaphore, IO_NO_INCREMENT, 1, FALSE);  
  7.     LONG count = KeReadStateSemaphore(pkSemaphore);  
  8.     //KdPrint(("\tThe Semaphore count is %d\n", count));  
  9.     KdPrint(("Leave SemaphoreFun\n"));  
  10.     // 結束執行緒  
  11.     PsTerminateSystemThread(STATUS_SUCCESS);  
  12. }  
  13.   
  14. #pragma PAGEDCODE  
  15. VOID TestSemaphore()   
  16. {  
  17.     HANDLE hMyThread;  
  18.     KSEMAPHORE kSemaphore;  
  19.     // 初始化內核信號燈  
  20.     KeInitializeSemaphore(&kSemaphore, 22);  
  21.     // 讀取信號燈狀態  
  22.     LONG count = KeReadStateSemaphore(&kSemaphore);  
  23.     KdPrint(("The Semaphore count is %d\n", count));  
  24.     // 等待信號燈  
  25.     KeWaitForSingleObject(&kSemaphore, Executive, KernelMode, FALSE, NULL);  
  26.     // 讀取信號燈狀態  
  27.     count = KeReadStateSemaphore(&kSemaphore);  
  28.     KdPrint(("The Semaphore count is %d\n", count));  
  29.     NTSTATUS status = PsCreateSystemThread(&hMyThread, 0, NULL, NtCurrentProcess(), NULL, SemaphoreFun, &kSemaphore);  
  30. }  

底下是執行結果 : 

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...