/*
 * Advpack file functions
 *
 * Copyright 2006 James Hawkins
 *
 * 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 <stdlib.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "winver.h"
#include "winternl.h"
#include "setupapi.h"
#include "advpub.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "advpack_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(advpack);

/* converts an ansi double null-terminated list to a unicode list */
static LPWSTR ansi_to_unicode_list(LPCSTR ansi_list)
{
    DWORD len, wlen = 0;
    LPWSTR list;
    LPCSTR ptr = ansi_list;

    while (*ptr) ptr += lstrlenA(ptr) + 1;
    len = ptr + 1 - ansi_list;
    wlen = MultiByteToWideChar(CP_ACP, 0, ansi_list, len, NULL, 0);
    list = HeapAlloc(GetProcessHeap(), 0, wlen * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, ansi_list, len, list, wlen);
    return list;
}

/***********************************************************************
 *      AddDelBackupEntryA (ADVPACK.@)
 *
 * See AddDelBackupEntryW.
 */
HRESULT WINAPI AddDelBackupEntryA(LPCSTR lpcszFileList, LPCSTR lpcszBackupDir,
                                  LPCSTR lpcszBaseName, DWORD dwFlags)
{
    UNICODE_STRING backupdir, basename;
    LPWSTR filelist, backup;
    HRESULT res;

    TRACE("(%s, %s, %s, %ld)\n", debugstr_a(lpcszFileList),
          debugstr_a(lpcszBackupDir), debugstr_a(lpcszBaseName), dwFlags);

    if (lpcszFileList)
        filelist = ansi_to_unicode_list(lpcszFileList);
    else
        filelist = NULL;

    RtlCreateUnicodeStringFromAsciiz(&backupdir, lpcszBackupDir);
    RtlCreateUnicodeStringFromAsciiz(&basename, lpcszBaseName);

    if (lpcszBackupDir)
        backup = backupdir.Buffer;
    else
        backup = NULL;

    res = AddDelBackupEntryW(filelist, backup, basename.Buffer, dwFlags);

    HeapFree(GetProcessHeap(), 0, filelist);

    RtlFreeUnicodeString(&backupdir);
    RtlFreeUnicodeString(&basename);

    return res;
}

/***********************************************************************
 *      AddDelBackupEntryW (ADVPACK.@)
 *
 * Either appends the files in the file list to the backup section of
 * the specified INI, or deletes the entries from the INI file.
 *
 * PARAMS
 *   lpcszFileList  [I] NULL-separated list of filenames.
 *   lpcszBackupDir [I] Path of the backup directory.
 *   lpcszBaseName  [I] Basename of the INI file.
 *   dwFlags        [I] AADBE_ADD_ENTRY adds the entries in the file list
 *                      to the INI file, while AADBE_DEL_ENTRY removes
 *                      the entries from the INI file.
 *
 * RETURNS
 *   S_OK in all cases.
 *
 * NOTES
 *   If the INI file does not exist before adding entries to it, the file
 *   will be created.
 * 
 *   If lpcszBackupDir is NULL, the INI file is assumed to exist in
 *   c:\windows or created there if it does not exist.
 */
HRESULT WINAPI AddDelBackupEntryW(LPCWSTR lpcszFileList, LPCWSTR lpcszBackupDir,
                                  LPCWSTR lpcszBaseName, DWORD dwFlags)
{
    WCHAR szIniPath[MAX_PATH];
    LPWSTR szString = NULL;

    static const WCHAR szBackupEntry[] = {
        '-','1',',','0',',','0',',','0',',','0',',','0',',','-','1',0
    };
    
    static const WCHAR backslash[] = {'\\',0};
    static const WCHAR ini[] = {'.','i','n','i',0};
    static const WCHAR backup[] = {'b','a','c','k','u','p',0};

    TRACE("(%s, %s, %s, %ld)\n", debugstr_w(lpcszFileList),
          debugstr_w(lpcszBackupDir), debugstr_w(lpcszBaseName), dwFlags);

    if (!lpcszFileList || !*lpcszFileList)
        return S_OK;

    if (lpcszBackupDir)
        lstrcpyW(szIniPath, lpcszBackupDir);
    else
        GetWindowsDirectoryW(szIniPath, MAX_PATH);

    lstrcatW(szIniPath, backslash);
    lstrcatW(szIniPath, lpcszBaseName);
    lstrcatW(szIniPath, ini);

    SetFileAttributesW(szIniPath, FILE_ATTRIBUTE_NORMAL);

    if (dwFlags & AADBE_ADD_ENTRY)
        szString = (LPWSTR)szBackupEntry;
    else if (dwFlags & AADBE_DEL_ENTRY)
        szString = NULL;

    /* add or delete the INI entries */
    while (*lpcszFileList)
    {
        WritePrivateProfileStringW(backup, lpcszFileList, szString, szIniPath);
        lpcszFileList += lstrlenW(lpcszFileList) + 1;
    }

    /* hide the INI file */
    SetFileAttributesW(szIniPath, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN);

    return S_OK;
}

