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

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "cpl.h"
#include "winreg.h"
#include "ole2.h"
#include "commctrl.h"
#include "advpub.h"
#include "wininet.h"
#include "shellapi.h"
#include "urlmon.h"
#include "msi.h"

#include "appwiz.h"
#include "res.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(appwizcpl);

#define GECKO_VERSION "2.36"

#ifdef __i386__
#define ARCH_STRING "x86"
#define GECKO_SHA "08b02bf0e3ff3a315135afa1132ddb3a25a63e15"
#elif defined(__x86_64__)
#define ARCH_STRING "x86_64"
#define GECKO_SHA "a7624eb685d04c4ef1f4f093095a5a324808d57c"
#else
#define ARCH_STRING ""
#define GECKO_SHA "???"
#endif

#define MONO_VERSION "4.5.6"
#define MONO_SHA "12ec9a4fa5958426292effd40d9230c7acbba1e8"

typedef struct {
    const char *version;
    const char *file_name;
    const char *subdir_name;
    const char *sha;
    const char *url_default;
    const char *config_key;
    const char *url_config_key;
    const char *dir_config_key;
    LPCWSTR dialog_template;
} addon_info_t;

static const addon_info_t addons_info[] = {
    {
        GECKO_VERSION,
        "wine_gecko-" GECKO_VERSION "-" ARCH_STRING ".msi",
        "gecko",
        GECKO_SHA,
        "http://source.winehq.org/winegecko.php",
        "MSHTML", "GeckoUrl", "GeckoCabDir",
        MAKEINTRESOURCEW(ID_DWL_GECKO_DIALOG)
    },
    {
        MONO_VERSION,
        "wine-mono-" MONO_VERSION ".msi",
        "mono",
        MONO_SHA,
        "http://source.winehq.org/winemono.php",
        "Dotnet", "MonoUrl", "MonoCabDir",
        MAKEINTRESOURCEW(ID_DWL_MONO_DIALOG)
    }
};

static const addon_info_t *addon;

static HWND install_dialog = NULL;
static LPWSTR url = NULL;
static IBinding *dwl_binding;
static WCHAR *msi_file;

static WCHAR * (CDECL *p_wine_get_dos_file_name)(const char*);
static const WCHAR kernel32_dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};


/* SHA definitions are copied from advapi32. They aren't available in headers. */

typedef struct {
   ULONG Unknown[6];
   ULONG State[5];
   ULONG Count[2];
   UCHAR Buffer[64];
} SHA_CTX, *PSHA_CTX;

void WINAPI A_SHAInit(PSHA_CTX);
void WINAPI A_SHAUpdate(PSHA_CTX,const unsigned char*,UINT);
void WINAPI A_SHAFinal(PSHA_CTX,PULONG);

static BOOL sha_check(const WCHAR *file_name)
{
    const unsigned char *file_map;
    HANDLE file, map;
    ULONG sha[5];
    char buf[2*sizeof(sha)+1];
    SHA_CTX ctx;
    DWORD size, i;

    file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
    if(file == INVALID_HANDLE_VALUE) {
        WARN("Could not open file: %u\n", GetLastError());
        return FALSE;
    }

    size = GetFileSize(file, NULL);

    map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
    CloseHandle(file);
    if(!map)
        return FALSE;

    file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
    CloseHandle(map);
    if(!file_map)
        return FALSE;

    A_SHAInit(&ctx);
    A_SHAUpdate(&ctx, file_map, size);
    A_SHAFinal(&ctx, sha);

    UnmapViewOfFile(file_map);

    for(i=0; i < sizeof(sha); i++)
        sprintf(buf + i*2, "%02x", *((unsigned char*)sha+i));

    if(strcmp(buf, addon->sha)) {
        WARN("Got %s, expected %s\n", buf, addon->sha);
        return FALSE;
    }

    return TRUE;
}

static void set_status(DWORD id)
{
    HWND status = GetDlgItem(install_dialog, ID_DWL_STATUS);
    WCHAR buf[64];

    LoadStringW(hInst, id, buf, sizeof(buf)/sizeof(WCHAR));
    SendMessageW(status, WM_SETTEXT, 0, (LPARAM)buf);
}

