热门问题
时间线
聊天
视角
核心模式驱动程序框架
来自维基百科,自由的百科全书
Remove ads
核心模式驱动程序框架(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)。
Remove ads
与WDM的关系
自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; }
Remove ads
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; }
Remove ads
如果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; }
Remove ads
VOID EvtDeviceIoDefault(
IN WDFQUEUE Queue,
IN WDFREQUEST Request
)
{
WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
}
外部链接
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads