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

Windows 9x 虛擬裝置驅動程式 (VxD) 設計全景:架構、VToolsD 實戰與音訊卡驅動案例

     編輯:關於C++

歷史定位

Windows 9x 為相容 MS-DOS/Win16/Win32 應用,引入虛擬機 (VM) 架構。VxD (Virtual Device Driver) 運行於 Ring 0,受 VMM (Virtual Machine Manager) 管控,負責:

  • 虛擬化硬體資源(讓多 VM 共享實體裝置)
  • 仲裁 VM 存取衝突
  • 提供 Ring 3 應用呼叫的系統服務

Win 98 同時支援 WDM 與 VxD 兩種驅動模型。

VMM 與 VxD 核心關係

  • VMM 本身是特殊 VxD,掌控 VM 建立/調度/銷毀、虛擬記憶體、執行緒分時。
  • VxD 透過 DDB (Device Descriptor Block) 向 VMM 登記:入口點、服務表、版本資訊。
  • VxD 可靜態隨開機載入,或動態載入/卸載 (如本文案例)。

VxD 記憶體段類型(12 種段)

段類型位元寬度用途生命週期
Real-Mode Init16-bit保護模式前初始化初始化後捨棄
Protected-Mode Init32-bit進入保護模式後初始化初始化後捨棄
Pageable32-bit大多數代碼/資料可分頁換出
Locked / Non-pageable32-bitISR、VxD 入口、異步服務常駐記憶體
Static32-bit動態載入 VxD 的共享代碼/資料卸載後保留
Debug Only32-bit僅除錯環境載入除錯時才存在

開發工具鏈:VToolsD 2.03 + VC++ 5.0

  • QuickVxD:向導產生 .h/.cpp/.mak 框架,含訊息分派、API 入口、服務表樣板。
  • C Runtime / C++ Class Library:封裝 VMM 服務,大幅降低門檻。
  • VxDLoad / VxDView:動態載入/檢視工具。
  • 除錯器:**Soft-ICE for Win 95**(Ring 0 唯一可用除錯器)。

優於 DDK:VToolsD 屏蔽底層細節、提供豐富 C++ 封裝、支援面向對象開發。

實戰案例:可視電話音訊卡 VxD (Audcard.vxd)

硬體規格

  • PC/XT 總線擴展卡,每 20 ms 產生一次 IRQ5 中斷。
  • 中斷由動態載入的 Audcard.vxd 處理,ISR 結束後 Shell_PostMessage 通知應用層。
  • 應用層透過 DeviceIoControl ↔ OnW32DeviceIoControl 交換緩衝區。

中斷處理流程

  1. CPU 進入 Ring 0,IDT 指向 VMM 通用存根。
  2. VMM 判斷中斷來源 → 轉交 VPICD (Virtual PIC Device)。
  3. VPICD 呼叫已註冊 IRQ5 的 VxD (Audcard.vxd) ISR。
  4. ISR 讀取硬體資料 → Shell_PostMessage 發送自定義訊息 (0x1000) 給應用視窗。
  5. 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();
}

應用層互動 API

  • CreateFile("\\\\.\\Audcard") → 觸發動態載入
  • DeviceIoControl(hDev, IOCTL_CODE, inBuf, inSize, outBuf, outSize, &bytes, NULL) → 對應 OnW32DeviceIoControl
  • CloseHandle(hDev) → 觸發動態卸載

VxD 開發必備知識清單

  1. 作業系統核心:位址空間、執行上下文、鎖、IPC、非同步事件。
  2. Intel 架構:暫存器、指令集、保護機制、分頁、V86 模式。
  3. VMM 服務表:事件、記憶體、排程、同步、除錯、I/O 捕獲、中斷、VM 回調、登錄表、配置管理…

結語

VxD 開發是 Ring 0 程式設計的經典練兵場。雖然 Windows 9x 已退役,但其虛擬化、中斷虛擬化、Ring 0/3 轉換、動態載入等核心概念,在現代 Hypervisor、WDM/KMDF、UEFI 驅動、甚至雲端虛擬化技術中均有映射。透過 VToolsD 實作音訊卡驅動,能建立最紮實的系統級思維基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved