手头有一个实例代码,一个wdm架构的bus驱动,它可以向pnp管理器报一个设备。现在我想把它改成NT式的,理论上可以做到吗?也就是让NT式的驱动也能够向pnp管理器报一个设备。

解决方案 »

  1.   

    NT不支持。。
    理论上可以,实际不可以,因为你该NT你要自定义很多函数去实现PNP,那就意味着要该整个内核
      

  2.   

    wdm需要数字签名,这个是要$的……
      

  3.   

    怎么自定义函数去实现pnp,恳请指点
      

  4.   

    NT 的PNP ,自己做会死人的一、初始化系统在引导时会调用IopInitializePlugPlayServices初始化即插即用服务。
    初始化过程有如下步骤:1、判断默认总线类型。通过查询文件系统分配表中的HalQuerySystemInformation得到
    当前系统的总线信息。除了IBM的MCA之外,查询到的其他类型的总线信息都认为是ISA总线。
    2、初始化根仲裁器。相关的设备有端口设备、物理内存、中断、总线设备。
    初始化过程设置了ARBITER_INSTANCE结构中必须提供的四个回调函数
    (unpack/score requirement和pack/unpack resource)。
    3、打开或创建CCS\Enum\Root键、创建HTREE\ROOT\0键。初始化拔除设备列表、意外拔除设备列表、
    设备树同步资源锁、设备树为空通知事件、设备树枚举操作通知事件、PnP自旋锁、DockDevice的
    链表和互斥锁。(WarmDevice)
    4、创建名为PnpManager的驱动对象。创建未命名的设备对象。
    PnpManager驱动中只设置了AddDevice、IRP_MJ_PNP、IRP_MJ_POWER这三个必须的回调函数用于枚举
    系统中其他设备。而创建的这个未命名对象就是第一个pdo设备。照例pdo设备都会在Flags中设置
    DO_BUS_ENUMERATED_DEVICE,这也是判断PDO和FDO的标准之一。
    5、分配根设备结点。分配的同时,相关的数据也就完成初始化过程,其中包括:设备结点计数、
    总线类型(也就是默认总线类型)、本结点的枚举互斥锁、本结点内的仲裁器和转换器列表、并设置了
    PDO和NODE两个结构的相互指针。设置Flags为DNF_STARTED、DNF_PROCESSED、DNF_ENUMERATED,并
    把它命名为HTREE\ROOT\0。
    6、打开CCS\Control\Pnp键。如果DetectionEnabled项,就把项的值传给PnPDetectionEnabled,看样子这个
    项可以控制PnP的枚举。当然,默认情况是开启的。
    7、初始化PnP Notify。有的驱动要管理某一类的设备就需要注册一个通知来获得它感兴趣设备的插入和拔除。
    比如fdisk,就是通过这种机制管理磁盘设备的。
    8、以上7步就是第一次初始化过程,第二次初始化过程还要根据CCS\Pnp\DisableFirmwareMapper的值俩决定
    是否枚举固件。
    二、枚举过程在初始化的第一和第二过程都会开启根结点的枚举操作。枚举操作有以下几种:
    枚举设备树、枚举设备、枚举根设备、枚举引导设备等。其中根设备和引导设备是同步枚举的,其它都是
    通过工作项异步枚举的。在Windows 2000以前是通过IopDeviceActionWorker,而Windows XP是通过
    PipDeviceActionWorker实现枚举。枚举设备树要经过以下几步:
    枚举请求被放入一个列表之中,每个请求通过PI_DEVICE_REQUEST结构描述。在Worker得到运行的时候,
    它会处理每个挂在列表中的请求。在获得某一个请求时,它可能会经历如下处理过程:1、重新处理引导设备资源。有时在第一次枚举设备的时候会出现资源不足或是资源需求改变的情况,
    所以就应该有机制再次处理并满足这些设备的资源需求。
    2、重新分配设备资源。只处理资源需求改变的情况。
    3、重新满足设备资源。只处理资源未被满足的情况。
    4、开始新设备。
    5、重新枚举设备树。在处理各种设备节点请求时需要特别注意同步问题和树节点的状态控制。除去复杂的逻辑判断,实际上
    起主要实现函数只有以下几个:IopProcessAssignResources、IopProcessStartDevices、IopRestartDeviceNode、
    IopProcessNewDeviceNode、IopBusCheck三、调用关系IopBusCheck使用IopEnumerateDevice、IopProcessAssignResources、IopProcessStartDevices完成主要
    功能。1、IopEnumerateDevice,它会根据传入的参数作为PDO,并枚举这个总线上所有的PDO。
    它会调用IopQueryDeviceRelations向这个PDO的驱动发送IRP_MJ_PNP和IRP_MN_QUERY_DEVICE_RELATIONS。
    根据驱动返回的数据设置这个PDO对应的设备节点。分配子节点时会使用IopAllocateDeviceNode和
    IopInsertTreeDeviceNode。最后通过调用IopProcessNewChildren为新的子节点调用AddDevice回调函数。
    IopProcessNewDeviceNode用来查询注册表并创建对应设备实例,IopCallDriverAddDevice是用来调用
    AddDevice的。2、IopProcessStartDevices,实际上起关键作用的是IopProcessStartDevicesWorker。它对本结点及其所有
    的子结点递归使用IopStartAndEnumerateDevice。顾名思义,它有IopStartDevice和IopEnumerateDevice
    两个过程。IopStartDevice的实现是向对应驱动发送IRP_MJ_PNP和IRP_MN_START_DEVICE。3、IopProcessNewDeviceNode,首先创建HKLM\System\CCS\Enum中对应项,然后向对应驱动发送IRP_MJ_PNP和
    IRP_MN_QUERY_ID查询UID/PID,接着发送IRP_MJ_PNP和IRP_MN_QUERY_CAPABILITIES查询兼容ID,用
    IRP_MJ_PNP和IRP_MN_QUERY_DEVICE_TEXT查询设备描述字符,创建HKLM\System\Enum\<Enumerator>\deviceId
    中的对应项,最后用IRP_MJ_PNP和IRP_MN_QUERY_RESOURCE_REQUIREMENTS查询基本配置信息。在处理完注册表
    与驱动查询之后发送PnP事件。4、IopRestartDeviceNode,它是用来释放在创建设备节点时分配的内存,这样就为重新枚举做了清理工作。5、IopProcessAssignResources,它枚举本节点以及子结点,为它们分配IOP_RESOURCE_REQUEST结构并设置部分值。
      

  5.   

    5楼的结论是怎么得来的?是windows 7 32bit下的结果吗?
    就是Windows 7 32bit 系统下 WDM 驱动需要签名,而nt式的不需要?
      

  6.   

    晕我问题的重点不在 whql什么的我想知道对签名的需求,64位的我知道即使nt的也需要驱动的数字签名,我没有wdm的未签名的驱动例子,我想知道是否 windows下签名验证是针对WDM的,而不是针对nt的。
      

  7.   

    我对这些了解还不够多。我说下我的理解吧(针对win7,其它版本我没有试验过):数字签名不是针对驱动的,对于正式发布的APP也需要数字签名。
    64位驱动程序(编译时用X64环境进行编译的)不管是wdm的还是NT式的必须有数字签名才能在系统下(包括64位和32位)安装。上面是我在实际安装时遇到的情况,不对的地方还请各位指出。非常感谢。
      

  8.   

    可是我自己编的sfilter过滤驱动,却可以在自己机器上的win7下安装并运行啊你说的那些我都听说过,而且我也验证了:在64位下,我写的驱动加载不了,只有在启动时候F8,然后有一项禁用驱动签名机制,这样才能加载,不过这个时候系统的情况与正常情况有什么不同就不知道了。没继续下去。我用的版本是可以选择32位和64位的,我不知道过滤驱动是否可以用WDM结构方式写,所以我那几楼的疑问就是想知道,
    Windows简明验证机制的真实情况是否那么严格,严格到什么程度?
    对于32bit的win7,是否NT的不需要签名(毕竟我已经验证了,某种情况的确不需要签名就可以启动,貌似运行的还很正常),或者哪类需要签名(没有签名能加载的是否是在运行时候有所限制)
    相对的,对于32bit的Win7, WDM的则需要签名(这句话完全是针对5楼的你的话嘛~)