核心模式驱动程序框架

✍ dations ◷ 2025-06-09 16:13:10 #微软API,驱动程序

核心模式驱动程序框架(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)驱动程序之创建了:

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在实现上包含了:

在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 = ;
 KdPrint((__DRIVER_NAME "DriverEntry Begin\n"));
 WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd); status = WdfDriverCreate(                     DriverObject,                     RegistryPath,                     ,                     &config, // Pointer to config structure                     ); // 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;}

Add Device

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,                                       ,                                       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;}

Prepare Hardware

如果EvtDeviceAdd顺利运行成功,那么EvtDevicePrepareHardware是框架下一个被运行的函数,用以保证驱动程序能够访问硬件。

相关

  • gRNA向导RNA(guide RNA,gRNA),也称为小向导RNA(small guide RNA,sgRNA)。是作用于动质体(kinetoplastid)体内一种称为RNA编辑(RNA editing)的后转录修饰过程中。也是一种小型非编码RNA。可
  • 切尔诺贝利 (消歧义)切尔诺贝利(拉丁化:Chernobyl)是一座乌克兰的城市名,位在切尔诺贝利核事故发生地附近。切尔诺贝利也可指:
  • 詹姆斯·鲍德温詹姆斯·亚瑟·鲍德温(英语:James Arthur Baldwin,1924年8月2日-1987年12月1日),美国作家,小说家,诗人,剧作家和社会活动家。作为黑人和同性恋者,鲍德温的不少作品关注20世纪中叶美国
  • 加德兹area_total_km2 人加德兹(波斯语:گردیز‎)位于阿富汗东部,是帕克蒂亚省的首府。
  • 110街坐标:40°47′57″N 73°57′17″W / 40.799261°N 73.954602°W / 40.799261; -73.954602110街(110th Street)是纽约市曼哈顿区上城的一条东西向街道。它通常作为哈林区与中央
  • 洛坎机场洛坎机场(他加禄语:Paliparan ng Loakan;IATA代码:BAG;ICAO代码:RPUB)建于1934年,是目前菲律宾本格特省碧瑶市唯一的机场,被菲律宾民用航空局(CAAP)列为二级机场(即国内小型机场)。该机
  • 松田耕平松田耕平((日文)まつだ こうへい,1922年1月28日-2002年7月10日)为日本东洋工业(现称马自达)的第四任社长,祖父为该公司第二任社长松田重次郎,生父为该公司第三任社长松田恒次,长子为现
  • 柳本·贝罗夫柳本·贝罗夫(保加利亚语:Любен Беров,1925年10月6日保加利亚索非亚-2006年12月7日),保加利亚经济学家、政治家,曾任保加利亚总理。贝罗夫毕业于索非亚大学经济系,1950年-
  • 殉爆度殉爆度,代表炸药对震波的敏感度,亦即炸药受到其它炸药爆炸影响而起爆(殉爆(英语:Sympathetic detonation))的难易程度。标准的殉爆度测试方法,是取两段相同的炸药,分开一个距离,引爆其
  • 中蛙亚目角蟾科 Megophryidae 锄足蟾科 Pelobatidae 潜蟾科 Pelodytidae 北美锄足蟾科 Scaphiopodidae 异舌蟾科 Rhinophrynidae 负子蟾科 Pipidae中蛙亚目(Mesobatrachia)是无尾目下