BILGI: Windows NT sürücü geliştiricileri--yanınızda kaçının için ipuçları

Makale çevirileri Makale çevirileri
Makale numarası: 186775 - Bu makalenin geçerli olduğu ürünleri görün.
Hepsini aç | Hepsini kapa

Özet

Aşağıda, Windows NT aygıt sürücülerini oluşturmak için bazı ipuçları verilmiştir. Sunulan ipuçları tüm teknolojileri için geçerlidir. Bu denetim listesi sürücü sorunlarını gidermek için de kullanılabilir.

Temel bir Windows NT mimarisi hakkında bilgi ve etkin Aşağıda sunulan bilgiler kullanılacak karşılaşıyorsunuz bazı aygıt sürücüsü geliştirme olması gerekir. Lütfen aygıt sürücüsü geliştirme hakkında daha fazla bilgi için MSDN Professional üyeliği kullanılabilen Windows NT aygıt sürücüsü Seti (DDK) BELGESINE bakın.

Daha fazla bilgi

Geliştiriciler, Windows NT aygıt sürücüleriyle çalışırken kaçınmalısınız şeyler listesi aşağıdadır:

  1. (IoMarkIrpPending) g/Ç istek paketi (IRP) işaretleme olmadan bir dağıtım yordamı tarafından hiçbir zaman iade STATUS_PENDING.
  2. Hiçbir zaman KeSynchronizeExecution, bir kesme hizmet yordamı çağırmak (ISR). Bu, sisteminizin kilitlenmeye.
  3. Hiçbir zaman DeviceObject Flags-> DO_BUFFERED_IO hem DO_DIRECT_IO ayarlayın. Bu sistem yanıltır ve sonuçta da önemli bir hata neden. Bu değerler, yalnızca ıoctl'ler tanımlama içinde kullanıldığı için Ayrıca, hiçbir zaman METHOD_BUFFERED, METHOD_NEITHER METHOD_IN_DIRECT veya METHOD_OUT_DIRECT DeviceObject, Flags-> ayarlayın.
  4. Hiçbir zaman dağıtıcısı nesneleri bir disk belleği havuzu ayırma. Bunu yaparsanız, zaman zaman sistem bugchecks neden olur.
  5. Hiç disk belleği havuzundan bellek ayıramıyor veya IRQL çalıştırırken, disk belleği havuzundaki bir bellek erişim > DISPATCH_LEVEL =. Bu önemli bir hatadır.
  6. Sıfır olmayan bir aralık IRQL konumunda hiçbir zaman bir çekirdek dağıtıcısı nesnesinde bekle > DISPATCH_LEVEL =. Bu önemli bir hatadır.
  7. Hiçbir zaman arama iş parçacığının doğrudan veya dolaylı olarak bekleyin, IRQL yürütülürken herhangi işlev çağrısı neden olan > DISPATCH_LEVEL =. Bu önemli bir hatadır.
  8. Hiçbir zaman, bilgisayarınıza en üst düzey yordamı çağırıldı düzeyinin altına kesme isteği düzeyinde (IRQL) azaltın.
  9. KeRaiseIrql() adlı henüz hiçbir zaman KeLowerIrql() arayın.
  10. Hiçbir zaman bir işlemci (KeStallExecutionProcessor) 50 mikrosaniye olarak uzun yavaşlamayı.
  11. Kesinlikle gerekli daha uzun döndürme kilitlerin basılı tutun. Daha iyi genel sistem performansı için 25 mikrosaniye olarak uzun sistem genelinde döndürme kilitlerin basılı.
  12. Hiçbir zaman KeAcquireSpinLock KeReleaseSpinLock, veya KeAcquireSpinLockAtDpcLevel ve KeReleaseSpinLockFromDpcLevel, DISPATCH_LEVEL büyük bir IRQL konumunda çalıştırırken arayın.
  13. Özgün IRQL değil geri nedeniyle hiçbir zaman KeAcquireSpinLock ile arama KeReleaseSpinLockFromDpcLevel tarafından alınmış bir döndürme kilidi serbest bırakın.
  14. Hiçbir zaman KeAcquireSpinLock ve <a2>KeReleaseSpinLock</a2> veya <a4>ISR veya SynchCritSection bir routine(s) gelen bir yürütmeyle ã lgili döndürme kilit kullanan başka bir yordam çağrısı.
  15. Bir yordam DriverEntry dışındaki bir aygıt nesnesi oluşturduğunuzda DO_DEVICE_INITIALIZING bayrağı temizlemek hiçbir zaman unutmayın.
  16. Hiçbir zaman (KeInsertQueueDpc kullanarak) bir ertelenmiş yordam çağrısı (DPC) nesnesi farklı işlemciler üzerinde birden çok iş parçacığı ile aynı anda sıraya. Bu, önemli bir hata neden olabilir.
  17. Hiçbir zaman bir CutomerTimerDPC yordamına gelen Dönemsel bir süreölçer ayırması. Bir DPC yordamına gelen nonperiodic süreölçerleri ayırması.
  18. Hiçbir zaman aynı DPC işaretçiyi KeSetTimer veya KeSetTimerEx geçirmek (CustomTimerDpc) ve (CustomDpc) KeInsertQueueDpc olur çünkü koşullar durumunu.
  19. Hiçbir zaman IoStartNextPacket döndürme kilit tutarak arayın. Bu, sisteminizin kilitlenmeye.
  20. Hiçbir zaman IoCompleteRequest döndürme kilit tutarak arayın. Bu, sisteminizin kilitlenmeye.
  21. Sürücü tamamlama yordamı ayarlar, NULL'A tamamlama yordamı ayarlamadan hiçbir zaman IoCompleteRequest arayın.
  22. G/Ç durum bloğu içinde IRP IoCompleteRequest çağırmadan önce hiçbir zaman unutmayın.
  23. Hiçbir zaman bir IRP Kuyruklama veya başka bir sürücü (ıocalldriver) göndermeden sonra IoMarkPending arayın. IRP IoMarkPending sürücüsünü çağırır ve bir hata denetimi oluşabilir önce tamamlanabilir. Tamamlanma yordamlar sürücüler için tamamlanma yordamlar, IRP PendingReturned-> ayarlanmışsa, IoMarkPending çağırmalısınız.
  24. Sonra üzerinde IoCompleteRequest adlı, hiçbir zaman bir IRP dokunma.
  25. Hiçbir zaman IoCancelIrp IRP henüz tamamlanmadı bilmiyorsanız, sürücü tarafından ait bir IRP arayın.
  26. Hiçbir zaman için çağrıyı, dağıtım yordamı dönünceye kadar kendi dağıtım yordamı üzerinde çalıştığı IRP IoCancelIrp arayın.
  27. Hiçbir zaman bir ara sürücüsünden daha düşük düzeydeki sürücüler için ırp'leri oluşturmak için IoMakeAssociatedIrp arayın. Ara sürücünüz aldığınız IRP ilişkili bir IRP olabilir ve diğer ırp'leri zaten ilişkilendirilmiş bir IRP için ilişkilendirme edemiyor.
  28. Hiçbir zaman arama gerçekleştirmek için ayarlanmış bir IRP üzerinde IoMakeAssociatedIrp g/Ç arabelleğe alınmış.
  29. Yalnızca hiçbir zaman sanal aygıt g/Ç yazmaçların işaretçiler KQUEUE ve bunlara erişebilirsiniz. Bir aygıta erişmek için her zaman doğru Donanım Soyutlama Katmanı (HAL) işlevlerini kullanın.
  30. Hiçbir zaman erişim IRP veya aygıt nesnesi alanlardan DISPATCH_LEVEL değiştirilebilir bir ISR. Simetrik çok işlemcili bir sistemde bu verilerin bozulmasına neden olabilir.
  31. Bu veri, düşük IRQL koduna göre yazılabilir, yüksek-IRQL çalıştırırken verileri hiçbir zaman değiştirin. KeSynchronizeExecution yordamını kullanın.
  32. (Herhangi varsa) hiçbir zaman bir sürücünün kendi döndürme kilitlerinin DispatchCleanup yordamında, sistem genelinde iptal döndürme kilit (IoAcquireCancelSpinLock) alınıyor önce alın. Sürücünüz boyunca tutarlı bir kilit alım sıradüzeni aşağıdaki olası kilitlenmeleri korunma için gereklidir.
  33. Hiçbir zaman, <a0>iptal</a0> yordamında IoAcquireCancelSpinLock her zaman sistem ile adlandırılır çünkü döndürme kilidi iptal çağrısı, kendi adına tutulan.
  34. Bir iptal yordamından dönmeden önce IoReleaseCancelSpinLock çağırmak hiçbir zaman unutmayın.
  35. Bu, yalnızca tek işlemcili sistemlerde çalışır, çünkü <a0></a0> eşitleme IRQL tabanlı hiçbir zaman kullanmayın. IRQL bir işlemciye yükseltme kesmeler diğer işlemcilerde maske değil.
  36. Hiçbir zaman RtlCopyMemory çakışan bir bellek adresi aralıklarını kullanın. Kullanım RtlMoveMemory.
  37. Hiçbir zaman bile belirli bir CPU için sayfa boyutları sabittir varsayalım. Kullanım PAGE_SIZE ve diğer ilgili sabitleri taşınabilirliği sağlamak için üstbilgi dosyalarında tanımlanan sayfa.
  38. Hiçbir zaman Registry\Machine\Hardware ve Registry\Machine\System dışındaki herhangi bir kayıt defteri anahtarlarının Boot\System başlatma aşamasında yüklenen sürücü DriverEntry yordamı erişmek.
  39. Hiçbir zaman bir sürücünün kayıt defteri anahtarı (Registry\Machine\System\CurrentControlSet\Services) altındaki bir yazıcı sürücüsü yüklemek için bir sıralama anahtarı oluşturun. Sistem, bu anahtar dinamik olarak oluşturur.
  40. Hiçbir zaman girişimi, gerekli veri yolu göreli g/Ç bağlantı noktaları, bellek aralığı, kesme veya doğrudan bellek erişimi (DMA) claiming fiziksel bir aygıtı başlatmak için kanal/bağlantı noktası donanım kaynaklarının, kayıt defterindeki ilk.
  41. Hiçbir zaman bu IoRegisterDriverReinitialization, DriverEntry çağrı olağan sürece, ancak STATUS_SUCCESS geri döndürür.
  42. Hiçbir zaman KeSetEvent Wait parametre kümesi ile DOğRU olarak diske alınabilir bir iş parçacığı veya IRQL PASSIVE_LEVEL sırasında çalıştırılan sayfalanabilir sürücü yordamına arayın. Bu tür bir arama, yordamı öğrenmek KeSetEvent çağrıları KeWait arasında disk durumda önemli bir sayfa hatası neden olurNesne.
  43. Hiçbir zaman KeReleaseSemaphore Wait parametre kümesi ile DOğRU olarak diske alınabilir bir iş parçacığı veya IRQL PASSIVE_LEVEL sırasında çalıştırılan sayfalanabilir sürücü yordamına arayın. Sizin yordamı öğrenmek KeReleaseSemaphore çağrıları KeWait arasında disk durumdaNesne, bu tür bir arama önemli bir sayfa hatası neden olur.
  44. Hiçbir zaman KeReleaseMutex Wait parametre kümesi ile DOğRU olarak diske alınabilir bir iş parçacığı veya IRQL PASSIVE_LEVEL sırasında çalıştırılan sayfalanabilir sürücü yordamına arayın. Sizin yordamı öğrenmek KeReleaseMutex çağrıları KeWait arasında disk durumdaNesne, bu tür bir arama önemli bir sayfa hatası neden olur.
  45. Hiçbir zaman KeBugCheckEx veya KeBugCheck sistemi getirmek için bir perakende Windows NT sürücüsü çağırmanıza, sistem bellek bozulmasına neden veya sonunda, sistem hata denetimi için neden önemli bir hata sürece hatayla karşılaştı. Hata durumları düzgün bir şekilde işlemek her zaman deneyin.
  46. Hiçbir zaman hangi herhangi belirli IoTimer yordamına olarak adlandırılan aralıkları sonuçta bağlıdır çünkü sistem saatinin çözümlemesine bir IoTimer yordamının tam olarak bir saniyelik sınırında çağırılacak varsayalım.
  47. Hiçbir zaman Win32s uygulama programlama arabirimleri (API) bir çekirdek modu aygıt sürücüsü ' arayın.
  48. Yığın, Çekirdek modunda çalışırken arama parçacığının Çekirdek modu yığınının dinamik olarak ulaşması değil çünkü taşma neden hiçbir zaman kullanma özyinelemeli işlevler.
  49. ISR aldığınız <a1>kesme</a1> nesnesinin adresi her zaman bir IoConnectInterrupt aldım aynı çünkü hiçbir zaman birden çok kesme, işleme kesme nesnesi işaretçisi (PKINTERRUPT) içinde bir ISR kesmeler tanımlamak için kullanın. Yalnızca IoConnectInterrupt içinde belirttiğiniz ServiceContext değeri kullanması gereken geçerli interrupting aygıtı tanımlamak için.
  50. Hiçbir zaman CustomTimerDpc (KeCancelTimer) temizleme olmayan bir sürücüyü kaldırın. DPC sürücü bellekten sonra harekete geçirildi, varolmayan kodlu olmayan isabet ve hata denetimi bir sisteme neden.
  51. Hiçbir zaman g/Ç CompletionRoutine sürücüsünün içinde ayarlanmış olan tüm ırp'leri kadar bir sürücü bellekten kaldırma tamamlandı. Sürücü bellekten sonra IRP alt Sürücünün tamamladığı, sistem varolmayan kod yürütebilir ve sistemin çökmesine neden çalışabilir.
  52. Hiçbir zaman sürücünüz bu hazır olana kadar bu aygıt kesme etkinleştirin. Yalnızca sürücünüz tamamen başlatıldı ve sistem, sürücünün iç yapıları ISR ve DPC rötuş yapmak güvenlidir sonra etkinleştirmeniz gerekir.
  53. Hiçbir zaman arama kilitlenmeye neden olabilir, çünkü bir sayaç kilidi tutarken sürücünüz dışında.
  54. Ilgili g/Ç Yöneticisi tarafından post-processing STATUS_MORE_PROCESSING_REQUIRED, g/Ç CompletionRoutine IoBuildAsynchronousFsdRequest/ıoallocateırp sürücünüzle IRP tamamlama için hazır olmadığı için oluşturulmuş bir IRP için'den farklı herhangi bir durum hiçbir zaman iade. Bu tür bir IRP açıkça serbest (IoFreeIrp) sürücü tarafından. IRP yeniden kullanılmak üzere tasarlanmıştır, onu CompletionRoutine <a1>Durum</a1> STATUS_MORE_PROCESSING_REQUIRED dönmeden önce serbest.
  55. Hiçbir zaman bir IRP IoBuildSynchronousFsdRequest/IoBuildDeviceIoControlRequest ile bir rasgele bir iş parçacığının içeriğinde tahsis IRP (IRP ThreadListEntry->) iş parçacığının ilişkili kaldığından, serbest kadar.
  56. Hiçbir zaman IoInitializeIrp tahsis edildi bir IRP ıoallocateırp ile üzerinde DOğRU ChargeQuota parametresi ayarlanmış arayın. ChargeQuota true olarak ayarlanmış bir IRP ayrılamadı, g/Ç Yöneticisi, bu bellek IRP ıRP'ın iç bayrağı için ayrılan havuzu hakkındaki bilgileri saklar.

    Böyle bir IRP üzerinde IoInitializeIrp aradığınızda, bu işlevi, tüm IRP Scripts sıfır olarak tahsisat havuzu bilgileri kaybolur. IRP serbest zaman bu bellek bozulmasına yol açar. Ayrıca, GÇ yöneticisinden gelen bir IRP hiçbir zaman yeniden. Bir IRP yeniden kullanmak istiyorsanız, kendi ıoallocateırp kullanarak tahsis.
  57. Hiçbir zaman arama iş parçacığı yığınının bir nesneyi ayrılırsa WaitMode UserMode KeWaitForSingleObject/KeWaitForMultipleObjects içinde olarak belirtin. Bu corollary bekledi nesne, işlev yığın içinde oluşturulursa, KernelMode dışında belleğine alınan iş parçacığı yığınının engellemek için bu WaitMode olarak belirttiğiniz gerekir ' dir.
  58. Hiçbir zaman bir kritik bölüm kodu koruma olmadan bir kullanıcı modu iş parçacığının içeriğinde ERESOURCES ve FastMutex(Unsafe) gibi kaynakları edinin.

    Iş parçacığı askıya (bir APC sıraya göre yapılır), bu kaynakların alım için APC_LEVEL, IRQL yükseltmenizi değil çünkü bu kaynak aldı, sonra da sistem güvenliğini kilitlenme ve güvenliğinin aşılmasına neden olabilir. Bu nedenle, KeEnterCriticalRegion ça??rarak gibi kaynakları da açıkça IRQL, APC_LEVEL veya yükseltme tarafından kritik bir bölümde edinmeniz.

Referanslar

Windows NT için MSDN aygıt sürücüsü tasarım kılavuzu

Özellikler

Makale numarası: 186775 - Last Review: 27 Temmuz 2004 Salı - Gözden geçirme: 2.1
Bu makaledeki bilginin uygulandığı durum:
  • Microsoft Win32 Device Driver Kit for Windows NT 3.51
  • Microsoft Win32 Device Driver Kit for Windows NT 4.0
Anahtar Kelimeler: 
kbmt kbinfo KB186775 KbMttr
Machine-translated Article
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:186775
Kullanım Dışı Bilgi Bankası İçeriği Yasal Uyarı
Bu makale, Microsoft'un artık destek sağlamadığı ürünler ile ilgili olarak yazılmıştır. Bu nedenle, bu makale "olduğu gibi" sağlanmıştır ve bundan sonra güncelleştirilmeyecektir.

Geri Bildirim Ver

 

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