WinInet InternetReadFile返回0x8007007a(传递给系统调用的数据区域太小)

时间:2013-08-15 08:14:10

标签: c++ wininet

我遇到了 WinInet的InternetReadFile (C ++)的问题。
在极少数情况下,函数失败,GetLastError返回上述错误 0x8007007a (根据ErrorLookup对应于“传递给系统调用的数据区域太小”)。

我对此有几个问题:

  1. 为什么在极少数情况下会发生这种情况,但在其他情况下却有效 很好(我当然在谈论总是下载相同的~15MB zip文件)?
  2. 这是否与传递给API调用的缓冲区大小有关?我正在为此调用使用1024个BYTES的const缓冲区大小。我应该使用更大的缓冲区大小吗?如果是这样,我怎么知道什么是“正确的”缓冲区大小?
  3. 如果我收到此错误,我该怎么做才能在运行时恢复?
  4. 添加代码段(请注意,这不会有效,因为某些初始化代码是必需的):

    #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);
    

1 个答案:

答案 0 :(得分:3)

InternetReadFile是一个记录错误:

  

WinINet尝试一次将一行写入lpBuffer缓冲区。如果应用程序的缓冲区太小而无法容纳至少一行生成的HTML,则会返回错误代码ERROR_INSUFFICIENT_BUFFER,以指示应用程序需要更大的缓冲区。

所以你应该通过增加缓冲区大小来处理这个错误。如果需要,可以重复两倍大小。

存在一些差异。目前尚不清楚您是否正在阅读一个HTML文件,15MB似乎过多。另一个是这个错误应该重复。但最令人不安的是错误代码值,它包含在HRESULT中,这是COM组件返回的错误代码。您应该从GetLastError()获取Windows错误代码,仅为0x7a而不是0x8007007a。

确保您的错误检查正确无误。只有在InternetReadFile()返回FALSE时才调用GetLastError()。如果检查出来(请总是发一个片段),那么请考虑这个错误实际上是在上游生成的,可能是防火墙或片状反恶意软件。