/*
 * Copyright 2010 Jacek Caban for CodeWeavers
 * Copyright 2010 Thomas Mullaly
 *
 * 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 <limits.h>

#include "urlmon_main.h"
#include "wine/debug.h"

#define NO_SHLWAPI_REG
#include "shlwapi.h"

#include "strsafe.h"

#define URI_DISPLAY_NO_ABSOLUTE_URI         0x1
#define URI_DISPLAY_NO_DEFAULT_PORT_AUTH    0x2

#define ALLOW_NULL_TERM_SCHEME          0x01
#define ALLOW_NULL_TERM_USER_NAME       0x02
#define ALLOW_NULL_TERM_PASSWORD        0x04
#define ALLOW_BRACKETLESS_IP_LITERAL    0x08
#define SKIP_IP_FUTURE_CHECK            0x10
#define IGNORE_PORT_DELIMITER           0x20

#define RAW_URI_FORCE_PORT_DISP     0x1
#define RAW_URI_CONVERT_TO_DOS_PATH 0x2

#define COMBINE_URI_FORCE_FLAG_USE  0x1

WINE_DEFAULT_DEBUG_CHANNEL(urlmon);

static const IID IID_IUriObj = {0x4b364760,0x9f51,0x11df,{0x98,0x1c,0x08,0x00,0x20,0x0c,0x9a,0x66}};

typedef struct {
    IUri                IUri_iface;
    IUriBuilderFactory  IUriBuilderFactory_iface;
    IPersistStream      IPersistStream_iface;
    IMarshal            IMarshal_iface;

    LONG ref;

    BSTR            raw_uri;

    /* Information about the canonicalized URI's buffer. */
    WCHAR           *canon_uri;
    DWORD           canon_size;
    DWORD           canon_len;
    BOOL            display_modifiers;
    DWORD           create_flags;

    INT             scheme_start;
    DWORD           scheme_len;
    URL_SCHEME      scheme_type;

    INT             userinfo_start;
    DWORD           userinfo_len;
    INT             userinfo_split;

    INT             host_start;
    DWORD           host_len;
    Uri_HOST_TYPE   host_type;

    INT             port_offset;
    DWORD           port;
    BOOL            has_port;

    INT             authority_start;
    DWORD           authority_len;

    INT             domain_offset;

    INT             path_start;
    DWORD           path_len;
    INT             extension_offset;

    INT             query_start;
    DWORD           query_len;

    INT             fragment_start;
    DWORD           fragment_len;
} Uri;

typedef struct {
    IUriBuilder IUriBuilder_iface;
    LONG ref;

    Uri *uri;
    DWORD modified_props;

    WCHAR   *fragment;
    DWORD   fragment_len;

    WCHAR   *host;
    DWORD   host_len;

    WCHAR   *password;
    DWORD   password_len;

    WCHAR   *path;
    DWORD   path_len;

    BOOL    has_port;
    DWORD   port;

    WCHAR   *query;
    DWORD   query_len;

    WCHAR   *scheme;
    DWORD   scheme_len;

    WCHAR   *username;
    DWORD   username_len;
} UriBuilder;

typedef struct {
    const WCHAR *str;
    DWORD       len;
} h16;

typedef struct {
    /* IPv6 addresses can hold up to 8 h16 components. */
    h16         components[8];
    DWORD       h16_count;

    /* An IPv6 can have 1 elision ("::"). */
    const WCHAR *elision;

    /* An IPv6 can contain 1 IPv4 address as the last 32bits of the address. */
    const WCHAR *ipv4;
    DWORD       ipv4_len;

    INT         components_size;
    INT         elision_size;
} ipv6_address;

typedef struct {
    BSTR            uri;

    BOOL            is_relative;
    BOOL            is_opaque;
    BOOL            has_implicit_scheme;
    BOOL            has_implicit_ip;
    UINT            implicit_ipv4;
    BOOL            must_have_path;

    const WCHAR     *scheme;
    DWORD           scheme_len;
    URL_SCHEME      scheme_type;

    const WCHAR     *username;
    DWORD           username_len;

    const WCHAR     *password;
    DWORD           password_len;

    const WCHAR     *host;
    DWORD           host_len;
    Uri_HOST_TYPE   host_type;

    BOOL            has_ipv6;
    ipv6_address    ipv6_address;

    BOOL            has_port;
    const WCHAR     *port;
    DWORD           port_len;
    DWORD           port_value;

    const WCHAR     *path;
    DWORD           path_len;

    const WCHAR     *query;
    DWORD           query_len;

    const WCHAR     *fragment;
    DWORD           fragment_len;
} parse_data;

static const CHAR hexDigits[] = "0123456789ABCDEF";

/* List of scheme types/scheme names that are recognized by the IUri interface as of IE 7. */
static const struct {
    URL_SCHEME  scheme;
    WCHAR       scheme_name[16];
} recognized_schemes[] = {
    {URL_SCHEME_FTP,            {'f','t','p',0}},
    {URL_SCHEME_HTTP,           {'h','t','t','p',0}},
    {URL_SCHEME_GOPHER,         {'g','o','p','h','e','r',0}},
    {URL_SCHEME_MAILTO,         {'m','a','i','l','t','o',0}},
    {URL_SCHEME_NEWS,           {'n','e','w','s',0}},
    {URL_SCHEME_NNTP,           {'n','n','t','p',0}},
    {URL_SCHEME_TELNET,         {'t','e','l','n','e','t',0}},
    {URL_SCHEME_WAIS,           {'w','a','i','s',0}},
    {URL_SCHEME_FILE,           {'f','i','l','e',0}},
    {URL_SCHEME_MK,             {'m','k',0}},
    {URL_SCHEME_HTTPS,          {'h','t','t','p','s',0}},
    {URL_SCHEME_SHELL,          {'s','h','e','l','l',0}},
    {URL_SCHEME_SNEWS,          {'s','n','e','w','s',0}},
    {URL_SCHEME_LOCAL,          {'l','o','c','a','l',0}},
    {URL_SCHEME_JAVASCRIPT,     {'j','a','v','a','s','c','r','i','p','t',0}},
    {URL_SCHEME_VBSCRIPT,       {'v','b','s','c','r','i','p','t',0}},
    {URL_SCHEME_ABOUT,          {'a','b','o','u','t',0}},
    {URL_SCHEME_RES,            {'r','e','s',0}},
    {URL_SCHEME_MSSHELLROOTED,  {'m','s','-','s','h','e','l','l','-','r','o','o','t','e','d',0}},
    {URL_SCHEME_MSSHELLIDLIST,  {'m','s','-','s','h','e','l','l','-','i','d','l','i','s','t',0}},
    {URL_SCHEME_MSHELP,         {'h','c','p',0}},
    {URL_SCHEME_WILDCARD,       {'*',0}}
};

/* List of default ports Windows recognizes. */
static const struct {
    URL_SCHEME  scheme;
    USHORT      port;
} default_ports[] = {
    {URL_SCHEME_FTP,    21},
    {URL_SCHEME_HTTP,   80},
    {URL_SCHEME_GOPHER, 70},
    {URL_SCHEME_NNTP,   119},
    {URL_SCHEME_TELNET, 23},
    {URL_SCHEME_WAIS,   210},
    {URL_SCHEME_HTTPS,  443},
};

/* List of 3-character top level domain names Windows seems to recognize.
 * There might be more, but, these are the only ones I've found so far.
 */
static const struct {
    WCHAR tld_name[4];
} recognized_tlds[] = {
    {{'c','o','m',0}},
    {{'e','d','u',0}},
    {{'g','o','v',0}},
    {{'i','n','t',0}},
    {{'m','i','l',0}},
    {{'n','e','t',0}},
    {{'o','r','g',0}}
};

static Uri *get_uri_obj(IUri *uri)
{
    Uri *ret;
    HRESULT hres;

    hres = IUri_QueryInterface(uri, &IID_IUriObj, (void**)&ret);
    return SUCCEEDED(hres) ? ret : NULL;
}

static inline BOOL is_alpha(WCHAR val) {
    return ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'));
}

static inline BOOL is_num(WCHAR val) {
    return (val >= '0' && val <= '9');
}

static inline BOOL is_drive_path(const WCHAR *str) {
    return (is_alpha(str[0]) && (str[1] == ':' || str[1] == '|'));
}

static inline BOOL is_unc_path(const WCHAR *str) {
    return (str[0] == '\\' && str[0] == '\\');
}

static inline BOOL is_forbidden_dos_path_char(WCHAR val) {
    return (val == '>' || val == '<' || val == '\"');
}

/* A URI is implicitly a file path if it begins with
 * a drive letter (e.g. X:) or starts with "\\" (UNC path).
 */
static inline BOOL is_implicit_file_path(const WCHAR *str) {
    return (is_unc_path(str) || (is_alpha(str[0]) && str[1] == ':'));
}

/* Checks if the URI is a hierarchical URI. A hierarchical
 * URI is one that has "//" after the scheme.
 */
static BOOL check_hierarchical(const WCHAR **ptr) {
    const WCHAR *start = *ptr;

    if(**ptr != '/')
        return FALSE;

    ++(*ptr);
    if(**ptr != '/') {
        *ptr = start;
        return FALSE;
    }

    ++(*ptr);
    return TRUE;
}

/* unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~" */
static inline BOOL is_unreserved(WCHAR val) {
    return (is_alpha(val) || is_num(val) || val == '-' || val == '.' ||
            val == '_' || val == '~');
}

/* sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
 *               / "*" / "+" / "," / ";" / "="
 */
static inline BOOL is_subdelim(WCHAR val) {
    return (val == '!' || val == '$' || val == '&' ||
            val == '\'' || val == '(' || val == ')' ||
            val == '*' || val == '+' || val == ',' ||
            val == ';' || val == '=');
}

/* gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@" */
static inline BOOL is_gendelim(WCHAR val) {
    return (val == ':' || val == '/' || val == '?' ||
            val == '#' || val == '[' || val == ']' ||
            val == '@');
}

/* Characters that delimit the end of the authority
 * section of a URI. Sometimes a '\\' is considered
 * an authority delimiter.
 */
static inline BOOL is_auth_delim(WCHAR val, BOOL acceptSlash) {
    return (val == '#' || val == '/' || val == '?' ||
            val == '\0' || (acceptSlash && val == '\\'));
}

/* reserved = gen-delims / sub-delims */
static inline BOOL is_reserved(WCHAR val) {
    return (is_subdelim(val) || is_gendelim(val));
}

static inline BOOL is_hexdigit(WCHAR val) {
    return ((val >= 'a' && val <= 'f') ||
            (val >= 'A' && val <= 'F') ||
            (val >= '0' && val <= '9'));
}

static inline BOOL is_path_delim(WCHAR val) {
    return (!val || val == '#' || val == '?');
}

static inline BOOL is_slash(WCHAR c)
{
    return c == '/' || c == '\\';
}

static BOOL is_default_port(URL_SCHEME scheme, DWORD port) {
    DWORD i;

    for(i = 0; i < sizeof(default_ports)/sizeof(default_ports[0]); ++i) {
        if(default_ports[i].scheme == scheme && default_ports[i].port)
            return TRUE;
    }

    return FALSE;
}

/* List of schemes types Windows seems to expect to be hierarchical. */
static inline BOOL is_hierarchical_scheme(URL_SCHEME type) {
    return(type == URL_SCHEME_HTTP || type == URL_SCHEME_FTP ||
           type == URL_SCHEME_GOPHER || type == URL_SCHEME_NNTP ||
           type == URL_SCHEME_TELNET || type == URL_SCHEME_WAIS ||
           type == URL_SCHEME_FILE || type == URL_SCHEME_HTTPS ||
           type == URL_SCHEME_RES);
}

/* Checks if 'flags' contains an invalid combination of Uri_CREATE flags. */
static inline BOOL has_invalid_flag_combination(DWORD flags) {
    return((flags & Uri_CREATE_DECODE_EXTRA_INFO && flags & Uri_CREATE_NO_DECODE_EXTRA_INFO) ||
           (flags & Uri_CREATE_CANONICALIZE && flags & Uri_CREATE_NO_CANONICALIZE) ||
           (flags & Uri_CREATE_CRACK_UNKNOWN_SCHEMES && flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES) ||
           (flags & Uri_CREATE_PRE_PROCESS_HTML_URI && flags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI) ||
           (flags & Uri_CREATE_IE_SETTINGS && flags & Uri_CREATE_NO_IE_SETTINGS));
}

/* Applies each default Uri_CREATE flags to 'flags' if it
 * doesn't cause a flag conflict.
 */
static void apply_default_flags(DWORD *flags) {
    if(!(*flags & Uri_CREATE_NO_CANONICALIZE))
        *flags |= Uri_CREATE_CANONICALIZE;
    if(!(*flags & Uri_CREATE_NO_DECODE_EXTRA_INFO))
        *flags |= Uri_CREATE_DECODE_EXTRA_INFO;
    if(!(*flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES))
        *flags |= Uri_CREATE_CRACK_UNKNOWN_SCHEMES;
    if(!(*flags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI))
        *flags |= Uri_CREATE_PRE_PROCESS_HTML_URI;
    if(!(*flags & Uri_CREATE_IE_SETTINGS))
        *flags |= Uri_CREATE_NO_IE_SETTINGS;
}

/* Determines if the URI is hierarchical using the information already parsed into
 * data and using the current location of parsing in the URI string.
 *
 * Windows considers a URI hierarchical if one of the following is true:
 *  A.) It's a wildcard scheme.
 *  B.) It's an implicit file scheme.
 *  C.) It's a known hierarchical scheme and it has two '\\' after the scheme name.
 *      (the '\\' will be converted into "//" during canonicalization).
 *  D.) "//" appears after the scheme name (or at the beginning if no scheme is given).
 */
static inline BOOL is_hierarchical_uri(const WCHAR **ptr, const parse_data *data) {
    const WCHAR *start = *ptr;

    if(data->scheme_type == URL_SCHEME_WILDCARD)
        return TRUE;
    else if(data->scheme_type == URL_SCHEME_FILE && data->has_implicit_scheme)
        return TRUE;
    else if(is_hierarchical_scheme(data->scheme_type) && (*ptr)[0] == '\\' && (*ptr)[1] == '\\') {
        *ptr += 2;
        return TRUE;
    } else if(check_hierarchical(ptr))
        return TRUE;

    *ptr = start;
    return FALSE;
}

/* Computes the size of the given IPv6 address.
 * Each h16 component is 16 bits. If there is an IPv4 address, it's
 * 32 bits. If there's an elision it can be 16 to 128 bits, depending
 * on the number of other components.
 *
 * Modeled after google-url's CheckIPv6ComponentsSize function
 */
static void compute_ipv6_comps_size(ipv6_address *address) {
    address->components_size = address->h16_count * 2;

    if(address->ipv4)
        /* IPv4 address is 4 bytes. */
        address->components_size += 4;

    if(address->elision) {
        /* An elision can be anywhere from 2 bytes up to 16 bytes.
         * Its size depends on the size of the h16 and IPv4 components.
         */
        address->elision_size = 16 - address->components_size;
        if(address->elision_size < 2)
            address->elision_size = 2;
    } else
        address->elision_size = 0;
}

/* Taken from dlls/jscript/lex.c */
static int hex_to_int(WCHAR val) {
    if(val >= '0' && val <= '9')
        return val - '0';
    else if(val >= 'a' && val <= 'f')
        return val - 'a' + 10;
    else if(val >= 'A' && val <= 'F')
        return val - 'A' + 10;

    return -1;
}

/* Helper function for converting a percent encoded string
 * representation of a WCHAR value into its actual WCHAR value. If
 * the two characters following the '%' aren't valid hex values then
 * this function returns the NULL character.
 *
 * E.g.
 *  "%2E" will result in '.' being returned by this function.
 */
static WCHAR decode_pct_val(const WCHAR *ptr) {
    WCHAR ret = '\0';

    if(*ptr == '%' && is_hexdigit(*(ptr + 1)) && is_hexdigit(*(ptr + 2))) {
        INT a = hex_to_int(*(ptr + 1));
        INT b = hex_to_int(*(ptr + 2));

        ret = a << 4;
        ret += b;
    }

    return ret;
}

/* Helper function for percent encoding a given character
 * and storing the encoded value into a given buffer (dest).
 *
 * It's up to the calling function to ensure that there is
 * at least enough space in 'dest' for the percent encoded
 * value to be stored (so dest + 3 spaces available).
 */
static inline void pct_encode_val(WCHAR val, WCHAR *dest) {
    dest[0] = '%';
    dest[1] = hexDigits[(val >> 4) & 0xf];
    dest[2] = hexDigits[val & 0xf];
}

/* Attempts to parse the domain name from the host.
 *
 * This function also includes the Top-level Domain (TLD) name
 * of the host when it tries to find the domain name. If it finds
 * a valid domain name it will assign 'domain_start' the offset
 * into 'host' where the domain name starts.
 *
 * It's implied that if there is a domain name its range is:
 * [host+domain_start, host+host_len).
 */
void find_domain_name(const WCHAR *host, DWORD host_len,
                             INT *domain_start) {
    const WCHAR *last_tld, *sec_last_tld, *end;

    end = host+host_len-1;

    *domain_start = -1;

    /* There has to be at least enough room for a '.' followed by a
     * 3-character TLD for a domain to even exist in the host name.
     */
    if(host_len < 4)
        return;

    last_tld = memrchrW(host, '.', host_len);
    if(!last_tld)
        /* http://hostname -> has no domain name. */
        return;

    sec_last_tld = memrchrW(host, '.', last_tld-host);
    if(!sec_last_tld) {
        /* If the '.' is at the beginning of the host there
         * has to be at least 3 characters in the TLD for it
         * to be valid.
         *  Ex: .com -> .com as the domain name.
         *      .co  -> has no domain name.
         */
        if(last_tld-host == 0) {
            if(end-(last_tld-1) < 3)
                return;
        } else if(last_tld-host == 3) {
            DWORD i;

            /* If there are three characters in front of last_tld and
             * they are on the list of recognized TLDs, then this
             * host doesn't have a domain (since the host only contains
             * a TLD name.
             *  Ex: edu.uk -> has no domain name.
             *      foo.uk -> foo.uk as the domain name.
             */
            for(i = 0; i < sizeof(recognized_tlds)/sizeof(recognized_tlds[0]); ++i) {
                if(!StrCmpNIW(host, recognized_tlds[i].tld_name, 3))
                    return;
            }
        } else if(last_tld-host < 3)
            /* Anything less than 3 characters is considered part
             * of the TLD name.
             *  Ex: ak.uk -> Has no domain name.
             */
            return;

        /* Otherwise the domain name is the whole host name. */
        *domain_start = 0;
    } else if(end+1-last_tld > 3) {
        /* If the last_tld has more than 3 characters, then it's automatically
         * considered the TLD of the domain name.
         *  Ex: www.winehq.org.uk.test -> uk.test as the domain name.
         */
        *domain_start = (sec_last_tld+1)-host;
    } else if(last_tld - (sec_last_tld+1) < 4) {
        DWORD i;
        /* If the sec_last_tld is 3 characters long it HAS to be on the list of
         * recognized to still be considered part of the TLD name, otherwise
         * its considered the domain name.
         *  Ex: www.google.com.uk -> google.com.uk as the domain name.
         *      www.google.foo.uk -> foo.uk as the domain name.
         */
        if(last_tld - (sec_last_tld+1) == 3) {
            for(i = 0; i < sizeof(recognized_tlds)/sizeof(recognized_tlds[0]); ++i) {
                if(!StrCmpNIW(sec_last_tld+1, recognized_tlds[i].tld_name, 3)) {
                    const WCHAR *domain = memrchrW(host, '.', sec_last_tld-host);

                    if(!domain)
                        *domain_start = 0;
                    else
                        *domain_start = (domain+1) - host;
                    TRACE("Found domain name %s\n", debugstr_wn(host+*domain_start,
                                                        (host+host_len)-(host+*domain_start)));
                    return;
                }
            }

            *domain_start = (sec_last_tld+1)-host;
        } else {
            /* Since the sec_last_tld is less than 3 characters it's considered
             * part of the TLD.
             *  Ex: www.google.fo.uk -> google.fo.uk as the domain name.
             */
            const WCHAR *domain = memrchrW(host, '.', sec_last_tld-host);

            if(!domain)
                *domain_start = 0;
            else
                *domain_start = (domain+1) - host;
        }
    } else {
        /* The second to last TLD has more than 3 characters making it
         * the domain name.
         *  Ex: www.google.test.us -> test.us as the domain name.
         */
        *domain_start = (sec_last_tld+1)-host;
    }

    TRACE("Found domain name %s\n", debugstr_wn(host+*domain_start,
                                        (host+host_len)-(host+*domain_start)));
}

/* Removes the dot segments from a hierarchical URIs path component. This
 * function performs the removal in place.
 *
 * This function returns the new length of the path string.
 */
static DWORD remove_dot_segments(WCHAR *path, DWORD path_len) {
    WCHAR *out = path;
    const WCHAR *in = out;
    const WCHAR *end = out + path_len;
    DWORD len;

    while(in < end) {
        /* Move the first path segment in the input buffer to the end of
         * the output buffer, and any subsequent characters up to, including
         * the next "/" character (if any) or the end of the input buffer.
         */
        while(in < end && !is_slash(*in))
            *out++ = *in++;
        if(in == end)
            break;
        *out++ = *in++;

        while(in < end) {
            if(*in != '.')
                break;

            /* Handle ending "/." */
            if(in + 1 == end) {
                ++in;
                break;
            }

            /* Handle "/./" */
            if(is_slash(in[1])) {
                in += 2;
                continue;
            }

            /* If we don't have "/../" or ending "/.." */
            if(in[1] != '.' || (in + 2 != end && !is_slash(in[2])))
                break;

            /* Find the slash preceding out pointer and move out pointer to it */
            if(out > path+1 && is_slash(*--out))
                --out;
            while(out > path && !is_slash(*(--out)));
            if(is_slash(*out))
                ++out;
            in += 2;
            if(in != end)
                ++in;
        }
    }

    len = out - path;
    TRACE("(%p %d): Path after dot segments removed %s len=%d\n", path, path_len,
        debugstr_wn(path, len), len);
    return len;
}

/* Attempts to find the file extension in a given path. */
static INT find_file_extension(const WCHAR *path, DWORD path_len) {
    const WCHAR *end;

    for(end = path+path_len-1; end >= path && *end != '/' && *end != '\\'; --end) {
        if(*end == '.')
            return end-path;
    }

    return -1;
}

/* Computes the location where the elision should occur in the IPv6
 * address using the numerical values of each component stored in
 * 'values'. If the address shouldn't contain an elision then 'index'
 * is assigned -1 as its value. Otherwise 'index' will contain the
 * starting index (into values) where the elision should be, and 'count'
 * will contain the number of cells the elision covers.
 *
 * NOTES:
 *  Windows will expand an elision if the elision only represents one h16
 *  component of the address.
 *
 *  Ex: [1::2:3:4:5:6:7] -> [1:0:2:3:4:5:6:7]
 *
 *  If the IPv6 address contains an IPv4 address, the IPv4 address is also
 *  considered for being included as part of an elision if all its components
 *  are zeros.
 *
 *  Ex: [1:2:3:4:5:6:0.0.0.0] -> [1:2:3:4:5:6::]
 */
static void compute_elision_location(const ipv6_address *address, const USHORT values[8],
                                     INT *index, DWORD *count) {
    DWORD i, max_len, cur_len;
    INT max_index, cur_index;

    max_len = cur_len = 0;
    max_index = cur_index = -1;
    for(i = 0; i < 8; ++i) {
        BOOL check_ipv4 = (address->ipv4 && i == 6);
        BOOL is_end = (check_ipv4 || i == 7);

        if(check_ipv4) {
            /* Check if the IPv4 address contains only zeros. */
            if(values[i] == 0 && values[i+1] == 0) {
                if(cur_index == -1)
                    cur_index = i;

                cur_len += 2;
                ++i;
            }
        } else if(values[i] == 0) {
            if(cur_index == -1)
                cur_index = i;

            ++cur_len;
        }

        if(is_end || values[i] != 0) {
            /* We only consider it for an elision if it's
             * more than 1 component long.
             */
            if(cur_len > 1 && cur_len > max_len) {
                /* Found the new elision location. */
                max_len = cur_len;
                max_index = cur_index;
            }

            /* Reset the current range for the next range of zeros. */
            cur_index = -1;
            cur_len = 0;
        }
    }

    *index = max_index;
    *count = max_len;
}

/* Removes all the leading and trailing white spaces or
 * control characters from the URI and removes all control
 * characters inside of the URI string.
 */
static BSTR pre_process_uri(LPCWSTR uri) {
    const WCHAR *start, *end, *ptr;
    WCHAR *ptr2;
    DWORD len;
    BSTR ret;

    start = uri;
    /* Skip leading controls and whitespace. */
    while(*start && (iscntrlW(*start) || isspaceW(*start))) ++start;

    /* URI consisted only of control/whitespace. */
    if(!*start)
        return SysAllocStringLen(NULL, 0);

    end = start + strlenW(start);
    while(--end > start && (iscntrlW(*end) || isspaceW(*end)));

    len = ++end - start;
    for(ptr = start; ptr < end; ptr++) {
        if(iscntrlW(*ptr))
            len--;
    }

    ret = SysAllocStringLen(NULL, len);
    if(!ret)
        return NULL;

    for(ptr = start, ptr2=ret; ptr < end; ptr++) {
        if(!iscntrlW(*ptr))
            *ptr2++ = *ptr;
    }

    return ret;
}

/* Converts the specified IPv4 address into an uint value.
 *
 * This function assumes that the IPv4 address has already been validated.
 */
static UINT ipv4toui(const WCHAR *ip, DWORD len) {
    UINT ret = 0;
    DWORD comp_value = 0;
    const WCHAR *ptr;

    for(ptr = ip; ptr < ip+len; ++ptr) {
        if(*ptr == '.') {
            ret <<= 8;
            ret += comp_value;
            comp_value = 0;
        } else
            comp_value = comp_value*10 + (*ptr-'0');
    }

    ret <<= 8;
    ret += comp_value;

    return ret;
}

/* Converts an IPv4 address in numerical form into its fully qualified
 * string form. This function returns the number of characters written
 * to 'dest'. If 'dest' is NULL this function will return the number of
 * characters that would have been written.
 *
 * It's up to the caller to ensure there's enough space in 'dest' for the
 * address.
 */
static DWORD ui2ipv4(WCHAR *dest, UINT address) {
    static const WCHAR formatW[] =
        {'%','u','.','%','u','.','%','u','.','%','u',0};
    DWORD ret = 0;
    UCHAR digits[4];

    digits[0] = (address >> 24) & 0xff;
    digits[1] = (address >> 16) & 0xff;
    digits[2] = (address >> 8) & 0xff;
    digits[3] = address & 0xff;

    if(!dest) {
        WCHAR tmp[16];
        ret = sprintfW(tmp, formatW, digits[0], digits[1], digits[2], digits[3]);
    } else
        ret = sprintfW(dest, formatW, digits[0], digits[1], digits[2], digits[3]);

    return ret;
}

static DWORD ui2str(WCHAR *dest, UINT value) {
    static const WCHAR formatW[] = {'%','u',0};
    DWORD ret = 0;

    if(!dest) {
        WCHAR tmp[11];
        ret = sprintfW(tmp, formatW, value);
    } else
        ret = sprintfW(dest, formatW, value);

    return ret;
}

/* Converts a h16 component (from an IPv6 address) into its
 * numerical value.
 *
 * This function assumes that the h16 component has already been validated.
 */
static USHORT h16tous(h16 component) {
    DWORD i;
    USHORT ret = 0;

    for(i = 0; i < component.len; ++i) {
        ret <<= 4;
        ret += hex_to_int(component.str[i]);
    }

    return ret;
}

/* Converts an IPv6 address into its 128 bits (16 bytes) numerical value.
 *
 * This function assumes that the ipv6_address has already been validated.
 */
static BOOL ipv6_to_number(const ipv6_address *address, USHORT number[8]) {
    DWORD i, cur_component = 0;
    BOOL already_passed_elision = FALSE;

    for(i = 0; i < address->h16_count; ++i) {
        if(address->elision) {
            if(address->components[i].str > address->elision && !already_passed_elision) {
                /* Means we just passed the elision and need to add its values to
                 * 'number' before we do anything else.
                 */
                DWORD j = 0;
                for(j = 0; j < address->elision_size; j+=2)
                    number[cur_component++] = 0;

                already_passed_elision = TRUE;
            }
        }

        number[cur_component++] = h16tous(address->components[i]);
    }

    /* Case when the elision appears after the h16 components. */
    if(!already_passed_elision && address->elision) {
        for(i = 0; i < address->elision_size; i+=2)
            number[cur_component++] = 0;
    }

    if(address->ipv4) {
        UINT value = ipv4toui(address->ipv4, address->ipv4_len);

        if(cur_component != 6) {
            ERR("(%p %p): Failed sanity check with %d\n", address, number, cur_component);
            return FALSE;
        }

        number[cur_component++] = (value >> 16) & 0xffff;
        number[cur_component] = value & 0xffff;
    }

    return TRUE;
}

/* Checks if the characters pointed to by 'ptr' are
 * a percent encoded data octet.
 *
 * pct-encoded = "%" HEXDIG HEXDIG
 */
static BOOL check_pct_encoded(const WCHAR **ptr) {
    const WCHAR *start = *ptr;

    if(**ptr != '%')
        return FALSE;

    ++(*ptr);
    if(!is_hexdigit(**ptr)) {
        *ptr = start;
        return FALSE;
    }

    ++(*ptr);
    if(!is_hexdigit(**ptr)) {
        *ptr = start;
        return FALSE;
    }

    ++(*ptr);
    return TRUE;
}

