/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdarg.h>
#include <stdlib.h>

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

WINE_DEFAULT_DEBUG_CHANNEL(advpack);

/***********************************************************************
 *      AddDelBackupEntry (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
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * 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.
 *
 * BUGS
 *   Unimplemented.
 */
HRESULT WINAPI AddDelBackupEntry(LPCSTR lpcszFileList, LPCSTR lpcszBackupDir,
                                 LPCSTR lpcszBaseName, DWORD dwFlags)
{
    FIXME("(%p, %p, %p, %ld) stub\n", lpcszFileList, lpcszBackupDir,
          lpcszBaseName, dwFlags);

    return E_FAIL;
}

/* 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 SetupDefaultQueueCallbackA(Context, Notification,
                                          Param1, Param2);
    }

    return 1;
}

/***********************************************************************
 *      AdvInstallFile (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 AdvInstallFile(HWND hwnd, LPCSTR lpszSourceDir, LPCSTR lpszSourceFile,
                              LPCSTR lpszDestDir, LPCSTR lpszDestFile,
                              DWORD dwFlags, DWORD dwReserved)
{
    PSP_FILE_CALLBACK_A pFileCallback;
    LPSTR szPath, szDestFilename;
    char szRootPath[ROOT_LENGTH];
    DWORD dwLen, dwLastError;
    HSPFILEQ fileQueue;
    PVOID pContext;

    TRACE("(%p,%p,%p,%p,%p,%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;
        
    fileQueue = SetupOpenFileQueue();
    if (fileQueue == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(GetLastError());

    pContext = NULL;
    dwLastError = ERROR_SUCCESS;

    lstrcpynA(szRootPath, lpszSourceDir, ROOT_LENGTH);
    szPath = (LPSTR)lpszSourceDir + ROOT_LENGTH;

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

    /* add the file copy operation to the setup queue */
    if (!SetupQueueCopyA(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 (!SetupCommitFileQueueA(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(LPSTR fname, DWORD flags)
{
    DWORD fattrs = GetFileAttributesA(fname);
    HRESULT ret = E_FAIL;

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

        /* Generate a path with wildcard suitable for iterating */
        if (CharPrevA(fname, fname + fname_len) != "\\")
        {
            lstrcpyA(fname + fname_len, "\\");
            ++fname_len;
        }
        lstrcpyA(fname + fname_len, "*");

        if ((hFindFile = FindFirstFileA(fname, &w32fd)) != INVALID_HANDLE_VALUE)
        {
            /* Iterate through the files in the directory */
            for (done = FALSE; !done; done = !FindNextFileA(hFindFile, &w32fd))
            {
                TRACE("%s\n", w32fd.cFileName);
                if (lstrcmpA(".", w32fd.cFileName) != 0 &&
                    lstrcmpA("..", w32fd.cFileName) != 0)
                {
                    lstrcpyA(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", fname);
            if (SetFileAttributesA(fname, FILE_ATTRIBUTE_NORMAL) && RemoveDirectoryA(fname))
            {
                ret = S_OK;
            }
        }
    }
    else
    {
        TRACE("%s: file\n", fname);
        if (SetFileAttributesA(fname, FILE_ATTRIBUTE_NORMAL) && DeleteFileA(fname))
        {
            ret = S_OK;
        }
    }
    
    return ret;
}

/***********************************************************************
 *              DelNode    (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 DelNode( LPCSTR pszFileOrDirName, DWORD dwFlags )
{
    CHAR fname[MAX_PATH];
    HRESULT ret = E_FAIL;
    
    TRACE("(%s, 0x%08lx)\n", debugstr_a(pszFileOrDirName), dwFlags);
    
    if (dwFlags)
        FIXME("Flags ignored!\n");

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

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

        ret = DELNODE_recurse_dirtree(fname, dwFlags);
    }

    return ret;
}

/* returns the parameter at dwIndex in a list of parameters
 * separated by the cSeparator character
 */
static LPSTR get_parameter(LPSTR szParameters, CHAR cSeparator, DWORD dwIndex)
{
    LPSTR szParam = NULL;
    DWORD i = 0;

    while (*szParameters && i < dwIndex)
    {
        if (*szParameters == cSeparator)
            i++;

        szParameters++;
    }

    if (!*szParameters)
        return NULL;

    szParam = HeapAlloc(GetProcessHeap(), 0, lstrlenA(szParameters));
    lstrcpyA(szParam, szParameters);

    return szParam;
}

/***********************************************************************
 *             DelNodeRunDLL32    (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 DelNodeRunDLL32( HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show )
{
    LPSTR szFilename, szFlags;
    DWORD dwFlags;
    HRESULT res;

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

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

    dwFlags = atol(szFlags);

    res = DelNode(szFilename, dwFlags);

    HeapFree(GetProcessHeap(), 0, szFilename);
    HeapFree(GetProcessHeap(), 0, szFlags);

    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;
}

/***********************************************************************
 *             ExtractFiles    (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 ExtractFiles ( 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("(%p %p %ld %p %p %ld)\n", CabName, ExpandDir, Flags,
          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;
}

/***********************************************************************
 *      FileSaveMarkNotExist (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 FileSaveMarkNotExist(LPSTR pszFileList, LPSTR pszDir, LPSTR pszBaseName)
{
    TRACE("(%p, %p, %p)\n", pszFileList, pszDir, pszBaseName);

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

/***********************************************************************
 *      FileSaveRestore (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 FileSaveRestore(HWND hDlg, LPSTR pszFileList, LPSTR pszDir,
                               LPSTR pszBaseName, DWORD dwFlags)
{
    FIXME("(%p, %p, %p, %p, %ld) stub\n", hDlg, pszFileList, pszDir,
          pszBaseName, dwFlags);

    return E_FAIL;
}

/***********************************************************************
 *      FileSaveRestoreOnINF (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 FileSaveRestoreOnINF(HWND hWnd, PCSTR pszTitle, PCSTR pszINF,
                                    PCSTR pszSection, PCSTR pszBackupDir,
                                    PCSTR pszBaseBackupFile, DWORD dwFlags)
{
    FIXME("(%p, %p, %p, %p, %p, %p, %ld) stub\n", hWnd, pszTitle, pszINF,
          pszSection, pszBackupDir, pszBaseBackupFile, dwFlags);

    return E_FAIL;
}

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

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

/***********************************************************************
 *             GetVersionFromFileEx    (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 GetVersionFromFileEx( LPSTR lpszFilename, LPDWORD pdwMSVer,
                                     LPDWORD pdwLSVer, BOOL bVersion )
{
    VS_FIXEDFILEINFO *pFixedVersionInfo;
    LANGANDCODEPAGE *pLangAndCodePage;
    DWORD dwHandle, dwInfoSize;
    CHAR szWinDir[MAX_PATH];
    CHAR szFile[MAX_PATH];
    LPVOID pVersionInfo = NULL;
    BOOL bFileCopied = FALSE;
    UINT uValueLen;

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

    *pdwLSVer = 0;
    *pdwMSVer = 0;

    lstrcpynA(szFile, lpszFilename, MAX_PATH);

    dwInfoSize = GetFileVersionInfoSizeA(szFile, &dwHandle);
    if (!dwInfoSize)
    {
        /* check that the file exists */
        if (GetFileAttributesA(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.
        */
        GetWindowsDirectoryA(szWinDir, MAX_PATH);
        GetTempFileNameA(szWinDir, NULL, 0, szFile);
        CopyFileA(lpszFilename, szFile, FALSE);
        bFileCopied = TRUE;

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

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

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

    if (bVersion)
    {
        if (!VerQueryValueA(pVersionInfo, "\\",
            (LPVOID *)&pFixedVersionInfo, &uValueLen))
            goto done;

        if (!uValueLen)
            goto done;

        *pdwMSVer = pFixedVersionInfo->dwFileVersionMS;
        *pdwLSVer = pFixedVersionInfo->dwFileVersionLS;
    }
    else
    {
        if (!VerQueryValueA(pVersionInfo, "\\VarFileInfo\\Translation",
             (LPVOID *)&pLangAndCodePage, &uValueLen))
            goto done;

        if (!uValueLen)
            goto done;

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

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

    if (bFileCopied)
        DeleteFileA(szFile);

    return S_OK;
}
