在使用 SetupAPI 前,必需要先了解 device setup class,device interface class,device information set 這些跟 windows 上裝置管理相關的概念
Device Setup Class
微軟將以相同方式安裝和設定的 device 歸類成一個個的 device setup class,例如 IDE 硬碟,usb 隨身碟,都被歸類在 disk drives device setup class微軟為幾乎所有的裝置都定義了 device setup class,每一個 device setup class 都有對應的 GUID,可以在 Devguid.h 裡面找到其 GUID並在程式中使用,系統上的 device 也可以在 ..\CurrentControlSet\Control\Class\ClassGuid 找到該 device 的資料
Device Interface Class
Device interface class 是一組接口的定義,可以讓 device driver 將它的功能讓其他的 driver,系統元件或是 user mode 程式來使用,可以想成若是一個 driver 註冊了某個 device interface class,它就必定支援某些功能每個 device interface class 都有對應的 GUID,微軟定義了大部分通用的 device interface class
不同類型的裝置可能會屬於同一個 device interface class,例如 usb 滑鼠或 PS/2 接口的滑鼠都屬於 GUID_DEVINTERFACE_MOUSE
drivers 通常只註冊一個 device interface class,不過也有例外,例如一個可以被 mounted 的 disk 應該註冊 GUID_DEVINTERFACE_DISK 和 MOUNTDEV_MOUNTED_DEVICE_GUID
Device Information Set
Windows 中屬於 device setup class 或 device interface class 的 device 必須要透過 device information set 和 device information element 來操作device information set 中包含 device information element,device information element 又包含了 device devnode 的 handle 和指向 device interface list 的 pointer
我們的程式實際上看不到這些資料結構內含哪些資料,因為這是 Windows 內部使用的資料結構,我們只會拿到 device information set 的 handle 並且透過 handle 來呼叫 SetupAPI
通常是用 SetupDiGetClassDevs API 來取得 device information set 的 handle,而且 device information set 裡面的元素不是固定的,而是動態的根據不同的條件系統幫忙 create 出來的一個結構,例如用不同的 disk type 的 device setup class 參數,SetupDiGetClassDevs API 會回傳只包含 disk type 的 device information set 回來
要怎麼使用 SetupAPI
了解了這些概念後,就可以使用 SetupAPI 開始對 device 做一些操作,例如想知道系統上有多少磁碟機,可以用 GUID_DEVCLASS_DISKDRIVE device setup class 當參數傳給 SetupDiGetClassDevsSetupDiGetClassDevs 有提供 enumerator 參數可以讓 caller 做進一步篩選想選取的 device,例如可以傳 "USBSTOR" 參數,只取得 usb 磁碟機的 device information set
取得 device information set 之後,用SetupDiEnumDeviceInfo 取得每一個 device 的 SP_DEVINFO_DATA 資料結構,再用 SetupDiGetDeviceRegistryProperty 取得 device 的資訊例如 friendly name
除了取得 device 的資訊,還可以對這些 device 做更多的操作,例如想要 uninstall 某些 device,一樣取得 device information set 與各個 device 的 SP_DEVINFO_DATA 之後,可以呼叫 DiUninstallDevice,就可以將 device 移除
沒有留言:
張貼留言