/* dec-octet   = DIGIT                 ; 0-9
 *             / %x31-39 DIGIT         ; 10-99
 *             / "1" 2DIGIT            ; 100-199
 *             / "2" %x30-34 DIGIT     ; 200-249
 *             / "25" %x30-35          ; 250-255
 */
static BOOL check_dec_octet(const WCHAR **ptr) {
    const WCHAR *c1, *c2, *c3;

    c1 = *ptr;
    /* A dec-octet must be at least 1 digit long. */
    if(*c1 < '0' || *c1 > '9')
        return FALSE;

    ++(*ptr);

    c2 = *ptr;
    /* Since the 1-digit requirement was met, it doesn't
     * matter if this is a DIGIT value, it's considered a
     * dec-octet.
     */
    if(*c2 < '0' || *c2 > '9')
        return TRUE;

    ++(*ptr);

    c3 = *ptr;
    /* Same explanation as above. */
    if(*c3 < '0' || *c3 > '9')
        return TRUE;

    /* Anything > 255 isn't a valid IP dec-octet. */
    if(*c1 >= '2' && *c2 >= '5' && *c3 >= '5') {
        *ptr = c1;
        return FALSE;
    }

    ++(*ptr);
    return TRUE;
}

/* Checks if there is an implicit IPv4 address in the host component of the URI.
 * The max value of an implicit IPv4 address is UINT_MAX.
 *
 *  Ex:
 *      "234567" would be considered an implicit IPv4 address.
 */
static BOOL check_implicit_ipv4(const WCHAR **ptr, UINT *val) {
    const WCHAR *start = *ptr;
    ULONGLONG ret = 0;
    *val = 0;

    while(is_num(**ptr)) {
        ret = ret*10 + (**ptr - '0');

        if(ret > UINT_MAX) {
            *ptr = start;
            return FALSE;
        }
        ++(*ptr);
    }

    if(*ptr == start)
        return FALSE;

    *val = ret;
    return TRUE;
}

/* Checks if the string contains an IPv4 address.
 *
 * This function has a strict mode or a non-strict mode of operation
 * When 'strict' is set to FALSE this function will return TRUE if
 * the string contains at least 'dec-octet "." dec-octet' since partial
 * IPv4 addresses will be normalized out into full IPv4 addresses. When
 * 'strict' is set this function expects there to be a full IPv4 address.
 *
 * IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
 */
static BOOL check_ipv4address(const WCHAR **ptr, BOOL strict) {
    const WCHAR *start = *ptr;

    if(!check_dec_octet(ptr)) {
        *ptr = start;
        return FALSE;
    }

    if(**ptr != '.') {
        *ptr = start;
        return FALSE;
    }

    ++(*ptr);
    if(!check_dec_octet(ptr)) {
        *ptr = start;
        return FALSE;
    }

    if(**ptr != '.') {
        if(strict) {
            *ptr = start;
            return FALSE;
        } else
            return TRUE;
    }

    ++(*ptr);
    if(!check_dec_octet(ptr)) {
        *ptr = start;
        return FALSE;
    }

    if(**ptr != '.') {
        if(strict) {
            *ptr = start;
            return FALSE;
        } else
            return TRUE;
    }

    ++(*ptr);
    if(!check_dec_octet(ptr)) {
        *ptr = start;
        return FALSE;
    }

    /* Found a four digit ip address. */
    return TRUE;
}
/* Tries to parse the scheme name of the URI.
 *
 * scheme = ALPHA *(ALPHA | NUM | '+' | '-' | '.') as defined by RFC 3896.
 * NOTE: Windows accepts a number as the first character of a scheme.
 */
static BOOL parse_scheme_name(const WCHAR **ptr, parse_data *data, DWORD extras) {
    const WCHAR *start = *ptr;

    data->scheme = NULL;
    data->scheme_len = 0;

    while(**ptr) {
        if(**ptr == '*' && *ptr == start) {
            /* Might have found a wildcard scheme. If it is the next
             * char has to be a ':' for it to be a valid URI
             */
            ++(*ptr);
            break;
        } else if(!is_num(**ptr) && !is_alpha(**ptr) && **ptr != '+' &&
           **ptr != '-' && **ptr != '.')
            break;

        (*ptr)++;
    }

    if(*ptr == start)
        return FALSE;

    /* Schemes must end with a ':' */
    if(**ptr != ':' && !((extras & ALLOW_NULL_TERM_SCHEME) && !**ptr)) {
        *ptr = start;
        return FALSE;
    }

    data->scheme = start;
    data->scheme_len = *ptr - start;

    ++(*ptr);
    return TRUE;
}

/* Tries to deduce the corresponding URL_SCHEME for the given URI. Stores
 * the deduced URL_SCHEME in data->scheme_type.
 */
static BOOL parse_scheme_type(parse_data *data) {
    /* If there's scheme data then see if it's a recognized scheme. */
    if(data->scheme && data->scheme_len) {
        DWORD i;

        for(i = 0; i < sizeof(recognized_schemes)/sizeof(recognized_schemes[0]); ++i) {
            if(lstrlenW(recognized_schemes[i].scheme_name) == data->scheme_len) {
                /* Has to be a case insensitive compare. */
                if(!StrCmpNIW(recognized_schemes[i].scheme_name, data->scheme, data->scheme_len)) {
                    data->scheme_type = recognized_schemes[i].scheme;
                    return TRUE;
                }
            }
        }

        /* If we get here it means it's not a recognized scheme. */
        data->scheme_type = URL_SCHEME_UNKNOWN;
        return TRUE;
    } else if(data->is_relative) {
        /* Relative URI's have no scheme. */
        data->scheme_type = URL_SCHEME_UNKNOWN;
        return TRUE;
    } else {
        /* Should never reach here! what happened... */
        FIXME("(%p): Unable to determine scheme type for URI %s\n", data, debugstr_w(data->uri));
        return FALSE;
    }
}

/* Tries to parse (or deduce) the scheme_name of a URI. If it can't
 * parse a scheme from the URI it will try to deduce the scheme_name and scheme_type
 * using the flags specified in 'flags' (if any). Flags that affect how this function
 * operates are the Uri_CREATE_ALLOW_* flags.
 *
 * All parsed/deduced information will be stored in 'data' when the function returns.
 *
 * Returns TRUE if it was able to successfully parse the information.
 */
static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
    static const WCHAR fileW[] = {'f','i','l','e',0};
    static const WCHAR wildcardW[] = {'*',0};

    /* First check to see if the uri could implicitly be a file path. */
    if(is_implicit_file_path(*ptr)) {
        if(flags & Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME) {
            data->scheme = fileW;
            data->scheme_len = lstrlenW(fileW);
            data->has_implicit_scheme = TRUE;

            TRACE("(%p %p %x): URI is an implicit file path.\n", ptr, data, flags);
        } else {
            /* Windows does not consider anything that can implicitly be a file
             * path to be a valid URI if the ALLOW_IMPLICIT_FILE_SCHEME flag is not set...
             */
            TRACE("(%p %p %x): URI is implicitly a file path, but, the ALLOW_IMPLICIT_FILE_SCHEME flag wasn't set.\n",
                    ptr, data, flags);
            return FALSE;
        }
    } else if(!parse_scheme_name(ptr, data, extras)) {
        /* No scheme was found, this means it could be:
         *      a) an implicit Wildcard scheme
         *      b) a relative URI
         *      c) an invalid URI.
         */
        if(flags & Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME) {
            data->scheme = wildcardW;
            data->scheme_len = lstrlenW(wildcardW);
            data->has_implicit_scheme = TRUE;

            TRACE("(%p %p %x): URI is an implicit wildcard scheme.\n", ptr, data, flags);
        } else if (flags & Uri_CREATE_ALLOW_RELATIVE) {
            data->is_relative = TRUE;
            TRACE("(%p %p %x): URI is relative.\n", ptr, data, flags);
        } else {
            TRACE("(%p %p %x): Malformed URI found. Unable to deduce scheme name.\n", ptr, data, flags);
            return FALSE;
        }
    }

    if(!data->is_relative)
        TRACE("(%p %p %x): Found scheme=%s scheme_len=%d\n", ptr, data, flags,
                debugstr_wn(data->scheme, data->scheme_len), data->scheme_len);

    if(!parse_scheme_type(data))
        return FALSE;

    TRACE("(%p %p %x): Assigned %d as the URL_SCHEME.\n", ptr, data, flags, data->scheme_type);
    return TRUE;
}

static BOOL parse_username(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
    data->username = *ptr;

    while(**ptr != ':' && **ptr != '@') {
        if(**ptr == '%') {
            if(!check_pct_encoded(ptr)) {
                if(data->scheme_type != URL_SCHEME_UNKNOWN) {
                    *ptr = data->username;
                    data->username = NULL;
                    return FALSE;
                }
            } else
                continue;
        } else if(extras & ALLOW_NULL_TERM_USER_NAME && !**ptr)
            break;
        else if(is_auth_delim(**ptr, data->scheme_type != URL_SCHEME_UNKNOWN)) {
            *ptr = data->username;
            data->username = NULL;
            return FALSE;
        }

        ++(*ptr);
    }

    data->username_len = *ptr - data->username;
    return TRUE;
}

static BOOL parse_password(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
    data->password = *ptr;

    while(**ptr != '@') {
        if(**ptr == '%') {
            if(!check_pct_encoded(ptr)) {
                if(data->scheme_type != URL_SCHEME_UNKNOWN) {
                    *ptr = data->password;
                    data->password = NULL;
                    return FALSE;
                }
            } else
                continue;
        } else if(extras & ALLOW_NULL_TERM_PASSWORD && !**ptr)
            break;
        else if(is_auth_delim(**ptr, data->scheme_type != URL_SCHEME_UNKNOWN)) {
            *ptr = data->password;
            data->password = NULL;
            return FALSE;
        }

        ++(*ptr);
    }

    data->password_len = *ptr - data->password;
    return TRUE;
}

/* Parses the userinfo part of the URI (if it exists). The userinfo field of
 * a URI can consist of "username:password@", or just "username@".
 *
 * RFC def:
 * userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )
 *
 * NOTES:
 *  1)  If there is more than one ':' in the userinfo part of the URI Windows
 *      uses the first occurrence of ':' to delimit the username and password
 *      components.
 *
 *      ex:
 *          ftp://user:pass:word@winehq.org
 *
 *      would yield "user" as the username and "pass:word" as the password.
 *
 *  2)  Windows allows any character to appear in the "userinfo" part of
 *      a URI, as long as it's not an authority delimiter character set.
 */
static void parse_userinfo(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const WCHAR *start = *ptr;

    if(!parse_username(ptr, data, flags, 0)) {
        TRACE("(%p %p %x): URI contained no userinfo.\n", ptr, data, flags);
        return;
    }

    if(**ptr == ':') {
        ++(*ptr);
        if(!parse_password(ptr, data, flags, 0)) {
            *ptr = start;
            data->username = NULL;
            data->username_len = 0;
            TRACE("(%p %p %x): URI contained no userinfo.\n", ptr, data, flags);
            return;
        }
    }

    if(**ptr != '@') {
        *ptr = start;
        data->username = NULL;
        data->username_len = 0;
        data->password = NULL;
        data->password_len = 0;

        TRACE("(%p %p %x): URI contained no userinfo.\n", ptr, data, flags);
        return;
    }

    if(data->username)
        TRACE("(%p %p %x): Found username %s len=%d.\n", ptr, data, flags,
            debugstr_wn(data->username, data->username_len), data->username_len);

    if(data->password)
        TRACE("(%p %p %x): Found password %s len=%d.\n", ptr, data, flags,
            debugstr_wn(data->password, data->password_len), data->password_len);

    ++(*ptr);
}

/* Attempts to parse a port from the URI.
 *
 * NOTES:
 *  Windows seems to have a cap on what the maximum value
 *  for a port can be. The max value is USHORT_MAX.
 *
 * port = *DIGIT
 */
static BOOL parse_port(const WCHAR **ptr, parse_data *data, DWORD flags) {
    UINT port = 0;
    data->port = *ptr;

    while(!is_auth_delim(**ptr, data->scheme_type != URL_SCHEME_UNKNOWN)) {
        if(!is_num(**ptr)) {
            *ptr = data->port;
            data->port = NULL;
            return FALSE;
        }

        port = port*10 + (**ptr-'0');

        if(port > USHRT_MAX) {
            *ptr = data->port;
            data->port = NULL;
            return FALSE;
        }

        ++(*ptr);
    }

    data->has_port = TRUE;
    data->port_value = port;
    data->port_len = *ptr - data->port;

    TRACE("(%p %p %x): Found port %s len=%d value=%u\n", ptr, data, flags,
        debugstr_wn(data->port, data->port_len), data->port_len, data->port_value);
    return TRUE;
}

/* Attempts to parse a IPv4 address from the URI.
 *
 * NOTES:
 *  Windows normalizes IPv4 addresses, This means there are three
 *  possibilities for the URI to contain an IPv4 address.
 *      1)  A well formed address (ex. 192.2.2.2).
 *      2)  A partially formed address. For example "192.0" would
 *          normalize to "192.0.0.0" during canonicalization.
 *      3)  An implicit IPv4 address. For example "256" would
 *          normalize to "0.0.1.0" during canonicalization. Also
 *          note that the maximum value for an implicit IP address
 *          is UINT_MAX, if the value in the URI exceeds this then
 *          it is not considered an IPv4 address.
 */
static BOOL parse_ipv4address(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const BOOL is_unknown = data->scheme_type == URL_SCHEME_UNKNOWN;
    data->host = *ptr;

    if(!check_ipv4address(ptr, FALSE)) {
        if(!check_implicit_ipv4(ptr, &data->implicit_ipv4)) {
            TRACE("(%p %p %x): URI didn't contain anything looking like an IPv4 address.\n",
                ptr, data, flags);
            *ptr = data->host;
            data->host = NULL;
            return FALSE;
        } else
            data->has_implicit_ip = TRUE;
    }

    data->host_len = *ptr - data->host;
    data->host_type = Uri_HOST_IPV4;

    /* Check if what we found is the only part of the host name (if it isn't
     * we don't have an IPv4 address).
     */
    if(**ptr == ':') {
        ++(*ptr);
        if(!parse_port(ptr, data, flags)) {
            *ptr = data->host;
            data->host = NULL;
            return FALSE;
        }
    } else if(!is_auth_delim(**ptr, !is_unknown)) {
        /* Found more data which belongs to the host, so this isn't an IPv4. */
        *ptr = data->host;
        data->host = NULL;
        data->has_implicit_ip = FALSE;
        return FALSE;
    }

    TRACE("(%p %p %x): IPv4 address found. host=%s host_len=%d host_type=%d\n",
        ptr, data, flags, debugstr_wn(data->host, data->host_len),
        data->host_len, data->host_type);
    return TRUE;
}

/* Attempts to parse the reg-name from the URI.
 *
 * Because of the way Windows handles ':' this function also
 * handles parsing the port.
 *
 * reg-name = *( unreserved / pct-encoded / sub-delims )
 *
 * NOTE:
 *  Windows allows everything, but, the characters in "auth_delims" and ':'
 *  to appear in a reg-name, unless it's an unknown scheme type then ':' is
 *  allowed to appear (even if a valid port isn't after it).
 *
 *  Windows doesn't like host names which start with '[' and end with ']'
 *  and don't contain a valid IP literal address in between them.
 *
 *  On Windows if a '[' is encountered in the host name the ':' no longer
 *  counts as a delimiter until you reach the next ']' or an "authority delimiter".
 *
 *  A reg-name CAN be empty.
 */
static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
    const BOOL has_start_bracket = **ptr == '[';
    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
    const BOOL is_res = data->scheme_type == URL_SCHEME_RES;
    BOOL inside_brackets = has_start_bracket;

    /* res URIs don't have ports. */
    BOOL ignore_col = (extras & IGNORE_PORT_DELIMITER) || is_res;

    /* We have to be careful with file schemes. */
    if(data->scheme_type == URL_SCHEME_FILE) {
        /* This is because an implicit file scheme could be "C:\\test" and it
         * would trick this function into thinking the host is "C", when after
         * canonicalization the host would end up being an empty string. A drive
         * path can also have a '|' instead of a ':' after the drive letter.
         */
        if(is_drive_path(*ptr)) {
            /* Regular old drive paths have no host type (or host name). */
            data->host_type = Uri_HOST_UNKNOWN;
            data->host = *ptr;
            data->host_len = 0;
            return TRUE;
        } else if(is_unc_path(*ptr))
            /* Skip past the "\\" of a UNC path. */
            *ptr += 2;
    }

    data->host = *ptr;

    /* For res URIs, everything before the first '/' is
     * considered the host.
     */
    while((!is_res && !is_auth_delim(**ptr, known_scheme)) ||
          (is_res && **ptr && **ptr != '/')) {
        if(**ptr == ':' && !ignore_col) {
            /* We can ignore ':' if were inside brackets.*/
            if(!inside_brackets) {
                const WCHAR *tmp = (*ptr)++;

                /* Attempt to parse the port. */
                if(!parse_port(ptr, data, flags)) {
                    /* Windows expects there to be a valid port for known scheme types. */
                    if(data->scheme_type != URL_SCHEME_UNKNOWN) {
                        *ptr = data->host;
                        data->host = NULL;
                        TRACE("(%p %p %x %x): Expected valid port\n", ptr, data, flags, extras);
                        return FALSE;
                    } else
                        /* Windows gives up on trying to parse a port when it
                         * encounters an invalid port.
                         */
                        ignore_col = TRUE;
                } else {
                    data->host_len = tmp - data->host;
                    break;
                }
            }
        } else if(**ptr == '%' && (known_scheme && !is_res)) {
            /* Has to be a legit % encoded value. */
            if(!check_pct_encoded(ptr)) {
                *ptr = data->host;
                data->host = NULL;
                return FALSE;
            } else
                continue;
        } else if(is_res && is_forbidden_dos_path_char(**ptr)) {
            *ptr = data->host;
            data->host = NULL;
            return FALSE;
        } else if(**ptr == ']')
            inside_brackets = FALSE;
        else if(**ptr == '[')
            inside_brackets = TRUE;

        ++(*ptr);
    }

    if(has_start_bracket) {
        /* Make sure the last character of the host wasn't a ']'. */
        if(*(*ptr-1) == ']') {
            TRACE("(%p %p %x %x): Expected an IP literal inside of the host\n",
                ptr, data, flags, extras);
            *ptr = data->host;
            data->host = NULL;
            return FALSE;
        }
    }

    /* Don't overwrite our length if we found a port earlier. */
    if(!data->port)
        data->host_len = *ptr - data->host;

    /* If the host is empty, then it's an unknown host type. */
    if(data->host_len == 0 || is_res)
        data->host_type = Uri_HOST_UNKNOWN;
    else
        data->host_type = Uri_HOST_DNS;

    TRACE("(%p %p %x %x): Parsed reg-name. host=%s len=%d\n", ptr, data, flags, extras,
        debugstr_wn(data->host, data->host_len), data->host_len);
    return TRUE;
}

/* Attempts to parse an IPv6 address out of the URI.
 *
 * IPv6address =                               6( h16 ":" ) ls32
 *                /                       "::" 5( h16 ":" ) ls32
 *                / [               h16 ] "::" 4( h16 ":" ) ls32
 *                / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
 *                / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
 *                / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
 *                / [ *4( h16 ":" ) h16 ] "::"              ls32
 *                / [ *5( h16 ":" ) h16 ] "::"              h16
 *                / [ *6( h16 ":" ) h16 ] "::"
 *
 * ls32        = ( h16 ":" h16 ) / IPv4address
 *             ; least-significant 32 bits of address.
 *
 * h16         = 1*4HEXDIG
 *             ; 16 bits of address represented in hexadecimal.
 *
 * Modeled after google-url's 'DoParseIPv6' function.
 */
static BOOL parse_ipv6address(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const WCHAR *start, *cur_start;
    ipv6_address ip;

    start = cur_start = *ptr;
    memset(&ip, 0, sizeof(ipv6_address));

    for(;; ++(*ptr)) {
        /* Check if we're on the last character of the host. */
        BOOL is_end = (is_auth_delim(**ptr, data->scheme_type != URL_SCHEME_UNKNOWN)
                        || **ptr == ']');

        BOOL is_split = (**ptr == ':');
        BOOL is_elision = (is_split && !is_end && *(*ptr+1) == ':');

        /* Check if we're at the end of a component, or
         * if we're at the end of the IPv6 address.
         */
        if(is_split || is_end) {
            DWORD cur_len = 0;

            cur_len = *ptr - cur_start;

            /* h16 can't have a length > 4. */
            if(cur_len > 4) {
                *ptr = start;

                TRACE("(%p %p %x): h16 component to long.\n",
                    ptr, data, flags);
                return FALSE;
            }

            if(cur_len == 0) {
                /* An h16 component can't have the length of 0 unless
                 * the elision is at the beginning of the address, or
                 * at the end of the address.
                 */
                if(!((*ptr == start && is_elision) ||
                    (is_end && (*ptr-2) == ip.elision))) {
                    *ptr = start;
                    TRACE("(%p %p %x): IPv6 component cannot have a length of 0.\n",
                        ptr, data, flags);
                    return FALSE;
                }
            }

            if(cur_len > 0) {
                /* An IPv6 address can have no more than 8 h16 components. */
                if(ip.h16_count >= 8) {
                    *ptr = start;
                    TRACE("(%p %p %x): Not a IPv6 address, to many h16 components.\n",
                        ptr, data, flags);
                    return FALSE;
                }

                ip.components[ip.h16_count].str = cur_start;
                ip.components[ip.h16_count].len = cur_len;

                TRACE("(%p %p %x): Found h16 component %s, len=%d, h16_count=%d\n",
                    ptr, data, flags, debugstr_wn(cur_start, cur_len), cur_len,
                    ip.h16_count);
                ++ip.h16_count;
            }
        }

        if(is_end)
            break;

        if(is_elision) {
            /* A IPv6 address can only have 1 elision ('::'). */
            if(ip.elision) {
                *ptr = start;

                TRACE("(%p %p %x): IPv6 address cannot have 2 elisions.\n",
                    ptr, data, flags);
                return FALSE;
            }

            ip.elision = *ptr;
            ++(*ptr);
        }

        if(is_split)
            cur_start = *ptr+1;
        else {
            if(!check_ipv4address(ptr, TRUE)) {
                if(!is_hexdigit(**ptr)) {
                    /* Not a valid character for an IPv6 address. */
                    *ptr = start;
                    return FALSE;
                }
            } else {
                /* Found an IPv4 address. */
                ip.ipv4 = cur_start;
                ip.ipv4_len = *ptr - cur_start;

                TRACE("(%p %p %x): Found an attached IPv4 address %s len=%d.\n",
                    ptr, data, flags, debugstr_wn(ip.ipv4, ip.ipv4_len),
                    ip.ipv4_len);

                /* IPv4 addresses can only appear at the end of a IPv6. */
                break;
            }
        }
    }

    compute_ipv6_comps_size(&ip);

    /* Make sure the IPv6 address adds up to 16 bytes. */
    if(ip.components_size + ip.elision_size != 16) {
        *ptr = start;
        TRACE("(%p %p %x): Invalid IPv6 address, did not add up to 16 bytes.\n",
            ptr, data, flags);
        return FALSE;
    }

    if(ip.elision_size == 2) {
        /* For some reason on Windows if an elision that represents
         * only one h16 component is encountered at the very begin or
         * end of an IPv6 address, Windows does not consider it a
         * valid IPv6 address.
         *
         *  Ex: [::2:3:4:5:6:7] is not valid, even though the sum
         *      of all the components == 128bits.
         */
         if(ip.elision < ip.components[0].str ||
            ip.elision > ip.components[ip.h16_count-1].str) {
            *ptr = start;
            TRACE("(%p %p %x): Invalid IPv6 address. Detected elision of 2 bytes at the beginning or end of the address.\n",
                ptr, data, flags);
            return FALSE;
        }
    }

    data->host_type = Uri_HOST_IPV6;
    data->has_ipv6 = TRUE;
    data->ipv6_address = ip;

    TRACE("(%p %p %x): Found valid IPv6 literal %s len=%d\n",
        ptr, data, flags, debugstr_wn(start, *ptr-start),
        (int)(*ptr-start));
    return TRUE;
}

/*  IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) */
static BOOL parse_ipvfuture(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const WCHAR *start = *ptr;

    /* IPvFuture has to start with a 'v' or 'V'. */
    if(**ptr != 'v' && **ptr != 'V')
        return FALSE;

    /* Following the v there must be at least 1 hex digit. */
    ++(*ptr);
    if(!is_hexdigit(**ptr)) {
        *ptr = start;
        return FALSE;
    }

    ++(*ptr);
    while(is_hexdigit(**ptr))
        ++(*ptr);

    /* End of the hexdigit sequence must be a '.' */
    if(**ptr != '.') {
        *ptr = start;
        return FALSE;
    }

    ++(*ptr);
    if(!is_unreserved(**ptr) && !is_subdelim(**ptr) && **ptr != ':') {
        *ptr = start;
        return FALSE;
    }

    ++(*ptr);
    while(is_unreserved(**ptr) || is_subdelim(**ptr) || **ptr == ':')
        ++(*ptr);

    data->host_type = Uri_HOST_UNKNOWN;

    TRACE("(%p %p %x): Parsed IPvFuture address %s len=%d\n", ptr, data, flags,
          debugstr_wn(start, *ptr-start), (int)(*ptr-start));

    return TRUE;
}

/* IP-literal = "[" ( IPv6address / IPvFuture  ) "]" */
static BOOL parse_ip_literal(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
    data->host = *ptr;

    if(**ptr != '[' && !(extras & ALLOW_BRACKETLESS_IP_LITERAL)) {
        data->host = NULL;
        return FALSE;
    } else if(**ptr == '[')
        ++(*ptr);

    if(!parse_ipv6address(ptr, data, flags)) {
        if(extras & SKIP_IP_FUTURE_CHECK || !parse_ipvfuture(ptr, data, flags)) {
            *ptr = data->host;
            data->host = NULL;
            return FALSE;
        }
    }

    if(**ptr != ']' && !(extras & ALLOW_BRACKETLESS_IP_LITERAL)) {
        *ptr = data->host;
        data->host = NULL;
        return FALSE;
    } else if(!**ptr && extras & ALLOW_BRACKETLESS_IP_LITERAL) {
        /* The IP literal didn't contain brackets and was followed by
         * a NULL terminator, so no reason to even check the port.
         */
        data->host_len = *ptr - data->host;
        return TRUE;
    }

    ++(*ptr);
    if(**ptr == ':') {
        ++(*ptr);
        /* If a valid port is not found, then let it trickle down to
         * parse_reg_name.
         */
        if(!parse_port(ptr, data, flags)) {
            *ptr = data->host;
            data->host = NULL;
            return FALSE;
        }
    } else
        data->host_len = *ptr - data->host;

    return TRUE;
}

/* Parses the host information from the URI.
 *
 * host = IP-literal / IPv4address / reg-name
 */
static BOOL parse_host(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
    if(!parse_ip_literal(ptr, data, flags, extras)) {
        if(!parse_ipv4address(ptr, data, flags)) {
            if(!parse_reg_name(ptr, data, flags, extras)) {
                TRACE("(%p %p %x %x): Malformed URI, Unknown host type.\n",
                    ptr, data, flags, extras);
                return FALSE;
            }
        }
    }

    return TRUE;
}

/* Parses the authority information from the URI.
 *
 * authority   = [ userinfo "@" ] host [ ":" port ]
 */
static BOOL parse_authority(const WCHAR **ptr, parse_data *data, DWORD flags) {
    parse_userinfo(ptr, data, flags);

    /* Parsing the port will happen during one of the host parsing
     * routines (if the URI has a port).
     */
    if(!parse_host(ptr, data, flags, 0))
        return FALSE;

    return TRUE;
}

