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

/* Msi top level apis directly related to installs */

#define COBJMACROS

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "msi.h"
#include "msidefs.h"
#include "objbase.h"
#include "oleauto.h"

#include "msipriv.h"
#include "msiserver.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);

/***********************************************************************
 * MsiDoActionA       (MSI.@)
 */
UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
{
    LPWSTR szwAction;
    UINT ret;

    TRACE("%s\n", debugstr_a(szAction));

    szwAction = strdupAtoW(szAction);
    if (szAction && !szwAction)
        return ERROR_FUNCTION_FAILED; 

    ret = MsiDoActionW( hInstall, szwAction );
    msi_free( szwAction );
    return ret;
}

/***********************************************************************
 * MsiDoActionW       (MSI.@)
 */
UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
{
    MSIPACKAGE *package;
    UINT ret;

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

    if (!szAction)
        return ERROR_INVALID_PARAMETER;

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

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

        action = SysAllocString( szAction );
        if (!action)
        {
            IWineMsiRemotePackage_Release( remote_package );
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_DoAction( remote_package, action );

        SysFreeString( action );
        IWineMsiRemotePackage_Release( remote_package );

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }
 
    ret = ACTION_PerformAction( package, szAction );
    msiobj_release( &package->hdr );

    return ret;
}

/***********************************************************************
 * MsiSequenceA       (MSI.@)
 */
UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
{
    LPWSTR szwTable;
    UINT ret;

    TRACE("%s, %d\n", debugstr_a(szTable), iSequenceMode);

    szwTable = strdupAtoW(szTable);
    if (szTable && !szwTable)
        return ERROR_FUNCTION_FAILED; 

    ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
    msi_free( szwTable );
    return ret;
}

/***********************************************************************
 * MsiSequenceW       (MSI.@)
 */
UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
{
    MSIPACKAGE *package;
    UINT ret;

    TRACE("%s, %d\n", debugstr_w(szTable), iSequenceMode);

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

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

        table = SysAllocString( szTable );
        if (!table)
        {
            IWineMsiRemotePackage_Release( remote_package );
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_Sequence( remote_package, table, iSequenceMode );

        SysFreeString( table );
        IWineMsiRemotePackage_Release( remote_package );

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }
    ret = MSI_Sequence( package, szTable );
    msiobj_release( &package->hdr );
    return ret;
}

UINT msi_strcpy_to_awstring( const WCHAR *str, int len, awstring *awbuf, DWORD *sz )
{
    UINT r = ERROR_SUCCESS;

    if (awbuf->str.w && !sz)
        return ERROR_INVALID_PARAMETER;
    if (!sz)
        return ERROR_SUCCESS;

    if (len < 0) len = strlenW( str );
 
    if (awbuf->unicode && awbuf->str.w)
        memcpy( awbuf->str.w, str, min(len + 1, *sz) * sizeof(WCHAR) );
    else
    {
        int lenA = WideCharToMultiByte( CP_ACP, 0, str, len + 1, NULL, 0, NULL, NULL );
        if (lenA) lenA--;
        WideCharToMultiByte( CP_ACP, 0, str, len + 1, awbuf->str.a, *sz, NULL, NULL );
        if (awbuf->str.a && *sz && lenA >= *sz)
            awbuf->str.a[*sz - 1] = 0;
        len = lenA;
    }
    if (awbuf->str.w && len >= *sz)
        r = ERROR_MORE_DATA;
    *sz = len;
    return r;
}

const WCHAR *msi_get_target_folder( MSIPACKAGE *package, const WCHAR *name )
{
    MSIFOLDER *folder = msi_get_loaded_folder( package, name );

    if (!folder) return NULL;
    if (!folder->ResolvedTarget)
    {
        MSIFOLDER *parent = folder;
        while (parent->Parent && strcmpW( parent->Parent, parent->Directory ))
        {
            parent = msi_get_loaded_folder( package, parent->Parent );
        }
        msi_resolve_target_folder( package, parent->Directory, TRUE );
    }
    return folder->ResolvedTarget;
}

/***********************************************************************
 * MsiGetTargetPath   (internal)
 */
static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
                               awstring *szPathBuf, LPDWORD pcchPathBuf )
{
    MSIPACKAGE *package;
    const WCHAR *path;
    UINT r = ERROR_FUNCTION_FAILED;

    if (!szFolder)
        return ERROR_INVALID_PARAMETER;

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

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

        folder = SysAllocString( szFolder );
        if (!folder)
        {
            IWineMsiRemotePackage_Release( remote_package );
            return ERROR_OUTOFMEMORY;
        }

        len = 0;
        hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder, NULL, &len );
        if (FAILED(hr))
            goto done;

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

        hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder, value, &len );
        if (FAILED(hr))
            goto done;

        r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf );

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

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

            return ERROR_FUNCTION_FAILED;
        }

        return r;
    }

    path = msi_get_target_folder( package, szFolder );
    msiobj_release( &package->hdr );

    if (!path)
        return ERROR_DIRECTORY;

    return msi_strcpy_to_awstring( path, -1, szPathBuf, pcchPathBuf );
}