/* FIXME: this is only for the local case, X:\ */
#define ROOT_LENGTH 3

UINT CALLBACK pQuietQueueCallback(PVOID Context, UINT Notification,
                                  UINT_PTR Param1, UINT_PTR Param2)
{
    return 1;
}

UINT CALLBACK pQueueCallback(PVOID Context, UINT Notification,
                             UINT_PTR Param1, UINT_PTR Param2)
{
    /* only be verbose for error notifications */
    if (!Notification ||
        Notification == SPFILENOTIFY_RENAMEERROR ||
        Notification == SPFILENOTIFY_DELETEERROR ||
        Notification == SPFILENOTIFY_COPYERROR)
    {
        return SetupDefaultQueueCallbackW(Context, Notification,
                                          Param1, Param2);
    }

    return 1;
}

/***********************************************************************
 *      AdvInstallFileA (ADVPACK.@)
 *
 * See AdvInstallFileW.
 */
HRESULT WINAPI AdvInstallFileA(HWND hwnd, LPCSTR lpszSourceDir, LPCSTR lpszSourceFile,
                               LPCSTR lpszDestDir, LPCSTR lpszDestFile,
                               DWORD dwFlags, DWORD dwReserved)
{
    UNICODE_STRING sourcedir, sourcefile;
    UNICODE_STRING destdir, destfile;
    HRESULT res;

    TRACE("(%p, %s, %s, %s, %s, %ld, %ld)\n", hwnd, debugstr_a(lpszSourceDir),
          debugstr_a(lpszSourceFile), debugstr_a(lpszDestDir),
          debugstr_a(lpszDestFile), dwFlags, dwReserved);

    if (!lpszSourceDir || !lpszSourceFile || !lpszDestDir)
        return E_INVALIDARG;

    RtlCreateUnicodeStringFromAsciiz(&sourcedir, lpszSourceDir);
    RtlCreateUnicodeStringFromAsciiz(&sourcefile, lpszSourceFile);
    RtlCreateUnicodeStringFromAsciiz(&destdir, lpszDestDir);
    RtlCreateUnicodeStringFromAsciiz(&destfile, lpszDestFile);

    res = AdvInstallFileW(hwnd, sourcedir.Buffer, sourcefile.Buffer,
                          destdir.Buffer, destfile.Buffer, dwFlags, dwReserved);

    RtlFreeUnicodeString(&sourcedir);
    RtlFreeUnicodeString(&sourcefile);
    RtlFreeUnicodeString(&destdir);
    RtlFreeUnicodeString(&destfile);

    return res;
}

/***********************************************************************
 *      AdvInstallFileW (ADVPACK.@)
 *
 * Copies a file from the source to a destination.
 *
 * PARAMS
 *   hwnd           [I] Handle to the window used for messages.
 *   lpszSourceDir  [I] Source directory.
 *   lpszSourceFile [I] Source filename.
 *   lpszDestDir    [I] Destination directory.
 *   lpszDestFile   [I] Optional destination filename.
 *   dwFlags        [I] See advpub.h.
 *   dwReserved     [I] Reserved.  Must be 0.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * NOTES
 *   If lpszDestFile is NULL, the destination filename is the same as
 *   lpszSourceFIle.
 */
