WinInet InternetReadFile returns 0x8007007a (The data area passed to a system call is too small)

0

I have an issue with WinInet's InternetReadFile (C++).
In some rare cases the function fails and GetLastError returns the mentioned error 0x8007007a (which according to ErrorLookup corresponds to "The data area passed to a system call is too small").

I have a few questions regarding this:

  1. Why does this happen in some rare cases but in other cases works fine (I'm talking of course about always downloading the same ~15MB zip file) ?
  2. Is this really related to the buffer size passed to the API call ? I am using a const buffer size of 1024 BYTES for this call. Should I use a bigger buffer size ? If so, how can I know what is the "right" buffer size ?
  3. What can I do to recover during run time if I do get this error ?

Adding a code snippet (note that this will not work as is because some init code is necessary):

#define HTTP_RESPONSE_BUFFER_SIZE 1024
std::vector<char> responseBuffer;
DWORD dwResponseBytesRead = 0;

do
{
    const size_t oldBufferSize = responseBuffer.size();
    responseBuffer.resize(oldBufferSize + HTTP_RESPONSE_BUFFER_SIZE);

    // Now we read again to the last place we stopped
    // writing in the previous iteration.
    dwResponseBytesRead = 0;
    BOOL bInternetReadFile = ::InternetReadFile(hOpenRequest, // hFile. Retrieved from a previous call to ::HttpOpenRequest
        (LPVOID)&responseBuffer[oldBufferSize], // lpBuffer.
        HTTP_RESPONSE_BUFFER_SIZE, // dwNumberOfBytesToRead.
        &dwResponseBytesRead); // lpdwNumberOfBytesRead.

    if(!bInternetReadFile)
    {
        // Do clean up and exit.
        DWORD dwErr = ::GetLastError(); // This, in some cases, will return: 0x7a 
        HRESULT hr = HRESULT_FROM_WIN32(dwErr); // This, in some cases, will return: 0x8007007a
        return;
    }

    // Adjust the buffer according to the actual number of bytes read.
    responseBuffer.resize(oldBufferSize + dwResponseBytesRead);
}
while(dwResponseBytesRead != 0);
c++
wininet
asked on Stack Overflow Aug 15, 2013 by Shaish • edited Aug 15, 2013 by Shaish

1 Answer

3

It is a documented error for InternetReadFile:

WinINet attempts to write the HTML to the lpBuffer buffer a line at a time. If the application's buffer is too small to fit at least one line of generated HTML, the error code ERROR_INSUFFICIENT_BUFFER is returned as an indication to the application that it needs a larger buffer.

So you are supposed to handle this error by increasing the buffer size. Just double the size, repeatedly if necessary.

There are some discrepancies in question. It isn't clear that you are reading an HTML file for one, 15MB seems excessive. Another is that this error should repeat well. But most troubling is the error code value, it is wrapped in an HRESULT, the kind of error code that a COM component would return. You should be getting a Windows error code back from GetLastError(), just 0x7a and not 0x8007007a.

Do make sure that your error checking is correct. Only ever call GetLastError() when InternetReadFile() returned FALSE. If that checks out (always post a snippet please) then do consider that this error is actually generated upstream, perhaps the firewall or flaky anti-malware.

answered on Stack Overflow Aug 15, 2013 by Hans Passant

User contributions licensed under CC BY-SA 3.0