/*
 * Internet Security and Zone Manager
 *
 * Copyright (c) 2004 Huw D M Davies
 * Copyright 2004 Jacek Caban
 * Copyright 2009 Detlef Riekenberg
 * Copyright 2011 Thomas Mullaly for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdio.h>

#include "urlmon_main.h"
#include "winreg.h"
#include "wininet.h"

#define NO_SHLWAPI_REG
#include "shlwapi.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(urlmon);

static const WCHAR currentlevelW[] = {'C','u','r','r','e','n','t','L','e','v','e','l',0};
static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
static const WCHAR displaynameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
static const WCHAR fileW[] = {'f','i','l','e',0};
static const WCHAR flagsW[] = {'F','l','a','g','s',0};
static const WCHAR iconW[] = {'I','c','o','n',0};
static const WCHAR minlevelW[] = {'M','i','n','L','e','v','e','l',0};
static const WCHAR recommendedlevelW[] = {'R','e','c','o','m','m','e','n','d','e','d',
                                          'L','e','v','e','l',0};
static const WCHAR wszZonesKey[] = {'S','o','f','t','w','a','r','e','\\',
                                    'M','i','c','r','o','s','o','f','t','\\',
                                    'W','i','n','d','o','w','s','\\',
                                    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
                                    'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
                                    'Z','o','n','e','s','\\',0};
static const WCHAR wszZoneMapDomainsKey[] = {'S','o','f','t','w','a','r','e','\\',
                                             'M','i','c','r','o','s','o','f','t','\\',
                                             'W','i','n','d','o','w','s','\\',
                                             'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
                                             'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
                                             'Z','o','n','e','M','a','p','\\',
                                             'D','o','m','a','i','n','s',0};

static inline BOOL is_drive_path(const WCHAR *path)
{
    return isalphaW(*path) && *(path+1) == ':';
}

/* 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);
}

/********************************************************************
 * get_string_from_reg [internal]
 *
 * helper to get a string from the reg.
 *
 */
static void get_string_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPWSTR out, DWORD maxlen)
{
    DWORD type = REG_SZ;
    DWORD len = maxlen * sizeof(WCHAR);
    DWORD res;

    res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len);

    if (res && hklm) {
        len = maxlen * sizeof(WCHAR);
        type = REG_SZ;
        res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len);
    }

    if (res) {
        TRACE("%s failed: %d\n", debugstr_w(name), res);
        *out = '\0';
    }
}

/********************************************************************
 * get_dword_from_reg [internal]
 *
 * helper to get a dword from the reg.
 *
 */
static void get_dword_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPDWORD out)
{
    DWORD type = REG_DWORD;
    DWORD len = sizeof(DWORD);
    DWORD res;

    res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len);

    if (res && hklm) {
        len = sizeof(DWORD);
        type = REG_DWORD;
        res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len);
    }

    if (res) {
        TRACE("%s failed: %d\n", debugstr_w(name), res);
        *out = 0;
    }
}

static HRESULT get_zone_from_reg(LPCWSTR schema, DWORD *zone)
{
    DWORD res, size;
    HKEY hkey;

    static const WCHAR wszZoneMapProtocolKey[] =
        {'S','o','f','t','w','a','r','e','\\',
         'M','i','c','r','o','s','o','f','t','\\',
         'W','i','n','d','o','w','s','\\',
         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
         'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
         'Z','o','n','e','M','a','p','\\',
         'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0};

    res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapProtocolKey, &hkey);
    if(res != ERROR_SUCCESS) {
        ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey));
        return E_UNEXPECTED;
    }

    size = sizeof(DWORD);
    res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
    RegCloseKey(hkey);
    if(res == ERROR_SUCCESS)
        return S_OK;

    res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapProtocolKey, &hkey);
    if(res != ERROR_SUCCESS) {
        ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey));
        return E_UNEXPECTED;
    }

    size = sizeof(DWORD);
    res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
    RegCloseKey(hkey);
    if(res == ERROR_SUCCESS)
        return S_OK;

    *zone = 3;
    return S_OK;
}

/********************************************************************
 * matches_domain_pattern [internal]
 *
 * Checks if the given string matches the specified domain pattern.
 *
 * This function looks for explicit wildcard domain components iff
 * they appear at the very beginning of the 'pattern' string
 *
 *  pattern = "*.google.com"
 */
static BOOL matches_domain_pattern(LPCWSTR pattern, LPCWSTR str, BOOL implicit_wildcard, LPCWSTR *matched)
{
    BOOL matches = FALSE;
    DWORD pattern_len = strlenW(pattern);
    DWORD str_len = strlenW(str);

    TRACE("(%d) Checking if %s matches %s\n", implicit_wildcard, debugstr_w(str), debugstr_w(pattern));

    *matched = NULL;
    if(str_len >= pattern_len) {
        /* Check if there's an explicit wildcard in the pattern. */
        if(pattern[0] == '*' && pattern[1] == '.') {
            /* Make sure that 'str' matches the wildcard pattern.
             *
             * Example:
             *  pattern = "*.google.com"
             *
             * So in this case 'str' would have to end with ".google.com" in order
             * to map to this pattern.
             */
            if(str_len >= pattern_len+1 && !strcmpiW(str+(str_len-pattern_len+1), pattern+1)) {
                /* Check if there's another '.' inside of the "unmatched" portion
                 * of 'str'.
                 *
                 * Example:
                 *  pattern = "*.google.com"
                 *  str     = "test.testing.google.com"
                 *
                 * The currently matched portion is ".google.com" in 'str', we need
                 * see if there's a '.' inside of the unmatched portion ("test.testing"), because
                 * if there is and 'implicit_wildcard' isn't set, then this isn't
                 * a match.
                 */
                const WCHAR *ptr;
                if(str_len > pattern_len+1 && (ptr = memrchrW(str, '.', str_len-pattern_len-2))) {
                    if(implicit_wildcard) {
                        matches = TRUE;
                        *matched = ptr+1;
                    }
                } else {
                    matches = TRUE;
                    *matched = str;
                }
            }
        } else if(implicit_wildcard && str_len > pattern_len) {
            /* When the pattern has an implicit wildcard component, it means
             * that anything goes in 'str' as long as it ends with the pattern
             * and that the beginning of the match has a '.' before it.
             *
             * Example:
             *  pattern = "google.com"
             *  str     = "www.google.com"
             *
             * Implicitly matches the pattern, where as:
             *
             *  pattern = "google.com"
             *  str     = "wwwgoogle.com"
             *
             * Doesn't match the pattern.
             */
            if(str_len > pattern_len) {
                if(str[str_len-pattern_len-1] == '.' && !strcmpiW(str+(str_len-pattern_len), pattern)) {
                    matches = TRUE;
                    *matched = str+(str_len-pattern_len);
                }
            }
        } else {
            /* The pattern doesn't have an implicit wildcard, or an explicit wildcard,
             * so 'str' has to be an exact match to the 'pattern'.
             */
            if(!strcmpiW(str, pattern)) {
                matches = TRUE;
                *matched = str;
            }
        }
    }

    if(matches)
        TRACE("Found a match: matched=%s\n", debugstr_w(*matched));
    else
        TRACE("No match found\n");

    return matches;
}

static BOOL get_zone_for_scheme(HKEY key, LPCWSTR schema, DWORD *zone)
{
    static const WCHAR wildcardW[] = {'*',0};

    DWORD res;
    DWORD size = sizeof(DWORD);
    DWORD type;

    /* See if the key contains a value for the scheme first. */
    res = RegQueryValueExW(key, schema, NULL, &type, (BYTE*)zone, &size);
    if(res == ERROR_SUCCESS) {
        if(type == REG_DWORD)
            return TRUE;
        WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(schema));
    }

    /* Try to get the zone for the wildcard scheme. */
    size = sizeof(DWORD);
    res = RegQueryValueExW(key, wildcardW, NULL, &type, (BYTE*)zone, &size);
    if(res != ERROR_SUCCESS)
        return FALSE;

    if(type != REG_DWORD) {
        WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(wildcardW));
        return FALSE;
    }

    return TRUE;
}

