/*
 * Implementation of the Microsoft Installer (msi.dll)
 *
 * Copyright 2004 Aric Stewart 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
 */

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define COBJMACROS

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "shlwapi.h"
#include "wingdi.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "objidl.h"
#include "wincrypt.h"
#include "winuser.h"
#include "wininet.h"
#include "winver.h"
#include "urlmon.h"
#include "shlobj.h"
#include "wine/unicode.h"
#include "objbase.h"
#include "msidefs.h"
#include "sddl.h"

#include "msipriv.h"
#include "msiserver.h"
#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);

static void free_feature( MSIFEATURE *feature )
{
    struct list *item, *cursor;

    LIST_FOR_EACH_SAFE( item, cursor, &feature->Children )
    {
        FeatureList *fl = LIST_ENTRY( item, FeatureList, entry );
        list_remove( &fl->entry );
        msi_free( fl );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &feature->Components )
    {
        ComponentList *cl = LIST_ENTRY( item, ComponentList, entry );
        list_remove( &cl->entry );
        msi_free( cl );
    }
    msi_free( feature->Feature );
    msi_free( feature->Feature_Parent );
    msi_free( feature->Directory );
    msi_free( feature->Description );
    msi_free( feature->Title );
    msi_free( feature );
}

static void free_folder( MSIFOLDER *folder )
{
    struct list *item, *cursor;

    LIST_FOR_EACH_SAFE( item, cursor, &folder->children )
    {
        FolderList *fl = LIST_ENTRY( item, FolderList, entry );
        list_remove( &fl->entry );
        msi_free( fl );
    }
    msi_free( folder->Parent );
    msi_free( folder->Directory );
    msi_free( folder->TargetDefault );
    msi_free( folder->SourceLongPath );
    msi_free( folder->SourceShortPath );
    msi_free( folder->ResolvedTarget );
    msi_free( folder->ResolvedSource );
    msi_free( folder );
}

static void free_extension( MSIEXTENSION *ext )
{
    struct list *item, *cursor;

    LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs )
    {
        MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry );

        list_remove( &verb->entry );
        msi_free( verb->Verb );
        msi_free( verb->Command );
        msi_free( verb->Argument );
        msi_free( verb );
    }

    msi_free( ext->Extension );
    msi_free( ext->ProgIDText );
    msi_free( ext );
}

static void free_assembly( MSIASSEMBLY *assembly )
{
    msi_free( assembly->feature );
    msi_free( assembly->manifest );
    msi_free( assembly->application );
    msi_free( assembly->display_name );
    if (assembly->tempdir) RemoveDirectoryW( assembly->tempdir );
    msi_free( assembly->tempdir );
    msi_free( assembly );
}

void msi_free_action_script( MSIPACKAGE *package, UINT script )
{
    UINT i;
    for (i = 0; i < package->script_actions_count[script]; i++)
        msi_free( package->script_actions[script][i] );

    msi_free( package->script_actions[script] );
    package->script_actions[script] = NULL;
    package->script_actions_count[script] = 0;
}

static void free_package_structures( MSIPACKAGE *package )
{
    struct list *item, *cursor;
    int i;

    LIST_FOR_EACH_SAFE( item, cursor, &package->features )
    {
        MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry );
        list_remove( &feature->entry );
        free_feature( feature );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->folders )
    {
        MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
        list_remove( &folder->entry );
        free_folder( folder );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->files )
    {
        MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry );

        list_remove( &file->entry );
        msi_free( file->File );
        msi_free( file->FileName );
        msi_free( file->ShortName );
        msi_free( file->LongName );
        msi_free( file->Version );
        msi_free( file->Language );
        if (msi_is_global_assembly( file->Component )) DeleteFileW( file->TargetPath );
        msi_free( file->TargetPath );
        msi_free( file );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->components )
    {
        MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );

        list_remove( &comp->entry );
        msi_free( comp->Component );
        msi_free( comp->ComponentId );
        msi_free( comp->Directory );
        msi_free( comp->Condition );
        msi_free( comp->KeyPath );
        msi_free( comp->FullKeypath );
        if (comp->assembly) free_assembly( comp->assembly );
        msi_free( comp );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->filepatches )
    {
        MSIFILEPATCH *patch = LIST_ENTRY( item, MSIFILEPATCH, entry );

        list_remove( &patch->entry );
        msi_free( patch->path );
        msi_free( patch );
    }

    /* clean up extension, progid, class and verb structures */
    LIST_FOR_EACH_SAFE( item, cursor, &package->classes )
    {
        MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry );

        list_remove( &cls->entry );
        msi_free( cls->clsid );
        msi_free( cls->Context );
        msi_free( cls->Description );
        msi_free( cls->FileTypeMask );
        msi_free( cls->IconPath );
        msi_free( cls->DefInprocHandler );
        msi_free( cls->DefInprocHandler32 );
        msi_free( cls->Argument );
        msi_free( cls->ProgIDText );
        msi_free( cls );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->extensions )
    {
        MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry );

        list_remove( &ext->entry );
        free_extension( ext );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->progids )
    {
        MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry );

        list_remove( &progid->entry );
        msi_free( progid->ProgID );
        msi_free( progid->Description );
        msi_free( progid->IconPath );
        msi_free( progid );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->mimes )
    {
        MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry );

        list_remove( &mt->entry );
        msi_free( mt->suffix );
        msi_free( mt->clsid );
        msi_free( mt->ContentType );
        msi_free( mt );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->appids )
    {
        MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry );

        list_remove( &appid->entry );
        msi_free( appid->AppID );
        msi_free( appid->RemoteServerName );
        msi_free( appid->LocalServer );
        msi_free( appid->ServiceParameters );
        msi_free( appid->DllSurrogate );
        msi_free( appid );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_info )
    {
        MSISOURCELISTINFO *info = LIST_ENTRY( item, MSISOURCELISTINFO, entry );

        list_remove( &info->entry );
        msi_free( info->value );
        msi_free( info );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_media )
    {
        MSIMEDIADISK *info = LIST_ENTRY( item, MSIMEDIADISK, entry );

        list_remove( &info->entry );
        msi_free( info->volume_label );
        msi_free( info->disk_prompt );
        msi_free( info );
    }

    for (i = 0; i < SCRIPT_MAX; i++)
        msi_free_action_script( package, i );

    for (i = 0; i < package->unique_actions_count; i++)
        msi_free( package->unique_actions[i] );
    msi_free( package->unique_actions);

    LIST_FOR_EACH_SAFE( item, cursor, &package->binaries )
    {
        MSIBINARY *binary = LIST_ENTRY( item, MSIBINARY, entry );

        list_remove( &binary->entry );
        if (binary->module)
            FreeLibrary( binary->module );
        if (!DeleteFileW( binary->tmpfile ))
            ERR("failed to delete %s (%u)\n", debugstr_w(binary->tmpfile), GetLastError());
        msi_free( binary->source );
        msi_free( binary->tmpfile );
        msi_free( binary );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->cabinet_streams )
    {
        MSICABINETSTREAM *cab = LIST_ENTRY( item, MSICABINETSTREAM, entry );

        list_remove( &cab->entry );
        IStorage_Release( cab->storage );
        msi_free( cab->stream );
        msi_free( cab );
    }

    LIST_FOR_EACH_SAFE( item, cursor, &package->patches )
    {
        MSIPATCHINFO *patch = LIST_ENTRY( item, MSIPATCHINFO, entry );

        list_remove( &patch->entry );
        if (patch->delete_on_close && !DeleteFileW( patch->localfile ))
        {
            ERR("failed to delete %s (%u)\n", debugstr_w(patch->localfile), GetLastError());
        }
        msi_free_patchinfo( patch );
    }

    msi_free( package->BaseURL );
    msi_free( package->PackagePath );
    msi_free( package->ProductCode );
    msi_free( package->ActionFormat );
    msi_free( package->LastAction );
    msi_free( package->LastActionTemplate );
    msi_free( package->langids );

    /* cleanup control event subscriptions */
    msi_event_cleanup_all_subscriptions( package );
}

static void MSI_FreePackage( MSIOBJECTHDR *arg)
{
    MSIPACKAGE *package = (MSIPACKAGE *)arg;

    msi_destroy_assembly_caches( package );

    if( package->dialog )
        msi_dialog_destroy( package->dialog );

    msiobj_release( &package->db->hdr );
    free_package_structures(package);
    CloseHandle( package->log_file );

    if (package->delete_on_close) DeleteFileW( package->localfile );
    msi_free( package->localfile );
    MSI_ProcessMessage(NULL, INSTALLMESSAGE_TERMINATE, 0);
}

static UINT create_temp_property_table(MSIPACKAGE *package)
{
    static const WCHAR query[] = {
        'C','R','E','A','T','E',' ','T','A','B','L','E',' ',
        '`','_','P','r','o','p','e','r','t','y','`',' ','(',' ',
        '`','_','P','r','o','p','e','r','t','y','`',' ',
        'C','H','A','R','(','5','6',')',' ','N','O','T',' ','N','U','L','L',' ',
        'T','E','M','P','O','R','A','R','Y',',',' ',
        '`','V','a','l','u','e','`',' ','C','H','A','R','(','9','8',')',' ',
        'N','O','T',' ','N','U','L','L',' ','T','E','M','P','O','R','A','R','Y',
        ' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ',
        '`','_','P','r','o','p','e','r','t','y','`',')',' ','H','O','L','D',0};
    MSIQUERY *view;
    UINT rc;

    rc = MSI_DatabaseOpenViewW(package->db, query, &view);
    if (rc != ERROR_SUCCESS)
        return rc;

    rc = MSI_ViewExecute(view, 0);
    MSI_ViewClose(view);
    msiobj_release(&view->hdr);
    return rc;
}

