驅動程式 - Windows Driver Model (WDM) - 教學說明 - 3. 系統透過呼叫DriverUnload()來卸載驅動程式



當驅動程式準備被系統卸載時,DriverUnload()會被系統呼叫,這是驅動程式最後可以釋放資源的地方,若沒有適當的釋放資源,則驅動程式無法被卸載,遇到這種狀況時,系統會提示需要重新開機才可以正確卸載驅動程式,而DriverUnload()是在DriverEntry()裡面註冊的,所以系統才會知道DriverUnload()位於何處

DriverUnload()定義如下

void DriverUnload(PDRIVER_OBJECT);

因為WDM驅動程式會收到PNP Remove Device的IRP,所以當系統要卸載驅動程式時,系統會呼叫PNP對應的Callback並帶入IRP_MN_REMOVE_DEVICE(在IRP_MJ_PNP之下),WDM驅動程式一般會在該Callback釋放資源,若是Legacy驅動程式,因為Device Object是在DriverEntry()產生,加上又沒有IRP_MN_REMOVE_DEVICE IRP,所以必須在DriverUnload()釋放資源,這是兩種驅動程式的主要差異地方

範例:

void DriverUnload(PDRIVER_OBJECT pMyDriver)
{
}

WDM驅動程式的DriverUnload()一般不做任何事情,因為釋放資源的地方已經改到IRP_MN_REMOVE_DEVICE Callback,原因在於WDM驅動程式的資源配置是在AddDevice()配置,所以釋放資源的地方就變成是收到IRP_MN_REMOVE_DEVICE時才移除之前配置的資源,當然,如果使用者有在DriverEntry()配置資源,那相對應的,理應在DriverUnload()釋放這些配置的資源,沒有正確釋放驅動程式的資源時,系統將提示無法正確卸載驅動程式,遇到這種狀況,只能重新開機