enum install_res {
    INSTALL_OK = 0,
    INSTALL_FAILED,
    INSTALL_NEXT,
};

static enum install_res install_file(const WCHAR *file_name)
{
    ULONG res;

    res = MsiInstallProductW(file_name, NULL);
    if(res != ERROR_SUCCESS) {
        ERR("MsiInstallProduct failed: %u\n", res);
        return INSTALL_FAILED;
    }

    return INSTALL_OK;
}

static enum install_res install_from_unix_file(const char *dir, const char *subdir, const char *file_name)
{
    LPWSTR dos_file_name;
    char *file_path;
    int fd, len;
    enum install_res ret;

    len = strlen(dir);
    file_path = heap_alloc(len+strlen(subdir)+strlen(file_name)+3);
    if(!file_path)
        return INSTALL_FAILED;

    memcpy(file_path, dir, len);
    if(len && file_path[len-1] != '/' && file_path[len-1] != '\\')
        file_path[len++] = '/';
    if(*subdir) {
        strcpy(file_path+len, subdir);
        len += strlen(subdir);
        file_path[len++] = '/';
    }
    strcpy(file_path+len, file_name);

    fd = open(file_path, O_RDONLY);
    if(fd == -1) {
        TRACE("%s not found\n", debugstr_a(file_path));
        heap_free(file_path);
        return INSTALL_NEXT;
    }

    close(fd);

    if(p_wine_get_dos_file_name) { /* Wine UNIX mode */
	dos_file_name = p_wine_get_dos_file_name(file_path);
	if(!dos_file_name) {
	    ERR("Could not get dos file name of %s\n", debugstr_a(file_path));
            heap_free(file_path);
	    return INSTALL_FAILED;
	}
    } else { /* Windows mode */
	UINT res;
	WARN("Could not get wine_get_dos_file_name function, calling install_cab directly.\n");
	res = MultiByteToWideChar( CP_ACP, 0, file_path, -1, 0, 0);
	dos_file_name = heap_alloc (res*sizeof(WCHAR));
	MultiByteToWideChar( CP_ACP, 0, file_path, -1, dos_file_name, res);
    }

    heap_free(file_path);

    ret = install_file(dos_file_name);

    heap_free(dos_file_name);
    return ret;
}

static HKEY open_config_key(void)
{
    HKEY hkey, ret;
    DWORD res;

    static const WCHAR wine_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e',0};

    /* @@ Wine registry key: HKCU\Software\Wine\$config_key */
    res = RegOpenKeyW(HKEY_CURRENT_USER, wine_keyW, &hkey);
    if(res != ERROR_SUCCESS)
        return NULL;

    res = RegOpenKeyA(hkey, addon->config_key, &ret);
    RegCloseKey(hkey);
    return res == ERROR_SUCCESS ? ret : NULL;
}

static enum install_res install_from_registered_dir(void)
{
    char *package_dir;
    HKEY hkey;
    DWORD res, type, size = MAX_PATH;
    enum install_res ret;

    hkey = open_config_key();
    if(!hkey)
        return INSTALL_NEXT;

    package_dir = heap_alloc(size);
    res = RegGetValueA(hkey, NULL, addon->dir_config_key, RRF_RT_ANY, &type, (PBYTE)package_dir, &size);
    if(res == ERROR_MORE_DATA) {
        package_dir = heap_realloc(package_dir, size);
        res = RegGetValueA(hkey, NULL, addon->dir_config_key, RRF_RT_ANY, &type, (PBYTE)package_dir, &size);
    }
    RegCloseKey(hkey);
    if(res == ERROR_FILE_NOT_FOUND) {
        heap_free(package_dir);
        return INSTALL_NEXT;
    } else if(res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) {
        heap_free(package_dir);
        return INSTALL_FAILED;
    }

    TRACE("Trying %s/%s\n", debugstr_a(package_dir), debugstr_a(addon->file_name));

    ret = install_from_unix_file(package_dir, "", addon->file_name);

    heap_free(package_dir);
    return ret;
}

