MIBインターフェーステーブルの取得

(2004.03.25)
#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;
};
一覧に戻る
© 2003 WAC.com All Right Reserved.