**視窗驅動程式模型**（**Windows Driver Model**，簡稱WDM），是微軟視窗作業系統的驅動程式設計架構，包括對於各項裝置（Device）的支援，如鍵盤（Keyboard）、滑鼠（Mouse）、網路卡（Network Driver Interface Specification，Ndis）、通用序列匯流排（Universal Serial Bus，USB）等。WDM可支援Windows 98, Windows 98 Second Edition, Windows Me, Windows 2000, Windows XP以及Windows Server 2003在x86平台上的建制工作。這個架構分成好幾個管理層面：

* 核心（Kernel）
* 物件管理（Object Manager）
* 執行（Executive）
* 輸入輸出管理（I/O Manager）
* 記憶體管理（Memory Manager）
* 行程服務（Process Service）
* 執行時期函式庫（Run-time Library）
* 電源管理（Power Manager）
* 隨插即用子系統（Plug and Play Subsystem）
* 視窗管理指令（Windows Management Instrumentation，WMI）
* 核心流（Kernel Streaming）
* 硬體抽象層（Hardware Abstraction Layer）

種類
--

驅動程式的種類有匯流排驅動程式（bus driver）、功能驅動程式（function driver）、篩選驅動程式（filter driver）三種：

* 匯流排驅動程式（bus drivers）
	+ 虛擬匯流排驅動程式（Virtual bus drivers）：呼叫IoInvalidateDeviceRelations通知PnP Manager。
* 功能驅動程式（function drivers）
	+ 微埠型驅動程式（miniport drivers）：屬於USB, Audio, SCSI以及network的轉換器（adapters）。
	+ 虛擬裝置驅動程式（Virtual device drivers）
	+ 類型驅動程式（Class drivers）
* 篩選性驅動程式（filter drivers）
	+ 上層篩選性驅動程式（upper-filter drivers）
	+ 下層篩選性驅動程式（lower-filter drivers）

程式進入點
-----

如同許多語言從main函式開始，WDM驅動程式的載入（Loading）乃至於動作，以及其卸載（Unload）行為，都有其步驟與規則。WDM驅動程式可以動態式的載入與卸載，當偵測到裝置（Device）插入的時候，依據「PnP Manager」會自動地載入相對應的裝置驅動程式，然後成為「Driver Object」，並呼叫DriverEntry函式。所有的WDM驅動程式，都必須擁有這個DriverEntry常式（routine），而且「此一名稱不可改變」的，所有的驅動程式也是從這裡開始執行的，I/O Manager首先呼叫驱动程式的`DriverEntry()`。DriverEntry在DDK Compiler編譯出來的輸出符號表是"`DriverEntry@8`"，原因是微軟的C編譯器把stdcall函示（例如VcDCall）的名稱加上"記號"，加上一個＠符號，在附上參數的總位元組個數，8指此function的所有參數所佔的byte數。

DriverEntry函式有兩個參數，其中第一个参数`PDRIVER_OBJECT DriverObject`是指向该驅動程式对应的物件指標；`PUNICODE_STRING RegistryPath`，驅動程式的服务主要鍵碼，這個參數的使用時機並不多。以下是一個簡單而標準的DriverEntry基本實作：

```
 NTSTATUS DriverEntry(PDRIVER\_OBJECT DriverObject, PUNICODE\_STRING pRegistryString)
 {
 //PDEVICE\_OBJECT DriverObject;
 UNICODE\_STRING deviceName;
 RtlInitUnicodeString( &deviceName, DEVICE\_NAME );
 
 status = IoCreateDevice( DriverObject, 0, &deviceName, 
 FILE\_DEVICE\_UNKNOWN, FILE\_DEVICE\_SECURE\_OPEN, true, &pDeviceObj );
 
 UNICODE\_STRING linkName;
 RtlInitUnicodeString( &linkName, LINK\_NAME );
 status = IoCreateSymbolicLink( &linkName, &deviceName );
 
 DriverObject->DriverUnload = DriverUnload;
 DriverObject->MajorFunction[IRP\_MJ\_CREATE] =
 DriverObject->MajorFunction[IRP\_MJ\_CLOSE] =
 DriverObject->MajorFunction[IRP\_MJ\_DEVICE\_CONTROL] = xxDriverDispatch;
 DriverObject->DriverUnload = xxUnload;
 
 return STATUS\_SUCCESS;
 }

```

IRQL
----

DriverEntry運作在IRQL = PASSIVE\_LEVEL等級，所以可以使用分頁內存。WDM有數個經常實作的PASSIVE\_LEVEL等級如下：