/********************************************************************
 * search_domain_for_zone [internal]
 *
 * Searches the specified 'domain' registry key to see if 'host' maps into it, or any
 * of it's subdomain registry keys.
 *
 * Returns S_OK if a match is found, S_FALSE if no matches were found, or an error code.
 */
static HRESULT search_domain_for_zone(HKEY domains, LPCWSTR domain, DWORD domain_len, LPCWSTR schema,
                                      LPCWSTR host, DWORD host_len, DWORD *zone)
{
    BOOL found = FALSE;
    HKEY domain_key;
    DWORD res;
    LPCWSTR matched;

    if(host_len >= domain_len && matches_domain_pattern(domain, host, TRUE, &matched)) {
        res = RegOpenKeyW(domains, domain, &domain_key);
        if(res != ERROR_SUCCESS) {
            ERR("Failed to open domain key %s: %d\n", debugstr_w(domain), res);
            return E_UNEXPECTED;
        }

        if(matched == host)
            found = get_zone_for_scheme(domain_key, schema, zone);
        else {
            INT domain_offset;
            DWORD subdomain_count, subdomain_len;
            BOOL check_domain = TRUE;

            find_domain_name(domain, domain_len, &domain_offset);

            res = RegQueryInfoKeyW(domain_key, NULL, NULL, NULL, &subdomain_count, &subdomain_len,
                                   NULL, NULL, NULL, NULL, NULL, NULL);
            if(res != ERROR_SUCCESS) {
                ERR("Unable to query info for key %s: %d\n", debugstr_w(domain), res);
                RegCloseKey(domain_key);
                return E_UNEXPECTED;
            }

            if(subdomain_count) {
                WCHAR *subdomain;
                WCHAR *component;
                DWORD i;

                subdomain = heap_alloc((subdomain_len+1)*sizeof(WCHAR));
                if(!subdomain) {
                    RegCloseKey(domain_key);
                    return E_OUTOFMEMORY;
                }

                component = heap_strndupW(host, matched-host-1);
                if(!component) {
                    heap_free(subdomain);
                    RegCloseKey(domain_key);
                    return E_OUTOFMEMORY;
                }

                for(i = 0; i < subdomain_count; ++i) {
                    DWORD len = subdomain_len+1;
                    const WCHAR *sub_matched;

                    res = RegEnumKeyExW(domain_key, i, subdomain, &len, NULL, NULL, NULL, NULL);
                    if(res != ERROR_SUCCESS) {
                        heap_free(component);
                        heap_free(subdomain);
                        RegCloseKey(domain_key);
                        return E_UNEXPECTED;
                    }

                    if(matches_domain_pattern(subdomain, component, FALSE, &sub_matched)) {
                        HKEY subdomain_key;

                        res = RegOpenKeyW(domain_key, subdomain, &subdomain_key);
                        if(res != ERROR_SUCCESS) {
                            ERR("Unable to open subdomain key %s of %s: %d\n", debugstr_w(subdomain),
                                debugstr_w(domain), res);
                            heap_free(component);
                            heap_free(subdomain);
                            RegCloseKey(domain_key);
                            return E_UNEXPECTED;
                        }

                        found = get_zone_for_scheme(subdomain_key, schema, zone);
                        check_domain = FALSE;
                        RegCloseKey(subdomain_key);
                        break;
                    }
                }
                heap_free(subdomain);
                heap_free(component);
            }

            /* There's a chance that 'host' implicitly mapped into 'domain', in
             * which case we check to see if 'domain' contains zone information.
             *
             * This can only happen if 'domain' is it's own domain name.
             *  Example:
             *      "google.com" (domain name = "google.com")
             *
             *  So if:
             *      host = "www.google.com"
             *
             *  Then host would map directly into the "google.com" domain key.
             *
             * If 'domain' has more than just it's domain name, or it does not
             * have a domain name, then we don't perform the check. The reason
             * for this is that these domains don't allow implicit mappings.
             *  Example:
             *      domain = "org" (has no domain name)
             *      host   = "www.org"
             *
             *  The mapping would only happen if the "org" key had an explicit subkey
             *  called "www".
             */
            if(check_domain && !domain_offset && !strchrW(host, matched-host-1))
                found = get_zone_for_scheme(domain_key, schema, zone);
        }
        RegCloseKey(domain_key);
    }

    return found ? S_OK : S_FALSE;
}

static HRESULT search_for_domain_mapping(HKEY domains, LPCWSTR schema, LPCWSTR host, DWORD host_len, DWORD *zone)
{
    WCHAR *domain;
    DWORD domain_count, domain_len, i;
    DWORD res;
    HRESULT hres = S_FALSE;

    res = RegQueryInfoKeyW(domains, NULL, NULL, NULL, &domain_count, &domain_len,
                           NULL, NULL, NULL, NULL, NULL, NULL);
    if(res != ERROR_SUCCESS) {
        WARN("Failed to retrieve information about key\n");
        return E_UNEXPECTED;
    }

    if(!domain_count)
        return S_FALSE;

    domain = heap_alloc((domain_len+1)*sizeof(WCHAR));
    if(!domain)
        return E_OUTOFMEMORY;

    for(i = 0; i < domain_count; ++i) {
        DWORD len = domain_len+1;

        res = RegEnumKeyExW(domains, i, domain, &len, NULL, NULL, NULL, NULL);
        if(res != ERROR_SUCCESS) {
            heap_free(domain);
            return E_UNEXPECTED;
        }

        hres = search_domain_for_zone(domains, domain, len, schema, host, host_len, zone);
        if(FAILED(hres) || hres == S_OK)
            break;
    }

    heap_free(domain);
    return hres;
}

static HRESULT get_zone_from_domains(IUri *uri, DWORD *zone)
{
    HRESULT hres;
    BSTR host, scheme;
    DWORD res;
    HKEY domains;
    DWORD scheme_type;

    hres = IUri_GetScheme(uri, &scheme_type);
    if(FAILED(hres))
        return hres;

    /* Windows doesn't play nice with unknown scheme types when it tries
     * to check if a host name maps into any domains.
     */
    if(scheme_type == URL_SCHEME_UNKNOWN)
        return S_FALSE;

    hres = IUri_GetHost(uri, &host);
    if(FAILED(hres))
        return hres;

    /* Known hierarchical scheme types must have a host. If they don't Windows
     * assigns URLZONE_INVALID to the zone.
     */
    if((scheme_type != URL_SCHEME_UNKNOWN && scheme_type != URL_SCHEME_FILE)
        && is_hierarchical_scheme(scheme_type) && !*host) {
        *zone = URLZONE_INVALID;

        SysFreeString(host);

        /* The MapUrlToZone functions return S_OK when this condition occurs. */
        return S_OK;
    }

    hres = IUri_GetSchemeName(uri, &scheme);
    if(FAILED(hres)) {
        SysFreeString(host);
        return hres;
    }

    /* First try CURRENT_USER. */
    res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapDomainsKey, &domains);
    if(res == ERROR_SUCCESS) {
        hres = search_for_domain_mapping(domains, scheme, host, SysStringLen(host), zone);
        RegCloseKey(domains);
    } else
        WARN("Failed to open HKCU's %s key\n", debugstr_w(wszZoneMapDomainsKey));

    /* If that doesn't work try LOCAL_MACHINE. */
    if(hres == S_FALSE) {
        res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapDomainsKey, &domains);
        if(res == ERROR_SUCCESS) {
            hres = search_for_domain_mapping(domains, scheme, host, SysStringLen(host), zone);
            RegCloseKey(domains);
        } else
            WARN("Failed to open HKLM's %s key\n", debugstr_w(wszZoneMapDomainsKey));
    }

    SysFreeString(host);
    SysFreeString(scheme);
    return hres;
}

