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 :デバイスの有効・無効をプログラムから切り替える方法

 

 


↓ランキングに参加してます↓
ブログランキング・にほんブログ村へ
人気ブログランキングへ