#pragma once
#include <new>
#include <Iphlpapi.h>
#pragma comment(lib, "Iphlpapi.lib")
/////////////////////////////////////////////////////////////////////////////
// CAdaptersInfo
class CAdaptersInfo
{
public:
CAdaptersInfo()
{
m_nBytes = 0;
m_pInfo = NULL;
}
~CAdaptersInfo()
{
delete[] (char*) m_pInfo;
}
public:
HRESULT Fetch()
{
HRESULT hr = S_OK;
restart:
ULONG nBytes = m_nBytes;
DWORD dwResult = ::GetAdaptersInfo(m_pInfo, &nBytes);
switch (dwResult)
{
case NO_ERROR:
return S_OK;
case ERROR_BUFFER_OVERFLOW:
{
hr = Realloc(nBytes);
if (SUCCEEDED(hr))
{
goto restart;
}
return hr;
}
default:
return E_FAIL;
}
}
public:
const PIP_ADAPTER_INFO FindByIfIndex(DWORD dwIfIndex) const
{
for (PIP_ADAPTER_INFO pInfo = m_pInfo;
pInfo != NULL; pInfo = pInfo->Next)
{
if (pInfo->Index == dwIfIndex)
{
return pInfo;
}
}
return NULL;
}
const PIP_ADAPTER_INFO FindByAddr(IPAddr addr) const
{
DWORD dwIfIndex = 0;
if (::GetBestInterface(addr, &dwIfIndex) == NO_ERROR)
{
return FindByIfIndex(dwIfIndex);
}
return NULL;
}
private:
HRESULT Realloc(ULONG nBytes)
{
try
{
delete[] (char*) m_pInfo;
m_pInfo = (PIP_ADAPTER_INFO) new char[nBytes];
m_nBytes = nBytes;
}
catch (std::bad_alloc&)
{
return E_OUTOFMEMORY;
}
catch (...)
{
return E_FAIL;
}
return S_OK;
}
private:
ULONG m_nBytes;
PIP_ADAPTER_INFO m_pInfo;
};