ネットワークアダプタの情報を取得する方法は幾つかあるようです。 それぞれの方法で、取得できる内容や、場合によって取得できる/できない、等がある かもしれませんので、挙動を確認しやすいように、各APIを呼び出して、そのまま printf 出力するプログラムを作ってみました。
ビルドする際は、 ole32.lib、oleaut32.lib、wbemuuid.lib をリンカに渡してください。
// Copyright Mocchi 2012, 2019 // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) #include <cstring> #include <cstdio> #include <vector> #include <string> #define _WIN32_DCOM #include <windows.h> #include <iphlpapi.h> #include <nb30.h> #include <wbemidl.h> #include <objbase.h> struct BStrContainer{ std::vector<BSTR> ss; BSTR Add(const WCHAR *str){ ss.push_back(::SysAllocString(str)); return ss.back(); } ~BStrContainer(){ for (size_t i = 0; i < ss.size(); ++i){ ::SysFreeString(ss[i]); } ss.clear(); } }; struct ComPtrContainer{ std::vector<IUnknown *> unks; template <typename T> void Add(T *p){ unks.push_back(0); unks.back() = p; } ~ComPtrContainer(){ for (size_t i = 0; i < unks.size(); ++i){ unks[i]->Release(); } unks.clear(); } }; int main(void){ std::printf("****** GetIfTable method *****\n"); HMODULE hMod_iphlpapi = ::LoadLibraryA("iphlpapi.dll"); HMODULE hMod_netapi = ::LoadLibraryA("netapi32.dll"); do{ FARPROC proc = 0; if (hMod_iphlpapi) proc = ::GetProcAddress(hMod_iphlpapi, "GetIfTable"); std::printf("iphlpapi:%p GetIfTable:%p\n", hMod_iphlpapi, proc); if (!proc) break; typedef DWORD (WINAPI *GetIfTableType)(MIB_IFTABLE *pIfTable, ULONG *pdwSize, BOOL bOrder); GetIfTableType GetIfTable_ = reinterpret_cast<GetIfTableType>(proc); DWORD dwSize = sizeof(MIB_IFTABLE); GetIfTable_(0, &dwSize, FALSE); std::printf("size:%u\n", dwSize); std::vector<BYTE> iftablebuf(dwSize); MIB_IFTABLE *iftable = reinterpret_cast<MIB_IFTABLE *>(&iftablebuf[0]); if (GetIfTable_(iftable, &dwSize, FALSE) != NO_ERROR){ std::printf("GetIfTable => Error\n"); break; } std::printf("entries:%d\n", iftable->dwNumEntries); for (int i = 0; i < iftable->dwNumEntries; ++i){ std::printf(" No %d\n", i+1); MIB_IFROW *ifrow = &iftable->table[i]; std::wprintf(L" NIC Name:%s\n", ifrow->wszName); std::string desc(ifrow->bDescr, ifrow->bDescr+ifrow->dwDescrLen); std::printf(" Description:%s\n", desc.c_str()); std::printf(" Type:%u\n", ifrow->dwType); std::printf(" PhysAddr:"); for (int h = 0; h < 6; ++h) std::printf("%02x", ifrow->bPhysAddr[h]); std::printf("\n"); } }while(0); std::printf("****** GetAdaptorsInfo method *****\n"); do{ FARPROC proc = 0; if (hMod_iphlpapi) proc = ::GetProcAddress(hMod_iphlpapi, "GetAdaptersInfo"); std::printf("iphlpapi:%p GetAdaptersInfo:%p\n", hMod_iphlpapi, proc); if (!proc) break; typedef DWORD (WINAPI *GetAdaptersInfoType)(IP_ADAPTER_INFO *pAdapterInfo, ULONG *pOutBufLen); GetAdaptersInfoType GetAdaptersInfo_ = reinterpret_cast<GetAdaptersInfoType>(proc); DWORD dwSize = sizeof(IP_ADAPTER_INFO); GetAdaptersInfo_(0, &dwSize); std::printf("size:%u\n", dwSize); std::vector<BYTE> iaibuf(dwSize); IP_ADAPTER_INFO *iai = reinterpret_cast<IP_ADAPTER_INFO *>(&iaibuf[0]); if (GetAdaptersInfo_(iai, &dwSize) != NO_ERROR){ std::printf("Error GetAdaptersInfo\n"); break; } for (IP_ADAPTER_INFO *iter = iai; iter; iter = iter->Next){ std::printf(" ComboIndex:%d\n", iter->ComboIndex); std::printf(" AdapterName:%s\n", iter->AdapterName); std::printf(" Description:%s\n", iter->Description); std::printf(" Type:%u\n", iter->Type); std::printf(" Address:"); for (int h = 0; h < 6; ++h) std::printf("%02x", iter->Address[h]); std::printf("\n"); } }while(0); std::printf("****** GetNetworkParams method *****\n"); do{ FARPROC proc = 0; if (hMod_iphlpapi) proc = ::GetProcAddress(hMod_iphlpapi, "GetNetworkParams"); std::printf("iphlpapi:%p GetNetworkParams:%p\n", hMod_iphlpapi, proc); if (!proc) break; typedef DWORD (WINAPI *GetNetworkParamsType)(FIXED_INFO *pFixedInfo, ULONG *pOutBufLen); GetNetworkParamsType GetNetworkParams_ = reinterpret_cast<GetNetworkParamsType>(proc); DWORD dwSize = 0; if (GetNetworkParams_(0, &dwSize) != ERROR_BUFFER_OVERFLOW){ std::printf("error GetNetworkParams for getting size\n"); break; } std::vector<BYTE> buf(dwSize); FIXED_INFO *fi = reinterpret_cast<FIXED_INFO *>(&buf[0]); DWORD rc; if (rc = GetNetworkParams_(fi, &dwSize)){ std::printf("error GetNetworkParams for getting data\n"); break; } std::printf("Host Name:%s\n", fi->HostName); std::printf("Domain Name:%s\n", fi->DomainName); for (IP_ADDR_STRING *iter = &fi->DnsServerList; iter; iter = iter->Next){ std::printf(" DNS Servers: %s\n", iter->IpAddress.String); } }while(0); std::printf("****** Netbios NCBASTAT method *****\n"); do{ FARPROC proc = 0; if (hMod_netapi) proc = ::GetProcAddress(hMod_netapi, "Netbios"); std::printf("netapi:%p Netbios:%p\n", hMod_netapi, proc); if (!proc) break; typedef DWORD (WINAPI *NetbiosType)(NCB *ncb); NetbiosType Netbios_ = reinterpret_cast<NetbiosType>(proc); UCHAR rc; NCB ncb; ncb.ncb_command = NCBENUM; LANA_ENUM le; ncb.ncb_buffer = reinterpret_cast<UCHAR *>(&le); ncb.ncb_length = sizeof(le); rc = Netbios_(&ncb); if (rc){ std::printf("error NCBENUM : %d\n", rc); break; } std::printf("ncb entries:%d\n", le.length); for (int i = 0; i < le.length; ++i){ std::printf(" No:%d\n", i); ncb.ncb_command = NCBRESET; ncb.ncb_lana_num = le.lana[i]; rc = Netbios_(&ncb); if (rc){ std::printf(" No:%d NCBRESET failed (%d)\n", i, rc); continue; } ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = le.lana[i]; ::strcpy(reinterpret_cast<char *>(ncb.ncb_callname), "* "); struct { ADAPTER_STATUS as; NAME_BUFFER nb; }AStatItem; ncb.ncb_buffer = reinterpret_cast<UCHAR *>(&AStatItem); ncb.ncb_length = sizeof(AStatItem); rc = Netbios_(&ncb); if (rc){ std::printf(" No:%d NCBASTAT failed (%d)\n", i, rc); continue; } std::wstring name(reinterpret_cast<WCHAR *>(AStatItem.nb.name), reinterpret_cast<WCHAR *>(AStatItem.nb.name)+AStatItem.nb.name_num); std::wprintf(L" Name:%s\n", name.c_str()); std::printf(" Address:"); for (int h = 0; h < 6; ++h) std::printf("%02x", AStatItem.as.adapter_address[h]); std::printf("\n"); } }while(0); std::printf("****** Win32_NetworkAdapterConfiguration method *****\n"); // ... COM の API なので、素の C++ だけで扱うにはちょっと面倒 ... do{ HRESULT rc; ComPtrContainer cpc; BStrContainer bc; ::CoInitializeEx( 0, COINIT_MULTITHREADED ); if (FAILED(rc = ::CoInitializeSecurity(0, -1, 0, 0, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, 0, EOAC_NONE, 0))){ std::printf("CoInitializeSecurity failed (%d)\n", rc); break; } IWbemLocator *wl = 0; if (FAILED(rc = ::CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<VOID **>(&wl)))){ std::printf("CoCreateInstance CLSID_WbemLocator failed (%d)\n", rc); break; } cpc.Add(wl); IWbemServices *ws = 0; if (FAILED(rc = wl->ConnectServer(bc.Add(L"root\\cimv2"), 0, 0, 0, WBEM_FLAG_CONNECT_USE_MAX_WAIT, 0, 0, &ws ))){ std::printf("ConnectServer failed (%d)\n", rc); break; } cpc.unks.push_back(ws); if (FAILED(rc = ::CoSetProxyBlanket(ws, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, 0, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE))){ std::printf("CoSetProxyBlanket failed (%d)\n", rc); break; } IEnumWbemClassObject *ewco; if (FAILED(rc = ws->ExecQuery(L"WQL", L"Select * FROM Win32_NetworkAdapterConfiguration", WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 0, &ewco)) || !ewco){ std::printf("Enum failed (%d)\n", rc); break; } #if 0 if (FAILED(rc = ws->CreateInstanceEnum(L"Win32_NetworkAdapter", WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 0, &ewco)) || !ewco){ std::printf("CreateInstanceEnum failed (%d)\n", rc); break; } #endif IWbemClassObject *obj = 0; ULONG returned = 0; ewco->Reset(); for(int i = 0;; ++i){ ewco->Next(WBEM_INFINITE, 1, &obj, &returned); if (returned == 0) break; std::printf(" No:%d\n", i); VARIANT propval; obj->Get(L"IPAddress", 0, &propval, 0, 0); ::VariantChangeType(&propval, &propval, 0, VT_BSTR); if (propval.vt == VT_BSTR){ std::wprintf(L" IPAddress:%s\n", propval.bstrVal); } else if (propval.vt & (VT_ARRAY | VT_BSTR)){ SAFEARRAY *sa = V_ARRAY(&propval); unsigned int dims = ::SafeArrayGetDim(sa); // dims は常に1 ? std::vector<long> idx(dims); long lb, ub; ::SafeArrayGetLBound(sa, dims, &lb); ::SafeArrayGetUBound(sa, dims, &ub); BSTR *bstr = 0; for (long i = lb; i <= ub; ++i){ idx[dims-1] = i; ::SafeArrayGetElement(sa, &idx[0], &bstr); std::wprintf(L" IPAddress[%d]:%s\n", i, bstr); } } else std::printf(" IPAddress: failed\n"); ::VariantClear(&propval); obj->Get(L"Description", 0, &propval, 0, 0); ::VariantChangeType(&propval, &propval, 0, VT_BSTR); if (propval.vt == VT_BSTR) std::wprintf(L" Description:%s\n", propval.bstrVal); else std::printf(" Description: failed\n"); ::VariantClear(&propval); obj->Get(L"MACAddress", 0, &propval, 0, 0); ::VariantChangeType(&propval, &propval, 0, VT_BSTR); int ma[6] = {0}; if (propval.vt == VT_BSTR){ std::wprintf(L" MACAddress:%s\n", propval.bstrVal); if (std::swscanf(propval.bstrVal, L"%02x:%02x:%02x:%02x:%02x:%02x", &ma[0], &ma[1], &ma[2], &ma[3], &ma[4], &ma[5], &ma[6]) != 6){ std::printf(" convert failed\n"); } } else std::printf(" MACAddress: failed\n"); ::VariantClear(&propval); obj->Release(); } }while(0); }
[PageInfo]
LastUpdate: 2019-03-29 13:34:09, ModifiedBy: mocchi_2012
[Permissions]
view:all, edit:admins, delete/config:admins