示例工程【免费下载链接】Windows-driver-samplesThis repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver and desktop-only driver samples.项目地址https://gitcode.com/gh_mirrors/wi/Windows-driver-samples点击查看免费下载本篇技术指南以仓库中的 nfc/NfcCxSample 示例为主体深入讲解如何基于 Windows NFC 类扩展NFC Class Extension简称 NFC CX编写 NFC 功能驱动程序。示例完整对应 Microsoft 官方 NFC CX 快速入门指南NFC CX quick start guide所创建的全部代码读者读完可掌握 NFC 驱动从 DriverEntry 初始化、NFC CX 客户端配置、RF 发现参数设置到 NCI 数据包收发回调的完整实现路径并了解该示例在构建与安装环节INF 与工程配置中的关键细节。示例概述与前置条件NfcCxSample 是用于创建 NFC 功能驱动程序NFC functional driver的模板其核心思路是驱动本身不直接实现 NFC 协议栈而是通过NFC 类扩展NFC CX驱动提供的框架接口完成大部分协议处理客户端驱动只需按约定实现少量回调函数。使用 NFC CX 需要满足两个硬性前置条件README 中明确列出NFC 控制器必须实现 NFC Forum 的 NCI 协议NFC Controller InterfaceNFC CX 与控制器之间的全部交互均基于 NCI 数据包完成。驱动必须基于 UMDF 2 框架编写示例工程在项目配置中显式声明了UMDF_VERSION_MAJOR 2见 windows-drivertemplate-nfc.vcxproj。此外该示例构建的是Universal Windows Driver只使用 OneCoreUAP 中包含的 API 和 DDI因此可在支持通用驱动模型的 Windows 版本上安装运行。项目文件清单与代码结构README 的 File manifest 部分给出了项目的组成。按仓库实际内容完整文件清单如下WDK 提供不在仓库内NfcCx.h——NFC CX 客户端驱动 API 头文件随 WDK 一起发布。示例源码在 Device.h 中通过#include NfcCx.h引入。驱动源码Driver.cppDriverEntry驱动初始化入口。Device.cppDeviceContext::AddDevice设备初始化含 NFC CX 初始化、WriteNciPacketEvtNfcCxWriteNciPacket回调实现、ReadNciPacket演示调用NfcCxNciReadNotification。Device.hDeviceContext类存储设备实例状态。工程与打包文件windows-drivertemplate-nfc.infUMDF 驱动安装 INF。windows-drivertemplate-nfc.vcxproj 及 windows-drivertemplate-nfc.vcxproj.filtersMSBuild 工程与过滤器文件。windows-drivertemplate-nfc.sln解决方案文件提供 Debug/Release × x64/ARM64 四种配置。DeviceContext是驱动唯一的状态类它通过 WDF 上下文扩展机制与设备对象绑定。在 Device.h 末尾使用WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DeviceContext, DeviceGetContext)生成DeviceGetContext()辅助函数供各回调函数从WDFDEVICE句柄安全取回上下文指针。DriverEntry驱动入口的最小化初始化Driver.cpp 中的DriverEntry遵循 WDF 驱动的最佳实践——初始化阶段几乎不做任何实际工作全部资源都推迟到设备创建阶段extern C NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { NTSTATUS status; // 将 DeviceContext::AddDevice 注册为 EvtDriverDeviceAdd 回调 WDF_DRIVER_CONFIG driverConfig; WDF_DRIVER_CONFIG_INIT(driverConfig, DeviceContext::AddDevice); // 初始化 WDF 框架 status WdfDriverCreate( DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, driverConfig, WDF_NO_HANDLE); if (!NT_SUCCESS(status)) { return status; } return STATUS_SUCCESS; }关键点在于WDF_DRIVER_CONFIG_INIT(driverConfig, DeviceContext::AddDevice)驱动将设备添加回调指向DeviceContext::AddDevice静态成员函数之后 WDF 会在系统启动枚举设备或热插拔新设备时调用它。AddDevice设备初始化与 NFC CX 配置设备初始化的完整流程集中在DeviceContext::AddDeviceDevice.cpp它也是理解 NFC CX 客户端编程模型的核心。整个过程可拆解为四个阶段1. 配置 NFC 类扩展客户端NFC_CX_CLIENT_CONFIG nfcCxConfig; NFC_CX_CLIENT_CONFIG_INIT(nfcCxConfig, NFC_CX_TRANSPORT_CUSTOM); nfcCxConfig.EvtNfcCxWriteNciPacket WriteNciPacket; nfcCxConfig.DriverFlags NFC_CX_DRIVER_ENABLE_EEPROM_WRITE_PROTECTION; status NfcCxDeviceInitConfig(DeviceInit, nfcCxConfig);此处几个字段各有明确用途传输类型参数NFC_CX_TRANSPORT_CUSTOM源码注释特别说明该值仅用于遥测telemetry目的不改变驱动实际行为。因此即便控制器走的是 I2C/SPI/USB 等总线客户端仍可按需声明为 CUSTOM。EvtNfcCxWriteNciPacketNFC CX 需要向控制器发送 NCI 数据包时回调的函数是必填项。DriverFlags NFC_CX_DRIVER_ENABLE_EEPROM_WRITE_PROTECTION指示 NFC CX 读取已有的 NCI 配置值仅在必要时更新避免不必要的 EEPROM 写入。NfcCxDeviceInitConfig将客户端配置写入 WDFDEVICE_INIT 结构必须在WdfDeviceCreate之前调用否则 NFC CX 无法参与后续设备初始化。工程中还预留了一个条件编译开关ENABLE_IF_IMPLEMENTING_CUSTOM_IOCTLS启用时会将自定义IoControl回调挂到nfcCxConfig.EvtNfcCxDeviceIoControl见 Device.cpp。2. 注册 PnP 电源回调WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; WDF_PNPPOWER_EVENT_CALLBACKS_INIT(pnpCallbacks); pnpCallbacks.EvtDevicePrepareHardware PrepareHardware; pnpCallbacks.EvtDeviceReleaseHardware ReleaseHardware; pnpCallbacks.EvtDeviceD0Entry D0Entry; pnpCallbacks.EvtDeviceD0Exit D0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, pnpCallbacks);这组回调负责硬件资源生命周期PrepareHardware/ReleaseHardware管理资源可用性D0Entry/D0Exit管理电源状态切换其实现细节在下一节展开。3. 创建设备对象与 C 对象内存WDF_OBJECT_ATTRIBUTES deviceAttributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(deviceAttributes, DeviceContext); deviceAttributes.EvtDestroyCallback Destroy; status WdfDeviceCreate(DeviceInit, deviceAttributes, device); DeviceContext* context DeviceGetContext(device); new (context) DeviceContext(device); // placement new 在 WDF 分配的内存上构造对象由于 WDF 为上下文扩展分配的是裸内存示例使用 C 的placement new在DeviceGetContext返回的内存上构造DeviceContext对象相应地DeviceContext::DestroyDevice.cpp在 WDF 释放对象前手动调用析构函数与 placement new 一一对应。这是将 C 类嵌入 WDF 对象上下文的经典范式。4. 初始化 NFC CX 并下发 RF 发现配置status NfcCxDeviceInitialize(device);NfcCxDeviceInitialize让 NFC 类扩展接管设备对象、完成其内部初始化必须晚于WdfDeviceCreate。随后示例创建并下发一组“全功能开启”的 RF 发现配置NFC_CX_RF_DISCOVERY_CONFIG discoveryConfig; NFC_CX_RF_DISCOVERY_CONFIG_INIT(discoveryConfig); discoveryConfig.PollConfig NFC_CX_POLL_NFC_A | NFC_CX_POLL_NFC_B | NFC_CX_POLL_NFC_F_212 | NFC_CX_POLL_NFC_F_424 | NFC_CX_POLL_NFC_15693 | NFC_CX_POLL_NFC_ACTIVE | NFC_CX_POLL_NFC_A_KOVIO; discoveryConfig.NfcIPMode NFC_CX_NFCIP_NFC_A | NFC_CX_NFCIP_NFC_F_212 | NFC_CX_NFCIP_NFC_F_424 | NFC_CX_NFCIP_NFC_ACTIVE | NFC_CX_NFCIP_NFC_ACTIVE_A | NFC_CX_NFCIP_NFC_ACTIVE_F_212 | NFC_CX_NFCIP_NFC_ACTIVE_F_424; discoveryConfig.NfcIPTgtMode NFC_CX_NFCIP_TGT_NFC_A | NFC_CX_NFCIP_TGT_NFC_F | NFC_CX_NFCIP_TGT_NFC_ACTIVE_A | NFC_CX_NFCIP_TGT_NFC_ACTIVE_F; discoveryConfig.NfcCEMode NFC_CX_CE_NFC_A | NFC_CX_CE_NFC_B | NFC_CX_CE_NFC_F; status NfcCxSetRfDiscoveryConfig(device, discoveryConfig);NFC_CX_RF_DISCOVERY_CONFIG的四个字段分别控制PollConfig读卡器Poll模式支持的射频技术覆盖 NFC-A/B、NFC-F 212/424、ISO 15693、Active 模式及 KovioNFC-A 变体。NfcIPMode对等Peer-to-Peer模式下的发起端Initiator技术组合包括 Active 模式下的 A/F 212/F 424。NfcIPTgtMode对等模式下的目标端Target技术组合。NfcCEMode卡模拟Card Emulation模式支持的技术示例开启 A/B/F 三种。这些位掩码组合基本覆盖了当前 NFC 生态的主要射频技术实际产品可按需裁剪。射频配置下发成功后AddDevice即返回STATUS_SUCCESS。工程中还预留了ENABLE_IF_USING_SEQUENCE_HANDLER_CALLBACKS编译开关Device.cpp启用后会将NFC_CX_SEQUENCE枚举范围内的每个序列号注册到NfcCxRegisterSequenceHandler用于在 NFC CX 状态机发生特定转换时插入自定义控制器命令。电源管理通过 NfcCxHardwareEvent 启停控制器示例对 D0 电源回调的实现很有代表性——客户端驱动并不直接向控制器发 NCI 包而是把启停动作交给 NFC CXD0EntryDevice.cpp设备进入完全上电状态时构造NFC_CX_HARDWARE_EVENT并设置HostAction HostActionStart调用NfcCxHardwareEvent(Device, eventArgs)由 NFC CX 向控制器发送初始化所需的 NCI 数据包。D0ExitDevice.cpp设备进入低功耗状态前设置HostAction HostActionStop通知 NFC CX 反初始化控制器。源码注释指出一个重要特性若存在可能正在使用 NFC 控制器的客户端进程NFC CX 默认会阻止D0Exit回调被调用因此 D0 退出阶段可以安全地让控制器处于完全未初始化状态无需自行处理客户端占用冲突。PrepareHardware/ReleaseHardware目前是占位实现标注FIX ME留给开发者填写初始化/释放真实总线资源如 I2C/SPI/GPIO的代码。NCI 数据包收发两个关键方向NFC CX 与控制器之间通过 NCI 数据包双向通信客户端驱动需分别实现“下行发送”与“上行接收”。下行WriteNciPacketEvtNfcCxWriteNciPacketDevice.cpp 实现了 NFC CX 发往控制器的 NCI 包回调void DeviceContext::WriteNciPacket(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request) { void* nciPacket; size_t nciPacketLength; status WdfRequestRetrieveInputBuffer(Request, 0, nciPacket, nciPacketLength); if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return; } // FIX ME: 使用相应总线 API 将 NCI 包发送给 NFC 控制器硬件 // 例如 I2C/SPI 走 SPB 外设驱动接口USB 走 USB 驱动开发指南。 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED); }该回调从 WDFREQUEST 中取出 NCI 数据缓冲WdfRequestRetrieveInputBuffer真正的总线发送动作留作FIX MEI2C/SPI 场景应调用 SPB 外设驱动接口USB 场景则走 USB 连续读取器等端点通信。发送成功后应改为以STATUS_SUCCESS完成请求。上行ReadNciPacket 与 NfcCxNciReadNotification控制器主动上报的 NCI 包需要转发给 NFC CX。示例提供的ReadNciPacket辅助函数Device.cpp演示了标准做法NTSTATUS DeviceContext::ReadNciPacket(void* nciPacket, size_t nciPacketLength) { if (!_NciReadMemory) { // 首次调用以设备为父对象创建预分配 WDFMEMORY WDF_OBJECT_ATTRIBUTES memoryAttributes; WDF_OBJECT_ATTRIBUTES_INIT(memoryAttributes); memoryAttributes.ParentObject _Device; status WdfMemoryCreatePreallocated(memoryAttributes, nciPacket, nciPacketLength, _NciReadMemory); } else { // 后续调用让 WDFMEMORY 重新指向新数据包 status WdfMemoryAssignBuffer(_NciReadMemory, nciPacket, nciPacketLength); } // NfcCxNciReadNotification 不持有 WDFMEMORY 引用调用返回后即可释放数据内存 status NfcCxNciReadNotification(_Device, _NciReadMemory); ... }这里有两个值得注意的细节示例复用一个成员WDFMEMORY _NciReadMemory定义于 Device.h首次通过WdfMemoryCreatePreallocated创建、之后用WdfMemoryAssignBuffer重新绑定新缓冲避免频繁创建对象。源码注释明确NfcCxNciReadNotification不会保存传入 WDFMEMORY 的引用因此函数返回后即可安全释放 NCI 数据包内存。若 NCI 包本身已封装在既有 WDFMEMORY 中也可以直接将该内存传给NfcCxNciReadNotification跳过本辅助函数。触发该函数的时机同样以FIX ME标注I2C/SPI 场景通常在 GPIO 中断响应中调用USB 场景则依赖 USB 连续读取器机制收到数据后调用。可选扩展序列处理与自定义 IOCTLSequenceHandlerDevice.cpp对应EvtNfcCxSequenceHandler在 NFC CX 状态机发生特定状态转换时被调用可用于向控制器发送自定义命令。示例中直接以STATUS_SUCCESS立即完成CompletionRoutine支持异步调用。IoControlDevice.cpp对应EvtNfcCxDeviceIoControl。NFC CX 会注册默认 I/O 队列、优先处理所有 I/O 请求若启用该回调NFC CX 无法识别的 IOCTL 会被转发到这里。示例当前不支持自定义 IOCTL统一以STATUS_INVALID_DEVICE_STATE完成请求。两者均以条件编译开关ENABLE_IF_USING_SEQUENCE_HANDLER_CALLBACKS、ENABLE_IF_IMPLEMENTING_CUSTOM_IOCTLS保护属于可选能力。构建与安装配置要点INFUMDF 2 NFC CX 扩展windows-drivertemplate-nfc.inf 展示了 NFC CX 客户端驱动的 INF 关键结构[Version] 节设备类别为ClassProximityClassGuid{5630831C-06C9-4856-B327-F5D32586E060}即邻近NFC设备类。DriverVer留空需在 stampinf 属性页设置。[Manufacturer] 节目标平台限定为NT$ARCH$.10.0...17134Windows 10 1803 及以上硬件 ID 为Root\windows-drivertemplate-nfc标注TODO: edit hw-id实际产品需替换为控制器对应的设备 ID如 ACPI 硬件 ID。[MyDevice_Install.NT] 系列节通过IncludeWUDFRD.inf、NeedsWUDFRD.NT引入 WDF 反射器Reflector支持这是 UMDF 驱动安装的标准骨架。[windows-drivertemplate-nfc_Install] 节UmdfLibraryVersion$UMDFVERSION$绑定当前 WDK 的 UMDF 2 库版本ServiceBinary%13%\windows-drivertemplate-nfc.dll指向驱动存储中的 DLL而UmdfExtensionsNfcCx0102正是把 NFC 类扩展作为 UMDF 扩展组件加载进驱动栈的关键声明。工程文件Universal 驱动属性windows-drivertemplate-nfc.vcxproj 中的关键配置PlatformToolsetWindowsUserModeDriver10.0、ConfigurationTypeDynamicLibrary编译为 UMDF 用户态驱动 DLL。DriverTargetPlatformUniversal、TargetVersionWindows10产物为通用驱动。UMDF_VERSION_MAJOR2锁定 UMDF 2。NfcDrivertrue启用 NFC 驱动相关的构建支持链接 NFC CX 客户端库等。启用RunCodeAnalysis与EnablePREfast默认开启代码分析签名摘要算法使用 SHA256。支持 Debug/Release × x64/ARM64 四种平台组合见 windows-drivertemplate-nfc.sln。使用 Visual Studio WDK 打开 windows-drivertemplate-nfc.sln 即可直接编译如需命令行构建可参考仓库根目录的 Build-Samples.ps1 与 BuildEnvironment.ps1 脚本了解整体构建流程。从模板到量产驱动的落地清单综合 README 与源码中的FIX ME标注把该模板改造成可交付的 NFC 驱动需完成以下动作实现WriteNciPacket按实际总线I2C/SPI/GPIO 中断或 USB 端点把 NCI 包写入控制器成功后以STATUS_SUCCESS完成请求。接入ReadNciPacket在硬件通知GPIO 中断、USB 连续读取回调中调用将控制器上报的 NCI 包经NfcCxNciReadNotification交给 NFC CX。填充PrepareHardware/ReleaseHardware初始化/释放总线与硬件资源必要时在ReleaseHardware中清理PrepareHardware创建的资源。按需裁剪 RF 配置根据产品支持的射频技术调整NFC_CX_RF_DISCOVERY_CONFIG各字段的位掩码。更新 INF替换ManufacturerName、硬件 ID 与DriverVer并确认UmdfExtensionsNfcCx0102与所用 WDK 版本匹配。可选项启用ENABLE_IF_USING_SEQUENCE_HANDLER_CALLBACKS实现序列回调或启用ENABLE_IF_IMPLEMENTING_CUSTOM_IOCTLS扩展私有 IOCTL。由于 NFC CX 承担了 NCI 协议状态机与射频调度的绝大部分工作客户端驱动的职责被收敛为“总线搬运 资源管理 少量策略配置”这正是该模板所展示的 NFC 驱动开发的现代形态。赞分享示例工程【免费下载链接】Windows-driver-samplesThis repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver and desktop-only driver samples.项目地址https://gitcode.com/gh_mirrors/wi/Windows-driver-samples点击查看免费下载相关推荐Godot逆向工程完整指南用GDRE Tools把PCK一键还原成可编辑项目Godot逆向工程完整指南用GDRE Tools把PCK一键还原成可编辑项目 如果有一天你发现游戏源码丢了、备份损坏了或者想拆开一个用 Godot 做的游戏示例工程Windows驱动程序示例项目教程Windows驱动程序示例项目教程 1. 项目介绍 Windows Driver Samples 是一个由微软维护的GitHub仓库提供了多种Windows驱示例工程Windows 驱动程序示例项目教程Windows 驱动程序示例项目教程 项目的目录结构及介绍 Windows 驱动程序示例项目Windows driver samples是由微软提供的一个开示例工程上一篇up/up的多语言部署示例混合运行时下一篇Page Assist技术剖析本地AI模型与浏览器深度集成的架构实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考