/* Attempts to parse the path information of a hierarchical URI. */
static BOOL parse_path_hierarchical(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const WCHAR *start = *ptr;
    static const WCHAR slash[] = {'/',0};
    const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;

    if(is_path_delim(**ptr)) {
        if(data->scheme_type == URL_SCHEME_WILDCARD && !data->must_have_path) {
            data->path = NULL;
            data->path_len = 0;
        } else if(!(flags & Uri_CREATE_NO_CANONICALIZE)) {
            /* If the path component is empty, then a '/' is added. */
            data->path = slash;
            data->path_len = 1;
        }
    } else {
        while(!is_path_delim(**ptr)) {
            if(**ptr == '%' && data->scheme_type != URL_SCHEME_UNKNOWN && !is_file) {
                if(!check_pct_encoded(ptr)) {
                    *ptr = start;
                    return FALSE;
                } else
                    continue;
            } else if(is_forbidden_dos_path_char(**ptr) && is_file &&
                      (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
                /* File schemes with USE_DOS_PATH set aren't allowed to have
                 * a '<' or '>' or '\"' appear in them.
                 */
                *ptr = start;
                return FALSE;
            } else if(**ptr == '\\') {
                /* Not allowed to have a backslash if NO_CANONICALIZE is set
                 * and the scheme is known type (but not a file scheme).
                 */
                if(flags & Uri_CREATE_NO_CANONICALIZE) {
                    if(data->scheme_type != URL_SCHEME_FILE &&
                       data->scheme_type != URL_SCHEME_UNKNOWN) {
                        *ptr = start;
                        return FALSE;
                    }
                }
            }

            ++(*ptr);
        }

        /* The only time a URI doesn't have a path is when
         * the NO_CANONICALIZE flag is set and the raw URI
         * didn't contain one.
         */
        if(*ptr == start) {
            data->path = NULL;
            data->path_len = 0;
        } else {
            data->path = start;
            data->path_len = *ptr - start;
        }
    }

    if(data->path)
        TRACE("(%p %p %x): Parsed path %s len=%d\n", ptr, data, flags,
            debugstr_wn(data->path, data->path_len), data->path_len);
    else
        TRACE("(%p %p %x): The URI contained no path\n", ptr, data, flags);

    return TRUE;
}

/* Parses the path of an opaque URI (much less strict then the parser
 * for a hierarchical URI).
 *
 * NOTE:
 *  Windows allows invalid % encoded data to appear in opaque URI paths
 *  for unknown scheme types.
 *
 *  File schemes with USE_DOS_PATH set aren't allowed to have '<', '>', or '\"'
 *  appear in them.
 */
static BOOL parse_path_opaque(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
    const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;

    data->path = *ptr;

    while(!is_path_delim(**ptr)) {
        if(**ptr == '%' && known_scheme) {
            if(!check_pct_encoded(ptr)) {
                *ptr = data->path;
                data->path = NULL;
                return FALSE;
            } else
                continue;
        } else if(is_forbidden_dos_path_char(**ptr) && is_file &&
                  (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
            *ptr = data->path;
            data->path = NULL;
            return FALSE;
        }

        ++(*ptr);
    }

    data->path_len = *ptr - data->path;
    TRACE("(%p %p %x): Parsed opaque URI path %s len=%d\n", ptr, data, flags,
        debugstr_wn(data->path, data->path_len), data->path_len);
    return TRUE;
}

/* Determines how the URI should be parsed after the scheme information.
 *
 * If the scheme is followed by "//", then it is treated as a hierarchical URI
 * which then the authority and path information will be parsed out. Otherwise, the
 * URI will be treated as an opaque URI which the authority information is not parsed
 * out.
 *
 * RFC 3896 definition of hier-part:
 *
 * hier-part   = "//" authority path-abempty
 *                 / path-absolute
 *                 / path-rootless
 *                 / path-empty
 *
 * MSDN opaque URI definition:
 *  scheme ":" path [ "#" fragment ]
 *
 * NOTES:
 *  If the URI is of an unknown scheme type and has a "//" following the scheme then it
 *  is treated as a hierarchical URI, but, if the CREATE_NO_CRACK_UNKNOWN_SCHEMES flag is
 *  set then it is considered an opaque URI regardless of what follows the scheme information
 *  (per MSDN documentation).
 */
static BOOL parse_hierpart(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const WCHAR *start = *ptr;

    data->must_have_path = FALSE;

    /* For javascript: URIs, simply set everything as a path */
    if(data->scheme_type == URL_SCHEME_JAVASCRIPT) {
        data->path = *ptr;
        data->path_len = strlenW(*ptr);
        data->is_opaque = TRUE;
        *ptr += data->path_len;
        return TRUE;
    }

    /* Checks if the authority information needs to be parsed. */
    if(is_hierarchical_uri(ptr, data)) {
        /* Only treat it as a hierarchical URI if the scheme_type is known or
         * the Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES flag is not set.
         */
        if(data->scheme_type != URL_SCHEME_UNKNOWN ||
           !(flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES)) {
            TRACE("(%p %p %x): Treating URI as an hierarchical URI.\n", ptr, data, flags);
            data->is_opaque = FALSE;

            if(data->scheme_type == URL_SCHEME_WILDCARD && !data->has_implicit_scheme) {
                if(**ptr == '/' && *(*ptr+1) == '/') {
                    data->must_have_path = TRUE;
                    *ptr += 2;
                }
            }

            /* TODO: Handle hierarchical URI's, parse authority then parse the path. */
            if(!parse_authority(ptr, data, flags))
                return FALSE;

            return parse_path_hierarchical(ptr, data, flags);
        } else
            /* Reset ptr to its starting position so opaque path parsing
             * begins at the correct location.
             */
            *ptr = start;
    }

    /* If it reaches here, then the URI will be treated as an opaque
     * URI.
     */

    TRACE("(%p %p %x): Treating URI as an opaque URI.\n", ptr, data, flags);

    data->is_opaque = TRUE;
    if(!parse_path_opaque(ptr, data, flags))
        return FALSE;

    return TRUE;
}

/* Attempts to parse the query string from the URI.
 *
 * NOTES:
 *  If NO_DECODE_EXTRA_INFO flag is set, then invalid percent encoded
 *  data is allowed to appear in the query string. For unknown scheme types
 *  invalid percent encoded data is allowed to appear regardless.
 */
static BOOL parse_query(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;

    if(**ptr != '?') {
        TRACE("(%p %p %x): URI didn't contain a query string.\n", ptr, data, flags);
        return TRUE;
    }

    data->query = *ptr;

    ++(*ptr);
    while(**ptr && **ptr != '#') {
        if(**ptr == '%' && known_scheme &&
           !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
            if(!check_pct_encoded(ptr)) {
                *ptr = data->query;
                data->query = NULL;
                return FALSE;
            } else
                continue;
        }

        ++(*ptr);
    }

    data->query_len = *ptr - data->query;

    TRACE("(%p %p %x): Parsed query string %s len=%d\n", ptr, data, flags,
        debugstr_wn(data->query, data->query_len), data->query_len);
    return TRUE;
}

/* Attempts to parse the fragment from the URI.
 *
 * NOTES:
 *  If NO_DECODE_EXTRA_INFO flag is set, then invalid percent encoded
 *  data is allowed to appear in the query string. For unknown scheme types
 *  invalid percent encoded data is allowed to appear regardless.
 */
static BOOL parse_fragment(const WCHAR **ptr, parse_data *data, DWORD flags) {
    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;

    if(**ptr != '#') {
        TRACE("(%p %p %x): URI didn't contain a fragment.\n", ptr, data, flags);
        return TRUE;
    }

    data->fragment = *ptr;

    ++(*ptr);
    while(**ptr) {
        if(**ptr == '%' && known_scheme &&
           !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
            if(!check_pct_encoded(ptr)) {
                *ptr = data->fragment;
                data->fragment = NULL;
                return FALSE;
            } else
                continue;
        }

        ++(*ptr);
    }

    data->fragment_len = *ptr - data->fragment;

    TRACE("(%p %p %x): Parsed fragment %s len=%d\n", ptr, data, flags,
        debugstr_wn(data->fragment, data->fragment_len), data->fragment_len);
    return TRUE;
}

/* Parses and validates the components of the specified by data->uri
 * and stores the information it parses into 'data'.
 *
 * Returns TRUE if it successfully parsed the URI. False otherwise.
 */
static BOOL parse_uri(parse_data *data, DWORD flags) {
    const WCHAR *ptr;
    const WCHAR **pptr;

    ptr = data->uri;
    pptr = &ptr;

    TRACE("(%p %x): BEGINNING TO PARSE URI %s.\n", data, flags, debugstr_w(data->uri));

    if(!parse_scheme(pptr, data, flags, 0))
        return FALSE;

    if(!parse_hierpart(pptr, data, flags))
        return FALSE;

    if(!parse_query(pptr, data, flags))
        return FALSE;

    if(!parse_fragment(pptr, data, flags))
        return FALSE;

    TRACE("(%p %x): FINISHED PARSING URI.\n", data, flags);
    return TRUE;
}

static BOOL canonicalize_username(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    const WCHAR *ptr;

    if(!data->username) {
        uri->userinfo_start = -1;
        return TRUE;
    }

    uri->userinfo_start = uri->canon_len;
    for(ptr = data->username; ptr < data->username+data->username_len; ++ptr) {
        if(*ptr == '%') {
            /* Only decode % encoded values for known scheme types. */
            if(data->scheme_type != URL_SCHEME_UNKNOWN) {
                /* See if the value really needs decoding. */
                WCHAR val = decode_pct_val(ptr);
                if(is_unreserved(val)) {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = val;

                    ++uri->canon_len;

                    /* Move pass the hex characters. */
                    ptr += 2;
                    continue;
                }
            }
        } else if(!is_reserved(*ptr) && !is_unreserved(*ptr) && *ptr != '\\') {
            /* Only percent encode forbidden characters if the NO_ENCODE_FORBIDDEN_CHARACTERS flag
             * is NOT set.
             */
            if(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS)) {
                if(!computeOnly)
                    pct_encode_val(*ptr, uri->canon_uri + uri->canon_len);

                uri->canon_len += 3;
                continue;
            }
        }

        if(!computeOnly)
            /* Nothing special, so just copy the character over. */
            uri->canon_uri[uri->canon_len] = *ptr;
        ++uri->canon_len;
    }

    return TRUE;
}

static BOOL canonicalize_password(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    const WCHAR *ptr;

    if(!data->password) {
        uri->userinfo_split = -1;
        return TRUE;
    }

    if(uri->userinfo_start == -1)
        /* Has a password, but, doesn't have a username. */
        uri->userinfo_start = uri->canon_len;

    uri->userinfo_split = uri->canon_len - uri->userinfo_start;

    /* Add the ':' to the userinfo component. */
    if(!computeOnly)
        uri->canon_uri[uri->canon_len] = ':';
    ++uri->canon_len;

    for(ptr = data->password; ptr < data->password+data->password_len; ++ptr) {
        if(*ptr == '%') {
            /* Only decode % encoded values for known scheme types. */
            if(data->scheme_type != URL_SCHEME_UNKNOWN) {
                /* See if the value really needs decoding. */
                WCHAR val = decode_pct_val(ptr);
                if(is_unreserved(val)) {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = val;

                    ++uri->canon_len;

                    /* Move pass the hex characters. */
                    ptr += 2;
                    continue;
                }
            }
        } else if(!is_reserved(*ptr) && !is_unreserved(*ptr) && *ptr != '\\') {
            /* Only percent encode forbidden characters if the NO_ENCODE_FORBIDDEN_CHARACTERS flag
             * is NOT set.
             */
            if(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS)) {
                if(!computeOnly)
                    pct_encode_val(*ptr, uri->canon_uri + uri->canon_len);

                uri->canon_len += 3;
                continue;
            }
        }

        if(!computeOnly)
            /* Nothing special, so just copy the character over. */
            uri->canon_uri[uri->canon_len] = *ptr;
        ++uri->canon_len;
    }

    return TRUE;
}

/* Canonicalizes the userinfo of the URI represented by the parse_data.
 *
 * Canonicalization of the userinfo is a simple process. If there are any percent
 * encoded characters that fall in the "unreserved" character set, they are decoded
 * to their actual value. If a character is not in the "unreserved" or "reserved" sets
 * then it is percent encoded. Other than that the characters are copied over without
 * change.
 */
static BOOL canonicalize_userinfo(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    uri->userinfo_start = uri->userinfo_split = -1;
    uri->userinfo_len = 0;

    if(!data->username && !data->password)
        /* URI doesn't have userinfo, so nothing to do here. */
        return TRUE;

    if(!canonicalize_username(data, uri, flags, computeOnly))
        return FALSE;

    if(!canonicalize_password(data, uri, flags, computeOnly))
        return FALSE;

    uri->userinfo_len = uri->canon_len - uri->userinfo_start;
    if(!computeOnly)
        TRACE("(%p %p %x %d): Canonicalized userinfo, userinfo_start=%d, userinfo=%s, userinfo_split=%d userinfo_len=%d.\n",
                data, uri, flags, computeOnly, uri->userinfo_start, debugstr_wn(uri->canon_uri + uri->userinfo_start, uri->userinfo_len),
                uri->userinfo_split, uri->userinfo_len);

    /* Now insert the '@' after the userinfo. */
    if(!computeOnly)
        uri->canon_uri[uri->canon_len] = '@';
    ++uri->canon_len;

    return TRUE;
}

/* Attempts to canonicalize a reg_name.
 *
 * Things that happen:
 *  1)  If Uri_CREATE_NO_CANONICALIZE flag is not set, then the reg_name is
 *      lower cased. Unless it's an unknown scheme type, which case it's
 *      no lower cased regardless.
 *
 *  2)  Unreserved % encoded characters are decoded for known
 *      scheme types.
 *
 *  3)  Forbidden characters are % encoded as long as
 *      Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS flag is not set and
 *      it isn't an unknown scheme type.
 *
 *  4)  If it's a file scheme and the host is "localhost" it's removed.
 *
 *  5)  If it's a file scheme and Uri_CREATE_FILE_USE_DOS_PATH is set,
 *      then the UNC path characters are added before the host name.
 */
static BOOL canonicalize_reg_name(const parse_data *data, Uri *uri,
                                  DWORD flags, BOOL computeOnly) {
    static const WCHAR localhostW[] =
            {'l','o','c','a','l','h','o','s','t',0};
    const WCHAR *ptr;
    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;

    if(data->scheme_type == URL_SCHEME_FILE &&
       data->host_len == lstrlenW(localhostW)) {
        if(!StrCmpNIW(data->host, localhostW, data->host_len)) {
            uri->host_start = -1;
            uri->host_len = 0;
            uri->host_type = Uri_HOST_UNKNOWN;
            return TRUE;
        }
    }

    if(data->scheme_type == URL_SCHEME_FILE && flags & Uri_CREATE_FILE_USE_DOS_PATH) {
        if(!computeOnly) {
            uri->canon_uri[uri->canon_len] = '\\';
            uri->canon_uri[uri->canon_len+1] = '\\';
        }
        uri->canon_len += 2;
        uri->authority_start = uri->canon_len;
    }

    uri->host_start = uri->canon_len;

    for(ptr = data->host; ptr < data->host+data->host_len; ++ptr) {
        if(*ptr == '%' && known_scheme) {
            WCHAR val = decode_pct_val(ptr);
            if(is_unreserved(val)) {
                /* If NO_CANONICALIZE is not set, then windows lower cases the
                 * decoded value.
                 */
                if(!(flags & Uri_CREATE_NO_CANONICALIZE) && isupperW(val)) {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = tolowerW(val);
                } else {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = val;
                }
                ++uri->canon_len;

                /* Skip past the % encoded character. */
                ptr += 2;
                continue;
            } else {
                /* Just copy the % over. */
                if(!computeOnly)
                    uri->canon_uri[uri->canon_len] = *ptr;
                ++uri->canon_len;
            }
        } else if(*ptr == '\\') {
            /* Only unknown scheme types could have made it here with a '\\' in the host name. */
            if(!computeOnly)
                uri->canon_uri[uri->canon_len] = *ptr;
            ++uri->canon_len;
        } else if(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) &&
                  !is_unreserved(*ptr) && !is_reserved(*ptr) && known_scheme) {
            if(!computeOnly) {
                pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);

                /* The percent encoded value gets lower cased also. */
                if(!(flags & Uri_CREATE_NO_CANONICALIZE)) {
                    uri->canon_uri[uri->canon_len+1] = tolowerW(uri->canon_uri[uri->canon_len+1]);
                    uri->canon_uri[uri->canon_len+2] = tolowerW(uri->canon_uri[uri->canon_len+2]);
                }
            }

            uri->canon_len += 3;
        } else {
            if(!computeOnly) {
                if(!(flags & Uri_CREATE_NO_CANONICALIZE) && known_scheme)
                    uri->canon_uri[uri->canon_len] = tolowerW(*ptr);
                else
                    uri->canon_uri[uri->canon_len] = *ptr;
            }

            ++uri->canon_len;
        }
    }

    uri->host_len = uri->canon_len - uri->host_start;

    if(!computeOnly)
        TRACE("(%p %p %x %d): Canonicalize reg_name=%s len=%d\n", data, uri, flags,
            computeOnly, debugstr_wn(uri->canon_uri+uri->host_start, uri->host_len),
            uri->host_len);

    if(!computeOnly)
        find_domain_name(uri->canon_uri+uri->host_start, uri->host_len,
            &(uri->domain_offset));

    return TRUE;
}

/* Attempts to canonicalize an implicit IPv4 address. */
static BOOL canonicalize_implicit_ipv4address(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    uri->host_start = uri->canon_len;

    TRACE("%u\n", data->implicit_ipv4);
    /* For unknown scheme types Windows doesn't convert
     * the value into an IP address, but it still considers
     * it an IPv4 address.
     */
    if(data->scheme_type == URL_SCHEME_UNKNOWN) {
        if(!computeOnly)
            memcpy(uri->canon_uri+uri->canon_len, data->host, data->host_len*sizeof(WCHAR));
        uri->canon_len += data->host_len;
    } else {
        if(!computeOnly)
            uri->canon_len += ui2ipv4(uri->canon_uri+uri->canon_len, data->implicit_ipv4);
        else
            uri->canon_len += ui2ipv4(NULL, data->implicit_ipv4);
    }

    uri->host_len = uri->canon_len - uri->host_start;
    uri->host_type = Uri_HOST_IPV4;

    if(!computeOnly)
        TRACE("%p %p %x %d): Canonicalized implicit IP address=%s len=%d\n",
            data, uri, flags, computeOnly,
            debugstr_wn(uri->canon_uri+uri->host_start, uri->host_len),
            uri->host_len);

    return TRUE;
}

/* Attempts to canonicalize an IPv4 address.
 *
 * If the parse_data represents a URI that has an implicit IPv4 address
 * (ex. http://256/, this function will convert 256 into 0.0.1.0). If
 * the implicit IP address exceeds the value of UINT_MAX (maximum value
 * for an IPv4 address) it's canonicalized as if it were a reg-name.
 *
 * If the parse_data contains a partial or full IPv4 address it normalizes it.
 * A partial IPv4 address is something like "192.0" and would be normalized to
 * "192.0.0.0". With a full (or partial) IPv4 address like "192.002.01.003" would
 * be normalized to "192.2.1.3".
 *
 * NOTES:
 *  Windows ONLY normalizes IPv4 address for known scheme types (one that isn't
 *  URL_SCHEME_UNKNOWN). For unknown scheme types, it simply copies the data from
 *  the original URI into the canonicalized URI, but, it still recognizes URI's
 *  host type as HOST_IPV4.
 */
static BOOL canonicalize_ipv4address(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    if(data->has_implicit_ip)
        return canonicalize_implicit_ipv4address(data, uri, flags, computeOnly);
    else {
        uri->host_start = uri->canon_len;

        /* Windows only normalizes for known scheme types. */
        if(data->scheme_type != URL_SCHEME_UNKNOWN) {
            /* parse_data contains a partial or full IPv4 address, so normalize it. */
            DWORD i, octetDigitCount = 0, octetCount = 0;
            BOOL octetHasDigit = FALSE;

            for(i = 0; i < data->host_len; ++i) {
                if(data->host[i] == '0' && !octetHasDigit) {
                    /* Can ignore leading zeros if:
                     *  1) It isn't the last digit of the octet.
                     *  2) i+1 != data->host_len
                     *  3) i+1 != '.'
                     */
                    if(octetDigitCount == 2 ||
                       i+1 == data->host_len ||
                       data->host[i+1] == '.') {
                        if(!computeOnly)
                            uri->canon_uri[uri->canon_len] = data->host[i];
                        ++uri->canon_len;
                        TRACE("Adding zero\n");
                    }
                } else if(data->host[i] == '.') {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = data->host[i];
                    ++uri->canon_len;

                    octetDigitCount = 0;
                    octetHasDigit = FALSE;
                    ++octetCount;
                } else {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = data->host[i];
                    ++uri->canon_len;

                    ++octetDigitCount;
                    octetHasDigit = TRUE;
                }
            }

            /* Make sure the canonicalized IP address has 4 dec-octets.
             * If doesn't add "0" ones until there is 4;
             */
            for( ; octetCount < 3; ++octetCount) {
                if(!computeOnly) {
                    uri->canon_uri[uri->canon_len] = '.';
                    uri->canon_uri[uri->canon_len+1] = '0';
                }

                uri->canon_len += 2;
            }
        } else {
            /* Windows doesn't normalize addresses in unknown schemes. */
            if(!computeOnly)
                memcpy(uri->canon_uri+uri->canon_len, data->host, data->host_len*sizeof(WCHAR));
            uri->canon_len += data->host_len;
        }

        uri->host_len = uri->canon_len - uri->host_start;
        if(!computeOnly)
            TRACE("(%p %p %x %d): Canonicalized IPv4 address, ip=%s len=%d\n",
                data, uri, flags, computeOnly,
                debugstr_wn(uri->canon_uri+uri->host_start, uri->host_len),
                uri->host_len);
    }

    return TRUE;
}

/* Attempts to canonicalize the IPv6 address of the URI.
 *
 * Multiple things happen during the canonicalization of an IPv6 address:
 *  1)  Any leading zero's in a h16 component are removed.
 *      Ex: [0001:0022::] -> [1:22::]
 *
 *  2)  The longest sequence of zero h16 components are compressed
 *      into a "::" (elision). If there's a tie, the first is chosen.
 *
 *      Ex: [0:0:0:0:1:6:7:8]   -> [::1:6:7:8]
 *          [0:0:0:0:1:2::]     -> [::1:2:0:0]
 *          [0:0:1:2:0:0:7:8]   -> [::1:2:0:0:7:8]
 *
 *  3)  If an IPv4 address is attached to the IPv6 address, it's
 *      also normalized.
 *      Ex: [::001.002.022.000] -> [::1.2.22.0]
 *
 *  4)  If an elision is present, but, only represents one h16 component
 *      it's expanded.
 *
 *      Ex: [1::2:3:4:5:6:7] -> [1:0:2:3:4:5:6:7]
 *
 *  5)  If the IPv6 address contains an IPv4 address and there exists
 *      at least 1 non-zero h16 component the IPv4 address is converted
 *      into two h16 components, otherwise it's normalized and kept as is.
 *
 *      Ex: [::192.200.003.4]       -> [::192.200.3.4]
 *          [ffff::192.200.003.4]   -> [ffff::c0c8:3041]
 *
 * NOTE:
 *  For unknown scheme types Windows simply copies the address over without any
 *  changes.
 *
 *  IPv4 address can be included in an elision if all its components are 0's.
 */
static BOOL canonicalize_ipv6address(const parse_data *data, Uri *uri,
                                     DWORD flags, BOOL computeOnly) {
    uri->host_start = uri->canon_len;

    if(data->scheme_type == URL_SCHEME_UNKNOWN) {
        if(!computeOnly)
            memcpy(uri->canon_uri+uri->canon_len, data->host, data->host_len*sizeof(WCHAR));
        uri->canon_len += data->host_len;
    } else {
        USHORT values[8];
        INT elision_start;
        DWORD i, elision_len;

        if(!ipv6_to_number(&(data->ipv6_address), values)) {
            TRACE("(%p %p %x %d): Failed to compute numerical value for IPv6 address.\n",
                data, uri, flags, computeOnly);
            return FALSE;
        }

        if(!computeOnly)
            uri->canon_uri[uri->canon_len] = '[';
        ++uri->canon_len;

        /* Find where the elision should occur (if any). */
        compute_elision_location(&(data->ipv6_address), values, &elision_start, &elision_len);

        TRACE("%p %p %x %d): Elision starts at %d, len=%u\n", data, uri, flags,
            computeOnly, elision_start, elision_len);

        for(i = 0; i < 8; ++i) {
            BOOL in_elision = (elision_start > -1 && i >= elision_start &&
                               i < elision_start+elision_len);
            BOOL do_ipv4 = (i == 6 && data->ipv6_address.ipv4 && !in_elision &&
                            data->ipv6_address.h16_count == 0);

            if(i == elision_start) {
                if(!computeOnly) {
                    uri->canon_uri[uri->canon_len] = ':';
                    uri->canon_uri[uri->canon_len+1] = ':';
                }
                uri->canon_len += 2;
            }

            /* We can ignore the current component if we're in the elision. */
            if(in_elision)
                continue;

            /* We only add a ':' if we're not at i == 0, or when we're at
             * the very end of elision range since the ':' colon was handled
             * earlier. Otherwise we would end up with ":::" after elision.
             */
            if(i != 0 && !(elision_start > -1 && i == elision_start+elision_len)) {
                if(!computeOnly)
                    uri->canon_uri[uri->canon_len] = ':';
                ++uri->canon_len;
            }

            if(do_ipv4) {
                UINT val;
                DWORD len;

                /* Combine the two parts of the IPv4 address values. */
                val = values[i];
                val <<= 16;
                val += values[i+1];

                if(!computeOnly)
                    len = ui2ipv4(uri->canon_uri+uri->canon_len, val);
                else
                    len = ui2ipv4(NULL, val);

                uri->canon_len += len;
                ++i;
            } else {
                /* Write a regular h16 component to the URI. */

                /* Short circuit for the trivial case. */
                if(values[i] == 0) {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = '0';
                    ++uri->canon_len;
                } else {
                    static const WCHAR formatW[] = {'%','x',0};

                    if(!computeOnly)
                        uri->canon_len += sprintfW(uri->canon_uri+uri->canon_len,
                                            formatW, values[i]);
                    else {
                        WCHAR tmp[5];
                        uri->canon_len += sprintfW(tmp, formatW, values[i]);
                    }
                }
            }
        }

        /* Add the closing ']'. */
        if(!computeOnly)
            uri->canon_uri[uri->canon_len] = ']';
        ++uri->canon_len;
    }

    uri->host_len = uri->canon_len - uri->host_start;

    if(!computeOnly)
        TRACE("(%p %p %x %d): Canonicalized IPv6 address %s, len=%d\n", data, uri, flags,
            computeOnly, debugstr_wn(uri->canon_uri+uri->host_start, uri->host_len),
            uri->host_len);

    return TRUE;
}

/* Attempts to canonicalize the host of the URI (if any). */
static BOOL canonicalize_host(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    uri->host_start = -1;
    uri->host_len = 0;
    uri->domain_offset = -1;

    if(data->host) {
        switch(data->host_type) {
        case Uri_HOST_DNS:
            uri->host_type = Uri_HOST_DNS;
            if(!canonicalize_reg_name(data, uri, flags, computeOnly))
                return FALSE;

            break;
        case Uri_HOST_IPV4:
            uri->host_type = Uri_HOST_IPV4;
            if(!canonicalize_ipv4address(data, uri, flags, computeOnly))
                return FALSE;

            break;
        case Uri_HOST_IPV6:
            if(!canonicalize_ipv6address(data, uri, flags, computeOnly))
                return FALSE;

            uri->host_type = Uri_HOST_IPV6;
            break;
        case Uri_HOST_UNKNOWN:
            if(data->host_len > 0 || data->scheme_type != URL_SCHEME_FILE) {
                uri->host_start = uri->canon_len;

                /* Nothing happens to unknown host types. */
                if(!computeOnly)
                    memcpy(uri->canon_uri+uri->canon_len, data->host, data->host_len*sizeof(WCHAR));
                uri->canon_len += data->host_len;
                uri->host_len = data->host_len;
            }

            uri->host_type = Uri_HOST_UNKNOWN;
            break;
        default:
            FIXME("(%p %p %x %d): Canonicalization for host type %d not supported.\n", data,
                    uri, flags, computeOnly, data->host_type);
            return FALSE;
       }
   }

   return TRUE;
}

static BOOL canonicalize_port(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    BOOL has_default_port = FALSE;
    USHORT default_port = 0;
    DWORD i;

    uri->port_offset = -1;

    /* Check if the scheme has a default port. */
    for(i = 0; i < sizeof(default_ports)/sizeof(default_ports[0]); ++i) {
        if(default_ports[i].scheme == data->scheme_type) {
            has_default_port = TRUE;
            default_port = default_ports[i].port;
            break;
        }
    }

    uri->has_port = data->has_port || has_default_port;

    /* Possible cases:
     *  1)  Has a port which is the default port.
     *  2)  Has a port (not the default).
     *  3)  Doesn't have a port, but, scheme has a default port.
     *  4)  No port.
     */
    if(has_default_port && data->has_port && data->port_value == default_port) {
        /* If it's the default port and this flag isn't set, don't do anything. */
        if(flags & Uri_CREATE_NO_CANONICALIZE) {
            uri->port_offset = uri->canon_len-uri->authority_start;
            if(!computeOnly)
                uri->canon_uri[uri->canon_len] = ':';
            ++uri->canon_len;

            if(data->port) {
                /* Copy the original port over. */
                if(!computeOnly)
                    memcpy(uri->canon_uri+uri->canon_len, data->port, data->port_len*sizeof(WCHAR));
                uri->canon_len += data->port_len;
            } else {
                if(!computeOnly)
                    uri->canon_len += ui2str(uri->canon_uri+uri->canon_len, data->port_value);
                else
                    uri->canon_len += ui2str(NULL, data->port_value);
            }
        }

        uri->port = default_port;
    } else if(data->has_port) {
        uri->port_offset = uri->canon_len-uri->authority_start;
        if(!computeOnly)
            uri->canon_uri[uri->canon_len] = ':';
        ++uri->canon_len;

        if(flags & Uri_CREATE_NO_CANONICALIZE && data->port) {
            /* Copy the original over without changes. */
            if(!computeOnly)
                memcpy(uri->canon_uri+uri->canon_len, data->port, data->port_len*sizeof(WCHAR));
            uri->canon_len += data->port_len;
        } else {
            if(!computeOnly)
                uri->canon_len += ui2str(uri->canon_uri+uri->canon_len, data->port_value);
            else
                uri->canon_len += ui2str(NULL, data->port_value);
        }

        uri->port = data->port_value;
    } else if(has_default_port)
        uri->port = default_port;

    return TRUE;
}

/* Canonicalizes the authority of the URI represented by the parse_data. */
static BOOL canonicalize_authority(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    uri->authority_start = uri->canon_len;
    uri->authority_len = 0;

    if(!canonicalize_userinfo(data, uri, flags, computeOnly))
        return FALSE;

    if(!canonicalize_host(data, uri, flags, computeOnly))
        return FALSE;

    if(!canonicalize_port(data, uri, flags, computeOnly))
        return FALSE;

    if(uri->host_start != -1 || (data->is_relative && (data->password || data->username)))
        uri->authority_len = uri->canon_len - uri->authority_start;
    else
        uri->authority_start = -1;

    return TRUE;
}

