/*
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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];
    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:

    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, %d)\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, %d): 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, %d)\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, %d): stub\n", hWnd, debugstr_w(pszTitle),
          debugstr_w(pszINF), debugstr_w(pszSection),
          hHKLMBackKey, hHKCUBackKey, dwFlags);

    return E_FAIL;   
}
