/*
 * 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
 */

#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 "wincrypt.h"
#include "winver.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "sddl.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);

/*
 * These apis are defined in MSI 3.0
 */

typedef struct tagMediaInfo
{
    LPWSTR  path;
    WCHAR   szIndex[10];
    WCHAR   type;
} media_info;

static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, BOOL user, BOOL create)
{
    HKEY rootkey = 0; 
    UINT rc; 
    static const WCHAR szSourceList[] = {'S','o','u','r','c','e','L','i','s','t',0};

    if (user)
        rc = MSIREG_OpenUserProductsKey(szProduct, &rootkey, create);
    else
        rc = MSIREG_OpenProductsKey(szProduct, &rootkey, create);

    if (rc)
        return rc;

    if (create)
        rc = RegCreateKeyW(rootkey, szSourceList, key);
    else
        rc = RegOpenKeyW(rootkey,szSourceList, key); 

    return rc;
}

static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
{
    UINT rc;
    static const WCHAR media[] = {'M','e','d','i','a',0};

    if (create)
        rc = RegCreateKeyW(rootkey, media, key);
    else
        rc = RegOpenKeyW(rootkey,media, key); 

    return rc;
}

static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
{
    UINT rc;
    static const WCHAR net[] = {'N','e','t',0};

    if (create)
        rc = RegCreateKeyW(rootkey, net, key);
    else
        rc = RegOpenKeyW(rootkey, net, key); 

    return rc;
}

static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
{
    UINT rc;
    static const WCHAR URL[] = {'U','R','L',0};

    if (create)
        rc = RegCreateKeyW(rootkey, URL, key);
    else
        rc = RegOpenKeyW(rootkey, URL, key); 

    return rc;
}


static UINT find_given_source(HKEY key, LPCWSTR szSource, media_info *ss)
{
    DWORD index = 0;
    WCHAR szIndex[10];
    DWORD size;
    DWORD val_size;
    LPWSTR val;
    UINT rc = ERROR_SUCCESS;

    while (rc == ERROR_SUCCESS)
    {
        val = NULL;
        val_size = 0;
        size = sizeof(szIndex)/sizeof(szIndex[0]);
        rc = RegEnumValueW(key, index, szIndex, &size, NULL, NULL, NULL, &val_size);
        if (rc != ERROR_NO_MORE_ITEMS)
        {
            val = msi_alloc(val_size);
            RegEnumValueW(key, index, szIndex, &size, NULL, NULL, (LPBYTE)val, 
                &val_size);
            if (lstrcmpiW(szSource,val)==0)
            {
                ss->path = val;
                strcpyW(ss->szIndex,szIndex);
                break;
            }
            else
                strcpyW(ss->szIndex,szIndex);

            msi_free(val);
            index ++;
        }
    }
    return rc;
}

/******************************************************************
 *  MsiSourceListGetInfoW   (MSI.@)
 */
UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
                                   MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
                                   LPCWSTR szProperty, LPWSTR szValue, 
                                   LPDWORD pcchValue) 
{
    HKEY sourcekey;
    UINT rc;

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

    if (!szProduct || lstrlenW(szProduct) > 39)
        return ERROR_INVALID_PARAMETER;

    if (szValue && !pcchValue)
        return ERROR_INVALID_PARAMETER;
    
    if (dwOptions == MSICODE_PATCH)
    {
        FIXME("Unhandled options MSICODE_PATCH\n");
        return ERROR_FUNCTION_FAILED;
    }
    
    if (szUserSid)
        FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));

    if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
        FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");

    if (dwContext == MSIINSTALLCONTEXT_MACHINE)
        rc = OpenSourceKey(szProduct, &sourcekey, FALSE, FALSE);
    else
        rc = OpenSourceKey(szProduct, &sourcekey, TRUE, FALSE);

    if (rc != ERROR_SUCCESS)
        return ERROR_UNKNOWN_PRODUCT;

    if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
    {
        HKEY key;
        rc = OpenMediaSubkey(sourcekey, &key, FALSE);
        if (rc == ERROR_SUCCESS)
            rc = RegQueryValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW,
                    0, 0, (LPBYTE)szValue, pcchValue);
        if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
            rc = ERROR_UNKNOWN_PROPERTY;
        RegCloseKey(key);
    }
    else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) ==0)
    {
        HKEY key;
        rc = OpenMediaSubkey(sourcekey, &key, FALSE);
        if (rc == ERROR_SUCCESS)
            rc = RegQueryValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0, 0,
                    (LPBYTE)szValue, pcchValue);
        if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
            rc = ERROR_UNKNOWN_PROPERTY;
        RegCloseKey(key);
    }
    else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
    {
        LPWSTR buffer;
        DWORD size = 0;

        RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
                NULL, &size);
        if (size == 0)
            rc = ERROR_UNKNOWN_PROPERTY;
        else
        {
            LPWSTR ptr;
            buffer = msi_alloc(size);
            rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
                    0, 0, (LPBYTE)buffer,&size); 
            ptr = strchrW(buffer,';');
            if (ptr) ptr = strchrW(ptr+1,';');
            if (!ptr)
                rc = ERROR_UNKNOWN_PROPERTY;
            else
            {
                ptr ++;
                lstrcpynW(szValue, ptr, *pcchValue);
                if (lstrlenW(ptr) > *pcchValue)
                {
                    *pcchValue = lstrlenW(ptr)+1;
                    rc = ERROR_MORE_DATA;
                }
                else
                    rc = ERROR_SUCCESS;
            }
            msi_free(buffer);
        }
    }
    else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0)
    {
        LPWSTR buffer;
        DWORD size = 0;

        RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
                NULL, &size);
        if (size == 0)
            rc = ERROR_UNKNOWN_PROPERTY;
        else
        {
            buffer = msi_alloc(size);
            rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
                    0, 0, (LPBYTE)buffer,&size); 
            if (*pcchValue < 1)
            {
                rc = ERROR_MORE_DATA;
                *pcchValue = 1;
            }
            else
            {
                szValue[0] = buffer[0];
                rc = ERROR_SUCCESS;
            }
            msi_free(buffer);
        }
    }
    else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
    {
        rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0, 
                (LPBYTE)szValue, pcchValue);
        if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
            rc = ERROR_UNKNOWN_PROPERTY;
    }
    else
    {
        FIXME("Unknown property %s\n",debugstr_w(szProperty));
        rc = ERROR_UNKNOWN_PROPERTY;
    }

    RegCloseKey(sourcekey);
    return rc;
}

/******************************************************************
 *  MsiSourceListSetInfoW   (MSI.@)
 */
UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
                                   MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
                                   LPCWSTR szProperty, LPCWSTR szValue)
{
    HKEY sourcekey;
    UINT rc;

    TRACE("%s %s %x %x %s %s\n", debugstr_w(szProduct), debugstr_w(szUserSid),
            dwContext, dwOptions, debugstr_w(szProperty), debugstr_w(szValue));

    if (!szProduct || lstrlenW(szProduct) > 39)
        return ERROR_INVALID_PARAMETER;

    if (dwOptions & MSICODE_PATCH)
    {
        FIXME("Unhandled options MSICODE_PATCH\n");
        return ERROR_FUNCTION_FAILED;
    }
    
    if (szUserSid)
        FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));

    if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
        FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");

    if (dwContext == MSIINSTALLCONTEXT_MACHINE)
        rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
    else
        rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);

    if (rc != ERROR_SUCCESS)
        return ERROR_UNKNOWN_PRODUCT;


    if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
    {
        HKEY key;
        DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
        rc = OpenMediaSubkey(sourcekey, &key, FALSE);
        if (rc == ERROR_SUCCESS)
            rc = RegSetValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW, 0,
                    REG_SZ, (const BYTE *)szValue, size);
        if (rc != ERROR_SUCCESS)
            rc = ERROR_UNKNOWN_PROPERTY;
        RegCloseKey(key);
    }
    else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) == 0)
    {
        HKEY key;
        DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
        rc = OpenMediaSubkey(sourcekey, &key, FALSE);
        if (rc == ERROR_SUCCESS)
            rc = RegSetValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0,
                    REG_SZ, (const BYTE *)szValue, size);
        if (rc != ERROR_SUCCESS)
            rc = ERROR_UNKNOWN_PROPERTY;
        RegCloseKey(key);
    }
    else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
    {
        LPWSTR buffer = NULL;
        DWORD size;
        WCHAR typechar = 'n';
        static const WCHAR LastUsedSource_Fmt[] = {'%','c',';','%','i',';','%','s',0};

        /* make sure the source is registered */
        MsiSourceListAddSourceExW(szProduct, szUserSid, dwContext, 
                dwOptions, szValue, 0); 

        if (dwOptions & MSISOURCETYPE_NETWORK)
            typechar = 'n';
        else if (dwOptions & MSISOURCETYPE_URL)
            typechar = 'u';
        else if (dwOptions & MSISOURCETYPE_MEDIA)
            typechar = 'm';
        else
            ERR("Unknown source type! %x\n", dwOptions);

        size = (lstrlenW(szValue)+5)*sizeof(WCHAR);
        buffer = msi_alloc(size);
        sprintfW(buffer, LastUsedSource_Fmt, typechar, 1, szValue);
        rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 
                REG_EXPAND_SZ, (LPBYTE)buffer, size);
        if (rc != ERROR_SUCCESS)
            rc = ERROR_UNKNOWN_PROPERTY;
        msi_free( buffer );
    }
    else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
    {
        DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
        rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0,
                REG_SZ, (const BYTE *)szValue, size);
        if (rc != ERROR_SUCCESS)
            rc = ERROR_UNKNOWN_PROPERTY;
    }
    else
    {
        FIXME("Unknown property %s\n",debugstr_w(szProperty));
        rc = ERROR_UNKNOWN_PROPERTY;
    }

    RegCloseKey(sourcekey);
    return rc;

}