/***********************************************************************
 * MsiGetTargetPathA        (MSI.@)
 */
UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, 
                               LPSTR szPathBuf, LPDWORD pcchPathBuf )
{
    LPWSTR szwFolder;
    awstring path;
    UINT r;

    TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);

    szwFolder = strdupAtoW(szFolder);
    if (szFolder && !szwFolder)
        return ERROR_FUNCTION_FAILED; 

    path.unicode = FALSE;
    path.str.a = szPathBuf;

    r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );

    msi_free( szwFolder );

    return r;
}

/***********************************************************************
 * MsiGetTargetPathW        (MSI.@)
 */
UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
                               LPWSTR szPathBuf, LPDWORD pcchPathBuf )
{
    awstring path;

    TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);

    path.unicode = TRUE;
    path.str.w = szPathBuf;

    return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
}

static WCHAR *get_source_root( MSIPACKAGE *package )
{
    msi_set_sourcedir_props( package, FALSE );
    return msi_dup_property( package->db, szSourceDir );
}

WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder )
{
    MSIFOLDER *f;
    LPWSTR p, path = NULL, parent;

    TRACE("working to resolve %s\n", debugstr_w(name));

    if (!strcmpW( name, szSourceDir )) name = szTargetDir;
    if (!(f = msi_get_loaded_folder( package, name ))) return NULL;

    /* special resolving for root dir */
    if (!strcmpW( name, szTargetDir ) && !f->ResolvedSource)
    {
        f->ResolvedSource = get_source_root( package );
    }
    if (folder) *folder = f;
    if (f->ResolvedSource)
    {
        path = strdupW( f->ResolvedSource );
        TRACE("   already resolved to %s\n", debugstr_w(path));
        return path;
    }
    if (!f->Parent) return path;
    parent = f->Parent;
    TRACE(" ! parent is %s\n", debugstr_w(parent));

    p = msi_resolve_source_folder( package, parent, NULL );

    if (package->WordCount & msidbSumInfoSourceTypeCompressed)
        path = get_source_root( package );
    else if (package->WordCount & msidbSumInfoSourceTypeSFN)
        path = msi_build_directory_name( 3, p, f->SourceShortPath, NULL );
    else
        path = msi_build_directory_name( 3, p, f->SourceLongPath, NULL );

    TRACE("-> %s\n", debugstr_w(path));
    f->ResolvedSource = strdupW( path );
    msi_free( p );

    return path;
}

/***********************************************************************
 * MSI_GetSourcePath   (internal)
 */
static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
                               awstring *szPathBuf, LPDWORD pcchPathBuf )
{
    MSIPACKAGE *package;
    LPWSTR path;
    UINT r = ERROR_FUNCTION_FAILED;

    TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );

    if (!szFolder)
        return ERROR_INVALID_PARAMETER;

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

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

        folder = SysAllocString( szFolder );
        if (!folder)
        {
            IWineMsiRemotePackage_Release( remote_package );
            return ERROR_OUTOFMEMORY;
        }

        len = 0;
        hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder, NULL, &len );
        if (FAILED(hr))
            goto done;

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

        hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder, value, &len );
        if (FAILED(hr))
            goto done;

        r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf );

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

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

            return ERROR_FUNCTION_FAILED;
        }

        return r;
    }

    if (szPathBuf->str.w && !pcchPathBuf )
    {
        msiobj_release( &package->hdr );
        return ERROR_INVALID_PARAMETER;
    }

    path = msi_resolve_source_folder( package, szFolder, NULL );
    msiobj_release( &package->hdr );

    TRACE("path = %s\n", debugstr_w(path));
    if (!path)
        return ERROR_DIRECTORY;

    r = msi_strcpy_to_awstring( path, -1, szPathBuf, pcchPathBuf );
    msi_free( path );
    return r;
}

/***********************************************************************
 * MsiGetSourcePathA     (MSI.@)
 */
UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder, 
                               LPSTR szPathBuf, LPDWORD pcchPathBuf )
{
    LPWSTR folder;
    awstring str;
    UINT r;

    TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);

    str.unicode = FALSE;
    str.str.a = szPathBuf;

    folder = strdupAtoW( szFolder );
    r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
    msi_free( folder );

    return r;
}

/***********************************************************************
 * MsiGetSourcePathW     (MSI.@)
 */
UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
                               LPWSTR szPathBuf, LPDWORD pcchPathBuf )
{
    awstring str;

    TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );

    str.unicode = TRUE;
    str.str.w = szPathBuf;

    return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
}

/***********************************************************************
 * MsiSetTargetPathA  (MSI.@)
 */
UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
                               LPCSTR szFolderPath )
{
    LPWSTR szwFolder = NULL, szwFolderPath = NULL;
    UINT rc = ERROR_OUTOFMEMORY;

    if ( !szFolder || !szFolderPath )
        return ERROR_INVALID_PARAMETER;

    szwFolder = strdupAtoW(szFolder);
    szwFolderPath = strdupAtoW(szFolderPath);
    if (!szwFolder || !szwFolderPath)
        goto end;

    rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );

end:
    msi_free(szwFolder);
    msi_free(szwFolderPath);

    return rc;
}

static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR *path )
{
    FolderList *fl;
    MSIFOLDER *child;
    WCHAR *target_path;

    if (!(target_path = msi_normalize_path( path ))) return;
    if (strcmpW( target_path, folder->ResolvedTarget ))
    {
        msi_free( folder->ResolvedTarget );
        folder->ResolvedTarget = target_path;
        msi_set_property( package->db, folder->Directory, folder->ResolvedTarget, -1 );

        LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry )
        {
            child = fl->folder;
            msi_resolve_target_folder( package, child->Directory, FALSE );
        }
    }
    else msi_free( target_path );
}

UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath )
{
    DWORD attrib;
    MSIFOLDER *folder;
    MSIFILE *file;

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

    attrib = GetFileAttributesW(szFolderPath);
    /* native MSI tests writeability by making temporary files at each drive */
    if (attrib != INVALID_FILE_ATTRIBUTES &&
        (attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY))
    {
        return ERROR_FUNCTION_FAILED;
    }
    if (!(folder = msi_get_loaded_folder( package, szFolder ))) return ERROR_DIRECTORY;

    set_target_path( package, folder, szFolderPath );

    LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
    {
        const WCHAR *dir;
        MSICOMPONENT *comp = file->Component;

        if (!comp->Enabled || msi_is_global_assembly( comp )) continue;

        dir = msi_get_target_folder( package, comp->Directory );
        msi_free( file->TargetPath );
        file->TargetPath = msi_build_directory_name( 2, dir, file->FileName );
    }
    return ERROR_SUCCESS;
}

/***********************************************************************
 * MsiSetTargetPathW  (MSI.@)
 */
UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, 
                             LPCWSTR szFolderPath)
{
    MSIPACKAGE *package;
    UINT ret;

    TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath));

    if ( !szFolder || !szFolderPath )
        return ERROR_INVALID_PARAMETER;

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

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

        folder = SysAllocString( szFolder );
        path = SysAllocString( szFolderPath );
        if (!folder || !path)
        {
            SysFreeString(folder);
            SysFreeString(path);
            IWineMsiRemotePackage_Release( remote_package );
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_SetTargetPath( remote_package, folder, path );

        SysFreeString(folder);
        SysFreeString(path);
        IWineMsiRemotePackage_Release( remote_package );

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
    msiobj_release( &package->hdr );
    return ret;
}

/***********************************************************************
 *           MsiGetMode    (MSI.@)
 *
 * Returns an internal installer state (if it is running in a mode iRunMode)
 *
 * PARAMS
 *   hInstall    [I]  Handle to the installation
 *   hRunMode    [I]  Checking run mode
 *        MSIRUNMODE_ADMIN             Administrative mode
 *        MSIRUNMODE_ADVERTISE         Advertisement mode
 *        MSIRUNMODE_MAINTENANCE       Maintenance mode
 *        MSIRUNMODE_ROLLBACKENABLED   Rollback is enabled
 *        MSIRUNMODE_LOGENABLED        Log file is writing
 *        MSIRUNMODE_OPERATIONS        Operations in progress??
 *        MSIRUNMODE_REBOOTATEND       We need to reboot after installation completed
 *        MSIRUNMODE_REBOOTNOW         We need to reboot to continue the installation
 *        MSIRUNMODE_CABINET           Files from cabinet are installed
 *        MSIRUNMODE_SOURCESHORTNAMES  Long names in source files is suppressed
 *        MSIRUNMODE_TARGETSHORTNAMES  Long names in destination files is suppressed
 *        MSIRUNMODE_RESERVED11        Reserved
 *        MSIRUNMODE_WINDOWS9X         Running under Windows95/98
 *        MSIRUNMODE_ZAWENABLED        Demand installation is supported
 *        MSIRUNMODE_RESERVED14        Reserved
 *        MSIRUNMODE_RESERVED15        Reserved
 *        MSIRUNMODE_SCHEDULED         called from install script
 *        MSIRUNMODE_ROLLBACK          called from rollback script
 *        MSIRUNMODE_COMMIT            called from commit script
 *
 * RETURNS
 *    In the state: TRUE
 *    Not in the state: FALSE
 *
 */
BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
{
    MSIPACKAGE *package;
    BOOL r = FALSE;

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

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

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

        hr = IWineMsiRemotePackage_GetMode(remote_package, iRunMode, &ret);
        IWineMsiRemotePackage_Release(remote_package);

        if (hr == S_OK)
            return ret;

        return FALSE;
    }

    switch (iRunMode)
    {
    case MSIRUNMODE_ADMIN:
        FIXME("no support for administrative installs\n");
        break;

    case MSIRUNMODE_ADVERTISE:
        FIXME("no support for advertised installs\n");
        break;

    case MSIRUNMODE_WINDOWS9X:
        if (GetVersion() & 0x80000000)
            r = TRUE;
        break;

    case MSIRUNMODE_OPERATIONS:
    case MSIRUNMODE_RESERVED11:
    case MSIRUNMODE_RESERVED14:
    case MSIRUNMODE_RESERVED15:
        break;

    case MSIRUNMODE_SCHEDULED:
        r = (package->script == SCRIPT_INSTALL);
        break;

    case MSIRUNMODE_ROLLBACK:
        r = (package->script == SCRIPT_ROLLBACK);
        break;

    case MSIRUNMODE_COMMIT:
        r = (package->script == SCRIPT_COMMIT);
        break;

    case MSIRUNMODE_MAINTENANCE:
        r = msi_get_property_int( package->db, szInstalled, 0 ) != 0;
        break;

    case MSIRUNMODE_ROLLBACKENABLED:
        r = msi_get_property_int( package->db, szRollbackDisabled, 0 ) == 0;
        break;

    case MSIRUNMODE_REBOOTATEND:
        r = package->need_reboot_at_end;
        break;

    case MSIRUNMODE_REBOOTNOW:
        r = package->need_reboot_now;
        break;

    case MSIRUNMODE_LOGENABLED:
        r = (package->log_file != INVALID_HANDLE_VALUE);
        break;

    default:
        FIXME("unimplemented run mode: %d\n", iRunMode);
        r = TRUE;
    }

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

/***********************************************************************
 *           MsiSetMode    (MSI.@)
 */
UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
{
    MSIPACKAGE *package;
    UINT r;

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

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

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

        hr = IWineMsiRemotePackage_SetMode( remote_package, iRunMode, fState );
        IWineMsiRemotePackage_Release( remote_package );

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    switch (iRunMode)
    {
    case MSIRUNMODE_REBOOTATEND:
        package->need_reboot_at_end = (fState != 0);
        r = ERROR_SUCCESS;
        break;

    case MSIRUNMODE_REBOOTNOW:
        package->need_reboot_now = (fState != 0);
        r = ERROR_SUCCESS;
        break;

    default:
        r = ERROR_ACCESS_DENIED;
    }

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

/***********************************************************************
 * MsiSetFeatureStateA (MSI.@)
 *
 * According to the docs, when this is called it immediately recalculates
 * all the component states as well
 */
UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
                                INSTALLSTATE iState)
{
    LPWSTR szwFeature = NULL;
    UINT rc;

    szwFeature = strdupAtoW(szFeature);

    if (!szwFeature)
        return ERROR_FUNCTION_FAILED;
   
    rc = MsiSetFeatureStateW(hInstall,szwFeature, iState); 

    msi_free(szwFeature);

    return rc;
}

