From: Paul Gofman pgofman@codeweavers.com
--- dlls/winhttp/request.c | 42 ++++++++++++++++++++++++++++--- dlls/winhttp/tests/notification.c | 6 ++++- 2 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 59431e3a9f2..29b30fc2583 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -3213,7 +3213,7 @@ BOOL WINAPI WinHttpReadData( HINTERNET hrequest, void *buffer, DWORD to_read, DW DWORD ret; struct request *request; BOOL async; - BOOL wont_block; + BOOL wont_block = FALSE;
TRACE( "%p, %p, %lu, %p\n", hrequest, buffer, to_read, read );
@@ -3229,7 +3229,44 @@ BOOL WINAPI WinHttpReadData( HINTERNET hrequest, void *buffer, DWORD to_read, DW return FALSE; }
- if ((async = request->connect->hdr.flags & WINHTTP_FLAG_ASYNC) && !skip_async_queue( request, &wont_block )) + if (!(async = request->connect->hdr.flags & WINHTTP_FLAG_ASYNC) || skip_async_queue( request, &wont_block )) + { + ret = read_data( request, buffer, to_read, read, async ); + } + else if (wont_block) + { + /* Data available but recursion limit reached, only queue callback. */ + struct send_callback *s; + + if (!(s = malloc( sizeof(*s) ))) + { + release_object( &request->hdr ); + SetLastError( ERROR_OUTOFMEMORY ); + return FALSE; + } + + if (!(ret = read_data( request, buffer, to_read, &s->count, FALSE ))) + { + if (read) *read = s->count; + s->status = WINHTTP_CALLBACK_STATUS_READ_COMPLETE; + s->info = buffer; + s->buflen = s->count; + } + else + { + s->result.dwResult = API_READ_DATA; + s->result.dwError = ret; + s->status = WINHTTP_CALLBACK_STATUS_REQUEST_ERROR; + s->info = &s->result; + s->buflen = sizeof(s->result); + } + + if ((ret = queue_task( &request->queue, task_send_callback, &s->task_hdr, &request->hdr ))) + free( s ); + else + ret = ERROR_IO_PENDING; + } + else { struct read_data *r;
@@ -3248,7 +3285,6 @@ BOOL WINAPI WinHttpReadData( HINTERNET hrequest, void *buffer, DWORD to_read, DW else ret = ERROR_IO_PENDING; } - else ret = read_data( request, buffer, to_read, read, async );
release_object( &request->hdr ); SetLastError( ret ); diff --git a/dlls/winhttp/tests/notification.c b/dlls/winhttp/tests/notification.c index 40db323fb5e..ed70ed906f0 100644 --- a/dlls/winhttp/tests/notification.c +++ b/dlls/winhttp/tests/notification.c @@ -1921,10 +1921,14 @@ static void CALLBACK test_recursion_callback( HINTERNET handle, DWORD_PTR contex "got %lu, thread %#lx\n", context->recursion_count, GetCurrentThreadId() ); context->max_recursion_query = max( context->max_recursion_query, context->recursion_count ); InterlockedIncrement( &context->recursion_count ); - ret = WinHttpReadData( context->request, &b, 1, NULL ); + b = 0xff; + len = 0xdeadbeef; + ret = WinHttpReadData( context->request, &b, 1, &len ); err = GetLastError(); ok( ret, "failed to read data, GetLastError() %lu\n", err ); ok( err == ERROR_SUCCESS || err == ERROR_IO_PENDING, "got %lu\n", err ); + ok( b != 0xff, "got %#x.\n", b ); + ok( len == 1, "got %lu.\n", len ); if (err == ERROR_SUCCESS) context->have_sync_callback = TRUE; InterlockedDecrement( &context->recursion_count ); break;