On Sunday 27 January 2008 06:42:45 EA Durbin wrote:

[ I decided to CC wine-devel since you're the second person to ask ]

> You had completed some work on winhttp and provided a snapshot in bug 9200.
> Has this been sent to wine-patches yet?  I was going to tinker with it a bit
> to see if I could get an app working and wondered if you had anything more
> up to date or if this had been merged into git yet? If you've already got
> a solution I don't want to reinvent the wheel.    

Here's a rediffed version of my unfinished winhttp patch. I wrote it primarily
to explore the option of implementing winhttp on top of wininet.

Basically we are faced with a choice between this option, which requires
a Wine-only extension to wininet to implement winhttp style callbacks, and
duplicating wininet code.

I think layering can be done in a relatively clean way by making wininet
handle the superset of wininet and winhttp callbacks and adding callback
filtering as required by winhttp. Old wininet behavior can then be obtained
by an implicit filter on the wininet subset of callbacks.

If time permits I'll write a comprehensive test suite for winhttp which
should help us make an informed decision.

 -Hans
diff --git a/dlls/winhttp/Makefile.in b/dlls/winhttp/Makefile.in
index 893c990..a007251 100644
--- a/dlls/winhttp/Makefile.in
+++ b/dlls/winhttp/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = winhttp.dll
-IMPORTS   = kernel32
+IMPORTS   = wininet kernel32
 
 C_SRCS	  = main.c
 
diff --git a/dlls/winhttp/main.c b/dlls/winhttp/main.c
index c3616b6..e4ccbaf 100644
--- a/dlls/winhttp/main.c
+++ b/dlls/winhttp/main.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2007 Jacek Caban for CodeWeavers
+ * Copyright 2007 Hans Leidekker
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -23,12 +24,234 @@
 #include "windef.h"
 #include "winbase.h"
 #include "objbase.h"
-#include "winhttp.h"
+#include "wininet.h"
+#include "winhttp_private.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
 
+static inline WCHAR *winhttp_strdup( const WCHAR *src )
+{
+    WCHAR *dst;
+
+    if (!src) return NULL;
+    if ((dst = HeapAlloc( GetProcessHeap(), 0, (strlenW( src ) + 1) * sizeof(WCHAR) )))
+        strcpyW( dst, src );
+    return dst;
+}
+
+#define QUERY_MODIFIER_FLAGS_MASK ( WINHTTP_QUERY_FLAG_REQUEST_HEADERS \
+                                  | WINHTTP_QUERY_FLAG_SYSTEMTIME      \
+                                  | WINHTTP_QUERY_FLAG_NUMBER          \
+                                  )
+#define QUERY_HEADER_MASK (~QUERY_MODIFIER_FLAGS_MASK)
+
+static DWORD map_info_level(DWORD level)
+{
+    DWORD index, ret;
+
+    static const DWORD info_level[] =
+    {
+        HTTP_QUERY_MIME_VERSION,                HTTP_QUERY_CONTENT_TYPE,
+        HTTP_QUERY_CONTENT_TRANSFER_ENCODING,   HTTP_QUERY_CONTENT_ID,
+        HTTP_QUERY_CONTENT_DESCRIPTION,         HTTP_QUERY_CONTENT_LENGTH,
+        HTTP_QUERY_CONTENT_LANGUAGE,            HTTP_QUERY_ALLOW,
+        HTTP_QUERY_PUBLIC,                      HTTP_QUERY_DATE,
+        HTTP_QUERY_EXPIRES,                     HTTP_QUERY_LAST_MODIFIED,
+        HTTP_QUERY_MESSAGE_ID,                  HTTP_QUERY_URI,
+        HTTP_QUERY_DERIVED_FROM,                HTTP_QUERY_COST,
+        HTTP_QUERY_LINK,                        HTTP_QUERY_PRAGMA,
+        HTTP_QUERY_VERSION,                     HTTP_QUERY_STATUS_CODE,
+        HTTP_QUERY_STATUS_TEXT,                 HTTP_QUERY_RAW_HEADERS,
+        HTTP_QUERY_RAW_HEADERS_CRLF,            HTTP_QUERY_CONNECTION,
+        HTTP_QUERY_ACCEPT,                      HTTP_QUERY_ACCEPT_CHARSET,
+        HTTP_QUERY_ACCEPT_ENCODING,             HTTP_QUERY_ACCEPT_LANGUAGE,
+        HTTP_QUERY_AUTHORIZATION,               HTTP_QUERY_CONTENT_ENCODING,
+        HTTP_QUERY_FORWARDED,                   HTTP_QUERY_FROM,
+        HTTP_QUERY_IF_MODIFIED_SINCE,           HTTP_QUERY_LOCATION,
+        HTTP_QUERY_ORIG_URI,                    HTTP_QUERY_REFERER,
+        HTTP_QUERY_RETRY_AFTER,                 HTTP_QUERY_SERVER,
+        HTTP_QUERY_TITLE,                       HTTP_QUERY_USER_AGENT,
+        HTTP_QUERY_WWW_AUTHENTICATE,            HTTP_QUERY_PROXY_AUTHENTICATE,
+        HTTP_QUERY_ACCEPT_RANGES,               HTTP_QUERY_SET_COOKIE,
+        HTTP_QUERY_COOKIE,                      HTTP_QUERY_REQUEST_METHOD,
+        HTTP_QUERY_REFRESH,                     HTTP_QUERY_CONTENT_DISPOSITION,
+        HTTP_QUERY_AGE,                         HTTP_QUERY_CACHE_CONTROL,
+        HTTP_QUERY_CONTENT_BASE,                HTTP_QUERY_CONTENT_LOCATION,
+        HTTP_QUERY_CONTENT_MD5,                 HTTP_QUERY_CONTENT_RANGE,
+        HTTP_QUERY_ETAG,                        HTTP_QUERY_HOST,
+        HTTP_QUERY_IF_MATCH,                    HTTP_QUERY_IF_NONE_MATCH,
+        HTTP_QUERY_IF_RANGE,                    HTTP_QUERY_IF_UNMODIFIED_SINCE,
+        HTTP_QUERY_MAX_FORWARDS,                HTTP_QUERY_PROXY_AUTHORIZATION,
+        HTTP_QUERY_RANGE,                       HTTP_QUERY_TRANSFER_ENCODING,
+        HTTP_QUERY_UPGRADE,                     HTTP_QUERY_VARY,
+        HTTP_QUERY_VIA,                         HTTP_QUERY_WARNING,
+        HTTP_QUERY_EXPECT,                      HTTP_QUERY_PROXY_CONNECTION,
+        HTTP_QUERY_UNLESS_MODIFIED_SINCE,       HTTP_QUERY_PROXY_SUPPORT,
+        HTTP_QUERY_AUTHENTICATION_INFO,         HTTP_QUERY_PASSPORT_URLS,
+        HTTP_QUERY_PASSPORT_CONFIG
+    };
+
+    index = level & QUERY_HEADER_MASK;
+    if (index < sizeof(info_level) / sizeof(info_level[0])) ret = info_level[index];
+    else if (level == WINHTTP_QUERY_CUSTOM) ret = HTTP_QUERY_CUSTOM;
+    else
+    {
+        WARN("unknown info level: %d\n", level);
+        return level;
+    }
+    if (level & WINHTTP_QUERY_FLAG_REQUEST_HEADERS) ret |= HTTP_QUERY_FLAG_REQUEST_HEADERS;
+    if (level & WINHTTP_QUERY_FLAG_SYSTEMTIME)      ret |= HTTP_QUERY_FLAG_SYSTEMTIME;
+    if (level & WINHTTP_QUERY_FLAG_NUMBER)          ret |= HTTP_QUERY_FLAG_NUMBER;
+    return ret;
+}
+
+static DWORD map_option(DWORD option, BOOL *retval)
+{
+    DWORD opt;
+
+    *retval = TRUE;
+    switch (option)
+    {
+    case WINHTTP_OPTION_CALLBACK:               opt = INTERNET_OPTION_CALLBACK; break;
+    case WINHTTP_OPTION_CONNECT_TIMEOUT:        opt = INTERNET_OPTION_CONNECT_TIMEOUT; break;
+    case WINHTTP_OPTION_CONNECT_RETRIES:        opt = INTERNET_OPTION_CONNECT_RETRIES; break;
+    case WINHTTP_OPTION_SEND_TIMEOUT:           opt = INTERNET_OPTION_SEND_TIMEOUT; break;
+    case WINHTTP_OPTION_RECEIVE_TIMEOUT:        opt = INTERNET_OPTION_RECEIVE_TIMEOUT; break;
+    case WINHTTP_OPTION_HANDLE_TYPE:            opt = INTERNET_OPTION_HANDLE_TYPE; break;
+    case WINHTTP_OPTION_READ_BUFFER_SIZE:       opt = INTERNET_OPTION_READ_BUFFER_SIZE; break;
+    case WINHTTP_OPTION_WRITE_BUFFER_SIZE:      opt = INTERNET_OPTION_WRITE_BUFFER_SIZE; break;
+    case WINHTTP_OPTION_PARENT_HANDLE:          opt = INTERNET_OPTION_PARENT_HANDLE; break;
+    case WINHTTP_OPTION_EXTENDED_ERROR:         opt = INTERNET_OPTION_EXTENDED_ERROR; break;
+    case WINHTTP_OPTION_SECURITY_FLAGS:         opt = INTERNET_OPTION_SECURITY_FLAGS; break;
+    case WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT:    opt = INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT; break;
+    case WINHTTP_OPTION_URL:                    opt = INTERNET_OPTION_URL; break;
+    case WINHTTP_OPTION_SECURITY_KEY_BITNESS:   opt = INTERNET_OPTION_SECURITY_KEY_BITNESS; break;
+    case WINHTTP_OPTION_PROXY:                  opt = INTERNET_OPTION_PROXY; break;
+    case WINHTTP_OPTION_USER_AGENT:             opt = INTERNET_OPTION_USER_AGENT; break;
+    case WINHTTP_OPTION_CONTEXT_VALUE:          opt = INTERNET_OPTION_CONTEXT_VALUE; break;
+    case WINHTTP_OPTION_CLIENT_CERT_CONTEXT:    opt = INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT; break;
+    case WINHTTP_OPTION_REQUEST_PRIORITY:       opt = INTERNET_OPTION_REQUEST_PRIORITY; break;
+    case WINHTTP_OPTION_HTTP_VERSION:           opt = INTERNET_OPTION_HTTP_VERSION; break;
+    case WINHTTP_OPTION_CODEPAGE:               opt = INTERNET_OPTION_CODEPAGE; break;
+    case WINHTTP_OPTION_MAX_CONNS_PER_SERVER:   opt = INTERNET_OPTION_MAX_CONNS_PER_SERVER; break;
+    case WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER:   opt = INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER; break;
+    case WINHTTP_OPTION_USERNAME:               opt = INTERNET_OPTION_USERNAME; break;
+    case WINHTTP_OPTION_PASSWORD:               opt = INTERNET_OPTION_PASSWORD; break;
+    case WINHTTP_OPTION_PROXY_USERNAME:         opt = INTERNET_OPTION_PROXY_USERNAME; break;
+    case WINHTTP_OPTION_PROXY_PASSWORD:         opt = INTERNET_OPTION_PROXY_PASSWORD; break;
+
+
+    case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT:
+    case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+    case WINHTTP_OPTION_DISABLE_FEATURE:
+    case WINHTTP_OPTION_AUTOLOGON_POLICY:
+    case WINHTTP_OPTION_SERVER_CERT_CONTEXT:
+    case WINHTTP_OPTION_ENABLE_FEATURE:
+    case WINHTTP_OPTION_WORKER_THREAD_COUNT:
+    case WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT:
+    case WINHTTP_OPTION_PASSPORT_COBRANDING_URL:
+    case WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH:
+    case WINHTTP_OPTION_SECURE_PROTOCOLS:
+    case WINHTTP_OPTION_ENABLETRACING:
+    case WINHTTP_OPTION_PASSPORT_SIGN_OUT:
+    case WINHTTP_OPTION_PASSPORT_RETURN_URL:
+    case WINHTTP_OPTION_REDIRECT_POLICY:
+    case WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS:
+    case WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE:
+    case WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE:
+    case WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE:
+        FIXME("option not supported: %x\n", option);
+        return 0;
+    default:
+        WARN("unknown option: %x\n", option);
+        *retval = FALSE;
+        return 0;
+    }
+    return opt;
+}
+
+static DWORD map_open_flags(DWORD flags)
+{
+    DWORD ret = 0;
+
+    if (flags & WINHTTP_FLAG_ASYNC) ret |= INTERNET_FLAG_ASYNC;
+    return ret;
+}
+
+static DWORD map_req_flags(DWORD flags)
+{
+    DWORD ret = 0;
+
+    if (flags & WINHTTP_FLAG_SECURE)               ret |= INTERNET_FLAG_SECURE;
+    if (flags & WINHTTP_FLAG_BYPASS_PROXY_CACHE)   ret |= INTERNET_FLAG_PRAGMA_NOCACHE;
+
+    if (flags & WINHTTP_FLAG_ESCAPE_PERCENT)       FIXME("WINHTTP_FLAG_ESCAPE_PERCENT not implemented\n");
+    if (flags & WINHTTP_FLAG_NULL_CODEPAGE)        FIXME("WINHTTP_FLAG_NULL_CODEPAGE not implemented\n");
+    if (flags & WINHTTP_FLAG_ESCAPE_DISABLE)       FIXME("WINHTTP_FLAG_ESCAPE_DISABLE not implemented\n");
+    if (flags & WINHTTP_FLAG_ESCAPE_DISABLE_QUERY) FIXME("WINHTTP_FLAG_ESCAPE_DISABLE_QUERY not implemented\n");
+    return ret;
+}
+
+static DWORD map_req_modifiers(DWORD modifiers)
+{
+    DWORD ret = 0;
+
+    if (modifiers & WINHTTP_ADDREQ_FLAG_ADD)                     ret |= HTTP_ADDREQ_FLAG_ADD;
+    if (modifiers & WINHTTP_ADDREQ_FLAG_ADD_IF_NEW)              ret |= HTTP_ADDREQ_FLAG_ADD_IF_NEW;
+    if (modifiers & WINHTTP_ADDREQ_FLAG_COALESCE)                ret |= HTTP_ADDREQ_FLAG_COALESCE;
+    if (modifiers & WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA)     ret |= HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA;
+    if (modifiers & WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON) ret |= HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON;
+    if (modifiers & WINHTTP_ADDREQ_FLAG_REPLACE)                 ret |= HTTP_ADDREQ_FLAG_REPLACE;
+    return ret;
+}
+
+/***********************************************************************
+ *  HTTP_EncodeBase64 (taken from dlls/wininet/http.c)
+ */
+static UINT HTTP_EncodeBase64( LPCSTR bin, unsigned int len, LPWSTR base64 )
+{
+    UINT n = 0, x;
+    static const CHAR HTTP_Base64Enc[] =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+    while( len > 0 )
+    {
+        /* first 6 bits, all from bin[0] */
+        base64[n++] = HTTP_Base64Enc[(bin[0] & 0xfc) >> 2];
+        x = (bin[0] & 3) << 4;
+
+        /* next 6 bits, 2 from bin[0] and 4 from bin[1] */
+        if( len == 1 )
+        {
+            base64[n++] = HTTP_Base64Enc[x];
+            base64[n++] = '=';
+            base64[n++] = '=';
+            break;
+        }
+        base64[n++] = HTTP_Base64Enc[ x | ( (bin[1]&0xf0) >> 4 ) ];
+        x = ( bin[1] & 0x0f ) << 2;
+
+        /* next 6 bits 4 from bin[1] and 2 from bin[2] */
+        if( len == 2 )
+        {
+            base64[n++] = HTTP_Base64Enc[x];
+            base64[n++] = '=';
+            break;
+        }
+        base64[n++] = HTTP_Base64Enc[ x | ( (bin[2]&0xc0 ) >> 6 ) ];
+
+        /* last 6 bits, all from bin [2] */
+        base64[n++] = HTTP_Base64Enc[ bin[2] & 0x3f ];
+        bin += 3;
+        len -= 3;
+    }
+    base64[n] = 0;
+    return n;
+}
+
 /******************************************************************
  *              DllMain (winhttp.@)
  */