/* Attempts to canonicalize the path of a hierarchical URI.
 *
 * Things that happen:
 *  1). Forbidden characters are percent encoded, unless the NO_ENCODE_FORBIDDEN
 *      flag is set or it's a file URI. Forbidden characters are always encoded
 *      for file schemes regardless and forbidden characters are never encoded
 *      for unknown scheme types.
 *
 *  2). For known scheme types '\\' are changed to '/'.
 *
 *  3). Percent encoded, unreserved characters are decoded to their actual values.
 *      Unless the scheme type is unknown. For file schemes any percent encoded
 *      character in the unreserved or reserved set is decoded.
 *
 *  4). For File schemes if the path is starts with a drive letter and doesn't
 *      start with a '/' then one is appended.
 *      Ex: file://c:/test.mp3 -> file:///c:/test.mp3
 *
 *  5). Dot segments are removed from the path for all scheme types
 *      unless NO_CANONICALIZE flag is set. Dot segments aren't removed
 *      for wildcard scheme types.
 *
 * NOTES:
 *      file://c:/test%20test   -> file:///c:/test%2520test
 *      file://c:/test%3Etest   -> file:///c:/test%253Etest
 * if Uri_CREATE_FILE_USE_DOS_PATH is not set:
 *      file:///c:/test%20test  -> file:///c:/test%20test
 *      file:///c:/test%test    -> file:///c:/test%25test
 */
static DWORD canonicalize_path_hierarchical(const WCHAR *path, DWORD path_len, URL_SCHEME scheme_type, BOOL has_host, DWORD flags,
        WCHAR *ret_path) {
    const BOOL known_scheme = scheme_type != URL_SCHEME_UNKNOWN;
    const BOOL is_file = scheme_type == URL_SCHEME_FILE;
    const BOOL is_res = scheme_type == URL_SCHEME_RES;
    const WCHAR *ptr;
    BOOL escape_pct = FALSE;
    DWORD len = 0;

    if(!path)
        return 0;

    ptr = path;

    if(is_file && !has_host) {
        /* Check if a '/' needs to be appended for the file scheme. */
        if(path_len > 1 && is_drive_path(ptr) && !(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
            if(ret_path)
                ret_path[len] = '/';
            len++;
            escape_pct = TRUE;
        } else if(*ptr == '/') {
            if(!(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
                /* Copy the extra '/' over. */
                if(ret_path)
                    ret_path[len] = '/';
                len++;
            }
            ++ptr;
        }

        if(is_drive_path(ptr)) {
            if(ret_path) {
                ret_path[len] = *ptr;
                /* If there's a '|' after the drive letter, convert it to a ':'. */
                ret_path[len+1] = ':';
            }
            ptr += 2;
            len += 2;
        }
    }

    if(!is_file && *path && *path != '/') {
        /* Prepend a '/' to the path if it doesn't have one. */
        if(ret_path)
            ret_path[len] = '/';
        len++;
    }

    for(; ptr < path+path_len; ++ptr) {
        BOOL do_default_action = TRUE;

        if(*ptr == '%' && !is_res) {
            const WCHAR *tmp = ptr;
            WCHAR val;

            /* Check if the % represents a valid encoded char, or if it needs encoding. */
            BOOL force_encode = !check_pct_encoded(&tmp) && is_file && !(flags&Uri_CREATE_FILE_USE_DOS_PATH);
            val = decode_pct_val(ptr);

            if(force_encode || escape_pct) {
                /* Escape the percent sign in the file URI. */
                if(ret_path)
                    pct_encode_val(*ptr, ret_path+len);
                len += 3;
                do_default_action = FALSE;
            } else if((is_unreserved(val) && known_scheme) ||
                      (is_file && (is_unreserved(val) || is_reserved(val) ||
                      (val && flags&Uri_CREATE_FILE_USE_DOS_PATH && !is_forbidden_dos_path_char(val))))) {
                if(ret_path)
                    ret_path[len] = val;
                len++;

                ptr += 2;
                continue;
            }
        } else if(*ptr == '/' && is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
            /* Convert the '/' back to a '\\'. */
            if(ret_path)
                ret_path[len] = '\\';
            len++;
            do_default_action = FALSE;
        } else if(*ptr == '\\' && known_scheme) {
            if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH))) {
                /* Convert '\\' into a '/'. */
                if(ret_path)
                    ret_path[len] = '/';
                len++;
                do_default_action = FALSE;
            }
        } else if(known_scheme && !is_res && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
                  (!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) || is_file)) {
            if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH))) {
                /* Escape the forbidden character. */
                if(ret_path)
                    pct_encode_val(*ptr, ret_path+len);
                len += 3;
                do_default_action = FALSE;
            }
        }

        if(do_default_action) {
            if(ret_path)
                ret_path[len] = *ptr;
            len++;
        }
    }

    /* Removing the dot segments only happens when it's not in
     * computeOnly mode and it's not a wildcard scheme. File schemes
     * with USE_DOS_PATH set don't get dot segments removed.
     */
    if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) &&
       scheme_type != URL_SCHEME_WILDCARD) {
        if(!(flags & Uri_CREATE_NO_CANONICALIZE) && ret_path) {
            /* Remove the dot segments (if any) and reset everything to the new
             * correct length.
             */
            len = remove_dot_segments(ret_path, len);
        }
    }

    if(ret_path)
        TRACE("Canonicalized path %s len=%d\n", debugstr_wn(ret_path, len), len);
    return len;
}

/* Attempts to canonicalize the path for an opaque URI.
 *
 * For known scheme types:
 *  1)  forbidden characters are percent encoded if
 *      NO_ENCODE_FORBIDDEN_CHARACTERS isn't set.
 *
 *  2)  Percent encoded, unreserved characters are decoded
 *      to their actual values, for known scheme types.
 *
 *  3)  '\\' are changed to '/' for known scheme types
 *      except for mailto schemes.
 *
 *  4)  For file schemes, if USE_DOS_PATH is set all '/'
 *      are converted to backslashes.
 *
 *  5)  For file schemes, if USE_DOS_PATH isn't set all '\'
 *      are converted to forward slashes.
 */
static BOOL canonicalize_path_opaque(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    const WCHAR *ptr;
    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
    const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;
    const BOOL is_mk = data->scheme_type == URL_SCHEME_MK;

    if(!data->path) {
        uri->path_start = -1;
        uri->path_len = 0;
        return TRUE;
    }

    uri->path_start = uri->canon_len;

    if(is_mk){
        /* hijack this flag for SCHEME_MK to tell the function when to start
         * converting slashes */
        flags |= Uri_CREATE_FILE_USE_DOS_PATH;
    }

    /* For javascript: URIs, simply copy path part without any canonicalization */
    if(data->scheme_type == URL_SCHEME_JAVASCRIPT) {
        if(!computeOnly)
            memcpy(uri->canon_uri+uri->canon_len, data->path, data->path_len*sizeof(WCHAR));
        uri->path_len = data->path_len;
        uri->canon_len += data->path_len;
        return TRUE;
    }

    /* Windows doesn't allow a "//" to appear after the scheme
     * of a URI, if it's an opaque URI.
     */
    if(data->scheme && *(data->path) == '/' && *(data->path+1) == '/') {
        /* So it inserts a "/." before the "//" if it exists. */
        if(!computeOnly) {
            uri->canon_uri[uri->canon_len] = '/';
            uri->canon_uri[uri->canon_len+1] = '.';
        }

        uri->canon_len += 2;
    }

    for(ptr = data->path; ptr < data->path+data->path_len; ++ptr) {
        BOOL do_default_action = TRUE;

        if(*ptr == '%' && known_scheme) {
            WCHAR val = decode_pct_val(ptr);

            if(is_unreserved(val)) {
                if(!computeOnly)
                    uri->canon_uri[uri->canon_len] = val;
                ++uri->canon_len;

                ptr += 2;
                continue;
            }
        } else if(*ptr == '/' && is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
            if(!computeOnly)
                uri->canon_uri[uri->canon_len] = '\\';
            ++uri->canon_len;
            do_default_action = FALSE;
        } else if(*ptr == '\\') {
            if((data->is_relative || is_mk || is_file) && !(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
                /* Convert to a '/'. */
                if(!computeOnly)
                    uri->canon_uri[uri->canon_len] = '/';
                ++uri->canon_len;
                do_default_action = FALSE;
            }
        } else if(is_mk && *ptr == ':' && ptr + 1 < data->path + data->path_len && *(ptr + 1) == ':') {
            flags &= ~Uri_CREATE_FILE_USE_DOS_PATH;
        } else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
                  !(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS)) {
            if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH))) {
                if(!computeOnly)
                    pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
                uri->canon_len += 3;
                do_default_action = FALSE;
            }
        }

        if(do_default_action) {
            if(!computeOnly)
                uri->canon_uri[uri->canon_len] = *ptr;
            ++uri->canon_len;
        }
    }

    if(is_mk && !computeOnly && !(flags & Uri_CREATE_NO_CANONICALIZE)) {
        DWORD new_len = remove_dot_segments(uri->canon_uri + uri->path_start,
                                            uri->canon_len - uri->path_start);
        uri->canon_len = uri->path_start + new_len;
    }

    uri->path_len = uri->canon_len - uri->path_start;

    if(!computeOnly)
        TRACE("(%p %p %x %d): Canonicalized opaque URI path %s len=%d\n", data, uri, flags, computeOnly,
            debugstr_wn(uri->canon_uri+uri->path_start, uri->path_len), uri->path_len);
    return TRUE;
}

/* Determines how the URI represented by the parse_data should be canonicalized.
 *
 * Essentially, if the parse_data represents an hierarchical URI then it calls
 * canonicalize_authority and the canonicalization functions for the path. If the
 * URI is opaque it canonicalizes the path of the URI.
 */
static BOOL canonicalize_hierpart(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    if(!data->is_opaque || (data->is_relative && (data->password || data->username))) {
        /* "//" is only added for non-wildcard scheme types.
         *
         * A "//" is only added to a relative URI if it has a
         * host or port component (this only happens if a IUriBuilder
         * is generating an IUri).
         */
        if((data->is_relative && (data->host || data->has_port)) ||
           (!data->is_relative && data->scheme_type != URL_SCHEME_WILDCARD)) {
            if(data->scheme_type == URL_SCHEME_WILDCARD)
                FIXME("Here\n");

            if(!computeOnly) {
                INT pos = uri->canon_len;

                uri->canon_uri[pos] = '/';
                uri->canon_uri[pos+1] = '/';
           }
           uri->canon_len += 2;
        }

        if(!canonicalize_authority(data, uri, flags, computeOnly))
            return FALSE;

        if(data->is_relative && (data->password || data->username)) {
            if(!canonicalize_path_opaque(data, uri, flags, computeOnly))
                return FALSE;
        } else {
            if(!computeOnly)
                uri->path_start = uri->canon_len;
            uri->path_len = canonicalize_path_hierarchical(data->path, data->path_len, data->scheme_type, data->host_len != 0,
                    flags, computeOnly ? NULL : uri->canon_uri+uri->canon_len);
            uri->canon_len += uri->path_len;
            if(!computeOnly && !uri->path_len)
                uri->path_start = -1;
        }
    } else {
        /* Opaque URI's don't have an authority. */
        uri->userinfo_start = uri->userinfo_split = -1;
        uri->userinfo_len = 0;
        uri->host_start = -1;
        uri->host_len = 0;
        uri->host_type = Uri_HOST_UNKNOWN;
        uri->has_port = FALSE;
        uri->authority_start = -1;
        uri->authority_len = 0;
        uri->domain_offset = -1;
        uri->port_offset = -1;

        if(is_hierarchical_scheme(data->scheme_type)) {
            DWORD i;

            /* Absolute URIs aren't displayed for known scheme types
             * which should be hierarchical URIs.
             */
            uri->display_modifiers |= URI_DISPLAY_NO_ABSOLUTE_URI;

            /* Windows also sets the port for these (if they have one). */
            for(i = 0; i < sizeof(default_ports)/sizeof(default_ports[0]); ++i) {
                if(data->scheme_type == default_ports[i].scheme) {
                    uri->has_port = TRUE;
                    uri->port = default_ports[i].port;
                    break;
                }
            }
        }

        if(!canonicalize_path_opaque(data, uri, flags, computeOnly))
            return FALSE;
    }

    if(uri->path_start > -1 && !computeOnly)
        /* Finding file extensions happens for both types of URIs. */
        uri->extension_offset = find_file_extension(uri->canon_uri+uri->path_start, uri->path_len);
    else
        uri->extension_offset = -1;

    return TRUE;
}

/* Attempts to canonicalize the query string of the URI.
 *
 * Things that happen:
 *  1)  For known scheme types forbidden characters
 *      are percent encoded, unless the NO_DECODE_EXTRA_INFO flag is set
 *      or NO_ENCODE_FORBIDDEN_CHARACTERS is set.
 *
 *  2)  For known scheme types, percent encoded, unreserved characters
 *      are decoded as long as the NO_DECODE_EXTRA_INFO flag isn't set.
 */
static BOOL canonicalize_query(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    const WCHAR *ptr, *end;
    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;

    if(!data->query) {
        uri->query_start = -1;
        uri->query_len = 0;
        return TRUE;
    }

    uri->query_start = uri->canon_len;

    end = data->query+data->query_len;
    for(ptr = data->query; ptr < end; ++ptr) {
        if(*ptr == '%') {
            if(known_scheme && !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
                WCHAR val = decode_pct_val(ptr);
                if(is_unreserved(val)) {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = val;
                    ++uri->canon_len;

                    ptr += 2;
                    continue;
                }
            }
        } else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr)) {
            if(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) &&
               !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
                if(!computeOnly)
                    pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
                uri->canon_len += 3;
                continue;
            }
        }

        if(!computeOnly)
            uri->canon_uri[uri->canon_len] = *ptr;
        ++uri->canon_len;
    }

    uri->query_len = uri->canon_len - uri->query_start;

    if(!computeOnly)
        TRACE("(%p %p %x %d): Canonicalized query string %s len=%d\n", data, uri, flags,
            computeOnly, debugstr_wn(uri->canon_uri+uri->query_start, uri->query_len),
            uri->query_len);
    return TRUE;
}

static BOOL canonicalize_fragment(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    const WCHAR *ptr, *end;
    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;

    if(!data->fragment) {
        uri->fragment_start = -1;
        uri->fragment_len = 0;
        return TRUE;
    }

    uri->fragment_start = uri->canon_len;

    end = data->fragment + data->fragment_len;
    for(ptr = data->fragment; ptr < end; ++ptr) {
        if(*ptr == '%') {
            if(known_scheme && !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
                WCHAR val = decode_pct_val(ptr);
                if(is_unreserved(val)) {
                    if(!computeOnly)
                        uri->canon_uri[uri->canon_len] = val;
                    ++uri->canon_len;

                    ptr += 2;
                    continue;
                }
            }
        } else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr)) {
            if(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) &&
               !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
                if(!computeOnly)
                    pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
                uri->canon_len += 3;
                continue;
            }
        }

        if(!computeOnly)
            uri->canon_uri[uri->canon_len] = *ptr;
        ++uri->canon_len;
    }

    uri->fragment_len = uri->canon_len - uri->fragment_start;

    if(!computeOnly)
        TRACE("(%p %p %x %d): Canonicalized fragment %s len=%d\n", data, uri, flags,
            computeOnly, debugstr_wn(uri->canon_uri+uri->fragment_start, uri->fragment_len),
            uri->fragment_len);
    return TRUE;
}

/* Canonicalizes the scheme information specified in the parse_data using the specified flags. */
static BOOL canonicalize_scheme(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
    uri->scheme_start = -1;
    uri->scheme_len = 0;

    if(!data->scheme) {
        /* The only type of URI that doesn't have to have a scheme is a relative
         * URI.
         */
        if(!data->is_relative) {
            FIXME("(%p %p %x): Unable to determine the scheme type of %s.\n", data,
                    uri, flags, debugstr_w(data->uri));
            return FALSE;
        }
    } else {
        if(!computeOnly) {
            DWORD i;
            INT pos = uri->canon_len;

            for(i = 0; i < data->scheme_len; ++i) {
                /* Scheme name must be lower case after canonicalization. */
                uri->canon_uri[i + pos] = tolowerW(data->scheme[i]);
            }

            uri->canon_uri[i + pos] = ':';
            uri->scheme_start = pos;

            TRACE("(%p %p %x): Canonicalized scheme=%s, len=%d.\n", data, uri, flags,
                    debugstr_wn(uri->canon_uri+uri->scheme_start,  data->scheme_len), data->scheme_len);
        }

        /* This happens in both computation modes. */
        uri->canon_len += data->scheme_len + 1;
        uri->scheme_len = data->scheme_len;
    }
    return TRUE;
}

/* Computes what the length of the URI specified by the parse_data will be
 * after canonicalization occurs using the specified flags.
 *
 * This function will return a non-zero value indicating the length of the canonicalized
 * URI, or -1 on error.
 */
static int compute_canonicalized_length(const parse_data *data, DWORD flags) {
    Uri uri;

    memset(&uri, 0, sizeof(Uri));

    TRACE("(%p %x): Beginning to compute canonicalized length for URI %s\n", data, flags,
            debugstr_w(data->uri));

    if(!canonicalize_scheme(data, &uri, flags, TRUE)) {
        ERR("(%p %x): Failed to compute URI scheme length.\n", data, flags);
        return -1;
    }

    if(!canonicalize_hierpart(data, &uri, flags, TRUE)) {
        ERR("(%p %x): Failed to compute URI hierpart length.\n", data, flags);
        return -1;
    }

    if(!canonicalize_query(data, &uri, flags, TRUE)) {
        ERR("(%p %x): Failed to compute query string length.\n", data, flags);
        return -1;
    }

    if(!canonicalize_fragment(data, &uri, flags, TRUE)) {
        ERR("(%p %x): Failed to compute fragment length.\n", data, flags);
        return -1;
    }

    TRACE("(%p %x): Finished computing canonicalized URI length. length=%d\n", data, flags, uri.canon_len);

    return uri.canon_len;
}

/* Canonicalizes the URI data specified in the parse_data, using the given flags. If the
 * canonicalization succeeds it will store all the canonicalization information
 * in the pointer to the Uri.
 *
 * To canonicalize a URI this function first computes what the length of the URI
 * specified by the parse_data will be. Once this is done it will then perform the actual
 * canonicalization of the URI.
 */
static HRESULT canonicalize_uri(const parse_data *data, Uri *uri, DWORD flags) {
    INT len;

    uri->canon_uri = NULL;
    uri->canon_size = uri->canon_len = 0;

    TRACE("(%p %p %x): beginning to canonicalize URI %s.\n", data, uri, flags, debugstr_w(data->uri));

    /* First try to compute the length of the URI. */
    len = compute_canonicalized_length(data, flags);
    if(len == -1) {
        ERR("(%p %p %x): Could not compute the canonicalized length of %s.\n", data, uri, flags,
                debugstr_w(data->uri));
        return E_INVALIDARG;
    }

    uri->canon_uri = heap_alloc((len+1)*sizeof(WCHAR));
    if(!uri->canon_uri)
        return E_OUTOFMEMORY;

    uri->canon_size = len;
    if(!canonicalize_scheme(data, uri, flags, FALSE)) {
        ERR("(%p %p %x): Unable to canonicalize the scheme of the URI.\n", data, uri, flags);
        return E_INVALIDARG;
    }
    uri->scheme_type = data->scheme_type;

    if(!canonicalize_hierpart(data, uri, flags, FALSE)) {
        ERR("(%p %p %x): Unable to canonicalize the heirpart of the URI\n", data, uri, flags);
        return E_INVALIDARG;
    }

    if(!canonicalize_query(data, uri, flags, FALSE)) {
        ERR("(%p %p %x): Unable to canonicalize query string of the URI.\n",
            data, uri, flags);
        return E_INVALIDARG;
    }

    if(!canonicalize_fragment(data, uri, flags, FALSE)) {
        ERR("(%p %p %x): Unable to canonicalize fragment of the URI.\n",
            data, uri, flags);
        return E_INVALIDARG;
    }

    /* There's a possibility we didn't use all the space we allocated
     * earlier.
     */
    if(uri->canon_len < uri->canon_size) {
        /* This happens if the URI is hierarchical and dot
         * segments were removed from its path.
         */
        WCHAR *tmp = heap_realloc(uri->canon_uri, (uri->canon_len+1)*sizeof(WCHAR));
        if(!tmp)
            return E_OUTOFMEMORY;

        uri->canon_uri = tmp;
        uri->canon_size = uri->canon_len;
    }

    uri->canon_uri[uri->canon_len] = '\0';
    TRACE("(%p %p %x): finished canonicalizing the URI. uri=%s\n", data, uri, flags, debugstr_w(uri->canon_uri));

    return S_OK;
}

static HRESULT get_builder_component(LPWSTR *component, DWORD *component_len,
                                     LPCWSTR source, DWORD source_len,
                                     LPCWSTR *output, DWORD *output_len)
{
    if(!output_len) {
        if(output)
            *output = NULL;
        return E_POINTER;
    }

    if(!output) {
        *output_len = 0;
        return E_POINTER;
    }

    if(!(*component) && source) {
        /* Allocate 'component', and copy the contents from 'source'
         * into the new allocation.
         */
        *component = heap_alloc((source_len+1)*sizeof(WCHAR));
        if(!(*component))
            return E_OUTOFMEMORY;

        memcpy(*component, source, source_len*sizeof(WCHAR));
        (*component)[source_len] = '\0';
        *component_len = source_len;
    }

    *output = *component;
    *output_len = *component_len;
    return *output ? S_OK : S_FALSE;
}

/* Allocates 'component' and copies the string from 'new_value' into 'component'.
 * If 'prefix' is set and 'new_value' isn't NULL, then it checks if 'new_value'
 * starts with 'prefix'. If it doesn't then 'prefix' is prepended to 'component'.
 *
 * If everything is successful, then will set 'success_flag' in 'flags'.
 */
static HRESULT set_builder_component(LPWSTR *component, DWORD *component_len, LPCWSTR new_value,
                                     WCHAR prefix, DWORD *flags, DWORD success_flag)
{
    heap_free(*component);

    if(!new_value) {
        *component = NULL;
        *component_len = 0;
    } else {
        BOOL add_prefix = FALSE;
        DWORD len = lstrlenW(new_value);
        DWORD pos = 0;

        if(prefix && *new_value != prefix) {
            add_prefix = TRUE;
            *component = heap_alloc((len+2)*sizeof(WCHAR));
        } else
            *component = heap_alloc((len+1)*sizeof(WCHAR));

        if(!(*component))
            return E_OUTOFMEMORY;

        if(add_prefix)
            (*component)[pos++] = prefix;

        memcpy(*component+pos, new_value, (len+1)*sizeof(WCHAR));
        *component_len = len+pos;
    }

    *flags |= success_flag;
    return S_OK;
}

static void reset_builder(UriBuilder *builder) {
    if(builder->uri)
        IUri_Release(&builder->uri->IUri_iface);
    builder->uri = NULL;

    heap_free(builder->fragment);
    builder->fragment = NULL;
    builder->fragment_len = 0;

    heap_free(builder->host);
    builder->host = NULL;
    builder->host_len = 0;

    heap_free(builder->password);
    builder->password = NULL;
    builder->password_len = 0;

    heap_free(builder->path);
    builder->path = NULL;
    builder->path_len = 0;

    heap_free(builder->query);
    builder->query = NULL;
    builder->query_len = 0;

    heap_free(builder->scheme);
    builder->scheme = NULL;
    builder->scheme_len = 0;

    heap_free(builder->username);
    builder->username = NULL;
    builder->username_len = 0;

    builder->has_port = FALSE;
    builder->port = 0;
    builder->modified_props = 0;
}

static HRESULT validate_scheme_name(const UriBuilder *builder, parse_data *data, DWORD flags) {
    const WCHAR *component;
    const WCHAR *ptr;
    const WCHAR **pptr;
    DWORD expected_len;

    if(builder->scheme) {
        ptr = builder->scheme;
        expected_len = builder->scheme_len;
    } else if(builder->uri && builder->uri->scheme_start > -1) {
        ptr = builder->uri->canon_uri+builder->uri->scheme_start;
        expected_len = builder->uri->scheme_len;
    } else {
        static const WCHAR nullW[] = {0};
        ptr = nullW;
        expected_len = 0;
    }

    component = ptr;
    pptr = &ptr;
    if(parse_scheme(pptr, data, flags, ALLOW_NULL_TERM_SCHEME) &&
       data->scheme_len == expected_len) {
        if(data->scheme)
            TRACE("(%p %p %x): Found valid scheme component %s len=%d.\n", builder, data, flags,
               debugstr_wn(data->scheme, data->scheme_len), data->scheme_len);
    } else {
        TRACE("(%p %p %x): Invalid scheme component found %s.\n", builder, data, flags,
            debugstr_wn(component, expected_len));
        return INET_E_INVALID_URL;
   }

    return S_OK;
}

static HRESULT validate_username(const UriBuilder *builder, parse_data *data, DWORD flags) {
    const WCHAR *ptr;
    const WCHAR **pptr;
    DWORD expected_len;

    if(builder->username) {
        ptr = builder->username;
        expected_len = builder->username_len;
    } else if(!(builder->modified_props & Uri_HAS_USER_NAME) && builder->uri &&
              builder->uri->userinfo_start > -1 && builder->uri->userinfo_split != 0) {
        /* Just use the username from the base Uri. */
        data->username = builder->uri->canon_uri+builder->uri->userinfo_start;
        data->username_len = (builder->uri->userinfo_split > -1) ?
                                        builder->uri->userinfo_split : builder->uri->userinfo_len;
        ptr = NULL;
    } else {
        ptr = NULL;
        expected_len = 0;
    }

    if(ptr) {
        const WCHAR *component = ptr;
        pptr = &ptr;
        if(parse_username(pptr, data, flags, ALLOW_NULL_TERM_USER_NAME) &&
           data->username_len == expected_len)
            TRACE("(%p %p %x): Found valid username component %s len=%d.\n", builder, data, flags,
                debugstr_wn(data->username, data->username_len), data->username_len);
        else {
            TRACE("(%p %p %x): Invalid username component found %s.\n", builder, data, flags,
                debugstr_wn(component, expected_len));
            return INET_E_INVALID_URL;
        }
    }

    return S_OK;
}

static HRESULT validate_password(const UriBuilder *builder, parse_data *data, DWORD flags) {
    const WCHAR *ptr;
    const WCHAR **pptr;
    DWORD expected_len;

    if(builder->password) {
        ptr = builder->password;
        expected_len = builder->password_len;
    } else if(!(builder->modified_props & Uri_HAS_PASSWORD) && builder->uri &&
              builder->uri->userinfo_split > -1) {
        data->password = builder->uri->canon_uri+builder->uri->userinfo_start+builder->uri->userinfo_split+1;
        data->password_len = builder->uri->userinfo_len-builder->uri->userinfo_split-1;
        ptr = NULL;
    } else {
        ptr = NULL;
        expected_len = 0;
    }

    if(ptr) {
        const WCHAR *component = ptr;
        pptr = &ptr;
        if(parse_password(pptr, data, flags, ALLOW_NULL_TERM_PASSWORD) &&
           data->password_len == expected_len)
            TRACE("(%p %p %x): Found valid password component %s len=%d.\n", builder, data, flags,
                debugstr_wn(data->password, data->password_len), data->password_len);
        else {
            TRACE("(%p %p %x): Invalid password component found %s.\n", builder, data, flags,
                debugstr_wn(component, expected_len));
            return INET_E_INVALID_URL;
        }
    }

    return S_OK;
}

static HRESULT validate_userinfo(const UriBuilder *builder, parse_data *data, DWORD flags) {
    HRESULT hr;

    hr = validate_username(builder, data, flags);
    if(FAILED(hr))
        return hr;

    hr = validate_password(builder, data, flags);
    if(FAILED(hr))
        return hr;

    return S_OK;
}

static HRESULT validate_host(const UriBuilder *builder, parse_data *data, DWORD flags) {
    const WCHAR *ptr;
    const WCHAR **pptr;
    DWORD expected_len;

    if(builder->host) {
        ptr = builder->host;
        expected_len = builder->host_len;
    } else if(!(builder->modified_props & Uri_HAS_HOST) && builder->uri && builder->uri->host_start > -1) {
        ptr = builder->uri->canon_uri + builder->uri->host_start;
        expected_len = builder->uri->host_len;
    } else
        ptr = NULL;

    if(ptr) {
        const WCHAR *component = ptr;
        DWORD extras = ALLOW_BRACKETLESS_IP_LITERAL|IGNORE_PORT_DELIMITER|SKIP_IP_FUTURE_CHECK;
        pptr = &ptr;

        if(parse_host(pptr, data, flags, extras) && data->host_len == expected_len)
            TRACE("(%p %p %x): Found valid host name %s len=%d type=%d.\n", builder, data, flags,
                debugstr_wn(data->host, data->host_len), data->host_len, data->host_type);
        else {
            TRACE("(%p %p %x): Invalid host name found %s.\n", builder, data, flags,
                debugstr_wn(component, expected_len));
            return INET_E_INVALID_URL;
        }
    }

    return S_OK;
}