UINT msi_clone_properties( MSIDATABASE *db )
{
    static const WCHAR query_select[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        '`','P','r','o','p','e','r','t','y','`',0};
    static const WCHAR query_insert[] = {
        'I','N','S','E','R','T',' ','I','N','T','O',' ',
        '`','_','P','r','o','p','e','r','t','y','`',' ',
        '(','`','_','P','r','o','p','e','r','t','y','`',',','`','V','a','l','u','e','`',')',' ',
        'V','A','L','U','E','S',' ','(','?',',','?',')',0};
    static const WCHAR query_update[] = {
        'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ',
        'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ',
        'W','H','E','R','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','?',0};
    MSIQUERY *view_select;
    UINT rc;

    rc = MSI_DatabaseOpenViewW( db, query_select, &view_select );
    if (rc != ERROR_SUCCESS)
        return rc;

    rc = MSI_ViewExecute( view_select, 0 );
    if (rc != ERROR_SUCCESS)
    {
        MSI_ViewClose( view_select );
        msiobj_release( &view_select->hdr );
        return rc;
    }

    while (1)
    {
        MSIQUERY *view_insert, *view_update;
        MSIRECORD *rec_select;

        rc = MSI_ViewFetch( view_select, &rec_select );
        if (rc != ERROR_SUCCESS)
            break;

        rc = MSI_DatabaseOpenViewW( db, query_insert, &view_insert );
        if (rc != ERROR_SUCCESS)
        {
            msiobj_release( &rec_select->hdr );
            continue;
        }

        rc = MSI_ViewExecute( view_insert, rec_select );
        MSI_ViewClose( view_insert );
        msiobj_release( &view_insert->hdr );
        if (rc != ERROR_SUCCESS)
        {
            MSIRECORD *rec_update;

            TRACE("insert failed, trying update\n");

            rc = MSI_DatabaseOpenViewW( db, query_update, &view_update );
            if (rc != ERROR_SUCCESS)
            {
                WARN("open view failed %u\n", rc);
                msiobj_release( &rec_select->hdr );
                continue;
            }

            rec_update = MSI_CreateRecord( 2 );
            MSI_RecordCopyField( rec_select, 1, rec_update, 2 );
            MSI_RecordCopyField( rec_select, 2, rec_update, 1 );
            rc = MSI_ViewExecute( view_update, rec_update );
            if (rc != ERROR_SUCCESS)
                WARN("update failed %u\n", rc);

            MSI_ViewClose( view_update );
            msiobj_release( &view_update->hdr );
            msiobj_release( &rec_update->hdr );
        }

        msiobj_release( &rec_select->hdr );
    }

    MSI_ViewClose( view_select );
    msiobj_release( &view_select->hdr );
    return rc;
}

/*
 * set_installed_prop
 *
 * Sets the "Installed" property to indicate that
 *  the product is installed for the current user.
 */
static UINT set_installed_prop( MSIPACKAGE *package )
{
    HKEY hkey;
    UINT r;

    if (!package->ProductCode) return ERROR_FUNCTION_FAILED;

    r = MSIREG_OpenUninstallKey( package->ProductCode, package->platform, &hkey, FALSE );
    if (r == ERROR_SUCCESS)
    {
        RegCloseKey( hkey );
        msi_set_property( package->db, szInstalled, szOne, -1 );
    }
    return r;
}

static UINT set_user_sid_prop( MSIPACKAGE *package )
{
    SID_NAME_USE use;
    LPWSTR user_name;
    LPWSTR sid_str = NULL, dom = NULL;
    DWORD size, dom_size;
    PSID psid = NULL;
    UINT r = ERROR_FUNCTION_FAILED;

    size = 0;
    GetUserNameW( NULL, &size );

    user_name = msi_alloc( (size + 1) * sizeof(WCHAR) );
    if (!user_name)
        return ERROR_OUTOFMEMORY;

    if (!GetUserNameW( user_name, &size ))
        goto done;

    size = 0;
    dom_size = 0;
    LookupAccountNameW( NULL, user_name, NULL, &size, NULL, &dom_size, &use );

    psid = msi_alloc( size );
    dom = msi_alloc( dom_size*sizeof (WCHAR) );
    if (!psid || !dom)
    {
        r = ERROR_OUTOFMEMORY;
        goto done;
    }

    if (!LookupAccountNameW( NULL, user_name, psid, &size, dom, &dom_size, &use ))
        goto done;

    if (!ConvertSidToStringSidW( psid, &sid_str ))
        goto done;

    r = msi_set_property( package->db, szUserSID, sid_str, -1 );

done:
    LocalFree( sid_str );
    msi_free( dom );
    msi_free( psid );
    msi_free( user_name );

    return r;
}

