/*
 * Advpack registry functions
 *
 * Copyright 2004 Huw D M Davies
 *
 * 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>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winerror.h"
#include "winuser.h"
#include "winternl.h"
#include "setupapi.h"
#include "advpub.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(advpack);

static const WCHAR REGINST[] = {'R','E','G','I','N','S','T',0};
static const WCHAR Strings[] = {'S','t','r','i','n','g','s',0};
static const WCHAR MOD_PATH[] = {'_','M','O','D','_','P','A','T','H',0};
static const WCHAR SYS_MOD_PATH[] = {'_','S','Y','S','_','M','O','D','_','P','A','T','H',0};
static const WCHAR SystemRoot[] = {'S','y','s','t','e','m','R','o','o','t',0};
static const WCHAR escaped_SystemRoot[] = {'%','S','y','s','t','e','m','R','o','o','t','%',0};
static const WCHAR quote[] = {'\"',0};

static BOOL get_temp_ini_path(LPWSTR name)
{
    WCHAR tmp_dir[MAX_PATH];
    WCHAR prefix[] = {'a','v','p',0};

    if(!GetTempPathW(sizeof(tmp_dir)/sizeof(WCHAR), tmp_dir))
       return FALSE;

    if(!GetTempFileNameW(tmp_dir, prefix, 0, name))
        return FALSE;
    return TRUE;
}

static BOOL create_tmp_ini_file(HMODULE hm, WCHAR *ini_file)
{
    HRSRC hrsrc;
    HGLOBAL hmem = NULL;
    DWORD rsrc_size, bytes_written;
    VOID *rsrc_data;
    HANDLE hf = INVALID_HANDLE_VALUE;

    if(!get_temp_ini_path(ini_file)) {
        ERR("Can't get temp ini file path\n");
        goto error;
    }

    if(!(hrsrc = FindResourceW(hm, REGINST, REGINST))) {
        ERR("Can't find REGINST resource\n");
        goto error;
    }

    rsrc_size = SizeofResource(hm, hrsrc);
    hmem = LoadResource(hm, hrsrc);
    rsrc_data = LockResource(hmem);

    if(!rsrc_data || !rsrc_size) {
        ERR("Can't load REGINST resource\n");
        goto error;
    }       

    if((hf = CreateFileW(ini_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                         FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) {
        ERR("Unable to create temp ini file\n");
        goto error;
    }
    if(!WriteFile(hf, rsrc_data, rsrc_size, &bytes_written, NULL) || rsrc_size != bytes_written) {
        ERR("Write failed\n");
        goto error;
    }
    FreeResource(hmem);
    CloseHandle(hf);
    return TRUE;
error:
    if(hmem) FreeResource(hmem);
    if(hf != INVALID_HANDLE_VALUE) CloseHandle(hf);
    return FALSE;
}

static void strentry_atow(STRENTRYA *aentry, STRENTRYW *wentry)
{
    DWORD name_len, val_len;

    name_len = MultiByteToWideChar(CP_ACP, 0, aentry->pszName, -1, NULL, 0);
    val_len = MultiByteToWideChar(CP_ACP, 0, aentry->pszValue, -1, NULL, 0);

    wentry->pszName = HeapAlloc(GetProcessHeap(), 0, name_len * sizeof(WCHAR));
    wentry->pszValue = HeapAlloc(GetProcessHeap(), 0, val_len * sizeof(WCHAR));

    MultiByteToWideChar(CP_ACP, 0, aentry->pszName, -1, wentry->pszName, name_len);
    MultiByteToWideChar(CP_ACP, 0, aentry->pszValue, -1, wentry->pszValue, val_len);
}

static STRTABLEW *strtable_atow(const STRTABLEA *atable)
{
    STRTABLEW *wtable;
    DWORD j;

    wtable = HeapAlloc(GetProcessHeap(), 0, sizeof(STRTABLEW));
    wtable->pse = HeapAlloc(GetProcessHeap(), 0, atable->cEntries * sizeof(STRENTRYW));
    wtable->cEntries = atable->cEntries;

    for (j = 0; j < wtable->cEntries; j++)
        strentry_atow(&atable->pse[j], &wtable->pse[j]);

    return wtable;
}

static void free_strtable(STRTABLEW *wtable)
{
    DWORD j;

    for (j = 0; j < wtable->cEntries; j++)
    {
        HeapFree(GetProcessHeap(), 0, wtable->pse[j].pszName);
        HeapFree(GetProcessHeap(), 0, wtable->pse[j].pszValue);
    }

    HeapFree(GetProcessHeap(), 0, wtable->pse);
    HeapFree(GetProcessHeap(), 0, wtable);
}

/***********************************************************************
 *          RegInstallA (advpack.@)
 *
 * See RegInstallW.
 */
