/*
 * Advpack main
 *
 * Copyright 2004 Huw D M Davies
 * Copyright 2005 Sami Aario
 *
 * 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 "winuser.h"
#include "winreg.h"
#include "winver.h"
#include "winternl.h"
#include "winnls.h"
#include "setupapi.h"
#include "advpub.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "advpack_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(advpack);

typedef HRESULT (WINAPI *DLLREGISTER) (void);

#define MAX_FIELD_LENGTH    512
#define PREFIX_LEN          5

/* registry path of the Installed Components key for per-user stubs */
static const WCHAR setup_key[] = {
    'S','O','F','T','W','A','R','E','\\',
    'M','i','c','r','o','s','o','f','t','\\',
    'A','c','t','i','v','e',' ','S','e','t','u','p','\\',
    'I','n','s','t','a','l','l','e','d',' ',
    'C','o','m','p','o','n','e','n','t','s',0
};

/* parses the destination directory parameters from pszSection
 * the parameters are of the form: root,key,value,unknown,fallback
 * we first read the reg value root\\key\\value and if that fails,
 * use fallback as the destination directory
 */
static void get_dest_dir(HINF hInf, PCWSTR pszSection, PWSTR pszBuffer, DWORD dwSize)
{
    INFCONTEXT context;
    WCHAR key[MAX_PATH], value[MAX_PATH];
    WCHAR prefix[PREFIX_LEN];
    HKEY root, subkey;
    DWORD size;

    static const WCHAR hklm[] = {'H','K','L','M',0};
    static const WCHAR hkcu[] = {'H','K','C','U',0};

    /* load the destination parameters */
    SetupFindFirstLineW(hInf, pszSection, NULL, &context);
    SetupGetStringFieldW(&context, 1, prefix, PREFIX_LEN, &size);
    SetupGetStringFieldW(&context, 2, key, MAX_PATH, &size);
    SetupGetStringFieldW(&context, 3, value, MAX_PATH, &size);

    if (!lstrcmpW(prefix, hklm))
        root = HKEY_LOCAL_MACHINE;
    else if (!lstrcmpW(prefix, hkcu))
        root = HKEY_CURRENT_USER;
    else
        root = NULL;

    size = dwSize * sizeof(WCHAR);

    /* fallback to the default destination dir if reg fails */
    if (RegOpenKeyW(root, key, &subkey) ||
        RegQueryValueExW(subkey, value, NULL, NULL, (LPBYTE)pszBuffer, &size))
    {
        SetupGetStringFieldW(&context, 5, pszBuffer, dwSize, NULL);
    }

    RegCloseKey(subkey);
}

/* loads the LDIDs specified in the install section of an INF */
void set_ldids(HINF hInf, LPCWSTR pszInstallSection, LPCWSTR pszWorkingDir)
{
    WCHAR field[MAX_FIELD_LENGTH];
    WCHAR line[MAX_FIELD_LENGTH];
    WCHAR dest[MAX_PATH];
    INFCONTEXT context;
    DWORD size;
    int ldid;

    static const WCHAR source_dir[] = {'S','o','u','r','c','e','D','i','r',0};

    static const WCHAR custDestW[] = {
        'C','u','s','t','o','m','D','e','s','t','i','n','a','t','i','o','n',0
    };

    if (!SetupGetLineTextW(NULL, hInf, pszInstallSection, custDestW,
                           field, MAX_FIELD_LENGTH, &size))
        return;

    if (!SetupFindFirstLineW(hInf, field, NULL, &context))
        return;

    do
    {
        LPWSTR value, ptr, key, key_copy = NULL;

        SetupGetLineTextW(&context, NULL, NULL, NULL,
                          line, MAX_FIELD_LENGTH, &size);

        /* SetupGetLineTextW returns the value if there is only one key, but
         * returns the whole line if there is more than one key
         */
        if (!(value = strchrW(line, '=')))
        {
            SetupGetStringFieldW(&context, 0, NULL, 0, &size);
            key = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
            key_copy = key;
            SetupGetStringFieldW(&context, 0, key, size, &size);
            value = line;
        }
        else
        {
            key = line;
            *(value++) = '\0';
        }

        /* remove leading whitespace from the value */
        while (*value == ' ')
            value++;

        /* FIXME: need to check the query option */
        ptr = strchrW(value, ',');
        if (ptr)
            *ptr = '\0';

        /* set dest to pszWorkingDir if key is SourceDir */
        if (pszWorkingDir && !lstrcmpiW(value, source_dir))
            lstrcpynW(dest, pszWorkingDir, MAX_PATH);
        else
            get_dest_dir(hInf, value, dest, MAX_PATH);

        /* set all ldids to dest */
        while ((ptr = get_parameter(&key, ',')))
        {
            ldid = atolW(ptr);
            SetupSetDirectoryIdW(hInf, ldid, dest);
        }
        HeapFree(GetProcessHeap(), 0, key_copy);
    } while (SetupFindNextLine(&context, &context));
}