static LPWSTR get_fusion_filename(MSIPACKAGE *package)
{
    HKEY netsetup;
    LONG res;
    LPWSTR file = NULL;
    DWORD index = 0, size;
    WCHAR ver[MAX_PATH];
    WCHAR name[MAX_PATH];
    WCHAR windir[MAX_PATH];

    static const WCHAR fusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
    static const WCHAR sub[] = {
        'S','o','f','t','w','a','r','e','\\',
        'M','i','c','r','o','s','o','f','t','\\',
        'N','E','T',' ','F','r','a','m','e','w','o','r','k',' ','S','e','t','u','p','\\',
        'N','D','P',0
    };
    static const WCHAR subdir[] = {
        'M','i','c','r','o','s','o','f','t','.','N','E','T','\\',
        'F','r','a','m','e','w','o','r','k','\\',0
    };

    res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, sub, 0, KEY_ENUMERATE_SUB_KEYS, &netsetup);
    if (res != ERROR_SUCCESS)
        return NULL;

    GetWindowsDirectoryW(windir, MAX_PATH);

    ver[0] = '\0';
    size = MAX_PATH;
    while (RegEnumKeyExW(netsetup, index, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
    {
        index++;

        /* verify existence of fusion.dll .Net 3.0 does not install a new one */
        if (strcmpW( ver, name ) < 0)
        {
            LPWSTR check;
            size = lstrlenW(windir) + lstrlenW(subdir) + lstrlenW(name) +lstrlenW(fusion) + 3;
            check = msi_alloc(size * sizeof(WCHAR));

            if (!check)
            {
                msi_free(file);
                return NULL;
            }

            lstrcpyW(check, windir);
            lstrcatW(check, szBackSlash);
            lstrcatW(check, subdir);
            lstrcatW(check, name);
            lstrcatW(check, szBackSlash);
            lstrcatW(check, fusion);

            if(GetFileAttributesW(check) != INVALID_FILE_ATTRIBUTES)
            {
                msi_free(file);
                file = check;
                lstrcpyW(ver, name);
            }
            else
                msi_free(check);
        }
    }

    RegCloseKey(netsetup);
    return file;
}

typedef struct tagLANGANDCODEPAGE
{
  WORD wLanguage;
  WORD wCodePage;
} LANGANDCODEPAGE;

static void set_msi_assembly_prop(MSIPACKAGE *package)
{
    UINT val_len;
    DWORD size, handle;
    LPVOID version = NULL;
    WCHAR buf[MAX_PATH];
    LPWSTR fusion, verstr;
    LANGANDCODEPAGE *translate;

    static const WCHAR netasm[] = {
        'M','s','i','N','e','t','A','s','s','e','m','b','l','y','S','u','p','p','o','r','t',0
    };
    static const WCHAR translation[] = {
        '\\','V','a','r','F','i','l','e','I','n','f','o',
        '\\','T','r','a','n','s','l','a','t','i','o','n',0
    };
    static const WCHAR verfmt[] = {
        '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
        '\\','%','0','4','x','%','0','4','x',
        '\\','P','r','o','d','u','c','t','V','e','r','s','i','o','n',0
    };

    fusion = get_fusion_filename(package);
    if (!fusion)
        return;

    size = GetFileVersionInfoSizeW(fusion, &handle);
    if (!size)
        goto done;

    version = msi_alloc(size);
    if (!version)
        goto done;

    if (!GetFileVersionInfoW(fusion, handle, size, version))
        goto done;

    if (!VerQueryValueW(version, translation, (LPVOID *)&translate, &val_len))
        goto done;

    sprintfW(buf, verfmt, translate[0].wLanguage, translate[0].wCodePage);

    if (!VerQueryValueW(version, buf, (LPVOID *)&verstr, &val_len))
        goto done;

    if (!val_len || !verstr)
        goto done;

    msi_set_property( package->db, netasm, verstr, -1 );

done:
    msi_free(fusion);
    msi_free(version);
}

static VOID set_installer_properties(MSIPACKAGE *package)
{
    WCHAR *ptr;
    OSVERSIONINFOEXW OSVersion;
    MEMORYSTATUSEX msex;
    DWORD verval, len;
    WCHAR pth[MAX_PATH], verstr[11], bufstr[22];
    HDC dc;
    HKEY hkey;
    LPWSTR username, companyname;
    SYSTEM_INFO sys_info;
    LANGID langid;

    static const WCHAR szCommonFilesFolder[] = {'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
    static const WCHAR szProgramFilesFolder[] = {'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
    static const WCHAR szCommonAppDataFolder[] = {'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
    static const WCHAR szFavoritesFolder[] = {'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
    static const WCHAR szFontsFolder[] = {'F','o','n','t','s','F','o','l','d','e','r',0};
    static const WCHAR szSendToFolder[] = {'S','e','n','d','T','o','F','o','l','d','e','r',0};
    static const WCHAR szStartMenuFolder[] = {'S','t','a','r','t','M','e','n','u','F','o','l','d','e','r',0};
    static const WCHAR szStartupFolder[] = {'S','t','a','r','t','u','p','F','o','l','d','e','r',0};
    static const WCHAR szTemplateFolder[] = {'T','e','m','p','l','a','t','e','F','o','l','d','e','r',0};
    static const WCHAR szDesktopFolder[] = {'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
    static const WCHAR szProgramMenuFolder[] = {'P','r','o','g','r','a','m','M','e','n','u','F','o','l','d','e','r',0};
    static const WCHAR szAdminToolsFolder[] = {'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
    static const WCHAR szSystemFolder[] = {'S','y','s','t','e','m','F','o','l','d','e','r',0};
    static const WCHAR szSystem16Folder[] = {'S','y','s','t','e','m','1','6','F','o','l','d','e','r',0};
    static const WCHAR szLocalAppDataFolder[] = {'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
    static const WCHAR szMyPicturesFolder[] = {'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
    static const WCHAR szPersonalFolder[] = {'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
    static const WCHAR szWindowsVolume[] = {'W','i','n','d','o','w','s','V','o','l','u','m','e',0};
    static const WCHAR szPrivileged[] = {'P','r','i','v','i','l','e','g','e','d',0};
    static const WCHAR szVersion9x[] = {'V','e','r','s','i','o','n','9','X',0};
    static const WCHAR szVersionNT[] = {'V','e','r','s','i','o','n','N','T',0};
    static const WCHAR szMsiNTProductType[] = {'M','s','i','N','T','P','r','o','d','u','c','t','T','y','p','e',0};
    static const WCHAR szFormat[] = {'%','u',0};
    static const WCHAR szFormat2[] = {'%','u','.','%','u',0};
    static const WCHAR szWindowsBuild[] = {'W','i','n','d','o','w','s','B','u','i','l','d',0};
    static const WCHAR szServicePackLevel[] = {'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',0};
    static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
    static const WCHAR szVersionDatabase[] = { 'V','e','r','s','i','o','n','D','a','t','a','b','a','s','e',0 };
    static const WCHAR szPhysicalMemory[] = { 'P','h','y','s','i','c','a','l','M','e','m','o','r','y',0 };
    static const WCHAR szScreenX[] = {'S','c','r','e','e','n','X',0};
    static const WCHAR szScreenY[] = {'S','c','r','e','e','n','Y',0};
    static const WCHAR szColorBits[] = {'C','o','l','o','r','B','i','t','s',0};
    static const WCHAR szIntFormat[] = {'%','d',0};
    static const WCHAR szMsiAMD64[] = { 'M','s','i','A','M','D','6','4',0 };
    static const WCHAR szMsix64[] = { 'M','s','i','x','6','4',0 };
    static const WCHAR szSystem64Folder[] = { 'S','y','s','t','e','m','6','4','F','o','l','d','e','r',0 };
    static const WCHAR szCommonFiles64Folder[] = { 'C','o','m','m','o','n','F','i','l','e','s','6','4','F','o','l','d','e','r',0 };
    static const WCHAR szProgramFiles64Folder[] = { 'P','r','o','g','r','a','m','F','i','l','e','s','6','4','F','o','l','d','e','r',0 };
    static const WCHAR szVersionNT64[] = { 'V','e','r','s','i','o','n','N','T','6','4',0 };
    static const WCHAR szUserInfo[] = {
        'S','O','F','T','W','A','R','E','\\',
        'M','i','c','r','o','s','o','f','t','\\',
        'M','S',' ','S','e','t','u','p',' ','(','A','C','M','E',')','\\',
        'U','s','e','r',' ','I','n','f','o',0
    };
    static const WCHAR szDefName[] = { 'D','e','f','N','a','m','e',0 };
    static const WCHAR szDefCompany[] = { 'D','e','f','C','o','m','p','a','n','y',0 };
    static const WCHAR szCurrentVersion[] = {
        'S','O','F','T','W','A','R','E','\\',
        'M','i','c','r','o','s','o','f','t','\\',
        'W','i','n','d','o','w','s',' ','N','T','\\',
        'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0
    };
    static const WCHAR szRegisteredUser[] = {'R','e','g','i','s','t','e','r','e','d','O','w','n','e','r',0};
    static const WCHAR szRegisteredOrganization[] = {
        'R','e','g','i','s','t','e','r','e','d','O','r','g','a','n','i','z','a','t','i','o','n',0
    };
    static const WCHAR szUSERNAME[] = {'U','S','E','R','N','A','M','E',0};
    static const WCHAR szCOMPANYNAME[] = {'C','O','M','P','A','N','Y','N','A','M','E',0};
    static const WCHAR szUserLanguageID[] = {'U','s','e','r','L','a','n','g','u','a','g','e','I','D',0};
    static const WCHAR szSystemLangID[] = {'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0};
    static const WCHAR szProductState[] = {'P','r','o','d','u','c','t','S','t','a','t','e',0};
    static const WCHAR szLogonUser[] = {'L','o','g','o','n','U','s','e','r',0};
    static const WCHAR szNetHoodFolder[] = {'N','e','t','H','o','o','d','F','o','l','d','e','r',0};
    static const WCHAR szPrintHoodFolder[] = {'P','r','i','n','t','H','o','o','d','F','o','l','d','e','r',0};
    static const WCHAR szRecentFolder[] = {'R','e','c','e','n','t','F','o','l','d','e','r',0};
    static const WCHAR szComputerName[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0};

    /*
     * Other things that probably should be set:
     *
     * VirtualMemory ShellAdvSupport DefaultUIFont PackagecodeChanging
     * CaptionHeight BorderTop BorderSide TextHeight RedirectedDllSupport
     */

    SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szCommonAppDataFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_FAVORITES, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szFavoritesFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szFontsFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_SENDTO, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szSendToFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szStartMenuFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szStartupFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_TEMPLATES, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szTemplateFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szDesktopFolder, pth, -1 );

    /* FIXME: set to AllUsers profile path if ALLUSERS is set */
    SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szProgramMenuFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_ADMINTOOLS, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szAdminToolsFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szAppDataFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szSystemFolder, pth, -1 );
    msi_set_property( package->db, szSystem16Folder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szLocalAppDataFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szMyPicturesFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szPersonalFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szWindowsFolder, pth, -1 );
    
    SHGetFolderPathW(NULL, CSIDL_PRINTHOOD, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szPrintHoodFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_NETHOOD, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szNetHoodFolder, pth, -1 );

    SHGetFolderPathW(NULL, CSIDL_RECENT, NULL, 0, pth);
    strcatW(pth, szBackSlash);
    msi_set_property( package->db, szRecentFolder, pth, -1 );

    /* Physical Memory is specified in MB. Using total amount. */
    msex.dwLength = sizeof(msex);
    GlobalMemoryStatusEx( &msex );
    len = sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys / 1024 / 1024) );
    msi_set_property( package->db, szPhysicalMemory, bufstr, len );

    SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth);
    ptr = strchrW(pth,'\\');
    if (ptr) *(ptr + 1) = 0;
    msi_set_property( package->db, szWindowsVolume, pth, -1 );
    
    len = GetTempPathW(MAX_PATH, pth);
    msi_set_property( package->db, szTempFolder, pth, len );

    /* in a wine environment the user is always admin and privileged */
    msi_set_property( package->db, szAdminUser, szOne, -1 );
    msi_set_property( package->db, szPrivileged, szOne, -1 );

    /* set the os things */
    OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
    GetVersionExW((OSVERSIONINFOW *)&OSVersion);
    verval = OSVersion.dwMinorVersion + OSVersion.dwMajorVersion * 100;
    len = sprintfW( verstr, szFormat, verval );
    switch (OSVersion.dwPlatformId)
    {
        case VER_PLATFORM_WIN32_WINDOWS:    
            msi_set_property( package->db, szVersion9x, verstr, len );
            break;
        case VER_PLATFORM_WIN32_NT:
            msi_set_property( package->db, szVersionNT, verstr, len );
            len = sprintfW( bufstr, szFormat,OSVersion.wProductType );
            msi_set_property( package->db, szMsiNTProductType, bufstr, len );
            break;
    }
    len = sprintfW( bufstr, szFormat, OSVersion.dwBuildNumber );
    msi_set_property( package->db, szWindowsBuild, bufstr, len );
    len = sprintfW( bufstr, szFormat, OSVersion.wServicePackMajor );
    msi_set_property( package->db, szServicePackLevel, bufstr, len );

    len = sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION );
    msi_set_property( package->db, szVersionMsi, bufstr, len );
    len = sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100 );
    msi_set_property( package->db, szVersionDatabase, bufstr, len );

    GetNativeSystemInfo( &sys_info );
    len = sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel );
    msi_set_property( package->db, szIntel, bufstr, len );
    if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
    {
        GetSystemDirectoryW( pth, MAX_PATH );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szSystemFolder, pth, -1 );

        SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szProgramFilesFolder, pth, -1 );

        SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szCommonFilesFolder, pth, -1 );
    }
    else if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
    {
        msi_set_property( package->db, szMsiAMD64, bufstr, -1 );
        msi_set_property( package->db, szMsix64, bufstr, -1 );
        msi_set_property( package->db, szVersionNT64, verstr, -1 );

        GetSystemDirectoryW( pth, MAX_PATH );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szSystem64Folder, pth, -1 );

        GetSystemWow64DirectoryW( pth, MAX_PATH );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szSystemFolder, pth, -1 );

        SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szProgramFiles64Folder, pth, -1 );

        SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, pth );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szProgramFilesFolder, pth, -1 );

        SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szCommonFiles64Folder, pth, -1 );

        SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, pth );
        PathAddBackslashW( pth );
        msi_set_property( package->db, szCommonFilesFolder, pth, -1 );
    }

    /* Screen properties. */
    dc = GetDC(0);
    len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, HORZRES) );
    msi_set_property( package->db, szScreenX, bufstr, len );
    len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, VERTRES) );
    msi_set_property( package->db, szScreenY, bufstr, len );
    len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, BITSPIXEL) );
    msi_set_property( package->db, szColorBits, bufstr, len );
    ReleaseDC(0, dc);

    /* USERNAME and COMPANYNAME */
    username = msi_dup_property( package->db, szUSERNAME );
    companyname = msi_dup_property( package->db, szCOMPANYNAME );

    if ((!username || !companyname) &&
        RegOpenKeyW( HKEY_CURRENT_USER, szUserInfo, &hkey ) == ERROR_SUCCESS)
    {
        if (!username &&
            (username = msi_reg_get_val_str( hkey, szDefName )))
            msi_set_property( package->db, szUSERNAME, username, -1 );
        if (!companyname &&
            (companyname = msi_reg_get_val_str( hkey, szDefCompany )))
            msi_set_property( package->db, szCOMPANYNAME, companyname, -1 );
        CloseHandle( hkey );
    }
    if ((!username || !companyname) &&
        RegOpenKeyW( HKEY_LOCAL_MACHINE, szCurrentVersion, &hkey ) == ERROR_SUCCESS)
    {
        if (!username &&
            (username = msi_reg_get_val_str( hkey, szRegisteredUser )))
            msi_set_property( package->db, szUSERNAME, username, -1 );
        if (!companyname &&
            (companyname = msi_reg_get_val_str( hkey, szRegisteredOrganization )))
            msi_set_property( package->db, szCOMPANYNAME, companyname, -1 );
        CloseHandle( hkey );
    }
    msi_free( username );
    msi_free( companyname );

    if ( set_user_sid_prop( package ) != ERROR_SUCCESS)
        ERR("Failed to set the UserSID property\n");

    set_msi_assembly_prop( package );

    langid = GetUserDefaultLangID();
    len = sprintfW( bufstr, szIntFormat, langid );
    msi_set_property( package->db, szUserLanguageID, bufstr, len );

    langid = GetSystemDefaultLangID();
    len = sprintfW( bufstr, szIntFormat, langid );
    msi_set_property( package->db, szSystemLangID, bufstr, len );

    len = sprintfW( bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode) );
    msi_set_property( package->db, szProductState, bufstr, len );

    len = 0;
    if (!GetUserNameW( NULL, &len ) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        WCHAR *username;
        if ((username = msi_alloc( len * sizeof(WCHAR) )))
        {
            if (GetUserNameW( username, &len ))
                msi_set_property( package->db, szLogonUser, username, len - 1 );
            msi_free( username );
        }
    }
    len = 0;
    if (!GetComputerNameW( NULL, &len ) && GetLastError() == ERROR_BUFFER_OVERFLOW)
    {
        WCHAR *computername;
        if ((computername = msi_alloc( len * sizeof(WCHAR) )))
        {
            if (GetComputerNameW( computername, &len ))
                msi_set_property( package->db, szComputerName, computername, len );
            msi_free( computername );
        }
    }
}

