Reputation: 91
I'm having a very strange problem whilst trying to download a file from the internet inside a C++ application written for Windows Compact 2013.
BOOL WWW::Read(char* buffer, DWORD buffer_size)
{
memset(buffer, 0, buffer_size);
m_dwBytesRead = 0;
BOOL bResult = InternetReadFile(m_handle, buffer, buffer_size, &m_dwBytesRead);
if (!bResult)
{
DWORD dwLastError = GetLastError();
TCHAR *err;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPTSTR)&err, 0, NULL))
{
LOGMSG(1, (TEXT("InternetReadFile failed at - (%u) %s\r\n"), dwLastError, err));
LocalFree(err);
}
}
// FUDGE
if (m_dwBytesRead == 0)
{
DWORD dwZeros = countZeros(buffer, buffer_size);
if (dwZeros < buffer_size)
{
m_dwBytesRead = buffer_size;
}
}
// END OF FUDGE
return bResult;
}
I repeatedly call the above function from another member function as follows
DWORD dwWritten;
while (!(Read(buffer, DOWNLOAD_BUFFER_SIZE) && m_dwBytesRead == 0))
{
WriteFile(m_hDownload, buffer, m_dwBytesRead, &dwWritten, NULL);
m_dwActualSize += dwWritten;
++m_dwChunks;
if (m_dwBytesRead > 0)
m_dwInactivity = 0;
else if (++m_dwInactivity > INACTIVITY_LIMIT)
return WDS_INACTIVITY;
}
Without the FUDGE, this function fails the first time through, and works correctly on subsequent calls. The error that I get on the first pass through this function call is
InternetReadFile failed at - (112) There is not enough space on the disk.
I don't understand why I should be getting a "not enough space on disk" error during a READ operation. I have checked that that the buffer is allocated, and available, and matches the expected size. In fact when I inspect the contents of the buffer, I find that it HAS been filled with the expected number of bytes, however the contents of the m_dwBytesRead variable is still set to 0.
As you can see, I have tried to code around this specific case by inspecting the contents of the buffer to see if it has been filled, and then fudging the m_dwBytesRead variable, but this is only a temporary work around to get me past this error, I really need to understand why this problem is occurring.
The consequences of this error (without my fudge), is that the data is thrown away, and I end up with a file that is missing the first block but otherwise fully correct. Consequently MD5 checks fail, and I am missing the first part of the file.
I just happen to know that the file will always be larger than the block size that I am using, so my fudge will work, but I don't like having these horrible workarounds in the code when they shouldn't be needed.
If anyone can shed any light upon what is causing the problem, it would be greatly appreciated.
I'm using Visual Studio 2013 C++ (native Windows app, not MFC), the target is 32-bit and Unicode, running on Windows Compact 2013.
Many thanks, Andrew
Upvotes: 2
Views: 1189
Reputation: 101646
Is the machine actually running out of disk space? InternetReadFile
will write to disk behind your back by default:
To ensure all data is retrieved, an application must continue to call the InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero. This is especially important if the requested data is written to the cache, because otherwise the cache will not be properly updated and the file downloaded will not be committed to the cache. Note that caching happens automatically unless the original request to open the data stream set the
INTERNET_FLAG_NO_CACHE_WRITE
flag.
Upvotes: 2