程式扎記: [ Windows DDP ] WDM 式驅動載入介紹

標籤

2010年12月27日 星期一

[ Windows DDP ] WDM 式驅動載入介紹


前言 :
和 NT 式驅動不同, WDM 式驅動程式不是被當作服務來載入的, 因此不能簡單地依靠修改登錄表來載入驅動. WDM 式驅動的載入需要由一個以 INF 為副檔名的文字檔來描述安裝過程. WDM 式驅動比 NT 式驅動增加了對隨插即用的支援, 這需要安裝的時候提供一個 INF 檔進行配合. 例如在 PC 上新插入一個裝置, 系統會偵測到這個裝置, 並報告作業系統這個裝置的 VenderID 和 ProductID 等資訊.

WDM 的手動安裝 :
Windows 在安裝的時候會提供很多 INF 檔, 根據不同的 VenderID 和 ProductID, 會找出合適這個裝置的 INF 檔. 如果系統沒有合適的 INF 檔, 系統會向使用者詢問是否可以提供這個 INF 檔, 如果不能則會到微軟網站去尋找. 經過一系列的定位 INF 檔步驟後, 尋找到最終的 INF 檔. 系統會根據 INF 檔上的指示, 將驅動程式 (.sys 檔) 和相關檔案複製到系統指定目錄下. 並修改登錄表. 同是會通知 PNP 管理器和 I/O 管理器, 新建新裝置, 並執行驅動程式的入口程式 DriverEntry. INF 檔包含了 WDM 裝置驅動程式需要的資訊, 這包括了新建或修改登錄表資訊, 複製檔案等.
在 Windows 裡會呼叫大量的 INF 檔, 這些 INF 檔記錄了知名裝置廠商提供的驅動程式. 因此大部分硬體安裝在 Windows 的時候, 是不需要安裝驅動的. 當系統插入新裝置時, 如果沒有找到對應驅動時, 會提示使用者安裝方法, 如下圖. 經過一系列的詢問, 系統會讓使用者定位 INF 檔的位置.


簡單的 INF 檔剖析 :
INF 是一個文字檔, 由若干個節 (Section) 組成. 每個節的名稱用一個方括號指示, 緊接著方括號後面就是內容. 每一行就是一項內容, 其形式都是類似 SomeEntry=SomeValue.
每個項的順序都是可以控制的. INF 中注釋語句是用分號開頭.
下面以前面的 HelloWDM 的 INF 作範例分析. 因為這是個虛擬裝置, 所以 VenderID 和 ProductID 用 PCI\VEN_9999 和 DEV_9999 代替 :
; - HelloWDM.inf :
;; The Win2K DDK documentation contains an excellent INF reference.

;--------- Version Section ---------------------------------------------------

[Version]
Signature="$CHICAGO$"
Provider=Zhangfan_Device
DriverVer=11/1/2007,3.0.0.3

; If device fits one of the standard classes, use the name and GUID here,
; otherwise create your own device class and GUID as this example shows.


Class=ZhangfanDevice
ClassGUID={EF2962F0-0D55-4bff-B8AA-2221EE8A79B0}


;--------- SourceDiskNames and SourceDiskFiles Section -----------------------

; These sections identify source disks and files for installation. 
; 可以根據實際狀況進行修改

[SourceDisksNames]
1 = "HelloWDM",Disk1,,

[SourceDisksFiles]
HelloWDM.sys = 1,MyDriver_Check,

;--------- ClassInstall/ClassInstall32 Section -------------------------------

; Not necessary if using a standard class

; 9X Style
[ClassInstall]
Addreg=Class_AddReg

; NT Style
[ClassInstall32]
Addreg=Class_AddReg

[Class_AddReg]
HKR,,,,%DeviceClassName%
HKR,,Icon,,"-5"

;--------- DestinationDirs Section -------------------------------------------

[DestinationDirs]
YouMark_Files_Driver = 10,System32\Drivers

;--------- Manufacturer and Models Sections ----------------------------------

[Manufacturer]
%MfgName%=Mfg0

[Mfg0]

; PCI hardware Ids use the form
; PCI\VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd
; 改成自己的ID.

%DeviceDesc%=YouMark_DDI, PCI\VEN_9999&DEV_9999

;---------- DDInstall Sections -----------------------------------------------
; --------- Windows 9X -----------------


