/*
 * Wininet
 *
 * Copyright 1999 Corel Corporation
 * Copyright 2002 CodeWeavers Inc.
 * Copyright 2002 Jaco Greeff
 * Copyright 2002 TransGaming Technologies Inc.
 * Copyright 2004 Mike McCormack for CodeWeavers
 *
 * Ulrich Czekalla
 * Aric Stewart
 * David Hammerton
 *
 * 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 "ws2tcpip.h"

#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>

#ifdef HAVE_CORESERVICES_CORESERVICES_H
#define GetCurrentThread MacGetCurrentThread
#define LoadResource MacLoadResource
#include <CoreServices/CoreServices.h>
#undef GetCurrentThread
#undef LoadResource
#undef DPRINTF
#endif

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "wininet.h"
#include "winnls.h"
#include "wine/debug.h"
#include "winerror.h"
#define NO_SHLWAPI_STREAM
#include "shlwapi.h"

#include "wine/exception.h"

#include "internet.h"
#include "resource.h"

#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(wininet);

typedef struct
{
    DWORD  dwError;
    CHAR   response[MAX_REPLY_LEN];
} WITHREADERROR, *LPWITHREADERROR;

static DWORD g_dwTlsErrIndex = TLS_OUT_OF_INDEXES;
HMODULE WININET_hModule;

static CRITICAL_SECTION WININET_cs;
static CRITICAL_SECTION_DEBUG WININET_cs_debug = 
{
    0, 0, &WININET_cs,
    { &WININET_cs_debug.ProcessLocksList, &WININET_cs_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": WININET_cs") }
};
static CRITICAL_SECTION WININET_cs = { &WININET_cs_debug, -1, 0, 0, 0, 0 };

static object_header_t **handle_table;
static UINT_PTR next_handle;
static UINT_PTR handle_table_size;

typedef struct
{
    DWORD  proxyEnabled;
    LPWSTR proxy;
    LPWSTR proxyBypass;
    LPWSTR proxyUsername;
    LPWSTR proxyPassword;
} proxyinfo_t;

static ULONG max_conns = 2, max_1_0_conns = 4;
static ULONG connect_timeout = 60000;

static const WCHAR szInternetSettings[] =
    { 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
      'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
      'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0 };
static const WCHAR szProxyServer[] = { 'P','r','o','x','y','S','e','r','v','e','r', 0 };
static const WCHAR szProxyEnable[] = { 'P','r','o','x','y','E','n','a','b','l','e', 0 };
static const WCHAR szProxyOverride[] = { 'P','r','o','x','y','O','v','e','r','r','i','d','e', 0 };

void *alloc_object(object_header_t *parent, const object_vtbl_t *vtbl, size_t size)
{
    UINT_PTR handle = 0, num;
    object_header_t *ret;
    object_header_t **p;
    BOOL res = TRUE;

    ret = heap_alloc_zero(size);
    if(!ret)
        return NULL;

    list_init(&ret->children);

    EnterCriticalSection( &WININET_cs );

    if(!handle_table_size) {
        num = 16;
        p = heap_alloc_zero(sizeof(handle_table[0]) * num);
        if(p) {
            handle_table = p;
            handle_table_size = num;
            next_handle = 1;
        }else {
            res = FALSE;
        }
    }else if(next_handle == handle_table_size) {
        num = handle_table_size * 2;
        p = heap_realloc_zero(handle_table, sizeof(handle_table[0]) * num);
        if(p) {
            handle_table = p;
            handle_table_size = num;
        }else {
            res = FALSE;
        }
    }

    if(res) {
        handle = next_handle;
        if(handle_table[handle])
            ERR("handle isn't free but should be\n");
        handle_table[handle] = ret;
        ret->valid_handle = TRUE;

        while(handle_table[next_handle] && next_handle < handle_table_size)
            next_handle++;
    }

    LeaveCriticalSection( &WININET_cs );

    if(!res) {
        heap_free(ret);
        return NULL;
    }

    ret->vtbl = vtbl;
    ret->refs = 1;
    ret->hInternet = (HINTERNET)handle;

    if(parent) {
        ret->lpfnStatusCB = parent->lpfnStatusCB;
        ret->dwInternalFlags = parent->dwInternalFlags & INET_CALLBACKW;
    }

    return ret;
}

object_header_t *WININET_AddRef( object_header_t *info )
{
    ULONG refs = InterlockedIncrement(&info->refs);
    TRACE("%p -> refcount = %d\n", info, refs );
    return info;
}

object_header_t *get_handle_object( HINTERNET hinternet )
{
    object_header_t *info = NULL;
    UINT_PTR handle = (UINT_PTR) hinternet;

    EnterCriticalSection( &WININET_cs );

    if(handle > 0 && handle < handle_table_size && handle_table[handle] && handle_table[handle]->valid_handle)
        info = WININET_AddRef(handle_table[handle]);

    LeaveCriticalSection( &WININET_cs );

    TRACE("handle %ld -> %p\n", handle, info);

    return info;
}

static void invalidate_handle(object_header_t *info)
{
    object_header_t *child, *next;

    if(!info->valid_handle)
        return;
    info->valid_handle = FALSE;

    /* Free all children as native does */
    LIST_FOR_EACH_ENTRY_SAFE( child, next, &info->children, object_header_t, entry )
    {
        TRACE("invalidating child handle %p for parent %p\n", child->hInternet, info);
        invalidate_handle( child );
    }

    WININET_Release(info);
}

BOOL WININET_Release( object_header_t *info )
{
    ULONG refs = InterlockedDecrement(&info->refs);
    TRACE( "object %p refcount = %d\n", info, refs );
    if( !refs )
    {
        invalidate_handle(info);
        if ( info->vtbl->CloseConnection )
        {
            TRACE( "closing connection %p\n", info);
            info->vtbl->CloseConnection( info );
        }
        /* Don't send a callback if this is a session handle created with InternetOpenUrl */
        if ((info->htype != WH_HHTTPSESSION && info->htype != WH_HFTPSESSION)
            || !(info->dwInternalFlags & INET_OPENURL))
        {
            INTERNET_SendCallback(info, info->dwContext,
                                  INTERNET_STATUS_HANDLE_CLOSING, &info->hInternet,
                                  sizeof(HINTERNET));
        }
        TRACE( "destroying object %p\n", info);
        if ( info->htype != WH_HINIT )
            list_remove( &info->entry );
        info->vtbl->Destroy( info );

        if(info->hInternet) {
            UINT_PTR handle = (UINT_PTR)info->hInternet;

            EnterCriticalSection( &WININET_cs );

            handle_table[handle] = NULL;
            if(next_handle > handle)
                next_handle = handle;

            LeaveCriticalSection( &WININET_cs );
        }

        heap_free(info);
    }
    return TRUE;
}

/***********************************************************************
 * DllMain [Internal] Initializes the internal 'WININET.DLL'.
 *
 * PARAMS
 *     hinstDLL    [I] handle to the DLL's instance
 *     fdwReason   [I]
 *     lpvReserved [I] reserved, must be NULL
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */

BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason) {
        case DLL_PROCESS_ATTACH:

            g_dwTlsErrIndex = TlsAlloc();

            if (g_dwTlsErrIndex == TLS_OUT_OF_INDEXES)
                return FALSE;

            if(!init_urlcache())
            {
                TlsFree(g_dwTlsErrIndex);
                return FALSE;
            }

            WININET_hModule = hinstDLL;
            break;

        case DLL_THREAD_ATTACH:
            break;

        case DLL_THREAD_DETACH:
            if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
            {
                heap_free(TlsGetValue(g_dwTlsErrIndex));
            }
            break;

        case DLL_PROCESS_DETACH:
            if (lpvReserved) break;
            collect_connections(COLLECT_CLEANUP);
            NETCON_unload();
            free_urlcache();
            free_cookie();

            if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
            {
                heap_free(TlsGetValue(g_dwTlsErrIndex));
                TlsFree(g_dwTlsErrIndex);
            }
            break;
    }
    return TRUE;
}

/***********************************************************************
 *		DllInstall (WININET.@)
 */
HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
{
    FIXME("(%x %s): stub\n", bInstall, debugstr_w(cmdline));
    return S_OK;
}

/***********************************************************************
 *           INTERNET_SaveProxySettings
 *
 * Stores the proxy settings given by lpwai into the registry
 *
 * RETURNS
 *     ERROR_SUCCESS if no error, or error code on fail
 */
static LONG INTERNET_SaveProxySettings( proxyinfo_t *lpwpi )
{
    HKEY key;
    LONG ret;

    if ((ret = RegOpenKeyW( HKEY_CURRENT_USER, szInternetSettings, &key )))
        return ret;

    if ((ret = RegSetValueExW( key, szProxyEnable, 0, REG_DWORD, (BYTE*)&lpwpi->proxyEnabled, sizeof(DWORD))))
    {
        RegCloseKey( key );
        return ret;
    }

    if (lpwpi->proxy)
    {
        if ((ret = RegSetValueExW( key, szProxyServer, 0, REG_SZ, (BYTE*)lpwpi->proxy, sizeof(WCHAR) * (lstrlenW(lpwpi->proxy) + 1))))
        {
            RegCloseKey( key );
            return ret;
        }
    }
    else
    {
        if ((ret = RegDeleteValueW( key, szProxyServer )) && ret != ERROR_FILE_NOT_FOUND)
        {
            RegCloseKey( key );
            return ret;
        }
    }

    RegCloseKey(key);
    return ERROR_SUCCESS;
}

/***********************************************************************
 *           INTERNET_FindProxyForProtocol
 *
 * Searches the proxy string for a proxy of the given protocol.
 * Returns the found proxy, or the default proxy if none of the given
 * protocol is found.
 *
 * PARAMETERS
 *     szProxy       [In]     proxy string to search
 *     proto         [In]     protocol to search for, e.g. "http"
 *     foundProxy    [Out]    found proxy
 *     foundProxyLen [In/Out] length of foundProxy buffer, in WCHARs
 *
 * RETURNS
 *     TRUE if a proxy is found, FALSE if not.  If foundProxy is too short,
 *     *foundProxyLen is set to the required size in WCHARs, including the
 *     NULL terminator, and the last error is set to ERROR_INSUFFICIENT_BUFFER.
 */
BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen)
{
    LPCWSTR ptr;
    BOOL ret = FALSE;

    TRACE("(%s, %s)\n", debugstr_w(szProxy), debugstr_w(proto));

    /* First, look for the specified protocol (proto=scheme://host:port) */
    for (ptr = szProxy; !ret && ptr && *ptr; )
    {
        LPCWSTR end, equal;

        if (!(end = strchrW(ptr, ' ')))
            end = ptr + strlenW(ptr);
        if ((equal = strchrW(ptr, '=')) && equal < end &&
             equal - ptr == strlenW(proto) &&
             !strncmpiW(proto, ptr, strlenW(proto)))
        {
            if (end - equal > *foundProxyLen)
            {
                WARN("buffer too short for %s\n",
                     debugstr_wn(equal + 1, end - equal - 1));
                *foundProxyLen = end - equal;
                SetLastError(ERROR_INSUFFICIENT_BUFFER);
            }
            else
            {
                memcpy(foundProxy, equal + 1, (end - equal) * sizeof(WCHAR));
                foundProxy[end - equal] = 0;
                ret = TRUE;
            }
        }
        if (*end == ' ')
            ptr = end + 1;
        else
            ptr = end;
    }
    if (!ret)
    {
        /* It wasn't found: look for no protocol */
        for (ptr = szProxy; !ret && ptr && *ptr; )
        {
            LPCWSTR end;

            if (!(end = strchrW(ptr, ' ')))
                end = ptr + strlenW(ptr);
            if (!strchrW(ptr, '='))
            {
                if (end - ptr + 1 > *foundProxyLen)
                {
                    WARN("buffer too short for %s\n",
                         debugstr_wn(ptr, end - ptr));
                    *foundProxyLen = end - ptr + 1;
                    SetLastError(ERROR_INSUFFICIENT_BUFFER);
                }
                else
                {
                    memcpy(foundProxy, ptr, (end - ptr) * sizeof(WCHAR));
                    foundProxy[end - ptr] = 0;
                    ret = TRUE;
                }
            }
            if (*end == ' ')
                ptr = end + 1;
            else
                ptr = end;
        }
    }
    if (ret)
        TRACE("found proxy for %s: %s\n", debugstr_w(proto),
              debugstr_w(foundProxy));
    return ret;
}

/***********************************************************************
 *           InternetInitializeAutoProxyDll   (WININET.@)
 *
 * Setup the internal proxy
 *
 * PARAMETERS
 *     dwReserved
 *
 * RETURNS
 *     FALSE on failure
 *
 */
BOOL WINAPI InternetInitializeAutoProxyDll(DWORD dwReserved)
{
    FIXME("STUB\n");
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

/***********************************************************************
 *           DetectAutoProxyUrl   (WININET.@)
 *
 * Auto detect the proxy url
 *
 * RETURNS
 *     FALSE on failure
 *
 */
BOOL WINAPI DetectAutoProxyUrl(LPSTR lpszAutoProxyUrl,
	DWORD dwAutoProxyUrlLength, DWORD dwDetectFlags)
{
    FIXME("STUB\n");
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

static void FreeProxyInfo( proxyinfo_t *lpwpi )
{
    heap_free(lpwpi->proxy);
    heap_free(lpwpi->proxyBypass);
    heap_free(lpwpi->proxyUsername);
    heap_free(lpwpi->proxyPassword);
}

static proxyinfo_t *global_proxy;

static void free_global_proxy( void )
{
    EnterCriticalSection( &WININET_cs );
    if (global_proxy)
    {
        FreeProxyInfo( global_proxy );
        heap_free( global_proxy );
    }
    LeaveCriticalSection( &WININET_cs );
}

static BOOL parse_proxy_url( proxyinfo_t *info, const WCHAR *url )
{
    static const WCHAR fmt[] = {'%','.','*','s',':','%','u',0};
    URL_COMPONENTSW uc = {sizeof(uc)};

    uc.dwHostNameLength = 1;
    uc.dwUserNameLength = 1;
    uc.dwPasswordLength = 1;

    if (!InternetCrackUrlW( url, 0, 0, &uc )) return FALSE;
    if (!uc.dwHostNameLength)
    {
        if (!(info->proxy = heap_strdupW( url ))) return FALSE;
        info->proxyUsername = NULL;
        info->proxyPassword = NULL;
        return TRUE;
    }
    if (!(info->proxy = heap_alloc( (uc.dwHostNameLength + 12) * sizeof(WCHAR) ))) return FALSE;
    sprintfW( info->proxy, fmt, uc.dwHostNameLength, uc.lpszHostName, uc.nPort );

    if (!uc.dwUserNameLength) info->proxyUsername = NULL;
    else if (!(info->proxyUsername = heap_strndupW( uc.lpszUserName, uc.dwUserNameLength )))
    {
        heap_free( info->proxy );
        return FALSE;
    }
    if (!uc.dwPasswordLength) info->proxyPassword = NULL;
    else if (!(info->proxyPassword = heap_strndupW( uc.lpszPassword, uc.dwPasswordLength )))
    {
        heap_free( info->proxyUsername );
        heap_free( info->proxy );
        return FALSE;
    }
    return TRUE;
}

/***********************************************************************
 *          INTERNET_LoadProxySettings
 *
 * Loads proxy information from process-wide global settings, the registry,
 * or the environment into lpwpi.
 *
 * The caller should call FreeProxyInfo when done with lpwpi.
 *
 * FIXME:
 * The proxy may be specified in the form 'http=proxy.my.org'
 * Presumably that means there can be ftp=ftpproxy.my.org too.
 */
static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
{
    HKEY key;
    DWORD type, len;
    LPCSTR envproxy;
    LONG ret;

    memset( lpwpi, 0, sizeof(*lpwpi) );

    EnterCriticalSection( &WININET_cs );
    if (global_proxy)
    {
        lpwpi->proxyEnabled = global_proxy->proxyEnabled;
        lpwpi->proxy = heap_strdupW( global_proxy->proxy );
        lpwpi->proxyBypass = heap_strdupW( global_proxy->proxyBypass );
    }
    LeaveCriticalSection( &WININET_cs );

    if ((ret = RegOpenKeyW( HKEY_CURRENT_USER, szInternetSettings, &key )))
    {
        FreeProxyInfo( lpwpi );
        return ret;
    }

    len = sizeof(DWORD);
    if (RegQueryValueExW( key, szProxyEnable, NULL, &type, (BYTE *)&lpwpi->proxyEnabled, &len ) || type != REG_DWORD)
    {
        lpwpi->proxyEnabled = 0;
        if((ret = RegSetValueExW( key, szProxyEnable, 0, REG_DWORD, (BYTE *)&lpwpi->proxyEnabled, sizeof(DWORD) )))
        {
            FreeProxyInfo( lpwpi );
            RegCloseKey( key );
            return ret;
        }
    }

    if (!(envproxy = getenv( "http_proxy" )) || lpwpi->proxyEnabled)
    {
        /* figure out how much memory the proxy setting takes */
        if (!RegQueryValueExW( key, szProxyServer, NULL, &type, NULL, &len ) && len && (type == REG_SZ))
        {
            LPWSTR szProxy, p;
            static const WCHAR szHttp[] = {'h','t','t','p','=',0};

            if (!(szProxy = heap_alloc(len)))
            {
                RegCloseKey( key );
                FreeProxyInfo( lpwpi );
                return ERROR_OUTOFMEMORY;
            }
            RegQueryValueExW( key, szProxyServer, NULL, &type, (BYTE*)szProxy, &len );

            /* find the http proxy, and strip away everything else */
            p = strstrW( szProxy, szHttp );
            if (p)
            {
                p += lstrlenW( szHttp );
                lstrcpyW( szProxy, p );
            }
            p = strchrW( szProxy, ';' );
            if (p) *p = 0;

            FreeProxyInfo( lpwpi );
            lpwpi->proxy = szProxy;
            lpwpi->proxyBypass = NULL;

            TRACE("http proxy (from registry) = %s\n", debugstr_w(lpwpi->proxy));
        }
        else
        {
            TRACE("No proxy server settings in registry.\n");
            FreeProxyInfo( lpwpi );
            lpwpi->proxy = NULL;
            lpwpi->proxyBypass = NULL;
        }
    }
    else if (envproxy)
    {
        WCHAR *envproxyW;

        len = MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, NULL, 0 );
        if (!(envproxyW = heap_alloc(len * sizeof(WCHAR))))
        {
            RegCloseKey( key );
            return ERROR_OUTOFMEMORY;
        }
        MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, envproxyW, len );

        FreeProxyInfo( lpwpi );
        if (parse_proxy_url( lpwpi, envproxyW ))
        {
            TRACE("http proxy (from environment) = %s\n", debugstr_w(lpwpi->proxy));
            lpwpi->proxyEnabled = 1;
            lpwpi->proxyBypass = NULL;
        }
        else
        {
            WARN("failed to parse http_proxy value %s\n", debugstr_w(envproxyW));
            lpwpi->proxyEnabled = 0;
            lpwpi->proxy = NULL;
            lpwpi->proxyBypass = NULL;
        }
        heap_free( envproxyW );
    }

    if (lpwpi->proxyEnabled)
    {
        TRACE("Proxy is enabled.\n");

        if (!(envproxy = getenv( "no_proxy" )))
        {
            /* figure out how much memory the proxy setting takes */
            if (!RegQueryValueExW( key, szProxyOverride, NULL, &type, NULL, &len ) && len && (type == REG_SZ))
            {
                LPWSTR szProxy;

                if (!(szProxy = heap_alloc(len)))
                {
                    RegCloseKey( key );
                    return ERROR_OUTOFMEMORY;
                }
                RegQueryValueExW( key, szProxyOverride, NULL, &type, (BYTE*)szProxy, &len );

                heap_free( lpwpi->proxyBypass );
                lpwpi->proxyBypass = szProxy;

                TRACE("http proxy bypass (from registry) = %s\n", debugstr_w(lpwpi->proxyBypass));
            }
            else
            {
                heap_free( lpwpi->proxyBypass );
                lpwpi->proxyBypass = NULL;

                TRACE("No proxy bypass server settings in registry.\n");
            }
        }
        else
        {
            WCHAR *envproxyW;

            len = MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, NULL, 0 );
            if (!(envproxyW = heap_alloc(len * sizeof(WCHAR))))
            {
                RegCloseKey( key );
                return ERROR_OUTOFMEMORY;
            }
            MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, envproxyW, len );

            heap_free( lpwpi->proxyBypass );
            lpwpi->proxyBypass = envproxyW;

            TRACE("http proxy bypass (from environment) = %s\n", debugstr_w(lpwpi->proxyBypass));
        }
    }
    else TRACE("Proxy is disabled.\n");

    RegCloseKey( key );
    return ERROR_SUCCESS;
}