static MSIPACKAGE *msi_alloc_package( void )
{
    MSIPACKAGE *package;

    package = alloc_msiobject( MSIHANDLETYPE_PACKAGE, sizeof (MSIPACKAGE),
                               MSI_FreePackage );
    if( package )
    {
        list_init( &package->components );
        list_init( &package->features );
        list_init( &package->files );
        list_init( &package->filepatches );
        list_init( &package->tempfiles );
        list_init( &package->folders );
        list_init( &package->subscriptions );
        list_init( &package->appids );
        list_init( &package->classes );
        list_init( &package->mimes );
        list_init( &package->extensions );
        list_init( &package->progids );
        list_init( &package->RunningActions );
        list_init( &package->sourcelist_info );
        list_init( &package->sourcelist_media );
        list_init( &package->patches );
        list_init( &package->binaries );
        list_init( &package->cabinet_streams );
    }

    return package;
}

static UINT msi_load_admin_properties(MSIPACKAGE *package)
{
    BYTE *data;
    UINT r, sz;

    static const WCHAR stmname[] = {'A','d','m','i','n','P','r','o','p','e','r','t','i','e','s',0};

    r = read_stream_data(package->db->storage, stmname, FALSE, &data, &sz);
    if (r != ERROR_SUCCESS)
        return r;

    r = msi_parse_command_line(package, (WCHAR *)data, TRUE);

    msi_free(data);
    return r;
}

void msi_adjust_privilege_properties( MSIPACKAGE *package )
{
    /* FIXME: this should depend on the user's privileges */
    if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2)
    {
        TRACE("resetting ALLUSERS property from 2 to 1\n");
        msi_set_property( package->db, szAllUsers, szOne, -1 );
    }
    msi_set_property( package->db, szAdminUser, szOne, -1 );
}

MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
{
    static const WCHAR fmtW[] = {'%','u',0};
    MSIPACKAGE *package;
    WCHAR uilevel[11];
    int len;
    UINT r;

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

    package = msi_alloc_package();
    if (package)
    {
        msiobj_addref( &db->hdr );
        package->db = db;

        package->LastAction = NULL;
        package->LastActionTemplate = NULL;
        package->LastActionResult = MSI_NULL_INTEGER;
        package->WordCount = 0;
        package->PackagePath = strdupW( db->path );
        package->BaseURL = strdupW( base_url );

        create_temp_property_table( package );
        msi_clone_properties( package->db );
        msi_adjust_privilege_properties( package );

        package->ProductCode = msi_dup_property( package->db, szProductCode );

        set_installer_properties( package );

        package->ui_level = gUILevel;
        len = sprintfW( uilevel, fmtW, gUILevel & INSTALLUILEVEL_MASK );
        msi_set_property( package->db, szUILevel, uilevel, len );

        r = msi_load_suminfo_properties( package );
        if (r != ERROR_SUCCESS)
        {
            msiobj_release( &package->hdr );
            return NULL;
        }

        if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
            msi_load_admin_properties( package );

        package->log_file = INVALID_HANDLE_VALUE;
        package->script = SCRIPT_NONE;
    }
    return package;
}

UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename )
{
    LPINTERNET_CACHE_ENTRY_INFOW cache_entry;
    DWORD size = 0;
    HRESULT hr;

    /* call will always fail, because size is 0,
     * but will return ERROR_FILE_NOT_FOUND first
     * if the file doesn't exist
     */
    GetUrlCacheEntryInfoW( szUrl, NULL, &size );
    if ( GetLastError() != ERROR_FILE_NOT_FOUND )
    {
        cache_entry = msi_alloc( size );
        if ( !GetUrlCacheEntryInfoW( szUrl, cache_entry, &size ) )
        {
            UINT error = GetLastError();
            msi_free( cache_entry );
            return error;
        }

        lstrcpyW( filename, cache_entry->lpszLocalFileName );
        msi_free( cache_entry );
        return ERROR_SUCCESS;
    }

    hr = URLDownloadToCacheFileW( NULL, szUrl, filename, MAX_PATH, 0, NULL );
    if ( FAILED(hr) )
    {
        WARN("failed to download %s to cache file\n", debugstr_w(szUrl));
        return ERROR_FUNCTION_FAILED;
    }

    return ERROR_SUCCESS;
}

UINT msi_create_empty_local_file( LPWSTR path, LPCWSTR suffix )
{
    static const WCHAR szInstaller[] = {
        '\\','I','n','s','t','a','l','l','e','r','\\',0};
    static const WCHAR fmt[] = {'%','x',0};
    DWORD time, len, i, offset;
    HANDLE handle;

    time = GetTickCount();
    GetWindowsDirectoryW( path, MAX_PATH );
    strcatW( path, szInstaller );
    CreateDirectoryW( path, NULL );

    len = strlenW(path);
    for (i = 0; i < 0x10000; i++)
    {
        offset = snprintfW( path + len, MAX_PATH - len, fmt, (time + i) & 0xffff );
        memcpy( path + len + offset, suffix, (strlenW( suffix ) + 1) * sizeof(WCHAR) );
        handle = CreateFileW( path, GENERIC_WRITE, 0, NULL,
                              CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
        if (handle != INVALID_HANDLE_VALUE)
        {
            CloseHandle(handle);
            break;
        }
        if (GetLastError() != ERROR_FILE_EXISTS &&
            GetLastError() != ERROR_SHARING_VIOLATION)
            return ERROR_FUNCTION_FAILED;
    }

    return ERROR_SUCCESS;
}

static enum platform parse_platform( const WCHAR *str )
{
    if (!str[0] || !strcmpW( str, szIntel )) return PLATFORM_INTEL;
    else if (!strcmpW( str, szIntel64 )) return PLATFORM_INTEL64;
    else if (!strcmpW( str, szX64 ) || !strcmpW( str, szAMD64 )) return PLATFORM_X64;
    else if (!strcmpW( str, szARM )) return PLATFORM_ARM;
    return PLATFORM_UNKNOWN;
}

static UINT parse_suminfo( MSISUMMARYINFO *si, MSIPACKAGE *package )
{
    WCHAR *template, *p, *q, *platform;
    DWORD i, count;

    package->version = msi_suminfo_get_int32( si, PID_PAGECOUNT );
    TRACE("version: %d\n", package->version);

    template = msi_suminfo_dup_string( si, PID_TEMPLATE );
    if (!template)
        return ERROR_SUCCESS; /* native accepts missing template property */

    TRACE("template: %s\n", debugstr_w(template));

    p = strchrW( template, ';' );
    if (!p)
    {
        WARN("invalid template string %s\n", debugstr_w(template));
        msi_free( template );
        return ERROR_PATCH_PACKAGE_INVALID;
    }
    *p = 0;
    platform = template;
    if ((q = strchrW( platform, ',' ))) *q = 0;
    package->platform = parse_platform( platform );
    while (package->platform == PLATFORM_UNKNOWN && q)
    {
        platform = q + 1;
        if ((q = strchrW( platform, ',' ))) *q = 0;
        package->platform = parse_platform( platform );
    }
    if (package->platform == PLATFORM_UNKNOWN)
    {
        WARN("unknown platform %s\n", debugstr_w(template));
        msi_free( template );
        return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
    }
    p++;
    if (!*p)
    {
        msi_free( template );
        return ERROR_SUCCESS;
    }
    count = 1;
    for (q = p; (q = strchrW( q, ',' )); q++) count++;

    package->langids = msi_alloc( count * sizeof(LANGID) );
    if (!package->langids)
    {
        msi_free( template );
        return ERROR_OUTOFMEMORY;
    }

    i = 0;
    while (*p)
    {
        q = strchrW( p, ',' );
        if (q) *q = 0;
        package->langids[i] = atoiW( p );
        if (!q) break;
        p = q + 1;
        i++;
    }
    package->num_langids = i + 1;

    msi_free( template );
    return ERROR_SUCCESS;
}

static UINT validate_package( MSIPACKAGE *package )
{
    UINT i;

    if (package->platform == PLATFORM_INTEL64)
        return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
#ifndef __arm__
    if (package->platform == PLATFORM_ARM)
        return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
#endif
    if (package->platform == PLATFORM_X64)
    {
        if (!is_64bit && !is_wow64)
            return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
        if (package->version < 200)
            return ERROR_INSTALL_PACKAGE_INVALID;
    }
    if (!package->num_langids)
    {
        return ERROR_SUCCESS;
    }
    for (i = 0; i < package->num_langids; i++)
    {
        LANGID langid = package->langids[i];

        if (PRIMARYLANGID( langid ) == LANG_NEUTRAL)
        {
            langid = MAKELANGID( PRIMARYLANGID( GetSystemDefaultLangID() ), SUBLANGID( langid ) );
        }
        if (SUBLANGID( langid ) == SUBLANG_NEUTRAL)
        {
            langid = MAKELANGID( PRIMARYLANGID( langid ), SUBLANGID( GetSystemDefaultLangID() ) );
        }
        if (IsValidLocale( langid, LCID_INSTALLED ))
            return ERROR_SUCCESS;
    }
    return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
}

static WCHAR *get_product_code( MSIDATABASE *db )
{
    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ',
        'F','R','O','M',' ','`','P','r','o','p','e','r','t','y','`',' ',
        'W','H','E','R','E',' ','`','P','r','o','p','e','r','t','y','`','=',
        '\'','P','r','o','d','u','c','t','C','o','d','e','\'',0};
    MSIQUERY *view;
    MSIRECORD *rec;
    WCHAR *ret = NULL;

    if (MSI_DatabaseOpenViewW( db, query, &view ) != ERROR_SUCCESS)
    {
        return NULL;
    }
    if (MSI_ViewExecute( view, 0 ) != ERROR_SUCCESS)
    {
        MSI_ViewClose( view );
        msiobj_release( &view->hdr );
        return NULL;
    }
    if (MSI_ViewFetch( view, &rec ) == ERROR_SUCCESS)
    {
        ret = strdupW( MSI_RecordGetString( rec, 1 ) );
        msiobj_release( &rec->hdr );
    }
    MSI_ViewClose( view );
    msiobj_release( &view->hdr );
    return ret;
}

static UINT get_registered_local_package( const WCHAR *product, const WCHAR *package, WCHAR *localfile )
{
    MSIINSTALLCONTEXT context;
    HKEY product_key, props_key;
    WCHAR *registered_package = NULL, unsquashed[GUID_SIZE];
    UINT r;

    r = msi_locate_product( product, &context );
    if (r != ERROR_SUCCESS)
        return r;

    r = MSIREG_OpenProductKey( product, NULL, context, &product_key, FALSE );
    if (r != ERROR_SUCCESS)
        return r;

    r = MSIREG_OpenInstallProps( product, context, NULL, &props_key, FALSE );
    if (r != ERROR_SUCCESS)
    {
        RegCloseKey( product_key );
        return r;
    }
    r = ERROR_FUNCTION_FAILED;
    registered_package = msi_reg_get_val_str( product_key, INSTALLPROPERTY_PACKAGECODEW );
    if (!registered_package)
        goto done;

    unsquash_guid( registered_package, unsquashed );
    if (!strcmpiW( package, unsquashed ))
    {
        WCHAR *filename = msi_reg_get_val_str( props_key, INSTALLPROPERTY_LOCALPACKAGEW );
        if (!filename)
            goto done;

        strcpyW( localfile, filename );
        msi_free( filename );
        r = ERROR_SUCCESS;
    }
done:
    msi_free( registered_package );
    RegCloseKey( props_key );
    RegCloseKey( product_key );
    return r;
}

