views:

288

answers:

2

I've got some legacy code in C++ here that does some things I don't understand. I'm running it in Visual C++ 2008 Express Edition on a machine running Windows XP.

The code uses some Windows functions: GetAdaptersInfo and GetAdaptersAddressess. I realize that the final parameter for both of these is a pointer to the size of the buffer and since it's in_out, it can be changed within the function.

My question is: are these functions supposed to change the buffer length?

In the code I have, every time these functions are called the buffer length variable is initialized to zero, and after the function is called, it's still 0.

+1  A: 

Your code needs to look something like this:

// First get the desired size.
unsigned long outBufLen = 0;
DWORD dwResult = GetAdaptersInfo(NULL, &outBufLen);
if (dwResult == ERROR_BUFFER_OVERFLOW)  // This is what we're expecting
{
    // Now allocate a structure of the requried size.
    PIP_ADAPTER_INFO pIpAdapterInfo = (PIP_ADAPTER_INFO) malloc(outBufLen);
    dwResult = GetAdaptersInfo(pIpAdapterInfo, &outBufLen);
    if (dwResult == ERROR_SUCCESS)
    {
        // Yay!
RichieHindle
So GetAdaptersInfo gets the size that the pIpAdapterInfo element would be in the first call, and then in the second call actually gets the Adapter Info? That's interesting. Thanks for the clarification.
RCC
Yes. It's quite common for Windows APIs that fill buffers to work this way.
RichieHindle
+1  A: 

Of course, the example code shown above contains a race condition.... if the size of the structure Windows wants to return grows after the first call to GetAdaptersInfo() but before the second call to GetAdaptersInfo(), the second call to GetAdaptersInfo() will fail with ERROR_BUFFER_OVERFLOW as well, and your function won't work.

Yes, that does happen in real life -- I've had it happen to me. If you want the code to be reliable, you need to call GetAdaptersInfo() in a loop, increasing your buffer's size as many times as necessary until the call succeeds.

There has to be a less error-prone way to construct an API... unfortunately Microsoft hasn't yet found it. :^P

Jeremy Friesner
+1 Good point. And wow, you were spectacularly unlucky to be caught by that!
RichieHindle