INFORMACE: Tipy pro Windows NT Driver vývojáře--věci eliminace

Překlady článku Překlady článku
ID článku: 186775 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Souhrn

Následují některé tipy pro vytváření WINDOWSNT ovladače zařízení. Tipy prezentovány použít všechny technologií. Můžete také použít tento jako kontrolní seznam pro řešení potíží s ovladači.

Potřebujete mít základní znalosti WINDOWSNT architektura a některé setkat použít informace zobrazené pod efektivně vývoj ovladačů zařízení. Další informace o vývoj ovladačů zařízení naleznete sadě ovladač zařízení WINDOWSNT (DDK), která je k dispozici prostřednictvím členství MSDN Professional.

Další informace

Seznam Věci, které vývojáři měli vyhnout při práci s WINDOWSNT ovladače zařízení je následující:

  1. Nikdy vratky STATUS_PENDING z rutina dispatch bez označení I/O paket požadavku (IRP) čekající (IoMarkIrpPending)
  2. Nikdy volání z rutina služba přerušení KeSynchronizeExecution (ISR). Bude zablokování systému.
  3. Nikdy nastavit DeviceObject-> příznaky DO_BUFFERED_IO a DO_DIRECT_IO. Můžete matoucí systému a nakonec vést k závažné chybě. Také nikdy nastavit METHOD_BUFFERED, METHOD_NEITHER, METHOD_IN_DIRECT nebo METHOD_OUT_DIRECT v DeviceObject-> příznaky, protože tyto hodnoty jsou používány pouze v definování IOCTL.
  4. Nikdy přidělit Dispečer objekty ze stránkovaného fondu. Pokud tak učiníte, způsobí bugchecks občasné systému.
  5. Nikdy vyhradit paměť ze stránkovaného fondu nebo přístup k paměti stránkovaného fondu při spuštění na úrovni IRQL > = DISPATCH_LEVEL. Je závažná chyba.
  6. Nikdy čekat na objekt jádra Dispečer nenulovou interval na úrovni IRQL > = DISPATCH_LEVEL. Je závažná chyba.
  7. Nikdy volání libovolné funkce, které způsobí volání podprocesu čekat při provádění na úrovni IRQL přímo nebo nepřímo > = DISPATCH_LEVEL. Je závažná chyba.
  8. Nikdy nižší úroveň požadavek přerušení (IRQL) pod úroveň, jakou má byla vyvolána rutina nejvyšší úrovně.
  9. Pokud ještě volána KeRaiseIrql() nikdy volání KeLowerIrql().
  10. Nikdy parkovacího místa procesoru (KeStallExecutionProcessor) delší než 50 mikrosekundách.
  11. Nikdy držení žádné zámky Otočný delší než nezbytné. Pro lepší celkový výkon systému není držení žádné zámky celý systém Otočný delší než 25 mikrosekundách.
  12. Nikdy volání KeAcquireSpinLock a KeReleaseSpinLock, KeAcquireSpinLockAtDpcLevel a KeReleaseSpinLockFromDpcLevel, při spuštění na úrovni IRQL větší než DISPATCH_LEVEL.
  13. Nikdy uvolněte Otočný zámek, který byl získán s KeAcquireSpinLock podle volajícího KeReleaseSpinLockFromDpcLevel, protože obnoveny původní IRQL.
  14. Nikdy volání KeAcquireSpinLock a KeReleaseSpinLock nebo rutina, která používá zámek executive Otočný z ISR nebo SynchCritSection routine(s).
  15. Nikdy zapomenete zrušte DO_DEVICE_INITIALIZING příznak při vytvoření objektu zařízení v rutině než DriverEntry.
  16. Nikdy fronty objekt volání (DPC) deferred procedure (pomocí KeInsertQueueDpc) s více podprocesy na různých procesorech současně. Může vést k závažné chybě.
  17. Nikdy navrátit periodické časovač z rutina CutomerTimerDPC. Má být navráceno nonperiodic časovače z rutina DPC.
  18. Nikdy předat stejný ukazatel DPC KeSetTimer nebo KeSetTimerEx (CustomTimerDpc) a KeInsertQueueDpc (CustomDpc), protože způsobuje, že soupeřit podmínky.
  19. Při stisknuté uzamčení Otočný nikdy volání IoStartNextPacket. Možné zablokování systému.
  20. Nikdy volání IoCompleteRequest při stisknuté Otočný uzamčení. Možné zablokování systému.
  21. Nikdy volání IoCompleteRequest bez nastavení rutina dokončení NULL, pokud ovladač nastaví rutina dokončení.
  22. Nikdy zapomenete před voláním IoCompleteRequest nastavte stav bloku I/O IRP.
  23. Nikdy volání IoMarkPending po IRP front nebo odesílání jiný ovladač (IoCallDriver). IRP může být dokončen před ovladač IoMarkPending volá a může dojít k kontroly chyb. U ovladačů s rutiny dokončení musí rutiny dokončení volání IoMarkPending Pokud nastavit Irp-> PendingReturned.
  24. Po zavolali IoCompleteRequest na něm nikdy dotykového ovládání IRP.
  25. IRP, která není vlastněna daným ovladač, pokud víte, že IRP nebyl dokončen ještě nikdy volat IoCancelIrp.
  26. Nikdy volání IoCancelIrp pro IRP rutina dispatch pracuje na dokud rutina dispatch vrátí volajícího.
  27. Nikdy volání IoMakeAssociatedIrp vytvořit IRP nižší ovladače z zprostředkujícího ovladače. IRP získat v zprostředkující ovladač může být přidružené IRP a jiných IRP již přidružené IRP nelze přidružit.
  28. Nikdy volání IoMakeAssociatedIrp IRP, který je nastaven k provedení vyrovnávací paměť I/O.
  29. Nikdy stačí zrušit virtuální ukazatelů registry zařízení I/O a k nim přístup. Vždy použít funkce správný hardware abstraction layer (HAL) přístup k zařízení.
  30. Nikdy přístup IRP nebo zařízení objekt polí z ISR, které může být změněno z DISPATCH_LEVEL. Na symetrického víceprocesorového systému to může způsobit poškození dat.
  31. Při spuštění na vysoké úrovni IRQL, pokud data mohou být napsána podle kódu nízkou IRQL nikdy měnit data. Použít rutina KeSynchronizeExecution.
  32. Nikdy získat jeden zámky Otočný ovladač jeho vlastní (Pokud máte některý) v DispatchCleanup rutina, před načítání zámku Otočný zrušit celý systém (IoAcquireCancelSpinLock). Následující hierarchie pořízení konzistentní uzamčení celé ovladač je nezbytné k předcházení potenciální zablokování.
  33. Nikdy uchovávány IoAcquireCancelSpinLock rutina Storno protože vždy volat s systému zrušit uzamčení Otočný volání jeho jménem.
  34. Nikdy zapomenete volání IoReleaseCancelSpinLock před návratem z rutina Storno.
  35. Nikdy použít systémem IRQL synchronizace, protože tento postup funguje pouze v systémech jeden procesor. Zvýšení IRQL na jeden procesor není masky přerušení jiných procesorů.
  36. Nikdy nepoužívejte pro rozsahy adres paměti překrývající RtlCopyMemory. Použití RtlMoveMemory.
  37. Nikdy předpokládají velikosti stránek jsou konstantní i pro daný PROCESOR. Použití PAGE_SIZE a další stránky související konstanty definované v záhlaví souborů udržovat přenositelnost.
  38. Nikdy přístup k žádné klíče registru než Registry\Machine\Hardware a Registry\Machine\System z DriverEntry rutina ovladače načteny ve fázi inicializace Boot\System.
  39. Nikdy vytvořit klíč Enum pro načtení ovladače klíči registru ovladač (Registry\Machine\System\CurrentControlSet\Services). Systém vytvoří tento klíč dynamicky.
  40. Nikdy pokus o inicializaci fyzické zařízení bez claiming nezbytné sběrnice relativní I/O portů, rozsahy paměti, přerušení nebo přímý přístup paměti (DMA) kanál/port hardwarových prostředků v registru nejprve.
  41. Nikdy IoRegisterDriverReinitialization volání z vašeho DriverEntry rutiny Pokud vrátí STATUS_SUCCESS.
  42. Nikdy volání KeSetEvent s nastaveným parametru Wait TRUE z podprocesu stránkovatelné nebo rutina stránkované ovladač spuštěna v PASSIVE_LEVEL IRQL. Tento typ volání způsobí neplatnost stránky závažné Pokud vaše rutina nestane stránkovaného mimo mezi volání KeSetEvent a KeWaitObjekty.
  43. Nikdy volání KeReleaseSemaphore s nastaveným parametru Wait TRUE z podprocesu stránkovatelné nebo rutina stránkované ovladač spuštěna v PASSIVE_LEVEL IRQL. Pokud vaše rutina nestane stránkovaného mimo mezi volání KeReleaseSemaphore a KeWaitObject(s) způsobí neplatnost závažné stránky tohoto typu volání.
  44. Nikdy volání KeReleaseMutex s nastaveným parametru Wait TRUE z podprocesu stránkovatelné nebo rutina stránkované ovladač spuštěna v PASSIVE_LEVEL IRQL. Pokud vaše rutina nestane stránkovaného mimo mezi volání KeReleaseMutex a KeWaitObject(s) způsobí neplatnost závažné stránky tohoto typu volání.
  45. Nikdy volání KeBugCheckEx nebo KeBugCheck z maloobchodní ovladače WINDOWSNT přenést dolů systému, pokud došlo k chybě je kritická chyba, které by poškození systémové paměti nebo způsobit nakonec systému kontroly chyb. Vždy vyzkoušejte řádně zpracovávat chybové podmínky.
  46. Nikdy předpokládají, že rutina IoTimer nazývá přesně na hranici jednu sekundu, protože intervaly, na které žádné konkrétní IoTimer rutina nazývá závisí na rozlišení systémové hodiny.
  47. Nikdy volání Win32s rozhraní pro programování aplikací (API) z ovladač zařízení režimu jádra.
  48. Nikdy použití rekurzivní funkce, které mohou způsobit zásobníku přetečení protože zásobníku volání podprocesu v režimu jádra nezvětší dynamicky je spuštěna v režimu jádra.
  49. Nikdy ukazatelů objekt přerušení (PKINTERRUPT), které zpracovává více než jeden přerušení identifikovat pomocí přerušení ISR protože adresu získat v ISR objekt přerušení vždy nebude stejná jako dostali od IoConnectInterrupt. Hodnota ServiceContext, určete v IoConnectInterrupt měli použít pouze k identifikaci aktuální interrupting zařízení.
  50. Nikdy uvolnění ovladače bez zrušením CustomTimerDpc (KeCancelTimer). Pokud DPC je aktivována po ovladač je uvolněn, by přístupů bez existent kód a způsobit, že systém kontroly chyb.
  51. Uvolnění ovladače dokud IRP, které mají CompletionRoutine I/O ovladač nastavit v ní jsou nikdy dokončena. Pokud IRP získává dolním ovladačem dokončena po ovladač je uvolněn, by se mohl pokusit spustit kód neexistující a způsobit selhání systému v systému.
  52. Dokud ovladač je připraven zpracovat ji nikdy povolit zařízení přerušení. Byste měli povolit pouze po ovladač zcela inicializována a je bezpečné systému dotknout ovladač interní struktury v ISR a DPC.
  53. Nikdy volání mimo ovladač při stisknuté spinlock, protože může způsobit zablokování.
  54. Nikdy návratový stav jakékoli jiné než STATUS_MORE_PROCESSING_REQUIRED z CompletionRoutine I/O pro vytvořené ovladač s IoBuildAsynchronousFsdRequest/IoAllocateIrp, protože IRP není připraven pro dokončení IRP související post-processing správcem I/O. Například IRP by měl být uvolněno explicitně (IoFreeIrp) ovladačem. Pokud IRP není určen pro opakované použití, ji může být uvolněno v CompletionRoutine před vrácením stav STATUS_MORE_PROCESSING_REQUIRED.
  55. Přidělit v kontextu spuštění libovolného podproces nikdy IRP s IoBuildSynchronousFsdRequest/IoBuildDeviceIoControlRequest, protože zůstává IRP přidružen k podprocesu (Irp-> ThreadListEntry) dokud je uvolněno.
  56. Nikdy volat IoInitializeIrp IRP, která byla rozdělena s IoAllocateIrp s ChargeQuota parametr nastavenou na hodnotu TRUE. Při přidělování IRP s ChargeQuota nastavenou na TRUE správce I/O udržuje informace o fondu, ze kterého přidělené paměti pro IRP v interní příznak IRP.

    Při volání IoInitializeIrp na takové IRP informace o přidělení fondu je jako tato funkce blindly zeros celý IRP ztraceny. To vede k poškození paměti při uvolnit IRP. Nikdy znovu také IRP, který pochází ze správce IO. Pokud chcete znovu použít IRP jste měli přidělit vlastní pomocí IoAllocateIrp.
  57. Pokud je v zásobníku volání podprocesu přidělena objekt nikdy zadat WaitMode jako uživatelského KeWaitForSingleObject/KeWaitForMultipleObjects. Corollary tohoto je, že pokud právě čekaly objekt je vytvořen v zásobníku funkci, musíte určit KernelMode jako WaitMode zabránit právě stránkovaného limit zásobníku podprocesu.
  58. Nikdy získat prostředky jako například ERESOURCES a FastMutex(Unsafe) v kontextu podprocesu uživatelského režimu bez Ochrana kódu v kritické části.

    Protože pořízení tyto prostředky nevyvolává IRQL k APC_LEVEL, pokud podproces je pozastaveno (provádí APC front) po má získali prostředku, může způsobit zablokování a ohrozit zabezpečení systému. Proto byste získat takové prostředky buď explicitně zvednutím IRQL APC_LEVEL nebo v kritické části voláním KeEnterCriticalRegion.

Odkazy

Příručka návrh ovladač zařízení MSDN WINDOWSNT

Vlastnosti

ID článku: 186775 - Poslední aktualizace: 27. července 2004 - Revize: 2.1
Informace v tomto článku jsou určeny pro produkt:
  • Microsoft Win32 Device Driver Kit for Windows NT 3.51
  • Microsoft Win32 Device Driver Kit for Windows NT 4.0
Klíčová slova: 
kbmt kbinfo KB186775 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:186775
Právní omezení pro obsah znalostní báze týkající se produktů, jejichž podpora byla ukončena
Tento článek byl napsán o produktech, pro které společnost Microsoft již neposkytuje nadále podporu. Článek je tedy nabízen v takovém stavu, v jakém je, a nebude již nadále aktualizován.

Dejte nám zpětnou vazbu

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com