首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Windows 虛擬設備驅動程序 (VxD) 核心概念與開發入門(一)

     編輯:關於C++

一、VxD 簡介

本文詳細介紹 VxD 的角色與開發方法。若 Windows 95 內建的標準 VxD 無法對您的硬體或軟體(含 16 位與 32 位)提供完整相容支援,您需要開發專屬 VxD。此外,若想讓 Windows 使用者享用您的硬體或軟體的新特性,同樣需要建立 VxD。文章涵蓋建立 VxD 所需的結構、程序、呼叫慣例,以及建置與測試步驟。VxD 可為靜態或動態載入,本文以靜態 VxD 為主,但格式與功能說明兩者皆適用。

二、什麼是 VxD

VxD 是管理系統資源(如硬體裝置、已安裝軟體)的 32 位可執行程式,使多個應用程式能同時存取這些資源。Windows 透過 VxD 實現基於 Windows 應用程式的多工處理。VxD 在與 Windows 協作時處理中斷,並在不影響其他應用程式執行的情況下,為特定應用程式執行 I/O 作業。大多數 VxD 管理硬體裝置,部分管理或替代相關軟體(如 ROM BIOS 例程)。VxD 可包含裝置相關程式碼,或依賴其他軟體執行裝置操作。無論何種情況,VxD 都會為每個應用程式保留裝置狀態記錄,確保應用程式恢復執行時裝置處於正確狀態。

部分 VxD 僅管理已安裝軟體(如 MS-DOS 裝置驅動程式或 TSR 程式),這類 VxD 通常包含模擬這些軟體、保護其資料供執行中應用程式使用的程式碼。VxD 有時也用於提升已安裝軟體效能:Intel 相容 CPU 執行 32 位 VxD 比執行 16 位 MS-DOS 驅動程式或 TSR 更有效率。

三、標準 VxD

Windows 內建多種 VxD 支援常見硬體與可安裝軟體。某些情況下需修改 VxD 以提供新特性或支援非標準硬體。Windows 也提供許多不預期修改、但能輔助其他 VxD 的 VxD(如 V86 記憶體管理器 V86MMGR、虛擬可程式化中斷控制器 VPICD)。Windows 95 DDK 包含大量裝置驅動程式原始碼供開發參考。

四、建立 VxD 流程

  1. 閱讀硬體手冊中描述該型號硬體 VxD 的章節。
  2. 撰寫所需的控制程序、VxD 服務與 API 函數。
  3. 建立模組定義檔,指定適當模組名稱作為 VxD 識別,並匯出裝置描述區塊 (DDB)。
  4. 組譯與連結 VxD。
  5. 使用除錯版 Windows 95 測試 VxD(可使用 Soft-ICE 除錯)。
  6. 建立安裝檔(INF 檔),透過修改登錄與複製檔案至 SYSTEM 等目錄安裝 VxD。
  7. 建立最終發行套件。

五、開發前備知識

假設讀者為資深組合語言程式設計師,熟悉 Intel 相容處理器指令集與系統架構,並理解:

  • 保護模式與虛擬 8086 (V86) 模式
  • 平坦記憶體模型
  • 中斷與例外處理
  • 保護與特權等級
  • 區段與分頁記憶體管理、錯誤處理
  • I/O 保護與錯誤處理

亦假設讀者熟知目標硬體特性、對應 ROM BIOS 例程與其他可安裝軟體。

六、撰寫 VxD 步驟

多數情況下撰寫 VxD 是為了支援新硬體或軟體,手工建立通常比修改既有 VxD 容易,因多數 VxD 具有裝置相關性。但既有 VxD 原始碼仍需仔細分析,因其可能包含通用格式、結構,以及使用 VMM/VxD 服務實現實用功能的範例。

  1. 建立 VxD 框架:含各區段、VxD 宣告、裝置控制程序、系統控制訊息處理基礎、API 程序基礎。
  2. 加入實模式初始化程序(可選)。
  3. 完成初始化訊息處理程序:初始化控制區塊、配置全域記憶體、安裝中斷、I/O 捕獲與分頁錯誤回呼程序。
  4. 完成處理各類中斷與錯誤的回呼程序。
  5. 加入服務表定義與宣告(可選)。
  6. 完成 API 程序(可選)。
  7. 完成系統控制訊息處理程序以建立與刪除虛擬機。

