SetupDi* 啟用與停用裝置
來源:互聯網
上載者:User
想要實作類別似裝置管理員的功能,其實也不是很難,無非就是調用一些API函數,就像本文描述的,採用的API函數就是SetupDi系列的函數。不過這類函數有很多,具體的請參見MSDN,而實現裝置啟用、停用僅需要用到的就只有5個函數:
SetupDiGetClassDevs // 擷取裝置資訊集
SetupDiEnumDeviceInfo // 從裝置資訊集中枚舉每個裝置的具體資訊
SetupDiGetDeviceRegistryProperty // 從註冊表中讀取PnP裝置的屬性
SetupDiSetClassInstallParams // 設定(包括取消)裝置類的安裝參數
SetupDiCallClassInstaller // 安裝指定裝置
以上函數均在setupapi.h標頭檔中聲明,該標頭檔包含在setupapi.lib函數庫中(使用以上函數前需要聲明這個標頭檔)。
接下來就是如何?裝置的啟用與停用。
從原理上講,裝置的啟用與停用其實就是對該裝置進行重安裝。
首先,我們需要聲明兩個變數用來儲存指定裝置類的屬性資訊:
HDEVINFO m_hDevInfo; // 類似裝置控制代碼,以下暫且稱為裝置控制代碼
SP_DEVINFO_DATA m_DeviceInfoData; // 裝置詳細屬性資訊
然後調用SetupDiGetClassDevs函數擷取裝置控制代碼的值。(在這個函數中,需要指定裝置類的GUID,如果不清楚這個GUID,可以在相應的安裝檔案.inf中尋找。注意:是裝置類的GUID,不是裝置的GUID!)
接著迴圈使用SetupDiEnumDeviceInfo函數枚舉對應裝置類中的裝置,並使用SetupDiGetDeviceRegistryProperty函數擷取得到的裝置的詳細資料,進行判斷是否為所需的裝置(判斷的方式有多種,具體參考MSDN,本文採用裝置描述進行判斷)。
一旦枚舉結束(即枚舉不成功,而且用GetLastError()可以得到錯誤碼259)即可退出迴圈。當然如果找到裝置,即可break退出。
如果找到對應的裝置,就調用SetupDiSetClassInstallParams函數設定安裝的屬性。這裡有個注意的地方需要詳細說明一下:
SetupDiSetClassInstallParams的函數原型如下:
WINSETUPAPI BOOL WINAPI
SetupDiSetClassInstallParams(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL
IN PSP_CLASSINSTALL_HEADER ClassInstallParams, OPTIONAL
IN DWORD ClassInstallParamsSize
);
注意第三個參數PSP_CLASSINSTALL_HEADER ClassInstallParams,
這裡我們不採用這個結構,而是採用另外一個結構:SP_PROPCHANGE_PARAMS
並在這個結構中,
設定ClassInstallHeader欄位中(我們發現這個欄位也是一個結構,就是PSP_CLASSINSTALL_HEADER結構)的InstallFunction欄位值為DIF_PROPERTYCHANGE,
設定StateChange值為DICS_ENABLE(該值為啟用,若是停用則為DICS_DISABLE)
然後採用強行轉換將其轉為PSP_CLASSINSTALL_HEADER結構。
最後,調用SetupDiCallClassInstaller函數執行裝置的安裝(即:啟用或者停用),注意該函數第一個參數值應為DIF_PROPERTYCHANGE。
從裝置管理員中,可以驗證我們的做法。