static HRESULT map_security_uri_to_zone(IUri *uri, DWORD *zone)
{
    HRESULT hres;
    BSTR scheme;

    *zone = URLZONE_INVALID;

    hres = IUri_GetSchemeName(uri, &scheme);
    if(FAILED(hres))
        return hres;

    if(!strcmpiW(scheme, fileW)) {
        BSTR path;
        WCHAR *ptr, *path_start, root[20];

        hres = IUri_GetPath(uri, &path);
        if(FAILED(hres)) {
            SysFreeString(scheme);
            return hres;
        }

        if(*path == '/' && is_drive_path(path+1))
            path_start = path+1;
        else
            path_start = path;

        if((ptr = strchrW(path_start, ':')) && ptr-path_start+1 < sizeof(root)/sizeof(WCHAR)) {
            UINT type;

            memcpy(root, path_start, (ptr-path_start+1)*sizeof(WCHAR));
            root[ptr-path_start+1] = 0;

            type = GetDriveTypeW(root);

            switch(type) {
            case DRIVE_UNKNOWN:
            case DRIVE_NO_ROOT_DIR:
                break;
            case DRIVE_REMOVABLE:
            case DRIVE_FIXED:
            case DRIVE_CDROM:
            case DRIVE_RAMDISK:
                *zone = URLZONE_LOCAL_MACHINE;
                hres = S_OK;
                break;
            case DRIVE_REMOTE:
                *zone = URLZONE_INTERNET;
                hres = S_OK;
                break;
            default:
                FIXME("unsupported drive type %d\n", type);
            }
        }
        SysFreeString(path);
    }

    if(*zone == URLZONE_INVALID) {
        hres = get_zone_from_domains(uri, zone);
        if(hres == S_FALSE)
            hres = get_zone_from_reg(scheme, zone);
    }

    SysFreeString(scheme);
    return hres;
}

static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
{
    IUri *secur_uri;
    LPWSTR secur_url;
    HRESULT hres;

    *zone = URLZONE_INVALID;

    hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0);
    if(hres != S_OK) {
        DWORD size = strlenW(url)*sizeof(WCHAR);

        secur_url = CoTaskMemAlloc(size);
        if(!secur_url)
            return E_OUTOFMEMORY;

        memcpy(secur_url, url, size);
    }

    hres = CreateUri(secur_url, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &secur_uri);
    if(FAILED(hres)) {
        CoTaskMemFree(secur_url);
        return hres;
    }

    hres = map_security_uri_to_zone(secur_uri, zone);
    IUri_Release(secur_uri);

    if(FAILED(hres) || !ret_url)
        CoTaskMemFree(secur_url);
    else
        *ret_url = secur_url;

    return hres;
}

static HRESULT map_uri_to_zone(IUri *uri, DWORD *zone, IUri **ret_uri)
{
    HRESULT hres;
    IUri *secur_uri;

    hres = CoInternetGetSecurityUrlEx(uri, &secur_uri, PSU_SECURITY_URL_ONLY, 0);
    if(FAILED(hres))
        return hres;

    hres = map_security_uri_to_zone(secur_uri, zone);
    if(FAILED(hres) || !ret_uri)
        IUri_Release(secur_uri);
    else
        *ret_uri = secur_uri;

    return hres;
}

static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey)
{
    static const WCHAR wszFormat[] = {'%','s','%','u',0};

    WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+12];
    DWORD res;

    wsprintfW(key_name, wszFormat, wszZonesKey, zone);

    res = RegOpenKeyW(parent_key, key_name, hkey);

    if(res != ERROR_SUCCESS) {
        WARN("RegOpenKey failed\n");
        return E_INVALIDARG;
    }

    return S_OK;
}

static HRESULT get_action_policy(DWORD zone, DWORD action, BYTE *policy, DWORD size, URLZONEREG zone_reg)
{
    HKEY parent_key;
    HKEY hkey;
    LONG res;
    HRESULT hres;

    switch(action) {
    case URLACTION_SCRIPT_OVERRIDE_SAFETY:
    case URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY:
        *(DWORD*)policy = URLPOLICY_DISALLOW;
        return S_OK;
    }

    switch(zone_reg) {
    case URLZONEREG_DEFAULT:
    case URLZONEREG_HKCU:
        parent_key = HKEY_CURRENT_USER;
        break;
    case URLZONEREG_HKLM:
        parent_key = HKEY_LOCAL_MACHINE;
        break;
    default:
        WARN("Unknown URLZONEREG: %d\n", zone_reg);
        return E_FAIL;
    };

    hres = open_zone_key(parent_key, zone, &hkey);
    if(SUCCEEDED(hres)) {
        WCHAR action_str[16];
        DWORD len = size;

        static const WCHAR formatW[] = {'%','X',0};

        wsprintfW(action_str, formatW, action);

        res = RegQueryValueExW(hkey, action_str, NULL, NULL, policy, &len);
        if(res == ERROR_MORE_DATA) {
            hres = E_INVALIDARG;
        }else if(res == ERROR_FILE_NOT_FOUND) {
            hres = E_FAIL;
        }else if(res != ERROR_SUCCESS) {
            ERR("RegQueryValue failed: %d\n", res);
            hres = E_UNEXPECTED;
        }

        RegCloseKey(hkey);
    }

    if(FAILED(hres) && zone_reg == URLZONEREG_DEFAULT)
        return get_action_policy(zone, action, policy, size, URLZONEREG_HKLM);

    return hres;
}

static HRESULT generate_security_id(IUri *uri, BYTE *secid, DWORD *secid_len, DWORD zone)
{
    DWORD len;
    HRESULT hres;
    DWORD scheme_type;

    if(zone == URLZONE_INVALID)
        return E_INVALIDARG;

    hres = IUri_GetScheme(uri, &scheme_type);
    if(FAILED(hres))
        return hres;

    /* Windows handles opaque URLs differently then hierarchical ones. */
    if(!is_hierarchical_scheme(scheme_type) && scheme_type != URL_SCHEME_WILDCARD) {
        BSTR display_uri;

        hres = IUri_GetDisplayUri(uri, &display_uri);
        if(FAILED(hres))
            return hres;

        len = WideCharToMultiByte(CP_ACP, 0, display_uri, -1, NULL, 0, NULL, NULL)-1;

        if(len+sizeof(DWORD) > *secid_len) {
            SysFreeString(display_uri);
            return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
        }

        WideCharToMultiByte(CP_ACP, 0, display_uri, -1, (LPSTR)secid, len, NULL, NULL);
        SysFreeString(display_uri);

        *(DWORD*)(secid+len) = zone;
    } else {
        BSTR host, scheme;
        DWORD host_len, scheme_len;
        BYTE *ptr;

        hres = IUri_GetHost(uri, &host);
        if(FAILED(hres))
            return hres;

        /* The host can't be empty for Wildcard URIs. */
        if(scheme_type == URL_SCHEME_WILDCARD && !*host) {
            SysFreeString(host);
            return E_INVALIDARG;
        }

        hres = IUri_GetSchemeName(uri, &scheme);
        if(FAILED(hres)) {
            SysFreeString(host);
            return hres;
        }

        host_len = WideCharToMultiByte(CP_ACP, 0, host, -1, NULL, 0, NULL, NULL)-1;
        scheme_len = WideCharToMultiByte(CP_ACP, 0, scheme, -1, NULL, 0, NULL, NULL)-1;

        len = host_len+scheme_len+sizeof(BYTE);

        if(len+sizeof(DWORD) > *secid_len) {
            SysFreeString(host);
            SysFreeString(scheme);
            return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
        }

        WideCharToMultiByte(CP_ACP, 0, scheme, -1, (LPSTR)secid, len, NULL, NULL);
        SysFreeString(scheme);

        ptr = secid+scheme_len;
        *ptr++ = ':';

        WideCharToMultiByte(CP_ACP, 0, host, -1, (LPSTR)ptr, host_len, NULL, NULL);
        SysFreeString(host);

        ptr += host_len;

        *(DWORD*)ptr = zone;
    }

    *secid_len = len+sizeof(DWORD);

    return S_OK;
}

static HRESULT get_security_id_for_url(LPCWSTR url, BYTE *secid, DWORD *secid_len)
{
    HRESULT hres;
    DWORD zone = URLZONE_INVALID;
    LPWSTR secur_url = NULL;
    IUri *uri;

    hres = map_url_to_zone(url, &zone, &secur_url);
    if(FAILED(hres))
        return hres == 0x80041001 ? E_INVALIDARG : hres;

    hres = CreateUri(secur_url, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &uri);
    CoTaskMemFree(secur_url);
    if(FAILED(hres))
        return hres;

    hres = generate_security_id(uri, secid, secid_len, zone);
    IUri_Release(uri);

    return hres;
}

