mirror of
https://github.com/reactos/reactos.git
synced 2024-08-01 09:01:13 +00:00
Synced winhttp.dll with Wine HEAD using stuff and methods from wininet.dll.
It helps Chrome setup starting (but not working yet). svn path=/trunk/; revision=36016
This commit is contained in:
parent
d158ab5aa3
commit
51ee2d9ff9
159
reactos/dll/win32/winhttp/handle.c
Normal file
159
reactos/dll/win32/winhttp/handle.c
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2008 Hans Leidekker for CodeWeavers
|
||||||
|
*
|
||||||
|
* Based on the handle implementation from wininet.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winhttp.h"
|
||||||
|
|
||||||
|
#include "winhttp_private.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
|
||||||
|
|
||||||
|
#define HANDLE_CHUNK_SIZE 0x10
|
||||||
|
|
||||||
|
static CRITICAL_SECTION handle_cs;
|
||||||
|
static CRITICAL_SECTION_DEBUG handle_cs_debug =
|
||||||
|
{
|
||||||
|
0, 0, &handle_cs,
|
||||||
|
{ &handle_cs_debug.ProcessLocksList, &handle_cs_debug.ProcessLocksList },
|
||||||
|
0, 0, { (ULONG_PTR)(__FILE__ ": handle_cs") }
|
||||||
|
};
|
||||||
|
static CRITICAL_SECTION handle_cs = { &handle_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
static object_header_t **handles;
|
||||||
|
static ULONG_PTR next_handle;
|
||||||
|
static ULONG_PTR max_handles;
|
||||||
|
|
||||||
|
object_header_t *addref_object( object_header_t *hdr )
|
||||||
|
{
|
||||||
|
ULONG refs = InterlockedIncrement( &hdr->refs );
|
||||||
|
TRACE("%p -> refcount = %d\n", hdr, refs);
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_header_t *grab_object( HINTERNET hinternet )
|
||||||
|
{
|
||||||
|
object_header_t *hdr = NULL;
|
||||||
|
ULONG_PTR handle = (ULONG_PTR)hinternet;
|
||||||
|
|
||||||
|
EnterCriticalSection( &handle_cs );
|
||||||
|
|
||||||
|
if ((handle > 0) && (handle <= max_handles) && handles[handle - 1])
|
||||||
|
hdr = addref_object( handles[handle - 1] );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &handle_cs );
|
||||||
|
|
||||||
|
TRACE("handle 0x%lx -> %p\n", handle, hdr);
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_object( object_header_t *hdr )
|
||||||
|
{
|
||||||
|
ULONG refs = InterlockedDecrement( &hdr->refs );
|
||||||
|
TRACE("object %p refcount = %d\n", hdr, refs);
|
||||||
|
if (!refs)
|
||||||
|
{
|
||||||
|
if (hdr->type == WINHTTP_HANDLE_TYPE_REQUEST) close_connection( (request_t *)hdr );
|
||||||
|
|
||||||
|
send_callback( hdr, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, &hdr->handle, sizeof(HINTERNET) );
|
||||||
|
|
||||||
|
TRACE("destroying object %p\n", hdr);
|
||||||
|
if (hdr->type != WINHTTP_HANDLE_TYPE_SESSION) list_remove( &hdr->entry );
|
||||||
|
hdr->vtbl->destroy( hdr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HINTERNET alloc_handle( object_header_t *hdr )
|
||||||
|
{
|
||||||
|
object_header_t **p;
|
||||||
|
ULONG_PTR handle = 0, num;
|
||||||
|
|
||||||
|
list_init( &hdr->children );
|
||||||
|
|
||||||
|
EnterCriticalSection( &handle_cs );
|
||||||
|
if (!max_handles)
|
||||||
|
{
|
||||||
|
num = HANDLE_CHUNK_SIZE;
|
||||||
|
if (!(p = heap_alloc_zero( sizeof(ULONG_PTR) * num ))) goto end;
|
||||||
|
handles = p;
|
||||||
|
max_handles = num;
|
||||||
|
}
|
||||||
|
if (max_handles == next_handle)
|
||||||
|
{
|
||||||
|
num = max_handles + HANDLE_CHUNK_SIZE;
|
||||||
|
if (!(p = heap_realloc_zero( handles, sizeof(ULONG_PTR) * num ))) goto end;
|
||||||
|
handles = p;
|
||||||
|
max_handles = num;
|
||||||
|
}
|
||||||
|
handle = next_handle;
|
||||||
|
if (handles[handle]) ERR("handle isn't free but should be\n");
|
||||||
|
|
||||||
|
handles[handle] = addref_object( hdr );
|
||||||
|
while (handles[next_handle] && (next_handle < max_handles)) next_handle++;
|
||||||
|
|
||||||
|
end:
|
||||||
|
LeaveCriticalSection( &handle_cs );
|
||||||
|
return hdr->handle = (HINTERNET)(handle + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL free_handle( HINTERNET hinternet )
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
ULONG_PTR handle = (ULONG_PTR)hinternet;
|
||||||
|
object_header_t *hdr = NULL, *child, *next;
|
||||||
|
|
||||||
|
EnterCriticalSection( &handle_cs );
|
||||||
|
|
||||||
|
if ((handle > 0) && (handle <= max_handles))
|
||||||
|
{
|
||||||
|
handle--;
|
||||||
|
if (handles[handle])
|
||||||
|
{
|
||||||
|
hdr = handles[handle];
|
||||||
|
TRACE("destroying handle 0x%lx for object %p\n", handle + 1, hdr);
|
||||||
|
handles[handle] = NULL;
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &handle_cs );
|
||||||
|
|
||||||
|
if (hdr)
|
||||||
|
{
|
||||||
|
LIST_FOR_EACH_ENTRY_SAFE( child, next, &hdr->children, object_header_t, entry )
|
||||||
|
{
|
||||||
|
TRACE("freeing child handle %p for parent handle 0x%lx\n", child->handle, handle + 1);
|
||||||
|
free_handle( child->handle );
|
||||||
|
}
|
||||||
|
release_object( hdr );
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection( &handle_cs );
|
||||||
|
if (next_handle > handle && !handles[handle]) next_handle = handle;
|
||||||
|
LeaveCriticalSection( &handle_cs );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
192
reactos/dll/win32/winhttp/inet_ntop.c
Normal file
192
reactos/dll/win32/winhttp/inet_ntop.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
/* from NetBSD: inet_ntop.c,v 1.9 2000/01/22 22:19:16 mycroft Exp */
|
||||||
|
|
||||||
|
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||||
|
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||||
|
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||||
|
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ENOSPC 28
|
||||||
|
#define EAFNOSUPPORT 52
|
||||||
|
|
||||||
|
#ifndef IN6ADDRSZ
|
||||||
|
#define IN6ADDRSZ 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INT16SZ
|
||||||
|
#define INT16SZ 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SPRINTF_CHAR
|
||||||
|
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||||
|
#else
|
||||||
|
# define SPRINTF(x) ((size_t)sprintf x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING: Don't even consider trying to compile this on a system where
|
||||||
|
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
|
||||||
|
|
||||||
|
#ifdef INET6
|
||||||
|
static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* char *
|
||||||
|
* inet_ntop(af, src, dst, size)
|
||||||
|
* convert a network format address to presentation format.
|
||||||
|
* return:
|
||||||
|
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||||
|
* author:
|
||||||
|
* Paul Vixie, 1996.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (af) {
|
||||||
|
case AF_INET:
|
||||||
|
return (inet_ntop4(src, dst, size));
|
||||||
|
#ifdef INET6
|
||||||
|
case AF_INET6:
|
||||||
|
return (inet_ntop6(src, dst, size));
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* const char *
|
||||||
|
* inet_ntop4(src, dst, size)
|
||||||
|
* format an IPv4 address, more or less like inet_ntoa()
|
||||||
|
* return:
|
||||||
|
* `dst' (as a const)
|
||||||
|
* notes:
|
||||||
|
* (1) uses no statics
|
||||||
|
* (2) takes a u_char* not an in_addr as input
|
||||||
|
* author:
|
||||||
|
* Paul Vixie, 1996.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
inet_ntop4(const u_char *src, char *dst, size_t size)
|
||||||
|
{
|
||||||
|
static const char fmt[] = "%u.%u.%u.%u";
|
||||||
|
char tmp[sizeof "255.255.255.255"];
|
||||||
|
|
||||||
|
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
strcpy(dst, tmp);
|
||||||
|
return (dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef INET6
|
||||||
|
/* const char *
|
||||||
|
* inet_ntop6(src, dst, size)
|
||||||
|
* convert IPv6 binary address into presentation (printable) format
|
||||||
|
* author:
|
||||||
|
* Paul Vixie, 1996.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
inet_ntop6(const u_char *src, char *dst, size_t size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Note that int32_t and int16_t need only be "at least" large enough
|
||||||
|
* to contain a value of the specified size. On some systems, like
|
||||||
|
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||||
|
* Keep this in mind if you think this function should have been coded
|
||||||
|
* to use pointer overlays. All the world's not a VAX.
|
||||||
|
*/
|
||||||
|
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||||
|
struct { int base, len; } best, cur;
|
||||||
|
u_int words[IN6ADDRSZ / INT16SZ];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Preprocess:
|
||||||
|
* Copy the input (bytewise) array into a wordwise array.
|
||||||
|
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||||
|
*/
|
||||||
|
memset(words, '\0', sizeof words);
|
||||||
|
for (i = 0; i < IN6ADDRSZ; i++)
|
||||||
|
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||||
|
best.base = -1;
|
||||||
|
cur.base = -1;
|
||||||
|
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||||
|
if (words[i] == 0) {
|
||||||
|
if (cur.base == -1)
|
||||||
|
cur.base = i, cur.len = 1;
|
||||||
|
else
|
||||||
|
cur.len++;
|
||||||
|
} else {
|
||||||
|
if (cur.base != -1) {
|
||||||
|
if (best.base == -1 || cur.len > best.len)
|
||||||
|
best = cur;
|
||||||
|
cur.base = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cur.base != -1) {
|
||||||
|
if (best.base == -1 || cur.len > best.len)
|
||||||
|
best = cur;
|
||||||
|
}
|
||||||
|
if (best.base != -1 && best.len < 2)
|
||||||
|
best.base = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format the result.
|
||||||
|
*/
|
||||||
|
tp = tmp;
|
||||||
|
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||||
|
/* Are we inside the best run of 0x00's? */
|
||||||
|
if (best.base != -1 && i >= best.base &&
|
||||||
|
i < (best.base + best.len)) {
|
||||||
|
if (i == best.base)
|
||||||
|
*tp++ = ':';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Are we following an initial run of 0x00s or any real hex? */
|
||||||
|
if (i != 0)
|
||||||
|
*tp++ = ':';
|
||||||
|
/* Is this address an encapsulated IPv4? */
|
||||||
|
if (i == 6 && best.base == 0 &&
|
||||||
|
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||||
|
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||||
|
return (NULL);
|
||||||
|
tp += strlen(tp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tp += SPRINTF((tp, "%x", words[i]));
|
||||||
|
}
|
||||||
|
/* Was it a trailing run of 0x00's? */
|
||||||
|
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
|
||||||
|
*tp++ = ':';
|
||||||
|
*tp++ = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for overflow, copy, and we're done.
|
||||||
|
*/
|
||||||
|
if ((size_t)(tp - tmp) > size) {
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
strcpy(dst, tmp);
|
||||||
|
return (dst);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
#include "winhttp_private.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
|
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
@ -83,167 +85,40 @@ HRESULT WINAPI DllUnregisterServer(void)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SCHEME_HTTP 3
|
||||||
|
#define SCHEME_HTTPS 4
|
||||||
|
|
||||||
|
BOOL WINAPI InternetCrackUrlW( LPCWSTR, DWORD, DWORD, LPURL_COMPONENTSW );
|
||||||
|
BOOL WINAPI InternetCreateUrlW( LPURL_COMPONENTS, DWORD, LPWSTR, LPDWORD );
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* WinHttpCheckPlatform (winhttp.@)
|
* WinHttpCrackUrl (winhttp.@)
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI WinHttpCheckPlatform(void)
|
BOOL WINAPI WinHttpCrackUrl( LPCWSTR url, DWORD len, DWORD flags, LPURL_COMPONENTSW components )
|
||||||
{
|
{
|
||||||
FIXME("stub\n");
|
BOOL ret;
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
|
TRACE("%s, %d, %x, %p\n", debugstr_w(url), len, flags, components);
|
||||||
|
|
||||||
|
if ((ret = InternetCrackUrlW( url, len, flags, components )))
|
||||||
|
{
|
||||||
|
/* fix up an incompatibility between wininet and winhttp */
|
||||||
|
if (components->nScheme == SCHEME_HTTP) components->nScheme = INTERNET_SCHEME_HTTP;
|
||||||
|
else if (components->nScheme == SCHEME_HTTPS) components->nScheme = INTERNET_SCHEME_HTTPS;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_WINHTTP_UNRECOGNIZED_SCHEME );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/***********************************************************************
|
return ret;
|
||||||
* WinHttpDetectAutoProxyConfigUrl (winhttp.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI WinHttpDetectAutoProxyConfigUrl(DWORD flags, LPWSTR *url)
|
|
||||||
{
|
|
||||||
FIXME("(%x %p)\n", flags, url);
|
|
||||||
|
|
||||||
SetLastError(ERROR_WINHTTP_AUTODETECTION_FAILED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* WinHttpGetIEProxyConfigForCurrentUser (winhttp.@)
|
* WinHttpCreateUrl (winhttp.@)
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config)
|
BOOL WINAPI WinHttpCreateUrl( LPURL_COMPONENTS comps, DWORD flags, LPWSTR url, LPDWORD len )
|
||||||
{
|
{
|
||||||
if(!config)
|
TRACE("%p, 0x%08x, %p, %p\n", comps, flags, url, len);
|
||||||
{
|
return InternetCreateUrlW( comps, flags, url, len );
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: read from HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings */
|
|
||||||
FIXME("returning no proxy used\n");
|
|
||||||
config->fAutoDetect = FALSE;
|
|
||||||
config->lpszAutoConfigUrl = NULL;
|
|
||||||
config->lpszProxy = NULL;
|
|
||||||
config->lpszProxyBypass = NULL;
|
|
||||||
|
|
||||||
SetLastError(ERROR_SUCCESS);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpOpen (winhttp.@)
|
|
||||||
*/
|
|
||||||
HINTERNET WINAPI WinHttpOpen(LPCWSTR pwszUserAgent, DWORD dwAccessType,
|
|
||||||
LPCWSTR pwszProxyName, LPCWSTR pwszProxyByPass,
|
|
||||||
DWORD dwFlags)
|
|
||||||
{
|
|
||||||
FIXME("(%s, %d, %s, %s, 0x%x): stub\n", debugstr_w(pwszUserAgent),
|
|
||||||
dwAccessType, debugstr_w(pwszProxyName), debugstr_w(pwszProxyByPass),
|
|
||||||
dwFlags);
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpConnect (winhttp.@)
|
|
||||||
*/
|
|
||||||
|
|
||||||
HINTERNET WINAPI WinHttpConnect (HINTERNET hSession, LPCWSTR pwszServerName,
|
|
||||||
INTERNET_PORT nServerPort, DWORD dwReserved)
|
|
||||||
{
|
|
||||||
FIXME("(%s, %d, 0x%x): stub\n", debugstr_w(pwszServerName), nServerPort, dwReserved);
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpOpenRequest (winhttp.@)
|
|
||||||
*/
|
|
||||||
HINTERNET WINAPI WinHttpOpenRequest (HINTERNET hConnect, LPCWSTR pwszVerb, LPCWSTR pwszObjectName,
|
|
||||||
LPCWSTR pwszVersion, LPCWSTR pwszReferrer, LPCWSTR* ppwszAcceptTypes,
|
|
||||||
DWORD dwFlags)
|
|
||||||
{
|
|
||||||
FIXME("(%s, %s, %s, %s, 0x%x): stub\n", debugstr_w(pwszVerb), debugstr_w(pwszObjectName),
|
|
||||||
debugstr_w(pwszVersion), debugstr_w(pwszReferrer), dwFlags);
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpSendRequest (winhttp.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI WinHttpSendRequest (HINTERNET hRequest, LPCWSTR pwszHeaders, DWORD dwHeadersLength,
|
|
||||||
LPVOID lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength,
|
|
||||||
DWORD_PTR dwContext)
|
|
||||||
{
|
|
||||||
FIXME("(%s, %d, %d, %d): stub\n", debugstr_w(pwszHeaders), dwHeadersLength, dwOptionalLength, dwTotalLength);
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpQueryOption (winhttp.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI WinHttpQueryOption (HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength)
|
|
||||||
{
|
|
||||||
FIXME("(%d): stub\n", dwOption);
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpQueryDataAvailable (winhttp.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI WinHttpQueryDataAvailable (HINTERNET hInternet, LPDWORD lpdwNumberOfBytesAvailable)
|
|
||||||
{
|
|
||||||
FIXME("stub\n");
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpReceiveResponse (winhttp.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI WinHttpReceiveResponse (HINTERNET hRequest, LPVOID lpReserved)
|
|
||||||
{
|
|
||||||
FIXME("stub\n");
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpSetOption (winhttp.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI WinHttpSetOption (HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, DWORD dwBufferLength)
|
|
||||||
{
|
|
||||||
FIXME("stub\n");
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpReadData (winhttp.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI WinHttpReadData (HINTERNET hInternet, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead,
|
|
||||||
LPDWORD lpdwNumberOfBytesRead)
|
|
||||||
{
|
|
||||||
FIXME("(%d): stub\n", dwNumberOfBytesToRead);
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* WinHttpReadData (winhttp.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI WinHttpCloseHandle (HINTERNET hInternet)
|
|
||||||
{
|
|
||||||
FIXME("stub\n");
|
|
||||||
|
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
626
reactos/dll/win32/winhttp/net.c
Normal file
626
reactos/dll/win32/winhttp/net.c
Normal file
|
@ -0,0 +1,626 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2008 Hans Leidekker for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_IOCTL_H
|
||||||
|
# include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_FILIO_H
|
||||||
|
# include <sys/filio.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
# include <poll.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
# include <openssl/ssl.h>
|
||||||
|
#undef FAR
|
||||||
|
#undef DSA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "wine/library.h"
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winhttp.h"
|
||||||
|
|
||||||
|
/* to avoid conflicts with the Unix socket headers */
|
||||||
|
#define USE_WS_PREFIX
|
||||||
|
#include "winsock2.h"
|
||||||
|
|
||||||
|
#include "winhttp_private.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
|
||||||
|
|
||||||
|
#define DEFAULT_SEND_TIMEOUT 30
|
||||||
|
#define DEFAULT_RECEIVE_TIMEOUT 30
|
||||||
|
#define RESPONSE_TIMEOUT 30
|
||||||
|
|
||||||
|
#ifndef HAVE_GETADDRINFO
|
||||||
|
|
||||||
|
/* critical section to protect non-reentrant gethostbyname() */
|
||||||
|
static CRITICAL_SECTION cs_gethostbyname;
|
||||||
|
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
|
{
|
||||||
|
0, 0, &cs_gethostbyname,
|
||||||
|
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||||
|
0, 0, { (DWORD_PTR)(__FILE__ ": cs_gethostbyname") }
|
||||||
|
};
|
||||||
|
static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SONAME_LIBSSL
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
static void *libssl_handle;
|
||||||
|
static void *libcrypto_handle;
|
||||||
|
|
||||||
|
static SSL_METHOD *method;
|
||||||
|
|
||||||
|
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||||
|
|
||||||
|
MAKE_FUNCPTR( SSL_library_init );
|
||||||
|
MAKE_FUNCPTR( SSL_load_error_strings );
|
||||||
|
MAKE_FUNCPTR( SSLv23_method );
|
||||||
|
MAKE_FUNCPTR( SSL_CTX_new );
|
||||||
|
MAKE_FUNCPTR( SSL_CTX_free );
|
||||||
|
MAKE_FUNCPTR( SSL_new );
|
||||||
|
MAKE_FUNCPTR( SSL_free );
|
||||||
|
MAKE_FUNCPTR( SSL_set_fd );
|
||||||
|
MAKE_FUNCPTR( SSL_connect );
|
||||||
|
MAKE_FUNCPTR( SSL_shutdown );
|
||||||
|
MAKE_FUNCPTR( SSL_write );
|
||||||
|
MAKE_FUNCPTR( SSL_read );
|
||||||
|
MAKE_FUNCPTR( SSL_get_verify_result );
|
||||||
|
MAKE_FUNCPTR( SSL_get_peer_certificate );
|
||||||
|
MAKE_FUNCPTR( SSL_CTX_get_timeout );
|
||||||
|
MAKE_FUNCPTR( SSL_CTX_set_timeout );
|
||||||
|
MAKE_FUNCPTR( SSL_CTX_set_default_verify_paths );
|
||||||
|
|
||||||
|
MAKE_FUNCPTR( BIO_new_fp );
|
||||||
|
MAKE_FUNCPTR( ERR_get_error );
|
||||||
|
MAKE_FUNCPTR( ERR_error_string );
|
||||||
|
#undef MAKE_FUNCPTR
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* translate a unix error code into a winsock error code */
|
||||||
|
static int sock_get_error( int err )
|
||||||
|
{
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case EINTR: return WSAEINTR;
|
||||||
|
case EBADF: return WSAEBADF;
|
||||||
|
case EPERM:
|
||||||
|
case EACCES: return WSAEACCES;
|
||||||
|
case EFAULT: return WSAEFAULT;
|
||||||
|
case EINVAL: return WSAEINVAL;
|
||||||
|
case EMFILE: return WSAEMFILE;
|
||||||
|
case EWOULDBLOCK: return WSAEWOULDBLOCK;
|
||||||
|
case EINPROGRESS: return WSAEINPROGRESS;
|
||||||
|
case EALREADY: return WSAEALREADY;
|
||||||
|
case ENOTSOCK: return WSAENOTSOCK;
|
||||||
|
case EDESTADDRREQ: return WSAEDESTADDRREQ;
|
||||||
|
case EMSGSIZE: return WSAEMSGSIZE;
|
||||||
|
case EPROTOTYPE: return WSAEPROTOTYPE;
|
||||||
|
case ENOPROTOOPT: return WSAENOPROTOOPT;
|
||||||
|
case EPROTONOSUPPORT: return WSAEPROTONOSUPPORT;
|
||||||
|
case ESOCKTNOSUPPORT: return WSAESOCKTNOSUPPORT;
|
||||||
|
case EOPNOTSUPP: return WSAEOPNOTSUPP;
|
||||||
|
case EPFNOSUPPORT: return WSAEPFNOSUPPORT;
|
||||||
|
case EAFNOSUPPORT: return WSAEAFNOSUPPORT;
|
||||||
|
case EADDRINUSE: return WSAEADDRINUSE;
|
||||||
|
case EADDRNOTAVAIL: return WSAEADDRNOTAVAIL;
|
||||||
|
case ENETDOWN: return WSAENETDOWN;
|
||||||
|
case ENETUNREACH: return WSAENETUNREACH;
|
||||||
|
case ENETRESET: return WSAENETRESET;
|
||||||
|
case ECONNABORTED: return WSAECONNABORTED;
|
||||||
|
case EPIPE:
|
||||||
|
case ECONNRESET: return WSAECONNRESET;
|
||||||
|
case ENOBUFS: return WSAENOBUFS;
|
||||||
|
case EISCONN: return WSAEISCONN;
|
||||||
|
case ENOTCONN: return WSAENOTCONN;
|
||||||
|
case ESHUTDOWN: return WSAESHUTDOWN;
|
||||||
|
case ETOOMANYREFS: return WSAETOOMANYREFS;
|
||||||
|
case ETIMEDOUT: return WSAETIMEDOUT;
|
||||||
|
case ECONNREFUSED: return WSAECONNREFUSED;
|
||||||
|
case ELOOP: return WSAELOOP;
|
||||||
|
case ENAMETOOLONG: return WSAENAMETOOLONG;
|
||||||
|
case EHOSTDOWN: return WSAEHOSTDOWN;
|
||||||
|
case EHOSTUNREACH: return WSAEHOSTUNREACH;
|
||||||
|
case ENOTEMPTY: return WSAENOTEMPTY;
|
||||||
|
#ifdef EPROCLIM
|
||||||
|
case EPROCLIM: return WSAEPROCLIM;
|
||||||
|
#endif
|
||||||
|
#ifdef EUSERS
|
||||||
|
case EUSERS: return WSAEUSERS;
|
||||||
|
#endif
|
||||||
|
#ifdef EDQUOT
|
||||||
|
case EDQUOT: return WSAEDQUOT;
|
||||||
|
#endif
|
||||||
|
#ifdef ESTALE
|
||||||
|
case ESTALE: return WSAESTALE;
|
||||||
|
#endif
|
||||||
|
#ifdef EREMOTE
|
||||||
|
case EREMOTE: return WSAEREMOTE;
|
||||||
|
#endif
|
||||||
|
default: errno = err; perror( "sock_set_error" ); return WSAEFAULT;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define sock_get_error(x) WSAGetLastError()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOL netconn_init( netconn_t *conn, BOOL secure )
|
||||||
|
{
|
||||||
|
conn->socket = -1;
|
||||||
|
if (!secure) return TRUE;
|
||||||
|
|
||||||
|
#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
|
||||||
|
if (libssl_handle) return TRUE;
|
||||||
|
if (!(libssl_handle = wine_dlopen( SONAME_LIBSSL, RTLD_NOW, NULL, 0 )))
|
||||||
|
{
|
||||||
|
ERR("Trying to use SSL but couldn't load %s. Expect trouble.\n", SONAME_LIBSSL);
|
||||||
|
set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!(libcrypto_handle = wine_dlopen( SONAME_LIBCRYPTO, RTLD_NOW, NULL, 0 )))
|
||||||
|
{
|
||||||
|
ERR("Trying to use SSL but couldn't load %s. Expect trouble.\n", SONAME_LIBCRYPTO);
|
||||||
|
set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#define LOAD_FUNCPTR(x) \
|
||||||
|
if (!(p##x = wine_dlsym( libssl_handle, #x, NULL, 0 ))) \
|
||||||
|
{ \
|
||||||
|
ERR("Failed to load symbol %s\n", #x); \
|
||||||
|
set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR ); \
|
||||||
|
return FALSE; \
|
||||||
|
}
|
||||||
|
LOAD_FUNCPTR( SSL_library_init );
|
||||||
|
LOAD_FUNCPTR( SSL_load_error_strings );
|
||||||
|
LOAD_FUNCPTR( SSLv23_method );
|
||||||
|
LOAD_FUNCPTR( SSL_CTX_new );
|
||||||
|
LOAD_FUNCPTR( SSL_CTX_free );
|
||||||
|
LOAD_FUNCPTR( SSL_new );
|
||||||
|
LOAD_FUNCPTR( SSL_free );
|
||||||
|
LOAD_FUNCPTR( SSL_set_fd );
|
||||||
|
LOAD_FUNCPTR( SSL_connect );
|
||||||
|
LOAD_FUNCPTR( SSL_shutdown );
|
||||||
|
LOAD_FUNCPTR( SSL_write );
|
||||||
|
LOAD_FUNCPTR( SSL_read );
|
||||||
|
LOAD_FUNCPTR( SSL_get_verify_result );
|
||||||
|
LOAD_FUNCPTR( SSL_get_peer_certificate );
|
||||||
|
LOAD_FUNCPTR( SSL_CTX_get_timeout );
|
||||||
|
LOAD_FUNCPTR( SSL_CTX_set_timeout );
|
||||||
|
LOAD_FUNCPTR( SSL_CTX_set_default_verify_paths );
|
||||||
|
#undef LOAD_FUNCPTR
|
||||||
|
|
||||||
|
#define LOAD_FUNCPTR(x) \
|
||||||
|
if (!(p##x = wine_dlsym( libcrypto_handle, #x, NULL, 0 ))) \
|
||||||
|
{ \
|
||||||
|
ERR("Failed to load symbol %s\n", #x); \
|
||||||
|
set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR ); \
|
||||||
|
return FALSE; \
|
||||||
|
}
|
||||||
|
LOAD_FUNCPTR( BIO_new_fp );
|
||||||
|
LOAD_FUNCPTR( ERR_get_error );
|
||||||
|
LOAD_FUNCPTR( ERR_error_string );
|
||||||
|
#undef LOAD_FUNCPTR
|
||||||
|
|
||||||
|
pSSL_library_init();
|
||||||
|
pSSL_load_error_strings();
|
||||||
|
pBIO_new_fp( stderr, BIO_NOCLOSE );
|
||||||
|
|
||||||
|
method = pSSLv23_method();
|
||||||
|
conn->ssl_ctx = pSSL_CTX_new( method );
|
||||||
|
|
||||||
|
#else
|
||||||
|
WARN("SSL support not compiled in.\n");
|
||||||
|
set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_connected( netconn_t *conn )
|
||||||
|
{
|
||||||
|
return (conn->socket != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_create( netconn_t *conn, int domain, int type, int protocol )
|
||||||
|
{
|
||||||
|
if ((conn->socket = socket( domain, type, protocol )) == -1)
|
||||||
|
{
|
||||||
|
WARN("unable to create socket (%s)\n", strerror(errno));
|
||||||
|
set_last_error( sock_get_error( errno ) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_close( netconn_t *conn )
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
#ifdef SONAME_LIBSSL
|
||||||
|
if (conn->secure)
|
||||||
|
{
|
||||||
|
heap_free( conn->peek_msg_mem );
|
||||||
|
conn->peek_msg_mem = NULL;
|
||||||
|
conn->peek_msg = NULL;
|
||||||
|
conn->peek_len = 0;
|
||||||
|
|
||||||
|
pSSL_shutdown( conn->ssl_conn );
|
||||||
|
pSSL_free( conn->ssl_conn );
|
||||||
|
|
||||||
|
conn->ssl_conn = NULL;
|
||||||
|
conn->secure = FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
res = closesocket( conn->socket );
|
||||||
|
conn->socket = -1;
|
||||||
|
if (res == -1)
|
||||||
|
{
|
||||||
|
set_last_error( sock_get_error( errno ) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned int addr_len )
|
||||||
|
{
|
||||||
|
if (connect( conn->socket, sockaddr, addr_len ) == -1)
|
||||||
|
{
|
||||||
|
WARN("unable to connect to host (%s)\n", strerror(errno));
|
||||||
|
set_last_error( sock_get_error( errno ) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_secure_connect( netconn_t *conn )
|
||||||
|
{
|
||||||
|
#ifdef SONAME_LIBSSL
|
||||||
|
X509 *cert;
|
||||||
|
long res;
|
||||||
|
|
||||||
|
if (!pSSL_CTX_set_default_verify_paths( conn->ssl_ctx ))
|
||||||
|
{
|
||||||
|
ERR("SSL_CTX_set_default_verify_paths failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
|
||||||
|
set_last_error( ERROR_OUTOFMEMORY );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!(conn->ssl_conn = pSSL_new( conn->ssl_ctx )))
|
||||||
|
{
|
||||||
|
ERR("SSL_new failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
|
||||||
|
set_last_error( ERROR_OUTOFMEMORY );
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (!pSSL_set_fd( conn->ssl_conn, conn->socket ))
|
||||||
|
{
|
||||||
|
ERR("SSL_set_fd failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
|
||||||
|
set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (pSSL_connect( conn->ssl_conn ) <= 0)
|
||||||
|
{
|
||||||
|
ERR("SSL_connect failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
|
||||||
|
set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (!(cert = pSSL_get_peer_certificate( conn->ssl_conn )))
|
||||||
|
{
|
||||||
|
ERR("No certificate for server: %s\n", pERR_error_string( pERR_get_error(), 0 ));
|
||||||
|
set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if ((res = pSSL_get_verify_result( conn->ssl_conn )) != X509_V_OK)
|
||||||
|
{
|
||||||
|
/* FIXME: we should set an error and return, but we only print an error at the moment */
|
||||||
|
ERR("couldn't verify server certificate (%ld)\n", res);
|
||||||
|
}
|
||||||
|
TRACE("established SSL connection\n");
|
||||||
|
conn->secure = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (conn->ssl_conn)
|
||||||
|
{
|
||||||
|
pSSL_shutdown( conn->ssl_conn );
|
||||||
|
pSSL_free( conn->ssl_conn );
|
||||||
|
conn->ssl_conn = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_send( netconn_t *conn, const void *msg, size_t len, int flags, int *sent )
|
||||||
|
{
|
||||||
|
if (!netconn_connected( conn )) return FALSE;
|
||||||
|
if (conn->secure)
|
||||||
|
{
|
||||||
|
#ifdef SONAME_LIBSSL
|
||||||
|
if (flags) FIXME("SSL_write doesn't support any flags (%08x)\n", flags);
|
||||||
|
*sent = pSSL_write( conn->ssl_conn, msg, len );
|
||||||
|
if (*sent < 1 && len) return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if ((*sent = send( conn->socket, msg, len, flags )) == -1)
|
||||||
|
{
|
||||||
|
set_last_error( sock_get_error( errno ) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd )
|
||||||
|
{
|
||||||
|
*recvd = 0;
|
||||||
|
if (!netconn_connected( conn )) return FALSE;
|
||||||
|
if (!len) return TRUE;
|
||||||
|
|
||||||
|
if (conn->secure)
|
||||||
|
{
|
||||||
|
#ifdef SONAME_LIBSSL
|
||||||
|
if (flags & ~(MSG_PEEK | MSG_WAITALL))
|
||||||
|
FIXME("SSL_read does not support the following flags: %08x\n", flags);
|
||||||
|
|
||||||
|
/* this ugly hack is all for MSG_PEEK */
|
||||||
|
if (flags & MSG_PEEK && !conn->peek_msg)
|
||||||
|
{
|
||||||
|
if (!(conn->peek_msg = conn->peek_msg_mem = heap_alloc( len + 1 ))) return FALSE;
|
||||||
|
}
|
||||||
|
else if (flags & MSG_PEEK && conn->peek_msg)
|
||||||
|
{
|
||||||
|
if (len < conn->peek_len) FIXME("buffer isn't big enough, should we wrap?\n");
|
||||||
|
*recvd = min( len, conn->peek_len );
|
||||||
|
memcpy( buf, conn->peek_msg, *recvd );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (conn->peek_msg)
|
||||||
|
{
|
||||||
|
*recvd = min( len, conn->peek_len );
|
||||||
|
memcpy( buf, conn->peek_msg, *recvd );
|
||||||
|
conn->peek_len -= *recvd;
|
||||||
|
conn->peek_msg += *recvd;
|
||||||
|
|
||||||
|
if (conn->peek_len == 0)
|
||||||
|
{
|
||||||
|
heap_free( conn->peek_msg_mem );
|
||||||
|
conn->peek_msg_mem = NULL;
|
||||||
|
conn->peek_msg = NULL;
|
||||||
|
}
|
||||||
|
/* check if we have enough data from the peek buffer */
|
||||||
|
if (!(flags & MSG_WAITALL) || (*recvd == len)) return TRUE;
|
||||||
|
}
|
||||||
|
*recvd += pSSL_read( conn->ssl_conn, (char *)buf + *recvd, len - *recvd );
|
||||||
|
if (flags & MSG_PEEK) /* must copy into buffer */
|
||||||
|
{
|
||||||
|
conn->peek_len = *recvd;
|
||||||
|
if (!*recvd)
|
||||||
|
{
|
||||||
|
heap_free( conn->peek_msg_mem );
|
||||||
|
conn->peek_msg_mem = NULL;
|
||||||
|
conn->peek_msg = NULL;
|
||||||
|
}
|
||||||
|
else memcpy( conn->peek_msg, buf, *recvd );
|
||||||
|
}
|
||||||
|
if (*recvd < 1 && len) return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if ((*recvd = recv( conn->socket, buf, len, flags )) == -1)
|
||||||
|
{
|
||||||
|
set_last_error( sock_get_error( errno ) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_query_data_available( netconn_t *conn, DWORD *available )
|
||||||
|
{
|
||||||
|
#ifdef FIONREAD
|
||||||
|
int ret, unread;
|
||||||
|
#endif
|
||||||
|
*available = 0;
|
||||||
|
if (!netconn_connected( conn )) return FALSE;
|
||||||
|
|
||||||
|
if (conn->secure)
|
||||||
|
{
|
||||||
|
#ifdef SONAME_LIBSSL
|
||||||
|
if (conn->peek_msg) *available = conn->peek_len;
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#ifdef FIONREAD
|
||||||
|
if (!(ret = ioctlsocket( conn->socket, FIONREAD, &unread )))
|
||||||
|
{
|
||||||
|
TRACE("%d bytes of queued, but unread data\n", unread);
|
||||||
|
*available += unread;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_get_next_line( netconn_t *conn, char *buffer, DWORD *buflen )
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set infd;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
DWORD recvd = 0;
|
||||||
|
|
||||||
|
if (!netconn_connected( conn )) return FALSE;
|
||||||
|
|
||||||
|
if (conn->secure)
|
||||||
|
{
|
||||||
|
#ifdef SONAME_LIBSSL
|
||||||
|
long timeout;
|
||||||
|
|
||||||
|
timeout = pSSL_CTX_get_timeout( conn->ssl_ctx );
|
||||||
|
pSSL_CTX_set_timeout( conn->ssl_ctx, DEFAULT_RECEIVE_TIMEOUT );
|
||||||
|
|
||||||
|
while (recvd < *buflen)
|
||||||
|
{
|
||||||
|
int dummy;
|
||||||
|
if (!netconn_recv( conn, &buffer[recvd], 1, 0, &dummy ))
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_CONNECTION_ABORTED );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buffer[recvd] == '\n')
|
||||||
|
{
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buffer[recvd] != '\r') recvd++;
|
||||||
|
}
|
||||||
|
pSSL_CTX_set_timeout( conn->ssl_ctx, timeout );
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
buffer[recvd++] = 0;
|
||||||
|
*buflen = recvd;
|
||||||
|
TRACE("received line %s\n", debugstr_a(buffer));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_ZERO(&infd);
|
||||||
|
FD_SET(conn->socket, &infd);
|
||||||
|
tv.tv_sec=RESPONSE_TIMEOUT;
|
||||||
|
tv.tv_usec=0;
|
||||||
|
while (recvd < *buflen)
|
||||||
|
{
|
||||||
|
if (select(conn->socket+1,&infd,NULL,NULL,&tv) > 0)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
if ((res = recv( conn->socket, &buffer[recvd], 1, 0 )) <= 0)
|
||||||
|
{
|
||||||
|
if (res == -1) set_last_error( sock_get_error( errno ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buffer[recvd] == '\n')
|
||||||
|
{
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buffer[recvd] != '\r') recvd++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_WINHTTP_TIMEOUT );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
buffer[recvd++] = 0;
|
||||||
|
*buflen = recvd;
|
||||||
|
TRACE("received line %s\n", debugstr_a(buffer));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD netconn_set_timeout( netconn_t *netconn, BOOL send, int value )
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
/* value is in milliseconds, convert to struct timeval */
|
||||||
|
tv.tv_sec = value / 1000;
|
||||||
|
tv.tv_usec = (value % 1000) * 1000;
|
||||||
|
|
||||||
|
if ((res = setsockopt( netconn->socket, SOL_SOCKET, send ? SO_SNDTIMEO : SO_RCVTIMEO, &tv, sizeof(tv) ) == -1))
|
||||||
|
{
|
||||||
|
WARN("setsockopt failed (%s)\n", strerror( errno ));
|
||||||
|
return sock_get_error( errno );
|
||||||
|
}
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr_in *sa )
|
||||||
|
{
|
||||||
|
char *hostname;
|
||||||
|
#ifdef HAVE_GETADDRINFO
|
||||||
|
struct addrinfo *res, hints;
|
||||||
|
int ret;
|
||||||
|
#else
|
||||||
|
struct hostent *he;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(hostname = strdupWA( hostnameW ))) return FALSE;
|
||||||
|
|
||||||
|
#ifdef HAVE_GETADDRINFO
|
||||||
|
memset( &hints, 0, sizeof(struct addrinfo) );
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
|
||||||
|
ret = getaddrinfo( hostname, NULL, &hints, &res );
|
||||||
|
heap_free( hostname );
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
TRACE("failed to get address of %s (%s)\n", debugstr_a(hostname), gai_strerror(ret));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
memset( sa, 0, sizeof(struct sockaddr_in) );
|
||||||
|
memcpy( &sa->sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof(struct in_addr) );
|
||||||
|
sa->sin_family = res->ai_family;
|
||||||
|
sa->sin_port = htons( port );
|
||||||
|
|
||||||
|
freeaddrinfo( res );
|
||||||
|
#else
|
||||||
|
EnterCriticalSection( &cs_gethostbyname );
|
||||||
|
|
||||||
|
he = gethostbyname( hostname );
|
||||||
|
heap_free( hostname );
|
||||||
|
if (!he)
|
||||||
|
{
|
||||||
|
TRACE("failed to get address of %s (%d)\n", debugstr_a(hostname), h_errno);
|
||||||
|
LeaveCriticalSection( &cs_gethostbyname );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
memset( sa, 0, sizeof(struct sockaddr_in) );
|
||||||
|
memcpy( (char *)&sa->sin_addr, he->h_addr, he->h_length );
|
||||||
|
sa->sin_family = he->h_addrtype;
|
||||||
|
sa->sin_port = htons( port );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &cs_gethostbyname );
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
1546
reactos/dll/win32/winhttp/request.c
Normal file
1546
reactos/dll/win32/winhttp/request.c
Normal file
File diff suppressed because it is too large
Load diff
693
reactos/dll/win32/winhttp/session.c
Normal file
693
reactos/dll/win32/winhttp/session.c
Normal file
|
@ -0,0 +1,693 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2008 Hans Leidekker for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winhttp.h"
|
||||||
|
|
||||||
|
#include "winhttp_private.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
|
||||||
|
|
||||||
|
void set_last_error( DWORD error )
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
SetLastError( error );
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_callback( object_header_t *hdr, DWORD status, LPVOID info, DWORD buflen )
|
||||||
|
{
|
||||||
|
TRACE("%p, 0x%08x, %p, %u\n", hdr, status, info, buflen);
|
||||||
|
|
||||||
|
if (hdr->notify_mask & status) hdr->callback( hdr->handle, hdr->context, status, info, buflen );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpCheckPlatform (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpCheckPlatform( void )
|
||||||
|
{
|
||||||
|
TRACE("\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* session_destroy (internal)
|
||||||
|
*/
|
||||||
|
static void session_destroy( object_header_t *hdr )
|
||||||
|
{
|
||||||
|
session_t *session = (session_t *)hdr;
|
||||||
|
|
||||||
|
TRACE("%p\n", session);
|
||||||
|
|
||||||
|
heap_free( session->agent );
|
||||||
|
heap_free( session->proxy_server );
|
||||||
|
heap_free( session->proxy_bypass );
|
||||||
|
heap_free( session->proxy_username );
|
||||||
|
heap_free( session->proxy_password );
|
||||||
|
heap_free( session );
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen )
|
||||||
|
{
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
case WINHTTP_OPTION_PROXY:
|
||||||
|
{
|
||||||
|
WINHTTP_PROXY_INFO *pi = buffer;
|
||||||
|
|
||||||
|
FIXME("%u %s %s\n", pi->dwAccessType, debugstr_w(pi->lpszProxy), debugstr_w(pi->lpszProxyBypass));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
case WINHTTP_OPTION_REDIRECT_POLICY:
|
||||||
|
{
|
||||||
|
DWORD policy = *(DWORD *)buffer;
|
||||||
|
|
||||||
|
TRACE("0x%x\n", policy);
|
||||||
|
hdr->redirect_policy = policy;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
FIXME("unimplemented option %u\n", option);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const object_vtbl_t session_vtbl =
|
||||||
|
{
|
||||||
|
session_destroy,
|
||||||
|
NULL,
|
||||||
|
session_set_option
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpOpen (winhttp.@)
|
||||||
|
*/
|
||||||
|
HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWSTR bypass, DWORD flags )
|
||||||
|
{
|
||||||
|
session_t *session;
|
||||||
|
HINTERNET handle = NULL;
|
||||||
|
|
||||||
|
TRACE("%s, %u, %s, %s, 0x%08x\n", debugstr_w(agent), access, debugstr_w(proxy), debugstr_w(bypass), flags);
|
||||||
|
|
||||||
|
if (!(session = heap_alloc_zero( sizeof(session_t) ))) return NULL;
|
||||||
|
|
||||||
|
session->hdr.type = WINHTTP_HANDLE_TYPE_SESSION;
|
||||||
|
session->hdr.vtbl = &session_vtbl;
|
||||||
|
session->hdr.flags = flags;
|
||||||
|
session->hdr.refs = 1;
|
||||||
|
session->access = access;
|
||||||
|
|
||||||
|
if (agent && !(session->agent = strdupW( agent ))) goto end;
|
||||||
|
if (proxy && !(session->proxy_server = strdupW( proxy ))) goto end;
|
||||||
|
if (bypass && !(session->proxy_bypass = strdupW( bypass ))) goto end;
|
||||||
|
|
||||||
|
if (!(handle = alloc_handle( &session->hdr ))) goto end;
|
||||||
|
session->hdr.handle = handle;
|
||||||
|
|
||||||
|
end:
|
||||||
|
release_object( &session->hdr );
|
||||||
|
TRACE("returning %p\n", handle);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* connect_destroy (internal)
|
||||||
|
*/
|
||||||
|
static void connect_destroy( object_header_t *hdr )
|
||||||
|
{
|
||||||
|
connect_t *connect = (connect_t *)hdr;
|
||||||
|
|
||||||
|
TRACE("%p\n", connect);
|
||||||
|
|
||||||
|
release_object( &connect->session->hdr );
|
||||||
|
|
||||||
|
heap_free( connect->hostname );
|
||||||
|
heap_free( connect->servername );
|
||||||
|
heap_free( connect->username );
|
||||||
|
heap_free( connect->password );
|
||||||
|
heap_free( connect );
|
||||||
|
}
|
||||||
|
|
||||||
|
static const object_vtbl_t connect_vtbl =
|
||||||
|
{
|
||||||
|
connect_destroy,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpConnect (winhttp.@)
|
||||||
|
*/
|
||||||
|
HINTERNET WINAPI WinHttpConnect( HINTERNET hsession, LPCWSTR server, INTERNET_PORT port, DWORD reserved )
|
||||||
|
{
|
||||||
|
connect_t *connect;
|
||||||
|
session_t *session;
|
||||||
|
HINTERNET hconnect = NULL;
|
||||||
|
|
||||||
|
TRACE("%p, %s, %u, %x\n", hsession, debugstr_w(server), port, reserved);
|
||||||
|
|
||||||
|
if (!server)
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_INVALID_PARAMETER );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(session = (session_t *)grab_object( hsession )))
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_INVALID_HANDLE );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (session->hdr.type != WINHTTP_HANDLE_TYPE_SESSION)
|
||||||
|
{
|
||||||
|
release_object( &session->hdr );
|
||||||
|
set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(connect = heap_alloc_zero( sizeof(connect_t) )))
|
||||||
|
{
|
||||||
|
release_object( &session->hdr );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
connect->hdr.type = WINHTTP_HANDLE_TYPE_CONNECT;
|
||||||
|
connect->hdr.vtbl = &connect_vtbl;
|
||||||
|
connect->hdr.refs = 1;
|
||||||
|
connect->hdr.flags = session->hdr.flags;
|
||||||
|
connect->hdr.callback = session->hdr.callback;
|
||||||
|
connect->hdr.notify_mask = session->hdr.notify_mask;
|
||||||
|
connect->hdr.context = session->hdr.context;
|
||||||
|
|
||||||
|
addref_object( &session->hdr );
|
||||||
|
connect->session = session;
|
||||||
|
list_add_head( &session->hdr.children, &connect->hdr.entry );
|
||||||
|
|
||||||
|
if (server && !(connect->hostname = strdupW( server ))) goto end;
|
||||||
|
connect->hostport = port ? port : (connect->hdr.flags & WINHTTP_FLAG_SECURE ? 443 : 80);
|
||||||
|
|
||||||
|
if (server && !(connect->servername = strdupW( server ))) goto end;
|
||||||
|
connect->serverport = port ? port : (connect->hdr.flags & WINHTTP_FLAG_SECURE ? 443 : 80);
|
||||||
|
|
||||||
|
if (!(hconnect = alloc_handle( &connect->hdr ))) goto end;
|
||||||
|
connect->hdr.handle = hconnect;
|
||||||
|
|
||||||
|
send_callback( &session->hdr, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED, &hconnect, sizeof(hconnect) );
|
||||||
|
|
||||||
|
end:
|
||||||
|
release_object( &connect->hdr );
|
||||||
|
|
||||||
|
TRACE("returning %p\n", hconnect);
|
||||||
|
return hconnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* request_destroy (internal)
|
||||||
|
*/
|
||||||
|
static void request_destroy( object_header_t *hdr )
|
||||||
|
{
|
||||||
|
request_t *request = (request_t *)hdr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
TRACE("%p\n", request);
|
||||||
|
|
||||||
|
release_object( &request->connect->hdr );
|
||||||
|
|
||||||
|
heap_free( request->verb );
|
||||||
|
heap_free( request->path );
|
||||||
|
heap_free( request->version );
|
||||||
|
heap_free( request->raw_headers );
|
||||||
|
heap_free( request->status_text );
|
||||||
|
for (i = 0; i < request->num_headers; i++)
|
||||||
|
{
|
||||||
|
heap_free( request->headers[i].field );
|
||||||
|
heap_free( request->headers[i].value );
|
||||||
|
}
|
||||||
|
heap_free( request->headers );
|
||||||
|
heap_free( request );
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen )
|
||||||
|
{
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
case WINHTTP_OPTION_SECURITY_FLAGS:
|
||||||
|
{
|
||||||
|
DWORD flags = 0;
|
||||||
|
|
||||||
|
if (hdr->flags & WINHTTP_FLAG_SECURE) flags |= SECURITY_FLAG_SECURE;
|
||||||
|
*(DWORD *)buffer = flags;
|
||||||
|
*buflen = sizeof(DWORD);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
FIXME("unimplemented option %u\n", option);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen )
|
||||||
|
{
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
case WINHTTP_OPTION_PROXY:
|
||||||
|
{
|
||||||
|
WINHTTP_PROXY_INFO *pi = buffer;
|
||||||
|
|
||||||
|
FIXME("%u %s %s\n", pi->dwAccessType, debugstr_w(pi->lpszProxy), debugstr_w(pi->lpszProxyBypass));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
case WINHTTP_OPTION_DISABLE_FEATURE:
|
||||||
|
{
|
||||||
|
DWORD disable = *(DWORD *)buffer;
|
||||||
|
|
||||||
|
TRACE("0x%x\n", disable);
|
||||||
|
hdr->disable_flags &= disable;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
case WINHTTP_OPTION_AUTOLOGON_POLICY:
|
||||||
|
{
|
||||||
|
DWORD policy = *(DWORD *)buffer;
|
||||||
|
|
||||||
|
TRACE("0x%x\n", policy);
|
||||||
|
hdr->logon_policy = policy;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
case WINHTTP_OPTION_REDIRECT_POLICY:
|
||||||
|
{
|
||||||
|
DWORD policy = *(DWORD *)buffer;
|
||||||
|
|
||||||
|
TRACE("0x%x\n", policy);
|
||||||
|
hdr->redirect_policy = policy;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
FIXME("unimplemented option %u\n", option);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const object_vtbl_t request_vtbl =
|
||||||
|
{
|
||||||
|
request_destroy,
|
||||||
|
request_query_option,
|
||||||
|
request_set_option
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpOpenRequest (winhttp.@)
|
||||||
|
*/
|
||||||
|
HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, LPCWSTR verb, LPCWSTR object, LPCWSTR version,
|
||||||
|
LPCWSTR referrer, LPCWSTR *types, DWORD flags )
|
||||||
|
{
|
||||||
|
request_t *request;
|
||||||
|
connect_t *connect;
|
||||||
|
HINTERNET hrequest = NULL;
|
||||||
|
|
||||||
|
TRACE("%p, %s, %s, %s, %s, %p, 0x%08x\n", hconnect, debugstr_w(verb), debugstr_w(object),
|
||||||
|
debugstr_w(version), debugstr_w(referrer), types, flags);
|
||||||
|
|
||||||
|
if (!(connect = (connect_t *)grab_object( hconnect )))
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_INVALID_HANDLE );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (connect->hdr.type != WINHTTP_HANDLE_TYPE_CONNECT)
|
||||||
|
{
|
||||||
|
release_object( &connect->hdr );
|
||||||
|
set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(request = heap_alloc_zero( sizeof(request_t) )))
|
||||||
|
{
|
||||||
|
release_object( &connect->hdr );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
request->hdr.type = WINHTTP_HANDLE_TYPE_REQUEST;
|
||||||
|
request->hdr.vtbl = &request_vtbl;
|
||||||
|
request->hdr.refs = 1;
|
||||||
|
request->hdr.flags = flags;
|
||||||
|
request->hdr.callback = connect->hdr.callback;
|
||||||
|
request->hdr.notify_mask = connect->hdr.notify_mask;
|
||||||
|
request->hdr.context = connect->hdr.context;
|
||||||
|
|
||||||
|
addref_object( &connect->hdr );
|
||||||
|
request->connect = connect;
|
||||||
|
list_add_head( &connect->hdr.children, &request->hdr.entry );
|
||||||
|
|
||||||
|
if (!netconn_init( &request->netconn, request->hdr.flags & WINHTTP_FLAG_SECURE )) goto end;
|
||||||
|
|
||||||
|
if (verb && !(request->verb = strdupW( verb ))) goto end;
|
||||||
|
if (object && !(request->path = strdupW( object ))) goto end;
|
||||||
|
if (version && !(request->version = strdupW( version ))) goto end;
|
||||||
|
|
||||||
|
if (!(hrequest = alloc_handle( &request->hdr ))) goto end;
|
||||||
|
request->hdr.handle = hrequest;
|
||||||
|
|
||||||
|
send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED, &hrequest, sizeof(hrequest) );
|
||||||
|
|
||||||
|
end:
|
||||||
|
release_object( &request->hdr );
|
||||||
|
|
||||||
|
TRACE("returning %p\n", hrequest);
|
||||||
|
return hrequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpCloseHandle (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpCloseHandle( HINTERNET handle )
|
||||||
|
{
|
||||||
|
object_header_t *hdr;
|
||||||
|
|
||||||
|
TRACE("%p\n", handle);
|
||||||
|
|
||||||
|
if (!(hdr = grab_object( handle )))
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_INVALID_HANDLE );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
release_object( hdr );
|
||||||
|
free_handle( handle );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen )
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
case WINHTTP_OPTION_CONTEXT_VALUE:
|
||||||
|
{
|
||||||
|
*(DWORD_PTR *)buffer = hdr->context;
|
||||||
|
*buflen = sizeof(DWORD_PTR);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (hdr->vtbl->query_option) ret = hdr->vtbl->query_option( hdr, option, buffer, buflen );
|
||||||
|
else FIXME("unimplemented option %u\n", option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpQueryOption (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpQueryOption( HINTERNET handle, DWORD option, LPVOID buffer, LPDWORD buflen )
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
object_header_t *hdr;
|
||||||
|
|
||||||
|
TRACE("%p, %u, %p, %p\n", handle, option, buffer, buflen);
|
||||||
|
|
||||||
|
if (!(hdr = grab_object( handle )))
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_INVALID_HANDLE );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = query_option( hdr, option, buffer, buflen );
|
||||||
|
|
||||||
|
release_object( hdr );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen )
|
||||||
|
{
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
case WINHTTP_OPTION_CONTEXT_VALUE:
|
||||||
|
{
|
||||||
|
hdr->context = *(DWORD_PTR *)buffer;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (hdr->vtbl->set_option) ret = hdr->vtbl->set_option( hdr, option, buffer, buflen );
|
||||||
|
else FIXME("unimplemented option %u\n", option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpSetOption (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpSetOption( HINTERNET handle, DWORD option, LPVOID buffer, DWORD buflen )
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
object_header_t *hdr;
|
||||||
|
|
||||||
|
TRACE("%p, %u, %p, %u\n", handle, option, buffer, buflen);
|
||||||
|
|
||||||
|
if (!(hdr = grab_object( handle )))
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_INVALID_HANDLE );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = set_option( hdr, option, buffer, buflen );
|
||||||
|
|
||||||
|
release_object( hdr );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpDetectAutoProxyConfigUrl (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpDetectAutoProxyConfigUrl( DWORD flags, LPWSTR *url )
|
||||||
|
{
|
||||||
|
FIXME("0x%08x, %p\n", flags, url);
|
||||||
|
|
||||||
|
set_last_error( ERROR_WINHTTP_AUTODETECTION_FAILED );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpGetDefaultProxyConfiguration (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpGetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
|
||||||
|
{
|
||||||
|
FIXME("%p\n", info);
|
||||||
|
|
||||||
|
info->dwAccessType = WINHTTP_ACCESS_TYPE_NO_PROXY;
|
||||||
|
info->lpszProxy = NULL;
|
||||||
|
info->lpszProxyBypass = NULL;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpGetIEProxyConfigForCurrentUser (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser( WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *config )
|
||||||
|
{
|
||||||
|
TRACE("%p\n", config);
|
||||||
|
|
||||||
|
if (!config)
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_INVALID_PARAMETER );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: read from HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings */
|
||||||
|
|
||||||
|
FIXME("returning no proxy used\n");
|
||||||
|
config->fAutoDetect = FALSE;
|
||||||
|
config->lpszAutoConfigUrl = NULL;
|
||||||
|
config->lpszProxy = NULL;
|
||||||
|
config->lpszProxyBypass = NULL;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpGetProxyForUrl (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpGetProxyForUrl( HINTERNET hsession, LPCWSTR url, WINHTTP_AUTOPROXY_OPTIONS *options,
|
||||||
|
WINHTTP_PROXY_INFO *info )
|
||||||
|
{
|
||||||
|
FIXME("%p, %s, %p, %p\n", hsession, debugstr_w(url), options, info);
|
||||||
|
|
||||||
|
set_last_error( ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpSetDefaultProxyConfiguration (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpSetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
|
||||||
|
{
|
||||||
|
FIXME("%p [%u, %s, %s]\n", info, info->dwAccessType, debugstr_w(info->lpszProxy),
|
||||||
|
debugstr_w(info->lpszProxyBypass));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpSetStatusCallback (winhttp.@)
|
||||||
|
*/
|
||||||
|
WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback( HINTERNET handle, WINHTTP_STATUS_CALLBACK callback,
|
||||||
|
DWORD flags, DWORD_PTR reserved )
|
||||||
|
{
|
||||||
|
object_header_t *hdr;
|
||||||
|
WINHTTP_STATUS_CALLBACK ret;
|
||||||
|
|
||||||
|
TRACE("%p, %p, 0x%08x, 0x%lx\n", handle, callback, flags, reserved);
|
||||||
|
|
||||||
|
if (!(hdr = grab_object( handle )))
|
||||||
|
{
|
||||||
|
set_last_error( ERROR_INVALID_HANDLE );
|
||||||
|
return WINHTTP_INVALID_STATUS_CALLBACK;
|
||||||
|
}
|
||||||
|
ret = hdr->callback;
|
||||||
|
hdr->callback = callback;
|
||||||
|
hdr->notify_mask = flags;
|
||||||
|
|
||||||
|
release_object( hdr );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpSetTimeouts (winhttp.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int send, int receive )
|
||||||
|
{
|
||||||
|
FIXME("%p, %d, %d, %d, %d\n", handle, resolve, connect, send, receive);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const WCHAR wkday[7][4] =
|
||||||
|
{{'S','u','n', 0}, {'M','o','n', 0}, {'T','u','e', 0}, {'W','e','d', 0},
|
||||||
|
{'T','h','u', 0}, {'F','r','i', 0}, {'S','a','t', 0}};
|
||||||
|
static const WCHAR month[12][4] =
|
||||||
|
{{'J','a','n', 0}, {'F','e','b', 0}, {'M','a','r', 0}, {'A','p','r', 0},
|
||||||
|
{'M','a','y', 0}, {'J','u','n', 0}, {'J','u','l', 0}, {'A','u','g', 0},
|
||||||
|
{'S','e','p', 0}, {'O','c','t', 0}, {'N','o','v', 0}, {'D','e','c', 0}};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpTimeFromSystemTime (WININET.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpTimeFromSystemTime( const SYSTEMTIME *time, LPWSTR string )
|
||||||
|
{
|
||||||
|
static const WCHAR format[] =
|
||||||
|
{'%','s',',',' ','%','0','2','d',' ','%','s',' ','%','4','d',' ','%','0',
|
||||||
|
'2','d',':','%','0','2','d',':','%','0','2','d',' ','G','M','T', 0};
|
||||||
|
|
||||||
|
TRACE("%p, %p\n", time, string);
|
||||||
|
|
||||||
|
if (!time || !string) return FALSE;
|
||||||
|
|
||||||
|
sprintfW( string, format,
|
||||||
|
wkday[time->wDayOfWeek],
|
||||||
|
time->wDay,
|
||||||
|
month[time->wMonth - 1],
|
||||||
|
time->wYear,
|
||||||
|
time->wHour,
|
||||||
|
time->wMinute,
|
||||||
|
time->wSecond );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* WinHttpTimeToSystemTime (WININET.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI WinHttpTimeToSystemTime( LPCWSTR string, SYSTEMTIME *time )
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
const WCHAR *s = string;
|
||||||
|
WCHAR *end;
|
||||||
|
|
||||||
|
TRACE("%s, %p\n", debugstr_w(string), time);
|
||||||
|
|
||||||
|
if (!string || !time) return FALSE;
|
||||||
|
|
||||||
|
/* Windows does this too */
|
||||||
|
GetSystemTime( time );
|
||||||
|
|
||||||
|
/* Convert an RFC1123 time such as 'Fri, 07 Jan 2005 12:06:35 GMT' into
|
||||||
|
* a SYSTEMTIME structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (*s && !isalphaW( *s )) s++;
|
||||||
|
if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0') return TRUE;
|
||||||
|
time->wDayOfWeek = 7;
|
||||||
|
|
||||||
|
for (i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
if (toupperW( wkday[i][0] ) == toupperW( s[0] ) &&
|
||||||
|
toupperW( wkday[i][1] ) == toupperW( s[1] ) &&
|
||||||
|
toupperW( wkday[i][2] ) == toupperW( s[2] ) )
|
||||||
|
{
|
||||||
|
time->wDayOfWeek = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time->wDayOfWeek > 6) return TRUE;
|
||||||
|
while (*s && !isdigitW( *s )) s++;
|
||||||
|
time->wDay = strtolW( s, &end, 10 );
|
||||||
|
s = end;
|
||||||
|
|
||||||
|
while (*s && !isalphaW( *s )) s++;
|
||||||
|
if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0') return TRUE;
|
||||||
|
time->wMonth = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
if (toupperW( month[i][0]) == toupperW( s[0] ) &&
|
||||||
|
toupperW( month[i][1]) == toupperW( s[1] ) &&
|
||||||
|
toupperW( month[i][2]) == toupperW( s[2] ) )
|
||||||
|
{
|
||||||
|
time->wMonth = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (time->wMonth == 0) return TRUE;
|
||||||
|
|
||||||
|
while (*s && !isdigitW( *s )) s++;
|
||||||
|
if (*s == '\0') return TRUE;
|
||||||
|
time->wYear = strtolW( s, &end, 10 );
|
||||||
|
s = end;
|
||||||
|
|
||||||
|
while (*s && !isdigitW( *s )) s++;
|
||||||
|
if (*s == '\0') return TRUE;
|
||||||
|
time->wHour = strtolW( s, &end, 10 );
|
||||||
|
s = end;
|
||||||
|
|
||||||
|
while (*s && !isdigitW( *s )) s++;
|
||||||
|
if (*s == '\0') return TRUE;
|
||||||
|
time->wMinute = strtolW( s, &end, 10 );
|
||||||
|
s = end;
|
||||||
|
|
||||||
|
while (*s && !isdigitW( *s )) s++;
|
||||||
|
if (*s == '\0') return TRUE;
|
||||||
|
time->wSecond = strtolW( s, &end, 10 );
|
||||||
|
s = end;
|
||||||
|
|
||||||
|
time->wMilliseconds = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -9,9 +9,15 @@
|
||||||
<define name="__WINESRC__" />
|
<define name="__WINESRC__" />
|
||||||
<define name="WINVER">0x600</define>
|
<define name="WINVER">0x600</define>
|
||||||
<define name="_WIN32_WINNT">0x600</define>
|
<define name="_WIN32_WINNT">0x600</define>
|
||||||
|
<file>handle.c</file>
|
||||||
<file>main.c</file>
|
<file>main.c</file>
|
||||||
|
<file>net.c</file>
|
||||||
|
<file>request.c</file>
|
||||||
|
<file>session.c</file>
|
||||||
<file>winhttp.spec</file>
|
<file>winhttp.spec</file>
|
||||||
<library>wine</library>
|
<library>wine</library>
|
||||||
|
<library>wininet</library>
|
||||||
|
<library>ws2_32</library>
|
||||||
<library>kernel32</library>
|
<library>kernel32</library>
|
||||||
<library>ntdll</library>
|
<library>ntdll</library>
|
||||||
</module>
|
</module>
|
||||||
|
|
|
@ -2,30 +2,30 @@
|
||||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||||
@ stdcall -private DllRegisterServer()
|
@ stdcall -private DllRegisterServer()
|
||||||
@ stdcall -private DllUnregisterServer()
|
@ stdcall -private DllUnregisterServer()
|
||||||
@ stub WinHttpAddRequestHeaders
|
@ stdcall WinHttpAddRequestHeaders(ptr wstr long long)
|
||||||
@ stdcall WinHttpCheckPlatform()
|
@ stdcall WinHttpCheckPlatform()
|
||||||
@ stdcall WinHttpCloseHandle(ptr)
|
@ stdcall WinHttpCloseHandle(ptr)
|
||||||
@ stdcall WinHttpConnect(ptr wstr long long)
|
@ stdcall WinHttpConnect(ptr wstr long long)
|
||||||
@ stub WinHttpCrackUrl
|
@ stdcall WinHttpCrackUrl(wstr long long ptr)
|
||||||
@ stub WinHttpCreateUrl
|
@ stdcall WinHttpCreateUrl(ptr long ptr ptr)
|
||||||
@ stdcall WinHttpDetectAutoProxyConfigUrl(long ptr)
|
@ stdcall WinHttpDetectAutoProxyConfigUrl(long ptr)
|
||||||
@ stub WinHttpGetDefaultProxyConfiguration
|
@ stdcall WinHttpGetDefaultProxyConfiguration(ptr)
|
||||||
@ stdcall WinHttpGetIEProxyConfigForCurrentUser(ptr)
|
@ stdcall WinHttpGetIEProxyConfigForCurrentUser(ptr)
|
||||||
@ stub WinHttpGetProxyForUrl
|
@ stdcall WinHttpGetProxyForUrl(ptr wstr ptr ptr)
|
||||||
@ stdcall WinHttpOpen(wstr long wstr wstr long)
|
@ stdcall WinHttpOpen(wstr long wstr wstr long)
|
||||||
@ stdcall WinHttpOpenRequest(ptr wstr wstr wstr wstr ptr long)
|
@ stdcall WinHttpOpenRequest(ptr wstr wstr wstr wstr ptr long)
|
||||||
@ stub WinHttpQueryAuthSchemes
|
@ stdcall WinHttpQueryAuthSchemes(ptr ptr ptr ptr)
|
||||||
@ stdcall WinHttpQueryDataAvailable(ptr ptr)
|
@ stdcall WinHttpQueryDataAvailable(ptr ptr)
|
||||||
@ stub WinHttpQueryHeaders
|
@ stdcall WinHttpQueryHeaders(ptr long wstr ptr ptr ptr)
|
||||||
@ stdcall WinHttpQueryOption(ptr long ptr ptr)
|
@ stdcall WinHttpQueryOption(ptr long ptr ptr)
|
||||||
@ stdcall WinHttpReadData(ptr ptr long ptr)
|
@ stdcall WinHttpReadData(ptr ptr long ptr)
|
||||||
@ stdcall WinHttpReceiveResponse(ptr ptr)
|
@ stdcall WinHttpReceiveResponse(ptr ptr)
|
||||||
@ stdcall WinHttpSendRequest(ptr wstr long ptr long long ptr)
|
@ stdcall WinHttpSendRequest(ptr wstr long ptr long long ptr)
|
||||||
@ stub WinHttpSetCredentials
|
@ stdcall WinHttpSetCredentials(ptr long long wstr ptr ptr)
|
||||||
@ stub WinHttpSetDefaultProxyConfiguration
|
@ stdcall WinHttpSetDefaultProxyConfiguration(ptr)
|
||||||
@ stdcall WinHttpSetOption(ptr long ptr long)
|
@ stdcall WinHttpSetOption(ptr long ptr long)
|
||||||
@ stub WinHttpSetStatusCallback
|
@ stdcall WinHttpSetStatusCallback(ptr ptr long ptr)
|
||||||
@ stub WinHttpSetTimeouts
|
@ stdcall WinHttpSetTimeouts(ptr long long long long)
|
||||||
@ stub WinHttpTimeFromSystemTime
|
@ stdcall WinHttpTimeFromSystemTime(ptr ptr)
|
||||||
@ stub WinHttpTimeToSystemTime
|
@ stdcall WinHttpTimeToSystemTime(wstr ptr)
|
||||||
@ stub WinHttpWriteData
|
@ stdcall WinHttpWriteData(ptr ptr long ptr)
|
||||||
|
|
211
reactos/dll/win32/winhttp/winhttp_private.h
Normal file
211
reactos/dll/win32/winhttp/winhttp_private.h
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2008 Hans Leidekker for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _WINE_WINHTTP_PRIVATE_H_
|
||||||
|
#define _WINE_WINHTTP_PRIVATE_H_
|
||||||
|
|
||||||
|
#ifndef __WINE_CONFIG_H
|
||||||
|
# error You must include config.h to use this header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wine/list.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETDB_H
|
||||||
|
# include <netdb.h>
|
||||||
|
#endif
|
||||||
|
#if defined(__MINGW32__) || defined (_MSC_VER)
|
||||||
|
# include "ws2tcpip.h"
|
||||||
|
# ifndef MSG_WAITALL
|
||||||
|
# define MSG_WAITALL 0
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define closesocket close
|
||||||
|
# define ioctlsocket ioctl
|
||||||
|
#endif /* __MINGW32__ */
|
||||||
|
|
||||||
|
typedef struct _object_header_t object_header_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void (*destroy)( object_header_t * );
|
||||||
|
BOOL (*query_option)( object_header_t *, DWORD, void *, DWORD * );
|
||||||
|
BOOL (*set_option)( object_header_t *, DWORD, void *, DWORD );
|
||||||
|
} object_vtbl_t;
|
||||||
|
|
||||||
|
struct _object_header_t
|
||||||
|
{
|
||||||
|
DWORD type;
|
||||||
|
HINTERNET handle;
|
||||||
|
const object_vtbl_t *vtbl;
|
||||||
|
DWORD flags;
|
||||||
|
DWORD disable_flags;
|
||||||
|
DWORD logon_policy;
|
||||||
|
DWORD redirect_policy;
|
||||||
|
DWORD error;
|
||||||
|
DWORD_PTR context;
|
||||||
|
LONG refs;
|
||||||
|
WINHTTP_STATUS_CALLBACK callback;
|
||||||
|
DWORD notify_mask;
|
||||||
|
struct list entry;
|
||||||
|
struct list children;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
object_header_t hdr;
|
||||||
|
LPWSTR agent;
|
||||||
|
DWORD access;
|
||||||
|
LPWSTR proxy_server;
|
||||||
|
LPWSTR proxy_bypass;
|
||||||
|
LPWSTR proxy_username;
|
||||||
|
LPWSTR proxy_password;
|
||||||
|
} session_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
object_header_t hdr;
|
||||||
|
session_t *session;
|
||||||
|
LPWSTR hostname; /* final destination of the request */
|
||||||
|
LPWSTR servername; /* name of the server we directly connect to */
|
||||||
|
LPWSTR username;
|
||||||
|
LPWSTR password;
|
||||||
|
INTERNET_PORT hostport;
|
||||||
|
INTERNET_PORT serverport;
|
||||||
|
struct sockaddr_in sockaddr;
|
||||||
|
} connect_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int socket;
|
||||||
|
BOOL secure; /* SSL active on connection? */
|
||||||
|
void *ssl_ctx;
|
||||||
|
void *ssl_conn;
|
||||||
|
char *peek_msg;
|
||||||
|
char *peek_msg_mem;
|
||||||
|
size_t peek_len;
|
||||||
|
} netconn_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LPWSTR field;
|
||||||
|
LPWSTR value;
|
||||||
|
BOOL is_request; /* part of request headers? */
|
||||||
|
} header_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
object_header_t hdr;
|
||||||
|
connect_t *connect;
|
||||||
|
LPWSTR verb;
|
||||||
|
LPWSTR path;
|
||||||
|
LPWSTR version;
|
||||||
|
LPWSTR raw_headers;
|
||||||
|
netconn_t netconn;
|
||||||
|
LPWSTR status_text;
|
||||||
|
DWORD content_length; /* total number of bytes to be read (per chunk) */
|
||||||
|
DWORD content_read; /* bytes read so far */
|
||||||
|
header_t *headers;
|
||||||
|
DWORD num_headers;
|
||||||
|
} request_t;
|
||||||
|
|
||||||
|
object_header_t *addref_object( object_header_t * );
|
||||||
|
object_header_t *grab_object( HINTERNET );
|
||||||
|
void release_object( object_header_t * );
|
||||||
|
HINTERNET alloc_handle( object_header_t * );
|
||||||
|
BOOL free_handle( HINTERNET );
|
||||||
|
|
||||||
|
void set_last_error( DWORD );
|
||||||
|
void send_callback( object_header_t *, DWORD, LPVOID, DWORD );
|
||||||
|
void close_connection( request_t * );
|
||||||
|
|
||||||
|
BOOL netconn_close( netconn_t * );
|
||||||
|
BOOL netconn_connect( netconn_t *, const struct sockaddr *, unsigned int );
|
||||||
|
BOOL netconn_connected( netconn_t * );
|
||||||
|
BOOL netconn_create( netconn_t *, int, int, int );
|
||||||
|
BOOL netconn_get_next_line( netconn_t *, char *, DWORD * );
|
||||||
|
BOOL netconn_init( netconn_t *, BOOL );
|
||||||
|
BOOL netconn_query_data_available( netconn_t *, DWORD * );
|
||||||
|
BOOL netconn_recv( netconn_t *, void *, size_t, int, int * );
|
||||||
|
BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr_in * );
|
||||||
|
BOOL netconn_secure_connect( netconn_t * );
|
||||||
|
BOOL netconn_send( netconn_t *, const void *, size_t, int, int * );
|
||||||
|
|
||||||
|
static inline void *heap_alloc( SIZE_T size )
|
||||||
|
{
|
||||||
|
return HeapAlloc( GetProcessHeap(), 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *heap_alloc_zero( SIZE_T size )
|
||||||
|
{
|
||||||
|
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *heap_realloc( LPVOID mem, SIZE_T size )
|
||||||
|
{
|
||||||
|
return HeapReAlloc( GetProcessHeap(), 0, mem, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *heap_realloc_zero( LPVOID mem, SIZE_T size )
|
||||||
|
{
|
||||||
|
return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mem, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOL heap_free( LPVOID mem )
|
||||||
|
{
|
||||||
|
return HeapFree( GetProcessHeap(), 0, mem );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WCHAR *strdupW( const WCHAR *src )
|
||||||
|
{
|
||||||
|
WCHAR *dst;
|
||||||
|
|
||||||
|
if (!src) return NULL;
|
||||||
|
dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) );
|
||||||
|
if (dst) strcpyW( dst, src );
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WCHAR *strdupAW( const char *src )
|
||||||
|
{
|
||||||
|
WCHAR *dst = NULL;
|
||||||
|
if (src)
|
||||||
|
{
|
||||||
|
DWORD len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 );
|
||||||
|
if ((dst = heap_alloc( len * sizeof(WCHAR) )))
|
||||||
|
MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len );
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *strdupWA( const WCHAR *src )
|
||||||
|
{
|
||||||
|
char *dst = NULL;
|
||||||
|
if (src)
|
||||||
|
{
|
||||||
|
int len = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL );
|
||||||
|
if ((dst = heap_alloc( len )))
|
||||||
|
WideCharToMultiByte( CP_ACP, 0, src, -1, dst, len, NULL, NULL );
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _WINE_WINHTTP_PRIVATE_H_ */
|
103
reactos/dll/win32/winhttp/winhttp_ros.diff
Normal file
103
reactos/dll/win32/winhttp/winhttp_ros.diff
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
--- net.c Wed Sep 03 14:46:10 2008
|
||||||
|
+++ net.c Sun Sep 07 10:54:26 2008
|
||||||
|
@@ -59,6 +59,7 @@
|
||||||
|
|
||||||
|
#define DEFAULT_SEND_TIMEOUT 30
|
||||||
|
#define DEFAULT_RECEIVE_TIMEOUT 30
|
||||||
|
+#define RESPONSE_TIMEOUT 30
|
||||||
|
|
||||||
|
#ifndef HAVE_GETADDRINFO
|
||||||
|
|
||||||
|
@@ -110,6 +111,7 @@
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
/* translate a unix error code into a winsock error code */
|
||||||
|
static int sock_get_error( int err )
|
||||||
|
{
|
||||||
|
@@ -174,6 +176,9 @@
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
+#else
|
||||||
|
+#define sock_get_error(x) WSAGetLastError()
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
BOOL netconn_init( netconn_t *conn, BOOL secure )
|
||||||
|
{
|
||||||
|
@@ -282,7 +287,7 @@
|
||||||
|
conn->secure = FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
- res = close( conn->socket );
|
||||||
|
+ res = closesocket( conn->socket );
|
||||||
|
conn->socket = -1;
|
||||||
|
if (res == -1)
|
||||||
|
{
|
||||||
|
@@ -463,7 +468,7 @@
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#ifdef FIONREAD
|
||||||
|
- if (!(ret = ioctl( conn->socket, FIONREAD, &unread )))
|
||||||
|
+ if (!(ret = ioctlsocket( conn->socket, FIONREAD, &unread )))
|
||||||
|
{
|
||||||
|
TRACE("%d bytes of queued, but unread data\n", unread);
|
||||||
|
*available += unread;
|
||||||
|
@@ -474,7 +479,8 @@
|
||||||
|
|
||||||
|
BOOL netconn_get_next_line( netconn_t *conn, char *buffer, DWORD *buflen )
|
||||||
|
{
|
||||||
|
- struct pollfd pfd;
|
||||||
|
+ struct timeval tv;
|
||||||
|
+ fd_set infd;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
DWORD recvd = 0;
|
||||||
|
|
||||||
|
@@ -516,11 +522,13 @@
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
- pfd.fd = conn->socket;
|
||||||
|
- pfd.events = POLLIN;
|
||||||
|
+ FD_ZERO(&infd);
|
||||||
|
+ FD_SET(conn->socket, &infd);
|
||||||
|
+ tv.tv_sec=RESPONSE_TIMEOUT;
|
||||||
|
+ tv.tv_usec=0;
|
||||||
|
while (recvd < *buflen)
|
||||||
|
{
|
||||||
|
- if (poll( &pfd, 1, DEFAULT_RECEIVE_TIMEOUT * 1000 ) > 0)
|
||||||
|
+ if (select(conn->socket+1,&infd,NULL,NULL,&tv) > 0)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
if ((res = recv( conn->socket, &buffer[recvd], 1, 0 )) <= 0)
|
||||||
|
--- request.c Fri Sep 05 17:34:17 2008
|
||||||
|
+++ request.c Sun Sep 07 10:55:25 2008
|
||||||
|
@@ -34,6 +34,8 @@
|
||||||
|
|
||||||
|
#include "winhttp_private.h"
|
||||||
|
|
||||||
|
+#include "inet_ntop.c"
|
||||||
|
+
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
|
||||||
|
|
||||||
|
static const WCHAR attr_accept[] = {'A','c','c','e','p','t',0};
|
||||||
|
--- winhttp_private.h Thu Sep 04 15:27:29 2008
|
||||||
|
+++ winhttp_private.h Sun Sep 07 10:46:54 2008
|
||||||
|
@@ -33,8 +33,14 @@
|
||||||
|
# include <netdb.h>
|
||||||
|
#endif
|
||||||
|
#if defined(__MINGW32__) || defined (_MSC_VER)
|
||||||
|
-# include <ws2tcpip.h>
|
||||||
|
-#endif
|
||||||
|
+# include "ws2tcpip.h"
|
||||||
|
+# ifndef MSG_WAITALL
|
||||||
|
+# define MSG_WAITALL 0
|
||||||
|
+# endif
|
||||||
|
+#else
|
||||||
|
+# define closesocket close
|
||||||
|
+# define ioctlsocket ioctl
|
||||||
|
+#endif /* __MINGW32__ */
|
||||||
|
|
||||||
|
typedef struct _object_header_t object_header_t;
|
||||||
|
|
Loading…
Reference in a new issue