/***********************************************************************
 *           INTERNET_ConfigureProxy
 */
static BOOL INTERNET_ConfigureProxy( appinfo_t *lpwai )
{
    proxyinfo_t wpi;

    if (INTERNET_LoadProxySettings( &wpi ))
        return FALSE;

    if (wpi.proxyEnabled)
    {
        TRACE("http proxy = %s bypass = %s\n", debugstr_w(wpi.proxy), debugstr_w(wpi.proxyBypass));

        lpwai->accessType    = INTERNET_OPEN_TYPE_PROXY;
        lpwai->proxy         = wpi.proxy;
        lpwai->proxyBypass   = wpi.proxyBypass;
        lpwai->proxyUsername = wpi.proxyUsername;
        lpwai->proxyPassword = wpi.proxyPassword;
        return TRUE;
    }

    lpwai->accessType = INTERNET_OPEN_TYPE_DIRECT;
    FreeProxyInfo(&wpi);
    return FALSE;
}

/***********************************************************************
 *           dump_INTERNET_FLAGS
 *
 * Helper function to TRACE the internet flags.
 *
 * RETURNS
 *    None
 *
 */
static void dump_INTERNET_FLAGS(DWORD dwFlags) 
{
#define FE(x) { x, #x }
    static const wininet_flag_info flag[] = {
        FE(INTERNET_FLAG_RELOAD),
        FE(INTERNET_FLAG_RAW_DATA),
        FE(INTERNET_FLAG_EXISTING_CONNECT),
        FE(INTERNET_FLAG_ASYNC),
        FE(INTERNET_FLAG_PASSIVE),
        FE(INTERNET_FLAG_NO_CACHE_WRITE),
        FE(INTERNET_FLAG_MAKE_PERSISTENT),
        FE(INTERNET_FLAG_FROM_CACHE),
        FE(INTERNET_FLAG_SECURE),
        FE(INTERNET_FLAG_KEEP_CONNECTION),
        FE(INTERNET_FLAG_NO_AUTO_REDIRECT),
        FE(INTERNET_FLAG_READ_PREFETCH),
        FE(INTERNET_FLAG_NO_COOKIES),
        FE(INTERNET_FLAG_NO_AUTH),
        FE(INTERNET_FLAG_CACHE_IF_NET_FAIL),
        FE(INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP),
        FE(INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS),
        FE(INTERNET_FLAG_IGNORE_CERT_DATE_INVALID),
        FE(INTERNET_FLAG_IGNORE_CERT_CN_INVALID),
        FE(INTERNET_FLAG_RESYNCHRONIZE),
        FE(INTERNET_FLAG_HYPERLINK),
        FE(INTERNET_FLAG_NO_UI),
        FE(INTERNET_FLAG_PRAGMA_NOCACHE),
        FE(INTERNET_FLAG_CACHE_ASYNC),
        FE(INTERNET_FLAG_FORMS_SUBMIT),
        FE(INTERNET_FLAG_NEED_FILE),
        FE(INTERNET_FLAG_TRANSFER_ASCII),
        FE(INTERNET_FLAG_TRANSFER_BINARY)
    };
#undef FE
    unsigned int i;

    for (i = 0; i < (sizeof(flag) / sizeof(flag[0])); i++) {
	if (flag[i].val & dwFlags) {
	    TRACE(" %s", flag[i].name);
	    dwFlags &= ~flag[i].val;
	}
    }	
    if (dwFlags)
        TRACE(" Unknown flags (%08x)\n", dwFlags);
    else
        TRACE("\n");
}

/***********************************************************************
 *           INTERNET_CloseHandle (internal)
 *
 * Close internet handle
 *
 */
static VOID APPINFO_Destroy(object_header_t *hdr)
{
    appinfo_t *lpwai = (appinfo_t*)hdr;

    TRACE("%p\n",lpwai);

    heap_free(lpwai->agent);
    heap_free(lpwai->proxy);
    heap_free(lpwai->proxyBypass);
    heap_free(lpwai->proxyUsername);
    heap_free(lpwai->proxyPassword);
}

static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
    appinfo_t *ai = (appinfo_t*)hdr;

    switch(option) {
    case INTERNET_OPTION_HANDLE_TYPE:
        TRACE("INTERNET_OPTION_HANDLE_TYPE\n");

        if (*size < sizeof(ULONG))
            return ERROR_INSUFFICIENT_BUFFER;

        *size = sizeof(DWORD);
        *(DWORD*)buffer = INTERNET_HANDLE_TYPE_INTERNET;
        return ERROR_SUCCESS;

    case INTERNET_OPTION_USER_AGENT: {
        DWORD bufsize;

        TRACE("INTERNET_OPTION_USER_AGENT\n");

        bufsize = *size;

        if (unicode) {
            DWORD len = ai->agent ? strlenW(ai->agent) : 0;

            *size = (len + 1) * sizeof(WCHAR);
            if(!buffer || bufsize < *size)
                return ERROR_INSUFFICIENT_BUFFER;

            if (ai->agent)
                strcpyW(buffer, ai->agent);
            else
                *(WCHAR *)buffer = 0;
            /* If the buffer is copied, the returned length doesn't include
             * the NULL terminator.
             */
            *size = len;
        }else {
            if (ai->agent)
                *size = WideCharToMultiByte(CP_ACP, 0, ai->agent, -1, NULL, 0, NULL, NULL);
            else
                *size = 1;
            if(!buffer || bufsize < *size)
                return ERROR_INSUFFICIENT_BUFFER;

            if (ai->agent)
                WideCharToMultiByte(CP_ACP, 0, ai->agent, -1, buffer, *size, NULL, NULL);
            else
                *(char *)buffer = 0;
            /* If the buffer is copied, the returned length doesn't include
             * the NULL terminator.
             */
            *size -= 1;
        }

        return ERROR_SUCCESS;
    }

    case INTERNET_OPTION_PROXY:
        if(!size) return ERROR_INVALID_PARAMETER;
        if (unicode) {
            INTERNET_PROXY_INFOW *pi = (INTERNET_PROXY_INFOW *)buffer;
            DWORD proxyBytesRequired = 0, proxyBypassBytesRequired = 0;
            LPWSTR proxy, proxy_bypass;

            if (ai->proxy)
                proxyBytesRequired = (lstrlenW(ai->proxy) + 1) * sizeof(WCHAR);
            if (ai->proxyBypass)
                proxyBypassBytesRequired = (lstrlenW(ai->proxyBypass) + 1) * sizeof(WCHAR);
            if (!pi || *size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired)
            {
                *size = sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired;
                return ERROR_INSUFFICIENT_BUFFER;
            }
            proxy = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW));
            proxy_bypass = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired);

            pi->dwAccessType = ai->accessType;
            pi->lpszProxy = NULL;
            pi->lpszProxyBypass = NULL;
            if (ai->proxy) {
                lstrcpyW(proxy, ai->proxy);
                pi->lpszProxy = proxy;
            }

            if (ai->proxyBypass) {
                lstrcpyW(proxy_bypass, ai->proxyBypass);
                pi->lpszProxyBypass = proxy_bypass;
            }

            *size = sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired;
            return ERROR_SUCCESS;
        }else {
            INTERNET_PROXY_INFOA *pi = (INTERNET_PROXY_INFOA *)buffer;
            DWORD proxyBytesRequired = 0, proxyBypassBytesRequired = 0;
            LPSTR proxy, proxy_bypass;

            if (ai->proxy)
                proxyBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->proxy, -1, NULL, 0, NULL, NULL);
            if (ai->proxyBypass)
                proxyBypassBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->proxyBypass, -1,
                        NULL, 0, NULL, NULL);
            if (!pi || *size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired)
            {
                *size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired;
                return ERROR_INSUFFICIENT_BUFFER;
            }
            proxy = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA));
            proxy_bypass = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired);

            pi->dwAccessType = ai->accessType;
            pi->lpszProxy = NULL;
            pi->lpszProxyBypass = NULL;
            if (ai->proxy) {
                WideCharToMultiByte(CP_ACP, 0, ai->proxy, -1, proxy, proxyBytesRequired, NULL, NULL);
                pi->lpszProxy = proxy;
            }

            if (ai->proxyBypass) {
                WideCharToMultiByte(CP_ACP, 0, ai->proxyBypass, -1, proxy_bypass,
                        proxyBypassBytesRequired, NULL, NULL);
                pi->lpszProxyBypass = proxy_bypass;
            }

            *size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired;
            return ERROR_SUCCESS;
        }

    case INTERNET_OPTION_CONNECT_TIMEOUT:
        TRACE("INTERNET_OPTION_CONNECT_TIMEOUT\n");

        if (*size < sizeof(ULONG))
            return ERROR_INSUFFICIENT_BUFFER;

        *(ULONG*)buffer = ai->connect_timeout;
        *size = sizeof(ULONG);

        return ERROR_SUCCESS;
    }

    return INET_QueryOption(hdr, option, buffer, size, unicode);
}

static DWORD APPINFO_SetOption(object_header_t *hdr, DWORD option, void *buf, DWORD size)
{
    appinfo_t *ai = (appinfo_t*)hdr;

    switch(option) {
    case INTERNET_OPTION_CONNECT_TIMEOUT:
        TRACE("INTERNET_OPTION_CONNECT_TIMEOUT\n");

        if(size != sizeof(connect_timeout))
            return ERROR_INTERNET_BAD_OPTION_LENGTH;
        if(!*(ULONG*)buf)
            return ERROR_BAD_ARGUMENTS;

        ai->connect_timeout = *(ULONG*)buf;
        return ERROR_SUCCESS;
    case INTERNET_OPTION_USER_AGENT:
        heap_free(ai->agent);
        if (!(ai->agent = heap_strdupW(buf))) return ERROR_OUTOFMEMORY;
        return ERROR_SUCCESS;
    }

    return INET_SetOption(hdr, option, buf, size);
}

static const object_vtbl_t APPINFOVtbl = {
    APPINFO_Destroy,
    NULL,
    APPINFO_QueryOption,
    APPINFO_SetOption,
    NULL,
    NULL,
    NULL,
    NULL
};


/***********************************************************************
 *           InternetOpenW   (WININET.@)
 *
 * Per-application initialization of wininet
 *
 * RETURNS
 *    HINTERNET on success
 *    NULL on failure
 *
 */
HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType,
    LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags)
{
    appinfo_t *lpwai = NULL;

    if (TRACE_ON(wininet)) {
#define FE(x) { x, #x }
	static const wininet_flag_info access_type[] = {
	    FE(INTERNET_OPEN_TYPE_PRECONFIG),
	    FE(INTERNET_OPEN_TYPE_DIRECT),
	    FE(INTERNET_OPEN_TYPE_PROXY),
	    FE(INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY)
	};
#undef FE
	DWORD i;
	const char *access_type_str = "Unknown";
	
	TRACE("(%s, %i, %s, %s, %i)\n", debugstr_w(lpszAgent), dwAccessType,
	      debugstr_w(lpszProxy), debugstr_w(lpszProxyBypass), dwFlags);
	for (i = 0; i < (sizeof(access_type) / sizeof(access_type[0])); i++) {
	    if (access_type[i].val == dwAccessType) {
		access_type_str = access_type[i].name;
		break;
	    }
	}
	TRACE("  access type : %s\n", access_type_str);
	TRACE("  flags       :");
	dump_INTERNET_FLAGS(dwFlags);
    }

    /* Clear any error information */
    INTERNET_SetLastError(0);

    if((dwAccessType == INTERNET_OPEN_TYPE_PROXY) && !lpszProxy) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    lpwai = alloc_object(NULL, &APPINFOVtbl, sizeof(appinfo_t));
    if (!lpwai) {
        SetLastError(ERROR_OUTOFMEMORY);
        return NULL;
    }

    lpwai->hdr.htype = WH_HINIT;
    lpwai->hdr.dwFlags = dwFlags;
    lpwai->accessType = dwAccessType;
    lpwai->proxyUsername = NULL;
    lpwai->proxyPassword = NULL;
    lpwai->connect_timeout = connect_timeout;

    lpwai->agent = heap_strdupW(lpszAgent);
    if(dwAccessType == INTERNET_OPEN_TYPE_PRECONFIG)
        INTERNET_ConfigureProxy( lpwai );
    else if(dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
        lpwai->proxy = heap_strdupW(lpszProxy);
        lpwai->proxyBypass = heap_strdupW(lpszProxyBypass);
    }

    TRACE("returning %p\n", lpwai);

    return lpwai->hdr.hInternet;
}


/***********************************************************************
 *           InternetOpenA   (WININET.@)
 *
 * Per-application initialization of wininet
 *
 * RETURNS
 *    HINTERNET on success
 *    NULL on failure
 *
 */
HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType,
    LPCSTR lpszProxy, LPCSTR lpszProxyBypass, DWORD dwFlags)
{
    WCHAR *szAgent, *szProxy, *szBypass;
    HINTERNET rc;

    TRACE("(%s, 0x%08x, %s, %s, 0x%08x)\n", debugstr_a(lpszAgent),
       dwAccessType, debugstr_a(lpszProxy), debugstr_a(lpszProxyBypass), dwFlags);

    szAgent = heap_strdupAtoW(lpszAgent);
    szProxy = heap_strdupAtoW(lpszProxy);
    szBypass = heap_strdupAtoW(lpszProxyBypass);

    rc = InternetOpenW(szAgent, dwAccessType, szProxy, szBypass, dwFlags);

    heap_free(szAgent);
    heap_free(szProxy);
    heap_free(szBypass);
    return rc;
}

/***********************************************************************
 *           InternetGetLastResponseInfoA (WININET.@)
 *
 * Return last wininet error description on the calling thread
 *
 * RETURNS
 *    TRUE on success of writing to buffer
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError,
    LPSTR lpszBuffer, LPDWORD lpdwBufferLength)
{
    LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);

    TRACE("\n");

    if (lpwite)
    {
        *lpdwError = lpwite->dwError;
        if (lpwite->dwError)
        {
            memcpy(lpszBuffer, lpwite->response, *lpdwBufferLength);
            *lpdwBufferLength = strlen(lpszBuffer);
        }
        else
            *lpdwBufferLength = 0;
    }
    else
    {
        *lpdwError = 0;
        *lpdwBufferLength = 0;
    }

    return TRUE;
}

/***********************************************************************
 *           InternetGetLastResponseInfoW (WININET.@)
 *
 * Return last wininet error description on the calling thread
 *
 * RETURNS
 *    TRUE on success of writing to buffer
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetGetLastResponseInfoW(LPDWORD lpdwError,
    LPWSTR lpszBuffer, LPDWORD lpdwBufferLength)
{
    LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);

    TRACE("\n");

    if (lpwite)
    {
        *lpdwError = lpwite->dwError;
        if (lpwite->dwError)
        {
            memcpy(lpszBuffer, lpwite->response, *lpdwBufferLength);
            *lpdwBufferLength = lstrlenW(lpszBuffer);
        }
        else
            *lpdwBufferLength = 0;
    }
    else
    {
        *lpdwError = 0;
        *lpdwBufferLength = 0;
    }

    return TRUE;
}

/***********************************************************************
 *           InternetGetConnectedState (WININET.@)
 *
 * Return connected state
 *
 * RETURNS
 *    TRUE if connected
 *    if lpdwStatus is not null, return the status (off line,
 *    modem, lan...) in it.
 *    FALSE if not connected
 */
BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved)
{
    TRACE("(%p, 0x%08x)\n", lpdwStatus, dwReserved);

    if (lpdwStatus) {
	WARN("always returning LAN connection.\n");
	*lpdwStatus = INTERNET_CONNECTION_LAN;
    }
    return TRUE;
}