static WCHAR *get_package_code( MSIDATABASE *db )
{
    WCHAR *ret;
    MSISUMMARYINFO *si;
    UINT r;

    r = msi_get_suminfo( db->storage, 0, &si );
    if (r != ERROR_SUCCESS)
    {
        r = msi_get_db_suminfo( db, 0, &si );
        if (r != ERROR_SUCCESS)
        {
            WARN("failed to load summary info %u\n", r);
            return NULL;
        }
    }
    ret = msi_suminfo_dup_string( si, PID_REVNUMBER );
    msiobj_release( &si->hdr );
    return ret;
}

static UINT get_local_package( const WCHAR *filename, WCHAR *localfile )
{
    WCHAR *product_code, *package_code;
    MSIDATABASE *db;
    UINT r;

    if ((r = MSI_OpenDatabaseW( filename, MSIDBOPEN_READONLY, &db )) != ERROR_SUCCESS)
    {
        if (GetFileAttributesW( filename ) == INVALID_FILE_ATTRIBUTES)
            return ERROR_FILE_NOT_FOUND;
        return r;
    }
    if (!(product_code = get_product_code( db )))
    {
        msiobj_release( &db->hdr );
        return ERROR_INSTALL_PACKAGE_INVALID;
    }
    if (!(package_code = get_package_code( db )))
    {
        msi_free( product_code );
        msiobj_release( &db->hdr );
        return ERROR_INSTALL_PACKAGE_INVALID;
    }
    r = get_registered_local_package( product_code, package_code, localfile );
    msi_free( package_code );
    msi_free( product_code );
    msiobj_release( &db->hdr );
    return r;
}