HRESULT WINAPI AdvInstallFileW(HWND hwnd, LPCWSTR lpszSourceDir, LPCWSTR lpszSourceFile,
                               LPCWSTR lpszDestDir, LPCWSTR lpszDestFile,
                               DWORD dwFlags, DWORD dwReserved)
{
    PSP_FILE_CALLBACK_W pFileCallback;
    LPWSTR szPath, szDestFilename;
    WCHAR szRootPath[ROOT_LENGTH];
    DWORD dwLen, dwLastError;
    HSPFILEQ fileQueue;
    PVOID pContext;

    TRACE("(%p, %s, %s, %s, %s, %ld, %ld)\n", hwnd, debugstr_w(lpszSourceDir),
          debugstr_w(lpszSourceFile), debugstr_w(lpszDestDir),
          debugstr_w(lpszDestFile), dwFlags, dwReserved);

    if (!lpszSourceDir || !lpszSourceFile || !lpszDestDir)
        return E_INVALIDARG;
        
    fileQueue = SetupOpenFileQueue();
    if (fileQueue == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(GetLastError());

    pContext = NULL;
    dwLastError = ERROR_SUCCESS;

    lstrcpynW(szRootPath, lpszSourceDir, ROOT_LENGTH);
    szPath = (LPWSTR)lpszSourceDir + ROOT_LENGTH;

    /* use lpszSourceFile as destination filename if lpszDestFile is NULL */
    if (lpszDestFile)
    {
        dwLen = lstrlenW(lpszDestFile);
        szDestFilename = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
        lstrcpyW(szDestFilename, lpszDestFile);
    }
    else
    {
        dwLen = lstrlenW(lpszSourceFile);
        szDestFilename = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
        lstrcpyW(szDestFilename, lpszSourceFile);
    }

    /* add the file copy operation to the setup queue */
    if (!SetupQueueCopyW(fileQueue, szRootPath, szPath, lpszSourceFile, NULL,
                         NULL, lpszDestDir, szDestFilename, dwFlags))
    {
        dwLastError = GetLastError();
        goto done;
    }

    pContext = SetupInitDefaultQueueCallbackEx(hwnd, INVALID_HANDLE_VALUE,
                                               0, 0, NULL);
    if (!pContext)
    {
        dwLastError = GetLastError();
        goto done;
    }

    /* don't output anything for AIF_QUIET */
    if (dwFlags & AIF_QUIET)
        pFileCallback = pQuietQueueCallback;
    else
        pFileCallback = pQueueCallback;

    /* perform the file copy */
    if (!SetupCommitFileQueueW(hwnd, fileQueue, pFileCallback, pContext))
    {
        dwLastError = GetLastError();
        goto done;
    }

done:
    SetupTermDefaultQueueCallback(pContext);
    SetupCloseFileQueue(fileQueue);
    
    HeapFree(GetProcessHeap(), 0, szDestFilename);
    
    return HRESULT_FROM_WIN32(dwLastError);
}

static HRESULT DELNODE_recurse_dirtree(LPWSTR fname, DWORD flags)
{
    DWORD fattrs = GetFileAttributesW(fname);
    HRESULT ret = E_FAIL;

    static const WCHAR backslash[] = {'\\',0};
    static const WCHAR asterisk[] = {'*',0};
    static const WCHAR dot[] = {'.',0};
    static const WCHAR dotdot[] = {'.','.',0};

    if (fattrs & FILE_ATTRIBUTE_DIRECTORY)
    {
        HANDLE hFindFile;
        WIN32_FIND_DATAW w32fd;
        BOOL done = TRUE;
        int fname_len = lstrlenW(fname);

        /* Generate a path with wildcard suitable for iterating */
        if (lstrcmpW(CharPrevW(fname, fname + fname_len), backslash))
        {
            lstrcpyW(fname + fname_len, backslash);
            ++fname_len;
        }
        lstrcpyW(fname + fname_len, asterisk);

        if ((hFindFile = FindFirstFileW(fname, &w32fd)) != INVALID_HANDLE_VALUE)
        {
            /* Iterate through the files in the directory */
            for (done = FALSE; !done; done = !FindNextFileW(hFindFile, &w32fd))
            {
                TRACE("%s\n", debugstr_w(w32fd.cFileName));
                if (lstrcmpW(dot, w32fd.cFileName) != 0 &&
                    lstrcmpW(dotdot, w32fd.cFileName) != 0)
                {
                    lstrcpyW(fname + fname_len, w32fd.cFileName);
                    if (DELNODE_recurse_dirtree(fname, flags) != S_OK)
                    {
                        break; /* Failure */
                    }
                }
            }
            FindClose(hFindFile);
        }

        /* We're done with this directory, so restore the old path without wildcard */
        *(fname + fname_len) = '\0';

        if (done)
        {
            TRACE("%s: directory\n", debugstr_w(fname));
            if (SetFileAttributesW(fname, FILE_ATTRIBUTE_NORMAL) && RemoveDirectoryW(fname))
            {
                ret = S_OK;
            }
        }
    }
    else
    {
        TRACE("%s: file\n", debugstr_w(fname));
        if (SetFileAttributesW(fname, FILE_ATTRIBUTE_NORMAL) && DeleteFileW(fname))
        {
            ret = S_OK;
        }
    }
    
    return ret;
}

/***********************************************************************
 *              DelNodeA   (ADVPACK.@)
 *
 * See DelNodeW.
 */
HRESULT WINAPI DelNodeA(LPCSTR pszFileOrDirName, DWORD dwFlags)
{
    UNICODE_STRING fileordirname;
    HRESULT res;

    TRACE("(%s, %ld)\n", debugstr_a(pszFileOrDirName), dwFlags);

    RtlCreateUnicodeStringFromAsciiz(&fileordirname, pszFileOrDirName);

    res = DelNodeW(fileordirname.Buffer, dwFlags);

    RtlFreeUnicodeString(&fileordirname);

    return res;
}

/***********************************************************************
 *              DelNodeW   (ADVPACK.@)
 *
 * Deletes a file or directory
 *
 * PARAMS
 *   pszFileOrDirName   [I] Name of file or directory to delete
 *   dwFlags            [I] Flags; see include/advpub.h
 *
 * RETURNS 
 *   Success: S_OK
 *   Failure: E_FAIL
 *
 * BUGS
 *   - Ignores flags
 *   - Native version apparently does a lot of checking to make sure
 *     we're not trying to delete a system directory etc.
 */
HRESULT WINAPI DelNodeW(LPCWSTR pszFileOrDirName, DWORD dwFlags)
{
    WCHAR fname[MAX_PATH];
    HRESULT ret = E_FAIL;
    
    TRACE("(%s, %ld)\n", debugstr_w(pszFileOrDirName), dwFlags);
    
    if (dwFlags)
        FIXME("Flags ignored!\n");

    if (pszFileOrDirName && *pszFileOrDirName)
    {
        lstrcpyW(fname, pszFileOrDirName);

        /* TODO: Should check for system directory deletion etc. here */

        ret = DELNODE_recurse_dirtree(fname, dwFlags);
    }

    return ret;
}

/***********************************************************************
 *             DelNodeRunDLL32A   (ADVPACK.@)
 *
 * See DelNodeRunDLL32W.
 */
HRESULT WINAPI DelNodeRunDLL32A(HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show)
{
    UNICODE_STRING params;
    HRESULT hr;

    TRACE("(%p, %p, %s, %i)\n", hWnd, hInst, debugstr_a(cmdline), show);

    RtlCreateUnicodeStringFromAsciiz(&params, cmdline);

    hr = DelNodeRunDLL32W(hWnd, hInst, params.Buffer, show);

    RtlFreeUnicodeString(&params);

    return hr;
}

/***********************************************************************
 *             DelNodeRunDLL32W   (ADVPACK.@)
 *
 * Deletes a file or directory, WinMain style.
 *
 * PARAMS
 *   hWnd    [I] Handle to the window used for the display.
 *   hInst   [I] Instance of the process.
 *   cmdline [I] Contains parameters in the order FileOrDirName,Flags.
 *   show    [I] How the window should be shown.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 */
HRESULT WINAPI DelNodeRunDLL32W(HWND hWnd, HINSTANCE hInst, LPWSTR cmdline, INT show)
{
    LPWSTR szFilename, szFlags;
    LPWSTR cmdline_copy, cmdline_ptr;
    DWORD dwFlags = 0;
    HRESULT res;

    TRACE("(%p, %p, %s, %i)\n", hWnd, hInst, debugstr_w(cmdline), show);

    cmdline_copy = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(cmdline) + 1) * sizeof(WCHAR));
    cmdline_ptr = cmdline_copy;
    lstrcpyW(cmdline_copy, cmdline);

    /* get the parameters at indexes 0 and 1 respectively */
    szFilename = get_parameter(&cmdline_ptr, ',');
    szFlags = get_parameter(&cmdline_ptr, ',');

    if (szFlags)
        dwFlags = atolW(szFlags);

    res = DelNodeW(szFilename, dwFlags);

    HeapFree(GetProcessHeap(), 0, cmdline_copy);

    return res;
}

