/*
 * Implementation of the Microsoft Installer (msi.dll)
 *
 * Copyright 2002,2003,2004,2005 Mike McCormack 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdarg.h>

#define COBJMACROS
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "shlwapi.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "msipriv.h"
#include "objidl.h"
#include "wincrypt.h"
#include "wine/unicode.h"
#include "objbase.h"
#include "winver.h"
#include "winuser.h"

#include "initguid.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);

/*
 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
 *  which is a problem because LPCTSTR isn't defined when compiling wine.
 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
 *  and make sure to only use it in W functions.
 */
#define LPCTSTR LPCWSTR

DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000,
             0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);

/* the UI level */
INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
HWND           gUIhwnd = 0;
INSTALLUI_HANDLERA gUIHandlerA = NULL;
INSTALLUI_HANDLERW gUIHandlerW = NULL;
DWORD gUIFilter = 0;
LPVOID gUIContext = NULL;
WCHAR gszLogFile[MAX_PATH];
HINSTANCE msi_hInstance;

/*
 *  .MSI  file format
 *
 *  A .msi file is a structured storage file.
 *  It should contain a number of streams.
 */

VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
{
    MSIDATABASE *db = (MSIDATABASE *) arg;
    DWORD r;

    free_cached_tables( db );
    r = IStorage_Release( db->storage );
    if( r )
        ERR("database reference count was not zero (%ld)\n", r);
}

UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
{
    IStorage *stg = NULL;
    HRESULT r;
    MSIDATABASE *db = NULL;
    UINT ret = ERROR_FUNCTION_FAILED;
    LPWSTR szMode;
    STATSTG stat;

    TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );

    if( !pdb )
        return ERROR_INVALID_PARAMETER;

    szMode = (LPWSTR) szPersist;
    if( HIWORD( szPersist ) )
    {
        /* UINT len = lstrlenW( szPerist ) + 1; */
        FIXME("don't support persist files yet\b");
        return ERROR_INVALID_PARAMETER;
        /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
    }
    else if( szPersist == MSIDBOPEN_READONLY )
    {
        r = StgOpenStorage( szDBPath, NULL,
              STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
    }
    else if( szPersist == MSIDBOPEN_CREATE )
    {
        r = StgCreateDocfile( szDBPath, 
              STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
        if( r == ERROR_SUCCESS )
        {
            IStorage_SetClass( stg, &CLSID_MsiDatabase );
            r = init_string_table( stg );
        }
    }
    else if( szPersist == MSIDBOPEN_TRANSACT )
    {
        r = StgOpenStorage( szDBPath, NULL,
              STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
    }
    else
    {
        ERR("unknown flag %p\n",szPersist);
        return ERROR_INVALID_PARAMETER;
    }

    if( FAILED( r ) )
    {
        FIXME("open failed r = %08lx!\n",r);
        return ERROR_FUNCTION_FAILED;
    }

    r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
    if( FAILED( r ) )
    {
        FIXME("Failed to stat storage\n");
        goto end;
    }

    if( memcmp( &stat.clsid, &CLSID_MsiDatabase, sizeof (GUID) ) )
    {
        ERR("storage GUID is not a MSI database GUID %s\n",
             debugstr_guid(&stat.clsid) );
        goto end;
    }


    db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
                              MSI_CloseDatabase );
    if( !db )
    {
        FIXME("Failed to allocate a handle\n");
        goto end;
    }

    if( TRACE_ON( msi ) )
        enum_stream_names( stg );

    db->storage = stg;
    db->mode = szMode;

    ret = load_string_table( db );
    if( ret != ERROR_SUCCESS )
        goto end;

    msiobj_addref( &db->hdr );
    IStorage_AddRef( stg );
    *pdb = db;

end:
    if( db )
        msiobj_release( &db->hdr );
    if( stg )
        IStorage_Release( stg );

    return ret;
}

UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
{
    MSIDATABASE *db;
    UINT ret;

    TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);

    ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db );
    if( ret == ERROR_SUCCESS )
    {
        *phDB = alloc_msihandle( &db->hdr );
        msiobj_release( &db->hdr );
    }

    return ret;
}

UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
{
    HRESULT r = ERROR_FUNCTION_FAILED;
    LPWSTR szwDBPath = NULL, szwPersist = NULL;
    UINT len;

    TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);

    if( szDBPath )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, NULL, 0 );
        szwDBPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwDBPath )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, szwDBPath, len );
    }

    if( HIWORD(szPersist) )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szPersist, -1, NULL, 0 );
        szwPersist = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwPersist )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szPersist, -1, szwPersist, len );
    }
    else
        szwPersist = (LPWSTR) szPersist;

    r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );

end:
    HeapFree( GetProcessHeap(), 0, szwPersist );
    HeapFree( GetProcessHeap(), 0, szwDBPath );

    return r;
}

UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
{
    UINT len, ret;
    LPWSTR szwProd = NULL;

    TRACE("%s %p\n",debugstr_a(szProduct), phProduct);

    if( szProduct )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
        szwProd = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
        if( szwProd )
            MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProd, len );
    }

    ret = MsiOpenProductW( szwProd, phProduct );

    HeapFree( GetProcessHeap(), 0, szwProd );

    return ret;
}

UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
{
    static const WCHAR szLocalPackage[] = {
        'L','o','c','a','l','P','a','c','k','a','g','e', 0
    };
    LPWSTR path = NULL;
    UINT r;
    HKEY hKeyProduct = NULL;
    DWORD count, type;

    TRACE("%s %p\n",debugstr_w(szProduct), phProduct);

    r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
    if( r != ERROR_SUCCESS )
    {
        r = ERROR_UNKNOWN_PRODUCT;
        goto end;
    }

    /* find the size of the path */
    type = count = 0;
    r = RegQueryValueExW( hKeyProduct, szLocalPackage,
                          NULL, &type, NULL, &count );
    if( r != ERROR_SUCCESS )
    {
        r = ERROR_UNKNOWN_PRODUCT;
        goto end;
    }

    /* now alloc and fetch the path of the database to open */
    path = HeapAlloc( GetProcessHeap(), 0, count );
    if( !path )
        goto end;

    r = RegQueryValueExW( hKeyProduct, szLocalPackage,
                          NULL, &type, (LPBYTE) path, &count );
    if( r != ERROR_SUCCESS )
    {
        r = ERROR_UNKNOWN_PRODUCT;
        goto end;
    }

    r = MsiOpenPackageW( path, phProduct );

end:
    HeapFree( GetProcessHeap(), 0, path );
    if( hKeyProduct )
        RegCloseKey( hKeyProduct );

    return r;
}

UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
                LPCSTR szTransforms, LANGID lgidLanguage)
{
    FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
          debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
                LPCWSTR szTransforms, LANGID lgidLanguage)
{
    FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
          debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
      LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
{
    FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
          debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
          lgidLanguage, dwPlatform, dwOptions);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
      LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
{
    FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
          debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
          lgidLanguage, dwPlatform, dwOptions);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
{
    LPWSTR szwPath = NULL, szwCommand = NULL;
    UINT r = ERROR_FUNCTION_FAILED; /* FIXME: check return code */

    TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));

    if( szPackagePath )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, NULL, 0 );
        szwPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwPath )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, szwPath, len );
    }

    if( szCommandLine )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
        szwCommand = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwCommand )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommand, len );
    }
 
    r = MsiInstallProductW( szwPath, szwCommand );

end:
    HeapFree( GetProcessHeap(), 0, szwPath );
    HeapFree( GetProcessHeap(), 0, szwCommand );

    return r;
}

UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{
    MSIPACKAGE *package = NULL;
    UINT rc = ERROR_SUCCESS; 
    MSIHANDLE handle;

    FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));

    rc = MsiVerifyPackageW(szPackagePath);
    if (rc != ERROR_SUCCESS)
        return rc;

    rc = MSI_OpenPackageW(szPackagePath,&package);
    if (rc != ERROR_SUCCESS)
        return rc;

    handle = alloc_msihandle( &package->hdr );

    rc = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);

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

UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
{
    FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
{
    FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
        INSTALLTYPE eInstallType, LPCSTR szCommandLine)
{
    FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
          eInstallType, debugstr_a(szCommandLine));
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
         INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
{
    FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
          eInstallType, debugstr_w(szCommandLine));
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
                        INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
{
    MSIHANDLE handle; 
    MSIPACKAGE* package;
    UINT rc;
    HKEY hkey=0,hkey1=0;
    DWORD sz;
    static const WCHAR szSouceList[] = {
        'S','o','u','r','c','e','L','i','s','t',0};
    static const WCHAR szLUS[] = {
        'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
    WCHAR sourcepath[0x200];
    static const WCHAR szInstalled[] = {
        ' ','I','n','s','t','a','l','l','e','d','=','1',0};
    LPWSTR commandline;

    FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
          debugstr_w(szCommandLine));

    if (eInstallState != INSTALLSTATE_LOCAL && 
        eInstallState != INSTALLSTATE_DEFAULT)
    {
        FIXME("Not implemented for anything other than local installs\n");
        return ERROR_CALL_NOT_IMPLEMENTED;
    }

    rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
    if (rc != ERROR_SUCCESS)
        goto end;

    rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
    if (rc != ERROR_SUCCESS)
        goto end;

    sz = sizeof(sourcepath);
    rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
    if (rc != ERROR_SUCCESS)
        goto end;

    RegCloseKey(hkey1);
    /*
     * ok 1, we need to find the msi file for this product.
     *    2, find the source dir for the files
     *    3, do the configure/install.
     *    4, cleanupany runonce entry. 
     */

    rc = MsiOpenProductW(szProduct,&handle);
    if (rc != ERROR_SUCCESS)
        goto end;

    package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
    if (!package)
    {
        rc = ERROR_INVALID_HANDLE;
        goto end;
    }
  
    sz = strlenW(szInstalled);

    if (szCommandLine)
        sz += strlenW(szCommandLine);

    commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));

    if (szCommandLine) 
        strcpyW(commandline,szCommandLine);
    else
        commandline[0] = 0;

    if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
        strcatW(commandline,szInstalled);

    rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);

    msiobj_release( &package->hdr );

    HeapFree(GetProcessHeap(),0,commandline);
end:
    RegCloseKey(hkey);

    return rc;
}

UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
                        INSTALLSTATE eInstallState, LPCSTR szCommandLine)
{
    LPWSTR szwProduct = NULL;
    LPWSTR szwCommandLine = NULL;
    UINT hr = ERROR_FUNCTION_FAILED;

    if( szProduct )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
        szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwProduct )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
    }

    if( szCommandLine)
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
        szwCommandLine= HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwCommandLine)
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommandLine, len );
    }

    hr = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
                                szwCommandLine );
end:
    HeapFree( GetProcessHeap(), 0, szwProduct );
    HeapFree( GetProcessHeap(), 0, szwCommandLine);

    return hr;
}

UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, 
                                 INSTALLSTATE eInstallState)
{
    LPWSTR szwProduct = NULL;
    UINT hr = ERROR_SUCCESS;

    FIXME("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);

    if( szProduct )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
        szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwProduct )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
    }

    hr = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );

end:
    HeapFree( GetProcessHeap(), 0, szwProduct );

    return hr;
}

UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel, 
                                 INSTALLSTATE eInstallState)
{
    FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);

    return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState,
                                  NULL);
}

UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
{
    LPWSTR szwComponent = NULL;
    UINT hr = ERROR_INSTALL_FAILURE;
    WCHAR szwBuffer[GUID_SIZE];

    FIXME("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));

    if( szComponent )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
        szwComponent = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwComponent )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
    }
    else
        return ERROR_INVALID_PARAMETER;

    hr = MsiGetProductCodeW( szwComponent, szwBuffer );

    if( ERROR_SUCCESS == hr )
        WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);

end:
    HeapFree( GetProcessHeap(), 0, szwComponent );

    return hr;
}

UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
{
    FIXME("%s %s\n",debugstr_w(szComponent), debugstr_w(szBuffer));
    if (NULL == szComponent)
        return ERROR_INVALID_PARAMETER;
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
                 LPSTR szBuffer, DWORD *pcchValueBuf)
{
    LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
    UINT hr = ERROR_INSTALL_FAILURE;

    FIXME("%s %s %p %p\n",debugstr_a(szProduct), debugstr_a(szAttribute),
          szBuffer, pcchValueBuf);

    if( NULL != szBuffer && NULL == pcchValueBuf )
        return ERROR_INVALID_PARAMETER;
    if( szProduct )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
        szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwProduct )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
    }
    else
        return ERROR_INVALID_PARAMETER;
    
    if( szAttribute )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szAttribute, -1, NULL, 0 );
        szwAttribute = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwAttribute )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szAttribute, -1, szwAttribute, len );
    }
    else
    {
        hr = ERROR_INVALID_PARAMETER;
        goto end;
    }

    if( szBuffer )
    {
        szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
        if( !szwBuffer )     
            goto end;
    }

    hr = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );

    if( ERROR_SUCCESS == hr )
        WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, *pcchValueBuf, NULL, NULL);

end:
    HeapFree( GetProcessHeap(), 0, szwProduct );
    HeapFree( GetProcessHeap(), 0, szwAttribute );
    HeapFree( GetProcessHeap(), 0, szwBuffer );

    return hr;    
}

UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
                LPWSTR szBuffer, DWORD *pcchValueBuf)
{
    MSIHANDLE hProduct;
    UINT hr;
    
    FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
          szBuffer, pcchValueBuf);

    if (NULL != szBuffer && NULL == pcchValueBuf)
        return ERROR_INVALID_PARAMETER;
    if (NULL == szProduct || NULL == szAttribute)
        return ERROR_INVALID_PARAMETER;

    hr = MsiOpenProductW(szProduct, &hProduct);
    if (ERROR_SUCCESS != hr)
        return hr;

    hr = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
    MsiCloseHandle(hProduct);
    return hr;
}

UINT WINAPI MsiDatabaseImportA(LPCSTR szFolderPath, LPCSTR szFilename)
{
    FIXME("%s %s\n",debugstr_a(szFolderPath), debugstr_a(szFilename));
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiDatabaseImportW(LPCWSTR szFolderPath, LPCWSTR szFilename)
{
    FIXME("%s %s\n",debugstr_w(szFolderPath), debugstr_w(szFilename));
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
{
    LPWSTR szwLogFile = NULL;
    UINT hr = ERROR_INSTALL_FAILURE;

    FIXME("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);

    if( szLogFile )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szLogFile, -1, NULL, 0 );
        szwLogFile = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        if( !szwLogFile )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szLogFile, -1, szwLogFile, len );
    }
    else
        return ERROR_INVALID_PARAMETER;

    hr = MsiEnableLogW( dwLogMode, szwLogFile, attributes );

end:
    HeapFree( GetProcessHeap(), 0, szwLogFile );

    return hr;
}

UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
{
    HANDLE file = INVALID_HANDLE_VALUE;

    TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);

    strcpyW(gszLogFile,szLogFile);
    if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
        DeleteFileW(szLogFile);
    file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
                           FILE_ATTRIBUTE_NORMAL, NULL);
    if (file != INVALID_HANDLE_VALUE)
        CloseHandle(file);
    else
        ERR("Unable to enable log %s\n",debugstr_w(szLogFile));

    return ERROR_SUCCESS;
}

INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
{
    LPWSTR szwProduct;
    UINT len;
    INSTALLSTATE rc;

    len = MultiByteToWideChar(CP_ACP,0,szProduct,-1,NULL,0);
    szwProduct = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP,0,szProduct,-1,szwProduct,len);
    rc = MsiQueryProductStateW(szwProduct);
    HeapFree(GetProcessHeap(),0,szwProduct);
    return rc;
}

INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
{
    UINT rc;
    INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
    HKEY hkey=0;
    static const WCHAR szWindowsInstaller[] = {
         'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
    DWORD sz;

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

    rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
    if (rc != ERROR_SUCCESS)
        goto end;

    RegCloseKey(hkey);

    rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
    if (rc != ERROR_SUCCESS)
        goto end;

    sz = sizeof(rrc);
    rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
    if (rc != ERROR_SUCCESS)
        goto end;

    switch (rrc)
    {
    case 1:
        /* default */
        rrc = INSTALLSTATE_DEFAULT;
        break;
    default:
        FIXME("Unknown install state read from registry (%i)\n",rrc);
        rrc = INSTALLSTATE_UNKNOWN;
        break;
    }
end:
    RegCloseKey(hkey);
    return rrc;
}

INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
{
    INSTALLUILEVEL old = gUILevel;
    HWND oldwnd = gUIhwnd;

    TRACE("%08x %p\n", dwUILevel, phWnd);

    gUILevel = dwUILevel;
    if (phWnd)
    {
        gUIhwnd = *phWnd;
        *phWnd = oldwnd;
    }
    return old;
}

INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler, 
                                  DWORD dwMessageFilter, LPVOID pvContext)
{
    INSTALLUI_HANDLERA prev = gUIHandlerA;

    TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
    gUIHandlerA = puiHandler;
    gUIFilter = dwMessageFilter;
    gUIContext = pvContext;

    return prev;
}

INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
                                  DWORD dwMessageFilter, LPVOID pvContext)
{
    INSTALLUI_HANDLERW prev = gUIHandlerW;

    TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
    gUIHandlerW = puiHandler;
    gUIFilter = dwMessageFilter;
    gUIContext = pvContext;

    return prev;
}

/******************************************************************
 *  MsiLoadStringW            [MSI.@]
 *
 * Loads a string from MSI's string resources.
 *
 * PARAMS
 *
 *   handle        [I]  only -1 is handled currently
 *   id            [I]  id of the string to be loaded
 *   lpBuffer      [O]  buffer for the string to be written to
 *   nBufferMax    [I]  maximum size of the buffer in characters
 *   lang          [I]  the preferred language for the string
 *
 * RETURNS
 *
 *   If successful, this function returns the language id of the string loaded
 *   If the function fails, the function returns zero.
 *
 * NOTES
 *
 *   The type of the first parameter is unknown.  LoadString's prototype
 *  suggests that it might be a module handle.  I have made it an MSI handle
 *  for starters, as -1 is an invalid MSI handle, but not an invalid module
 *  handle.  Maybe strings can be stored in an MSI database somehow.
 */
LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
                int nBufferMax, LANGID lang )
{
    HRSRC hres;
    HGLOBAL hResData;
    LPWSTR p;
    DWORD i, len;

    TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);

    if( handle != -1 )
        FIXME("don't know how to deal with handle = %08lx\n", handle);

    if( !lang )
        lang = GetUserDefaultLangID();

    hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
                            (LPWSTR)1, lang );
    if( !hres )
        return 0;
    hResData = LoadResource( msi_hInstance, hres );
    if( !hResData )
        return 0;
    p = LockResource( hResData );
    if( !p )
        return 0;

    for (i = 0; i < (id&0xf); i++)
	p += *p + 1;
    len = *p;

    if( nBufferMax <= len )
        return 0;

    memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
    lpBuffer[ len ] = 0;

    TRACE("found -> %s\n", debugstr_w(lpBuffer));

    return lang;
}

LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
                int nBufferMax, LANGID lang )
{
    LPWSTR bufW;
    LANGID r;
    DWORD len;

    bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
    r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
    if( r )
    {
        len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
        if( len <= nBufferMax )
            WideCharToMultiByte( CP_ACP, 0, bufW, -1,
                                 lpBuffer, nBufferMax, NULL, NULL );
        else
            r = 0;
    }
    HeapFree(GetProcessHeap(), 0, bufW);
    return r;
}

INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
                DWORD *pcchBuf)
{
    FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
    return INSTALLSTATE_UNKNOWN;
}

INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPSTR lpPathBuf,
                DWORD *pcchBuf)
{
    FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
    return INSTALLSTATE_UNKNOWN;
}

UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
                WORD wLanguageId, DWORD f)
{
    FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
          uType,wLanguageId,f);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
                WORD wLanguageId, DWORD f)
{
    FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
          uType,wLanguageId,f);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
                DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
                DWORD* pcchPathBuf ) 
{
    FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
          debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
          pcchPathBuf);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
                DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
                DWORD* pcchPathBuf )
{
    FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName), 
          debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
          pcchPathBuf);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
                LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
{
    FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
                LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
{
    FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
    return ERROR_CALL_NOT_IMPLEMENTED;
}

HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
                DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
                DWORD* pcbHashData)
{
    FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
          ppcCertContext, pbHashData, pcbHashData);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
                DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
                DWORD* pcbHashData)
{
    FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
          ppcCertContext, pbHashData, pcbHashData);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
                                    LPSTR szValue, DWORD *pccbValue )
{
    FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
                                    LPWSTR szValue, DWORD *pccbValue )
{
    FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
{
    UINT r, len;
    LPWSTR szPack = NULL;

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

    if( szPackage )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szPackage, -1, NULL, 0 );
        szPack = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
        if( !szPack )
            return ERROR_OUTOFMEMORY;
        MultiByteToWideChar( CP_ACP, 0, szPackage, -1, szPack, len );
    }

    r = MsiVerifyPackageW( szPack );

    HeapFree( GetProcessHeap(), 0, szPack );

    return r;
}

UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
{
    MSIHANDLE handle;
    UINT r;

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

    r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
    MsiCloseHandle( handle );

    return r;
}

INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
                                         LPSTR lpPathBuf, DWORD* pcchBuf)
{
    LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
    INSTALLSTATE rc;
    UINT len, incoming_len;

    if( szProduct )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
        szwProduct= HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
        if( !szwProduct)
            return ERROR_OUTOFMEMORY;
        MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
    }

    if( szComponent )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
        szwComponent= HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
        if( !szwComponent )
        {
            HeapFree( GetProcessHeap(), 0, szwProduct);
            return ERROR_OUTOFMEMORY;
        }
        MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
    }

    if( pcchBuf && *pcchBuf > 0 )
        lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
    else
        lpwPathBuf = NULL;

    incoming_len = *pcchBuf;
    rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);

    HeapFree( GetProcessHeap(), 0, szwProduct);
    HeapFree( GetProcessHeap(), 0, szwComponent);
    if (lpwPathBuf)
    {
        if (rc != INSTALLSTATE_UNKNOWN)
            WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
                            lpPathBuf, incoming_len, NULL, NULL);
        HeapFree( GetProcessHeap(), 0, lpwPathBuf);
    }

    return rc;
}

INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
                                         LPWSTR lpPathBuf, DWORD* pcchBuf)
{
    WCHAR squished_pc[GUID_SIZE];
    UINT rc;
    INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
    HKEY hkey = 0;
    LPWSTR path = NULL;
    DWORD sz, type;

    TRACE("%s %s %p %p\n", debugstr_w(szProduct),
           debugstr_w(szComponent), lpPathBuf, pcchBuf);

    if( lpPathBuf && !pcchBuf )
        return INSTALLSTATE_INVALIDARG;

    squash_guid(szProduct,squished_pc);

    rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
    if( rc != ERROR_SUCCESS )
        goto end;

    RegCloseKey(hkey);

    rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
    if( rc != ERROR_SUCCESS )
        goto end;

    sz = 0;
    type = 0;
    rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
    if( rc != ERROR_SUCCESS )
        goto end;
    if( type != REG_SZ )
        goto end;

    sz += sizeof(WCHAR);
    path = HeapAlloc( GetProcessHeap(), 0, sz );
    if( !path )
        goto end;

    rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
    if( rc != ERROR_SUCCESS )
        goto end;

    TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
           debugstr_w(szProduct), debugstr_w(path));

    if (path[0]=='0')
    {
        FIXME("Registry entry.. check entry\n");
            rrc = INSTALLSTATE_LOCAL;
    }
    else
    {
        /* PROBABLY a file */
        if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
            rrc = INSTALLSTATE_LOCAL;
        else
            rrc = INSTALLSTATE_ABSENT;
    }

    if( pcchBuf )
    {
        sz = sz / sizeof(WCHAR);
        if( *pcchBuf >= sz )
            strcpyW( lpPathBuf, path );
        *pcchBuf = sz;
    }

