2016-08-05 78 views
0

我正在研究WDK7的Microsoft Toaster示例代碼,並發現一個微妙的問題。如何從我的Windows驅動程序代碼中區分devmgmt的Disable和Uninstall?

現在在Windows 7

試圖編譯驅動器(WDM busenum和WDM featured1)如自述爲導向,enum -p 1增加了一個烤麪包機設備,然後,我打開設備管理器(devmgmt),查找設備,卸載吧。

Uninstall toaster device from devmgmt.msc

這將破壞烤麪包機設備節點(我相信); 我們可以看到,ToasterDevice01節點現在從設備管理器中消失。 !devnode 0 1顯示多士爐devnode仍然存在,State = DeviceNodeUninitialized(0x301),Previous State = DeviceNodeRemoved(0x312)。

然後,我執行enum -p 1試圖再次添加設備。但是我得到錯誤0x57(ERROR_INVALID_PARAMETER)。

enum -p 1 , got 0x57 error

我調試源代碼,並查明原因:buspdo.c不devmgmt的禁用和卸載操作區別開來。他的代碼邏輯是:

  • 如果烤麪包機得到意外刪除(enum -u 1),它調用Bus_DestroyPdo()這是正確的行爲。
  • 如果吐司機從devmgmt獲取Disabled,它的確如此而不是呼叫Bus_DestroyPdo(),這也是正確的。

問題是,當終端用戶從devmgmt執行卸載,它遵循禁用路徑。現在發生了一些不好的事情:Windows刪除烤麪包機devnode,但烤麪包機總線驅動程序不會銷燬相應的PDO,因此,當下次用戶執行enum -p 1時,烤麪包機總線驅動程序Bus_PlugInDevice()指責帶有Seri​​alNo == 1的烤麪包機設備已經存在,因此用戶請求失敗。

enter image description here

BTW:烤麪包機的KMDF版本(僅適用於靜態枚舉版本試過今天)

現在我的問題是清楚的表現出類似的問題:如何從禁止和卸載區分開來,將我做的巴士司機或小孩設備驅動程序? KMDF版本的答案也是受歡迎的。

+0

devnode真的被摧毀了嗎?我認爲它仍然可能存在,因爲PDO存在(PDO包含對coresnode devnode的引用)。當您禁用並通過設備管理器啓用設備時,示例的行爲方式是否相同? –

+0

請告訴我一種能夠檢查devnode是否存在的方式(如某種股票實用程序),謝謝。 –

+0

我不知道任何能夠做到這一點的工具。您可以使用我的工具(https://github.com/MartinDrab/VrtuleTree/releases)在卸載後檢查PDO是否存在(https://github.com/MartinDrab/VrtuleTree/releases-文件 - >創建快照並查找\ Driver \ )。內核似乎在刪除PDO時刪除了devnode結構。 –

回答

0

現在我可以做出結論。我們的客戶端驅動程序無法區分從設備管理器禁用和卸載。這是微軟的設計。

爲了區分,我們需要應用層的幫助。爲子設備提供一個CoInstaller,並且當CoInstaller獲取DIF_REMOVE通知(這是devmgmt進行卸載的結果)時,將自定義IOCTL(例如IOCTL_UNPLUG_MY_CHILD)發送到內核驅動程序,以便內核驅動程序拔出相應的子進程。

相關問題