/***********************************************************************
 *           CloseINFEngine (ADVPACK.@)
 *
 * Closes a handle to an INF file opened with OpenINFEngine.
 *
 * PARAMS
 *   hInf [I] Handle to the INF file to close.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 */
HRESULT WINAPI CloseINFEngine(HINF hInf)
{
    TRACE("(%p)\n", hInf);

    if (!hInf)
        return E_INVALIDARG;

    SetupCloseInfFile(hInf);
    return S_OK;
}

/***********************************************************************
 *           DllMain (ADVPACK.@)
 */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);

    if (fdwReason == DLL_PROCESS_ATTACH)
        DisableThreadLibraryCalls(hinstDLL);

    return TRUE;
}

/***********************************************************************
 *              IsNTAdmin	(ADVPACK.@)
 *
 * Checks if the user has admin privileges.
 *
 * PARAMS
 *   reserved  [I] Reserved.  Must be 0.
 *   pReserved [I] Reserved.  Must be NULL.
 *
 * RETURNS
 *   TRUE if user has admin rights, FALSE otherwise.
 */
BOOL WINAPI IsNTAdmin(DWORD reserved, LPDWORD pReserved)
{
    SID_IDENTIFIER_AUTHORITY SidAuthority = {SECURITY_NT_AUTHORITY};
    PTOKEN_GROUPS pTokenGroups;
    BOOL bSidFound = FALSE;
    DWORD dwSize, i;
    HANDLE hToken;
    PSID pSid;

    TRACE("(%d, %p)\n", reserved, pReserved);

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
        return FALSE;

    if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize))
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        {
            CloseHandle(hToken);
            return FALSE;
        }
    }

    pTokenGroups = HeapAlloc(GetProcessHeap(), 0, dwSize);
    if (!pTokenGroups)
    {
        CloseHandle(hToken);
        return FALSE;
    }

    if (!GetTokenInformation(hToken, TokenGroups, pTokenGroups, dwSize, &dwSize))
    {
        HeapFree(GetProcessHeap(), 0, pTokenGroups);
        CloseHandle(hToken);
        return FALSE;
    }

    CloseHandle(hToken);

    if (!AllocateAndInitializeSid(&SidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
                                  DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid))
    {
        HeapFree(GetProcessHeap(), 0, pTokenGroups);
        return FALSE;
    }

    for (i = 0; i < pTokenGroups->GroupCount; i++)
    {
        if (EqualSid(pSid, pTokenGroups->Groups[i].Sid))
        {
            bSidFound = TRUE;
            break;
        }
    }

    HeapFree(GetProcessHeap(), 0, pTokenGroups);
    FreeSid(pSid);

    return bSidFound;
}

/***********************************************************************
 *             NeedRebootInit  (ADVPACK.@)
 *
 * Sets up conditions for reboot checking.
 *
 * RETURNS
 *   Value required by NeedReboot.
 */
DWORD WINAPI NeedRebootInit(VOID)
{
    FIXME("(VOID): stub\n");
    return 0;
}

/***********************************************************************
 *             NeedReboot      (ADVPACK.@)
 *
 * Determines whether a reboot is required.
 *
 * PARAMS
 *   dwRebootCheck [I] Value from NeedRebootInit.
 *
 * RETURNS
 *   TRUE if a reboot is needed, FALSE otherwise.
 *
 * BUGS
 *   Unimplemented.
 */