/***********************************************************************
 *           InternetGetConnectedStateExW (WININET.@)
 *
 * Return connected state
 *
 * PARAMS
 *
 * lpdwStatus         [O] Flags specifying the status of the internet connection.
 * lpszConnectionName [O] Pointer to buffer to receive the friendly name of the internet connection.
 * dwNameLen          [I] Size of the buffer, in characters.
 * dwReserved         [I] Reserved. Must be set to 0.
 *
 * RETURNS
 *    TRUE if connected
 *    if lpdwStatus is not null, return the status (off line,
 *    modem, lan...) in it.
 *    FALSE if not connected
 *
 * NOTES
 *   If the system has no available network connections, an empty string is
 *   stored in lpszConnectionName. If there is a LAN connection, a localized
 *   "LAN Connection" string is stored. Presumably, if only a dial-up
 *   connection is available then the name of the dial-up connection is
 *   returned. Why any application, other than the "Internet Settings" CPL,
 *   would want to use this function instead of the simpler InternetGetConnectedStateW
 *   function is beyond me.
 */
BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnectionName,
                                         DWORD dwNameLen, DWORD dwReserved)
{
    TRACE("(%p, %p, %d, 0x%08x)\n", lpdwStatus, lpszConnectionName, dwNameLen, dwReserved);

    /* Must be zero */
    if(dwReserved)
        return FALSE;

    if (lpdwStatus) {
        WARN("always returning LAN connection.\n");
        *lpdwStatus = INTERNET_CONNECTION_LAN;
    }

    /* When the buffer size is zero LoadStringW fills the buffer with a pointer to
     * the resource, avoid it as we must not change the buffer in this case */
    if(lpszConnectionName && dwNameLen) {
        *lpszConnectionName = '\0';
        LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen);
    }

    return TRUE;
}


/***********************************************************************
 *           InternetGetConnectedStateExA (WININET.@)
 */
BOOL WINAPI InternetGetConnectedStateExA(LPDWORD lpdwStatus, LPSTR lpszConnectionName,
                                         DWORD dwNameLen, DWORD dwReserved)
{
    LPWSTR lpwszConnectionName = NULL;
    BOOL rc;

    TRACE("(%p, %p, %d, 0x%08x)\n", lpdwStatus, lpszConnectionName, dwNameLen, dwReserved);

    if (lpszConnectionName && dwNameLen > 0)
        lpwszConnectionName = heap_alloc(dwNameLen * sizeof(WCHAR));

    rc = InternetGetConnectedStateExW(lpdwStatus,lpwszConnectionName, dwNameLen,
                                      dwReserved);
    if (rc && lpwszConnectionName)
        WideCharToMultiByte(CP_ACP,0,lpwszConnectionName,-1,lpszConnectionName,
                            dwNameLen, NULL, NULL);

    heap_free(lpwszConnectionName);
    return rc;
}


/***********************************************************************
 *           InternetConnectW (WININET.@)
 *
 * Open a ftp, gopher or http session
 *
 * RETURNS
 *    HINTERNET a session handle on success
 *    NULL on failure
 *
 */
HINTERNET WINAPI InternetConnectW(HINTERNET hInternet,
    LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
    LPCWSTR lpszUserName, LPCWSTR lpszPassword,
    DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext)
{
    appinfo_t *hIC;
    HINTERNET rc = NULL;
    DWORD res = ERROR_SUCCESS;

    TRACE("(%p, %s, %u, %s, %p, %u, %x, %lx)\n", hInternet, debugstr_w(lpszServerName),
          nServerPort, debugstr_w(lpszUserName), lpszPassword, dwService, dwFlags, dwContext);

    if (!lpszServerName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    hIC = (appinfo_t*)get_handle_object( hInternet );
    if ( (hIC == NULL) || (hIC->hdr.htype != WH_HINIT) )
    {
        res = ERROR_INVALID_HANDLE;
        goto lend;
    }

    switch (dwService)
    {
        case INTERNET_SERVICE_FTP:
            rc = FTP_Connect(hIC, lpszServerName, nServerPort,
            lpszUserName, lpszPassword, dwFlags, dwContext, 0);
            if(!rc)
                res = INTERNET_GetLastError();
            break;

        case INTERNET_SERVICE_HTTP:
	    res = HTTP_Connect(hIC, lpszServerName, nServerPort,
                    lpszUserName, lpszPassword, dwFlags, dwContext, 0, &rc);
            break;

        case INTERNET_SERVICE_GOPHER:
        default:
            break;
    }
lend:
    if( hIC )
        WININET_Release( &hIC->hdr );

    TRACE("returning %p\n", rc);
    SetLastError(res);
    return rc;
}


/***********************************************************************
 *           InternetConnectA (WININET.@)
 *
 * Open a ftp, gopher or http session
 *
 * RETURNS
 *    HINTERNET a session handle on success
 *    NULL on failure
 *
 */
HINTERNET WINAPI InternetConnectA(HINTERNET hInternet,
    LPCSTR lpszServerName, INTERNET_PORT nServerPort,
    LPCSTR lpszUserName, LPCSTR lpszPassword,
    DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext)
{
    HINTERNET rc = NULL;
    LPWSTR szServerName;
    LPWSTR szUserName;
    LPWSTR szPassword;

    szServerName = heap_strdupAtoW(lpszServerName);
    szUserName = heap_strdupAtoW(lpszUserName);
    szPassword = heap_strdupAtoW(lpszPassword);

    rc = InternetConnectW(hInternet, szServerName, nServerPort,
        szUserName, szPassword, dwService, dwFlags, dwContext);

    heap_free(szServerName);
    heap_free(szUserName);
    heap_free(szPassword);
    return rc;
}


/***********************************************************************
 *           InternetFindNextFileA (WININET.@)
 *
 * Continues a file search from a previous call to FindFirstFile
 *
 * RETURNS
 *    TRUE on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetFindNextFileA(HINTERNET hFind, LPVOID lpvFindData)
{
    BOOL ret;
    WIN32_FIND_DATAW fd;
    
    ret = InternetFindNextFileW(hFind, lpvFindData?&fd:NULL);
    if(lpvFindData)
        WININET_find_data_WtoA(&fd, (LPWIN32_FIND_DATAA)lpvFindData);
    return ret;
}

/***********************************************************************
 *           InternetFindNextFileW (WININET.@)
 *
 * Continues a file search from a previous call to FindFirstFile
 *
 * RETURNS
 *    TRUE on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData)
{
    object_header_t *hdr;
    DWORD res;

    TRACE("\n");

    hdr = get_handle_object(hFind);
    if(!hdr) {
        WARN("Invalid handle\n");
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if(hdr->vtbl->FindNextFileW) {
        res = hdr->vtbl->FindNextFileW(hdr, lpvFindData);
    }else {
        WARN("Handle doesn't support NextFile\n");
        res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
    }

    WININET_Release(hdr);

    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}

/***********************************************************************
 *           InternetCloseHandle (WININET.@)
 *
 * Generic close handle function
 *
 * RETURNS
 *    TRUE on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetCloseHandle(HINTERNET hInternet)
{
    object_header_t *obj;
    
    TRACE("%p\n", hInternet);

    obj = get_handle_object( hInternet );
    if (!obj) {
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    invalidate_handle(obj);
    WININET_Release(obj);

    return TRUE;
}

static BOOL set_url_component(WCHAR **component, DWORD *component_length, const WCHAR *value, DWORD len)
{
    TRACE("%s (%d)\n", debugstr_wn(value, len), len);

    if (!*component_length)
        return TRUE;

    if (!*component) {
        *(const WCHAR**)component = value;
        *component_length = len;
        return TRUE;
    }

    if (*component_length < len+1) {
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    *component_length = len;
    if(len)
        memcpy(*component, value, len*sizeof(WCHAR));
    (*component)[len] = 0;
    return TRUE;
}

static BOOL set_url_component_WtoA(const WCHAR *comp_w, DWORD length, const WCHAR *url_w, char **comp, DWORD *ret_length,
                                   const char *url_a)
{
    size_t size, ret_size = *ret_length;

    if (!*ret_length)
        return TRUE;
    size = WideCharToMultiByte(CP_ACP, 0, comp_w, length, NULL, 0, NULL, NULL);

    if (!*comp) {
        *comp = comp_w ? (char*)url_a + WideCharToMultiByte(CP_ACP, 0, url_w, comp_w-url_w, NULL, 0, NULL, NULL) : NULL;
        *ret_length = size;
        return TRUE;
    }

    if (size+1 > ret_size) {
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        *ret_length = size+1;
        return FALSE;
    }

    *ret_length = size;
    WideCharToMultiByte(CP_ACP, 0, comp_w, length, *comp, ret_size-1, NULL, NULL);
    (*comp)[size] = 0;
    return TRUE;
}

static BOOL set_url_component_AtoW(const char *comp_a, DWORD len_a, WCHAR **comp_w, DWORD *len_w, WCHAR **buf)
{
    *len_w = len_a;

    if(!comp_a) {
        *comp_w = NULL;
        return TRUE;
    }

    if(!(*comp_w = *buf = heap_alloc(len_a*sizeof(WCHAR)))) {
        SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }

    return TRUE;
}

/***********************************************************************
 *           InternetCrackUrlA (WININET.@)
 *
 * See InternetCrackUrlW.
 */
BOOL WINAPI InternetCrackUrlA(const char *url, DWORD url_length, DWORD flags, URL_COMPONENTSA *ret_comp)
{
    WCHAR *host = NULL, *user = NULL, *pass = NULL, *path = NULL, *scheme = NULL, *extra = NULL;
    URL_COMPONENTSW comp;
    WCHAR *url_w;
    BOOL ret;

    TRACE("(%s %u %x %p)\n", url_length ? debugstr_an(url, url_length) : debugstr_a(url), url_length, flags, ret_comp);

    if (!url || !*url || !ret_comp || ret_comp->dwStructSize != sizeof(URL_COMPONENTSA)) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    comp.dwStructSize = sizeof(comp);

    ret = set_url_component_AtoW(ret_comp->lpszHostName, ret_comp->dwHostNameLength,
                                 &comp.lpszHostName, &comp.dwHostNameLength, &host)
        && set_url_component_AtoW(ret_comp->lpszUserName, ret_comp->dwUserNameLength,
                                  &comp.lpszUserName, &comp.dwUserNameLength, &user)
        && set_url_component_AtoW(ret_comp->lpszPassword, ret_comp->dwPasswordLength,
                                  &comp.lpszPassword, &comp.dwPasswordLength, &pass)
        && set_url_component_AtoW(ret_comp->lpszUrlPath, ret_comp->dwUrlPathLength,
                                  &comp.lpszUrlPath, &comp.dwUrlPathLength, &path)
        && set_url_component_AtoW(ret_comp->lpszScheme, ret_comp->dwSchemeLength,
                                  &comp.lpszScheme, &comp.dwSchemeLength, &scheme)
        && set_url_component_AtoW(ret_comp->lpszExtraInfo, ret_comp->dwExtraInfoLength,
                                  &comp.lpszExtraInfo, &comp.dwExtraInfoLength, &extra);

    if(ret && !(url_w = heap_strndupAtoW(url, url_length ? url_length : -1, &url_length))) {
        SetLastError(ERROR_OUTOFMEMORY);
        ret = FALSE;
    }

    if (ret && (ret = InternetCrackUrlW(url_w, url_length, flags, &comp))) {
        ret_comp->nScheme = comp.nScheme;
        ret_comp->nPort = comp.nPort;

        ret = set_url_component_WtoA(comp.lpszHostName, comp.dwHostNameLength, url_w,
                                     &ret_comp->lpszHostName, &ret_comp->dwHostNameLength, url)
            && set_url_component_WtoA(comp.lpszUserName, comp.dwUserNameLength, url_w,
                                      &ret_comp->lpszUserName, &ret_comp->dwUserNameLength, url)
            && set_url_component_WtoA(comp.lpszPassword, comp.dwPasswordLength, url_w,
                                      &ret_comp->lpszPassword, &ret_comp->dwPasswordLength, url)
            && set_url_component_WtoA(comp.lpszUrlPath, comp.dwUrlPathLength, url_w,
                                      &ret_comp->lpszUrlPath, &ret_comp->dwUrlPathLength, url)
            && set_url_component_WtoA(comp.lpszScheme, comp.dwSchemeLength, url_w,
                                      &ret_comp->lpszScheme, &ret_comp->dwSchemeLength, url)
            && set_url_component_WtoA(comp.lpszExtraInfo, comp.dwExtraInfoLength, url_w,
                                      &ret_comp->lpszExtraInfo, &ret_comp->dwExtraInfoLength, url);

        if(ret)
            TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", debugstr_a(url),
                  debugstr_an(ret_comp->lpszScheme, ret_comp->dwSchemeLength),
                  debugstr_an(ret_comp->lpszHostName, ret_comp->dwHostNameLength),
                  debugstr_an(ret_comp->lpszUrlPath, ret_comp->dwUrlPathLength),
                  debugstr_an(ret_comp->lpszExtraInfo, ret_comp->dwExtraInfoLength));
    }

    heap_free(host);
    heap_free(user);
    heap_free(pass);
    heap_free(path);
    heap_free(scheme);
    heap_free(extra);
    heap_free(url_w);
    return ret;
}

static const WCHAR url_schemes[][7] =
{
    {'f','t','p',0},
    {'g','o','p','h','e','r',0},
    {'h','t','t','p',0},
    {'h','t','t','p','s',0},
    {'f','i','l','e',0},
    {'n','e','w','s',0},
    {'m','a','i','l','t','o',0},
    {'r','e','s',0},
};

/***********************************************************************
 *           GetInternetSchemeW (internal)
 *
 * Get scheme of url
 *
 * RETURNS
 *    scheme on success
 *    INTERNET_SCHEME_UNKNOWN on failure
 *
 */
static INTERNET_SCHEME GetInternetSchemeW(LPCWSTR lpszScheme, DWORD nMaxCmp)
{
    int i;

    TRACE("%s %d\n",debugstr_wn(lpszScheme, nMaxCmp), nMaxCmp);

    if(lpszScheme==NULL)
        return INTERNET_SCHEME_UNKNOWN;

    for (i = 0; i < sizeof(url_schemes)/sizeof(url_schemes[0]); i++)
        if (!strncmpiW(lpszScheme, url_schemes[i], nMaxCmp))
            return INTERNET_SCHEME_FIRST + i;

    return INTERNET_SCHEME_UNKNOWN;
}

/***********************************************************************
 *           InternetCrackUrlW   (WININET.@)
 *
 * Break up URL into its components
 *
 * RETURNS
 *    TRUE on success
 *    FALSE on failure
 */
