Освобождение ресурсов Driver-Allocated
Особенности использования реестра драйвером, настройки системных объектов и ресурсов в расширениях устройства, расширениях контроллера или в пуле, выделенном драйвером, зависят от драйвера к драйверу. Однако любая подпрограмма выгрузки должна поэтапно освобождать ресурсы, используемые драйвером.
Любая подпрограмма выгрузки драйвера должна гарантировать, что никакие другие подпрограммы драйвера в настоящее время не используют или могут в ближайшее время использовать определенный ресурс, прежде чем он будет освобожден.
Как правило, подпрограмма выгрузки освобождает все ресурсы, выделенные драйвером, на следующих этапах:
Если драйвер еще не сделал этого, отключите прерывания на любых физических устройствах, если это возможно, а затем вызовите IoDisconnectInterrupt сразу после отключения прерываний.
Убедитесь, что никакие другие подпрограммы драйвера не могут ссылаться на ресурсы, которые подпрограмма выгрузки намерена освободить.
Например, подпрограмма Unload должна вызывать IoStopTimer , если подпрограмма IoTimer драйвера в настоящее время включена для определенного объекта устройства. Он должен гарантировать, что ни один поток не ожидает каких-либо объектов диспетчера драйвера и что его объекты таймера не помещаются в очередь для вызовов подпрограмм CustomTimerDpc , прежде чем освободить хранилище для объектов диспетчера. Он должен вызвать KeRemoveQueueDpc, если у него есть подпрограмма CustomDpc , которую ISR мог поместить в очередь, и т. д.
Если драйвер называется IoQueueWorkItem, он должен убедиться, что рабочий элемент завершен. IoQueueWorkItem извлекает ссылку на связанный объект устройства; драйвер не может быть выгружен, если такие ссылки остаются.
Если драйвер называется PsCreateSystemThread, подпрограмма Unload также должна привести к запуску созданного драйвером потока, чтобы сам поток смог вызвать PsTerminateSystemThread перед выгрузкой драйвера. Драйвер не может освободить созданный драйвером системный поток, вызвав ZwClose с ThreadHandle, возвращенным PsCreateSystemThread.
Высвободим все ресурсы для конкретных устройств, выделенные драйвером. Для этого может потребоваться вызвать следующие процедуры поддержки системы:
IoDeleteSymbolicLink , если подпрограмма DriverEntry или Reinitialize называется IoCreateSymbolicLink или IoCreateUnprotectedSymbolicLink, и IoDeassignArcName , если драйвер называется IoAssignArcName.
ExFreePool , если DriverEntry или любая другая подпрограмма драйвера с именем ExAllocatePoolWithTag и драйвер еще не освободил выделенную память.
MmUnmapIoSpace , если подпрограмма DriverEntry или Повторная инициализация называется MmMapIoSpace.
MmFreeNonCachedMemory , если подпрограмма DriverEntry или Повторная инициализация называется MmAllocateNonCachedMemory.
MmFreeContiguousMemory , если подпрограмма DriverEntry или Повторная инициализация называется MmAllocateContiguousMemory.
FreeCommonBuffer, если подпрограмма DriverEntry или Повторная инициализация называется AllocateCommonBuffer.
IoAssignResources или IoReportResourceUsage, если подпрограмма DriverEntry или Reinitialize вызвала одну из этих процедур поддержки или HalAssignSlotResources для утверждения аппаратных ресурсов в реестре конфигурации для себя и (или) для физических устройств по отдельности.
Освободите системные объекты и ресурсы, которые подпрограмма DriverEntry или Повторная инициализация настраивается в расширении устройства объектов устройства или в расширении контроллера объекта контроллера (если он был создан). В частности, драйвер должен выполнить следующие действия перед попыткой удалить объект устройства (IoDeleteDevice) или объект контроллера (IoDeleteController):
- Вызовите IoDisconnectInterrupt , чтобы освободить указатель объекта прерывания, хранящийся в соответствующем расширении устройства или контроллера.
- Вызовите ObDereferenceObject с указателем на объект файла следующего ниже драйвера, если он вызвал IoGetDeviceObjectPointer и сохранил этот указатель в расширении устройства или контроллера.
- Вызовите IoDetachDevice с указателем на объект устройства нижнего драйвера, если он называется IoAttachDevice или IoAttachDeviceToDeviceStack и сохраняет этот указатель в расширении устройства или контроллера.
Освободите аппаратные ресурсы, которые программа DriverEntry или Повторная инициализация утверждала для физических устройств драйвера, если таковые есть, в реестре в дереве \Registry\Machine\Hardware\ResourceMap .
Удалите все имена для своих устройств, которые подпрограмма DriverEntry или Повторная инициализация хранится в реестре в разделе \Registry.. \DeviceMap tree , а также.
После того как драйвер освободит ресурсы устройства, системы и оборудования, он может удалить свои объекты устройства и контроллера, как описано в разделе Освобождение объектов устройства и контроллера.