static HRESULT get_security_id_for_uri(IUri *uri, BYTE *secid, DWORD *secid_len)
{
    HRESULT hres;
    IUri *secur_uri;
    DWORD zone = URLZONE_INVALID;

    hres = map_uri_to_zone(uri, &zone, &secur_uri);
    if(FAILED(hres))
        return hres;

    hres = generate_security_id(secur_uri, secid, secid_len, zone);
    IUri_Release(secur_uri);

    return hres;
}

/***********************************************************************
 *           InternetSecurityManager implementation
 *
 */
typedef struct {
    IInternetSecurityManagerEx2 IInternetSecurityManagerEx2_iface;

    LONG ref;

    IInternetSecurityMgrSite *mgrsite;
    IInternetSecurityManager *custom_manager;
} SecManagerImpl;

static inline SecManagerImpl *impl_from_IInternetSecurityManagerEx2(IInternetSecurityManagerEx2 *iface)
{
    return CONTAINING_RECORD(iface, SecManagerImpl, IInternetSecurityManagerEx2_iface);
}

static HRESULT WINAPI SecManagerImpl_QueryInterface(IInternetSecurityManagerEx2* iface,REFIID riid,void** ppvObject)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);

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

    /* Perform a sanity check on the parameters.*/
    if ( (This==0) || (ppvObject==0) )
	return E_INVALIDARG;

    /* Initialize the return parameter */
    *ppvObject = 0;

    /* Compare the riid with the interface IDs implemented by this object.*/
    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IInternetSecurityManager, riid) ||
        IsEqualIID(&IID_IInternetSecurityManagerEx, riid) ||
        IsEqualIID(&IID_IInternetSecurityManagerEx2, riid))
        *ppvObject = iface;

    /* Check that we obtained an interface.*/
    if (!*ppvObject) {
        WARN("not supported interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    /* Query Interface always increases the reference count by one when it is successful */
    IInternetSecurityManager_AddRef(iface);

    return S_OK;
}

static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManagerEx2* iface)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

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

    return refCount;
}

static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManagerEx2* iface)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

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

    /* destroy the object if there's no more reference on it */
    if (!refCount){
        if(This->mgrsite)
            IInternetSecurityMgrSite_Release(This->mgrsite);
        if(This->custom_manager)
            IInternetSecurityManager_Release(This->custom_manager);

        heap_free(This);

        URLMON_UnlockModule();
    }

    return refCount;
}

static HRESULT WINAPI SecManagerImpl_SetSecuritySite(IInternetSecurityManagerEx2 *iface,
                                                     IInternetSecurityMgrSite *pSite)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);

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

    if(This->mgrsite)
        IInternetSecurityMgrSite_Release(This->mgrsite);

    if(This->custom_manager) {
        IInternetSecurityManager_Release(This->custom_manager);
        This->custom_manager = NULL;
    }

    This->mgrsite = pSite;

    if(pSite) {
        IServiceProvider *servprov;
        HRESULT hres;

        IInternetSecurityMgrSite_AddRef(pSite);

        hres = IInternetSecurityMgrSite_QueryInterface(pSite, &IID_IServiceProvider,
                (void**)&servprov);
        if(SUCCEEDED(hres)) {
            IServiceProvider_QueryService(servprov, &SID_SInternetSecurityManager,
                    &IID_IInternetSecurityManager, (void**)&This->custom_manager);
            IServiceProvider_Release(servprov);
        }
    }

    return S_OK;
}

static HRESULT WINAPI SecManagerImpl_GetSecuritySite(IInternetSecurityManagerEx2 *iface,
                                                     IInternetSecurityMgrSite **ppSite)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);

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

    if(!ppSite)
        return E_INVALIDARG;

    if(This->mgrsite)
        IInternetSecurityMgrSite_AddRef(This->mgrsite);

    *ppSite = This->mgrsite;
    return S_OK;
}

static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManagerEx2 *iface,
                                                  LPCWSTR pwszUrl, DWORD *pdwZone,
                                                  DWORD dwFlags)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    HRESULT hres;

    TRACE("(%p)->(%s %p %08x)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags);

    if(This->custom_manager) {
        hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager,
                pwszUrl, pdwZone, dwFlags);
        if(hres != INET_E_DEFAULT_ACTION)
            return hres;
    }

    if(!pwszUrl) {
        *pdwZone = URLZONE_INVALID;
        return E_INVALIDARG;
    }

    if(dwFlags)
        FIXME("not supported flags: %08x\n", dwFlags);

    return map_url_to_zone(pwszUrl, pdwZone, NULL);
}

static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManagerEx2 *iface,
        LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);

    TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId,
          pcbSecurityId, dwReserved);

    if(This->custom_manager) {
        HRESULT hres;

        hres = IInternetSecurityManager_GetSecurityId(This->custom_manager,
                pwszUrl, pbSecurityId, pcbSecurityId, dwReserved);
        if(hres != INET_E_DEFAULT_ACTION)
            return hres;
    }

    if(!pwszUrl || !pbSecurityId || !pcbSecurityId)
        return E_INVALIDARG;

    if(dwReserved)
        FIXME("dwReserved is not supported\n");

    return get_security_id_for_url(pwszUrl, pbSecurityId, pcbSecurityId);
}


static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManagerEx2 *iface,
                                                      LPCWSTR pwszUrl, DWORD dwAction,
                                                      BYTE *pPolicy, DWORD cbPolicy,
                                                      BYTE *pContext, DWORD cbContext,
                                                      DWORD dwFlags, DWORD dwReserved)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    DWORD zone, policy;
    HRESULT hres;

    TRACE("(%p)->(%s %08x %p %08x %p %08x %08x %08x)\n", iface, debugstr_w(pwszUrl), dwAction,
          pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);

    if(This->custom_manager) {
        hres = IInternetSecurityManager_ProcessUrlAction(This->custom_manager, pwszUrl, dwAction,
                pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);
        if(hres != INET_E_DEFAULT_ACTION)
            return hres;
    }

    if(dwFlags || dwReserved)
        FIXME("Unsupported arguments\n");

    if(!pwszUrl)
        return E_INVALIDARG;

    hres = map_url_to_zone(pwszUrl, &zone, NULL);
    if(FAILED(hres))
        return hres;

    hres = get_action_policy(zone, dwAction, (BYTE*)&policy, sizeof(policy), URLZONEREG_DEFAULT);
    if(FAILED(hres))
        return hres;

    TRACE("policy %x\n", policy);
    if(cbPolicy >= sizeof(DWORD))
        *(DWORD*)pPolicy = policy;

    switch(GetUrlPolicyPermissions(policy)) {
    case URLPOLICY_ALLOW:
    case URLPOLICY_CHANNEL_SOFTDIST_PRECACHE:
        return S_OK;
    case URLPOLICY_DISALLOW:
        return S_FALSE;
    case URLPOLICY_QUERY:
        FIXME("URLPOLICY_QUERY not implemented\n");
        return E_FAIL;
    default:
        FIXME("Not implemented policy %x\n", policy);
    }

    return E_FAIL;
}
                                               

static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManagerEx2 *iface,
                                                       LPCWSTR pwszUrl, REFGUID guidKey,
                                                       BYTE **ppPolicy, DWORD *pcbPolicy,
                                                       BYTE *pContext, DWORD cbContext,
                                                       DWORD dwReserved)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    HRESULT hres;

    TRACE("(%p)->(%s %s %p %p %p %08x %08x )\n", iface, debugstr_w(pwszUrl), debugstr_guid(guidKey),
          ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);

    if(This->custom_manager) {
        hres = IInternetSecurityManager_QueryCustomPolicy(This->custom_manager, pwszUrl, guidKey,
                ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
        if(hres != INET_E_DEFAULT_ACTION)
            return hres;
    }

    WARN("Unknown guidKey %s\n", debugstr_guid(guidKey));
    return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}

