GUIDからデバイスドライバのデバイスインターフェース名を取得する

概要

Windowsのアプリケーションでデバイスドライバを利用する場合、シリアルポートなどは"¥¥.¥COM1"のようにデバイス名の頭に"¥¥.¥"を付けてCreateFile()でオープンすればデバイスドライバが利用できるのですが、USBポートなどは"¥¥.¥USB1"のようにしても基本的にはオープンできません。

(該当のデバイスドライバが"USB1"のようなシンボリック名を登録していれば出来るのですが、通常のデバイスドライバではシンボリック名の登録は行わないようです。)

では、どのようにしてドライバのインターフェース名を取得するかと言うと、デバイスドライバではデバイスドライバが独自に割り付けたGUIDからデバイスインターフェース名を生成するようにWindowsに登録しますので、アプリケーションは、このGUIDからデバイスインターフェース名を取得するようにします。

GUIDからデバイスドライバのデバイスインターフェース名を取得する処理の流れを簡単に説明すると、以下のようになります。

GUIDからデバイスドライバのデバイスインターフェース名を取得するには、以下のインクルードファイルとライブラリが必要になります。

追加するインクルード

setupapi.h

追加するライブラリ

setupapi.lib

サンプルコード

GUIDからデバイスドライバのインターフェース名を取得するサンプルコードを以下に示します。

※このコードは『Multi Port Terminal 2』にて実際に使用しているソースコードから抜粋しています。


/****************************************************************************/
/*!
 *  @brief  GUIDからデバイスドライバ名を取得する.
 *
 *  @param  [in]    guid_str    GUID文字列のポインタ.
 *  @param  [in]    drv_name    GUIDから得たドライバ名を格納する領域のポインタ.
 *
 *  @retval TRUE = OK. / FALSE = NG.
 */
BOOL     GetGuidToDeviceName( GUID* guid, LPTSTR drv_name )
{
    HDEVINFO                    hDev;
    SP_INTERFACE_DEVICE_DATA    info;
    BOOL                        result = FALSE;

    //! GUIDが示すクラスのデバイス情報を取得する.
    hDev = SetupDiGetClassDevs( guid, NULL, NULL,
                                   (DIGCF_PRESENT | DIGCF_INTERFACEDEVICE) );

    //! デバイスインターフェースのコンテキスト構造体を取得する.
    info.cbSize = sizeof( SP_INTERFACE_DEVICE_DATA );
    if( SetupDiEnumDeviceInterfaces( hDev, 0, guid, 0, &info ) ){

        PSP_INTERFACE_DEVICE_DETAIL_DATA    detail;
        DWORD                               size = 0;

        //! デバイスインターフェース詳細情報のメモリサイズを取得する.
        SetupDiGetDeviceInterfaceDetail( hDev, &info, NULL, 0, &size, NULL );

        //! デバイスインターフェース詳細情報の領域を確保する.
        detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc( size );
        if( detail ){
            DWORD   len = 0;
            memset( detail, 0, size );

            //! デバイスインターフェースの詳細情報を読込む.
            detail->cbSize = sizeof( SP_INTERFACE_DEVICE_DETAIL_DATA );
            if( SetupDiGetInterfaceDeviceDetail( hDev, 
                                         &info, detail, size, &len, NULL ) ){
                _tcscpy( drv_name, detail->DevicePath );
                result = TRUE;
            }
            free( detail );
        }
    }
    //! デバイスインフォメーションを破棄する.
    SetupDiDestroyDeviceInfoList( hDev );
    return result;
}
	

GUIDが示すクラスのデバイス情報を取得する

SetupDiGetClassDevs()を呼び出してGUIDが示すクラスのデバイス情報を取得します。


    HDEVINFO SetupDiGetClassDevs(
                         LPGUID ClassGuid,
                         PCTSTR Enumerator,
                         HWND hwndParent,
                         DWORD Flags )
	

引数説明
ClassGuid

インターフェースクラスのGUIDのポインタ。

Enumerator

