From 1c659954df22593771c455a731b1bee761fb8742 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Wed, 25 Aug 2021 12:57:53 +0300 Subject: [PATCH] winhttp: Execute WinHttpQueryDataAvailable() synchronously if the data is available. Signed-off-by: Paul Gofman Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/winhttp/request.c | 9 ++++++--- dlls/winhttp/tests/notification.c | 11 +++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index b8f5817737e..03f895a7fdb 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -2873,6 +2873,7 @@ BOOL WINAPI WinHttpQueryDataAvailable( HINTERNET hrequest, LPDWORD available ) { DWORD ret; struct request *request; + BOOL async; TRACE("%p, %p\n", hrequest, available); @@ -2888,7 +2889,8 @@ BOOL WINAPI WinHttpQueryDataAvailable( HINTERNET hrequest, LPDWORD available ) return FALSE; } - if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC) + if ((async = request->connect->hdr.flags & WINHTTP_FLAG_ASYNC) && !end_of_read_data( request ) + && !query_data_ready( request )) { struct query_data *q; @@ -2902,12 +2904,13 @@ BOOL WINAPI WinHttpQueryDataAvailable( HINTERNET hrequest, LPDWORD available ) release_object( &request->hdr ); free( q ); } + else ret = ERROR_IO_PENDING; } - else ret = query_data_available( request, available, FALSE ); + else ret = query_data_available( request, available, async ); release_object( &request->hdr ); SetLastError( ret ); - return !ret; + return !ret || ret == ERROR_IO_PENDING; } static void CALLBACK task_read_data( TP_CALLBACK_INSTANCE *instance, void *ctx, TP_WORK *work ) diff --git a/dlls/winhttp/tests/notification.c b/dlls/winhttp/tests/notification.c index 98e4024867f..7d1bfa78a49 100644 --- a/dlls/winhttp/tests/notification.c +++ b/dlls/winhttp/tests/notification.c @@ -71,6 +71,8 @@ struct info unsigned int index; HANDLE wait; unsigned int line; + DWORD last_thread_id; + DWORD last_status; }; struct test_request @@ -85,6 +87,9 @@ static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DW BOOL status_ok, function_ok; struct info *info = (struct info *)context; + info->last_status = status; + info->last_thread_id = GetCurrentThreadId(); + if (status == WINHTTP_CALLBACK_STATUS_HANDLE_CREATED) { DWORD size = sizeof(struct info *); @@ -177,6 +182,8 @@ static void setup_test( struct info *info, enum api function, unsigned int line ok_(__FILE__,line)(info->test[info->index].function == function, "unexpected function %u, expected %u. probably some notifications were missing\n", info->test[info->index].function, function); + info->last_thread_id = 0xdeadbeef; + info->last_status = 0xdeadbeef; } static void end_test( struct info *info, unsigned int line ) @@ -597,6 +604,10 @@ static void test_async( void ) ok(err == ERROR_SUCCESS || err == ERROR_IO_PENDING || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); WaitForSingleObject( info.wait, INFINITE ); + ok(info.last_status == WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE, "got status %#x.\n", status); + ok((err == ERROR_SUCCESS && info.last_thread_id == GetCurrentThreadId()) + || (err == ERROR_IO_PENDING && info.last_thread_id != GetCurrentThreadId()), + "Got unexpected thread %#x, err %#x.\n", info.last_thread_id, err); setup_test( &info, winhttp_read_data, __LINE__ ); ret = WinHttpReadData( req, buffer, sizeof(buffer), NULL );