static void setup_port(const UriBuilder *builder, parse_data *data, DWORD flags) {
    if(builder->modified_props & Uri_HAS_PORT) {
        if(builder->has_port) {
            data->has_port = TRUE;
            data->port_value = builder->port;
        }
    } else if(builder->uri && builder->uri->has_port) {
        data->has_port = TRUE;
        data->port_value = builder->uri->port;
    }

    if(data->has_port)
        TRACE("(%p %p %x): Using %u as port for IUri.\n", builder, data, flags, data->port_value);
}

static HRESULT validate_path(const UriBuilder *builder, parse_data *data, DWORD flags) {
    const WCHAR *ptr = NULL;
    const WCHAR *component;
    const WCHAR **pptr;
    DWORD expected_len;
    BOOL check_len = TRUE;
    BOOL valid = FALSE;

    if(builder->path) {
        ptr = builder->path;
        expected_len = builder->path_len;
    } else if(!(builder->modified_props & Uri_HAS_PATH) &&
              builder->uri && builder->uri->path_start > -1) {
        ptr = builder->uri->canon_uri+builder->uri->path_start;
        expected_len = builder->uri->path_len;
    } else {
        static const WCHAR nullW[] = {0};
        ptr = nullW;
        check_len = FALSE;
        expected_len = -1;
    }

    component = ptr;
    pptr = &ptr;

    /* How the path is validated depends on what type of
     * URI it is.
     */
    valid = data->is_opaque ?
        parse_path_opaque(pptr, data, flags) : parse_path_hierarchical(pptr, data, flags);

    if(!valid || (check_len && expected_len != data->path_len)) {
        TRACE("(%p %p %x): Invalid path component %s.\n", builder, data, flags,
            debugstr_wn(component, expected_len) );
        return INET_E_INVALID_URL;
    }

    TRACE("(%p %p %x): Valid path component %s len=%d.\n", builder, data, flags,
        debugstr_wn(data->path, data->path_len), data->path_len);

    return S_OK;
}

static HRESULT validate_query(const UriBuilder *builder, parse_data *data, DWORD flags) {
    const WCHAR *ptr = NULL;
    const WCHAR **pptr;
    DWORD expected_len;

    if(builder->query) {
        ptr = builder->query;
        expected_len = builder->query_len;
    } else if(!(builder->modified_props & Uri_HAS_QUERY) && builder->uri &&
              builder->uri->query_start > -1) {
        ptr = builder->uri->canon_uri+builder->uri->query_start;
        expected_len = builder->uri->query_len;
    }

    if(ptr) {
        const WCHAR *component = ptr;
        pptr = &ptr;

        if(parse_query(pptr, data, flags) && expected_len == data->query_len)
            TRACE("(%p %p %x): Valid query component %s len=%d.\n", builder, data, flags,
                debugstr_wn(data->query, data->query_len), data->query_len);
        else {
            TRACE("(%p %p %x): Invalid query component %s.\n", builder, data, flags,
                debugstr_wn(component, expected_len));
            return INET_E_INVALID_URL;
        }
    }

    return S_OK;
}

static HRESULT validate_fragment(const UriBuilder *builder, parse_data *data, DWORD flags) {
    const WCHAR *ptr = NULL;
    const WCHAR **pptr;
    DWORD expected_len;

    if(builder->fragment) {
        ptr = builder->fragment;
        expected_len = builder->fragment_len;
    } else if(!(builder->modified_props & Uri_HAS_FRAGMENT) && builder->uri &&
              builder->uri->fragment_start > -1) {
        ptr = builder->uri->canon_uri+builder->uri->fragment_start;
        expected_len = builder->uri->fragment_len;
    }

    if(ptr) {
        const WCHAR *component = ptr;
        pptr = &ptr;

        if(parse_fragment(pptr, data, flags) && expected_len == data->fragment_len)
            TRACE("(%p %p %x): Valid fragment component %s len=%d.\n", builder, data, flags,
                debugstr_wn(data->fragment, data->fragment_len), data->fragment_len);
        else {
            TRACE("(%p %p %x): Invalid fragment component %s.\n", builder, data, flags,
                debugstr_wn(component, expected_len));
            return INET_E_INVALID_URL;
        }
    }

    return S_OK;
}

static HRESULT validate_components(const UriBuilder *builder, parse_data *data, DWORD flags) {
    HRESULT hr;

    memset(data, 0, sizeof(parse_data));

    TRACE("(%p %p %x): Beginning to validate builder components.\n", builder, data, flags);

    hr = validate_scheme_name(builder, data, flags);
    if(FAILED(hr))
        return hr;

    /* Extra validation for file schemes. */
    if(data->scheme_type == URL_SCHEME_FILE) {
        if((builder->password || (builder->uri && builder->uri->userinfo_split > -1)) ||
           (builder->username || (builder->uri && builder->uri->userinfo_start > -1))) {
            TRACE("(%p %p %x): File schemes can't contain a username or password.\n",
                builder, data, flags);
            return INET_E_INVALID_URL;
        }
    }

    hr = validate_userinfo(builder, data, flags);
    if(FAILED(hr))
        return hr;

    hr = validate_host(builder, data, flags);
    if(FAILED(hr))
        return hr;

    setup_port(builder, data, flags);

    /* The URI is opaque if it doesn't have an authority component. */
    if(!data->is_relative)
        data->is_opaque = !data->username && !data->password && !data->host && !data->has_port
            && data->scheme_type != URL_SCHEME_FILE;
    else
        data->is_opaque = !data->host && !data->has_port;

    hr = validate_path(builder, data, flags);
    if(FAILED(hr))
        return hr;

    hr = validate_query(builder, data, flags);
    if(FAILED(hr))
        return hr;

    hr = validate_fragment(builder, data, flags);
    if(FAILED(hr))
        return hr;

    TRACE("(%p %p %x): Finished validating builder components.\n", builder, data, flags);

    return S_OK;
}

static HRESULT compare_file_paths(const Uri *a, const Uri *b, BOOL *ret)
{
    WCHAR *canon_path_a, *canon_path_b;
    DWORD len_a, len_b;

    if(!a->path_len) {
        *ret = !b->path_len;
        return S_OK;
    }

    if(!b->path_len) {
        *ret = FALSE;
        return S_OK;
    }

    /* Fast path */
    if(a->path_len == b->path_len && !memicmpW(a->canon_uri+a->path_start, b->canon_uri+b->path_start, a->path_len)) {
        *ret = TRUE;
        return S_OK;
    }

    len_a = canonicalize_path_hierarchical(a->canon_uri+a->path_start, a->path_len, a->scheme_type, FALSE, 0, NULL);
    len_b = canonicalize_path_hierarchical(b->canon_uri+b->path_start, b->path_len, b->scheme_type, FALSE, 0, NULL);

    canon_path_a = heap_alloc(len_a*sizeof(WCHAR));
    if(!canon_path_a)
        return E_OUTOFMEMORY;
    canon_path_b = heap_alloc(len_b*sizeof(WCHAR));
    if(!canon_path_b) {
        heap_free(canon_path_a);
        return E_OUTOFMEMORY;
    }

    len_a = canonicalize_path_hierarchical(a->canon_uri+a->path_start, a->path_len, a->scheme_type, FALSE, 0, canon_path_a);
    len_b = canonicalize_path_hierarchical(b->canon_uri+b->path_start, b->path_len, b->scheme_type, FALSE, 0, canon_path_b);

    *ret = len_a == len_b && !memicmpW(canon_path_a, canon_path_b, len_a);

    heap_free(canon_path_a);
    heap_free(canon_path_b);
    return S_OK;
}

/* Checks if the two Uri's are logically equivalent. It's a simple
 * comparison, since they are both of type Uri, and it can access
 * the properties of each Uri directly without the need to go
 * through the "IUri_Get*" interface calls.
 */
static HRESULT compare_uris(const Uri *a, const Uri *b, BOOL *ret) {
    const BOOL known_scheme = a->scheme_type != URL_SCHEME_UNKNOWN;
    const BOOL are_hierarchical = a->authority_start > -1 && b->authority_start > -1;
    HRESULT hres;

    *ret = FALSE;

    if(a->scheme_type != b->scheme_type)
        return S_OK;

    /* Only compare the scheme names (if any) if their unknown scheme types. */
    if(!known_scheme) {
        if((a->scheme_start > -1 && b->scheme_start > -1) &&
           (a->scheme_len == b->scheme_len)) {
            /* Make sure the schemes are the same. */
            if(StrCmpNW(a->canon_uri+a->scheme_start, b->canon_uri+b->scheme_start, a->scheme_len))
                return S_OK;
        } else if(a->scheme_len != b->scheme_len)
            /* One of the Uri's has a scheme name, while the other doesn't. */
            return S_OK;
    }

    /* If they have a userinfo component, perform case sensitive compare. */
    if((a->userinfo_start > -1 && b->userinfo_start > -1) &&
       (a->userinfo_len == b->userinfo_len)) {
        if(StrCmpNW(a->canon_uri+a->userinfo_start, b->canon_uri+b->userinfo_start, a->userinfo_len))
            return S_OK;
    } else if(a->userinfo_len != b->userinfo_len)
        /* One of the Uri's had a userinfo, while the other one doesn't. */
        return S_OK;

    /* Check if they have a host name. */
    if((a->host_start > -1 && b->host_start > -1) &&
       (a->host_len == b->host_len)) {
        /* Perform a case insensitive compare if they are a known scheme type. */
        if(known_scheme) {
            if(StrCmpNIW(a->canon_uri+a->host_start, b->canon_uri+b->host_start, a->host_len))
                return S_OK;
        } else if(StrCmpNW(a->canon_uri+a->host_start, b->canon_uri+b->host_start, a->host_len))
            return S_OK;
    } else if(a->host_len != b->host_len)
        /* One of the Uri's had a host, while the other one didn't. */
        return S_OK;

    if(a->has_port && b->has_port) {
        if(a->port != b->port)
            return S_OK;
    } else if(a->has_port || b->has_port)
        /* One had a port, while the other one didn't. */
        return S_OK;

    /* Windows is weird with how it handles paths. For example
     * One URI could be "http://google.com" (after canonicalization)
     * and one could be "http://google.com/" and the IsEqual function
     * would still evaluate to TRUE, but, only if they are both hierarchical
     * URIs.
     */
    if(a->scheme_type == URL_SCHEME_FILE) {
        BOOL cmp;

        hres = compare_file_paths(a, b, &cmp);
        if(FAILED(hres) || !cmp)
            return hres;
    } else if((a->path_start > -1 && b->path_start > -1) &&
       (a->path_len == b->path_len)) {
        if(StrCmpNW(a->canon_uri+a->path_start, b->canon_uri+b->path_start, a->path_len))
            return S_OK;
    } else if(are_hierarchical && a->path_len == -1 && b->path_len == 0) {
        if(*(a->canon_uri+a->path_start) != '/')
            return S_OK;
    } else if(are_hierarchical && b->path_len == 1 && a->path_len == 0) {
        if(*(b->canon_uri+b->path_start) != '/')
            return S_OK;
    } else if(a->path_len != b->path_len)
        return S_OK;

    /* Compare the query strings of the two URIs. */
    if((a->query_start > -1 && b->query_start > -1) &&
       (a->query_len == b->query_len)) {
        if(StrCmpNW(a->canon_uri+a->query_start, b->canon_uri+b->query_start, a->query_len))
            return S_OK;
    } else if(a->query_len != b->query_len)
        return S_OK;

    if((a->fragment_start > -1 && b->fragment_start > -1) &&
       (a->fragment_len == b->fragment_len)) {
        if(StrCmpNW(a->canon_uri+a->fragment_start, b->canon_uri+b->fragment_start, a->fragment_len))
            return S_OK;
    } else if(a->fragment_len != b->fragment_len)
        return S_OK;

    /* If we get here, the two URIs are equivalent. */
    *ret = TRUE;
    return S_OK;
}

static void convert_to_dos_path(const WCHAR *path, DWORD path_len,
                                WCHAR *output, DWORD *output_len)
{
    const WCHAR *ptr = path;

    if(path_len > 3 && *ptr == '/' && is_drive_path(path+1))
        /* Skip over the leading / before the drive path. */
        ++ptr;

    for(; ptr < path+path_len; ++ptr) {
        if(*ptr == '/') {
            if(output)
                *output++ = '\\';
            (*output_len)++;
        } else {
            if(output)
                *output++ = *ptr;
            (*output_len)++;
        }
    }
}

/* Generates a raw uri string using the parse_data. */
static DWORD generate_raw_uri(const parse_data *data, BSTR uri, DWORD flags) {
    DWORD length = 0;

    if(data->scheme) {
        if(uri) {
            memcpy(uri, data->scheme, data->scheme_len*sizeof(WCHAR));
            uri[data->scheme_len] = ':';
        }
        length += data->scheme_len+1;
    }

    if(!data->is_opaque) {
        /* For the "//" which appears before the authority component. */
        if(uri) {
            uri[length] = '/';
            uri[length+1] = '/';
        }
        length += 2;

        /* Check if we need to add the "\\" before the host name
         * of a UNC server name in a DOS path.
         */
        if(flags & RAW_URI_CONVERT_TO_DOS_PATH &&
           data->scheme_type == URL_SCHEME_FILE && data->host) {
            if(uri) {
                uri[length] = '\\';
                uri[length+1] = '\\';
            }
            length += 2;
        }
    }

    if(data->username) {
        if(uri)
            memcpy(uri+length, data->username, data->username_len*sizeof(WCHAR));
        length += data->username_len;
    }

    if(data->password) {
        if(uri) {
            uri[length] = ':';
            memcpy(uri+length+1, data->password, data->password_len*sizeof(WCHAR));
        }
        length += data->password_len+1;
    }

    if(data->password || data->username) {
        if(uri)
            uri[length] = '@';
        ++length;
    }

    if(data->host) {
        /* IPv6 addresses get the brackets added around them if they don't already
         * have them.
         */
        const BOOL add_brackets = data->host_type == Uri_HOST_IPV6 && *(data->host) != '[';
        if(add_brackets) {
            if(uri)
                uri[length] = '[';
            ++length;
        }

        if(uri)
            memcpy(uri+length, data->host, data->host_len*sizeof(WCHAR));
        length += data->host_len;

        if(add_brackets) {
            if(uri)
                uri[length] = ']';
            length++;
        }
    }

    if(data->has_port) {
        /* The port isn't included in the raw uri if it's the default
         * port for the scheme type.
         */
        DWORD i;
        BOOL is_default = FALSE;

        for(i = 0; i < sizeof(default_ports)/sizeof(default_ports[0]); ++i) {
            if(data->scheme_type == default_ports[i].scheme &&
               data->port_value == default_ports[i].port)
                is_default = TRUE;
        }

        if(!is_default || flags & RAW_URI_FORCE_PORT_DISP) {
            if(uri)
                uri[length] = ':';
            ++length;

            if(uri)
                length += ui2str(uri+length, data->port_value);
            else
                length += ui2str(NULL, data->port_value);
        }
    }

    /* Check if a '/' should be added before the path for hierarchical URIs. */
    if(!data->is_opaque && data->path && *(data->path) != '/') {
        if(uri)
            uri[length] = '/';
        ++length;
    }

    if(data->path) {
        if(!data->is_opaque && data->scheme_type == URL_SCHEME_FILE &&
           flags & RAW_URI_CONVERT_TO_DOS_PATH) {
            DWORD len = 0;

            if(uri)
                convert_to_dos_path(data->path, data->path_len, uri+length, &len);
            else
                convert_to_dos_path(data->path, data->path_len, NULL, &len);

            length += len;
        } else {
            if(uri)
                memcpy(uri+length, data->path, data->path_len*sizeof(WCHAR));
            length += data->path_len;
        }
    }

    if(data->query) {
        if(uri)
            memcpy(uri+length, data->query, data->query_len*sizeof(WCHAR));
        length += data->query_len;
    }

    if(data->fragment) {
        if(uri)
            memcpy(uri+length, data->fragment, data->fragment_len*sizeof(WCHAR));
        length += data->fragment_len;
    }

    if(uri)
        TRACE("(%p %p): Generated raw uri=%s len=%d\n", data, uri, debugstr_wn(uri, length), length);
    else
        TRACE("(%p %p): Computed raw uri len=%d\n", data, uri, length);

    return length;
}

static HRESULT generate_uri(const UriBuilder *builder, const parse_data *data, Uri *uri, DWORD flags) {
    HRESULT hr;
    DWORD length = generate_raw_uri(data, NULL, 0);
    uri->raw_uri = SysAllocStringLen(NULL, length);
    if(!uri->raw_uri)
        return E_OUTOFMEMORY;

    generate_raw_uri(data, uri->raw_uri, 0);

    hr = canonicalize_uri(data, uri, flags);
    if(FAILED(hr)) {
        if(hr == E_INVALIDARG)
            return INET_E_INVALID_URL;
        return hr;
    }

    uri->create_flags = flags;
    return S_OK;
}

static inline Uri* impl_from_IUri(IUri *iface)
{
    return CONTAINING_RECORD(iface, Uri, IUri_iface);
}

static inline void destroy_uri_obj(Uri *This)
{
    SysFreeString(This->raw_uri);
    heap_free(This->canon_uri);
    heap_free(This);
}

static HRESULT WINAPI Uri_QueryInterface(IUri *iface, REFIID riid, void **ppv)
{
    Uri *This = impl_from_IUri(iface);

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IUri_iface;
    }else if(IsEqualGUID(&IID_IUri, riid)) {
        TRACE("(%p)->(IID_IUri %p)\n", This, ppv);
        *ppv = &This->IUri_iface;
    }else if(IsEqualGUID(&IID_IUriBuilderFactory, riid)) {
        TRACE("(%p)->(IID_IUriBuilderFactory %p)\n", This, ppv);
        *ppv = &This->IUriBuilderFactory_iface;
    }else if(IsEqualGUID(&IID_IPersistStream, riid)) {
        TRACE("(%p)->(IID_IPersistStream %p)\n", This, ppv);
        *ppv = &This->IPersistStream_iface;
    }else if(IsEqualGUID(&IID_IMarshal, riid)) {
        TRACE("(%p)->(IID_IMarshal %p)\n", This, ppv);
        *ppv = &This->IMarshal_iface;
    }else if(IsEqualGUID(&IID_IUriObj, riid)) {
        TRACE("(%p)->(IID_IUriObj %p)\n", This, ppv);
        *ppv = This;
        return S_OK;
    }else {
        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI Uri_AddRef(IUri *iface)
{
    Uri *This = impl_from_IUri(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI Uri_Release(IUri *iface)
{
    Uri *This = impl_from_IUri(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref)
        destroy_uri_obj(This);

    return ref;
}

static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BSTR *pbstrProperty, DWORD dwFlags)
{
    Uri *This = impl_from_IUri(iface);
    HRESULT hres;
    TRACE("(%p %s)->(%d %p %x)\n", This, debugstr_w(This->canon_uri), uriProp, pbstrProperty, dwFlags);

    if(!This->create_flags)
        return E_UNEXPECTED;
    if(!pbstrProperty)
        return E_POINTER;

    if(uriProp > Uri_PROPERTY_STRING_LAST) {
        /* Windows allocates an empty BSTR for invalid Uri_PROPERTY's. */
        *pbstrProperty = SysAllocStringLen(NULL, 0);
        if(!(*pbstrProperty))
            return E_OUTOFMEMORY;

        /* It only returns S_FALSE for the ZONE property... */
        if(uriProp == Uri_PROPERTY_ZONE)
            return S_FALSE;
        else
            return S_OK;
    }

    /* Don't have support for flags yet. */
    if(dwFlags) {
        FIXME("(%p)->(%d %p %x)\n", This, uriProp, pbstrProperty, dwFlags);
        return E_NOTIMPL;
    }

    switch(uriProp) {
    case Uri_PROPERTY_ABSOLUTE_URI:
        if(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI) {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        } else {
            if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1) {
                if(This->userinfo_len == 0) {
                    /* Don't include the '@' after the userinfo component. */
                    *pbstrProperty = SysAllocStringLen(NULL, This->canon_len-1);
                    hres = S_OK;
                    if(*pbstrProperty) {
                        /* Copy everything before it. */
                        memcpy(*pbstrProperty, This->canon_uri, This->userinfo_start*sizeof(WCHAR));

                        /* And everything after it. */
                        memcpy(*pbstrProperty+This->userinfo_start, This->canon_uri+This->userinfo_start+1,
                               (This->canon_len-This->userinfo_start-1)*sizeof(WCHAR));
                    }
                } else if(This->userinfo_split == 0 && This->userinfo_len == 1) {
                    /* Don't include the ":@" */
                    *pbstrProperty = SysAllocStringLen(NULL, This->canon_len-2);
                    hres = S_OK;
                    if(*pbstrProperty) {
                        memcpy(*pbstrProperty, This->canon_uri, This->userinfo_start*sizeof(WCHAR));
                        memcpy(*pbstrProperty+This->userinfo_start, This->canon_uri+This->userinfo_start+2,
                               (This->canon_len-This->userinfo_start-2)*sizeof(WCHAR));
                    }
                } else {
                    *pbstrProperty = SysAllocString(This->canon_uri);
                    hres = S_OK;
                }
            } else {
                *pbstrProperty = SysAllocString(This->canon_uri);
                hres = S_OK;
            }
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_AUTHORITY:
        if(This->authority_start > -1) {
            if(This->port_offset > -1 && is_default_port(This->scheme_type, This->port) &&
               This->display_modifiers & URI_DISPLAY_NO_DEFAULT_PORT_AUTH)
                /* Don't include the port in the authority component. */
                *pbstrProperty = SysAllocStringLen(This->canon_uri+This->authority_start, This->port_offset);
            else
                *pbstrProperty = SysAllocStringLen(This->canon_uri+This->authority_start, This->authority_len);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_DISPLAY_URI:
        /* The Display URI contains everything except for the userinfo for known
         * scheme types.
         */
        if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1) {
            *pbstrProperty = SysAllocStringLen(NULL, This->canon_len-This->userinfo_len);

            if(*pbstrProperty) {
                /* Copy everything before the userinfo over. */
                memcpy(*pbstrProperty, This->canon_uri, This->userinfo_start*sizeof(WCHAR));
                /* Copy everything after the userinfo over. */
                memcpy(*pbstrProperty+This->userinfo_start,
                   This->canon_uri+This->userinfo_start+This->userinfo_len+1,
                   (This->canon_len-(This->userinfo_start+This->userinfo_len+1))*sizeof(WCHAR));
            }
        } else
            *pbstrProperty = SysAllocString(This->canon_uri);

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;
        else
            hres = S_OK;

        break;
    case Uri_PROPERTY_DOMAIN:
        if(This->domain_offset > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+This->domain_offset,
                                               This->host_len-This->domain_offset);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_EXTENSION:
        if(This->extension_offset > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri+This->path_start+This->extension_offset,
                                               This->path_len-This->extension_offset);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_FRAGMENT:
        if(This->fragment_start > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri+This->fragment_start, This->fragment_len);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_HOST:
        if(This->host_start > -1) {
            /* The '[' and ']' aren't included for IPv6 addresses. */
            if(This->host_type == Uri_HOST_IPV6)
                *pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+1, This->host_len-2);
            else
                *pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start, This->host_len);

            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_PASSWORD:
        if(This->userinfo_split > -1) {
            *pbstrProperty = SysAllocStringLen(
                This->canon_uri+This->userinfo_start+This->userinfo_split+1,
                This->userinfo_len-This->userinfo_split-1);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            return E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_PATH:
        if(This->path_start > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri+This->path_start, This->path_len);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_PATH_AND_QUERY:
        if(This->path_start > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri+This->path_start, This->path_len+This->query_len);
            hres = S_OK;
        } else if(This->query_start > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri+This->query_start, This->query_len);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_QUERY:
        if(This->query_start > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri+This->query_start, This->query_len);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_RAW_URI:
        *pbstrProperty = SysAllocString(This->raw_uri);
        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;
        else
            hres = S_OK;
        break;
    case Uri_PROPERTY_SCHEME_NAME:
        if(This->scheme_start > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri + This->scheme_start, This->scheme_len);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_USER_INFO:
        if(This->userinfo_start > -1) {
            *pbstrProperty = SysAllocStringLen(This->canon_uri+This->userinfo_start, This->userinfo_len);
            hres = S_OK;
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            hres = E_OUTOFMEMORY;

        break;
    case Uri_PROPERTY_USER_NAME:
        if(This->userinfo_start > -1 && This->userinfo_split != 0) {
            /* If userinfo_split is set, that means a password exists
             * so the username is only from userinfo_start to userinfo_split.
             */
            if(This->userinfo_split > -1) {
                *pbstrProperty = SysAllocStringLen(This->canon_uri + This->userinfo_start, This->userinfo_split);
                hres = S_OK;
            } else {
                *pbstrProperty = SysAllocStringLen(This->canon_uri + This->userinfo_start, This->userinfo_len);
                hres = S_OK;
            }
        } else {
            *pbstrProperty = SysAllocStringLen(NULL, 0);
            hres = S_FALSE;
        }

        if(!(*pbstrProperty))
            return E_OUTOFMEMORY;

        break;
    default:
        FIXME("(%p)->(%d %p %x)\n", This, uriProp, pbstrProperty, dwFlags);
        hres = E_NOTIMPL;
    }

    return hres;
}

static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, DWORD *pcchProperty, DWORD dwFlags)
{
    Uri *This = impl_from_IUri(iface);
    HRESULT hres;
    TRACE("(%p %s)->(%d %p %x)\n", This, debugstr_w(This->canon_uri), uriProp, pcchProperty, dwFlags);

    if(!This->create_flags)
        return E_UNEXPECTED;
    if(!pcchProperty)
        return E_INVALIDARG;

    /* Can only return a length for a property if it's a string. */
    if(uriProp > Uri_PROPERTY_STRING_LAST)
        return E_INVALIDARG;

    /* Don't have support for flags yet. */
    if(dwFlags) {
        FIXME("(%p)->(%d %p %x)\n", This, uriProp, pcchProperty, dwFlags);
        return E_NOTIMPL;
    }

    switch(uriProp) {
    case Uri_PROPERTY_ABSOLUTE_URI:
        if(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI) {
            *pcchProperty = 0;
            hres = S_FALSE;
        } else {
            if(This->scheme_type != URL_SCHEME_UNKNOWN) {
                if(This->userinfo_start > -1 && This->userinfo_len == 0)
                    /* Don't include the '@' in the length. */
                    *pcchProperty = This->canon_len-1;
                else if(This->userinfo_start > -1 && This->userinfo_len == 1 &&
                        This->userinfo_split == 0)
                    /* Don't include the ":@" in the length. */
                    *pcchProperty = This->canon_len-2;
                else
                    *pcchProperty = This->canon_len;
            } else
                *pcchProperty = This->canon_len;

            hres = S_OK;
        }

        break;
    case Uri_PROPERTY_AUTHORITY:
        if(This->port_offset > -1 &&
           This->display_modifiers & URI_DISPLAY_NO_DEFAULT_PORT_AUTH &&
           is_default_port(This->scheme_type, This->port))
            /* Only count up until the port in the authority. */
            *pcchProperty = This->port_offset;
        else
            *pcchProperty = This->authority_len;
        hres = (This->authority_start > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_DISPLAY_URI:
        if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1)
            *pcchProperty = This->canon_len-This->userinfo_len-1;
        else
            *pcchProperty = This->canon_len;

        hres = S_OK;
        break;
    case Uri_PROPERTY_DOMAIN:
        if(This->domain_offset > -1)
            *pcchProperty = This->host_len - This->domain_offset;
        else
            *pcchProperty = 0;

        hres = (This->domain_offset > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_EXTENSION:
        if(This->extension_offset > -1) {
            *pcchProperty = This->path_len - This->extension_offset;
            hres = S_OK;
        } else {
            *pcchProperty = 0;
            hres = S_FALSE;
        }

        break;
    case Uri_PROPERTY_FRAGMENT:
        *pcchProperty = This->fragment_len;
        hres = (This->fragment_start > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_HOST:
        *pcchProperty = This->host_len;

        /* '[' and ']' aren't included in the length. */
        if(This->host_type == Uri_HOST_IPV6)
            *pcchProperty -= 2;

        hres = (This->host_start > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_PASSWORD:
        *pcchProperty = (This->userinfo_split > -1) ? This->userinfo_len-This->userinfo_split-1 : 0;
        hres = (This->userinfo_split > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_PATH:
        *pcchProperty = This->path_len;
        hres = (This->path_start > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_PATH_AND_QUERY:
        *pcchProperty = This->path_len+This->query_len;
        hres = (This->path_start > -1 || This->query_start > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_QUERY:
        *pcchProperty = This->query_len;
        hres = (This->query_start > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_RAW_URI:
        *pcchProperty = SysStringLen(This->raw_uri);
        hres = S_OK;
        break;
    case Uri_PROPERTY_SCHEME_NAME:
        *pcchProperty = This->scheme_len;
        hres = (This->scheme_start > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_USER_INFO:
        *pcchProperty = This->userinfo_len;
        hres = (This->userinfo_start > -1) ? S_OK : S_FALSE;
        break;
    case Uri_PROPERTY_USER_NAME:
        *pcchProperty = (This->userinfo_split > -1) ? This->userinfo_split : This->userinfo_len;
        if(This->userinfo_split == 0)
            hres = S_FALSE;
        else
            hres = (This->userinfo_start > -1) ? S_OK : S_FALSE;
        break;
    default:
        FIXME("(%p)->(%d %p %x)\n", This, uriProp, pcchProperty, dwFlags);
        hres = E_NOTIMPL;
    }

    return hres;
}

static HRESULT WINAPI Uri_GetPropertyDWORD(IUri *iface, Uri_PROPERTY uriProp, DWORD *pcchProperty, DWORD dwFlags)
{
    Uri *This = impl_from_IUri(iface);
    HRESULT hres;

    TRACE("(%p %s)->(%d %p %x)\n", This, debugstr_w(This->canon_uri), uriProp, pcchProperty, dwFlags);

    if(!This->create_flags)
        return E_UNEXPECTED;
    if(!pcchProperty)
        return E_INVALIDARG;

    /* Microsoft's implementation for the ZONE property of a URI seems to be lacking...
     * From what I can tell, instead of checking which URLZONE the URI belongs to it
     * simply assigns URLZONE_INVALID and returns E_NOTIMPL. This also applies to the GetZone
     * function.
     */
    if(uriProp == Uri_PROPERTY_ZONE) {
        *pcchProperty = URLZONE_INVALID;
        return E_NOTIMPL;
    }

    if(uriProp < Uri_PROPERTY_DWORD_START) {
        *pcchProperty = 0;
        return E_INVALIDARG;
    }

    switch(uriProp) {
    case Uri_PROPERTY_HOST_TYPE:
        *pcchProperty = This->host_type;
        hres = S_OK;
        break;
    case Uri_PROPERTY_PORT:
        if(!This->has_port) {
            *pcchProperty = 0;
            hres = S_FALSE;
        } else {
            *pcchProperty = This->port;
            hres = S_OK;
        }

        break;
    case Uri_PROPERTY_SCHEME:
        *pcchProperty = This->scheme_type;
        hres = S_OK;
        break;
    default:
        FIXME("(%p)->(%d %p %x)\n", This, uriProp, pcchProperty, dwFlags);
        hres = E_NOTIMPL;
    }

    return hres;
}

static HRESULT WINAPI Uri_HasProperty(IUri *iface, Uri_PROPERTY uriProp, BOOL *pfHasProperty)
{
    Uri *This = impl_from_IUri(iface);

    TRACE("(%p %s)->(%d %p)\n", This, debugstr_w(This->canon_uri), uriProp, pfHasProperty);

    if(!pfHasProperty)
        return E_INVALIDARG;

    switch(uriProp) {
    case Uri_PROPERTY_ABSOLUTE_URI:
        *pfHasProperty = !(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI);
        break;
    case Uri_PROPERTY_AUTHORITY:
        *pfHasProperty = This->authority_start > -1;
        break;
    case Uri_PROPERTY_DISPLAY_URI:
        *pfHasProperty = TRUE;
        break;
    case Uri_PROPERTY_DOMAIN:
        *pfHasProperty = This->domain_offset > -1;
        break;
    case Uri_PROPERTY_EXTENSION:
        *pfHasProperty = This->extension_offset > -1;
        break;
    case Uri_PROPERTY_FRAGMENT:
        *pfHasProperty = This->fragment_start > -1;
        break;
    case Uri_PROPERTY_HOST:
        *pfHasProperty = This->host_start > -1;
        break;
    case Uri_PROPERTY_PASSWORD:
        *pfHasProperty = This->userinfo_split > -1;
        break;
    case Uri_PROPERTY_PATH:
        *pfHasProperty = This->path_start > -1;
        break;
    case Uri_PROPERTY_PATH_AND_QUERY:
        *pfHasProperty = (This->path_start > -1 || This->query_start > -1);
        break;
    case Uri_PROPERTY_QUERY:
        *pfHasProperty = This->query_start > -1;
        break;
    case Uri_PROPERTY_RAW_URI:
        *pfHasProperty = TRUE;
        break;
    case Uri_PROPERTY_SCHEME_NAME:
        *pfHasProperty = This->scheme_start > -1;
        break;
    case Uri_PROPERTY_USER_INFO:
        *pfHasProperty = This->userinfo_start > -1;
        break;
    case Uri_PROPERTY_USER_NAME:
        if(This->userinfo_split == 0)
            *pfHasProperty = FALSE;
        else
            *pfHasProperty = This->userinfo_start > -1;
        break;
    case Uri_PROPERTY_HOST_TYPE:
        *pfHasProperty = TRUE;
        break;
    case Uri_PROPERTY_PORT:
        *pfHasProperty = This->has_port;
        break;
    case Uri_PROPERTY_SCHEME:
        *pfHasProperty = TRUE;
        break;
    case Uri_PROPERTY_ZONE:
        *pfHasProperty = FALSE;
        break;
    default:
        FIXME("(%p)->(%d %p): Unsupported property type.\n", This, uriProp, pfHasProperty);
        return E_NOTIMPL;
    }

    return S_OK;
}

static HRESULT WINAPI Uri_GetAbsoluteUri(IUri *iface, BSTR *pstrAbsoluteUri)
{
    TRACE("(%p)->(%p)\n", iface, pstrAbsoluteUri);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_ABSOLUTE_URI, pstrAbsoluteUri, 0);
}

static HRESULT WINAPI Uri_GetAuthority(IUri *iface, BSTR *pstrAuthority)
{
    TRACE("(%p)->(%p)\n", iface, pstrAuthority);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_AUTHORITY, pstrAuthority, 0);
}

static HRESULT WINAPI Uri_GetDisplayUri(IUri *iface, BSTR *pstrDisplayUri)
{
    TRACE("(%p)->(%p)\n", iface, pstrDisplayUri);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_DISPLAY_URI, pstrDisplayUri, 0);
}

static HRESULT WINAPI Uri_GetDomain(IUri *iface, BSTR *pstrDomain)
{
    TRACE("(%p)->(%p)\n", iface, pstrDomain);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_DOMAIN, pstrDomain, 0);
}

static HRESULT WINAPI Uri_GetExtension(IUri *iface, BSTR *pstrExtension)
{
    TRACE("(%p)->(%p)\n", iface, pstrExtension);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_EXTENSION, pstrExtension, 0);
}

static HRESULT WINAPI Uri_GetFragment(IUri *iface, BSTR *pstrFragment)
{
    TRACE("(%p)->(%p)\n", iface, pstrFragment);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_FRAGMENT, pstrFragment, 0);
}

static HRESULT WINAPI Uri_GetHost(IUri *iface, BSTR *pstrHost)
{
    TRACE("(%p)->(%p)\n", iface, pstrHost);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_HOST, pstrHost, 0);
}

static HRESULT WINAPI Uri_GetPassword(IUri *iface, BSTR *pstrPassword)
{
    TRACE("(%p)->(%p)\n", iface, pstrPassword);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_PASSWORD, pstrPassword, 0);
}

static HRESULT WINAPI Uri_GetPath(IUri *iface, BSTR *pstrPath)
{
    TRACE("(%p)->(%p)\n", iface, pstrPath);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_PATH, pstrPath, 0);
}

