/*
 * setupapi query 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 "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "setupapi.h"
#include "advpub.h"
#include "winnls.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "setupapi_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(setupapi);

#ifdef __i386__
static const WCHAR source_disks_names_platform[] =
    {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s','.','x','8','6',0};
static const WCHAR source_disks_files_platform[] =
    {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s','.','x','8','6',0};
#elif defined(__x86_64)
static const WCHAR source_disks_names_platform[] =
    {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s','.','a','m','d','6','4',0};
static const WCHAR source_disks_files_platform[] =
    {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s','.','a','m','d','6','4',0};
#else  /* FIXME: other platforms */
static const WCHAR source_disks_names_platform[] =
    {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
static const WCHAR source_disks_files_platform[] =
    {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
#endif
static const WCHAR source_disks_names[] =
    {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
static const WCHAR source_disks_files[] =
    {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};

/* fills the PSP_INF_INFORMATION struct fill_info is TRUE
 * always returns the required size of the information
 */
static BOOL fill_inf_info(HINF inf, PSP_INF_INFORMATION buffer, DWORD size, DWORD *required)
{
    LPCWSTR filename = PARSER_get_inf_filename(inf);
    DWORD total_size = FIELD_OFFSET(SP_INF_INFORMATION, VersionData)
                        + (lstrlenW(filename) + 1) * sizeof(WCHAR);

    if (required) *required = total_size;

    /* FIXME: we need to parse the INF file to find the correct version info */
    if (buffer)
    {
        if (size < total_size)
        {
            SetLastError(ERROR_INSUFFICIENT_BUFFER);
            return FALSE;
        }
        buffer->InfStyle = INF_STYLE_WIN4;
        buffer->InfCount = 1;
        /* put the filename in buffer->VersionData */
        lstrcpyW((LPWSTR)&buffer->VersionData[0], filename);
    }
    return TRUE;
}

static HINF search_for_inf(LPCVOID InfSpec, DWORD SearchControl)
{
    HINF hInf = INVALID_HANDLE_VALUE;
    WCHAR inf_path[MAX_PATH];

    static const WCHAR infW[] = {'\\','i','n','f','\\',0};
    static const WCHAR system32W[] = {'\\','s','y','s','t','e','m','3','2','\\',0};

    if (SearchControl == INFINFO_REVERSE_DEFAULT_SEARCH)
    {
        GetWindowsDirectoryW(inf_path, MAX_PATH);
        lstrcatW(inf_path, system32W);
        lstrcatW(inf_path, InfSpec);

        hInf = SetupOpenInfFileW(inf_path, NULL,
                                 INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
        if (hInf != INVALID_HANDLE_VALUE)
            return hInf;

        GetWindowsDirectoryW(inf_path, MAX_PATH);
        lstrcpyW(inf_path, infW);
        lstrcatW(inf_path, InfSpec);

        return SetupOpenInfFileW(inf_path, NULL,
                                 INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
    }

    return INVALID_HANDLE_VALUE;
}

/***********************************************************************
 *      SetupGetInfInformationA    (SETUPAPI.@)
 *
 */
BOOL WINAPI SetupGetInfInformationA(LPCVOID InfSpec, DWORD SearchControl,
                                    PSP_INF_INFORMATION ReturnBuffer,
                                    DWORD ReturnBufferSize, PDWORD RequiredSize)
{
    LPWSTR inf = (LPWSTR)InfSpec;
    DWORD len;
    BOOL ret;

    if (InfSpec && SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
    {
        len = MultiByteToWideChar(CP_ACP, 0, InfSpec, -1, NULL, 0);
        inf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (!inf)
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
        MultiByteToWideChar(CP_ACP, 0, InfSpec, -1, inf, len);
    }

    ret = SetupGetInfInformationW(inf, SearchControl, ReturnBuffer,
                                  ReturnBufferSize, RequiredSize);

    if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
        HeapFree(GetProcessHeap(), 0, inf);

    return ret;
}

/***********************************************************************
 *      SetupGetInfInformationW    (SETUPAPI.@)
 * 
 * BUGS
 *   Only handles the case when InfSpec is an INF handle.
 */
BOOL WINAPI SetupGetInfInformationW(LPCVOID InfSpec, DWORD SearchControl,
                                     PSP_INF_INFORMATION ReturnBuffer,
                                     DWORD ReturnBufferSize, PDWORD RequiredSize)
{
    HINF inf;
    BOOL ret;
    DWORD infSize;

    TRACE("(%p, %d, %p, %d, %p)\n", InfSpec, SearchControl, ReturnBuffer,
           ReturnBufferSize, RequiredSize);

    if (!InfSpec)
    {
        if (SearchControl == INFINFO_INF_SPEC_IS_HINF)
            SetLastError(ERROR_INVALID_HANDLE);
        else
            SetLastError(ERROR_INVALID_PARAMETER);

        return FALSE;
    }

    switch (SearchControl)
    {
        case INFINFO_INF_SPEC_IS_HINF:
            inf = (HINF)InfSpec;
            break;
        case INFINFO_INF_NAME_IS_ABSOLUTE:
        case INFINFO_DEFAULT_SEARCH:
            inf = SetupOpenInfFileW(InfSpec, NULL,
                                    INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
            break;
        case INFINFO_REVERSE_DEFAULT_SEARCH:
            inf = search_for_inf(InfSpec, SearchControl);
            break;
        case INFINFO_INF_PATH_LIST_SEARCH:
            FIXME("Unhandled search control: %d\n", SearchControl);

            if (RequiredSize)
                *RequiredSize = 0;

            return FALSE;
        default:
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
    }

    if (inf == INVALID_HANDLE_VALUE)
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    ret = fill_inf_info(inf, ReturnBuffer, ReturnBufferSize, &infSize);
    if (!ReturnBuffer && (ReturnBufferSize >= infSize))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        ret = FALSE;
    }
    if (RequiredSize) *RequiredSize = infSize;

    if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
        SetupCloseInfFile(inf);

    return ret;
}

/***********************************************************************
 *      SetupQueryInfFileInformationA    (SETUPAPI.@)
 */
BOOL WINAPI SetupQueryInfFileInformationA(PSP_INF_INFORMATION InfInformation,
                                          UINT InfIndex, PSTR ReturnBuffer,
                                          DWORD ReturnBufferSize, PDWORD RequiredSize)
{
    LPWSTR filenameW;
    DWORD size;
    BOOL ret;

    ret = SetupQueryInfFileInformationW(InfInformation, InfIndex, NULL, 0, &size);
    if (!ret)
        return FALSE;

    filenameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));

    ret = SetupQueryInfFileInformationW(InfInformation, InfIndex,
                                        filenameW, size, &size);
    if (!ret)
    {
        HeapFree(GetProcessHeap(), 0, filenameW);
        return FALSE;
    }

    if (RequiredSize)
        *RequiredSize = size;

    if (!ReturnBuffer)
    {
        HeapFree(GetProcessHeap(), 0, filenameW);
        if (ReturnBufferSize)
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }

        return TRUE;
    }

    if (size > ReturnBufferSize)
    {
        HeapFree(GetProcessHeap(), 0, filenameW);
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    WideCharToMultiByte(CP_ACP, 0, filenameW, -1, ReturnBuffer, size, NULL, NULL);
    HeapFree(GetProcessHeap(), 0, filenameW);

    return ret;
}

/***********************************************************************
 *      SetupQueryInfFileInformationW    (SETUPAPI.@)
 */
BOOL WINAPI SetupQueryInfFileInformationW(PSP_INF_INFORMATION InfInformation,
                                          UINT InfIndex, PWSTR ReturnBuffer,
                                          DWORD ReturnBufferSize, PDWORD RequiredSize) 
{
    DWORD len;
    LPWSTR ptr;

    TRACE("(%p, %u, %p, %d, %p) Stub!\n", InfInformation, InfIndex,
          ReturnBuffer, ReturnBufferSize, RequiredSize);

    if (!InfInformation)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (InfIndex != 0)
        FIXME("Appended INF files are not handled\n");

    ptr = (LPWSTR)InfInformation->VersionData;
    len = lstrlenW(ptr);

    if (RequiredSize)
        *RequiredSize = len + 1;

    if (!ReturnBuffer)
        return TRUE;

    if (ReturnBufferSize < len)
    {
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    lstrcpyW(ReturnBuffer, ptr);
    return TRUE;
}

/***********************************************************************
 *            SetupGetSourceFileLocationA   (SETUPAPI.@)
 */

BOOL WINAPI SetupGetSourceFileLocationA( HINF hinf, PINFCONTEXT context, PCSTR filename,
                                         PUINT source_id, PSTR buffer, DWORD buffer_size,
                                         PDWORD required_size )
{
    BOOL ret = FALSE;
    WCHAR *filenameW = NULL, *bufferW = NULL;
    DWORD required;
    INT size;

    TRACE("%p, %p, %s, %p, %p, 0x%08x, %p\n", hinf, context, debugstr_a(filename), source_id,
          buffer, buffer_size, required_size);

    if (filename && *filename && !(filenameW = strdupAtoW( filename )))
        return FALSE;

    if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, NULL, 0, &required ))
        goto done;

    if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
        goto done;

    if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, bufferW, required, NULL ))
        goto done;

    size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
    if (required_size) *required_size = size;

    if (buffer)
    {
        if (buffer_size >= size)
            WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            goto done;
        }
    }
    ret = TRUE;

 done:
    HeapFree( GetProcessHeap(), 0, filenameW );
    HeapFree( GetProcessHeap(), 0, bufferW );
    return ret;
}