/* update component state based on a feature change */
void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature )
{
    INSTALLSTATE newstate;
    ComponentList *cl;

    newstate = feature->ActionRequest;
    if (newstate == INSTALLSTATE_ABSENT) newstate = INSTALLSTATE_UNKNOWN;

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

        if (!component->Enabled) continue;

        TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n",
            newstate, debugstr_w(component->Component), component->Installed,
            component->Action, component->ActionRequest);

        if (newstate == INSTALLSTATE_LOCAL)
        {
            component->Action = INSTALLSTATE_LOCAL;
            component->ActionRequest = INSTALLSTATE_LOCAL;
        }
        else
        {
            ComponentList *clist;
            MSIFEATURE *f;

            component->hasLocalFeature = FALSE;

            component->Action = newstate;
            component->ActionRequest = newstate;
            /* if any other feature wants it local we need to set it local */
            LIST_FOR_EACH_ENTRY(f, &package->features, MSIFEATURE, entry)
            {
                if ( f->ActionRequest != INSTALLSTATE_LOCAL &&
                     f->ActionRequest != INSTALLSTATE_SOURCE )
                {
                    continue;
                }
                LIST_FOR_EACH_ENTRY(clist, &f->Components, ComponentList, entry)
                {
                    if (clist->component == component &&
                        (f->ActionRequest == INSTALLSTATE_LOCAL ||
                         f->ActionRequest == INSTALLSTATE_SOURCE))
                    {
                        TRACE("Saved by %s\n", debugstr_w(f->Feature));
                        component->hasLocalFeature = TRUE;

                        if (component->Attributes & msidbComponentAttributesOptional)
                        {
                            if (f->Attributes & msidbFeatureAttributesFavorSource)
                            {
                                component->Action = INSTALLSTATE_SOURCE;
                                component->ActionRequest = INSTALLSTATE_SOURCE;
                            }
                            else
                            {
                                component->Action = INSTALLSTATE_LOCAL;
                                component->ActionRequest = INSTALLSTATE_LOCAL;
                            }
                        }
                        else if (component->Attributes & msidbComponentAttributesSourceOnly)
                        {
                            component->Action = INSTALLSTATE_SOURCE;
                            component->ActionRequest = INSTALLSTATE_SOURCE;
                        }
                        else
                        {
                            component->Action = INSTALLSTATE_LOCAL;
                            component->ActionRequest = INSTALLSTATE_LOCAL;
                        }
                    }
                }
            }
        }
        TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n",
            newstate, debugstr_w(component->Component), component->Installed,
            component->Action, component->ActionRequest);
    }
}