static HRESULT WINAPI Uri_GetPathAndQuery(IUri *iface, BSTR *pstrPathAndQuery)
{
    TRACE("(%p)->(%p)\n", iface, pstrPathAndQuery);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_PATH_AND_QUERY, pstrPathAndQuery, 0);
}

static HRESULT WINAPI Uri_GetQuery(IUri *iface, BSTR *pstrQuery)
{
    TRACE("(%p)->(%p)\n", iface, pstrQuery);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_QUERY, pstrQuery, 0);
}

static HRESULT WINAPI Uri_GetRawUri(IUri *iface, BSTR *pstrRawUri)
{
    TRACE("(%p)->(%p)\n", iface, pstrRawUri);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_RAW_URI, pstrRawUri, 0);
}

static HRESULT WINAPI Uri_GetSchemeName(IUri *iface, BSTR *pstrSchemeName)
{
    TRACE("(%p)->(%p)\n", iface, pstrSchemeName);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_SCHEME_NAME, pstrSchemeName, 0);
}

static HRESULT WINAPI Uri_GetUserInfo(IUri *iface, BSTR *pstrUserInfo)
{
    TRACE("(%p)->(%p)\n", iface, pstrUserInfo);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_USER_INFO, pstrUserInfo, 0);
}

static HRESULT WINAPI Uri_GetUserName(IUri *iface, BSTR *pstrUserName)
{
    TRACE("(%p)->(%p)\n", iface, pstrUserName);
    return IUri_GetPropertyBSTR(iface, Uri_PROPERTY_USER_NAME, pstrUserName, 0);
}

static HRESULT WINAPI Uri_GetHostType(IUri *iface, DWORD *pdwHostType)
{
    TRACE("(%p)->(%p)\n", iface, pdwHostType);
    return IUri_GetPropertyDWORD(iface, Uri_PROPERTY_HOST_TYPE, pdwHostType, 0);
}

static HRESULT WINAPI Uri_GetPort(IUri *iface, DWORD *pdwPort)
{
    TRACE("(%p)->(%p)\n", iface, pdwPort);
    return IUri_GetPropertyDWORD(iface, Uri_PROPERTY_PORT, pdwPort, 0);
}

static HRESULT WINAPI Uri_GetScheme(IUri *iface, DWORD *pdwScheme)
{
    TRACE("(%p)->(%p)\n", iface, pdwScheme);
    return IUri_GetPropertyDWORD(iface, Uri_PROPERTY_SCHEME, pdwScheme, 0);
}

static HRESULT WINAPI Uri_GetZone(IUri *iface, DWORD *pdwZone)
{
    TRACE("(%p)->(%p)\n", iface, pdwZone);
    return IUri_GetPropertyDWORD(iface, Uri_PROPERTY_ZONE,pdwZone, 0);
}

static HRESULT WINAPI Uri_GetProperties(IUri *iface, DWORD *pdwProperties)
{
    Uri *This = impl_from_IUri(iface);
    TRACE("(%p %s)->(%p)\n", This, debugstr_w(This->canon_uri), pdwProperties);

    if(!This->create_flags)
        return E_UNEXPECTED;
    if(!pdwProperties)
        return E_INVALIDARG;

    /* All URIs have these. */
    *pdwProperties = Uri_HAS_DISPLAY_URI|Uri_HAS_RAW_URI|Uri_HAS_SCHEME|Uri_HAS_HOST_TYPE;

    if(!(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI))
        *pdwProperties |= Uri_HAS_ABSOLUTE_URI;

    if(This->scheme_start > -1)
        *pdwProperties |= Uri_HAS_SCHEME_NAME;

    if(This->authority_start > -1) {
        *pdwProperties |= Uri_HAS_AUTHORITY;
        if(This->userinfo_start > -1) {
            *pdwProperties |= Uri_HAS_USER_INFO;
            if(This->userinfo_split != 0)
                *pdwProperties |= Uri_HAS_USER_NAME;
        }
        if(This->userinfo_split > -1)
            *pdwProperties |= Uri_HAS_PASSWORD;
        if(This->host_start > -1)
            *pdwProperties |= Uri_HAS_HOST;
        if(This->domain_offset > -1)
            *pdwProperties |= Uri_HAS_DOMAIN;
    }

    if(This->has_port)
        *pdwProperties |= Uri_HAS_PORT;
    if(This->path_start > -1)
        *pdwProperties |= Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY;
    if(This->query_start > -1)
        *pdwProperties |= Uri_HAS_QUERY|Uri_HAS_PATH_AND_QUERY;

    if(This->extension_offset > -1)
        *pdwProperties |= Uri_HAS_EXTENSION;

    if(This->fragment_start > -1)
        *pdwProperties |= Uri_HAS_FRAGMENT;

    return S_OK;
}

static HRESULT WINAPI Uri_IsEqual(IUri *iface, IUri *pUri, BOOL *pfEqual)
{
    Uri *This = impl_from_IUri(iface);
    Uri *other;

    TRACE("(%p %s)->(%p %p)\n", This, debugstr_w(This->canon_uri), pUri, pfEqual);

    if(!This->create_flags)
        return E_UNEXPECTED;
    if(!pfEqual)
        return E_POINTER;

    if(!pUri) {
        *pfEqual = FALSE;

        /* For some reason Windows returns S_OK here... */
        return S_OK;
    }

    /* Try to convert it to a Uri (allows for a more simple comparison). */
    if(!(other = get_uri_obj(pUri))) {
        FIXME("(%p)->(%p %p) No support for unknown IUri's yet.\n", iface, pUri, pfEqual);
        return E_NOTIMPL;
    }

    TRACE("comparing to %s\n", debugstr_w(other->canon_uri));
    return compare_uris(This, other, pfEqual);
}

static const IUriVtbl UriVtbl = {
    Uri_QueryInterface,
    Uri_AddRef,
    Uri_Release,
    Uri_GetPropertyBSTR,
    Uri_GetPropertyLength,
    Uri_GetPropertyDWORD,
    Uri_HasProperty,
    Uri_GetAbsoluteUri,
    Uri_GetAuthority,
    Uri_GetDisplayUri,
    Uri_GetDomain,
    Uri_GetExtension,
    Uri_GetFragment,
    Uri_GetHost,
    Uri_GetPassword,
    Uri_GetPath,
    Uri_GetPathAndQuery,
    Uri_GetQuery,
    Uri_GetRawUri,
    Uri_GetSchemeName,
    Uri_GetUserInfo,
    Uri_GetUserName,
    Uri_GetHostType,
    Uri_GetPort,
    Uri_GetScheme,
    Uri_GetZone,
    Uri_GetProperties,
    Uri_IsEqual
};

static inline Uri* impl_from_IUriBuilderFactory(IUriBuilderFactory *iface)
{
    return CONTAINING_RECORD(iface, Uri, IUriBuilderFactory_iface);
}

static HRESULT WINAPI UriBuilderFactory_QueryInterface(IUriBuilderFactory *iface, REFIID riid, void **ppv)
{
    Uri *This = impl_from_IUriBuilderFactory(iface);
    return IUri_QueryInterface(&This->IUri_iface, riid, ppv);
}

static ULONG WINAPI UriBuilderFactory_AddRef(IUriBuilderFactory *iface)
{
    Uri *This = impl_from_IUriBuilderFactory(iface);
    return IUri_AddRef(&This->IUri_iface);
}

static ULONG WINAPI UriBuilderFactory_Release(IUriBuilderFactory *iface)
{
    Uri *This = impl_from_IUriBuilderFactory(iface);
    return IUri_Release(&This->IUri_iface);
}

static HRESULT WINAPI UriBuilderFactory_CreateIUriBuilder(IUriBuilderFactory *iface,
                                                          DWORD dwFlags,
                                                          DWORD_PTR dwReserved,
                                                          IUriBuilder **ppIUriBuilder)
{
    Uri *This = impl_from_IUriBuilderFactory(iface);
    TRACE("(%p)->(%08x %08x %p)\n", This, dwFlags, (DWORD)dwReserved, ppIUriBuilder);

    if(!ppIUriBuilder)
        return E_POINTER;

    if(dwFlags || dwReserved) {
        *ppIUriBuilder = NULL;
        return E_INVALIDARG;
    }

    return CreateIUriBuilder(NULL, 0, 0, ppIUriBuilder);
}

static HRESULT WINAPI UriBuilderFactory_CreateInitializedIUriBuilder(IUriBuilderFactory *iface,
                                                                     DWORD dwFlags,
                                                                     DWORD_PTR dwReserved,
                                                                     IUriBuilder **ppIUriBuilder)
{
    Uri *This = impl_from_IUriBuilderFactory(iface);
    TRACE("(%p)->(%08x %08x %p)\n", This, dwFlags, (DWORD)dwReserved, ppIUriBuilder);

    if(!ppIUriBuilder)
        return E_POINTER;

    if(dwFlags || dwReserved) {
        *ppIUriBuilder = NULL;
        return E_INVALIDARG;
    }

    return CreateIUriBuilder(&This->IUri_iface, 0, 0, ppIUriBuilder);
}

static const IUriBuilderFactoryVtbl UriBuilderFactoryVtbl = {
    UriBuilderFactory_QueryInterface,
    UriBuilderFactory_AddRef,
    UriBuilderFactory_Release,
    UriBuilderFactory_CreateIUriBuilder,
    UriBuilderFactory_CreateInitializedIUriBuilder
};

static inline Uri* impl_from_IPersistStream(IPersistStream *iface)
{
    return CONTAINING_RECORD(iface, Uri, IPersistStream_iface);
}

static HRESULT WINAPI PersistStream_QueryInterface(IPersistStream *iface, REFIID riid, void **ppvObject)
{
    Uri *This = impl_from_IPersistStream(iface);
    return IUri_QueryInterface(&This->IUri_iface, riid, ppvObject);
}

static ULONG WINAPI PersistStream_AddRef(IPersistStream *iface)
{
    Uri *This = impl_from_IPersistStream(iface);
    return IUri_AddRef(&This->IUri_iface);
}

static ULONG WINAPI PersistStream_Release(IPersistStream *iface)
{
    Uri *This = impl_from_IPersistStream(iface);
    return IUri_Release(&This->IUri_iface);
}

static HRESULT WINAPI PersistStream_GetClassID(IPersistStream *iface, CLSID *pClassID)
{
    Uri *This = impl_from_IPersistStream(iface);
    TRACE("(%p)->(%p)\n", This, pClassID);

    if(!pClassID)
        return E_INVALIDARG;

    *pClassID = CLSID_CUri;
    return S_OK;
}

static HRESULT WINAPI PersistStream_IsDirty(IPersistStream *iface)
{
    Uri *This = impl_from_IPersistStream(iface);
    TRACE("(%p)\n", This);
    return S_FALSE;
}

struct persist_uri {
    DWORD size;
    DWORD unk1[2];
    DWORD create_flags;
    DWORD unk2[3];
    DWORD fields_no;
    BYTE data[1];
};

static HRESULT WINAPI PersistStream_Load(IPersistStream *iface, IStream *pStm)
{
    Uri *This = impl_from_IPersistStream(iface);
    struct persist_uri *data;
    parse_data parse;
    DWORD size;
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, pStm);

    if(This->create_flags)
        return E_UNEXPECTED;
    if(!pStm)
        return E_INVALIDARG;

    hr = IStream_Read(pStm, &size, sizeof(DWORD), NULL);
    if(FAILED(hr))
        return hr;
    data = heap_alloc(size);
    if(!data)
        return E_OUTOFMEMORY;
    hr = IStream_Read(pStm, &data->unk1, size-sizeof(DWORD)-2, NULL);
    if(FAILED(hr))
        return hr;

    if(size < sizeof(struct persist_uri)) {
        heap_free(data);
        return S_OK;
    }

    if(*(DWORD*)data->data != Uri_PROPERTY_RAW_URI) {
        heap_free(data);
        ERR("Can't find raw_uri\n");
        return E_UNEXPECTED;
    }

    This->raw_uri = SysAllocString((WCHAR*)(data->data+sizeof(DWORD)*2));
    if(!This->raw_uri) {
        heap_free(data);
        return E_OUTOFMEMORY;
    }
    This->create_flags = data->create_flags;
    heap_free(data);
    TRACE("%x %s\n", This->create_flags, debugstr_w(This->raw_uri));

    memset(&parse, 0, sizeof(parse_data));
    parse.uri = This->raw_uri;
    if(!parse_uri(&parse, This->create_flags)) {
        SysFreeString(This->raw_uri);
        This->create_flags = 0;
        return E_UNEXPECTED;
    }

    hr = canonicalize_uri(&parse, This, This->create_flags);
    if(FAILED(hr)) {
        SysFreeString(This->raw_uri);
        This->create_flags = 0;
        return hr;
    }

    return S_OK;
}

static inline BYTE* persist_stream_add_strprop(Uri *This, BYTE *p, DWORD type, DWORD len, WCHAR *data)
{
    len *= sizeof(WCHAR);
    *(DWORD*)p = type;
    p += sizeof(DWORD);
    *(DWORD*)p = len+sizeof(WCHAR);
    p += sizeof(DWORD);
    memcpy(p, data, len);
    p += len;
    *(WCHAR*)p = 0;
    return p+sizeof(WCHAR);
}

static inline void persist_stream_save(Uri *This, IStream *pStm, BOOL marshal, struct persist_uri *data)
{
    BYTE *p = NULL;

    data->create_flags = This->create_flags;

    if(This->create_flags) {
        data->fields_no = 1;
        p = persist_stream_add_strprop(This, data->data, Uri_PROPERTY_RAW_URI,
                SysStringLen(This->raw_uri), This->raw_uri);
    }
    if(This->scheme_type!=URL_SCHEME_HTTP && This->scheme_type!=URL_SCHEME_HTTPS
            && This->scheme_type!=URL_SCHEME_FTP)
        return;

    if(This->fragment_len) {
        data->fields_no++;
        p = persist_stream_add_strprop(This, p, Uri_PROPERTY_FRAGMENT,
                This->fragment_len, This->canon_uri+This->fragment_start);
    }

    if(This->host_len) {
        data->fields_no++;
        if(This->host_type == Uri_HOST_IPV6)
            p = persist_stream_add_strprop(This, p, Uri_PROPERTY_HOST,
                    This->host_len-2, This->canon_uri+This->host_start+1);
        else
            p = persist_stream_add_strprop(This, p, Uri_PROPERTY_HOST,
                    This->host_len, This->canon_uri+This->host_start);
    }

    if(This->userinfo_split > -1) {
        data->fields_no++;
        p = persist_stream_add_strprop(This, p, Uri_PROPERTY_PASSWORD,
                This->userinfo_len-This->userinfo_split-1,
                This->canon_uri+This->userinfo_start+This->userinfo_split+1);
    }

    if(This->path_len) {
        data->fields_no++;
        p = persist_stream_add_strprop(This, p, Uri_PROPERTY_PATH,
                This->path_len, This->canon_uri+This->path_start);
    } else if(marshal) {
        WCHAR no_path = '/';
        data->fields_no++;
        p = persist_stream_add_strprop(This, p, Uri_PROPERTY_PATH, 1, &no_path);
    }

    if(This->has_port) {
        data->fields_no++;
        *(DWORD*)p = Uri_PROPERTY_PORT;
        p += sizeof(DWORD);
        *(DWORD*)p = sizeof(DWORD);
        p += sizeof(DWORD);
        *(DWORD*)p = This->port;
        p += sizeof(DWORD);
    }

    if(This->query_len) {
        data->fields_no++;
        p = persist_stream_add_strprop(This, p, Uri_PROPERTY_QUERY,
                This->query_len, This->canon_uri+This->query_start);
    }

    if(This->scheme_len) {
        data->fields_no++;
        p = persist_stream_add_strprop(This, p, Uri_PROPERTY_SCHEME_NAME,
                This->scheme_len, This->canon_uri+This->scheme_start);
    }

    if(This->userinfo_start>-1 && This->userinfo_split!=0) {
        data->fields_no++;
        if(This->userinfo_split > -1)
            p = persist_stream_add_strprop(This, p, Uri_PROPERTY_USER_NAME,
                    This->userinfo_split, This->canon_uri+This->userinfo_start);
        else
            p = persist_stream_add_strprop(This, p, Uri_PROPERTY_USER_NAME,
                    This->userinfo_len, This->canon_uri+This->userinfo_start);
    }
}

static HRESULT WINAPI PersistStream_Save(IPersistStream *iface, IStream *pStm, BOOL fClearDirty)
{
    Uri *This = impl_from_IPersistStream(iface);
    struct persist_uri *data;
    ULARGE_INTEGER size;
    HRESULT hres;

    TRACE("(%p)->(%p %x)\n", This, pStm, fClearDirty);

    if(!pStm)
        return E_INVALIDARG;

    hres = IPersistStream_GetSizeMax(&This->IPersistStream_iface, &size);
    if(FAILED(hres))
        return hres;

    data = heap_alloc_zero(size.u.LowPart);
    if(!data)
        return E_OUTOFMEMORY;
    data->size = size.u.LowPart;
    persist_stream_save(This, pStm, FALSE, data);

    hres = IStream_Write(pStm, data, data->size-2, NULL);
    heap_free(data);
    return hres;
}

static HRESULT WINAPI PersistStream_GetSizeMax(IPersistStream *iface, ULARGE_INTEGER *pcbSize)
{
    Uri *This = impl_from_IPersistStream(iface);
    TRACE("(%p)->(%p)\n", This, pcbSize);

    if(!pcbSize)
        return E_INVALIDARG;

    pcbSize->u.LowPart = 2+sizeof(struct persist_uri);
    pcbSize->u.HighPart = 0;
    if(This->create_flags)
        pcbSize->u.LowPart += (SysStringLen(This->raw_uri)+1)*sizeof(WCHAR) + 2*sizeof(DWORD);
    else /* there's no place for fields no */
        pcbSize->u.LowPart -= sizeof(DWORD);
    if(This->scheme_type!=URL_SCHEME_HTTP && This->scheme_type!=URL_SCHEME_HTTPS
            && This->scheme_type!=URL_SCHEME_FTP)
        return S_OK;

    if(This->fragment_len)
        pcbSize->u.LowPart += (This->fragment_len+1)*sizeof(WCHAR) + 2*sizeof(DWORD);
    if(This->host_len) {
        if(This->host_type == Uri_HOST_IPV6)
            pcbSize->u.LowPart += (This->host_len-1)*sizeof(WCHAR) + 2*sizeof(DWORD);
        else
            pcbSize->u.LowPart += (This->host_len+1)*sizeof(WCHAR) + 2*sizeof(DWORD);
    }
    if(This->userinfo_split > -1)
        pcbSize->u.LowPart += (This->userinfo_len-This->userinfo_split)*sizeof(WCHAR) + 2*sizeof(DWORD);
    if(This->path_len)
        pcbSize->u.LowPart += (This->path_len+1)*sizeof(WCHAR) + 2*sizeof(DWORD);
    if(This->has_port)
        pcbSize->u.LowPart += 3*sizeof(DWORD);
    if(This->query_len)
        pcbSize->u.LowPart += (This->query_len+1)*sizeof(WCHAR) + 2*sizeof(DWORD);
    if(This->scheme_len)
        pcbSize->u.LowPart += (This->scheme_len+1)*sizeof(WCHAR) + 2*sizeof(DWORD);
    if(This->userinfo_start>-1 && This->userinfo_split!=0) {
        if(This->userinfo_split > -1)
            pcbSize->u.LowPart += (This->userinfo_split+1)*sizeof(WCHAR) + 2*sizeof(DWORD);
        else
            pcbSize->u.LowPart += (This->userinfo_len+1)*sizeof(WCHAR) + 2*sizeof(DWORD);
    }
    return S_OK;
}

static const IPersistStreamVtbl PersistStreamVtbl = {
    PersistStream_QueryInterface,
    PersistStream_AddRef,
    PersistStream_Release,
    PersistStream_GetClassID,
    PersistStream_IsDirty,
    PersistStream_Load,
    PersistStream_Save,
    PersistStream_GetSizeMax
};

static inline Uri* impl_from_IMarshal(IMarshal *iface)
{
    return CONTAINING_RECORD(iface, Uri, IMarshal_iface);
}

static HRESULT WINAPI Marshal_QueryInterface(IMarshal *iface, REFIID riid, void **ppvObject)
{
    Uri *This = impl_from_IMarshal(iface);
    return IUri_QueryInterface(&This->IUri_iface, riid, ppvObject);
}

static ULONG WINAPI Marshal_AddRef(IMarshal *iface)
{
    Uri *This = impl_from_IMarshal(iface);
    return IUri_AddRef(&This->IUri_iface);
}

static ULONG WINAPI Marshal_Release(IMarshal *iface)
{
    Uri *This = impl_from_IMarshal(iface);
    return IUri_Release(&This->IUri_iface);
}

static HRESULT WINAPI Marshal_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv,
        DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid)
{
    Uri *This = impl_from_IMarshal(iface);
    TRACE("(%p)->(%s %p %x %p %x %p)\n", This, debugstr_guid(riid), pv,
            dwDestContext, pvDestContext, mshlflags, pCid);

    if(!pCid || (dwDestContext!=MSHCTX_LOCAL && dwDestContext!=MSHCTX_NOSHAREDMEM
                && dwDestContext!=MSHCTX_INPROC))
        return E_INVALIDARG;

    *pCid = CLSID_CUri;
    return S_OK;
}

struct inproc_marshal_uri {
    DWORD size;
    DWORD mshlflags;
    DWORD unk[4]; /* process identifier? */
    Uri *uri;
};

static HRESULT WINAPI Marshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv,
        DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize)
{
    Uri *This = impl_from_IMarshal(iface);
    ULARGE_INTEGER size;
    HRESULT hres;
    TRACE("(%p)->(%s %p %x %p %x %p)\n", This, debugstr_guid(riid), pv,
            dwDestContext, pvDestContext, mshlflags, pSize);

    if(!pSize || (dwDestContext!=MSHCTX_LOCAL && dwDestContext!=MSHCTX_NOSHAREDMEM
                && dwDestContext!=MSHCTX_INPROC))
        return E_INVALIDARG;

    if(dwDestContext == MSHCTX_INPROC) {
        *pSize = sizeof(struct inproc_marshal_uri);
        return S_OK;
    }

    hres = IPersistStream_GetSizeMax(&This->IPersistStream_iface, &size);
    if(FAILED(hres))
        return hres;
    if(!This->path_len && (This->scheme_type==URL_SCHEME_HTTP
                || This->scheme_type==URL_SCHEME_HTTPS
                || This->scheme_type==URL_SCHEME_FTP))
        size.u.LowPart += 3*sizeof(DWORD);
    *pSize = size.u.LowPart+2*sizeof(DWORD);
    return S_OK;
}

