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

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winreg.h"
#include "winsvc.h"
#include "odbcinst.h"
#include "wine/debug.h"
#include "msidefs.h"
#include "msipriv.h"
#include "winuser.h"
#include "shlobj.h"
#include "objbase.h"
#include "mscoree.h"
#include "fusion.h"
#include "shlwapi.h"
#include "wine/unicode.h"
#include "winver.h"

#define REG_PROGRESS_VALUE 13200
#define COMPONENT_PROGRESS_VALUE 24000

WINE_DEFAULT_DEBUG_CHANNEL(msi);

/*
 * consts and values used
 */
static const WCHAR c_colon[] = {'C',':','\\',0};

static const WCHAR szCreateFolders[] =
    {'C','r','e','a','t','e','F','o','l','d','e','r','s',0};
static const WCHAR szCostFinalize[] =
    {'C','o','s','t','F','i','n','a','l','i','z','e',0};
static const WCHAR szWriteRegistryValues[] =
    {'W','r','i','t','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};
static const WCHAR szCostInitialize[] =
    {'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};
static const WCHAR szFileCost[] = 
    {'F','i','l','e','C','o','s','t',0};
static const WCHAR szInstallInitialize[] = 
    {'I','n','s','t','a','l','l','I','n','i','t','i','a','l','i','z','e',0};
static const WCHAR szInstallValidate[] = 
    {'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};
static const WCHAR szLaunchConditions[] = 
    {'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};
static const WCHAR szProcessComponents[] = 
    {'P','r','o','c','e','s','s','C','o','m','p','o','n','e','n','t','s',0};
static const WCHAR szRegisterTypeLibraries[] = 
    {'R','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r','i','e','s',0};
static const WCHAR szCreateShortcuts[] = 
    {'C','r','e','a','t','e','S','h','o','r','t','c','u','t','s',0};
static const WCHAR szPublishProduct[] = 
    {'P','u','b','l','i','s','h','P','r','o','d','u','c','t',0};
static const WCHAR szWriteIniValues[] = 
    {'W','r','i','t','e','I','n','i','V','a','l','u','e','s',0};
static const WCHAR szSelfRegModules[] = 
    {'S','e','l','f','R','e','g','M','o','d','u','l','e','s',0};
static const WCHAR szPublishFeatures[] = 
    {'P','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
static const WCHAR szRegisterProduct[] = 
    {'R','e','g','i','s','t','e','r','P','r','o','d','u','c','t',0};
static const WCHAR szInstallExecute[] = 
    {'I','n','s','t','a','l','l','E','x','e','c','u','t','e',0};
static const WCHAR szInstallExecuteAgain[] = 
    {'I','n','s','t','a','l','l','E','x','e','c','u','t','e','A','g','a','i','n',0};
static const WCHAR szInstallFinalize[] = 
    {'I','n','s','t','a','l','l','F','i','n','a','l','i','z','e',0};
static const WCHAR szForceReboot[] = 
    {'F','o','r','c','e','R','e','b','o','o','t',0};
static const WCHAR szResolveSource[] =
    {'R','e','s','o','l','v','e','S','o','u','r','c','e',0};
static const WCHAR szAllocateRegistrySpace[] = 
    {'A','l','l','o','c','a','t','e','R','e','g','i','s','t','r','y','S','p','a','c','e',0};
static const WCHAR szBindImage[] = 
    {'B','i','n','d','I','m','a','g','e',0};
static const WCHAR szDeleteServices[] = 
    {'D','e','l','e','t','e','S','e','r','v','i','c','e','s',0};
static const WCHAR szDisableRollback[] = 
    {'D','i','s','a','b','l','e','R','o','l','l','b','a','c','k',0};
static const WCHAR szExecuteAction[] = 
    {'E','x','e','c','u','t','e','A','c','t','i','o','n',0};
static const WCHAR szInstallAdminPackage[] = 
    {'I','n','s','t','a','l','l','A','d','m','i','n','P','a','c','k','a','g','e',0};
static const WCHAR szInstallSFPCatalogFile[] = 
    {'I','n','s','t','a','l','l','S','F','P','C','a','t','a','l','o','g','F','i','l','e',0};
static const WCHAR szIsolateComponents[] = 
    {'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t','s',0};
static const WCHAR szMigrateFeatureStates[] =
    {'M','i','g','r','a','t','e','F','e','a','t','u','r','e','S','t','a','t','e','s',0};
static const WCHAR szMsiPublishAssemblies[] = 
    {'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
static const WCHAR szMsiUnpublishAssemblies[] = 
    {'M','s','i','U','n','p','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
static const WCHAR szInstallODBC[] = 
    {'I','n','s','t','a','l','l','O','D','B','C',0};
static const WCHAR szInstallServices[] = 
    {'I','n','s','t','a','l','l','S','e','r','v','i','c','e','s',0};
static const WCHAR szPatchFiles[] =
    {'P','a','t','c','h','F','i','l','e','s',0};
static const WCHAR szPublishComponents[] = 
    {'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','s',0};
static const WCHAR szRegisterComPlus[] =
    {'R','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
static const WCHAR szRegisterUser[] =
    {'R','e','g','i','s','t','e','r','U','s','e','r',0};
static const WCHAR szRemoveEnvironmentStrings[] =
    {'R','e','m','o','v','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};
static const WCHAR szRemoveExistingProducts[] =
    {'R','e','m','o','v','e','E','x','i','s','t','i','n','g','P','r','o','d','u','c','t','s',0};
static const WCHAR szRemoveFolders[] =
    {'R','e','m','o','v','e','F','o','l','d','e','r','s',0};
static const WCHAR szRemoveIniValues[] =
    {'R','e','m','o','v','e','I','n','i','V','a','l','u','e','s',0};
static const WCHAR szRemoveODBC[] =
    {'R','e','m','o','v','e','O','D','B','C',0};
static const WCHAR szRemoveRegistryValues[] =
    {'R','e','m','o','v','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};
static const WCHAR szRemoveShortcuts[] =
    {'R','e','m','o','v','e','S','h','o','r','t','c','u','t','s',0};
static const WCHAR szRMCCPSearch[] =
    {'R','M','C','C','P','S','e','a','r','c','h',0};
static const WCHAR szScheduleReboot[] =
    {'S','c','h','e','d','u','l','e','R','e','b','o','o','t',0};
static const WCHAR szSelfUnregModules[] =
    {'S','e','l','f','U','n','r','e','g','M','o','d','u','l','e','s',0};
static const WCHAR szSetODBCFolders[] =
    {'S','e','t','O','D','B','C','F','o','l','d','e','r','s',0};
static const WCHAR szStartServices[] =
    {'S','t','a','r','t','S','e','r','v','i','c','e','s',0};
static const WCHAR szStopServices[] =
    {'S','t','o','p','S','e','r','v','i','c','e','s',0};
static const WCHAR szUnpublishComponents[] =
    {'U','n','p','u','b','l','i','s','h', 'C','o','m','p','o','n','e','n','t','s',0};
static const WCHAR szUnpublishFeatures[] =
    {'U','n','p','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
static const WCHAR szUnregisterComPlus[] =
    {'U','n','r','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
static const WCHAR szUnregisterTypeLibraries[] =
    {'U','n','r','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r','i','e','s',0};
static const WCHAR szValidateProductID[] =
    {'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};
static const WCHAR szWriteEnvironmentStrings[] =
    {'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};

/********************************************************
 * helper functions
 ********************************************************/

static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action)
{
    static const WCHAR Query_t[] = 
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','A','c','t','i','o', 'n','T','e','x','t','`',' ',
         'W','H','E','R','E', ' ','`','A','c','t','i','o','n','`',' ','=', 
         ' ','\'','%','s','\'',0};
    MSIRECORD * row;

    row = MSI_QueryGetRecord( package->db, Query_t, action );
    if (!row)
        return;
    MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, row);
    msiobj_release(&row->hdr);
}

static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, 
                          UINT rc)
{
    MSIRECORD * row;
    static const WCHAR template_s[]=
        {'A','c','t','i','o','n',' ','s','t','a','r','t',' ','%','s',':',' ',
         '%','s', '.',0};
    static const WCHAR template_e[]=
        {'A','c','t','i','o','n',' ','e','n','d','e','d',' ','%','s',':',' ',
         '%','s', '.',' ','R','e','t','u','r','n',' ','v','a','l','u','e',' ',
         '%','i','.',0};
    static const WCHAR format[] = 
        {'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
    WCHAR message[1024];
    WCHAR timet[0x100];

    GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
    if (start)
        sprintfW(message,template_s,timet,action);
    else
        sprintfW(message,template_e,timet,action,rc);
    
    row = MSI_CreateRecord(1);
    MSI_RecordSetStringW(row,1,message);
 
    MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
    msiobj_release(&row->hdr);
}

UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine,
                             BOOL preserve_case )
{
    LPCWSTR ptr,ptr2;
    BOOL quote;
    DWORD len;
    LPWSTR prop = NULL, val = NULL;

    if (!szCommandLine)
        return ERROR_SUCCESS;

    ptr = szCommandLine;
       
    while (*ptr)
    {
        if (*ptr==' ')
        {
            ptr++;
            continue;
        }

        TRACE("Looking at %s\n",debugstr_w(ptr));

        ptr2 = strchrW(ptr,'=');
        if (!ptr2)
        {
            ERR("command line contains unknown string : %s\n", debugstr_w(ptr));
            break;
        }
 
        quote = FALSE;

        len = ptr2-ptr;
        prop = msi_alloc((len+1)*sizeof(WCHAR));
        memcpy(prop,ptr,len*sizeof(WCHAR));
        prop[len]=0;

        if (!preserve_case)
            struprW(prop);

        ptr2++;
       
        len = 0; 
        ptr = ptr2; 
        while (*ptr && (quote || (!quote && *ptr!=' ')))
        {
            if (*ptr == '"')
                quote = !quote;
            ptr++;
            len++;
        }
       
        if (*ptr2=='"')
        {
            ptr2++;
            len -= 2;
        }
        val = msi_alloc((len+1)*sizeof(WCHAR));
        memcpy(val,ptr2,len*sizeof(WCHAR));
        val[len] = 0;

        if (lstrlenW(prop) > 0)
        {
            UINT r = msi_set_property( package->db, prop, val );

            TRACE("Found commandline property (%s) = (%s)\n", 
                   debugstr_w(prop), debugstr_w(val));

            if (r == ERROR_SUCCESS && !strcmpW( prop, cszSourceDir ))
                msi_reset_folders( package, TRUE );
        }
        msi_free(val);
        msi_free(prop);
    }

    return ERROR_SUCCESS;
}


static LPWSTR* msi_split_string( LPCWSTR str, WCHAR sep )
{
    LPCWSTR pc;
    LPWSTR p, *ret = NULL;
    UINT count = 0;

    if (!str)
        return ret;

    /* count the number of substrings */
    for ( pc = str, count = 0; pc; count++ )
    {
        pc = strchrW( pc, sep );
        if (pc)
            pc++;
    }

    /* allocate space for an array of substring pointers and the substrings */
    ret = msi_alloc( (count+1) * sizeof (LPWSTR) +
                     (lstrlenW(str)+1) * sizeof(WCHAR) );
    if (!ret)
        return ret;

    /* copy the string and set the pointers */
    p = (LPWSTR) &ret[count+1];
    lstrcpyW( p, str );
    for( count = 0; (ret[count] = p); count++ )
    {
        p = strchrW( p, sep );
        if (p)
            *p++ = 0;
    }

    return ret;
}

static UINT msi_check_transform_applicable( MSIPACKAGE *package, IStorage *patch )
{
    static const WCHAR szSystemLanguageID[] =
        { 'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0 };

    LPWSTR prod_code, patch_product, langid = NULL, template = NULL;
    UINT ret = ERROR_FUNCTION_FAILED;

    prod_code = msi_dup_property( package->db, szProductCode );
    patch_product = msi_get_suminfo_product( patch );

    TRACE("db = %s patch = %s\n", debugstr_w(prod_code), debugstr_w(patch_product));

    if ( strstrW( patch_product, prod_code ) )
    {
        MSISUMMARYINFO *si;
        const WCHAR *p;

        si = MSI_GetSummaryInformationW( patch, 0 );
        if (!si)
        {
            ERR("no summary information!\n");
            goto end;
        }

        template = msi_suminfo_dup_string( si, PID_TEMPLATE );
        if (!template)
        {
            ERR("no template property!\n");
            msiobj_release( &si->hdr );
            goto end;
        }

        if (!template[0])
        {
            ret = ERROR_SUCCESS;
            msiobj_release( &si->hdr );
            goto end;
        }

        langid = msi_dup_property( package->db, szSystemLanguageID );
        if (!langid)
        {
            msiobj_release( &si->hdr );
            goto end;
        }

        p = strchrW( template, ';' );
        if (p && (!strcmpW( p + 1, langid ) || !strcmpW( p + 1, szZero )))
        {
            TRACE("applicable transform\n");
            ret = ERROR_SUCCESS;
        }

        /* FIXME: check platform */

        msiobj_release( &si->hdr );
    }

end:
    msi_free( patch_product );
    msi_free( prod_code );
    msi_free( template );
    msi_free( langid );

    return ret;
}

static UINT msi_apply_substorage_transform( MSIPACKAGE *package,
                                 MSIDATABASE *patch_db, LPCWSTR name )
{
    UINT ret = ERROR_FUNCTION_FAILED;
    IStorage *stg = NULL;
    HRESULT r;

    TRACE("%p %s\n", package, debugstr_w(name) );

    if (*name++ != ':')
    {
        ERR("expected a colon in %s\n", debugstr_w(name));
        return ERROR_FUNCTION_FAILED;
    }

    r = IStorage_OpenStorage( patch_db->storage, name, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg );
    if (SUCCEEDED(r))
    {
        ret = msi_check_transform_applicable( package, stg );
        if (ret == ERROR_SUCCESS)
            msi_table_apply_transform( package->db, stg );
        else
            TRACE("substorage transform %s wasn't applicable\n", debugstr_w(name));
        IStorage_Release( stg );
    }
    else
        ERR("failed to open substorage %s\n", debugstr_w(name));

    return ERROR_SUCCESS;
}

UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
{
    LPWSTR guid_list, *guids, product_code;
    UINT i, ret = ERROR_FUNCTION_FAILED;

    product_code = msi_dup_property( package->db, szProductCode );
    if (!product_code)
    {
        /* FIXME: the property ProductCode should be written into the DB somewhere */
        ERR("no product code to check\n");
        return ERROR_SUCCESS;
    }

    guid_list = msi_suminfo_dup_string( si, PID_TEMPLATE );
    guids = msi_split_string( guid_list, ';' );
    for ( i = 0; guids[i] && ret != ERROR_SUCCESS; i++ )
    {
        if (!lstrcmpW( guids[i], product_code ))
            ret = ERROR_SUCCESS;
    }
    msi_free( guids );
    msi_free( guid_list );
    msi_free( product_code );

    return ret;
}

static UINT msi_set_media_source_prop(MSIPACKAGE *package)
{
    MSIQUERY *view;
    MSIRECORD *rec = NULL;
    LPWSTR patch;
    LPCWSTR prop;
    UINT r;

    static const WCHAR query[] = {'S','E','L','E','C','T',' ',
        '`','S','o','u','r','c','e','`',' ','F','R','O','M',' ',
        '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
        '`','S','o','u','r','c','e','`',' ','I','S',' ',
        'N','O','T',' ','N','U','L','L',0};

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

    r = MSI_ViewExecute(view, 0);
    if (r != ERROR_SUCCESS)
        goto done;

    if (MSI_ViewFetch(view, &rec) == ERROR_SUCCESS)
    {
        prop = MSI_RecordGetString(rec, 1);
        patch = msi_dup_property(package->db, szPatch);
        msi_set_property(package->db, prop, patch);
        msi_free(patch);
    }

done:
    if (rec) msiobj_release(&rec->hdr);
    msiobj_release(&view->hdr);

    return r;
}

UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch )
{
    MSIPATCHINFO *pi;
    UINT r = ERROR_SUCCESS;

    pi = msi_alloc_zero( sizeof(MSIPATCHINFO) );
    if (!pi)
        return ERROR_OUTOFMEMORY;

    pi->patchcode = msi_suminfo_dup_string( si, PID_REVNUMBER );
    if (!pi->patchcode)
    {
        msi_free( pi );
        return ERROR_OUTOFMEMORY;
    }

    pi->transforms = msi_suminfo_dup_string( si, PID_LASTAUTHOR );
    if (!pi->transforms)
    {
        msi_free( pi->patchcode );
        msi_free( pi );
        return ERROR_OUTOFMEMORY;
    }

    *patch = pi;
    return r;
}

UINT msi_apply_patch_db( MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch )
{
    UINT i, r = ERROR_SUCCESS;
    WCHAR **substorage;

    /* apply substorage transforms */
    substorage = msi_split_string( patch->transforms, ';' );
    for (i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++)
        r = msi_apply_substorage_transform( package, patch_db, substorage[i] );

    msi_free( substorage );
    if (r != ERROR_SUCCESS)
        return r;

    msi_set_media_source_prop( package );

    /*
     * There might be a CAB file in the patch package,
     * so append it to the list of storages to search for streams.
     */
    append_storage_to_db( package->db, patch_db->storage );

    list_add_tail( &package->patches, &patch->entry );
    return ERROR_SUCCESS;
}

static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
{
    static const WCHAR dotmsp[] = {'.','m','s','p',0};
    MSIDATABASE *patch_db = NULL;
    WCHAR localfile[MAX_PATH];
    MSISUMMARYINFO *si;
    MSIPATCHINFO *patch = NULL;
    UINT r = ERROR_SUCCESS;

    TRACE("%p %s\n", package, debugstr_w( file ) );

    r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db );
    if ( r != ERROR_SUCCESS )
    {
        ERR("failed to open patch collection %s\n", debugstr_w( file ) );
        return r;
    }

    si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
    if (!si)
    {
        msiobj_release( &patch_db->hdr );
        return ERROR_FUNCTION_FAILED;
    }

    r = msi_check_patch_applicable( package, si );
    if (r != ERROR_SUCCESS)
    {
        TRACE("patch not applicable\n");
        r = ERROR_SUCCESS;
        goto done;
    }

    r = msi_parse_patch_summary( si, &patch );
    if ( r != ERROR_SUCCESS )
        goto done;

    r = msi_get_local_package_name( localfile, dotmsp );
    if ( r != ERROR_SUCCESS )
        goto done;

    TRACE("copying to local package %s\n", debugstr_w(localfile));

    if (!CopyFileW( file, localfile, FALSE ))
    {
        ERR("Unable to copy package (%s -> %s) (error %u)\n",
            debugstr_w(file), debugstr_w(localfile), GetLastError());
        r = GetLastError();
        goto done;
    }
    patch->localfile = strdupW( localfile );

    r = msi_apply_patch_db( package, patch_db, patch );
    if ( r != ERROR_SUCCESS )
        WARN("patch failed to apply %u\n", r);

done:
    msiobj_release( &si->hdr );
    msiobj_release( &patch_db->hdr );
    if (patch && r != ERROR_SUCCESS)
    {
        if (patch->localfile)
            DeleteFileW( patch->localfile );

        msi_free( patch->patchcode );
        msi_free( patch->transforms );
        msi_free( patch->localfile );
        msi_free( patch );
    }
    return r;
}

/* get the PATCH property, and apply all the patches it specifies */
static UINT msi_apply_patches( MSIPACKAGE *package )
{
    LPWSTR patch_list, *patches;
    UINT i, r = ERROR_SUCCESS;

    patch_list = msi_dup_property( package->db, szPatch );

    TRACE("patches to be applied: %s\n", debugstr_w( patch_list ) );

    patches = msi_split_string( patch_list, ';' );
    for( i=0; patches && patches[i] && r == ERROR_SUCCESS; i++ )
        r = msi_apply_patch_package( package, patches[i] );

    msi_free( patches );
    msi_free( patch_list );

    return r;
}

static UINT msi_apply_transforms( MSIPACKAGE *package )
{
    static const WCHAR szTransforms[] = {
        'T','R','A','N','S','F','O','R','M','S',0 };
    LPWSTR xform_list, *xforms;
    UINT i, r = ERROR_SUCCESS;

    xform_list = msi_dup_property( package->db, szTransforms );
    xforms = msi_split_string( xform_list, ';' );

    for( i=0; xforms && xforms[i] && r == ERROR_SUCCESS; i++ )
    {
        if (xforms[i][0] == ':')
            r = msi_apply_substorage_transform( package, package->db, xforms[i] );
        else
            r = MSI_DatabaseApplyTransformW( package->db, xforms[i], 0 );
    }

    msi_free( xforms );
    msi_free( xform_list );

    return r;
}

static BOOL ui_sequence_exists( MSIPACKAGE *package )
{
    MSIQUERY *view;
    UINT rc;

    static const WCHAR ExecSeqQuery [] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','I','n','s','t','a','l','l',
         'U','I','S','e','q','u','e','n','c','e','`',
         ' ','W','H','E','R','E',' ',
         '`','S','e','q','u','e','n','c','e','`',' ',
         '>',' ','0',' ','O','R','D','E','R',' ','B','Y',' ',
         '`','S','e','q','u','e','n','c','e','`',0};

    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
    if (rc == ERROR_SUCCESS)
    {
        msiobj_release(&view->hdr);
        return TRUE;
    }

    return FALSE;
}

static UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
{
    LPWSTR source, check;

    if (msi_get_property_int( package->db, szInstalled, 0 ))
    {
        HKEY hkey;

        MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE );
        source = msi_reg_get_val_str( hkey, INSTALLPROPERTY_INSTALLSOURCEW );
        RegCloseKey( hkey );
    }
    else
    {
        LPWSTR p, db;
        DWORD len;

        db = msi_dup_property( package->db, szOriginalDatabase );
        if (!db)
            return ERROR_OUTOFMEMORY;

        p = strrchrW( db, '\\' );
        if (!p)
        {
            p = strrchrW( db, '/' );
            if (!p)
            {
                msi_free(db);
                return ERROR_SUCCESS;
            }
        }

        len = p - db + 2;
        source = msi_alloc( len * sizeof(WCHAR) );
        lstrcpynW( source, db, len );
        msi_free( db );
    }

    check = msi_dup_property( package->db, cszSourceDir );
    if (!check || replace)
    {
        UINT r = msi_set_property( package->db, cszSourceDir, source );
        if (r == ERROR_SUCCESS)
            msi_reset_folders( package, TRUE );
    }
    msi_free( check );

    check = msi_dup_property( package->db, cszSOURCEDIR );
    if (!check || replace)
        msi_set_property( package->db, cszSOURCEDIR, source );

    msi_free( check );
    msi_free( source );

    return ERROR_SUCCESS;
}

static BOOL needs_ui_sequence(MSIPACKAGE *package)
{
    INT level = msi_get_property_int(package->db, szUILevel, 0);
    return (level & INSTALLUILEVEL_MASK) >= INSTALLUILEVEL_REDUCED;
}

UINT msi_set_context(MSIPACKAGE *package)
{
    int num;

    package->Context = MSIINSTALLCONTEXT_USERUNMANAGED;

    num = msi_get_property_int(package->db, szAllUsers, 0);
    if (num == 1 || num == 2)
        package->Context = MSIINSTALLCONTEXT_MACHINE;

    return ERROR_SUCCESS;
}

static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param)
{
    UINT rc;
    LPCWSTR cond, action;
    MSIPACKAGE *package = param;

    action = MSI_RecordGetString(row,1);
    if (!action)
    {
        ERR("Error is retrieving action name\n");
        return ERROR_FUNCTION_FAILED;
    }

    /* check conditions */
    cond = MSI_RecordGetString(row,2);

    /* this is a hack to skip errors in the condition code */
    if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)
    {
        TRACE("Skipping action: %s (condition is false)\n", debugstr_w(action));
        return ERROR_SUCCESS;
    }

    if (needs_ui_sequence(package))
        rc = ACTION_PerformUIAction(package, action, -1);
    else
        rc = ACTION_PerformAction(package, action, -1, FALSE);

    msi_dialog_check_messages( NULL );

    if (package->CurrentInstallState != ERROR_SUCCESS)
        rc = package->CurrentInstallState;

    if (rc == ERROR_FUNCTION_NOT_CALLED)
        rc = ERROR_SUCCESS;

    if (rc != ERROR_SUCCESS)
        ERR("Execution halted, action %s returned %i\n", debugstr_w(action), rc);

    return rc;
}

UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable, INT iSequenceMode )
{
    MSIQUERY * view;
    UINT r;
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','%','s','`',
         ' ','W','H','E','R','E',' ', 
         '`','S','e','q','u','e','n','c','e','`',' ',
         '>',' ','0',' ','O','R','D','E','R',' ','B','Y',' ',
         '`','S','e','q','u','e','n','c','e','`',0};

    TRACE("%p %s %i\n", package, debugstr_w(szTable), iSequenceMode );

    r = MSI_OpenQuery( package->db, &view, query, szTable );
    if (r == ERROR_SUCCESS)
    {
        r = MSI_IterateRecords( view, NULL, ITERATE_Actions, package );
        msiobj_release(&view->hdr);
    }

    return r;
}

static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran)
{
    MSIQUERY * view;
    UINT rc;
    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
         '`','I','n','s','t','a','l','l','E','x','e','c','u','t','e',
         'S','e','q','u','e','n','c','e','`',' ', 'W','H','E','R','E',' ',
         '`','S','e','q','u','e','n','c','e','`',' ', '>',' ','%','i',' ',
         'O','R','D','E','R',' ', 'B','Y',' ',
         '`','S','e','q','u','e','n','c','e','`',0 };
    static const WCHAR IVQuery[] =
        {'S','E','L','E','C','T',' ','`','S','e','q','u','e','n','c','e','`',
         ' ', 'F','R','O','M',' ','`','I','n','s','t','a','l','l',
         'E','x','e','c','u','t','e','S','e','q','u','e','n','c','e','`',' ',
         'W','H','E','R','E',' ','`','A','c','t','i','o','n','`',' ','=',
         ' ','\'', 'I','n','s','t','a','l','l',
         'V','a','l','i','d','a','t','e','\'', 0};
    INT seq = 0;

    if (package->script->ExecuteSequenceRun)
    {
        TRACE("Execute Sequence already Run\n");
        return ERROR_SUCCESS;
    }

    package->script->ExecuteSequenceRun = TRUE;

    /* get the sequence number */
    if (UIran)
    {
        MSIRECORD *row = MSI_QueryGetRecord(package->db, IVQuery);
        if( !row )
            return ERROR_FUNCTION_FAILED;
        seq = MSI_RecordGetInteger(row,1);
        msiobj_release(&row->hdr);
    }

    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);
    if (rc == ERROR_SUCCESS)
    {
        TRACE("Running the actions\n");

        rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package);
        msiobj_release(&view->hdr);
    }

    return rc;
}

static UINT ACTION_ProcessUISequence(MSIPACKAGE *package)
{
    MSIQUERY * view;
    UINT rc;
    static const WCHAR ExecSeqQuery [] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','I','n','s','t','a','l','l',
         'U','I','S','e','q','u','e','n','c','e','`',
         ' ','W','H','E','R','E',' ', 
         '`','S','e','q','u','e','n','c','e','`',' ',
         '>',' ','0',' ','O','R','D','E','R',' ','B','Y',' ',
         '`','S','e','q','u','e','n','c','e','`',0};

    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
    if (rc == ERROR_SUCCESS)
    {
        TRACE("Running the actions\n"); 

        rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package);
        msiobj_release(&view->hdr);
    }

    return rc;
}

/********************************************************
 * ACTION helper functions and functions that perform the actions
 *******************************************************/
static BOOL ACTION_HandleCustomAction( MSIPACKAGE* package, LPCWSTR action,
                                       UINT* rc, UINT script, BOOL force )
{
    BOOL ret=FALSE;
    UINT arc;

    arc = ACTION_CustomAction(package, action, script, force);

    if (arc != ERROR_CALL_NOT_IMPLEMENTED)
    {
        *rc = arc;
        ret = TRUE;
    }
    return ret;
}

/*
 * Actual Action Handlers
 */

static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE *package = param;
    LPCWSTR dir, component;
    LPWSTR full_path;
    MSIRECORD *uirow;
    MSIFOLDER *folder;
    MSICOMPONENT *comp;

    component = MSI_RecordGetString(row, 2);
    comp = get_loaded_component(package, component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    dir = MSI_RecordGetString(row,1);
    if (!dir)
    {
        ERR("Unable to get folder id\n");
        return ERROR_SUCCESS;
    }

    uirow = MSI_CreateRecord(1);
    MSI_RecordSetStringW(uirow, 1, dir);
    ui_actiondata(package, szCreateFolders, uirow);
    msiobj_release(&uirow->hdr);

    full_path = resolve_folder(package,dir,FALSE,FALSE,TRUE,&folder);
    if (!full_path)
    {
        ERR("Unable to resolve folder id %s\n",debugstr_w(dir));
        return ERROR_SUCCESS;
    }

    TRACE("Folder is %s\n",debugstr_w(full_path));

    if (folder->State == 0)
        create_full_pathW(full_path);

    folder->State = 3;

    msi_free(full_path);
    return ERROR_SUCCESS;
}

/* FIXME: probably should merge this with the above function */
static UINT msi_create_directory( MSIPACKAGE* package, LPCWSTR dir )
{
    UINT rc = ERROR_SUCCESS;
    MSIFOLDER *folder;
    LPWSTR install_path;

    install_path = resolve_folder(package, dir, FALSE, FALSE, TRUE, &folder);
    if (!install_path)
        return ERROR_FUNCTION_FAILED; 

    /* create the path */
    if (folder->State == 0)
    {
        create_full_pathW(install_path);
        folder->State = 2;
    }
    msi_free(install_path);

    return rc;
}

UINT msi_create_component_directories( MSIPACKAGE *package )
{
    MSICOMPONENT *comp;

    /* create all the folders required by the components are going to install */
    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
    {
        if (comp->ActionRequest != INSTALLSTATE_LOCAL)
            continue;
        msi_create_directory( package, comp->Directory );
    }

    return ERROR_SUCCESS;
}

static UINT ACTION_CreateFolders(MSIPACKAGE *package)
{
    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ',
         '`','D','i','r','e','c','t','o','r','y','_','`',
         ' ','F','R','O','M',' ',
         '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0 };
    UINT rc;
    MSIQUERY *view;

    /* create all the empty folders specified in the CreateFolder table */
    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view );
    if (rc != ERROR_SUCCESS)
        return ERROR_SUCCESS;

    rc = MSI_IterateRecords(view, NULL, ITERATE_CreateFolders, package);
    msiobj_release(&view->hdr);

    return rc;
}

static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPCWSTR dir, component;
    LPWSTR full_path;
    MSIRECORD *uirow;
    MSIFOLDER *folder;
    MSICOMPONENT *comp;

    component = MSI_RecordGetString(row, 2);
    comp = get_loaded_component(package, component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_ABSENT;

    dir = MSI_RecordGetString( row, 1 );
    if (!dir)
    {
        ERR("Unable to get folder id\n");
        return ERROR_SUCCESS;
    }

    full_path = resolve_folder( package, dir, FALSE, FALSE, TRUE, &folder );
    if (!full_path)
    {
        ERR("Unable to resolve folder id %s\n", debugstr_w(dir));
        return ERROR_SUCCESS;
    }

    TRACE("folder is %s\n", debugstr_w(full_path));

    uirow = MSI_CreateRecord( 1 );
    MSI_RecordSetStringW( uirow, 1, full_path );
    ui_actiondata( package, szRemoveFolders, uirow );
    msiobj_release( &uirow->hdr );

    RemoveDirectoryW( full_path );
    folder->State = 0;

    msi_free( full_path );
    return ERROR_SUCCESS;
}

static UINT ACTION_RemoveFolders( MSIPACKAGE *package )
{
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ', '`','D','i','r','e','c','t','o','r','y','_','`',
         ' ','F','R','O','M',' ', '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0};

    MSIQUERY *view;
    UINT rc;

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveFolders, package );
    msiobj_release( &view->hdr );

    return rc;
}

static UINT load_component( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    MSICOMPONENT *comp;

    comp = msi_alloc_zero( sizeof(MSICOMPONENT) );
    if (!comp)
        return ERROR_FUNCTION_FAILED;

    list_add_tail( &package->components, &comp->entry );

    /* fill in the data */
    comp->Component = msi_dup_record_field( row, 1 );

    TRACE("Loading Component %s\n", debugstr_w(comp->Component));

    comp->ComponentId = msi_dup_record_field( row, 2 );
    comp->Directory = msi_dup_record_field( row, 3 );
    comp->Attributes = MSI_RecordGetInteger(row,4);
    comp->Condition = msi_dup_record_field( row, 5 );
    comp->KeyPath = msi_dup_record_field( row, 6 );

    comp->Installed = INSTALLSTATE_UNKNOWN;
    msi_component_set_state(package, comp, INSTALLSTATE_UNKNOWN);

    return ERROR_SUCCESS;
}

static UINT load_all_components( MSIPACKAGE *package )
{
    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ', 
         '`','C','o','m','p','o','n','e','n','t','`',0 };
    MSIQUERY *view;
    UINT r;

    if (!list_empty(&package->components))
        return ERROR_SUCCESS;

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

    r = MSI_IterateRecords(view, NULL, load_component, package);
    msiobj_release(&view->hdr);
    return r;
}