static LPWSTR get_source_id( HINF hinf, PINFCONTEXT context, PCWSTR filename )
{
    DWORD size;
    LPWSTR source_id;

    if (!SetupFindFirstLineW( hinf, source_disks_files_platform, filename, context ) &&
        !SetupFindFirstLineW( hinf, source_disks_files, filename, context ))
        return NULL;

    if (!SetupGetStringFieldW( context, 1, NULL, 0, &size ))
        return NULL;

    if (!(source_id = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
        return NULL;

    if (!SetupGetStringFieldW( context, 1, source_id, size, NULL ))
    {
        HeapFree( GetProcessHeap(), 0, source_id );
        return NULL;
    }

    if (!SetupFindFirstLineW( hinf, source_disks_names_platform, source_id, context ) &&
        !SetupFindFirstLineW( hinf, source_disks_names, source_id, context ))
    {
        HeapFree( GetProcessHeap(), 0, source_id );
        return NULL;
    }
    return source_id;
}

/***********************************************************************
 *            SetupGetSourceFileLocationW   (SETUPAPI.@)
 */

BOOL WINAPI SetupGetSourceFileLocationW( HINF hinf, PINFCONTEXT context, PCWSTR filename,
                                         PUINT source_id, PWSTR buffer, DWORD buffer_size,
                                         PDWORD required_size )
{
    INFCONTEXT ctx;
    WCHAR *end, *source_id_str;

    TRACE("%p, %p, %s, %p, %p, 0x%08x, %p\n", hinf, context, debugstr_w(filename), source_id,
          buffer, buffer_size, required_size);

    if (!context) context = &ctx;

    if (!(source_id_str = get_source_id( hinf, context, filename )))
        return FALSE;

    *source_id = strtolW( source_id_str, &end, 10 );
    if (end == source_id_str || *end)
    {
        HeapFree( GetProcessHeap(), 0, source_id_str );
        return FALSE;
    }
    HeapFree( GetProcessHeap(), 0, source_id_str );

    if (SetupGetStringFieldW( context, 4, buffer, buffer_size, required_size ))
        return TRUE;

    if (required_size) *required_size = 1;
    if (buffer)
    {
        if (buffer_size >= 1) buffer[0] = 0;
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            return FALSE;
        }
    }
    return TRUE;
}

/***********************************************************************
 *            SetupGetSourceInfoA  (SETUPAPI.@)
 */

BOOL WINAPI SetupGetSourceInfoA( HINF hinf, UINT source_id, UINT info,
                                 PSTR buffer, DWORD buffer_size, LPDWORD required_size )
{
    BOOL ret = FALSE;
    WCHAR *bufferW = NULL;
    DWORD required;
    INT size;

    TRACE("%p, %d, %d, %p, %d, %p\n", hinf, source_id, info, buffer, buffer_size,
          required_size);

    if (!SetupGetSourceInfoW( hinf, source_id, info, NULL, 0, &required ))
        return FALSE;

    if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
        return FALSE;

    if (!SetupGetSourceInfoW( hinf, source_id, info, bufferW, required, NULL ))
        goto done;

    size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
    if (required_size) *required_size = size;

    if (buffer)
    {
        if (buffer_size >= size)
            WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            goto done;
        }
    }
    ret = TRUE;

 done:
    HeapFree( GetProcessHeap(), 0, bufferW );
    return ret;
}

