Module: wine
Branch: master
Commit: 663c0146a5395c83a075cb09c2864b718150d34b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=663c0146a5395c83a075cb09c…
Author: Misha Koshelev <mk144210(a)bcm.edu>
Date: Sun Jul 15 16:32:57 2007 -0500
wininet: Fix behavior of InternetQueryDataAvailable if INTERNET_FLAG_ASYNC is set.
---
dlls/wininet/internet.c | 77 ++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 66 insertions(+), 11 deletions(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index 214f8ee..32891be 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -3251,10 +3251,40 @@ lend:
* Determines how much data is available to be read.
*
* RETURNS
- * If there is data available then TRUE, otherwise if there
- * is not or an error occurred then FALSE. Use GetLastError() to
- * check for ERROR_NO_MORE_FILES to see if it was the former.
+ * TRUE on success, FALSE if an error occurred. If
+ * INTERNET_FLAG_ASYNC was specified in InternetOpen, and
+ * no data is presently available, FALSE is returned with
+ * the last error ERROR_IO_PENDING; a callback with status
+ * INTERNET_STATUS_REQUEST_COMPLETE will be sent when more
+ * data is available.
*/
+void AsyncInternetQueryDataAvailableProc(WORKREQUEST *workRequest)
+{
+ LPWININETHTTPREQW lpwhr;
+ INTERNET_ASYNC_RESULT iar;
+ char buffer[4048];
+
+ TRACE("INTERNETQUERYDATAAVAILABLE %p\n", workRequest->hdr);
+
+ switch (workRequest->hdr->htype)
+ {
+ case WH_HHTTPREQ:
+ lpwhr = (LPWININETHTTPREQW)workRequest->hdr;
+ iar.dwResult = NETCON_recv(&lpwhr->netConnection, buffer,
+ min(sizeof(buffer),
+ lpwhr->dwContentLength - lpwhr->dwContentRead),
+ MSG_PEEK, (int *)&iar.dwError);
+ INTERNET_SendCallback(workRequest->hdr, workRequest->hdr->dwContext,
+ INTERNET_STATUS_REQUEST_COMPLETE, &iar,
+ sizeof(INTERNET_ASYNC_RESULT));
+ break;
+
+ default:
+ FIXME("unsupported file type\n");
+ break;
+ }
+}
+
BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
LPDWORD lpdwNumberOfBytesAvailble,
DWORD dwFlags, DWORD dwConext)
@@ -3278,20 +3308,45 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
if (NETCON_query_data_available(&lpwhr->netConnection,
lpdwNumberOfBytesAvailble))
{
- if (!*lpdwNumberOfBytesAvailble &&
- !NETCON_recv(&lpwhr->netConnection, buffer,
- min(sizeof(buffer), lpwhr->dwContentLength - lpwhr->dwContentRead),
- MSG_PEEK, (int *)lpdwNumberOfBytesAvailble))
+ retval = TRUE;
+ if (!*lpdwNumberOfBytesAvailble)
{
- INTERNET_SetLastError(ERROR_NO_MORE_FILES);
- retval = FALSE;
+ /* Even if we are in async mode, we need to determine whether
+ * there is actually more data available. We do this by trying
+ * to peek only a single byte in async mode. */
+ BOOL async = (lpwhr->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC);
+ if (!NETCON_recv(&lpwhr->netConnection, buffer,
+ async ? 1 : min(sizeof(buffer),
+ lpwhr->dwContentLength - lpwhr->dwContentRead),
+ MSG_PEEK, (int *)lpdwNumberOfBytesAvailble))
+ {
+ INTERNET_SetLastError(ERROR_NO_MORE_FILES);
+ retval = FALSE;
+ }
+ else if (async && *lpdwNumberOfBytesAvailble)
+ {
+ WORKREQUEST workRequest;
+
+ *lpdwNumberOfBytesAvailble = 0;
+ workRequest.asyncproc = AsyncInternetQueryDataAvailableProc;
+ workRequest.hdr = WININET_AddRef( &lpwhr->hdr );
+
+ retval = INTERNET_AsyncCall(&workRequest);
+ if (!retval)
+ {
+ WININET_Release( &lpwhr->hdr );
+ }
+ else
+ {
+ INTERNET_SetLastError(ERROR_IO_PENDING);
+ retval = FALSE;
+ }
+ }
}
- retval = TRUE;
}
else
{
INTERNET_SetLastError(ERROR_NO_MORE_FILES);
- retval = FALSE;
}
break;