typedef struct {
    MSIPACKAGE *package;
    MSIFEATURE *feature;
} _ilfs;

static UINT add_feature_component( MSIFEATURE *feature, MSICOMPONENT *comp )
{
    ComponentList *cl;

    cl = msi_alloc( sizeof (*cl) );
    if ( !cl )
        return ERROR_NOT_ENOUGH_MEMORY;
    cl->component = comp;
    list_add_tail( &feature->Components, &cl->entry );

    return ERROR_SUCCESS;
}

static UINT add_feature_child( MSIFEATURE *parent, MSIFEATURE *child )
{
    FeatureList *fl;

    fl = msi_alloc( sizeof(*fl) );
    if ( !fl )
        return ERROR_NOT_ENOUGH_MEMORY;
    fl->feature = child;
    list_add_tail( &parent->Children, &fl->entry );

    return ERROR_SUCCESS;
}

static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
{
    _ilfs* ilfs = param;
    LPCWSTR component;
    MSICOMPONENT *comp;

    component = MSI_RecordGetString(row,1);

    /* check to see if the component is already loaded */
    comp = get_loaded_component( ilfs->package, component );
    if (!comp)
    {
        ERR("unknown component %s\n", debugstr_w(component));
        return ERROR_FUNCTION_FAILED;
    }

    add_feature_component( ilfs->feature, comp );
    comp->Enabled = TRUE;

    return ERROR_SUCCESS;
}

static MSIFEATURE *find_feature_by_name( MSIPACKAGE *package, LPCWSTR name )
{
    MSIFEATURE *feature;

    if ( !name )
        return NULL;

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        if ( !lstrcmpW( feature->Feature, name ) )
            return feature;
    }

    return NULL;
}

static UINT load_feature(MSIRECORD * row, LPVOID param)
{
    MSIPACKAGE* package = param;
    MSIFEATURE* feature;
    static const WCHAR Query1[] = 
        {'S','E','L','E','C','T',' ',
         '`','C','o','m','p','o','n','e','n','t','_','`',
         ' ','F','R','O','M',' ','`','F','e','a','t','u','r','e',
         'C','o','m','p','o','n','e','n','t','s','`',' ',
         'W','H','E','R','E',' ',
         '`','F','e', 'a','t','u','r','e','_','`',' ','=','\'','%','s','\'',0};
    MSIQUERY * view;
    UINT    rc;
    _ilfs ilfs;

    /* fill in the data */

    feature = msi_alloc_zero( sizeof (MSIFEATURE) );
    if (!feature)
        return ERROR_NOT_ENOUGH_MEMORY;

    list_init( &feature->Children );
    list_init( &feature->Components );
    
    feature->Feature = msi_dup_record_field( row, 1 );

    TRACE("Loading feature %s\n",debugstr_w(feature->Feature));

    feature->Feature_Parent = msi_dup_record_field( row, 2 );
    feature->Title = msi_dup_record_field( row, 3 );
    feature->Description = msi_dup_record_field( row, 4 );

    if (!MSI_RecordIsNull(row,5))
        feature->Display = MSI_RecordGetInteger(row,5);
  
    feature->Level= MSI_RecordGetInteger(row,6);
    feature->Directory = msi_dup_record_field( row, 7 );
    feature->Attributes = MSI_RecordGetInteger(row,8);

    feature->Installed = INSTALLSTATE_UNKNOWN;
    msi_feature_set_state(package, feature, INSTALLSTATE_UNKNOWN);

    list_add_tail( &package->features, &feature->entry );

    /* load feature components */

    rc = MSI_OpenQuery( package->db, &view, Query1, feature->Feature );
    if (rc != ERROR_SUCCESS)
        return ERROR_SUCCESS;

    ilfs.package = package;
    ilfs.feature = feature;

    MSI_IterateRecords(view, NULL, iterate_load_featurecomponents , &ilfs);
    msiobj_release(&view->hdr);

    return ERROR_SUCCESS;
}

static UINT find_feature_children(MSIRECORD * row, LPVOID param)
{
    MSIPACKAGE* package = param;
    MSIFEATURE *parent, *child;

    child = find_feature_by_name( package, MSI_RecordGetString( row, 1 ) );
    if (!child)
        return ERROR_FUNCTION_FAILED;

    if (!child->Feature_Parent)
        return ERROR_SUCCESS;

    parent = find_feature_by_name( package, child->Feature_Parent );
    if (!parent)
        return ERROR_FUNCTION_FAILED;

    add_feature_child( parent, child );
    return ERROR_SUCCESS;
}

static UINT load_all_features( MSIPACKAGE *package )
{
    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
        '`','F','e','a','t','u','r','e','`',' ','O','R','D','E','R',
        ' ','B','Y',' ','`','D','i','s','p','l','a','y','`',0};
    MSIQUERY *view;
    UINT r;

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

    r = MSI_IterateRecords( view, NULL, load_feature, package );
    if (r != ERROR_SUCCESS)
        return r;

    r = MSI_IterateRecords( view, NULL, find_feature_children, package );
    msiobj_release( &view->hdr );

    return r;
}

static LPWSTR folder_split_path(LPWSTR p, WCHAR ch)
{
    if (!p)
        return p;
    p = strchrW(p, ch);
    if (!p)
        return p;
    *p = 0;
    return p+1;
}

static UINT load_file_hash(MSIPACKAGE *package, MSIFILE *file)
{
    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
        '`','M','s','i','F','i','l','e','H','a','s','h','`',' ',
        'W','H','E','R','E',' ','`','F','i','l','e','_','`',' ','=',' ','\'','%','s','\'',0};
    MSIQUERY *view = NULL;
    MSIRECORD *row = NULL;
    UINT r;

    TRACE("%s\n", debugstr_w(file->File));

    r = MSI_OpenQuery(package->db, &view, query, file->File);
    if (r != ERROR_SUCCESS)
        goto done;

    r = MSI_ViewExecute(view, NULL);
    if (r != ERROR_SUCCESS)
        goto done;

    r = MSI_ViewFetch(view, &row);
    if (r != ERROR_SUCCESS)
        goto done;

    file->hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
    file->hash.dwData[0] = MSI_RecordGetInteger(row, 3);
    file->hash.dwData[1] = MSI_RecordGetInteger(row, 4);
    file->hash.dwData[2] = MSI_RecordGetInteger(row, 5);
    file->hash.dwData[3] = MSI_RecordGetInteger(row, 6);

done:
    if (view) msiobj_release(&view->hdr);
    if (row) msiobj_release(&row->hdr);
    return r;
}

static UINT load_file_disk_id( MSIPACKAGE *package, MSIFILE *file )
{
    MSIRECORD *row;
    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','`','D','i','s','k','I','d','`',' ', 'F','R','O','M',' ',
        '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
        '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=',' ','%','i',0};

    row = MSI_QueryGetRecord( package->db, query, file->Sequence );
    if (!row)
    {
        WARN("query failed\n");
        return ERROR_FUNCTION_FAILED;
    }

    file->disk_id = MSI_RecordGetInteger( row, 1 );
    msiobj_release( &row->hdr );
    return ERROR_SUCCESS;
}

static UINT load_file(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE* package = param;
    LPCWSTR component;
    MSIFILE *file;

    /* fill in the data */

    file = msi_alloc_zero( sizeof (MSIFILE) );
    if (!file)
        return ERROR_NOT_ENOUGH_MEMORY;
 
    file->File = msi_dup_record_field( row, 1 );

    component = MSI_RecordGetString( row, 2 );
    file->Component = get_loaded_component( package, component );

    if (!file->Component)
    {
        WARN("Component not found: %s\n", debugstr_w(component));
        msi_free(file->File);
        msi_free(file);
        return ERROR_SUCCESS;
    }

    file->FileName = msi_dup_record_field( row, 3 );
    reduce_to_longfilename( file->FileName );

    file->ShortName = msi_dup_record_field( row, 3 );
    file->LongName = strdupW( folder_split_path(file->ShortName, '|'));
    
    file->FileSize = MSI_RecordGetInteger( row, 4 );
    file->Version = msi_dup_record_field( row, 5 );
    file->Language = msi_dup_record_field( row, 6 );
    file->Attributes = MSI_RecordGetInteger( row, 7 );
    file->Sequence = MSI_RecordGetInteger( row, 8 );

    file->state = msifs_invalid;

    /* if the compressed bits are not set in the file attributes,
     * then read the information from the package word count property
     */
    if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
    {
        file->IsCompressed = FALSE;
    }
    else if (file->Attributes &
             (msidbFileAttributesCompressed | msidbFileAttributesPatchAdded))
    {
        file->IsCompressed = TRUE;
    }
    else if (file->Attributes & msidbFileAttributesNoncompressed)
    {
        file->IsCompressed = FALSE;
    }
    else
    {
        file->IsCompressed = package->WordCount & msidbSumInfoSourceTypeCompressed;
    }

    load_file_hash(package, file);
    load_file_disk_id(package, file);

    TRACE("File Loaded (%s)\n",debugstr_w(file->File));  

    list_add_tail( &package->files, &file->entry );
 
    return ERROR_SUCCESS;
}

static UINT load_all_files(MSIPACKAGE *package)
{
    MSIQUERY * view;
    UINT rc;
    static const WCHAR Query[] =
        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
         '`','F','i','l','e','`',' ', 'O','R','D','E','R',' ','B','Y',' ',
         '`','S','e','q','u','e','n','c','e','`', 0};

    if (!list_empty(&package->files))
        return ERROR_SUCCESS;

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

    rc = MSI_IterateRecords(view, NULL, load_file, package);
    msiobj_release(&view->hdr);

    return ERROR_SUCCESS;
}

static UINT load_folder( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    static WCHAR szEmpty[] = { 0 };
    LPWSTR p, tgt_short, tgt_long, src_short, src_long;
    MSIFOLDER *folder;

    folder = msi_alloc_zero( sizeof (MSIFOLDER) );
    if (!folder)
        return ERROR_NOT_ENOUGH_MEMORY;

    folder->Directory = msi_dup_record_field( row, 1 );

    TRACE("%s\n", debugstr_w(folder->Directory));

    p = msi_dup_record_field(row, 3);

    /* split src and target dir */
    tgt_short = p;
    src_short = folder_split_path( p, ':' );

    /* split the long and short paths */
    tgt_long = folder_split_path( tgt_short, '|' );
    src_long = folder_split_path( src_short, '|' );

    /* check for no-op dirs */
    if (!lstrcmpW(szDot, tgt_short))
        tgt_short = szEmpty;
    if (!lstrcmpW(szDot, src_short))
        src_short = szEmpty;

    if (!tgt_long)
        tgt_long = tgt_short;

    if (!src_short) {
        src_short = tgt_short;
        src_long = tgt_long;
    }

    if (!src_long)
        src_long = src_short;

    /* FIXME: use the target short path too */
    folder->TargetDefault = strdupW(tgt_long);
    folder->SourceShortPath = strdupW(src_short);
    folder->SourceLongPath = strdupW(src_long);
    msi_free(p);

    TRACE("TargetDefault = %s\n",debugstr_w( folder->TargetDefault ));
    TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
    TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));

    folder->Parent = msi_dup_record_field( row, 2 );

    folder->Property = msi_dup_property( package->db, folder->Directory );

    list_add_tail( &package->folders, &folder->entry );

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

    return ERROR_SUCCESS;
}

static UINT load_all_folders( MSIPACKAGE *package )
{
    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
         '`','D','i','r','e','c','t','o','r','y','`',0 };
    MSIQUERY *view;
    UINT r;

    if (!list_empty(&package->folders))
        return ERROR_SUCCESS;

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

    r = MSI_IterateRecords(view, NULL, load_folder, package);
    msiobj_release(&view->hdr);
    return r;
}

/*
 * I am not doing any of the costing functionality yet.
 * Mostly looking at doing the Component and Feature loading
 *
 * The native MSI does A LOT of modification to tables here. Mostly adding
 * a lot of temporary columns to the Feature and Component tables.
 *
 *    note: Native msi also tracks the short filename. But I am only going to
 *          track the long ones.  Also looking at this directory table
 *          it appears that the directory table does not get the parents
 *          resolved base on property only based on their entries in the
 *          directory table.
 */
static UINT ACTION_CostInitialize(MSIPACKAGE *package)
{
    static const WCHAR szCosting[] =
        {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };

    msi_set_property( package->db, szCosting, szZero );
    msi_set_property( package->db, cszRootDrive, c_colon );

    load_all_folders( package );
    load_all_components( package );
    load_all_features( package );
    load_all_files( package );

    return ERROR_SUCCESS;
}

static UINT execute_script(MSIPACKAGE *package, UINT script )
{
    UINT i;
    UINT rc = ERROR_SUCCESS;

    TRACE("Executing Script %i\n",script);

    if (!package->script)
    {
        ERR("no script!\n");
        return ERROR_FUNCTION_FAILED;
    }

    for (i = 0; i < package->script->ActionCount[script]; i++)
    {
        LPWSTR action;
        action = package->script->Actions[script][i];
        ui_actionstart(package, action);
        TRACE("Executing Action (%s)\n",debugstr_w(action));
        rc = ACTION_PerformAction(package, action, script, TRUE);
        if (rc != ERROR_SUCCESS)
            break;
    }
    msi_free_action_script(package, script);
    return rc;
}

static UINT ACTION_FileCost(MSIPACKAGE *package)
{
    return ERROR_SUCCESS;
}

static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
{
    MSICOMPONENT *comp;
    INSTALLSTATE state;
    UINT r;

    state = MsiQueryProductStateW(package->ProductCode);

    LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
    {
        if (!comp->ComponentId)
            continue;

        if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT)
            comp->Installed = INSTALLSTATE_ABSENT;
        else
        {
            r = MsiQueryComponentStateW(package->ProductCode, NULL,
                                        package->Context, comp->ComponentId,
                                        &comp->Installed);
            if (r != ERROR_SUCCESS)
                comp->Installed = INSTALLSTATE_ABSENT;
        }
    }
}

static void ACTION_GetFeatureInstallStates(MSIPACKAGE *package)
{
    MSIFEATURE *feature;
    INSTALLSTATE state;

    state = MsiQueryProductStateW(package->ProductCode);

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT)
            feature->Installed = INSTALLSTATE_ABSENT;
        else
        {
            feature->Installed = MsiQueryFeatureStateW(package->ProductCode,
                                                       feature->Feature);
        }
    }
}

static BOOL process_state_property(MSIPACKAGE* package, int level,
                                   LPCWSTR property, INSTALLSTATE state)
{
    LPWSTR override;
    MSIFEATURE *feature;

    override = msi_dup_property( package->db, property );
    if (!override)
        return FALSE;

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        if (lstrcmpW(property, szRemove) &&
            (feature->Level <= 0 || feature->Level > level))
            continue;

        if (!strcmpW(property, szReinstall)) state = feature->Installed;

        if (strcmpiW(override, szAll)==0)
            msi_feature_set_state(package, feature, state);
        else
        {
            LPWSTR ptr = override;
            LPWSTR ptr2 = strchrW(override,',');

            while (ptr)
            {
                int len = ptr2 - ptr;

                if ((ptr2 && strlenW(feature->Feature) == len && !strncmpW(ptr, feature->Feature, len))
                    || (!ptr2 && !strcmpW(ptr, feature->Feature)))
                {
                    msi_feature_set_state(package, feature, state);
                    break;
                }
                if (ptr2)
                {
                    ptr=ptr2+1;
                    ptr2 = strchrW(ptr,',');
                }
                else
                    break;
            }
        }
    }
    msi_free(override);

    return TRUE;
}

static BOOL process_overrides( MSIPACKAGE *package, int level )
{
    static const WCHAR szAddLocal[] =
        {'A','D','D','L','O','C','A','L',0};
    static const WCHAR szAddSource[] =
        {'A','D','D','S','O','U','R','C','E',0};
    static const WCHAR szAdvertise[] =
        {'A','D','V','E','R','T','I','S','E',0};
    BOOL ret = FALSE;

    /* all these activation/deactivation things happen in order and things
     * later on the list override things earlier on the list.
     *
     *  0  INSTALLLEVEL processing
     *  1  ADDLOCAL
     *  2  REMOVE
     *  3  ADDSOURCE
     *  4  ADDDEFAULT
     *  5  REINSTALL
     *  6  ADVERTISE
     *  7  COMPADDLOCAL
     *  8  COMPADDSOURCE
     *  9  FILEADDLOCAL
     * 10  FILEADDSOURCE
     * 11  FILEADDDEFAULT
     */
    ret |= process_state_property( package, level, szAddLocal, INSTALLSTATE_LOCAL );
    ret |= process_state_property( package, level, szRemove, INSTALLSTATE_ABSENT );
    ret |= process_state_property( package, level, szAddSource, INSTALLSTATE_SOURCE );
    ret |= process_state_property( package, level, szReinstall, INSTALLSTATE_UNKNOWN );
    ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED );

    if (ret)
        msi_set_property( package->db, szPreselected, szOne );

    return ret;
}

UINT MSI_SetFeatureStates(MSIPACKAGE *package)
{
    int level;
    static const WCHAR szlevel[] =
        {'I','N','S','T','A','L','L','L','E','V','E','L',0};
    MSICOMPONENT* component;
    MSIFEATURE *feature;

    TRACE("Checking Install Level\n");

    level = msi_get_property_int(package->db, szlevel, 1);

    if (!msi_get_property_int( package->db, szPreselected, 0 ))
    {
        LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
        {
            BOOL feature_state = ((feature->Level > 0) &&
                                  (feature->Level <= level));

            if ((feature_state) && (feature->Action == INSTALLSTATE_UNKNOWN))
            {
                if (feature->Attributes & msidbFeatureAttributesFavorSource)
                    msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE);
                else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise)
                    msi_feature_set_state(package, feature, INSTALLSTATE_ADVERTISED);
                else
                    msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL);
            }
        }

        /* disable child features of unselected parent features */
        LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
        {
            FeatureList *fl;

            if (feature->Level > 0 && feature->Level <= level)
                continue;

            LIST_FOR_EACH_ENTRY( fl, &feature->Children, FeatureList, entry )
                msi_feature_set_state(package, fl->feature, INSTALLSTATE_UNKNOWN);
        }
    }

    /*
     * now we want to enable or disable components base on feature
     */

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        ComponentList *cl;

        TRACE("Examining Feature %s (Level %i, Installed %i, Action %i)\n",
              debugstr_w(feature->Feature), feature->Level, feature->Installed, feature->Action);

        if (!feature->Level)
            continue;

        /* features with components that have compressed files are made local */
        LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
        {
            if (cl->component->Enabled &&
                cl->component->ForceLocalState &&
                feature->Action == INSTALLSTATE_SOURCE)
            {
                msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL);
                break;
            }
        }

        LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
        {
            component = cl->component;

            if (!component->Enabled)
                continue;

            switch (feature->Action)
            {
            case INSTALLSTATE_ABSENT:
                component->anyAbsent = 1;
                break;
            case INSTALLSTATE_ADVERTISED:
                component->hasAdvertiseFeature = 1;
                break;
            case INSTALLSTATE_SOURCE:
                component->hasSourceFeature = 1;
                break;
            case INSTALLSTATE_LOCAL:
                component->hasLocalFeature = 1;
                break;
            case INSTALLSTATE_DEFAULT:
                if (feature->Attributes & msidbFeatureAttributesFavorAdvertise)
                    component->hasAdvertiseFeature = 1;
                else if (feature->Attributes & msidbFeatureAttributesFavorSource)
                    component->hasSourceFeature = 1;
                else
                    component->hasLocalFeature = 1;
                break;
            default:
                break;
            }
        }
    }

    LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
    {
        /* if the component isn't enabled, leave it alone */
        if (!component->Enabled)
            continue;

        /* check if it's local or source */
        if (!(component->Attributes & msidbComponentAttributesOptional) &&
             (component->hasLocalFeature || component->hasSourceFeature))
        {
            if ((component->Attributes & msidbComponentAttributesSourceOnly) &&
                 !component->ForceLocalState)
                msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
            else
                msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
            continue;
        }

        /* if any feature is local, the component must be local too */
        if (component->hasLocalFeature)
        {
            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
            continue;
        }

        if (component->hasSourceFeature)
        {
            msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
            continue;
        }

        if (component->hasAdvertiseFeature)
        {
            msi_component_set_state(package, component, INSTALLSTATE_ADVERTISED);
            continue;
        }

        TRACE("nobody wants component %s\n", debugstr_w(component->Component));
        if (component->anyAbsent)
            msi_component_set_state(package, component, INSTALLSTATE_ABSENT);
    }

    LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
    {
        if (component->Action == INSTALLSTATE_DEFAULT)
        {
            TRACE("%s was default, setting to local\n", debugstr_w(component->Component));
            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
        }

        TRACE("Result: Component %s (Installed %i, Action %i)\n",
            debugstr_w(component->Component), component->Installed, component->Action);
    }


    return ERROR_SUCCESS;
}