UINT msi_set_original_database_property( MSIDATABASE *db, const WCHAR *package )
{
    UINT r;

    if (UrlIsW( package, URLIS_URL ))
        r = msi_set_property( db, szOriginalDatabase, package, -1 );
    else if (package[0] == '#')
        r = msi_set_property( db, szOriginalDatabase, db->path, -1 );
    else
    {
        DWORD len;
        WCHAR *path;

        if (!(len = GetFullPathNameW( package, 0, NULL, NULL ))) return GetLastError();
        if (!(path = msi_alloc( len * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
        len = GetFullPathNameW( package, len, path, NULL );
        r = msi_set_property( db, szOriginalDatabase, path, len );
        msi_free( path );
    }
    return r;
}

UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
{
    static const WCHAR dotmsi[] = {'.','m','s','i',0};
    MSIDATABASE *db;
    MSIPACKAGE *package;
    MSIHANDLE handle;
    MSIRECORD *data_row, *info_row;
    LPWSTR ptr, base_url = NULL;
    UINT r;
    WCHAR localfile[MAX_PATH], cachefile[MAX_PATH];
    LPCWSTR file = szPackage;
    DWORD index = 0;
    MSISUMMARYINFO *si;
    BOOL delete_on_close = FALSE;
    LPWSTR productname;
    WCHAR *info_template;

    TRACE("%s %p\n", debugstr_w(szPackage), pPackage);

    MSI_ProcessMessage(NULL, INSTALLMESSAGE_INITIALIZE, 0);

    localfile[0] = 0;
    if( szPackage[0] == '#' )
    {
        handle = atoiW(&szPackage[1]);
        db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
        if( !db )
        {
            IWineMsiRemoteDatabase *remote_database;

            remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
            if ( !remote_database )
                return ERROR_INVALID_HANDLE;

            IWineMsiRemoteDatabase_Release( remote_database );
            WARN("MsiOpenPackage not allowed during a custom action!\n");

            return ERROR_FUNCTION_FAILED;
        }
    }
    else
    {
        if ( UrlIsW( szPackage, URLIS_URL ) )
        {
            r = msi_download_file( szPackage, cachefile );
            if (r != ERROR_SUCCESS)
                return r;

            file = cachefile;

            base_url = strdupW( szPackage );
            if (!base_url)
                return ERROR_OUTOFMEMORY;

            ptr = strrchrW( base_url, '/' );
            if (ptr) *(ptr + 1) = '\0';
        }
        r = get_local_package( file, localfile );
        if (r != ERROR_SUCCESS || GetFileAttributesW( localfile ) == INVALID_FILE_ATTRIBUTES)
        {
            r = msi_create_empty_local_file( localfile, dotmsi );
            if (r != ERROR_SUCCESS)
            {
                msi_free ( base_url );
                return r;
            }

            if (!CopyFileW( file, localfile, FALSE ))
            {
                r = GetLastError();
                WARN("unable to copy package %s to %s (%u)\n", debugstr_w(file), debugstr_w(localfile), r);
                DeleteFileW( localfile );
                msi_free ( base_url );
                return r;
            }
            delete_on_close = TRUE;
        }
        TRACE("opening package %s\n", debugstr_w( localfile ));
        r = MSI_OpenDatabaseW( localfile, MSIDBOPEN_TRANSACT, &db );
        if (r != ERROR_SUCCESS)
        {
            msi_free ( base_url );
            return r;
        }
    }
    package = MSI_CreatePackage( db, base_url );
    msi_free( base_url );
    msiobj_release( &db->hdr );
    if (!package) return ERROR_INSTALL_PACKAGE_INVALID;
    package->localfile = strdupW( localfile );
    package->delete_on_close = delete_on_close;

    r = msi_get_suminfo( db->storage, 0, &si );
    if (r != ERROR_SUCCESS)
    {
        r = msi_get_db_suminfo( db, 0, &si );
        if (r != ERROR_SUCCESS)
        {
            WARN("failed to load summary info\n");
            msiobj_release( &package->hdr );
            return ERROR_INSTALL_PACKAGE_INVALID;
        }
    }
    r = parse_suminfo( si, package );
    msiobj_release( &si->hdr );
    if (r != ERROR_SUCCESS)
    {
        WARN("failed to parse summary info %u\n", r);
        msiobj_release( &package->hdr );
        return r;
    }
    r = validate_package( package );
    if (r != ERROR_SUCCESS)
    {
        msiobj_release( &package->hdr );
        return r;
    }
    msi_set_property( package->db, szDatabase, db->path, -1 );
    set_installed_prop( package );
    msi_set_context( package );

    while (1)
    {
        WCHAR patch_code[GUID_SIZE];
        r = MsiEnumPatchesExW( package->ProductCode, NULL, package->Context,
                               MSIPATCHSTATE_APPLIED, index, patch_code, NULL, NULL, NULL, NULL );
        if (r != ERROR_SUCCESS)
            break;

        TRACE("found registered patch %s\n", debugstr_w(patch_code));

        r = msi_apply_registered_patch( package, patch_code );
        if (r != ERROR_SUCCESS)
        {
            ERR("registered patch failed to apply %u\n", r);
            msiobj_release( &package->hdr );
            return r;
        }
        index++;
    }
    if (index) msi_adjust_privilege_properties( package );

    r = msi_set_original_database_property( package->db, szPackage );
    if (r != ERROR_SUCCESS)
    {
        msiobj_release( &package->hdr );
        return r;
    }
    if (gszLogFile)
        package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
                                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

    /* FIXME: when should these messages be sent? */
    data_row = MSI_CreateRecord(3);
    if (!data_row)
	return ERROR_OUTOFMEMORY;
    MSI_RecordSetStringW(data_row, 0, NULL);
    MSI_RecordSetInteger(data_row, 1, 0);
    MSI_RecordSetInteger(data_row, 2, package->num_langids ? package->langids[0] : 0);
    MSI_RecordSetInteger(data_row, 3, msi_get_string_table_codepage(package->db->strings));
    MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_COMMONDATA, data_row);

    info_row = MSI_CreateRecord(0);
    if (!info_row)
    {
	msiobj_release(&data_row->hdr);
	return ERROR_OUTOFMEMORY;
    }
    info_template = msi_get_error_message(package->db, MSIERR_INFO_LOGGINGSTART);
    MSI_RecordSetStringW(info_row, 0, info_template);
    msi_free(info_template);
    MSI_ProcessMessage(package, INSTALLMESSAGE_INFO|MB_ICONHAND, info_row);

    MSI_ProcessMessage(package, INSTALLMESSAGE_COMMONDATA, data_row);

    productname = msi_dup_property(package->db, INSTALLPROPERTY_PRODUCTNAMEW);
    MSI_RecordSetInteger(data_row, 1, 1);
    MSI_RecordSetStringW(data_row, 2, productname);
    MSI_RecordSetStringW(data_row, 3, NULL);
    MSI_ProcessMessage(package, INSTALLMESSAGE_COMMONDATA, data_row);

    msi_free(productname);
    msiobj_release(&info_row->hdr);
    msiobj_release(&data_row->hdr);

    *pPackage = package;
    return ERROR_SUCCESS;
}

UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
{
    MSIPACKAGE *package = NULL;
    UINT ret;

    TRACE("%s %08x %p\n", debugstr_w(szPackage), dwOptions, phPackage );

    if( !szPackage || !phPackage )
        return ERROR_INVALID_PARAMETER;

    if ( !*szPackage )
    {
        FIXME("Should create an empty database and package\n");
        return ERROR_FUNCTION_FAILED;
    }

    if( dwOptions )
        FIXME("dwOptions %08x not supported\n", dwOptions);

    ret = MSI_OpenPackageW( szPackage, &package );
    if( ret == ERROR_SUCCESS )
    {
        *phPackage = alloc_msihandle( &package->hdr );
        if (! *phPackage)
            ret = ERROR_NOT_ENOUGH_MEMORY;
        msiobj_release( &package->hdr );
    }
    else
        MSI_ProcessMessage(NULL, INSTALLMESSAGE_TERMINATE, 0);

    return ret;
}

UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
{
    return MsiOpenPackageExW( szPackage, 0, phPackage );
}

UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
{
    LPWSTR szwPack = NULL;
    UINT ret;

    if( szPackage )
    {
        szwPack = strdupAtoW( szPackage );
        if( !szwPack )
            return ERROR_OUTOFMEMORY;
    }

    ret = MsiOpenPackageExW( szwPack, dwOptions, phPackage );

    msi_free( szwPack );

    return ret;
}

UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
{
    return MsiOpenPackageExA( szPackage, 0, phPackage );
}

MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
{
    MSIPACKAGE *package;
    MSIHANDLE handle = 0;
    IUnknown *remote_unk;
    IWineMsiRemotePackage *remote_package;

    TRACE("(%d)\n",hInstall);

    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
    if( package)
    {
        handle = alloc_msihandle( &package->db->hdr );
        msiobj_release( &package->hdr );
    }
    else if ((remote_unk = msi_get_remote(hInstall)))
    {
        if (IUnknown_QueryInterface(remote_unk, &IID_IWineMsiRemotePackage,
                                        (LPVOID *)&remote_package) == S_OK)
        {
            IWineMsiRemotePackage_GetActiveDatabase(remote_package, &handle);
            IWineMsiRemotePackage_Release(remote_package);
        }
        else
        {
            WARN("remote handle %d is not a package\n", hInstall);
        }
        IUnknown_Release(remote_unk);
    }

    return handle;
}

static INT internal_ui_handler(MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record, LPCWSTR message)
{
    static const WCHAR szActionData[] = {'A','c','t','i','o','n','D','a','t','a',0};
    static const WCHAR szActionText[] = {'A','c','t','i','o','n','T','e','x','t',0};
    static const WCHAR szSetProgress[] = {'S','e','t','P','r','o','g','r','e','s','s',0};
    static const WCHAR szWindows_Installer[] =
        {'W','i','n','d','o','w','s',' ','I','n','s','t','a','l','l','e','r',0};

    if (!package || (package->ui_level & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE)
        return 0;

    /* todo: check if message needs additional styles (topmost/foreground/modality?) */

    switch (eMessageType & 0xff000000)
    {
    case INSTALLMESSAGE_FATALEXIT:
    case INSTALLMESSAGE_ERROR:
    case INSTALLMESSAGE_OUTOFDISKSPACE:
        if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
        if (!(eMessageType & MB_ICONMASK))
            eMessageType |= MB_ICONEXCLAMATION;
        return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
    case INSTALLMESSAGE_WARNING:
        if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
        if (!(eMessageType & MB_ICONMASK))
            eMessageType |= MB_ICONASTERISK;
        return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
    case INSTALLMESSAGE_USER:
        if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
        if (!(eMessageType & MB_ICONMASK))
            eMessageType |= MB_USERICON;
        return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
    case INSTALLMESSAGE_INFO:
    case INSTALLMESSAGE_INITIALIZE:
    case INSTALLMESSAGE_TERMINATE:
    case INSTALLMESSAGE_INSTALLSTART:
    case INSTALLMESSAGE_INSTALLEND:
        return 0;
    case INSTALLMESSAGE_SHOWDIALOG:
    {
        LPWSTR dialog = msi_dup_record_field(record, 0);
        INT rc = ACTION_DialogBox(package, dialog);
        msi_free(dialog);
        return rc;
    }
    case INSTALLMESSAGE_ACTIONSTART:
    {
        LPWSTR deformatted;
        MSIRECORD *uirow = MSI_CreateRecord(1);
        if (!uirow) return -1;
        deformat_string(package, MSI_RecordGetString(record, 2), &deformatted);
        MSI_RecordSetStringW(uirow, 1, deformatted);
        msi_event_fire(package, szActionText, uirow);

        msi_free(deformatted);
        msiobj_release(&uirow->hdr);
        return 1;
    }
    case INSTALLMESSAGE_ACTIONDATA:
    {
        MSIRECORD *uirow = MSI_CreateRecord(1);
        if (!uirow) return -1;
        MSI_RecordSetStringW(uirow, 1, message);
        msi_event_fire(package, szActionData, uirow);
        msiobj_release(&uirow->hdr);

        if (package->action_progress_increment)
        {
            uirow = MSI_CreateRecord(2);
            if (!uirow) return -1;
            MSI_RecordSetInteger(uirow, 1, 2);
            MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
            msi_event_fire(package, szSetProgress, uirow);
            msiobj_release(&uirow->hdr);
        }
        return 1;
    }
    case INSTALLMESSAGE_PROGRESS:
        msi_event_fire(package, szSetProgress, record);
        return 1;
    case INSTALLMESSAGE_COMMONDATA:
        switch (MSI_RecordGetInteger(record, 1))
        {
        case 0:
        case 1:
            /* do nothing */
            return 0;
        default:
            /* fall through */
            ;
        }
    default:
        FIXME("internal UI not implemented for message 0x%08x (UI level = %x)\n", eMessageType, package->ui_level);
        return 0;
    }
}

static const WCHAR szActionNotFound[] = {'D','E','B','U','G',':',' ','E','r','r','o','r',' ','[','1',']',':',' ',' ','A','c','t','i','o','n',' ','n','o','t',' ','f','o','u','n','d',':',' ','[','2',']',0};

static const struct
{
    int id;
    const WCHAR *text;
}
internal_errors[] =
{
    {2726, szActionNotFound},
    {0}
};

static LPCWSTR get_internal_error_message(int error)
{
    int i = 0;

    while (internal_errors[i].id != 0)
    {
        if (internal_errors[i].id == error)
            return internal_errors[i].text;
        i++;
    }

    FIXME("missing error message %d\n", error);
    return NULL;
}

/* Returned string must be freed */
LPWSTR msi_get_error_message(MSIDATABASE *db, int error)
{
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ',
         'F','R','O','M',' ','`','E','r','r','o','r','`',' ','W','H','E','R','E',' ',
         '`','E','r','r','o','r','`',' ','=',' ','%','i',0};
    MSIRECORD *record;
    LPWSTR ret = NULL;

    if ((record = MSI_QueryGetRecord(db, query, error)))
    {
        ret = msi_dup_record_field(record, 1);
        msiobj_release(&record->hdr);
    }
    else if (error < 2000)
    {
        int len = LoadStringW(msi_hInstance, IDS_ERROR_BASE + error, (LPWSTR) &ret, 0);
        if (len)
        {
            ret = msi_alloc((len + 1) * sizeof(WCHAR));
            LoadStringW(msi_hInstance, IDS_ERROR_BASE + error, ret, len + 1);
        }
        else
            ret = NULL;
    }

    return ret;
}

INT MSI_ProcessMessageVerbatim(MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record)
{
    LPWSTR message = {0};
    DWORD len;
    DWORD log_type = 1 << (eMessageType >> 24);
    UINT res;
    INT rc = 0;
    char *msg;

    TRACE("%x\n", eMessageType);
    if (TRACE_ON(msi)) dump_record(record);

    if (!package || !record)
        message = NULL;
    else {
        res = MSI_FormatRecordW(package, record, message, &len);
        if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
            return res;
        len++;
        message = msi_alloc(len * sizeof(WCHAR));
        if (!message) return ERROR_OUTOFMEMORY;
        MSI_FormatRecordW(package, record, message, &len);
    }

    /* convert it to ASCII */
    len = WideCharToMultiByte( CP_ACP, 0, message, -1, NULL, 0, NULL, NULL );
    msg = msi_alloc( len );
    WideCharToMultiByte( CP_ACP, 0, message, -1, msg, len, NULL, NULL );

    if (gUIHandlerRecord && (gUIFilterRecord & log_type))
    {
        MSIHANDLE rec = alloc_msihandle(&record->hdr);
        TRACE("Calling UI handler %p(pvContext=%p, iMessageType=%08x, hRecord=%u)\n",
              gUIHandlerRecord, gUIContextRecord, eMessageType, rec);
        rc = gUIHandlerRecord( gUIContextRecord, eMessageType, rec );
        MsiCloseHandle( rec );
    }
    if (!rc && gUIHandlerW && (gUIFilter & log_type))
    {
        TRACE("Calling UI handler %p(pvContext=%p, iMessageType=%08x, szMessage=%s)\n",
              gUIHandlerW, gUIContext, eMessageType, debugstr_w(message));
        rc = gUIHandlerW( gUIContext, eMessageType, message );
    }
    else if (!rc && gUIHandlerA && (gUIFilter & log_type))
    {
        TRACE("Calling UI handler %p(pvContext=%p, iMessageType=%08x, szMessage=%s)\n",
              gUIHandlerA, gUIContext, eMessageType, debugstr_a(msg));
        rc = gUIHandlerA( gUIContext, eMessageType, msg );
    }

    if (!rc)
        rc = internal_ui_handler(package, eMessageType, record, message);

    if (!rc && package && package->log_file != INVALID_HANDLE_VALUE &&
        (eMessageType & 0xff000000) != INSTALLMESSAGE_PROGRESS)
    {
        DWORD written;
        WriteFile( package->log_file, msg, len - 1, &written, NULL );
        WriteFile( package->log_file, "\n", 1, &written, NULL );
    }
    msi_free( msg );
    msi_free( message );

    return rc;
}

INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record )
{
    switch (eMessageType & 0xff000000)
    {
    case INSTALLMESSAGE_FATALEXIT:
    case INSTALLMESSAGE_ERROR:
    case INSTALLMESSAGE_WARNING:
    case INSTALLMESSAGE_USER:
    case INSTALLMESSAGE_INFO:
    case INSTALLMESSAGE_OUTOFDISKSPACE:
        if (MSI_RecordGetInteger(record, 1) != MSI_NULL_INTEGER)
        {
            /* error message */

            LPWSTR template;
            LPWSTR template_rec = NULL, template_prefix = NULL;
            int error = MSI_RecordGetInteger(record, 1);

            if (MSI_RecordIsNull(record, 0))
            {
                if (error >= 32)
                {
                    template_rec = msi_get_error_message(package->db, error);

                    if (!template_rec && error >= 2000)
                    {
                        /* internal error, not localized */
                        if ((template_rec = (LPWSTR) get_internal_error_message(error)))
                        {
                            MSI_RecordSetStringW(record, 0, template_rec);
                            MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_INFO, record);
                        }
                        template_rec = msi_get_error_message(package->db, MSIERR_INSTALLERROR);
                        MSI_RecordSetStringW(record, 0, template_rec);
                        MSI_ProcessMessageVerbatim(package, eMessageType, record);
                        msi_free(template_rec);
                        return 0;
                    }
                }
            }
            else
                template_rec = msi_dup_record_field(record, 0);

            template_prefix = msi_get_error_message(package->db, eMessageType >> 24);
            if (!template_prefix) template_prefix = strdupW(szEmpty);

            if (!template_rec)
            {
                /* always returns 0 */
                MSI_RecordSetStringW(record, 0, template_prefix);
                MSI_ProcessMessageVerbatim(package, eMessageType, record);
                msi_free(template_prefix);
                return 0;
            }

            template = msi_alloc((strlenW(template_rec) + strlenW(template_prefix) + 1) * sizeof(WCHAR));
            if (!template) return ERROR_OUTOFMEMORY;

            strcpyW(template, template_prefix);
            strcatW(template, template_rec);
            MSI_RecordSetStringW(record, 0, template);

            msi_free(template_prefix);
            msi_free(template_rec);
            msi_free(template);
        }
        break;
    case INSTALLMESSAGE_ACTIONSTART:
    {
        WCHAR *template = msi_get_error_message(package->db, MSIERR_ACTIONSTART);
        MSI_RecordSetStringW(record, 0, template);
        msi_free(template);

        msi_free(package->LastAction);
        msi_free(package->LastActionTemplate);
        package->LastAction = msi_dup_record_field(record, 1);
        if (!package->LastAction) package->LastAction = strdupW(szEmpty);
        package->LastActionTemplate = msi_dup_record_field(record, 3);
        break;
    }
    case INSTALLMESSAGE_ACTIONDATA:
        if (package->LastAction && package->LastActionTemplate)
        {
            static const WCHAR template_s[] =
                {'{','{','%','s',':',' ','}','}','%','s',0};
            WCHAR *template;

            template = msi_alloc((strlenW(package->LastAction) + strlenW(package->LastActionTemplate) + 7) * sizeof(WCHAR));
            if (!template) return ERROR_OUTOFMEMORY;
            sprintfW(template, template_s, package->LastAction, package->LastActionTemplate);
            MSI_RecordSetStringW(record, 0, template);
            msi_free(template);
        }
        break;
    case INSTALLMESSAGE_COMMONDATA:
    {
        WCHAR *template = msi_get_error_message(package->db, MSIERR_COMMONDATA);
        MSI_RecordSetStringW(record, 0, template);
        msi_free(template);
    }
    break;
    }

    return MSI_ProcessMessageVerbatim(package, eMessageType, record);
}

INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
                              MSIHANDLE hRecord)
{
    UINT ret = ERROR_INVALID_HANDLE;
    MSIPACKAGE *package = NULL;
    MSIRECORD *record = NULL;

    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_INITIALIZE ||
        (eMessageType & 0xff000000) == INSTALLMESSAGE_TERMINATE)
        return -1;

    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_COMMONDATA &&
        MsiRecordGetInteger(hRecord, 1) != 2)
        return -1;

    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
    if( !package )
    {
        HRESULT hr;
        IWineMsiRemotePackage *remote_package;

        remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
        if (!remote_package)
            return ERROR_INVALID_HANDLE;

        hr = IWineMsiRemotePackage_ProcessMessage( remote_package, eMessageType, hRecord );

        IWineMsiRemotePackage_Release( remote_package );

        if (FAILED(hr))
        {
            if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
                return HRESULT_CODE(hr);

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
    if( !record )
        goto out;

    ret = MSI_ProcessMessage( package, eMessageType, record );

out:
    msiobj_release( &package->hdr );
    if( record )
        msiobj_release( &record->hdr );

    return ret;
}

/* property code */

UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue )
{
    LPWSTR szwName = NULL, szwValue = NULL;
    UINT r = ERROR_OUTOFMEMORY;

    szwName = strdupAtoW( szName );
    if( szName && !szwName )
        goto end;

    szwValue = strdupAtoW( szValue );
    if( szValue && !szwValue )
        goto end;

    r = MsiSetPropertyW( hInstall, szwName, szwValue);

end:
    msi_free( szwName );
    msi_free( szwValue );

    return r;
}

void msi_reset_folders( MSIPACKAGE *package, BOOL source )
{
    MSIFOLDER *folder;

    LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
    {
        if ( source )
        {
            msi_free( folder->ResolvedSource );
            folder->ResolvedSource = NULL;
        }
        else
        {
            msi_free( folder->ResolvedTarget );
            folder->ResolvedTarget = NULL;
        }
    }
}

UINT msi_set_property( MSIDATABASE *db, const WCHAR *name, const WCHAR *value, int len )
{
    static const WCHAR insert_query[] = {
        'I','N','S','E','R','T',' ','I','N','T','O',' ',
        '`','_','P','r','o','p','e','r','t','y','`',' ',
        '(','`','_','P','r','o','p','e','r','t','y','`',',','`','V','a','l','u','e','`',')',' ',
        'V','A','L','U','E','S',' ','(','?',',','?',')',0};
    static const WCHAR update_query[] = {
        'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ',
        'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ','W','H','E','R','E',' ',
        '`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
    static const WCHAR delete_query[] = {
        'D','E','L','E','T','E',' ','F','R','O','M',' ',
        '`','_','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ',
        '`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
    MSIQUERY *view;
    MSIRECORD *row = NULL;
    DWORD sz = 0;
    WCHAR query[1024];
    UINT rc;

    TRACE("%p %s %s %d\n", db, debugstr_w(name), debugstr_wn(value, len), len);

    if (!name)
        return ERROR_INVALID_PARAMETER;

    /* this one is weird... */
    if (!name[0])
        return value ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS;

    if (value && len < 0) len = strlenW( value );

    rc = msi_get_property( db, name, 0, &sz );
    if (!value || (!*value && !len))
    {
        sprintfW( query, delete_query, name );
    }
    else if (rc == ERROR_MORE_DATA || rc == ERROR_SUCCESS)
    {
        sprintfW( query, update_query, name );
        row = MSI_CreateRecord(1);
        msi_record_set_string( row, 1, value, len );
    }
    else
    {
        strcpyW( query, insert_query );
        row = MSI_CreateRecord(2);
        msi_record_set_string( row, 1, name, -1 );
        msi_record_set_string( row, 2, value, len );
    }

    rc = MSI_DatabaseOpenViewW(db, query, &view);
    if (rc == ERROR_SUCCESS)
    {
        rc = MSI_ViewExecute(view, row);
        MSI_ViewClose(view);
        msiobj_release(&view->hdr);
    }
    if (row) msiobj_release(&row->hdr);
    return rc;
}

UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
{
    MSIPACKAGE *package;
    UINT ret;

    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
    if( !package )
    {
        HRESULT hr;
        BSTR name = NULL, value = NULL;
        IWineMsiRemotePackage *remote_package;

        remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
        if (!remote_package)
            return ERROR_INVALID_HANDLE;

        name = SysAllocString( szName );
        value = SysAllocString( szValue );
        if ((!name && szName) || (!value && szValue))
        {
            SysFreeString( name );
            SysFreeString( value );
            IWineMsiRemotePackage_Release( remote_package );
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_SetProperty( remote_package, name, value );

        SysFreeString( name );
        SysFreeString( value );
        IWineMsiRemotePackage_Release( remote_package );

        if (FAILED(hr))
        {
            if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
                return HRESULT_CODE(hr);

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    ret = msi_set_property( package->db, szName, szValue, -1 );
    if (ret == ERROR_SUCCESS && !strcmpW( szName, szSourceDir ))
        msi_reset_folders( package, TRUE );

    msiobj_release( &package->hdr );
    return ret;
}

static MSIRECORD *msi_get_property_row( MSIDATABASE *db, LPCWSTR name )
{
    static const WCHAR query[]= {
        'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ',
        'F','R','O','M',' ' ,'`','_','P','r','o','p','e','r','t','y','`',' ',
        'W','H','E','R','E',' ' ,'`','_','P','r','o','p','e','r','t','y','`','=','?',0};
    MSIRECORD *rec, *row = NULL;
    MSIQUERY *view;
    UINT r;

    static const WCHAR szDate[] = {'D','a','t','e',0};
    static const WCHAR szTime[] = {'T','i','m','e',0};
    WCHAR *buffer;
    int length;

    if (!name || !*name)
        return NULL;

    if (!strcmpW(name, szDate))
    {
        length = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, NULL, 0);
        if (!length)
            return NULL;
        buffer = msi_alloc(length * sizeof(WCHAR));
        GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, buffer, length);

        row = MSI_CreateRecord(1);
        if (!row)
            return NULL;
        MSI_RecordSetStringW(row, 1, buffer);
        msi_free(buffer);
        return row;
    }
    else if (!strcmpW(name, szTime))
    {
        length = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER, NULL, NULL, NULL, 0);
        if (!length)
            return NULL;
        buffer = msi_alloc(length * sizeof(WCHAR));
        GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER, NULL, NULL, buffer, length);

        row = MSI_CreateRecord(1);
        if (!row)
            return NULL;
        MSI_RecordSetStringW(row, 1, buffer);
        msi_free(buffer);
        return row;
    }

    rec = MSI_CreateRecord(1);
    if (!rec)
        return NULL;

    MSI_RecordSetStringW(rec, 1, name);

    r = MSI_DatabaseOpenViewW(db, query, &view);
    if (r == ERROR_SUCCESS)
    {
        MSI_ViewExecute(view, rec);
        MSI_ViewFetch(view, &row);
        MSI_ViewClose(view);
        msiobj_release(&view->hdr);
    }
    msiobj_release(&rec->hdr);
    return row;
}

/* internal function, not compatible with MsiGetPropertyW */
UINT msi_get_property( MSIDATABASE *db, LPCWSTR szName,
                       LPWSTR szValueBuf, LPDWORD pchValueBuf )
{
    MSIRECORD *row;
    UINT rc = ERROR_FUNCTION_FAILED;

    TRACE("%p %s %p %p\n", db, debugstr_w(szName), szValueBuf, pchValueBuf);

    row = msi_get_property_row( db, szName );

    if (*pchValueBuf > 0)
        szValueBuf[0] = 0;

    if (row)
    {
        rc = MSI_RecordGetStringW(row, 1, szValueBuf, pchValueBuf);
        msiobj_release(&row->hdr);
    }

    if (rc == ERROR_SUCCESS)
        TRACE("returning %s for property %s\n", debugstr_wn(szValueBuf, *pchValueBuf),
            debugstr_w(szName));
    else if (rc == ERROR_MORE_DATA)
        TRACE("need %d sized buffer for %s\n", *pchValueBuf,
            debugstr_w(szName));
    else
    {
        *pchValueBuf = 0;
        TRACE("property %s not found\n", debugstr_w(szName));
    }

    return rc;
}

LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop)
{
    DWORD sz = 0;
    LPWSTR str;
    UINT r;

    r = msi_get_property(db, prop, NULL, &sz);
    if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
        return NULL;

    sz++;
    str = msi_alloc(sz * sizeof(WCHAR));
    r = msi_get_property(db, prop, str, &sz);
    if (r != ERROR_SUCCESS)
    {
        msi_free(str);
        str = NULL;
    }

    return str;
}

int msi_get_property_int( MSIDATABASE *db, LPCWSTR prop, int def )
{
    LPWSTR str = msi_dup_property( db, prop );
    int val = str ? atoiW(str) : def;
    msi_free(str);
    return val;
}

