WindowsドライバーSetupDiシリーズの機能
Windows Driver Setupdi Series Functions
記事のディレクトリ
- 機器情報管理のためのSetupDiシリーズ機能
1. SetupDiGetClassDevs
1.1デバイス情報を列挙する
HDEVINFO SetupDiGetClassDevs( _In_opt_ const GUID *ClassGuid, _In_opt_ PCTSTR Enumerator, _In_opt_ HWND hwndParent, _In_ DWORD Flags )
SetupDiGetClassDevs
指定したカテゴリまたはすべてのカテゴリにインストールされているすべてのデバイスに関する情報を取得します。
1.2パラメータの説明
ClassGuid
:特定のカテゴリGUIDへのポインタ(レジストリにクエリを実行する必要があります)。setDIGCF_ALLCLASSES
Markの場合、このパラメータは無視され、すべてのタイプの機器情報テーブルが返されます( ここでのGUIDには、デバイスインストールクラスのGUIDとデバイスインターフェイスクラスのGUIDがあります。 )。
Enumerator
:列挙されたコンテンツをフィルタリングします。例:PCIはPCIデバイスのみを表示します。
hwndParent
:コレクションメンバーのユーザーインターフェイスを関連付けるために使用されるトップレベルウィンドウのハンドル
Flags
:デバイス情報テーブルを確立するための制御オプションは、次の値にすることができます
DIGCF_ALLCLASSES
最も広い範囲:すべてのデバイスクラスまたはインターフェイスクラスをサポートするデバイスDIGCF_DEVICEINTERFACE
:デバイスインターフェイスクラスをサポートするデバイスのみを含めるDIGCF_DEFAULT
:デフォルトのインターフェースクラスをサポートするデバイスのみを含めるDIGCF_PRESENT
:現在接続されているデバイスDIGCF_PROFILE
:ハードウェアプロファイル内のデバイスは、ハードウェアプロファイル内にあるデバイスに応じて、レジストリキーに移動しますHKLM/SYSTEM/CurrentControlSet/Hardware Profiles/Current/System/CurrentControlSet
表示します。
1.3戻り値
成功すると、指定されたパラメーターに一致する、インストールされているすべてのデバイス情報を含むハンドルが返されます。
失敗した場合は戻るINVALID_HANDLE_VALUE
1.4原則
主にfrom HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnum
(インターフェースクラスの場合はpass HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlDeviceClasses
Get)すべての情報を列挙し、次にget ClassGUID
を実行し、この値に基づいてパラメーターをフィルター処理します。その中で、ここでは主にさまざまなフラグに基づいており、次にさまざまなレジストリを列挙します。
FlagsがDIGCF_DEVICEINTERFACE
から開始HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlDeviceClasses
関連情報を読み取るように指定されている場合のみ。
結果をフィルタリングした後、結果をグローバルリンクリストDeviceInfoSet
Inに入れます。これは、後続の関数トラバーサル用に提供されます。
2つのカテゴリをトラバースできます。
- デバイスセットアップクラス制御オプション
- デバイスインターフェイスクラス制御オプション。
この関数によって返される結果情報は次のとおりです。
その中にDeviceInfoSet /* HDEVINFO */
構造は次のとおりで、次のようにLIST_ENTRY ListHead
リンクDeviceInfo
があります。
struct DeviceInfoSet /* HDEVINFO */ { DWORD magic /* SETUP_DEVICE_INFO_SET_MAGIC */ GUID ClassGuid HKEY HKLM HMACHINE hMachine SP_DEVINSTALL_PARAMS_W InstallParams LIST_ENTRY DriverListHead LIST_ENTRY ListHead //DeviceInfo struct DeviceInfo *SelectedDevice struct ClassInstallParams ClassInstallParams HMODULE hmodClassPropPageProvider PVOID pClassPropPageProvider PCWSTR MachineName WCHAR szData[ANYSIZE_ARRAY] }
DeviceInfo
構造情報は次のとおりです。
struct DeviceInfo /* Element of DeviceInfoSet.ListHead */ { LIST_ENTRY ListEntry DEVINST dnDevInst struct DeviceInfoSet *set SP_DEVINSTALL_PARAMS_W InstallParams PCWSTR instanceId PCWSTR UniqueId PCWSTR DeviceDescription GUID ClassGuid DWORD CreationFlags LIST_ENTRY DriverListHead /* List of struct DriverInfoElement */ LIST_ENTRY InterfaceListHead /* List of struct DeviceInterface */ struct ClassInstallParams ClassInstallParams HMODULE hmodDevicePropPageProvider PVOID pDevicePropPageProvider WCHAR Data[ANYSIZE_ARRAY] }
DeviceInterface
デバイスインターフェイスの構造情報は次のとおりです。
struct DeviceInterface /* Element of DeviceInfo.InterfaceListHead */ { LIST_ENTRY ListEntry struct DeviceInfo *DeviceInfo GUID InterfaceClassGuid DWORD Flags WCHAR SymbolicLink[ANYSIZE_ARRAY] }
SetupDiGetClassDevs
デバイス情報のコレクションを取得するには、次の2つのインターフェイスを介して同じ目的を達成できます(実際SetupDiGetClassDevs
内部もこの関数を介して達成されます)。
SetupDiCreateDeviceInfoList
:デバイスコレクションを作成します。SetupDiCreateDeviceInfo
:デバイス情報を作成します。
2. SetupDiEnumDeviceInfo
2.1列挙メンバー
BOOL SetupDiEnumDeviceInfo( _In_ HDEVINFO DeviceInfoSet, _In_ DWORD MemberIndex, _Out_ PSP_DEVINFO_DATA DeviceInfoData )
SetupDiEnumDeviceInfo
指定されたデバイス情報コレクションのメンバーを列挙し、データをPSP_DEVINFO_DATA
inに配置します
2.2パラメータの説明
DeviceInfoSet
:デバイス情報のコレクションへのハンドルを提供します
MemberIndex
:取得するデバイス情報のメンバーシリアル番号を0から指定してください。
DeviceInfoData
:direction SP_DEVINFO_DATA
構造体へのポインター、指定されたメンバーに関する戻り情報が構造体に配置されます
typedef struct _SP_DEVINFO_DATA { DWORD cbSize GUID ClassGuid DWORD DevInst ULONG_PTR Reserved } SP_DEVINFO_DATA, *PSP_DEVINFO_DATA
2.3戻り値
成功した場合はTrueを返し、そうでない場合はFalseを返します。
すべてのデバイス情報メンバーを列挙する場合、ローダーは最初にMemberIndex
呼び出しに0に設定SetupDiEnumDeviceInfo
、次にインクリメントMemberIndex
(forループを使用)、呼び出しSetupDiEnumDeviceInfo
すべてのメンバーがトラバースされるまで(この時点で関数はFalseを返し、GetLastError
return ERROR_NO_MORE_ITEMS
)。
2.4原則
列挙DeviceInfoSet
リンクリスト内の要素。
3.SetupDiEnumDeviceInterfaces
3.1列挙型インターフェース
上記の関数は、「デバイス情報コレクション」内のデバイスを列挙するために使用されます。これに対応して、コレクション内のデバイスインターフェイスを列挙する機能があります。
WINSETUPAPI BOOL WINAPI SetupDiEnumDeviceInterfaces( IN HDEVINFO DeviceInfoSet, // Device information collection IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL// Device member IN LPGUID InterfaceClassGuid, // Interface GUID IN DWORD MemberIndex, // Index of the interface in the collection OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData// Returned interface information )
DeviceInfoSet
「デバイス情報収集」変数、つまりSetupDiGetClassDevs
呼び出しの戻り値です。
DeviceInfoData
値を設定する人はほとんどいませんが、この値を設定すると、コレクション内のDeviceInfoDataに含まれているデバイスインターフェイスクラスのみが関数の列挙中に列挙されます。たとえば、DeviceInfoData
表示されるデバイスは、GUID1とGUID2の2つのデバイスインターフェイスクラスをサポートし、関数は、他のデバイスに関係なく、コレクション内のこれら2つのデバイスインターフェイスのみを検索します。
この関数はデバイスインターフェイスを取得するために使用され、同じデバイス内の一連の設定には複数のデバイスインターフェイスクラスを含めることができるため、 パラメータInterfaceClassGuid
デバイスインターフェイスGUIDを設定するために使用 。
MemberIndex
意味は以前と同じです。呼び出しの初期値を0に設定し、MemberIndex値が設定範囲を超えるまで呼び出しを繰り返して、SetupDiEnumDeviceInterfaces
FALSEを返して増分ループを終了する必要があります。
DeviceInterfaceData
デバイスインターフェイス情報はに返されます。
typedef struct _SP_DEVICE_INTERFACE_DATA { DWORD cbSize GUID InterfaceClassGuid DWORD Flags ULONG_PTR Reserved } SP_DEVICE_INTERFACE_DATA, *PSP_DEVICE_INTERFACE_DATA
3.2インターフェースデータの取得
BOOL SetupDiGetDeviceInterfaceDetail( _In_ HDEVINFO DeviceInfoSet, _In_ PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, _Out_opt_ PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, _In_ DWORD DeviceInterfaceDetailDataSize, _Out_opt_ PDWORD RequiredSize, _Out_opt_ PSP_DEVINFO_DATA DeviceInfoData ) typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA { DWORD cbSize TCHAR DevicePath[ANYSIZE_ARRAY] } SP_DEVICE_INTERFACE_DETAIL_DATA, *PSP_DEVICE_INTERFACE_DETAIL_DATA
4. SetupDiGetDeviceRegistryProperty
4.1デバイスのプロパティ
BOOL SetupDiGetDeviceRegistryProperty( _In_ HDEVINFO DeviceInfoSet, _In_ PSP_DEVINFO_DATA DeviceInfoData, _In_ DWORD Property, _Out_opt_ PDWORD PropertyRegDataType, _Out_opt_ PBYTE PropertyBuffer, _In_ DWORD PropertyBufferSize, _Out_opt_ PDWORD RequiredSize )
SetupDiGetDeviceRegistryProperty
:この関数は、指定されたプラグアンドプレイデバイスの特性を取得するために使用されます(この関数は、主にSystem CurrentControlSet Enumレジストリを使用して関連するハードウェア情報を照会します)
4.2パラメータの説明
DeviceInfoSet
:デバイス情報ハンドル。
DeviceInfoData
:SP_DEVINFO_DATA
構造、含むDeviceInfoSet
デバイス情報
Property
次の値を取ります。
SPDRP_ADDRESS
:デバイスのアドレスを照会しますSPDRP_BUSNUMBER
:デバイスのバス番号を照会しますSPDRP_BUSTYPEGUID
:デバイスのGUID番号を照会します- ……
4.3備考
この機能の主な原則は、レジストリからPnPデバイスの属性を読み取ることです。
5. SetupDiDestroyDeviceInfoList
5.1破壊
SetupDiDestroyDeviceInfoList
デバイス情報のコレクションを破棄し、関連するすべてのメモリを解放します
BOOL SetupDiDestroyDeviceInfoList( HDEVINFO DeviceInfoSet )
5.2パラメータ
DeviceInfoSet
:リリースされるデバイス情報ハンドル
5.3戻り値
成功した場合はゼロ以外を返し、それ以外の場合はゼロを返します
6.全体の原則
- レジストリ
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlClass{4d36e97d-e325-11ce-bfc1-08002be10318}
デバイスインストールクラスの列挙情報を取得します。 - インスタンスを介してインスタンスIDを取得します。
- 入手
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnum
以下の機器関連情報。 HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlClass
:現在のデバイスタイプを表す、デバイスインストールカテゴリのGUIDです。HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlDeviceClasses
:デバイスインターフェイスGUID- レジストリを介して
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlDeviceClasses
デバイスインターフェイスの列挙情報を取得します。
6.1デバイスインターフェイスクラス
あらゆる種類のドライバーは、ユーザーまたは他のユーザーに特定の種類の名前を提供する必要があります。また、ユーザーはこの名前を使用して、さまざまなデバイスを区別し、それらを使用してIOを実行します。
Windows NT 4.0以前のバージョンでは、 ドライバは、デバイスオブジェクトの名前を作成し、そのデバイスコネクタを作成して、システムに登録します。 。
Windows 2000以降、ドライバはデバイスオブジェクトに名前を付けなくなりましたが、デバイスインターフェイスクラスを使用します。 デバイスインターフェイスクラスは、ユーザーにデバイスおよびドライバー機能へのアクセスを提供できます。ドライバーはデバイスインターフェイスクラスを登録し、デバイスオブジェクトのデバイスインターフェイスクラスのインスタンスを作成します 。
各デバイスインターフェイスクラスにはGUIDがあります。システムは、共通のデバイスクラスとそのGUIDをデバイス固有のヘッダーファイルで定義します。ただし、デバイス開発者はデバイスクラスをカスタマイズできます。
たとえば、3つの異なるタイプのマウスは、それぞれUSBポート、シリアルポート、および赤外線ポートを使用している場合でも、同じデバイスインターフェイスクラスに属することができます。彼らのドライバーは彼をGUID_DEVINTERFACE_MOUSE
デバイスインターフェイスクラスとして登録しました。このデバイスインターフェイスクラスのGUIDは、Ntddmou.hで定義されています。
特に、これらのドライバーは1つのデバイスクラスのみを登録します。ただし、さまざまなデバイスのドライバには、標準のインターフェイスクラス以外のインターフェイスクラスを登録するための特別な機能があります。たとえば、インストール可能なディスクドライバを登録する必要があります(GUID_DEVINTERFACE_DISK
)インターフェイスクラスおよび(MOUNTDEV_MOUNTED_DEVICE_GUID
)インストール可能な機器カテゴリ。
ドライバーがデバイスインターフェイスのインスタンスを登録すると、IOマネージャーはデバイスのGUIDとシンボリックリンク名をデバイスインターフェイスに関連付けます。シンボリックリンク名はレジストリに保存され、システムの起動時に存在します。ユーザーは、このインターフェイスにクエリを実行して、このインターフェイスをサポートするデバイスのシンボリックリンク名を取得できます。ユーザーは、このシンボリックリンク名を使用して、デバイスでIOを実行できます。
6.2機器の設置
デバイスのインストールを容易にするために、同じインストール方法のデバイスは同じデバイスインストールカテゴリに分類されます。たとえば、SCSIメディア変換デバイスは、MediumChangerデバイスセットアップクラスに分類されます。デバイスインストールクラスは、デバイスインストールプロセス中のデバイスインストールを定義します。プログラムとその関連プログラムで使用されるクラス。
Microsoftは、ほとんどのデバイスの標準機器インストールクラスを定義しています。デバイス開発者は機器の設置クラスをカスタマイズできますが、標準の機器の設置クラスを使用できない場合に備えておく必要があります。
各デバイスインストールクラスにはGUIDがあり、システムはDevguid.hで各デバイスインストールクラスのGUIDを提供し、対応するシンボリックリンク名を提供します。
機器設置クラスは、独自の機器用に定義されています..CurrentControlSetControlClassClassGuid
次のサブキー。
開発者は、INFファイルを使用して新しいデバイスインストールクラスを作成できます。
6.3デバイスインターフェースクラスの登録
NTSTATUS IoRegisterDeviceInterface( IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName )
InterfaceClassGuid
これはインターフェースクラスのGUIDを指定します。新しいGUIDが指定されると、次のように、デバイスインターフェイスクラスレジストリに新しいエントリが生成されます。
DEFINE_GUID(IOM_RING_INTERFACE, 0xfdcac3d6, 0xe85f, 0x4f22, 0xa2, 0x3c, 0x75, 0xe2, 0xbd, 0xef, 0x7f, 0x62) nStatus = IoRegisterDeviceInterface(PhysicalDeviceObject, &IOM_RING_INTERFACE, NULL, &pDeviceExtension->InterfaceName)
次に、生成されたレジストリキーはHKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlDeviceClasses{fdcac3d6-e85f-4f22-a23c-75e2bdef7f62}
です。
7.例
仕事用に開くことができるUSBのデバイスインターフェイスを照会するコードは次のとおりです。
DEFINE_GUID (UsbClassGuid, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed) int _tmain(int argc, _TCHAR* argv[]) { HDEVINFO hDevInfo SP_DEVICE_INTERFACE_DATA spDevData PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail BOOL bRes = TRUE int nCount = 0 hDevInfo = ::SetupDiGetClassDevs(NULL,NULL,NULL,DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE | DIGCF_PRESENT) if (hDevInfo != INVALID_HANDLE_VALUE) { pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT,1024) pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) while (bRes) { spDevData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA) bRes = ::SetupDiEnumDeviceInterfaces(hDevInfo,NULL,(LPGUID)&UsbClassGuid,nCount,&spDevData) if (bRes) { bRes = ::SetupDiGetInterfaceDeviceDetail(hDevInfo,&spDevData,pDetail,1024,NULL,NULL) if (bRes) { wcout << L'success : ' << pDetail->DevicePath << endl nCount ++ } } } ::GlobalFree(pDetail) ::SetupDiDestroyDeviceInfoList(hDevInfo) } return 0 }
このコードの戻り結果は次のとおりです。
success : \?usb#vid_24ae&pid_1813#5&262ed807&1&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed} success : \?usb#vid_0bda&pid_58dd#200901010001#{a5dcbf10-6530-11d2-901f-00c04fb951ed}