BOOL WINAPI InternetCrackUrlW(const WCHAR *lpszUrl, DWORD dwUrlLength, DWORD dwFlags, URL_COMPONENTSW *lpUC)
{
  /*
   * RFC 1808
   * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
   *
   */
    LPCWSTR lpszParam    = NULL;
    BOOL  found_colon = FALSE;
    LPCWSTR lpszap;
    LPCWSTR lpszcp = NULL, lpszNetLoc;

    TRACE("(%s %u %x %p)\n",
          lpszUrl ? debugstr_wn(lpszUrl, dwUrlLength ? dwUrlLength : strlenW(lpszUrl)) : "(null)",
          dwUrlLength, dwFlags, lpUC);

    if (!lpszUrl || !*lpszUrl || !lpUC)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    if (!dwUrlLength) dwUrlLength = strlenW(lpszUrl);

    if (dwFlags & ICU_DECODE)
    {
        WCHAR *url_tmp;
        DWORD len = dwUrlLength + 1;
        BOOL ret;

        if (!(url_tmp = heap_strndupW(lpszUrl, dwUrlLength)))
        {
            SetLastError(ERROR_OUTOFMEMORY);
            return FALSE;
        }
        ret = InternetCanonicalizeUrlW(url_tmp, url_tmp, &len, ICU_DECODE | ICU_NO_ENCODE);
        if (ret)
            ret = InternetCrackUrlW(url_tmp, len, dwFlags & ~ICU_DECODE, lpUC);
        heap_free(url_tmp);
        return ret;
    }
    lpszap = lpszUrl;
    
    /* Determine if the URI is absolute. */
    while (lpszap - lpszUrl < dwUrlLength)
    {
        if (isalnumW(*lpszap) || *lpszap == '+' || *lpszap == '.' || *lpszap == '-')
        {
            lpszap++;
            continue;
        }
        if (*lpszap == ':')
        {
            found_colon = TRUE;
            lpszcp = lpszap;
        }
        else
        {
            lpszcp = lpszUrl; /* Relative url */
        }

        break;
    }

    if(!found_colon){
        SetLastError(ERROR_INTERNET_UNRECOGNIZED_SCHEME);
        return FALSE;
    }

    lpUC->nScheme = INTERNET_SCHEME_UNKNOWN;
    lpUC->nPort = INTERNET_INVALID_PORT_NUMBER;

    /* Parse <params> */
    lpszParam = memchrW(lpszap, '?', dwUrlLength - (lpszap - lpszUrl));
    if(!lpszParam)
        lpszParam = memchrW(lpszap, '#', dwUrlLength - (lpszap - lpszUrl));

    if(!set_url_component(&lpUC->lpszExtraInfo, &lpUC->dwExtraInfoLength,
                          lpszParam, lpszParam ? dwUrlLength-(lpszParam-lpszUrl) : 0))
        return FALSE;


    /* Get scheme first. */
    lpUC->nScheme = GetInternetSchemeW(lpszUrl, lpszcp - lpszUrl);
    if(!set_url_component(&lpUC->lpszScheme, &lpUC->dwSchemeLength, lpszUrl, lpszcp - lpszUrl))
        return FALSE;

    /* Eat ':' in protocol. */
    lpszcp++;

    /* double slash indicates the net_loc portion is present */
    if ((lpszcp[0] == '/') && (lpszcp[1] == '/'))
    {
        lpszcp += 2;

        lpszNetLoc = memchrW(lpszcp, '/', dwUrlLength - (lpszcp - lpszUrl));
        if (lpszParam)
        {
            if (lpszNetLoc)
                lpszNetLoc = min(lpszNetLoc, lpszParam);
            else
                lpszNetLoc = lpszParam;
        }
        else if (!lpszNetLoc)
            lpszNetLoc = lpszcp + dwUrlLength-(lpszcp-lpszUrl);

        /* Parse net-loc */
        if (lpszNetLoc)
        {
            LPCWSTR lpszHost;
            LPCWSTR lpszPort;

            /* [<user>[<:password>]@]<host>[:<port>] */
            /* First find the user and password if they exist */

            lpszHost = memchrW(lpszcp, '@', dwUrlLength - (lpszcp - lpszUrl));
            if (lpszHost == NULL || lpszHost > lpszNetLoc)
            {
                /* username and password not specified. */
                set_url_component(&lpUC->lpszUserName, &lpUC->dwUserNameLength, NULL, 0);
                set_url_component(&lpUC->lpszPassword, &lpUC->dwPasswordLength, NULL, 0);
            }
            else /* Parse out username and password */
            {
                LPCWSTR lpszUser = lpszcp;
                LPCWSTR lpszPasswd = lpszHost;

                while (lpszcp < lpszHost)
                {
                    if (*lpszcp == ':')
                        lpszPasswd = lpszcp;

                    lpszcp++;
                }

                if(!set_url_component(&lpUC->lpszUserName, &lpUC->dwUserNameLength, lpszUser, lpszPasswd - lpszUser))
                    return FALSE;

                if (lpszPasswd != lpszHost)
                    lpszPasswd++;
                if(!set_url_component(&lpUC->lpszPassword, &lpUC->dwPasswordLength,
                                      lpszPasswd == lpszHost ? NULL : lpszPasswd, lpszHost - lpszPasswd))
                    return FALSE;

                lpszcp++; /* Advance to beginning of host */
            }

            /* Parse <host><:port> */

            lpszHost = lpszcp;
            lpszPort = lpszNetLoc;

            /* special case for res:// URLs: there is no port here, so the host is the
               entire string up to the first '/' */
            if(lpUC->nScheme==INTERNET_SCHEME_RES)
            {
                if(!set_url_component(&lpUC->lpszHostName, &lpUC->dwHostNameLength, lpszHost, lpszPort - lpszHost))
                    return FALSE;
                lpszcp=lpszNetLoc;
            }
            else
            {
                while (lpszcp < lpszNetLoc)
                {
                    if (*lpszcp == ':')
                        lpszPort = lpszcp;

                    lpszcp++;
                }

                /* If the scheme is "file" and the host is just one letter, it's not a host */
                if(lpUC->nScheme==INTERNET_SCHEME_FILE && lpszPort <= lpszHost+1)
                {
                    lpszcp=lpszHost;
                    set_url_component(&lpUC->lpszHostName, &lpUC->dwHostNameLength, NULL, 0);
                }
                else
                {
                    if(!set_url_component(&lpUC->lpszHostName, &lpUC->dwHostNameLength, lpszHost, lpszPort - lpszHost))
                        return FALSE;
                    if (lpszPort != lpszNetLoc)
                        lpUC->nPort = atoiW(++lpszPort);
                    else switch (lpUC->nScheme)
                    {
                    case INTERNET_SCHEME_HTTP:
                        lpUC->nPort = INTERNET_DEFAULT_HTTP_PORT;
                        break;
                    case INTERNET_SCHEME_HTTPS:
                        lpUC->nPort = INTERNET_DEFAULT_HTTPS_PORT;
                        break;
                    case INTERNET_SCHEME_FTP:
                        lpUC->nPort = INTERNET_DEFAULT_FTP_PORT;
                        break;
                    case INTERNET_SCHEME_GOPHER:
                        lpUC->nPort = INTERNET_DEFAULT_GOPHER_PORT;
                        break;
                    default:
                        break;
                    }
                }
            }
        }
    }
    else
    {
        set_url_component(&lpUC->lpszUserName, &lpUC->dwUserNameLength, NULL, 0);
        set_url_component(&lpUC->lpszPassword, &lpUC->dwPasswordLength, NULL, 0);
        set_url_component(&lpUC->lpszHostName, &lpUC->dwHostNameLength, NULL, 0);
    }

    /* Here lpszcp points to:
     *
     * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
     *                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     */
    if (lpszcp != 0 && lpszcp - lpszUrl < dwUrlLength && (!lpszParam || lpszcp <= lpszParam))
    {
        DWORD len;

        /* Only truncate the parameter list if it's already been saved
         * in lpUC->lpszExtraInfo.
         */
        if (lpszParam && lpUC->dwExtraInfoLength && lpUC->lpszExtraInfo)
            len = lpszParam - lpszcp;
        else
        {
            /* Leave the parameter list in lpszUrlPath.  Strip off any trailing
             * newlines if necessary.
             */
            LPWSTR lpsznewline = memchrW(lpszcp, '\n', dwUrlLength - (lpszcp - lpszUrl));
            if (lpsznewline != NULL)
                len = lpsznewline - lpszcp;
            else
                len = dwUrlLength-(lpszcp-lpszUrl);
        }
        if (lpUC->dwUrlPathLength && lpUC->lpszUrlPath &&
                lpUC->nScheme == INTERNET_SCHEME_FILE)
        {
            WCHAR tmppath[MAX_PATH];
            if (*lpszcp == '/')
            {
                len = MAX_PATH;
                PathCreateFromUrlW(lpszUrl, tmppath, &len, 0);
            }
            else
            {
                WCHAR *iter;
                memcpy(tmppath, lpszcp, len * sizeof(WCHAR));
                tmppath[len] = '\0';

                iter = tmppath;
                while (*iter) {
                    if (*iter == '/')
                        *iter = '\\';
                    ++iter;
                }
            }
            /* if ends in \. or \.. append a backslash */
            if (tmppath[len - 1] == '.' &&
                    (tmppath[len - 2] == '\\' ||
                     (tmppath[len - 2] == '.' && tmppath[len - 3] == '\\')))
            {
                if (len < MAX_PATH - 1)
                {
                    tmppath[len] = '\\';
                    tmppath[len+1] = '\0';
                    ++len;
                }
            }
            if(!set_url_component(&lpUC->lpszUrlPath, &lpUC->dwUrlPathLength, tmppath, len))
                return FALSE;
        }
        else if(!set_url_component(&lpUC->lpszUrlPath, &lpUC->dwUrlPathLength, lpszcp, len))
            return FALSE;
    }
    else
    {
        if (lpUC->lpszUrlPath && (lpUC->dwUrlPathLength > 0))
            lpUC->lpszUrlPath[0] = 0;
        lpUC->dwUrlPathLength = 0;
    }

    TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", debugstr_wn(lpszUrl,dwUrlLength),
             debugstr_wn(lpUC->lpszScheme,lpUC->dwSchemeLength),
             debugstr_wn(lpUC->lpszHostName,lpUC->dwHostNameLength),
             debugstr_wn(lpUC->lpszUrlPath,lpUC->dwUrlPathLength),
             debugstr_wn(lpUC->lpszExtraInfo,lpUC->dwExtraInfoLength));

    return TRUE;
}

/***********************************************************************
 *           InternetAttemptConnect (WININET.@)
 *
 * Attempt to make a connection to the internet
 *
 * RETURNS
 *    ERROR_SUCCESS on success
 *    Error value   on failure
 *
 */
DWORD WINAPI InternetAttemptConnect(DWORD dwReserved)
{
    FIXME("Stub\n");
    return ERROR_SUCCESS;
}


/***********************************************************************
 *           convert_url_canonicalization_flags
 *
 * Helper for InternetCanonicalizeUrl
 *
 * PARAMS
 *     dwFlags [I] Flags suitable for InternetCanonicalizeUrl
 *
 * RETURNS
 *     Flags suitable for UrlCanonicalize
 */
static DWORD convert_url_canonicalization_flags(DWORD dwFlags)
{
    DWORD dwUrlFlags = URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE;

    if (dwFlags & ICU_BROWSER_MODE)        dwUrlFlags |= URL_BROWSER_MODE;
    if (dwFlags & ICU_DECODE)              dwUrlFlags |= URL_UNESCAPE;
    if (dwFlags & ICU_ENCODE_PERCENT)      dwUrlFlags |= URL_ESCAPE_PERCENT;
    if (dwFlags & ICU_ENCODE_SPACES_ONLY)  dwUrlFlags |= URL_ESCAPE_SPACES_ONLY;
    /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
    if (dwFlags & ICU_NO_ENCODE)           dwUrlFlags ^= URL_ESCAPE_UNSAFE;
    if (dwFlags & ICU_NO_META)             dwUrlFlags |= URL_NO_META;

    return dwUrlFlags;
}

/***********************************************************************
 *           InternetCanonicalizeUrlA (WININET.@)
 *
 * Escape unsafe characters and spaces
 *
 * RETURNS
 *    TRUE on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetCanonicalizeUrlA(LPCSTR lpszUrl, LPSTR lpszBuffer,
	LPDWORD lpdwBufferLength, DWORD dwFlags)
{
    HRESULT hr;

    TRACE("(%s, %p, %p, 0x%08x) buffer length: %d\n", debugstr_a(lpszUrl), lpszBuffer,
        lpdwBufferLength, dwFlags, lpdwBufferLength ? *lpdwBufferLength : -1);

    dwFlags = convert_url_canonicalization_flags(dwFlags);
    hr = UrlCanonicalizeA(lpszUrl, lpszBuffer, lpdwBufferLength, dwFlags);
    if (hr == E_POINTER) SetLastError(ERROR_INSUFFICIENT_BUFFER);
    if (hr == E_INVALIDARG) SetLastError(ERROR_INVALID_PARAMETER);

    return hr == S_OK;
}

/***********************************************************************
 *           InternetCanonicalizeUrlW (WININET.@)
 *
 * Escape unsafe characters and spaces
 *
 * RETURNS
 *    TRUE on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetCanonicalizeUrlW(LPCWSTR lpszUrl, LPWSTR lpszBuffer,
    LPDWORD lpdwBufferLength, DWORD dwFlags)
{
    HRESULT hr;

    TRACE("(%s, %p, %p, 0x%08x) buffer length: %d\n", debugstr_w(lpszUrl), lpszBuffer,
          lpdwBufferLength, dwFlags, lpdwBufferLength ? *lpdwBufferLength : -1);

    dwFlags = convert_url_canonicalization_flags(dwFlags);
    hr = UrlCanonicalizeW(lpszUrl, lpszBuffer, lpdwBufferLength, dwFlags);
    if (hr == E_POINTER) SetLastError(ERROR_INSUFFICIENT_BUFFER);
    if (hr == E_INVALIDARG) SetLastError(ERROR_INVALID_PARAMETER);

    return hr == S_OK;
}

/* #################################################### */

static INTERNET_STATUS_CALLBACK set_status_callback(
    object_header_t *lpwh, INTERNET_STATUS_CALLBACK callback, BOOL unicode)
{
    INTERNET_STATUS_CALLBACK ret;

    if (unicode) lpwh->dwInternalFlags |= INET_CALLBACKW;
    else lpwh->dwInternalFlags &= ~INET_CALLBACKW;

    ret = lpwh->lpfnStatusCB;
    lpwh->lpfnStatusCB = callback;

    return ret;
}

/***********************************************************************
 *           InternetSetStatusCallbackA (WININET.@)
 *
 * Sets up a callback function which is called as progress is made
 * during an operation.
 *
 * RETURNS
 *    Previous callback or NULL 	on success
 *    INTERNET_INVALID_STATUS_CALLBACK  on failure
 *
 */
INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA(
	HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
{
    INTERNET_STATUS_CALLBACK retVal;
    object_header_t *lpwh;

    TRACE("%p\n", hInternet);

    if (!(lpwh = get_handle_object(hInternet)))
        return INTERNET_INVALID_STATUS_CALLBACK;

    retVal = set_status_callback(lpwh, lpfnIntCB, FALSE);

    WININET_Release( lpwh );
    return retVal;
}

/***********************************************************************
 *           InternetSetStatusCallbackW (WININET.@)
 *
 * Sets up a callback function which is called as progress is made
 * during an operation.
 *
 * RETURNS
 *    Previous callback or NULL 	on success
 *    INTERNET_INVALID_STATUS_CALLBACK  on failure
 *
 */
INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(
	HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
{
    INTERNET_STATUS_CALLBACK retVal;
    object_header_t *lpwh;

    TRACE("%p\n", hInternet);

    if (!(lpwh = get_handle_object(hInternet)))
        return INTERNET_INVALID_STATUS_CALLBACK;

    retVal = set_status_callback(lpwh, lpfnIntCB, TRUE);

    WININET_Release( lpwh );
    return retVal;
}

/***********************************************************************
 *           InternetSetFilePointer (WININET.@)
 */
DWORD WINAPI InternetSetFilePointer(HINTERNET hFile, LONG lDistanceToMove,
    PVOID pReserved, DWORD dwMoveContext, DWORD_PTR dwContext)
{
    FIXME("(%p %d %p %d %lx): stub\n", hFile, lDistanceToMove, pReserved, dwMoveContext, dwContext);
    return FALSE;
}

/***********************************************************************
 *           InternetWriteFile (WININET.@)
 *
 * Write data to an open internet file
 *
 * RETURNS
 *    TRUE  on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer,
	DWORD dwNumOfBytesToWrite, LPDWORD lpdwNumOfBytesWritten)
{
    object_header_t *lpwh;
    BOOL res;

    TRACE("(%p %p %d %p)\n", hFile, lpBuffer, dwNumOfBytesToWrite, lpdwNumOfBytesWritten);

    lpwh = get_handle_object( hFile );
    if (!lpwh) {
        WARN("Invalid handle\n");
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if(lpwh->vtbl->WriteFile) {
        res = lpwh->vtbl->WriteFile(lpwh, lpBuffer, dwNumOfBytesToWrite, lpdwNumOfBytesWritten);
    }else {
        WARN("No Writefile method.\n");
        res = ERROR_INVALID_HANDLE;
    }

    WININET_Release( lpwh );

    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}


/***********************************************************************
 *           InternetReadFile (WININET.@)
 *
 * Read data from an open internet file
 *
 * RETURNS
 *    TRUE  on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
        DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead)
{
    object_header_t *hdr;
    DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;

    TRACE("%p %p %d %p\n", hFile, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead);

    hdr = get_handle_object(hFile);
    if (!hdr) {
        INTERNET_SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if(hdr->vtbl->ReadFile)
        res = hdr->vtbl->ReadFile(hdr, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead);

    WININET_Release(hdr);

    TRACE("-- %s (%u) (bytes read: %d)\n", res == ERROR_SUCCESS ? "TRUE": "FALSE", res,
          pdwNumOfBytesRead ? *pdwNumOfBytesRead : -1);

    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}

/***********************************************************************
 *           InternetReadFileExA (WININET.@)
 *
 * Read data from an open internet file
 *
 * PARAMS
 *  hFile         [I] Handle returned by InternetOpenUrl or HttpOpenRequest.
 *  lpBuffersOut  [I/O] Buffer.
 *  dwFlags       [I] Flags. See notes.
 *  dwContext     [I] Context for callbacks.
 *
 * RETURNS
 *    TRUE  on success
 *    FALSE on failure
 *
 * NOTES
 *  The parameter dwFlags include zero or more of the following flags:
 *|IRF_ASYNC - Makes the call asynchronous.
 *|IRF_SYNC - Makes the call synchronous.
 *|IRF_USE_CONTEXT - Forces dwContext to be used.
 *|IRF_NO_WAIT - Don't block if the data is not available, just return what is available.
 *
 * However, in testing IRF_USE_CONTEXT seems to have no effect - dwContext isn't used.
 *
 * SEE
 *  InternetOpenUrlA(), HttpOpenRequestA()
 */
BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOut,
	DWORD dwFlags, DWORD_PTR dwContext)
{
    object_header_t *hdr;
    DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;

    TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffersOut, dwFlags, dwContext);

    if (lpBuffersOut->dwStructSize != sizeof(*lpBuffersOut)) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    hdr = get_handle_object(hFile);
    if (!hdr) {
        INTERNET_SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if(hdr->vtbl->ReadFileEx)
        res = hdr->vtbl->ReadFileEx(hdr, lpBuffersOut->lpvBuffer, lpBuffersOut->dwBufferLength,
                &lpBuffersOut->dwBufferLength, dwFlags, dwContext);

    WININET_Release(hdr);

    TRACE("-- %s (%u, bytes read: %d)\n", res == ERROR_SUCCESS ? "TRUE": "FALSE",
          res, lpBuffersOut->dwBufferLength);

    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}

/***********************************************************************
 *           InternetReadFileExW (WININET.@)
 * SEE
 *  InternetReadFileExA()
 */
BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer,
	DWORD dwFlags, DWORD_PTR dwContext)
{
    object_header_t *hdr;
    DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;

    TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffer, dwFlags, dwContext);

    if (lpBuffer->dwStructSize != sizeof(*lpBuffer)) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    hdr = get_handle_object(hFile);
    if (!hdr) {
        INTERNET_SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if(hdr->vtbl->ReadFileEx)
        res = hdr->vtbl->ReadFileEx(hdr, lpBuffer->lpvBuffer, lpBuffer->dwBufferLength, &lpBuffer->dwBufferLength,
                dwFlags, dwContext);

    WININET_Release(hdr);

    TRACE("-- %s (%u, bytes read: %d)\n", res == ERROR_SUCCESS ? "TRUE": "FALSE",
          res, lpBuffer->dwBufferLength);

    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}

static BOOL get_proxy_autoconfig_url( char *buf, DWORD buflen )
{
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6

    CFDictionaryRef settings = CFNetworkCopySystemProxySettings();
    const void *ref;
    BOOL ret = FALSE;

    if (!settings) return FALSE;

    if (!(ref = CFDictionaryGetValue( settings, kCFNetworkProxiesProxyAutoConfigURLString )))
    {
        CFRelease( settings );
        return FALSE;
    }
    if (CFStringGetCString( ref, buf, buflen, kCFStringEncodingASCII ))
    {
        TRACE( "returning %s\n", debugstr_a(buf) );
        ret = TRUE;
    }
    CFRelease( settings );
    return ret;
#else
    FIXME( "no support on this platform\n" );
    return FALSE;
#endif
}