static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE *package = param;
    LPCWSTR name;
    LPWSTR path;
    MSIFOLDER *f;

    name = MSI_RecordGetString(row,1);

    f = get_loaded_folder(package, name);
    if (!f) return ERROR_SUCCESS;

    /* reset the ResolvedTarget */
    msi_free(f->ResolvedTarget);
    f->ResolvedTarget = NULL;

    /* This helper function now does ALL the work */
    TRACE("Dir %s ...\n",debugstr_w(name));
    path = resolve_folder(package,name,FALSE,TRUE,TRUE,NULL);
    TRACE("resolves to %s\n",debugstr_w(path));
    msi_free(path);

    return ERROR_SUCCESS;
}

static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE *package = param;
    LPCWSTR name;
    MSIFEATURE *feature;

    name = MSI_RecordGetString( row, 1 );

    feature = get_loaded_feature( package, name );
    if (!feature)
        ERR("FAILED to find loaded feature %s\n",debugstr_w(name));
    else
    {
        LPCWSTR Condition;
        Condition = MSI_RecordGetString(row,3);

        if (MSI_EvaluateConditionW(package,Condition) == MSICONDITION_TRUE)
        {
            int level = MSI_RecordGetInteger(row,2);
            TRACE("Resetting feature %s to level %i\n", debugstr_w(name), level);
            feature->Level = level;
        }
    }
    return ERROR_SUCCESS;
}

static LPWSTR get_disk_file_version( LPCWSTR filename )
{
    static const WCHAR name_fmt[] =
        {'%','u','.','%','u','.','%','u','.','%','u',0};
    static const WCHAR name[] = {'\\',0};
    VS_FIXEDFILEINFO *lpVer;
    WCHAR filever[0x100];
    LPVOID version;
    DWORD versize;
    DWORD handle;
    UINT sz;

    TRACE("%s\n", debugstr_w(filename));

    versize = GetFileVersionInfoSizeW( filename, &handle );
    if (!versize)
        return NULL;

    version = msi_alloc( versize );
    GetFileVersionInfoW( filename, 0, versize, version );

    if (!VerQueryValueW( version, name, (LPVOID*)&lpVer, &sz ))
    {
        msi_free( version );
        return NULL;
    }

    sprintfW( filever, name_fmt,
        HIWORD(lpVer->dwFileVersionMS),
        LOWORD(lpVer->dwFileVersionMS),
        HIWORD(lpVer->dwFileVersionLS),
        LOWORD(lpVer->dwFileVersionLS));

    msi_free( version );

    return strdupW( filever );
}

static DWORD get_disk_file_size( LPCWSTR filename )
{
    HANDLE file;
    DWORD size;

    TRACE("%s\n", debugstr_w(filename));

    file = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
    if (file == INVALID_HANDLE_VALUE)
        return INVALID_FILE_SIZE;

    size = GetFileSize( file, NULL );
    CloseHandle( file );
    return size;
}

static BOOL hash_matches( MSIFILE *file )
{
    UINT r;
    MSIFILEHASHINFO hash;

    hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
    r = MsiGetFileHashW( file->TargetPath, 0, &hash );
    if (r != ERROR_SUCCESS)
        return FALSE;

    return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) );
}

static UINT set_file_install_states( MSIPACKAGE *package )
{
    LPWSTR file_version;
    MSIFILE *file;

    LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
    {
        MSICOMPONENT* comp = file->Component;
        DWORD file_size;
        LPWSTR p;

        if (!comp)
            continue;

        if (file->IsCompressed)
            comp->ForceLocalState = TRUE;

        /* calculate target */
        p = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL);

        msi_free(file->TargetPath);

        TRACE("file %s is named %s\n",
               debugstr_w(file->File), debugstr_w(file->FileName));

        file->TargetPath = build_directory_name(2, p, file->FileName);

        msi_free(p);

        TRACE("file %s resolves to %s\n",
               debugstr_w(file->File), debugstr_w(file->TargetPath));

        if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
        {
            file->state = msifs_missing;
            comp->Cost += file->FileSize;
            continue;
        }
        if (file->Version && (file_version = get_disk_file_version( file->TargetPath )))
        {
            TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(file_version));

            if (strcmpiW(file_version, file->Version) < 0)
            {
                file->state = msifs_overwrite;
                comp->Cost += file->FileSize;
            }
            else
            {
                TRACE("Destination file version equal or greater, not overwriting\n");
                file->state = msifs_present;
            }
            msi_free( file_version );
            continue;
        }
        if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize)
        {
            file->state = msifs_overwrite;
            comp->Cost += file->FileSize - file_size;
            continue;
        }
        if (file->hash.dwFileHashInfoSize && hash_matches( file ))
        {
            TRACE("File hashes match, not overwriting\n");
            file->state = msifs_present;
            continue;
        }
        file->state = msifs_overwrite;
        comp->Cost += file->FileSize - file_size;
    }

    return ERROR_SUCCESS;
}

/*
 * A lot is done in this function aside from just the costing.
 * The costing needs to be implemented at some point but for now I am going
 * to focus on the directory building
 *
 */
static UINT ACTION_CostFinalize(MSIPACKAGE *package)
{
    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','D','i','r','e','c','t','o','r','y','`',0};
    static const WCHAR ConditionQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','C','o','n','d','i','t','i','o','n','`',0};
    static const WCHAR szCosting[] =
        {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
    static const WCHAR szlevel[] =
        {'I','N','S','T','A','L','L','L','E','V','E','L',0};
    static const WCHAR szOutOfDiskSpace[] =
        {'O','u','t','O','f','D','i','s','k','S','p','a','c','e',0};
    MSICOMPONENT *comp;
    UINT rc = ERROR_SUCCESS;
    MSIQUERY * view;
    LPWSTR level;

    TRACE("Building Directory properties\n");

    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
    if (rc == ERROR_SUCCESS)
    {
        rc = MSI_IterateRecords(view, NULL, ITERATE_CostFinalizeDirectories,
                        package);
        msiobj_release(&view->hdr);
    }

    /* read components states from the registry */
    ACTION_GetComponentInstallStates(package);
    ACTION_GetFeatureInstallStates(package);

    TRACE("Calculating file install states\n");
    set_file_install_states( package );

    if (!process_overrides( package, msi_get_property_int( package->db, szlevel, 1 ) ))
    {
        TRACE("Evaluating feature conditions\n");

        rc = MSI_DatabaseOpenViewW( package->db, ConditionQuery, &view );
        if (rc == ERROR_SUCCESS)
        {
            rc = MSI_IterateRecords( view, NULL, ITERATE_CostFinalizeConditions, package );
            msiobj_release( &view->hdr );
        }
    }
    TRACE("Evaluating component conditions\n");

    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
    {
        if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE)
        {
            TRACE("Disabling component %s\n", debugstr_w(comp->Component));
            comp->Enabled = FALSE;
        }
        else
            comp->Enabled = TRUE;
    }

    msi_set_property( package->db, szCosting, szOne );
    /* set default run level if not set */
    level = msi_dup_property( package->db, szlevel );
    if (!level)
        msi_set_property( package->db, szlevel, szOne );
    msi_free(level);

    /* FIXME: check volume disk space */
    msi_set_property( package->db, szOutOfDiskSpace, szZero );

    return MSI_SetFeatureStates(package);
}

/* OK this value is "interpreted" and then formatted based on the 
   first few characters */
static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, 
                         DWORD *size)
{
    LPSTR data = NULL;

    if (value[0]=='#' && value[1]!='#' && value[1]!='%')
    {
        if (value[1]=='x')
        {
            LPWSTR ptr;
            CHAR byte[5];
            LPWSTR deformated = NULL;
            int count;

            deformat_string(package, &value[2], &deformated);

            /* binary value type */
            ptr = deformated;
            *type = REG_BINARY;
            if (strlenW(ptr)%2)
                *size = (strlenW(ptr)/2)+1;
            else
                *size = strlenW(ptr)/2;

            data = msi_alloc(*size);

            byte[0] = '0'; 
            byte[1] = 'x'; 
            byte[4] = 0; 
            count = 0;
            /* if uneven pad with a zero in front */
            if (strlenW(ptr)%2)
            {
                byte[2]= '0';
                byte[3]= *ptr;
                ptr++;
                data[count] = (BYTE)strtol(byte,NULL,0);
                count ++;
                TRACE("Uneven byte count\n");
            }
            while (*ptr)
            {
                byte[2]= *ptr;
                ptr++;
                byte[3]= *ptr;
                ptr++;
                data[count] = (BYTE)strtol(byte,NULL,0);
                count ++;
            }
            msi_free(deformated);

            TRACE("Data %i bytes(%i)\n",*size,count);
        }
        else
        {
            LPWSTR deformated;
            LPWSTR p;
            DWORD d = 0;
            deformat_string(package, &value[1], &deformated);

            *type=REG_DWORD; 
            *size = sizeof(DWORD);
            data = msi_alloc(*size);
            p = deformated;
            if (*p == '-')
                p++;
            while (*p)
            {
                if ( (*p < '0') || (*p > '9') )
                    break;
                d *= 10;
                d += (*p - '0');
                p++;
            }
            if (deformated[0] == '-')
                d = -d;
            *(LPDWORD)data = d;
            TRACE("DWORD %i\n",*(LPDWORD)data);

            msi_free(deformated);
        }
    }
    else
    {
        static const WCHAR szMulti[] = {'[','~',']',0};
        LPCWSTR ptr;
        *type=REG_SZ;

        if (value[0]=='#')
        {
            if (value[1]=='%')
            {
                ptr = &value[2];
                *type=REG_EXPAND_SZ;
            }
            else
                ptr = &value[1];
         }
         else
            ptr=value;

        if (strstrW(value,szMulti))
            *type = REG_MULTI_SZ;

        /* remove initial delimiter */
        if (!strncmpW(value, szMulti, 3))
            ptr = value + 3;

        *size = deformat_string(package, ptr,(LPWSTR*)&data);

        /* add double NULL terminator */
        if (*type == REG_MULTI_SZ)
        {
            *size += 2 * sizeof(WCHAR); /* two NULL terminators */
            data = msi_realloc_zero(data, *size);
        }
    }
    return data;
}

static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key )
{
    const WCHAR *ret;

    switch (root)
    {
    case -1:
        if (msi_get_property_int( package->db, szAllUsers, 0 ))
        {
            *root_key = HKEY_LOCAL_MACHINE;
            ret = szHLM;
        }
        else
        {
            *root_key = HKEY_CURRENT_USER;
            ret = szHCU;
        }
        break;
    case 0:
        *root_key = HKEY_CLASSES_ROOT;
        ret = szHCR;
        break;
    case 1:
        *root_key = HKEY_CURRENT_USER;
        ret = szHCU;
        break;
    case 2:
        *root_key = HKEY_LOCAL_MACHINE;
        ret = szHLM;
        break;
    case 3:
        *root_key = HKEY_USERS;
        ret = szHU;
        break;
    default:
        ERR("Unknown root %i\n", root);
        return NULL;
    }

    return ret;
}

static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE *package = param;
    LPSTR value_data = NULL;
    HKEY  root_key, hkey;
    DWORD type,size;
    LPWSTR  deformated;
    LPCWSTR szRoot, component, name, key, value;
    MSICOMPONENT *comp;
    MSIRECORD * uirow;
    LPWSTR uikey;
    INT   root;
    BOOL check_first = FALSE;
    UINT rc;

    ui_progress(package,2,0,0,0);

    value = NULL;
    key = NULL;
    uikey = NULL;
    name = NULL;

    component = MSI_RecordGetString(row, 6);
    comp = get_loaded_component(package,component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    name = MSI_RecordGetString(row, 4);
    if( MSI_RecordIsNull(row,5) && name )
    {
        /* null values can have special meanings */
        if (name[0]=='-' && name[1] == 0)
                return ERROR_SUCCESS;
        else if ((name[0]=='+' && name[1] == 0) || 
                 (name[0] == '*' && name[1] == 0))
                name = NULL;
        check_first = TRUE;
    }

    root = MSI_RecordGetInteger(row,2);
    key = MSI_RecordGetString(row, 3);

    szRoot = get_root_key( package, root, &root_key );
    if (!szRoot)
        return ERROR_SUCCESS;

    deformat_string(package, key , &deformated);
    size = strlenW(deformated) + strlenW(szRoot) + 1;
    uikey = msi_alloc(size*sizeof(WCHAR));
    strcpyW(uikey,szRoot);
    strcatW(uikey,deformated);

    if (RegCreateKeyW( root_key, deformated, &hkey))
    {
        ERR("Could not create key %s\n",debugstr_w(deformated));
        msi_free(deformated);
        msi_free(uikey);
        return ERROR_SUCCESS;
    }
    msi_free(deformated);

    value = MSI_RecordGetString(row,5);
    if (value)
        value_data = parse_value(package, value, &type, &size); 
    else
    {
        value_data = (LPSTR)strdupW(szEmpty);
        size = sizeof(szEmpty);
        type = REG_SZ;
    }

    deformat_string(package, name, &deformated);

    if (!check_first)
    {
        TRACE("Setting value %s of %s\n",debugstr_w(deformated),
                        debugstr_w(uikey));
        RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size);
    }
    else
    {
        DWORD sz = 0;
        rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz);
        if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
        {
            TRACE("value %s of %s checked already exists\n",
                            debugstr_w(deformated), debugstr_w(uikey));
        }
        else
        {
            TRACE("Checked and setting value %s of %s\n",
                            debugstr_w(deformated), debugstr_w(uikey));
            if (deformated || size)
                RegSetValueExW(hkey, deformated, 0, type, (LPBYTE) value_data, size);
        }
    }
    RegCloseKey(hkey);

    uirow = MSI_CreateRecord(3);
    MSI_RecordSetStringW(uirow,2,deformated);
    MSI_RecordSetStringW(uirow,1,uikey);
    if (type == REG_SZ || type == REG_EXPAND_SZ)
        MSI_RecordSetStringW(uirow,3,(LPWSTR)value_data);
    ui_actiondata(package,szWriteRegistryValues,uirow);
    msiobj_release( &uirow->hdr );

    msi_free(value_data);
    msi_free(deformated);
    msi_free(uikey);

    return ERROR_SUCCESS;
}

static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
{
    UINT rc;
    MSIQUERY * view;
    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','R','e','g','i','s','t','r','y','`',0 };

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

    /* increment progress bar each time action data is sent */
    ui_progress(package,1,REG_PROGRESS_VALUE,1,0);

    rc = MSI_IterateRecords(view, NULL, ITERATE_WriteRegistryValues, package);

    msiobj_release(&view->hdr);
    return rc;
}

static void delete_reg_key_or_value( HKEY hkey_root, LPCWSTR key, LPCWSTR value, BOOL delete_key )
{
    LONG res;
    HKEY hkey;
    DWORD num_subkeys, num_values;

    if (delete_key)
    {
        if ((res = RegDeleteTreeW( hkey_root, key )))
        {
            WARN("Failed to delete key %s (%d)\n", debugstr_w(key), res);
        }
        return;
    }

    if (!(res = RegOpenKeyW( hkey_root, key, &hkey )))
    {
        if ((res = RegDeleteValueW( hkey, value )))
        {
            WARN("Failed to delete value %s (%d)\n", debugstr_w(value), res);
        }
        res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, &num_values,
                                NULL, NULL, NULL, NULL );
        RegCloseKey( hkey );

        if (!res && !num_subkeys && !num_values)
        {
            TRACE("Removing empty key %s\n", debugstr_w(key));
            RegDeleteKeyW( hkey_root, key );
        }
        return;
    }
    WARN("Failed to open key %s (%d)\n", debugstr_w(key), res);
}


static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPCWSTR component, name, key_str, root_key_str;
    LPWSTR deformated_key, deformated_name, ui_key_str;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    BOOL delete_key = FALSE;
    HKEY hkey_root;
    UINT size;
    INT root;

    ui_progress( package, 2, 0, 0, 0 );

    component = MSI_RecordGetString( row, 6 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_ABSENT;

    name = MSI_RecordGetString( row, 4 );
    if (MSI_RecordIsNull( row, 5 ) && name )
    {
        if (name[0] == '+' && !name[1])
            return ERROR_SUCCESS;
        else if ((name[0] == '-' && !name[1]) || (name[0] == '*' && !name[1]))
        {
            delete_key = TRUE;
            name = NULL;
        }
    }

    root = MSI_RecordGetInteger( row, 2 );
    key_str = MSI_RecordGetString( row, 3 );

    root_key_str = get_root_key( package, root, &hkey_root );
    if (!root_key_str)
        return ERROR_SUCCESS;

    deformat_string( package, key_str, &deformated_key );
    size = strlenW( deformated_key ) + strlenW( root_key_str ) + 1;
    ui_key_str = msi_alloc( size * sizeof(WCHAR) );
    strcpyW( ui_key_str, root_key_str );
    strcatW( ui_key_str, deformated_key );

    deformat_string( package, name, &deformated_name );

    delete_reg_key_or_value( hkey_root, deformated_key, deformated_name, delete_key );
    msi_free( deformated_key );

    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, ui_key_str );
    MSI_RecordSetStringW( uirow, 2, deformated_name );

    ui_actiondata( package, szRemoveRegistryValues, uirow );
    msiobj_release( &uirow->hdr );

    msi_free( ui_key_str );
    msi_free( deformated_name );
    return ERROR_SUCCESS;
}

static UINT ITERATE_RemoveRegistryValuesOnInstall( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPCWSTR component, name, key_str, root_key_str;
    LPWSTR deformated_key, deformated_name, ui_key_str;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    BOOL delete_key = FALSE;
    HKEY hkey_root;
    UINT size;
    INT root;

    ui_progress( package, 2, 0, 0, 0 );

    component = MSI_RecordGetString( row, 5 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    if ((name = MSI_RecordGetString( row, 4 )))
    {
        if (name[0] == '-' && !name[1])
        {
            delete_key = TRUE;
            name = NULL;
        }
    }

    root = MSI_RecordGetInteger( row, 2 );
    key_str = MSI_RecordGetString( row, 3 );

    root_key_str = get_root_key( package, root, &hkey_root );
    if (!root_key_str)
        return ERROR_SUCCESS;

    deformat_string( package, key_str, &deformated_key );
    size = strlenW( deformated_key ) + strlenW( root_key_str ) + 1;
    ui_key_str = msi_alloc( size * sizeof(WCHAR) );
    strcpyW( ui_key_str, root_key_str );
    strcatW( ui_key_str, deformated_key );

    deformat_string( package, name, &deformated_name );

    delete_reg_key_or_value( hkey_root, deformated_key, deformated_name, delete_key );
    msi_free( deformated_key );

    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, ui_key_str );
    MSI_RecordSetStringW( uirow, 2, deformated_name );

    ui_actiondata( package, szRemoveRegistryValues, uirow );
    msiobj_release( &uirow->hdr );

    msi_free( ui_key_str );
    msi_free( deformated_name );
    return ERROR_SUCCESS;
}

static UINT ACTION_RemoveRegistryValues( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;
    static const WCHAR registry_query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','R','e','g','i','s','t','r','y','`',0 };
    static const WCHAR remove_registry_query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','R','e','m','o','v','e','R','e','g','i','s','t','r','y','`',0 };

    /* increment progress bar each time action data is sent */
    ui_progress( package, 1, REG_PROGRESS_VALUE, 1, 0 );

    rc = MSI_DatabaseOpenViewW( package->db, registry_query, &view );
    if (rc == ERROR_SUCCESS)
    {
        rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveRegistryValuesOnUninstall, package );
        msiobj_release( &view->hdr );
        if (rc != ERROR_SUCCESS)
            return rc;
    }

    rc = MSI_DatabaseOpenViewW( package->db, remove_registry_query, &view );
    if (rc == ERROR_SUCCESS)
    {
        rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveRegistryValuesOnInstall, package );
        msiobj_release( &view->hdr );
        if (rc != ERROR_SUCCESS)
            return rc;
    }

    return ERROR_SUCCESS;
}

static UINT ACTION_InstallInitialize(MSIPACKAGE *package)
{
    package->script->CurrentlyScripting = TRUE;

    return ERROR_SUCCESS;
}


static UINT ACTION_InstallValidate(MSIPACKAGE *package)
{
    MSICOMPONENT *comp;
    DWORD progress = 0;
    DWORD total = 0;
    static const WCHAR q1[]=
        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
         '`','R','e','g','i','s','t','r','y','`',0};
    UINT rc;
    MSIQUERY * view;
    MSIFEATURE *feature;
    MSIFILE *file;

    TRACE("InstallValidate\n");

    rc = MSI_DatabaseOpenViewW(package->db, q1, &view);
    if (rc == ERROR_SUCCESS)
    {
        MSI_IterateRecords( view, &progress, NULL, package );
        msiobj_release( &view->hdr );
        total += progress * REG_PROGRESS_VALUE;
    }

    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
        total += COMPONENT_PROGRESS_VALUE;

    LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
        total += file->FileSize;

    ui_progress(package,0,total,0,0);

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        TRACE("Feature: %s; Installed: %i; Action %i; Request %i\n",
            debugstr_w(feature->Feature), feature->Installed, feature->Action,
            feature->ActionRequest);
    }
    
    return ERROR_SUCCESS;
}

static UINT ITERATE_LaunchConditions(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE* package = param;
    LPCWSTR cond = NULL; 
    LPCWSTR message = NULL;
    UINT r;

    static const WCHAR title[]=
        {'I','n','s','t','a','l','l',' ','F','a', 'i','l','e','d',0};

    cond = MSI_RecordGetString(row,1);

    r = MSI_EvaluateConditionW(package,cond);
    if (r == MSICONDITION_FALSE)
    {
        if ((gUILevel & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
        {
            LPWSTR deformated;
            message = MSI_RecordGetString(row,2);
            deformat_string(package,message,&deformated);
            MessageBoxW(NULL,deformated,title,MB_OK);
            msi_free(deformated);
        }

        return ERROR_INSTALL_FAILURE;
    }

    return ERROR_SUCCESS;
}

static UINT ACTION_LaunchConditions(MSIPACKAGE *package)
{
    UINT rc;
    MSIQUERY * view = NULL;
    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','`',0};

    TRACE("Checking launch conditions\n");

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

    rc = MSI_IterateRecords(view, NULL, ITERATE_LaunchConditions, package);
    msiobj_release(&view->hdr);

    return rc;
}

static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp )
{

    if (!cmp->KeyPath)
        return resolve_folder(package,cmp->Directory,FALSE,FALSE,TRUE,NULL);

    if (cmp->Attributes & msidbComponentAttributesRegistryKeyPath)
    {
        MSIRECORD * row = 0;
        UINT root,len;
        LPWSTR deformated,buffer,deformated_name;
        LPCWSTR key,name;
        static const WCHAR ExecSeqQuery[] =
            {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
             '`','R','e','g','i','s','t','r','y','`',' ',
             'W','H','E','R','E',' ', '`','R','e','g','i','s','t','r','y','`',
             ' ','=',' ' ,'\'','%','s','\'',0 };
        static const WCHAR fmt[]={'%','0','2','i',':','\\','%','s','\\',0};
        static const WCHAR fmt2[]=
            {'%','0','2','i',':','\\','%','s','\\','%','s',0};

        row = MSI_QueryGetRecord(package->db, ExecSeqQuery,cmp->KeyPath);
        if (!row)
            return NULL;

        root = MSI_RecordGetInteger(row,2);
        key = MSI_RecordGetString(row, 3);
        name = MSI_RecordGetString(row, 4);
        deformat_string(package, key , &deformated);
        deformat_string(package, name, &deformated_name);

        len = strlenW(deformated) + 6;
        if (deformated_name)
            len+=strlenW(deformated_name);

        buffer = msi_alloc( len *sizeof(WCHAR));

        if (deformated_name)
            sprintfW(buffer,fmt2,root,deformated,deformated_name);
        else
            sprintfW(buffer,fmt,root,deformated);

        msi_free(deformated);
        msi_free(deformated_name);
        msiobj_release(&row->hdr);

        return buffer;
    }
    else if (cmp->Attributes & msidbComponentAttributesODBCDataSource)
    {
        FIXME("UNIMPLEMENTED keypath as ODBC Source\n");
        return NULL;
    }
    else
    {
        MSIFILE *file = get_loaded_file( package, cmp->KeyPath );

        if (file)
            return strdupW( file->TargetPath );
    }
    return NULL;
}

static HKEY openSharedDLLsKey(void)
{
    HKEY hkey=0;
    static const WCHAR path[] =
        {'S','o','f','t','w','a','r','e','\\',
         'M','i','c','r','o','s','o','f','t','\\',
         'W','i','n','d','o','w','s','\\',
         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
         'S','h','a','r','e','d','D','L','L','s',0};

    RegCreateKeyW(HKEY_LOCAL_MACHINE,path,&hkey);
    return hkey;
}