/***********************************************************************
 *            SetupGetSourceInfoW  (SETUPAPI.@)
 */

BOOL WINAPI SetupGetSourceInfoW( HINF hinf, UINT source_id, UINT info,
                                 PWSTR buffer, DWORD buffer_size, LPDWORD required_size )
{
    INFCONTEXT ctx;
    WCHAR source_id_str[11];
    static const WCHAR fmt[] = {'%','d',0};
    DWORD index;

    TRACE("%p, %d, %d, %p, %d, %p\n", hinf, source_id, info, buffer, buffer_size,
          required_size);

    sprintfW( source_id_str, fmt, source_id );

    if (!SetupFindFirstLineW( hinf, source_disks_names_platform, source_id_str, &ctx ) &&
        !SetupFindFirstLineW( hinf, source_disks_names, source_id_str, &ctx ))
        return FALSE;

    switch (info)
    {
    case SRCINFO_PATH:          index = 4; break;
    case SRCINFO_TAGFILE:       index = 2; break;
    case SRCINFO_DESCRIPTION:   index = 1; break;
    default:
        WARN("unknown info level: %d\n", info);
        return FALSE;
    }

    if (SetupGetStringFieldW( &ctx, index, buffer, buffer_size, required_size ))
        return TRUE;

    if (required_size) *required_size = 1;
    if (buffer)
    {
        if (buffer_size >= 1) buffer[0] = 0;
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            return FALSE;
        }
    }
    return TRUE;
}

