/*
 * 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 = lstrlenA(InfSpec) + 1;
        inf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        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;
}