/* The following defintions were copied from dlls/cabinet/cabinet.h */

/* EXTRACTdest flags */
#define EXTRACT_FILLFILELIST  0x00000001
#define EXTRACT_EXTRACTFILES  0x00000002

struct ExtractFileList {
        LPSTR  filename;
        struct ExtractFileList *next;
        BOOL   unknown;  /* always 1L */
} ;

/* the first parameter of the function Extract */
typedef struct {
        long  result1;          /* 0x000 */
        long  unknown1[3];      /* 0x004 */
        struct ExtractFileList *filelist; /* 0x010 */
        long  filecount;        /* 0x014 */
        DWORD flags;            /* 0x018 */
        char  directory[0x104]; /* 0x01c */
        char  lastfile[0x20c];  /* 0x120 */
} EXTRACTdest;

static HRESULT (WINAPI *pExtract)(EXTRACTdest*, LPCSTR);

/* removes legal characters before and after file list, and
 * converts the file list to a NULL-separated list
 */
static LPSTR convert_file_list(LPCSTR FileList, DWORD *dwNumFiles)
{
    DWORD dwLen;
    char *first = (char *)FileList;
    char *last = (char *)FileList + strlen(FileList) - 1;
    LPSTR szConvertedList, temp;
    
    /* any number of these chars before the list is OK */
    while (first < last && (*first == ' ' || *first == '\t' || *first == ':'))
        first++;

    /* any number of these chars after the list is OK */
    while (last > first && (*last == ' ' || *last == '\t' || *last == ':'))
        last--;

    if (first == last)
        return NULL;

    dwLen = last - first + 3; /* room for double-null termination */
    szConvertedList = HeapAlloc(GetProcessHeap(), 0, dwLen);
    lstrcpynA(szConvertedList, first, dwLen - 1);

    szConvertedList[dwLen - 1] = '\0';
    szConvertedList[dwLen] = '\0';

    /* empty list */
    if (!lstrlenA(szConvertedList))
        return NULL;
        
    *dwNumFiles = 1;

    /* convert the colons to double-null termination */
    temp = szConvertedList;
    while (*temp)
    {
        if (*temp == ':')
        {
            *temp = '\0';
            (*dwNumFiles)++;
        }

        temp++;
    }

    return szConvertedList;
}