/***********************************************************************
 *            SetupGetTargetPathA   (SETUPAPI.@)
 */

BOOL WINAPI SetupGetTargetPathA( HINF hinf, PINFCONTEXT context, PCSTR section, PSTR buffer,
                                 DWORD buffer_size, PDWORD required_size )
{
    BOOL ret = FALSE;
    WCHAR *sectionW = NULL, *bufferW = NULL;
    DWORD required;
    INT size;

    TRACE("%p, %p, %s, %p, 0x%08x, %p\n", hinf, context, debugstr_a(section), buffer,
          buffer_size, required_size);

    if (section && !(sectionW = strdupAtoW( section )))
        return FALSE;

    if (!SetupGetTargetPathW( hinf, context, sectionW, NULL, 0, &required ))
        goto done;

    if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
        goto done;

    if (!SetupGetTargetPathW( hinf, context, sectionW, bufferW, required, NULL ))
        goto done;

    size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
    if (required_size) *required_size = size;

    if (buffer)
    {
        if (buffer_size >= size)
            WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            goto done;
        }
    }
    ret = TRUE;

 done:
    HeapFree( GetProcessHeap(), 0, sectionW );
    HeapFree( GetProcessHeap(), 0, bufferW );
    return ret;
}

/***********************************************************************
 *            SetupGetTargetPathW   (SETUPAPI.@)
 */

BOOL WINAPI SetupGetTargetPathW( HINF hinf, PINFCONTEXT context, PCWSTR section, PWSTR buffer,
                                 DWORD buffer_size, PDWORD required_size )
{
    static const WCHAR destination_dirs[] =
        {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};
    static const WCHAR default_dest_dir[]  =
        {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};

    INFCONTEXT ctx;
    WCHAR *dir, systemdir[MAX_PATH];
    unsigned int size;
    BOOL ret = FALSE;

    TRACE("%p, %p, %s, %p, 0x%08x, %p\n", hinf, context, debugstr_w(section), buffer,
          buffer_size, required_size);

    if (context) ret = SetupFindFirstLineW( hinf, destination_dirs, NULL, context );
    else if (section)
    {
        if (!(ret = SetupFindFirstLineW( hinf, destination_dirs, section, &ctx )))
            ret = SetupFindFirstLineW( hinf, destination_dirs, default_dest_dir, &ctx );
    }
    if (!ret || !(dir = PARSER_get_dest_dir( context ? context : &ctx )))
    {
        GetSystemDirectoryW( systemdir, MAX_PATH );
        dir = systemdir;
    }
    size = strlenW( dir ) + 1;
    if (required_size) *required_size = size;

    if (buffer)
    {
        if (buffer_size >= size)
            lstrcpyW( buffer, dir );
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            if (dir != systemdir) HeapFree( GetProcessHeap(), 0, dir );
            return FALSE;
        }
    }
    if (dir != systemdir) HeapFree( GetProcessHeap(), 0, dir );
    return TRUE;
}

