potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

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

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