From: Amine Khaldi Date: Sun, 22 Nov 2015 10:13:38 +0000 (+0000) Subject: [WINHTTP] Sync with Wine Staging 1.7.55. CORE-10536 X-Git-Tag: ReactOS-0.4.0~60^2~100 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=19bc65b1acb664bcbdafada19fdcbedd15acb404 [WINHTTP] Sync with Wine Staging 1.7.55. CORE-10536 svn path=/trunk/; revision=70007 --- diff --git a/reactos/dll/win32/winhttp/request.c b/reactos/dll/win32/winhttp/request.c index a2fa48afcaa..fff0a1dae45 100644 --- a/reactos/dll/win32/winhttp/request.c +++ b/reactos/dll/win32/winhttp/request.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "inet_ntop.c" @@ -206,6 +207,11 @@ static DWORD CALLBACK task_proc( LPVOID param ) } case WAIT_OBJECT_0 + 1: TRACE("exiting\n"); + CloseHandle( request->task_cancel ); + CloseHandle( request->task_wait ); + request->task_cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &request->task_cs ); + request->hdr.vtbl->destroy( &request->hdr ); return 0; default: @@ -525,6 +531,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; } @@ -655,11 +662,8 @@ static BOOL query_headers( request_t *request, DWORD level, LPCWSTR name, LPVOID if (!(p = headers)) return FALSE; for (len = 0; *p; p++) if (*p != '\r') len++; - if (!buffer || (len + 1) * sizeof(WCHAR) > *buflen) - { - len++; + if (!buffer || len * sizeof(WCHAR) > *buflen) set_last_error( ERROR_INSUFFICIENT_BUFFER ); - } else { for (p = headers, q = buffer; *p; p++, q++) @@ -671,8 +675,8 @@ static BOOL query_headers( request_t *request, DWORD level, LPCWSTR name, LPVOID p++; /* skip '\n' */ } } - *q = 0; TRACE("returning data: %s\n", debugstr_wn(buffer, len)); + if (len) len--; ret = TRUE; } *buflen = len * sizeof(WCHAR); @@ -832,6 +836,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; } @@ -1036,7 +1041,7 @@ static BOOL open_connection( request_t *request ) return FALSE; } } - if (!netconn_secure_connect( &request->netconn, connect->servername )) + if (!netconn_secure_connect( &request->netconn, connect->hostname )) { netconn_close( &request->netconn ); heap_free( addressW ); @@ -1249,6 +1254,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; } @@ -1373,6 +1379,7 @@ BOOL WINAPI WinHttpQueryAuthSchemes( HINTERNET hrequest, LPDWORD supported, LPDW } release_object( &request->hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1827,6 +1834,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; } @@ -2072,19 +2080,17 @@ static BOOL read_reply( request_t *request ) static const WCHAR crlf[] = {'\r','\n',0}; char buffer[MAX_REPLY_LEN]; - DWORD buflen, len, offset, received_len, crlf_len = 2; /* strlenW(crlf) */ + DWORD buflen, len, offset, crlf_len = 2; /* strlenW(crlf) */ char *status_code, *status_text; WCHAR *versionW, *status_textW, *raw_headers; WCHAR status_codeW[4]; /* sizeof("nnn") */ if (!netconn_connected( &request->netconn )) return FALSE; - received_len = 0; do { buflen = MAX_REPLY_LEN; if (!read_line( request, buffer, &buflen )) return FALSE; - received_len += buflen; /* first line should look like 'HTTP/1.x nnn OK' where nnn is the status code */ if (!(status_code = strchr( buffer, ' ' ))) return FALSE; @@ -2137,8 +2143,7 @@ static BOOL read_reply( request_t *request ) buflen = MAX_REPLY_LEN; if (!read_line( request, buffer, &buflen )) return TRUE; - received_len += buflen; - if (!*buffer) break; + if (!*buffer) buflen = 1; while (len - offset < buflen + crlf_len) { @@ -2147,6 +2152,11 @@ static BOOL read_reply( request_t *request ) if (!(tmp = heap_realloc( raw_headers, len * sizeof(WCHAR) ))) return FALSE; request->raw_headers = raw_headers = tmp; } + if (!*buffer) + { + memcpy( raw_headers + offset, crlf, sizeof(crlf) ); + break; + } MultiByteToWideChar( CP_ACP, 0, buffer, buflen, raw_headers + offset, buflen ); if (!(header = parse_header( raw_headers + offset ))) break; @@ -2469,6 +2479,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; } @@ -2540,6 +2551,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; } @@ -2589,6 +2601,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; } @@ -2660,6 +2673,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; } @@ -2700,6 +2714,7 @@ struct winhttp_request LONG receive_timeout; WINHTTP_PROXY_INFO proxy; BOOL async; + UINT url_codepage; }; static inline struct winhttp_request *impl_from_IWinHttpRequest( IWinHttpRequest *iface ) @@ -2922,6 +2937,48 @@ static HRESULT WINAPI winhttp_request_Invoke( TRACE("%p, %d, %s, %d, %d, %p, %p, %p, %p\n", request, member, debugstr_guid(riid), lcid, flags, params, result, excep_info, arg_err); + if (!IsEqualIID( riid, &IID_NULL )) return DISP_E_UNKNOWNINTERFACE; + + if (member == DISPID_HTTPREQUEST_OPTION) + { + VARIANT ret_value, option; + UINT err_pos; + + if (!result) result = &ret_value; + if (!arg_err) arg_err = &err_pos; + + VariantInit( &option ); + VariantInit( result ); + + if (!flags) return S_OK; + + if (flags == DISPATCH_PROPERTYPUT) + { + hr = DispGetParam( params, 0, VT_I4, &option, arg_err ); + if (FAILED(hr)) return hr; + + hr = IWinHttpRequest_put_Option( &request->IWinHttpRequest_iface, V_I4( &option ), params->rgvarg[0] ); + if (FAILED(hr)) + WARN("put_Option(%d) failed: %x\n", V_I4( &option ), hr); + return hr; + } + else if (flags & (DISPATCH_PROPERTYGET | DISPATCH_METHOD)) + { + hr = DispGetParam( params, 0, VT_I4, &option, arg_err ); + if (FAILED(hr)) return hr; + + hr = IWinHttpRequest_get_Option( &request->IWinHttpRequest_iface, V_I4( &option ), result ); + if (FAILED(hr)) + WARN("get_Option(%d) failed: %x\n", V_I4( &option ), hr); + return hr; + } + + FIXME("unsupported flags %x\n", flags); + return E_NOTIMPL; + } + + /* fallback to standard implementation */ + hr = get_typeinfo( IWinHttpRequest_tid, &typeinfo ); if (SUCCEEDED(hr)) { @@ -3048,6 +3105,7 @@ static void initialize_request( struct winhttp_request *request ) request->connect_timeout = 60000; request->send_timeout = 30000; request->receive_timeout = 30000; + request->url_codepage = CP_UTF8; VariantInit( &request->data ); request->state = REQUEST_STATE_INITIALIZED; } @@ -3068,6 +3126,7 @@ static void reset_request( struct winhttp_request *request ) request->bytes_read = 0; request->error = ERROR_SUCCESS; request->async = FALSE; + request->url_codepage = CP_UTF8; VariantClear( &request->data ); request->state = REQUEST_STATE_INITIALIZED; } @@ -3973,8 +4032,25 @@ static HRESULT WINAPI winhttp_request_get_Option( WinHttpRequestOption option, VARIANT *value ) { - FIXME("\n"); - return E_NOTIMPL; + struct winhttp_request *request = impl_from_IWinHttpRequest( iface ); + HRESULT hr = S_OK; + + TRACE("%p, %u, %p\n", request, option, value); + + EnterCriticalSection( &request->cs ); + switch (option) + { + case WinHttpRequestOption_URLCodePage: + V_VT( value ) = VT_I4; + V_I4( value ) = request->url_codepage; + break; + default: + FIXME("unimplemented option %u\n", option); + hr = E_NOTIMPL; + break; + } + LeaveCriticalSection( &request->cs ); + return hr; } static HRESULT WINAPI winhttp_request_put_Option( @@ -3998,6 +4074,28 @@ static HRESULT WINAPI winhttp_request_put_Option( request->disable_feature |= WINHTTP_DISABLE_REDIRECTS; break; } + case WinHttpRequestOption_URLCodePage: + { + static const WCHAR utf8W[] = {'u','t','f','-','8',0}; + VARIANT cp; + + VariantInit( &cp ); + hr = VariantChangeType( &cp, &value, 0, VT_UI4 ); + if (SUCCEEDED( hr )) + { + request->url_codepage = V_UI4( &cp ); + TRACE("URL codepage: %u\n", request->url_codepage); + } + else if (V_VT( &value ) == VT_BSTR && !strcmpiW( V_BSTR( &value ), utf8W )) + { + TRACE("URL codepage: UTF-8\n"); + request->url_codepage = CP_UTF8; + hr = S_OK; + } + else + FIXME("URL codepage %s is not recognized\n", debugstr_variant( &value )); + break; + } default: FIXME("unimplemented option %u\n", option); hr = E_NOTIMPL; @@ -4151,6 +4249,7 @@ HRESULT WinHttpRequest_create( void **obj ) request->state = REQUEST_STATE_UNINITIALIZED; request->proxy.lpszProxy = NULL; request->proxy.lpszProxyBypass = NULL; + request->url_codepage = CP_UTF8; InitializeCriticalSection( &request->cs ); request->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": winhttp_request.cs"); diff --git a/reactos/dll/win32/winhttp/session.c b/reactos/dll/win32/winhttp/session.c index 02c7ae7cb55..6ac56220cc5 100644 --- a/reactos/dll/win32/winhttp/session.c +++ b/reactos/dll/win32/winhttp/session.c @@ -70,6 +70,8 @@ static void session_destroy( object_header_t *hdr ) TRACE("%p\n", session); + if (session->unload_event) SetEvent( session->unload_event ); + LIST_FOR_EACH_SAFE( item, next, &session->cookie_cache ) { domain = LIST_ENTRY( item, domain_t, entry ); @@ -174,6 +176,10 @@ static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffe case WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH: FIXME("WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH: 0x%x\n", *(DWORD *)buffer); return TRUE; + case WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT: + TRACE("WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT: %p\n", *(HANDLE *)buffer); + session->unload_event = *(HANDLE *)buffer; + return TRUE; default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_INVALID_PARAMETER ); @@ -250,6 +256,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; } @@ -526,6 +533,7 @@ end: release_object( &connect->hdr ); release_object( &session->hdr ); TRACE("returning %p\n", hconnect); + if (hconnect) set_last_error( ERROR_SUCCESS ); return hconnect; } @@ -541,13 +549,13 @@ static void request_destroy( object_header_t *hdr ) if (request->task_thread) { + /* Signal to the task proc to quit. It will call + this again when it does. */ + HANDLE thread = request->task_thread; + request->task_thread = 0; SetEvent( request->task_cancel ); - WaitForSingleObject( request->task_thread, INFINITE ); - CloseHandle( request->task_thread ); - CloseHandle( request->task_cancel ); - CloseHandle( request->task_wait ); - request->task_cs.DebugInfo->Spare[0] = 0; - DeleteCriticalSection( &request->task_cs ); + CloseHandle( thread ); + return; } release_object( &request->connect->hdr ); @@ -1101,6 +1109,7 @@ end: release_object( &request->hdr ); release_object( &connect->hdr ); TRACE("returning %p\n", hrequest); + if (hrequest) set_last_error( ERROR_SUCCESS ); return hrequest; } @@ -1120,6 +1129,7 @@ BOOL WINAPI WinHttpCloseHandle( HINTERNET handle ) } release_object( hdr ); free_handle( handle ); + set_last_error( ERROR_SUCCESS ); return TRUE; } @@ -1180,6 +1190,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; } @@ -1238,6 +1249,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; } @@ -1348,6 +1360,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) @@ -1408,6 +1421,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; } @@ -1575,6 +1589,7 @@ BOOL WINAPI WinHttpGetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info ) info->lpszProxy = NULL; info->lpszProxyBypass = NULL; } + set_last_error( ERROR_SUCCESS ); return TRUE; } @@ -1657,6 +1672,7 @@ done: GlobalFree( config->lpszProxyBypass ); config->lpszProxyBypass = NULL; } + else set_last_error( ERROR_SUCCESS ); return ret; } @@ -1841,6 +1857,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; } @@ -1948,6 +1965,7 @@ BOOL WINAPI WinHttpSetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info ) } RegCloseKey( key ); } + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -1972,6 +1990,7 @@ WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback( HINTERNET handle, WINHT hdr->notify_mask = flags; release_object( hdr ); + set_last_error( ERROR_SUCCESS ); return ret; } @@ -2019,8 +2038,6 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int if (netconn_set_timeout( &request->netconn, TRUE, send )) ret = FALSE; if (netconn_set_timeout( &request->netconn, FALSE, receive )) ret = FALSE; } - - release_object( &request->hdr ); break; case WINHTTP_HANDLE_TYPE_SESSION: @@ -2038,10 +2055,11 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int break; default: - release_object( hdr ); set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); - return FALSE; + ret = FALSE; } + release_object( hdr ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -2064,7 +2082,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], @@ -2075,6 +2097,7 @@ BOOL WINAPI WinHttpTimeFromSystemTime( const SYSTEMTIME *time, LPWSTR string ) time->wMinute, time->wSecond ); + set_last_error( ERROR_SUCCESS ); return TRUE; } @@ -2089,7 +2112,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 ); @@ -2098,6 +2125,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/reactos/dll/win32/winhttp/url.c b/reactos/dll/win32/winhttp/url.c index 07be103dfbc..c191c1320b1 100644 --- a/reactos/dll/win32/winhttp/url.c +++ b/reactos/dll/win32/winhttp/url.c @@ -291,6 +291,7 @@ exit: if (ret) uc->nScheme = scheme; heap_free( url_decoded ); heap_free( url_escaped ); + if (ret) set_last_error( ERROR_SUCCESS ); return ret; } @@ -509,5 +510,6 @@ BOOL WINAPI WinHttpCreateUrl( LPURL_COMPONENTS uc, DWORD flags, LPWSTR url, LPDW } } *url = 0; + set_last_error( ERROR_SUCCESS ); return TRUE; } diff --git a/reactos/dll/win32/winhttp/winhttp_private.h b/reactos/dll/win32/winhttp/winhttp_private.h index 052c0a5f8a8..2df4f473476 100644 --- a/reactos/dll/win32/winhttp/winhttp_private.h +++ b/reactos/dll/win32/winhttp/winhttp_private.h @@ -125,6 +125,7 @@ typedef struct LPWSTR proxy_username; LPWSTR proxy_password; struct list cookie_cache; + HANDLE unload_event; } session_t; typedef struct diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 1cadcf78a96..73d30734b39 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -204,7 +204,7 @@ reactos/dll/win32/windowscodecs # Synced to WineStaging-1.7.47 reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.7.47 reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.7.47 reactos/dll/win32/wing32 # Synced to WineStaging-1.7.55 -reactos/dll/win32/winhttp # Synced to WineStaging-1.7.47 +reactos/dll/win32/winhttp # Synced to WineStaging-1.7.55 reactos/dll/win32/wininet # Synced to WineStaging-1.7.47 reactos/dll/win32/winmm # Forked at Wine-20050628 reactos/dll/win32/winmm/midimap # Forked at Wine-20050628