@@ -84,16 +307,100 @@ HRESULT WINAPI DllUnregisterServer(void)
 }
 
 /***********************************************************************
+ *          WinHttpAddRequestHeaders (winhttp.@)
+ */
+BOOL WINAPI WinHttpAddRequestHeaders(HINTERNET request, LPCWSTR headers, DWORD len, DWORD modifiers)
+{
+    TRACE("(%p %s %d %x)\n", request, debugstr_w(headers), len, modifiers);
+    return HttpAddRequestHeadersW(request, headers, len, map_req_modifiers(modifiers));
+}
+
+/***********************************************************************
  *          WinHttpCheckPlatform (winhttp.@)
  */
 BOOL WINAPI WinHttpCheckPlatform(void)
 {
-    FIXME("stub\n");
-    SetLastError(ERROR_NOT_SUPPORTED);
+    TRACE("()\n");
+    return TRUE;
+}
+
+/***********************************************************************
+ *          WinHttpCloseHandle (winhttp.@)
+ */
+BOOL WINAPI WinHttpCloseHandle(HINTERNET handle)
+{
+    TRACE("(%p)\n", handle);
+    return InternetCloseHandle(handle);
+}
+
+/***********************************************************************
+ *          WinHttpConnect (winhttp.@)
+ */
+HINTERNET WINAPI WinHttpConnect(HINTERNET session, LPCWSTR server, INTERNET_PORT port, DWORD reserved)
+{
+    TRACE("(%p %s %d %x)\n", session, debugstr_w(server), port, reserved);
+    return InternetConnectW(session, server, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
+}
+
+/***********************************************************************
+ *          WinHttpCrackUrl (winhttp.@)
+ */
+BOOL WINAPI WinHttpCrackUrl(LPCWSTR url, DWORD len, DWORD flags, LPURL_COMPONENTSW components)
+{
+    TRACE("(%s %d %x %p)\n", debugstr_w(url), len, flags, components);
+    return InternetCrackUrlW(url, len, flags, components);
+}
+
+/***********************************************************************
+ *          WinHttpCreateUrl (winhttp.@)
+ */
+BOOL WINAPI WinHttpCreateUrl(LPURL_COMPONENTSW components, DWORD flags, LPWSTR url, LPDWORD len)
+{
+    TRACE("(%p %x %p %p)\n", components, flags, url, len);
+    return InternetCreateUrlW(components, flags, url, len);
+}
+
+/***********************************************************************
+ *          WinHttpDetectAutoProxyConfigUrl (winhttp.@)
+ */
+BOOL WINAPI WinHttpDetectAutoProxyConfigUrl(DWORD flags, LPWSTR *url)
+{
+    FIXME("(%x %p)\n", flags, url);
+
+    SetLastError(ERROR_WINHTTP_AUTODETECTION_FAILED);
     return FALSE;
 }
 
 /***********************************************************************
+ *         WinHttpGetDefaultProxyConfiguration (winhttp.@)
+ */
+BOOL WINAPI WinHttpGetDefaultProxyConfiguration(WINHTTP_PROXY_INFO *info)
+{
+    INTERNET_PROXY_INFOW proxy;
+    DWORD size;
+
+    TRACE("(%p)\n", info);
+
+    size = sizeof(proxy);
+    if (!InternetQueryOptionW(NULL, INTERNET_OPTION_PROXY, &proxy, &size))
+        return FALSE;
+
+    switch (proxy.dwAccessType)
+    {
+    case INTERNET_OPEN_TYPE_PRECONFIG: info->dwAccessType = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY; break;
+    case INTERNET_OPEN_TYPE_DIRECT:    info->dwAccessType = WINHTTP_ACCESS_TYPE_NO_PROXY; break;
+    case INTERNET_OPEN_TYPE_PROXY:     info->dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; break;
+    default:
+        ERR("unknown access type: %x\n", proxy.dwAccessType);
+        return FALSE;
+    }
+    info->lpszProxy       = winhttp_strdup(proxy.lpszProxy);
+    info->lpszProxyBypass = winhttp_strdup(proxy.lpszProxyBypass);
+
+    return TRUE;
+}
+
+/***********************************************************************
  *          WinHttpGetIEProxyConfigForCurrentUser (winhttp.@)
  */
 BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config)
