Нарушение доступа при получении сетевых адаптеров с GetAdaptersAddresses в C - PullRequest
0 голосов
/ 18 октября 2018

Я не знаю, является ли код из https://docs.microsoft.com/en-us/windows/desktop/api/iphlpapi/nf-iphlpapi-getadaptersaddresses неправильным, но когда я пытаюсь использовать его в своем C-проекте, я получаю печально известное

Место чтения нарушения доступа 0xFFFFFFFFFFFFFFFF

Я пытался увеличить размер буфера, но, похоже, это не помогло.Я думаю, что это происходит после того, как первый адаптер пропущен через цикл.

#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 голосов
/ 18 октября 2018

В блоке цикла 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));
...