Signed-off-by: Paul Gofman pgofman@codeweavers.com --- winhttp functions (in particular, WinHttpQueryDataAvailable and WinHttpReadData) can execute synchronously if the data is available. This is the documented behaviour which is also confirmed by the tests.
'eFootball PES 2021 Season Update' depends on this behaviour. It creates asynchronous session but then breaks in various ways if WinHttpReadData() actually queues the async task. The game always calls WinHttpQueryDataAvailable() first and then WinHttpReadData with the read size equal to the available data, so that the read is always synchronous on Windows.
dlls/winhttp/request.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index a6c16d7b653..b8f5817737e 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -2815,19 +2815,26 @@ BOOL WINAPI WinHttpReceiveResponse( HINTERNET hrequest, LPVOID reserved ) return !ret; }
+static DWORD query_data_ready( struct request *request ) +{ + DWORD count; + + count = get_available_data( request ); + if (!request->read_chunked && request->netconn) count += netconn_query_data_available( request->netconn ); + + return count; +} + static DWORD query_data_available( struct request *request, DWORD *available, BOOL async ) { DWORD ret = ERROR_SUCCESS, count = 0;
if (end_of_read_data( request )) goto done;
- count = get_available_data( request ); - if (!request->read_chunked && request->netconn) count += netconn_query_data_available( request->netconn ); - if (!count) + if (!(count = query_data_ready( request ))) { if ((ret = refill_buffer( request, async ))) goto done; - count = get_available_data( request ); - if (!request->read_chunked && request->netconn) count += netconn_query_data_available( request->netconn ); + count = query_data_ready( request ); }
done: