ネットワークインターフェース情報の取得(5)

ロジックに一部間違いがあったので、Loopbackインターフェース(MS TCP Loopback interface)にアドレスが表示されていなかった。
これは、アドレスをloadInterfaceInfoメソッド中のループで取得するように組み込んでいたのが間違いで、GetAdaptersInfo()関数ではLoopbackにアダプタが割り当てられていないので、処理をすることが出来なかったことに起因していた。
アドレスを設定するロジックを、loadInterfaceInfo()メソッドではなくgetInterfaceList()メソッドの中で処理させることで、Loopbackインターフェースもアドレス情報を設定することが出来た。
変更点としては、
ifinfo.cppのgetInterfaceList()メソッドを

interface_list IfInfo::getInterfaceList() {
    interface_list if_list;

    DWORD dwSize = 0;
    GetIfTable(NULL, &dwSize, true);
    PMIB_IFTABLE pIfTable = (MIB_IFTABLE *)calloc(dwSize, 1);
    if (pIfTable != NULL) {
        if (GetIfTable(pIfTable, &dwSize, true) == NO_ERROR) {
            for (u_int i = 0; i < pIfTable->dwNumEntries; i++) {
                IfInfo if_table = IfInfo();
                MIB_IFROW pInterface = pIfTable->table[i];
                if_table.ifIndex = pInterface.dwIndex;
                if_table.ifName = if_table.description = String((_TCHAR *)_bstr_t((char *)pInterface.bDescr));
                if_table.ipAddressList = AddrInfo::setAddressList(if_table.ifIndex);
                if_table.ifType = pInterface.dwType;
                if_table.opStatus = pInterface.dwOperStatus;
                if_list.push_back(if_table);
            }
        }
        free(pIfTable);
    }

    return if_list;
}

に変更し、loadInterfaceInfo()メソッドを

void IfInfo::loadInterfaceInfo(IfInfo& if_table) {
    DWORD dwSize = 0;
    GetAdaptersInfo(NULL, &dwSize);
    PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)calloc(dwSize, 1);
    if (pAdapterInfo != NULL) {
        if (GetAdaptersInfo(pAdapterInfo, &dwSize) == ERROR_SUCCESS) {
            PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
            while (pAdapter) {
                if (pAdapter->Index == if_table.ifIndex) {
                    if_table.adapterName = String((_TCHAR *)_bstr_t(pAdapter->AdapterName));
                    if_table.ifAddress = getMacAddress(pAdapter->Address, pAdapter->AddressLength);
                    if_table.dhcpEnabled = pAdapter->DhcpEnabled ? true : false;
                    HKEY hkey = NULL;
                    _bstr_t adapter = _bstr_t(_T("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"));
                    adapter += _bstr_t((char *)pAdapter->AdapterName);
                    adapter += _bstr_t(_T("\\Connection"));
                    int rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (_TCHAR *)adapter, 0, KEY_READ, &hkey);
                    if (rc == ERROR_SUCCESS) {
                        DWORD valueType = 0;
                        DWORD nameLen = 0;
                        rc = RegQueryValueEx(hkey, _T("Name"), 0, &valueType, NULL, &nameLen);
                        _TCHAR *buff = (_TCHAR *)calloc(nameLen+1, sizeof(char));
                        rc = RegQueryValueEx(hkey, _T("Name"), 0, &valueType, (LPBYTE)buff, &nameLen);
                        if_table.ifName = String(buff);
                        RegCloseKey(hkey);
                        free(buff);
                    }
                }
                pAdapter = pAdapter->Next;
            }
            free(pAdapterInfo);
        }
    }
}

に変更した。


余談ですが、WMIの時にはAPIについて色々と説明がつけられていたのに、ネットワークインターフェース情報の取得にはあまり説明のコメントがないと思っておられる方もいるかと思いますが、ある程度形になってきた時点で、きちんとしたソースコードをダウンロードできるように整理したいと思っているので、その時にはコメント付きにしたいと思ってます。