diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 9ea304d4..697023a2 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -1971,6 +1971,13 @@ if test "$enable_wpcap_Dynamic_Linking" -eq 1; then enable_wpcap_Several_Fixes=1 fi +if test "$enable_wininet_Cleanup" -eq 1; then + if test "$enable_wininet_HTTPREQ_ReadFile_Async" -gt 1; then + abort "Patchset wininet-HTTPREQ_ReadFile_Async disabled, but wininet-Cleanup depends on that." + fi + enable_wininet_HTTPREQ_ReadFile_Async=1 +fi + if test "$enable_wined3d_CSMT_Helper" -eq 1; then if test "$enable_makedep_PARENTSPEC" -gt 1; then abort "Patchset makedep-PARENTSPEC disabled, but wined3d-CSMT_Helper depends on that." @@ -7424,8 +7431,29 @@ if test "$enable_winhttp_System_Proxy_Autoconfig" -eq 1; then ) >> "$patchlist" fi +# Patchset wininet-HTTPREQ_ReadFile_Async +# | +# | Modified files: +# | * dlls/wininet/http.c, dlls/wininet/tests/http.c +# | +if test "$enable_wininet_HTTPREQ_ReadFile_Async" -eq 1; then + patch_apply wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.-resen.patch + patch_apply wininet-HTTPREQ_ReadFile_Async/0002-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch + patch_apply wininet-HTTPREQ_ReadFile_Async/0003-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.-resen.patch + patch_apply wininet-HTTPREQ_ReadFile_Async/0004-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch + ( + echo '+ { "Michael Müller", "wininet: Fix async check in HTTPREQ_ReadFileEx.", 1 },'; + echo '+ { "Sebastian Lackner", "wininet/tests: Add tests for asynchronous InternetReadFileEx.", 3 },'; + echo '+ { "Michael Müller", "wininet: Handle async mode in HTTPREQ_ReadFile.", 1 },'; + echo '+ { "Sebastian Lackner", "wininet/tests: Add tests for asynchronous InternetReadFile.", 3 },'; + ) >> "$patchlist" +fi + # Patchset wininet-Cleanup # | +# | This patchset has the following (direct or indirect) dependencies: +# | * wininet-HTTPREQ_ReadFile_Async +# | # | Modified files: # | * dlls/wininet/http.c, dlls/wininet/tests/http.c # | @@ -7444,20 +7472,6 @@ if test "$enable_wininet_Cleanup" -eq 1; then ) >> "$patchlist" fi -# Patchset wininet-HTTPREQ_ReadFile_Async -# | -# | Modified files: -# | * dlls/wininet/http.c -# | -if test "$enable_wininet_HTTPREQ_ReadFile_Async" -eq 1; then - patch_apply wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.patch - patch_apply wininet-HTTPREQ_ReadFile_Async/0002-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.patch - ( - echo '+ { "Michael Müller", "wininet: Fix async check in HTTPREQ_ReadFileEx.", 1 },'; - echo '+ { "Michael Müller", "wininet: Handle async mode in HTTPREQ_ReadFile.", 1 },'; - ) >> "$patchlist" -fi - # Patchset wininet-HttpOpenRequestW # | # | This patchset fixes the following Wine bugs: diff --git a/patches/wininet-Cleanup/0002-wininet-tests-Test-auth-credential-reusage-with-host.patch b/patches/wininet-Cleanup/0002-wininet-tests-Test-auth-credential-reusage-with-host.patch index 6dd9904e..7de9dd44 100644 --- a/patches/wininet-Cleanup/0002-wininet-tests-Test-auth-credential-reusage-with-host.patch +++ b/patches/wininet-Cleanup/0002-wininet-tests-Test-auth-credential-reusage-with-host.patch @@ -1,4 +1,4 @@ -From 5049ef6fb20ab57cfe18209df3deee1bf1c5d069 Mon Sep 17 00:00:00 2001 +From 284cf431a6dc5ba77356c0103098f4009cb498eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Fri, 15 May 2015 21:18:37 +0200 Subject: wininet/tests: Test auth credential reusage with host override. @@ -8,12 +8,12 @@ Subject: wininet/tests: Test auth credential reusage with host override. 1 file changed, 92 insertions(+) diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c -index 559ab3e..29abb2f 100644 +index 16773e6..a6e860b 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c -@@ -2394,6 +2394,20 @@ static DWORD CALLBACK server_thread(LPVOID param) - else - send(c, notokmsg, sizeof notokmsg-1, 0); +@@ -2401,6 +2401,20 @@ static DWORD CALLBACK server_thread(LPVOID param) + WaitForSingleObject(conn_wait_event, INFINITE); + send(c, page1_mid, page1_end - page1_mid, 0); } + if (strstr(buffer, "HEAD /test_auth_host1")) + { @@ -32,7 +32,7 @@ index 559ab3e..29abb2f 100644 shutdown(c, 2); closesocket(c); c = -1; -@@ -3086,6 +3100,84 @@ static void test_header_override(int port) +@@ -3112,6 +3126,84 @@ static void test_header_override(int port) InternetCloseHandle(req); InternetCloseHandle(con); InternetCloseHandle(ses); @@ -118,5 +118,5 @@ index 559ab3e..29abb2f 100644 static void test_http1_1(int port) -- -2.4.3 +2.8.0 diff --git a/patches/wininet-Cleanup/definition b/patches/wininet-Cleanup/definition index 52d34a96..c4fdd1fe 100644 --- a/patches/wininet-Cleanup/definition +++ b/patches/wininet-Cleanup/definition @@ -1 +1,2 @@ # Fixes: [28911] Add HTTP Host header in HttpSendRequest instead of HttpOpenRequest +Depends: wininet-HTTPREQ_ReadFile_Async diff --git a/patches/wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.patch b/patches/wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.-resen.patch similarity index 63% rename from patches/wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.patch rename to patches/wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.-resen.patch index c3fe166a..982eaac6 100644 --- a/patches/wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.patch +++ b/patches/wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.-resen.patch @@ -1,8 +1,13 @@ -From c0897fede8556c5970ff7a5db97795a0ccd88b43 Mon Sep 17 00:00:00 2001 +From 6545fc4c2c3fcc407b849185f9042118826e2ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Tue, 5 Apr 2016 17:55:47 +0200 -Subject: wininet: Fix async check in HTTPREQ_ReadFileEx. +Date: Tue, 26 Apr 2016 23:37:13 +0200 +Subject: wininet: Fix async check in HTTPREQ_ReadFileEx. (resend) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Signed-off-by: Michael Müller +Signed-off-by: Sebastian Lackner --- dlls/wininet/http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) @@ -21,5 +26,5 @@ index bdc659d..2774ab0 100644 read_file_ex_task_t *task; -- -2.7.1 +2.8.0 diff --git a/patches/wininet-HTTPREQ_ReadFile_Async/0002-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch b/patches/wininet-HTTPREQ_ReadFile_Async/0002-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch new file mode 100644 index 00000000..a687c31d --- /dev/null +++ b/patches/wininet-HTTPREQ_ReadFile_Async/0002-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch @@ -0,0 +1,162 @@ +From f9828f2ad26faa73c8820f98610a393c46339289 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 26 Apr 2016 23:37:54 +0200 +Subject: wininet/tests: Add tests for asynchronous InternetReadFileEx. (v3) + +Signed-off-by: Sebastian Lackner +--- + dlls/wininet/tests/http.c | 117 +++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 116 insertions(+), 1 deletion(-) + +diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c +index 82fd10b..fcaba10 100644 +--- a/dlls/wininet/tests/http.c ++++ b/dlls/wininet/tests/http.c +@@ -109,7 +109,7 @@ static int expect[MAX_INTERNET_STATUS], optional[MAX_INTERNET_STATUS], + wine_allow[MAX_INTERNET_STATUS], notified[MAX_INTERNET_STATUS]; + static const char *status_string[MAX_INTERNET_STATUS]; + +-static HANDLE hCompleteEvent, conn_close_event; ++static HANDLE hCompleteEvent, conn_close_event, conn_wait_event; + static DWORD req_error; + + #define TESTF_REDIRECT 0x01 +@@ -2358,6 +2358,15 @@ static DWORD CALLBACK server_thread(LPVOID param) + else + send(c, notokmsg, sizeof notokmsg-1, 0); + } ++ if (strstr(buffer, "/async_read")) ++ { ++ const char *page1_mid = page1 + (sizeof page1 - 1)/2; ++ const char *page1_end = page1 + sizeof page1 - 1; ++ send(c, okmsg, sizeof okmsg-1, 0); ++ send(c, page1, page1_mid - page1, 0); ++ WaitForSingleObject(conn_wait_event, INFINITE); ++ send(c, page1_mid, page1_end - page1_mid, 0); ++ } + shutdown(c, 2); + closesocket(c); + c = -1; +@@ -4420,6 +4429,111 @@ static void test_basic_auth_credentials_reuse(int port) + InternetCloseHandle( ses ); + } + ++static void test_async_read(int port) ++{ ++ HINTERNET ses, con, req; ++ INTERNET_BUFFERSA ib; ++ char buffer[0x100]; ++ DWORD pending_reads; ++ DWORD res, count; ++ BOOL ret; ++ ++ hCompleteEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ++ conn_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL); ++ ++ /* test asynchronous InternetReadFileEx */ ++ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC ); ++ ok( ses != NULL, "InternetOpenA failed\n" ); ++ pInternetSetStatusCallbackA( ses, &callback ); ++ ++ SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED ); ++ con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef ); ++ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() ); ++ CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED ); ++ ++ SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED ); ++ req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef ); ++ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() ); ++ CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED ); ++ ++ SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT ); ++ SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY ); ++ SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER ); ++ SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER ); ++ SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST ); ++ SET_EXPECT( INTERNET_STATUS_REQUEST_SENT ); ++ SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE ); ++ SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED ); ++ SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION ); ++ SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED ); ++ SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE ); ++ ++ SetLastError( 0xdeadbeef ); ++ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 ); ++ ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" ); ++ ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() ); ++ WaitForSingleObject( hCompleteEvent, INFINITE ); ++ ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error ); ++ ++ CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT ); ++ CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY ); ++ CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER ); ++ CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER ); ++ CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST ); ++ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT ); ++ CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE ); ++ CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED ); ++ CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION ); ++ CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED ); ++ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE ); ++ ++ pending_reads = 0; ++ memset( &ib, 0, sizeof(ib) ); ++ memset( buffer, 0, sizeof(buffer) ); ++ ib.dwStructSize = sizeof(ib); ++ for (count = 0; count < sizeof(buffer); count += ib.dwBufferLength) ++ { ++ ib.lpvBuffer = buffer + count; ++ ib.dwBufferLength = min(16, sizeof(buffer) - count); ++ ++ SET_OPTIONAL( INTERNET_STATUS_RECEIVING_RESPONSE ); ++ SET_OPTIONAL( INTERNET_STATUS_RESPONSE_RECEIVED ); ++ ++ ret = InternetReadFileExA( req, &ib, 0, 0xdeadbeef ); ++ if (!count) /* the first part should arrive immediately */ ++ ok( ret, "InternetReadFileExA failed %u\n", GetLastError() ); ++ if (!ret) ++ { ++ ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() ); ++ SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE ); ++ if (!pending_reads++) ++ { ++ res = WaitForSingleObject( hCompleteEvent, 0 ); ++ ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res ); ++ SetEvent( conn_wait_event ); ++ } ++ res = WaitForSingleObject( hCompleteEvent, INFINITE ); ++ ok( res == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", res ); ++ ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error ); ++ todo_wine_if( pending_reads > 1 ) ++ ok( ib.dwBufferLength != 0, "expected ib.dwBufferLength != 0\n" ); ++ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE ); ++ } ++ ++ CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE ); ++ CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED ); ++ if (!ib.dwBufferLength) break; ++ } ++ ++ todo_wine ++ ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads ); ++ ok( !strcmp(buffer, page1), "unexpected buffer content\n" ); ++ close_async_handle( ses, hCompleteEvent, 2 ); ++ ++ CloseHandle( hCompleteEvent ); ++ CloseHandle( conn_wait_event ); ++} ++ + static void test_http_connection(void) + { + struct server_info si; +@@ -4469,6 +4583,7 @@ static void test_http_connection(void) + test_request_content_length(si.port); + test_accept_encoding(si.port); + test_basic_auth_credentials_reuse(si.port); ++ test_async_read(si.port); + + /* send the basic request again to shutdown the server thread */ + test_basic_request(si.port, "GET", "/quit"); +-- +2.8.0 + diff --git a/patches/wininet-HTTPREQ_ReadFile_Async/0002-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.patch b/patches/wininet-HTTPREQ_ReadFile_Async/0003-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.-resen.patch similarity index 72% rename from patches/wininet-HTTPREQ_ReadFile_Async/0002-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.patch rename to patches/wininet-HTTPREQ_ReadFile_Async/0003-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.-resen.patch index 32a7952e..3ec15800 100644 --- a/patches/wininet-HTTPREQ_ReadFile_Async/0002-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.patch +++ b/patches/wininet-HTTPREQ_ReadFile_Async/0003-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.-resen.patch @@ -1,14 +1,19 @@ -From e2da56d0cda302fbc815da6f35ef5cc0cf5f7c95 Mon Sep 17 00:00:00 2001 +From ace80a3673e0f48a26e27b821c03e96140c1557b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Tue, 5 Apr 2016 17:58:29 +0200 -Subject: wininet: Handle async mode in HTTPREQ_ReadFile. +Date: Tue, 26 Apr 2016 23:38:16 +0200 +Subject: wininet: Handle async mode in HTTPREQ_ReadFile. (resend) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Signed-off-by: Michael Müller +Signed-off-by: Sebastian Lackner --- - dlls/wininet/http.c | 57 +++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 40 insertions(+), 17 deletions(-) + dlls/wininet/http.c | 61 ++++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c -index 2774ab0..fac3d4d 100644 +index 2774ab0..6c2c567 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -3105,23 +3105,6 @@ static BOOL drain_content(http_request_t *req, BOOL blocking) @@ -35,7 +40,7 @@ index 2774ab0..fac3d4d 100644 typedef struct { task_header_t hdr; void *buf; -@@ -3238,6 +3221,46 @@ static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD s +@@ -3238,6 +3221,50 @@ static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD s return res; } @@ -51,8 +56,11 @@ index 2774ab0..fac3d4d 100644 + if (TryEnterCriticalSection( &req->read_section )) + { + if (get_avail_data(req)) -+ goto read_data; -+ ++ { ++ res = HTTPREQ_Read(req, buffer, size, read); ++ LeaveCriticalSection( &req->read_section ); ++ goto done; ++ } + LeaveCriticalSection( &req->read_section ); + } + @@ -61,6 +69,7 @@ index 2774ab0..fac3d4d 100644 + task->size = size; + task->ret_read = read; + ++ *read = 0; + INTERNET_AsyncCall(&task->hdr); + + return ERROR_IO_PENDING; @@ -70,12 +79,12 @@ index 2774ab0..fac3d4d 100644 + if(hdr->dwError == INTERNET_HANDLE_IN_USE) + hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR; + -+read_data: + res = HTTPREQ_Read(req, buffer, size, read); + if(res == ERROR_SUCCESS) + res = hdr->dwError; + LeaveCriticalSection( &req->read_section ); + ++done: + return res; +} + @@ -83,5 +92,5 @@ index 2774ab0..fac3d4d 100644 task_header_t hdr; DWORD *ret_size; -- -2.7.1 +2.8.0 diff --git a/patches/wininet-HTTPREQ_ReadFile_Async/0004-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch b/patches/wininet-HTTPREQ_ReadFile_Async/0004-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch new file mode 100644 index 00000000..7eebcc30 --- /dev/null +++ b/patches/wininet-HTTPREQ_ReadFile_Async/0004-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch @@ -0,0 +1,120 @@ +From 748c8bfe4b67785a4c2933365d73a87e3ed31f80 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 26 Apr 2016 23:38:41 +0200 +Subject: wininet/tests: Add tests for asynchronous InternetReadFile. (v3) + +Signed-off-by: Sebastian Lackner +--- + dlls/wininet/tests/http.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 88 insertions(+), 1 deletion(-) + +diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c +index fcaba10..67392cd 100644 +--- a/dlls/wininet/tests/http.c ++++ b/dlls/wininet/tests/http.c +@@ -4435,7 +4435,7 @@ static void test_async_read(int port) + INTERNET_BUFFERSA ib; + char buffer[0x100]; + DWORD pending_reads; +- DWORD res, count; ++ DWORD res, count, bytes; + BOOL ret; + + hCompleteEvent = CreateEventW(NULL, FALSE, FALSE, NULL); +@@ -4529,6 +4529,93 @@ static void test_async_read(int port) + ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads ); + ok( !strcmp(buffer, page1), "unexpected buffer content\n" ); + close_async_handle( ses, hCompleteEvent, 2 ); ++ ResetEvent( conn_wait_event ); ++ ++ /* test asynchronous InternetReadFile */ ++ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC ); ++ ok( ses != NULL, "InternetOpenA failed\n" ); ++ pInternetSetStatusCallbackA( ses, &callback ); ++ ++ SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED ); ++ con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef ); ++ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() ); ++ CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED ); ++ ++ SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED ); ++ req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef ); ++ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() ); ++ CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED ); ++ ++ SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT ); ++ SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY ); ++ SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER ); ++ SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER ); ++ SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST ); ++ SET_EXPECT( INTERNET_STATUS_REQUEST_SENT ); ++ SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE ); ++ SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED ); ++ SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION ); ++ SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED ); ++ SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE ); ++ ++ SetLastError( 0xdeadbeef ); ++ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 ); ++ ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" ); ++ ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() ); ++ WaitForSingleObject( hCompleteEvent, INFINITE ); ++ ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error ); ++ ++ CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT ); ++ CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY ); ++ CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER ); ++ CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER ); ++ CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST ); ++ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT ); ++ CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE ); ++ CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED ); ++ CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION ); ++ CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED ); ++ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE ); ++ ++ pending_reads = 0; ++ memset( buffer, 0, sizeof(buffer) ); ++ for (count = 0; count < sizeof(buffer); count += bytes) ++ { ++ SET_OPTIONAL( INTERNET_STATUS_RECEIVING_RESPONSE ); ++ SET_OPTIONAL( INTERNET_STATUS_RESPONSE_RECEIVED ); ++ ++ bytes = 0xdeadbeef; ++ ret = InternetReadFile( req, buffer + count, min(16, sizeof(buffer) - count), &bytes ); ++ if (!count) /* the first part should arrive immediately */ ++ ok( ret, "InternetReadFile failed %u\n", GetLastError() ); ++ if (!ret) ++ { ++ ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() ); ++ ok( bytes == 0, "expected 0, got %u\n", bytes ); ++ SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE ); ++ if (!pending_reads++) ++ { ++ res = WaitForSingleObject( hCompleteEvent, 0 ); ++ ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res ); ++ SetEvent( conn_wait_event ); ++ } ++ res = WaitForSingleObject( hCompleteEvent, INFINITE ); ++ ok( res == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", res ); ++ ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error ); ++ todo_wine_if( pending_reads > 1 ) ++ ok( bytes != 0, "expected bytes != 0\n" ); ++ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE ); ++ } ++ ++ CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE ); ++ CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED ); ++ if (!bytes) break; ++ } ++ ++ todo_wine ++ ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads ); ++ ok( !strcmp(buffer, page1), "unexpected buffer content\n" ); ++ close_async_handle( ses, hCompleteEvent, 2 ); + + CloseHandle( hCompleteEvent ); + CloseHandle( conn_wait_event ); +-- +2.8.0 +