BOOL WINAPI NeedReboot(DWORD dwRebootCheck)
{
    FIXME("(%d): stub\n", dwRebootCheck);
    return FALSE;
}

/***********************************************************************
 *             OpenINFEngineA   (ADVPACK.@)
 *
 * See OpenINFEngineW.
 */
HRESULT WINAPI OpenINFEngineA(LPCSTR pszInfFilename, LPCSTR pszInstallSection,
                              DWORD dwFlags, HINF *phInf, PVOID pvReserved)
{
    UNICODE_STRING filenameW, installW;
    HRESULT res;

    TRACE("(%s, %s, %d, %p, %p)\n", debugstr_a(pszInfFilename),
          debugstr_a(pszInstallSection), dwFlags, phInf, pvReserved);

    if (!pszInfFilename || !phInf)
        return E_INVALIDARG;

    RtlCreateUnicodeStringFromAsciiz(&filenameW, pszInfFilename);
    RtlCreateUnicodeStringFromAsciiz(&installW, pszInstallSection);

    res = OpenINFEngineW(filenameW.Buffer, installW.Buffer,
                         dwFlags, phInf, pvReserved);

    RtlFreeUnicodeString(&filenameW);
    RtlFreeUnicodeString(&installW);

    return res;
}

/***********************************************************************
 *             OpenINFEngineW   (ADVPACK.@)
 *
 * Opens and returns a handle to an INF file to be used by
 * TranslateInfStringEx to continuously translate the INF file.
 *
 * PARAMS
 *   pszInfFilename    [I] Filename of the INF to open.
 *   pszInstallSection [I] Name of the Install section in the INF.
 *   dwFlags           [I] See advpub.h.
 *   phInf             [O] Handle to the loaded INF file.
 *   pvReserved        [I] Reserved.  Must be NULL.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 */
