/*
 * 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_PerformUIAction( package, szAction, -1 );
    msiobj_release( &package->hdr );

    return ret;
}

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

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

    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\n", debugstr_w(szTable));

    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, iSequenceMode );
    msiobj_release( &package->hdr );
 
    return ret;
}

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

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

    if (!sz)
        return r;
 
    if (awbuf->unicode)
    {
        len = lstrlenW( str );
        if (awbuf->str.w) 
            lstrcpynW( awbuf->str.w, str, *sz );
    }
    else
    {
        len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
        if (len)
            len--;
        WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL );
        if ( awbuf->str.a && *sz && (len >= *sz) )
            awbuf->str.a[*sz - 1] = 0;
    }

    if (awbuf->str.w && len >= *sz)
        r = ERROR_MORE_DATA;
    *sz = len;
    return r;
}

/***********************************************************************
 * MsiGetTargetPath   (internal)
 */
static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
                               awstring *szPathBuf, LPDWORD pcchPathBuf )
{
    MSIPACKAGE *package;
    LPWSTR 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,
                                                  (BSTR *)value, &len);
        if (FAILED(hr))
            goto done;

        r = msi_strcpy_to_awstring( value, 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 = resolve_folder( package, szFolder, FALSE, FALSE, TRUE, NULL );
    msiobj_release( &package->hdr );

    if (!path)
        return ERROR_DIRECTORY;

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

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

/***********************************************************************
 * MsiGetSourcePath   (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,
                                                  (BSTR *)value, &len);
        if (FAILED(hr))
            goto done;

        r = msi_strcpy_to_awstring( value, 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 = resolve_folder(package, szFolder, TRUE, FALSE, TRUE, NULL);
    msiobj_release( &package->hdr );

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

    r = msi_strcpy_to_awstring( path, 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", szFolder, debugstr_a(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;
}

/*
 * Ok my original interpretation of this was wrong. And it looks like msdn has
 * changed a bit also. The given folder path does not have to actually already
 * exist, it just cannot be read only and must be a legal folder path.
 */
UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, 
                             LPCWSTR szFolderPath)
{
    DWORD attrib;
    LPWSTR path = NULL;
    LPWSTR path2 = NULL;
    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;

    path = resolve_folder(package,szFolder,FALSE,FALSE,FALSE,&folder);
    if (!path)
        return ERROR_DIRECTORY;

    msi_free(folder->Property);
    folder->Property = build_directory_name(2, szFolderPath, NULL);

    if (lstrcmpiW(path, folder->Property) == 0)
    {
        /*
         *  Resolved Target has not really changed, so just 
         *  set this folder and do not recalculate everything.
         */
        msi_free(folder->ResolvedTarget);
        folder->ResolvedTarget = NULL;
        path2 = resolve_folder(package,szFolder,FALSE,TRUE,FALSE,NULL);
        msi_free(path2);
    }
    else
    {
        MSIFOLDER *f;

        LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
        {
            msi_free(f->ResolvedTarget);
            f->ResolvedTarget=NULL;
        }

        LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
        {
            path2 = resolve_folder(package, f->Directory, FALSE, TRUE, FALSE, NULL);
            msi_free(path2);
        }

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

            if (!comp)
                continue;

            p = resolve_folder(package, comp->Directory, FALSE, FALSE, FALSE, NULL);
            msi_free(file->TargetPath);

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

    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_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->scheduled_action_running;
        break;

    case MSIRUNMODE_ROLLBACK:
        r = package->rollback_action_running;
        break;

    case MSIRUNMODE_COMMIT:
        r = package->commit_action_running;
        break;

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

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

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

    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 = 1;
        r = ERROR_SUCCESS;
        break;

    case MSIRUNMODE_REBOOTNOW:
        FIXME("unimplemented run mode: %d\n", iRunMode);
        r = ERROR_FUNCTION_FAILED;
        break;

    default:
        r = ERROR_ACCESS_DENIED;
    }

    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;
}



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

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

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

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

    msi_feature_set_state(package, feature, iState);

    ACTION_UpdateComponentStates(package,szFeature);

    /* update all the features that are children of this feature */
    LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
    {
        if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
            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;
}

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

    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 = get_loaded_feature(package,szFeature);
    if (!feature)
        return ERROR_UNKNOWN_FEATURE;

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

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

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

    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;
}

UINT MSI_GetFeatureCost(MSIPACKAGE *package, MSIFEATURE *feature,
                        MSICOSTTREE iCostTree, INSTALLSTATE iState,
                        LPINT piCost)
{
    FIXME("(%s %i %i %p): not implemented yet\n",
        debugstr_w(feature->Feature), iCostTree, iState, piCost);
    if (piCost) *piCost = 0;
    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 = 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;
}

/***********************************************************************
 * 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 = get_loaded_component(package, szComponent);
    if (!comp)
        return ERROR_UNKNOWN_COMPONENT;

    comp->Installed = 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 = get_loaded_component(package,szComponent);
    if (!comp)
        return ERROR_UNKNOWN_COMPONENT;

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

    if (piAction)
        *piAction = comp->Action;

    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;
    static const WCHAR szProductLanguage[] =
        {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
    
    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, szProductLanguage, 0 );
    msiobj_release( &package->hdr );
    return langid;
}

UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
{
    static const WCHAR szInstallLevel[] = {
        'I','N','S','T','A','L','L','L','E','V','E','L',0 };
    static const WCHAR fmt[] = { '%','d',0 };
    WCHAR level[6];
    UINT r;

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

    if (iInstallLevel > 32767)
        return ERROR_INVALID_PARAMETER;

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

    sprintfW( level, fmt, iInstallLevel );
    r = MSI_SetPropertyW( package, szInstallLevel, level );
    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;
}
