Hans Leidekker : winhttp: Implement IWinHttpRequest::Open.

Alexandre Julliard julliard at winehq.org
Thu Jul 21 10:50:49 CDT 2011


Module: wine
Branch: master
Commit: 4aeec1b88de11b171fe8746e2a34f20dc9ac4211
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4aeec1b88de11b171fe8746e2a34f20dc9ac4211

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Thu Jul 21 11:50:45 2011 +0200

winhttp: Implement IWinHttpRequest::Open.

---

 dlls/winhttp/request.c         |   88 ++++++++++++++++++++++++++++++++++++++-
 dlls/winhttp/winhttp_private.h |   31 ++++++++++++++
 2 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index c936fdd..2608119 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -2137,10 +2137,25 @@ BOOL WINAPI WinHttpWriteData( HINTERNET hrequest, LPCVOID buffer, DWORD to_write
     return ret;
 }
 
+enum request_state
+{
+    REQUEST_STATE_INVALID,
+    REQUEST_STATE_OPEN,
+    REQUEST_STATE_SENT,
+    REQUEST_STATE_RESPONSE_RECEIVED,
+    REQUEST_STATE_BODY_RECEIVED
+};
+
 struct winhttp_request
 {
     IWinHttpRequest IWinHttpRequest_iface;
     LONG refs;
+    enum request_state state;
+    HINTERNET hsession;
+    HINTERNET hconnect;
+    HINTERNET hrequest;
+    HANDLE wait;
+    HANDLE cancel;
 };
 
 static inline struct winhttp_request *impl_from_IWinHttpRequest( IWinHttpRequest *iface )