static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
    /* FIXME: This function currently handles more options than it should. Options requiring
     * proper handles should be moved to proper functions */
    switch(option) {
    case INTERNET_OPTION_HTTP_VERSION:
        if (*size < sizeof(HTTP_VERSION_INFO))
            return ERROR_INSUFFICIENT_BUFFER;

        /*
         * Presently hardcoded to 1.1
         */
        ((HTTP_VERSION_INFO*)buffer)->dwMajorVersion = 1;
        ((HTTP_VERSION_INFO*)buffer)->dwMinorVersion = 1;
        *size = sizeof(HTTP_VERSION_INFO);

        return ERROR_SUCCESS;

    case INTERNET_OPTION_CONNECTED_STATE:
        FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n");

        if (*size < sizeof(ULONG))
            return ERROR_INSUFFICIENT_BUFFER;

        *(ULONG*)buffer = INTERNET_STATE_CONNECTED;
        *size = sizeof(ULONG);

        return ERROR_SUCCESS;

    case INTERNET_OPTION_PROXY: {
        appinfo_t ai;
        BOOL ret;

        TRACE("Getting global proxy info\n");
        memset(&ai, 0, sizeof(appinfo_t));
        INTERNET_ConfigureProxy(&ai);

        ret = APPINFO_QueryOption(&ai.hdr, INTERNET_OPTION_PROXY, buffer, size, unicode); /* FIXME */
        APPINFO_Destroy(&ai.hdr);
        return ret;
    }

    case INTERNET_OPTION_MAX_CONNS_PER_SERVER:
        TRACE("INTERNET_OPTION_MAX_CONNS_PER_SERVER\n");

        if (*size < sizeof(ULONG))
            return ERROR_INSUFFICIENT_BUFFER;

        *(ULONG*)buffer = max_conns;
        *size = sizeof(ULONG);

        return ERROR_SUCCESS;

    case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER:
            TRACE("INTERNET_OPTION_MAX_CONNS_1_0_SERVER\n");

            if (*size < sizeof(ULONG))
                return ERROR_INSUFFICIENT_BUFFER;

            *(ULONG*)buffer = max_1_0_conns;
            *size = sizeof(ULONG);

            return ERROR_SUCCESS;

    case INTERNET_OPTION_SECURITY_FLAGS:
        FIXME("INTERNET_OPTION_SECURITY_FLAGS: Stub\n");
        return ERROR_SUCCESS;

    case INTERNET_OPTION_VERSION: {
        static const INTERNET_VERSION_INFO info = { 1, 2 };

        TRACE("INTERNET_OPTION_VERSION\n");

        if (*size < sizeof(INTERNET_VERSION_INFO))
            return ERROR_INSUFFICIENT_BUFFER;

        memcpy(buffer, &info, sizeof(info));
        *size = sizeof(info);

        return ERROR_SUCCESS;
    }

    case INTERNET_OPTION_PER_CONNECTION_OPTION: {
        char url[INTERNET_MAX_URL_LENGTH + 1];
        INTERNET_PER_CONN_OPTION_LISTW *con = buffer;
        INTERNET_PER_CONN_OPTION_LISTA *conA = buffer;
        DWORD res = ERROR_SUCCESS, i;
        proxyinfo_t pi;
        BOOL have_url;
        LONG ret;

        TRACE("Getting global proxy info\n");
        if((ret = INTERNET_LoadProxySettings(&pi)))
            return ret;

        have_url = get_proxy_autoconfig_url(url, sizeof(url));

        FIXME("INTERNET_OPTION_PER_CONNECTION_OPTION stub\n");

        if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) {
            FreeProxyInfo(&pi);
            return ERROR_INSUFFICIENT_BUFFER;
        }

        for (i = 0; i < con->dwOptionCount; i++) {
            INTERNET_PER_CONN_OPTIONW *optionW = con->pOptions + i;
            INTERNET_PER_CONN_OPTIONA *optionA = conA->pOptions + i;

            switch (optionW->dwOption) {
            case INTERNET_PER_CONN_FLAGS:
                if(pi.proxyEnabled)
                    optionW->Value.dwValue = PROXY_TYPE_PROXY;
                else
                    optionW->Value.dwValue = PROXY_TYPE_DIRECT;
                if (have_url)
                    /* native includes PROXY_TYPE_DIRECT even if PROXY_TYPE_PROXY is set */
                    optionW->Value.dwValue |= PROXY_TYPE_DIRECT|PROXY_TYPE_AUTO_PROXY_URL;
                break;

            case INTERNET_PER_CONN_PROXY_SERVER:
                if (unicode)
                    optionW->Value.pszValue = heap_strdupW(pi.proxy);
                else
                    optionA->Value.pszValue = heap_strdupWtoA(pi.proxy);
                break;

            case INTERNET_PER_CONN_PROXY_BYPASS:
                if (unicode)
                    optionW->Value.pszValue = heap_strdupW(pi.proxyBypass);
                else
                    optionA->Value.pszValue = heap_strdupWtoA(pi.proxyBypass);
                break;

            case INTERNET_PER_CONN_AUTOCONFIG_URL:
                if (!have_url)
                    optionW->Value.pszValue = NULL;
                else if (unicode)
                    optionW->Value.pszValue = heap_strdupAtoW(url);
                else
                    optionA->Value.pszValue = heap_strdupA(url);
                break;

            case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
                optionW->Value.dwValue = AUTO_PROXY_FLAG_ALWAYS_DETECT;
                break;

            case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
            case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
            case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME:
            case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
                FIXME("Unhandled dwOption %d\n", optionW->dwOption);
                memset(&optionW->Value, 0, sizeof(optionW->Value));
                break;

            default:
                FIXME("Unknown dwOption %d\n", optionW->dwOption);
                res = ERROR_INVALID_PARAMETER;
                break;
            }
        }
        FreeProxyInfo(&pi);

        return res;
    }
    case INTERNET_OPTION_REQUEST_FLAGS:
    case INTERNET_OPTION_USER_AGENT:
        *size = 0;
        return ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
    case INTERNET_OPTION_POLICY:
        return ERROR_INVALID_PARAMETER;
    case INTERNET_OPTION_CONNECT_TIMEOUT:
        TRACE("INTERNET_OPTION_CONNECT_TIMEOUT\n");

        if (*size < sizeof(ULONG))
            return ERROR_INSUFFICIENT_BUFFER;

        *(ULONG*)buffer = connect_timeout;
        *size = sizeof(ULONG);

        return ERROR_SUCCESS;
    }

    FIXME("Stub for %d\n", option);
    return ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
}

DWORD INET_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
    switch(option) {
    case INTERNET_OPTION_CONTEXT_VALUE:
        if (!size)
            return ERROR_INVALID_PARAMETER;

        if (*size < sizeof(DWORD_PTR)) {
            *size = sizeof(DWORD_PTR);
            return ERROR_INSUFFICIENT_BUFFER;
        }
        if (!buffer)
            return ERROR_INVALID_PARAMETER;

        *(DWORD_PTR *)buffer = hdr->dwContext;
        *size = sizeof(DWORD_PTR);
        return ERROR_SUCCESS;

    case INTERNET_OPTION_REQUEST_FLAGS:
        WARN("INTERNET_OPTION_REQUEST_FLAGS\n");
        *size = sizeof(DWORD);
        return ERROR_INTERNET_INCORRECT_HANDLE_TYPE;

    case INTERNET_OPTION_MAX_CONNS_PER_SERVER:
    case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER:
        WARN("Called on global option %u\n", option);
        return ERROR_INTERNET_INVALID_OPERATION;
    }

    /* FIXME: we shouldn't call it here */
    return query_global_option(option, buffer, size, unicode);
}

/***********************************************************************
 *           InternetQueryOptionW (WININET.@)
 *
 * Queries an options on the specified handle
 *
 * RETURNS
 *    TRUE  on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption,
                                 LPVOID lpBuffer, LPDWORD lpdwBufferLength)
{
    object_header_t *hdr;
    DWORD res = ERROR_INVALID_HANDLE;

    TRACE("%p %d %p %p\n", hInternet, dwOption, lpBuffer, lpdwBufferLength);

    if(hInternet) {
        hdr = get_handle_object(hInternet);
        if (hdr) {
            res = hdr->vtbl->QueryOption(hdr, dwOption, lpBuffer, lpdwBufferLength, TRUE);
            WININET_Release(hdr);
        }
    }else {
        res = query_global_option(dwOption, lpBuffer, lpdwBufferLength, TRUE);
    }

    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}

/***********************************************************************
 *           InternetQueryOptionA (WININET.@)
 *
 * Queries an options on the specified handle
 *
 * RETURNS
 *    TRUE  on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption,
                                 LPVOID lpBuffer, LPDWORD lpdwBufferLength)
{
    object_header_t *hdr;
    DWORD res = ERROR_INVALID_HANDLE;

    TRACE("%p %d %p %p\n", hInternet, dwOption, lpBuffer, lpdwBufferLength);

    if(hInternet) {
        hdr = get_handle_object(hInternet);
        if (hdr) {
            res = hdr->vtbl->QueryOption(hdr, dwOption, lpBuffer, lpdwBufferLength, FALSE);
            WININET_Release(hdr);
        }
    }else {
        res = query_global_option(dwOption, lpBuffer, lpdwBufferLength, FALSE);
    }

    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}

DWORD INET_SetOption(object_header_t *hdr, DWORD option, void *buf, DWORD size)
{
    switch(option) {
    case INTERNET_OPTION_CALLBACK:
        WARN("Not settable option %u\n", option);
        return ERROR_INTERNET_OPTION_NOT_SETTABLE;
    case INTERNET_OPTION_MAX_CONNS_PER_SERVER:
    case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER:
        WARN("Called on global option %u\n", option);
        return ERROR_INTERNET_INVALID_OPERATION;
    }

    return ERROR_INTERNET_INVALID_OPTION;
}

static DWORD set_global_option(DWORD option, void *buf, DWORD size)
{
    switch(option) {
    case INTERNET_OPTION_CALLBACK:
        WARN("Not global option %u\n", option);
        return ERROR_INTERNET_INCORRECT_HANDLE_TYPE;

    case INTERNET_OPTION_MAX_CONNS_PER_SERVER:
        TRACE("INTERNET_OPTION_MAX_CONNS_PER_SERVER\n");

        if(size != sizeof(max_conns))
            return ERROR_INTERNET_BAD_OPTION_LENGTH;
        if(!*(ULONG*)buf)
            return ERROR_BAD_ARGUMENTS;

        max_conns = *(ULONG*)buf;
        return ERROR_SUCCESS;

    case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER:
        TRACE("INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER\n");

        if(size != sizeof(max_1_0_conns))
            return ERROR_INTERNET_BAD_OPTION_LENGTH;
        if(!*(ULONG*)buf)
            return ERROR_BAD_ARGUMENTS;

        max_1_0_conns = *(ULONG*)buf;
        return ERROR_SUCCESS;

    case INTERNET_OPTION_CONNECT_TIMEOUT:
        TRACE("INTERNET_OPTION_CONNECT_TIMEOUT\n");

        if(size != sizeof(connect_timeout))
            return ERROR_INTERNET_BAD_OPTION_LENGTH;
        if(!*(ULONG*)buf)
            return ERROR_BAD_ARGUMENTS;

        connect_timeout = *(ULONG*)buf;
        return ERROR_SUCCESS;

    case INTERNET_OPTION_SETTINGS_CHANGED:
        FIXME("INTERNETOPTION_SETTINGS_CHANGED semi-stub\n");
        collect_connections(COLLECT_CONNECTIONS);
        return ERROR_SUCCESS;

    case INTERNET_OPTION_SUPPRESS_BEHAVIOR:
        FIXME("INTERNET_OPTION_SUPPRESS_BEHAVIOR stub\n");

        if(size != sizeof(ULONG))
            return ERROR_INTERNET_BAD_OPTION_LENGTH;

        FIXME("%08x\n", *(ULONG*)buf);
        return ERROR_SUCCESS;
    }

    return ERROR_INTERNET_INVALID_OPTION;
}

/***********************************************************************
 *           InternetSetOptionW (WININET.@)
 *
 * Sets an options on the specified handle
 *
 * RETURNS
 *    TRUE  on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
                           LPVOID lpBuffer, DWORD dwBufferLength)
{
    object_header_t *lpwhh;
    BOOL ret = TRUE;
    DWORD res;

    TRACE("(%p %d %p %d)\n", hInternet, dwOption, lpBuffer, dwBufferLength);

    lpwhh = (object_header_t*) get_handle_object( hInternet );
    if(lpwhh)
        res = lpwhh->vtbl->SetOption(lpwhh, dwOption, lpBuffer, dwBufferLength);
    else
        res = set_global_option(dwOption, lpBuffer, dwBufferLength);

    if(res != ERROR_INTERNET_INVALID_OPTION) {
        if(lpwhh)
            WININET_Release(lpwhh);

        if(res != ERROR_SUCCESS)
            SetLastError(res);

        return res == ERROR_SUCCESS;
    }

    switch (dwOption)
    {
    case INTERNET_OPTION_HTTP_VERSION:
      {
        HTTP_VERSION_INFO* pVersion=(HTTP_VERSION_INFO*)lpBuffer;
        FIXME("Option INTERNET_OPTION_HTTP_VERSION(%d,%d): STUB\n",pVersion->dwMajorVersion,pVersion->dwMinorVersion);
      }
      break;
    case INTERNET_OPTION_ERROR_MASK:
      {
        if(!lpwhh) {
            SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
            return FALSE;
        } else if(*(ULONG*)lpBuffer & (~(INTERNET_ERROR_MASK_INSERT_CDROM|
                        INTERNET_ERROR_MASK_COMBINED_SEC_CERT|
                        INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY))) {
            SetLastError(ERROR_INVALID_PARAMETER);
            ret = FALSE;
        } else if(dwBufferLength != sizeof(ULONG)) {
            SetLastError(ERROR_INTERNET_BAD_OPTION_LENGTH);
            ret = FALSE;
        } else
            TRACE("INTERNET_OPTION_ERROR_MASK: %x\n", *(ULONG*)lpBuffer);
            lpwhh->ErrorMask = *(ULONG*)lpBuffer;
      }
      break;
    case INTERNET_OPTION_PROXY:
    {
        INTERNET_PROXY_INFOW *info = lpBuffer;

        if (!lpBuffer || dwBufferLength < sizeof(INTERNET_PROXY_INFOW))
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }
        if (!hInternet)
        {
            EnterCriticalSection( &WININET_cs );
            free_global_proxy();
            global_proxy = heap_alloc( sizeof(proxyinfo_t) );
            if (global_proxy)
            {
                if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY)
                {
                    global_proxy->proxyEnabled = 1;
                    global_proxy->proxy = heap_strdupW( info->lpszProxy );
                    global_proxy->proxyBypass = heap_strdupW( info->lpszProxyBypass );
                }
                else
                {
                    global_proxy->proxyEnabled = 0;
                    global_proxy->proxy = global_proxy->proxyBypass = NULL;
                }
            }
            LeaveCriticalSection( &WININET_cs );
        }
        else
        {
            /* In general, each type of object should handle
             * INTERNET_OPTION_PROXY directly.  This FIXME ensures it doesn't
             * get silently dropped.
             */
            FIXME("INTERNET_OPTION_PROXY unimplemented\n");
            SetLastError(ERROR_INTERNET_INVALID_OPTION);
            ret = FALSE;
        }
        break;
    }
    case INTERNET_OPTION_CODEPAGE:
      {
        ULONG codepage = *(ULONG *)lpBuffer;
        FIXME("Option INTERNET_OPTION_CODEPAGE (%d): STUB\n", codepage);
      }
      break;
    case INTERNET_OPTION_REQUEST_PRIORITY:
      {
        ULONG priority = *(ULONG *)lpBuffer;
        FIXME("Option INTERNET_OPTION_REQUEST_PRIORITY (%d): STUB\n", priority);
      }
      break;
    case INTERNET_OPTION_CONNECT_TIMEOUT:
      {
        ULONG connecttimeout = *(ULONG *)lpBuffer;
        FIXME("Option INTERNET_OPTION_CONNECT_TIMEOUT (%d): STUB\n", connecttimeout);
      }
      break;
    case INTERNET_OPTION_DATA_RECEIVE_TIMEOUT:
      {
        ULONG receivetimeout = *(ULONG *)lpBuffer;
        FIXME("Option INTERNET_OPTION_DATA_RECEIVE_TIMEOUT (%d): STUB\n", receivetimeout);
      }
      break;
    case INTERNET_OPTION_RESET_URLCACHE_SESSION:
        FIXME("Option INTERNET_OPTION_RESET_URLCACHE_SESSION: STUB\n");
        break;
    case INTERNET_OPTION_END_BROWSER_SESSION:
        FIXME("Option INTERNET_OPTION_END_BROWSER_SESSION: STUB\n");
        break;
    case INTERNET_OPTION_CONNECTED_STATE:
        FIXME("Option INTERNET_OPTION_CONNECTED_STATE: STUB\n");
        break;
    case INTERNET_OPTION_DISABLE_PASSPORT_AUTH:
	TRACE("Option INTERNET_OPTION_DISABLE_PASSPORT_AUTH: harmless stub, since not enabled\n");
	break;
    case INTERNET_OPTION_SEND_TIMEOUT:
    case INTERNET_OPTION_RECEIVE_TIMEOUT:
    case INTERNET_OPTION_DATA_SEND_TIMEOUT:
    {
        ULONG timeout = *(ULONG *)lpBuffer;
        FIXME("INTERNET_OPTION_SEND/RECEIVE_TIMEOUT/DATA_SEND_TIMEOUT %d\n", timeout);
        break;
    }
    case INTERNET_OPTION_CONNECT_RETRIES:
    {
        ULONG retries = *(ULONG *)lpBuffer;
        FIXME("INTERNET_OPTION_CONNECT_RETRIES %d\n", retries);
        break;
    }
    case INTERNET_OPTION_CONTEXT_VALUE:
    {
        if (!lpwhh)
        {
            SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
            return FALSE;
        }
        if (!lpBuffer || dwBufferLength != sizeof(DWORD_PTR))
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            ret = FALSE;
        }
        else
            lpwhh->dwContext = *(DWORD_PTR *)lpBuffer;
        break;
    }
    case INTERNET_OPTION_SECURITY_FLAGS:
	 FIXME("Option INTERNET_OPTION_SECURITY_FLAGS; STUB\n");
	 break;
    case INTERNET_OPTION_DISABLE_AUTODIAL:
	 FIXME("Option INTERNET_OPTION_DISABLE_AUTODIAL; STUB\n");
	 break;
    case INTERNET_OPTION_HTTP_DECODING:
        FIXME("INTERNET_OPTION_HTTP_DECODING; STUB\n");
        SetLastError(ERROR_INTERNET_INVALID_OPTION);
        ret = FALSE;
        break;
    case INTERNET_OPTION_COOKIES_3RD_PARTY:
        FIXME("INTERNET_OPTION_COOKIES_3RD_PARTY; STUB\n");
        SetLastError(ERROR_INTERNET_INVALID_OPTION);
        ret = FALSE;
        break;
    case INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY:
        FIXME("INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY; STUB\n");
        SetLastError(ERROR_INTERNET_INVALID_OPTION);
        ret = FALSE;
        break;
    case INTERNET_OPTION_CODEPAGE_PATH:
        FIXME("INTERNET_OPTION_CODEPAGE_PATH; STUB\n");
        SetLastError(ERROR_INTERNET_INVALID_OPTION);
        ret = FALSE;
        break;
    case INTERNET_OPTION_CODEPAGE_EXTRA:
        FIXME("INTERNET_OPTION_CODEPAGE_EXTRA; STUB\n");
        SetLastError(ERROR_INTERNET_INVALID_OPTION);
        ret = FALSE;
        break;
    case INTERNET_OPTION_IDN:
        FIXME("INTERNET_OPTION_IDN; STUB\n");
        SetLastError(ERROR_INTERNET_INVALID_OPTION);
        ret = FALSE;
        break;
    case INTERNET_OPTION_POLICY:
        SetLastError(ERROR_INVALID_PARAMETER);
        ret = FALSE;
        break;
    case INTERNET_OPTION_PER_CONNECTION_OPTION: {
        INTERNET_PER_CONN_OPTION_LISTW *con = lpBuffer;
        LONG res;
        unsigned int i;
        proxyinfo_t pi;

        if (INTERNET_LoadProxySettings(&pi)) return FALSE;

        for (i = 0; i < con->dwOptionCount; i++) {
            INTERNET_PER_CONN_OPTIONW *option = con->pOptions + i;

            switch (option->dwOption) {
            case INTERNET_PER_CONN_PROXY_SERVER:
                heap_free(pi.proxy);
                pi.proxy = heap_strdupW(option->Value.pszValue);
                break;

            case INTERNET_PER_CONN_FLAGS:
                if(option->Value.dwValue & PROXY_TYPE_PROXY)
                    pi.proxyEnabled = 1;
                else
                {
                    if(option->Value.dwValue != PROXY_TYPE_DIRECT)
                        FIXME("Unhandled flags: 0x%x\n", option->Value.dwValue);
                    pi.proxyEnabled = 0;
                }
                break;

            case INTERNET_PER_CONN_PROXY_BYPASS:
                heap_free(pi.proxyBypass);
                pi.proxyBypass = heap_strdupW(option->Value.pszValue);
                break;

            case INTERNET_PER_CONN_AUTOCONFIG_URL:
            case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
            case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
            case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
            case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME:
            case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
                FIXME("Unhandled dwOption %d\n", option->dwOption);
                break;

            default:
                FIXME("Unknown dwOption %d\n", option->dwOption);
                SetLastError(ERROR_INVALID_PARAMETER);
                break;
            }
        }

        if ((res = INTERNET_SaveProxySettings(&pi)))
            SetLastError(res);

        FreeProxyInfo(&pi);

        ret = (res == ERROR_SUCCESS);
        break;
        }
    default:
        FIXME("Option %d STUB\n",dwOption);
        SetLastError(ERROR_INTERNET_INVALID_OPTION);
        ret = FALSE;
        break;
    }

    if(lpwhh)
        WININET_Release( lpwhh );

    return ret;
}