取得するデバイス名にフィルタは掛けないのでNULLを指定します。

hwndParent

ウィンドウハンドルを指定するのですが、NULLでよいと思います。

Flags

サンプルコードで指定しているフラグは以下のとおりです。
- DIGCF_DEVICEINTERFACE
  ClassGuidで指定されたGUIDに属するデバイスで
  インターフェースを公開しているデバイスを返す。
- DIGCF_PRESENT
  存在するデバイスのみを返す。

SetupDiGetClassDevs()が成功すると戻り値としてデバイス情報セットのハンドルが返ります。

デバイスインターフェースのコンテキスト構造体を取得する

SetupDiEnumDeviceInterfaces()を呼び出してデバイスインターフェースのコンテキスト構造体を取得します。


    BOOL SetupDiEnumDeviceInterfaces(
                        HDEVINFO DeviceInfoSet,
                        PSP_DEVINFO_DATA DeviceInfoData,
                        LPGUID InterfaceClassGuid,
                        DWORD MemberIndex,
                        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData )
	

引数説明
DeviceInfoSet

SetupDiGetClassDevs()で取得したデバイス情報セットのハンドル。

DeviceInfoData

0を指定します。

InterfaceClassGuid

インターフェースクラスのGUIDのポインタ。

MemberIndex

デバイス情報セット内のインターフェイスリストのインデックス番号を指定します。
サンプルコードでは単一のインターフェースしか参照しないので0のみを指定しています。

DeviceInterfaceData

コンテキスト構造体のポインタ。

SetupDiEnumDeviceInterfaces()が成功するとTRUE(0以外)が返ります。

デバイスインターフェースの詳細情報を取得する

SetupDiGetDeviceInterfaceDetail()を呼び出してデバイスインターフェースの詳細情報を取得します。

デバイスインターフェース詳細情報で必要なメモリサイズの取得も本APIで行います。


    BOOL SetupDiGetDeviceInterfaceDetail(
                    HDEVINFO DeviceInfoSet,
                    PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
                    PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
                    DWORD DeviceInterfaceDetailDataSize,
                    PDWORD RequiredSize,
                    PSP_DEVINFO_DATA DeviceInfoData )
	

引数説明
DeviceInfoSet

SetupDiGetClassDevs()で取得したデバイス情報セットのハンドル。

DeviceInterfaceData

SetupDiEnumDeviceInterfaces()で取得したコンテキスト構造体のポインタ。

DeviceInterfaceDetailData

デバイスインターフェースの詳細情報を格納する構造体のポインタ。
デバイスインターフェースの詳細情報を格納する構造体のメモリサイズを取得する場合NULLを指定する。

DeviceInterfaceDetailDataSize

引数 DeviceInterfaceDetailData で指定した構造体のバイト数。
デバイスインターフェースの詳細情報を格納する構造体のメモリサイズを取得する場合0を指定する。

RequiredSize

デバイスインターフェースの詳細情報を格納する構造体のメモリサイズを格納する変数のポインタ。
関数実行後にデバイスインターフェースの詳細情報を格納する構造体のバイト数が格納されます。

DeviceInfoData

使用しないのでNULLを指定します。

SetupDiGetDeviceInterfaceDetail()が成功するとTRUE(0以外)が返ります。

SP_DEVICE_INTERFACE_DETAIL_DATA構造体は以下のとおりです。

メンバ名説明
cbSize構造体のサイズ。
DevicePathデバイスドライバのインターフェース名。

使用したデバイス情報を破棄する

SetupDiGetClassDevs()で取得したデバイス情報をSetupDiDestroyDeviceInfoList()を呼び出して破棄します。


    BOOL SetupDiDestroyDeviceInfoList( HDEVINFO DeviceInfoSet )
	

引数説明
DeviceInfoSet

SetupDiGetClassDevs()で取得したデバイス情報セットのハンドル。

SetupDiDestroyDeviceInfoList()が成功するとTRUE(0以外)が返ります。



商標に関する表示