static HRESULT WINAPI Marshal_MarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid,
        void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
{
    Uri *This = impl_from_IMarshal(iface);
    DWORD *data;
    DWORD size;
    HRESULT hres;

    TRACE("(%p)->(%p %s %p %x %p %x)\n", This, pStm, debugstr_guid(riid), pv,
            dwDestContext, pvDestContext, mshlflags);

    if(!pStm || mshlflags!=MSHLFLAGS_NORMAL || (dwDestContext!=MSHCTX_LOCAL
                && dwDestContext!=MSHCTX_NOSHAREDMEM && dwDestContext!=MSHCTX_INPROC))
        return E_INVALIDARG;

    if(dwDestContext == MSHCTX_INPROC) {
        struct inproc_marshal_uri data;

        data.size = sizeof(data);
        data.mshlflags = MSHCTX_INPROC;
        data.unk[0] = 0;
        data.unk[1] = 0;
        data.unk[2] = 0;
        data.unk[3] = 0;
        data.uri = This;

        hres = IStream_Write(pStm, &data, data.size, NULL);
        if(FAILED(hres))
            return hres;

        IUri_AddRef(&This->IUri_iface);
        return S_OK;
    }

    hres = IMarshal_GetMarshalSizeMax(iface, riid, pv, dwDestContext,
            pvDestContext, mshlflags, &size);
    if(FAILED(hres))
        return hres;

    data = heap_alloc_zero(size);
    if(!data)
        return E_OUTOFMEMORY;

    data[0] = size;
    data[1] = dwDestContext;
    data[2] = size-2*sizeof(DWORD);
    persist_stream_save(This, pStm, TRUE, (struct persist_uri*)(data+2));

    hres = IStream_Write(pStm, data, data[0]-2, NULL);
    heap_free(data);
    return hres;
}

static HRESULT WINAPI Marshal_UnmarshalInterface(IMarshal *iface,
        IStream *pStm, REFIID riid, void **ppv)
{
    Uri *This = impl_from_IMarshal(iface);
    DWORD header[2];
    HRESULT hres;

    TRACE("(%p)->(%p %s %p)\n", This, pStm, debugstr_guid(riid), ppv);

    if(This->create_flags)
        return E_UNEXPECTED;
    if(!pStm || !riid || !ppv)
        return E_INVALIDARG;

    hres = IStream_Read(pStm, header, sizeof(header), NULL);
    if(FAILED(hres))
        return hres;

    if(header[1]!=MSHCTX_LOCAL && header[1]!=MSHCTX_NOSHAREDMEM
            && header[1]!=MSHCTX_INPROC)
        return E_UNEXPECTED;

    if(header[1] == MSHCTX_INPROC) {
        struct inproc_marshal_uri data;
        parse_data parse;

        hres = IStream_Read(pStm, data.unk, sizeof(data)-2*sizeof(DWORD), NULL);
        if(FAILED(hres))
            return hres;

        This->raw_uri = SysAllocString(data.uri->raw_uri);
        if(!This->raw_uri) {
            return E_OUTOFMEMORY;
        }

        memset(&parse, 0, sizeof(parse_data));
        parse.uri = This->raw_uri;

        if(!parse_uri(&parse, data.uri->create_flags))
            return E_INVALIDARG;

        hres = canonicalize_uri(&parse, This, data.uri->create_flags);
        if(FAILED(hres))
            return hres;

        This->create_flags = data.uri->create_flags;
        IUri_Release(&data.uri->IUri_iface);

        return IUri_QueryInterface(&This->IUri_iface, riid, ppv);
    }

    hres = IPersistStream_Load(&This->IPersistStream_iface, pStm);
    if(FAILED(hres))
        return hres;

    return IUri_QueryInterface(&This->IUri_iface, riid, ppv);
}

static HRESULT WINAPI Marshal_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
{
    Uri *This = impl_from_IMarshal(iface);
    LARGE_INTEGER off;
    DWORD header[2];
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, pStm);

    if(!pStm)
        return E_INVALIDARG;

    hres = IStream_Read(pStm, header, 2*sizeof(DWORD), NULL);
    if(FAILED(hres))
        return hres;

    if(header[1] == MSHCTX_INPROC) {
        struct inproc_marshal_uri data;

        hres = IStream_Read(pStm, data.unk, sizeof(data)-2*sizeof(DWORD), NULL);
        if(FAILED(hres))
            return hres;

        IUri_Release(&data.uri->IUri_iface);
        return S_OK;
    }

    off.u.LowPart = header[0]-sizeof(header)-2;
    off.u.HighPart = 0;
    return IStream_Seek(pStm, off, STREAM_SEEK_CUR, NULL);
}

static HRESULT WINAPI Marshal_DisconnectObject(IMarshal *iface, DWORD dwReserved)
{
    Uri *This = impl_from_IMarshal(iface);
    TRACE("(%p)->(%x)\n", This, dwReserved);
    return S_OK;
}

static const IMarshalVtbl MarshalVtbl = {
    Marshal_QueryInterface,
    Marshal_AddRef,
    Marshal_Release,
    Marshal_GetUnmarshalClass,
    Marshal_GetMarshalSizeMax,
    Marshal_MarshalInterface,
    Marshal_UnmarshalInterface,
    Marshal_ReleaseMarshalData,
    Marshal_DisconnectObject
};

HRESULT Uri_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
    Uri *ret = heap_alloc_zero(sizeof(Uri));

    TRACE("(%p %p)\n", pUnkOuter, ppobj);

    *ppobj = ret;
    if(!ret)
        return E_OUTOFMEMORY;

    ret->IUri_iface.lpVtbl = &UriVtbl;
    ret->IUriBuilderFactory_iface.lpVtbl = &UriBuilderFactoryVtbl;
    ret->IPersistStream_iface.lpVtbl = &PersistStreamVtbl;
    ret->IMarshal_iface.lpVtbl = &MarshalVtbl;
    ret->ref = 1;

    *ppobj = &ret->IUri_iface;
    return S_OK;
}

/***********************************************************************
 *           CreateUri (urlmon.@)
 *
 * Creates a new IUri object using the URI represented by pwzURI. This function
 * parses and validates the components of pwzURI and then canonicalizes the
 * parsed components.
 *
 * PARAMS
 *  pwzURI      [I] The URI to parse, validate, and canonicalize.
 *  dwFlags     [I] Flags which can affect how the parsing/canonicalization is performed.
 *  dwReserved  [I] Reserved (not used).
 *  ppURI       [O] The resulting IUri after parsing/canonicalization occurs.
 *
 * RETURNS
 *  Success: Returns S_OK. ppURI contains the pointer to the newly allocated IUri.
 *  Failure: E_INVALIDARG if there are invalid flag combinations in dwFlags, or an
 *           invalid parameter, or pwzURI doesn't represent a valid URI.
 *           E_OUTOFMEMORY if any memory allocation fails.
 *
 * NOTES
 *  Default flags:
 *      Uri_CREATE_CANONICALIZE, Uri_CREATE_DECODE_EXTRA_INFO, Uri_CREATE_CRACK_UNKNOWN_SCHEMES,
 *      Uri_CREATE_PRE_PROCESS_HTML_URI, Uri_CREATE_NO_IE_SETTINGS.
 */
HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IUri **ppURI)
{
    const DWORD supported_flags = Uri_CREATE_ALLOW_RELATIVE|Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME|
        Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME|Uri_CREATE_NO_CANONICALIZE|Uri_CREATE_CANONICALIZE|
        Uri_CREATE_DECODE_EXTRA_INFO|Uri_CREATE_NO_DECODE_EXTRA_INFO|Uri_CREATE_CRACK_UNKNOWN_SCHEMES|
        Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES|Uri_CREATE_PRE_PROCESS_HTML_URI|Uri_CREATE_NO_PRE_PROCESS_HTML_URI|
        Uri_CREATE_NO_IE_SETTINGS|Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS|Uri_CREATE_FILE_USE_DOS_PATH;
    Uri *ret;
    HRESULT hr;
    parse_data data;

    TRACE("(%s %x %x %p)\n", debugstr_w(pwzURI), dwFlags, (DWORD)dwReserved, ppURI);

    if(!ppURI)
        return E_INVALIDARG;

    if(!pwzURI) {
        *ppURI = NULL;
        return E_INVALIDARG;
    }

    /* Check for invalid flags. */
    if(has_invalid_flag_combination(dwFlags)) {
        *ppURI = NULL;
        return E_INVALIDARG;
    }

    /* Currently unsupported. */
    if(dwFlags & ~supported_flags)
        FIXME("Ignoring unsupported flag(s) %x\n", dwFlags & ~supported_flags);

    hr = Uri_Construct(NULL, (void**)&ret);
    if(FAILED(hr)) {
        *ppURI = NULL;
        return hr;
    }

    /* Explicitly set the default flags if it doesn't cause a flag conflict. */
    apply_default_flags(&dwFlags);

    /* Pre process the URI, unless told otherwise. */
    if(!(dwFlags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI))
        ret->raw_uri = pre_process_uri(pwzURI);
    else
        ret->raw_uri = SysAllocString(pwzURI);

    if(!ret->raw_uri) {
        heap_free(ret);
        return E_OUTOFMEMORY;
    }

    memset(&data, 0, sizeof(parse_data));
    data.uri = ret->raw_uri;

    /* Validate and parse the URI into its components. */
    if(!parse_uri(&data, dwFlags)) {
        /* Encountered an unsupported or invalid URI */
        IUri_Release(&ret->IUri_iface);
        *ppURI = NULL;
        return E_INVALIDARG;
    }

    /* Canonicalize the URI. */
    hr = canonicalize_uri(&data, ret, dwFlags);
    if(FAILED(hr)) {
        IUri_Release(&ret->IUri_iface);
        *ppURI = NULL;
        return hr;
    }

    ret->create_flags = dwFlags;

    *ppURI = &ret->IUri_iface;
    return S_OK;
}

/***********************************************************************
 *           CreateUriWithFragment (urlmon.@)
 *
 * Creates a new IUri object. This is almost the same as CreateUri, expect that
 * it allows you to explicitly specify a fragment (pwzFragment) for pwzURI.
 *
 * PARAMS
 *  pwzURI      [I] The URI to parse and perform canonicalization on.
 *  pwzFragment [I] The explicit fragment string which should be added to pwzURI.
 *  dwFlags     [I] The flags which will be passed to CreateUri.
 *  dwReserved  [I] Reserved (not used).
 *  ppURI       [O] The resulting IUri after parsing/canonicalization.
 *
 * RETURNS
 *  Success: S_OK. ppURI contains the pointer to the newly allocated IUri.
 *  Failure: E_INVALIDARG if pwzURI already contains a fragment and pwzFragment
 *           isn't NULL. Will also return E_INVALIDARG for the same reasons as
 *           CreateUri will. E_OUTOFMEMORY if any allocation fails.
 */
HRESULT WINAPI CreateUriWithFragment(LPCWSTR pwzURI, LPCWSTR pwzFragment, DWORD dwFlags,
                                     DWORD_PTR dwReserved, IUri **ppURI)
{
    HRESULT hres;
    TRACE("(%s %s %x %x %p)\n", debugstr_w(pwzURI), debugstr_w(pwzFragment), dwFlags, (DWORD)dwReserved, ppURI);

    if(!ppURI)
        return E_INVALIDARG;

    if(!pwzURI) {
        *ppURI = NULL;
        return E_INVALIDARG;
    }

    /* Check if a fragment should be appended to the URI string. */
    if(pwzFragment) {
        WCHAR *uriW;
        DWORD uri_len, frag_len;
        BOOL add_pound;

        /* Check if the original URI already has a fragment component. */
        if(StrChrW(pwzURI, '#')) {
            *ppURI = NULL;
            return E_INVALIDARG;
        }

        uri_len = lstrlenW(pwzURI);
        frag_len = lstrlenW(pwzFragment);

        /* If the fragment doesn't start with a '#', one will be added. */
        add_pound = *pwzFragment != '#';

        if(add_pound)
            uriW = heap_alloc((uri_len+frag_len+2)*sizeof(WCHAR));
        else
            uriW = heap_alloc((uri_len+frag_len+1)*sizeof(WCHAR));

        if(!uriW)
            return E_OUTOFMEMORY;

        memcpy(uriW, pwzURI, uri_len*sizeof(WCHAR));
        if(add_pound)
            uriW[uri_len++] = '#';
        memcpy(uriW+uri_len, pwzFragment, (frag_len+1)*sizeof(WCHAR));

        hres = CreateUri(uriW, dwFlags, 0, ppURI);

        heap_free(uriW);
    } else
        /* A fragment string wasn't specified, so just forward the call. */
        hres = CreateUri(pwzURI, dwFlags, 0, ppURI);

    return hres;
}

static HRESULT build_uri(const UriBuilder *builder, IUri **uri, DWORD create_flags,
                         DWORD use_orig_flags, DWORD encoding_mask)
{
    HRESULT hr;
    parse_data data;
    Uri *ret;

    if(!uri)
        return E_POINTER;

    if(encoding_mask && (!builder->uri || builder->modified_props)) {
        *uri = NULL;
        return E_NOTIMPL;
    }

    /* Decide what flags should be used when creating the Uri. */
    if((use_orig_flags & UriBuilder_USE_ORIGINAL_FLAGS) && builder->uri)
        create_flags = builder->uri->create_flags;
    else {
        if(has_invalid_flag_combination(create_flags)) {
            *uri = NULL;
            return E_INVALIDARG;
        }

        /* Set the default flags if they don't cause a conflict. */
        apply_default_flags(&create_flags);
    }

    /* Return the base IUri if no changes have been made and the create_flags match. */
    if(builder->uri && !builder->modified_props && builder->uri->create_flags == create_flags) {
        *uri = &builder->uri->IUri_iface;
        IUri_AddRef(*uri);
        return S_OK;
    }

    hr = validate_components(builder, &data, create_flags);
    if(FAILED(hr)) {
        *uri = NULL;
        return hr;
    }

    hr = Uri_Construct(NULL, (void**)&ret);
    if(FAILED(hr)) {
        *uri = NULL;
        return hr;
    }

    hr = generate_uri(builder, &data, ret, create_flags);
    if(FAILED(hr)) {
        IUri_Release(&ret->IUri_iface);
        *uri = NULL;
        return hr;
    }

    *uri = &ret->IUri_iface;
    return S_OK;
}

static inline UriBuilder* impl_from_IUriBuilder(IUriBuilder *iface)
{
    return CONTAINING_RECORD(iface, UriBuilder, IUriBuilder_iface);
}

static HRESULT WINAPI UriBuilder_QueryInterface(IUriBuilder *iface, REFIID riid, void **ppv)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IUriBuilder_iface;
    }else if(IsEqualGUID(&IID_IUriBuilder, riid)) {
        TRACE("(%p)->(IID_IUriBuilder %p)\n", This, ppv);
        *ppv = &This->IUriBuilder_iface;
    }else {
        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI UriBuilder_AddRef(IUriBuilder *iface)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI UriBuilder_Release(IUriBuilder *iface)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        if(This->uri) IUri_Release(&This->uri->IUri_iface);
        heap_free(This->fragment);
        heap_free(This->host);
        heap_free(This->password);
        heap_free(This->path);
        heap_free(This->query);
        heap_free(This->scheme);
        heap_free(This->username);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI UriBuilder_CreateUriSimple(IUriBuilder *iface,
                                                 DWORD        dwAllowEncodingPropertyMask,
                                                 DWORD_PTR    dwReserved,
                                                 IUri       **ppIUri)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    HRESULT hr;
    TRACE("(%p)->(%d %d %p)\n", This, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);

    hr = build_uri(This, ppIUri, 0, UriBuilder_USE_ORIGINAL_FLAGS, dwAllowEncodingPropertyMask);
    if(hr == E_NOTIMPL)
        FIXME("(%p)->(%d %d %p)\n", This, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
    return hr;
}

static HRESULT WINAPI UriBuilder_CreateUri(IUriBuilder *iface,
                                           DWORD        dwCreateFlags,
                                           DWORD        dwAllowEncodingPropertyMask,
                                           DWORD_PTR    dwReserved,
                                           IUri       **ppIUri)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    HRESULT hr;
    TRACE("(%p)->(0x%08x %d %d %p)\n", This, dwCreateFlags, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);

    if(dwCreateFlags == -1)
        hr = build_uri(This, ppIUri, 0, UriBuilder_USE_ORIGINAL_FLAGS, dwAllowEncodingPropertyMask);
    else
        hr = build_uri(This, ppIUri, dwCreateFlags, 0, dwAllowEncodingPropertyMask);

    if(hr == E_NOTIMPL)
        FIXME("(%p)->(0x%08x %d %d %p)\n", This, dwCreateFlags, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
    return hr;
}

static HRESULT WINAPI UriBuilder_CreateUriWithFlags(IUriBuilder *iface,
                                         DWORD        dwCreateFlags,
                                         DWORD        dwUriBuilderFlags,
                                         DWORD        dwAllowEncodingPropertyMask,
                                         DWORD_PTR    dwReserved,
                                         IUri       **ppIUri)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    HRESULT hr;
    TRACE("(%p)->(0x%08x 0x%08x %d %d %p)\n", This, dwCreateFlags, dwUriBuilderFlags,
        dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);

    hr = build_uri(This, ppIUri, dwCreateFlags, dwUriBuilderFlags, dwAllowEncodingPropertyMask);
    if(hr == E_NOTIMPL)
        FIXME("(%p)->(0x%08x 0x%08x %d %d %p)\n", This, dwCreateFlags, dwUriBuilderFlags,
            dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
    return hr;
}

static HRESULT WINAPI  UriBuilder_GetIUri(IUriBuilder *iface, IUri **ppIUri)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p)\n", This, ppIUri);

    if(!ppIUri)
        return E_POINTER;

    if(This->uri) {
        IUri *uri = &This->uri->IUri_iface;
        IUri_AddRef(uri);
        *ppIUri = uri;
    } else
        *ppIUri = NULL;

    return S_OK;
}

static HRESULT WINAPI UriBuilder_SetIUri(IUriBuilder *iface, IUri *pIUri)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p)\n", This, pIUri);

    if(pIUri) {
        Uri *uri;

        if((uri = get_uri_obj(pIUri))) {
            /* Only reset the builder if it's Uri isn't the same as
             * the Uri passed to the function.
             */
            if(This->uri != uri) {
                reset_builder(This);

                This->uri = uri;
                if(uri->has_port)
                    This->port = uri->port;

                IUri_AddRef(pIUri);
            }
        } else {
            FIXME("(%p)->(%p) Unknown IUri types not supported yet.\n", This, pIUri);
            return E_NOTIMPL;
        }
    } else if(This->uri)
        /* Only reset the builder if it's Uri isn't NULL. */
        reset_builder(This);

    return S_OK;
}

static HRESULT WINAPI UriBuilder_GetFragment(IUriBuilder *iface, DWORD *pcchFragment, LPCWSTR *ppwzFragment)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p %p)\n", This, pcchFragment, ppwzFragment);

    if(!This->uri || This->uri->fragment_start == -1 || This->modified_props & Uri_HAS_FRAGMENT)
        return get_builder_component(&This->fragment, &This->fragment_len, NULL, 0, ppwzFragment, pcchFragment);
    else
        return get_builder_component(&This->fragment, &This->fragment_len, This->uri->canon_uri+This->uri->fragment_start,
                                     This->uri->fragment_len, ppwzFragment, pcchFragment);
}

static HRESULT WINAPI UriBuilder_GetHost(IUriBuilder *iface, DWORD *pcchHost, LPCWSTR *ppwzHost)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p %p)\n", This, pcchHost, ppwzHost);

    if(!This->uri || This->uri->host_start == -1 || This->modified_props & Uri_HAS_HOST)
        return get_builder_component(&This->host, &This->host_len, NULL, 0, ppwzHost, pcchHost);
    else {
        if(This->uri->host_type == Uri_HOST_IPV6)
            /* Don't include the '[' and ']' around the address. */
            return get_builder_component(&This->host, &This->host_len, This->uri->canon_uri+This->uri->host_start+1,
                                         This->uri->host_len-2, ppwzHost, pcchHost);
        else
            return get_builder_component(&This->host, &This->host_len, This->uri->canon_uri+This->uri->host_start,
                                         This->uri->host_len, ppwzHost, pcchHost);
    }
}

static HRESULT WINAPI UriBuilder_GetPassword(IUriBuilder *iface, DWORD *pcchPassword, LPCWSTR *ppwzPassword)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p %p)\n", This, pcchPassword, ppwzPassword);

    if(!This->uri || This->uri->userinfo_split == -1 || This->modified_props & Uri_HAS_PASSWORD)
        return get_builder_component(&This->password, &This->password_len, NULL, 0, ppwzPassword, pcchPassword);
    else {
        const WCHAR *start = This->uri->canon_uri+This->uri->userinfo_start+This->uri->userinfo_split+1;
        DWORD len = This->uri->userinfo_len-This->uri->userinfo_split-1;
        return get_builder_component(&This->password, &This->password_len, start, len, ppwzPassword, pcchPassword);
    }
}

static HRESULT WINAPI UriBuilder_GetPath(IUriBuilder *iface, DWORD *pcchPath, LPCWSTR *ppwzPath)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p %p)\n", This, pcchPath, ppwzPath);

    if(!This->uri || This->uri->path_start == -1 || This->modified_props & Uri_HAS_PATH)
        return get_builder_component(&This->path, &This->path_len, NULL, 0, ppwzPath, pcchPath);
    else
        return get_builder_component(&This->path, &This->path_len, This->uri->canon_uri+This->uri->path_start,
                                     This->uri->path_len, ppwzPath, pcchPath);
}

static HRESULT WINAPI UriBuilder_GetPort(IUriBuilder *iface, BOOL *pfHasPort, DWORD *pdwPort)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p %p)\n", This, pfHasPort, pdwPort);

    if(!pfHasPort) {
        if(pdwPort)
            *pdwPort = 0;
        return E_POINTER;
    }

    if(!pdwPort) {
        *pfHasPort = FALSE;
        return E_POINTER;
    }

    *pfHasPort = This->has_port;
    *pdwPort = This->port;
    return S_OK;
}

static HRESULT WINAPI UriBuilder_GetQuery(IUriBuilder *iface, DWORD *pcchQuery, LPCWSTR *ppwzQuery)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p %p)\n", This, pcchQuery, ppwzQuery);

    if(!This->uri || This->uri->query_start == -1 || This->modified_props & Uri_HAS_QUERY)
        return get_builder_component(&This->query, &This->query_len, NULL, 0, ppwzQuery, pcchQuery);
    else
        return get_builder_component(&This->query, &This->query_len, This->uri->canon_uri+This->uri->query_start,
                                     This->uri->query_len, ppwzQuery, pcchQuery);
}

static HRESULT WINAPI UriBuilder_GetSchemeName(IUriBuilder *iface, DWORD *pcchSchemeName, LPCWSTR *ppwzSchemeName)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p %p)\n", This, pcchSchemeName, ppwzSchemeName);

    if(!This->uri || This->uri->scheme_start == -1 || This->modified_props & Uri_HAS_SCHEME_NAME)
        return get_builder_component(&This->scheme, &This->scheme_len, NULL, 0, ppwzSchemeName, pcchSchemeName);
    else
        return get_builder_component(&This->scheme, &This->scheme_len, This->uri->canon_uri+This->uri->scheme_start,
                                     This->uri->scheme_len, ppwzSchemeName, pcchSchemeName);
}

static HRESULT WINAPI UriBuilder_GetUserName(IUriBuilder *iface, DWORD *pcchUserName, LPCWSTR *ppwzUserName)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p %p)\n", This, pcchUserName, ppwzUserName);

    if(!This->uri || This->uri->userinfo_start == -1 || This->uri->userinfo_split == 0 ||
       This->modified_props & Uri_HAS_USER_NAME)
        return get_builder_component(&This->username, &This->username_len, NULL, 0, ppwzUserName, pcchUserName);
    else {
        const WCHAR *start = This->uri->canon_uri+This->uri->userinfo_start;

        /* Check if there's a password in the userinfo section. */
        if(This->uri->userinfo_split > -1)
            /* Don't include the password. */
            return get_builder_component(&This->username, &This->username_len, start,
                                         This->uri->userinfo_split, ppwzUserName, pcchUserName);
        else
            return get_builder_component(&This->username, &This->username_len, start,
                                         This->uri->userinfo_len, ppwzUserName, pcchUserName);
    }
}

static HRESULT WINAPI UriBuilder_SetFragment(IUriBuilder *iface, LPCWSTR pwzNewValue)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzNewValue));
    return set_builder_component(&This->fragment, &This->fragment_len, pwzNewValue, '#',
                                 &This->modified_props, Uri_HAS_FRAGMENT);
}

static HRESULT WINAPI UriBuilder_SetHost(IUriBuilder *iface, LPCWSTR pwzNewValue)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzNewValue));

    /* Host name can't be set to NULL. */
    if(!pwzNewValue)
        return E_INVALIDARG;

    return set_builder_component(&This->host, &This->host_len, pwzNewValue, 0,
                                 &This->modified_props, Uri_HAS_HOST);
}

static HRESULT WINAPI UriBuilder_SetPassword(IUriBuilder *iface, LPCWSTR pwzNewValue)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzNewValue));
    return set_builder_component(&This->password, &This->password_len, pwzNewValue, 0,
                                 &This->modified_props, Uri_HAS_PASSWORD);
}

static HRESULT WINAPI UriBuilder_SetPath(IUriBuilder *iface, LPCWSTR pwzNewValue)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzNewValue));
    return set_builder_component(&This->path, &This->path_len, pwzNewValue, 0,
                                 &This->modified_props, Uri_HAS_PATH);
}

static HRESULT WINAPI UriBuilder_SetPort(IUriBuilder *iface, BOOL fHasPort, DWORD dwNewValue)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%d %d)\n", This, fHasPort, dwNewValue);

    This->has_port = fHasPort;
    This->port = dwNewValue;
    This->modified_props |= Uri_HAS_PORT;
    return S_OK;
}

static HRESULT WINAPI UriBuilder_SetQuery(IUriBuilder *iface, LPCWSTR pwzNewValue)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzNewValue));
    return set_builder_component(&This->query, &This->query_len, pwzNewValue, '?',
                                 &This->modified_props, Uri_HAS_QUERY);
}

static HRESULT WINAPI UriBuilder_SetSchemeName(IUriBuilder *iface, LPCWSTR pwzNewValue)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzNewValue));

    /* Only set the scheme name if it's not NULL or empty. */
    if(!pwzNewValue || !*pwzNewValue)
        return E_INVALIDARG;

    return set_builder_component(&This->scheme, &This->scheme_len, pwzNewValue, 0,
                                 &This->modified_props, Uri_HAS_SCHEME_NAME);
}

static HRESULT WINAPI UriBuilder_SetUserName(IUriBuilder *iface, LPCWSTR pwzNewValue)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzNewValue));
    return set_builder_component(&This->username, &This->username_len, pwzNewValue, 0,
                                 &This->modified_props, Uri_HAS_USER_NAME);
}

static HRESULT WINAPI UriBuilder_RemoveProperties(IUriBuilder *iface, DWORD dwPropertyMask)
{
    const DWORD accepted_flags = Uri_HAS_AUTHORITY|Uri_HAS_DOMAIN|Uri_HAS_EXTENSION|Uri_HAS_FRAGMENT|Uri_HAS_HOST|
                                 Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|
                                 Uri_HAS_USER_INFO|Uri_HAS_USER_NAME;

    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(0x%08x)\n", This, dwPropertyMask);

    if(dwPropertyMask & ~accepted_flags)
        return E_INVALIDARG;

    if(dwPropertyMask & Uri_HAS_FRAGMENT)
        UriBuilder_SetFragment(iface, NULL);

    /* Even though you can't set the host name to NULL or an
     * empty string, you can still remove it... for some reason.
     */
    if(dwPropertyMask & Uri_HAS_HOST)
        set_builder_component(&This->host, &This->host_len, NULL, 0,
                              &This->modified_props, Uri_HAS_HOST);

    if(dwPropertyMask & Uri_HAS_PASSWORD)
        UriBuilder_SetPassword(iface, NULL);

    if(dwPropertyMask & Uri_HAS_PATH)
        UriBuilder_SetPath(iface, NULL);

    if(dwPropertyMask & Uri_HAS_PORT)
        UriBuilder_SetPort(iface, FALSE, 0);

    if(dwPropertyMask & Uri_HAS_QUERY)
        UriBuilder_SetQuery(iface, NULL);

    if(dwPropertyMask & Uri_HAS_USER_NAME)
        UriBuilder_SetUserName(iface, NULL);

    return S_OK;
}

static HRESULT WINAPI UriBuilder_HasBeenModified(IUriBuilder *iface, BOOL *pfModified)
{
    UriBuilder *This = impl_from_IUriBuilder(iface);
    TRACE("(%p)->(%p)\n", This, pfModified);

    if(!pfModified)
        return E_POINTER;

    *pfModified = This->modified_props > 0;
    return S_OK;
}

static const IUriBuilderVtbl UriBuilderVtbl = {
    UriBuilder_QueryInterface,
    UriBuilder_AddRef,
    UriBuilder_Release,
    UriBuilder_CreateUriSimple,
    UriBuilder_CreateUri,
    UriBuilder_CreateUriWithFlags,
    UriBuilder_GetIUri,
    UriBuilder_SetIUri,
    UriBuilder_GetFragment,
    UriBuilder_GetHost,
    UriBuilder_GetPassword,
    UriBuilder_GetPath,
    UriBuilder_GetPort,
    UriBuilder_GetQuery,
    UriBuilder_GetSchemeName,
    UriBuilder_GetUserName,
    UriBuilder_SetFragment,
    UriBuilder_SetHost,
    UriBuilder_SetPassword,
    UriBuilder_SetPath,
    UriBuilder_SetPort,
    UriBuilder_SetQuery,
    UriBuilder_SetSchemeName,
    UriBuilder_SetUserName,
    UriBuilder_RemoveProperties,
    UriBuilder_HasBeenModified,
};

/***********************************************************************
 *           CreateIUriBuilder (urlmon.@)
 */