static UINT ACTION_GetSharedDLLsCount(LPCWSTR dll)
{
    HKEY hkey;
    DWORD count=0;
    DWORD type;
    DWORD sz = sizeof(count);
    DWORD rc;
    
    hkey = openSharedDLLsKey();
    rc = RegQueryValueExW(hkey, dll, NULL, &type, (LPBYTE)&count, &sz);
    if (rc != ERROR_SUCCESS)
        count = 0;
    RegCloseKey(hkey);
    return count;
}

static UINT ACTION_WriteSharedDLLsCount(LPCWSTR path, UINT count)
{
    HKEY hkey;

    hkey = openSharedDLLsKey();
    if (count > 0)
        msi_reg_set_val_dword( hkey, path, count );
    else
        RegDeleteValueW(hkey,path);
    RegCloseKey(hkey);
    return count;
}

/*
 * Return TRUE if the count should be written out and FALSE if not
 */
static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp )
{
    MSIFEATURE *feature;
    INT count = 0;
    BOOL write = FALSE;

    /* only refcount DLLs */
    if (comp->KeyPath == NULL || 
        comp->Attributes & msidbComponentAttributesRegistryKeyPath || 
        comp->Attributes & msidbComponentAttributesODBCDataSource)
        write = FALSE;
    else
    {
        count = ACTION_GetSharedDLLsCount( comp->FullKeypath);
        write = (count > 0);

        if (comp->Attributes & msidbComponentAttributesSharedDllRefCount)
            write = TRUE;
    }

    /* increment counts */
    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        ComponentList *cl;

        if (feature->ActionRequest != INSTALLSTATE_LOCAL)
            continue;

        LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
        {
            if ( cl->component == comp )
                count++;
        }
    }

    /* decrement counts */
    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        ComponentList *cl;

        if (feature->ActionRequest != INSTALLSTATE_ABSENT)
            continue;

        LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
        {
            if ( cl->component == comp )
                count--;
        }
    }

    /* ref count all the files in the component */
    if (write)
    {
        MSIFILE *file;

        LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
        {
            if (file->Component == comp)
                ACTION_WriteSharedDLLsCount( file->TargetPath, count );
        }
    }
    
    /* add a count for permanent */
    if (comp->Attributes & msidbComponentAttributesPermanent)
        count ++;
    
    comp->RefCount = count;

    if (write)
        ACTION_WriteSharedDLLsCount( comp->FullKeypath, comp->RefCount );
}

static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
{
    WCHAR squished_pc[GUID_SIZE];
    WCHAR squished_cc[GUID_SIZE];
    UINT rc;
    MSICOMPONENT *comp;
    HKEY hkey;

    TRACE("\n");

    squash_guid(package->ProductCode,squished_pc);
    ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0);

    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
    {
        MSIRECORD * uirow;

        ui_progress(package,2,0,0,0);
        if (!comp->ComponentId)
            continue;

        squash_guid(comp->ComponentId,squished_cc);

        msi_free(comp->FullKeypath);
        comp->FullKeypath = resolve_keypath( package, comp );

        ACTION_RefCountComponent( package, comp );

        TRACE("Component %s (%s), Keypath=%s, RefCount=%i\n",
                            debugstr_w(comp->Component),
                            debugstr_w(squished_cc),
                            debugstr_w(comp->FullKeypath),
                            comp->RefCount);

        if (comp->ActionRequest == INSTALLSTATE_LOCAL ||
            comp->ActionRequest == INSTALLSTATE_SOURCE)
        {
            if (!comp->FullKeypath)
                continue;

            if (package->Context == MSIINSTALLCONTEXT_MACHINE)
                rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, szLocalSid,
                                                     &hkey, TRUE);
            else
                rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, NULL,
                                                     &hkey, TRUE);

            if (rc != ERROR_SUCCESS)
                continue;

            if (comp->Attributes & msidbComponentAttributesPermanent)
            {
                static const WCHAR szPermKey[] =
                    { '0','0','0','0','0','0','0','0','0','0','0','0',
                      '0','0','0','0','0','0','0','0','0','0','0','0',
                      '0','0','0','0','0','0','0','0',0 };

                msi_reg_set_val_str(hkey, szPermKey, comp->FullKeypath);
            }

            if (comp->Action == INSTALLSTATE_LOCAL)
                msi_reg_set_val_str(hkey, squished_pc, comp->FullKeypath);
            else
            {
                MSIFILE *file;
                MSIRECORD *row;
                LPWSTR ptr, ptr2;
                WCHAR source[MAX_PATH];
                WCHAR base[MAX_PATH];
                LPWSTR sourcepath;

                static const WCHAR fmt[] = {'%','0','2','d','\\',0};
                static const WCHAR query[] = {
                    'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
                    '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
                    '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ',
                    '>','=',' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ',
                    '`','D','i','s','k','I','d','`',0};

                file = get_loaded_file(package, comp->KeyPath);
                if (!file)
                    continue;

                row = MSI_QueryGetRecord(package->db, query, file->Sequence);
                sprintfW(source, fmt, MSI_RecordGetInteger(row, 1));
                ptr2 = strrchrW(source, '\\') + 1;
                msiobj_release(&row->hdr);

                lstrcpyW(base, package->PackagePath);
                ptr = strrchrW(base, '\\');
                *(ptr + 1) = '\0';

                sourcepath = resolve_file_source(package, file);
                ptr = sourcepath + lstrlenW(base);
                lstrcpyW(ptr2, ptr);
                msi_free(sourcepath);

                msi_reg_set_val_str(hkey, squished_pc, source);
            }
            RegCloseKey(hkey);
        }
        else if (comp->ActionRequest == INSTALLSTATE_ABSENT)
        {
            if (package->Context == MSIINSTALLCONTEXT_MACHINE)
                MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid);
            else
                MSIREG_DeleteUserDataComponentKey(comp->ComponentId, NULL);
        }
        comp->Action = comp->ActionRequest;

        /* UI stuff */
        uirow = MSI_CreateRecord(3);
        MSI_RecordSetStringW(uirow,1,package->ProductCode);
        MSI_RecordSetStringW(uirow,2,comp->ComponentId);
        MSI_RecordSetStringW(uirow,3,comp->FullKeypath);
        ui_actiondata(package,szProcessComponents,uirow);
        msiobj_release( &uirow->hdr );
    }

    return ERROR_SUCCESS;
}

typedef struct {
    CLSID       clsid;
    LPWSTR      source;

    LPWSTR      path;
    ITypeLib    *ptLib;
} typelib_struct;

static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType, 
                                       LPWSTR lpszName, LONG_PTR lParam)
{
    TLIBATTR *attr;
    typelib_struct *tl_struct = (typelib_struct*) lParam;
    static const WCHAR fmt[] = {'%','s','\\','%','i',0};
    int sz; 
    HRESULT res;

    if (!IS_INTRESOURCE(lpszName))
    {
        ERR("Not Int Resource Name %s\n",debugstr_w(lpszName));
        return TRUE;
    }

    sz = strlenW(tl_struct->source)+4;
    sz *= sizeof(WCHAR);

    if ((INT_PTR)lpszName == 1)
        tl_struct->path = strdupW(tl_struct->source);
    else
    {
        tl_struct->path = msi_alloc(sz);
        sprintfW(tl_struct->path,fmt,tl_struct->source, lpszName);
    }

    TRACE("trying %s\n", debugstr_w(tl_struct->path));
    res = LoadTypeLib(tl_struct->path,&tl_struct->ptLib);
    if (FAILED(res))
    {
        msi_free(tl_struct->path);
        tl_struct->path = NULL;

        return TRUE;
    }

    ITypeLib_GetLibAttr(tl_struct->ptLib, &attr);
    if (IsEqualGUID(&(tl_struct->clsid),&(attr->guid)))
    {
        ITypeLib_ReleaseTLibAttr(tl_struct->ptLib, attr);
        return FALSE;
    }

    msi_free(tl_struct->path);
    tl_struct->path = NULL;

    ITypeLib_ReleaseTLibAttr(tl_struct->ptLib, attr);
    ITypeLib_Release(tl_struct->ptLib);

    return TRUE;
}

static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE* package = param;
    LPCWSTR component;
    MSICOMPONENT *comp;
    MSIFILE *file;
    typelib_struct tl_struct;
    ITypeLib *tlib;
    HMODULE module;
    HRESULT hr;

    component = MSI_RecordGetString(row,3);
    comp = get_loaded_component(package,component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    file = get_loaded_file( package, comp->KeyPath ); 
    if (!file)
        return ERROR_SUCCESS;

    ui_actiondata( package, szRegisterTypeLibraries, row );

    module = LoadLibraryExW( file->TargetPath, NULL, LOAD_LIBRARY_AS_DATAFILE );
    if (module)
    {
        LPCWSTR guid;
        guid = MSI_RecordGetString(row,1);
        CLSIDFromString((LPCWSTR)guid, &tl_struct.clsid);
        tl_struct.source = strdupW( file->TargetPath );
        tl_struct.path = NULL;

        EnumResourceNamesW(module, szTYPELIB, Typelib_EnumResNameProc,
                        (LONG_PTR)&tl_struct);

        if (tl_struct.path)
        {
            LPWSTR help = NULL;
            LPCWSTR helpid;
            HRESULT res;

            helpid = MSI_RecordGetString(row,6);

            if (helpid)
                help = resolve_folder(package,helpid,FALSE,FALSE,TRUE,NULL);
            res = RegisterTypeLib(tl_struct.ptLib,tl_struct.path,help);
            msi_free(help);

            if (FAILED(res))
                ERR("Failed to register type library %s\n",
                        debugstr_w(tl_struct.path));
            else
                TRACE("Registered %s\n", debugstr_w(tl_struct.path));

            ITypeLib_Release(tl_struct.ptLib);
            msi_free(tl_struct.path);
        }
        else
            ERR("Failed to load type library %s\n",
                    debugstr_w(tl_struct.source));

        FreeLibrary(module);
        msi_free(tl_struct.source);
    }
    else
    {
        hr = LoadTypeLibEx(file->TargetPath, REGKIND_REGISTER, &tlib);
        if (FAILED(hr))
        {
            ERR("Failed to load type library: %08x\n", hr);
            return ERROR_INSTALL_FAILURE;
        }

        ITypeLib_Release(tlib);
    }

    return ERROR_SUCCESS;
}

static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
{
    /* 
     * OK this is a bit confusing.. I am given a _Component key and I believe
     * that the file that is being registered as a type library is the "key file
     * of that component" which I interpret to mean "The file in the KeyPath of
     * that component".
     */
    UINT rc;
    MSIQUERY * view;
    static const WCHAR Query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','T','y','p','e','L','i','b','`',0};

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

    rc = MSI_IterateRecords(view, NULL, ITERATE_RegisterTypeLibraries, package);
    msiobj_release(&view->hdr);
    return rc;
}

static UINT ITERATE_UnregisterTypeLibraries( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPCWSTR component, guid;
    MSICOMPONENT *comp;
    GUID libid;
    UINT version;
    LCID language;
    SYSKIND syskind;
    HRESULT hr;

    component = MSI_RecordGetString( row, 3 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_ABSENT;

    ui_actiondata( package, szUnregisterTypeLibraries, row );

    guid = MSI_RecordGetString( row, 1 );
    CLSIDFromString( (LPCWSTR)guid, &libid );
    version = MSI_RecordGetInteger( row, 4 );
    language = MSI_RecordGetInteger( row, 2 );

#ifdef _WIN64
    syskind = SYS_WIN64;
#else
    syskind = SYS_WIN32;
#endif

    hr = UnRegisterTypeLib( &libid, (version >> 8) & 0xffff, version & 0xff, language, syskind );
    if (FAILED(hr))
    {
        WARN("Failed to unregister typelib: %08x\n", hr);
    }

    return ERROR_SUCCESS;
}

static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','T','y','p','e','L','i','b','`',0};

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_UnregisterTypeLibraries, package );
    msiobj_release( &view->hdr );
    return rc;
}

static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row )
{
    static const WCHAR szlnk[] = {'.','l','n','k',0};
    LPCWSTR directory, extension;
    LPWSTR link_folder, link_file, filename;

    directory = MSI_RecordGetString( row, 2 );
    link_folder = resolve_folder( package, directory, FALSE, FALSE, TRUE, NULL );

    /* may be needed because of a bug somewhere else */
    create_full_pathW( link_folder );

    filename = msi_dup_record_field( row, 3 );
    reduce_to_longfilename( filename );

    extension = strchrW( filename, '.' );
    if (!extension || strcmpiW( extension, szlnk ))
    {
        int len = strlenW( filename );
        filename = msi_realloc( filename, len * sizeof(WCHAR) + sizeof(szlnk) );
        memcpy( filename + len, szlnk, sizeof(szlnk) );
    }
    link_file = build_directory_name( 2, link_folder, filename );
    msi_free( link_folder );
    msi_free( filename );

    return link_file;
}

static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE *package = param;
    LPWSTR link_file, deformated, path;
    LPCWSTR component, target;
    MSICOMPONENT *comp;
    IShellLinkW *sl = NULL;
    IPersistFile *pf = NULL;
    HRESULT res;

    component = MSI_RecordGetString(row, 4);
    comp = get_loaded_component(package, component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    ui_actiondata(package,szCreateShortcuts,row);

    res = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                    &IID_IShellLinkW, (LPVOID *) &sl );

    if (FAILED( res ))
    {
        ERR("CLSID_ShellLink not available\n");
        goto err;
    }

    res = IShellLinkW_QueryInterface( sl, &IID_IPersistFile,(LPVOID*) &pf );
    if (FAILED( res ))
    {
        ERR("QueryInterface(IID_IPersistFile) failed\n");
        goto err;
    }

    target = MSI_RecordGetString(row, 5);
    if (strchrW(target, '['))
    {
        deformat_string(package, target, &deformated);
        IShellLinkW_SetPath(sl,deformated);
        msi_free(deformated);
    }
    else
    {
        FIXME("poorly handled shortcut format, advertised shortcut\n");
        IShellLinkW_SetPath(sl,comp->FullKeypath);
    }

    if (!MSI_RecordIsNull(row,6))
    {
        LPCWSTR arguments = MSI_RecordGetString(row, 6);
        deformat_string(package, arguments, &deformated);
        IShellLinkW_SetArguments(sl,deformated);
        msi_free(deformated);
    }

    if (!MSI_RecordIsNull(row,7))
    {
        LPCWSTR description = MSI_RecordGetString(row, 7);
        IShellLinkW_SetDescription(sl, description);
    }

    if (!MSI_RecordIsNull(row,8))
        IShellLinkW_SetHotkey(sl,MSI_RecordGetInteger(row,8));

    if (!MSI_RecordIsNull(row,9))
    {
        INT index; 
        LPCWSTR icon = MSI_RecordGetString(row, 9);

        path = build_icon_path(package, icon);
        index = MSI_RecordGetInteger(row,10);

        /* no value means 0 */
        if (index == MSI_NULL_INTEGER)
            index = 0;

        IShellLinkW_SetIconLocation(sl, path, index);
        msi_free(path);
    }

    if (!MSI_RecordIsNull(row,11))
        IShellLinkW_SetShowCmd(sl,MSI_RecordGetInteger(row,11));

    if (!MSI_RecordIsNull(row,12))
    {
        LPCWSTR wkdir = MSI_RecordGetString(row, 12);
        path = resolve_folder(package, wkdir, FALSE, FALSE, TRUE, NULL);
        if (path)
            IShellLinkW_SetWorkingDirectory(sl, path);
        msi_free(path);
    }

    link_file = get_link_file(package, row);

    TRACE("Writing shortcut to %s\n", debugstr_w(link_file));
    IPersistFile_Save(pf, link_file, FALSE);

    msi_free(link_file);

err:
    if (pf)
        IPersistFile_Release( pf );
    if (sl)
        IShellLinkW_Release( sl );

    return ERROR_SUCCESS;
}

static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
{
    UINT rc;
    HRESULT res;
    MSIQUERY * view;
    static const WCHAR Query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','S','h','o','r','t','c','u','t','`',0};

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

    res = CoInitialize( NULL );

    rc = MSI_IterateRecords(view, NULL, ITERATE_CreateShortcuts, package);
    msiobj_release(&view->hdr);

    if (SUCCEEDED(res))
        CoUninitialize();

    return rc;
}

static UINT ITERATE_RemoveShortcuts( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPWSTR link_file;
    LPCWSTR component;
    MSICOMPONENT *comp;

    component = MSI_RecordGetString( row, 4 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_ABSENT;

    ui_actiondata( package, szRemoveShortcuts, row );

    link_file = get_link_file( package, row );

    TRACE("Removing shortcut file %s\n", debugstr_w( link_file ));
    if (!DeleteFileW( link_file ))
    {
        WARN("Failed to remove shortcut file %u\n", GetLastError());
    }
    msi_free( link_file );

    return ERROR_SUCCESS;
}

static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','S','h','o','r','t','c','u','t','`',0};

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveShortcuts, package );
    msiobj_release( &view->hdr );

    return rc;
}

static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE* package = param;
    HANDLE the_file;
    LPWSTR FilePath;
    LPCWSTR FileName;
    CHAR buffer[1024];
    DWORD sz;
    UINT rc;

    FileName = MSI_RecordGetString(row,1);
    if (!FileName)
    {
        ERR("Unable to get FileName\n");
        return ERROR_SUCCESS;
    }

    FilePath = build_icon_path(package,FileName);

    TRACE("Creating icon file at %s\n",debugstr_w(FilePath));

    the_file = CreateFileW(FilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL, NULL);

    if (the_file == INVALID_HANDLE_VALUE)
    {
        ERR("Unable to create file %s\n",debugstr_w(FilePath));
        msi_free(FilePath);
        return ERROR_SUCCESS;
    }

    do 
    {
        DWORD write;
        sz = 1024;
        rc = MSI_RecordReadStream(row,2,buffer,&sz);
        if (rc != ERROR_SUCCESS)
        {
            ERR("Failed to get stream\n");
            CloseHandle(the_file);  
            DeleteFileW(FilePath);
            break;
        }
        WriteFile(the_file,buffer,sz,&write,NULL);
    } while (sz == 1024);

    msi_free(FilePath);
    CloseHandle(the_file);

    return ERROR_SUCCESS;
}

static UINT msi_publish_icons(MSIPACKAGE *package)
{
    UINT r;
    MSIQUERY *view;

    static const WCHAR query[]= {
        'S','E','L','E','C','T',' ','*',' ',
        'F','R','O','M',' ','`','I','c','o','n','`',0};

    r = MSI_DatabaseOpenViewW(package->db, query, &view);
    if (r == ERROR_SUCCESS)
    {
        MSI_IterateRecords(view, NULL, ITERATE_PublishIcon, package);
        msiobj_release(&view->hdr);
    }

    return ERROR_SUCCESS;
}

static UINT msi_publish_sourcelist(MSIPACKAGE *package, HKEY hkey)
{
    UINT r;
    HKEY source;
    LPWSTR buffer;
    MSIMEDIADISK *disk;
    MSISOURCELISTINFO *info;

    r = RegCreateKeyW(hkey, szSourceList, &source);
    if (r != ERROR_SUCCESS)
        return r;

    RegCloseKey(source);

    buffer = strrchrW(package->PackagePath, '\\') + 1;
    r = MsiSourceListSetInfoW(package->ProductCode, NULL,
                              package->Context, MSICODE_PRODUCT,
                              INSTALLPROPERTY_PACKAGENAMEW, buffer);
    if (r != ERROR_SUCCESS)
        return r;

    r = MsiSourceListSetInfoW(package->ProductCode, NULL,
                              package->Context, MSICODE_PRODUCT,
                              INSTALLPROPERTY_MEDIAPACKAGEPATHW, szEmpty);
    if (r != ERROR_SUCCESS)
        return r;

    r = MsiSourceListSetInfoW(package->ProductCode, NULL,
                              package->Context, MSICODE_PRODUCT,
                              INSTALLPROPERTY_DISKPROMPTW, szEmpty);
    if (r != ERROR_SUCCESS)
        return r;

    LIST_FOR_EACH_ENTRY(info, &package->sourcelist_info, MSISOURCELISTINFO, entry)
    {
        if (!lstrcmpW(info->property, INSTALLPROPERTY_LASTUSEDSOURCEW))
            msi_set_last_used_source(package->ProductCode, NULL, info->context,
                                     info->options, info->value);
        else
            MsiSourceListSetInfoW(package->ProductCode, NULL,
                                  info->context, info->options,
                                  info->property, info->value);
    }

    LIST_FOR_EACH_ENTRY(disk, &package->sourcelist_media, MSIMEDIADISK, entry)
    {
        MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
                                   disk->context, disk->options,
                                   disk->disk_id, disk->volume_label, disk->disk_prompt);
    }

    return ERROR_SUCCESS;
}

static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey)
{
    MSIHANDLE hdb, suminfo;
    WCHAR guids[MAX_PATH];
    WCHAR packcode[SQUISH_GUID_SIZE];
    LPWSTR buffer;
    LPWSTR ptr;
    DWORD langid;
    DWORD size;
    UINT r;

    static const WCHAR szProductLanguage[] =
        {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
    static const WCHAR szARPProductIcon[] =
        {'A','R','P','P','R','O','D','U','C','T','I','C','O','N',0};
    static const WCHAR szProductVersion[] =
        {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
    static const WCHAR szAssignment[] =
        {'A','s','s','i','g','n','m','e','n','t',0};
    static const WCHAR szAdvertiseFlags[] =
        {'A','d','v','e','r','t','i','s','e','F','l','a','g','s',0};
    static const WCHAR szClients[] =
        {'C','l','i','e','n','t','s',0};
    static const WCHAR szColon[] = {':',0};

    buffer = msi_dup_property(package->db, INSTALLPROPERTY_PRODUCTNAMEW);
    msi_reg_set_val_str(hkey, INSTALLPROPERTY_PRODUCTNAMEW, buffer);
    msi_free(buffer);

    langid = msi_get_property_int(package->db, szProductLanguage, 0);
    msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid);

    /* FIXME */
    msi_reg_set_val_dword(hkey, INSTALLPROPERTY_AUTHORIZED_LUA_APPW, 0);

    buffer = msi_dup_property(package->db, szARPProductIcon);
    if (buffer)
    {
        LPWSTR path = build_icon_path(package,buffer);
        msi_reg_set_val_str(hkey, INSTALLPROPERTY_PRODUCTICONW, path);
        msi_free(path);
        msi_free(buffer);
    }

    buffer = msi_dup_property(package->db, szProductVersion);
    if (buffer)
    {
        DWORD verdword = msi_version_str_to_dword(buffer);
        msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONW, verdword);
        msi_free(buffer);
    }

    msi_reg_set_val_dword(hkey, szAssignment, 0);
    msi_reg_set_val_dword(hkey, szAdvertiseFlags, 0x184);
    msi_reg_set_val_dword(hkey, INSTALLPROPERTY_INSTANCETYPEW, 0);
    msi_reg_set_val_str(hkey, szClients, szColon);

    hdb = alloc_msihandle(&package->db->hdr);
    if (!hdb)
        return ERROR_NOT_ENOUGH_MEMORY;

    r = MsiGetSummaryInformationW(hdb, NULL, 0, &suminfo);
    MsiCloseHandle(hdb);
    if (r != ERROR_SUCCESS)
        goto done;

    size = MAX_PATH;
    r = MsiSummaryInfoGetPropertyW(suminfo, PID_REVNUMBER, NULL, NULL,
                                   NULL, guids, &size);
    if (r != ERROR_SUCCESS)
        goto done;

    ptr = strchrW(guids, ';');
    if (ptr) *ptr = 0;
    squash_guid(guids, packcode);
    msi_reg_set_val_str(hkey, INSTALLPROPERTY_PACKAGECODEW, packcode);

done:
    MsiCloseHandle(suminfo);
    return ERROR_SUCCESS;
}

static UINT msi_publish_upgrade_code(MSIPACKAGE *package)
{
    UINT r;
    HKEY hkey;
    LPWSTR upgrade;
    WCHAR squashed_pc[SQUISH_GUID_SIZE];

    static const WCHAR szUpgradeCode[] =
        {'U','p','g','r','a','d','e','C','o','d','e',0};

    upgrade = msi_dup_property(package->db, szUpgradeCode);
    if (!upgrade)
        return ERROR_SUCCESS;

    if (package->Context == MSIINSTALLCONTEXT_MACHINE)
    {
        r = MSIREG_OpenClassesUpgradeCodesKey(upgrade, &hkey, TRUE);
        if (r != ERROR_SUCCESS)
            goto done;
    }
    else
    {
        r = MSIREG_OpenUserUpgradeCodesKey(upgrade, &hkey, TRUE);
        if (r != ERROR_SUCCESS)
            goto done;
    }

    squash_guid(package->ProductCode, squashed_pc);
    msi_reg_set_val_str(hkey, squashed_pc, NULL);

    RegCloseKey(hkey);

done:
    msi_free(upgrade);
    return r;
}

static BOOL msi_check_publish(MSIPACKAGE *package)
{
    MSIFEATURE *feature;

    LIST_FOR_EACH_ENTRY(feature, &package->features, MSIFEATURE, entry)
    {
        if (feature->ActionRequest == INSTALLSTATE_LOCAL)
            return TRUE;
    }

    return FALSE;
}

static BOOL msi_check_unpublish(MSIPACKAGE *package)
{
    MSIFEATURE *feature;

    LIST_FOR_EACH_ENTRY(feature, &package->features, MSIFEATURE, entry)
    {
        if (feature->ActionRequest != INSTALLSTATE_ABSENT)
            return FALSE;
    }

    return TRUE;
}

