使用C中的GetAdaptersAddresses获取网络适配器时发生访问冲突

时间:2018-10-18 08:30:05

标签: c networking adapter access-violation

我不知道https://docs.microsoft.com/en-us/windows/desktop/api/iphlpapi/nf-iphlpapi-getadaptersaddresses中的代码是否错误,但是当我尝试在我的C项目中使用它时,我一直声名狼藉

  

访问冲突读取位置0xFFFFFFFFFFFFFFFFFF

我尝试增加缓冲区大小,但似乎没有任何解决办法。我认为这是在第一个适配器通过循环之后发生的。

#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <winsock2.h>
#include <iptypes.h>
#include <iphlpapi.h>
#include <windows.h>

#pragma comment(lib, "IPHLPAPI.lib")

#define MALLOC(x)       HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x)         HeapFree(GetProcessHeap(), 0, (x))

FILE* fLog = NULL;

void netinfo() {
    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;

    DWORD dwRetVal = 0;
    ULONG outBufLen = 15000;
    ULONG iter = 0;
    do {
        pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
        if (pAddresses == NULL) {
            fwprintf(fLog, L"MALLOC error");
            break;

            dwRetVal = GetAdaptersAddresses(
                AF_UNSPEC,
                GAA_FLAG_INCLUDE_PREFIX,
                NULL,
                pAddresses,
                &outBufLen
            );

            if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
                FREE(pAddresses);
                pAddresses = NULL;
                fwprintf(fLog, L"GetAdaptersAddresses() error");
            } else {
                break;
            }

            iter++;
        }
    } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));

    wchar_t netAddressLog[256];
    if (dwRetVal == NO_ERROR && pAddresses != NULL) {
        pCurrAddresses = pAddresses;
        while (pCurrAddresses) {
            // this is where the debugger stops !!!
            swprintf(netAddressLog, 256, L"Index: %u", pCurrAddresses->IfIndex);
            fwprintf(fLog, netAddressLog);
            pCurrAddresses = pCurrAddresses->Next;
        }
    } else {
        fwprintf(fLog, L"GetAdaptersAddresses() error");
    }

    if (pAddresses) {
        FREE(pAddresses);
    }
}

int main(int argc, char **argv) {
    errno_t error = _wfopen_s(&fLog, L"log.txt", L"a+");

    netinfo();

    fclose(fLog);
}

因此,当尝试访问pCurrAddresses->IfIndex时,程序将在第一个循环之后失败(在该循环中,它会记录一些奇怪的大数字作为索引)。我正在尝试将经过略微修改的代码与MSDN中的代码进行比较,但我无法弄清楚。

我知道我的代码需要更好的组织,但是现在这是一个障碍

1 个答案:

答案 0 :(得分:1)

while循环块中存在一些问题:

do {
    pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
    if (pAddresses == NULL) {
        fwprintf(fLog, L"MALLOC error");
        break;
        /* a } is missing here*/

        dwRetVal = GetAdaptersAddresses(
            AF_UNSPEC,
            GAA_FLAG_INCLUDE_PREFIX,
            NULL,
            pAddresses,
            &outBufLen
        );

        if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
            FREE(pAddresses);
            pAddresses = NULL;
            fwprintf(fLog, L"GetAdaptersAddresses() error");
        } else {
            break;
        }

        iter++;
    }
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));

正确的正确代码可能是:

do {
    pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
    if (pAddresses == NULL) {
        fwprintf(fLog, L"MALLOC error");
        break;
    }
    dwRetVal = GetAdaptersAddresses(
        AF_UNSPEC,
        GAA_FLAG_INCLUDE_PREFIX,
        NULL,
        pAddresses,
        &outBufLen
    );

    if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
        FREE(pAddresses);
        pAddresses = NULL;
        fwprintf(fLog, L"GetAdaptersAddresses() error");
    } else {
        break;
    }

    iter++;        
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));