* DriverEntry
* Dispatch Function：DispatchXxx
* Unload：UnloadXxx
* AddDevice: XxxAddDevice
* Reinitialize: XxxReinitialize

另外還有幾個DISPATCH\_LEVEL等級的函式如下：

* StartIo
* AdapterControl
* ControllerControl
* IoTimer
* Dpc（延遲程序呼叫，Deferred Procedure Call）

派送行程
----

當*DriverEntry*函式完成物件的初始化與系統註冊之後，接下來的重點便會落在Dispatch Function身上。每當I/O Manager得到一個請求時（例如按鍵，移動滑鼠），它使用請求的函數代碼（IoControlCode）呼叫驅動程序中幾個Dispatch行程。

```
 NTSTATUS xxDispatch (IN PDEVICE\_OBJECT DeviceObject,IN PIRP pIrp)
 { 
 NTSTATUS ntStatus = STATUS\_SUCCESS;
 ULONG IoControlCodes = 0; 
 PIO\_STACK\_LOCATION IrpStack=NULL; 
 
 pIrp->IoStatus.Status = STATUS\_SUCCESS;
 pIrp->IoStatus.Information = 0;
 
 IrpStack = IoGetCurrentIrpStackLocation(pIrp); 
 
 switch (IrpStack->MajorFunction)
 { 
 case IRP\_MJ\_CREATE:
 break;
 case IRP\_MJ\_CLOSE:
 break;
 case IRP\_MJ\_DEVICE\_CONTROL:
 IoControlCodes=IrpStack->Parameters.DeviceIoControl.IoControlCode;
 switch (IoControlCodes)
 { 
 case IOCTL\_1:
 break;
 case IOCTL\_2:
 break;
 default:
 pIrp->IoStatus.Status = STATUS\_INVALID\_PARAMETER;
 break;
 }
 break;
 default:
 break;
 }
 ntStatus=pIrp->IoStatus.Status;
 
 IoCompleteRequest(pIrp,IO\_NO\_INCREMENT);
 
 return ntStatus;
 }

```

卸載
--

Unload負責在驅動程式被停止前做一些必要的處理動作，如释放资源，记录最後状态等。

```
 VOID DriverUnLoad (IN PDRIVER\_OBJECT DriverObject)
 { 
 if (DeviceObject) {
 IoUnregisterFileSystem(DeviceObject);
 IoDeleteDevice(DeviceObject);
 //DeviceObject = 0;
 }

```

編譯
--

驅動程式的编译需要使用DDK（*Device Driver Kit*）中的build指令，它是一道命令行程序，一般會在後面加上參數：**-ceZ**。例如：

```
 C:\driver sample>build.exe -ceZ
```

DDK可用於建立用於 Windows 2000、Windows XP、Microsoft Windows Server 2003、Vista的建置環境，但在Windows作業系統並非預設的功能，必須另行安裝。安装完成後你會看到Build Enviroment，**free是指release版，check則是debug版**。

* Windows XP checked 64 Bit Build Environment
* Windows XP checked Build Environment
* Windows XP free 64 Bit Build Environment
* Windows XP free Build Environment

build指令一開始呼叫Build.exe編譯連結器，從系統「環境變數」（Environment Variable）Include中得到引用文件的地址，然後呼叫**Visual C++**的编译链接器Nmake.exe进行实际的编译链接工作。在編譯過程中遇到的错误，遇到的警告，會記錄到buildxxx.log，buildxxx.wrn，buildxxx.err等文件中。

安裝
--

安裝過程分成兩個步驟：

* 首先將编译成的.sys文件複製到Windows NT的System32\\Drivers\\目錄下；
* 接著在Registry的HKEY\_LOCAL\_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\下建立和.sys文件同名的键，然后在之下建立名为Start、Type、ErrorControl的三種REG\_DWORD類型的键值。

範例
--

Microsoft DDK提供了大量的WDM範例（samples）參考，這些範例隨著DDK的安裝，會進駐我們的系統之中（WINDDK\xx00\src）。一般人不大可能從輪子造起一個新的驅動程式，大部份要靠"既有的範例"來改良一個新的驅動程式。

* 1394
* Audio
* AVStream
* filesys
* general
* hid
* input
* ir
* kernel

批評
--

* WDM學習曲線過長。
* 電源管理（power management）事件與隨插即用（Plug-and-play）差異太大。導致系統的睡眠（sleep）與清醒（wake up）狀態容易產生問題。
* I/O cancellation幾乎不可能達成。
* 每支驅動程式動輒要撰寫數千行的程式碼。
* 不支援純使用者模式（pure user-mode）驅動程式。

相關條目
----

* Windows Driver Foundation
* Windows Display Driver Model
* VxD