static UINT msi_publish_patches( MSIPACKAGE *package, HKEY prodkey )
{
    static const WCHAR szAllPatches[] = {'A','l','l','P','a','t','c','h','e','s',0};
    WCHAR patch_squashed[GUID_SIZE];
    HKEY patches_key = NULL, product_patches_key;
    LONG res;
    MSIPATCHINFO *patch;
    UINT r;
    WCHAR *p, *all_patches = NULL;
    DWORD len = 0;

    res = RegCreateKeyExW( prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches_key, NULL );
    if (res != ERROR_SUCCESS)
        return ERROR_FUNCTION_FAILED;

    r = MSIREG_OpenUserDataProductPatchesKey( package->ProductCode, package->Context, &product_patches_key, TRUE );
    if (r != ERROR_SUCCESS)
        goto done;

    LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry )
    {
        squash_guid( patch->patchcode, patch_squashed );
        len += strlenW( patch_squashed ) + 1;
    }

    p = all_patches = msi_alloc( (len + 1) * sizeof(WCHAR) );
    if (!all_patches)
        goto done;

    LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry )
    {
        HKEY patch_key;

        squash_guid( patch->patchcode, p );
        p += strlenW( p ) + 1;

        res = RegSetValueExW( patches_key, patch_squashed, 0, REG_SZ,
                              (const BYTE *)patch->transforms,
                              (strlenW(patch->transforms) + 1) * sizeof(WCHAR) );
        if (res != ERROR_SUCCESS)
            goto done;

        r = MSIREG_OpenUserDataPatchKey( patch->patchcode, package->Context, &patch_key, TRUE );
        if (r != ERROR_SUCCESS)
            goto done;

        res = RegSetValueExW( patch_key, szLocalPackage, 0, REG_SZ,
                              (const BYTE *)patch->localfile,
                              (strlenW(patch->localfile) + 1) * sizeof(WCHAR) );
        RegCloseKey( patch_key );
        if (res != ERROR_SUCCESS)
            goto done;

        res = RegCreateKeyExW( product_patches_key, patch_squashed, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patch_key, NULL );
        RegCloseKey( patch_key );
        if (res != ERROR_SUCCESS)
            goto done;
    }

    all_patches[len] = 0;
    res = RegSetValueExW( patches_key, szPatches, 0, REG_MULTI_SZ,
                          (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) );
    if (res != ERROR_SUCCESS)
        goto done;

    res = RegSetValueExW( product_patches_key, szAllPatches, 0, REG_MULTI_SZ,
                          (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) );
    if (res != ERROR_SUCCESS)
        r = ERROR_FUNCTION_FAILED;

done:
    RegCloseKey( product_patches_key );
    RegCloseKey( patches_key );
    msi_free( all_patches );
    return r;
}

/*
 * 99% of the work done here is only done for 
 * advertised installs. However this is where the
 * Icon table is processed and written out
 * so that is what I am going to do here.
 */
static UINT ACTION_PublishProduct(MSIPACKAGE *package)
{
    UINT rc;
    HKEY hukey = NULL, hudkey = NULL;
    MSIRECORD *uirow;

    /* FIXME: also need to publish if the product is in advertise mode */
    if (!msi_check_publish(package))
        return ERROR_SUCCESS;

    rc = MSIREG_OpenProductKey(package->ProductCode, NULL, package->Context,
                               &hukey, TRUE);
    if (rc != ERROR_SUCCESS)
        goto end;

    rc = MSIREG_OpenUserDataProductKey(package->ProductCode, package->Context,
                                       NULL, &hudkey, TRUE);
    if (rc != ERROR_SUCCESS)
        goto end;

    rc = msi_publish_upgrade_code(package);
    if (rc != ERROR_SUCCESS)
        goto end;

    if (!list_empty(&package->patches))
    {
        rc = msi_publish_patches(package, hukey);
        if (rc != ERROR_SUCCESS)
            goto end;
    }

    rc = msi_publish_product_properties(package, hukey);
    if (rc != ERROR_SUCCESS)
        goto end;

    rc = msi_publish_sourcelist(package, hukey);
    if (rc != ERROR_SUCCESS)
        goto end;

    rc = msi_publish_icons(package);

end:
    uirow = MSI_CreateRecord( 1 );
    MSI_RecordSetStringW( uirow, 1, package->ProductCode );
    ui_actiondata( package, szPublishProduct, uirow );
    msiobj_release( &uirow->hdr );

    RegCloseKey(hukey);
    RegCloseKey(hudkey);

    return rc;
}

static WCHAR *get_ini_file_name( MSIPACKAGE *package, MSIRECORD *row )
{
    WCHAR *filename, *ptr, *folder, *ret;
    const WCHAR *dirprop;

    filename = msi_dup_record_field( row, 2 );
    if (filename && (ptr = strchrW( filename, '|' )))
        ptr++;
    else
        ptr = filename;

    dirprop = MSI_RecordGetString( row, 3 );
    if (dirprop)
    {
        folder = resolve_folder( package, dirprop, FALSE, FALSE, TRUE, NULL );
        if (!folder)
            folder = msi_dup_property( package->db, dirprop );
    }
    else
        folder = msi_dup_property( package->db, szWindowsFolder );

    if (!folder)
    {
        ERR("Unable to resolve folder %s\n", debugstr_w(dirprop));
        msi_free( filename );
        return NULL;
    }

    ret = build_directory_name( 2, folder, ptr );

    msi_free( filename );
    msi_free( folder );
    return ret;
}

static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE *package = param;
    LPCWSTR component, section, key, value, identifier;
    LPWSTR deformated_section, deformated_key, deformated_value, fullname;
    MSIRECORD * uirow;
    INT action;
    MSICOMPONENT *comp;

    component = MSI_RecordGetString(row, 8);
    comp = get_loaded_component(package,component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    identifier = MSI_RecordGetString(row,1); 
    section = MSI_RecordGetString(row,4);
    key = MSI_RecordGetString(row,5);
    value = MSI_RecordGetString(row,6);
    action = MSI_RecordGetInteger(row,7);

    deformat_string(package,section,&deformated_section);
    deformat_string(package,key,&deformated_key);
    deformat_string(package,value,&deformated_value);

    fullname = get_ini_file_name(package, row);

    if (action == 0)
    {
        TRACE("Adding value %s to section %s in %s\n",
                debugstr_w(deformated_key), debugstr_w(deformated_section),
                debugstr_w(fullname));
        WritePrivateProfileStringW(deformated_section, deformated_key,
                                   deformated_value, fullname);
    }
    else if (action == 1)
    {
        WCHAR returned[10];
        GetPrivateProfileStringW(deformated_section, deformated_key, NULL,
                                 returned, 10, fullname);
        if (returned[0] == 0)
        {
            TRACE("Adding value %s to section %s in %s\n",
                    debugstr_w(deformated_key), debugstr_w(deformated_section),
                    debugstr_w(fullname));

            WritePrivateProfileStringW(deformated_section, deformated_key,
                                       deformated_value, fullname);
        }
    }
    else if (action == 3)
        FIXME("Append to existing section not yet implemented\n");

    uirow = MSI_CreateRecord(4);
    MSI_RecordSetStringW(uirow,1,identifier);
    MSI_RecordSetStringW(uirow,2,deformated_section);
    MSI_RecordSetStringW(uirow,3,deformated_key);
    MSI_RecordSetStringW(uirow,4,deformated_value);
    ui_actiondata(package,szWriteIniValues,uirow);
    msiobj_release( &uirow->hdr );

    msi_free(fullname);
    msi_free(deformated_key);
    msi_free(deformated_value);
    msi_free(deformated_section);
    return ERROR_SUCCESS;
}

static UINT ACTION_WriteIniValues(MSIPACKAGE *package)
{
    UINT rc;
    MSIQUERY * view;
    static const WCHAR ExecSeqQuery[] = 
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','I','n','i','F','i','l','e','`',0};

    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
    if (rc != ERROR_SUCCESS)
    {
        TRACE("no IniFile table\n");
        return ERROR_SUCCESS;
    }

    rc = MSI_IterateRecords(view, NULL, ITERATE_WriteIniValues, package);
    msiobj_release(&view->hdr);
    return rc;
}

static UINT ITERATE_RemoveIniValuesOnUninstall( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPCWSTR component, section, key, value, identifier;
    LPWSTR deformated_section, deformated_key, deformated_value, filename;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    INT action;

    component = MSI_RecordGetString( row, 8 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_ABSENT;

    identifier = MSI_RecordGetString( row, 1 );
    section = MSI_RecordGetString( row, 4 );
    key = MSI_RecordGetString( row, 5 );
    value = MSI_RecordGetString( row, 6 );
    action = MSI_RecordGetInteger( row, 7 );

    deformat_string( package, section, &deformated_section );
    deformat_string( package, key, &deformated_key );
    deformat_string( package, value, &deformated_value );

    if (action == msidbIniFileActionAddLine || action == msidbIniFileActionCreateLine)
    {
        filename = get_ini_file_name( package, row );

        TRACE("Removing key %s from section %s in %s\n",
               debugstr_w(deformated_key), debugstr_w(deformated_section), debugstr_w(filename));

        if (!WritePrivateProfileStringW( deformated_section, deformated_key, NULL, filename ))
        {
            WARN("Unable to remove key %u\n", GetLastError());
        }
        msi_free( filename );
    }
    else
        FIXME("Unsupported action %d\n", action);


    uirow = MSI_CreateRecord( 4 );
    MSI_RecordSetStringW( uirow, 1, identifier );
    MSI_RecordSetStringW( uirow, 2, deformated_section );
    MSI_RecordSetStringW( uirow, 3, deformated_key );
    MSI_RecordSetStringW( uirow, 4, deformated_value );
    ui_actiondata( package, szRemoveIniValues, uirow );
    msiobj_release( &uirow->hdr );

    msi_free( deformated_key );
    msi_free( deformated_value );
    msi_free( deformated_section );
    return ERROR_SUCCESS;
}

static UINT ITERATE_RemoveIniValuesOnInstall( MSIRECORD *row, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPCWSTR component, section, key, value, identifier;
    LPWSTR deformated_section, deformated_key, deformated_value, filename;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    INT action;

    component = MSI_RecordGetString( row, 8 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    identifier = MSI_RecordGetString( row, 1 );
    section = MSI_RecordGetString( row, 4 );
    key = MSI_RecordGetString( row, 5 );
    value = MSI_RecordGetString( row, 6 );
    action = MSI_RecordGetInteger( row, 7 );

    deformat_string( package, section, &deformated_section );
    deformat_string( package, key, &deformated_key );
    deformat_string( package, value, &deformated_value );

    if (action == msidbIniFileActionRemoveLine)
    {
        filename = get_ini_file_name( package, row );

        TRACE("Removing key %s from section %s in %s\n",
               debugstr_w(deformated_key), debugstr_w(deformated_section), debugstr_w(filename));

        if (!WritePrivateProfileStringW( deformated_section, deformated_key, NULL, filename ))
        {
            WARN("Unable to remove key %u\n", GetLastError());
        }
        msi_free( filename );
    }
    else
        FIXME("Unsupported action %d\n", action);

    uirow = MSI_CreateRecord( 4 );
    MSI_RecordSetStringW( uirow, 1, identifier );
    MSI_RecordSetStringW( uirow, 2, deformated_section );
    MSI_RecordSetStringW( uirow, 3, deformated_key );
    MSI_RecordSetStringW( uirow, 4, deformated_value );
    ui_actiondata( package, szRemoveIniValues, uirow );
    msiobj_release( &uirow->hdr );

    msi_free( deformated_key );
    msi_free( deformated_value );
    msi_free( deformated_section );
    return ERROR_SUCCESS;
}

static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','I','n','i','F','i','l','e','`',0};
    static const WCHAR remove_query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','R','e','m','o','v','e','I','n','i','F','i','l','e','`',0};

    rc = MSI_DatabaseOpenViewW( package->db, query, &view );
    if (rc == ERROR_SUCCESS)
    {
        rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveIniValuesOnUninstall, package );
        msiobj_release( &view->hdr );
        if (rc != ERROR_SUCCESS)
            return rc;
    }

    rc = MSI_DatabaseOpenViewW( package->db, remove_query, &view );
    if (rc == ERROR_SUCCESS)
    {
        rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveIniValuesOnInstall, package );
        msiobj_release( &view->hdr );
        if (rc != ERROR_SUCCESS)
            return rc;
    }

    return ERROR_SUCCESS;
}

static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param)
{
    MSIPACKAGE *package = param;
    LPCWSTR filename;
    LPWSTR FullName;
    MSIFILE *file;
    DWORD len;
    static const WCHAR ExeStr[] =
        {'r','e','g','s','v','r','3','2','.','e','x','e',' ','\"',0};
    static const WCHAR close[] =  {'\"',0};
    STARTUPINFOW si;
    PROCESS_INFORMATION info;
    BOOL brc;
    MSIRECORD *uirow;
    LPWSTR uipath, p;

    memset(&si,0,sizeof(STARTUPINFOW));

    filename = MSI_RecordGetString(row,1);
    file = get_loaded_file( package, filename );

    if (!file)
    {
        ERR("Unable to find file id %s\n",debugstr_w(filename));
        return ERROR_SUCCESS;
    }

    len = strlenW(ExeStr) + strlenW( file->TargetPath ) + 2;

    FullName = msi_alloc(len*sizeof(WCHAR));
    strcpyW(FullName,ExeStr);
    strcatW( FullName, file->TargetPath );
    strcatW(FullName,close);

    TRACE("Registering %s\n",debugstr_w(FullName));
    brc = CreateProcessW(NULL, FullName, NULL, NULL, FALSE, 0, NULL, c_colon,
                    &si, &info);

    if (brc)
    {
        CloseHandle(info.hThread);
        msi_dialog_check_messages(info.hProcess);
        CloseHandle(info.hProcess);
    }

    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, filename );
    uipath = strdupW( file->TargetPath );
    if ((p = strrchrW( uipath,'\\' ))) *p = 0;
    MSI_RecordSetStringW( uirow, 2, uipath );
    ui_actiondata( package, szSelfRegModules, uirow );
    msiobj_release( &uirow->hdr );

    msi_free( FullName );
    msi_free( uipath );
    return ERROR_SUCCESS;
}

static UINT ACTION_SelfRegModules(MSIPACKAGE *package)
{
    UINT rc;
    MSIQUERY * view;
    static const WCHAR ExecSeqQuery[] = 
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','S','e','l','f','R','e','g','`',0};

    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
    if (rc != ERROR_SUCCESS)
    {
        TRACE("no SelfReg table\n");
        return ERROR_SUCCESS;
    }

    MSI_IterateRecords(view, NULL, ITERATE_SelfRegModules, package);
    msiobj_release(&view->hdr);

    return ERROR_SUCCESS;
}

static UINT ITERATE_SelfUnregModules( MSIRECORD *row, LPVOID param )
{
    static const WCHAR regsvr32[] =
        {'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','u',' ','\"',0};
    static const WCHAR close[] =  {'\"',0};
    MSIPACKAGE *package = param;
    LPCWSTR filename;
    LPWSTR cmdline;
    MSIFILE *file;
    DWORD len;
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    BOOL ret;
    MSIRECORD *uirow;
    LPWSTR uipath, p;

    memset( &si, 0, sizeof(STARTUPINFOW) );

    filename = MSI_RecordGetString( row, 1 );
    file = get_loaded_file( package, filename );

    if (!file)
    {
        ERR("Unable to find file id %s\n", debugstr_w(filename));
        return ERROR_SUCCESS;
    }

    len = strlenW( regsvr32 ) + strlenW( file->TargetPath ) + 2;

    cmdline = msi_alloc( len * sizeof(WCHAR) );
    strcpyW( cmdline, regsvr32 );
    strcatW( cmdline, file->TargetPath );
    strcatW( cmdline, close );

    TRACE("Unregistering %s\n", debugstr_w(cmdline));

    ret = CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, c_colon, &si, &pi );
    if (ret)
    {
        CloseHandle( pi.hThread );
        msi_dialog_check_messages( pi.hProcess );
        CloseHandle( pi.hProcess );
    }

    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, filename );
    uipath = strdupW( file->TargetPath );
    if ((p = strrchrW( uipath,'\\' ))) *p = 0;
    MSI_RecordSetStringW( uirow, 2, uipath );
    ui_actiondata( package, szSelfUnregModules, uirow );
    msiobj_release( &uirow->hdr );

    msi_free( cmdline );
    msi_free( uipath );
    return ERROR_SUCCESS;
}