HRESULT WINAPI OpenINFEngineW(LPCWSTR pszInfFilename, LPCWSTR pszInstallSection,
                              DWORD dwFlags, HINF *phInf, PVOID pvReserved)
{
    TRACE("(%s, %s, %d, %p, %p)\n", debugstr_w(pszInfFilename),
          debugstr_w(pszInstallSection), dwFlags, phInf, pvReserved);

    if (!pszInfFilename || !phInf)
        return E_INVALIDARG;

    *phInf = SetupOpenInfFileW(pszInfFilename, NULL, INF_STYLE_WIN4, NULL);
    if (*phInf == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

    set_ldids(*phInf, pszInstallSection, NULL);
    
    return S_OK;
}

/***********************************************************************
 *             RebootCheckOnInstallA   (ADVPACK.@)
 *
 * See RebootCheckOnInstallW.
 */
HRESULT WINAPI RebootCheckOnInstallA(HWND hWnd, LPCSTR pszINF,
                                     LPCSTR pszSec, DWORD dwReserved)
{
    UNICODE_STRING infW, secW;
    HRESULT res;

    TRACE("(%p, %s, %s, %d)\n", hWnd, debugstr_a(pszINF),
          debugstr_a(pszSec), dwReserved);

    if (!pszINF || !pszSec)
        return E_INVALIDARG;

    RtlCreateUnicodeStringFromAsciiz(&infW, pszINF);
    RtlCreateUnicodeStringFromAsciiz(&secW, pszSec);

    res = RebootCheckOnInstallW(hWnd, infW.Buffer, secW.Buffer, dwReserved);

    RtlFreeUnicodeString(&infW);
    RtlFreeUnicodeString(&secW);

    return res;
}

/***********************************************************************
 *             RebootCheckOnInstallW   (ADVPACK.@)
 *
 * Checks if a reboot is required for an installed INF section.
 *
 * PARAMS
 *   hWnd       [I] Handle to the window used for messages.
 *   pszINF     [I] Filename of the INF file.
 *   pszSec     [I] INF section to check.
 *   dwReserved [I] Reserved.  Must be 0.
 *
 * RETURNS
 *   Success: S_OK - Reboot is needed if the INF section is installed.
 *            S_FALSE - Reboot is not needed.
 *   Failure: HRESULT of GetLastError().
 *
 * NOTES
 *   if pszSec is NULL, RebootCheckOnInstall checks the DefaultInstall
 *   or DefaultInstall.NT section.
 *
 * BUGS
 *   Unimplemented.
 */
HRESULT WINAPI RebootCheckOnInstallW(HWND hWnd, LPCWSTR pszINF,
                                     LPCWSTR pszSec, DWORD dwReserved)
{
    FIXME("(%p, %s, %s, %d): stub\n", hWnd, debugstr_w(pszINF),
          debugstr_w(pszSec), dwReserved);

    return E_FAIL;
}

/* registers the OCX if do_reg is TRUE, unregisters it otherwise */
HRESULT do_ocx_reg(HMODULE hocx, BOOL do_reg)
{
    DLLREGISTER reg_func;

    if (do_reg)
        reg_func = (DLLREGISTER)GetProcAddress(hocx, "DllRegisterServer");
    else
        reg_func = (DLLREGISTER)GetProcAddress(hocx, "DllUnregisterServer");

    if (!reg_func)
        return E_FAIL;

    reg_func();
    return S_OK;
}

/***********************************************************************
 *             RegisterOCX    (ADVPACK.@)
 *
 * Registers an OCX.
 *
 * PARAMS
 *   hWnd    [I] Handle to the window used for the display.
 *   hInst   [I] Instance of the process.
 *   cmdline [I] Contains parameters in the order OCX,flags,param.
 *   show    [I] How the window should be shown.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * NOTES
 *   OCX - Filename of the OCX to register.
 *   flags - Controls the operation of RegisterOCX.
 *    'I' Call DllRegisterServer and DllInstall.
 *    'N' Only call DllInstall.
 *   param - Command line passed to DllInstall.
 */
HRESULT WINAPI RegisterOCX(HWND hWnd, HINSTANCE hInst, LPCSTR cmdline, INT show)
{
    LPWSTR ocx_filename, str_flags, param;
    LPWSTR cmdline_copy, cmdline_ptr;
    UNICODE_STRING cmdlineW;
    HRESULT hr = E_FAIL;
    HMODULE hm = NULL;
    DWORD size;

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

    RtlCreateUnicodeStringFromAsciiz(&cmdlineW, cmdline);

    size = (lstrlenW(cmdlineW.Buffer) + 1) * sizeof(WCHAR);
    cmdline_copy = HeapAlloc(GetProcessHeap(), 0, size);
    cmdline_ptr = cmdline_copy;
    lstrcpyW(cmdline_copy, cmdlineW.Buffer);

    ocx_filename = get_parameter(&cmdline_ptr, ',');
    if (!ocx_filename || !*ocx_filename)
        goto done;

    str_flags = get_parameter(&cmdline_ptr, ',');
    param = get_parameter(&cmdline_ptr, ',');

    hm = LoadLibraryExW(ocx_filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    if (!hm)
        goto done;

    hr = do_ocx_reg(hm, TRUE);

done:
    FreeLibrary(hm);
    HeapFree(GetProcessHeap(), 0, cmdline_copy);
    RtlFreeUnicodeString(&cmdlineW);

    return hr;
}

/***********************************************************************
 *             SetPerUserSecValuesA   (ADVPACK.@)
 *
 * See SetPerUserSecValuesW.
 */
HRESULT WINAPI SetPerUserSecValuesA(PERUSERSECTIONA* pPerUser)
{
    PERUSERSECTIONW perUserW;

    TRACE("(%p)\n", pPerUser);

    if (!pPerUser)
        return E_INVALIDARG;

    MultiByteToWideChar(CP_ACP, 0, pPerUser->szGUID, -1, perUserW.szGUID,
                        sizeof(perUserW.szGUID) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, pPerUser->szDispName, -1, perUserW.szDispName,
                        sizeof(perUserW.szDispName) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, pPerUser->szLocale, -1, perUserW.szLocale,
                        sizeof(perUserW.szLocale) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, pPerUser->szStub, -1, perUserW.szStub,
                        sizeof(perUserW.szStub) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, pPerUser->szVersion, -1, perUserW.szVersion,
                        sizeof(perUserW.szVersion) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, pPerUser->szCompID, -1, perUserW.szCompID,
                        sizeof(perUserW.szCompID) / sizeof(WCHAR));
    perUserW.dwIsInstalled = pPerUser->dwIsInstalled;
    perUserW.bRollback = pPerUser->bRollback;

    return SetPerUserSecValuesW(&perUserW);
}

/***********************************************************************
 *             SetPerUserSecValuesW   (ADVPACK.@)
 *
 * Prepares the per-user stub values under IsInstalled\{GUID} that
 * control the per-user installation.
 *
 * PARAMS
 *   pPerUser [I] Per-user stub values.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 */
HRESULT WINAPI SetPerUserSecValuesW(PERUSERSECTIONW* pPerUser)
{
    HKEY setup, guid;

    static const WCHAR stub_path[] = {'S','t','u','b','P','a','t','h',0};
    static const WCHAR version[] = {'V','e','r','s','i','o','n',0};
    static const WCHAR locale[] = {'L','o','c','a','l','e',0};
    static const WCHAR compid[] = {'C','o','m','p','o','n','e','n','t','I','D',0};
    static const WCHAR isinstalled[] = {'I','s','I','n','s','t','a','l','l','e','d',0};

    TRACE("(%p)\n", pPerUser);

    if (!pPerUser || !*pPerUser->szGUID)
        return S_OK;

    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, setup_key, 0, NULL, 0, KEY_WRITE,
                        NULL, &setup, NULL))
    {
        return E_FAIL;
    }

    if (RegCreateKeyExW(setup, pPerUser->szGUID, 0, NULL, 0, KEY_ALL_ACCESS,
                        NULL, &guid, NULL))
    {
        RegCloseKey(setup);
        return E_FAIL;
    }

    if (*pPerUser->szStub)
    {
        RegSetValueExW(guid, stub_path, 0, REG_SZ, (LPBYTE)pPerUser->szStub,
                       (lstrlenW(pPerUser->szStub) + 1) * sizeof(WCHAR));
    }

    if (*pPerUser->szVersion)
    {
        RegSetValueExW(guid, version, 0, REG_SZ, (LPBYTE)pPerUser->szVersion,
                       (lstrlenW(pPerUser->szVersion) + 1) * sizeof(WCHAR));
    }

    if (*pPerUser->szLocale)
    {
        RegSetValueExW(guid, locale, 0, REG_SZ, (LPBYTE)pPerUser->szLocale,
                       (lstrlenW(pPerUser->szLocale) + 1) * sizeof(WCHAR));
    }

    if (*pPerUser->szCompID)
    {
        RegSetValueExW(guid, compid, 0, REG_SZ, (LPBYTE)pPerUser->szCompID,
                       (lstrlenW(pPerUser->szCompID) + 1) * sizeof(WCHAR));
    }

    if (*pPerUser->szDispName)
    {
        RegSetValueExW(guid, NULL, 0, REG_SZ, (LPBYTE)pPerUser->szDispName,
                       (lstrlenW(pPerUser->szDispName) + 1) * sizeof(WCHAR));
    }

    RegSetValueExW(guid, isinstalled, 0, REG_DWORD,
                   (LPBYTE)&pPerUser->dwIsInstalled, sizeof(DWORD));

    RegCloseKey(guid);
    RegCloseKey(setup);

    return S_OK;
}

