From: Hans Leidekker Subject: winhttp: Always clear last error on success. Message-Id: <1438594051.28205.19.camel@codeweavers.com> Date: Mon, 03 Aug 2015 11:27:31 +0200 --- dlls/winhttp/request.c | 9 +++ dlls/winhttp/session.c | 29 ++++++++- dlls/winhttp/tests/notification.c | 47 +++++++++++--- dlls/winhttp/tests/url.c | 9 ++- dlls/winhttp/tests/winhttp.c | 131 ++++++++++++++++++++++++++++++++------ dlls/winhttp/url.c | 2 + 6 files changed, 194 insertions(+), 33 deletions(-) diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 9a79754..740a582 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -541,6 +541,7 @@ BOOL WINAPI WinHttpAddRequestHeaders( HINTERNET hrequest, LPCWSTR headers, DWORD ret = add_request_headers( request, headers, len, flags ); release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -848,6 +849,7 @@ BOOL WINAPI WinHttpQueryHeaders( HINTERNET hrequest, DWORD level, LPCWSTR name, ret = query_headers( request, level, name, buffer, buflen, index ); release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1265,6 +1267,7 @@ BOOL WINAPI WinHttpSendRequest( HINTERNET hrequest, LPCWSTR headers, DWORD heade ret = send_request( request, headers, headers_len, optional, optional_len, total_len, context, FALSE ); release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1388,6 +1391,7 @@ BOOL WINAPI WinHttpQueryAuthSchemes( HINTERNET hrequest, LPDWORD supported, LPDW } release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1842,6 +1846,7 @@ BOOL WINAPI WinHttpSetCredentials( HINTERNET hrequest, DWORD target, DWORD schem ret = set_credentials( request, target, scheme, username, password ); release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -2484,6 +2489,7 @@ BOOL WINAPI WinHttpReceiveResponse( HINTERNET hrequest, LPVOID reserved ) ret = receive_response( request, FALSE ); release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -2555,6 +2561,7 @@ BOOL WINAPI WinHttpQueryDataAvailable( HINTERNET hrequest, LPDWORD available ) ret = query_data_available( request, available, FALSE ); release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -2604,6 +2611,7 @@ BOOL WINAPI WinHttpReadData( HINTERNET hrequest, LPVOID buffer, DWORD to_read, L ret = read_data( request, buffer, to_read, read, FALSE ); release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -2675,6 +2683,7 @@ BOOL WINAPI WinHttpWriteData( HINTERNET hrequest, LPCVOID buffer, DWORD to_write ret = write_data( request, buffer, to_write, written, FALSE ); release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index 3dbbad3..28587f5 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -276,6 +276,7 @@ HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWST end: release_object( &session->hdr ); TRACE("returning %p\n", handle); + if (handle) set_last_error( ERROR_SUCCESS ); return handle; } @@ -552,6 +553,7 @@ end: release_object( &connect->hdr ); release_object( &session->hdr ); TRACE("returning %p\n", hconnect); + if (hconnect) set_last_error( ERROR_SUCCESS ); return hconnect; } @@ -1127,6 +1129,7 @@ end: release_object( &request->hdr ); release_object( &connect->hdr ); TRACE("returning %p\n", hrequest); + if (hrequest) set_last_error( ERROR_SUCCESS ); return hrequest; } @@ -1146,6 +1149,7 @@ BOOL WINAPI WinHttpCloseHandle( HINTERNET handle ) } release_object( hdr ); free_handle( handle ); + set_last_error( ERROR_SUCCESS ); return TRUE; } @@ -1206,6 +1210,7 @@ BOOL WINAPI WinHttpQueryOption( HINTERNET handle, DWORD option, LPVOID buffer, L ret = query_option( hdr, option, buffer, buflen ); release_object( hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1264,6 +1269,7 @@ BOOL WINAPI WinHttpSetOption( HINTERNET handle, DWORD option, LPVOID buffer, DWO ret = set_option( hdr, option, buffer, buflen ); release_object( hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1373,6 +1379,7 @@ BOOL WINAPI WinHttpDetectAutoProxyConfigUrl( DWORD flags, LPWSTR *url ) if (!(urlW = strdupAW( system_url ))) return FALSE; *url = urlW; + set_last_error( ERROR_SUCCESS ); return TRUE; } if (flags & WINHTTP_AUTO_DETECT_TYPE_DHCP) @@ -1433,6 +1440,7 @@ BOOL WINAPI WinHttpDetectAutoProxyConfigUrl( DWORD flags, LPWSTR *url ) set_last_error( ERROR_WINHTTP_AUTODETECTION_FAILED ); *url = NULL; } + else set_last_error( ERROR_SUCCESS ); return ret; } @@ -1600,6 +1608,7 @@ BOOL WINAPI WinHttpGetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info ) info->lpszProxy = NULL; info->lpszProxyBypass = NULL; } + set_last_error( ERROR_SUCCESS ); return TRUE; } @@ -1682,6 +1691,7 @@ done: GlobalFree( config->lpszProxyBypass ); config->lpszProxyBypass = NULL; } + else set_last_error( ERROR_SUCCESS ); return ret; } @@ -1866,6 +1876,7 @@ BOOL WINAPI WinHttpGetProxyForUrl( HINTERNET hsession, LPCWSTR url, WINHTTP_AUTO done: GlobalFree( detected_pac_url ); release_object( &session->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1973,6 +1984,7 @@ BOOL WINAPI WinHttpSetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info ) } RegCloseKey( key ); } + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1997,6 +2009,7 @@ WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback( HINTERNET handle, WINHT hdr->notify_mask = flags; release_object( hdr ); + set_last_error( ERROR_SUCCESS ); return ret; } @@ -2065,6 +2078,7 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int ret = FALSE; } release_object( hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -2087,7 +2101,11 @@ BOOL WINAPI WinHttpTimeFromSystemTime( const SYSTEMTIME *time, LPWSTR string ) TRACE("%p, %p\n", time, string); - if (!time || !string) return FALSE; + if (!time || !string) + { + set_last_error( ERROR_INVALID_PARAMETER ); + return FALSE; + } sprintfW( string, format, wkday[time->wDayOfWeek], @@ -2098,6 +2116,7 @@ BOOL WINAPI WinHttpTimeFromSystemTime( const SYSTEMTIME *time, LPWSTR string ) time->wMinute, time->wSecond ); + set_last_error( ERROR_SUCCESS ); return TRUE; } @@ -2112,7 +2131,11 @@ BOOL WINAPI WinHttpTimeToSystemTime( LPCWSTR string, SYSTEMTIME *time ) TRACE("%s, %p\n", debugstr_w(string), time); - if (!string || !time) return FALSE; + if (!string || !time) + { + set_last_error( ERROR_INVALID_PARAMETER ); + return FALSE; + } /* Windows does this too */ GetSystemTime( time ); @@ -2121,6 +2144,8 @@ BOOL WINAPI WinHttpTimeToSystemTime( LPCWSTR string, SYSTEMTIME *time ) * a SYSTEMTIME structure. */ + set_last_error( ERROR_SUCCESS ); + while (*s && !isalphaW( *s )) s++; if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0') return TRUE; time->wDayOfWeek = 7; diff --git a/dlls/winhttp/tests/notification.c b/dlls/winhttp/tests/notification.c index 5db8fe3..a409c0d 100644 --- a/dlls/winhttp/tests/notification.c +++ b/dlls/winhttp/tests/notification.c @@ -474,7 +474,7 @@ static const struct notification async_test[] = static void test_async( void ) { HANDLE ses, con, req, event; - DWORD size, status; + DWORD size, status, err; BOOL ret, unload = TRUE; struct info info, *context = &info; char buffer[1024]; @@ -495,22 +495,36 @@ static void test_async( void ) unload = FALSE; } + SetLastError( 0xdeadbeef ); WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 ); + err = GetLastError(); + ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); + SetLastError( 0xdeadbeef ); ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); - ok(ret, "failed to set context value %u\n", GetLastError()); + err = GetLastError(); + ok(ret, "failed to set context value %u\n", err); + ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); setup_test( &info, winhttp_connect, __LINE__ ); + SetLastError( 0xdeadbeef ); con = WinHttpConnect( ses, test_winehq, 0, 0 ); - ok(con != NULL, "failed to open a connection %u\n", GetLastError()); + err = GetLastError(); + ok(con != NULL, "failed to open a connection %u\n", err); + ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err); setup_test( &info, winhttp_open_request, __LINE__ ); + SetLastError( 0xdeadbeef ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); - ok(req != NULL, "failed to open a request %u\n", GetLastError()); + err = GetLastError(); + ok(req != NULL, "failed to open a request %u\n", err); + ok(err == ERROR_SUCCESS, "got %u\n", err); setup_test( &info, winhttp_send_request, __LINE__ ); + SetLastError( 0xdeadbeef ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); - if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT) + err = GetLastError(); + if (!ret && err == ERROR_WINHTTP_CANNOT_CONNECT) { skip("connection failed, skipping\n"); WinHttpCloseHandle( req ); @@ -519,30 +533,43 @@ static void test_async( void ) CloseHandle( info.wait ); return; } - ok(ret, "failed to send request %u\n", GetLastError()); + ok(ret, "failed to send request %u\n", err); + ok(err == ERROR_SUCCESS, "got %u\n", err); WaitForSingleObject( info.wait, INFINITE ); setup_test( &info, winhttp_receive_response, __LINE__ ); + SetLastError( 0xdeadbeef ); ret = WinHttpReceiveResponse( req, NULL ); - ok(ret, "failed to receive response %u\n", GetLastError()); + err = GetLastError(); + ok(ret, "failed to receive response %u\n", err); + ok(err == ERROR_SUCCESS, "got %u\n", err); WaitForSingleObject( info.wait, INFINITE ); size = sizeof(status); + SetLastError( 0xdeadbeef ); ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); - ok(ret, "failed unexpectedly %u\n", GetLastError()); + err = GetLastError(); + ok(ret, "failed unexpectedly %u\n", err); ok(status == 200, "request failed unexpectedly %u\n", status); + ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); setup_test( &info, winhttp_query_data, __LINE__ ); + SetLastError( 0xdeadbeef ); ret = WinHttpQueryDataAvailable( req, NULL ); - ok(ret, "failed to query data available %u\n", GetLastError()); + err = GetLastError(); + ok(ret, "failed to query data available %u\n", err); + ok(err == ERROR_SUCCESS || err == ERROR_IO_PENDING || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); WaitForSingleObject( info.wait, INFINITE ); setup_test( &info, winhttp_read_data, __LINE__ ); + SetLastError( 0xdeadbeef ); ret = WinHttpReadData( req, buffer, sizeof(buffer), NULL ); - ok(ret, "failed to query data available %u\n", GetLastError()); + err = GetLastError(); + ok(ret, "failed to read data %u\n", err); + ok(err == ERROR_SUCCESS, "got %u\n", err); WaitForSingleObject( info.wait, INFINITE ); diff --git a/dlls/winhttp/tests/url.c b/dlls/winhttp/tests/url.c index 7bd02c4..7935a19 100644 --- a/dlls/winhttp/tests/url.c +++ b/dlls/winhttp/tests/url.c @@ -169,11 +169,14 @@ static void WinHttpCreateUrl_test( void ) ok( len == 57, "expected len 57 got %u\n", len ); /* allocated url, NULL scheme */ + SetLastError( 0xdeadbeef ); uc.lpszScheme = NULL; url[0] = 0; len = 256; ret = WinHttpCreateUrl( &uc, 0, url, &len ); ok( ret, "expected success\n" ); + ok( GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, + "expected ERROR_SUCCESS got %u\n", GetLastError() ); ok( len == 56, "expected len 56 got %u\n", len ); ok( !lstrcmpW( url, url1 ), "url doesn't match\n" ); @@ -380,9 +383,13 @@ static void WinHttpCrackUrl_test( void ) /* no buffers */ reset_url_components( &uc ); + SetLastError( 0xdeadbeef ); ret = WinHttpCrackUrl( url_k1, 0, 0,&uc); + error = GetLastError(); - ok( ret, "WinHttpCrackUrl failed le=%u\n", GetLastError() ); + ok( ret, "WinHttpCrackUrl failed le=%u\n", error ); + ok( error == ERROR_SUCCESS || broken(error == ERROR_INVALID_PARAMETER) /* < win7 */, + "got %u, expected ERROR_SUCCESS\n", error ); ok( uc.nScheme == INTERNET_SCHEME_HTTP, "unexpected scheme\n" ); ok( uc.lpszScheme == url_k1,"unexpected scheme\n" ); ok( uc.dwSchemeLength == 4, "unexpected scheme length\n" ); diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index cdde303..cb462bb 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -41,8 +41,11 @@ static BOOL proxy_active(void) WINHTTP_PROXY_INFO proxy_info; BOOL active = FALSE; + SetLastError(0xdeadbeef); if (WinHttpGetDefaultProxyConfiguration(&proxy_info)) { + ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, + "got %u\n", GetLastError()); active = (proxy_info.lpszProxy != NULL); if (active) GlobalFree(proxy_info.lpszProxy); @@ -93,6 +96,8 @@ static void test_QueryOption(void) SetLastError(0xdeadbeef); ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size); ok(ret, "failed to query option %u\n", GetLastError()); + ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, + "got %u\n", GetLastError()); ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size); ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature); @@ -207,39 +212,57 @@ static void test_OpenRequest (void) { BOOL ret; HINTERNET session, request, connection; + DWORD err; + SetLastError(0xdeadbeef); session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + err = GetLastError(); ok(session != NULL, "WinHttpOpen failed to open session.\n"); + ok(err == ERROR_SUCCESS, "got %u\n", err); /* Test with a bad server name */ SetLastError(0xdeadbeef); connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0); + err = GetLastError(); ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError()); + ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err); /* Test with a valid server name */ + SetLastError(0xdeadbeef); connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); - ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError()); + err = GetLastError(); + ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", err); + ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err); + SetLastError(0xdeadbeef); request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); - if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED) + err = GetLastError(); + if (request == NULL && err == ERROR_WINHTTP_NAME_NOT_RESOLVED) { skip("Network unreachable, skipping.\n"); goto done; } - ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError()); + ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", err); + ok(err == ERROR_SUCCESS, "got %u\n", err); + SetLastError(0xdeadbeef); ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0); - if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT) + err = GetLastError(); + if (!ret && err == ERROR_WINHTTP_CANNOT_CONNECT) { skip("Connection failed, skipping.\n"); goto done; } - ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError()); + ok(ret, "WinHttpSendRequest failed: %u\n", err); + ok(err == ERROR_SUCCESS, "got %u\n", err); + + SetLastError(0xdeadbeef); ret = WinHttpCloseHandle(request); - ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret); + err = GetLastError(); + ok(ret, "WinHttpCloseHandle failed on closing request, got %u.\n", err); + ok(err == ERROR_SUCCESS, "got %u\n", err); done: ret = WinHttpCloseHandle(connection); @@ -337,9 +360,13 @@ static void test_SendRequest (void) for (i = 3; post_data[i]; i++) { bytes_rw = -1; + SetLastError(0xdeadbeef); ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw); if (ret) + { + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %u.\n", GetLastError()); ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw); + } else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */ { ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError()); @@ -347,7 +374,10 @@ static void test_SendRequest (void) } } + SetLastError(0xdeadbeef); ret = WinHttpReceiveResponse(request, NULL); + ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_NO_TOKEN) /* < win7 */, + "Expected ERROR_SUCCESS got %u.\n", GetLastError()); ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError()); bytes_rw = -1; @@ -374,9 +404,25 @@ static void test_WinHttpTimeFromSystemTime(void) {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ', '1','0',':','0','5',':','5','2',' ','G','M','T',0}; WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1]; + DWORD err; + + SetLastError(0xdeadbeef); + ret = WinHttpTimeFromSystemTime(&time, NULL); + err = GetLastError(); + ok(!ret, "WinHttpTimeFromSystemTime succeeded\n"); + ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); + + SetLastError(0xdeadbeef); + ret = WinHttpTimeFromSystemTime(NULL, time_string); + err = GetLastError(); + ok(!ret, "WinHttpTimeFromSystemTime succeeded\n"); + ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); + SetLastError(0xdeadbeef); ret = WinHttpTimeFromSystemTime(&time, time_string); - ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError()); + err = GetLastError(); + ok(ret, "WinHttpTimeFromSystemTime failed: %u\n", err); + ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0, "Time string returned did not match expected time string.\n"); } @@ -392,14 +438,33 @@ static void test_WinHttpTimeToSystemTime(void) static const WCHAR time_string2[] = {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ', '1','0',' ','0','5',' ','5','2','\n',0}; + DWORD err; + + SetLastError(0xdeadbeef); + ret = WinHttpTimeToSystemTime(time_string1, NULL); + err = GetLastError(); + ok(!ret, "WinHttpTimeToSystemTime succeeded\n"); + ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); + + SetLastError(0xdeadbeef); + ret = WinHttpTimeToSystemTime(NULL, &time); + err = GetLastError(); + ok(!ret, "WinHttpTimeToSystemTime succeeded\n"); + ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); + SetLastError(0xdeadbeef); ret = WinHttpTimeToSystemTime(time_string1, &time); - ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError()); + err = GetLastError(); + ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err); + ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0, "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n"); + SetLastError(0xdeadbeef); ret = WinHttpTimeToSystemTime(time_string2, &time); - ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError()); + err = GetLastError(); + ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err); + ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0, "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n"); } @@ -490,8 +555,11 @@ static void test_WinHttpAddHeaders(void) ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, test_header_name, buffer, &len, &index); ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n"); + SetLastError(0xdeadbeef); ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD); - ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError()); + err = GetLastError(); + ok(ret, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, err); + ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); index = 0; len = sizeof(buffer); @@ -1210,9 +1278,11 @@ static void test_set_default_proxy_config(void) if (!ret && GetLastError() == ERROR_ACCESS_DENIED) skip("couldn't set default proxy configuration: access denied\n"); else - ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n", - GetLastError()); - + { + ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError()); + ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, + "got %u\n", GetLastError()); + } set_default_proxy_reg_value( saved_proxy_settings, len, type ); } @@ -1248,6 +1318,8 @@ static void test_Timeouts (void) SetLastError(0xdeadbeef); ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1); ok(ret, "%u\n", GetLastError()); + ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, + "expected ERROR_SUCCESS, got %u\n", GetLastError()); SetLastError(0xdeadbeef); ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0); @@ -2183,14 +2255,20 @@ static void test_basic_authentication(int port) ok(status == 401, "request failed unexpectedly %u\n", status); supported = first = target = 0xdeadbeef; + SetLastError(0xdeadbeef); ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); - ok(ret, "failed to query authentication schemes %u\n", GetLastError()); + error = GetLastError(); + ok(ret, "failed to query authentication schemes %u\n", error); + ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error); ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported); ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first); ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target); + SetLastError(0xdeadbeef); ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL); - ok(ret, "failed to set credentials %u\n", GetLastError()); + error = GetLastError(); + ok(ret, "failed to set credentials %u\n", error); + ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error); ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL); ok(ret, "failed to set credentials %u\n", GetLastError()); @@ -2395,18 +2473,23 @@ static void test_no_content(int port) ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, 0); ok(!ret, "expected no content-length header\n"); - ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, - "wrong error %u\n", GetLastError() ); + ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError()); ok(status == 12345, "expected 0, got %d\n", status); + SetLastError(0xdeadbeef); size = 12345; ret = WinHttpQueryDataAvailable(req, &size); ok(ret, "expected success\n"); - ok(size == 0, "expected 0, got %d\n", size); + ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, + "wrong error %u\n", GetLastError()); + ok(!size, "expected 0, got %u\n", size); + SetLastError(0xdeadbeef); ret = WinHttpReadData(req, buf, len, &bytes_read); ok(ret, "expected success\n"); - ok( bytes_read == 0, "expected 0, got %u available\n", bytes_read ); + ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, + "wrong error %u\n", GetLastError()); + ok(!bytes_read, "expected 0, got %u\n", bytes_read); size = 12345; ret = WinHttpQueryDataAvailable(req, &size); @@ -3459,6 +3542,7 @@ if (0) /* crashes on some win2k systems */ } else { + ok( error == ERROR_SUCCESS, "got %u\n", error ); trace("%s\n", wine_dbgstr_w(url)); GlobalFree( url ); } @@ -3478,8 +3562,12 @@ static void test_WinHttpGetIEProxyConfigForCurrentUser(void) ok( !ret, "expected failure\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + SetLastError(0xdeadbeef); ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg ); + error = GetLastError(); ok( ret, "expected success\n" ); + ok( error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* < win7 */, "got %u\n", error ); + trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect); trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl)); trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy)); @@ -3566,9 +3654,12 @@ static void test_WinHttpGetProxyForUrl(void) options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A; memset( &info, 0, sizeof(info) ); + SetLastError(0xdeadbeef); ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); + error = GetLastError(); if (ret) { + ok( error == ERROR_SUCCESS, "got %u\n", error ); trace("Proxy.AccessType=%u\n", info.dwAccessType); trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy)); trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass)); diff --git a/dlls/winhttp/url.c b/dlls/winhttp/url.c index 2f0cf98..8469ea3 100644 --- a/dlls/winhttp/url.c +++ b/dlls/winhttp/url.c @@ -304,6 +304,7 @@ exit: if (ret) uc->nScheme = scheme; heap_free( url_decoded ); heap_free( url_escaped ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -522,5 +523,6 @@ BOOL WINAPI WinHttpCreateUrl( LPURL_COMPONENTS uc, DWORD flags, LPWSTR url, LPDW } } *url = 0; + set_last_error( ERROR_SUCCESS ); return TRUE; }