デバイスマネージャの特定デバイスのポート番号を取得する

Posted Sat Nov 15 2014

Windows でデバイスマネージャーの特定デバイスのポート番号を取ってくるサンプルです.

最近,CameraLink のカメラを制御するプログラムを作ってます.画像の取り込みは MIL を使って行いますが,カメラのパラメータ設定などは RS-232C 経由で行います.カメラに 232C で接続するにあたり,ボードからポート番号を取得したいと思い下記のプログラムを作りました.

#include <iostream>
#include <string>
#include <vector>

#include <windows.h>
#include <setupapi.h>

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

typedef std::basic_string<TCHAR> tstring;

bool ListDevice(const GUID& guid, std::vector<tstring>& devices)
{
  SP_DEVINFO_DATA devInfoData;
  ZeroMemory(&devInfoData, sizeof(devInfoData));
  devInfoData.cbSize = sizeof(devInfoData);

  int nDevice = 0;
  std::vector<tstring> tmp;
  HDEVINFO hDeviceInfo = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT |
                                             DIGCF_DEVICEINTERFACE);
  while (SetupDiEnumDeviceInfo(hDeviceInfo, nDevice++, &devInfoData)) {

    BYTE friendly_name[300];
    SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData,
                                     SPDRP_FRIENDLYNAME, NULL, friendly_name,
                                     sizeof(friendly_name), NULL);

    tmp.push_back(tstring((TCHAR*)friendly_name));
  }

  SetupDiDestroyDeviceInfoList(hDeviceInfo);

  devices.swap(tmp);

  return true;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
  std::vector<tstring> dev;
  ListDevice(GUID_DEVINTERFACE_COMPORT, dev);

  for (int i = 0; i < dev.size(); i++) {
    MessageBox(NULL, dev[i].c_str(), NULL, IDOK);
    if (dev[i].find(TEXT("Matrox")) != tstring::npos) {
      int start = dev[i].find(TEXT("("));
      int end = dev[i].find(TEXT(")"));

      MessageBox(NULL, dev[i].substr(start + 1, end - (start + 1)).c_str(), NULL, IDOK);

    }
  }

  return 0;
}

引数に渡し GUID を変えることで,デバイスマネージャー上で取ってくる情報を変えることができます.今回はデバイスマネージャー上に表示されるフレンドリー名を取得していますが,取得する情報を変えたい場合には,SetupDiGetDeviceRegistryProperty の第3引数を変えます.

参考