/***********************************************************************
 *           InternetSetOptionA (WININET.@)
 *
 * Sets an options on the specified handle.
 *
 * RETURNS
 *    TRUE  on success
 *    FALSE on failure
 *
 */
BOOL WINAPI InternetSetOptionA(HINTERNET hInternet, DWORD dwOption,
                           LPVOID lpBuffer, DWORD dwBufferLength)
{
    LPVOID wbuffer;
    DWORD wlen;
    BOOL r;

    switch( dwOption )
    {
    case INTERNET_OPTION_PROXY:
        {
        LPINTERNET_PROXY_INFOA pi = (LPINTERNET_PROXY_INFOA) lpBuffer;
        LPINTERNET_PROXY_INFOW piw;
        DWORD proxlen, prbylen;
        LPWSTR prox, prby;

        proxlen = MultiByteToWideChar( CP_ACP, 0, pi->lpszProxy, -1, NULL, 0);
        prbylen= MultiByteToWideChar( CP_ACP, 0, pi->lpszProxyBypass, -1, NULL, 0);
        wlen = sizeof(*piw) + proxlen + prbylen;
        wbuffer = heap_alloc(wlen*sizeof(WCHAR) );
        piw = (LPINTERNET_PROXY_INFOW) wbuffer;
        piw->dwAccessType = pi->dwAccessType;
        prox = (LPWSTR) &piw[1];
        prby = &prox[proxlen+1];
        MultiByteToWideChar( CP_ACP, 0, pi->lpszProxy, -1, prox, proxlen);
        MultiByteToWideChar( CP_ACP, 0, pi->lpszProxyBypass, -1, prby, prbylen);
        piw->lpszProxy = prox;
        piw->lpszProxyBypass = prby;
        }
        break;
    case INTERNET_OPTION_USER_AGENT:
    case INTERNET_OPTION_USERNAME:
    case INTERNET_OPTION_PASSWORD:
    case INTERNET_OPTION_PROXY_USERNAME:
    case INTERNET_OPTION_PROXY_PASSWORD:
        wlen = MultiByteToWideChar( CP_ACP, 0, lpBuffer, -1, NULL, 0 );
        if (!(wbuffer = heap_alloc( wlen * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
        MultiByteToWideChar( CP_ACP, 0, lpBuffer, -1, wbuffer, wlen );
        break;
    case INTERNET_OPTION_PER_CONNECTION_OPTION: {
        unsigned int i;
        INTERNET_PER_CONN_OPTION_LISTW *listW;
        INTERNET_PER_CONN_OPTION_LISTA *listA = lpBuffer;
        wlen = sizeof(INTERNET_PER_CONN_OPTION_LISTW);
        wbuffer = heap_alloc(wlen);
        listW = wbuffer;

        listW->dwSize = sizeof(INTERNET_PER_CONN_OPTION_LISTW);
        if (listA->pszConnection)
        {
            wlen = MultiByteToWideChar( CP_ACP, 0, listA->pszConnection, -1, NULL, 0 );
            listW->pszConnection = heap_alloc(wlen*sizeof(WCHAR));
            MultiByteToWideChar( CP_ACP, 0, listA->pszConnection, -1, listW->pszConnection, wlen );
        }
        else
            listW->pszConnection = NULL;
        listW->dwOptionCount = listA->dwOptionCount;
        listW->dwOptionError = listA->dwOptionError;
        listW->pOptions = heap_alloc(sizeof(INTERNET_PER_CONN_OPTIONW) * listA->dwOptionCount);

        for (i = 0; i < listA->dwOptionCount; ++i) {
            INTERNET_PER_CONN_OPTIONA *optA = listA->pOptions + i;
            INTERNET_PER_CONN_OPTIONW *optW = listW->pOptions + i;

            optW->dwOption = optA->dwOption;

            switch (optA->dwOption) {
            case INTERNET_PER_CONN_AUTOCONFIG_URL:
            case INTERNET_PER_CONN_PROXY_BYPASS:
            case INTERNET_PER_CONN_PROXY_SERVER:
            case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
            case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
                if (optA->Value.pszValue)
                {
                    wlen = MultiByteToWideChar( CP_ACP, 0, optA->Value.pszValue, -1, NULL, 0 );
                    optW->Value.pszValue = heap_alloc(wlen*sizeof(WCHAR));
                    MultiByteToWideChar( CP_ACP, 0, optA->Value.pszValue, -1, optW->Value.pszValue, wlen );
                }
                else
                    optW->Value.pszValue = NULL;
                break;
            case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
            case INTERNET_PER_CONN_FLAGS:
            case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
                optW->Value.dwValue = optA->Value.dwValue;
                break;
            case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME:
                optW->Value.ftValue = optA->Value.ftValue;
                break;
            default:
                WARN("Unknown PER_CONN dwOption: %d, guessing at conversion to Wide\n", optA->dwOption);
                optW->Value.dwValue = optA->Value.dwValue;
                break;
            }
        }
        }
        break;
    default:
        wbuffer = lpBuffer;
        wlen = dwBufferLength;
    }

    r = InternetSetOptionW(hInternet,dwOption, wbuffer, wlen);

    if( lpBuffer != wbuffer )
    {
        if (dwOption == INTERNET_OPTION_PER_CONNECTION_OPTION)
        {
            INTERNET_PER_CONN_OPTION_LISTW *list = wbuffer;
            unsigned int i;
            for (i = 0; i < list->dwOptionCount; ++i) {
                INTERNET_PER_CONN_OPTIONW *opt = list->pOptions + i;
                switch (opt->dwOption) {
                case INTERNET_PER_CONN_AUTOCONFIG_URL:
                case INTERNET_PER_CONN_PROXY_BYPASS:
                case INTERNET_PER_CONN_PROXY_SERVER:
                case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
                case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
                    heap_free( opt->Value.pszValue );
                    break;
                default:
                    break;
                }
            }
            heap_free( list->pOptions );
        }
        heap_free( wbuffer );
    }

    return r;
}


/***********************************************************************
 *           InternetSetOptionExA (WININET.@)
 */
BOOL WINAPI InternetSetOptionExA(HINTERNET hInternet, DWORD dwOption,
                           LPVOID lpBuffer, DWORD dwBufferLength, DWORD dwFlags)
{
    FIXME("Flags %08x ignored\n", dwFlags);
    return InternetSetOptionA( hInternet, dwOption, lpBuffer, dwBufferLength );
}

/***********************************************************************
 *           InternetSetOptionExW (WININET.@)
 */
BOOL WINAPI InternetSetOptionExW(HINTERNET hInternet, DWORD dwOption,
                           LPVOID lpBuffer, DWORD dwBufferLength, DWORD dwFlags)
{
    FIXME("Flags %08x ignored\n", dwFlags);
    if( dwFlags & ~ISO_VALID_FLAGS )
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    return InternetSetOptionW( hInternet, dwOption, lpBuffer, dwBufferLength );
}

static const WCHAR WININET_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 WININET_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 } };

/***********************************************************************
 *           InternetTimeFromSystemTimeA (WININET.@)
 */
BOOL WINAPI InternetTimeFromSystemTimeA( const SYSTEMTIME* time, DWORD format, LPSTR string, DWORD size )
{
    BOOL ret;
    WCHAR stringW[INTERNET_RFC1123_BUFSIZE];

    TRACE( "%p 0x%08x %p 0x%08x\n", time, format, string, size );

    if (!time || !string || format != INTERNET_RFC1123_FORMAT)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (size < INTERNET_RFC1123_BUFSIZE * sizeof(*string))
    {
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    ret = InternetTimeFromSystemTimeW( time, format, stringW, sizeof(stringW) );
    if (ret) WideCharToMultiByte( CP_ACP, 0, stringW, -1, string, size, NULL, NULL );

    return ret;
}

/***********************************************************************
 *           InternetTimeFromSystemTimeW (WININET.@)
 */
BOOL WINAPI InternetTimeFromSystemTimeW( const SYSTEMTIME* time, DWORD format, LPWSTR string, DWORD size )
{
    static const WCHAR date[] =
        { '%','s',',',' ','%','0','2','d',' ','%','s',' ','%','4','d',' ','%','0',
          '2','d',':','%','0','2','d',':','%','0','2','d',' ','G','M','T', 0 };

    TRACE( "%p 0x%08x %p 0x%08x\n", time, format, string, size );

    if (!time || !string || format != INTERNET_RFC1123_FORMAT)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (size < INTERNET_RFC1123_BUFSIZE * sizeof(*string))
    {
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    sprintfW( string, date,
              WININET_wkday[time->wDayOfWeek],
              time->wDay,
              WININET_month[time->wMonth - 1],
              time->wYear,
              time->wHour,
              time->wMinute,
              time->wSecond );

    return TRUE;
}

/***********************************************************************
 *           InternetTimeToSystemTimeA (WININET.@)
 */
BOOL WINAPI InternetTimeToSystemTimeA( LPCSTR string, SYSTEMTIME* time, DWORD reserved )
{
    BOOL ret = FALSE;
    WCHAR *stringW;

    TRACE( "%s %p 0x%08x\n", debugstr_a(string), time, reserved );

    stringW = heap_strdupAtoW(string);
    if (stringW)
    {
        ret = InternetTimeToSystemTimeW( stringW, time, reserved );
        heap_free( stringW );
    }
    return ret;
}

/***********************************************************************
 *           InternetTimeToSystemTimeW (WININET.@)
 */
BOOL WINAPI InternetTimeToSystemTimeW( LPCWSTR string, SYSTEMTIME* time, DWORD reserved )
{
    unsigned int i;
    const WCHAR *s = string;
    WCHAR       *end;

    TRACE( "%s %p 0x%08x\n", debugstr_w(string), time, reserved );

    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( WININET_wkday[i][0] ) == toupperW( s[0] ) &&
            toupperW( WININET_wkday[i][1] ) == toupperW( s[1] ) &&
            toupperW( WININET_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( WININET_month[i][0]) == toupperW( s[0] ) &&
            toupperW( WININET_month[i][1]) == toupperW( s[1] ) &&
            toupperW( WININET_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;
}

/***********************************************************************
 *	InternetCheckConnectionW (WININET.@)
 *
 * Pings a requested host to check internet connection
 *
 * RETURNS
 *   TRUE on success and FALSE on failure. If a failure then
 *   ERROR_NOT_CONNECTED is placed into GetLastError
 *
 */
BOOL WINAPI InternetCheckConnectionW( LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwReserved )
{
/*
 * this is a kludge which runs the resident ping program and reads the output.
 *
 * Anyone have a better idea?
 */

  BOOL   rc = FALSE;
  static const CHAR ping[] = "ping -c 1 ";
  static const CHAR redirect[] = " >/dev/null 2>/dev/null";
  WCHAR *host;
  DWORD len, host_len;
  INTERNET_PORT port;
  int status = -1;

  FIXME("(%s %x %x)\n", debugstr_w(lpszUrl), dwFlags, dwReserved);

  /*
   * Crack or set the Address
   */
  if (lpszUrl == NULL)
  {
     /*
      * According to the doc we are supposed to use the ip for the next
      * server in the WnInet internal server database. I have
      * no idea what that is or how to get it.
      *
      * So someone needs to implement this.
      */
     FIXME("Unimplemented with URL of NULL\n");
     return TRUE;
  }
  else
  {
     URL_COMPONENTSW components = {sizeof(components)};

     components.dwHostNameLength = 1;

     if (!InternetCrackUrlW(lpszUrl,0,0,&components))
       goto End;

     host = components.lpszHostName;
     host_len = components.dwHostNameLength;
     port = components.nPort;
     TRACE("host name: %s port: %d\n",debugstr_wn(host, host_len), port);
  }

  if (dwFlags & FLAG_ICC_FORCE_CONNECTION)
  {
      struct sockaddr_storage saddr;
      socklen_t sa_len = sizeof(saddr);
      WCHAR *host_z;
      int fd;
      BOOL b;

      host_z = heap_strndupW(host, host_len);
      if (!host_z)
          return FALSE;

      b = GetAddress(host_z, port, (struct sockaddr *)&saddr, &sa_len, NULL);
      heap_free(host_z);
      if(!b)
          goto End;
      init_winsock();
      fd = socket(saddr.ss_family, SOCK_STREAM, 0);
      if (fd != -1)
      {
          if (connect(fd, (struct sockaddr *)&saddr, sa_len) == 0)
              rc = TRUE;
          closesocket(fd);
      }
  }
  else
  {
      /*
       * Build our ping command
       */
      char *command;

      len = WideCharToMultiByte(CP_UNIXCP, 0, host, host_len, NULL, 0, NULL, NULL);
      command = heap_alloc(strlen(ping)+len+strlen(redirect)+1);
      strcpy(command, ping);
      WideCharToMultiByte(CP_UNIXCP, 0, host, host_len, command+sizeof(ping)-1, len, NULL, NULL);
      strcpy(command+sizeof(ping)-1+len, redirect);

      TRACE("Ping command is : %s\n",command);

      status = system(command);
      heap_free( command );

      TRACE("Ping returned a code of %i\n",status);

      /* Ping return code of 0 indicates success */
      if (status == 0)
         rc = TRUE;
  }

End:
  if (rc == FALSE)
    INTERNET_SetLastError(ERROR_NOT_CONNECTED);

  return rc;
}


/***********************************************************************
 *	InternetCheckConnectionA (WININET.@)
 *
 * Pings a requested host to check internet connection
 *
 * RETURNS
 *   TRUE on success and FALSE on failure. If a failure then
 *   ERROR_NOT_CONNECTED is placed into GetLastError
 *
 */
BOOL WINAPI InternetCheckConnectionA(LPCSTR lpszUrl, DWORD dwFlags, DWORD dwReserved)
{
    WCHAR *url = NULL;
    BOOL rc;

    if(lpszUrl) {
        url = heap_strdupAtoW(lpszUrl);
        if(!url)
            return FALSE;
    }

    rc = InternetCheckConnectionW(url, dwFlags, dwReserved);

    heap_free(url);
    return rc;
}


/**********************************************************
 *	INTERNET_InternetOpenUrlW (internal)
 *
 * Opens an URL
 *
 * RETURNS
 *   handle of connection or NULL on failure
 */
static HINTERNET INTERNET_InternetOpenUrlW(appinfo_t *hIC, LPCWSTR lpszUrl,
    LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext)
{
    URL_COMPONENTSW urlComponents;
    WCHAR protocol[INTERNET_MAX_SCHEME_LENGTH];
    WCHAR hostName[INTERNET_MAX_HOST_NAME_LENGTH];
    WCHAR userName[INTERNET_MAX_USER_NAME_LENGTH];
    WCHAR password[INTERNET_MAX_PASSWORD_LENGTH];
    WCHAR path[INTERNET_MAX_PATH_LENGTH];
    WCHAR extra[1024];
    HINTERNET client = NULL, client1 = NULL;
    DWORD res;
    
    TRACE("(%p, %s, %s, %08x, %08x, %08lx)\n", hIC, debugstr_w(lpszUrl), debugstr_w(lpszHeaders),
	  dwHeadersLength, dwFlags, dwContext);
    
    urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
    urlComponents.lpszScheme = protocol;
    urlComponents.dwSchemeLength = INTERNET_MAX_SCHEME_LENGTH;
    urlComponents.lpszHostName = hostName;
    urlComponents.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH;
    urlComponents.lpszUserName = userName;
    urlComponents.dwUserNameLength = INTERNET_MAX_USER_NAME_LENGTH;
    urlComponents.lpszPassword = password;
    urlComponents.dwPasswordLength = INTERNET_MAX_PASSWORD_LENGTH;
    urlComponents.lpszUrlPath = path;
    urlComponents.dwUrlPathLength = INTERNET_MAX_PATH_LENGTH;
    urlComponents.lpszExtraInfo = extra;
    urlComponents.dwExtraInfoLength = 1024;
    if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents))
	return NULL;
    switch(urlComponents.nScheme) {
    case INTERNET_SCHEME_FTP:
	if(urlComponents.nPort == 0)
	    urlComponents.nPort = INTERNET_DEFAULT_FTP_PORT;
	client = FTP_Connect(hIC, hostName, urlComponents.nPort,
			     userName, password, dwFlags, dwContext, INET_OPENURL);
	if(client == NULL)
	    break;
	client1 = FtpOpenFileW(client, path, GENERIC_READ, dwFlags, dwContext);
	if(client1 == NULL) {
	    InternetCloseHandle(client);
	    break;
	}
	break;
	
    case INTERNET_SCHEME_HTTP:
    case INTERNET_SCHEME_HTTPS: {
	static const WCHAR szStars[] = { '*','/','*', 0 };
	LPCWSTR accept[2] = { szStars, NULL };
	if(urlComponents.nPort == 0) {
	    if(urlComponents.nScheme == INTERNET_SCHEME_HTTP)
		urlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT;
	    else
		urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
	}
        if (urlComponents.nScheme == INTERNET_SCHEME_HTTPS) dwFlags |= INTERNET_FLAG_SECURE;

        /* FIXME: should use pointers, not handles, as handles are not thread-safe */
	res = HTTP_Connect(hIC, hostName, urlComponents.nPort,
                           userName, password, dwFlags, dwContext, INET_OPENURL, &client);
        if(res != ERROR_SUCCESS) {
            INTERNET_SetLastError(res);
	    break;
        }

	if (urlComponents.dwExtraInfoLength) {
		WCHAR *path_extra;
		DWORD len = urlComponents.dwUrlPathLength + urlComponents.dwExtraInfoLength + 1;

		if (!(path_extra = heap_alloc(len * sizeof(WCHAR))))
		{
			InternetCloseHandle(client);
			break;
		}
		strcpyW(path_extra, urlComponents.lpszUrlPath);
		strcatW(path_extra, urlComponents.lpszExtraInfo);
		client1 = HttpOpenRequestW(client, NULL, path_extra, NULL, NULL, accept, dwFlags, dwContext);
		heap_free(path_extra);
	}
	else
		client1 = HttpOpenRequestW(client, NULL, path, NULL, NULL, accept, dwFlags, dwContext);

	if(client1 == NULL) {
	    InternetCloseHandle(client);
	    break;
	}
	HttpAddRequestHeadersW(client1, lpszHeaders, dwHeadersLength, HTTP_ADDREQ_FLAG_ADD);
	if (!HttpSendRequestW(client1, NULL, 0, NULL, 0) &&
            GetLastError() != ERROR_IO_PENDING) {
	    InternetCloseHandle(client1);
	    client1 = NULL;
	    break;
	}
    }
    case INTERNET_SCHEME_GOPHER:
	/* gopher doesn't seem to be implemented in wine, but it's supposed
	 * to be supported by InternetOpenUrlA. */
    default:
        SetLastError(ERROR_INTERNET_UNRECOGNIZED_SCHEME);
	break;
    }

    TRACE(" %p <--\n", client1);
    
    return client1;
}

/**********************************************************
 *	InternetOpenUrlW (WININET.@)
 *
 * Opens an URL
 *
 * RETURNS
 *   handle of connection or NULL on failure
 */
typedef struct {
    task_header_t hdr;
    WCHAR *url;
    WCHAR *headers;
    DWORD headers_len;
    DWORD flags;
    DWORD_PTR context;
} open_url_task_t;

static void AsyncInternetOpenUrlProc(task_header_t *hdr)
{
    open_url_task_t *task = (open_url_task_t*)hdr;

    TRACE("%p\n", task->hdr.hdr);

    INTERNET_InternetOpenUrlW((appinfo_t*)task->hdr.hdr, task->url, task->headers,
            task->headers_len, task->flags, task->context);
    heap_free(task->url);
    heap_free(task->headers);
}

HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
    LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext)
{
    HINTERNET ret = NULL;
    appinfo_t *hIC = NULL;

    if (TRACE_ON(wininet)) {
	TRACE("(%p, %s, %s, %08x, %08x, %08lx)\n", hInternet, debugstr_w(lpszUrl), debugstr_w(lpszHeaders),
	      dwHeadersLength, dwFlags, dwContext);
	TRACE("  flags :");
	dump_INTERNET_FLAGS(dwFlags);
    }

    if (!lpszUrl)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        goto lend;
    }

    hIC = (appinfo_t*)get_handle_object( hInternet );
    if (NULL == hIC ||  hIC->hdr.htype != WH_HINIT) {
	SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
 	goto lend;
    }
    
    if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) {
	open_url_task_t *task;

        task = alloc_async_task(&hIC->hdr, AsyncInternetOpenUrlProc, sizeof(*task));
        task->url = heap_strdupW(lpszUrl);
        task->headers = heap_strdupW(lpszHeaders);
        task->headers_len = dwHeadersLength;
        task->flags = dwFlags;
        task->context = dwContext;
	
        INTERNET_AsyncCall(&task->hdr);
        SetLastError(ERROR_IO_PENDING);
    } else {
	ret = INTERNET_InternetOpenUrlW(hIC, lpszUrl, lpszHeaders, dwHeadersLength, dwFlags, dwContext);
    }
    
  lend:
    if( hIC )
        WININET_Release( &hIC->hdr );
    TRACE(" %p <--\n", ret);
    
    return ret;
}

