/*
 * 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];
    LPCWSTR 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 = 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 szDestFilename;
    LPCWSTR szPath;
    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 = 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;
    const char *first = FileList;
    const char *last = 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;
}
