Edited at

Win32 Setup APIでシステムに存在するデバイスのクラス・インターフェイスのクラスと説明を列挙する

More than 5 years have passed since last update.

VC上でWin32 Setup APIでシステムに存在するデバイスのクラス・インターフェイスのクラスと説明を列挙するコードの覚書です。main関数内ではメモリ管理や例外処理を怠っているので注意して下さい。


単純に列挙する

#pragma comment(lib, "SetupAPI.lib")


#define STRICT
#include <Windows.h>
#include <SetupAPI.h>
#define INITGUID
#include <devpkey.h>
#undef INITGUID

// デバイスの文字列型プロパティをヒープに確保して返します。
LPTSTR HeapAllocDevicePropertyString(
HANDLE HeapHandle,
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
const DEVPROPKEY* PropertyKey,
DEVPROPTYPE* PropertyType,
PDWORD CopiedSize,
DWORD Flags)
{
DEVPROPTYPE PropType;
DWORD Size;
if (!SetupDiGetDeviceProperty(
DeviceInfoSet,
DeviceInfoData,
PropertyKey,
&PropType,
nullptr, 0,
&Size,
0) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
if (PropertyType != nullptr) {
*PropertyType = DEVPROP_TYPE_NULL;
}
if (CopiedSize != nullptr) {
*CopiedSize = 0;
}
return nullptr;
}
if (PropertyType != nullptr) {
*PropertyType = PropType;
}
if (CopiedSize != nullptr) {
*CopiedSize = Size;
}
if (PropType != DEVPROP_TYPE_STRING) {
return nullptr;
}
LPTSTR buffer = (LPTSTR)HeapAlloc(HeapHandle, 0, Size);
if (!SetupDiGetDeviceProperty(
DeviceInfoSet,
DeviceInfoData,
PropertyKey,
&PropType,
(PBYTE)buffer, Size,
&Size,
0))
{
HeapFree(HeapHandle, 0, buffer);
return nullptr;
}
return buffer;
}

#include <iostream>

#if defined(UNICODE) || defined(_UNICODE)
#define tcout std::wcout
#else
#define tcout std::cout
#endif

void main()
{
// std::wcoutの日本語文字化けを回避
std::wcout.imbue(std::locale("Japanese", std::locale::ctype));

// 現在システムに存在する全てのクラス・インターフェイスを列挙
tcout << TEXT("DIGCF_ALLCLASSES | DIGCF_PRESENT") << std::endl;
HDEVINFO DevInfoHandle = SetupDiGetClassDevs(
nullptr, nullptr, nullptr,
DIGCF_ALLCLASSES | DIGCF_PRESENT);
SP_DEVINFO_DATA DevInfoData = {sizeof SP_DEVINFO_DATA};
for (DWORD i = 0; SetupDiEnumDeviceInfo(DevInfoHandle, i, &DevInfoData); i++)
{
LPTSTR ClassName = HeapAllocDevicePropertyString(
GetProcessHeap(),
DevInfoHandle,
&DevInfoData,
&DEVPKEY_Device_Class,
nullptr,
nullptr,
0);
LPTSTR DeviceDesc = HeapAllocDevicePropertyString(
GetProcessHeap(),
DevInfoHandle,
&DevInfoData,
&DEVPKEY_Device_DeviceDesc,
nullptr,
nullptr,
0);
tcout
<< (ClassName ? ClassName : TEXT(""))
<< TEXT(" - ")
<< (DeviceDesc ? DeviceDesc : TEXT(""))
<< std::endl;
HeapFree(GetProcessHeap(), 0, DeviceDesc);
HeapFree(GetProcessHeap(), 0, ClassName);
}
SetupDiDestroyDeviceInfoList(DevInfoHandle);
}


出力結果の一部

LegacyDriver - cpudrv64

System - ACPI 電源ボタン
USB - Generic USB Hub
LegacyDriver - pciide
Net - Realtek RTL8188CE Wireless LAN 802.11n PCI-E NIC
System - Intel(R) 7 Series/C216 Chipset Family PCI Express Root Port 2 - 1E12
CDROM - CD-ROM ドライブ
System - ACPI Lid
Processor - Intel Processor
Volume - 汎用ボリューム
System - Microsoft System Management BIOS Driver
LegacyDriver - Performance Counters for Windows Driver
LegacyDriver - Ancillary Function Driver for Winsock
Net - Microsoft Virtual WiFi Miniport Adapter
LegacyDriver - msahci
System - Microsoft Windows Management Interface for ACPI
Net - WAN Miniport (IKEv2)
LegacyDriver - PEAUTH
LegacyDriver - IDE Channel
LegacyDriver - System Attribute Cache
System - ACPI 温度管理ゾーン
Net - Qualcomm Atheros AR8162/8166/8168 PCI-E Fast Ethernet Controller (NDIS 6.2
0)
System - High Definition Audio コントローラー
Net - WAN ミニポート (L2TP)


