Search code examples
c++winapicrashhwid

GetAdaptersInfo crashing


I'm currently trying to do some hardware generation for a friend of mine and I noticed that GetAdaptersInfo kinda behaves weirdly. According to MSDN pOutBufLen should be pointing to a variable holding the value of sizeof(IP_ADAPTER_INFO) (640). But when I use that value it returns 111 (ERROR_BUFFER_OVERFLOW) and sets outBufLen to 2560. When calling the function with outBufLen set to 2560 it just crashes.

Minimal reproduction code:

#include <windows.h>
#include <Iphlpapi.h>

int main()
{
    IP_ADAPTER_INFO adapter_inf;
    unsigned long int outBufLen = sizeof(IP_ADAPTER_INFO);

    GetAdaptersInfo(nullptr, &outBufLen); // returning 111 (ERROR_BUFFER_OVERFLOW) and setting outBufLen to 2560
    GetAdaptersInfo(&adapter_inf, &outBufLen); // crash during this call

    return 0;
}

Don't know if it matters but 64-bit Windows 8 here.


Solution

  • GetAdaptersInfo(nullptr, &outBufLen);
    

    After this returns a value in outBufLen you are expected to pass a buffer of that length in the subsequent call. You do not do that, hence the runtime error.

    You need to allocate the pAdapterInfo dynamically using the length returned in outBufLen.

    ULONG outBufLen = 0;
    if (GetAdaptersInfo(nullptr, &outBufLen) != ERROR_BUFFER_OVERFLOW)
        // handle error
    PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO) malloc(outBufLen);
    if (GetAdaptersInfo(pAdapterInfo, &outBufLen) != ERROR_SUCCESS)
        // handle error
    

    I've used malloc here, and a C style cast, but you might prefer to use new and a C++ style cast. I didn't do that through my own lack of familiarity.

    Obviously you need to free the memory when you are finished with it.