static void free_file_node(struct ExtractFileList *pNode)
{
    HeapFree(GetProcessHeap(), 0, pNode->filename);
    HeapFree(GetProcessHeap(), 0, pNode);
}

/* determines whether szFile is in the NULL-separated szFileList */
static BOOL file_in_list(LPSTR szFile, LPSTR szFileList)
{
    DWORD dwLen = lstrlenA(szFile);
    DWORD dwTestLen;

    while (*szFileList)
    {
        dwTestLen = lstrlenA(szFileList);

        if (dwTestLen == dwLen)
        {
            if (!lstrcmpiA(szFile, szFileList))
                return TRUE;
        }

        szFileList += dwTestLen + 1;
    }

    return FALSE;
}

/* removes nodes from the linked list that aren't specified in szFileList
 * returns the number of files that are in both the linked list and szFileList
 */
static DWORD fill_file_list(EXTRACTdest *extractDest, LPCSTR szCabName, LPSTR szFileList)
{
    DWORD dwNumFound = 0;
    struct ExtractFileList *pNode;
    struct ExtractFileList *prev = NULL;

    extractDest->flags |= EXTRACT_FILLFILELIST;
    if (pExtract(extractDest, szCabName))
    {
        extractDest->flags &= ~EXTRACT_FILLFILELIST;
        return -1;
    }

    pNode = extractDest->filelist;
    while (pNode)
    {
        if (file_in_list(pNode->filename, szFileList))
        {
            prev = pNode;
            pNode = pNode->next;
            dwNumFound++;
        }
        else if (prev)
        {
            prev->next = pNode->next;
            free_file_node(pNode);
            pNode = prev->next;
        }
        else
        {
            extractDest->filelist = pNode->next;
            free_file_node(pNode);
            pNode = extractDest->filelist;
        }
    }

    extractDest->flags &= ~EXTRACT_FILLFILELIST;
    return dwNumFound;
}

/***********************************************************************
 *             ExtractFilesA    (ADVPACK.@)
 *
 * Extracts the specified files from a cab archive into
 * a destination directory.
 *
 * PARAMS
 *   CabName   [I] Filename of the cab archive.
 *   ExpandDir [I] Destination directory for the extracted files.
 *   Flags     [I] Reserved.
 *   FileList  [I] Optional list of files to extract.  See NOTES.
 *   LReserved [I] Reserved.  Must be NULL.
 *   Reserved  [I] Reserved.  Must be 0.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * NOTES
 *   FileList is a colon-separated list of filenames.  If FileList is
 *   non-NULL, only the files in the list will be extracted from the
 *   cab file, otherwise all files will be extracted.  Any number of
 *   spaces, tabs, or colons can be before or after the list, but
 *   the list itself must only be separated by colons.
 */
