GetIfTableを利用するとパソコンに認識されている全てのネットワークカードのMACアドレス、役割、接続速度などを調べてることができる。この関数は残念ながらWindows 95はサポートしていないため、動作はWindows 98以降となる。2007年に発売のWindows Vistaでもサポートされている。
このクラスを作るに当たって初めはWindows 95でも動作するように実装を進めたのだが...そうすんなりといかず、NetBIOSやSNMPでも環境によってはMACアドレスが取得できなかったため諦めた。
#pragma once
#include "atlstr.h"
#include "iphlpapi.h"
#pragma comment(lib,"iphlpapi.lib")
class CDnpNetworkInterface
{
_MIB_IFTABLE* _pInfoBuffer;
protected:
// Platform SDK: Internet Protocol Helper
//
// GetIfTable() によるMACアドレスの取得
//
// Windows98以降に対応(Windows 95 非対応!:Windows NT4.0はSP4以降に対応)
//
//※Windows 95はWinSock1を利用する。WinSock2やNetBiosだとNGなこともある
//※Windows VistaからはGetIfTable2も利用可能
//
bool GetNicInformation(void)
{
DWORD ret;
ULONG dwSize;
dwSize = 0;
ret = ::GetIfTable(NULL,&dwSize,TRUE);
if(ret != NO_ERROR && ret != ERROR_INSUFFICIENT_BUFFER)
return false;
if(_pInfoBuffer)
delete (BYTE*)_pInfoBuffer;
_pInfoBuffer = (_MIB_IFTABLE*)new BYTE[dwSize];
if(_pInfoBuffer == NULL)
return false;
ZeroMemory(_pInfoBuffer,dwSize);
ret = ::GetIfTable(_pInfoBuffer,&dwSize,TRUE);
if(ret != NO_ERROR)
{
delete (BYTE*)_pInfoBuffer;
_pInfoBuffer = NULL;
return false;
}
return true;
}
//
// クラス内にNICデータを取得済みかチェック
//
bool IsValidInfo(void)
{
if(_pInfoBuffer)
return true;
//なければ取得する
return GetNicInformation();
}
public:
//
// コンストラクタ
//
CDnpNetworkInterface()
{
_pInfoBuffer = NULL;
}
//
// デストラクタ
//
~CDnpNetworkInterface()
{
if(_pInfoBuffer)
delete (BYTE*)_pInfoBuffer;
}
//
// 検出されたNIC数取得
//
DWORD GetNicCount(void)
{
if(IsValidInfo() == false)
return 0;
return _pInfoBuffer->dwNumEntries;
}
//
// NIC名取得
//
bool GetNicName(DWORD dwIndex,CAtlString* pstrName)
{
if(pstrName == NULL)
return false;
*pstrName = _T("");
if(dwIndex >= GetNicCount())
return false;
*pstrName = (char*)_pInfoBuffer->table[dwIndex].bDescr;
return true;
}
//
// NICのMACアドレス取得
//
bool GetNicMacAddress(DWORD dwIndex,CAtlString* pstrMacAddress,int nFormat=0)
{
if(pstrMacAddress == NULL)
return false;
*pstrMacAddress = _T("");
if(dwIndex >= GetNicCount())
return false;
switch(nFormat)
{
case 1:
pstrMacAddress->Format(_T("%02X %02X %02X %02X %02X %02X")
,_pInfoBuffer->table[dwIndex].bPhysAddr[0]
,_pInfoBuffer->table[dwIndex].bPhysAddr[1]
,_pInfoBuffer->table[dwIndex].bPhysAddr[2]
,_pInfoBuffer->table[dwIndex].bPhysAddr[3]
,_pInfoBuffer->table[dwIndex].bPhysAddr[4]
,_pInfoBuffer->table[dwIndex].bPhysAddr[5]);
break;
case 2:
pstrMacAddress->Format(_T("%02X%02X%02X%02X%02X%02X")
,_pInfoBuffer->table[dwIndex].bPhysAddr[0]
,_pInfoBuffer->table[dwIndex].bPhysAddr[1]
,_pInfoBuffer->table[dwIndex].bPhysAddr[2]
,_pInfoBuffer->table[dwIndex].bPhysAddr[3]
,_pInfoBuffer->table[dwIndex].bPhysAddr[4]
,_pInfoBuffer->table[dwIndex].bPhysAddr[5]);
break;
case 0:
default:
pstrMacAddress->Format(_T("%02X-%02X-%02X-%02X-%02X-%02X")
,_pInfoBuffer->table[dwIndex].bPhysAddr[0]
,_pInfoBuffer->table[dwIndex].bPhysAddr[1]
,_pInfoBuffer->table[dwIndex].bPhysAddr[2]
,_pInfoBuffer->table[dwIndex].bPhysAddr[3]
,_pInfoBuffer->table[dwIndex].bPhysAddr[4]
,_pInfoBuffer->table[dwIndex].bPhysAddr[5]);
break;
}
return true;
}
//
// NICの接続速度取得
//
DWORD GetNicConnectionSpeed(DWORD dwIndex)
{
if(dwIndex >= GetNicCount())
return 0;
return _pInfoBuffer->table[dwIndex].dwSpeed;
}
//
// NICが正常に動いているかチェック(ディスコネクトされていないかなどをチェック)
//
bool IsNicWorking(DWORD dwIndex)
{
if(dwIndex >= GetNicCount())
return false;
return (_pInfoBuffer->table[dwIndex].dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL) ? true : false;
}
};
void Test(void)
{
bool ret;
DWORD i;
DWORD dwSize;
DWORD dwSpeed;
CAtlString strName;
CAtlString strMacAddress;
CAtlString strBuff;
CAtlString strMessage;
CDnpNetworkInterface cDevice;
dwSize = cDevice.GetNicCount();
for(i = 0; i < dwSize; i++)
{
ret = cDevice.GetNicName(i,&strName);
if(ret == false)
continue;
ret = cDevice.GetNicMacAddress(i,&strMacAddress);
if(ret == false)
continue;
dwSpeed = cDevice.GetNicConnectionSpeed(i);
strBuff.Format(_T("概要:%s\nMACアドレス:%s\n接続速度:%dKbps\n"),strName,strMacAddress,dwSpeed/1000);
strMessage += strBuff;
if(cDevice.IsNicWorking(i))
strMessage += _T("動作:正常\n");
else
strMessage += _T("動作:停止中\n");
strMessage += _T("\n");
}
::MessageBox(NULL,strMessage,_T(""),MB_OK);
}