static enum install_res install_from_default_dir(void)
{
    const char *data_dir, *package_dir;
    char *dir_buf = NULL;
    int len;
    enum install_res ret;

    if((data_dir = wine_get_data_dir())) {
        package_dir = data_dir;
    }else if((data_dir = wine_get_build_dir())) {
        len = strlen(data_dir);
        dir_buf = heap_alloc(len + sizeof("/../"));
        memcpy(dir_buf, data_dir, len);
        strcpy(dir_buf+len, "/../");
        package_dir = dir_buf;
    }else {
        return INSTALL_NEXT;
    }

    ret = install_from_unix_file(package_dir, addon->subdir_name, addon->file_name);
    heap_free(dir_buf);

    if (ret == INSTALL_NEXT)
        ret = install_from_unix_file(INSTALL_DATADIR "/wine/", addon->subdir_name, addon->file_name);
    if (ret == INSTALL_NEXT && strcmp(INSTALL_DATADIR, "/usr/share"))
        ret = install_from_unix_file("/usr/share/wine/", addon->subdir_name, addon->file_name);
    return ret;
}

static WCHAR *get_cache_file_name(BOOL ensure_exists)
{
    const char *home_dir = NULL, *xdg_cache_dir;
    size_t len, size = strlen(addon->file_name) + 7; /* strlen("/wine/"), '\0' */
    char *cache_file_name;
    WCHAR *ret;

    /* non-Wine (eg. Windows) cache is currently not supported */
    if(!p_wine_get_dos_file_name)
        return NULL;

    xdg_cache_dir = getenv("XDG_CACHE_HOME");
    if(xdg_cache_dir && *xdg_cache_dir) {
        size += strlen(xdg_cache_dir);
    }else {
        home_dir = getenv("HOME");
        if(!home_dir)
            return NULL;

        size += strlen(home_dir) + 8; /* strlen("/.cache/") */
    }

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

    if(xdg_cache_dir && *xdg_cache_dir) {
        len = strlen(xdg_cache_dir);
        if(len > 1 && xdg_cache_dir[len-1] == '/')
            len--;
        memcpy(cache_file_name, xdg_cache_dir, len);
        cache_file_name[len] = 0;
    }else {
        len = strlen(home_dir);
        memcpy(cache_file_name, home_dir, len);
        strcpy(cache_file_name+len, "/.cache");
        len += 7;
    }

    if(ensure_exists && mkdir(cache_file_name, 0777) && errno != EEXIST) {
        WARN("%s does not exist and could not be created: %s\n", cache_file_name, strerror(errno));
        heap_free(cache_file_name);
        return NULL;
    }

    strcpy(cache_file_name+len, "/wine");
    len += 5;

    if(ensure_exists && mkdir(cache_file_name, 0777) && errno != EEXIST) {
        WARN("%s does not exist and could not be created: %s\n", cache_file_name, strerror(errno));
        return NULL;
    }

    cache_file_name[len++] = '/';
    strcpy(cache_file_name+len, addon->file_name);
    ret = p_wine_get_dos_file_name(cache_file_name);

    TRACE("%s -> %s\n", cache_file_name, debugstr_w(ret));

    heap_free(cache_file_name);
    return ret;
}

static enum install_res install_from_cache(void)
{
    WCHAR *cache_file_name;
    enum install_res res;

    cache_file_name = get_cache_file_name(FALSE);
    if(!cache_file_name)
        return INSTALL_NEXT;

    if(!sha_check(cache_file_name)) {
        WARN("could not validate check sum\n");
        DeleteFileW(cache_file_name);
        heap_free(cache_file_name);
        return INSTALL_NEXT;
    }

    res = install_file(cache_file_name);
    heap_free(cache_file_name);
    return res;
}

static IInternetBindInfo InstallCallbackBindInfo;

static HRESULT WINAPI InstallCallback_QueryInterface(IBindStatusCallback *iface,
        REFIID riid, void **ppv)
{
    if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IBindStatusCallback, riid)) {
        *ppv = iface;
        return S_OK;
    }

    if(IsEqualGUID(&IID_IInternetBindInfo, riid)) {
        TRACE("IID_IInternetBindInfo\n");
        *ppv = &InstallCallbackBindInfo;
        return S_OK;
    }

    return E_INVALIDARG;
}