HRESULT WINAPI ExtractFilesA(LPCSTR CabName, LPCSTR ExpandDir, DWORD Flags,
                             LPCSTR FileList, LPVOID LReserved, DWORD Reserved)
{   
    EXTRACTdest extractDest;
    HMODULE hCabinet;
    HRESULT res = S_OK;
    DWORD dwFileCount = 0;
    DWORD dwFilesFound = 0;
    LPSTR szConvertedList = NULL;

    TRACE("(%s, %s, %ld, %s, %p, %ld)\n", debugstr_a(CabName), debugstr_a(ExpandDir),
          Flags, debugstr_a(FileList), LReserved, Reserved);

    if (!CabName || !ExpandDir)
        return E_INVALIDARG;

    if (GetFileAttributesA(ExpandDir) == INVALID_FILE_ATTRIBUTES)
        return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);

    hCabinet = LoadLibraryA("cabinet.dll");
    if (!hCabinet)
        return E_FAIL;

    pExtract = (void *)GetProcAddress(hCabinet, "Extract");
    if (!pExtract)
    {
        res = E_FAIL;
        goto done;
    }

    ZeroMemory(&extractDest, sizeof(EXTRACTdest));
    lstrcpyA(extractDest.directory, ExpandDir);

    if (FileList)
    {
        szConvertedList = convert_file_list(FileList, &dwFileCount);
        if (!szConvertedList || dwFileCount == -1)
        {
            res = E_FAIL;
            goto done;
        }

        dwFilesFound = fill_file_list(&extractDest, CabName, szConvertedList);
        if (dwFilesFound != dwFileCount)
        {
            res = E_FAIL;
            goto done;
        }
    }
    else
        extractDest.flags |= EXTRACT_FILLFILELIST;

    extractDest.flags |= EXTRACT_EXTRACTFILES;
    res = pExtract(&extractDest, CabName);

done:
    FreeLibrary(hCabinet);
    HeapFree(GetProcessHeap(), 0, szConvertedList);

    return res;
}

/***********************************************************************
 *      FileSaveMarkNotExistA (ADVPACK.@)
 *
 * See FileSaveMarkNotExistW.
 */
HRESULT WINAPI FileSaveMarkNotExistA(LPSTR pszFileList, LPSTR pszDir, LPSTR pszBaseName)
{
    TRACE("(%s, %s, %s)\n", debugstr_a(pszFileList),
          debugstr_a(pszDir), debugstr_a(pszBaseName));

    return AddDelBackupEntryA(pszFileList, pszDir, pszBaseName, AADBE_DEL_ENTRY);
}

/***********************************************************************
 *      FileSaveMarkNotExistW (ADVPACK.@)
 *
 * Marks the files in the file list as not existing so they won't be
 * backed up during a save.
 *
 * PARAMS
 *   pszFileList [I] NULL-separated list of filenames.
 *   pszDir      [I] Path of the backup directory.
 *   pszBaseName [I] Basename of the INI file.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 */
HRESULT WINAPI FileSaveMarkNotExistW(LPWSTR pszFileList, LPWSTR pszDir, LPWSTR pszBaseName)
{
    TRACE("(%s, %s, %s)\n", debugstr_w(pszFileList),
          debugstr_w(pszDir), debugstr_w(pszBaseName));

    return AddDelBackupEntryW(pszFileList, pszDir, pszBaseName, AADBE_DEL_ENTRY);
}

/***********************************************************************
 *      FileSaveRestoreA (ADVPACK.@)
 *
 * See FileSaveRestoreW.
 */
HRESULT WINAPI FileSaveRestoreA(HWND hDlg, LPSTR pszFileList, LPSTR pszDir,
                                LPSTR pszBaseName, DWORD dwFlags)
{
    UNICODE_STRING filelist, dir, basename;
    HRESULT hr;

    TRACE("(%p, %s, %s, %s, %ld)\n", hDlg, debugstr_a(pszFileList),
          debugstr_a(pszDir), debugstr_a(pszBaseName), dwFlags);

    RtlCreateUnicodeStringFromAsciiz(&filelist, pszFileList);
    RtlCreateUnicodeStringFromAsciiz(&dir, pszDir);
    RtlCreateUnicodeStringFromAsciiz(&basename, pszBaseName);

    hr = FileSaveRestoreW(hDlg, filelist.Buffer, dir.Buffer,
                          basename.Buffer, dwFlags);

    RtlFreeUnicodeString(&filelist);
    RtlFreeUnicodeString(&dir);
    RtlFreeUnicodeString(&basename);

    return hr;
}                         