/***********************************************************************
 *             TranslateInfStringA   (ADVPACK.@)
 *
 * See TranslateInfStringW.
 */
HRESULT WINAPI TranslateInfStringA(LPCSTR pszInfFilename, LPCSTR pszInstallSection,
                LPCSTR pszTranslateSection, LPCSTR pszTranslateKey, LPSTR pszBuffer,
                DWORD dwBufferSize, PDWORD pdwRequiredSize, PVOID pvReserved)
{
    UNICODE_STRING filenameW, installW;
    UNICODE_STRING translateW, keyW;
    LPWSTR bufferW;
    HRESULT res;
    DWORD len = 0;

    TRACE("(%s, %s, %s, %s, %p, %d, %p, %p)\n",
          debugstr_a(pszInfFilename), debugstr_a(pszInstallSection),
          debugstr_a(pszTranslateSection), debugstr_a(pszTranslateKey),
          pszBuffer, dwBufferSize,pdwRequiredSize, pvReserved);

    if (!pszInfFilename || !pszTranslateSection ||
        !pszTranslateKey || !pdwRequiredSize)
        return E_INVALIDARG;

    RtlCreateUnicodeStringFromAsciiz(&filenameW, pszInfFilename);
    RtlCreateUnicodeStringFromAsciiz(&installW, pszInstallSection);
    RtlCreateUnicodeStringFromAsciiz(&translateW, pszTranslateSection);
    RtlCreateUnicodeStringFromAsciiz(&keyW, pszTranslateKey);

    res = TranslateInfStringW(filenameW.Buffer, installW.Buffer,
                              translateW.Buffer, keyW.Buffer, NULL,
                              dwBufferSize, &len, NULL);

    if (res == S_OK)
    {
        bufferW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));

        res = TranslateInfStringW(filenameW.Buffer, installW.Buffer,
                                  translateW.Buffer, keyW.Buffer, bufferW,
                                  len, &len, NULL);
        if (res == S_OK)
        {
            *pdwRequiredSize = WideCharToMultiByte(CP_ACP, 0, bufferW, -1,
                                                   NULL, 0, NULL, NULL);

            if (dwBufferSize >= *pdwRequiredSize)
            {
                WideCharToMultiByte(CP_ACP, 0, bufferW, -1, pszBuffer,
                                    dwBufferSize, NULL, NULL);
            }
            else
                res = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
        }
        
        HeapFree(GetProcessHeap(), 0, bufferW);
    }

    RtlFreeUnicodeString(&filenameW);
    RtlFreeUnicodeString(&installW);
    RtlFreeUnicodeString(&translateW);
    RtlFreeUnicodeString(&keyW);

    return res;
}