分類して列挙する

#pragma comment(lib, "SetupAPI.lib")


#define STRICT
#include <Windows.h>
#include <SetupAPI.h>
#define INITGUID
#include <devpkey.h>
#undef INITGUID

// デバイスの文字列型プロパティをヒープに確保して返します。
LPTSTR HeapAllocDevicePropertyString(
HANDLE HeapHandle,
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
const DEVPROPKEY* PropertyKey,
DEVPROPTYPE* PropertyType,
PDWORD CopiedSize,
DWORD Flags)
{
DEVPROPTYPE PropType;
DWORD Size;
if (!SetupDiGetDeviceProperty(
DeviceInfoSet,
DeviceInfoData,
PropertyKey,
&PropType,
nullptr, 0,
&Size,
0) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
if (PropertyType != nullptr) {
*PropertyType = DEVPROP_TYPE_NULL;
}
if (CopiedSize != nullptr) {
*CopiedSize = 0;
}
return nullptr;
}
if (PropertyType != nullptr) {
*PropertyType = PropType;
}
if (CopiedSize != nullptr) {
*CopiedSize = Size;
}
if (PropType != DEVPROP_TYPE_STRING) {
return nullptr;
}
LPTSTR buffer = (LPTSTR)HeapAlloc(HeapHandle, 0, Size);
if (!SetupDiGetDeviceProperty(
DeviceInfoSet,
DeviceInfoData,
PropertyKey,
&PropType,
(PBYTE)buffer, Size,
&Size,
0))
{
HeapFree(HeapHandle, 0, buffer);
return nullptr;
}
return buffer;
}

#include <iostream>
#include <map>
#include <vector>

#if defined(UNICODE) || defined(_UNICODE)
#define tcout std::wcout
#else
#define tcout std::cout
#endif

typedef std::basic_string<TCHAR> tstring;

void main()
{
// std::wcoutの日本語文字化けを回避
std::wcout.imbue(std::locale("Japanese", std::locale::ctype));

// 現在システムに存在する全てのクラス・インターフェイスを列挙
// クラス毎に説明をまとめる
tcout << TEXT("DIGCF_ALLCLASSES | DIGCF_PRESENT") << std::endl;
HDEVINFO DevInfoHandle = SetupDiGetClassDevs(
nullptr, nullptr, nullptr,
DIGCF_ALLCLASSES | DIGCF_PRESENT);
SP_DEVINFO_DATA DevInfoData = {sizeof SP_DEVINFO_DATA};
std::map<tstring, std::vector<tstring>> ClassDescMap;
for (DWORD i = 0; SetupDiEnumDeviceInfo(DevInfoHandle, i, &DevInfoData); i++)
{
LPTSTR ClassName = HeapAllocDevicePropertyString(
GetProcessHeap(),
DevInfoHandle,
&DevInfoData,
&DEVPKEY_Device_Class,
nullptr,
nullptr,
0);
LPTSTR DeviceDesc = HeapAllocDevicePropertyString(
GetProcessHeap(),
DevInfoHandle,
&DevInfoData,
&DEVPKEY_Device_DeviceDesc,
nullptr,
nullptr,
0);
ClassDescMap[ClassName].push_back(DeviceDesc);
HeapFree(GetProcessHeap(), 0, DeviceDesc);
HeapFree(GetProcessHeap(), 0, ClassName);
}
SetupDiDestroyDeviceInfoList(DevInfoHandle);

// 列挙したクラス毎の説明を出力
for (auto ClassDescPair : ClassDescMap)
{
tcout << ClassDescPair.first.c_str() << std::endl;
for (auto Desc : ClassDescPair.second)
{
tcout << "\t" << Desc.c_str() << std::endl;
}
}
}


出力結果の一部

MEDIA

Realtek High Definition Audio
インテル(R) ディスプレイ用オーディオ
Monitor
汎用 PnP モニター
Mouse
Synaptics PS/2 Port TouchPad
Net
WAN ミニポート (SSTP)
Microsoft 6to4 Adapter
Microsoft ISATAP Adapter
Microsoft ISATAP Adapter
Microsoft ISATAP Adapter
Microsoft ISATAP Adapter
Microsoft Teredo Tunneling Adapter
Realtek RTL8188CE Wireless LAN 802.11n PCI-E NIC
Microsoft Virtual WiFi Miniport Adapter
WAN Miniport (IKEv2)
Qualcomm Atheros AR8162/8166/8168 PCI-E Fast Ethernet Controller (NDIS 6
.20)
WAN ミニポート (L2TP)
WAN ミニポート (ネットワーク モニター)
WAN ミニポート (IP)
WAN ミニポート (IPv6)
WAN ミニポート (PPPOE)
WAN ミニポート (PPTP)
Processor
Intel Processor
Intel Processor