/***********************************************************************
 *      FileSaveRestoreW (ADVPACK.@)
 *
 * Saves or restores the files in the specified file list.
 *
 * PARAMS
 *   hDlg        [I] Handle to the dialog used for the display.
 *   pszFileList [I] NULL-separated list of filenames.
 *   pszDir      [I] Path of the backup directory.
 *   pszBaseName [I] Basename of the backup files.
 *   dwFlags     [I] See advpub.h.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * NOTES
 *   If pszFileList is NULL on restore, all files will be restored.
 *
 * BUGS
 *   Unimplemented.
 */
HRESULT WINAPI FileSaveRestoreW(HWND hDlg, LPWSTR pszFileList, LPWSTR pszDir,
                                LPWSTR pszBaseName, DWORD dwFlags)
{
    FIXME("(%p, %s, %s, %s, %ld) stub\n", hDlg, debugstr_w(pszFileList),
          debugstr_w(pszDir), debugstr_w(pszBaseName), dwFlags);

    return E_FAIL;
}

/***********************************************************************
 *      FileSaveRestoreOnINFA (ADVPACK.@)
 *
 * See FileSaveRestoreOnINFW.
 */
HRESULT WINAPI FileSaveRestoreOnINFA(HWND hWnd, LPCSTR pszTitle, LPCSTR pszINF,
                                    LPCSTR pszSection, LPCSTR pszBackupDir,
                                    LPCSTR pszBaseBackupFile, DWORD dwFlags)
{
    UNICODE_STRING title, inf, section;
    UNICODE_STRING backupdir, backupfile;
    HRESULT hr;

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

    RtlCreateUnicodeStringFromAsciiz(&title, pszTitle);
    RtlCreateUnicodeStringFromAsciiz(&inf, pszINF);
    RtlCreateUnicodeStringFromAsciiz(&section, pszSection);
    RtlCreateUnicodeStringFromAsciiz(&backupdir, pszBackupDir);
    RtlCreateUnicodeStringFromAsciiz(&backupfile, pszBaseBackupFile);

    hr = FileSaveRestoreOnINFW(hWnd, title.Buffer, inf.Buffer, section.Buffer,
                               backupdir.Buffer, backupfile.Buffer, dwFlags);

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

    return hr;
}

/***********************************************************************
 *      FileSaveRestoreOnINFW (ADVPACK.@)
 *
 *
 * PARAMS
 *   hWnd              [I] Handle to the window used for the display.
 *   pszTitle          [I] Title of the window.
 *   pszINF            [I] Fully-qualified INF filename.
 *   pszSection        [I] GenInstall INF section name.
 *   pszBackupDir      [I] Directory to store the backup file.
 *   pszBaseBackupFile [I] Basename of the backup files.
 *   dwFlags           [I] See advpub.h
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * NOTES
 *   If pszSection is NULL, the default section will be used.
 *
 * BUGS
 *   Unimplemented.
 */
HRESULT WINAPI FileSaveRestoreOnINFW(HWND hWnd, LPCWSTR pszTitle, LPCWSTR pszINF,
                                     LPCWSTR pszSection, LPCWSTR pszBackupDir,
                                     LPCWSTR pszBaseBackupFile, DWORD dwFlags)
{
    FIXME("(%p, %s, %s, %s, %s, %s, %ld): stub\n", hWnd, debugstr_w(pszTitle),
          debugstr_w(pszINF), debugstr_w(pszSection), debugstr_w(pszBackupDir),
          debugstr_w(pszBaseBackupFile), dwFlags);

    return E_FAIL;
}

/***********************************************************************
 *             GetVersionFromFileA     (ADVPACK.@)
 *
 * See GetVersionFromFileExW.
 */
HRESULT WINAPI GetVersionFromFileA(LPCSTR Filename, LPDWORD MajorVer,
                                   LPDWORD MinorVer, BOOL Version )
{
    TRACE("(%s, %p, %p, %d)\n", debugstr_a(Filename), MajorVer, MinorVer, Version);
    return GetVersionFromFileExA(Filename, MajorVer, MinorVer, Version);
}

/***********************************************************************
 *             GetVersionFromFileW     (ADVPACK.@)
 *
 * See GetVersionFromFileExW.
 */
HRESULT WINAPI GetVersionFromFileW(LPCWSTR Filename, LPDWORD MajorVer,
                                   LPDWORD MinorVer, BOOL Version )
{
    TRACE("(%s, %p, %p, %d)\n", debugstr_w(Filename), MajorVer, MinorVer, Version);
    return GetVersionFromFileExW(Filename, MajorVer, MinorVer, Version);
}

/* data for GetVersionFromFileEx */
typedef struct tagLANGANDCODEPAGE
{
    WORD wLanguage;
    WORD wCodePage;
} LANGANDCODEPAGE;