HRESULT WINAPI RegInstallA(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable)
{
    UNICODE_STRING section;
    STRTABLEW *wtable;
    HRESULT hr;

    TRACE("(%p, %s, %p)\n", hm, debugstr_a(pszSection), pstTable);

    if (pstTable)
        wtable = strtable_atow(pstTable);
    else
        wtable = NULL;

    RtlCreateUnicodeStringFromAsciiz(&section, pszSection);

    hr = RegInstallW(hm, section.Buffer, wtable);

    if (pstTable)
        free_strtable(wtable);

    RtlFreeUnicodeString(&section);

    return hr;
}

static HRESULT write_predefined_strings(HMODULE hm, LPWSTR ini_path)
{
    WCHAR mod_path[MAX_PATH + 2];
    WCHAR sys_mod_path[MAX_PATH + 2];
    WCHAR sys_root[MAX_PATH];

    *mod_path = '\"';
    if (!GetModuleFileNameW(hm, mod_path + 1, sizeof(mod_path) / sizeof(WCHAR) - 2))
        return E_FAIL;

    lstrcatW(mod_path, quote);
    WritePrivateProfileStringW(Strings, MOD_PATH, mod_path, ini_path);

    *sys_root = '\0';
    GetEnvironmentVariableW(SystemRoot, sys_root, sizeof(sys_root) / sizeof(WCHAR));

    if(!strncmpiW(sys_root, mod_path + 1, strlenW(sys_root)))
    {
        *sys_mod_path = '\"';
        strcpyW(sys_mod_path + 1, escaped_SystemRoot);
        strcatW(sys_mod_path, mod_path + 1 + strlenW(sys_root));
    }
    else
    {
        FIXME("SYS_MOD_PATH needs more work\n");
        strcpyW(sys_mod_path, mod_path);
    }

    WritePrivateProfileStringW(Strings, SYS_MOD_PATH, sys_mod_path, ini_path);

    return S_OK;
}