static UINT ACTION_SelfUnregModules( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','S','e','l','f','R','e','g','`',0};

    rc = MSI_DatabaseOpenViewW( package->db, query, &view );
    if (rc != ERROR_SUCCESS)
    {
        TRACE("no SelfReg table\n");
        return ERROR_SUCCESS;
    }

    MSI_IterateRecords( view, NULL, ITERATE_SelfUnregModules, package );
    msiobj_release( &view->hdr );

    return ERROR_SUCCESS;
}

static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
{
    MSIFEATURE *feature;
    UINT rc;
    HKEY hkey = NULL, userdata = NULL;

    if (!msi_check_publish(package))
        return ERROR_SUCCESS;

    rc = MSIREG_OpenFeaturesKey(package->ProductCode, package->Context,
                                &hkey, TRUE);
    if (rc != ERROR_SUCCESS)
        goto end;

    rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, package->Context,
                                        &userdata, TRUE);
    if (rc != ERROR_SUCCESS)
        goto end;

    /* here the guids are base 85 encoded */
    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        ComponentList *cl;
        LPWSTR data = NULL;
        GUID clsid;
        INT size;
        BOOL absent = FALSE;
        MSIRECORD *uirow;

        if (feature->ActionRequest != INSTALLSTATE_LOCAL &&
            feature->ActionRequest != INSTALLSTATE_SOURCE &&
            feature->ActionRequest != INSTALLSTATE_ADVERTISED) absent = TRUE;

        size = 1;
        LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
        {
            size += 21;
        }
        if (feature->Feature_Parent)
            size += strlenW( feature->Feature_Parent )+2;

        data = msi_alloc(size * sizeof(WCHAR));

        data[0] = 0;
        LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
        {
            MSICOMPONENT* component = cl->component;
            WCHAR buf[21];

            buf[0] = 0;
            if (component->ComponentId)
            {
                TRACE("From %s\n",debugstr_w(component->ComponentId));
                CLSIDFromString(component->ComponentId, &clsid);
                encode_base85_guid(&clsid,buf);
                TRACE("to %s\n",debugstr_w(buf));
                strcatW(data,buf);
            }
        }

        if (feature->Feature_Parent)
        {
            static const WCHAR sep[] = {'\2',0};
            strcatW(data,sep);
            strcatW(data,feature->Feature_Parent);
        }

        msi_reg_set_val_str( userdata, feature->Feature, data );
        msi_free(data);

        size = 0;
        if (feature->Feature_Parent)
            size = strlenW(feature->Feature_Parent)*sizeof(WCHAR);
        if (!absent)
        {
            size += sizeof(WCHAR);
            RegSetValueExW(hkey,feature->Feature,0,REG_SZ,
                           (const BYTE*)(feature->Feature_Parent ? feature->Feature_Parent : szEmpty),size);
        }
        else
        {
            size += 2*sizeof(WCHAR);
            data = msi_alloc(size);
            data[0] = 0x6;
            data[1] = 0;
            if (feature->Feature_Parent)
                strcpyW( &data[1], feature->Feature_Parent );
            RegSetValueExW(hkey,feature->Feature,0,REG_SZ,
                       (LPBYTE)data,size);
            msi_free(data);
        }

        /* the UI chunk */
        uirow = MSI_CreateRecord( 1 );
        MSI_RecordSetStringW( uirow, 1, feature->Feature );
        ui_actiondata( package, szPublishFeatures, uirow);
        msiobj_release( &uirow->hdr );
        /* FIXME: call ui_progress? */
    }

end:
    RegCloseKey(hkey);
    RegCloseKey(userdata);
    return rc;
}

static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature)
{
    UINT r;
    HKEY hkey;
    MSIRECORD *uirow;

    TRACE("unpublishing feature %s\n", debugstr_w(feature->Feature));

    r = MSIREG_OpenFeaturesKey(package->ProductCode, package->Context,
                               &hkey, FALSE);
    if (r == ERROR_SUCCESS)
    {
        RegDeleteValueW(hkey, feature->Feature);
        RegCloseKey(hkey);
    }

    r = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, package->Context,
                                       &hkey, FALSE);
    if (r == ERROR_SUCCESS)
    {
        RegDeleteValueW(hkey, feature->Feature);
        RegCloseKey(hkey);
    }

    uirow = MSI_CreateRecord( 1 );
    MSI_RecordSetStringW( uirow, 1, feature->Feature );
    ui_actiondata( package, szUnpublishFeatures, uirow );
    msiobj_release( &uirow->hdr );

    return ERROR_SUCCESS;
}

static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package)
{
    MSIFEATURE *feature;

    if (!msi_check_unpublish(package))
        return ERROR_SUCCESS;

    LIST_FOR_EACH_ENTRY(feature, &package->features, MSIFEATURE, entry)
    {
        msi_unpublish_feature(package, feature);
    }

    return ERROR_SUCCESS;
}

static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey)
{
    SYSTEMTIME systime;
    DWORD size, langid;
    WCHAR date[9], *val, *buffer;
    const WCHAR *prop, *key;

    static const WCHAR date_fmt[] = {'%','i','%','0','2','i','%','0','2','i',0};
    static const WCHAR szWindowsInstaller[] =
        {'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
    static const WCHAR modpath_fmt[] =
        {'M','s','i','E','x','e','c','.','e','x','e',' ',
         '/','I','[','P','r','o','d','u','c','t','C','o','d','e',']',0};
    static const WCHAR szModifyPath[] =
        {'M','o','d','i','f','y','P','a','t','h',0};
    static const WCHAR szUninstallString[] =
        {'U','n','i','n','s','t','a','l','l','S','t','r','i','n','g',0};
    static const WCHAR szEstimatedSize[] =
        {'E','s','t','i','m','a','t','e','d','S','i','z','e',0};
    static const WCHAR szProductLanguage[] =
        {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
    static const WCHAR szProductVersion[] =
        {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
    static const WCHAR szDisplayVersion[] =
        {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
    static const WCHAR szInstallSource[] =
        {'I','n','s','t','a','l','l','S','o','u','r','c','e',0};
    static const WCHAR szARPAUTHORIZEDCDFPREFIX[] =
        {'A','R','P','A','U','T','H','O','R','I','Z','E','D','C','D','F','P','R','E','F','I','X',0};
    static const WCHAR szAuthorizedCDFPrefix[] =
        {'A','u','t','h','o','r','i','z','e','d','C','D','F','P','r','e','f','i','x',0};
    static const WCHAR szARPCONTACT[] =
        {'A','R','P','C','O','N','T','A','C','T',0};
    static const WCHAR szContact[] =
        {'C','o','n','t','a','c','t',0};
    static const WCHAR szARPCOMMENTS[] =
        {'A','R','P','C','O','M','M','E','N','T','S',0};
    static const WCHAR szComments[] =
        {'C','o','m','m','e','n','t','s',0};
    static const WCHAR szProductName[] =
        {'P','r','o','d','u','c','t','N','a','m','e',0};
    static const WCHAR szDisplayName[] =
        {'D','i','s','p','l','a','y','N','a','m','e',0};
    static const WCHAR szARPHELPLINK[] =
        {'A','R','P','H','E','L','P','L','I','N','K',0};
    static const WCHAR szHelpLink[] =
        {'H','e','l','p','L','i','n','k',0};
    static const WCHAR szARPHELPTELEPHONE[] =
        {'A','R','P','H','E','L','P','T','E','L','E','P','H','O','N','E',0};
    static const WCHAR szHelpTelephone[] =
        {'H','e','l','p','T','e','l','e','p','h','o','n','e',0};
    static const WCHAR szARPINSTALLLOCATION[] =
        {'A','R','P','I','N','S','T','A','L','L','L','O','C','A','T','I','O','N',0};
    static const WCHAR szInstallLocation[] =
        {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0};
    static const WCHAR szManufacturer[] =
        {'M','a','n','u','f','a','c','t','u','r','e','r',0};
    static const WCHAR szPublisher[] =
        {'P','u','b','l','i','s','h','e','r',0};
    static const WCHAR szARPREADME[] =
        {'A','R','P','R','E','A','D','M','E',0};
    static const WCHAR szReadme[] =
        {'R','e','a','d','M','e',0};
    static const WCHAR szARPSIZE[] =
        {'A','R','P','S','I','Z','E',0};
    static const WCHAR szSize[] =
        {'S','i','z','e',0};
    static const WCHAR szARPURLINFOABOUT[] =
        {'A','R','P','U','R','L','I','N','F','O','A','B','O','U','T',0};
    static const WCHAR szURLInfoAbout[] =
        {'U','R','L','I','n','f','o','A','b','o','u','t',0};
    static const WCHAR szARPURLUPDATEINFO[] =
        {'A','R','P','U','R','L','U','P','D','A','T','E','I','N','F','O',0};
    static const WCHAR szURLUpdateInfo[] =
        {'U','R','L','U','p','d','a','t','e','I','n','f','o',0};

    static const WCHAR *propval[] = {
        szARPAUTHORIZEDCDFPREFIX, szAuthorizedCDFPrefix,
        szARPCONTACT,             szContact,
        szARPCOMMENTS,            szComments,
        szProductName,            szDisplayName,
        szARPHELPLINK,            szHelpLink,
        szARPHELPTELEPHONE,       szHelpTelephone,
        szARPINSTALLLOCATION,     szInstallLocation,
        cszSourceDir,             szInstallSource,
        szManufacturer,           szPublisher,
        szARPREADME,              szReadme,
        szARPSIZE,                szSize,
        szARPURLINFOABOUT,        szURLInfoAbout,
        szARPURLUPDATEINFO,       szURLUpdateInfo,
        NULL
    };
    const WCHAR **p = propval;

    while (*p)
    {
        prop = *p++;
        key = *p++;
        val = msi_dup_property(package->db, prop);
        msi_reg_set_val_str(hkey, key, val);
        msi_free(val);
    }

    msi_reg_set_val_dword(hkey, szWindowsInstaller, 1);

    size = deformat_string(package, modpath_fmt, &buffer);
    RegSetValueExW(hkey, szModifyPath, 0, REG_EXPAND_SZ, (LPBYTE)buffer, size);
    RegSetValueExW(hkey, szUninstallString, 0, REG_EXPAND_SZ, (LPBYTE)buffer, size);
    msi_free(buffer);

    /* FIXME: Write real Estimated Size when we have it */
    msi_reg_set_val_dword(hkey, szEstimatedSize, 0);

    GetLocalTime(&systime);
    sprintfW(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
    msi_reg_set_val_str(hkey, INSTALLPROPERTY_INSTALLDATEW, date);

    langid = msi_get_property_int(package->db, szProductLanguage, 0);
    msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid);

    buffer = msi_dup_property(package->db, szProductVersion);
    msi_reg_set_val_str(hkey, szDisplayVersion, buffer);
    if (buffer)
    {
        DWORD verdword = msi_version_str_to_dword(buffer);

        msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONW, verdword);
        msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONMAJORW, verdword >> 24);
        msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONMINORW, (verdword >> 16) & 0xFF);
        msi_free(buffer);
    }

    return ERROR_SUCCESS;
}

static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
{
    WCHAR squashed_pc[SQUISH_GUID_SIZE];
    MSIRECORD *uirow;
    LPWSTR upgrade_code;
    HKEY hkey, props;
    HKEY upgrade;
    UINT rc;

    static const WCHAR szUpgradeCode[] = {
        'U','p','g','r','a','d','e','C','o','d','e',0};

    /* FIXME: also need to publish if the product is in advertise mode */
    if (!msi_check_publish(package))
        return ERROR_SUCCESS;

    rc = MSIREG_OpenUninstallKey(package->ProductCode, &hkey, TRUE);
    if (rc != ERROR_SUCCESS)
        return rc;

    rc = MSIREG_OpenInstallProps(package->ProductCode, package->Context,
                                 NULL, &props, TRUE);
    if (rc != ERROR_SUCCESS)
        goto done;

    msi_reg_set_val_str( props, INSTALLPROPERTY_LOCALPACKAGEW, package->db->localfile );
    msi_free( package->db->localfile );
    package->db->localfile = NULL;

    rc = msi_publish_install_properties(package, hkey);
    if (rc != ERROR_SUCCESS)
        goto done;

    rc = msi_publish_install_properties(package, props);
    if (rc != ERROR_SUCCESS)
        goto done;

    upgrade_code = msi_dup_property(package->db, szUpgradeCode);
    if (upgrade_code)
    {
        MSIREG_OpenUpgradeCodesKey(upgrade_code, &upgrade, TRUE);
        squash_guid(package->ProductCode, squashed_pc);
        msi_reg_set_val_str(upgrade, squashed_pc, NULL);
        RegCloseKey(upgrade);
        msi_free(upgrade_code);
    }

done:
    uirow = MSI_CreateRecord( 1 );
    MSI_RecordSetStringW( uirow, 1, package->ProductCode );
    ui_actiondata( package, szRegisterProduct, uirow );
    msiobj_release( &uirow->hdr );

    RegCloseKey(hkey);
    return ERROR_SUCCESS;
}

static UINT ACTION_InstallExecute(MSIPACKAGE *package)
{
    return execute_script(package,INSTALL_SCRIPT);
}

static UINT msi_unpublish_product(MSIPACKAGE *package)
{
    LPWSTR upgrade;
    LPWSTR remove = NULL;
    LPWSTR *features = NULL;
    BOOL full_uninstall = TRUE;
    MSIFEATURE *feature;
    MSIPATCHINFO *patch;

    static const WCHAR szUpgradeCode[] =
        {'U','p','g','r','a','d','e','C','o','d','e',0};

    remove = msi_dup_property(package->db, szRemove);
    if (!remove)
        return ERROR_SUCCESS;

    features = msi_split_string(remove, ',');
    if (!features)
    {
        msi_free(remove);
        ERR("REMOVE feature list is empty!\n");
        return ERROR_FUNCTION_FAILED;
    }

    if (!lstrcmpW(features[0], szAll))
        full_uninstall = TRUE;
    else
    {
        LIST_FOR_EACH_ENTRY(feature, &package->features, MSIFEATURE, entry)
        {
            if (feature->Action != INSTALLSTATE_ABSENT)
                full_uninstall = FALSE;
        }
    }

    if (!full_uninstall)
        goto done;

    MSIREG_DeleteProductKey(package->ProductCode);
    MSIREG_DeleteUserDataProductKey(package->ProductCode);
    MSIREG_DeleteUninstallKey(package->ProductCode);

    if (package->Context == MSIINSTALLCONTEXT_MACHINE)
    {
        MSIREG_DeleteLocalClassesProductKey(package->ProductCode);
        MSIREG_DeleteLocalClassesFeaturesKey(package->ProductCode);
    }
    else
    {
        MSIREG_DeleteUserProductKey(package->ProductCode);
        MSIREG_DeleteUserFeaturesKey(package->ProductCode);
    }

    upgrade = msi_dup_property(package->db, szUpgradeCode);
    if (upgrade)
    {
        MSIREG_DeleteUserUpgradeCodesKey(upgrade);
        msi_free(upgrade);
    }

    LIST_FOR_EACH_ENTRY(patch, &package->patches, MSIPATCHINFO, entry)
    {
        MSIREG_DeleteUserDataPatchKey(patch->patchcode, package->Context);
    }

done:
    msi_free(remove);
    msi_free(features);
    return ERROR_SUCCESS;
}

static UINT ACTION_InstallFinalize(MSIPACKAGE *package)
{
    UINT rc;

    rc = msi_unpublish_product(package);
    if (rc != ERROR_SUCCESS)
        return rc;

    /* turn off scheduling */
    package->script->CurrentlyScripting= FALSE;

    /* first do the same as an InstallExecute */
    rc = ACTION_InstallExecute(package);
    if (rc != ERROR_SUCCESS)
        return rc;

    /* then handle Commit Actions */
    rc = execute_script(package,COMMIT_SCRIPT);

    return rc;
}

UINT ACTION_ForceReboot(MSIPACKAGE *package)
{
    static const WCHAR RunOnce[] = {
    'S','o','f','t','w','a','r','e','\\',
    'M','i','c','r','o','s','o','f','t','\\',
    'W','i','n','d','o','w','s','\\',
    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
    'R','u','n','O','n','c','e',0};
    static const WCHAR InstallRunOnce[] = {
    'S','o','f','t','w','a','r','e','\\',
    'M','i','c','r','o','s','o','f','t','\\',
    'W','i','n','d','o','w','s','\\',
    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
    'I','n','s','t','a','l','l','e','r','\\',
    'R','u','n','O','n','c','e','E','n','t','r','i','e','s',0};

    static const WCHAR msiexec_fmt[] = {
    '%','s',
    '\\','M','s','i','E','x','e','c','.','e','x','e',' ','/','@',' ',
    '\"','%','s','\"',0};
    static const WCHAR install_fmt[] = {
    '/','I',' ','\"','%','s','\"',' ',
    'A','F','T','E','R','R','E','B','O','O','T','=','1',' ',
    'R','U','N','O','N','C','E','E','N','T','R','Y','=','\"','%','s','\"',0};
    WCHAR buffer[256], sysdir[MAX_PATH];
    HKEY hkey;
    WCHAR squished_pc[100];

    squash_guid(package->ProductCode,squished_pc);

    GetSystemDirectoryW(sysdir, sizeof(sysdir)/sizeof(sysdir[0]));
    RegCreateKeyW(HKEY_LOCAL_MACHINE,RunOnce,&hkey);
    snprintfW(buffer,sizeof(buffer)/sizeof(buffer[0]),msiexec_fmt,sysdir,
     squished_pc);

    msi_reg_set_val_str( hkey, squished_pc, buffer );
    RegCloseKey(hkey);

    TRACE("Reboot command %s\n",debugstr_w(buffer));

    RegCreateKeyW(HKEY_LOCAL_MACHINE,InstallRunOnce,&hkey);
    sprintfW(buffer,install_fmt,package->ProductCode,squished_pc);

    msi_reg_set_val_str( hkey, squished_pc, buffer );
    RegCloseKey(hkey);

    return ERROR_INSTALL_SUSPEND;
}

static UINT ACTION_ResolveSource(MSIPACKAGE* package)
{
    DWORD attrib;
    UINT rc;

    /*
     * We are currently doing what should be done here in the top level Install
     * however for Administrative and uninstalls this step will be needed
     */
    if (!package->PackagePath)
        return ERROR_SUCCESS;

    msi_set_sourcedir_props(package, TRUE);

    attrib = GetFileAttributesW(package->db->path);
    if (attrib == INVALID_FILE_ATTRIBUTES)
    {
        LPWSTR prompt;
        LPWSTR msg;
        DWORD size = 0;

        rc = MsiSourceListGetInfoW(package->ProductCode, NULL, 
                package->Context, MSICODE_PRODUCT,
                INSTALLPROPERTY_DISKPROMPTW,NULL,&size);
        if (rc == ERROR_MORE_DATA)
        {
            prompt = msi_alloc(size * sizeof(WCHAR));
            MsiSourceListGetInfoW(package->ProductCode, NULL, 
                    package->Context, MSICODE_PRODUCT,
                    INSTALLPROPERTY_DISKPROMPTW,prompt,&size);
        }
        else
            prompt = strdupW(package->db->path);

        msg = generate_error_string(package,1302,1,prompt);
        while(attrib == INVALID_FILE_ATTRIBUTES)
        {
            rc = MessageBoxW(NULL,msg,NULL,MB_OKCANCEL);
            if (rc == IDCANCEL)
            {
                rc = ERROR_INSTALL_USEREXIT;
                break;
            }
            attrib = GetFileAttributesW(package->db->path);
        }
        msi_free(prompt);
        rc = ERROR_SUCCESS;
    }
    else
        return ERROR_SUCCESS;

    return rc;
}

static UINT ACTION_RegisterUser(MSIPACKAGE *package)
{
    HKEY hkey = 0;
    LPWSTR buffer, productid = NULL;
    UINT i, rc = ERROR_SUCCESS;
    MSIRECORD *uirow;

    static const WCHAR szPropKeys[][80] = 
    {
        {'P','r','o','d','u','c','t','I','D',0},
        {'U','S','E','R','N','A','M','E',0},
        {'C','O','M','P','A','N','Y','N','A','M','E',0},
        {0},
    };

    static const WCHAR szRegKeys[][80] = 
    {
        {'P','r','o','d','u','c','t','I','D',0},
        {'R','e','g','O','w','n','e','r',0},
        {'R','e','g','C','o','m','p','a','n','y',0},
        {0},
    };

    if (msi_check_unpublish(package))
    {
        MSIREG_DeleteUserDataProductKey(package->ProductCode);
        goto end;
    }

    productid = msi_dup_property( package->db, INSTALLPROPERTY_PRODUCTIDW );
    if (!productid)
        goto end;

    rc = MSIREG_OpenInstallProps(package->ProductCode, package->Context,
                                 NULL, &hkey, TRUE);
    if (rc != ERROR_SUCCESS)
        goto end;

    for( i = 0; szPropKeys[i][0]; i++ )
    {
        buffer = msi_dup_property( package->db, szPropKeys[i] );
        msi_reg_set_val_str( hkey, szRegKeys[i], buffer );
        msi_free( buffer );
    }

end:
    uirow = MSI_CreateRecord( 1 );
    MSI_RecordSetStringW( uirow, 1, productid );
    ui_actiondata( package, szRegisterUser, uirow );
    msiobj_release( &uirow->hdr );

    msi_free(productid);
    RegCloseKey(hkey);
    return rc;
}


static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
{
    UINT rc;

    package->script->InWhatSequence |= SEQUENCE_EXEC;
    rc = ACTION_ProcessExecSequence(package,FALSE);
    return rc;
}


static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
{
    MSIPACKAGE *package = param;
    LPCWSTR compgroupid, component, feature, qualifier, text;
    LPWSTR advertise = NULL, output = NULL;
    HKEY hkey = NULL;
    UINT rc;
    MSICOMPONENT *comp;
    MSIFEATURE *feat;
    DWORD sz;
    MSIRECORD *uirow;

    feature = MSI_RecordGetString(rec, 5);
    feat = get_loaded_feature(package, feature);
    if (!feat)
        return ERROR_SUCCESS;

    if (feat->ActionRequest != INSTALLSTATE_LOCAL &&
        feat->ActionRequest != INSTALLSTATE_SOURCE &&
        feat->ActionRequest != INSTALLSTATE_ADVERTISED)
    {
        TRACE("Feature %s not scheduled for installation\n", debugstr_w(feature));
        feat->Action = feat->Installed;
        return ERROR_SUCCESS;
    }

    component = MSI_RecordGetString(rec, 3);
    comp = get_loaded_component(package, component);
    if (!comp)
        return ERROR_SUCCESS;

    compgroupid = MSI_RecordGetString(rec,1);
    qualifier = MSI_RecordGetString(rec,2);

    rc = MSIREG_OpenUserComponentsKey(compgroupid, &hkey, TRUE);
    if (rc != ERROR_SUCCESS)
        goto end;
    
    text = MSI_RecordGetString(rec,4);
    advertise = create_component_advertise_string(package, comp, feature);

    sz = strlenW(advertise);

    if (text)
        sz += lstrlenW(text);

    sz+=3;
    sz *= sizeof(WCHAR);
           
    output = msi_alloc_zero(sz);
    strcpyW(output,advertise);
    msi_free(advertise);

    if (text)
        strcatW(output,text);

    msi_reg_set_val_multi_str( hkey, qualifier, output );
    
end:
    RegCloseKey(hkey);
    msi_free(output);

    /* the UI chunk */
    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, compgroupid );
    MSI_RecordSetStringW( uirow, 2, qualifier);
    ui_actiondata( package, szPublishComponents, uirow);
    msiobj_release( &uirow->hdr );
    /* FIXME: call ui_progress? */

    return rc;
}

/*
 * At present I am ignorning the advertised components part of this and only
 * focusing on the qualified component sets
 */
static UINT ACTION_PublishComponents(MSIPACKAGE *package)
{
    UINT rc;
    MSIQUERY * view;
    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','P','u','b','l','i','s','h',
         'C','o','m','p','o','n','e','n','t','`',0};
    
    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
    if (rc != ERROR_SUCCESS)
        return ERROR_SUCCESS;

    rc = MSI_IterateRecords(view, NULL, ITERATE_PublishComponent, package);
    msiobj_release(&view->hdr);

    return rc;
}

static UINT ITERATE_UnpublishComponent( MSIRECORD *rec, LPVOID param )
{
    static const WCHAR szInstallerComponents[] = {
        'S','o','f','t','w','a','r','e','\\',
        'M','i','c','r','o','s','o','f','t','\\',
        'I','n','s','t','a','l','l','e','r','\\',
        'C','o','m','p','o','n','e','n','t','s','\\',0};

    MSIPACKAGE *package = param;
    LPCWSTR compgroupid, component, feature, qualifier;
    MSICOMPONENT *comp;
    MSIFEATURE *feat;
    MSIRECORD *uirow;
    WCHAR squashed[GUID_SIZE], keypath[MAX_PATH];
    LONG res;

    feature = MSI_RecordGetString( rec, 5 );
    feat = get_loaded_feature( package, feature );
    if (!feat)
        return ERROR_SUCCESS;

    if (feat->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Feature %s not scheduled for removal\n", debugstr_w(feature));
        feat->Action = feat->Installed;
        return ERROR_SUCCESS;
    }

    component = MSI_RecordGetString( rec, 3 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    compgroupid = MSI_RecordGetString( rec, 1 );
    qualifier = MSI_RecordGetString( rec, 2 );

    squash_guid( compgroupid, squashed );
    strcpyW( keypath, szInstallerComponents );
    strcatW( keypath, squashed );

    res = RegDeleteKeyW( HKEY_CURRENT_USER, keypath );
    if (res != ERROR_SUCCESS)
    {
        WARN("Unable to delete component key %d\n", res);
    }

    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, compgroupid );
    MSI_RecordSetStringW( uirow, 2, qualifier );
    ui_actiondata( package, szUnpublishComponents, uirow );
    msiobj_release( &uirow->hdr );

    return ERROR_SUCCESS;
}

static UINT ACTION_UnpublishComponents( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','P','u','b','l','i','s','h',
         'C','o','m','p','o','n','e','n','t','`',0};

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_UnpublishComponent, package );
    msiobj_release( &view->hdr );

    return rc;
}

static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
{
    MSIPACKAGE *package = param;
    MSIRECORD *row;
    MSIFILE *file;
    SC_HANDLE hscm, service = NULL;
    LPCWSTR comp, depends, pass;
    LPWSTR name = NULL, disp = NULL;
    LPCWSTR load_order, serv_name, key;
    DWORD serv_type, start_type;
    DWORD err_control;

    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
         '`','C','o','m','p','o','n','e','n','t','`',' ',
         'W','H','E','R','E',' ',
         '`','C','o','m','p','o','n','e','n','t','`',' ',
         '=','\'','%','s','\'',0};

    hscm = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASEW, GENERIC_WRITE);
    if (!hscm)
    {
        ERR("Failed to open the SC Manager!\n");
        goto done;
    }

    start_type = MSI_RecordGetInteger(rec, 5);
    if (start_type == SERVICE_BOOT_START || start_type == SERVICE_SYSTEM_START)
        goto done;

    depends = MSI_RecordGetString(rec, 8);
    if (depends && *depends)
        FIXME("Dependency list unhandled!\n");

    deformat_string(package, MSI_RecordGetString(rec, 2), &name);
    deformat_string(package, MSI_RecordGetString(rec, 3), &disp);
    serv_type = MSI_RecordGetInteger(rec, 4);
    err_control = MSI_RecordGetInteger(rec, 6);
    load_order = MSI_RecordGetString(rec, 7);
    serv_name = MSI_RecordGetString(rec, 9);
    pass = MSI_RecordGetString(rec, 10);
    comp = MSI_RecordGetString(rec, 12);

    /* fetch the service path */
    row = MSI_QueryGetRecord(package->db, query, comp);
    if (!row)
    {
        ERR("Control query failed!\n");
        goto done;
    }

    key = MSI_RecordGetString(row, 6);

    file = get_loaded_file(package, key);
    msiobj_release(&row->hdr);
    if (!file)
    {
        ERR("Failed to load the service file\n");
        goto done;
    }

    service = CreateServiceW(hscm, name, disp, GENERIC_ALL, serv_type,
                             start_type, err_control, file->TargetPath,
                             load_order, NULL, NULL, serv_name, pass);
    if (!service)
    {
        if (GetLastError() != ERROR_SERVICE_EXISTS)
            ERR("Failed to create service %s: %d\n", debugstr_w(name), GetLastError());
    }

done:
    CloseServiceHandle(service);
    CloseServiceHandle(hscm);
    msi_free(name);
    msi_free(disp);

    return ERROR_SUCCESS;
}

static UINT ACTION_InstallServices( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY * view;
    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         'S','e','r','v','i','c','e','I','n','s','t','a','l','l',0};
    
    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
    if (rc != ERROR_SUCCESS)
        return ERROR_SUCCESS;

    rc = MSI_IterateRecords(view, NULL, ITERATE_InstallService, package);
    msiobj_release(&view->hdr);

    return rc;
}

/* converts arg1[~]arg2[~]arg3 to a list of ptrs to the strings */
static LPCWSTR *msi_service_args_to_vector(LPWSTR args, DWORD *numargs)
{
    LPCWSTR *vector, *temp_vector;
    LPWSTR p, q;
    DWORD sep_len;

    static const WCHAR separator[] = {'[','~',']',0};

    *numargs = 0;
    sep_len = sizeof(separator) / sizeof(WCHAR) - 1;

    if (!args)
        return NULL;

    vector = msi_alloc(sizeof(LPWSTR));
    if (!vector)
        return NULL;

    p = args;
    do
    {
        (*numargs)++;
        vector[*numargs - 1] = p;

        if ((q = strstrW(p, separator)))
        {
            *q = '\0';

            temp_vector = msi_realloc(vector, (*numargs + 1) * sizeof(LPWSTR));
            if (!temp_vector)
            {
                msi_free(vector);
                return NULL;
            }
            vector = temp_vector;

            p = q + sep_len;
        }
    } while (q);

    return vector;
}

static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
{
    MSIPACKAGE *package = param;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    SC_HANDLE scm = NULL, service = NULL;
    LPCWSTR component, *vector = NULL;
    LPWSTR name, args, display_name = NULL;
    DWORD event, numargs, len;
    UINT r = ERROR_FUNCTION_FAILED;

    component = MSI_RecordGetString(rec, 6);
    comp = get_loaded_component(package, component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    deformat_string(package, MSI_RecordGetString(rec, 2), &name);
    deformat_string(package, MSI_RecordGetString(rec, 4), &args);
    event = MSI_RecordGetInteger(rec, 3);

    if (!(event & msidbServiceControlEventStart))
    {
        r = ERROR_SUCCESS;
        goto done;
    }

    scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
    if (!scm)
    {
        ERR("Failed to open the service control manager\n");
        goto done;
    }

    len = 0;
    if (!GetServiceDisplayNameW( scm, name, NULL, &len ) &&
        GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        if ((display_name = msi_alloc( ++len * sizeof(WCHAR ))))
            GetServiceDisplayNameW( scm, name, display_name, &len );
    }

    service = OpenServiceW(scm, name, SERVICE_START);
    if (!service)
    {
        ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
        goto done;
    }

    vector = msi_service_args_to_vector(args, &numargs);

    if (!StartServiceW(service, numargs, vector) &&
        GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)
    {
        ERR("Failed to start service %s (%u)\n", debugstr_w(name), GetLastError());
        goto done;
    }

    r = ERROR_SUCCESS;

done:
    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, display_name );
    MSI_RecordSetStringW( uirow, 2, name );
    ui_actiondata( package, szStartServices, uirow );
    msiobj_release( &uirow->hdr );

    CloseServiceHandle(service);
    CloseServiceHandle(scm);

    msi_free(name);
    msi_free(args);
    msi_free(vector);
    msi_free(display_name);
    return r;
}

static UINT ACTION_StartServices( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;

    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 };

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

    rc = MSI_IterateRecords(view, NULL, ITERATE_StartService, package);
    msiobj_release(&view->hdr);

    return rc;
}

static BOOL stop_service_dependents(SC_HANDLE scm, SC_HANDLE service)
{
    DWORD i, needed, count;
    ENUM_SERVICE_STATUSW *dependencies;
    SERVICE_STATUS ss;
    SC_HANDLE depserv;

    if (EnumDependentServicesW(service, SERVICE_ACTIVE, NULL,
                               0, &needed, &count))
        return TRUE;

    if (GetLastError() != ERROR_MORE_DATA)
        return FALSE;

    dependencies = msi_alloc(needed);
    if (!dependencies)
        return FALSE;

    if (!EnumDependentServicesW(service, SERVICE_ACTIVE, dependencies,
                                needed, &needed, &count))
        goto error;

    for (i = 0; i < count; i++)
    {
        depserv = OpenServiceW(scm, dependencies[i].lpServiceName,
                               SERVICE_STOP | SERVICE_QUERY_STATUS);
        if (!depserv)
            goto error;

        if (!ControlService(depserv, SERVICE_CONTROL_STOP, &ss))
            goto error;
    }

    return TRUE;

error:
    msi_free(dependencies);
    return FALSE;
}

static UINT stop_service( LPCWSTR name )
{
    SC_HANDLE scm = NULL, service = NULL;
    SERVICE_STATUS status;
    SERVICE_STATUS_PROCESS ssp;
    DWORD needed;

    scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!scm)
    {
        WARN("Failed to open the SCM: %d\n", GetLastError());
        goto done;
    }

    service = OpenServiceW(scm, name,
                           SERVICE_STOP |
                           SERVICE_QUERY_STATUS |
                           SERVICE_ENUMERATE_DEPENDENTS);
    if (!service)
    {
        WARN("Failed to open service (%s): %d\n", debugstr_w(name), GetLastError());
        goto done;
    }

    if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
                              sizeof(SERVICE_STATUS_PROCESS), &needed))
    {
        WARN("Failed to query service status (%s): %d\n", debugstr_w(name), GetLastError());
        goto done;
    }

    if (ssp.dwCurrentState == SERVICE_STOPPED)
        goto done;

    stop_service_dependents(scm, service);

    if (!ControlService(service, SERVICE_CONTROL_STOP, &status))
        WARN("Failed to stop service (%s): %d\n", debugstr_w(name), GetLastError());

done:
    CloseServiceHandle(service);
    CloseServiceHandle(scm);

    return ERROR_SUCCESS;
}

static UINT ITERATE_StopService( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    LPCWSTR component;
    LPWSTR name = NULL, display_name = NULL;
    DWORD event, len;
    SC_HANDLE scm;

    event = MSI_RecordGetInteger( rec, 3 );
    if (!(event & msidbServiceControlEventStop))
        return ERROR_SUCCESS;

    component = MSI_RecordGetString( rec, 6 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_ABSENT;

    scm = OpenSCManagerW( NULL, NULL, SC_MANAGER_CONNECT );
    if (!scm)
    {
        ERR("Failed to open the service control manager\n");
        goto done;
    }

    len = 0;
    if (!GetServiceDisplayNameW( scm, name, NULL, &len ) &&
        GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        if ((display_name = msi_alloc( ++len * sizeof(WCHAR ))))
            GetServiceDisplayNameW( scm, name, display_name, &len );
    }
    CloseServiceHandle( scm );

    deformat_string( package, MSI_RecordGetString( rec, 2 ), &name );
    stop_service( name );

done:
    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, display_name );
    MSI_RecordSetStringW( uirow, 2, name );
    ui_actiondata( package, szStopServices, uirow );
    msiobj_release( &uirow->hdr );

    msi_free( name );
    msi_free( display_name );
    return ERROR_SUCCESS;
}

static UINT ACTION_StopServices( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;

    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 };

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

    rc = MSI_IterateRecords(view, NULL, ITERATE_StopService, package);
    msiobj_release(&view->hdr);

    return rc;
}

static UINT ITERATE_DeleteService( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    LPCWSTR component;
    LPWSTR name = NULL, display_name = NULL;
    DWORD event, len;
    SC_HANDLE scm = NULL, service = NULL;

    event = MSI_RecordGetInteger( rec, 3 );
    if (!(event & msidbServiceControlEventDelete))
        return ERROR_SUCCESS;

    component = MSI_RecordGetString(rec, 6);
    comp = get_loaded_component(package, component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_ABSENT;

    deformat_string( package, MSI_RecordGetString(rec, 2), &name );
    stop_service( name );

    scm = OpenSCManagerW( NULL, NULL, SC_MANAGER_ALL_ACCESS );
    if (!scm)
    {
        WARN("Failed to open the SCM: %d\n", GetLastError());
        goto done;
    }

    len = 0;
    if (!GetServiceDisplayNameW( scm, name, NULL, &len ) &&
        GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        if ((display_name = msi_alloc( ++len * sizeof(WCHAR ))))
            GetServiceDisplayNameW( scm, name, display_name, &len );
    }

    service = OpenServiceW( scm, name, DELETE );
    if (!service)
    {
        WARN("Failed to open service (%s): %u\n", debugstr_w(name), GetLastError());
        goto done;
    }

    if (!DeleteService( service ))
        WARN("Failed to delete service (%s): %u\n", debugstr_w(name), GetLastError());

done:
    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, display_name );
    MSI_RecordSetStringW( uirow, 2, name );
    ui_actiondata( package, szDeleteServices, uirow );
    msiobj_release( &uirow->hdr );

    CloseServiceHandle( service );
    CloseServiceHandle( scm );
    msi_free( name );
    msi_free( display_name );

    return ERROR_SUCCESS;
}

