zoukankan      html  css  js  c++  java
  • 为不同版本的 Windows 编写驱动程序

    MSDN原文:https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff554887(v=vs.85).aspx

    创建驱动程序项目时,指定基本的目标操作系统,该系统是运行驱动程序的基本版本的 Windows。例如,你可以指定 Windows 7 为基本的目标操作系统。在这种情况下,驱动程序会在 Windows 7 和更高版本的 Windows 上运行。

    注意  如果为特定的基本版本的 Windows 开发驱动程序且希望驱动程序运行在更高版本的 Windows 上,则不得使用任何未记录的函数,也不得采用文档中介绍方法之外的任何方法使用记录的函数。否则,驱动程序可能会无法运行在更高版本的 Windows 上。即便你已经很小心,仅使用记录的函数,也应在每次发布新版本的 Windows 时在其上对驱动程序进行测试。
     

    编写仅使用共同功能的多版本驱动程序

    设计将在多个版本的 Windows 上运行的驱动程序时,最简单的方法是允许驱动程序仅使用运行该驱动程序的所有版本的 Windows 共同的 DDI 函数和结构。在此情形下,将最基本的目标操作系统设置为驱动程序支持的最早版本的 Windows。

    例如,要支持从 Windows 7 开始的所有版本的 Windows,应执行以下操作:

    1. 设计和实现驱动程序,以便该驱动程序仅使用 Windows 7 中提供的那些功能。

    2. 生成驱动程序时,将 Windows 7 指定为最基本的目标操作系统。

    虽然此过程很简单,但它可能会限制驱动程序仅使用更高版本的 Windows 上提供的功能子集。

    编写使用版本相关功能的多版本驱动程序

    内核模式驱动程序可以动态确定它运行的是哪个版本的 Windows 并且选择使用该版本上提供的功能。例如,必须支持从 Windows 7 开始的 Windows 所有版本的驱动程序可以在运行时确定它所运行的 Windows 版本。 如果驱动程序在 Windows 7 上运行,则它只能使用 Windows 7 支持的 DDI 函数。但是,同一个驱动程序可以使用仅适用于 Windows 8 的其他 DDI 函数,例如,当其运行时检查功能确定它在 Windows 8 上运行时。

    确定 Windows 版本

    RtlIsNtDdiVersionAvailable 为驱动程序可以在运行时用于确定特定版本的 Windows 提供的功能是否可用的函数。该函数的原型如下所示:

     
     
    BOOLEAN RtlIsNtDdiVersionAvailable(IN ULONG Version)
    
    

    在此原型中,Version 是一个值,指示 Windows DDI 的所需版本。此值必须为 DDI 版本常量之一,在 sdkddkver.h 中定义,例如 NTDDI_WIN8 或 NTDDI_WIN7。

    当调用程序运行在 Version. 指定的相同的 Windows 版本或更高版本上时,RtlIsNtDdiVersionAvailable 会返回 TRUE。

    驱动程序还可以通过调用 RtlIsServicePackVersionInstalled 函数检查特定的 Service Pack。该函数的原型如下所示:

     
     
    BOOLEAN RtlIsServicePackVersionInstalled(IN ULONG Version)
    
    

    在此原型中,Version 为一个值,指示所需的 Windows 版本和 Service Pack。此值必须为 DDI 版本常量之一,在 sdkddkver.h 中定义,例如 NTDDI_WS08SP3。

    注意,仅当操作系统版本与指定版本完全匹配时,RtlIsServicePackVersionInstalled 才会返回 TRUE。因此,如果驱动程序不是在 Windows Server 2008 SP4 上运行,则调用将 Version 设置为 NTDDI_WS08SP3 的 RtlIsServicePackVersionInstalled 会失败。

    条件性调用与 Windows 版本相关的函数

    在驱动程序确定计算机上可用的特定操作系统版本后,该驱动程序可以使用 MmGetSystemRoutineAddress 函数动态查找例程并通过指针调用该例程。Windows 7 和更高版本的操作系统版本上提供了此函数。

    注意  若要帮助保留键入检查和防止出现无意识的错误,应创建映射原始函数类型的 typedef。
     

    示例:确定 Windows 版本并条件性调用版本相关的函数

    此代码示例(来自驱动程序的头文件)将 PAISQSL 类型定义为指向 KeAcquireInStackQueuedSpinLock 函数的指针。然后,该示例声明此类型的 AcquireInStackQueuedSpinLock 变量。

     
     
    ...
     //
    // Pointer to the ordered spin lock function.
    // This function is only available on Windows 7 and
    // later systems
     typedef (* PAISQSL) (KeAcquireInStackQueuedSpinLock);
    PAISQSL AcquireInStackQueued = NULL;
     ...
     
    
    

    此代码示例(驱动程序的初始化代码)确定驱动程序是否在 Windows 7 或更高版本的操作系统上运行。如果是,代码会检索指向 KeAcquireInStackQueuedSpinLock 的指针。

     
     
    ...
     
    //
    // Are we running on Windows 7 or later?
    //
     if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7) ) {
     
     //
      // Yes... Windows 7 or later it is!
      //
         RtlInitUnicodeString(&funcName,
                      L"KeAcquireInStackQueuedSpinLock");
     
     //
      // Get a pointer to Windows implementation
      // of KeAcquireInStackQueuedSpinLock into our
      // variable "AcquireInStackQueued"
         AcquireInStackQueued = (PAISQSL)
                      MmGetSystemRoutineAddress(&funcName);
     }
     
    ...
    // Acquire a spin lock.
     
     if( NULL != AcquireInStackQueued) {
      (AcquireInStackQueued)(&SpinLock, &lockHandle);
    } else {
        KeAcquireSpinLock(&SpinLock);
    }
     
    
    

    在该示例中,驱动程序调用 RtlIsNtDdiVersionAvailable 以确定驱动程序是否在 Windows 7 或更高版本上运行。如果版本为 Windows 7 或更高版本,驱动程序将会调用 MmGetSystemRoutineAddress 来获取指向 KeAcquireInStackQueuedSpinLock 函数的指针并将此指针存储在名为 AcquireInStackQueued 的变量(该变量声明为 PAISQSL 类型)中。

    然后,当驱动程序必须获取旋转锁时,它会检查是否收到指向 KeAcquireInStackQueuedSpinLock 函数的指针。如果驱动程序已收到此指针,则驱动程序会使用该指针调用 KeAcquireInStackQueuedSpinLock。如果指向 KeAcquireInStackQueuedSpinLock 的指针为 Null,则驱动程序会使用 KeAcquireSpinLock 来获取旋转锁。

  • 相关阅读:
    2015年新的征程,我的博客开通啦!
    基于USB3.0、DP1.2的网络隔离数据安全传输方案
    USB OTG to PC USB API简介
    SMA2SATA、PCIe2SATA转换模块(也有叫:Sata Test Fixtures)
    SATA接口硬盘加密器
    SVN二次开发——让SVN、TSVN(TortoiseSVN)支持windows的访问控制模型、NTFS ADS(可选数据流、NTFS的安全属性)
    About USB Data Link Cable API
    蓝牙4.0BLE抓包(三) – 扫描请求和扫描响应
    nRF51822外设应用[2]:GPIOTE的应用-按键检测
    蓝牙4.0BLE抓包(二) – 广播包解析
  • 原文地址:https://www.cnblogs.com/sunylat/p/6243600.html
Copyright © 2011-2022 走看看