/***********************************************************************
 *             TranslateInfStringW   (ADVPACK.@)
 *
 * Translates the value of a specified key in an inf file into the
 * current locale by expanding string macros.
 *
 * PARAMS
 *   pszInfFilename      [I] Filename of the inf file.
 *   pszInstallSection   [I]
 *   pszTranslateSection [I] Inf section where the key exists.
 *   pszTranslateKey     [I] Key to translate.
 *   pszBuffer           [O] Contains the translated string on exit.
 *   dwBufferSize        [I] Size on input of pszBuffer.
 *   pdwRequiredSize     [O] Length of the translated key.
 *   pvReserved          [I] Reserved, must be NULL.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: An hresult error code.
 */
HRESULT WINAPI TranslateInfStringW(LPCWSTR pszInfFilename, LPCWSTR pszInstallSection,
                LPCWSTR pszTranslateSection, LPCWSTR pszTranslateKey, LPWSTR pszBuffer,
                DWORD dwBufferSize, PDWORD pdwRequiredSize, PVOID pvReserved)
{
    HINF hInf;
    HRESULT hret = S_OK;

    TRACE("(%s, %s, %s, %s, %p, %d, %p, %p)\n",
          debugstr_w(pszInfFilename), debugstr_w(pszInstallSection),
          debugstr_w(pszTranslateSection), debugstr_w(pszTranslateKey),
          pszBuffer, dwBufferSize,pdwRequiredSize, pvReserved);

    if (!pszInfFilename || !pszTranslateSection ||
        !pszTranslateKey || !pdwRequiredSize)
        return E_INVALIDARG;

    hInf = SetupOpenInfFileW(pszInfFilename, NULL, INF_STYLE_WIN4, NULL);
    if (hInf == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

    set_ldids(hInf, pszInstallSection, NULL);

    if (!SetupGetLineTextW(NULL, hInf, pszTranslateSection, pszTranslateKey,
                           pszBuffer, dwBufferSize, pdwRequiredSize))
    {
        if (dwBufferSize < *pdwRequiredSize)
            hret = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
        else
            hret = SPAPI_E_LINE_NOT_FOUND;
    }

    SetupCloseInfFile(hInf);
    return hret;
}

/***********************************************************************
 *             TranslateInfStringExA   (ADVPACK.@)
 *
 * See TranslateInfStringExW.
 */
HRESULT WINAPI TranslateInfStringExA(HINF hInf, LPCSTR pszInfFilename,
                                    LPCSTR pszTranslateSection, LPCSTR pszTranslateKey,
                                    LPSTR pszBuffer, DWORD dwBufferSize,
                                    PDWORD pdwRequiredSize, PVOID pvReserved)
{
    UNICODE_STRING filenameW, sectionW, keyW;
    LPWSTR bufferW;
    HRESULT res;
    DWORD len = 0;

    TRACE("(%p, %s, %s, %s, %s, %d, %p, %p)\n", hInf, debugstr_a(pszInfFilename),
          debugstr_a(pszTranslateSection), debugstr_a(pszTranslateKey),
          debugstr_a(pszBuffer), dwBufferSize, pdwRequiredSize, pvReserved);

    if (!pszInfFilename || !pszTranslateSection ||
        !pszTranslateKey || !pdwRequiredSize)
        return E_INVALIDARG;

    RtlCreateUnicodeStringFromAsciiz(&filenameW, pszInfFilename);
    RtlCreateUnicodeStringFromAsciiz(&sectionW, pszTranslateSection);
    RtlCreateUnicodeStringFromAsciiz(&keyW, pszTranslateKey);

    res = TranslateInfStringExW(hInf, filenameW.Buffer, sectionW.Buffer,
                                keyW.Buffer, NULL, 0, &len, NULL);

    if (res == S_OK)
    {
        bufferW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));

        res = TranslateInfStringExW(hInf, filenameW.Buffer, sectionW.Buffer,
                                keyW.Buffer, bufferW, len, &len, NULL);

        if (res == S_OK)
        {
            *pdwRequiredSize = WideCharToMultiByte(CP_ACP, 0, bufferW, -1,
                                                   NULL, 0, NULL, NULL);

            if (dwBufferSize >= *pdwRequiredSize)
            {
                WideCharToMultiByte(CP_ACP, 0, bufferW, -1, pszBuffer,
                                    dwBufferSize, NULL, NULL);
            }
            else
                res = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
        }
        
        HeapFree(GetProcessHeap(), 0, bufferW);
    }

    RtlFreeUnicodeString(&filenameW);
    RtlFreeUnicodeString(&sectionW);
    RtlFreeUnicodeString(&keyW);

    return res;
}