static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManagerEx2 *iface,
                                                    DWORD dwZone, LPCWSTR pwszPattern, DWORD dwFlags)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    HRESULT hres;

    TRACE("(%p)->(%08x %s %08x)\n", iface, dwZone, debugstr_w(pwszPattern),dwFlags);

    if(This->custom_manager) {
        hres = IInternetSecurityManager_SetZoneMapping(This->custom_manager, dwZone,
                pwszPattern, dwFlags);
        if(hres != INET_E_DEFAULT_ACTION)
            return hres;
    }

    FIXME("Default action is not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManagerEx2 *iface,
        DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    HRESULT hres;

    TRACE("(%p)->(%08x %p %08x)\n", iface, dwZone, ppenumString,dwFlags);

    if(This->custom_manager) {
        hres = IInternetSecurityManager_GetZoneMappings(This->custom_manager, dwZone,
                ppenumString, dwFlags);
        if(hres != INET_E_DEFAULT_ACTION)
            return hres;
    }

    FIXME("Default action is not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SecManagerImpl_ProcessUrlActionEx(IInternetSecurityManagerEx2 *iface,
        LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext,
        DWORD dwFlags, DWORD dwReserved, DWORD *pdwOutFlags)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    FIXME("(%p)->(%s %08x %p %d %p %d %08x %08x %p) stub\n", This, debugstr_w(pwszUrl), dwAction, pPolicy, cbPolicy,
          pContext, cbContext, dwFlags, dwReserved, pdwOutFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI SecManagerImpl_MapUrlToZoneEx2(IInternetSecurityManagerEx2 *iface,
        IUri *pUri, DWORD *pdwZone, DWORD dwFlags, LPWSTR *ppwszMappedUrl, DWORD *pdwOutFlags)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);

    TRACE("(%p)->(%p %p %08x %p %p)\n", This, pUri, pdwZone, dwFlags, ppwszMappedUrl, pdwOutFlags);

    if(This->custom_manager) {
        HRESULT hres;
        IInternetSecurityManagerEx2 *sec_mgr2;

        hres = IInternetSecurityManager_QueryInterface(This->custom_manager, &IID_IInternetSecurityManagerEx2,
                (void**)&sec_mgr2);
        if(SUCCEEDED(hres)) {
            hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, pUri, pdwZone, dwFlags, ppwszMappedUrl, pdwOutFlags);
            IInternetSecurityManagerEx2_Release(sec_mgr2);
        } else {
            BSTR url;

            hres = IUri_GetDisplayUri(pUri, &url);
            if(FAILED(hres))
                return hres;

            hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager, url, pdwZone, dwFlags);
            SysFreeString(url);
        }

        if(hres != INET_E_DEFAULT_ACTION)
            return hres;
    }

    if(!pdwZone)
        return E_INVALIDARG;

    if(!pUri) {
        *pdwZone = URLZONE_INVALID;
        return E_INVALIDARG;
    }

    if(dwFlags)
        FIXME("Unsupported flags: %08x\n", dwFlags);

    return map_uri_to_zone(pUri, pdwZone, NULL);
}

static HRESULT WINAPI SecManagerImpl_ProcessUrlActionEx2(IInternetSecurityManagerEx2 *iface,
        IUri *pUri, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext,
        DWORD dwFlags, DWORD_PTR dwReserved, DWORD *pdwOutFlags)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    FIXME("(%p)->(%p %08x %p %d %p %d %08x %08x %p) stub\n", This, pUri, dwAction, pPolicy,
          cbPolicy, pContext, cbContext, dwFlags, (DWORD)dwReserved, pdwOutFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI SecManagerImpl_GetSecurityIdEx2(IInternetSecurityManagerEx2 *iface,
        IUri *pUri, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    TRACE("(%p)->(%p %p %p %08x) stub\n", This, pUri, pbSecurityId, pcbSecurityId, (DWORD)dwReserved);

    if(dwReserved)
        FIXME("dwReserved is not supported yet\n");

    if(!pUri || !pcbSecurityId || !pbSecurityId)
        return E_INVALIDARG;

    return get_security_id_for_uri(pUri, pbSecurityId, pcbSecurityId);
}

static HRESULT WINAPI SecManagerImpl_QueryCustomPolicyEx2(IInternetSecurityManagerEx2 *iface,
        IUri *pUri, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext,
        DWORD cbContext, DWORD_PTR dwReserved)
{
    SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
    FIXME("(%p)->(%p %s %p %p %p %d %08x) stub\n", This, pUri, debugstr_guid(guidKey), ppPolicy, pcbPolicy,
          pContext, cbContext, (DWORD)dwReserved);
    return E_NOTIMPL;
}

static const IInternetSecurityManagerEx2Vtbl VT_SecManagerImpl =
{
    SecManagerImpl_QueryInterface,
    SecManagerImpl_AddRef,
    SecManagerImpl_Release,
    SecManagerImpl_SetSecuritySite,
    SecManagerImpl_GetSecuritySite,
    SecManagerImpl_MapUrlToZone,
    SecManagerImpl_GetSecurityId,
    SecManagerImpl_ProcessUrlAction,
    SecManagerImpl_QueryCustomPolicy,
    SecManagerImpl_SetZoneMapping,
    SecManagerImpl_GetZoneMappings,
    SecManagerImpl_ProcessUrlActionEx,
    SecManagerImpl_MapUrlToZoneEx2,
    SecManagerImpl_ProcessUrlActionEx2,
    SecManagerImpl_GetSecurityIdEx2,
    SecManagerImpl_QueryCustomPolicyEx2
};

HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
    SecManagerImpl *This;

    TRACE("(%p,%p)\n",pUnkOuter,ppobj);
    This = heap_alloc(sizeof(*This));

    /* Initialize the virtual function table. */
    This->IInternetSecurityManagerEx2_iface.lpVtbl = &VT_SecManagerImpl;

    This->ref = 1;
    This->mgrsite = NULL;
    This->custom_manager = NULL;

    *ppobj = This;

    URLMON_LockModule();

    return S_OK;
}

/***********************************************************************
 *           InternetZoneManager implementation
 *
 */
typedef struct {
    IInternetZoneManagerEx2 IInternetZoneManagerEx2_iface;
    LONG ref;
    LPDWORD *zonemaps;
    DWORD zonemap_count;
} ZoneMgrImpl;

static inline ZoneMgrImpl *impl_from_IInternetZoneManagerEx2(IInternetZoneManagerEx2 *iface)
{
    return CONTAINING_RECORD(iface, ZoneMgrImpl, IInternetZoneManagerEx2_iface);
}


/***********************************************************************
 * build_zonemap_from_reg [internal]
 *
 * Enumerate the Zones in the Registry and return the Zones in a DWORD-array
 * The number of the Zones is returned in data[0]
 */
static LPDWORD build_zonemap_from_reg(void)
{
    WCHAR name[32];
    HKEY hkey;
    LPDWORD data = NULL;
    DWORD allocated = 6; /* space for the zonecount and Zone "0" up to Zone "4" */
    DWORD used = 0;
    DWORD res;
    DWORD len;


    res = RegOpenKeyW(HKEY_CURRENT_USER, wszZonesKey, &hkey);
    if (res)
        return NULL;

    data = heap_alloc(allocated * sizeof(DWORD));
    if (!data)
        goto cleanup;

    while (!res) {
        name[0] = '\0';
        len = sizeof(name) / sizeof(name[0]);
        res = RegEnumKeyExW(hkey, used, name, &len, NULL, NULL, NULL, NULL);

        if (!res) {
            used++;
            if (used == allocated) {
                LPDWORD new_data;

                allocated *= 2;
                new_data = heap_realloc_zero(data, allocated * sizeof(DWORD));
                if (!new_data)
                    goto cleanup;

                data = new_data;
            }
            data[used] = atoiW(name);
        }
    }
    if (used) {
        RegCloseKey(hkey);
        data[0] = used;
        return data;
    }

cleanup:
    /* something failed */
    RegCloseKey(hkey);
    heap_free(data);
    return NULL;
}

/********************************************************************
 *      IInternetZoneManager_QueryInterface
 */
