デバイスインスタンスパス(デバイスインスタンスID)からIPアドレスやMACアドレスなどの情報を取り出したり、あるいはその逆でデバイスインスタンスパスを得る話です。WMIを使って良ければ、Win32_NetworkAdapterのPnPDeviceIdプロパティで解決ですが、諸般の事情でこれを使いたくない場合の方法です。
Setup APIやCfgMgr APIなどで取り扱われるデバイスインスタンスパスはWindowsに接続されているデバイスを識別する文字列です。一方、ネットワーク関係のAPIでは、各ネットワークインタフェースの識別方法にGUID、LUID、インタフェースインデックスなど複数あります。これらを結び付ける方法が知りたいわけです。
これには、Network Configuration InterfacesのAPIを使います。紹介記事がBindview とINetCfg API | Japan WDK Support Blogにあります。このAPIを使うと、デバイスインスタンスパスとインタフェースGUIDの組み合わせが判明します。
以下、サンプルプログラムです。
#include <iostream> #include <comdef.h> #include <windows.h> #include <netcfgx.h> #include <devguid.h> _COM_SMARTPTR_TYPEDEF(INetCfg, __uuidof(INetCfg)); _COM_SMARTPTR_TYPEDEF(INetCfgClass, __uuidof(INetCfgClass)); _COM_SMARTPTR_TYPEDEF(IEnumNetCfgComponent, __uuidof(IEnumNetCfgComponent)); _COM_SMARTPTR_TYPEDEF(INetCfgComponent, __uuidof(INetCfgComponent)); int main() { std::locale l(std::locale::classic(), "", std::locale::ctype); std::wcout.imbue(l); std::wclog.imbue(l); HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); if (FAILED(hr)) { return static_cast<int>(hr); } { INetCfgPtr nc(CLSID_CNetCfg, nullptr, CLSCTX_INPROC_SERVER); nc->Initialize(nullptr); INetCfgClassPtr ncc; nc->QueryNetCfgClass(&GUID_DEVCLASS_NET, IID_PPV_ARGS(&ncc)); IEnumNetCfgComponentPtr e; ncc->EnumComponents(&e); ULONG fetched; INetCfgComponentPtr component; while (e->Next(1, &component, &fetched) == S_OK) { DWORD characteristics; if (SUCCEEDED(component->GetCharacteristics(&characteristics))) { if ((characteristics & NCF_HIDDEN) != 0) continue; } PWSTR displayName; if (SUCCEEDED(component->GetDisplayName(&displayName))) { std::wcout << displayName << std::endl; CoTaskMemFree(displayName); } PWSTR devNodeId; if (SUCCEEDED(component->GetPnpDevNodeId(&devNodeId))) { std::wcout << '\t' << devNodeId << std::endl; CoTaskMemFree(devNodeId); } GUID guid; if (SUCCEEDED(component->GetInstanceGuid(&guid))) { WCHAR buf[39]; StringFromGUID2(guid, buf, ARRAYSIZE(buf)); std::wcout << '\t' << buf << std::endl; } std::wcout << std::hex << "\tcharacteristics: " << characteristics << std::endl; } nc->Uninitialize(); } CoUninitialize(); } |
このプログラムで出力しているGUIDは、Win32_NetworkAdapter.GUIDと一致します。
また、IP_ADAPTER_ADDRESSES::Luidとは、以下の関数で相互に変換できます。
この2関数はWindows Vistaで追加された関数です。もし、それ以前を対象とする場合はNhpAllocateAndGetInterfaceInfoFromStack関数を使いましょう。こちらでは、インタフェースインデックス (IP_ADAPTER_ADDRESSES::IfIndex)と結び付けられます。
スポンサード リンク |
この記事のカテゴリ
- VC++ ⇒ デバイスインスタンスパスからネットワークインタフェースの情報を引き出す(あるいはその逆)
- Windows ⇒ WinAPI ⇒ デバイス関係のAPI ⇒ デバイスインスタンスパスからネットワークインタフェースの情報を引き出す(あるいはその逆)