GetLastError()
is only meaningful if InternetReadFileEx()
(or any other API, for that matter) actually fails with an error. Otherwise, you will be processing an error from an earlier API call, giving your code a false illusion that an error happened when it really may not have. You MUST pay attention to API return values, but you are currently ignoring the return value of InternetReadFileEx()
.
Worse than that, though, you are using InternetReadFileEx()
in async mode but you are using a receiving buffer that is local to the INTERNET_STATUS_REQUEST_COMPLETE
callback handler. If InternetReadFileEx()
fails with an ERROR_IO_PENDING
error, the read is performed in the background and INTERNET_STATUS_REQUEST_COMPLETE
will be triggered when the read is complete. However, when that error occurs, you are breaking your loop (even though the read is still in progress) and that buffer will go out of scope before the read is finished. While the reading is still in progress, the receiving buffer is still on the stack and InternetReadFileEx()
is still writing to it, but it may get re-used for other things at the same time because your code moved on to do other things and did not wait for the read to finish.
You need to re-think your approach. Either:
remove the
IRF_ASYNC
flag, since that is how the rest of your callback code is expectingInternetReadFileEx()
to behave.re-write the code to operate in async mode correctly. Dynamically allocate the receive buffer (or at least store it somewhere else that remains in scope during the async reading), don't call
IStream::Write()
unless you actually have data to write (only whenInternetReadFileEx()
returned TRUE right away, or you get anINTERNET_STATUS_REQUEST_COMPLETE
event with a success code from an earlierInternetReadFileEx()
/ERROR_IO_PENDING
call), etc.
There are plenty of online examples and tutorials that show how to use InternetReadFileEx()
in async mode. Search around.