/***********************************************************************
 *          RegInstallW (advpack.@)
 *
 * Loads an INF from a string resource, adds entries to the string
 * substitution table, and executes the INF.
 *
 * PARAMS
 *   hm         [I] Module that contains the REGINST resouce.
 *   pszSection [I] The INF section to execute.
 *   pstTable   [I] Table of string substitutions.
 * 
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 */
HRESULT WINAPI RegInstallW(HMODULE hm, LPCWSTR pszSection, const STRTABLEW* pstTable)
{
    int i;
    CABINFOW cabinfo;
    WCHAR tmp_ini_path[MAX_PATH];
    HINF hinf = INVALID_HANDLE_VALUE;
    HRESULT hr = E_FAIL;

    TRACE("(%p, %s, %p)\n", hm, debugstr_w(pszSection), pstTable);

    if(!create_tmp_ini_file(hm, tmp_ini_path))
        return E_FAIL;

    if (write_predefined_strings(hm, tmp_ini_path))
        goto done;

    /* Write the additional string table */
    if (pstTable)
    {
        for(i = 0; i < pstTable->cEntries; i++)
        {
            WCHAR tmp_value[MAX_PATH + 2];
    
            tmp_value[0] = '\"';
            lstrcpyW(tmp_value + 1, pstTable->pse[i].pszValue);
            lstrcatW(tmp_value, quote);
    
            WritePrivateProfileStringW(Strings, pstTable->pse[i].pszName, tmp_value, tmp_ini_path);
        }
    }

    /* flush cache */
    WritePrivateProfileStringW(NULL, NULL, NULL, tmp_ini_path);

    /* FIXME: read AdvOptions val for dwFlags */
    ZeroMemory(&cabinfo, sizeof(CABINFOW));
    cabinfo.pszInf = tmp_ini_path;
    cabinfo.pszSection = (LPWSTR)pszSection;
    cabinfo.dwFlags = 0;

    hr = ExecuteCabW(NULL, &cabinfo, NULL);

done:
    if (hinf != INVALID_HANDLE_VALUE)
        SetupCloseInfFile(hinf);

    DeleteFileW(tmp_ini_path);

    return hr;
}

/***********************************************************************
 *          RegRestoreAllA (advpack.@)
 *
 * See RegRestoreAllW.
 */
HRESULT WINAPI RegRestoreAllA(HWND hWnd, LPSTR pszTitleString, HKEY hkBackupKey)
{
    UNICODE_STRING title;
    HRESULT hr;

    TRACE("(%p, %s, %p)\n", hWnd, debugstr_a(pszTitleString), hkBackupKey);

    RtlCreateUnicodeStringFromAsciiz(&title, pszTitleString);

    hr = RegRestoreAllW(hWnd, title.Buffer, hkBackupKey);

    RtlFreeUnicodeString(&title);

    return hr;
}

/***********************************************************************
 *          RegRestoreAllW (advpack.@)
 *
 * Restores all saved registry entries.
 *
 * PARAMS
 *   hWnd           [I] Handle to the window used for the display.
 *   pszTitleString [I] Title of the window.
 *   hkBackupKey    [I] Handle to the backup key.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * BUGS
 *   Unimplemented.
 */
HRESULT WINAPI RegRestoreAllW(HWND hWnd, LPWSTR pszTitleString, HKEY hkBackupKey)
{
    FIXME("(%p, %s, %p) stub\n", hWnd, debugstr_w(pszTitleString), hkBackupKey);
    
    return E_FAIL;   
}

/***********************************************************************
 *          RegSaveRestoreA (advpack.@)
 *
 * See RegSaveRestoreW.
 */
HRESULT WINAPI RegSaveRestoreA(HWND hWnd, LPCSTR pszTitleString, HKEY hkBackupKey,
                               LPCSTR pcszRootKey, LPCSTR pcszSubKey,
                               LPCSTR pcszValueName, DWORD dwFlags)
{
    UNICODE_STRING title, root, subkey, value;
    HRESULT hr;

    TRACE("(%p, %s, %p, %s, %s, %s, %ld)\n", hWnd, debugstr_a(pszTitleString),
          hkBackupKey, debugstr_a(pcszRootKey), debugstr_a(pcszSubKey),
          debugstr_a(pcszValueName), dwFlags);

    RtlCreateUnicodeStringFromAsciiz(&title, pszTitleString);
    RtlCreateUnicodeStringFromAsciiz(&root, pcszRootKey);
    RtlCreateUnicodeStringFromAsciiz(&subkey, pcszSubKey);
    RtlCreateUnicodeStringFromAsciiz(&value, pcszValueName);

    hr = RegSaveRestoreW(hWnd, title.Buffer, hkBackupKey, root.Buffer,
                         subkey.Buffer, value.Buffer, dwFlags);

    RtlFreeUnicodeString(&title);
    RtlFreeUnicodeString(&root);
    RtlFreeUnicodeString(&subkey);
    RtlFreeUnicodeString(&value);

    return hr;
}

