DDK开发安全事项
1. 一定不要在沒有標注 I /O 請求數(shù)據(jù)包 (I RP) 掛起 (I oMark I rpPending) 的情況下通過調(diào)度例程返回 S TATUS _PEN D I N G 。 ?
2. 一定不要通過中斷服務例程 (I S R) 調(diào)用 K eS y nchronizeExecut ion。 它會使系統(tǒng)死鎖。 ?
3. 一定不要將 D ev iceObject ->Flags 設置為 D O_B UFFERED _I O 和 D O_D I RECT_I O。 它會擾亂系統(tǒng)并最終導致致命錯誤。 而且,一定不要在 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. 一定不要通過頁面緩沖池分配調(diào)度程序?qū)ο蟆?如果這樣做,將會偶爾導致系統(tǒng)故障檢測 (B ugcheck )。 ?
5. 當運行于 I RQL ?>= D I S PATCH _L EVEL ?時,一定不要通過頁面緩沖池分配內(nèi)存,或訪問頁面緩沖池中的內(nèi)存。 這是一個致命錯誤。 ?
6. 一定不要在 I RQL ?>= D I S PATCH _L EVEL ?上等候核心調(diào)度程序?qū)ο蟪霈F(xiàn)非零間隔。 這是一個致命錯誤。 ?
7. 在 I RQL ?>= D I S PATCH _L EVEL ?上執(zhí)行時,一定不要調(diào)用任何導致調(diào)用線程發(fā)生直接或間接等待的函數(shù)。 這是一個致命錯誤。 ?
8. 一定不要把中斷請求級別 (I RQL ) 降低到低于您的頂級例程被調(diào)用的級別。 ?
9. 如果沒有調(diào)用過 K eRaiseI rql(),則一定不要調(diào)用 K eL owerI rql()。 ?
10. 一定不要使處理器 (K eS t allExecut ionProcessor) 停止運轉(zhuǎn)的時間超過 50 微秒。 ?
11. 一定不要使旋轉(zhuǎn)鎖 (S pin L ock ) 保持鎖定狀態(tài)的時間超過您的需要。 要使系統(tǒng)獲得更好的總體性能,請不要使任何系統(tǒng)范圍內(nèi)有效的旋轉(zhuǎn)鎖的鎖定時間超過 25 微秒。 ?
12. 當 I RQL ?大于 D I S PATCH _L EVEL ?時,一定不要調(diào)用 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. 一定不要通過調(diào)用 K eReleaseS pinL ock FromD pcL ev el 來釋放 K eAcquireS pinL ock ?所獲取的旋轉(zhuǎn)鎖,因為這會使原始 I RQL ?無法被還原。 ?
14. 一定不要在 I S R 或 S y nchCrit S ect ion 例程中調(diào)用 K eAcquireS pinL ock ?和 K eReleaseS pinL ock ?或者其它任何使用可執(zhí)行旋轉(zhuǎn)鎖的例程。 ?
15. 當您在例程中而不是在 D riv erEnt ry ?中創(chuàng)建設備對象時,一定不要忘記清除 D O_D EVI CE_I N I TI AL I ZI N G ?標記。 ?
16. 一定不要同時在不同處理器的多個線程中將延時過程調(diào)用 (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. 旋轉(zhuǎn)鎖鎖定時,一定不要調(diào)用 I oS t artN ex t Pack et。 這將使系統(tǒng)死鎖。 ?
20. 旋轉(zhuǎn)鎖鎖定時,一定不要調(diào)用 I oComplet eRequest。 這將使系統(tǒng)死鎖。 ?
21. 如果您的驅(qū)動程序設置了完成例程,那么一定不要在沒有把完成例程設置為 N UL L ?的情況下調(diào)用 I oComplet eRequest。 ?
22. 調(diào)用 I oComplet eRequest ?之前,一定不要忘記設置 I RP 中的 I /O 狀態(tài)區(qū)。 ?
23. 在將 I RP 添加到隊列中或?qū)⑺l(fā)送到另一個驅(qū)動程序 (I oCallD riv er) 之后,一定不要調(diào)用 I oMark Pending。 在驅(qū)動程序調(diào)用 I oMark Pending 之前,I RP 可能已經(jīng)完成,由此可能發(fā)生故障檢測。 對于包含完成例程的驅(qū)動程序,如
果設置了 I rp->PendingRet urned,則完成例程必須調(diào)用 I oMark Pending。 ?
24. 一定不要在已經(jīng)對某個 I RP 調(diào)用 I oComplet eRequest ?之后再去訪問該 I RP。 ?
25. 一定不要對不屬于您的驅(qū)動程序的 I RP 調(diào)用 I oCancelI rp,除非您知道該 I RP 還沒有完成。 ?
26. 在您的調(diào)度例程返回到調(diào)用者之前,一定不要對您的調(diào)度例程正在處理的 I RP 調(diào)用 I oCancelI rp。 ?
27. 一定不要從中間驅(qū)動程序調(diào)用 I oMak eAssociat edI rp 來為較低的驅(qū)動程序創(chuàng)建 I RP。 在中間驅(qū)動程序中所獲得的 I RP 可能是已被關(guān)聯(lián)的 I RP,而您不能將其它 I RP 關(guān)聯(lián)到已經(jīng)被關(guān)聯(lián)的 I RP。 ?
28. 一定不要對使用緩沖 I /O 而設置的 I RP 調(diào)用 I oMak eAssociat edI rp。 ?
29. 一定不要簡單地將指向設備 I /O 寄存器的虛擬指針解除引用并訪問這些指針。 始終使用正確的硬件抽象層 (H AL ) 函數(shù)來訪問設備。 ?
30. 如果 I RP 或設備對象可能在 D I S PATCH ?級別被修改,那么一定不要通過 I S R 來訪問 它。 在對稱多處理器系統(tǒng)中,這會造成數(shù)據(jù)損壞。 ?
31. 正在高級 I RQL ?中運行時,如果數(shù)據(jù)可能被低級 I ROL ?代碼寫入,那么一定不要修改該數(shù)據(jù)。 應當使用 K eS y nchronizeExecut ion 例程。 ?
32. 在獲取系統(tǒng)范圍的取消旋轉(zhuǎn)鎖 (I oAcquireCancelS pinL ock ) 之前,一定不要在您的 D ispat chCleanup 例程中獲取驅(qū)動程序自己的旋轉(zhuǎn)鎖(如果有的話)。 要避免可能出現(xiàn)的死鎖,一定要在驅(qū)動程序中遵循一致的鎖定獲取層次結(jié)
構(gòu)。 ?
33. 一定不要在取消例程中調(diào)用 I oAcquireCancelS pinL ock,因為該例程被調(diào)用時已經(jīng)獲取了系統(tǒng)級的取消旋轉(zhuǎn)鎖。 ?
34. 在從取消例程返回之前,一定不要忘記調(diào)用 I oReleaseCancelS pinL ock。 ?
35. 一定不要使用基于 I RQL ?的同步,因為它只對單處理器系統(tǒng)有效。 提高單處理器上的 I RQL ?將不會掩蔽在其它處理器上的中斷。 ?
36. 一定不要對重疊的內(nèi)存地址范圍使用 Rt lCopyMemory。 應當使用 Rt lMov eMemory。 ?
37. 一定不要假定頁面大小是常量,即使是用于給定的 CPU。 為了保持可移植性,應當使用 PAG E_S I ZE 以及在頭文件中所定義的其它頁面相關(guān)常量。 ?
38. 一定不要從引導\系統(tǒng)初始化階段加載的驅(qū)動程序的 D riv erEnt ry ?例程中訪問除 Regist ry \Machine\H ardware 和 Regist ry \Machine\S y st em 以外的任何注冊表項。 ?
39. 一定不要為了加載驅(qū)動程序而在驅(qū)動程序的注冊表項 (Regist ry \Machine\S y st em\CurrentCont rolS et \S erv ices) 下創(chuàng)建 Enum 項。 系統(tǒng)將動態(tài)地創(chuàng)建該項。 ?
40. 如果沒有先在注冊表中申請必需的與總線相關(guān)的 I /O 端口、內(nèi)存范圍、中斷或直接內(nèi)存訪問 (D MA) 通道/端口等硬件資源,一定不要初始化物理設備。 ?
41. 一定不要在您的 D riv erEnt ry ?例程調(diào)用 I oRegist erD riv erReinit ializat ion,除非重初始化例程返回了 S TATUS _S UCCES S 。 ?
42. I RQL ?為 PAS S I VE_L EVEL ?時,一定不要從被頁面調(diào)度的線程或驅(qū)動程序例程中在 Wait ?參數(shù)被設置為 TRUE 的情況下調(diào)用 K eS et Ev ent。 如果碰巧在調(diào)用 K eS et Ev ent ?和 K eWait ..Object (s) 之間您的例程被頁面調(diào)度出去,這類調(diào)用
就會導致致命的頁面錯誤。 ?
43. 與上例相同的條件下,同樣不能調(diào)用 K eReleaseS emaphore 。 ?
44. 與上例相同的條件下,同樣不能調(diào)用 K eReleaseMut ex ?。
45. 一定不要通過零售的 Windows N T 驅(qū)動程序調(diào)用 K eB ugCheck Ex ?或 K eB ugCheck ?來停止系統(tǒng)的運行,除非您遇到的是破壞系統(tǒng)內(nèi)存并最終導致系統(tǒng)進入故障檢測的重要錯誤。 應當始終巧妙地處理錯誤條件。
46. 一定不要假定 I oTimer 例程將會準確地在一秒邊界處被調(diào)用,因為任何特定 I oTimer 例程的調(diào)用間隔最終取決于系統(tǒng)時鐘。
47. 一定不要從核心模式的設備驅(qū)動程序調(diào)用 Win32 應用程序編程接口 (API )。
48. 一定不要使用會導致堆棧溢出的遞歸函數(shù),因為調(diào)用線程的核心模式堆棧不能動態(tài)增長。
49. 在處理多個中斷的 I S R 例程中,一定不要使用中斷對象指針 (PK I N TERRUPT) 來標識中斷,因為您在 I S R 中所獲得的中斷對象地址不會始終與您通過 I oConnect I nt errupt ?所獲得的地址相同。 要想識別當前發(fā)生中斷的設備,應當
僅使用您在 I oConnect I nt errupt ?中所指定的 S erv iceCont ex t ?值。
50. 如果沒有清零 Cust omTimerD pc (K eCancelTimer),一定不要卸載驅(qū)動程序。 如果在卸載驅(qū)動程序后啟動 D PC,它可能調(diào)用不存在的代碼,并導致系統(tǒng)進入故障檢測查。
51. 如果 I RP 中設置了某個驅(qū)動程序的 I /O Complet ionRout ine,那么一定要等到所有這些 I RP 完成之后,才能卸載該驅(qū)動程序。 如果卸載驅(qū)動程序后,I RP 被更低級的驅(qū)動程序完成,那么系統(tǒng)會試圖執(zhí)行不存在的代碼,并導致系
統(tǒng)崩潰。
52. 一定要等到驅(qū)動程序準備好要處理某個設備中斷時,才能啟用該設備中斷。 應當只在完成驅(qū)動程序初始化之后才啟用它,執(zhí)行 I S R 和 D PC 時,系統(tǒng)才能安全的訪問設備對象的若干私有成員。
53. 在旋轉(zhuǎn)鎖鎖定時,一定不要調(diào)用驅(qū)動程序以外的代碼,因為這會引起死鎖。
54. 如果您的驅(qū)動程序通過 I oB uildAsy nchronousFsdRequest /I oAllocat eI rp 創(chuàng)建了一個 I RP,那么,一定不要從您的 I /O Complet ionRout ine 為這個 I RP 返回 S TATUS _MORE_PROCES S I N G _REQUI RED ?以外的任何狀態(tài),因為該 I RP 沒
有為與完成有關(guān)的 I /O 管理器的處理后工作做好準備。 這樣的 I RP 應當被驅(qū)動程序顯式地釋放 (I oFreeI rp)。 如果本來沒有打算重用 I RP,可以在返回狀態(tài) 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 依然與該線程保持關(guān)聯(lián) (I rp->ThreadL ist Ent ry ),直到它被釋放。
56. 如果已經(jīng)使用 I oAllocat eI rp 在 ChargeQuot a 參數(shù)被設置為 TRUE 的情況下分配了某個 I RP,那么一定不要對該 I RP 調(diào)用 I oI nit ializeI rp。 如果在 ChargeQuot a 設置為 TRUE 的情況下分配 I RP,則 I /O 管理器將把它為該 I RP 分配
內(nèi)存時所用的緩沖池的相關(guān)信息保存在該 I RP 的內(nèi)部標記中。
如果對這樣的 I RP 調(diào)用 I oI nit ializeI rp,那么,當該函數(shù)盲目地清零整個 I RP 時,分配池信息將會丟失。 當您釋放 I RP 時,這將導致內(nèi)存被破壞。 同時,一定不要重用來自 I O 管理器的 I RP。 如果要重用 I RP,應當使用
I oAllocat eI rp 分配您自己的 I RP。
57. 如果在調(diào)用線程的堆棧中分配了對象,就一定不要在 K eWait ForS ingleObject /K eWait ForMult ipleObject s 中將 WaitMode 指定為 UserMode。 這樣做的結(jié)果是,如果被等候的對象是在函數(shù)堆棧中創(chuàng)建的,那么您必須將 WaitMode
指定為 K ernelMode 才能防止線程被頁面調(diào)度出去。
58. 在沒有對關(guān)鍵節(jié)中的代碼加以保護的情況下,一定不要在用戶模式線程的上下文中獲取諸如 ERES OURCES ?和 FastMut ex (Unsafe) 這類資源。
2. 一定不要通過中斷服務例程 (I S R) 調(diào)用 K eS y nchronizeExecut ion。 它會使系統(tǒng)死鎖。 ?
3. 一定不要將 D ev iceObject ->Flags 設置為 D O_B UFFERED _I O 和 D O_D I RECT_I O。 它會擾亂系統(tǒng)并最終導致致命錯誤。 而且,一定不要在 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. 一定不要通過頁面緩沖池分配調(diào)度程序?qū)ο蟆?如果這樣做,將會偶爾導致系統(tǒng)故障檢測 (B ugcheck )。 ?
5. 當運行于 I RQL ?>= D I S PATCH _L EVEL ?時,一定不要通過頁面緩沖池分配內(nèi)存,或訪問頁面緩沖池中的內(nèi)存。 這是一個致命錯誤。 ?
6. 一定不要在 I RQL ?>= D I S PATCH _L EVEL ?上等候核心調(diào)度程序?qū)ο蟪霈F(xiàn)非零間隔。 這是一個致命錯誤。 ?
7. 在 I RQL ?>= D I S PATCH _L EVEL ?上執(zhí)行時,一定不要調(diào)用任何導致調(diào)用線程發(fā)生直接或間接等待的函數(shù)。 這是一個致命錯誤。 ?
8. 一定不要把中斷請求級別 (I RQL ) 降低到低于您的頂級例程被調(diào)用的級別。 ?
9. 如果沒有調(diào)用過 K eRaiseI rql(),則一定不要調(diào)用 K eL owerI rql()。 ?
10. 一定不要使處理器 (K eS t allExecut ionProcessor) 停止運轉(zhuǎn)的時間超過 50 微秒。 ?
11. 一定不要使旋轉(zhuǎn)鎖 (S pin L ock ) 保持鎖定狀態(tài)的時間超過您的需要。 要使系統(tǒng)獲得更好的總體性能,請不要使任何系統(tǒng)范圍內(nèi)有效的旋轉(zhuǎn)鎖的鎖定時間超過 25 微秒。 ?
12. 當 I RQL ?大于 D I S PATCH _L EVEL ?時,一定不要調(diào)用 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. 一定不要通過調(diào)用 K eReleaseS pinL ock FromD pcL ev el 來釋放 K eAcquireS pinL ock ?所獲取的旋轉(zhuǎn)鎖,因為這會使原始 I RQL ?無法被還原。 ?
14. 一定不要在 I S R 或 S y nchCrit S ect ion 例程中調(diào)用 K eAcquireS pinL ock ?和 K eReleaseS pinL ock ?或者其它任何使用可執(zhí)行旋轉(zhuǎn)鎖的例程。 ?
15. 當您在例程中而不是在 D riv erEnt ry ?中創(chuàng)建設備對象時,一定不要忘記清除 D O_D EVI CE_I N I TI AL I ZI N G ?標記。 ?
16. 一定不要同時在不同處理器的多個線程中將延時過程調(diào)用 (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. 旋轉(zhuǎn)鎖鎖定時,一定不要調(diào)用 I oS t artN ex t Pack et。 這將使系統(tǒng)死鎖。 ?
20. 旋轉(zhuǎn)鎖鎖定時,一定不要調(diào)用 I oComplet eRequest。 這將使系統(tǒng)死鎖。 ?
21. 如果您的驅(qū)動程序設置了完成例程,那么一定不要在沒有把完成例程設置為 N UL L ?的情況下調(diào)用 I oComplet eRequest。 ?
22. 調(diào)用 I oComplet eRequest ?之前,一定不要忘記設置 I RP 中的 I /O 狀態(tài)區(qū)。 ?
23. 在將 I RP 添加到隊列中或?qū)⑺l(fā)送到另一個驅(qū)動程序 (I oCallD riv er) 之后,一定不要調(diào)用 I oMark Pending。 在驅(qū)動程序調(diào)用 I oMark Pending 之前,I RP 可能已經(jīng)完成,由此可能發(fā)生故障檢測。 對于包含完成例程的驅(qū)動程序,如
果設置了 I rp->PendingRet urned,則完成例程必須調(diào)用 I oMark Pending。 ?
24. 一定不要在已經(jīng)對某個 I RP 調(diào)用 I oComplet eRequest ?之后再去訪問該 I RP。 ?
25. 一定不要對不屬于您的驅(qū)動程序的 I RP 調(diào)用 I oCancelI rp,除非您知道該 I RP 還沒有完成。 ?
26. 在您的調(diào)度例程返回到調(diào)用者之前,一定不要對您的調(diào)度例程正在處理的 I RP 調(diào)用 I oCancelI rp。 ?
27. 一定不要從中間驅(qū)動程序調(diào)用 I oMak eAssociat edI rp 來為較低的驅(qū)動程序創(chuàng)建 I RP。 在中間驅(qū)動程序中所獲得的 I RP 可能是已被關(guān)聯(lián)的 I RP,而您不能將其它 I RP 關(guān)聯(lián)到已經(jīng)被關(guān)聯(lián)的 I RP。 ?
28. 一定不要對使用緩沖 I /O 而設置的 I RP 調(diào)用 I oMak eAssociat edI rp。 ?
29. 一定不要簡單地將指向設備 I /O 寄存器的虛擬指針解除引用并訪問這些指針。 始終使用正確的硬件抽象層 (H AL ) 函數(shù)來訪問設備。 ?
30. 如果 I RP 或設備對象可能在 D I S PATCH ?級別被修改,那么一定不要通過 I S R 來訪問 它。 在對稱多處理器系統(tǒng)中,這會造成數(shù)據(jù)損壞。 ?
31. 正在高級 I RQL ?中運行時,如果數(shù)據(jù)可能被低級 I ROL ?代碼寫入,那么一定不要修改該數(shù)據(jù)。 應當使用 K eS y nchronizeExecut ion 例程。 ?
32. 在獲取系統(tǒng)范圍的取消旋轉(zhuǎn)鎖 (I oAcquireCancelS pinL ock ) 之前,一定不要在您的 D ispat chCleanup 例程中獲取驅(qū)動程序自己的旋轉(zhuǎn)鎖(如果有的話)。 要避免可能出現(xiàn)的死鎖,一定要在驅(qū)動程序中遵循一致的鎖定獲取層次結(jié)
構(gòu)。 ?
33. 一定不要在取消例程中調(diào)用 I oAcquireCancelS pinL ock,因為該例程被調(diào)用時已經(jīng)獲取了系統(tǒng)級的取消旋轉(zhuǎn)鎖。 ?
34. 在從取消例程返回之前,一定不要忘記調(diào)用 I oReleaseCancelS pinL ock。 ?
35. 一定不要使用基于 I RQL ?的同步,因為它只對單處理器系統(tǒng)有效。 提高單處理器上的 I RQL ?將不會掩蔽在其它處理器上的中斷。 ?
36. 一定不要對重疊的內(nèi)存地址范圍使用 Rt lCopyMemory。 應當使用 Rt lMov eMemory。 ?
37. 一定不要假定頁面大小是常量,即使是用于給定的 CPU。 為了保持可移植性,應當使用 PAG E_S I ZE 以及在頭文件中所定義的其它頁面相關(guān)常量。 ?
38. 一定不要從引導\系統(tǒng)初始化階段加載的驅(qū)動程序的 D riv erEnt ry ?例程中訪問除 Regist ry \Machine\H ardware 和 Regist ry \Machine\S y st em 以外的任何注冊表項。 ?
39. 一定不要為了加載驅(qū)動程序而在驅(qū)動程序的注冊表項 (Regist ry \Machine\S y st em\CurrentCont rolS et \S erv ices) 下創(chuàng)建 Enum 項。 系統(tǒng)將動態(tài)地創(chuàng)建該項。 ?
40. 如果沒有先在注冊表中申請必需的與總線相關(guān)的 I /O 端口、內(nèi)存范圍、中斷或直接內(nèi)存訪問 (D MA) 通道/端口等硬件資源,一定不要初始化物理設備。 ?
41. 一定不要在您的 D riv erEnt ry ?例程調(diào)用 I oRegist erD riv erReinit ializat ion,除非重初始化例程返回了 S TATUS _S UCCES S 。 ?
42. I RQL ?為 PAS S I VE_L EVEL ?時,一定不要從被頁面調(diào)度的線程或驅(qū)動程序例程中在 Wait ?參數(shù)被設置為 TRUE 的情況下調(diào)用 K eS et Ev ent。 如果碰巧在調(diào)用 K eS et Ev ent ?和 K eWait ..Object (s) 之間您的例程被頁面調(diào)度出去,這類調(diào)用
就會導致致命的頁面錯誤。 ?
43. 與上例相同的條件下,同樣不能調(diào)用 K eReleaseS emaphore 。 ?
44. 與上例相同的條件下,同樣不能調(diào)用 K eReleaseMut ex ?。
45. 一定不要通過零售的 Windows N T 驅(qū)動程序調(diào)用 K eB ugCheck Ex ?或 K eB ugCheck ?來停止系統(tǒng)的運行,除非您遇到的是破壞系統(tǒng)內(nèi)存并最終導致系統(tǒng)進入故障檢測的重要錯誤。 應當始終巧妙地處理錯誤條件。
46. 一定不要假定 I oTimer 例程將會準確地在一秒邊界處被調(diào)用,因為任何特定 I oTimer 例程的調(diào)用間隔最終取決于系統(tǒng)時鐘。
47. 一定不要從核心模式的設備驅(qū)動程序調(diào)用 Win32 應用程序編程接口 (API )。
48. 一定不要使用會導致堆棧溢出的遞歸函數(shù),因為調(diào)用線程的核心模式堆棧不能動態(tài)增長。
49. 在處理多個中斷的 I S R 例程中,一定不要使用中斷對象指針 (PK I N TERRUPT) 來標識中斷,因為您在 I S R 中所獲得的中斷對象地址不會始終與您通過 I oConnect I nt errupt ?所獲得的地址相同。 要想識別當前發(fā)生中斷的設備,應當
僅使用您在 I oConnect I nt errupt ?中所指定的 S erv iceCont ex t ?值。
50. 如果沒有清零 Cust omTimerD pc (K eCancelTimer),一定不要卸載驅(qū)動程序。 如果在卸載驅(qū)動程序后啟動 D PC,它可能調(diào)用不存在的代碼,并導致系統(tǒng)進入故障檢測查。
51. 如果 I RP 中設置了某個驅(qū)動程序的 I /O Complet ionRout ine,那么一定要等到所有這些 I RP 完成之后,才能卸載該驅(qū)動程序。 如果卸載驅(qū)動程序后,I RP 被更低級的驅(qū)動程序完成,那么系統(tǒng)會試圖執(zhí)行不存在的代碼,并導致系
統(tǒng)崩潰。
52. 一定要等到驅(qū)動程序準備好要處理某個設備中斷時,才能啟用該設備中斷。 應當只在完成驅(qū)動程序初始化之后才啟用它,執(zhí)行 I S R 和 D PC 時,系統(tǒng)才能安全的訪問設備對象的若干私有成員。
53. 在旋轉(zhuǎn)鎖鎖定時,一定不要調(diào)用驅(qū)動程序以外的代碼,因為這會引起死鎖。
54. 如果您的驅(qū)動程序通過 I oB uildAsy nchronousFsdRequest /I oAllocat eI rp 創(chuàng)建了一個 I RP,那么,一定不要從您的 I /O Complet ionRout ine 為這個 I RP 返回 S TATUS _MORE_PROCES S I N G _REQUI RED ?以外的任何狀態(tài),因為該 I RP 沒
有為與完成有關(guān)的 I /O 管理器的處理后工作做好準備。 這樣的 I RP 應當被驅(qū)動程序顯式地釋放 (I oFreeI rp)。 如果本來沒有打算重用 I RP,可以在返回狀態(tài) 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 依然與該線程保持關(guān)聯(lián) (I rp->ThreadL ist Ent ry ),直到它被釋放。
56. 如果已經(jīng)使用 I oAllocat eI rp 在 ChargeQuot a 參數(shù)被設置為 TRUE 的情況下分配了某個 I RP,那么一定不要對該 I RP 調(diào)用 I oI nit ializeI rp。 如果在 ChargeQuot a 設置為 TRUE 的情況下分配 I RP,則 I /O 管理器將把它為該 I RP 分配
內(nèi)存時所用的緩沖池的相關(guān)信息保存在該 I RP 的內(nèi)部標記中。
如果對這樣的 I RP 調(diào)用 I oI nit ializeI rp,那么,當該函數(shù)盲目地清零整個 I RP 時,分配池信息將會丟失。 當您釋放 I RP 時,這將導致內(nèi)存被破壞。 同時,一定不要重用來自 I O 管理器的 I RP。 如果要重用 I RP,應當使用
I oAllocat eI rp 分配您自己的 I RP。
57. 如果在調(diào)用線程的堆棧中分配了對象,就一定不要在 K eWait ForS ingleObject /K eWait ForMult ipleObject s 中將 WaitMode 指定為 UserMode。 這樣做的結(jié)果是,如果被等候的對象是在函數(shù)堆棧中創(chuàng)建的,那么您必須將 WaitMode
指定為 K ernelMode 才能防止線程被頁面調(diào)度出去。
58. 在沒有對關(guān)鍵節(jié)中的代碼加以保護的情況下,一定不要在用戶模式線程的上下文中獲取諸如 ERES OURCES ?和 FastMut ex (Unsafe) 這類資源。
總結(jié)
- 上一篇: [专利与论文-12]:高级职称评定的面试
- 下一篇: 五分钟带你玩转docker(三)全网最新