static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name,
                             awstring *szValueBuf, LPDWORD pchValueBuf )
{
    MSIPACKAGE *package;
    MSIRECORD *row = NULL;
    UINT r = ERROR_FUNCTION_FAILED;
    LPCWSTR val = NULL;
    DWORD len = 0;

    TRACE("%u %s %p %p\n", handle, debugstr_w(name),
          szValueBuf->str.w, pchValueBuf );

    if (!name)
        return ERROR_INVALID_PARAMETER;

    package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE );
    if (!package)
    {
        HRESULT hr;
        IWineMsiRemotePackage *remote_package;
        LPWSTR value = NULL;
        BSTR bname;

        remote_package = (IWineMsiRemotePackage *)msi_get_remote( handle );
        if (!remote_package)
            return ERROR_INVALID_HANDLE;

        bname = SysAllocString( name );
        if (!bname)
        {
            IWineMsiRemotePackage_Release( remote_package );
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_GetProperty( remote_package, bname, NULL, &len );
        if (FAILED(hr))
            goto done;

        len++;
        value = msi_alloc(len * sizeof(WCHAR));
        if (!value)
        {
            r = ERROR_OUTOFMEMORY;
            goto done;
        }

        hr = IWineMsiRemotePackage_GetProperty( remote_package, bname, value, &len );
        if (FAILED(hr))
            goto done;

        r = msi_strcpy_to_awstring( value, len, szValueBuf, pchValueBuf );

        /* Bug required by Adobe installers */
        if (!szValueBuf->unicode && !szValueBuf->str.a)
            *pchValueBuf *= sizeof(WCHAR);

done:
        IWineMsiRemotePackage_Release(remote_package);
        SysFreeString(bname);
        msi_free(value);

        if (FAILED(hr))
        {
            if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
                return HRESULT_CODE(hr);

            return ERROR_FUNCTION_FAILED;
        }

        return r;
    }

    row = msi_get_property_row( package->db, name );
    if (row)
        val = msi_record_get_string( row, 1, (int *)&len );

    if (!val)
        val = szEmpty;

    r = msi_strcpy_to_awstring( val, len, szValueBuf, pchValueBuf );

    if (row)
        msiobj_release( &row->hdr );
    msiobj_release( &package->hdr );

    return r;
}

UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName,
                             LPSTR szValueBuf, LPDWORD pchValueBuf )
{
    awstring val;
    LPWSTR name;
    UINT r;

    val.unicode = FALSE;
    val.str.a = szValueBuf;

    name = strdupAtoW( szName );
    if (szName && !name)
        return ERROR_OUTOFMEMORY;

    r = MSI_GetProperty( hInstall, name, &val, pchValueBuf );
    msi_free( name );
    return r;
}

UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName,
                             LPWSTR szValueBuf, LPDWORD pchValueBuf )
{
    awstring val;

    val.unicode = TRUE;
    val.str.w = szValueBuf;

    return MSI_GetProperty( hInstall, szName, &val, pchValueBuf );
}

typedef struct _msi_remote_package_impl {
    IWineMsiRemotePackage IWineMsiRemotePackage_iface;
    MSIHANDLE package;
    LONG refs;
} msi_remote_package_impl;

static inline msi_remote_package_impl *impl_from_IWineMsiRemotePackage( IWineMsiRemotePackage *iface )
{
    return CONTAINING_RECORD(iface, msi_remote_package_impl, IWineMsiRemotePackage_iface);
}

static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface,
                REFIID riid,LPVOID *ppobj)
{
    if( IsEqualCLSID( riid, &IID_IUnknown ) ||
        IsEqualCLSID( riid, &IID_IWineMsiRemotePackage ) )
    {
        IWineMsiRemotePackage_AddRef( iface );
        *ppobj = iface;
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI mrp_AddRef( IWineMsiRemotePackage *iface )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );

    return InterlockedIncrement( &This->refs );
}

static ULONG WINAPI mrp_Release( IWineMsiRemotePackage *iface )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    ULONG r;

    r = InterlockedDecrement( &This->refs );
    if (r == 0)
    {
        MsiCloseHandle( This->package );
        msi_free( This );
    }
    return r;
}

static HRESULT WINAPI mrp_SetMsiHandle( IWineMsiRemotePackage *iface, MSIHANDLE handle )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    This->package = handle;
    return S_OK;
}

static HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHANDLE *handle )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    IWineMsiRemoteDatabase *rdb = NULL;
    HRESULT hr;
    MSIHANDLE hdb;

    hr = create_msi_remote_database( NULL, (LPVOID *)&rdb );
    if (FAILED(hr) || !rdb)
    {
        ERR("Failed to create remote database\n");
        return hr;
    }

    hdb = MsiGetActiveDatabase(This->package);

    hr = IWineMsiRemoteDatabase_SetMsiHandle( rdb, hdb );
    if (FAILED(hr))
    {
        ERR("Failed to set the database handle\n");
        return hr;
    }

    *handle = alloc_msi_remote_handle( (IUnknown *)rdb );
    return S_OK;
}

static HRESULT WINAPI mrp_GetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR value, DWORD *size )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiGetPropertyW(This->package, property, value, size);
    if (r != ERROR_SUCCESS) return HRESULT_FROM_WIN32(r);
    return S_OK;
}

static HRESULT WINAPI mrp_SetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR value )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiSetPropertyW(This->package, property, value);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_ProcessMessage( IWineMsiRemotePackage *iface, INSTALLMESSAGE message, MSIHANDLE record )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiProcessMessage(This->package, message, record);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_DoAction( IWineMsiRemotePackage *iface, BSTR action )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiDoActionW(This->package, action);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_Sequence( IWineMsiRemotePackage *iface, BSTR table, int sequence )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiSequenceW(This->package, table, sequence);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_GetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value, DWORD *size )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiGetTargetPathW(This->package, folder, value, size);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_SetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value)
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiSetTargetPathW(This->package, folder, value);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_GetSourcePath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value, DWORD *size )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiGetSourcePathW(This->package, folder, value, size);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_GetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL *ret )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    *ret = MsiGetMode(This->package, mode);
    return S_OK;
}

static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL state )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiSetMode(This->package, mode, state);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature,
                                    INSTALLSTATE *installed, INSTALLSTATE *action )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiGetFeatureStateW(This->package, feature, installed, action);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_SetFeatureState( IWineMsiRemotePackage *iface, BSTR feature, INSTALLSTATE state )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiSetFeatureStateW(This->package, feature, state);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_GetComponentState( IWineMsiRemotePackage *iface, BSTR component,
                                      INSTALLSTATE *installed, INSTALLSTATE *action )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiGetComponentStateW(This->package, component, installed, action);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_SetComponentState( IWineMsiRemotePackage *iface, BSTR component, INSTALLSTATE state )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiSetComponentStateW(This->package, component, state);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_GetLanguage( IWineMsiRemotePackage *iface, LANGID *language )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    *language = MsiGetLanguage(This->package);
    return S_OK;
}

static HRESULT WINAPI mrp_SetInstallLevel( IWineMsiRemotePackage *iface, int level )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiSetInstallLevel(This->package, level);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_FormatRecord( IWineMsiRemotePackage *iface, MSIHANDLE record,
                                        BSTR *value)
{
    DWORD size = 0;
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiFormatRecordW(This->package, record, NULL, &size);
    if (r == ERROR_SUCCESS)
    {
        *value = SysAllocStringLen(NULL, size);
        if (!*value)
            return E_OUTOFMEMORY;
        size++;
        r = MsiFormatRecordW(This->package, record, *value, &size);
    }
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR condition )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiEvaluateConditionW(This->package, condition);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_GetFeatureCost( IWineMsiRemotePackage *iface, BSTR feature,
                                          INT cost_tree, INSTALLSTATE state, INT *cost )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiGetFeatureCostW(This->package, feature, cost_tree, state, cost);
    return HRESULT_FROM_WIN32(r);
}

static HRESULT WINAPI mrp_EnumComponentCosts( IWineMsiRemotePackage *iface, BSTR component,
                                              DWORD index, INSTALLSTATE state, BSTR drive,
                                              DWORD *buflen, INT *cost, INT *temp )
{
    msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
    UINT r = MsiEnumComponentCostsW(This->package, component, index, state, drive, buflen, cost, temp);
    return HRESULT_FROM_WIN32(r);
}

static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl =
{
    mrp_QueryInterface,
    mrp_AddRef,
    mrp_Release,
    mrp_SetMsiHandle,
    mrp_GetActiveDatabase,
    mrp_GetProperty,
    mrp_SetProperty,
    mrp_ProcessMessage,
    mrp_DoAction,
    mrp_Sequence,
    mrp_GetTargetPath,
    mrp_SetTargetPath,
    mrp_GetSourcePath,
    mrp_GetMode,
    mrp_SetMode,
    mrp_GetFeatureState,
    mrp_SetFeatureState,
    mrp_GetComponentState,
    mrp_SetComponentState,
    mrp_GetLanguage,
    mrp_SetInstallLevel,
    mrp_FormatRecord,
    mrp_EvaluateCondition,
    mrp_GetFeatureCost,
    mrp_EnumComponentCosts
};

HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj )
{
    msi_remote_package_impl* This;

    This = msi_alloc( sizeof *This );
    if (!This)
        return E_OUTOFMEMORY;

    This->IWineMsiRemotePackage_iface.lpVtbl = &msi_remote_package_vtbl;
    This->package = 0;
    This->refs = 1;

    *ppObj = &This->IWineMsiRemotePackage_iface;

    return S_OK;
}

UINT msi_package_add_info(MSIPACKAGE *package, DWORD context, DWORD options,
                          LPCWSTR property, LPWSTR value)
{
    MSISOURCELISTINFO *info;

    LIST_FOR_EACH_ENTRY( info, &package->sourcelist_info, MSISOURCELISTINFO, entry )
    {
        if (!strcmpW( info->value, value )) return ERROR_SUCCESS;
    }

    info = msi_alloc(sizeof(MSISOURCELISTINFO));
    if (!info)
        return ERROR_OUTOFMEMORY;

    info->context = context;
    info->options = options;
    info->property = property;
    info->value = strdupW(value);
    list_add_head(&package->sourcelist_info, &info->entry);

    return ERROR_SUCCESS;
}

UINT msi_package_add_media_disk(MSIPACKAGE *package, DWORD context, DWORD options,
                                DWORD disk_id, LPWSTR volume_label, LPWSTR disk_prompt)
{
    MSIMEDIADISK *disk;

    LIST_FOR_EACH_ENTRY( disk, &package->sourcelist_media, MSIMEDIADISK, entry )
    {
        if (disk->disk_id == disk_id) return ERROR_SUCCESS;
    }

    disk = msi_alloc(sizeof(MSIMEDIADISK));
    if (!disk)
        return ERROR_OUTOFMEMORY;

    disk->context = context;
    disk->options = options;
    disk->disk_id = disk_id;
    disk->volume_label = strdupW(volume_label);
    disk->disk_prompt = strdupW(disk_prompt);
    list_add_head(&package->sourcelist_media, &disk->entry);

    return ERROR_SUCCESS;
}
