GetAdaptersInfo and GetAdaptersAddressess BufferLength Parameter

I have some legacy C ++ code that does some things that I don't understand. I run it in Visual C ++ 2008 Express Edition on a computer running Windows XP.

The code uses some Windows features: GetAdaptersInfo and GetAdaptersAddressess. I understand that the last parameter for both of them is a pointer to the size of the buffer, and since it is in_out, it can be changed inside the function.

My question is: should these functions change the length of the buffer?

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

+1
source share
3 answers

Your code should 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! 

Edit: See also Jeremy Friesner for an answer to the question of why this code is not enough.

+3
source

Of course, the @RichieHindle answer example code contains a race condition .... if the size of the Windows structure wants to return, it grows after the first call to GetAdaptersInfo (), but before the second call to GetAdaptersInfo (), the second call to GetAdaptersInfo () will also end with ERROR_BUFFER_OVERFLOW, and your function will not work.

Yes, this happens in real life - it happened to me. If you want the code to be reliable, you need to call GetAdaptersInfo () in a loop, increasing the size of your buffer as many times as necessary until the call succeeds.

There should be a less error-prone way to create an API ... Unfortunately, Microsoft has not yet found it .: ^ P

+6
source

In fact, using Visual studio 6, I used the number of adapters:

 DWORD drc = GetAdaptersInfo(NULL, &(Buflen = 0L)); if (drc == ERROR_BUFFER_OVERFLOW) n = Buflen / sizeof(IP_ADAPTER_INFO); 

Everything was in order, for example, 2 Buflen adapters were set to 1280, and sizeof(IP_ADAPTER_INFO) was set to 640.

Now I'm using Visual C ++ 2008 Express, and my result is truncated, because the function still sets Buflen to 1280, but the value of sizeof(IP_ADAPTER_INFO) now 648!

Is this a mistake or am I missing something?

+1
source

All Articles