/***********************************************************************
 *            SetupQueryInfOriginalFileInformationA   (SETUPAPI.@)
 */
BOOL WINAPI SetupQueryInfOriginalFileInformationA(
    PSP_INF_INFORMATION InfInformation, UINT InfIndex,
    PSP_ALTPLATFORM_INFO AlternativePlatformInfo,
    PSP_ORIGINAL_FILE_INFO_A OriginalFileInfo)
{
    BOOL ret;
    SP_ORIGINAL_FILE_INFO_W OriginalFileInfoW;

    TRACE("(%p, %d, %p, %p)\n", InfInformation, InfIndex,
        AlternativePlatformInfo, OriginalFileInfo);

    if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo))
    {
        WARN("incorrect OriginalFileInfo->cbSize of %d\n", OriginalFileInfo->cbSize);
        SetLastError( ERROR_INVALID_USER_BUFFER );
        return FALSE;
    }

    OriginalFileInfoW.cbSize = sizeof(OriginalFileInfoW);
    ret = SetupQueryInfOriginalFileInformationW(InfInformation, InfIndex,
        AlternativePlatformInfo, &OriginalFileInfoW);
    if (ret)
    {
        WideCharToMultiByte(CP_ACP, 0, OriginalFileInfoW.OriginalInfName, -1,
            OriginalFileInfo->OriginalInfName, MAX_PATH, NULL, NULL);
        WideCharToMultiByte(CP_ACP, 0, OriginalFileInfoW.OriginalCatalogName, -1,
            OriginalFileInfo->OriginalCatalogName, MAX_PATH, NULL, NULL);
    }

    return ret;
}

/***********************************************************************
 *            SetupQueryInfOriginalFileInformationW   (SETUPAPI.@)
 */
BOOL WINAPI SetupQueryInfOriginalFileInformationW(
    PSP_INF_INFORMATION InfInformation, UINT InfIndex,
    PSP_ALTPLATFORM_INFO AlternativePlatformInfo,
    PSP_ORIGINAL_FILE_INFO_W OriginalFileInfo)
{
    LPCWSTR inf_name;
    LPCWSTR inf_path;
    HINF hinf;
    static const WCHAR wszVersion[] = { 'V','e','r','s','i','o','n',0 };
    static const WCHAR wszCatalogFile[] = { 'C','a','t','a','l','o','g','F','i','l','e',0 };

    FIXME("(%p, %d, %p, %p): semi-stub\n", InfInformation, InfIndex,
        AlternativePlatformInfo, OriginalFileInfo);

    if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo))
    {
        WARN("incorrect OriginalFileInfo->cbSize of %d\n", OriginalFileInfo->cbSize);
        SetLastError(ERROR_INVALID_USER_BUFFER);
        return FALSE;
    }

    inf_path = (LPWSTR)InfInformation->VersionData;

    /* FIXME: we should get OriginalCatalogName from CatalogFile line in
     * the original inf file and cache it, but that would require building a
     * .pnf file. */
    hinf = SetupOpenInfFileW(inf_path, NULL, INF_STYLE_WIN4, NULL);
    if (hinf == INVALID_HANDLE_VALUE) return FALSE;

    if (!SetupGetLineTextW(NULL, hinf, wszVersion, wszCatalogFile,
                           OriginalFileInfo->OriginalCatalogName,
                           sizeof(OriginalFileInfo->OriginalCatalogName)/sizeof(OriginalFileInfo->OriginalCatalogName[0]),
                           NULL))
    {
        OriginalFileInfo->OriginalCatalogName[0] = '\0';
    }
    SetupCloseInfFile(hinf);

    /* FIXME: not quite correct as we just return the same file name as
     * destination (copied) inf file, not the source (original) inf file.
     * to fix it properly would require building a .pnf file */
    /* file name is stored in VersionData field of InfInformation */
    inf_name = strrchrW(inf_path, '\\');
    if (inf_name) inf_name++;
    else inf_name = inf_path;

    strcpyW(OriginalFileInfo->OriginalInfName, inf_name);

    return TRUE;
}