/******************************************************************
 *  MsiSourceListAddSourceW (MSI.@)
 */
UINT WINAPI MsiSourceListAddSourceW( LPCWSTR szProduct, LPCWSTR szUserName,
        DWORD dwReserved, LPCWSTR szSource)
{
    INT ret;
    LPWSTR sidstr = NULL;
    DWORD sidsize = 0;
    DWORD domsize = 0;

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

    if (LookupAccountNameW(NULL, szUserName, NULL, &sidsize, NULL, &domsize, NULL))
    {
        PSID psid = msi_alloc(sidsize);

        if (LookupAccountNameW(NULL, szUserName, psid, &sidsize, NULL, &domsize, NULL))
            ConvertSidToStringSidW(psid, &sidstr);

        msi_free(psid);
    }

    ret = MsiSourceListAddSourceExW(szProduct, sidstr, 
        MSIINSTALLCONTEXT_USERMANAGED, MSISOURCETYPE_NETWORK, szSource, 0);

    if (sidstr)
        LocalFree(sidstr);

    return ret;
}

/******************************************************************
 *  MsiSourceListAddSourceA (MSI.@)
 */
UINT WINAPI MsiSourceListAddSourceA( LPCSTR szProduct, LPCSTR szUserName,
        DWORD dwReserved, LPCSTR szSource)
{
    INT ret;
    LPWSTR szwproduct;
    LPWSTR szwusername;
    LPWSTR szwsource;

    szwproduct = strdupAtoW( szProduct );
    szwusername = strdupAtoW( szUserName );
    szwsource = strdupAtoW( szSource );

    ret = MsiSourceListAddSourceW(szwproduct, szwusername, 0, szwsource);

    msi_free(szwproduct);
    msi_free(szwusername);
    msi_free(szwsource);

    return ret;
}

/******************************************************************
 *  MsiSourceListAddSourceExW (MSI.@)
 */
UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
        MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource, 
        DWORD dwIndex)
{
    HKEY sourcekey;
    HKEY typekey;
    UINT rc;
    media_info source_struct;

    TRACE("%s %s %x %x %s %i\n", debugstr_w(szProduct), debugstr_w(szUserSid),
          dwContext, dwOptions, debugstr_w(szSource), dwIndex);

    if (!szProduct)
        return ERROR_INVALID_PARAMETER;

    if (!szSource)
        return ERROR_INVALID_PARAMETER;

    if (dwOptions & MSICODE_PATCH)
    {
        FIXME("Unhandled options MSICODE_PATCH\n");
        return ERROR_FUNCTION_FAILED;
    }

    if (szUserSid)
        FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));

    if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
        FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");

    if (dwContext == MSIINSTALLCONTEXT_MACHINE)
        rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
    else
        rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);

    if (rc != ERROR_SUCCESS)
        return ERROR_UNKNOWN_PRODUCT;

    if (dwOptions & MSISOURCETYPE_NETWORK)
        rc = OpenNetworkSubkey(sourcekey, &typekey, TRUE);
    else if (dwOptions & MSISOURCETYPE_URL)
        rc = OpenURLSubkey(sourcekey, &typekey, TRUE);
    else if (dwOptions & MSISOURCETYPE_MEDIA)
        rc = OpenMediaSubkey(sourcekey, &typekey, TRUE);
    else
    {
        ERR("unknown media type: %08x\n", dwOptions);
        RegCloseKey(sourcekey);
        return ERROR_FUNCTION_FAILED;
    }

    source_struct.szIndex[0] = 0;
    if (find_given_source(typekey, szSource, &source_struct)==ERROR_SUCCESS)
    {
        DWORD current_index = atoiW(source_struct.szIndex);
        /* found the source */
        if (dwIndex > 0 && current_index != dwIndex)
            FIXME("Need to reorder the sources!\n");
        msi_free( source_struct.path );
    }
    else
    {
        DWORD current_index = 0;
        static const WCHAR fmt[] = {'%','i',0};
        DWORD size = lstrlenW(szSource)*sizeof(WCHAR);

        if (source_struct.szIndex[0])
            current_index = atoiW(source_struct.szIndex);
        /* new source */
        if (dwIndex > 0 && dwIndex < current_index)
            FIXME("Need to reorder the sources!\n");

        current_index ++;
        sprintfW(source_struct.szIndex,fmt,current_index);
        rc = RegSetValueExW(typekey, source_struct.szIndex, 0, REG_EXPAND_SZ, 
                (const BYTE *)szSource, size);
    }

    RegCloseKey(typekey);
    RegCloseKey(sourcekey);
    return rc;
}

/******************************************************************
 *  MsiSourceListAddMediaDisk(MSI.@)
 */
UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid, 
        MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId, 
        LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt)
{
    HKEY sourcekey;
    HKEY mediakey;
    UINT rc;
    WCHAR szIndex[10];
    static const WCHAR fmt[] = {'%','i',0};
    static const WCHAR disk_fmt[] = {'%','s',';','%','s',0};
    static const WCHAR empty[1] = {0};
    LPCWSTR pt1,pt2;
    LPWSTR buffer;
    DWORD size;

    TRACE("%s %s %x %x %i %s %s\n", debugstr_w(szProduct),
            debugstr_w(szUserSid), dwContext, dwOptions, dwDiskId,
            debugstr_w(szVolumeLabel), debugstr_w(szDiskPrompt));

    if (!szProduct || lstrlenW(szProduct) > 39)
        return ERROR_INVALID_PARAMETER;

    if (dwOptions & MSICODE_PATCH)
    {
        FIXME("Unhandled options MSICODE_PATCH\n");
        return ERROR_FUNCTION_FAILED;
    }
    
    if (szUserSid)
        FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));

    if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
        FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");

    if (dwContext == MSIINSTALLCONTEXT_MACHINE)
        rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
    else
        rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);

    if (rc != ERROR_SUCCESS)
        return ERROR_UNKNOWN_PRODUCT;

    OpenMediaSubkey(sourcekey,&mediakey,TRUE);

    sprintfW(szIndex,fmt,dwDiskId);

    size = 2;
    if (szVolumeLabel)
    {
        size +=lstrlenW(szVolumeLabel);
        pt1 = szVolumeLabel;
    }
    else
        pt1 = empty;
    if (szDiskPrompt)
    {
        size +=lstrlenW(szDiskPrompt);
        pt2 = szDiskPrompt;
    }
    else
        pt2 = empty;

    size *=sizeof(WCHAR);

    buffer = msi_alloc(size);
    sprintfW(buffer,disk_fmt,pt1,pt2);

    RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);
    msi_free( buffer );

    RegCloseKey(sourcekey);
    RegCloseKey(mediakey);

    return ERROR_SUCCESS;
}

/******************************************************************
 *  MsiSourceListAddSourceExA (MSI.@)
 */
UINT WINAPI MsiSourceListClearAllA( LPCSTR szProduct, LPCSTR szUserName, DWORD dwReserved )
{
    FIXME("(%s %s %d)\n", debugstr_a(szProduct), debugstr_a(szUserName), dwReserved);
    return ERROR_SUCCESS;
}

/******************************************************************
 *  MsiSourceListAddSourceExW (MSI.@)
 */
UINT WINAPI MsiSourceListClearAllW( LPCWSTR szProduct, LPCWSTR szUserName, DWORD dwReserved )
{
    FIXME("(%s %s %d)\n", debugstr_w(szProduct), debugstr_w(szUserName), dwReserved);
    return ERROR_SUCCESS;
}