開發過程中可安裝 VxD 並在除錯器控制下運行 Windows,在 VxD 設定中斷點監控其管理的中斷,以驗證正確性。

1. VxD 區段

VxD 可包含下列五種區段的組合:

區段說明巨集/別名
VxD_CODE保護模式程式碼區段(必須),含系統控制程序、回呼程序、服務、API 程序VxD_CODE_SEG/VxD_CODE_ENDS,亦稱 _LTEXT
VxD_DATA保護模式資料區段(必須),含裝置描述表、服務表、部分全域資料VxD_DATA_SEG/VxD_DATA_ENDS,亦稱 _LDATA
VxD_ICODE保護模式初始化程式碼區段(可選),含僅初始化時使用的程序/服務,Init_Complete 後由 VMM 捨棄VxD_ICODE_SEG/VxD_ICODE_ENDS,亦稱 _ITEXT
VxD_IDATA保護模式初始化資料區段(可選),含初始化程序/服務使用的資料,Init_Complete 後捨棄VxD_IDATA_SEG/VxD_IDATA_ENDS,亦稱 _IDATA
VxD_REAL_INIT實模式初始化區段(可選),含實模式初始化程序與資料,VMM 載入 VxD 其他部分前呼叫,返回後捨棄VxD_REAL_INIT_SEG/VxD_REAL_INIT_ENDS,亦稱 _RTEXT

除實模式初始化區段外,所有程式碼與資料區段均為 32 位平坦記憶體模式的保護模式區段,定義其中的程序與資料均為 32 位位移量。VMM 載入 VxD 時會依實際記憶體位置修正所有位移量,因此保護模式區段中應使用 OFFSET32 巨集而非普通 OFFSET。VxD 不得改變 CS、DS、ES、SS 區段暫存器,但可使用 FS、GS。

2. 保護模式指令

VxD 來源檔必須以 .386p 指令開頭,告知組譯器允許保護模式指令。雖然 VxD 在特權等級 0 運行,但不應使用保護模式指令修改 CPU 運行狀態(如修改全域描述符/中斷描述符、任務狀態區段或暫存器),否則可能對 Windows 運行造成不利影響。唯一例外是虛擬數學協處理器驅動程式 (VMCPD) 可修改 CR0 中的 80387 位。

3. 包含檔

包含檔定義 VxD 所需巨集、結構、符號與服務表,用於宣告區段與程序、使用 VMM 與其他 VxD 服務。常用包含檔:

  • VMM.INC:所有 VMM 服務與所需巨集/符號(如 Declare_Virtual_Device、VMMCall)。
  • DEBUG.INC:除錯終端輸出資訊與資料檢查巨集,功能由定義除錯符號的 VxD 組譯時實現。
  • VPICD.INC:虛擬可程式化中斷控制器 (VPICD) 服務、巨集、符號。VPICD 處理所有中斷,許多 VxD 需其服務。
  • SHELL.INC:虛擬殼層裝置公共服務定義,提供如 MessageBox 等 Windows 函數呼叫,讓 VxD 顯示對話方塊。

4. VxD 宣告

每個 VxD 必須宣告名稱、版本號、初始化順序、裝置控制程序,多數還宣告裝置識別碼與 API 程序。使用 Declare_Virtual_Device 巨集實現,範例:

Declare_Virtual_Device VSAMPLED, 4, 0, VSAMPLED_Control, \
VSAMPLED_Device_ID, VSAMPLED_Init_Order, \
VSAMPLED_V86_API_Handler, \
VSAMPLED_PM_API_Handler