end:
    HeapFree(GetProcessHeap(), 0, path );
    RegCloseKey(hkey);
    return rrc;
}

INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
{
    INSTALLSTATE rc;
    UINT len;
    LPWSTR szwProduct= NULL;
    LPWSTR szwFeature= NULL;

    if( szProduct )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
        szwProduct= HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
        if( !szwProduct)
            return ERROR_OUTOFMEMORY;
        MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
    }

    if( szFeature )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szFeature, -1, NULL, 0 );
        szwFeature= HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
        if( !szwFeature)
        {
            HeapFree( GetProcessHeap(), 0, szwProduct);
            return ERROR_OUTOFMEMORY;
        }
        MultiByteToWideChar( CP_ACP, 0, szFeature, -1, szwFeature, len );
    }

    rc = MsiQueryFeatureStateW(szwProduct, szwFeature);

    HeapFree( GetProcessHeap(), 0, szwProduct);
    HeapFree( GetProcessHeap(), 0, szwFeature);

    return rc;
}

INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
{
    FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
    /*
     * Iterates all the features components and the features parents components
     */
    return INSTALLSTATE_LOCAL;
}

UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
                DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
{
    LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
    UINT len, ret = ERROR_OUTOFMEMORY;
    
    if( szFilePath )
    {
        len = MultiByteToWideChar( CP_ACP, 0, szFilePath, -1, NULL, 0 );
        szwFilePath = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
        if( !szwFilePath )
            goto end;
        MultiByteToWideChar( CP_ACP, 0, szFilePath, -1, szwFilePath, len );
    }
    
    if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
    {
        lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
        if( !lpwVersionBuff )
            goto end;
    }

    if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
    {
        lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
        if( !lpwLangBuff )
            goto end;
    }
        
    ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
                             lpwLangBuff, pcchLangBuf);
    
    if( lpwVersionBuff )
        WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
                            lpVersionBuf, *pcchVersionBuf, NULL, NULL);
    if( lpwLangBuff )
        WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
                            lpLangBuf, *pcchLangBuf, NULL, NULL);
    
end:
    HeapFree(GetProcessHeap(), 0, szwFilePath);
    HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
    HeapFree(GetProcessHeap(), 0, lpwLangBuff);
    
    return ret;
}

UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
                DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
{
    static const WCHAR szVersionResource[] = {'\\',0};
    static const WCHAR szVersionFormat[] = {
        '%','d','.','%','d','.','%','d','.','%','d',0};
    static const WCHAR szLangFormat[] = {'%','d',0};
    UINT ret = 0;
    DWORD dwVerLen;
    LPVOID lpVer = NULL;
    VS_FIXEDFILEINFO *ffi;
    UINT puLen;
    WCHAR tmp[32];

    TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
          lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
          lpLangBuf, pcchLangBuf?*pcchLangBuf:0);

    dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
    if( !dwVerLen )
        return GetLastError();

    lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
    if( !lpVer )
    {
        ret = ERROR_OUTOFMEMORY;
        goto end;
    }

    if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
    {
        ret = GetLastError();
        goto end;
    }
    if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
    {
        if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
            (puLen > 0) )
        {
            wsprintfW(tmp, szVersionFormat,
                  HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
                  HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
            lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
            *pcchVersionBuf = strlenW(lpVersionBuf);
        }
        else
        {
            *lpVersionBuf = 0;
            *pcchVersionBuf = 0;
        }
    }

    if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
    {
        DWORD lang = GetUserDefaultLangID();

        FIXME("Retrieve language from file\n");
        wsprintfW(tmp, szLangFormat, lang);
        lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
        *pcchLangBuf = strlenW(lpLangBuf);
    }

end:
    HeapFree(GetProcessHeap(), 0, lpVer);
    return ret;
}


/******************************************************************
 *    	DllMain
 */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch(fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        msi_hInstance = hinstDLL;
        DisableThreadLibraryCalls(hinstDLL);
        msi_dialog_register_class();
        break;
    case DLL_PROCESS_DETACH:
        msi_dialog_unregister_class();
        /* FIXME: Cleanup */
        break;
    }
    return TRUE;
}