@@ -2163,6 +2178,11 @@ static ULONG WINAPI winhttp_request_Release(
     if (!refs)
     {
         TRACE("destroying %p\n", request);
+        WinHttpCloseHandle( request->hrequest );
+        WinHttpCloseHandle( request->hconnect );
+        WinHttpCloseHandle( request->hsession );
+        CloseHandle( request->wait );
+        CloseHandle( request->cancel );
         heap_free( request );
     }
     return refs;
@@ -2342,8 +2362,70 @@ static HRESULT WINAPI winhttp_request_Open(
     BSTR url,
     VARIANT async )
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    struct winhttp_request *request = impl_from_IWinHttpRequest( iface );
+    HINTERNET hsession = NULL, hconnect = NULL, hrequest;
+    URL_COMPONENTS uc;
+    WCHAR *hostname, *path;
+    DWORD err, flags = 0;
+
+    TRACE("%p, %s, %s, %s\n", request, debugstr_w(method), debugstr_w(url),
+          debugstr_variant(&async));
+
+    if (!method) return E_INVALIDARG;
+
+    memset( &uc, 0, sizeof(uc) );
+    uc.dwStructSize = sizeof(uc);
+    uc.dwHostNameLength = ~0u;
+    uc.dwUrlPathLength  = ~0u;
+    if (!WinHttpCrackUrl( url, 0, 0, &uc )) return HRESULT_FROM_WIN32( GetLastError() );
+
+    if (!(hostname = heap_alloc( (uc.dwHostNameLength + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
+    memcpy( hostname, uc.lpszHostName, uc.dwHostNameLength * sizeof(WCHAR) );
+    hostname[uc.dwHostNameLength] = 0;
+    if (!(path = heap_alloc( (uc.dwUrlPathLength + 1) * sizeof(WCHAR) )))
+    {
+        heap_free( hostname );
+        return E_OUTOFMEMORY;
+    }
+    memcpy( path, uc.lpszUrlPath, uc.dwUrlPathLength * sizeof(WCHAR) );
+    path[uc.dwUrlPathLength] = 0;
+
+    if (V_BOOL( &async ) == VARIANT_TRUE) flags |= WINHTTP_FLAG_ASYNC;
+    if (!(hsession = WinHttpOpen( NULL, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, flags )))
+    {
+        err = GetLastError();
+        goto error;
+    }
+    if (!(hconnect = WinHttpConnect( hsession, hostname, uc.nPort, 0 )))
+    {
+        err = GetLastError();
+        goto error;
+    }
+    if (!(hrequest = WinHttpOpenRequest( hconnect, method, path, NULL, NULL, NULL, 0 )))
+    {
+        err = GetLastError();
+        goto error;
+    }
+    if (flags & WINHTTP_FLAG_ASYNC)
+    {
+        request->wait   = CreateEventW( NULL, FALSE, FALSE, NULL );
+        request->cancel = CreateEventW( NULL, FALSE, FALSE, NULL );
+        WinHttpSetOption( hrequest, WINHTTP_OPTION_CONTEXT_VALUE, &request, sizeof(request) );
+    }
+    request->state = REQUEST_STATE_OPEN;
+    request->hsession = hsession;
+    request->hconnect = hconnect;
+    request->hrequest = hrequest;
+    heap_free( hostname );
+    heap_free( path );
+    return S_OK;
+
+error:
+    WinHttpCloseHandle( hconnect );
+    WinHttpCloseHandle( hsession );
+    heap_free( hostname );
+    heap_free( path );
+    return HRESULT_FROM_WIN32( err );
 }
 
 static HRESULT WINAPI winhttp_request_SetRequestHeader(
@@ -2517,7 +2599,7 @@ HRESULT WinHttpRequest_create( IUnknown *unknown, void **obj )
 
     TRACE("%p, %p\n", unknown, obj);
 
-    if (!(request = heap_alloc( sizeof(*request) ))) return E_OUTOFMEMORY;
+    if (!(request = heap_alloc_zero( sizeof(*request) ))) return E_OUTOFMEMORY;
     request->IWinHttpRequest_iface.lpVtbl = &winhttp_request_vtbl;
     request->refs = 1;
 
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index 7607174..4bac24f 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -240,6 +240,37 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT
 
 extern HRESULT WinHttpRequest_create( IUnknown *, void ** ) DECLSPEC_HIDDEN;
 
+static inline const char *debugstr_variant( const VARIANT *v )
+{
+    if (!v) return "(null)";
+    switch (V_VT(v))
+    {
+    case VT_EMPTY:
+        return "{VT_EMPTY}";
+    case VT_NULL:
+        return "{VT_NULL}";
+    case VT_I4:
+        return wine_dbg_sprintf( "{VT_I4: %d}", V_I4(v) );
+    case VT_R8:
+        return wine_dbg_sprintf( "{VT_R8: %lf}", V_R8(v) );
+    case VT_BSTR:
+        return wine_dbg_sprintf( "{VT_BSTR: %s}", debugstr_w(V_BSTR(v)) );
+    case VT_DISPATCH:
+        return wine_dbg_sprintf( "{VT_DISPATCH: %p}", V_DISPATCH(v) );
+    case VT_BOOL:
+        return wine_dbg_sprintf( "{VT_BOOL: %x}", V_BOOL(v) );
+    case VT_UNKNOWN:
+        return wine_dbg_sprintf( "{VT_UNKNOWN: %p}", V_UNKNOWN(v) );
+    case VT_UINT:
+        return wine_dbg_sprintf( "{VT_UINT: %u}", V_UINT(v) );
+    case VT_BSTR|VT_BYREF:
+        return wine_dbg_sprintf( "{VT_BSTR|VT_BYREF: ptr %p, data %s}",
+            V_BSTRREF(v), V_BSTRREF(v) ? debugstr_w( *V_BSTRREF(v) ) : NULL );
+    default:
+        return wine_dbg_sprintf( "{vt %d}", V_VT(v) );
+    }
+}
+
 static inline void *heap_alloc( SIZE_T size )
 {
     return HeapAlloc( GetProcessHeap(), 0, size );




More information about the wine-cvs mailing list