釋放Driver-Allocated資源
驅動程式如何使用登錄、在其裝置擴充功能、控制器擴充功能或驅動程式配置的非分頁集區中設定系統物件和資源的詳細資料,會因驅動程式而異。 不過,任何 Unload 常式都必須釋放驅動程式分階段使用的資源。
任何驅動程式的 Unload 常式都必須確保目前沒有任何其他驅動程式常式正在使用,或可能很快就會使用特定資源,然後再釋放該資源。
一般而言, Unload 常式會以下列階段釋放所有驅動程式配置的資源:
如果驅動程式尚未這麼做,請盡可能停用任何實體裝置上的中斷,然後在中斷停用後立即呼叫 IoDisconnectInterrupt 。
請確定沒有其他驅動程式常式可以參考 Unload 常式想要釋放的資源。
例如,如果驅動程式的 IoTimer 常式目前已啟用特定裝置物件的 IoTimer 常式,則 Unload常式必須呼叫IoStopTimer。 它必須確定沒有任何執行緒正在等候任何驅動程式的發送器物件,而且其計時器物件不會排入佇列以呼叫其 CustomTimerDpc 常式,再釋放其發送器物件的儲存空間。 如果 KeRemoveQueueDpc 有 ISR 可能已排入佇列的 CustomDpc 常式,則必須呼叫 KeRemoveQueueDpc。
如果驅動程式稱為 IoQueueWorkItem,則必須確定工作專案已完成。 IoQueueWorkItem 會在相關聯的裝置物件上取出參考;如果有任何這類參考仍保留,則無法卸載驅動程式。
如果驅動程式稱為 PsCreateSystemThread, Unload 常式也必須執行驅動程式建立的執行緒,讓執行緒本身可以在卸載驅動程式之前呼叫 PsTerminateSystemThread 。 驅動程式無法使用PsCreateSystemThread所傳回的ThreadHandle呼叫ZwClose來釋放驅動程式建立的系統執行緒。
釋放驅動程式配置的任何裝置特定資源。 這樣做可能牽涉到呼叫下列系統支援常式:
如果DriverEntry或Reinitialize常式稱為IoCreateSymbolicLink或IoCreateUnprotectedSymbolicLink,則為IoDeleteSymbolicLink,如果驅動程式稱為IoAssignArcName,則為 IoDeassignArcName。
ExFreePool 如果 DriverEntry 或任何其他稱為 ExAllocatePoolWithTag 的驅動程式常式,而且驅動程式尚未釋放配置的記憶體。
如果DriverEntry或Reinitialize常式稱為MmMapIoSpace,則為 MmUnmapIoSpace。
如果DriverEntry或Reinitialize常式稱為mmAllocateNonCachedMemory,則 MmFreeNonCachedMemory。
如果DriverEntry或Reinitialize常式稱為MmAllocateContiguousMemory,則為MmFreeContiguousMemory。
如果DriverEntry或Reinitialize常式稱為AllocateCommonBuffer,則 FreeCommonBuffer。
如果DriverEntry或Reinitialize常式稱為其中一個支援常式或HalAssignSlotResources,以針對本身和/或其實體裝置個別宣告組態登錄中的硬體資源,IoAssignResources或IoReportResourceUsage。
釋放 DriverEntry 或 Reinitialize 常式在裝置物件的裝置延伸模組或控制器物件的控制器擴充中設定的系統物件和資源,如果建立一個) ,則會 (控制器物件的控制器延伸模組。 特別是,驅動程式必須先執行下列動作,才能嘗試刪除 IoDeleteDevice (ioDeleteDevice) 或控制器物件 (IoDeleteController) :
- 呼叫 IoDisconnectInterrupt 以釋放儲存在對應裝置或控制器擴充功能中的中斷物件指標。
- 如果它呼叫IoGetDeviceObject,並使用下一個較低驅動程式的檔案物件的指標呼叫ObDereferenceObject,並將此指標儲存在裝置或控制器擴充功能中。
- 如果IoDetachDevice 呼叫 IoAttachDevice或IoAttachDeviceToDeviceStack,並以較低驅動程式裝置物件的指標呼叫 IoDetachDevice,並將此指標儲存在裝置或控制器擴充功能中。
在\Registry\Machine\Hardware\ResourceMap樹狀目錄下的登錄中,釋放DriverEntry或Reinitialize針對驅動程式實體裝置宣告的硬體資源。
移除 DriverEntry 或 Reinitialize 儲存在 \Registry 之下登錄中之裝置的任何名稱 。\DeviceMap 樹狀結構也一樣。
在驅動程式釋放裝置、系統和硬體資源之後,它可以刪除其裝置和控制器物件,如 釋放裝置和控制器物件中所述。