Freigeben Driver-Allocated Ressourcen
Die Besonderheiten, wie ein Treiber die Registrierung verwendet, Systemobjekte und -ressourcen in seinen Geräteerweiterungen, Controllererweiterungen oder treiberseitig zugewiesenen nicht auslagerten Pool einrichtet, variiert von Treiber zu Treiber. Bei jeder Entladen-Routine müssen jedoch die Ressourcen freigegeben werden, die ein Treiber in Phasen verwendet.
Die Entladeroutine eines jeden Treibers muss sicherstellen, dass keine andere Treiberroutine derzeit eine bestimmte Ressource verwendet oder in Kürze verwendet, bevor diese Ressource freigegeben wird.
Im Allgemeinen gibt eine Unload-Routine alle treiberseitig zugewiesenen Ressourcen in den folgenden Phasen frei:
Wenn der Treiber dies noch nicht getan hat, deaktivieren Sie nach Möglichkeit Interrupts auf physischen Geräten, und rufen Sie Dann IoDisconnectInterrupt auf, sobald Interrupts deaktiviert sind.
Stellen Sie sicher, dass keine andere Treiberroutine auf die Ressourcen verweisen kann, die von der Unload-Routine freigegeben werden sollen.
Beispielsweise muss eine Unload-RoutineIoStopTimer aufrufen, wenn die IoTimer-Routine des Treibers derzeit für ein bestimmtes Geräteobjekt aktiviert ist. Es muss sicherstellen, dass kein Thread auf eines der Dispatcherobjekte des Treibers wartet und dass seine Timerobjekte nicht für Aufrufe der CustomTimerDpc-Routinen in die Warteschlange gestellt werden, bevor der Speicher für die Dispatcherobjekte freigegeben wird. Es muss KeRemoveQueueDpc aufrufen, wenn es über eine CustomDpc-Routine verfügt, die der ISR möglicherweise in die Warteschlange gestellt hat usw.
Wenn der Treiber IoQueueWorkItem heißt, muss er sicherstellen, dass das Arbeitselement abgeschlossen wurde. IoQueueWorkItem nimmt einen Verweis auf das zugeordnete Geräteobjekt aus. der Treiber kann nicht entladen werden, wenn solche Verweise vorhanden sind.
Wenn der Treiber PsCreateSystemThread heißt, muss die Unload-Routine auch dazu führen, dass der vom Treiber erstellte Thread ausgeführt wird, damit der Thread selbst PsTerminateSystemThread aufrufen kann, bevor der Treiber entladen wird. Ein Treiber kann einen vom Treiber erstellten Systemthread nicht freigeben, indem er ZwClose mit dem von PsCreateSystemThread zurückgegebenen ThreadHandle aufruft.
Geben Sie alle gerätespezifischen Ressourcen frei, die der Treiber zugewiesen hat. Dies kann das Aufrufen der folgenden Systemunterstützungsroutinen umfassen:
IoDeleteSymbolicLink , wenn die DriverEntry - oder Reinitialize-RoutineioCreateSymbolicLink oder IoCreateUnprotectedSymbolicLink genannt wird, und IoDeassignArcName , wenn der Treiber IoAssignArcName aufgerufen hat.
ExFreePool , wenn DriverEntry oder eine andere Treiberroutine namens ExAllocatePoolWithTag und der Treiber den zugewiesenen Arbeitsspeicher noch nicht freigegeben hat.
MmUnmapIoSpace , wenn die DriverEntry - oder NeuitialisierungsroutinemmMapIoSpace genannt wird.
MmFreeNonCachedMemory , wenn die DriverEntry - oder Reinitialize-RoutinemmAllocateNonCachedMemory genannt wird.
MmFreeContiguousMemory , wenn die DriverEntry - oder Reinitialize-Routine"MmAllocateContiguousMemory" genannt wird.
FreeCommonBuffer , wenn die DriverEntry - oder Reinitialize-Routinenamens AllocateCommonBuffer.
IoAssignResources oder IoReportResourceUsage , wenn die DriverEntry - oder Reinitialize-Routine eine dieser Supportroutinen oder HalAssignSlotResources aufgerufen hat , um Hardwareressourcen in der Konfigurationsregistrierung für sich selbst und/oder für ihre physischen Geräte einzeln zu beanspruchen.
Geben Sie Systemobjekte und Ressourcen frei, die die DriverEntry - oder Reinitialize-Routine in der Geräteerweiterung der Geräteobjekte oder in der Controllererweiterung des Controllerobjekts eingerichtet hat (sofern sie eine erstellt hat). Insbesondere muss der Treiber Folgendes tun, bevor er versucht, das Geräteobjekt (IoDeleteDevice) oder das Controllerobjekt (IoDeleteController) zu löschen:
- Rufen Sie IoDisconnectInterrupt auf, um den Interruptobjektzeiger frei zu geben, der in der entsprechenden Geräte- oder Controllererweiterung gespeichert ist.
- Rufen Sie ObDereferenceObject mit dem Zeiger auf das Dateiobjekt des nächstniedrigen Treibers auf, wenn es IoGetDeviceObjectPointer genannt und diesen Zeiger in einem Gerät oder einer Controllererweiterung gespeichert hat.
- Rufen Sie IoDetachDevice mit dem Zeiger auf das Geräteobjekt des unteren Treibers auf, wenn es IoAttachDevice oder IoAttachDeviceToDeviceStack aufgerufen und diesen Zeiger in einer Geräte- oder Controllererweiterung gespeichert hat.
Geben Sie die Hardwareressourcen frei, die die DriverEntry - oder Reinitialize-Routine für die physischen Geräte des Treibers beansprucht hat, falls vorhanden, in der Registrierung unter der Struktur \Registry\Machine\Hardware\ResourceMap .
Entfernen Sie alle Namen für ihre Geräte, die die DriverEntry - oder Neuitialisierungsroutine in der Registrierung unter \Registry gespeichert haben. \DeviceMap-Struktur ebenfalls.
Nachdem der Treiber Geräte-, System- und Hardwareressourcen freigegeben hat, kann er seine Geräte- und Controllerobjekte löschen, wie unter Freigeben von Geräte- und Controllerobjekten beschrieben.