/***********************************************************************
 *             TranslateInfStringExW   (ADVPACK.@)
 *
 * Using a handle to an INF file opened with OpenINFEngine, translates
 * the value of a specified key in an inf file into the current locale
 * by expanding string macros.
 *
 * PARAMS
 *   hInf                [I] Handle to the INF file.
 *   pszInfFilename      [I] Filename of the INF file.
 *   pszTranslateSection [I] Inf section where the key exists.
 *   pszTranslateKey     [I] Key to translate.
 *   pszBuffer           [O] Contains the translated string on exit.
 *   dwBufferSize        [I] Size on input of pszBuffer.
 *   pdwRequiredSize     [O] Length of the translated key.
 *   pvReserved          [I] Reserved.  Must be NULL.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * NOTES
 *   To use TranslateInfStringEx to translate an INF file continuously,
 *   open the INF file with OpenINFEngine, call TranslateInfStringEx as
 *   many times as needed, then release the handle with CloseINFEngine.
 *   When translating more than one keys, this method is more efficient
 *   than calling TranslateInfString, because the INF file is only
 *   opened once.
 */
HRESULT WINAPI TranslateInfStringExW(HINF hInf, LPCWSTR pszInfFilename,
                                     LPCWSTR pszTranslateSection, LPCWSTR pszTranslateKey,
                                     LPWSTR pszBuffer, DWORD dwBufferSize,
                                     PDWORD pdwRequiredSize, PVOID pvReserved)
{
    TRACE("(%p, %s, %s, %s, %s, %d, %p, %p)\n", hInf, debugstr_w(pszInfFilename),
          debugstr_w(pszTranslateSection), debugstr_w(pszTranslateKey),
          debugstr_w(pszBuffer), dwBufferSize, pdwRequiredSize, pvReserved);

    if (!hInf || !pszInfFilename || !pszTranslateSection || !pszTranslateKey)
        return E_INVALIDARG;

    if (!SetupGetLineTextW(NULL, hInf, pszTranslateSection, pszTranslateKey,
                           pszBuffer, dwBufferSize, pdwRequiredSize))
    {
        if (dwBufferSize < *pdwRequiredSize)
            return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);

        return SPAPI_E_LINE_NOT_FOUND;
    }

    return S_OK;   
}