HRESULT WINAPI CreateIUriBuilder(IUri *pIUri, DWORD dwFlags, DWORD_PTR dwReserved, IUriBuilder **ppIUriBuilder)
{
    UriBuilder *ret;

    TRACE("(%p %x %x %p)\n", pIUri, dwFlags, (DWORD)dwReserved, ppIUriBuilder);

    if(!ppIUriBuilder)
        return E_POINTER;

    ret = heap_alloc_zero(sizeof(UriBuilder));
    if(!ret)
        return E_OUTOFMEMORY;

    ret->IUriBuilder_iface.lpVtbl = &UriBuilderVtbl;
    ret->ref = 1;

    if(pIUri) {
        Uri *uri;

        if((uri = get_uri_obj(pIUri))) {
            if(!uri->create_flags)
                return E_UNEXPECTED;
            IUri_AddRef(pIUri);
            ret->uri = uri;

            if(uri->has_port)
                /* Windows doesn't set 'has_port' to TRUE in this case. */
                ret->port = uri->port;

        } else {
            heap_free(ret);
            *ppIUriBuilder = NULL;
            FIXME("(%p %x %x %p): Unknown IUri types not supported yet.\n", pIUri, dwFlags,
                (DWORD)dwReserved, ppIUriBuilder);
            return E_NOTIMPL;
        }
    }

    *ppIUriBuilder = &ret->IUriBuilder_iface;
    return S_OK;
}

/* Merges the base path with the relative path and stores the resulting path
 * and path len in 'result' and 'result_len'.
 */
static HRESULT merge_paths(parse_data *data, const WCHAR *base, DWORD base_len, const WCHAR *relative,
                           DWORD relative_len, WCHAR **result, DWORD *result_len, DWORD flags)
{
    const WCHAR *end = NULL;
    DWORD base_copy_len = 0;
    WCHAR *ptr;

    if(base_len) {
        if(data->scheme_type == URL_SCHEME_MK && *relative == '/') {
            /* Find '::' segment */
            for(end = base; end < base+base_len-1; end++) {
                if(end[0] == ':' && end[1] == ':') {
                    end++;
                    break;
                }
            }

            /* If not found, try finding the end of @xxx: */
            if(end == base+base_len-1)
                end = *base == '@' ? memchr(base, ':', base_len) : NULL;
        }else {
            /* Find the characters that will be copied over from the base path. */
            end = memrchrW(base, '/', base_len);
            if(!end && data->scheme_type == URL_SCHEME_FILE)
                /* Try looking for a '\\'. */
                end = memrchrW(base, '\\', base_len);
        }
    }

    if(end) {
        base_copy_len = (end+1)-base;
        *result = heap_alloc((base_copy_len+relative_len+1)*sizeof(WCHAR));
    } else
        *result = heap_alloc((relative_len+1)*sizeof(WCHAR));

    if(!(*result)) {
        *result_len = 0;
        return E_OUTOFMEMORY;
    }

    ptr = *result;
    if(end) {
        memcpy(ptr, base, base_copy_len*sizeof(WCHAR));
        ptr += base_copy_len;
    }

    memcpy(ptr, relative, relative_len*sizeof(WCHAR));
    ptr += relative_len;
    *ptr = '\0';

    *result_len = (ptr-*result);
    TRACE("ret %s\n", debugstr_wn(*result, *result_len));
    return S_OK;
}

static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result, DWORD extras) {
    Uri *ret;
    HRESULT hr;
    parse_data data;
    Uri *proc_uri = base;
    DWORD create_flags = 0, len = 0;

    memset(&data, 0, sizeof(parse_data));

    /* Base case is when the relative Uri has a scheme name,
     * if it does, then 'result' will contain the same data
     * as the relative Uri.
     */
    if(relative->scheme_start > -1) {
        data.uri = SysAllocString(relative->raw_uri);
        if(!data.uri) {
            *result = NULL;
            return E_OUTOFMEMORY;
        }

        parse_uri(&data, 0);

        hr = Uri_Construct(NULL, (void**)&ret);
        if(FAILED(hr)) {
            *result = NULL;
            return hr;
        }

        if(extras & COMBINE_URI_FORCE_FLAG_USE) {
            if(flags & URL_DONT_SIMPLIFY)
                create_flags |= Uri_CREATE_NO_CANONICALIZE;
            if(flags & URL_DONT_UNESCAPE_EXTRA_INFO)
                create_flags |= Uri_CREATE_NO_DECODE_EXTRA_INFO;
        }

        ret->raw_uri = data.uri;
        hr = canonicalize_uri(&data, ret, create_flags);
        if(FAILED(hr)) {
            IUri_Release(&ret->IUri_iface);
            *result = NULL;
            return hr;
        }

        apply_default_flags(&create_flags);
        ret->create_flags = create_flags;

        *result = &ret->IUri_iface;
    } else {
        WCHAR *path = NULL;
        DWORD raw_flags = 0;

        if(base->scheme_start > -1) {
            data.scheme = base->canon_uri+base->scheme_start;
            data.scheme_len = base->scheme_len;
            data.scheme_type = base->scheme_type;
        } else {
            data.is_relative = TRUE;
            data.scheme_type = URL_SCHEME_UNKNOWN;
            create_flags |= Uri_CREATE_ALLOW_RELATIVE;
        }

        if(relative->authority_start > -1)
            proc_uri = relative;

        if(proc_uri->authority_start > -1) {
            if(proc_uri->userinfo_start > -1 && proc_uri->userinfo_split != 0) {
                data.username = proc_uri->canon_uri+proc_uri->userinfo_start;
                data.username_len = (proc_uri->userinfo_split > -1) ? proc_uri->userinfo_split : proc_uri->userinfo_len;
            }

            if(proc_uri->userinfo_split > -1) {
                data.password = proc_uri->canon_uri+proc_uri->userinfo_start+proc_uri->userinfo_split+1;
                data.password_len = proc_uri->userinfo_len-proc_uri->userinfo_split-1;
            }

            if(proc_uri->host_start > -1) {
                data.host = proc_uri->canon_uri+proc_uri->host_start;
                data.host_len = proc_uri->host_len;
                data.host_type = proc_uri->host_type;
            }

            if(proc_uri->has_port) {
                data.has_port = TRUE;
                data.port_value = proc_uri->port;
            }
        } else if(base->scheme_type != URL_SCHEME_FILE)
            data.is_opaque = TRUE;

        if(proc_uri == relative || relative->path_start == -1 || !relative->path_len) {
            if(proc_uri->path_start > -1) {
                data.path = proc_uri->canon_uri+proc_uri->path_start;
                data.path_len = proc_uri->path_len;
            } else if(!data.is_opaque) {
                /* Just set the path as a '/' if the base didn't have
                 * one and if it's an hierarchical URI.
                 */
                static const WCHAR slashW[] = {'/',0};
                data.path = slashW;
                data.path_len = 1;
            }

            if(relative->query_start > -1)
                proc_uri = relative;

            if(proc_uri->query_start > -1) {
                data.query = proc_uri->canon_uri+proc_uri->query_start;
                data.query_len = proc_uri->query_len;
            }
        } else {
            const WCHAR *ptr, **pptr;
            DWORD path_offset = 0, path_len = 0;

            /* There's two possibilities on what will happen to the path component
             * of the result IUri. First, if the relative path begins with a '/'
             * then the resulting path will just be the relative path. Second, if
             * relative path doesn't begin with a '/' then the base path and relative
             * path are merged together.
             */
            if(relative->path_len && *(relative->canon_uri+relative->path_start) == '/' && data.scheme_type != URL_SCHEME_MK) {
                WCHAR *tmp = NULL;
                BOOL copy_drive_path = FALSE;

                /* If the relative IUri's path starts with a '/', then we
                 * don't use the base IUri's path. Unless the base IUri
                 * is a file URI, in which case it uses the drive path of
                 * the base IUri (if it has any) in the new path.
                 */
                if(base->scheme_type == URL_SCHEME_FILE) {
                    if(base->path_len > 3 && *(base->canon_uri+base->path_start) == '/' &&
                       is_drive_path(base->canon_uri+base->path_start+1)) {
                        path_len += 3;
                        copy_drive_path = TRUE;
                    }
                }

                path_len += relative->path_len;

                path = heap_alloc((path_len+1)*sizeof(WCHAR));
                if(!path) {
                    *result = NULL;
                    return E_OUTOFMEMORY;
                }

                tmp = path;

                /* Copy the base paths, drive path over. */
                if(copy_drive_path) {
                    memcpy(tmp, base->canon_uri+base->path_start, 3*sizeof(WCHAR));
                    tmp += 3;
                }

                memcpy(tmp, relative->canon_uri+relative->path_start, relative->path_len*sizeof(WCHAR));
                path[path_len] = '\0';
            } else {
                /* Merge the base path with the relative path. */
                hr = merge_paths(&data, base->canon_uri+base->path_start, base->path_len,
                                 relative->canon_uri+relative->path_start, relative->path_len,
                                 &path, &path_len, flags);
                if(FAILED(hr)) {
                    *result = NULL;
                    return hr;
                }

                /* If the resulting IUri is a file URI, the drive path isn't
                 * reduced out when the dot segments are removed.
                 */
                if(path_len >= 3 && data.scheme_type == URL_SCHEME_FILE && !data.host) {
                    if(*path == '/' && is_drive_path(path+1))
                        path_offset = 2;
                    else if(is_drive_path(path))
                        path_offset = 1;
                }
            }

            /* Check if the dot segments need to be removed from the path. */
            if(!(flags & URL_DONT_SIMPLIFY) && !data.is_opaque) {
                DWORD offset = (path_offset > 0) ? path_offset+1 : 0;
                DWORD new_len = remove_dot_segments(path+offset,path_len-offset);

                if(new_len != path_len) {
                    WCHAR *tmp = heap_realloc(path, (offset+new_len+1)*sizeof(WCHAR));
                    if(!tmp) {
                        heap_free(path);
                        *result = NULL;
                        return E_OUTOFMEMORY;
                    }

                    tmp[new_len+offset] = '\0';
                    path = tmp;
                    path_len = new_len+offset;
                }
            }

            if(relative->query_start > -1) {
                data.query = relative->canon_uri+relative->query_start;
                data.query_len = relative->query_len;
            }

            /* Make sure the path component is valid. */
            ptr = path;
            pptr = &ptr;
            if((data.is_opaque && !parse_path_opaque(pptr, &data, 0)) ||
               (!data.is_opaque && !parse_path_hierarchical(pptr, &data, 0))) {
                heap_free(path);
                *result = NULL;
                return E_INVALIDARG;
            }
        }

        if(relative->fragment_start > -1) {
            data.fragment = relative->canon_uri+relative->fragment_start;
            data.fragment_len = relative->fragment_len;
        }

        if(flags & URL_DONT_SIMPLIFY)
            raw_flags |= RAW_URI_FORCE_PORT_DISP;
        if(flags & URL_FILE_USE_PATHURL)
            raw_flags |= RAW_URI_CONVERT_TO_DOS_PATH;

        len = generate_raw_uri(&data, data.uri, raw_flags);
        data.uri = SysAllocStringLen(NULL, len);
        if(!data.uri) {
            heap_free(path);
            *result = NULL;
            return E_OUTOFMEMORY;
        }

        generate_raw_uri(&data, data.uri, raw_flags);

        hr = Uri_Construct(NULL, (void**)&ret);
        if(FAILED(hr)) {
            SysFreeString(data.uri);
            heap_free(path);
            *result = NULL;
            return hr;
        }

        if(flags & URL_DONT_SIMPLIFY)
            create_flags |= Uri_CREATE_NO_CANONICALIZE;
        if(flags & URL_FILE_USE_PATHURL)
            create_flags |= Uri_CREATE_FILE_USE_DOS_PATH;

        ret->raw_uri = data.uri;
        hr = canonicalize_uri(&data, ret, create_flags);
        if(FAILED(hr)) {
            IUri_Release(&ret->IUri_iface);
            *result = NULL;
            return hr;
        }

        if(flags & URL_DONT_SIMPLIFY)
            ret->display_modifiers |= URI_DISPLAY_NO_DEFAULT_PORT_AUTH;

        apply_default_flags(&create_flags);
        ret->create_flags = create_flags;
        *result = &ret->IUri_iface;

        heap_free(path);
    }

    return S_OK;
}

/***********************************************************************
 *           CoInternetCombineIUri (urlmon.@)
 */
HRESULT WINAPI CoInternetCombineIUri(IUri *pBaseUri, IUri *pRelativeUri, DWORD dwCombineFlags,
                                     IUri **ppCombinedUri, DWORD_PTR dwReserved)
{
    HRESULT hr;
    IInternetProtocolInfo *info;
    Uri *relative, *base;
    TRACE("(%p %p %x %p %x)\n", pBaseUri, pRelativeUri, dwCombineFlags, ppCombinedUri, (DWORD)dwReserved);

    if(!ppCombinedUri)
        return E_INVALIDARG;

    if(!pBaseUri || !pRelativeUri) {
        *ppCombinedUri = NULL;
        return E_INVALIDARG;
    }

    relative = get_uri_obj(pRelativeUri);
    base = get_uri_obj(pBaseUri);
    if(!relative || !base) {
        *ppCombinedUri = NULL;
        FIXME("(%p %p %x %p %x) Unknown IUri types not supported yet.\n",
            pBaseUri, pRelativeUri, dwCombineFlags, ppCombinedUri, (DWORD)dwReserved);
        return E_NOTIMPL;
    }

    info = get_protocol_info(base->canon_uri);
    if(info) {
        WCHAR result[INTERNET_MAX_URL_LENGTH+1];
        DWORD result_len = 0;

        hr = IInternetProtocolInfo_CombineUrl(info, base->canon_uri, relative->canon_uri, dwCombineFlags,
                                              result, INTERNET_MAX_URL_LENGTH+1, &result_len, 0);
        IInternetProtocolInfo_Release(info);
        if(SUCCEEDED(hr)) {
            hr = CreateUri(result, Uri_CREATE_ALLOW_RELATIVE, 0, ppCombinedUri);
            if(SUCCEEDED(hr))
                return hr;
        }
    }

    return combine_uri(base, relative, dwCombineFlags, ppCombinedUri, 0);
}

/***********************************************************************
 *           CoInternetCombineUrlEx (urlmon.@)
 */
HRESULT WINAPI CoInternetCombineUrlEx(IUri *pBaseUri, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
                                      IUri **ppCombinedUri, DWORD_PTR dwReserved)
{
    IUri *relative;
    Uri *base;
    HRESULT hr;
    IInternetProtocolInfo *info;

    TRACE("(%p %s %x %p %x) stub\n", pBaseUri, debugstr_w(pwzRelativeUrl), dwCombineFlags,
        ppCombinedUri, (DWORD)dwReserved);

    if(!ppCombinedUri)
        return E_POINTER;

    if(!pwzRelativeUrl) {
        *ppCombinedUri = NULL;
        return E_UNEXPECTED;
    }

    if(!pBaseUri) {
        *ppCombinedUri = NULL;
        return E_INVALIDARG;
    }

    base = get_uri_obj(pBaseUri);
    if(!base) {
        *ppCombinedUri = NULL;
        FIXME("(%p %s %x %p %x) Unknown IUri's not supported yet.\n", pBaseUri, debugstr_w(pwzRelativeUrl),
            dwCombineFlags, ppCombinedUri, (DWORD)dwReserved);
        return E_NOTIMPL;
    }

    info = get_protocol_info(base->canon_uri);
    if(info) {
        WCHAR result[INTERNET_MAX_URL_LENGTH+1];
        DWORD result_len = 0;

        hr = IInternetProtocolInfo_CombineUrl(info, base->canon_uri, pwzRelativeUrl, dwCombineFlags,
                                              result, INTERNET_MAX_URL_LENGTH+1, &result_len, 0);
        IInternetProtocolInfo_Release(info);
        if(SUCCEEDED(hr)) {
            hr = CreateUri(result, Uri_CREATE_ALLOW_RELATIVE, 0, ppCombinedUri);
            if(SUCCEEDED(hr))
                return hr;
        }
    }

    hr = CreateUri(pwzRelativeUrl, Uri_CREATE_ALLOW_RELATIVE, 0, &relative);
    if(FAILED(hr)) {
        *ppCombinedUri = NULL;
        return hr;
    }

    hr = combine_uri(base, get_uri_obj(relative), dwCombineFlags, ppCombinedUri, COMBINE_URI_FORCE_FLAG_USE);

    IUri_Release(relative);
    return hr;
}

static HRESULT parse_canonicalize(const Uri *uri, DWORD flags, LPWSTR output,
                                  DWORD output_len, DWORD *result_len)
{
    const WCHAR *ptr = NULL;
    WCHAR *path = NULL;
    const WCHAR **pptr;
    WCHAR buffer[INTERNET_MAX_URL_LENGTH+1];
    DWORD len = 0;
    BOOL reduce_path;

    /* URL_UNESCAPE only has effect if none of the URL_ESCAPE flags are set. */
    const BOOL allow_unescape = !(flags & URL_ESCAPE_UNSAFE) &&
                                !(flags & URL_ESCAPE_SPACES_ONLY) &&
                                !(flags & URL_ESCAPE_PERCENT);


    /* Check if the dot segments need to be removed from the
     * path component.
     */
    if(uri->scheme_start > -1 && uri->path_start > -1) {
        ptr = uri->canon_uri+uri->scheme_start+uri->scheme_len+1;
        pptr = &ptr;
    }
    reduce_path = !(flags & URL_NO_META) &&
                  !(flags & URL_DONT_SIMPLIFY) &&
                  ptr && check_hierarchical(pptr);

    for(ptr = uri->canon_uri; ptr < uri->canon_uri+uri->canon_len; ++ptr) {
        BOOL do_default_action = TRUE;

        /* Keep track of the path if we need to remove dot segments from
         * it later.
         */
        if(reduce_path && !path && ptr == uri->canon_uri+uri->path_start)
            path = buffer+len;

        /* Check if it's time to reduce the path. */
        if(reduce_path && ptr == uri->canon_uri+uri->path_start+uri->path_len) {
            DWORD current_path_len = (buffer+len) - path;
            DWORD new_path_len = remove_dot_segments(path, current_path_len);

            /* Update the current length. */
            len -= (current_path_len-new_path_len);
            reduce_path = FALSE;
        }

        if(*ptr == '%') {
            const WCHAR decoded = decode_pct_val(ptr);
            if(decoded) {
                if(allow_unescape && (flags & URL_UNESCAPE)) {
                    buffer[len++] = decoded;
                    ptr += 2;
                    do_default_action = FALSE;
                }
            }

            /* See if %'s needed to encoded. */
            if(do_default_action && (flags & URL_ESCAPE_PERCENT)) {
                pct_encode_val(*ptr, buffer+len);
                len += 3;
                do_default_action = FALSE;
            }
        } else if(*ptr == ' ') {
            if((flags & URL_ESCAPE_SPACES_ONLY) &&
               !(flags & URL_ESCAPE_UNSAFE)) {
                pct_encode_val(*ptr, buffer+len);
                len += 3;
                do_default_action = FALSE;
            }
        } else if(!is_reserved(*ptr) && !is_unreserved(*ptr)) {
            if(flags & URL_ESCAPE_UNSAFE) {
                pct_encode_val(*ptr, buffer+len);
                len += 3;
                do_default_action = FALSE;
            }
        }

        if(do_default_action)
            buffer[len++] = *ptr;
    }

    /* Sometimes the path is the very last component of the IUri, so
     * see if the dot segments need to be reduced now.
     */
    if(reduce_path && path) {
        DWORD current_path_len = (buffer+len) - path;
        DWORD new_path_len = remove_dot_segments(path, current_path_len);

        /* Update the current length. */
        len -= (current_path_len-new_path_len);
    }

    buffer[len++] = 0;

    /* The null terminator isn't included in the length. */
    *result_len = len-1;
    if(len > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;
    else
        memcpy(output, buffer, len*sizeof(WCHAR));

    return S_OK;
}

static HRESULT parse_friendly(IUri *uri, LPWSTR output, DWORD output_len,
                              DWORD *result_len)
{
    HRESULT hr;
    DWORD display_len;
    BSTR display;

    hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_DISPLAY_URI, &display_len, 0);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    *result_len = display_len;
    if(display_len+1 > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;

    hr = IUri_GetDisplayUri(uri, &display);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    memcpy(output, display, (display_len+1)*sizeof(WCHAR));
    SysFreeString(display);
    return S_OK;
}

static HRESULT parse_rootdocument(const Uri *uri, LPWSTR output, DWORD output_len,
                                  DWORD *result_len)
{
    static const WCHAR colon_slashesW[] = {':','/','/'};

    WCHAR *ptr;
    DWORD len = 0;

    /* Windows only returns the root document if the URI has an authority
     * and it's not an unknown scheme type or a file scheme type.
     */
    if(uri->authority_start == -1 ||
       uri->scheme_type == URL_SCHEME_UNKNOWN ||
       uri->scheme_type == URL_SCHEME_FILE) {
        *result_len = 0;
        if(!output_len)
            return STRSAFE_E_INSUFFICIENT_BUFFER;

        output[0] = 0;
        return S_OK;
    }

    len = uri->scheme_len+uri->authority_len;
    /* For the "://" and '/' which will be added. */
    len += 4;

    if(len+1 > output_len) {
        *result_len = len;
        return STRSAFE_E_INSUFFICIENT_BUFFER;
    }

    ptr = output;
    memcpy(ptr, uri->canon_uri+uri->scheme_start, uri->scheme_len*sizeof(WCHAR));

    /* Add the "://". */
    ptr += uri->scheme_len;
    memcpy(ptr, colon_slashesW, sizeof(colon_slashesW));

    /* Add the authority. */
    ptr += sizeof(colon_slashesW)/sizeof(WCHAR);
    memcpy(ptr, uri->canon_uri+uri->authority_start, uri->authority_len*sizeof(WCHAR));

    /* Add the '/' after the authority. */
    ptr += uri->authority_len;
    *ptr = '/';
    ptr[1] = 0;

    *result_len = len;
    return S_OK;
}

static HRESULT parse_document(const Uri *uri, LPWSTR output, DWORD output_len,
                              DWORD *result_len)
{
    DWORD len = 0;

    /* It has to be a known scheme type, but, it can't be a file
     * scheme. It also has to hierarchical.
     */
    if(uri->scheme_type == URL_SCHEME_UNKNOWN ||
       uri->scheme_type == URL_SCHEME_FILE ||
       uri->authority_start == -1) {
        *result_len = 0;
        if(output_len < 1)
            return STRSAFE_E_INSUFFICIENT_BUFFER;

        output[0] = 0;
        return S_OK;
    }

    if(uri->fragment_start > -1)
        len = uri->fragment_start;
    else
        len = uri->canon_len;

    *result_len = len;
    if(len+1 > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;

    memcpy(output, uri->canon_uri, len*sizeof(WCHAR));
    output[len] = 0;
    return S_OK;
}

static HRESULT parse_path_from_url(const Uri *uri, LPWSTR output, DWORD output_len,
                                   DWORD *result_len)
{
    const WCHAR *path_ptr;
    WCHAR buffer[INTERNET_MAX_URL_LENGTH+1];
    WCHAR *ptr;

    if(uri->scheme_type != URL_SCHEME_FILE) {
        *result_len = 0;
        if(output_len > 0)
            output[0] = 0;
        return E_INVALIDARG;
    }

    ptr = buffer;
    if(uri->host_start > -1) {
        static const WCHAR slash_slashW[] = {'\\','\\'};

        memcpy(ptr, slash_slashW, sizeof(slash_slashW));
        ptr += sizeof(slash_slashW)/sizeof(WCHAR);
        memcpy(ptr, uri->canon_uri+uri->host_start, uri->host_len*sizeof(WCHAR));
        ptr += uri->host_len;
    }

    path_ptr = uri->canon_uri+uri->path_start;
    if(uri->path_len > 3 && *path_ptr == '/' && is_drive_path(path_ptr+1))
        /* Skip past the '/' in front of the drive path. */
        ++path_ptr;

    for(; path_ptr < uri->canon_uri+uri->path_start+uri->path_len; ++path_ptr, ++ptr) {
        BOOL do_default_action = TRUE;

        if(*path_ptr == '%') {
            const WCHAR decoded = decode_pct_val(path_ptr);
            if(decoded) {
                *ptr = decoded;
                path_ptr += 2;
                do_default_action = FALSE;
            }
        } else if(*path_ptr == '/') {
            *ptr = '\\';
            do_default_action = FALSE;
        }

        if(do_default_action)
            *ptr = *path_ptr;
    }

    *ptr = 0;

    *result_len = ptr-buffer;
    if(*result_len+1 > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;

    memcpy(output, buffer, (*result_len+1)*sizeof(WCHAR));
    return S_OK;
}

static HRESULT parse_url_from_path(IUri *uri, LPWSTR output, DWORD output_len,
                                   DWORD *result_len)
{
    HRESULT hr;
    BSTR received;
    DWORD len = 0;

    hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_ABSOLUTE_URI, &len, 0);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    *result_len = len;
    if(len+1 > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;

    hr = IUri_GetAbsoluteUri(uri, &received);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    memcpy(output, received, (len+1)*sizeof(WCHAR));
    SysFreeString(received);

    return S_OK;
}

static HRESULT parse_schema(IUri *uri, LPWSTR output, DWORD output_len,
                            DWORD *result_len)
{
    HRESULT hr;
    DWORD len;
    BSTR received;

    hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_SCHEME_NAME, &len, 0);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    *result_len = len;
    if(len+1 > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;

    hr = IUri_GetSchemeName(uri, &received);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    memcpy(output, received, (len+1)*sizeof(WCHAR));
    SysFreeString(received);

    return S_OK;
}

static HRESULT parse_site(IUri *uri, LPWSTR output, DWORD output_len, DWORD *result_len)
{
    HRESULT hr;
    DWORD len;
    BSTR received;

    hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_HOST, &len, 0);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    *result_len = len;
    if(len+1 > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;

    hr = IUri_GetHost(uri, &received);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    memcpy(output, received, (len+1)*sizeof(WCHAR));
    SysFreeString(received);

    return S_OK;
}

static HRESULT parse_domain(IUri *uri, LPWSTR output, DWORD output_len, DWORD *result_len)
{
    HRESULT hr;
    DWORD len;
    BSTR received;

    hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_DOMAIN, &len, 0);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    *result_len = len;
    if(len+1 > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;

    hr = IUri_GetDomain(uri, &received);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    memcpy(output, received, (len+1)*sizeof(WCHAR));
    SysFreeString(received);

    return S_OK;
}

static HRESULT parse_anchor(IUri *uri, LPWSTR output, DWORD output_len, DWORD *result_len)
{
    HRESULT hr;
    DWORD len;
    BSTR received;

    hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_FRAGMENT, &len, 0);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    *result_len = len;
    if(len+1 > output_len)
        return STRSAFE_E_INSUFFICIENT_BUFFER;

    hr = IUri_GetFragment(uri, &received);
    if(FAILED(hr)) {
        *result_len = 0;
        return hr;
    }

    memcpy(output, received, (len+1)*sizeof(WCHAR));
    SysFreeString(received);

    return S_OK;
}

/***********************************************************************
 *           CoInternetParseIUri (urlmon.@)
 */
HRESULT WINAPI CoInternetParseIUri(IUri *pIUri, PARSEACTION ParseAction, DWORD dwFlags,
                                   LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult,
                                   DWORD_PTR dwReserved)
{
    HRESULT hr;
    Uri *uri;
    IInternetProtocolInfo *info;

    TRACE("(%p %d %x %p %d %p %x)\n", pIUri, ParseAction, dwFlags, pwzResult,
        cchResult, pcchResult, (DWORD)dwReserved);

    if(!pcchResult)
        return E_POINTER;

    if(!pwzResult || !pIUri) {
        *pcchResult = 0;
        return E_INVALIDARG;
    }

    if(!(uri = get_uri_obj(pIUri))) {
        *pcchResult = 0;
        FIXME("(%p %d %x %p %d %p %x) Unknown IUri's not supported for this action.\n",
            pIUri, ParseAction, dwFlags, pwzResult, cchResult, pcchResult, (DWORD)dwReserved);
        return E_NOTIMPL;
    }

    info = get_protocol_info(uri->canon_uri);
    if(info) {
        hr = IInternetProtocolInfo_ParseUrl(info, uri->canon_uri, ParseAction, dwFlags,
                                            pwzResult, cchResult, pcchResult, 0);
        IInternetProtocolInfo_Release(info);
        if(SUCCEEDED(hr)) return hr;
    }

    switch(ParseAction) {
    case PARSE_CANONICALIZE:
        hr = parse_canonicalize(uri, dwFlags, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_FRIENDLY:
        hr = parse_friendly(pIUri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_ROOTDOCUMENT:
        hr = parse_rootdocument(uri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_DOCUMENT:
        hr = parse_document(uri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_PATH_FROM_URL:
        hr = parse_path_from_url(uri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_URL_FROM_PATH:
        hr = parse_url_from_path(pIUri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_SCHEMA:
        hr = parse_schema(pIUri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_SITE:
        hr = parse_site(pIUri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_DOMAIN:
        hr = parse_domain(pIUri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_LOCATION:
    case PARSE_ANCHOR:
        hr = parse_anchor(pIUri, pwzResult, cchResult, pcchResult);
        break;
    case PARSE_SECURITY_URL:
    case PARSE_MIME:
    case PARSE_SERVER:
    case PARSE_SECURITY_DOMAIN:
        *pcchResult = 0;
        hr = E_FAIL;
        break;
    default:
        *pcchResult = 0;
        hr = E_NOTIMPL;
        FIXME("(%p %d %x %p %d %p %x) Partial stub.\n", pIUri, ParseAction, dwFlags,
            pwzResult, cchResult, pcchResult, (DWORD)dwReserved);
    }

    return hr;
}