/**********************************************************
 *	InternetOpenUrlA (WININET.@)
 *
 * Opens an URL
 *
 * RETURNS
 *   handle of connection or NULL on failure
 */
HINTERNET WINAPI InternetOpenUrlA(HINTERNET hInternet, LPCSTR lpszUrl,
    LPCSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext)
{
    HINTERNET rc = NULL;
    LPWSTR szUrl = NULL;
    WCHAR *headers = NULL;

    TRACE("\n");

    if(lpszUrl) {
        szUrl = heap_strdupAtoW(lpszUrl);
        if(!szUrl)
            return NULL;
    }

    if(lpszHeaders) {
        headers = heap_strndupAtoW(lpszHeaders, dwHeadersLength, &dwHeadersLength);
        if(!headers) {
            heap_free(szUrl);
            return NULL;
        }
    }
    
    rc = InternetOpenUrlW(hInternet, szUrl, headers, dwHeadersLength, dwFlags, dwContext);

    heap_free(szUrl);
    heap_free(headers);
    return rc;
}


static LPWITHREADERROR INTERNET_AllocThreadError(void)
{
    LPWITHREADERROR lpwite = heap_alloc(sizeof(*lpwite));

    if (lpwite)
    {
        lpwite->dwError = 0;
        lpwite->response[0] = '\0';
    }

    if (!TlsSetValue(g_dwTlsErrIndex, lpwite))
    {
        heap_free(lpwite);
        return NULL;
    }
    return lpwite;
}


/***********************************************************************
 *           INTERNET_SetLastError (internal)
 *
 * Set last thread specific error
 *
 * RETURNS
 *
 */
void INTERNET_SetLastError(DWORD dwError)
{
    LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);

    if (!lpwite)
        lpwite = INTERNET_AllocThreadError();

    SetLastError(dwError);
    if(lpwite)
        lpwite->dwError = dwError;
}


/***********************************************************************
 *           INTERNET_GetLastError (internal)
 *
 * Get last thread specific error
 *
 * RETURNS
 *
 */
DWORD INTERNET_GetLastError(void)
{
    LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
    if (!lpwite) return 0;
    /* TlsGetValue clears last error, so set it again here */
    SetLastError(lpwite->dwError);
    return lpwite->dwError;
}


/***********************************************************************
 *           INTERNET_WorkerThreadFunc (internal)
 *
 * Worker thread execution function
 *
 * RETURNS
 *
 */
static DWORD CALLBACK INTERNET_WorkerThreadFunc(LPVOID lpvParam)
{
    task_header_t *task = lpvParam;

    TRACE("\n");

    task->proc(task);
    WININET_Release(task->hdr);
    heap_free(task);

    if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
    {
        heap_free(TlsGetValue(g_dwTlsErrIndex));
        TlsSetValue(g_dwTlsErrIndex, NULL);
    }
    return TRUE;
}

void *alloc_async_task(object_header_t *hdr, async_task_proc_t proc, size_t size)
{
    task_header_t *task;

    task = heap_alloc(size);
    if(!task)
        return NULL;

    task->hdr = WININET_AddRef(hdr);
    task->proc = proc;
    return task;
}

/***********************************************************************
 *           INTERNET_AsyncCall (internal)
 *
 * Retrieves work request from queue
 *
 * RETURNS
 *
 */
DWORD INTERNET_AsyncCall(task_header_t *task)
{
    BOOL bSuccess;

    TRACE("\n");

    bSuccess = QueueUserWorkItem(INTERNET_WorkerThreadFunc, task, WT_EXECUTELONGFUNCTION);
    if (!bSuccess)
    {
        heap_free(task);
        return ERROR_INTERNET_ASYNC_THREAD_FAILED;
    }
    return ERROR_SUCCESS;
}


/***********************************************************************
 *          INTERNET_GetResponseBuffer  (internal)
 *
 * RETURNS
 *
 */
LPSTR INTERNET_GetResponseBuffer(void)
{
    LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
    if (!lpwite)
        lpwite = INTERNET_AllocThreadError();
    TRACE("\n");
    return lpwite->response;
}

/**********************************************************
 *	InternetQueryDataAvailable (WININET.@)
 *
 * Determines how much data is available to be read.
 *
 * RETURNS
 *   TRUE on success, FALSE if an error occurred. If
 *   INTERNET_FLAG_ASYNC was specified in InternetOpen, and
 *   no data is presently available, FALSE is returned with
 *   the last error ERROR_IO_PENDING; a callback with status
 *   INTERNET_STATUS_REQUEST_COMPLETE will be sent when more
 *   data is available.
 */
BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
                                LPDWORD lpdwNumberOfBytesAvailable,
                                DWORD dwFlags, DWORD_PTR dwContext)
{
    object_header_t *hdr;
    DWORD res;

    TRACE("(%p %p %x %lx)\n", hFile, lpdwNumberOfBytesAvailable, dwFlags, dwContext);

    hdr = get_handle_object( hFile );
    if (!hdr) {
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if(hdr->vtbl->QueryDataAvailable) {
        res = hdr->vtbl->QueryDataAvailable(hdr, lpdwNumberOfBytesAvailable, dwFlags, dwContext);
    }else {
        WARN("wrong handle\n");
        res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
    }

    WININET_Release(hdr);

    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}

DWORD create_req_file(const WCHAR *file_name, req_file_t **ret)
{
    req_file_t *req_file;

    req_file = heap_alloc_zero(sizeof(*req_file));
    if(!req_file)
        return ERROR_NOT_ENOUGH_MEMORY;

    req_file->ref = 1;

    req_file->file_name = heap_strdupW(file_name);
    if(!req_file->file_name) {
        heap_free(req_file);
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    req_file->file_handle = CreateFileW(req_file->file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
              NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if(req_file->file_handle == INVALID_HANDLE_VALUE) {
        req_file_release(req_file);
        return GetLastError();
    }

    *ret = req_file;
    return ERROR_SUCCESS;
}

void req_file_release(req_file_t *req_file)
{
    if(InterlockedDecrement(&req_file->ref))
        return;

    if(!req_file->is_committed)
        DeleteFileW(req_file->file_name);
    if(req_file->file_handle && req_file->file_handle != INVALID_HANDLE_VALUE)
        CloseHandle(req_file->file_handle);
    heap_free(req_file->file_name);
    heap_free(req_file);
}

/***********************************************************************
 *      InternetLockRequestFile (WININET.@)
 */
BOOL WINAPI InternetLockRequestFile(HINTERNET hInternet, HANDLE *lphLockReqHandle)
{
    req_file_t *req_file = NULL;
    object_header_t *hdr;
    DWORD res;

    TRACE("(%p %p)\n", hInternet, lphLockReqHandle);

    hdr = get_handle_object(hInternet);
    if (!hdr) {
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if(hdr->vtbl->LockRequestFile) {
        res = hdr->vtbl->LockRequestFile(hdr, &req_file);
    }else {
        WARN("wrong handle\n");
        res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
    }

    WININET_Release(hdr);

    *lphLockReqHandle = req_file;
    if(res != ERROR_SUCCESS)
        SetLastError(res);
    return res == ERROR_SUCCESS;
}

BOOL WINAPI InternetUnlockRequestFile(HANDLE hLockHandle)
{
    TRACE("(%p)\n", hLockHandle);

    req_file_release(hLockHandle);
    return TRUE;
}


/***********************************************************************
 *      InternetAutodial (WININET.@)
 *
 * On windows this function is supposed to dial the default internet
 * connection. We don't want to have Wine dial out to the internet so
 * we return TRUE by default. It might be nice to check if we are connected.
 *
 * RETURNS
 *   TRUE on success
 *   FALSE on failure
 *
 */
BOOL WINAPI InternetAutodial(DWORD dwFlags, HWND hwndParent)
{
    FIXME("STUB\n");

    /* Tell that we are connected to the internet. */
    return TRUE;
}

/***********************************************************************
 *      InternetAutodialHangup (WININET.@)
 *
 * Hangs up a connection made with InternetAutodial
 *
 * PARAM
 *    dwReserved
 * RETURNS
 *   TRUE on success
 *   FALSE on failure
 *
 */
BOOL WINAPI InternetAutodialHangup(DWORD dwReserved)
{
    FIXME("STUB\n");

    /* we didn't dial, we don't disconnect */
    return TRUE;
}

/***********************************************************************
 *      InternetCombineUrlA (WININET.@)
 *
 * Combine a base URL with a relative URL
 *
 * RETURNS
 *   TRUE on success
 *   FALSE on failure
 *
 */

BOOL WINAPI InternetCombineUrlA(LPCSTR lpszBaseUrl, LPCSTR lpszRelativeUrl,
                                LPSTR lpszBuffer, LPDWORD lpdwBufferLength,
                                DWORD dwFlags)
{
    HRESULT hr=S_OK;

    TRACE("(%s, %s, %p, %p, 0x%08x)\n", debugstr_a(lpszBaseUrl), debugstr_a(lpszRelativeUrl), lpszBuffer, lpdwBufferLength, dwFlags);

    /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
    dwFlags ^= ICU_NO_ENCODE;
    hr=UrlCombineA(lpszBaseUrl,lpszRelativeUrl,lpszBuffer,lpdwBufferLength,dwFlags);

    return (hr==S_OK);
}

/***********************************************************************
 *      InternetCombineUrlW (WININET.@)
 *
 * Combine a base URL with a relative URL
 *
 * RETURNS
 *   TRUE on success
 *   FALSE on failure
 *
 */

BOOL WINAPI InternetCombineUrlW(LPCWSTR lpszBaseUrl, LPCWSTR lpszRelativeUrl,
                                LPWSTR lpszBuffer, LPDWORD lpdwBufferLength,
                                DWORD dwFlags)
{
    HRESULT hr=S_OK;

    TRACE("(%s, %s, %p, %p, 0x%08x)\n", debugstr_w(lpszBaseUrl), debugstr_w(lpszRelativeUrl), lpszBuffer, lpdwBufferLength, dwFlags);

    /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
    dwFlags ^= ICU_NO_ENCODE;
    hr=UrlCombineW(lpszBaseUrl,lpszRelativeUrl,lpszBuffer,lpdwBufferLength,dwFlags);

    return (hr==S_OK);
}

/* max port num is 65535 => 5 digits */
#define MAX_WORD_DIGITS 5

#define URL_GET_COMP_LENGTH(url, component) ((url)->dw##component##Length ? \
    (url)->dw##component##Length : strlenW((url)->lpsz##component))
#define URL_GET_COMP_LENGTHA(url, component) ((url)->dw##component##Length ? \
    (url)->dw##component##Length : strlen((url)->lpsz##component))

static BOOL url_uses_default_port(INTERNET_SCHEME nScheme, INTERNET_PORT nPort)
{
    if ((nScheme == INTERNET_SCHEME_HTTP) &&
        (nPort == INTERNET_DEFAULT_HTTP_PORT))
        return TRUE;
    if ((nScheme == INTERNET_SCHEME_HTTPS) &&
        (nPort == INTERNET_DEFAULT_HTTPS_PORT))
        return TRUE;
    if ((nScheme == INTERNET_SCHEME_FTP) &&
        (nPort == INTERNET_DEFAULT_FTP_PORT))
        return TRUE;
    if ((nScheme == INTERNET_SCHEME_GOPHER) &&
        (nPort == INTERNET_DEFAULT_GOPHER_PORT))
        return TRUE;

    if (nPort == INTERNET_INVALID_PORT_NUMBER)
        return TRUE;

    return FALSE;
}

/* opaque urls do not fit into the standard url hierarchy and don't have
 * two following slashes */
static inline BOOL scheme_is_opaque(INTERNET_SCHEME nScheme)
{
    return (nScheme != INTERNET_SCHEME_FTP) &&
           (nScheme != INTERNET_SCHEME_GOPHER) &&
           (nScheme != INTERNET_SCHEME_HTTP) &&
           (nScheme != INTERNET_SCHEME_HTTPS) &&
           (nScheme != INTERNET_SCHEME_FILE);
}

static LPCWSTR INTERNET_GetSchemeString(INTERNET_SCHEME scheme)
{
    int index;
    if (scheme < INTERNET_SCHEME_FIRST)
        return NULL;
    index = scheme - INTERNET_SCHEME_FIRST;
    if (index >= sizeof(url_schemes)/sizeof(url_schemes[0]))
        return NULL;
    return (LPCWSTR)url_schemes[index];
}

/* we can calculate using ansi strings because we're just
 * calculating string length, not size
 */
static BOOL calc_url_length(LPURL_COMPONENTSW lpUrlComponents,
                            LPDWORD lpdwUrlLength)
{
    INTERNET_SCHEME nScheme;

    *lpdwUrlLength = 0;

    if (lpUrlComponents->lpszScheme)
    {
        DWORD dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, Scheme);
        *lpdwUrlLength += dwLen;
        nScheme = GetInternetSchemeW(lpUrlComponents->lpszScheme, dwLen);
    }
    else
    {
        LPCWSTR scheme;

        nScheme = lpUrlComponents->nScheme;

        if (nScheme == INTERNET_SCHEME_DEFAULT)
            nScheme = INTERNET_SCHEME_HTTP;
        scheme = INTERNET_GetSchemeString(nScheme);
        *lpdwUrlLength += strlenW(scheme);
    }

    (*lpdwUrlLength)++; /* ':' */
    if (!scheme_is_opaque(nScheme) || lpUrlComponents->lpszHostName)
        *lpdwUrlLength += strlen("//");

    if (lpUrlComponents->lpszUserName)
    {
        *lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, UserName);
        *lpdwUrlLength += strlen("@");
    }
    else
    {
        if (lpUrlComponents->lpszPassword)
        {
            INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }
    }

    if (lpUrlComponents->lpszPassword)
    {
        *lpdwUrlLength += strlen(":");
        *lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, Password);
    }

    if (lpUrlComponents->lpszHostName)
    {
        *lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, HostName);

        if (!url_uses_default_port(nScheme, lpUrlComponents->nPort))
        {
            char szPort[MAX_WORD_DIGITS+1];

            sprintf(szPort, "%d", lpUrlComponents->nPort);
            *lpdwUrlLength += strlen(szPort);
            *lpdwUrlLength += strlen(":");
        }

        if (lpUrlComponents->lpszUrlPath && *lpUrlComponents->lpszUrlPath != '/')
            (*lpdwUrlLength)++; /* '/' */
    }

    if (lpUrlComponents->lpszUrlPath)
        *lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath);

    if (lpUrlComponents->lpszExtraInfo)
        *lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, ExtraInfo);

    return TRUE;
}

