TouchDeviceActivate を作る時に関係資料がなかなか見つからなくてアレコレしたのでメモ。
ここでの紹介はデバイスの列挙、状態取得、有効化/無効化変更。
使用するAPI群
SetupDi 系。
ヘッダーファイル
- regstr.h
- setupapi.h
- cfgmgr32.h
ライブラリーファイル
- setupapi.lib
- cfgmgr32.lib
使用法
デバイス一覧を取得して無効化しているかを調べ、有効化/無効化を反転する。
記述してあるエラー処理は最低限なので注意。
あと、実行には管理者権限が必要。無い場合はアクセス権無しのエラーが出まする。
DWORD dwIndex; // デバイスのインデックス TCHAR* pName; // 文字列取得用バッファ DWORD dwSize; // バッファのサイズ DWORD dwRegType; // 何か BOOL bRet; // 戻り値 HDEVINFO hDevInfo; // デバイス情報 SP_DEVINFO_DATA sDevInfo; // デバイス情報 // デバイス一覧(ハードウェアクラスノード一覧)のハンドルを取得 // DIGCF_PRESENT を指定すると無効化しているデバイスが列挙されないので注意 hDevInfo = SetupDiGetClassDevs( NULL, 0, 0, DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE ); if( hDevInfo == INVALID_HANDLE_VALUE ) { // エラー return; } dwIndex = 0; ZeroMemory( &sDevInfo, sizeof(SP_DEVINFO_DATA) ); sDevInfo.cbSize = sizeof(SP_DEVINFO_DATA); while(true) { bRet = SetupDiEnumDeviceInfo( hDevInfo, dwIndex++, &sDevInfo ); if( !bRet ) { // 打ち止め break; } // SPDRP_DEVICEDESC(デバイスの説明/デバイスマネージャー上の表示名)の取得 // 例:"Microsoft Input Configuration Device" dwSize = 0; bRet = SetupDiGetDeviceRegistryProperty( hDevInfo, &sDevInfo, SPDRP_DEVICEDESC, &dwRegType, NULL, 0, &dwSize ); pName = new TCHAR[dwSize]; bRet = SetupDiGetDeviceRegistryProperty( hDevInfo, &sDevInfo, SPDRP_DEVICEDESC, &dwRegType, (BYTE*)pName, dwSize, &dwSize ); delete pName; // SPDRP_HARDWAREID(ハードウェアID)の取得 // 例:"HID\VID_056A&PID_0084&REV_0111&Col06" dwSize = 0; bRet = SetupDiGetDeviceRegistryProperty( hDevInfo, &sDevInfo, SPDRP_HARDWAREID, &dwRegType, NULL, 0, &dwSize ); pName = new TCHAR[dwSize]; bRet = SetupDiGetDeviceRegistryProperty( hDevInfo, &sDevInfo, SPDRP_HARDWAREID, &dwRegType, (BYTE*)pName, dwSize, &dwSize ); if( bRet ) { ULONG nStatus; // DN_ 接頭子の定数 ULONG nProblemNumber = 0; // CM_PROB_ 接頭子の定数 CONFIGRET cgr = CM_Get_DevNode_Status( &nStatus, &nProblemNumber, sDevInfo.DevInst, 0 ); // 無効化可能なモノ( DN_DISABLEABLE フラグ)のみを対象にする // 必要に応じて SPDRP_HARDWAREID で取得したIDを参照して操作するデバイスを決定する if( cgr == CR_SUCCESS && nStatus & DN_DISABLEABLE ) { enable = nProblemNumber == CM_PROB_DISABLED; // 無効化している場合は有効化にする判定 SP_PROPCHANGE_PARAMS pcp = {0}; pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); // 定型処理 pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; // 状態変更の指示 pcp.Scope = DICS_FLAG_GLOBAL; // コンピューター全体 pcp.HwProfile = 0; // 現在のプロファイル // 切り替え if( enable ) { // 有効化する pcp.StateChange = DICS_ENABLE; } else { // 無効化する pcp.StateChange = DICS_DISABLE; } // パラメーターを sDevInfo に適用 r = SetupDiSetClassInstallParams( hDevInfo, &sDevInfo, &pcp.ClassInstallHeader, sizeof(pcp) ); // パラメーターをデバイスに適用 r = SetupDiChangeState( hDevInfo, &sDevInfo ); } } delete pName; } // 解放 SetupDiDestroyDeviceInfoList( hDevInfo );
取得するハードウェアクラスノードの一覧には同じハードウェアIDを持つ複数のノードが含まれている事があるので、DN_DISABLEABLE フラグを使用してデバイスマネージャー上に見えている無効化可能ノードを識別。
参考サイト
Japan WDK Support Blog :デバイスの有効・無効をプログラムから切り替える方法