/***********************************************************************
 *             UserInstStubWrapperA   (ADVPACK.@)
 *
 * See UserInstStubWrapperW.
 */
HRESULT WINAPI UserInstStubWrapperA(HWND hWnd, HINSTANCE hInstance,
                                   LPSTR pszParms, INT nShow)
{
    UNICODE_STRING parmsW;
    HRESULT res;

    TRACE("(%p, %p, %s, %i)\n", hWnd, hInstance, debugstr_a(pszParms), nShow);

    if (!pszParms)
        return E_INVALIDARG;

    RtlCreateUnicodeStringFromAsciiz(&parmsW, pszParms);

    res = UserInstStubWrapperW(hWnd, hInstance, parmsW.Buffer, nShow);

    RtlFreeUnicodeString(&parmsW);

    return res;
}

/***********************************************************************
 *             UserInstStubWrapperW   (ADVPACK.@)
 *
 * Launches the user stub wrapper specified by the RealStubPath
 * registry value under Installed Components\szParms.
 *
 * PARAMS
 *   hWnd      [I] Handle to the window used for the display.
 *   hInstance [I] Instance of the process.
 *   szParms   [I] The GUID of the installation.
 *   show      [I] How the window should be shown.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * TODO
 *   If the type of the StubRealPath value is REG_EXPAND_SZ, then
 *   we should call ExpandEnvironmentStrings on the value and
 *   launch the result.
 */
HRESULT WINAPI UserInstStubWrapperW(HWND hWnd, HINSTANCE hInstance,
                                    LPWSTR pszParms, INT nShow)
{
    HKEY setup, guid;
    WCHAR stub[MAX_PATH];
    DWORD size = MAX_PATH;
    HRESULT hr = S_OK;
    BOOL res;

    static const WCHAR real_stub_path[] = {
        'R','e','a','l','S','t','u','b','P','a','t','h',0
    };

    TRACE("(%p, %p, %s, %i)\n", hWnd, hInstance, debugstr_w(pszParms), nShow);

    if (!pszParms || !*pszParms)
        return E_INVALIDARG;

    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, setup_key, 0, KEY_READ, &setup))
    {
        return E_FAIL;
    }

    if (RegOpenKeyExW(setup, pszParms, 0, KEY_READ, &guid))
    {
        RegCloseKey(setup);
        return E_FAIL;
    }

    res = RegQueryValueExW(guid, real_stub_path, NULL, NULL, (LPBYTE)stub, &size);
    if (res || !*stub)
        goto done;

    /* launch the user stub wrapper */
    hr = launch_exe(stub, NULL, NULL);

done:
    RegCloseKey(setup);
    RegCloseKey(guid);

    return hr;
}

/***********************************************************************
 *             UserUnInstStubWrapperA   (ADVPACK.@)
 *
 * See UserUnInstStubWrapperW.
 */
HRESULT WINAPI UserUnInstStubWrapperA(HWND hWnd, HINSTANCE hInstance,
                                      LPSTR pszParms, INT nShow)
{
    UNICODE_STRING parmsW;
    HRESULT res;

    TRACE("(%p, %p, %s, %i)\n", hWnd, hInstance, debugstr_a(pszParms), nShow);

    if (!pszParms)
        return E_INVALIDARG;

    RtlCreateUnicodeStringFromAsciiz(&parmsW, pszParms);

    res = UserUnInstStubWrapperW(hWnd, hInstance, parmsW.Buffer, nShow);

    RtlFreeUnicodeString(&parmsW);

    return res;
}

/***********************************************************************
 *             UserUnInstStubWrapperW   (ADVPACK.@)
 */
HRESULT WINAPI UserUnInstStubWrapperW(HWND hWnd, HINSTANCE hInstance,
                                      LPWSTR pszParms, INT nShow)
{
    FIXME("(%p, %p, %s, %i): stub\n", hWnd, hInstance, debugstr_w(pszParms), nShow);

    return E_FAIL;
}
