2010年12月29日 星期三

[ Windows DDP ] 驅動程式的基本結構 : 實驗 - 從 Log 檢視 驅動物件與裝置物件

前言 : 
在前面章節 NT 式驅動 WDM 式驅動 的基本結構介紹中, 為了驗證所學, 這裡將透過改寫 HelloDDK 與 HelloWDM 驅動程式來詳細列印出 驅動元件, 裝置元件與裝置堆疊等資訊. 

改寫 HelloDDK 查看驅動結構 : 
HelloDDK 驅動程式的結構比較簡單. 在垂直方向上, 它沒有掛載任何裝置, 在水平上也只有一個裝置物件. 為了增加程式賦雜性, 改寫程式碼中, 在 DriverEntry 中心建了兩個裝置物件, 其關係是水平方向上的關係. 用 CreateDevice 新建第一個裝置物件, 用 CreateDevice2 新建第二個裝置物件 : 

  1. //新建驅動裝置物件  
  2. status = CreateDevice(pDriverObject);  
  3. status = CreateDevice2(pDriverObject);  
為了查看驅動物件的相關資訊和水平方向相關資訊, 編寫了 Dump 函式, 並在DriverEntry 中呼叫, 程式碼如下 : 

- Driver.cpp (Dump 函式) :
  1. #pragma INITCODE  
  2. void Dump(IN PDRIVER_OBJECT pDriverObject)  
  3. {  
  4.     KdPrint(("----------------------------------------------\n"));  
  5.     KdPrint(("Begin Dump...\n"));  
  6.     KdPrint(("Driver Address:0X%08X\n",pDriverObject));  
  7.     KdPrint(("Driver name:%wZ\n",&pDriverObject->DriverName));  
  8.     KdPrint(("Driver HardwareDatabase:%wZ\n",pDriverObject->HardwareDatabase));  
  9.     KdPrint(("Driver first device:0X%08X\n",pDriverObject->DeviceObject));  
  10.       
  11.     PDEVICE_OBJECT pDevice = pDriverObject->DeviceObject;  
  12.     int i=1;  
  13.     for (;pDevice!=NULL;pDevice = pDevice->NextDevice)  
  14.     {  
  15.         KdPrint(("The %d device\n",i++));  
  16.         KdPrint(("Device AttachedDevice:0X%08X\n",pDevice->AttachedDevice));  
  17.         KdPrint(("Device NextDevice:0X%08X\n",pDevice->NextDevice));  
  18.         KdPrint(("Device StackSize:%d\n",pDevice->StackSize));  
  19.         KdPrint(("Device's DriverObject:0X%08X\n",pDevice->DriverObject));  
  20.     }  
  21.       
  22.     KdPrint(("Dump over!\n"));  
  23.     KdPrint(("----------------------------------------------\n"));  
  24. }  

經過改寫後的程式碼, 會新建出兩個裝置物件. 改寫後的驅動在被載入後, 會列出 log 資訊如下所示 (使用 DebugView) : 
 

改寫 HelloWDM 查看驅動結構 : 
在 HelloWDM 中可以觀察 FDO 和 PDO 裝置之間的關係, 它們是處於垂直關係. 由於在 AddDevice 常式之後 FDO 新建完成, 並且附加在 PDO 上. 這裡將羅列 PDO 和 FDO 的程式碼新增在 AddDevice 的後面. 
羅列 PDO 和 FDO 的程式碼被封裝在函式 DumpDeviceStack 中. 另外在前面改寫的 HelloDDK 中, 查看水平方向的程式碼亦可使用, DumpDeviceStack 程式碼如下 : 

- HelloWDM.cpp (DumpDeviceStack 函式) :
  1. #pragma PAGEDCODE  
  2. void DumpDeviceStack(IN PDEVICE_OBJECT  pdo)  
  3. {  
  4.     KdPrint(("----------------------------------------------\n"));  
  5.   
  6.     KdPrint(("Begin Dump device stack...\n"));  
  7.       
  8.     PDEVICE_OBJECT pDevice = pdo;  
  9.     int i=0;  
  10.     for (;pDevice!=NULL;pDevice=pDevice->AttachedDevice)  
  11.     {  
  12.         KdPrint(("The %d device in device stack\n",i++));  
  13.         KdPrint(("Device AttachedDevice:0X%08X\n",pDevice->AttachedDevice));  
  14.         KdPrint(("Device NextDevice:0X%08X\n",pDevice->NextDevice));  
  15.         KdPrint(("Device StackSize:%d\n",pDevice->StackSize));  
  16.         KdPrint(("Device's DriverObject:0X%08X\n",pDevice->DriverObject));  
  17.     }  
  18.   
  19.     KdPrint(("Dump over!\n"));  
  20.     KdPrint(("----------------------------------------------\n"));  
  21. }  

修改後的 HelloWDM 重新載入後, 列印出來 log 資訊如下 : 
 

結論 : 
從前面介紹NT驅動/WDK驅動結構到現在, 從中可以看出 WDM 驅動程式是從 NT 驅動程式基礎上變化過來, 可以將 WDM 驅動程式想成是 NT 驅動程式的特例. 同時我們也知道了 驅動程式的入口函式, 卸載函式, IRP 派遣函式等. 另外還有 驅動物件, 裝置物件的主要資料結構的簡介. 其中裝置物件之間可以形成垂直結構與水平結構的架構...

沒有留言:

張貼留言

[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...