2011-08-18 207 views
2

我的任務是跟蹤從Windows服務添加和刪除磁盤驅動器。我使用RegisterServiceCtrlHandlerEx和RegisterDeviceNotification來實現這一點。我的服務控制處理程序例程成功接收SERVICE_CONTROL_DEVICEEVENT控制代碼,並處理GUID_DEVINTERFACE_VOLUME clsss的DBT_DEVICEAREMIVAL和DBT_DEVICEREMOVECOMPLETE事件。順便說一下,Windows不會將DBT_DEVICEQUERYREMOVE,DBT_DEVICEQUERYREMOVEFAILED,DBT_DEVICEREMOVEPENDING事件發送到我的例程,但現在我想解決另一個問題。將卷GUID路徑轉換爲設備路徑

當我接收DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE事件和dbch_devicetype是DBT_DEVTYP_DEVICEINTERFACE我可以從DEV_BROADCAST_DEVICEINTERFACE結構的dbcc_name字段讀取設備名稱。它看起來是這樣的:\ \ STORAGE#RemovableMedia#7 & 331a4e33 RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}

我可以在這個字符串中使用GetVolumeNameForVolumeMountPoint過程僅在DBT_DEVICEARRIVAL轉換成卷GUID路徑事件。在DBT_DEVICEREMOVECOMPLETE事件GetVolumeNameForVolumeMountPoint返回錯誤3(系統找不到指定的路徑)。

另一方面,在服務啓動期間,我使用FindFirstVolume/FindNextVolume掃描系統中的所有卷,並返回給我所有卷的卷GUID路徑列表。

因此,如果卷存在時,我的服務啓動我可以收到其卷GUID路徑。如果該卷將被刪除,而我的服務正在運行的話,我會收到設備的名稱(如\?\ STORAGE#RemovableMedia#7 & 331a4e33 RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b})從 DBT_DEVICEREMOVECOMPLETE事件。

正如我上面寫的,我不能在DBT_DEVICEREMOVECOMPLETE事件期間使用GetVolumeNameForVolumeMountPoint來獲取卷GUID路徑。所以我想找到一種方法將從FindFirstVolume/FindNextVolume收到的卷GUID路徑轉換爲設備名稱。我需要這個維護我自己的系統中的可移動磁盤驅動器列表。

請給我一些關於這個問題的建議。

回答

1

所以我發現沒有辦法從FindFisrtVolume/FindNextVolume返回的卷GUID路徑中檢索設備路徑。相反,我將使用SetupApi枚舉設備接口來替換FindFisrtVolume/FindNextVolume。

下面是步驟來做到這一點:

  1. 呼叫SetupDiGetClassDevs(& GUID_DEVINTERFACE_VOLUME,NULL,NULL,DIGCF_INTERFACEDEVICE | DIGCF_PRESENT)來檢索設備信息設置。
  2. 使用SetupDiEnumDeviceInterfaces枚舉設備接口(devinfoset,NULL,& GUID_DEVINTERFACE_VOLUME,idx,& devitf)。
  3. 對於每個設備接口調用SetupDiGetDeviceInterfaceDetail來檢索設備路徑。

不幸的是,以這種方式檢索到的設備路徑與窗口在DBT_DEVICEAREMIVETE和DBT_DEVICEREMOVECOMPLETE事件中通過的設備路徑不同。所以當我們比較它們時,我們需要規範設備路徑。

1

要列舉設備構建自己的設備列表中,您可以使用SetupAPI

通過使用SETUPAPI程序,您可以枚舉 指定的設備接口類的所有設備和檢索的設備路徑 設備。

您先撥打SetupDiGetClassDevs,併爲您的設備類別提供適當的GUID,例如: GUID_DEVINTERFACE_VOLUME,然後重複調用SetupDiEnumDeviceInfo來迭代設備。

示例代碼展示瞭如何做到這一點:

  • Knowledge base article展示這一切
  • 過程的另一個描述可以發現here,看看對部分使用以下步驟來創建一個文件處理USB設備。

的各個裝置可使用SetupDiGetDeviceRegistryProperty中查詢的屬性(該路徑是其中)。

+1

您的回答很有用,但我需要添加一些說明。正如你所描述的,我嘗試使用SetupDiEnumDeviceInfo和SetupDiGetDeviceRegistryProperty。但這樣我無法獲得設備路徑。正確的方法是使用SetupDiEnumDeviceInterfaces和SetupDiGetDeviceInterfaceDetail。 –

+0

聽起來不錯。很高興你找到了一個方法! –