/***********************************************************************
 *          RegSaveRestoreW (advpack.@)
 *
 * Saves or restores the specified registry value.
 *
 * PARAMS
 *   hWnd           [I] Handle to the window used for the display.
 *   pszTitleString [I] Title of the window.
 *   hkBackupKey    [I] Key used to store the backup data.
 *   pcszRootKey    [I] Root key of the registry value
 *   pcszSubKey     [I] Sub key of the registry value.
 *   pcszValueName  [I] Value to save or restore. 
 *   dwFlags        [I] See advpub.h.
 * 
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * BUGS
 *   Unimplemented.
 */
HRESULT WINAPI RegSaveRestoreW(HWND hWnd, LPCWSTR pszTitleString, HKEY hkBackupKey,
                               LPCWSTR pcszRootKey, LPCWSTR pcszSubKey,
                               LPCWSTR pcszValueName, DWORD dwFlags)
{
    FIXME("(%p, %s, %p, %s, %s, %s, %ld): stub\n", hWnd, debugstr_w(pszTitleString),
          hkBackupKey, debugstr_w(pcszRootKey), debugstr_w(pcszSubKey),
          debugstr_w(pcszValueName), dwFlags);

    return E_FAIL;   
}

/***********************************************************************
 *          RegSaveRestoreOnINFA (advpack.@)
 *
 * See RegSaveRestoreOnINFW.
 */
HRESULT WINAPI RegSaveRestoreOnINFA(HWND hWnd, LPCSTR pszTitle, LPCSTR pszINF,
                                    LPCSTR pszSection, HKEY hHKLMBackKey,
                                    HKEY hHKCUBackKey, DWORD dwFlags)
{
    UNICODE_STRING title, inf, section;
    HRESULT hr;

    TRACE("(%p, %s, %s, %s, %p, %p, %ld)\n", hWnd, debugstr_a(pszTitle),
          debugstr_a(pszINF), debugstr_a(pszSection),
          hHKLMBackKey, hHKCUBackKey, dwFlags);

    RtlCreateUnicodeStringFromAsciiz(&title, pszTitle);
    RtlCreateUnicodeStringFromAsciiz(&inf, pszINF);
    RtlCreateUnicodeStringFromAsciiz(&section, pszSection);

    hr = RegSaveRestoreOnINFW(hWnd, title.Buffer, inf.Buffer, section.Buffer,
                              hHKLMBackKey, hHKCUBackKey, dwFlags);

    RtlFreeUnicodeString(&title);
    RtlFreeUnicodeString(&inf);
    RtlFreeUnicodeString(&section);

    return hr;
}

/***********************************************************************
 *          RegSaveRestoreOnINFW (advpack.@)
 *
 * Saves or restores the specified INF Reg section.
 *
 * PARAMS
 *   hWnd         [I] Handle to the window used for the display.
 *   pszTitle     [I] Title of the window.
 *   pszINF       [I] Filename of the INF.
 *   pszSection   [I] Section to save or restore.
 *   hHKLMBackKey [I] Opened key in HKLM to store data.
 *   hHKCUBackKey [I] Opened key in HKCU to store data.
 *   dwFlags      [I] See advpub.h
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * BUGS
 *   Unimplemented.
 */
HRESULT WINAPI RegSaveRestoreOnINFW(HWND hWnd, LPCWSTR pszTitle, LPCWSTR pszINF,
                                    LPCWSTR pszSection, HKEY hHKLMBackKey,
                                    HKEY hHKCUBackKey, DWORD dwFlags)
{
    FIXME("(%p, %s, %s, %s, %p, %p, %ld): stub\n", hWnd, debugstr_w(pszTitle),
          debugstr_w(pszINF), debugstr_w(pszSection),
          hHKLMBackKey, hHKCUBackKey, dwFlags);

    return E_FAIL;   
}