static UINT ACTION_DeleteServices( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;

    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 };

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_DeleteService, package );
    msiobj_release( &view->hdr );

    return rc;
}

static MSIFILE *msi_find_file( MSIPACKAGE *package, LPCWSTR filename )
{
    MSIFILE *file;

    LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry)
    {
        if (!lstrcmpW(file->File, filename))
            return file;
    }

    return NULL;
}

static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPWSTR driver, driver_path, ptr;
    WCHAR outpath[MAX_PATH];
    MSIFILE *driver_file, *setup_file;
    MSIRECORD *uirow;
    LPCWSTR desc;
    DWORD len, usage;
    UINT r = ERROR_SUCCESS;

    static const WCHAR driver_fmt[] = {
        'D','r','i','v','e','r','=','%','s',0};
    static const WCHAR setup_fmt[] = {
        'S','e','t','u','p','=','%','s',0};
    static const WCHAR usage_fmt[] = {
        'F','i','l','e','U','s','a','g','e','=','1',0};

    desc = MSI_RecordGetString(rec, 3);

    driver_file = msi_find_file(package, MSI_RecordGetString(rec, 4));
    setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5));

    if (!driver_file)
    {
        ERR("ODBC Driver entry not found!\n");
        return ERROR_FUNCTION_FAILED;
    }

    len = lstrlenW(desc) + lstrlenW(driver_fmt) + lstrlenW(driver_file->FileName);
    if (setup_file)
        len += lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName);
    len += lstrlenW(usage_fmt) + 2; /* \0\0 */

    driver = msi_alloc(len * sizeof(WCHAR));
    if (!driver)
        return ERROR_OUTOFMEMORY;

    ptr = driver;
    lstrcpyW(ptr, desc);
    ptr += lstrlenW(ptr) + 1;

    len = sprintfW(ptr, driver_fmt, driver_file->FileName);
    ptr += len + 1;

    if (setup_file)
    {
        len = sprintfW(ptr, setup_fmt, setup_file->FileName);
        ptr += len + 1;
    }

    lstrcpyW(ptr, usage_fmt);
    ptr += lstrlenW(ptr) + 1;
    *ptr = '\0';

    driver_path = strdupW(driver_file->TargetPath);
    ptr = strrchrW(driver_path, '\\');
    if (ptr) *ptr = '\0';

    if (!SQLInstallDriverExW(driver, driver_path, outpath, MAX_PATH,
                             NULL, ODBC_INSTALL_COMPLETE, &usage))
    {
        ERR("Failed to install SQL driver!\n");
        r = ERROR_FUNCTION_FAILED;
    }

    uirow = MSI_CreateRecord( 5 );
    MSI_RecordSetStringW( uirow, 1, desc );
    MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
    MSI_RecordSetStringW( uirow, 3, driver_path );
    ui_actiondata( package, szInstallODBC, uirow );
    msiobj_release( &uirow->hdr );

    msi_free(driver);
    msi_free(driver_path);

    return r;
}

static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPWSTR translator, translator_path, ptr;
    WCHAR outpath[MAX_PATH];
    MSIFILE *translator_file, *setup_file;
    MSIRECORD *uirow;
    LPCWSTR desc;
    DWORD len, usage;
    UINT r = ERROR_SUCCESS;

    static const WCHAR translator_fmt[] = {
        'T','r','a','n','s','l','a','t','o','r','=','%','s',0};
    static const WCHAR setup_fmt[] = {
        'S','e','t','u','p','=','%','s',0};

    desc = MSI_RecordGetString(rec, 3);

    translator_file = msi_find_file(package, MSI_RecordGetString(rec, 4));
    setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5));

    if (!translator_file)
    {
        ERR("ODBC Translator entry not found!\n");
        return ERROR_FUNCTION_FAILED;
    }

    len = lstrlenW(desc) + lstrlenW(translator_fmt) + lstrlenW(translator_file->FileName) + 2; /* \0\0 */
    if (setup_file)
        len += lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName);

    translator = msi_alloc(len * sizeof(WCHAR));
    if (!translator)
        return ERROR_OUTOFMEMORY;

    ptr = translator;
    lstrcpyW(ptr, desc);
    ptr += lstrlenW(ptr) + 1;

    len = sprintfW(ptr, translator_fmt, translator_file->FileName);
    ptr += len + 1;

    if (setup_file)
    {
        len = sprintfW(ptr, setup_fmt, setup_file->FileName);
        ptr += len + 1;
    }
    *ptr = '\0';

    translator_path = strdupW(translator_file->TargetPath);
    ptr = strrchrW(translator_path, '\\');
    if (ptr) *ptr = '\0';

    if (!SQLInstallTranslatorExW(translator, translator_path, outpath, MAX_PATH,
                                 NULL, ODBC_INSTALL_COMPLETE, &usage))
    {
        ERR("Failed to install SQL translator!\n");
        r = ERROR_FUNCTION_FAILED;
    }

    uirow = MSI_CreateRecord( 5 );
    MSI_RecordSetStringW( uirow, 1, desc );
    MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
    MSI_RecordSetStringW( uirow, 3, translator_path );
    ui_actiondata( package, szInstallODBC, uirow );
    msiobj_release( &uirow->hdr );

    msi_free(translator);
    msi_free(translator_path);

    return r;
}

static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPWSTR attrs;
    LPCWSTR desc, driver;
    WORD request = ODBC_ADD_SYS_DSN;
    INT registration;
    DWORD len;
    UINT r = ERROR_SUCCESS;
    MSIRECORD *uirow;

    static const WCHAR attrs_fmt[] = {
        'D','S','N','=','%','s',0 };

    desc = MSI_RecordGetString(rec, 3);
    driver = MSI_RecordGetString(rec, 4);
    registration = MSI_RecordGetInteger(rec, 5);

    if (registration == msidbODBCDataSourceRegistrationPerMachine) request = ODBC_ADD_SYS_DSN;
    else if (registration == msidbODBCDataSourceRegistrationPerUser) request = ODBC_ADD_DSN;

    len = lstrlenW(attrs_fmt) + lstrlenW(desc) + 2; /* \0\0 */
    attrs = msi_alloc(len * sizeof(WCHAR));
    if (!attrs)
        return ERROR_OUTOFMEMORY;

    len = sprintfW(attrs, attrs_fmt, desc);
    attrs[len + 1] = 0;

    if (!SQLConfigDataSourceW(NULL, request, driver, attrs))
    {
        ERR("Failed to install SQL data source!\n");
        r = ERROR_FUNCTION_FAILED;
    }

    uirow = MSI_CreateRecord( 5 );
    MSI_RecordSetStringW( uirow, 1, desc );
    MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
    MSI_RecordSetInteger( uirow, 3, request );
    ui_actiondata( package, szInstallODBC, uirow );
    msiobj_release( &uirow->hdr );

    msi_free(attrs);

    return r;
}

static UINT ACTION_InstallODBC( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;

    static const WCHAR driver_query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'O','D','B','C','D','r','i','v','e','r',0 };

    static const WCHAR translator_query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0 };

    static const WCHAR source_query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'O','D','B','C','D','a','t','a','S','o','u','r','c','e',0 };

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

    rc = MSI_IterateRecords(view, NULL, ITERATE_InstallODBCDriver, package);
    msiobj_release(&view->hdr);

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

    rc = MSI_IterateRecords(view, NULL, ITERATE_InstallODBCTranslator, package);
    msiobj_release(&view->hdr);

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

    rc = MSI_IterateRecords(view, NULL, ITERATE_InstallODBCDataSource, package);
    msiobj_release(&view->hdr);

    return rc;
}

static UINT ITERATE_RemoveODBCDriver( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    MSIRECORD *uirow;
    DWORD usage;
    LPCWSTR desc;

    desc = MSI_RecordGetString( rec, 3 );
    if (!SQLRemoveDriverW( desc, FALSE, &usage ))
    {
        WARN("Failed to remove ODBC driver\n");
    }
    else if (!usage)
    {
        FIXME("Usage count reached 0\n");
    }

    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, desc );
    MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
    ui_actiondata( package, szRemoveODBC, uirow );
    msiobj_release( &uirow->hdr );

    return ERROR_SUCCESS;
}

static UINT ITERATE_RemoveODBCTranslator( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    MSIRECORD *uirow;
    DWORD usage;
    LPCWSTR desc;

    desc = MSI_RecordGetString( rec, 3 );
    if (!SQLRemoveTranslatorW( desc, &usage ))
    {
        WARN("Failed to remove ODBC translator\n");
    }
    else if (!usage)
    {
        FIXME("Usage count reached 0\n");
    }

    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 1, desc );
    MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
    ui_actiondata( package, szRemoveODBC, uirow );
    msiobj_release( &uirow->hdr );

    return ERROR_SUCCESS;
}

static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    MSIRECORD *uirow;
    LPWSTR attrs;
    LPCWSTR desc, driver;
    WORD request = ODBC_REMOVE_SYS_DSN;
    INT registration;
    DWORD len;

    static const WCHAR attrs_fmt[] = {
        'D','S','N','=','%','s',0 };

    desc = MSI_RecordGetString( rec, 3 );
    driver = MSI_RecordGetString( rec, 4 );
    registration = MSI_RecordGetInteger( rec, 5 );

    if (registration == msidbODBCDataSourceRegistrationPerMachine) request = ODBC_REMOVE_SYS_DSN;
    else if (registration == msidbODBCDataSourceRegistrationPerUser) request = ODBC_REMOVE_DSN;

    len = strlenW( attrs_fmt ) + strlenW( desc ) + 2; /* \0\0 */
    attrs = msi_alloc( len * sizeof(WCHAR) );
    if (!attrs)
        return ERROR_OUTOFMEMORY;

    FIXME("Use ODBCSourceAttribute table\n");

    len = sprintfW( attrs, attrs_fmt, desc );
    attrs[len + 1] = 0;

    if (!SQLConfigDataSourceW( NULL, request, driver, attrs ))
    {
        WARN("Failed to remove ODBC data source\n");
    }
    msi_free( attrs );

    uirow = MSI_CreateRecord( 3 );
    MSI_RecordSetStringW( uirow, 1, desc );
    MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
    MSI_RecordSetInteger( uirow, 3, request );
    ui_actiondata( package, szRemoveODBC, uirow );
    msiobj_release( &uirow->hdr );

    return ERROR_SUCCESS;
}

static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;

    static const WCHAR driver_query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'O','D','B','C','D','r','i','v','e','r',0 };

    static const WCHAR translator_query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0 };

    static const WCHAR source_query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'O','D','B','C','D','a','t','a','S','o','u','r','c','e',0 };

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCDriver, package );
    msiobj_release( &view->hdr );

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCTranslator, package );
    msiobj_release( &view->hdr );

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCDataSource, package );
    msiobj_release( &view->hdr );

    return rc;
}

#define ENV_ACT_SETALWAYS   0x1
#define ENV_ACT_SETABSENT   0x2
#define ENV_ACT_REMOVE      0x4
#define ENV_ACT_REMOVEMATCH 0x8

#define ENV_MOD_MACHINE     0x20000000
#define ENV_MOD_APPEND      0x40000000
#define ENV_MOD_PREFIX      0x80000000
#define ENV_MOD_MASK        0xC0000000

#define check_flag_combo(x, y) ((x) & ~(y)) == (y)

static UINT env_parse_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
{
    LPCWSTR cptr = *name;

    static const WCHAR prefix[] = {'[','~',']',0};
    static const int prefix_len = 3;

    *flags = 0;
    while (*cptr)
    {
        if (*cptr == '=')
            *flags |= ENV_ACT_SETALWAYS;
        else if (*cptr == '+')
            *flags |= ENV_ACT_SETABSENT;
        else if (*cptr == '-')
            *flags |= ENV_ACT_REMOVE;
        else if (*cptr == '!')
            *flags |= ENV_ACT_REMOVEMATCH;
        else if (*cptr == '*')
            *flags |= ENV_MOD_MACHINE;
        else
            break;

        cptr++;
        (*name)++;
    }

    if (!*cptr)
    {
        ERR("Missing environment variable\n");
        return ERROR_FUNCTION_FAILED;
    }

    if (*value)
    {
        LPCWSTR ptr = *value;
        if (!strncmpW(ptr, prefix, prefix_len))
        {
            if (ptr[prefix_len] == szSemiColon[0])
            {
                *flags |= ENV_MOD_APPEND;
                *value += lstrlenW(prefix);
            }
            else
            {
                *value = NULL;
            }
        }
        else if (lstrlenW(*value) >= prefix_len)
        {
            ptr += lstrlenW(ptr) - prefix_len;
            if (!lstrcmpW(ptr, prefix))
            {
                if ((ptr-1) > *value && *(ptr-1) == szSemiColon[0])
                {
                    *flags |= ENV_MOD_PREFIX;
                    /* the "[~]" will be removed by deformat_string */;
                }
                else
                {
                    *value = NULL;
                }
            }
        }
    }

    if (check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) ||
        check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETABSENT) ||
        check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETALWAYS) ||
        check_flag_combo(*flags, ENV_ACT_SETABSENT | ENV_MOD_MASK))
    {
        ERR("Invalid flags: %08x\n", *flags);
        return ERROR_FUNCTION_FAILED;
    }

    if (!*flags)
        *flags = ENV_ACT_SETALWAYS | ENV_ACT_REMOVE;

    return ERROR_SUCCESS;
}

static UINT open_env_key( DWORD flags, HKEY *key )
{
    static const WCHAR user_env[] =
        {'E','n','v','i','r','o','n','m','e','n','t',0};
    static const WCHAR machine_env[] =
        {'S','y','s','t','e','m','\\',
         'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
         'C','o','n','t','r','o','l','\\',
         'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
         'E','n','v','i','r','o','n','m','e','n','t',0};
    const WCHAR *env;
    HKEY root;
    LONG res;

    if (flags & ENV_MOD_MACHINE)
    {
        env = machine_env;
        root = HKEY_LOCAL_MACHINE;
    }
    else
    {
        env = user_env;
        root = HKEY_CURRENT_USER;
    }

    res = RegOpenKeyExW( root, env, 0, KEY_ALL_ACCESS, key );
    if (res != ERROR_SUCCESS)
    {
        WARN("Failed to open key %s (%d)\n", debugstr_w(env), res);
        return ERROR_FUNCTION_FAILED;
    }

    return ERROR_SUCCESS;
}

static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPCWSTR name, value, component;
    LPWSTR data = NULL, newval = NULL, deformatted = NULL, ptr;
    DWORD flags, type, size;
    UINT res;
    HKEY env = NULL;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    int action = 0;

    component = MSI_RecordGetString(rec, 4);
    comp = get_loaded_component(package, component);
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_LOCAL)
    {
        TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_LOCAL;

    name = MSI_RecordGetString(rec, 2);
    value = MSI_RecordGetString(rec, 3);

    TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));

    res = env_parse_flags(&name, &value, &flags);
    if (res != ERROR_SUCCESS || !value)
       goto done;

    if (value && !deformat_string(package, value, &deformatted))
    {
        res = ERROR_OUTOFMEMORY;
        goto done;
    }

    value = deformatted;

    res = open_env_key( flags, &env );
    if (res != ERROR_SUCCESS)
        goto done;

    if (flags & ENV_MOD_MACHINE)
        action |= 0x20000000;

    size = 0;
    type = REG_SZ;
    res = RegQueryValueExW(env, name, NULL, &type, NULL, &size);
    if ((res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ||
        (res == ERROR_SUCCESS && type != REG_SZ && type != REG_EXPAND_SZ))
        goto done;

    if ((res == ERROR_FILE_NOT_FOUND || !(flags & ENV_MOD_MASK)))
    {
        action = 0x2;

        /* Nothing to do. */
        if (!value)
        {
            res = ERROR_SUCCESS;
            goto done;
        }

        /* If we are appending but the string was empty, strip ; */
        if ((flags & ENV_MOD_APPEND) && (value[0] == szSemiColon[0])) value++;

        size = (lstrlenW(value) + 1) * sizeof(WCHAR);
        newval = strdupW(value);
        if (!newval)
        {
            res = ERROR_OUTOFMEMORY;
            goto done;
        }
    }
    else
    {
        action = 0x1;

        /* Contrary to MSDN, +-variable to [~];path works */
        if (flags & ENV_ACT_SETABSENT && !(flags & ENV_MOD_MASK))
        {
            res = ERROR_SUCCESS;
            goto done;
        }

        data = msi_alloc(size);
        if (!data)
        {
            RegCloseKey(env);
            return ERROR_OUTOFMEMORY;
        }

        res = RegQueryValueExW(env, name, NULL, &type, (LPVOID)data, &size);
        if (res != ERROR_SUCCESS)
            goto done;

        if (flags & ENV_ACT_REMOVEMATCH && (!value || !lstrcmpW(data, value)))
        {
            action = 0x4;
            res = RegDeleteValueW(env, name);
            if (res != ERROR_SUCCESS)
                WARN("Failed to remove value %s (%d)\n", debugstr_w(name), res);
            goto done;
        }

        size = (lstrlenW(data) + 1) * sizeof(WCHAR);
        if (flags & ENV_MOD_MASK)
        {
            DWORD mod_size;
            int multiplier = 0;
            if (flags & ENV_MOD_APPEND) multiplier++;
            if (flags & ENV_MOD_PREFIX) multiplier++;
            mod_size = lstrlenW(value) * multiplier;
            size += mod_size * sizeof(WCHAR);
        }

        newval = msi_alloc(size);
        ptr = newval;
        if (!newval)
        {
            res = ERROR_OUTOFMEMORY;
            goto done;
        }

        if (flags & ENV_MOD_PREFIX)
        {
            lstrcpyW(newval, value);
            ptr = newval + lstrlenW(value);
            action |= 0x80000000;
        }

        lstrcpyW(ptr, data);

        if (flags & ENV_MOD_APPEND)
        {
            lstrcatW(newval, value);
            action |= 0x40000000;
        }
    }
    TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval));
    res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size);
    if (res)
    {
        WARN("Failed to set %s to %s (%d)\n",  debugstr_w(name), debugstr_w(newval), res);
    }

done:
    uirow = MSI_CreateRecord( 3 );
    MSI_RecordSetStringW( uirow, 1, name );
    MSI_RecordSetStringW( uirow, 2, newval );
    MSI_RecordSetInteger( uirow, 3, action );
    ui_actiondata( package, szWriteEnvironmentStrings, uirow );
    msiobj_release( &uirow->hdr );

    if (env) RegCloseKey(env);
    msi_free(deformatted);
    msi_free(data);
    msi_free(newval);
    return res;
}

static UINT ACTION_WriteEnvironmentStrings( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY * view;
    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','E','n','v','i','r','o','n','m','e','n','t','`',0};
    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
    if (rc != ERROR_SUCCESS)
        return ERROR_SUCCESS;

    rc = MSI_IterateRecords(view, NULL, ITERATE_WriteEnvironmentString, package);
    msiobj_release(&view->hdr);

    return rc;
}

static UINT ITERATE_RemoveEnvironmentString( MSIRECORD *rec, LPVOID param )
{
    MSIPACKAGE *package = param;
    LPCWSTR name, value, component;
    LPWSTR deformatted = NULL;
    DWORD flags;
    HKEY env;
    MSICOMPONENT *comp;
    MSIRECORD *uirow;
    int action = 0;
    LONG res;
    UINT r;

    component = MSI_RecordGetString( rec, 4 );
    comp = get_loaded_component( package, component );
    if (!comp)
        return ERROR_SUCCESS;

    if (comp->ActionRequest != INSTALLSTATE_ABSENT)
    {
        TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
        comp->Action = comp->Installed;
        return ERROR_SUCCESS;
    }
    comp->Action = INSTALLSTATE_ABSENT;

    name = MSI_RecordGetString( rec, 2 );
    value = MSI_RecordGetString( rec, 3 );

    TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));

    r = env_parse_flags( &name, &value, &flags );
    if (r != ERROR_SUCCESS)
       return r;

    if (!(flags & ENV_ACT_REMOVE))
    {
        TRACE("Environment variable %s not marked for removal\n", debugstr_w(name));
        return ERROR_SUCCESS;
    }

    if (value && !deformat_string( package, value, &deformatted ))
        return ERROR_OUTOFMEMORY;

    value = deformatted;

    r = open_env_key( flags, &env );
    if (r != ERROR_SUCCESS)
    {
        r = ERROR_SUCCESS;
        goto done;
    }

    if (flags & ENV_MOD_MACHINE)
        action |= 0x20000000;

    TRACE("Removing %s\n", debugstr_w(name));

    res = RegDeleteValueW( env, name );
    if (res != ERROR_SUCCESS)
    {
        WARN("Failed to delete value %s (%d)\n", debugstr_w(name), res);
        r = ERROR_SUCCESS;
    }

done:
    uirow = MSI_CreateRecord( 3 );
    MSI_RecordSetStringW( uirow, 1, name );
    MSI_RecordSetStringW( uirow, 2, value );
    MSI_RecordSetInteger( uirow, 3, action );
    ui_actiondata( package, szRemoveEnvironmentStrings, uirow );
    msiobj_release( &uirow->hdr );

    if (env) RegCloseKey( env );
    msi_free( deformatted );
    return r;
}

static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
{
    UINT rc;
    MSIQUERY *view;
    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','E','n','v','i','r','o','n','m','e','n','t','`',0};

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

    rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveEnvironmentString, package );
    msiobj_release( &view->hdr );

    return rc;
}

typedef struct tagMSIASSEMBLY
{
    struct list entry;
    MSICOMPONENT *component;
    MSIFEATURE *feature;
    MSIFILE *file;
    LPWSTR manifest;
    LPWSTR application;
    LPWSTR display_name;
    DWORD attributes;
    BOOL installed;
} MSIASSEMBLY;

static HRESULT (WINAPI *pCreateAssemblyCache)(IAssemblyCache **ppAsmCache,
                                              DWORD dwReserved);
static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion,
                                          LPVOID pvReserved, HMODULE *phModDll);

static BOOL init_functionpointers(void)
{
    HRESULT hr;
    HMODULE hfusion;
    HMODULE hmscoree;

    static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};

    hmscoree = LoadLibraryA("mscoree.dll");
    if (!hmscoree)
    {
        WARN("mscoree.dll not available\n");
        return FALSE;
    }

    pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim");
    if (!pLoadLibraryShim)
    {
        WARN("LoadLibraryShim not available\n");
        FreeLibrary(hmscoree);
        return FALSE;
    }

    hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion);
    if (FAILED(hr))
    {
        WARN("fusion.dll not available\n");
        FreeLibrary(hmscoree);
        return FALSE;
    }

    pCreateAssemblyCache = (void *)GetProcAddress(hfusion, "CreateAssemblyCache");

    FreeLibrary(hmscoree);
    return TRUE;
}

static UINT install_assembly(MSIPACKAGE *package, MSIASSEMBLY *assembly,
                             LPWSTR path)
{
    IAssemblyCache *cache;
    MSIRECORD *uirow;
    HRESULT hr;
    UINT r = ERROR_FUNCTION_FAILED;

    TRACE("installing assembly: %s\n", debugstr_w(path));

    uirow = MSI_CreateRecord( 2 );
    MSI_RecordSetStringW( uirow, 2, assembly->display_name );
    ui_actiondata( package, szMsiPublishAssemblies, uirow );
    msiobj_release( &uirow->hdr );

    if (assembly->feature)
        msi_feature_set_state(package, assembly->feature, INSTALLSTATE_LOCAL);

    if (assembly->manifest)
        FIXME("Manifest unhandled\n");

    if (assembly->application)
    {
        FIXME("Assembly should be privately installed\n");
        return ERROR_SUCCESS;
    }

    if (assembly->attributes == msidbAssemblyAttributesWin32)
    {
        FIXME("Win32 assemblies not handled\n");
        return ERROR_SUCCESS;
    }

    hr = pCreateAssemblyCache(&cache, 0);
    if (FAILED(hr))
        goto done;

    hr = IAssemblyCache_InstallAssembly(cache, 0, path, NULL);
    if (FAILED(hr))
        ERR("Failed to install assembly: %s %08x\n", debugstr_w(path), hr);

    r = ERROR_SUCCESS;

done:
    IAssemblyCache_Release(cache);
    return r;
}

typedef struct tagASSEMBLY_LIST
{
    MSIPACKAGE *package;
    IAssemblyCache *cache;
    struct list *assemblies;
} ASSEMBLY_LIST;

typedef struct tagASSEMBLY_NAME
{
    LPWSTR name;
    LPWSTR version;
    LPWSTR culture;
    LPWSTR pubkeytoken;
} ASSEMBLY_NAME;