; Experimentation has shown that DDInstall root names greater than 19 characters
; cause problems in Windows 98


[YouMark_DDI]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_9X_AddReg

[YouMark_9X_AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,HelloWDM.sys
HKR, "Parameters", "BreakOnEntry", 0x00010001, 0

; --------- Windows NT -----------------

[YouMark_DDI.NT]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_NT_AddReg

[YouMark_DDI.NT.Services]
Addservice = HelloWDM, 0x00000002, YouMark_AddService

[YouMark_AddService]
DisplayName = %SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\System32\Drivers\HelloWDM.sys

[YouMark_NT_AddReg]
HKLM, "System\CurrentControlSet\Services\HelloWDM\Parameters",\
"BreakOnEntry", 0x00010001, 0


; --------- Files (common) -------------

[YouMark_Files_Driver]
HelloWDM.sys

;--------- Strings Section ---------------------------------------------------

[Strings]
ProviderName="Zhangfan."
MfgName="Zhangfan Soft"
DeviceDesc="Hello World WDM!"
DeviceClassName="Zhangfan_Device"
SvcDesc="Zhangfan"

WDM 裝置安裝在登錄表中的變化 :
WDM 式驅動程式的安裝會在三方面些改登錄表, 分別是硬體子鍵, 類別子鍵和服務子鍵. 登錄表從這三方面的子鍵描述 WDM 裝置. 在安裝好 WDM 驅動後, 會根據 INF 資訊在登錄表進行修改. 安裝 WDM 驅動後, 除了在登錄表得到呈現外, 在裝置管理員, 裝置也會同時顯示出來. 在INF描述 的各種資訊, 都可以在從裝置管理員上發現對應的設定.
- 硬體子鍵
硬體子鍵, 也稱實例子鍵. 其資訊存放在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root 位置裡, 請參考下圖. 存取此鍵需要有系統管理員的存取權限 :

HelloWDM 是個虛擬裝置, 可以根據裝置管理員找到相關資訊 :

可以知道的是 PC 中可以有多於一個的同類裝置, 序號會依順序排列下去. 觀察登錄表會有以下內容, 而這些內容與 INF 中描述一致 :

* ClassGUID : 指明此裝置所屬的類別 GUID.
* Class : 指明此裝置所屬於的裝置類別
* HardwareID : 由裝置的 ProductID 和 VersionID 聯合組成. 由於此裝置是模擬裝置, 故為 pci\ven_9999@dev_9999
* Driver : 指明驅動位置.
* Mfg : 指明裝置製造上的名稱.
* Service : 指明此裝置在服務子鍵的位置
* DeviceDesc : 顯示的是此裝置在裝置管理員中顯示的名字.

- 類別子鍵
每個裝置都會從屬於一個裝置類別. 在 HelloWDM 中, 該裝置從屬於 ZhangfanDevice 裝置類別. 類別子鍵負責記錄這個類別的資訊. 類別子鍵位於 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class 目錄下.
這裡記錄了系統裡所有的裝置類別, 請每一個裝置類別都是以一個 GUID 記錄的. GUID 是一組 128 位元的數字, 從 INF 檔可以找到 HelloWDM 所屬類別為 ZhangfanDevice, 其 GUID 為 ClassGUID= {EF2962F0-0D55-4BFF-B8AA-2221EE8A79B0}. 所以可以在登錄表中查到如下資訊 :

其中 Icon 為 -5, 這個圖示是此類別裝置在裝置管理員中的圖示. 在此鍵的下面有一個子鍵 0000, 此子鍵內容類似於硬體子鍵的 0000. 下圖是裝置管理員中顯示的裝置類別名稱 :


- 服務子鍵
服務子鍵是為了相容以前 NT 式驅動程式, 可以用同樣方法觀察 NT 式驅動程式的服務子鍵. 服務子鍵是在 HKEY_LOCAL_MACHINE\SYSTEM\Current ControlSet\Services 目錄下, 底下是登錄表圖示 :

* ImagePath : 記錄驅動程式的執行路徑
* Type : 指示該表描述一個核心模式的驅動
* Start : 指示系統應動態裝入這個驅動程式. 此值會與 SERVICE_DEMOND_START 常數作對應.
* ErrorControl : 值為1, 指出如果裝入驅動程式失敗, 系統應彈出錯誤提示方塊
This message was edited 6 times. Last update was at 16/12/2010 13:46:23

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!