static ULONG WINAPI InstallCallback_AddRef(IBindStatusCallback *iface)
{
    return 2;
}

static ULONG WINAPI InstallCallback_Release(IBindStatusCallback *iface)
{
    return 1;
}

static HRESULT WINAPI InstallCallback_OnStartBinding(IBindStatusCallback *iface,
        DWORD dwReserved, IBinding *pib)
{
    set_status(IDS_DOWNLOADING);

    IBinding_AddRef(pib);
    dwl_binding = pib;

    return S_OK;
}

static HRESULT WINAPI InstallCallback_GetPriority(IBindStatusCallback *iface,
        LONG *pnPriority)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallCallback_OnLowResource(IBindStatusCallback *iface,
       DWORD dwReserved)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
        ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
    HWND progress = GetDlgItem(install_dialog, ID_DWL_PROGRESS);

    if(ulProgressMax)
        SendMessageW(progress, PBM_SETRANGE32, 0, ulProgressMax);
    if(ulProgress)
        SendMessageW(progress, PBM_SETPOS, ulProgress, 0);

    return S_OK;
}

static HRESULT WINAPI InstallCallback_OnStopBinding(IBindStatusCallback *iface,
        HRESULT hresult, LPCWSTR szError)
{
    if(dwl_binding) {
        IBinding_Release(dwl_binding);
        dwl_binding = NULL;
    }

    if(FAILED(hresult)) {
        if(hresult == E_ABORT)
            TRACE("Binding aborted\n");
        else
            ERR("Binding failed %08x\n", hresult);
        return S_OK;
    }

    if(!msi_file) {
        ERR("No MSI file\n");
        return E_FAIL;
    }

    set_status(IDS_INSTALLING);
    EnableWindow(GetDlgItem(install_dialog, IDCANCEL), 0);

    if(sha_check(msi_file)) {
        WCHAR *cache_file_name;

        install_file(msi_file);

        cache_file_name = get_cache_file_name(TRUE);
        if(cache_file_name) {
            MoveFileW(msi_file, cache_file_name);
            heap_free(cache_file_name);
        }
    }else {
        WCHAR message[256];

        if(LoadStringW(hInst, IDS_INVALID_SHA, message, sizeof(message)/sizeof(WCHAR)))
            MessageBoxW(NULL, message, NULL, MB_ICONERROR);
    }

    DeleteFileW(msi_file);
    heap_free(msi_file);
    msi_file = NULL;

    EndDialog(install_dialog, 0);
    return S_OK;
}

static HRESULT WINAPI InstallCallback_GetBindInfo(IBindStatusCallback *iface,
        DWORD* grfBINDF, BINDINFO* pbindinfo)
{
    TRACE("()\n");

    *grfBINDF = BINDF_ASYNCHRONOUS;
    return S_OK;
}

static HRESULT WINAPI InstallCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
        DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
{
    if(!msi_file) {
        msi_file = heap_strdupW(pstgmed->u.lpszFileName);
        TRACE("got file name %s\n", debugstr_w(msi_file));
    }

    return S_OK;
}

static HRESULT WINAPI InstallCallback_OnObjectAvailable(IBindStatusCallback *iface,
        REFIID riid, IUnknown* punk)
{
    ERR("\n");
    return E_NOTIMPL;
}

static const IBindStatusCallbackVtbl InstallCallbackVtbl = {
    InstallCallback_QueryInterface,
    InstallCallback_AddRef,
    InstallCallback_Release,
    InstallCallback_OnStartBinding,
    InstallCallback_GetPriority,
    InstallCallback_OnLowResource,
    InstallCallback_OnProgress,
    InstallCallback_OnStopBinding,
    InstallCallback_GetBindInfo,
    InstallCallback_OnDataAvailable,
    InstallCallback_OnObjectAvailable
};

static IBindStatusCallback InstallCallback = { &InstallCallbackVtbl };

