DDK开发安全事项

1. 一定不要在没有标注 I /O 请求数据包 (I RP) 挂起 (I oMark I rpPending) 的情况下通过调度例程返回 S TATUS _PEN D I N G 。  
2. 一定不要通过中断服务例程 (I S R) 调用 K eS y nchronizeExecut ion。 它会使系统死锁。  
3. 一定不要将 D ev iceObject ->Flags 设置为 D O_B UFFERED _I O 和 D O_D I RECT_I O。 它会扰乱系统并最终导致致命错误。 而且,一定不要在 D ev iceObject ->Flags 中设置 METH OD _B UFFERED 、METH OD _N EI TH ER、
METH OD _I N _D I RECT 或 METH OD _OUT_D I RECT,因为这些值只在定义 I OCTL  时使用。  
4. 一定不要通过页面缓冲池分配调度程序对象。 如果这样做,将会偶尔导致系统故障检测 (B ugcheck )。  
5. 当运行于 I RQL  >= D I S PATCH _L EVEL  时,一定不要通过页面缓冲池分配内存,或访问页面缓冲池中的内存。 这是一个致命错误。  
6. 一定不要在 I RQL  >= D I S PATCH _L EVEL  上等候核心调度程序对象出现非零间隔。 这是一个致命错误。  
7. 在 I RQL  >= D I S PATCH _L EVEL  上执行时,一定不要调用任何导致调用线程发生直接或间接等待的函数。 这是一个致命错误。  
8. 一定不要把中断请求级别 (I RQL ) 降低到低于您的顶级例程被调用的级别。  
9. 如果没有调用过 K eRaiseI rql(),则一定不要调用 K eL owerI rql()。  
10. 一定不要使处理器 (K eS t allExecut ionProcessor) 停止运转的时间超过 50 微秒。  
11. 一定不要使旋转锁 (S pin L ock ) 保持锁定状态的时间超过您的需要。 要使系统获得更好的总体性能,请不要使任何系统范围内有效的旋转锁的锁定时间超过 25 微秒。  
12. 当 I RQL  大于 D I S PATCH _L EVEL  时,一定不要调用 K eAcquireS pinL ock  和 K eReleaseS pinL ock,或 K eAcquireS pinL ock AtD pcL ev el 和 K eReleaseS pinL ock FromD pcL ev el。  
13. 一定不要通过调用 K eReleaseS pinL ock FromD pcL ev el 来释放 K eAcquireS pinL ock  所获取的旋转锁,因为这会使原始 I RQL  无法被还原。  
14. 一定不要在 I S R 或 S y nchCrit S ect ion 例程中调用 K eAcquireS pinL ock  和 K eReleaseS pinL ock  或者其它任何使用可执行旋转锁的例程。  
15. 当您在例程中而不是在 D riv erEnt ry  中创建设备对象时,一定不要忘记清除 D O_D EVI CE_I N I TI AL I ZI N G  标记。  
16. 一定不要同时在不同处理器的多个线程中将延时过程调用 (D PC) 对象添加到队列中(使用 K eI nsertQueueD pc)。 这会导致致命错误。  
17. 一定不要通过 Cut omerTimerD PC 例程释放周期定时器。 您可以通过 D PC 例程释放非周期定时器。  
18. 一定不要将相同的 D PC 指针传递给 K eS et Timer,或者 K eS et TimerEx  (Cust omTimerD pc) 和 K eI nsertQueueD pc (Cust omD pc),因为这将导致竞争。  
19. 旋转锁锁定时,一定不要调用 I oS t artN ex t Pack et。 这将使系统死锁。  
20. 旋转锁锁定时,一定不要调用 I oComplet eRequest。 这将使系统死锁。  
21. 如果您的驱动程序设置了完成例程,那么一定不要在没有把完成例程设置为 N UL L  的情况下调用 I oComplet eRequest。  
22. 调用 I oComplet eRequest  之前,一定不要忘记设置 I RP 中的 I /O 状态区。  
23. 在将 I RP 添加到队列中或将它发送到另一个驱动程序 (I oCallD riv er) 之后,一定不要调用 I oMark Pending。 在驱动程序调用 I oMark Pending 之前,I RP 可能已经完成,由此可能发生故障检测。 对于包含完成例程的驱动程序,如
果设置了 I rp->PendingRet urned,则完成例程必须调用 I oMark Pending。  
24. 一定不要在已经对某个 I RP 调用 I oComplet eRequest  之后再去访问该 I RP。  
25. 一定不要对不属于您的驱动程序的 I RP 调用 I oCancelI rp,除非您知道该 I RP 还没有完成。  
26. 在您的调度例程返回到调用者之前,一定不要对您的调度例程正在处理的 I RP 调用 I oCancelI rp。  
27. 一定不要从中间驱动程序调用 I oMak eAssociat edI rp 来为较低的驱动程序创建 I RP。 在中间驱动程序中所获得的 I RP 可能是已被关联的 I RP,而您不能将其它 I RP 关联到已经被关联的 I RP。  
28. 一定不要对使用缓冲 I /O 而设置的 I RP 调用 I oMak eAssociat edI rp。  
29. 一定不要简单地将指向设备 I /O 寄存器的虚拟指针解除引用并访问这些指针。 始终使用正确的硬件抽象层 (H AL ) 函数来访问设备。  
30. 如果 I RP 或设备对象可能在 D I S PATCH  级别被修改,那么一定不要通过 I S R 来访问 它。 在对称多处理器系统中,这会造成数据损坏。  
31. 正在高级 I RQL  中运行时,如果数据可能被低级 I ROL  代码写入,那么一定不要修改该数据。 应当使用 K eS y nchronizeExecut ion 例程。  
32. 在获取系统范围的取消旋转锁 (I oAcquireCancelS pinL ock ) 之前,一定不要在您的 D ispat chCleanup 例程中获取驱动程序自己的旋转锁(如果有的话)。 要避免可能出现的死锁,一定要在驱动程序中遵循一致的锁定获取层次结
构。  
33. 一定不要在取消例程中调用 I oAcquireCancelS pinL ock,因为该例程被调用时已经获取了系统级的取消旋转锁。  
34. 在从取消例程返回之前,一定不要忘记调用 I oReleaseCancelS pinL ock。  
35. 一定不要使用基于 I RQL  的同步,因为它只对单处理器系统有效。 提高单处理器上的 I RQL  将不会掩蔽在其它处理器上的中断。  
36. 一定不要对重叠的内存地址范围使用 Rt lCopyMemory。 应当使用 Rt lMov eMemory。  
37. 一定不要假定页面大小是常量,即使是用于给定的 CPU。 为了保持可移植性,应当使用 PAG E_S I ZE 以及在头文件中所定义的其它页面相关常量。  
38. 一定不要从引导\系统初始化阶段加载的驱动程序的 D riv erEnt ry  例程中访问除 Regist ry \Machine\H ardware 和 Regist ry \Machine\S y st em 以外的任何注册表项。  
39. 一定不要为了加载驱动程序而在驱动程序的注册表项 (Regist ry \Machine\S y st em\CurrentCont rolS et \S erv ices) 下创建 Enum 项。 系统将动态地创建该项。  
40. 如果没有先在注册表中申请必需的与总线相关的 I /O 端口、内存范围、中断或直接内存访问 (D MA) 通道/端口等硬件资源,一定不要初始化物理设备。  
41. 一定不要在您的 D riv erEnt ry  例程调用 I oRegist erD riv erReinit ializat ion,除非重初始化例程返回了 S TATUS _S UCCES S 。  
42. I RQL  为 PAS S I VE_L EVEL  时,一定不要从被页面调度的线程或驱动程序例程中在 Wait  参数被设置为 TRUE 的情况下调用 K eS et Ev ent。 如果碰巧在调用 K eS et Ev ent  和 K eWait ..Object (s) 之间您的例程被页面调度出去,这类调用
就会导致致命的页面错误。  
43. 与上例相同的条件下,同样不能调用 K eReleaseS emaphore 。  
44. 与上例相同的条件下,同样不能调用 K eReleaseMut ex  。
45. 一定不要通过零售的 Windows N T 驱动程序调用 K eB ugCheck Ex  或 K eB ugCheck  来停止系统的运行,除非您遇到的是破坏系统内存并最终导致系统进入故障检测的重要错误。 应当始终巧妙地处理错误条件。
46. 一定不要假定 I oTimer 例程将会准确地在一秒边界处被调用,因为任何特定 I oTimer 例程的调用间隔最终取决于系统时钟。
47. 一定不要从核心模式的设备驱动程序调用 Win32 应用程序编程接口 (API )。
48. 一定不要使用会导致堆栈溢出的递归函数,因为调用线程的核心模式堆栈不能动态增长。
49. 在处理多个中断的 I S R 例程中,一定不要使用中断对象指针 (PK I N TERRUPT) 来标识中断,因为您在 I S R 中所获得的中断对象地址不会始终与您通过 I oConnect I nt errupt  所获得的地址相同。 要想识别当前发生中断的设备,应当
仅使用您在 I oConnect I nt errupt  中所指定的 S erv iceCont ex t  值。
50. 如果没有清零 Cust omTimerD pc (K eCancelTimer),一定不要卸载驱动程序。 如果在卸载驱动程序后启动 D PC,它可能调用不存在的代码,并导致系统进入故障检测查。
51. 如果 I RP 中设置了某个驱动程序的 I /O Complet ionRout ine,那么一定要等到所有这些 I RP 完成之后,才能卸载该驱动程序。 如果卸载驱动程序后,I RP 被更低级的驱动程序完成,那么系统会试图执行不存在的代码,并导致系
统崩溃。
52. 一定要等到驱动程序准备好要处理某个设备中断时,才能启用该设备中断。 应当只在完成驱动程序初始化之后才启用它,执行 I S R 和 D PC 时,系统才能安全的访问设备对象的若干私有成员。
53. 在旋转锁锁定时,一定不要调用驱动程序以外的代码,因为这会引起死锁。
54. 如果您的驱动程序通过 I oB uildAsy nchronousFsdRequest /I oAllocat eI rp 创建了一个 I RP,那么,一定不要从您的 I /O Complet ionRout ine 为这个 I RP 返回 S TATUS _MORE_PROCES S I N G _REQUI RED  以外的任何状态,因为该 I RP 没
有为与完成有关的 I /O 管理器的处理后工作做好准备。 这样的 I RP 应当被驱动程序显式地释放 (I oFreeI rp)。 如果本来没有打算重用 I RP,可以在返回状态 S TATUS _MORE_PROCES S I N G _REQUI RED  之前,在 Complet ionRout ine 中
将它释放。
55. 一定不要在任意的线程上下文中使用 I oB uildS y nchronousFsdRequest /I oB uildD ev iceI oCont rolRequest  来分配 I RP,因为该 I RP 依然与该线程保持关联 (I rp->ThreadL ist Ent ry ),直到它被释放。
56. 如果已经使用 I oAllocat eI rp 在 ChargeQuot a 参数被设置为 TRUE 的情况下分配了某个 I RP,那么一定不要对该 I RP 调用 I oI nit ializeI rp。 如果在 ChargeQuot a 设置为 TRUE 的情况下分配 I RP,则 I /O 管理器将把它为该 I RP 分配
内存时所用的缓冲池的相关信息保存在该 I RP 的内部标记中。
如果对这样的 I RP 调用 I oI nit ializeI rp,那么,当该函数盲目地清零整个 I RP 时,分配池信息将会丢失。 当您释放 I RP 时,这将导致内存被破坏。 同时,一定不要重用来自 I O 管理器的 I RP。 如果要重用 I RP,应当使用
I oAllocat eI rp 分配您自己的 I RP。
57. 如果在调用线程的堆栈中分配了对象,就一定不要在 K eWait ForS ingleObject /K eWait ForMult ipleObject s 中将 WaitMode 指定为 UserMode。 这样做的结果是,如果被等候的对象是在函数堆栈中创建的,那么您必须将 WaitMode
指定为 K ernelMode 才能防止线程被页面调度出去。
58. 在没有对关键节中的代码加以保护的情况下,一定不要在用户模式线程的上下文中获取诸如 ERES OURCES  和 FastMut ex (Unsafe) 这类资源。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值