Windows Driver Model

视窗驱动程式模型（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平台上的建制工作。这个架构分成好几个管理层面：
种类.
驱动程式的种类有汇流排驱动程式（bus driver）、功能驱动程式（function driver）、筛选驱动程式（filter driver）三种：
程式进入点.
如同许多语言从main函式开始，WDM驱动程式的载入（Loading）乃至于动作，以及其卸载（Unload）行为，都有其步骤与规则。WDM驱动程式可以动态式的载入与卸载，当侦测到装置（Device）插入的时候，依据「PnP Manager」会自动地载入相对应的装置驱动程式，然后成为「Driver Object」，并呼叫DriverEntry函式。所有的WDM驱动程式，都必须拥有这个DriverEntry常式（routine），而且「此一名称不可改变」的，所有的驱动程式也是从这里开始执行的，I/O Manager首先呼叫驱动程式的codice_1。DriverEntry在DDK Compiler编译出来的输出符号表是“codice_2”，原因是微软的C编译器把stdcall函示（例如VcDCall）的名称加上“记号”，加上一个＠符号，在附上参数的总位元组个数，8指此function的所有参数所占的byte数。
DriverEntry函式有两个参数，其中第一个参数codice_3是指向该驱动程式对应的物件指标；codice_4，驱动程式的服务主要键码，这个参数的使用时机并不多。以下是一个简单而标准的DriverEntry基本实作：
 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryString)
 //PDEVICE_OBJECT DriverObject;
 UNICODE_STRING deviceName;
 RtlInitUnicodeString( &amp;deviceName, DEVICE_NAME );
 status = IoCreateDevice( DriverObject, 0, &amp;deviceName, 
 FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, true, &amp;pDeviceObj );
 UNICODE_STRING linkName;
 RtlInitUnicodeString( &amp;linkName, LINK_NAME );
 status = IoCreateSymbolicLink( &amp;linkName, &amp;deviceName );
 DriverObject-&gt;DriverUnload = DriverUnload;
 DriverObject-&gt;MajorFunction[IRP_MJ_CREATE] =
 DriverObject-&gt;MajorFunction[IRP_MJ_CLOSE] =
 DriverObject-&gt;MajorFunction[IRP_MJ_DEVICE_CONTROL] = xxDriverDispatch;
 DriverObject-&gt;DriverUnload = xxUnload;
 return STATUS_SUCCESS;
IRQL.
DriverEntry运作在IRQL = PASSIVE_LEVEL等级，所以可以使用分页内存。WDM有数个经常实作的PASSIVE_LEVEL等级如下：
另外还有几个DISPATCH_LEVEL等级的函式如下：
派送行程.
当"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-&gt;IoStatus.Status = STATUS_SUCCESS;
 pIrp-&gt;IoStatus.Information = 0;
 IrpStack = IoGetCurrentIrpStackLocation(pIrp); 
 switch (IrpStack-&gt;MajorFunction)
 case IRP_MJ_CREATE:
 break;
 case IRP_MJ_CLOSE:
 break;
 case IRP_MJ_DEVICE_CONTROL:
 IoControlCodes=IrpStack-&gt;Parameters.DeviceIoControl.IoControlCode;
 switch (IoControlCodes)
 case IOCTL_1:
 break;
 case IOCTL_2:
 break;
 default:
 pIrp-&gt;IoStatus.Status = STATUS_INVALID_PARAMETER;
 break;
 break;
 default:
 break;
 ntStatus=pIrp-&gt;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&gt;build.exe -ceZ
DDK可用于建立用于 Windows 2000、Windows XP、Microsoft Windows Server 2003、Vista的建置环境，但在Windows作业系统并非预设的功能，必须另行安装。安装完成后你会看到Build Enviroment，free是指release版，check则是debug版。
build指令一开始呼叫Build.exe编译连结器，从系统「环境变数」（Environment Variable）Include中得到引用文件的地址，然后呼叫Visual C++的编译链接器Nmake.exe进行实际的编译链接工作。在编译过程中遇到的错误，遇到的警告，会记录到buildxxx.log，buildxxx.wrn，buildxxx.err等文件中。
安装.
安装过程分成两个步骤：
范例.
Microsoft DDK提供了大量的WDM范例（samples）参考，这些范例随著DDK的安装，会进驻我们的系统之中（WINDDK\xx00\src）。一般人不大可能从轮子造起一个新的驱动程式，大部份要靠“既有的范例”来改良一个新的驱动程式。