static HRESULT WINAPI ZoneMgrImpl_QueryInterface(IInternetZoneManagerEx2* iface, REFIID riid, void** ppvObject)
{
    ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);

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

    if(!This || !ppvObject)
        return E_INVALIDARG;

    if(IsEqualIID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObject);
    }else if(IsEqualIID(&IID_IInternetZoneManager, riid)) {
        TRACE("(%p)->(IID_InternetZoneManager %p)\n", This, ppvObject);
    }else if(IsEqualIID(&IID_IInternetZoneManagerEx, riid)) {
        TRACE("(%p)->(IID_InternetZoneManagerEx %p)\n", This, ppvObject);
    }else if(IsEqualIID(&IID_IInternetZoneManagerEx2, riid)) {
        TRACE("(%p)->(IID_InternetZoneManagerEx2 %p)\n", This, ppvObject);
    }
    else
    {
        FIXME("Unknown interface: %s\n", debugstr_guid(riid));
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }

    *ppvObject = iface;
    IInternetZoneManager_AddRef(iface);
    return S_OK;
}

/********************************************************************
 *      IInternetZoneManager_AddRef
 */
static ULONG WINAPI ZoneMgrImpl_AddRef(IInternetZoneManagerEx2* iface)
{
    ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);

    return refCount;
}

/********************************************************************
 *      IInternetZoneManager_Release
 */
static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManagerEx2* iface)
{
    ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);

    if(!refCount) {
        while (This->zonemap_count) heap_free(This->zonemaps[--This->zonemap_count]);
        heap_free(This->zonemaps);
        heap_free(This);
        URLMON_UnlockModule();
    }
    
    return refCount;
}

/********************************************************************
 *      IInternetZoneManager_GetZoneAttributes
 */
static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManagerEx2* iface,
                                                    DWORD dwZone,
                                                    ZONEATTRIBUTES* pZoneAttributes)
{
    ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
    HRESULT hr;
    HKEY hcu;
    HKEY hklm = NULL;

    TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes);

    if (!pZoneAttributes)
        return E_INVALIDARG;

    hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu);
    if (FAILED(hr))
        return S_OK;  /* IE6 and older returned E_FAIL here */

    hr = open_zone_key(HKEY_LOCAL_MACHINE, dwZone, &hklm);
    if (FAILED(hr))
        TRACE("Zone %d not in HKLM\n", dwZone);

    get_string_from_reg(hcu, hklm, displaynameW, pZoneAttributes->szDisplayName, MAX_ZONE_PATH);
    get_string_from_reg(hcu, hklm, descriptionW, pZoneAttributes->szDescription, MAX_ZONE_DESCRIPTION);
    get_string_from_reg(hcu, hklm, iconW, pZoneAttributes->szIconPath, MAX_ZONE_PATH);
    get_dword_from_reg(hcu, hklm, minlevelW, &pZoneAttributes->dwTemplateMinLevel);
    get_dword_from_reg(hcu, hklm, currentlevelW, &pZoneAttributes->dwTemplateCurrentLevel);
    get_dword_from_reg(hcu, hklm, recommendedlevelW, &pZoneAttributes->dwTemplateRecommended);
    get_dword_from_reg(hcu, hklm, flagsW, &pZoneAttributes->dwFlags);

    RegCloseKey(hklm);
    RegCloseKey(hcu);
    return S_OK;
}

/********************************************************************
 *      IInternetZoneManager_SetZoneAttributes
 */
static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManagerEx2* iface,
                                                    DWORD dwZone,
                                                    ZONEATTRIBUTES* pZoneAttributes)
{
    ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
    HRESULT hr;
    HKEY hcu;

    TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes);

    if (!pZoneAttributes)
        return E_INVALIDARG;

    hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu);
    if (FAILED(hr))
        return S_OK;  /* IE6 returned E_FAIL here */

    /* cbSize is ignored */
    RegSetValueExW(hcu, displaynameW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDisplayName,
                    (lstrlenW(pZoneAttributes->szDisplayName)+1)* sizeof(WCHAR));

    RegSetValueExW(hcu, descriptionW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDescription,
                    (lstrlenW(pZoneAttributes->szDescription)+1)* sizeof(WCHAR));

    RegSetValueExW(hcu, iconW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szIconPath,
                    (lstrlenW(pZoneAttributes->szIconPath)+1)* sizeof(WCHAR));

    RegSetValueExW(hcu, minlevelW, 0, REG_DWORD,
                    (const BYTE*) &pZoneAttributes->dwTemplateMinLevel, sizeof(DWORD));

    RegSetValueExW(hcu, currentlevelW, 0, REG_DWORD,
                    (const BYTE*) &pZoneAttributes->dwTemplateCurrentLevel, sizeof(DWORD));

    RegSetValueExW(hcu, recommendedlevelW, 0, REG_DWORD,
                    (const BYTE*) &pZoneAttributes->dwTemplateRecommended, sizeof(DWORD));

    RegSetValueExW(hcu, flagsW, 0, REG_DWORD, (const BYTE*) &pZoneAttributes->dwFlags, sizeof(DWORD));
    RegCloseKey(hcu);
    return S_OK;

}

/********************************************************************
 *      IInternetZoneManager_GetZoneCustomPolicy
 */
static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManagerEx2* iface,
                                                      DWORD dwZone,
                                                      REFGUID guidKey,
                                                      BYTE** ppPolicy,
                                                      DWORD* pcbPolicy,
                                                      URLZONEREG ulrZoneReg)
{
    FIXME("(%p)->(%08x %s %p %p %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
                                                    ppPolicy, pcbPolicy, ulrZoneReg);
    return E_NOTIMPL;
}

/********************************************************************
 *      IInternetZoneManager_SetZoneCustomPolicy
 */
static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManagerEx2* iface,
                                                      DWORD dwZone,
                                                      REFGUID guidKey,
                                                      BYTE* ppPolicy,
                                                      DWORD cbPolicy,
                                                      URLZONEREG ulrZoneReg)
{
    FIXME("(%p)->(%08x %s %p %08x %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
                                                    ppPolicy, cbPolicy, ulrZoneReg);
    return E_NOTIMPL;
}

/********************************************************************
 *      IInternetZoneManager_GetZoneActionPolicy
 */
static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManagerEx2* iface,
        DWORD dwZone, DWORD dwAction, BYTE* pPolicy, DWORD cbPolicy, URLZONEREG urlZoneReg)
{
    TRACE("(%p)->(%d %08x %p %d %d)\n", iface, dwZone, dwAction, pPolicy,
            cbPolicy, urlZoneReg);

    if(!pPolicy)
        return E_INVALIDARG;

    return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg);
}

/********************************************************************
 *      IInternetZoneManager_SetZoneActionPolicy
 */
static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManagerEx2* iface,
                                                      DWORD dwZone,
                                                      DWORD dwAction,
                                                      BYTE* pPolicy,
                                                      DWORD cbPolicy,
                                                      URLZONEREG urlZoneReg)
{
    FIXME("(%p)->(%08x %08x %p %08x %08x) stub\n", iface, dwZone, dwAction, pPolicy,
                                                       cbPolicy, urlZoneReg);
    return E_NOTIMPL;
}

/********************************************************************
 *      IInternetZoneManager_PromptAction
 */
static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManagerEx2* iface,
                                               DWORD dwAction,
                                               HWND hwndParent,
                                               LPCWSTR pwszUrl,
                                               LPCWSTR pwszText,
                                               DWORD dwPromptFlags)
{
    FIXME("%p %08x %p %s %s %08x\n", iface, dwAction, hwndParent,
          debugstr_w(pwszUrl), debugstr_w(pwszText), dwPromptFlags );
    return E_NOTIMPL;
}

/********************************************************************
 *      IInternetZoneManager_LogAction
 */
static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManagerEx2* iface,
                                            DWORD dwAction,
                                            LPCWSTR pwszUrl,
                                            LPCWSTR pwszText,
                                            DWORD dwLogFlags)
{
    FIXME("(%p)->(%08x %s %s %08x) stub\n", iface, dwAction, debugstr_w(pwszUrl),
                                              debugstr_w(pwszText), dwLogFlags);
    return E_NOTIMPL;
}