此例宣告 VSAMPLED V4.0,對應來源檔必須定義 VSAMPLED_Control 裝置控制程序。VSAMPLED_Device_ID 與 VSAMPLED_Init_Order 指定非標準 VxD 的識別碼與初始化順序,該 VxD 支援 V86 與保護模式 API 程序。VMM 依巨集資訊初始化 VxD、發送系統控制訊息、允許 MS-DOS 應用程式/驅動程式/TSR 呼叫 VxD。為使 VMM 存取此資訊,巨集建立裝置描述區塊 (DDB) 並置於保護模式資料區段(格式同 VxD_Desc_Block 結構),並為 DDB 建立連結時必須明確匯出的標號(本例為 VSAMPLED_DDB)。

5. VxD 識別碼 (ID)

VxD 提供唯一識別碼以區別於其他 VxD。VMM 動態連結程序使用識別碼為適當 VxD 連結服務呼叫。若 VxD 提供服務、API 程序或其他需唯一識別的情況,必須擁有唯一識別碼。標準 VxD 使用預定義識別碼(符號定義於 VMM.INC),支援新裝置/介面的 VxD 必須申請新識別碼。Microsoft 透過申請與登記機制確保無廠商識別碼衝突,保留 0000h–01FFh 自用。無需唯一識別碼的 VxD 應使用 Undefined_Device_ID 符號。

6. 初始化順序

每個 VxD 擁有初始化順序值,指定 VMM 應於何時初始化該 VxD。VMM 依值由小至大順序初始化虛擬機 (VM)。若多個 VxD 值相同,VMM 依 SYSTEM.INI 出現順序初始化,但無保證。需呼叫其他 VxD 服務或優先攔截中斷的 VxD,初始化順序極重要。若需在標準 VxD 前/後初始化,其值應在標準 VxD 預定義初始化順序符號(定義於 VMM.INC)基礎上加減小數值。無需初始化順序值者,使用 Undefined_Init_Order 符號。

7. 裝置控制程序

每個 VxD 擁有一個裝置控制程序,VMM 透過呼叫它發送 VxD 系統控制訊息,指導 VxD 完成初始化或通知虛擬機變化(如建立 VM)。多數 VxD 使用 Begin_Control_Dispatch、Control_Dispatch、End_Control_Dispatch 巨集定義,範例:

Begin_Control_Dispatch VSAMPLED
Control_Dispatch Sys_Critical_Init, VSAMPLED_Crit_Init
Control_Dispatch Device_Init, VSAMPLED_Device_Init
Control_Dispatch Sys_Critical_Exit, VSAMPLED_Crit_Exit
End_Control_Dispatch VSAMPLED

巨集建立名為 VSAMPLED_Control 的控制程序,產生檢查 Sys_Critical_Init、Device_Init、Sys_Critical_Exit 訊息的指令。收到訊息時,控制程序呼叫對應處理程序(如 VSAMPLED_Crit_Init),這些處理程序必須在 VxD 中定義。

七、系統控制訊息

VMM 發送系統控制訊息通知 VxD 影響系統與虛擬機的變化。多數 VxD 需追蹤 VM 建立與狀態,故 VMM 在 VM 建立、初始化、終止時發送訊息。執行焦點移動、虛擬殼層需顯示訊息方塊時也會發送訊息。常見訊息與處理方式:

