核心模式驱动程序框架

✍ dations ◷ 2025-09-08 23:01:24 #微软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是框架下一个被运行的函数,用以保证驱动程序能够访问硬件。

相关

  • 6s2 4f14 5d12, 8, 18, 32, 9, 2蒸气压3, 2, 1 (弱第一:523.5 kJ·mol−1 第二:1340 kJ·mol−1 第三:2022.3 kJ·mol主条目:镥的同位素镥(Lutetium,台湾称镏,旧译作鏴)是一种化
  • 葛丽泰·嘉宝葛丽泰·嘉宝(Greta Garbo,1905年9月18日-1990年4月15日),本名葛丽泰·洛维萨·古斯塔夫松(Greta Lovisa Gustafsson),瑞典国宝级电影女演员,奥斯卡终身成就奖得主,好莱坞星光大道入选
  • 奖牌奖章或奖牌是一种拥有浮雕的金属制奖励品,一般用以奖励那些在运动、军事、科学、学术、艺术上或其他领域拥有特别成就及贡献者。在许多非军事项目,如一般的体育比赛,会颁发奖牌
  • 三投斯将军市三投斯将军市(英语:General Santos,简写:G.S.C.或GenSan.,宿雾语:Dakbayan sa General Santos)是一个位于菲律宾 民答那峨岛 斯哥斯萨根行政区 南哥打巴托省的城市。也是该省(南哥打
  • 天主教塔比拉兰教区天主教塔比拉兰教区(拉丁语:Dioecesis Tagbilarana、他加禄语:Diyosesis ng Tagbilaran、Cebuano:Dyosesis sa Tagbilaran)是菲律宾一个罗马天主教教区,属宿雾总教区。1941年11月8
  • 阿尔奈-汤普森分类法阿尔奈-汤普森分类法(英语:Aarne-Thompson classification system),简称AT分类法,是一套民间故事(Folk tales)与童话(Fairy tales)分类的方法。这套分类法先是由芬兰民俗学者安蒂·阿
  • 卡普斯钦斯基方程卡普斯钦斯基方程(英语:Kapustinskii equation)可以计算离子晶体的晶格能 ,而这是实验难以确定的。这是以卡普斯钦斯基的名字命名的,他在1956年提出了这个方程。这样计算的晶格能
  • 斯巴达克斯起义斯巴达克斯起义(又称“第三次奴隶战争”,拉丁语:Tertium Bellum Servile),是罗马共和国末期(前73年-前71年)由斯巴达克斯领导的大规模角斗士奴隶起义,也是古罗马三次奴隶战争中规模最
  • 歌仔册歌仔册为歌仔的唱本,是近代重要的一种闽南语通俗文学,主要流行于闽南或台湾等闽南人生活区域。歌仔册对闽南语白话的文书系统有着重大的影响,虽然歌仔册的用字极为不统一,且经常
  • 萝西·培瑞兹萝西·培瑞兹(英语:Rosa María "Rosie" Pérez,1964年9月6日-)是曾获奥斯卡奖提名的美国电影女演员、编舞家以及导演。她以浓厚的鼻音与布鲁克林口音著名。