INFORMAZIONI: Suggerimenti per Windows Driver NT per sviluppatori--informazioni per evitare

Traduzione articoli Traduzione articoli
Identificativo articolo: 186775 - Visualizza i prodotti a cui si riferisce l?articolo.
Espandi tutto | Chiudi tutto

Sommario

Riportato di seguito è riportati alcuni suggerimenti per la creazione di driver di periferica Windows NT. I suggerimenti presentati si applicano a tutte le tecnologie. È inoltre possibile utilizzare questo come un elenco di controllo per la risoluzione dei problemi di driver.

È necessario disporre di una conoscenza di base dell'architettura di Windows e lo sviluppo di alcuni driver periferica verificarsi utilizzare le informazioni presentate in modo efficace sotto. Per ulteriori informazioni sullo sviluppo di driver di periferica, vedere il kit di driver di periferica di Windows NT (DDK), disponibile mediante l'appartenenza a MSDN Professional.

Informazioni

Seguito è riportato un elenco delle operazioni che gli sviluppatori di evitare quando si utilizzano driver di periferica Windows NT:

  1. STATUS_PENDING mai restituito da una routine di invio senza contrassegnare il pacchetto di richiesta di I/O (IRP) in sospeso (IoMarkIrpPending).
  2. Non chiamare KeSynchronizeExecution da una routine di servizio di interrupt (ISR). Verrà un deadlock del sistema.
  3. Non impostare un DeviceObject-> flag DO_BUFFERED_IO e DO_DIRECT_IO. Può confondere il sistema e infine comportare errore irreversibile. Inoltre, non impostare METHOD_BUFFERED, METHOD_NEITHER, METHOD_IN_DIRECT o METHOD_OUT_DIRECT in DeviceObject-> flag, poiché questi valori vengono utilizzati solo nella definizione IOCTL.
  4. Non è possibile allocare oggetti dispatcher da un pool di paging. In caso contrario, ciò comporterà bugchecks occasionale del sistema.
  5. Non allocano memoria dal pool di paging o accesso memoria nel pool di paging durante l'esecuzione al livello IRQL > DISPATCH_LEVEL di =. È un errore irreversibile.
  6. Non attendere un oggetto dispatcher di kernel per un intervallo diverso da zero al livello IRQL > DISPATCH_LEVEL di =. È un errore irreversibile.
  7. Non chiamata una funzione che determina il thread chiamante in attesa direttamente o indirettamente durante l'esecuzione al livello IRQL mai > = DISPATCH_LEVEL. È un errore irreversibile.
  8. Non ridurre mai il livello di richiesta di interrupt (IRQL) sotto il livello in cui è stata richiamata la routine di primo livello.
  9. Se non è stato chiamato KeRaiseIrql() mai chiamare KeLowerIrql().
  10. Mai posto un processore (KeStallExecutionProcessor) più di 50 microsecondi.
  11. Non è possibile tenere i blocchi di selezione più tempo del necessario. Per migliorare le prestazioni sistema globale, non vengono mantenuti i blocchi a livello di sistema selezione più di 25 microsecondi.
  12. Non chiamare KeAcquireSpinLock e KeReleaseSpinLock, o KeAcquireSpinLockAtDpcLevel e KeReleaseSpinLockFromDpcLevel, durante l'esecuzione al livello IRQL maggiore DISPATCH_LEVEL.
  13. Non rilasciare un blocco di selezione che è stato acquistato con KeAcquireSpinLock dal chiamante KeReleaseSpinLockFromDpcLevel, poiché l'IRQL originale non verrà ripristinato.
  14. Non chiamare KeAcquireSpinLock e KeReleaseSpinLock o altre routine che utilizza un blocco selezione esecutivo da un routine(s) ISR o SynchCritSection.
  15. Non dimenticare cancellare il flag DO_DEVICE_INITIALIZING quando si crea un oggetto periferica in una routine diversa DriverEntry.
  16. Non coda mai un oggetto (DPC) chiamata di procedura differite (utilizzando KeInsertQueueDpc) con più thread su processori diversi contemporaneamente. Può causare un errore irreversibile.
  17. Non rilasciare un timer periodico da una routine CutomerTimerDPC. È possibile rilasciare timer non periodiche da una routine DPC.
  18. Non passare lo stesso puntatore DPC a KeSetTimer, o KeSetTimerEx (CustomTimerDpc) e KeInsertQueueDpc (CustomDpc), perché induce gareggiare condizioni.
  19. Non chiamare IoStartNextPacket durante un blocco di selezione. È possibile un deadlock del sistema.
  20. Non chiamare IoCompleteRequest durante un blocco di selezione. È possibile un deadlock del sistema.
  21. Non chiamare IoCompleteRequest senza impostare la routine di completamento su NULL se il driver imposta la routine di completamento.
  22. Non dimenticare impostare il blocco di stato I/O nell'IRP prima di chiamare IoCompleteRequest.
  23. Non chiamare IoMarkPending dopo l'accodamento di un IRP o inviarlo a un altro driver (IoCallDriver). L'IRP può essere completata prima che il driver chiama IoMarkPending e si verifichi un controllo errori. Per i driver con routine di completamento, è necessario che le routine di completamento chiamare IoMarkPending se è impostato IRP-> PendingReturned.
  24. Non accennare mai un IRP dopo aver chiamato IoCompleteRequest su di esso.
  25. Non è possibile chiamare IoCancelIrp su un IRP di proprietà per il driver se non si conosce che l'IRP non è stata ancora completata.
  26. Non è possibile chiamare IoCancelIrp per l'IRP sta lavorando alla routine di invio fino a quando la routine di invio viene restituito al chiamante.
  27. Non chiamare IoMakeAssociatedIrp per creare pacchetti IRP per i driver da un driver intermedio di livello inferiore. L'IRP del driver intermedio può essere un IRP associato e non è possibile associare altri pacchetti IRP per un IRP già associato.
  28. Mai chiamata IoMakeAssociatedIrp in un IRP impostato per eseguire nel buffer di I/O.
  29. Non è sufficiente risolvere virtuali puntatori ai registri di I/O della periferica e accedervi. Utilizzare sempre le funzioni di livello HAL (hardware abstraction layer) di astrazione hardware corretto per accedere a una periferica.
  30. Non accedere mai IRP o periferica di campi dell'oggetto da una ISR che può essere modificata da DISPATCH_LEVEL. In un sistema multiprocessore simmetrico questo può causare danneggiamento dei dati.
  31. Non modificare i dati durante l'esecuzione IRQL di elevata se i dati potrebbero essere scritto dal basso-tale codice. Utilizzare la routine KeSynchronizeExecution.
  32. Non acquisire uno dei blocchi di selezione del driver (se si dispone di uno) in una routine DispatchCleanup prima acquisire il blocco selezione di annullamento a livello di sistema (IoAcquireCancelSpinLock). Segue una gerarchia di acquisizione del blocco di coerente in tutto il driver è essenziale per evitare potenziali deadlock.
  33. Mai chiamata IoAcquireCancelSpinLock in una routine di annullamento poiché viene sempre chiamato con il sistema di annullare la selezione blocco viene mantenuto per suo conto.
  34. Non dimenticare di chiamare IoReleaseCancelSpinLock prima di restituire da una routine di annullamento.
  35. Non utilizzare mai sincronizzazione basata su tale poiché questo funziona solo su sistemi con processore singolo. Generazione IRQL su un processore non la mask di interrupt su altri processori.
  36. Non utilizzare mai RtlCopyMemory per intervalli di indirizzo di memoria sovrapposte. Utilizzare RtlMoveMemory.
  37. Non si supponga che le dimensioni di pagina siano costante, anche per una determinata CPU. Utilizzare PAGE_SIZE e l'altra pagina costanti correlate definite nei file di intestazione per garantire la portabilità.
  38. Non accedere mai alcuna chiave del Registro di sistema diversi da Registry\Machine\Hardware e Registry\Machine\System da DriverEntry routine di un driver caricato in fase di inizializzazione Boot\System.
  39. Non creare mai una chiave Enum per caricando un driver nella chiave di un driver Registro di sistema (Registry\Machine\System\CurrentControlSet\Services). Il sistema crea questa chiave in modo dinamico.
  40. Mai il tentativo di inizializzare un dispositivo fisico senza che le porte di I/O relativo bus necessarie, gli intervalli di memoria, interrupt o accesso diretto alla memoria (DMA) canale/porta le risorse hardware nel Registro di sistema prima.
  41. Non chiamano mai IoRegisterDriverReinitialization da DriverEntry la routine a meno che non restituisce STATUS_SUCCESS.
  42. Non chiamare KeSetEvent mai con il parametro Wait impostato su TRUE da un thread paginabile o di una routine di paginabile del driver che viene eseguito con tale PASSIVE_LEVEL. Questo tipo di chiamata ha un errore irreversibile della pagina, in caso di una routine per essere eseguito il paging tra le chiamate a KeSetEvent e KeWaitOggetti.
  43. Non chiamare KeReleaseSemaphore mai con il parametro Wait impostato su TRUE da un thread paginabile o di una routine di paginabile del driver che viene eseguito con tale PASSIVE_LEVEL. Se la routine si verifica per essere eseguito il paging tra le chiamate a KeReleaseSemaphore e KeWaitOggetto, questo tipo di una chiamata causa un errore di pagina irreversibile.
  44. Non chiamare KeReleaseMutex mai con il parametro Wait impostato su TRUE da un thread paginabile o di una routine di paginabile del driver che viene eseguito con tale PASSIVE_LEVEL. Se la routine si verifica per essere eseguito il paging tra le chiamate a KeReleaseMutex e KeWaitOggetto, questo tipo di una chiamata causa un errore di pagina irreversibile.
  45. Non consente di chiamare KeBugCheckEx o KeBugCheck da un driver in vendita al dettaglio di Windows NT per ridurre il sistema, a meno che l'errore è un errore critico che indirizzi di memoria di sistema danneggiata oppure potrebbe impedire al sistema controllo errori. Tenta sempre di gestire correttamente condizioni di errore.
  46. Non si supponga che una routine IoTimer verrà chiamata con precisione su un limite di un secondo poiché gli intervalli in cui qualsiasi IoTimer particolare routine viene chiamata in ultima analisi dipende dalla risoluzione del clock di sistema.
  47. Non è possibile chiamare Win32s application programming interface (API) da un driver di periferica in modalità kernel.
  48. Non utilizzare funzioni ricorsive che possono causare lo stack overflow perché dello stack di modalità kernel del thread chiamante non aumenta in modo dinamico mentre è in esecuzione in modalità kernel.
  49. Non utilizzare mai puntatori all'oggetto interrupt (PKINTERRUPT) che gestisce più di un interrupt, per identificare gli interrupt in una ISR poiché l'indirizzo dell'oggetto interrupt in ISR non sarà sempre l'identico a quello fornito dal IoConnectInterrupt. È solo necessario utilizzare il valore di ServiceContext specificato in IoConnectInterrupt per identificare la periferica di interruzione corrente.
  50. Non è possibile scaricare un driver senza dover cancellare CustomTimerDpc (KeCancelTimer). Se la DPC viene generato dopo che il driver è scaricato, Impossibile premere non di codice esistente e impedire al sistema controllo errori.
  51. Non scaricare un driver fino a quando tutti i pacchetti IRP che hanno il CompletionRoutine I/O del driver impostato in esso vengono completate. Se l'IRP ottiene completato dal driver inferiore dopo lo scaricamento del driver, il sistema potrebbe tentare di eseguire il codice non esistente e causare l'arresto anomalo del sistema.
  52. Non attivare interrupt della periferica fino a quando non il driver è pronto per gestire. Si consiglia di abilitare solo dopo il driver è completamente inizializzato ed è sicura per il sistema tocco le strutture interne del driver di ISR e DPC.
  53. Mai chiamata all'esterno del driver tenendo uno spinlock perché può provocare il blocco critico (deadlock).
  54. Mai restituito qualsiasi stato diverso da STATUS_MORE_PROCESSING_REQUIRED da CompletionRoutine di I/O per un IRP creato il driver con IoBuildAsynchronousFsdRequest/IoAllocateIrp poiché l'IRP non è preparato per il completamento correlate post-elaborazione dal gestore di I/O. Deve essere liberato in modo esplicito ad un IRP (IoFreeIrp) dal driver. Se l'IRP non è destinato per il riutilizzo, possono essere liberato nel CompletionRoutine prima di restituire lo stato STATUS_MORE_PROCESSING_REQUIRED.
  55. Mai allocare un IRP con IoBuildSynchronousFsdRequest/IoBuildDeviceIoControlRequest in un contesto di thread poiché l'IRP rimane associato al thread (IRP-> ThreadListEntry) fino a quando non viene liberata.
  56. Non chiamare IoInitializeIrp in un IRP che è stato allocato con IoAllocateIrp con ChargeQuota parametro impostato su TRUE. Quando si assegna un IRP impostato ChargeQuota su TRUE, il gestore I/O mantiene le informazioni per il pool da cui è allocata la memoria per l'IRP in flag interno del comando in esecuzione.

    Quando si chiama IoInitializeIrp su tali un IRP, le informazioni di pool di allocazione vengono perse come questa funzione zeri ciecamente l'IRP intero. Questo porta al danneggiamento della memoria quando si libera l'IRP. Inoltre, non riutilizzare un IRP fornito dal gestore I/O. Se si desidera riutilizzare un IRP, è necessario allocare proprio tramite IoAllocateIrp.
  57. Non specificare WaitMode come UserMode in KeWaitForSingleObject/KeWaitForMultipleObjects se l'oggetto viene allocato nello stack del thread chiamante. Il e questo è che, se l'oggetto in attesa viene creato nello stack di funzione, è necessario specificare KernelMode come il WaitMode per impedire che lo stack del thread viene eseguito il paging.
  58. Non acquisire risorse, ad esempio ERESOURCES e FastMutex(Unsafe) nel contesto di un thread in modalità utente senza la protezione del codice in una sezione critica.

    Poiché l'acquisizione di queste risorse non genera l'IRQL per APC_LEVEL, se il thread viene sospeso (operazione eseguita dall'accodamento un APC) dopo che ha acquisito la risorsa, potrebbe provocare il blocco critico (deadlock) e compromettere protezione del sistema. Di conseguenza, è necessario acquistare tali risorse, sia mediante la generazione in modo esplicito l'IRQL APC_LEVEL o in una sezione critica chiamando KeEnterCriticalRegion.

Riferimenti

Guida di progettazione di driver di periferica MSDN per Windows NT

Proprietà

Identificativo articolo: 186775 - Ultima modifica: martedì 27 luglio 2004 - Revisione: 2.1
Le informazioni in questo articolo si applicano a:
  • Microsoft Win32 Device Driver Kit for Windows NT 3.51
  • Microsoft Win32 Device Driver Kit for Windows NT 4.0
Chiavi: 
kbmt kbinfo KB186775 KbMtit
Traduzione automatica articoli
Il presente articolo è stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell?utente. Tuttavia, un articolo tradotto in modo automatico non è sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, più o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non è la sua. Microsoft non è responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell?utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.
Clicca qui per visualizzare la versione originale in inglese dell?articolo: 186775
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.
Dichiarazione di non responsabilità per articoli della Microsoft Knowledge Base su prodotti non più supportati
Questo articolo è stato scritto sui prodotti per cui Microsoft non offre più supporto. L?articolo, quindi, viene offerto ?così come è? e non verrà più aggiornato.

Invia suggerimenti

 

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