訊息觸發時機與處理要點
Begin_Message_Mode虛擬殼層需顯示訊息方塊但無法使用系統 VM 與 Windows 函數時。虛擬鍵盤/滑鼠/顯示裝置保存狀態、允許訊息模式服務、初始化相關裝置。
Create_VM新 VM 建立時收到的第一條訊息。VxD 應初始化與 VM 相關資料,特別是控制區塊。
Debug_Query從 WDEB386 除錯器收到。VxD 可顯示除錯清單、讀取使用者指令。
Destroy_VM第三條 VM 終止訊息。Simulate_Int/Exec_Int 服務對收到此訊息的 VM 不再有效。
Device_Init第二條訊息。允許中斷。多數 VxD 配置/複製初始狀態至系統 VM 控制區塊裝置專用區、安裝中斷回呼函數與 I/O 保護例外、指定實例資料。此時 Simulate_Int/Exec_Int 服務生效。
End_Message_Mode虛擬殼層不再需顯示訊息方塊時。虛擬鍵盤/滑鼠/顯示裝置恢復先前保存狀態、禁止訊息模式服務。
Init_Complete第三條訊息,也是最後一條系統初始化相關訊息。多數 VxD 不處理,但使用 V86 記憶體的 VxD 應在此訊息返回前定位並申請記憶體。VxD 返回時,VMM 捨棄 VxD 初始化程式碼與資料區段。
Query_Destroy虛擬殼層需決定是否刪除 VM 時。VxD 可設定進位旗標返回阻止刪除,並使用 SHELL_Message 服務通知使用者。
Reboot_Processor使用者嘗試重新啟動電腦時。可重啟電腦的 VxD(如鍵盤裝置)應完成該工作。
Set_Device_Focus執行焦點在 VM 間移動時。VxD 恢復硬體裝置至與 VM 相關狀態。若使用 I/O 捕獲管理無焦點 VM,應盡可能移除多餘 I/O 捕獲以加速 VM 運行。
Sys_Critical_Exit最後一條訊息。禁止中斷。Simulate_Int/Exec_Int 不再有效。VxD 應復位相關硬體裝置,確保能無問題返回實模式。
Sys_Critical_Init第一條訊息。中斷仍被禁止,VxD 應盡快完成任務。多數 VxD:安裝/初始化需支援硬體中斷與 VMM/其他 VxD 軟體中斷的函數、申請需獨佔 V86 記憶體分頁(如虛擬顯示裝置申請顯示記憶體)、初始化 VxD 服務所需資料(通常含讀取 SYSTEM.INI 設定)。處理此訊息時 Simulate_Int/Exec_Int 必須不可用。
Sys_VM_InitInit_Complete 後收到。VxD 應初始化系統 VM 硬體與軟體狀態。若設定進位旗標返回,VMM 終止所有程序並退出 Windows。
Sys_VM_Terminate第一條系統 VM 終止訊息。VxD 可開始準備終止。Simulate_Int/Exec_Int 有效。系統 VM 總是最後被終止的 VM。
System_Exit系統終止時的第一條訊息。VMM 在 Sys_VM_Terminate 後發送。允許中斷,但 Simulate_Int/Exec_Int 不再有效。若因嚴重錯誤觸發,VxD 可修改系統 VM 記憶體恢復系統狀態,使 Windows 能正常終止而不當機。
VM_Critical_Init新 VM 建立時的第二條訊息。VxD 可設定進位旗標阻止 VM 建立。禁止中斷,Simulate_Int/Exec_Int 無效。
VM_Init新 VM 建立時的第三條訊息。VxD 應初始化 VM 硬體與軟體狀態(如虛擬顯示裝置執行 INT 10H 設定初始顯示模式)。
VM_Not_Execute第二條 VM 終止訊息(若 VM 已被虛擬殼層刪除則為第一條)。可檢查 EDX 旗標判斷終止原因。Simulate_Int/Exec_Int 對該 VM 不再有效。
VM_ResumeVM 執行恢復時(如切換至前景)。VxD 應鎖定資源、準備內部結構。若設定進位旗標返回,VMM 不恢復 VM 執行。
VM_SuspendVM 被暫停時(如切換至背景)。VxD 應解鎖與 VM 相關資源。
VM_Terminate第一條 VM 終止訊息。VxD 可開始準備 VM 終止。Simulate_Int/Exec_Int 有效。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved