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