Misha Koshelev : wininet: Fix behavior of InternetQueryDataAvailable if INTERNET_FLAG_ASYNC is set.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jul 16 08:23:39 CDT 2007


Module: wine
Branch: master
Commit: 663c0146a5395c83a075cb09c2864b718150d34b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=663c0146a5395c83a075cb09c2864b718150d34b

Author: Misha Koshelev <mk144210 at 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;
 




More information about the wine-cvs mailing list