UINT MSI_SetFeatureStateW( MSIPACKAGE *package, LPCWSTR szFeature, INSTALLSTATE iState )
{
    UINT rc = ERROR_SUCCESS;
    MSIFEATURE *feature, *child;

    TRACE("%s %i\n", debugstr_w(szFeature), iState);

    feature = msi_get_loaded_feature( package, szFeature );
    if (!feature)
        return ERROR_UNKNOWN_FEATURE;

    if (iState == INSTALLSTATE_ADVERTISED && 
        feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
        return ERROR_FUNCTION_FAILED;

    feature->ActionRequest = iState;

    ACTION_UpdateComponentStates( package, feature );

    /* update all the features that are children of this feature */
    LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
    {
        if (child->Feature_Parent && !strcmpW( szFeature, child->Feature_Parent ))
            MSI_SetFeatureStateW(package, child->Feature, iState);
    }
    
    return rc;
}

/***********************************************************************
 * MsiSetFeatureStateW (MSI.@)
 */
UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
                                INSTALLSTATE iState)
{
    MSIPACKAGE* package;
    UINT rc = ERROR_SUCCESS;

    TRACE("%s %i\n",debugstr_w(szFeature), iState);

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

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

        feature = SysAllocString(szFeature);
        if (!feature)
        {
            IWineMsiRemotePackage_Release(remote_package);
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_SetFeatureState(remote_package, feature, iState);

        SysFreeString(feature);
        IWineMsiRemotePackage_Release(remote_package);

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    rc = MSI_SetFeatureStateW(package,szFeature,iState);

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

/***********************************************************************
* MsiSetFeatureAttributesA   (MSI.@)
*/
UINT WINAPI MsiSetFeatureAttributesA( MSIHANDLE handle, LPCSTR feature, DWORD attrs )
{
    UINT r;
    WCHAR *featureW = NULL;

    TRACE("%u, %s, 0x%08x\n", handle, debugstr_a(feature), attrs);

    if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;

    r = MsiSetFeatureAttributesW( handle, featureW, attrs );
    msi_free( featureW );
    return r;
}

static DWORD unmap_feature_attributes( DWORD attrs )
{
    DWORD ret = 0;

    if (attrs & INSTALLFEATUREATTRIBUTE_FAVORLOCAL)             ret = msidbFeatureAttributesFavorLocal;
    if (attrs & INSTALLFEATUREATTRIBUTE_FAVORSOURCE)            ret |= msidbFeatureAttributesFavorSource;
    if (attrs & INSTALLFEATUREATTRIBUTE_FOLLOWPARENT)           ret |= msidbFeatureAttributesFollowParent;
    if (attrs & INSTALLFEATUREATTRIBUTE_FAVORADVERTISE)         ret |= msidbFeatureAttributesFavorAdvertise;
    if (attrs & INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE)      ret |= msidbFeatureAttributesDisallowAdvertise;
    if (attrs & INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE) ret |= msidbFeatureAttributesNoUnsupportedAdvertise;
    return ret;
}

/***********************************************************************
* MsiSetFeatureAttributesW   (MSI.@)
*/
UINT WINAPI MsiSetFeatureAttributesW( MSIHANDLE handle, LPCWSTR name, DWORD attrs )
{
    MSIPACKAGE *package;
    MSIFEATURE *feature;
    WCHAR *costing;

    TRACE("%u, %s, 0x%08x\n", handle, debugstr_w(name), attrs);

    if (!name || !name[0]) return ERROR_UNKNOWN_FEATURE;

    if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
        return ERROR_INVALID_HANDLE;

    costing = msi_dup_property( package->db, szCostingComplete );
    if (!costing || !strcmpW( costing, szOne ))
    {
        msi_free( costing );
        msiobj_release( &package->hdr );
        return ERROR_FUNCTION_FAILED;
    }
    msi_free( costing );
    if (!(feature = msi_get_loaded_feature( package, name )))
    {
        msiobj_release( &package->hdr );
        return ERROR_UNKNOWN_FEATURE;
    }
    feature->Attributes = unmap_feature_attributes( attrs );
    msiobj_release( &package->hdr );
    return ERROR_SUCCESS;
}

/***********************************************************************
* MsiGetFeatureStateA   (MSI.@)
*/
UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
{
    LPWSTR szwFeature = NULL;
    UINT rc;
    
    if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY;

    rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction);
    msi_free( szwFeature);
    return rc;
}

UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
{
    MSIFEATURE *feature;

    feature = msi_get_loaded_feature(package,szFeature);
    if (!feature)
        return ERROR_UNKNOWN_FEATURE;

    if (piInstalled)
        *piInstalled = feature->Installed;

    if (piAction)
        *piAction = feature->ActionRequest;

    TRACE("returning %i %i\n", feature->Installed, feature->ActionRequest);

    return ERROR_SUCCESS;
}

/***********************************************************************
* MsiGetFeatureStateW   (MSI.@)
*/
UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
{
    MSIPACKAGE* package;
    UINT ret;

    TRACE("%d %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);

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

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

        feature = SysAllocString(szFeature);
        if (!feature)
        {
            IWineMsiRemotePackage_Release(remote_package);
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_GetFeatureState(remote_package, feature,
                                                   piInstalled, piAction);

        SysFreeString(feature);
        IWineMsiRemotePackage_Release(remote_package);

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
    msiobj_release( &package->hdr );
    return ret;
}

/***********************************************************************
* MsiGetFeatureCostA   (MSI.@)
*/
UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
                  MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
{
    LPWSTR szwFeature = NULL;
    UINT rc;

    szwFeature = strdupAtoW(szFeature);

    rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost);

    msi_free(szwFeature);

    return rc;
}

static INT feature_cost( MSIFEATURE *feature )
{
    INT cost = 0;
    ComponentList *cl;

    LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
    {
        cost += cl->component->Cost;
    }
    return cost;
}

UINT MSI_GetFeatureCost( MSIPACKAGE *package, MSIFEATURE *feature, MSICOSTTREE tree,
                         INSTALLSTATE state, LPINT cost )
{
    TRACE("%s, %u, %d, %p\n", debugstr_w(feature->Feature), tree, state, cost);

    *cost = 0;
    switch (tree)
    {
    case MSICOSTTREE_CHILDREN:
    {
        MSIFEATURE *child;

        LIST_FOR_EACH_ENTRY( child, &feature->Children, MSIFEATURE, entry )
        {
            if (child->ActionRequest == state)
                *cost += feature_cost( child );
        }
        break;
    }
    case MSICOSTTREE_PARENTS:
    {
        const WCHAR *feature_parent = feature->Feature_Parent;
        for (;;)
        {
            MSIFEATURE *parent = msi_get_loaded_feature( package, feature_parent );
            if (!parent)
                break;

            if (parent->ActionRequest == state)
                *cost += feature_cost( parent );

            feature_parent = parent->Feature_Parent;
        }
        break;
    }
    case MSICOSTTREE_SELFONLY:
        if (feature->ActionRequest == state)
            *cost = feature_cost( feature );
        break;

    default:
        WARN("unhandled cost tree %u\n", tree);
        break;
    }

    *cost /= 512;
    return ERROR_SUCCESS;
}

/***********************************************************************
* MsiGetFeatureCostW   (MSI.@)
*/
UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
                  MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
{
    MSIPACKAGE *package;
    MSIFEATURE *feature;
    UINT ret;

    TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature),
          iCostTree, iState, piCost);

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

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

        feature = SysAllocString(szFeature);
        if (!feature)
        {
            IWineMsiRemotePackage_Release(remote_package);
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_GetFeatureCost(remote_package, feature,
                                                  iCostTree, iState, piCost);

        SysFreeString(feature);
        IWineMsiRemotePackage_Release(remote_package);

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    feature = msi_get_loaded_feature(package, szFeature);

    if (feature)
        ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost);
    else
        ret = ERROR_UNKNOWN_FEATURE;

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

/***********************************************************************
* MsiGetFeatureInfoA   (MSI.@)
*/
UINT WINAPI MsiGetFeatureInfoA( MSIHANDLE handle, LPCSTR feature, LPDWORD attrs,
                                LPSTR title, LPDWORD title_len, LPSTR help, LPDWORD help_len )
{
    UINT r;
    WCHAR *titleW = NULL, *helpW = NULL, *featureW = NULL;

    TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_a(feature), attrs, title,
          title_len, help, help_len);

    if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;

    if (title && title_len && !(titleW = msi_alloc( *title_len * sizeof(WCHAR) )))
    {
        msi_free( featureW );
        return ERROR_OUTOFMEMORY;
    }
    if (help && help_len && !(helpW = msi_alloc( *help_len * sizeof(WCHAR) )))
    {
        msi_free( featureW );
        msi_free( titleW );
        return ERROR_OUTOFMEMORY;
    }
    r = MsiGetFeatureInfoW( handle, featureW, attrs, titleW, title_len, helpW, help_len );
    if (r == ERROR_SUCCESS)
    {
        if (titleW) WideCharToMultiByte( CP_ACP, 0, titleW, -1, title, *title_len + 1, NULL, NULL );
        if (helpW) WideCharToMultiByte( CP_ACP, 0, helpW, -1, help, *help_len + 1, NULL, NULL );
    }
    msi_free( titleW );
    msi_free( helpW );
    msi_free( featureW );
    return r;
}

