[WINHTTP] Sync with Wine Staging 1.7.55. CORE-10536
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 22 Nov 2015 10:13:38 +0000 (10:13 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 22 Nov 2015 10:13:38 +0000 (10:13 +0000)
svn path=/trunk/; revision=70007

reactos/dll/win32/winhttp/request.c
reactos/dll/win32/winhttp/session.c
reactos/dll/win32/winhttp/url.c
reactos/dll/win32/winhttp/winhttp_private.h
reactos/media/doc/README.WINE

index a2fa48a..fff0a1d 100644 (file)
@@ -28,6 +28,7 @@
 #include <assert.h>
 #include <winuser.h>
 #include <httprequest.h>
+#include <httprequestid.h>
 
 #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");
 
index 02c7ae7..6ac5622 100644 (file)
@@ -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;
index 07be103..c191c13 100644 (file)
@@ -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;
 }
index 052c0a5..2df4f47 100644 (file)
@@ -125,6 +125,7 @@ typedef struct
     LPWSTR proxy_username;
     LPWSTR proxy_password;
     struct list cookie_cache;
+    HANDLE unload_event;
 } session_t;
 
 typedef struct
index 1cadcf7..73d3073 100644 (file)
@@ -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