@@ -116,16 +423,392 @@ BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_
 }
 
 /***********************************************************************
+ *          WinHttpGetProxyForUrl (winhttp.@)
+ */
+BOOL WINAPI WinHttpGetProxyForUrl(HINTERNET session, LPCWSTR url, WINHTTP_AUTOPROXY_OPTIONS *options,
+                                  WINHTTP_PROXY_INFO *info)
+{
+    FIXME("(%p %s %p %p)\n", session, debugstr_w(url), options, info);
+    return FALSE;
+}
+
+/***********************************************************************
  *          WinHttpOpen (winhttp.@)
  */
-HINTERNET WINAPI WinHttpOpen(LPCWSTR pwszUserAgent, DWORD dwAccessType,
-                             LPCWSTR pwszProxyName, LPCWSTR pwszProxyByPass,
-                             DWORD dwFlags)
+HINTERNET WINAPI WinHttpOpen(LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWSTR bypass, DWORD flags)
+{
+    TRACE("(%s %x %s %s %x)\n", debugstr_w(agent), access, debugstr_w(proxy), debugstr_w(bypass), flags);
+    return InternetOpenW(agent, access, proxy, bypass, map_open_flags(flags));
+}
+
+/***********************************************************************
+ *          WinHttpOpenRequest (winhttp.@)
+ */
+HINTERNET WINAPI WinHttpOpenRequest(HINTERNET handle, LPCWSTR verb, LPCWSTR object, LPCWSTR version,
+                                    LPCWSTR referrer, LPCWSTR *accept, DWORD flags)
+{
+    DWORD flags_new;
+
+    TRACE("(%p %s %s %s %s %p %x)\n", handle, debugstr_w(verb), debugstr_w(object), debugstr_w(version),
+          debugstr_w(referrer), accept, flags);
+
+    flags_new = map_req_flags(flags) | INTERNET_FLAG_KEEP_CONNECTION;
+    return HttpOpenRequestW(handle, verb, object, version, referrer, accept, flags_new, 0);
+}
+
+#define ARRAYSIZE(array) (sizeof(array) / sizeof((array)[0]))
+
+static DWORD auth_scheme_from_header(WCHAR *header)
+{
+    static const WCHAR basic[]     = { 'B','a','s','i','c' };
+    static const WCHAR ntlm[]      = { 'N','T','L','M' };
+    static const WCHAR passport[]  = { 'P','a','s','s','p','o','r','t' };
+    static const WCHAR digest[]    = { 'D','i','g','e','s','t' };
+    static const WCHAR negotiate[] = { 'N','e','g','o','t','i','a','t','e' };
+
+    if (!strncmpiW(header, basic, ARRAYSIZE(basic)) &&
+        (header[ARRAYSIZE(basic)] != ' ' || !header[ARRAYSIZE(basic)])) return WINHTTP_AUTH_SCHEME_BASIC;
+
+    if (!strncmpiW(header, ntlm, ARRAYSIZE(ntlm)) &&
+        (header[ARRAYSIZE(ntlm)] != ' ' || !header[ARRAYSIZE(ntlm)])) return WINHTTP_AUTH_SCHEME_NTLM;
+
+    if (!strncmpiW(header, passport, ARRAYSIZE(passport)) &&
+        (header[ARRAYSIZE(passport)] != ' ' || !header[ARRAYSIZE(passport)])) return WINHTTP_AUTH_SCHEME_PASSPORT;
+
+    if (!strncmpiW(header, digest, ARRAYSIZE(digest)) &&
+        (header[ARRAYSIZE(digest)] != ' ' || !header[ARRAYSIZE(digest)])) return WINHTTP_AUTH_SCHEME_DIGEST;
+
+    if (!strncmpiW(header, negotiate, ARRAYSIZE(negotiate)) &&
+        (header[ARRAYSIZE(negotiate)] != ' ' || !header[ARRAYSIZE(negotiate)])) return WINHTTP_AUTH_SCHEME_NEGOTIATE;
+
+    return 0;
+}
+
+static BOOL query_auth_schemes(HINTERNET request, DWORD level, LPDWORD supported, LPDWORD first, LPDWORD target)
+{
+    DWORD index = 0;
+    BOOL ret = FALSE;
+
+    *supported = *first = 0;
+    for (;;)
+    {
+        DWORD len, scheme;
+        WCHAR *buffer;
+
+        len = 0;
+        HttpQueryInfoW(request, level, NULL, &len, &index);
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) break;
+
+        index--;
+        if (!(buffer = HeapAlloc(GetProcessHeap(), 0, len + sizeof(WCHAR)))) return FALSE;
+        if (!HttpQueryInfoW(request, level, buffer, &len, &index))
+        {
+            HeapFree(GetProcessHeap(), 0, buffer);
+            return FALSE;
+        }
+        scheme = auth_scheme_from_header(buffer);
+        if (index == 1) *first = scheme;
+        *supported |= scheme;
+
+        HeapFree(GetProcessHeap(), 0, buffer);
+        ret = TRUE;
+        index++;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *          WinHttpQueryAuthSchemes (winhttp.@)
+ */
+BOOL WINAPI WinHttpQueryAuthSchemes(HINTERNET request, LPDWORD supported, LPDWORD first, LPDWORD target)
 {
-    FIXME("(%s, %d, %s, %s, 0x%x): stub\n", debugstr_w(pwszUserAgent),
-        dwAccessType, debugstr_w(pwszProxyName), debugstr_w(pwszProxyByPass),
-        dwFlags);
+    BOOL ret = FALSE;
 
-    SetLastError(ERROR_NOT_SUPPORTED);
-    return NULL;
+    TRACE("(%p %p %p %p)\n", request, supported, first, target);
+
+    if (query_auth_schemes(request, HTTP_QUERY_WWW_AUTHENTICATE, supported, first, target))
+    {
+        *target = WINHTTP_AUTH_TARGET_SERVER;
+        ret = TRUE;
+    }
+    if (query_auth_schemes(request, HTTP_QUERY_PROXY_AUTHENTICATE, supported, first, target))
+    {
+        *target |= WINHTTP_AUTH_TARGET_PROXY;
+        ret = TRUE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *          WinHttpQueryDataAvailable (winhttp.@)
+ */
+BOOL WINAPI WinHttpQueryDataAvailable(HINTERNET request, LPDWORD available)
+{
+    TRACE("(%p %p)\n", request, available);
+    return InternetQueryDataAvailable(request, available, 0, 0);
+}
+
+/***********************************************************************
+ *          WinHttpQueryHeaders (winhttp.@)
+ */
+BOOL WINAPI WinHttpQueryHeaders(HINTERNET request, DWORD level, LPCWSTR name, LPVOID buffer,
+                                LPDWORD len, LPDWORD index)
+{
+    TRACE("(%p %d %s %p %p %p)\n", request, level, debugstr_w(name), buffer, len, index);
+    return HttpQueryInfoW(request, map_info_level(level), buffer, len, index);
+}
+
+/***********************************************************************
+ *          WinHttpQueryOption (winhttp.@)
+ */
+BOOL WINAPI WinHttpQueryOption(HINTERNET handle, DWORD option, LPVOID buffer, LPDWORD len)
+{
+    BOOL ret;
+    DWORD opt = 0;
+
+    TRACE("(%p %x %p %p)\n", handle, option, buffer, len);
+
+    if (!option || ((opt = map_option(option, &ret)) && ret))
+        ret = InternetQueryOptionW(handle, opt, buffer, len);
+
+    return ret;
+}
+
+/***********************************************************************
+ *          WinHttpReadData (winhttp.@)
+ */
+BOOL WINAPI WinHttpReadData(HINTERNET request, LPVOID buffer, DWORD to_read, LPDWORD read)
+{
+    TRACE("(%p %p %d %p)\n", request, buffer, to_read, read);
+    return InternetReadFile(request, buffer, to_read, read);
+}
+
+/***********************************************************************
+ *          WinHttpReceiveResponse (winhttp.@)
+ */
+BOOL WINAPI WinHttpReceiveResponse(HINTERNET request, LPVOID reserved)
+{
+    TRACE("(%p %p)\n", request, reserved);
+    return HttpEndRequestW(request, 0, 0, 0);
+}
+
+/***********************************************************************
+ *          WinHttpSendRequest (winhttp.@)
+ */
+BOOL WINAPI WinHttpSendRequest(HINTERNET request, LPCWSTR headers, DWORD headers_len,
+                               LPVOID optional, DWORD optional_len, DWORD total_len, DWORD_PTR context)
+{
+    INTERNET_BUFFERSW buffers;
+
+    TRACE("(%p %s %d %p %d %d %lx)\n", request, debugstr_w(headers), headers_len, optional,
+          optional_len, total_len, context);
+
+    memset(&buffers, 0, sizeof(buffers));
+    buffers.dwStructSize = sizeof(buffers);
+    if (headers)
+    {
+        buffers.lpcszHeader = headers;
+        if (headers_len == ~0UL) buffers.dwHeadersLength = strlenW(buffers.lpcszHeader) + 1;
+        else buffers.dwHeadersLength = headers_len;
+    }
+    buffers.lpvBuffer = optional;
+    buffers.dwBufferLength = optional_len;
+    buffers.dwBufferTotal = total_len;
+
+    return HttpSendRequestExW(request, &buffers, NULL, 0, context);
+}
+
+/***********************************************************************
+ *          WinHttpSetCredentials (winhttp.@)
+ */
+BOOL WINAPI WinHttpSetCredentials(HINTERNET request, DWORD target, DWORD scheme, LPCWSTR username,
+                                  LPCWSTR password, LPVOID params)
+{
+    static const WCHAR basic[] =
+        { 'B','a','s','i','c',' ',0 };
+    static const WCHAR auth_server[] =
+        { 'A','u','t','h','o','r','i','z','a','t','i','o','n',':',' ',0 };
+    static const WCHAR auth_proxy[] =
+        { 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',':',' ',0 };
+
+    const WCHAR *auth_scheme, *auth_target;
+    WCHAR *auth_header;
+    DWORD len, auth_data_len;
+    char *auth_data;
+    BOOL ret;
+
+    TRACE("(%p %x %x %s %s %p)\n", request, target, scheme, debugstr_w(username),
+          debugstr_w(password), params);
+
+    switch (target)
+    {
+    case WINHTTP_AUTH_TARGET_SERVER: auth_target = auth_server; break;
+    case WINHTTP_AUTH_TARGET_PROXY:  auth_target = auth_proxy; break;
+    default:
+        ERR("unknown target %x\n", target);
+        return FALSE;
+    }
+    switch (scheme)
+    {
+    case WINHTTP_AUTH_SCHEME_BASIC:
+    {
+        int userlen = WideCharToMultiByte(CP_UTF8, 0, username, strlenW(username), NULL, 0, NULL, NULL);
+        int passlen = WideCharToMultiByte(CP_UTF8, 0, password, strlenW(password), NULL, 0, NULL, NULL);
+
+        TRACE("basic authentication\n");
+
+        auth_scheme = basic;
+        auth_data_len = userlen + 1 + passlen;
+        if (!(auth_data = HeapAlloc(GetProcessHeap(), 0, auth_data_len))) return FALSE;
+
+        WideCharToMultiByte(CP_UTF8, 0, username, -1, auth_data, userlen, NULL, NULL);
+        auth_data[userlen] = ':';
+        WideCharToMultiByte(CP_UTF8, 0, password, -1, &auth_data[userlen + 1], passlen, NULL, NULL);
+        break;
+    }
+    case WINHTTP_AUTH_SCHEME_NTLM:
+    case WINHTTP_AUTH_SCHEME_PASSPORT:
+    case WINHTTP_AUTH_SCHEME_DIGEST:
+    case WINHTTP_AUTH_SCHEME_NEGOTIATE:
+        FIXME("unimplemented authentication scheme %x\n", scheme);
+        return FALSE;
+    default:
+        ERR("unknown authentication scheme %x\n", scheme);
+        return FALSE;
+    }
+
+    len = strlenW(auth_target) + strlenW(auth_scheme) + ((auth_data_len + 2) * 4) / 3;
+    if (!(auth_header = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR))))
+    {
+        HeapFree(GetProcessHeap(), 0, auth_data);
+        return FALSE;
+    }
+    strcpyW(auth_header, auth_target);
+    strcatW(auth_header, auth_scheme);
+    HTTP_EncodeBase64(auth_data, auth_data_len, auth_header + strlenW(auth_header));
+
+    ret = WinHttpSendRequest(request, auth_header, ~0UL, NULL, 0, 0, 0);
+
+    HeapFree(GetProcessHeap(), 0, auth_data);
+    HeapFree(GetProcessHeap(), 0, auth_header);
+    return ret;
+}
+
+/***********************************************************************
+ *         WinHttpSetDefaultProxyConfiguration (winhttp.@)
+ */
+BOOL WINAPI WinHttpSetDefaultProxyConfiguration(WINHTTP_PROXY_INFO *info)
+{
+    INTERNET_PROXY_INFOW proxy;
+
+    TRACE("(%p)\n", info);
+
+    switch (info->dwAccessType)
+    {
+    case WINHTTP_ACCESS_TYPE_DEFAULT_PROXY: proxy.dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG;
+    case WINHTTP_ACCESS_TYPE_NO_PROXY:      proxy.dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
+    case WINHTTP_ACCESS_TYPE_NAMED_PROXY:   proxy.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
+    default:
+        WARN("unknown access type: %x\n", info->dwAccessType);
+        return FALSE;
+    }
+    proxy.lpszProxy       = info->lpszProxy;
+    proxy.lpszProxyBypass = info->lpszProxyBypass;
+
+    return InternetSetOptionW(NULL, INTERNET_OPTION_PROXY, &proxy, sizeof(proxy));
+}
+
+/***********************************************************************
+ *          WinHttpSetOption (winhttp.@)
+ */
+BOOL WINAPI WinHttpSetOption(HINTERNET handle, DWORD option, LPVOID buffer, DWORD len)
+{
+    BOOL ret;
+    DWORD opt = 0;
+
+    TRACE("(%p %x %p %d)\n", handle, option, buffer, len);
+
+    if (!option || ((opt = map_option(option, &ret)) && ret))
+        ret = InternetSetOptionW(handle, opt, buffer, len);
+
+    return ret;
+}
+
+#define INTERNET_OPTION_CALLBACK_FILTERED     10000   /* Wine extension */
+
+/***********************************************************************
+ *          WinHttpSetStatusCallback (winhttp.@)
+ */
+WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback(HINTERNET handle, WINHTTP_STATUS_CALLBACK callback,
+                                                        DWORD flags, DWORD_PTR reserved)
+{
+    struct
+    {
+        DWORD filter;
+        INTERNET_STATUS_CALLBACK new;
+        INTERNET_STATUS_CALLBACK old;
+    } cbf;
+
+    TRACE("(%p %p %x %lx)\n", handle, callback, flags, reserved);
+
+    cbf.filter = flags;
+    cbf.new    = callback;
+    cbf.old    = NULL;
+    if (InternetSetOptionW(handle, INTERNET_OPTION_CALLBACK_FILTERED, &cbf, sizeof(cbf)))
+        return cbf.old;
+
+    return WINHTTP_INVALID_STATUS_CALLBACK;
+}
+
+/***********************************************************************
+ *          WinHttpSetTimeouts (winhttp.@)
+ */
+BOOL WINAPI WinHttpSetTimeouts(HINTERNET handle, int resolve, int connect, int send, int receive)
+{
+    ULONG timeout;
+
+    TRACE("(%p %d %d %d %d)\n", handle, resolve, connect, send, receive);
+
+    if (resolve < -1 || connect < -1 || send < -1 || receive < -1)
+        return ERROR_INVALID_PARAMETER;
+
+    if (resolve > 0) FIXME("resolve timeout not supported\n");
+
+    timeout = (connect > 0) ? connect : ~0UL;
+    InternetSetOptionW(handle, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
+
+    timeout = (send > 0) ? send : ~0UL;
+    InternetSetOptionW(handle, INTERNET_OPTION_SEND_TIMEOUT, &timeout, sizeof(timeout));
+
+    timeout = (receive > 0) ? receive : ~0UL;
+    InternetSetOptionW(handle, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeout, sizeof(timeout));
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *          WinHttpTimeFromSystemTime (winhttp.@)
+ */
+BOOL WINAPI WinHttpTimeFromSystemTime(const SYSTEMTIME *st, LPWSTR time)
+{
+    TRACE("(%p %p)\n", st, time);
+    return InternetTimeFromSystemTimeW(st, INTERNET_RFC1123_FORMAT, time, WINHTTP_TIME_FORMAT_BUFSIZE);
+}
+
+/***********************************************************************
+ *          WinHttpTimeToSystemTime (winhttp.@)
+ */
+BOOL WINAPI WinHttpTimeToSystemTime(LPCWSTR time, SYSTEMTIME *st)
+{
+    TRACE("(%s %p)\n", debugstr_w(time), st);
+    return InternetTimeToSystemTimeW(time, st, 0);
+}
+
+/***********************************************************************
+ *          WinHttpWriteData (winhttp.@)
+ */
+BOOL WINAPI WinHttpWriteData(HINTERNET request, LPCVOID buffer, DWORD to_write, LPDWORD written)
+{
+    TRACE("(%p %p %d %p)\n", request, buffer, to_write, written);
+    return InternetWriteFile(request, buffer, to_write, written);
 }
diff --git a/dlls/winhttp/winhttp.spec b/dlls/winhttp/winhttp.spec
index e1562b6..700628e 100644
--- a/dlls/winhttp/winhttp.spec
+++ b/dlls/winhttp/winhttp.spec
@@ -2,30 +2,30 @@
 @ stdcall -private DllGetClassObject(ptr ptr ptr)
 @ stdcall -private DllRegisterServer()
 @ stdcall -private DllUnregisterServer()
-@ stub WinHttpAddRequestHeaders
+@ stdcall WinHttpAddRequestHeaders(long wstr long long)
 @ stdcall WinHttpCheckPlatform()
-@ stub WinHttpCloseHandle
-@ stub WinHttpConnect
-@ stub WinHttpCrackUrl
-@ stub WinHttpCreateUrl
-@ stub WinHttpDetectAutoProxyConfigUrl
-@ stub WinHttpGetDefaultProxyConfiguration
+@ stdcall WinHttpCloseHandle(long)
+@ stdcall WinHttpConnect(long wstr long long)
+@ stdcall WinHttpCrackUrl(wstr long long ptr)
+@ stdcall WinHttpCreateUrl(ptr long ptr ptr)
+@ stdcall WinHttpDetectAutoProxyConfigUrl(long ptr)
+@ stdcall WinHttpGetDefaultProxyConfiguration(ptr)
 @ stdcall WinHttpGetIEProxyConfigForCurrentUser(ptr)
-@ stub WinHttpGetProxyForUrl
+@ stdcall WinHttpGetProxyForUrl(long wstr ptr ptr)
 @ stdcall WinHttpOpen(wstr long wstr wstr long)
-@ stub WinHttpOpenRequest
-@ stub WinHttpQueryAuthSchemes
-@ stub WinHttpQueryDataAvailable
-@ stub WinHttpQueryHeaders
-@ stub WinHttpQueryOption
-@ stub WinHttpReadData
-@ stub WinHttpReceiveResponse
-@ stub WinHttpSendRequest
-@ stub WinHttpSetCredentials
-@ stub WinHttpSetDefaultProxyConfiguration
-@ stub WinHttpSetOption
-@ stub WinHttpSetStatusCallback
-@ stub WinHttpSetTimeouts
-@ stub WinHttpTimeFromSystemTime
-@ stub WinHttpTimeToSystemTime
-@ stub WinHttpWriteData
+@ stdcall WinHttpOpenRequest(long wstr wstr wstr wstr ptr long)
+@ stdcall WinHttpQueryAuthSchemes(long ptr ptr ptr)
+@ stdcall WinHttpQueryDataAvailable(long ptr)
+@ stdcall WinHttpQueryHeaders(long long wstr ptr ptr ptr)
+@ stdcall WinHttpQueryOption(long long ptr ptr)
+@ stdcall WinHttpReadData(long ptr long ptr)
+@ stdcall WinHttpReceiveResponse(long ptr)
+@ stdcall WinHttpSendRequest(long wstr long ptr long long ptr)
+@ stdcall WinHttpSetCredentials(long long long wstr wstr ptr)
+@ stdcall WinHttpSetDefaultProxyConfiguration(ptr)
+@ stdcall WinHttpSetOption(long long ptr long)
+@ stdcall WinHttpSetStatusCallback(long ptr long ptr)
+@ stdcall WinHttpSetTimeouts(long long long long long)
+@ stdcall WinHttpTimeFromSystemTime(ptr ptr)
+@ stdcall WinHttpTimeToSystemTime(wstr ptr)
+@ stdcall WinHttpWriteData(long ptr long ptr)
diff --git a/include/winhttp.h b/include/winhttp.h
index c57563d..78bff23 100644
--- a/include/winhttp.h
+++ b/include/winhttp.h
@@ -26,6 +26,231 @@
 typedef LPVOID HINTERNET;
 typedef HINTERNET *LPHINTERNET;
 
+#define WINHTTP_TIME_FORMAT_BUFSIZE     62
+
+#define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS         0xffffffff
+
+#define WINHTTP_ERROR_BASE                      12000
+#define ERROR_WINHTTP_AUTODETECTION_FAILED      (WINHTTP_ERROR_BASE + 180)
+
+typedef VOID (CALLBACK *WINHTTP_STATUS_CALLBACK)(HINTERNET, DWORD_PTR, DWORD, LPVOID, DWORD);
+typedef WINHTTP_STATUS_CALLBACK *LPWINHTTP_STATUS_CALLBACK;
+
+#define WINHTTP_QUERY_MIME_VERSION              0
+#define WINHTTP_QUERY_CONTENT_TYPE              1
+#define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING 2
+#define WINHTTP_QUERY_CONTENT_ID                3
+#define WINHTTP_QUERY_CONTENT_DESCRIPTION       4
+#define WINHTTP_QUERY_CONTENT_LENGTH            5
+#define WINHTTP_QUERY_CONTENT_LANGUAGE          6
+#define WINHTTP_QUERY_ALLOW                     7
+#define WINHTTP_QUERY_PUBLIC                    8
+#define WINHTTP_QUERY_DATE                      9
+#define WINHTTP_QUERY_EXPIRES                   10
+#define WINHTTP_QUERY_LAST_MODIFIED             11
+#define WINHTTP_QUERY_MESSAGE_ID                12
+#define WINHTTP_QUERY_URI                       13
+#define WINHTTP_QUERY_DERIVED_FROM              14
+#define WINHTTP_QUERY_COST                      15
+#define WINHTTP_QUERY_LINK                      16
+#define WINHTTP_QUERY_PRAGMA                    17
+#define WINHTTP_QUERY_VERSION                   18
+#define WINHTTP_QUERY_STATUS_CODE               19
+#define WINHTTP_QUERY_STATUS_TEXT               20
+#define WINHTTP_QUERY_RAW_HEADERS               21
+#define WINHTTP_QUERY_RAW_HEADERS_CRLF          22
+#define WINHTTP_QUERY_CONNECTION                23
+#define WINHTTP_QUERY_ACCEPT                    24
+#define WINHTTP_QUERY_ACCEPT_CHARSET            25
+#define WINHTTP_QUERY_ACCEPT_ENCODING           26
+#define WINHTTP_QUERY_ACCEPT_LANGUAGE           27
+#define WINHTTP_QUERY_AUTHORIZATION             28
+#define WINHTTP_QUERY_CONTENT_ENCODING          29
+#define WINHTTP_QUERY_FORWARDED                 30
+#define WINHTTP_QUERY_FROM                      31
+#define WINHTTP_QUERY_IF_MODIFIED_SINCE         32
+#define WINHTTP_QUERY_LOCATION                  33
+#define WINHTTP_QUERY_ORIG_URI                  34
+#define WINHTTP_QUERY_REFERER                   35
+#define WINHTTP_QUERY_RETRY_AFTER               36
+#define WINHTTP_QUERY_SERVER                    37
+#define WINHTTP_QUERY_TITLE                     38
+#define WINHTTP_QUERY_USER_AGENT                39
+#define WINHTTP_QUERY_WWW_AUTHENTICATE          40
+#define WINHTTP_QUERY_PROXY_AUTHENTICATE        41
+#define WINHTTP_QUERY_ACCEPT_RANGES             42
+#define WINHTTP_QUERY_SET_COOKIE                43
+#define WINHTTP_QUERY_COOKIE                    44
+#define WINHTTP_QUERY_REQUEST_METHOD            45
+#define WINHTTP_QUERY_REFRESH                   46
+#define WINHTTP_QUERY_CONTENT_DISPOSITION       47
+#define WINHTTP_QUERY_AGE                       48
+#define WINHTTP_QUERY_CACHE_CONTROL             49
+#define WINHTTP_QUERY_CONTENT_BASE              50
+#define WINHTTP_QUERY_CONTENT_LOCATION          51
+#define WINHTTP_QUERY_CONTENT_MD5               52
+#define WINHTTP_QUERY_CONTENT_RANGE             53
+#define WINHTTP_QUERY_ETAG                      54
+#define WINHTTP_QUERY_HOST                      55
+#define WINHTTP_QUERY_IF_MATCH                  56
+#define WINHTTP_QUERY_IF_NONE_MATCH             57
+#define WINHTTP_QUERY_IF_RANGE                  58
+#define WINHTTP_QUERY_IF_UNMODIFIED_SINCE       59
+#define WINHTTP_QUERY_MAX_FORWARDS              60
+#define WINHTTP_QUERY_PROXY_AUTHORIZATION       61
+#define WINHTTP_QUERY_RANGE                     62
+#define WINHTTP_QUERY_TRANSFER_ENCODING         63
+#define WINHTTP_QUERY_UPGRADE                   64
+#define WINHTTP_QUERY_VARY                      65
+#define WINHTTP_QUERY_VIA                       66
+#define WINHTTP_QUERY_WARNING                   67
+#define WINHTTP_QUERY_EXPECT                    68
+#define WINHTTP_QUERY_PROXY_CONNECTION          69
+#define WINHTTP_QUERY_UNLESS_MODIFIED_SINCE     70
+#define WINHTTP_QUERY_PROXY_SUPPORT             75
+#define WINHTTP_QUERY_AUTHENTICATION_INFO       76
+#define WINHTTP_QUERY_PASSPORT_URLS             77
+#define WINHTTP_QUERY_PASSPORT_CONFIG           78
+#define WINHTTP_QUERY_CUSTOM                    65535
+
+#define WINHTTP_QUERY_FLAG_REQUEST_HEADERS  0x80000000
+#define WINHTTP_QUERY_FLAG_SYSTEMTIME       0x40000000
+#define WINHTTP_QUERY_FLAG_NUMBER           0x20000000
+
+#define WINHTTP_OPTION_CALLBACK                         1
+#define WINHTTP_OPTION_RESOLVE_TIMEOUT                  2
+#define WINHTTP_OPTION_CONNECT_TIMEOUT                  3
+#define WINHTTP_OPTION_CONNECT_RETRIES                  4
+#define WINHTTP_OPTION_SEND_TIMEOUT                     5
+#define WINHTTP_OPTION_RECEIVE_TIMEOUT                  6
+#define WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT         7
+#define WINHTTP_OPTION_HANDLE_TYPE                      9
+#define WINHTTP_OPTION_READ_BUFFER_SIZE                 12
+#define WINHTTP_OPTION_WRITE_BUFFER_SIZE                13
+#define WINHTTP_OPTION_PARENT_HANDLE                    21
+#define WINHTTP_OPTION_EXTENDED_ERROR                   24
+#define WINHTTP_OPTION_SECURITY_FLAGS                   31
+#define WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT      32
+#define WINHTTP_OPTION_URL                              34
+#define WINHTTP_OPTION_SECURITY_KEY_BITNESS             36
+#define WINHTTP_OPTION_PROXY                            38
+#define WINHTTP_OPTION_USER_AGENT                       41
+#define WINHTTP_OPTION_CONTEXT_VALUE                    45
+#define WINHTTP_OPTION_CLIENT_CERT_CONTEXT              47
+#define WINHTTP_OPTION_REQUEST_PRIORITY                 58
+#define WINHTTP_OPTION_HTTP_VERSION                     59
+#define WINHTTP_OPTION_DISABLE_FEATURE                  63
+#define WINHTTP_OPTION_CODEPAGE                         68
+#define WINHTTP_OPTION_MAX_CONNS_PER_SERVER             73
+#define WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER         74
+#define WINHTTP_OPTION_AUTOLOGON_POLICY                 77
+#define WINHTTP_OPTION_SERVER_CERT_CONTEXT              78
+#define WINHTTP_OPTION_ENABLE_FEATURE                   79
+#define WINHTTP_OPTION_WORKER_THREAD_COUNT              80
+#define WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT         81
+#define WINHTTP_OPTION_PASSPORT_COBRANDING_URL          82
+#define WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH          83
+#define WINHTTP_OPTION_SECURE_PROTOCOLS                 84
+#define WINHTTP_OPTION_ENABLETRACING                    85
+#define WINHTTP_OPTION_PASSPORT_SIGN_OUT                86
+#define WINHTTP_OPTION_PASSPORT_RETURN_URL              87
+#define WINHTTP_OPTION_REDIRECT_POLICY                  88
+#define WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS     89
+#define WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE         90
+#define WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE         91
+#define WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE          92
+
+#define WINHTTP_OPTION_USERNAME         0x1000
+#define WINHTTP_OPTION_PASSWORD         0x1001
+#define WINHTTP_OPTION_PROXY_USERNAME   0x1002
+#define WINHTTP_OPTION_PROXY_PASSWORD   0x1003
+
+#define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME          0x00000001
+#define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED           0x00000002
+#define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER    0x00000004
+#define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER     0x00000008
+#define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST         0x00000010
+#define WINHTTP_CALLBACK_STATUS_REQUEST_SENT            0x00000020
+#define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE      0x00000040
+#define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED       0x00000080
+#define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION      0x00000100
+#define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED       0x00000200
+#define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED          0x00000400
+#define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING          0x00000800
+#define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY         0x00001000
+#define WINHTTP_CALLBACK_STATUS_REDIRECT                0x00004000
+#define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE   0x00008000
+#define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE          0x00010000
+#define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE       0x00020000
+#define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE          0x00040000
+#define WINHTTP_CALLBACK_STATUS_READ_COMPLETE           0x00080000
+#define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE          0x00100000
+#define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR           0x00200000
+#define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE    0x00400000
+
+#define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME          (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME \
+                                                    | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED)
+#define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER     (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER \
+                                                    | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER)
+#define WINHTTP_CALLBACK_FLAG_SEND_REQUEST          (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST \
+                                                    | WINHTTP_CALLBACK_STATUS_REQUEST_SENT)
+#define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE      (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE \
+                                                    | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED)
+#define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION      (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION \
+                                                    | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED)
+#define WINHTTP_CALLBACK_FLAG_HANDLES               (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED \
+                                                    | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING)
+#define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY       WINHTTP_CALLBACK_STATUS_DETECTING_PROXY
+#define WINHTTP_CALLBACK_FLAG_REDIRECT              WINHTTP_CALLBACK_STATUS_REDIRECT
+#define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE
+#define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE        WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
+#define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE     WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
+#define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE        WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
+#define WINHTTP_CALLBACK_FLAG_READ_COMPLETE         WINHTTP_CALLBACK_STATUS_READ_COMPLETE
+#define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE        WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
+#define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR         WINHTTP_CALLBACK_STATUS_REQUEST_ERROR
+#define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE  WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
+
+#define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS       (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE   \
+                                                    | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE     \
+                                                    | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE        \
+                                                    | WINHTTP_CALLBACK_STATUS_READ_COMPLETE         \
+                                                    | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE        \
+                                                    | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR)
+#define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS     0xffffffff
+
+#define WINHTTP_INVALID_STATUS_CALLBACK     ((WINHTTP_STATUS_CALLBACK)(-1))
+
+#define WINHTTP_QUERY_FLAG_NUMBER           0x20000000
+#define WINHTTP_QUERY_FLAG_SYSTEMTIME       0x40000000
+#define WINHTTP_QUERY_FLAG_REQUEST_HEADERS  0x80000000
+
+#define WINHTTP_FLAG_SECURE                 0x00800000
+#define WINHTTP_FLAG_ESCAPE_PERCENT         0x00000004
+#define WINHTTP_FLAG_NULL_CODEPAGE          0x00000008
+#define WINHTTP_FLAG_ESCAPE_DISABLE         0x00000040
+#define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY   0x00000080
+#define WINHTTP_FLAG_BYPASS_PROXY_CACHE     0x00000100
+#define WINHTTP_FLAG_REFRESH                WINHTTP_FLAG_BYPASS_PROXY_CACHE
+
+#define WINHTTP_FLAG_ASYNC                  0x10000000
+
+#define WINHTTP_ADDREQ_FLAG_ADD_IF_NEW                  0x10000000
+#define WINHTTP_ADDREQ_FLAG_ADD                         0x20000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA         0x40000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON     0x01000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE                    WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
+#define WINHTTP_ADDREQ_FLAG_REPLACE                     0x80000000
+
+#define WINHTTP_AUTH_TARGET_SERVER  0x00000000
+#define WINHTTP_AUTH_TARGET_PROXY   0x00000001
+
+#define WINHTTP_AUTH_SCHEME_BASIC       0x00000001
+#define WINHTTP_AUTH_SCHEME_NTLM        0x00000002
+#define WINHTTP_AUTH_SCHEME_PASSPORT    0x00000004
+#define WINHTTP_AUTH_SCHEME_DIGEST      0x00000008
+#define WINHTTP_AUTH_SCHEME_NEGOTIATE   0x00000010
+
 #define INTERNET_DEFAULT_PORT           0
 #define INTERNET_DEFAULT_HTTP_PORT      80
 #define INTERNET_DEFAULT_HTTPS_PORT     443
@@ -99,6 +324,10 @@ typedef struct
     DWORD dwKeySize;
 } WINHTTP_CERTIFICATE_INFO;
 
+#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY   0
+#define WINHTTP_ACCESS_TYPE_NO_PROXY        1
+#define WINHTTP_ACCESS_TYPE_NAMED_PROXY     3
+
 typedef struct
 {
     DWORD dwAccessType;
@@ -110,6 +339,16 @@ typedef LPWINHTTP_PROXY_INFO LPWINHTTP_PROXY_INFOW;
 
 typedef struct
 {
+    DWORD   dwFlags;
+    DWORD   dwAutoDetectFlags;
+    LPCWSTR lpszAutoConfigUrl;
+    LPVOID  lpvReserved;
+    DWORD   dwReserved;
+    BOOL    fAutoLogonIfChallenged;
+} WINHTTP_AUTOPROXY_OPTIONS;
+
+typedef struct
+{
     BOOL   fAutoDetect;
     LPWSTR lpszAutoConfigUrl;
     LPWSTR lpszProxy;


Reply via email to