static void convert_urlcomp_atow(LPURL_COMPONENTSA lpUrlComponents, LPURL_COMPONENTSW urlCompW)
{
    INT len;

    ZeroMemory(urlCompW, sizeof(URL_COMPONENTSW));

    urlCompW->dwStructSize = sizeof(URL_COMPONENTSW);
    urlCompW->dwSchemeLength = lpUrlComponents->dwSchemeLength;
    urlCompW->nScheme = lpUrlComponents->nScheme;
    urlCompW->dwHostNameLength = lpUrlComponents->dwHostNameLength;
    urlCompW->nPort = lpUrlComponents->nPort;
    urlCompW->dwUserNameLength = lpUrlComponents->dwUserNameLength;
    urlCompW->dwPasswordLength = lpUrlComponents->dwPasswordLength;
    urlCompW->dwUrlPathLength = lpUrlComponents->dwUrlPathLength;
    urlCompW->dwExtraInfoLength = lpUrlComponents->dwExtraInfoLength;

    if (lpUrlComponents->lpszScheme)
    {
        len = URL_GET_COMP_LENGTHA(lpUrlComponents, Scheme) + 1;
        urlCompW->lpszScheme = heap_alloc(len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszScheme,
                            -1, urlCompW->lpszScheme, len);
    }

    if (lpUrlComponents->lpszHostName)
    {
        len = URL_GET_COMP_LENGTHA(lpUrlComponents, HostName) + 1;
        urlCompW->lpszHostName = heap_alloc(len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszHostName,
                            -1, urlCompW->lpszHostName, len);
    }

    if (lpUrlComponents->lpszUserName)
    {
        len = URL_GET_COMP_LENGTHA(lpUrlComponents, UserName) + 1;
        urlCompW->lpszUserName = heap_alloc(len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszUserName,
                            -1, urlCompW->lpszUserName, len);
    }

    if (lpUrlComponents->lpszPassword)
    {
        len = URL_GET_COMP_LENGTHA(lpUrlComponents, Password) + 1;
        urlCompW->lpszPassword = heap_alloc(len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszPassword,
                            -1, urlCompW->lpszPassword, len);
    }

    if (lpUrlComponents->lpszUrlPath)
    {
        len = URL_GET_COMP_LENGTHA(lpUrlComponents, UrlPath) + 1;
        urlCompW->lpszUrlPath = heap_alloc(len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszUrlPath,
                            -1, urlCompW->lpszUrlPath, len);
    }

    if (lpUrlComponents->lpszExtraInfo)
    {
        len = URL_GET_COMP_LENGTHA(lpUrlComponents, ExtraInfo) + 1;
        urlCompW->lpszExtraInfo = heap_alloc(len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszExtraInfo,
                            -1, urlCompW->lpszExtraInfo, len);
    }
}

/***********************************************************************
 *      InternetCreateUrlA (WININET.@)
 *
 * See InternetCreateUrlW.
 */
BOOL WINAPI InternetCreateUrlA(LPURL_COMPONENTSA lpUrlComponents, DWORD dwFlags,
                               LPSTR lpszUrl, LPDWORD lpdwUrlLength)
{
    BOOL ret;
    LPWSTR urlW = NULL;
    URL_COMPONENTSW urlCompW;

    TRACE("(%p,%d,%p,%p)\n", lpUrlComponents, dwFlags, lpszUrl, lpdwUrlLength);

    if (!lpUrlComponents || lpUrlComponents->dwStructSize != sizeof(URL_COMPONENTSW) || !lpdwUrlLength)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    convert_urlcomp_atow(lpUrlComponents, &urlCompW);

    if (lpszUrl)
        urlW = heap_alloc(*lpdwUrlLength * sizeof(WCHAR));

    ret = InternetCreateUrlW(&urlCompW, dwFlags, urlW, lpdwUrlLength);

    if (!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
        *lpdwUrlLength /= sizeof(WCHAR);

    /* on success, lpdwUrlLength points to the size of urlW in WCHARS
    * minus one, so add one to leave room for NULL terminator
    */
    if (ret)
        WideCharToMultiByte(CP_ACP, 0, urlW, -1, lpszUrl, *lpdwUrlLength + 1, NULL, NULL);

    heap_free(urlCompW.lpszScheme);
    heap_free(urlCompW.lpszHostName);
    heap_free(urlCompW.lpszUserName);
    heap_free(urlCompW.lpszPassword);
    heap_free(urlCompW.lpszUrlPath);
    heap_free(urlCompW.lpszExtraInfo);
    heap_free(urlW);
    return ret;
}

/***********************************************************************
 *      InternetCreateUrlW (WININET.@)
 *
 * Creates a URL from its component parts.
 *
 * PARAMS
 *  lpUrlComponents [I] URL Components.
 *  dwFlags         [I] Flags. See notes.
 *  lpszUrl         [I] Buffer in which to store the created URL.
 *  lpdwUrlLength   [I/O] On input, the length of the buffer pointed to by
 *                        lpszUrl in characters. On output, the number of bytes
 *                        required to store the URL including terminator.
 *
 * NOTES
 *
 * The dwFlags parameter can be zero or more of the following:
 *|ICU_ESCAPE - Generates escape sequences for unsafe characters in the path and extra info of the URL.
 *
 * RETURNS
 *   TRUE on success
 *   FALSE on failure
 *
 */
BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags,
                               LPWSTR lpszUrl, LPDWORD lpdwUrlLength)
{
    DWORD dwLen;
    INTERNET_SCHEME nScheme;

    static const WCHAR slashSlashW[] = {'/','/'};
    static const WCHAR fmtW[] = {'%','u',0};

    TRACE("(%p,%d,%p,%p)\n", lpUrlComponents, dwFlags, lpszUrl, lpdwUrlLength);

    if (!lpUrlComponents || lpUrlComponents->dwStructSize != sizeof(URL_COMPONENTSW) || !lpdwUrlLength)
    {
        INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (!calc_url_length(lpUrlComponents, &dwLen))
        return FALSE;

    if (!lpszUrl || *lpdwUrlLength < dwLen)
    {
        *lpdwUrlLength = (dwLen + 1) * sizeof(WCHAR);
        INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    *lpdwUrlLength = dwLen;
    lpszUrl[0] = 0x00;

    dwLen = 0;

    if (lpUrlComponents->lpszScheme)
    {
        dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, Scheme);
        memcpy(lpszUrl, lpUrlComponents->lpszScheme, dwLen * sizeof(WCHAR));
        lpszUrl += dwLen;

        nScheme = GetInternetSchemeW(lpUrlComponents->lpszScheme, dwLen);
    }
    else
    {
        LPCWSTR scheme;
        nScheme = lpUrlComponents->nScheme;

        if (nScheme == INTERNET_SCHEME_DEFAULT)
            nScheme = INTERNET_SCHEME_HTTP;

        scheme = INTERNET_GetSchemeString(nScheme);
        dwLen = strlenW(scheme);
        memcpy(lpszUrl, scheme, dwLen * sizeof(WCHAR));
        lpszUrl += dwLen;
    }

    /* all schemes are followed by at least a colon */
    *lpszUrl = ':';
    lpszUrl++;

    if (!scheme_is_opaque(nScheme) || lpUrlComponents->lpszHostName)
    {
        memcpy(lpszUrl, slashSlashW, sizeof(slashSlashW));
        lpszUrl += sizeof(slashSlashW)/sizeof(slashSlashW[0]);
    }

    if (lpUrlComponents->lpszUserName)
    {
        dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, UserName);
        memcpy(lpszUrl, lpUrlComponents->lpszUserName, dwLen * sizeof(WCHAR));
        lpszUrl += dwLen;

        if (lpUrlComponents->lpszPassword)
        {
            *lpszUrl = ':';
            lpszUrl++;

            dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, Password);
            memcpy(lpszUrl, lpUrlComponents->lpszPassword, dwLen * sizeof(WCHAR));
            lpszUrl += dwLen;
        }

        *lpszUrl = '@';
        lpszUrl++;
    }

    if (lpUrlComponents->lpszHostName)
    {
        dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, HostName);
        memcpy(lpszUrl, lpUrlComponents->lpszHostName, dwLen * sizeof(WCHAR));
        lpszUrl += dwLen;

        if (!url_uses_default_port(nScheme, lpUrlComponents->nPort))
        {
            WCHAR szPort[MAX_WORD_DIGITS+1];

            sprintfW(szPort, fmtW, lpUrlComponents->nPort);
            *lpszUrl = ':';
            lpszUrl++;
            dwLen = strlenW(szPort);
            memcpy(lpszUrl, szPort, dwLen * sizeof(WCHAR));
            lpszUrl += dwLen;
        }

        /* add slash between hostname and path if necessary */
        if (lpUrlComponents->lpszUrlPath && *lpUrlComponents->lpszUrlPath != '/')
        {
            *lpszUrl = '/';
            lpszUrl++;
        }
    }

    if (lpUrlComponents->lpszUrlPath)
    {
        dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath);
        memcpy(lpszUrl, lpUrlComponents->lpszUrlPath, dwLen * sizeof(WCHAR));
        lpszUrl += dwLen;
    }

    if (lpUrlComponents->lpszExtraInfo)
    {
        dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, ExtraInfo);
        memcpy(lpszUrl, lpUrlComponents->lpszExtraInfo, dwLen * sizeof(WCHAR));
        lpszUrl += dwLen;
    }

    *lpszUrl = '\0';

    return TRUE;
}

/***********************************************************************
 *      InternetConfirmZoneCrossingA (WININET.@)
 *
 */
DWORD WINAPI InternetConfirmZoneCrossingA( HWND hWnd, LPSTR szUrlPrev, LPSTR szUrlNew, BOOL bPost )
{
    FIXME("(%p, %s, %s, %x) stub\n", hWnd, debugstr_a(szUrlPrev), debugstr_a(szUrlNew), bPost);
    return ERROR_SUCCESS;
}

/***********************************************************************
 *      InternetConfirmZoneCrossingW (WININET.@)
 *
 */
DWORD WINAPI InternetConfirmZoneCrossingW( HWND hWnd, LPWSTR szUrlPrev, LPWSTR szUrlNew, BOOL bPost )
{
    FIXME("(%p, %s, %s, %x) stub\n", hWnd, debugstr_w(szUrlPrev), debugstr_w(szUrlNew), bPost);
    return ERROR_SUCCESS;
}

static DWORD zone_preference = 3;

/***********************************************************************
 *      PrivacySetZonePreferenceW (WININET.@)
 */
DWORD WINAPI PrivacySetZonePreferenceW( DWORD zone, DWORD type, DWORD template, LPCWSTR preference )
{
    FIXME( "%x %x %x %s: stub\n", zone, type, template, debugstr_w(preference) );

    zone_preference = template;
    return 0;
}

/***********************************************************************
 *      PrivacyGetZonePreferenceW (WININET.@)
 */
DWORD WINAPI PrivacyGetZonePreferenceW( DWORD zone, DWORD type, LPDWORD template,
                                        LPWSTR preference, LPDWORD length )
{
    FIXME( "%x %x %p %p %p: stub\n", zone, type, template, preference, length );

    if (template) *template = zone_preference;
    return 0;
}

/***********************************************************************
 *      InternetGetSecurityInfoByURLA (WININET.@)
 */
BOOL WINAPI InternetGetSecurityInfoByURLA(LPSTR lpszURL, PCCERT_CHAIN_CONTEXT *ppCertChain, DWORD *pdwSecureFlags)
{
    WCHAR *url;
    BOOL res;

    TRACE("(%s %p %p)\n", debugstr_a(lpszURL), ppCertChain, pdwSecureFlags);

    url = heap_strdupAtoW(lpszURL);
    if(!url)
        return FALSE;

    res = InternetGetSecurityInfoByURLW(url, ppCertChain, pdwSecureFlags);
    heap_free(url);
    return res;
}

/***********************************************************************
 *      InternetGetSecurityInfoByURLW (WININET.@)
 */
BOOL WINAPI InternetGetSecurityInfoByURLW(LPCWSTR lpszURL, PCCERT_CHAIN_CONTEXT *ppCertChain, DWORD *pdwSecureFlags)
{
    URL_COMPONENTSW url = {sizeof(url)};
    server_t *server;
    WCHAR *hostname;
    BOOL res;

    TRACE("(%s %p %p)\n", debugstr_w(lpszURL), ppCertChain, pdwSecureFlags);

    url.dwHostNameLength = 1;
    res = InternetCrackUrlW(lpszURL, 0, 0, &url);
    if(!res || url.nScheme != INTERNET_SCHEME_HTTPS) {
        SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
        return FALSE;
    }

    hostname = heap_strndupW(url.lpszHostName, url.dwHostNameLength);
    if(!hostname) {
        SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }

    server = get_server(hostname, url.nPort, TRUE, FALSE);
    heap_free(hostname);
    if(!server) {
        SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
        return FALSE;
    }

    if(server->cert_chain) {
        const CERT_CHAIN_CONTEXT *chain_dup;

        chain_dup = CertDuplicateCertificateChain(server->cert_chain);
        if(chain_dup) {
            *ppCertChain = chain_dup;
            *pdwSecureFlags = server->security_flags & _SECURITY_ERROR_FLAGS_MASK;
        }else {
            res = FALSE;
        }
    }else {
        SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
        res = FALSE;
    }

    server_release(server);
    return res;
}

DWORD WINAPI InternetDialA( HWND hwndParent, LPSTR lpszConnectoid, DWORD dwFlags,
                            DWORD_PTR* lpdwConnection, DWORD dwReserved )
{
    FIXME("(%p, %p, 0x%08x, %p, 0x%08x) stub\n", hwndParent, lpszConnectoid, dwFlags,
          lpdwConnection, dwReserved);
    return ERROR_SUCCESS;
}

DWORD WINAPI InternetDialW( HWND hwndParent, LPWSTR lpszConnectoid, DWORD dwFlags,
                            DWORD_PTR* lpdwConnection, DWORD dwReserved )
{
    FIXME("(%p, %p, 0x%08x, %p, 0x%08x) stub\n", hwndParent, lpszConnectoid, dwFlags,
          lpdwConnection, dwReserved);
    return ERROR_SUCCESS;
}

BOOL WINAPI InternetGoOnlineA( LPSTR lpszURL, HWND hwndParent, DWORD dwReserved )
{
    FIXME("(%s, %p, 0x%08x) stub\n", debugstr_a(lpszURL), hwndParent, dwReserved);
    return TRUE;
}

BOOL WINAPI InternetGoOnlineW( LPWSTR lpszURL, HWND hwndParent, DWORD dwReserved )
{
    FIXME("(%s, %p, 0x%08x) stub\n", debugstr_w(lpszURL), hwndParent, dwReserved);
    return TRUE;
}

DWORD WINAPI InternetHangUp( DWORD_PTR dwConnection, DWORD dwReserved )
{
    FIXME("(0x%08lx, 0x%08x) stub\n", dwConnection, dwReserved);
    return ERROR_SUCCESS;
}

BOOL WINAPI CreateMD5SSOHash( PWSTR pszChallengeInfo, PWSTR pwszRealm, PWSTR pwszTarget,
                              PBYTE pbHexHash )
{
    FIXME("(%s, %s, %s, %p) stub\n", debugstr_w(pszChallengeInfo), debugstr_w(pwszRealm),
          debugstr_w(pwszTarget), pbHexHash);
    return FALSE;
}

BOOL WINAPI ResumeSuspendedDownload( HINTERNET hInternet, DWORD dwError )
{
    FIXME("(%p, 0x%08x) stub\n", hInternet, dwError);
    return FALSE;
}

BOOL WINAPI InternetQueryFortezzaStatus(DWORD *a, DWORD_PTR b)
{
    FIXME("(%p, %08lx) stub\n", a, b);
    return FALSE;
}

DWORD WINAPI ShowClientAuthCerts(HWND parent)
{
    FIXME("%p: stub\n", parent);
    return 0;
}
