wininet: Add a new NETCON_query_data_available function.
Use it to implement the behaviour where InternetReadFileExA does a synchronous request if the data is available and asynchronous otherwise.
This commit is contained in:
parent
76507d475b
commit
56267608f1
|
@ -1855,26 +1855,32 @@ BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOu
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME: native only does it asynchronously if the amount of data
|
||||
* requested isn't available. See NtReadFile. */
|
||||
/* FIXME: IRF_ASYNC may not be the right thing to test here;
|
||||
* hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC is probably better, but
|
||||
* we should implement the above first */
|
||||
* hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC is probably better */
|
||||
if (dwFlags & IRF_ASYNC)
|
||||
{
|
||||
WORKREQUEST workRequest;
|
||||
struct WORKREQ_INTERNETREADFILEEXA *req;
|
||||
DWORD dwDataAvailable = 0;
|
||||
|
||||
workRequest.asyncproc = AsyncInternetReadFileExProc;
|
||||
workRequest.hdr = WININET_AddRef( lpwh );
|
||||
req = &workRequest.u.InternetReadFileExA;
|
||||
req->lpBuffersOut = lpBuffersOut;
|
||||
if (lpwh->htype == WH_HHTTPREQ)
|
||||
NETCON_query_data_available(&((LPWININETHTTPREQW)lpwh)->netConnection,
|
||||
&dwDataAvailable);
|
||||
|
||||
retval = INTERNET_AsyncCall(&workRequest);
|
||||
if (!retval) return FALSE;
|
||||
if (!dwDataAvailable)
|
||||
{
|
||||
WORKREQUEST workRequest;
|
||||
struct WORKREQ_INTERNETREADFILEEXA *req;
|
||||
|
||||
INTERNET_SetLastError(ERROR_IO_PENDING);
|
||||
return FALSE;
|
||||
workRequest.asyncproc = AsyncInternetReadFileExProc;
|
||||
workRequest.hdr = WININET_AddRef( lpwh );
|
||||
req = &workRequest.u.InternetReadFileExA;
|
||||
req->lpBuffersOut = lpBuffersOut;
|
||||
|
||||
retval = INTERNET_AsyncCall(&workRequest);
|
||||
if (!retval) return FALSE;
|
||||
|
||||
INTERNET_SetLastError(ERROR_IO_PENDING);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
retval = INTERNET_ReadFile(lpwh, lpBuffersOut->lpvBuffer,
|
||||
|
@ -3258,15 +3264,24 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
|
|||
switch (lpwhr->hdr.htype)
|
||||
{
|
||||
case WH_HHTTPREQ:
|
||||
if (!NETCON_recv(&lpwhr->netConnection, buffer,
|
||||
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))
|
||||
{
|
||||
INTERNET_SetLastError(ERROR_NO_MORE_FILES);
|
||||
retval = FALSE;
|
||||
}
|
||||
retval = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
INTERNET_SetLastError(ERROR_NO_MORE_FILES);
|
||||
retval = FALSE;
|
||||
}
|
||||
else
|
||||
retval = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -459,6 +459,7 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len,
|
|||
int *sent /* out */);
|
||||
BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
|
||||
int *recvd /* out */);
|
||||
BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available);
|
||||
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer);
|
||||
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection);
|
||||
BOOL NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value);
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -569,6 +572,35 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f
|
|||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NETCON_query_data_available
|
||||
* Returns the number of bytes of peeked data plus the number of bytes of
|
||||
* queued, but unread data.
|
||||
*/
|
||||
BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available)
|
||||
{
|
||||
if (!NETCON_connected(connection))
|
||||
return FALSE;
|
||||
|
||||
if (connection->peek_msg)
|
||||
*available = connection->peek_len;
|
||||
else
|
||||
*available = 0;
|
||||
#ifdef FIONREAD
|
||||
if (!connection->useSSL)
|
||||
{
|
||||
int unread;
|
||||
int retval = ioctl(connection->socketFD, FIONREAD, &unread);
|
||||
if (!retval)
|
||||
{
|
||||
TRACE("%d bytes of queued, but unread data\n", unread);
|
||||
*available += unread;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NETCON_getNextLine
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue