Windows 9x 為相容 MS-DOS/Win16/Win32 應用,引入虛擬機 (VM) 架構。VxD (Virtual Device Driver) 運行於 Ring 0,受 VMM (Virtual Machine Manager) 管控,負責:
Win 98 同時支援 WDM 與 VxD 兩種驅動模型。
| 段類型 | 位元寬度 | 用途 | 生命週期 |
|---|---|---|---|
| Real-Mode Init | 16-bit | 保護模式前初始化 | 初始化後捨棄 |
| Protected-Mode Init | 32-bit | 進入保護模式後初始化 | 初始化後捨棄 |
| Pageable | 32-bit | 大多數代碼/資料 | 可分頁換出 |
| Locked / Non-pageable | 32-bit | ISR、VxD 入口、異步服務 | 常駐記憶體 |
| Static | 32-bit | 動態載入 VxD 的共享代碼/資料 | 卸載後保留 |
| Debug Only | 32-bit | 僅除錯環境載入 | 除錯時才存在 |
.h/.cpp/.mak 框架,含訊息分派、API 入口、服務表樣板。優於 DDK:VToolsD 屏蔽底層細節、提供豐富 C++ 封裝、支援面向對象開發。
Audcard.vxd 處理,ISR 結束後 Shell_PostMessage 通知應用層。DeviceIoControl ↔ OnW32DeviceIoControl 交換緩衝區。Audcard.vxd) ISR。Shell_PostMessage 發送自定義訊息 (0x1000) 給應用視窗。sendPhysicalEOI() 通知 VPICD 中斷結束。// Audcard.h
#define MY_IRQ 5
class MyHwInt : public VHardwareInt {
public:
MyHwInt() : VHardwareInt(MY_IRQ, 0, 0, 0) {}
virtual VOID OnHardwareInt(VMHANDLE);
};
class AudcardDevice : public VDevice {
public:
virtual BOOL OnSysDynamicDeviceInit();
virtual BOOL OnSysDynamicDeviceExit();
virtual DWORD OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams);
MyHwInt* pMyIRQ;
};
// Audcard.cpp
BOOL AudcardDevice::OnSysDynamicDeviceInit() {
// 硬體初始化...
pMyIRQ = new MyHwInt();
if (pMyIRQ && pMyIRQ->hook()) { // 掛接中斷
pMyIRQ->physicalUnmask(); // 開啟 IRQ5
return TRUE;
}
return FALSE;
}
BOOL AudcardDevice::OnSysDynamicDeviceExit() {
delete pMyIRQ;
return TRUE;
}
VOID MyHwInt::OnHardwareInt(VMHANDLE hVM) {
// 讀取硬體緩衝區...
SHELL_PostMessage(AppWnd, WM_USER_POSTVXD, 0, 0, 0, NULL);
sendPhysicalEOI();
}
CreateFile("\\\\.\\Audcard") → 觸發動態載入DeviceIoControl(hDev, IOCTL_CODE, inBuf, inSize, outBuf, outSize, &bytes, NULL) → 對應 OnW32DeviceIoControlCloseHandle(hDev) → 觸發動態卸載VxD 開發是 Ring 0 程式設計的經典練兵場。雖然 Windows 9x 已退役,但其虛擬化、中斷虛擬化、Ring 0/3 轉換、動態載入等核心概念,在現代 Hypervisor、WDM/KMDF、UEFI 驅動、甚至雲端虛擬化技術中均有映射。透過 VToolsD 實作音訊卡驅動,能建立最紮實的系統級思維基礎。