static UINT parse_assembly_name(MSIRECORD *rec, LPVOID param)
{
    ASSEMBLY_NAME *asmname = param;
    LPCWSTR name = MSI_RecordGetString(rec, 2);
    LPWSTR val = msi_dup_record_field(rec, 3);

    static const WCHAR Name[] = {'N','a','m','e',0};
    static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
    static const WCHAR Culture[] = {'C','u','l','t','u','r','e',0};
    static const WCHAR PublicKeyToken[] = {
        'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0};

    if (!strcmpiW(name, Name))
        asmname->name = val;
    else if (!strcmpiW(name, Version))
        asmname->version = val;
    else if (!strcmpiW(name, Culture))
        asmname->culture = val;
    else if (!strcmpiW(name, PublicKeyToken))
        asmname->pubkeytoken = val;
    else
        msi_free(val);

    return ERROR_SUCCESS;
}

static void append_str(LPWSTR *str, DWORD *size, LPCWSTR append)
{
    if (!*str)
    {
        *size = lstrlenW(append) + 1;
        *str = msi_alloc((*size) * sizeof(WCHAR));
        lstrcpyW(*str, append);
        return;
    }

    (*size) += lstrlenW(append);
    *str = msi_realloc(*str, (*size) * sizeof(WCHAR));
    lstrcatW(*str, append);
}

static WCHAR *get_assembly_display_name( MSIDATABASE *db, MSICOMPONENT *comp )
{
    static const WCHAR separator[] = {',',' ',0};
    static const WCHAR Version[] = {'V','e','r','s','i','o','n','=',0};
    static const WCHAR Culture[] = {'C','u','l','t','u','r','e','=',0};
    static const WCHAR PublicKeyToken[] = {'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0};
    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        '`','M','s','i','A','s','s','e','m','b','l','y','N','a','m','e','`',' ',
        'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`',
        '=','\'','%','s','\'',0};
    ASSEMBLY_NAME name;
    MSIQUERY *view;
    LPWSTR display_name;
    DWORD size;
    UINT r;

    display_name = NULL;
    memset( &name, 0, sizeof(ASSEMBLY_NAME) );

    r = MSI_OpenQuery( db, &view, query, comp->Component );
    if (r != ERROR_SUCCESS)
        return NULL;

    MSI_IterateRecords( view, NULL, parse_assembly_name, &name );
    msiobj_release( &view->hdr );

    if (!name.name)
    {
        ERR("No assembly name specified!\n");
        return NULL;
    }

    append_str( &display_name, &size, name.name );

    if (name.version)
    {
        append_str( &display_name, &size, separator );
        append_str( &display_name, &size, Version );
        append_str( &display_name, &size, name.version );
    }
    if (name.culture)
    {
        append_str( &display_name, &size, separator );
        append_str( &display_name, &size, Culture );
        append_str( &display_name, &size, name.culture );
    }
    if (name.pubkeytoken)
    {
        append_str( &display_name, &size, separator );
        append_str( &display_name, &size, PublicKeyToken );
        append_str( &display_name, &size, name.pubkeytoken );
    }

    msi_free( name.name );
    msi_free( name.version );
    msi_free( name.culture );
    msi_free( name.pubkeytoken );

    return display_name;
}

static BOOL check_assembly_installed( MSIDATABASE *db, IAssemblyCache *cache, MSICOMPONENT *comp )
{
    ASSEMBLY_INFO asminfo;
    LPWSTR disp;
    BOOL found = FALSE;
    HRESULT hr;

    disp = get_assembly_display_name( db, comp );
    if (!disp)
        return FALSE;

    memset( &asminfo, 0, sizeof(ASSEMBLY_INFO) );
    asminfo.cbAssemblyInfo = sizeof(ASSEMBLY_INFO);

    hr = IAssemblyCache_QueryAssemblyInfo( cache, QUERYASMINFO_FLAG_VALIDATE, disp, &asminfo );
    if (SUCCEEDED(hr))
        found = (asminfo.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED);

    msi_free( disp );
    return found;
}

static UINT load_assembly(MSIRECORD *rec, LPVOID param)
{
    ASSEMBLY_LIST *list = param;
    MSIASSEMBLY *assembly;
    LPCWSTR component;

    assembly = msi_alloc_zero(sizeof(MSIASSEMBLY));
    if (!assembly)
        return ERROR_OUTOFMEMORY;

    component = MSI_RecordGetString(rec, 1);
    assembly->component = get_loaded_component(list->package, component);
    if (!assembly->component)
        return ERROR_SUCCESS;

    if (assembly->component->ActionRequest != INSTALLSTATE_LOCAL &&
        assembly->component->ActionRequest != INSTALLSTATE_SOURCE)
    {
        TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
        assembly->component->Action = assembly->component->Installed;
        return ERROR_SUCCESS;
    }
    assembly->component->Action = assembly->component->ActionRequest;

    assembly->feature = find_feature_by_name(list->package, MSI_RecordGetString(rec, 2));
    assembly->file = msi_find_file(list->package, assembly->component->KeyPath);

    if (!assembly->file)
    {
        ERR("File %s not found\n", debugstr_w(assembly->component->KeyPath));
        return ERROR_FUNCTION_FAILED;
    }

    assembly->manifest = strdupW(MSI_RecordGetString(rec, 3));
    assembly->application = strdupW(MSI_RecordGetString(rec, 4));
    assembly->attributes = MSI_RecordGetInteger(rec, 5);

    if (assembly->application)
    {
        WCHAR version[24];
        DWORD size = sizeof(version)/sizeof(WCHAR);

        /* FIXME: we should probably check the manifest file here */

        if (!MsiGetFileVersionW(assembly->file->TargetPath, version, &size, NULL, NULL) &&
            (!assembly->file->Version || strcmpW(version, assembly->file->Version) >= 0))
        {
            assembly->installed = TRUE;
        }
    }
    else
        assembly->installed = check_assembly_installed(list->package->db,
                                                       list->cache,
                                                       assembly->component);

    list_add_head(list->assemblies, &assembly->entry);
    return ERROR_SUCCESS;
}

static UINT load_assemblies(MSIPACKAGE *package, struct list *assemblies)
{
    IAssemblyCache *cache = NULL;
    ASSEMBLY_LIST list;
    MSIQUERY *view;
    HRESULT hr;
    UINT r;

    static const WCHAR query[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','M','s','i','A','s','s','e','m','b','l','y','`',0};

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

    hr = pCreateAssemblyCache(&cache, 0);
    if (FAILED(hr))
        return ERROR_FUNCTION_FAILED;

    list.package = package;
    list.cache = cache;
    list.assemblies = assemblies;

    r = MSI_IterateRecords(view, NULL, load_assembly, &list);
    msiobj_release(&view->hdr);

    IAssemblyCache_Release(cache);

    return r;
}

static void free_assemblies(struct list *assemblies)
{
    struct list *item, *cursor;

    LIST_FOR_EACH_SAFE(item, cursor, assemblies)
    {
        MSIASSEMBLY *assembly = LIST_ENTRY(item, MSIASSEMBLY, entry);

        list_remove(&assembly->entry);
        msi_free(assembly->application);
        msi_free(assembly->manifest);
        msi_free(assembly->display_name);
        msi_free(assembly);
    }
}

static BOOL find_assembly(struct list *assemblies, LPCWSTR file, MSIASSEMBLY **out)
{
    MSIASSEMBLY *assembly;

    LIST_FOR_EACH_ENTRY(assembly, assemblies, MSIASSEMBLY, entry)
    {
        if (!lstrcmpW(assembly->file->File, file))
        {
            *out = assembly;
            return TRUE;
        }
    }

    return FALSE;
}

static BOOL installassembly_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
                               LPWSTR *path, DWORD *attrs, PVOID user)
{
    MSIASSEMBLY *assembly;
    WCHAR temppath[MAX_PATH];
    struct list *assemblies = user;
    UINT r;

    if (!find_assembly(assemblies, file, &assembly))
        return FALSE;

    GetTempPathW(MAX_PATH, temppath);
    PathAddBackslashW(temppath);
    lstrcatW(temppath, assembly->file->FileName);

    if (action == MSICABEXTRACT_BEGINEXTRACT)
    {
        if (assembly->installed)
            return FALSE;

        *path = strdupW(temppath);
        *attrs = assembly->file->Attributes;
    }
    else if (action == MSICABEXTRACT_FILEEXTRACTED)
    {
        assembly->installed = TRUE;

        r = install_assembly(package, assembly, temppath);
        if (r != ERROR_SUCCESS)
            ERR("Failed to install assembly\n");
    }

    return TRUE;
}

static UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package )
{
    UINT r;
    struct list assemblies = LIST_INIT(assemblies);
    MSIASSEMBLY *assembly;
    MSIMEDIAINFO *mi;

    if (!init_functionpointers() || !pCreateAssemblyCache)
        return ERROR_FUNCTION_FAILED;

    r = load_assemblies(package, &assemblies);
    if (r != ERROR_SUCCESS)
        goto done;

    if (list_empty(&assemblies))
        goto done;

    mi = msi_alloc_zero(sizeof(MSIMEDIAINFO));
    if (!mi)
    {
        r = ERROR_OUTOFMEMORY;
        goto done;
    }

    LIST_FOR_EACH_ENTRY(assembly, &assemblies, MSIASSEMBLY, entry)
    {
        if (assembly->installed && !mi->is_continuous)
            continue;

        if (assembly->file->Sequence > mi->last_sequence || mi->is_continuous ||
            (assembly->file->IsCompressed && !mi->is_extracted))
        {
            MSICABDATA data;

            r = ready_media(package, assembly->file, mi);
            if (r != ERROR_SUCCESS)
            {
                ERR("Failed to ready media\n");
                break;
            }

            data.mi = mi;
            data.package = package;
            data.cb = installassembly_cb;
            data.user = &assemblies;

            if (assembly->file->IsCompressed &&
                !msi_cabextract(package, mi, &data))
            {
                ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
                r = ERROR_FUNCTION_FAILED;
                break;
            }
        }

        if (!assembly->file->IsCompressed)
        {
            LPWSTR source = resolve_file_source(package, assembly->file);

            r = install_assembly(package, assembly, source);
            if (r != ERROR_SUCCESS)
                ERR("Failed to install assembly\n");

            msi_free(source);
        }

        /* FIXME: write Installer assembly reg values */
    }

done:
    free_assemblies(&assemblies);
    return r;
}

static UINT ACTION_ValidateProductID( MSIPACKAGE *package )
{
    LPWSTR key, template, id;
    UINT r = ERROR_SUCCESS;

    id = msi_dup_property( package->db, szProductID );
    if (id)
    {
        msi_free( id );
        return ERROR_SUCCESS;
    }
    template = msi_dup_property( package->db, szPIDTemplate );
    key = msi_dup_property( package->db, szPIDKEY );

    if (key && template)
    {
        FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) );
        r = msi_set_property( package->db, szProductID, key );
    }
    msi_free( template );
    msi_free( key );
    return r;
}

static UINT ACTION_ScheduleReboot( MSIPACKAGE *package )
{
    TRACE("\n");
    package->need_reboot = 1;
    return ERROR_SUCCESS;
}

static UINT ACTION_AllocateRegistrySpace( MSIPACKAGE *package )
{
    static const WCHAR szAvailableFreeReg[] =
        {'A','V','A','I','L','A','B','L','E','F','R','E','E','R','E','G',0};
    MSIRECORD *uirow;
    int space = msi_get_property_int( package->db, szAvailableFreeReg, 0 );

    TRACE("%p %d kilobytes\n", package, space);

    uirow = MSI_CreateRecord( 1 );
    MSI_RecordSetInteger( uirow, 1, space );
    ui_actiondata( package, szAllocateRegistrySpace, uirow );
    msiobj_release( &uirow->hdr );

    return ERROR_SUCCESS;
}

static UINT ACTION_DisableRollback( MSIPACKAGE *package )
{
    FIXME("%p\n", package);
    return ERROR_SUCCESS;
}

static UINT ACTION_InstallAdminPackage( MSIPACKAGE *package )
{
    FIXME("%p\n", package);
    return ERROR_SUCCESS;
}

static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
{
    UINT r, count;
    MSIQUERY *view;

    static const WCHAR driver_query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'O','D','B','C','D','r','i','v','e','r',0 };

    static const WCHAR translator_query[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0 };

    r = MSI_DatabaseOpenViewW( package->db, driver_query, &view );
    if (r == ERROR_SUCCESS)
    {
        count = 0;
        r = MSI_IterateRecords( view, &count, NULL, package );
        msiobj_release( &view->hdr );
        if (count) FIXME("ignored %u rows in ODBCDriver table\n", count);
    }

    r = MSI_DatabaseOpenViewW( package->db, translator_query, &view );
    if (r == ERROR_SUCCESS)
    {
        count = 0;
        r = MSI_IterateRecords( view, &count, NULL, package );
        msiobj_release( &view->hdr );
        if (count) FIXME("ignored %u rows in ODBCTranslator table\n", count);
    }

    return ERROR_SUCCESS;
}

static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
                                           LPCSTR action, LPCWSTR table )
{
    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ',
        'F','R','O','M',' ','`','%','s','`',0 };
    MSIQUERY *view = NULL;
    DWORD count = 0;
    UINT r;
    
    r = MSI_OpenQuery( package->db, &view, query, table );
    if (r == ERROR_SUCCESS)
    {
        r = MSI_IterateRecords(view, &count, NULL, package);
        msiobj_release(&view->hdr);
    }

    if (count)
        FIXME("%s -> %u ignored %s table values\n",
              action, count, debugstr_w(table));

    return ERROR_SUCCESS;
}

static UINT ACTION_PatchFiles( MSIPACKAGE *package )
{
    static const WCHAR table[] = { 'P','a','t','c','h',0 };
    return msi_unimplemented_action_stub( package, "PatchFiles", table );
}

static UINT ACTION_BindImage( MSIPACKAGE *package )
{
    static const WCHAR table[] = { 'B','i','n','d','I','m','a','g','e',0 };
    return msi_unimplemented_action_stub( package, "BindImage", table );
}

static UINT ACTION_IsolateComponents( MSIPACKAGE *package )
{
    static const WCHAR table[] = {
        'I','s','o','l','a','t','e','d','C','o','m','p','o','n','e','n','t',0 };
    return msi_unimplemented_action_stub( package, "IsolateComponents", table );
}

static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package )
{
    static const WCHAR table[] = { 'U','p','g','r','a','d','e',0 };
    return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table );
}

static UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package )
{
    static const WCHAR table[] = {
        'M','s','i','A','s','s','e','m','b','l','y',0 };
    return msi_unimplemented_action_stub( package, "MsiUnpublishAssemblies", table );
}

static UINT ACTION_RMCCPSearch( MSIPACKAGE *package )
{
    static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 };
    return msi_unimplemented_action_stub( package, "RMCCPSearch", table );
}

static UINT ACTION_RegisterComPlus( MSIPACKAGE *package )
{
    static const WCHAR table[] = { 'C','o','m','p','l','u','s',0 };
    return msi_unimplemented_action_stub( package, "RegisterComPlus", table );
}

static UINT ACTION_UnregisterComPlus( MSIPACKAGE *package )
{
    static const WCHAR table[] = { 'C','o','m','p','l','u','s',0 };
    return msi_unimplemented_action_stub( package, "UnregisterComPlus", table );
}

static UINT ACTION_InstallSFPCatalogFile( MSIPACKAGE *package )
{
    static const WCHAR table[] = { 'S','F','P','C','a','t','a','l','o','g',0 };
    return msi_unimplemented_action_stub( package, "InstallSFPCatalogFile", table );
}

static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
{
    static const WCHAR table[] = { 'U','p','g','r','a','d','e',0 };
    return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table );
}

typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);

static const struct
{
    const WCHAR *action;
    UINT (*handler)(MSIPACKAGE *);
}
StandardActions[] =
{
    { szAllocateRegistrySpace, ACTION_AllocateRegistrySpace },
    { szAppSearch, ACTION_AppSearch },
    { szBindImage, ACTION_BindImage },
    { szCCPSearch, ACTION_CCPSearch },
    { szCostFinalize, ACTION_CostFinalize },
    { szCostInitialize, ACTION_CostInitialize },
    { szCreateFolders, ACTION_CreateFolders },
    { szCreateShortcuts, ACTION_CreateShortcuts },
    { szDeleteServices, ACTION_DeleteServices },
    { szDisableRollback, ACTION_DisableRollback },
    { szDuplicateFiles, ACTION_DuplicateFiles },
    { szExecuteAction, ACTION_ExecuteAction },
    { szFileCost, ACTION_FileCost },
    { szFindRelatedProducts, ACTION_FindRelatedProducts },
    { szForceReboot, ACTION_ForceReboot },
    { szInstallAdminPackage, ACTION_InstallAdminPackage },
    { szInstallExecute, ACTION_InstallExecute },
    { szInstallExecuteAgain, ACTION_InstallExecute },
    { szInstallFiles, ACTION_InstallFiles},
    { szInstallFinalize, ACTION_InstallFinalize },
    { szInstallInitialize, ACTION_InstallInitialize },
    { szInstallSFPCatalogFile, ACTION_InstallSFPCatalogFile },
    { szInstallValidate, ACTION_InstallValidate },
    { szIsolateComponents, ACTION_IsolateComponents },
    { szLaunchConditions, ACTION_LaunchConditions },
    { szMigrateFeatureStates, ACTION_MigrateFeatureStates },
    { szMoveFiles, ACTION_MoveFiles },
    { szMsiPublishAssemblies, ACTION_MsiPublishAssemblies },
    { szMsiUnpublishAssemblies, ACTION_MsiUnpublishAssemblies },
    { szInstallODBC, ACTION_InstallODBC },
    { szInstallServices, ACTION_InstallServices },
    { szPatchFiles, ACTION_PatchFiles },
    { szProcessComponents, ACTION_ProcessComponents },
    { szPublishComponents, ACTION_PublishComponents },
    { szPublishFeatures, ACTION_PublishFeatures },
    { szPublishProduct, ACTION_PublishProduct },
    { szRegisterClassInfo, ACTION_RegisterClassInfo },
    { szRegisterComPlus, ACTION_RegisterComPlus},
    { szRegisterExtensionInfo, ACTION_RegisterExtensionInfo },
    { szRegisterFonts, ACTION_RegisterFonts },
    { szRegisterMIMEInfo, ACTION_RegisterMIMEInfo },
    { szRegisterProduct, ACTION_RegisterProduct },
    { szRegisterProgIdInfo, ACTION_RegisterProgIdInfo },
    { szRegisterTypeLibraries, ACTION_RegisterTypeLibraries },
    { szRegisterUser, ACTION_RegisterUser },
    { szRemoveDuplicateFiles, ACTION_RemoveDuplicateFiles },
    { szRemoveEnvironmentStrings, ACTION_RemoveEnvironmentStrings },
    { szRemoveExistingProducts, ACTION_RemoveExistingProducts },
    { szRemoveFiles, ACTION_RemoveFiles },
    { szRemoveFolders, ACTION_RemoveFolders },
    { szRemoveIniValues, ACTION_RemoveIniValues },
    { szRemoveODBC, ACTION_RemoveODBC },
    { szRemoveRegistryValues, ACTION_RemoveRegistryValues },
    { szRemoveShortcuts, ACTION_RemoveShortcuts },
    { szResolveSource, ACTION_ResolveSource },
    { szRMCCPSearch, ACTION_RMCCPSearch },
    { szScheduleReboot, ACTION_ScheduleReboot },
    { szSelfRegModules, ACTION_SelfRegModules },
    { szSelfUnregModules, ACTION_SelfUnregModules },
    { szSetODBCFolders, ACTION_SetODBCFolders },
    { szStartServices, ACTION_StartServices },
    { szStopServices, ACTION_StopServices },
    { szUnpublishComponents, ACTION_UnpublishComponents },
    { szUnpublishFeatures, ACTION_UnpublishFeatures },
    { szUnregisterClassInfo, ACTION_UnregisterClassInfo },
    { szUnregisterComPlus, ACTION_UnregisterComPlus },
    { szUnregisterExtensionInfo, ACTION_UnregisterExtensionInfo },
    { szUnregisterFonts, ACTION_UnregisterFonts },
    { szUnregisterMIMEInfo, ACTION_UnregisterMIMEInfo },
    { szUnregisterProgIdInfo, ACTION_UnregisterProgIdInfo },
    { szUnregisterTypeLibraries, ACTION_UnregisterTypeLibraries },
    { szValidateProductID, ACTION_ValidateProductID },
    { szWriteEnvironmentStrings, ACTION_WriteEnvironmentStrings },
    { szWriteIniValues, ACTION_WriteIniValues },
    { szWriteRegistryValues, ACTION_WriteRegistryValues },
    { NULL, NULL },
};

static BOOL ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action,
                                        UINT* rc, BOOL force )
{
    BOOL ret = FALSE;
    BOOL run = force;
    int i;

    if (!run && !package->script->CurrentlyScripting)
        run = TRUE;

    if (!run)
    {
        if (strcmpW(action,szInstallFinalize) == 0 ||
            strcmpW(action,szInstallExecute) == 0 ||
            strcmpW(action,szInstallExecuteAgain) == 0)
                run = TRUE;
    }

    i = 0;
    while (StandardActions[i].action != NULL)
    {
        if (strcmpW(StandardActions[i].action, action)==0)
        {
            if (!run)
            {
                ui_actioninfo(package, action, TRUE, 0);
                *rc = schedule_action(package,INSTALL_SCRIPT,action);
                ui_actioninfo(package, action, FALSE, *rc);
            }
            else
            {
                ui_actionstart(package, action);
                if (StandardActions[i].handler)
                {
                    *rc = StandardActions[i].handler(package);
                }
                else
                {
                    FIXME("unhandled standard action %s\n",debugstr_w(action));
                    *rc = ERROR_SUCCESS;
                }
            }
            ret = TRUE;
            break;
        }
        i++;
    }
    return ret;
}

UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action, UINT script, BOOL force)
{
    UINT rc = ERROR_SUCCESS;
    BOOL handled;

    TRACE("Performing action (%s)\n", debugstr_w(action));

    handled = ACTION_HandleStandardAction(package, action, &rc, force);

    if (!handled)
        handled = ACTION_HandleCustomAction(package, action, &rc, script, force);

    if (!handled)
    {
        WARN("unhandled msi action %s\n", debugstr_w(action));
        rc = ERROR_FUNCTION_NOT_CALLED;
    }

    return rc;
}

UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action, UINT script)
{
    UINT rc = ERROR_SUCCESS;
    BOOL handled = FALSE;

    TRACE("Performing action (%s)\n", debugstr_w(action));

    handled = ACTION_HandleStandardAction(package, action, &rc,TRUE);

    if (!handled)
        handled = ACTION_HandleCustomAction(package, action, &rc, script, FALSE);

    if( !handled && ACTION_DialogBox(package, action) == ERROR_SUCCESS )
        handled = TRUE;

    if (!handled)
    {
        WARN("unhandled msi action %s\n", debugstr_w(action));
        rc = ERROR_FUNCTION_NOT_CALLED;
    }

    return rc;
}

static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
{
    UINT rc = ERROR_SUCCESS;
    MSIRECORD *row;

    static const WCHAR ExecSeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','I','n','s','t','a','l','l','E','x','e','c','u','t','e',
         'S','e','q','u','e','n','c','e','`',' ', 'W','H','E','R','E',' ',
         '`','S','e','q','u','e','n','c','e','`',' ', '=',' ','%','i',0};
    static const WCHAR UISeqQuery[] =
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
     '`','I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e',
     '`', ' ', 'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',
	 ' ', '=',' ','%','i',0};

    if (needs_ui_sequence(package))
        row = MSI_QueryGetRecord(package->db, UISeqQuery, seq);
    else
        row = MSI_QueryGetRecord(package->db, ExecSeqQuery, seq);

    if (row)
    {
        LPCWSTR action, cond;

        TRACE("Running the actions\n");

        /* check conditions */
        cond = MSI_RecordGetString(row, 2);

        /* this is a hack to skip errors in the condition code */
        if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)
        {
            msiobj_release(&row->hdr);
            return ERROR_SUCCESS;
        }

        action = MSI_RecordGetString(row, 1);
        if (!action)
        {
            ERR("failed to fetch action\n");
            msiobj_release(&row->hdr);
            return ERROR_FUNCTION_FAILED;
        }

        if (needs_ui_sequence(package))
            rc = ACTION_PerformUIAction(package, action, -1);
        else
            rc = ACTION_PerformAction(package, action, -1, FALSE);

        msiobj_release(&row->hdr);
    }

    return rc;
}

/****************************************************
 * TOP level entry points
 *****************************************************/

UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
                         LPCWSTR szCommandLine )
{
    UINT rc;
    BOOL ui_exists;

    static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
    static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};

    msi_set_property( package->db, szAction, szInstall );

    package->script->InWhatSequence = SEQUENCE_INSTALL;

    if (szPackagePath)
    {
        LPWSTR p, dir;
        LPCWSTR file;

        dir = strdupW(szPackagePath);
        p = strrchrW(dir, '\\');
        if (p)
        {
            *(++p) = 0;
            file = szPackagePath + (p - dir);
        }
        else
        {
            msi_free(dir);
            dir = msi_alloc(MAX_PATH * sizeof(WCHAR));
            GetCurrentDirectoryW(MAX_PATH, dir);
            lstrcatW(dir, szBackSlash);
            file = szPackagePath;
        }

        msi_free( package->PackagePath );
        package->PackagePath = msi_alloc((lstrlenW(dir) + lstrlenW(file) + 1) * sizeof(WCHAR));
        if (!package->PackagePath)
        {
            msi_free(dir);
            return ERROR_OUTOFMEMORY;
        }

        lstrcpyW(package->PackagePath, dir);
        lstrcatW(package->PackagePath, file);
        msi_free(dir);

        msi_set_sourcedir_props(package, FALSE);
    }

    msi_parse_command_line( package, szCommandLine, FALSE );

    msi_apply_transforms( package );
    msi_apply_patches( package );

    if (!szCommandLine && msi_get_property_int( package->db, szInstalled, 0 ))
    {
        TRACE("setting reinstall property\n");
        msi_set_property( package->db, szReinstall, szAll );
    }

    /* properties may have been added by a transform */
    msi_clone_properties( package );
    msi_set_context( package );

    if (needs_ui_sequence( package))
    {
        package->script->InWhatSequence |= SEQUENCE_UI;
        rc = ACTION_ProcessUISequence(package);
        ui_exists = ui_sequence_exists(package);
        if (rc == ERROR_SUCCESS || !ui_exists)
        {
            package->script->InWhatSequence |= SEQUENCE_EXEC;
            rc = ACTION_ProcessExecSequence(package, ui_exists);
        }
    }
    else
        rc = ACTION_ProcessExecSequence(package, FALSE);

    package->script->CurrentlyScripting = FALSE;

    /* process the ending type action */
    if (rc == ERROR_SUCCESS)
        ACTION_PerformActionSequence(package, -1);
    else if (rc == ERROR_INSTALL_USEREXIT)
        ACTION_PerformActionSequence(package, -2);
    else if (rc == ERROR_INSTALL_SUSPEND)
        ACTION_PerformActionSequence(package, -4);
    else  /* failed */
        ACTION_PerformActionSequence(package, -3);

    /* finish up running custom actions */
    ACTION_FinishCustomActions(package);

    if (rc == ERROR_SUCCESS && package->need_reboot)
        return ERROR_SUCCESS_REBOOT_REQUIRED;

    return rc;
}