/********************************************************************
 *      IInternetZoneManager_CreateZoneEnumerator
 */
static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManagerEx2* iface,
                                                       DWORD* pdwEnum,
                                                       DWORD* pdwCount,
                                                       DWORD dwFlags)
{
    ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
    LPDWORD * new_maps;
    LPDWORD data;
    DWORD i;

    TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pdwEnum, pdwCount, dwFlags);
    if (!pdwEnum || !pdwCount || (dwFlags != 0))
        return E_INVALIDARG;

    data = build_zonemap_from_reg();
    TRACE("found %d zones\n", data ? data[0] : -1);

    if (!data)
        return E_FAIL;

    for (i = 0; i < This->zonemap_count; i++) {
        if (This->zonemaps && !This->zonemaps[i]) {
            This->zonemaps[i] = data;
            *pdwEnum = i;
            *pdwCount = data[0];
            return S_OK;
        }
    }

    if (This->zonemaps) {
        /* try to double the nr. of pointers in the array */
        new_maps = heap_realloc_zero(This->zonemaps, This->zonemap_count * 2 * sizeof(LPDWORD));
        if (new_maps)
            This->zonemap_count *= 2;
    }
    else
    {
        This->zonemap_count = 2;
        new_maps = heap_alloc_zero(This->zonemap_count * sizeof(LPDWORD));
    }

    if (!new_maps) {
        heap_free(data);
        return E_FAIL;
    }
    This->zonemaps = new_maps;
    This->zonemaps[i] = data;
    *pdwEnum = i;
    *pdwCount = data[0];
    return S_OK;
}

/********************************************************************
 *      IInternetZoneManager_GetZoneAt
 */
static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManagerEx2* iface,
                                            DWORD dwEnum,
                                            DWORD dwIndex,
                                            DWORD* pdwZone)
{
    ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
    LPDWORD data;

    TRACE("(%p)->(0x%08x, %d, %p)\n", This, dwEnum, dwIndex, pdwZone);

    /* make sure, that dwEnum and dwIndex are in the valid range */
    if (dwEnum < This->zonemap_count) {
        if ((data = This->zonemaps[dwEnum])) {
            if (dwIndex < data[0]) {
                *pdwZone = data[dwIndex + 1];
                return S_OK;
            }
        }
    }
    return E_INVALIDARG;
}

/********************************************************************
 *      IInternetZoneManager_DestroyZoneEnumerator
 */
static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManagerEx2* iface,
                                                        DWORD dwEnum)
{
    ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
    LPDWORD data;

    TRACE("(%p)->(0x%08x)\n", This, dwEnum);
    /* make sure, that dwEnum is valid */
    if (dwEnum < This->zonemap_count) {
        if ((data = This->zonemaps[dwEnum])) {
            This->zonemaps[dwEnum] = NULL;
            heap_free(data);
            return S_OK;
        }
    }
    return E_INVALIDARG;
}

/********************************************************************
 *      IInternetZoneManager_CopyTemplatePoliciesToZone
 */
static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManagerEx2* iface,
                                                             DWORD dwTemplate,
                                                             DWORD dwZone,
                                                             DWORD dwReserved)
{
    FIXME("(%p)->(%08x %08x %08x) stub\n", iface, dwTemplate, dwZone, dwReserved);
    return E_NOTIMPL;
}

/********************************************************************
 *      IInternetZoneManagerEx_GetZoneActionPolicyEx
 */
static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicyEx(IInternetZoneManagerEx2* iface,
                                                        DWORD dwZone,
                                                        DWORD dwAction,
                                                        BYTE* pPolicy,
                                                        DWORD cbPolicy,
                                                        URLZONEREG urlZoneReg,
                                                        DWORD dwFlags)
{
    TRACE("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x)\n", iface, dwZone,
            dwAction, pPolicy, cbPolicy, urlZoneReg, dwFlags);

    if(!pPolicy)
        return E_INVALIDARG;

    if (dwFlags)
        FIXME("dwFlags 0x%x ignored\n", dwFlags);

    return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg);
}

/********************************************************************
 *      IInternetZoneManagerEx_SetZoneActionPolicyEx
 */
static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicyEx(IInternetZoneManagerEx2* iface,
                                                        DWORD dwZone,
                                                        DWORD dwAction,
                                                        BYTE* pPolicy,
                                                        DWORD cbPolicy,
                                                        URLZONEREG urlZoneReg,
                                                        DWORD dwFlags)
{
    FIXME("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x) stub\n", iface, dwZone, dwAction, pPolicy,
                                                       cbPolicy, urlZoneReg, dwFlags);
    return E_NOTIMPL;
}

/********************************************************************
 *      IInternetZoneManagerEx2_GetZoneAttributesEx
 */
static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributesEx(IInternetZoneManagerEx2* iface,
                                                      DWORD dwZone,
                                                      ZONEATTRIBUTES* pZoneAttributes,
                                                      DWORD dwFlags)
{
    TRACE("(%p)->(%d, %p, 0x%x)\n", iface, dwZone, pZoneAttributes, dwFlags);

    if (dwFlags)
        FIXME("dwFlags 0x%x ignored\n", dwFlags);

    return IInternetZoneManager_GetZoneAttributes(iface, dwZone, pZoneAttributes);
}


/********************************************************************
 *      IInternetZoneManagerEx2_GetZoneSecurityState
 */
static HRESULT WINAPI ZoneMgrImpl_GetZoneSecurityState(IInternetZoneManagerEx2* iface,
                                                       DWORD dwZoneIndex,
                                                       BOOL fRespectPolicy,
                                                       LPDWORD pdwState,
                                                       BOOL *pfPolicyEncountered)
{
    FIXME("(%p)->(%d, %d, %p, %p) stub\n", iface, dwZoneIndex, fRespectPolicy,
                                           pdwState, pfPolicyEncountered);

    *pdwState = SECURITY_IE_STATE_GREEN;

    if (pfPolicyEncountered)
        *pfPolicyEncountered = FALSE;

    return S_OK;
}

/********************************************************************
 *      IInternetZoneManagerEx2_GetIESecurityState
 */
static HRESULT WINAPI ZoneMgrImpl_GetIESecurityState(IInternetZoneManagerEx2* iface,
                                                     BOOL fRespectPolicy,
                                                     LPDWORD pdwState,
                                                     BOOL *pfPolicyEncountered,
                                                     BOOL fNoCache)
{
    FIXME("(%p)->(%d, %p, %p, %d) stub\n", iface, fRespectPolicy, pdwState,
                                           pfPolicyEncountered, fNoCache);

    *pdwState = SECURITY_IE_STATE_GREEN;

    if (pfPolicyEncountered)
        *pfPolicyEncountered = FALSE;

    return S_OK;
}

/********************************************************************
 *      IInternetZoneManagerEx2_FixInsecureSettings
 */
static HRESULT WINAPI ZoneMgrImpl_FixInsecureSettings(IInternetZoneManagerEx2* iface)
{
    FIXME("(%p) stub\n", iface);
    return S_OK;
}

/********************************************************************
 *      IInternetZoneManager_Construct
 */
static const IInternetZoneManagerEx2Vtbl ZoneMgrImplVtbl = {
    ZoneMgrImpl_QueryInterface,
    ZoneMgrImpl_AddRef,
    ZoneMgrImpl_Release,
    /* IInternetZoneManager */
    ZoneMgrImpl_GetZoneAttributes,
    ZoneMgrImpl_SetZoneAttributes,
    ZoneMgrImpl_GetZoneCustomPolicy,
    ZoneMgrImpl_SetZoneCustomPolicy,
    ZoneMgrImpl_GetZoneActionPolicy,
    ZoneMgrImpl_SetZoneActionPolicy,
    ZoneMgrImpl_PromptAction,
    ZoneMgrImpl_LogAction,
    ZoneMgrImpl_CreateZoneEnumerator,
    ZoneMgrImpl_GetZoneAt,
    ZoneMgrImpl_DestroyZoneEnumerator,
    ZoneMgrImpl_CopyTemplatePoliciesToZone,
    /* IInternetZoneManagerEx */
    ZoneMgrImpl_GetZoneActionPolicyEx,
    ZoneMgrImpl_SetZoneActionPolicyEx,
    /* IInternetZoneManagerEx2 */
    ZoneMgrImpl_GetZoneAttributesEx,
    ZoneMgrImpl_GetZoneSecurityState,
    ZoneMgrImpl_GetIESecurityState,
    ZoneMgrImpl_FixInsecureSettings,
};

HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
    ZoneMgrImpl* ret = heap_alloc_zero(sizeof(ZoneMgrImpl));

    TRACE("(%p %p)\n", pUnkOuter, ppobj);
    ret->IInternetZoneManagerEx2_iface.lpVtbl = &ZoneMgrImplVtbl;
    ret->ref = 1;
    *ppobj = (IInternetZoneManagerEx*)ret;

    URLMON_LockModule();

    return S_OK;
}

/***********************************************************************
 *           CoInternetCreateSecurityManager (URLMON.@)
 *
 */
HRESULT WINAPI CoInternetCreateSecurityManager( IServiceProvider *pSP,
    IInternetSecurityManager **ppSM, DWORD dwReserved )
{
    TRACE("%p %p %d\n", pSP, ppSM, dwReserved );

    if(pSP)
        FIXME("pSP not supported\n");

    return SecManagerImpl_Construct(NULL, (void**) ppSM);
}

/********************************************************************
 *      CoInternetCreateZoneManager (URLMON.@)
 */
HRESULT WINAPI CoInternetCreateZoneManager(IServiceProvider* pSP, IInternetZoneManager** ppZM, DWORD dwReserved)
{
    TRACE("(%p %p %x)\n", pSP, ppZM, dwReserved);
    return ZoneMgrImpl_Construct(NULL, (void**)ppZM);
}

static HRESULT parse_security_url(const WCHAR *url, PSUACTION action, WCHAR **result) {
    IInternetProtocolInfo *protocol_info;
    WCHAR *tmp, *new_url = NULL, *alloc_url = NULL;
    DWORD size, new_size;
    HRESULT hres = S_OK, parse_hres;

    while(1) {
        TRACE("parsing %s\n", debugstr_w(url));

        protocol_info = get_protocol_info(url);
        if(!protocol_info)
            break;

        size = strlenW(url)+1;
        new_url = CoTaskMemAlloc(size*sizeof(WCHAR));
        if(!new_url) {
            hres = E_OUTOFMEMORY;
            break;
        }

        new_size = 0;
        parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url, size, &new_size, 0);
        if(parse_hres == S_FALSE) {
            if(!new_size) {
                hres = E_UNEXPECTED;
                break;
            }

            tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR));
            if(!tmp) {
                hres = E_OUTOFMEMORY;
                break;
            }
            new_url = tmp;
            parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url,
                    new_size, &new_size, 0);
            if(parse_hres == S_FALSE) {
                hres = E_FAIL;
                break;
            }
        }

        if(parse_hres != S_OK || !strcmpW(url, new_url))
            break;

        CoTaskMemFree(alloc_url);
        url = alloc_url = new_url;
        new_url = NULL;
    }

    CoTaskMemFree(new_url);

    if(hres != S_OK) {
        WARN("failed: %08x\n", hres);
        CoTaskMemFree(alloc_url);
        return hres;
    }

    if(action == PSU_DEFAULT && (protocol_info = get_protocol_info(url))) {
        size = strlenW(url)+1;
        new_url = CoTaskMemAlloc(size * sizeof(WCHAR));
        if(new_url) {
            new_size = 0;
            parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0,
                    new_url, size, &new_size, 0);
            if(parse_hres == S_FALSE) {
                if(new_size) {
                    tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR));
                    if(tmp) {
                        new_url = tmp;
                        parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0, new_url,
                                new_size, &new_size, 0);
                        if(parse_hres == S_FALSE)
                            hres = E_FAIL;
                    }else {
                        hres = E_OUTOFMEMORY;
                    }
                }else {
                    hres = E_UNEXPECTED;
                }
            }

            if(hres == S_OK && parse_hres == S_OK) {
                CoTaskMemFree(alloc_url);
                url = alloc_url = new_url;
                new_url = NULL;
            }

            CoTaskMemFree(new_url);
        }else {
            hres = E_OUTOFMEMORY;
        }
        IInternetProtocolInfo_Release(protocol_info);
    }

    if(FAILED(hres)) {
        WARN("failed %08x\n", hres);
        CoTaskMemFree(alloc_url);
        return hres;
    }

    if(!alloc_url) {
        size = strlenW(url)+1;
        alloc_url = CoTaskMemAlloc(size * sizeof(WCHAR));
        if(!alloc_url)
            return E_OUTOFMEMORY;
        memcpy(alloc_url, url, size * sizeof(WCHAR));
    }

    *result = alloc_url;
    return S_OK;
}

/********************************************************************
 *      CoInternetGetSecurityUrl (URLMON.@)
 */
HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUACTION psuAction, DWORD dwReserved)
{
    WCHAR *secure_url;
    HRESULT hres;

    TRACE("(%p,%p,%u,%u)\n", pwzUrl, ppwzSecUrl, psuAction, dwReserved);

    hres = parse_security_url(pwzUrl, psuAction, &secure_url);
    if(FAILED(hres))
        return hres;

    if(psuAction != PSU_SECURITY_URL_ONLY) {
        PARSEDURLW parsed_url = { sizeof(parsed_url) };
        DWORD size;

        /* FIXME: Use helpers from uri.c */
        if(SUCCEEDED(ParseURLW(secure_url, &parsed_url))) {
            WCHAR *new_url;

            switch(parsed_url.nScheme) {
            case URL_SCHEME_FTP:
            case URL_SCHEME_HTTP:
            case URL_SCHEME_HTTPS:
                size = strlenW(secure_url)+1;
                new_url = CoTaskMemAlloc(size * sizeof(WCHAR));
                if(new_url)
                    hres = UrlGetPartW(secure_url, new_url, &size, URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME);
                else
                    hres = E_OUTOFMEMORY;
                CoTaskMemFree(secure_url);
                if(hres != S_OK) {
                    WARN("UrlGetPart failed: %08x\n", hres);
                    CoTaskMemFree(new_url);
                    return FAILED(hres) ? hres : E_FAIL;
                }
                secure_url = new_url;
            }
        }
    }

    *ppwzSecUrl = secure_url;
    return S_OK;
}

/********************************************************************
 *      CoInternetGetSecurityUrlEx (URLMON.@)
 */
HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri *pUri, IUri **ppSecUri, PSUACTION psuAction, DWORD_PTR dwReserved)
{
    URL_SCHEME scheme_type;
    BSTR secure_uri;
    WCHAR *ret_url;
    HRESULT hres;

    TRACE("(%p,%p,%u,%u)\n", pUri, ppSecUri, psuAction, (DWORD)dwReserved);

    if(!pUri || !ppSecUri)
        return E_INVALIDARG;

    hres = IUri_GetDisplayUri(pUri, &secure_uri);
    if(FAILED(hres))
        return hres;

    hres = parse_security_url(secure_uri, psuAction, &ret_url);
    SysFreeString(secure_uri);
    if(FAILED(hres))
        return hres;

    /* File URIs have to hierarchical. */
    hres = IUri_GetScheme(pUri, (DWORD*)&scheme_type);
    if(SUCCEEDED(hres) && scheme_type == URL_SCHEME_FILE) {
        const WCHAR *tmp = ret_url;

        /* Check and see if a "//" is after the scheme name. */
        tmp += sizeof(fileW)/sizeof(WCHAR);
        if(*tmp != '/' || *(tmp+1) != '/')
            hres = E_INVALIDARG;
    }

    if(SUCCEEDED(hres))
        hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri);
    CoTaskMemFree(ret_url);
    return hres;
}

/********************************************************************
 *      CompareSecurityIds (URLMON.@)
 */
HRESULT WINAPI CompareSecurityIds(BYTE *secid1, DWORD size1, BYTE *secid2, DWORD size2, DWORD reserved)
{
    FIXME("(%p %d %p %d %x)\n", secid1, size1, secid2, size2, reserved);
    return E_NOTIMPL;
}