typedef struct tagIClassFactoryImpl
{
    IClassFactoryVtbl *lpVtbl;
} IClassFactoryImpl;

static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
                REFIID riid,LPVOID *ppobj)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
    FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
    return E_NOINTERFACE;
}

static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
{
    return 2;
}

static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
{
    return 1;
}

static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
    LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;

    FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
    return E_FAIL;
}

static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;

    FIXME("%p %d\n", This, dolock);
    return S_OK;
}

static IClassFactoryVtbl MsiCF_Vtbl =
{
    MsiCF_QueryInterface,
    MsiCF_AddRef,
    MsiCF_Release,
    MsiCF_CreateInstance,
    MsiCF_LockServer
};

static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };

/******************************************************************
 *    	DllGetClassObject [MSI.@]
 */
HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
        IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
        IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
        IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
        IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
    {
        *ppv = (LPVOID) &Msi_CF;
        return S_OK;
    }
    return CLASS_E_CLASSNOTAVAILABLE;
}

/******************************************************************
 *    	DllGetVersion [MSI.@]
 */
HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
{
    TRACE("%p\n",pdvi);
  
    if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
        return E_INVALIDARG;
  
    pdvi->dwMajorVersion = MSI_MAJORVERSION;
    pdvi->dwMinorVersion = MSI_MINORVERSION;
    pdvi->dwBuildNumber = MSI_BUILDNUMBER;
    pdvi->dwPlatformID = 1;
  
    return S_OK;
}

/******************************************************************
 *    	DllCanUnloadNow [MSI.@]
 */
BOOL WINAPI MSI_DllCanUnloadNow(void)
{
    return S_FALSE;
}

UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
                                DWORD* pdwUseCount, WORD* pwDateUsed)
{
    FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
          pdwUseCount, pwDateUsed);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
                                DWORD* pdwUseCount, WORD* pwDateUsed)
{
    FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
          pdwUseCount, pwDateUsed);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature, 
                             DWORD dwInstallMode, DWORD dwReserved)
{
    FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
          dwInstallMode, dwReserved);

    /*
     * Polls all the components of the feature to find install state and then
     *  writes:
     *    Software\\Microsoft\\Windows\\CurrentVersion\\
     *    Installer\\Products\\<squishguid>\\<feature>
     *      "Usage"=dword:........
     */  
 
    return INSTALLSTATE_LOCAL; 
}

INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature, 
                             DWORD dwInstallMode, DWORD dwReserved)
{
    FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
          dwInstallMode, dwReserved);
   
    return INSTALLSTATE_LOCAL; 
}

INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
{
    FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
   
    return INSTALLSTATE_LOCAL; 
}

INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
{
    FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
   
    return INSTALLSTATE_LOCAL; 
}

UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent, 
                LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
                DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf, 
                DWORD* pcchPathBuf)
{
    FIXME("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
          debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
          Unused1, Unused2, lpPathBuf, pcchPathBuf);

    return ERROR_INDEX_ABSENT;
}

USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf, 
                DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf, 
                DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
{
    FIXME("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
          pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
          pcchSerialBuf);
  
    return USERINFOSTATE_UNKNOWN; 
}

USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf, 
                DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf, 
                DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
{
    FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
          pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
          pcchSerialBuf);
  
    return USERINFOSTATE_UNKNOWN; 
}

UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
{
    FIXME("%s\n",debugstr_w(szProduct));
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
{
    FIXME("%s\n",debugstr_a(szProduct));
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiCreateAndVerifyInstallerDirectory(void)
{
    FIXME("\n");
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
                                   LPSTR szProductCode, LPSTR szFeatureId,
                                   LPSTR szComponentCode )
{
    FIXME("\n");
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
                                   LPWSTR szProductCode, LPWSTR szFeatureId,
                                   LPWSTR szComponentCode )
{
    FIXME("\n");
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature, 
                                  DWORD dwReinstallMode )
{
    FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
                           dwReinstallMode);
    return ERROR_SUCCESS;
}

UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature, 
                                  DWORD dwReinstallMode )
{
    FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
                           dwReinstallMode);
    return ERROR_SUCCESS;
}
