GUIDからデバイスドライバのデバイスインターフェース名を取得する
Windowsのアプリケーションでデバイスドライバを利用する場合、シリアルポートなどは"¥¥.¥COM1"のようにデバイス名の頭に"¥¥.¥"を付けてCreateFile()でオープンすればデバイスドライバが利用できるのですが、USBポートなどは"¥¥.¥USB1"のようにしても基本的にはオープンできません。
(該当のデバイスドライバが"USB1"のようなシンボリック名を登録していれば出来るのですが、通常のデバイスドライバではシンボリック名の登録は行わないようです。)
では、どのようにしてドライバのインターフェース名を取得するかと言うと、デバイスドライバではデバイスドライバが独自に割り付けたGUIDからデバイスインターフェース名を生成するようにWindowsに登録しますので、アプリケーションは、このGUIDからデバイスインターフェース名を取得するようにします。
GUIDからデバイスドライバのデバイスインターフェース名を取得する処理の流れを簡単に説明すると、以下のようになります。
- GUIDが示すクラスのデバイス情報を取得します。
- デバイスインターフェースのコンテキスト構造体を取得します。
- デバイスインターフェース詳細情報のメモリサイズを取得します。
- デバイスインターフェース詳細情報の領域を確保します。
- デバイスインターフェースの詳細情報を取得します。
- (4)で確保したデバイスインターフェース詳細情報の領域を解放します。
- (1)で取得したデバイス情報を破棄します。
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;
}
SetupDiGetClassDevs()を呼び出してGUIDが示すクラスのデバイス情報を取得します。
HDEVINFO SetupDiGetClassDevs(
LPGUID ClassGuid,
PCTSTR Enumerator,
HWND hwndParent,
DWORD Flags )
引数 | 説明 |
---|---|
ClassGuid | インターフェースクラスのGUIDのポインタ。 |
Enumerator | 取得するデバイス名にフィルタは掛けないのでNULLを指定します。 |
hwndParent | ウィンドウハンドルを指定するのですが、NULLでよいと思います。 |
Flags |
サンプルコードで指定しているフラグは以下のとおりです。 |
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 |
デバイス情報セット内のインターフェイスリストのインデックス番号を指定します。 |
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 |
デバイスインターフェースの詳細情報を格納する構造体のポインタ。 |
DeviceInterfaceDetailDataSize |
引数 DeviceInterfaceDetailData で指定した構造体のバイト数。 |
RequiredSize |
デバイスインターフェースの詳細情報を格納する構造体のメモリサイズを格納する変数のポインタ。 |
DeviceInfoData | 使用しないのでNULLを指定します。 |
SetupDiGetDeviceInterfaceDetail()が成功するとTRUE(0以外)が返ります。
SP_DEVICE_INTERFACE_DETAIL_DATA構造体は以下のとおりです。
メンバ名 | 説明 |
---|---|
cbSize | 構造体のサイズ。 |
DevicePath | デバイスドライバのインターフェース名。 |
SetupDiGetClassDevs()で取得したデバイス情報をSetupDiDestroyDeviceInfoList()を呼び出して破棄します。
BOOL SetupDiDestroyDeviceInfoList( HDEVINFO DeviceInfoSet )
引数 | 説明 |
---|---|
DeviceInfoSet | SetupDiGetClassDevs()で取得したデバイス情報セットのハンドル。 |
SetupDiDestroyDeviceInfoList()が成功するとTRUE(0以外)が返ります。