#pragma once
#include <Iphlpapi.h>
#pragma comment(lib, "Iphlpapi.lib")
////////////////////////////////////////////////////////////////////////////////
// CIfTable
class CIfTable
{
public:
CIfTable()
{
m_nBytes = 0;
m_pIfTable = NULL;
}
~CIfTable()
{
delete[] (char*) m_pIfTable;
}
public:
int GetCount() const
{
return (m_pIfTable != NULL) ? m_pIfTable->dwNumEntries : 0;
}
const MIB_IFROW& operator [] (int n) const
{
ATLASSERT(m_pIfTable != NULL);
ATLASSERT(IsValidIndex(n));
return m_pIfTable->table[n];
}
public:
HRESULT Refresh(bool bOrder = true)
{
HRESULT hr = S_OK;
restart:
ULONG nBytes = m_nBytes;
DWORD dwResult = ::GetIfTable(m_pIfTable, &nBytes, bOrder);
switch (dwResult)
{
case NO_ERROR:
return S_OK;
case ERROR_INSUFFICIENT_BUFFER:
{
hr = Realloc(nBytes);
if (SUCCEEDED(hr))
{
goto restart;
}
return hr;
}
default:
return E_FAIL;
}
}
// Helper functions
public:
// MIB_IFROW の bDesc を CString に入れて返す。
// bDesc は '\0' で終わっているとは限らないので、
// このような処理が必要。
static CString GetIfLabel(const MIB_IFROW& rIf)
{
CString strIfDesc;
int len = rIf.dwDescrLen;
::strncpy(strIfDesc.GetBuffer(len), (const char*) rIf.bDescr, len);
strIfDesc.ReleaseBuffer(len);
return strIfDesc;
}
// MIB_IFROW の dwIndex の下16ビットを返す。
// 実際には dwIndex がインターフェイス毎にユニークな値だが、
// これは切断/接続で上位16ビットが変化してしまう。
// なので、変化する部分をマスクした値を識別用に使うことにする。
// 実際にこれで切断/接続をはさんでも識別可能だが、
// 公式な方法ではないのでどうなの??
static DWORD GetIfID(DWORD dwIndex)
{
return dwIndex & 0x0000FFFF;
}
static DWORD GetIfID(const MIB_IFROW& rIf)
{
return GetIfID(rIf.dwIndex);
}
private:
bool IsValidIndex(int n) const
{
return (0 <= n && n < (int) m_pIfTable->dwNumEntries);
}
HRESULT Realloc(ULONG nBytes)
{
try
{
delete[] (char*) m_pIfTable;
m_pIfTable = (MIB_IFTABLE*) new char[nBytes];
m_nBytes = nBytes;
}
catch (std::bad_alloc&)
{
return E_OUTOFMEMORY;
}
catch (...)
{
return E_FAIL;
}
return S_OK;
}
private:
ULONG m_nBytes;
MIB_IFTABLE* m_pIfTable;
};