核心模式驅動程式架構

核心模式驅動程式架構（Kernel-Mode Driver Framework，缩写KMDF）是微软公司推出的Windows驅動程式基礎（Windows Driver Foundation）之一，建構Windows XP與Windows Server 2003的核心模式（Kernel-Mode）驅動程式所需的基本功能，包括對隨插即用（PNP）、電源管理（Power Manager）、I/O佇列、直接記憶體存取（DMA）、Windows Management Instrumentation（WMI）和同步處理等的完整支援。KMDF的設計並不能用來取代WDM，它提供“Skeletal WDM”建置來替代WDM；目前，KMDF並不支援匯流排篩選驅動程式（Bus Filter Driver）。 Kernel-Mode Driver Framework目前支援下列類型的核心模式（kernel mode）驅動程式之建立了： 隨插即用（PNP）裝置所使用的Function Driver。 隨插即用（PNP）裝置所使用的Filter Driver。 隨插即用（PNP）裝置堆疊（Stack）所使用的Bus Driver。 Windows NT 4.0型態裝置所使用的Control裝置驅動程式。 KMDF是可重新進入程式庫（Reentrant Library）。 自Windows 2000開始，開發驅動程式必以WDM為基礎的，但開發難度太大，無法像使用者模式應用程式開發那樣容易。KMDF支援驅動程式在Windows Driver Model環境中撰寫驅動程式，簡化其中的過程，但是KMDF的設計並不能用來取代WDM，它提供「Skeletal WDM」建置來替代WDM。早期的WDM可支援Windows 98、Windows Me、Windows 2000和Windows XP；至於WDF計劃支援Windows XP，以及更新的版本。 KMDF係以物件為基底建立於WDM架構之上。不同的功能有不同的物件，KMDF在實作上包含了： 即插即用和电源管理 I/O队列 直接内存访问（DMA） Windows Management Instrumentation（WMI） 同步 在Windows作業系統中驅動程式的起始點都是在DriverEntry函式，DriveryEntry是驅動程式的進入點（entry point）。在DriverEntry函式的實作裡，你需要具現化（instantiate）你的WDFDRIVER物件，並且告知WDF framework要去哪裡呼叫你的系統。 NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { WDF_DRIVER_CONFIG config; NTSTATUS status = S_OK; KdPrint((__DRIVER_NAME "DriverEntry Begin\n")); WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd); status = WdfDriverCreate( DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, // Pointer to config structure WDF_NO_HANDLE); // or NULL, Pointer to get WDFDRIVER handle if(T_SUCCESS(status)) { KdPrint((__DRIVER_NAME "WdfDriverCreate failed with status 0x%08x\n", status)); } KdPrint((__DRIVER_NAME "DriverEntry End\n")); return status; } EvtDeviceAdd函數，在系統發現新硬體插入時被呼叫。這個函數將挑起WDF驅動程式架構的大部分工作，EvtDeviceAdd事件被喚起之餘一定會帶出一個WDFDRIVER物件，並且指向一個WDFDEVICE_INIT結構。在裝置產生（device crated）之前，必先進行初始化的動作。如果EvtDeviceAdd執行成功，那麼EvtDevicePrepareHardware是架構下一個被執行的函式，用以保證驅動程式能夠訪問硬體。 WDFSTATUS DioEvtDeviceAdd(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit) { WDFSTATUS status = STATUS_SUCCESS; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES objAttributes; WDFDEVICE device; PDIO_DEVICE_CONTEXT devContext; WDF_IO_QUEUE_CONFIG ioCallbacks; WDF_INTERRUPT_CONFIG interruptConfig; WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings; WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); pnpPowerCallbacks.EvtDevicePrepareHardware = DioEvtPrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = DioEvtReleaseHardware; pnpPowerCallbacks.EvtDeviceD0Entry= DioEvtDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Exit = DioEvtDeviceD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, pnpPowerCallbacks); WDF_OBJECT_ATTRIBUTES_INIT(&objAttributes); WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&objAttributes, DIO_DEVICE_CONTEXT); status = WdfDeviceInitUpdateName(DeviceInit, L"\\device\\WDFDIO"); status = WdfDeviceCreate(&DeviceInit, // Device Init structure &objAttributes, // Attributes for WDF Device &device); // return new WDF Device pointer, devContext = DioGetContextFromDevice(device); // Get device extension devContext->WdfDevice = device; // Create a symbolic link for the control object status = WdfDeviceCreateSymbolicLink(device, L"\\DosDevices\\WDFDIO"); WDF_IO_QUEUE_CONFIG_INIT(&ioCallbacks, WdfIoQueueDispatchSerial, WDF_NO_EVENT_CALLBACK, // StartIo WDF_NO_EVENT_CALLBACK); // CancelRoutine ioCallbacks.EvtIoDeviceControl = DioEvtDeviceControlIoctl; status = WdfDeviceCreateDefaultQueue(device, &ioCallbacks, WDF_NO_OBJECT_ATTRIBUTES, NULL); // pointer to default queue WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, // Configure the Interrupt object FALSE, // auto-queue DPC? DioIsr, // ISR DioDpc); // Defered Procedule Call interruptConfig.EvtInterruptEnable = DioEvtInterruptEnable; interruptConfig.EvtInterruptDisable = DioEvtInterruptDisable; status = WdfInterruptCreate(device, &interruptConfig, &objAttributes, &devContext->WdfInterrupt); WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, // Initialize idle policy IdleCannotWakeFromS0); status = WdfDeviceUpdateS0IdleSettings(device, &idleSettings); return status; } 如果EvtDeviceAdd順利執行成功，那麼EvtDevicePrepareHardware是架構下一個被執行的函式，用以保證驅動程式能夠訪問硬體。 NTSTATUS EvtDevicePrepareHardware( IN WDFDEVICE Device, IN WDFCMRESLIST ResourceList, IN WDFCMRESLIST ResourceListTranslated ) { NTSTATUS status = STATUS_SUCCESS; UNREFERENCED_PARAMETER(Device); UNREFERENCED_PARAMETER(ResourceList); UNREFERENCED_PARAMETER(ResourceListTranslated); return status; } NTSTATUS EvtDeviceD0Entry( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE PreviousState ) { NTSTATUS status = STATUS_SUCCESS; return status; } NTSTATUS EvtDeviceD0Exit( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE TargetState ) { NTSTATUS status = STATUS_SUCCESS; return status; } VOID EvtDeviceIoDefault( IN WDFQUEUE Queue, IN WDFREQUEST Request ) { WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED); } Windows Driver Kit （页面存档备份，存于互联网档案馆） Kernel-Mode Driver Framework Homepage （页面存档备份，存于互联网档案馆） Microsoft KMDF Paper （页面存档备份，存于互联网档案馆）