mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
winhttp: Implement IWinHttpRequest::Open.
This commit is contained in:
parent
6865dac3fa
commit
4aeec1b88d
@ -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;
|
||||
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user