外部連結
----

* Windows Driver Foundation Homepage
* Introducing Windows Driver Framework，written by well-known Windows driver developer, Walter Oney.
* Building and deploying a basic WDF Kernel Mode Driver，CodeProject
* Developing a WDF USB Kernel Mode Driver for the OSR USB FX2，CodeProject
* A simple demo for WDM Driver development

參考
--

* Walter Oney，《Windows Driver Model》

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
微軟應用開發介面與框架 |
| --- |
|  |
| 圖形介面 | 
* 
* DirectX
* Direct2D
* Direct3D
* D3DX
* GDI / GDI+
* WPF
* Silverlight
* WinRT XAML（英语：）
* Windows色彩系统
* Windows Image Acquisition（英语：）
* Windows Imaging Component（英语：）
* DXGI
* Windows高级光栅化平台（WARP）
* WinG标准

 |
|  |
| 音樂與音效 | 
* DirectMusic
* DirectSound
* DirectX（英语：）
* 跨平台音频创作工具（XACT）
* Speech API（英语：）
* XAudio2（英语：）

 |
|  |
| 多媒體 | 
* DirectX
	+ Media Objects
	+ DXVA
* Xinput
* DirectInput
* DirectShow
* Image Mastering API
* Managed DirectX（英语：）
* Media Foundation
* XNA
* Windows Media
* Video for Windows

 |
|  |
| Web | 
* MSHTML
* RSS平台（英语：）
* JScript
* VBScript
* 瀏覽器協助工具物件
* XMLHTTP
* SideBar小工具
* TypeScript

 |
|  |
| 資料存取 | 
* 資料存取元件集
	+ ADO
	+ ADO.NET
		- Entity Framework
	+ ODBC
	+ OLE DB
* 可扩展存储引擎
* WCF Data Services
* 同步框架（英语：）
* Jet資料庫引擎
* 微軟XML剖析器
* OPC

 |
|  |
| 網路 | 
* Winsock
	+ LSP
* Winsock内核（英语：）
* Windows筛选平台
* 網路驅動程式介面規格（NDIS）
* Windows Rally
* 后台智能传输服务（BITS）
* 對等通訊API（英语：）
* MSMQ（英语：）
* MS MPI（英语：）
* DirectPlay
* Active Directory Service Interface

 |
|  |
| 通訊 | 
* 訊息API（英语：）
* 電話API
* WCF

 |
|  |
| 管理 | 
* Win32控制台
* Windows Script Host
* WMI
* PowerShell
* 工作排程器
* Offline Files（英语：）
* 磁碟區陰影複製服務
* Windows Installer
* Windows錯誤回報（英语：）
* 事件記錄器
* 通用日志文件系统

 |
|  |
| 元件與模型 | 
* COM
* COM+
* ActiveX
* DCOM
* .NET框架

 |
|  |
| 函式庫 | 
* 框架类库
* MFC
* 活动模板库（ATL）
* WTL

 |
|  |
| 驱动程序 | 
* WDM
* WDF
	+ KMDF
	+ UMDF
* WDDM
* NDIS
* UAA
* BDA（英语：）
* VxD

 |
|  |
| 安全性 | 
* Crypto API
	+ CAPICOM
* Windows CardSpace
* 数据保护API
* 安全支持提供者接口（SSPI）

 |
|  |
| .NET | 
* ASP.NET
* ASP.NET AJAX
* ADO.NET
* Remoting
* Silverlight
* 任务并行库（英语：）（TPL）
* WCF
* Windows CardSpace
* WPF
* WF
* Core家族
	+ .NET Core
	+ ASP.NET Core
	+ Entity Framework Core
	+ ASP.NET Core MVC

 |
|  |
| 工廠 | 
* EFx Factory（英语：）
* Enterprise Library（英语：）
* 複合使用者介面（英语：）
* CCF（英语：）
* CSF（英语：）

 |
|  |
| 行程間通訊 | 
* MSRPC（英语：）
* 動態資料交換（DDE）
* Remoting
* WCF

 |
|  |
| 可協助性 | 
* Active Accessibility（英语：）
* 使用者介面自動化（英语：）

 |
|  |
| 文字與多語系支援 | 
* DirectWrite
* 文本服务框架（英语：）
* 文本对象模型（英语：）
* 输入法编辑器
* 語言介面套件（英语：）
* 多語系使用者介面（英语：）
* Uniscribe

 |
|  |
| 遊戲開發 | 
* Direct3D
* D3DX
* DirectSound
* DirectInput
* DirectPlay
* DirectMusic
* Managed DirectX（英语：）
* XNA

 |

 |