static HRESULT WINAPI InstallCallbackBindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
{
    return IBindStatusCallback_QueryInterface(&InstallCallback, riid, ppv);
}

static ULONG WINAPI InstallCallbackBindInfo_AddRef(IInternetBindInfo *iface)
{
    return 2;
}

static ULONG WINAPI InstallCallbackBindInfo_Release(IInternetBindInfo *iface)
{
    return 1;
}

static HRESULT WINAPI InstallCallbackBindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *bindf, BINDINFO *bindinfo)
{
    ERR("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallCallbackBindInfo_GetBindString(IInternetBindInfo *iface, ULONG string_type,
        WCHAR **strs, ULONG cnt, ULONG *fetched)
{
    static const WCHAR wine_addon_downloaderW[] =
        {'W','i','n','e',' ','A','d','d','o','n',' ','D','o','w','n','l','o','a','d','e','r',0};

    switch(string_type) {
    case BINDSTRING_USER_AGENT:
        TRACE("BINDSTRING_USER_AGENT\n");

        *strs = CoTaskMemAlloc(sizeof(wine_addon_downloaderW));
        if(!*strs)
            return E_OUTOFMEMORY;

        memcpy(*strs, wine_addon_downloaderW, sizeof(wine_addon_downloaderW));
        *fetched = 1;
        return S_OK;
    }

    return E_NOTIMPL;
}

static const IInternetBindInfoVtbl InstallCallbackBindInfoVtbl = {
    InstallCallbackBindInfo_QueryInterface,
    InstallCallbackBindInfo_AddRef,
    InstallCallbackBindInfo_Release,
    InstallCallbackBindInfo_GetBindInfo,
    InstallCallbackBindInfo_GetBindString
};

static IInternetBindInfo InstallCallbackBindInfo = { &InstallCallbackBindInfoVtbl };

static void append_url_params( WCHAR *url )
{
    static const WCHAR arch_formatW[] = {'?','a','r','c','h','='};
    static const WCHAR v_formatW[] = {'&','v','='};
    static const WCHAR winevW[] = {'&','w','i','n','e','v','='};
    DWORD size = INTERNET_MAX_URL_LENGTH * sizeof(WCHAR);
    DWORD len = strlenW(url);

    memcpy(url+len, arch_formatW, sizeof(arch_formatW));
    len += sizeof(arch_formatW)/sizeof(WCHAR);
    len += MultiByteToWideChar(CP_ACP, 0, ARCH_STRING, sizeof(ARCH_STRING),
                               url+len, size/sizeof(WCHAR)-len)-1;
    memcpy(url+len, v_formatW, sizeof(v_formatW));
    len += sizeof(v_formatW)/sizeof(WCHAR);
    len += MultiByteToWideChar(CP_ACP, 0, addon->version, -1, url+len, size/sizeof(WCHAR)-len)-1;
    memcpy(url+len, winevW, sizeof(winevW));
    len += sizeof(winevW)/sizeof(WCHAR);
    MultiByteToWideChar(CP_ACP, 0, PACKAGE_VERSION, -1, url+len, size/sizeof(WCHAR)-len);
}

static LPWSTR get_url(void)
{
    DWORD size = INTERNET_MAX_URL_LENGTH*sizeof(WCHAR);
    WCHAR *url, *config_key;
    HKEY hkey;
    DWORD res, type;
    DWORD returned_size;

    static const WCHAR httpW[] = {'h','t','t','p'};

    url = heap_alloc(size);
    returned_size = size;

    hkey = open_config_key();
    if (hkey)
    {
        config_key = heap_strdupAtoW(addon->url_config_key);
        res = RegQueryValueExW(hkey, config_key, NULL, &type, (LPBYTE)url, &returned_size);
        heap_free(config_key);
        RegCloseKey(hkey);
        if(res == ERROR_SUCCESS && type == REG_SZ) goto found;
    }

    MultiByteToWideChar( CP_ACP, 0, addon->url_default, -1, url, size / sizeof(WCHAR) );

found:
    if (returned_size > sizeof(httpW) && !memcmp(url, httpW, sizeof(httpW))) append_url_params( url );

    TRACE("Got URL %s\n", debugstr_w(url));
    return url;
}

static BOOL start_download(void)
{
    IBindCtx *bind_ctx;
    IMoniker *mon;
    IUnknown *tmp;
    HRESULT hres;

    hres = CreateURLMoniker(NULL, url, &mon);
    if(FAILED(hres))
        return FALSE;

    hres = CreateAsyncBindCtx(0, &InstallCallback, NULL, &bind_ctx);
    if(SUCCEEDED(hres)) {
        hres = IMoniker_BindToStorage(mon, bind_ctx, NULL, &IID_IUnknown, (void**)&tmp);
        IBindCtx_Release(bind_ctx);
    }
    IMoniker_Release(mon);
    if(FAILED(hres))
        return FALSE;

    if(tmp)
        IUnknown_Release(tmp);
    return TRUE;
}

static void run_winebrowser(const WCHAR *url)
{
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    WCHAR app[MAX_PATH];
    LONG len, url_len;
    WCHAR *args;
    BOOL ret;

    static const WCHAR winebrowserW[] = {'\\','w','i','n','e','b','r','o','w','s','e','r','.','e','x','e',0};

    url_len = strlenW(url);

    len = GetSystemDirectoryW(app, MAX_PATH-sizeof(winebrowserW)/sizeof(WCHAR));
    memcpy(app+len, winebrowserW, sizeof(winebrowserW));
    len += sizeof(winebrowserW)/sizeof(WCHAR) -1;

    args = heap_alloc((len+1+url_len)*sizeof(WCHAR));
    if(!args)
        return;

    memcpy(args, app, len*sizeof(WCHAR));
    args[len++] = ' ';
    memcpy(args+len, url, (url_len+1) * sizeof(WCHAR));

    TRACE("starting %s\n", debugstr_w(args));

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    ret = CreateProcessW(app, args, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi);
    heap_free(args);
    if (ret) {
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }
}

static INT_PTR CALLBACK installer_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg) {
    case WM_INITDIALOG:
        ShowWindow(GetDlgItem(hwnd, ID_DWL_PROGRESS), SW_HIDE);
        install_dialog = hwnd;
        return TRUE;

    case WM_NOTIFY:
        switch (((NMHDR *)lParam)->code)
        {
        case NM_CLICK:
        case NM_RETURN:
            if (wParam == ID_DWL_STATUS)
                run_winebrowser(((NMLINK*)lParam)->item.szUrl);
            break;
        }
        break;

    case WM_COMMAND:
        switch(wParam) {
        case IDCANCEL:
            if(dwl_binding)
                IBinding_Abort(dwl_binding);
            EndDialog(hwnd, 0);
            return FALSE;

        case ID_DWL_INSTALL:
            ShowWindow(GetDlgItem(hwnd, ID_DWL_PROGRESS), SW_SHOW);
            EnableWindow(GetDlgItem(hwnd, ID_DWL_INSTALL), 0);
            if(!start_download())
                EndDialog(install_dialog, 0);
        }
    }

    return FALSE;
}

BOOL install_addon(addon_t addon_type)
{
    if(!*ARCH_STRING)
        return FALSE;

    addon = addons_info+addon_type;

    p_wine_get_dos_file_name = (void*)GetProcAddress(GetModuleHandleW(kernel32_dllW), "wine_get_dos_file_name");

    /*
     * Try to find addon .msi file in following order:
     * - directory stored in $dir_config_key value of HKCU/Software/Wine/$config_key key
     * - $datadir/$addon_subdir/
     * - $INSTALL_DATADIR/wine/$addon_subdir/
     * - /usr/share/wine/$addon_subdir/
     * - download from URL stored in $url_config_key value of HKCU/Software/Wine/$config_key key
     */
    if (install_from_registered_dir() == INSTALL_NEXT
        && install_from_default_dir() == INSTALL_NEXT
        && install_from_cache() == INSTALL_NEXT
        && (url = get_url()))
        DialogBoxW(hInst, addon->dialog_template, 0, installer_proc);

    heap_free(url);
    url = NULL;
    return TRUE;
}