static DWORD map_feature_attributes( DWORD attrs )
{
    DWORD ret = 0;

    if (attrs == msidbFeatureAttributesFavorLocal)            ret |= INSTALLFEATUREATTRIBUTE_FAVORLOCAL;
    if (attrs & msidbFeatureAttributesFavorSource)            ret |= INSTALLFEATUREATTRIBUTE_FAVORSOURCE;
    if (attrs & msidbFeatureAttributesFollowParent)           ret |= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT;
    if (attrs & msidbFeatureAttributesFavorAdvertise)         ret |= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE;
    if (attrs & msidbFeatureAttributesDisallowAdvertise)      ret |= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE;
    if (attrs & msidbFeatureAttributesNoUnsupportedAdvertise) ret |= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE;
    return ret;
}

static UINT MSI_GetFeatureInfo( MSIPACKAGE *package, LPCWSTR name, LPDWORD attrs,
                                LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
{
    UINT r = ERROR_SUCCESS;
    MSIFEATURE *feature = msi_get_loaded_feature( package, name );
    int len;

    if (!feature) return ERROR_UNKNOWN_FEATURE;
    if (attrs) *attrs = map_feature_attributes( feature->Attributes );
    if (title_len)
    {
        if (feature->Title) len = strlenW( feature->Title );
        else len = 0;
        if (*title_len <= len)
        {
            *title_len = len;
            if (title) r = ERROR_MORE_DATA;
        }
        else if (title)
        {
            if (feature->Title) strcpyW( title, feature->Title );
            else *title = 0;
            *title_len = len;
        }
    }
    if (help_len)
    {
        if (feature->Description) len = strlenW( feature->Description );
        else len = 0;
        if (*help_len <= len)
        {
            *help_len = len;
            if (help) r = ERROR_MORE_DATA;
        }
        else if (help)
        {
            if (feature->Description) strcpyW( help, feature->Description );
            else *help = 0;
            *help_len = len;
        }
    }
    return r;
}

/***********************************************************************
* MsiGetFeatureInfoW   (MSI.@)
*/
UINT WINAPI MsiGetFeatureInfoW( MSIHANDLE handle, LPCWSTR feature, LPDWORD attrs,
                                LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
{
    UINT r;
    MSIPACKAGE *package;

    TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_w(feature), attrs, title,
          title_len, help, help_len);

    if (!feature) return ERROR_INVALID_PARAMETER;

    if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
        return ERROR_INVALID_HANDLE;

    /* features may not have been loaded yet */
    msi_load_all_components( package );
    msi_load_all_features( package );

    r = MSI_GetFeatureInfo( package, feature, attrs, title, title_len, help, help_len );
    msiobj_release( &package->hdr );
    return r;
}

/***********************************************************************
 * MsiSetComponentStateA (MSI.@)
 */
UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
                                  INSTALLSTATE iState)
{
    UINT rc;
    LPWSTR szwComponent = strdupAtoW(szComponent);

    rc = MsiSetComponentStateW(hInstall, szwComponent, iState);

    msi_free(szwComponent);

    return rc;
}

/***********************************************************************
 * MsiGetComponentStateA (MSI.@)
 */
UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
{
    LPWSTR szwComponent= NULL;
    UINT rc;
    
    szwComponent= strdupAtoW(szComponent);

    rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);

    msi_free( szwComponent);

    return rc;
}

static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
                                   INSTALLSTATE iState)
{
    MSICOMPONENT *comp;

    TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);

    comp = msi_get_loaded_component(package, szComponent);
    if (!comp)
        return ERROR_UNKNOWN_COMPONENT;

    if (comp->Enabled)
        comp->Action = iState;

    return ERROR_SUCCESS;
}

UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
{
    MSICOMPONENT *comp;

    TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
           piInstalled, piAction);

    comp = msi_get_loaded_component(package,szComponent);
    if (!comp)
        return ERROR_UNKNOWN_COMPONENT;

    if (piInstalled)
    {
        if (comp->Enabled)
            *piInstalled = comp->Installed;
        else
            *piInstalled = INSTALLSTATE_UNKNOWN;
    }

    if (piAction)
    {
        if (comp->Enabled)
            *piAction = comp->Action;
        else
            *piAction = INSTALLSTATE_UNKNOWN;
    }

    TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
    return ERROR_SUCCESS;
}

/***********************************************************************
 * MsiSetComponentStateW (MSI.@)
 */
UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
                                  INSTALLSTATE iState)
{
    MSIPACKAGE* package;
    UINT ret;

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

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

        component = SysAllocString(szComponent);
        if (!component)
        {
            IWineMsiRemotePackage_Release(remote_package);
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_SetComponentState(remote_package, component, iState);

        SysFreeString(component);
        IWineMsiRemotePackage_Release(remote_package);

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    ret = MSI_SetComponentStateW(package, szComponent, iState);
    msiobj_release(&package->hdr);
    return ret;
}

/***********************************************************************
 * MsiGetComponentStateW (MSI.@)
 */
UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
{
    MSIPACKAGE* package;
    UINT ret;

    TRACE("%d %s %p %p\n", hInstall, debugstr_w(szComponent),
           piInstalled, piAction);

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

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

        component = SysAllocString(szComponent);
        if (!component)
        {
            IWineMsiRemotePackage_Release(remote_package);
            return ERROR_OUTOFMEMORY;
        }

        hr = IWineMsiRemotePackage_GetComponentState(remote_package, component,
                                                     piInstalled, piAction);

        SysFreeString(component);
        IWineMsiRemotePackage_Release(remote_package);

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
    msiobj_release( &package->hdr );
    return ret;
}

/***********************************************************************
 * MsiGetLanguage (MSI.@)
 */
LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
{
    MSIPACKAGE* package;
    LANGID langid;

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

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

        hr = IWineMsiRemotePackage_GetLanguage(remote_package, &lang);

        if (SUCCEEDED(hr))
            return lang;

        return 0;
    }

    langid = msi_get_property_int( package->db, szProductLanguage, 0 );
    msiobj_release( &package->hdr );
    return langid;
}

UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
{
    static const WCHAR fmt[] = { '%','d',0 };
    WCHAR level[6];
    int len;
    UINT r;

    TRACE("%p %i\n", package, iInstallLevel);

    if (iInstallLevel > 32767)
        return ERROR_INVALID_PARAMETER;

    if (iInstallLevel < 1)
        return MSI_SetFeatureStates( package );

    len = sprintfW( level, fmt, iInstallLevel );
    r = msi_set_property( package->db, szInstallLevel, level, len );
    if ( r == ERROR_SUCCESS )
        r = MSI_SetFeatureStates( package );

    return r;
}

/***********************************************************************
 * MsiSetInstallLevel (MSI.@)
 */
UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
{
    MSIPACKAGE* package;
    UINT r;

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

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

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

        hr = IWineMsiRemotePackage_SetInstallLevel(remote_package, iInstallLevel);

        IWineMsiRemotePackage_Release(remote_package);

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

            return ERROR_FUNCTION_FAILED;
        }

        return ERROR_SUCCESS;
    }

    r = MSI_SetInstallLevel( package, iInstallLevel );

    msiobj_release( &package->hdr );

    return r;
}

/***********************************************************************
 * MsiGetFeatureValidStatesW (MSI.@)
 */
UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature,
                  LPDWORD pInstallState)
{
    if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL;
    FIXME("%d %s %p stub returning %d\n",
        hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0);

    return ERROR_SUCCESS;
}

/***********************************************************************
 * MsiGetFeatureValidStatesA (MSI.@)
 */
UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature,
                  LPDWORD pInstallState)
{
    UINT ret;
    LPWSTR szwFeature = strdupAtoW(szFeature);

    ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState);

    msi_free(szwFeature);

    return ret;
}
