當虛擬機器管理器 (VMM) 初始化一個 VxD 時,會依序執行以下六個關鍵步驟:
Sys_Critical_Init 訊息至裝置控制程序:此時硬體中斷被禁止,VxD 應儘快完成自身初始化。Device_Init 訊息至裝置控制程序:硬體中斷已允許,VxD 必須準備好管理來自設備的中斷。Init_Complete 訊息至裝置控制程序。Init_Complete 後,不得嘗試存取這些段中的程序與資料。在初始化過程的任何時刻,VxD 均可設定進位旗標返回 VMM 以阻止載入。部分 VMM 服務(如初始化資訊服務)僅在初始化期間有效。
任何靜態裝置驅動程式均可提供實模式初始化程序,在 Windows 切換至保護模式前執行初始化任務。VMM 載入 VxD 時會呼叫該程序,其可檢查 Windows 環境(包括登錄檔與初始化檔設定)以決定是否應載入該 VxD。該程序亦可向 Windows 回傳資訊,為每個虛擬機器的實例指定保留給設備專用的實體記憶體分頁與資料項位址。
VxD 可提供服務功能(函數或程序)供 VMM 與其他 VxD 使用,使其能直接存取該 VxD 的特性、測試並修改其功能。VxD 無法像 Windows DLL 那樣導出函數,而是透過 INT 20H 由 VMM 提供動態連結至 VxD 服務。中斷處理程序依服務編號判斷支援該服務的 VxD,並查詢 VxD 服務表中的服務位址。
VxD 使用 BeginProc/EndProc 巨集搭配 Service 與 Async_Service 選項定義服務。巨集標記服務程式碼的起止,選項標識該程序為服務。範例:
BeginProc VSAMPLED_Get_Version, Service
mov ax, 030Ah
clc
ret
EndProc VSAMPLED_Get_Version
Async_Service 表示該服務可被非同步呼叫(如在中斷處理中呼叫)。非同步服務必須可重入,且不得呼叫 VMM 與非非同步的 VxD 服務。
VMM 與標準 VxD 採用兩種呼叫慣例:
_)開頭,參數透過堆疊中的 32 位值傳遞,結果透過 EAX(32 位)或 EAX/EDX(64 位)回傳,服務保護 EBX、ES、FS、GS、ESI、EDI,僅修改旗標暫存器與 EAX、EBX、EDX。VxD 使用 Begin_Service_Table/End_Service_Table 巨集宣告服務表,標記包含服務名與選用段名的列表。宣告必須置於含 Declare_Virtual_Device 巨集的檔案中,且須先定義裝置指定符號。範例:
Create_VSAMPLED_Service_Table equ 1
Begin_Service_Table VSAMPLED
VSAMPELD_Service VSAMPLED_Get_Version, Local
VSAMPLED_Service VSAMPLED_Service_1
VSAMPLED_Service VSAMPLED_Service_2, VxD_ICODE
End_Service_Table VSAMPLED
Create_VSAMPLED_Service_Table 符號指示為 VSAMPLED 建立服務表。BeginProc 定義的名稱完全一致。LOCAL 選項;否則視為外部服務。VxD_CODE 區段,需註明區段名(如 VxD_ICODE)。Get_Version 服務(清除進位旗標並在 AX 回傳版本號),新服務必須附加於表尾或保留空間中。插入服務會導致所有使用該 VxD 服務的 VxD 需重建。VxD 可透過包含另一 VxD 的服務表宣告來引入其服務,此時裝置指定符號定義不得先於服務表宣告。呼叫端使用 VMMcall 巨集呼叫 VMM 服務,VxDcall 巨集呼叫 VxD 服務。由於電腦配置不同,VxD 可能在啟動時載入失敗,因此呼叫端必須在呼叫前驗證目標 VxD 服務是否有效:嘗試呼叫其 Get_Version,若 VxD 未載入,VMM 會設定進位旗標並在 AX 回傳 0。
VxD 可提供 V86 模式與保護模式 API 程序,允許虛擬機中執行的應用程式存取 VxD 功能。若要啟用,必須在 Declare_Virtual_Device 巨集參數中定義。應用程式將 BX 設為 VxD 識別碼,呼叫 INT 2FH 功能 1684H 取得特定虛擬機 API 程序入口位址,VMM 回傳位址供應用程式間接呼叫。
呼叫時,VMM 保存應用程式暫存器並呼叫 VxD API 程序,將目前虛擬機控制代碼置於 BX,Client_Reg_Struc 結構位址置於 EBP。API 程序必須檢測客戶暫存器值(透過 Client_Reg_Struc)判斷呼叫功能。慣例上,AH 指定主功能號,AL 指定次功能號,其他暫存器作參數。API 程序透過修改客戶暫存器回傳值,可修改 EAX、EBX、ECX、EDX、ESI、EDI。
BeginProc VSAMPLED_API_Get_Version
movzx eax, [ebp.Client_AX] ; 取功能號
or eax, eax
jnz Undefined
Get_Version:
mov [ebp.Client_AX], 030AH ; 在客戶暫存器 AX 回傳值
and [ebp.Client_Flags], NOT CF_Mask ; 清除進位旗標
ret
Undefined:
or [ebp.Client_Flags], CF_Mask ; 設定進位旗標
ret
EndProc VSAMPLED_API_Get_Version
VxD 可為 INT 2FH 中斷安裝回呼程序以提供功能,允許應用程式在 VxD 未提供 API 程序時存取 VxD(如標準虛擬顯示裝置支援與 Windows 顯示驅動程式通訊的 INT 2FH 功能集)。Windows 自身安裝 INT 2FH 處理程序支援多種功能,允許 MS-DOS 裝置驅動程式與 TSR 在 Windows 啟動或虛擬機運行時執行特定動作。
MASM.EXE(MASM 6.11+)組譯。.DEF),使用 32 位平坦模式連結器 LINK.EXE 連結目標檔。慣例上輸出檔名與 VxD 同名,副檔名為 .VXD。MAPSYM.EXE 為可執行檔建立除錯資訊。VxD 不與 Windows DLL 相容,Windows 應用程式無法直接載入使用。但 Win32 應用程式可透過 CreateFile 與 DeviceIoControl 載入動態載入的 VxD 並互動。模組定義檔格式範例:
LIBRARY VSAMPLED
DESCRIPTION 'VSAMPLED Device (Version 4.0)'
EXETYPE DEV386
SEGMENTS
_LTEXT PRELOAD NONDISCARDABLE
_LDATA PRELOAD NONDISCARDABLE
_ITEXT CLASS 'ICODE' DISCARDABLE
_IDATA CLASS 'ICODE' DISCARDABLE
_TEXT CLASS 'PCODE' NONDISCARDABLE
_DATA CLASS 'PCODE' NONDISCARDABLE
EXPORTS
VSAMPLED_DDB @1
LIBRARY 必須指定與裝置描述區塊(DDB)相同的 VxD 名稱,EXPORTS 必須指定 DDB 名稱,DDB 匯出序數固定為 1。