/***********************************************************************
 *             GetVersionFromFileExA   (ADVPACK.@)
 *
 * See GetVersionFromFileExW.
 */
HRESULT WINAPI GetVersionFromFileExA(LPCSTR lpszFilename, LPDWORD pdwMSVer,
                                     LPDWORD pdwLSVer, BOOL bVersion )
{
    UNICODE_STRING filename;
    HRESULT res;

    TRACE("(%s, %p, %p, %d)\n", debugstr_a(lpszFilename),
          pdwMSVer, pdwLSVer, bVersion);

    RtlCreateUnicodeStringFromAsciiz(&filename, lpszFilename);

    res = GetVersionFromFileExW(filename.Buffer, pdwMSVer, pdwLSVer, bVersion);

    RtlFreeUnicodeString(&filename);

    return res;
}

/***********************************************************************
 *             GetVersionFromFileExW   (ADVPACK.@)
 *
 * Gets the files version or language information.
 *
 * PARAMS
 *   lpszFilename [I] The file to get the info from.
 *   pdwMSVer     [O] Major version.
 *   pdwLSVer     [O] Minor version.
 *   bVersion     [I] Whether to retrieve version or language info.
 *
 * RETURNS
 *   Always returns S_OK.
 *
 * NOTES
 *   If bVersion is TRUE, version information is retrieved, else
 *   pdwMSVer gets the language ID and pdwLSVer gets the codepage ID.
 */
HRESULT WINAPI GetVersionFromFileExW(LPCWSTR lpszFilename, LPDWORD pdwMSVer,
                                     LPDWORD pdwLSVer, BOOL bVersion )
{
    VS_FIXEDFILEINFO *pFixedVersionInfo;
    LANGANDCODEPAGE *pLangAndCodePage;
    DWORD dwHandle, dwInfoSize;
    WCHAR szWinDir[MAX_PATH];
    WCHAR szFile[MAX_PATH];
    LPVOID pVersionInfo = NULL;
    BOOL bFileCopied = FALSE;
    UINT uValueLen;

    static WCHAR backslash[] = {'\\',0};
    static WCHAR translation[] = {
        '\\','V','a','r','F','i','l','e','I','n','f','o',
        '\\','T','r','a','n','s','l','a','t','i','o','n',0
    };

    TRACE("(%s, %p, %p, %d)\n", debugstr_w(lpszFilename),
          pdwMSVer, pdwLSVer, bVersion);

    *pdwLSVer = 0;
    *pdwMSVer = 0;

    lstrcpynW(szFile, lpszFilename, MAX_PATH);

    dwInfoSize = GetFileVersionInfoSizeW(szFile, &dwHandle);
    if (!dwInfoSize)
    {
        /* check that the file exists */
        if (GetFileAttributesW(szFile) == INVALID_FILE_ATTRIBUTES)
            return S_OK;

        /* file exists, but won't be found by GetFileVersionInfoSize,
        * so copy it to the temp dir where it will be found.
        */
        GetWindowsDirectoryW(szWinDir, MAX_PATH);
        GetTempFileNameW(szWinDir, NULL, 0, szFile);
        CopyFileW(lpszFilename, szFile, FALSE);
        bFileCopied = TRUE;

        dwInfoSize = GetFileVersionInfoSizeW(szFile, &dwHandle);
        if (!dwInfoSize)
            goto done;
    }

    pVersionInfo = HeapAlloc(GetProcessHeap(), 0, dwInfoSize);
    if (!pVersionInfo)
        goto done;

    if (!GetFileVersionInfoW(szFile, dwHandle, dwInfoSize, pVersionInfo))
        goto done;

    if (bVersion)
    {
        if (!VerQueryValueW(pVersionInfo, backslash,
            (LPVOID *)&pFixedVersionInfo, &uValueLen))
            goto done;

        if (!uValueLen)
            goto done;

        *pdwMSVer = pFixedVersionInfo->dwFileVersionMS;
        *pdwLSVer = pFixedVersionInfo->dwFileVersionLS;
    }
    else
    {
        if (!VerQueryValueW(pVersionInfo, translation,
             (LPVOID *)&pLangAndCodePage, &uValueLen))
            goto done;

        if (!uValueLen)
            goto done;

        *pdwMSVer = pLangAndCodePage->wLanguage;
        *pdwLSVer = pLangAndCodePage->wCodePage;
    }

done:
    HeapFree(GetProcessHeap(), 0, pVersionInfo);

    if (bFileCopied)
        DeleteFileW(szFile);

    return S_OK;
}
