/*
 * MSCMS - Color Management System for Wine
 *
 * Copyright 2004, 2005, 2006, 2008 Hans Leidekker
 *
 * 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 "config.h"
#include "wine/debug.h"
#include "wine/unicode.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "icm.h"

#include "mscms_priv.h"

#define IS_SEPARATOR(ch)  ((ch) == '\\' || (ch) == '/')

static void MSCMS_basename( LPCWSTR path, LPWSTR name )
{
    INT i = lstrlenW( path );

    while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
    lstrcpyW( name, &path[i] );
}

static inline LPWSTR MSCMS_strdupW( LPCSTR str )
{
    LPWSTR ret = NULL;
    if (str)
    {
        DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
        if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
            MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
    }
    return ret;
}

const char *MSCMS_dbgstr_tag( DWORD tag )
{
    return wine_dbg_sprintf( "'%c%c%c%c'",
        (char)(tag >> 24), (char)(tag >> 16), (char)(tag >> 8), (char)(tag) );
}

WINE_DEFAULT_DEBUG_CHANNEL(mscms);

/******************************************************************************
 * AssociateColorProfileWithDeviceA               [MSCMS.@]
 */
BOOL WINAPI AssociateColorProfileWithDeviceA( PCSTR machine, PCSTR profile, PCSTR device )
{
    int len;
    BOOL ret = FALSE;
    WCHAR *profileW, *deviceW;

    TRACE( "( %s, %s, %s )\n", debugstr_a(machine), debugstr_a(profile), debugstr_a(device) );

    if (!profile || !device)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    if (machine)
    {
        SetLastError( ERROR_NOT_SUPPORTED );
        return FALSE;
    }

    len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
    if (!(profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;

    MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );

    len = MultiByteToWideChar( CP_ACP, 0, device, -1, NULL, 0 );
    if ((deviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
    {
        MultiByteToWideChar( CP_ACP, 0, device, -1, deviceW, len );
        ret = AssociateColorProfileWithDeviceW( NULL, profileW, deviceW );
    }

    HeapFree( GetProcessHeap(), 0, profileW );
    HeapFree( GetProcessHeap(), 0, deviceW );
    return ret;
}

static BOOL set_profile_device_key( PCWSTR file, const BYTE *value, DWORD size )
{
    static const WCHAR fmtW[] = {'%','c','%','c','%','c','%','c',0};
    static const WCHAR icmW[] = {'S','o','f','t','w','a','r','e','\\',
                                 'M','i','c','r','o','s','o','f','t','\\',
                                 'W','i','n','d','o','w','s',' ','N','T','\\',
                                 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
                                 'I','C','M',0};
    PROFILEHEADER header;
    PROFILE profile;
    HPROFILE handle;
    HKEY icm_key, class_key;
    WCHAR basenameW[MAX_PATH], classW[5];

    profile.dwType = PROFILE_FILENAME;
    profile.pProfileData = (PVOID)file;
    profile.cbDataSize = (lstrlenW( file ) + 1) * sizeof(WCHAR);

    /* FIXME is the profile installed? */
    if (!(handle = OpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING )))
    {
        SetLastError( ERROR_INVALID_PROFILE );
        return FALSE;
    }
    if (!GetColorProfileHeader( handle, &header ))
    {
        CloseColorProfile( handle );
        SetLastError( ERROR_INVALID_PROFILE );
        return FALSE;
    }
    RegCreateKeyExW( HKEY_LOCAL_MACHINE, icmW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &icm_key, NULL );

    MSCMS_basename( file, basenameW );
    sprintfW( classW, fmtW, (header.phClass >> 24) & 0xff, (header.phClass >> 16) & 0xff,
                            (header.phClass >> 8) & 0xff,  header.phClass & 0xff );

    RegCreateKeyExW( icm_key, classW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &class_key, NULL );
    if (value) RegSetValueExW( class_key, basenameW, 0, REG_BINARY, value, size );
    else RegDeleteValueW( class_key, basenameW );

    RegCloseKey( class_key );
    RegCloseKey( icm_key );
    CloseColorProfile( handle );
    return TRUE;
}

/******************************************************************************
 * AssociateColorProfileWithDeviceW               [MSCMS.@]
 */
BOOL WINAPI AssociateColorProfileWithDeviceW( PCWSTR machine, PCWSTR profile, PCWSTR device )
{
    static const BYTE dummy_value[12];

    TRACE( "( %s, %s, %s )\n", debugstr_w(machine), debugstr_w(profile), debugstr_w(device) );

    if (!profile || !device)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    if (machine)
    {
        SetLastError( ERROR_NOT_SUPPORTED );
        return FALSE;
    }

    return set_profile_device_key( profile, dummy_value, sizeof(dummy_value) );
}

/******************************************************************************
 * DisassociateColorProfileFromDeviceA            [MSCMS.@]
 */
BOOL WINAPI DisassociateColorProfileFromDeviceA( PCSTR machine, PCSTR profile, PCSTR device )
{
    int len;
    BOOL ret = FALSE;
    WCHAR *profileW, *deviceW;

    TRACE( "( %s, %s, %s )\n", debugstr_a(machine), debugstr_a(profile), debugstr_a(device) );

    if (!profile || !device)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    if (machine)
    {
        SetLastError( ERROR_NOT_SUPPORTED );
        return FALSE;
    }

    len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
    if (!(profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;

    MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );

    len = MultiByteToWideChar( CP_ACP, 0, device, -1, NULL, 0 );
    if ((deviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
    {
        MultiByteToWideChar( CP_ACP, 0, device, -1, deviceW, len );
        ret = DisassociateColorProfileFromDeviceW( NULL, profileW, deviceW );
    }

    HeapFree( GetProcessHeap(), 0, profileW );
    HeapFree( GetProcessHeap(), 0, deviceW );
    return ret;
}

/******************************************************************************
 * DisassociateColorProfileFromDeviceW            [MSCMS.@]
 */
BOOL WINAPI DisassociateColorProfileFromDeviceW( PCWSTR machine, PCWSTR profile, PCWSTR device )
{
    TRACE( "( %s, %s, %s )\n", debugstr_w(machine), debugstr_w(profile), debugstr_w(device) );

    if (!profile || !device)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    if (machine)
    {
        SetLastError( ERROR_NOT_SUPPORTED );
        return FALSE;
    }

    return set_profile_device_key( profile, NULL, 0 );
}

/******************************************************************************
 * GetColorDirectoryA               [MSCMS.@]
 *
 * See GetColorDirectoryW.
 */
BOOL WINAPI GetColorDirectoryA( PCSTR machine, PSTR buffer, PDWORD size )
{
    INT len;
    LPWSTR bufferW;
    BOOL ret = FALSE;
    DWORD sizeW;

    TRACE( "( %p, %p )\n", buffer, size );

    if (machine || !size) return FALSE;

    if (!buffer)
    {
        ret = GetColorDirectoryW( NULL, NULL, &sizeW );
        *size = sizeW / sizeof(WCHAR);
        return FALSE;
    }

    sizeW = *size * sizeof(WCHAR);

    bufferW = HeapAlloc( GetProcessHeap(), 0, sizeW );

    if (bufferW)
    {
        if ((ret = GetColorDirectoryW( NULL, bufferW, &sizeW )))
        {
            *size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
            len = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, *size, NULL, NULL );
            if (!len) ret = FALSE;
        }
        else *size = sizeW / sizeof(WCHAR);

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

/******************************************************************************
 * GetColorDirectoryW               [MSCMS.@]
 *
 * Get the directory where color profiles are stored.
 *
 * PARAMS
 *  machine  [I]   Name of the machine for which to get the color directory.
 *                 Must be NULL, which indicates the local machine.
 *  buffer   [I]   Buffer to receive the path name.
 *  size     [I/O] Size of the buffer in bytes. On return the variable holds
 *                 the number of bytes actually needed.
 */
BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
{
    WCHAR colordir[MAX_PATH];
    static const WCHAR colorsubdir[] =
        {'\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\','c','o','l','o','r',0};
    DWORD len;

    TRACE( "( %p, %p )\n", buffer, size );

    if (machine || !size) return FALSE;

    GetSystemDirectoryW( colordir, sizeof(colordir) / sizeof(WCHAR) );
    lstrcatW( colordir, colorsubdir );

    len = lstrlenW( colordir ) * sizeof(WCHAR);

    if (buffer && len <= *size)
    {
        lstrcpyW( buffer, colordir );
        *size = len;
        return TRUE;
    }

    SetLastError( ERROR_MORE_DATA );
    *size = len;
    return FALSE;
}

/******************************************************************************
 * GetColorProfileElement               [MSCMS.@]
 *
 * Retrieve data for a specified tag type.
 *
 * PARAMS
 *  profile  [I]   Handle to a color profile.
 *  type     [I]   ICC tag type. 
 *  offset   [I]   Offset in bytes to start copying from. 
 *  size     [I/O] Size of the buffer in bytes. On return the variable holds
 *                 the number of bytes actually needed.
 *  buffer   [O]   Buffer to receive the tag data.
 *  ref      [O]   Pointer to a BOOL that specifies whether more than one tag
 *                 references the data.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
                                    PVOID buffer, PBOOL ref )
{
    BOOL ret = FALSE;
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );
    DWORD i, count;
    icTag tag;

    TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", handle, type, offset, size, buffer, ref );

    if (!profile) return FALSE;

    if (!size || !ref)
    {
        release_profile( profile );
        return FALSE;
    }
    count = MSCMS_get_tag_count( profile->iccprofile );

    for (i = 0; i < count; i++)
    {
        MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );

        if (tag.sig == type)
        {
            if ((tag.size - offset) > *size || !buffer)
            {
                *size = (tag.size - offset);
                release_profile( profile );
                return FALSE;
            }
            MSCMS_get_tag_data( profile->iccprofile, &tag, offset, buffer );

            *ref = FALSE; /* FIXME: calculate properly */
            release_profile( profile );
            return TRUE;
        }
    }
    release_profile( profile );

#endif /* HAVE_LCMS */
    return ret;
}

/******************************************************************************
 * GetColorProfileElementTag               [MSCMS.@]
 *
 * Get the tag type from a color profile by index. 
 *
 * PARAMS
 *  profile  [I]   Handle to a color profile.
 *  index    [I]   Index into the tag table of the color profile.
 *  type     [O]   Pointer to a variable that holds the ICC tag type on return.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 * NOTES
 *  The tag table index starts at 1.
 *  Use GetCountColorProfileElements to retrieve a count of tagged elements.
 */
BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE type )
{
    BOOL ret = FALSE;
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );
    DWORD count;
    icTag tag;

    TRACE( "( %p, %d, %p )\n", handle, index, type );

    if (!profile) return FALSE;

    if (!type)
    {
        release_profile( profile );
        return FALSE;
    }
    count = MSCMS_get_tag_count( profile->iccprofile );
    if (index > count || index < 1)
    {
        release_profile( profile );
        return FALSE;
    }
    MSCMS_get_tag_by_index( profile->iccprofile, index - 1, &tag );
    *type = tag.sig;

    release_profile( profile );
    ret = TRUE;

#endif /* HAVE_LCMS */
    return ret;
}

/******************************************************************************
 * GetColorProfileFromHandle               [MSCMS.@]
 *
 * Retrieve an ICC color profile by handle.
 *
 * PARAMS
 *  profile  [I]   Handle to a color profile.
 *  buffer   [O]   Buffer to receive the ICC profile.
 *  size     [I/O] Size of the buffer in bytes. On return the variable holds the
 *                 number of bytes actually needed.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 * NOTES
 *  The profile returned will be in big-endian format.
 */
BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD size )
{
    BOOL ret = FALSE;
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );
    PROFILEHEADER header;

    TRACE( "( %p, %p, %p )\n", handle, buffer, size );

    if (!profile) return FALSE;

    if (!size)
    {
        release_profile( profile );
        return FALSE;
    }
    MSCMS_get_profile_header( profile->iccprofile, &header );

    if (!buffer || header.phSize > *size)
    {
        *size = header.phSize;
        release_profile( profile );
        return FALSE;
    }

    /* No endian conversion needed */
    memcpy( buffer, profile->iccprofile, header.phSize );
    *size = header.phSize;

    release_profile( profile );
    ret = TRUE;

#endif /* HAVE_LCMS */
    return ret;
}

/******************************************************************************
 * GetColorProfileHeader               [MSCMS.@]
 *
 * Retrieve a color profile header by handle.
 *
 * PARAMS
 *  profile  [I]   Handle to a color profile.
 *  header   [O]   Buffer to receive the ICC profile header.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 * NOTES
 *  The profile header returned will be adjusted for endianess.
 */
BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
{
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );

    TRACE( "( %p, %p )\n", handle, header );

    if (!profile) return FALSE;

    if (!header)
    {
        release_profile( profile );
        return FALSE;
    }
    MSCMS_get_profile_header( profile->iccprofile, header );

    release_profile( profile );
    return TRUE;

#else
    return FALSE;
#endif /* HAVE_LCMS */
}

/******************************************************************************
 * GetCountColorProfileElements               [MSCMS.@]
 *
 * Retrieve the number of elements in a color profile.
 *
 * PARAMS
 *  profile  [I] Handle to a color profile.
 *  count    [O] Pointer to a variable which is set to the number of elements
 *               in the color profile.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
{
    BOOL ret = FALSE;
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );

    TRACE( "( %p, %p )\n", handle, count );

    if (!profile) return FALSE;

    if (!count)
    {
        release_profile( profile );
        return FALSE;
    }
    *count = MSCMS_get_tag_count( profile->iccprofile );

    release_profile( profile );
    ret = TRUE;

#endif /* HAVE_LCMS */
    return ret;
}

/******************************************************************************
 * GetStandardColorSpaceProfileA               [MSCMS.@]
 *
 * See GetStandardColorSpaceProfileW.
 */
BOOL WINAPI GetStandardColorSpaceProfileA( PCSTR machine, DWORD id, PSTR profile, PDWORD size )
{
    INT len;
    LPWSTR profileW;
    BOOL ret = FALSE;
    DWORD sizeW;

    TRACE( "( 0x%08x, %p, %p )\n", id, profile, size );

    if (machine) 
    {
        SetLastError( ERROR_NOT_SUPPORTED );
        return FALSE;
    }

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

    sizeW = *size * sizeof(WCHAR);

    if (!profile)
    {
        ret = GetStandardColorSpaceProfileW( NULL, id, NULL, &sizeW );
        *size = sizeW / sizeof(WCHAR);
        return FALSE;
    }

    profileW = HeapAlloc( GetProcessHeap(), 0, sizeW );

    if (profileW)
    {
        if ((ret = GetStandardColorSpaceProfileW( NULL, id, profileW, &sizeW )))
        {
            *size = WideCharToMultiByte( CP_ACP, 0, profileW, -1, NULL, 0, NULL, NULL );
            len = WideCharToMultiByte( CP_ACP, 0, profileW, -1, profile, *size, NULL, NULL );
            if (!len) ret = FALSE;
        }
        else *size = sizeW / sizeof(WCHAR);

        HeapFree( GetProcessHeap(), 0, profileW );
    }
    return ret;
}

/******************************************************************************
 * GetStandardColorSpaceProfileW               [MSCMS.@]
 *
 * Retrieve the profile filename for a given standard color space id.
 *
 * PARAMS
 *  machine  [I]   Name of the machine for which to get the standard color space.
 *                 Must be NULL, which indicates the local machine.
 *  id       [I]   Id of a standard color space.
 *  profile  [O]   Buffer to receive the profile filename.
 *  size     [I/O] Size of the filename buffer in bytes.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI GetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profile, PDWORD size )
{
    static const WCHAR rgbprofilefile[] =
        { '\\','s','r','g','b',' ','c','o','l','o','r',' ',
          's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
    WCHAR rgbprofile[MAX_PATH];
    DWORD len = sizeof(rgbprofile);

    TRACE( "( 0x%08x, %p, %p )\n", id, profile, size );

    if (machine) 
    {
        SetLastError( ERROR_NOT_SUPPORTED );
        return FALSE;
    }

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

    if (!profile)
    {
        SetLastError( ERROR_INSUFFICIENT_BUFFER );
        return FALSE;
    }

    GetColorDirectoryW( machine, rgbprofile, &len );

    switch (id)
    {
        case SPACE_RGB: /* 'RGB ' */
            lstrcatW( rgbprofile, rgbprofilefile );
            len = lstrlenW( rgbprofile ) * sizeof(WCHAR);

            if (*size < len || !profile)
            {
                *size = len;
                SetLastError( ERROR_MORE_DATA );
                return FALSE;
            }

            lstrcpyW( profile, rgbprofile );
            break;

        default:
            SetLastError( ERROR_FILE_NOT_FOUND );
            return FALSE;
    }
    return TRUE;
}

static BOOL MSCMS_header_from_file( LPCWSTR file, PPROFILEHEADER header )
{
    BOOL ret;
    PROFILE profile;
    WCHAR path[MAX_PATH], slash[] = {'\\',0};
    DWORD size = sizeof(path);
    HANDLE handle;

    ret = GetColorDirectoryW( NULL, path, &size );
    if (!ret)
    {
        WARN( "Can't retrieve color directory\n" );
        return FALSE;
    }
    if (size + sizeof(slash) + sizeof(WCHAR) * lstrlenW( file ) > sizeof(path))
    {
        WARN( "Filename too long\n" );
        return FALSE;
    }

    lstrcatW( path, slash );
    lstrcatW( path, file );

    profile.dwType = PROFILE_FILENAME;
    profile.pProfileData = path;
    profile.cbDataSize = lstrlenW( path ) + 1;

    handle = OpenColorProfileW( &profile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING );
    if (!handle)
    {
        WARN( "Can't open color profile\n" );
        return FALSE;
    }

    ret = GetColorProfileHeader( handle, header );
    if (!ret)
        WARN( "Can't retrieve color profile header\n" );

    CloseColorProfile( handle );
    return ret;
}

static BOOL MSCMS_match_profile( PENUMTYPEW rec, PPROFILEHEADER hdr )
{
    if (rec->dwFields & ET_DEVICENAME)
    {
        FIXME( "ET_DEVICENAME: %s\n", debugstr_w(rec->pDeviceName) );
    }
    if (rec->dwFields & ET_MEDIATYPE)
    {
        FIXME( "ET_MEDIATYPE: 0x%08x\n", rec->dwMediaType );
    }
    if (rec->dwFields & ET_DITHERMODE)
    {
        FIXME( "ET_DITHERMODE: 0x%08x\n", rec->dwDitheringMode );
    }
    if (rec->dwFields & ET_RESOLUTION)
    {
        FIXME( "ET_RESOLUTION: 0x%08x, 0x%08x\n",
               rec->dwResolution[0], rec->dwResolution[1] );
    }
    if (rec->dwFields & ET_DEVICECLASS)
    {
        FIXME( "ET_DEVICECLASS: %s\n", MSCMS_dbgstr_tag(rec->dwMediaType) );
    }
    if (rec->dwFields & ET_CMMTYPE)
    {
        TRACE( "ET_CMMTYPE: %s\n", MSCMS_dbgstr_tag(rec->dwCMMType) );
        if (rec->dwCMMType != hdr->phCMMType) return FALSE;
    }
    if (rec->dwFields & ET_CLASS)
    {
        TRACE( "ET_CLASS: %s\n", MSCMS_dbgstr_tag(rec->dwClass) );
        if (rec->dwClass != hdr->phClass) return FALSE;
    }
    if (rec->dwFields & ET_DATACOLORSPACE)
    {
        TRACE( "ET_DATACOLORSPACE: %s\n", MSCMS_dbgstr_tag(rec->dwDataColorSpace) );
        if (rec->dwDataColorSpace != hdr->phDataColorSpace) return FALSE;
    }
    if (rec->dwFields & ET_CONNECTIONSPACE)
    {
        TRACE( "ET_CONNECTIONSPACE: %s\n", MSCMS_dbgstr_tag(rec->dwConnectionSpace) );
        if (rec->dwConnectionSpace != hdr->phConnectionSpace) return FALSE;
    }
    if (rec->dwFields & ET_SIGNATURE)
    {
        TRACE( "ET_SIGNATURE: %s\n", MSCMS_dbgstr_tag(rec->dwSignature) );
        if (rec->dwSignature != hdr->phSignature) return FALSE;
    }
    if (rec->dwFields & ET_PLATFORM)
    {
        TRACE( "ET_PLATFORM: %s\n", MSCMS_dbgstr_tag(rec->dwPlatform) );
        if (rec->dwPlatform != hdr->phPlatform) return FALSE;
    }
    if (rec->dwFields & ET_PROFILEFLAGS)
    {
        TRACE( "ET_PROFILEFLAGS: 0x%08x\n", rec->dwProfileFlags );
        if (rec->dwProfileFlags != hdr->phProfileFlags) return FALSE;
    }
    if (rec->dwFields & ET_MANUFACTURER)
    {
        TRACE( "ET_MANUFACTURER: %s\n", MSCMS_dbgstr_tag(rec->dwManufacturer) );
        if (rec->dwManufacturer != hdr->phManufacturer) return FALSE;
    }
    if (rec->dwFields & ET_MODEL)
    {
        TRACE( "ET_MODEL: %s\n", MSCMS_dbgstr_tag(rec->dwModel) );
        if (rec->dwModel != hdr->phModel) return FALSE;
    }
    if (rec->dwFields & ET_ATTRIBUTES)
    {
        TRACE( "ET_ATTRIBUTES: 0x%08x, 0x%08x\n",
               rec->dwAttributes[0], rec->dwAttributes[1] );
        if (rec->dwAttributes[0] != hdr->phAttributes[0] || 
            rec->dwAttributes[1] != hdr->phAttributes[1]) return FALSE;
    }
    if (rec->dwFields & ET_RENDERINGINTENT)
    {
        TRACE( "ET_RENDERINGINTENT: 0x%08x\n", rec->dwRenderingIntent );
        if (rec->dwRenderingIntent != hdr->phRenderingIntent) return FALSE;
    }
    if (rec->dwFields & ET_CREATOR)
    {
        TRACE( "ET_CREATOR: %s\n", MSCMS_dbgstr_tag(rec->dwCreator) );
        if (rec->dwCreator != hdr->phCreator) return FALSE;
    }
    return TRUE;
}

/******************************************************************************
 * EnumColorProfilesA               [MSCMS.@]
 *
 * See EnumColorProfilesW.
 */
BOOL WINAPI EnumColorProfilesA( PCSTR machine, PENUMTYPEA record, PBYTE buffer,
                                PDWORD size, PDWORD number )
{
    BOOL match, ret = FALSE;
    char spec[] = "\\*.icm";
    char colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL;
    DWORD i, len = sizeof(colordir), count = 0, totalsize = 0;
    PROFILEHEADER header;
    WIN32_FIND_DATAA data;
    ENUMTYPEW recordW;
    WCHAR *fileW = NULL, *deviceW = NULL;
    HANDLE find;

    TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number );

    if (machine || !record || !size ||
        record->dwSize != sizeof(ENUMTYPEA) ||
        record->dwVersion != ENUM_TYPE_VERSION) return FALSE;

    ret = GetColorDirectoryA( machine, colordir, &len );
    if (!ret || len + sizeof(spec) > MAX_PATH)
    {
        WARN( "can't retrieve color directory\n" );
        return FALSE;
    }

    lstrcpyA( glob, colordir );
    lstrcatA( glob, spec );

    find = FindFirstFileA( glob, &data );
    if (find == INVALID_HANDLE_VALUE) return FALSE;

    profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(char *) + 1 );
    if (!profiles) goto exit;

    memcpy( &recordW, record, sizeof(ENUMTYPEA) );
    if (record->pDeviceName)
    {
        deviceW = MSCMS_strdupW( record->pDeviceName );
        if (!(recordW.pDeviceName = deviceW)) goto exit;
    }

    fileW = MSCMS_strdupW( data.cFileName );
    if (!fileW) goto exit;

    ret = MSCMS_header_from_file( fileW, &header );
    if (ret)
    {
        match = MSCMS_match_profile( &recordW, &header );
        if (match)
        {
            len = sizeof(char) * (lstrlenA( data.cFileName ) + 1);
            profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );

            if (!profiles[count]) goto exit;
            else
            {
                TRACE( "matching profile: %s\n", debugstr_a(data.cFileName) );
                lstrcpyA( profiles[count], data.cFileName );
                totalsize += len;
                count++;
            }
        }
    }
    HeapFree( GetProcessHeap(), 0, fileW );
    fileW = NULL;

    while (FindNextFileA( find, &data ))
    {
        fileW = MSCMS_strdupW( data.cFileName );
        if (!fileW) goto exit;

        ret = MSCMS_header_from_file( fileW, &header );
        if (!ret)
        {
            HeapFree( GetProcessHeap(), 0, fileW );
            continue;
        }

        match = MSCMS_match_profile( &recordW, &header );
        if (match)
        {
            char **tmp = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
                                      profiles, sizeof(char *) * (count + 1) );
            if (!tmp) goto exit;
            else profiles = tmp;

            len = sizeof(char) * (lstrlenA( data.cFileName ) + 1);
            profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );

            if (!profiles[count]) goto exit;
            else
            {
                TRACE( "matching profile: %s\n", debugstr_a(data.cFileName) );
                lstrcpyA( profiles[count], data.cFileName );
                totalsize += len;
                count++;
            }
        }
        HeapFree( GetProcessHeap(), 0, fileW );
        fileW = NULL;
    }

    totalsize++;
    if (buffer && *size >= totalsize)
    {
        char *p = (char *)buffer;

        for (i = 0; i < count; i++)
        {
            lstrcpyA( p, profiles[i] );
            p += lstrlenA( profiles[i] ) + 1;
        }
        *p = 0;
        ret = TRUE;
    }
    else ret = FALSE;

    *size = totalsize;
    if (number) *number = count;

exit:
    for (i = 0; i < count; i++)
        HeapFree( GetProcessHeap(), 0, profiles[i] );
    HeapFree( GetProcessHeap(), 0, profiles );
    HeapFree( GetProcessHeap(), 0, deviceW );
    HeapFree( GetProcessHeap(), 0, fileW );
    FindClose( find );

    return ret;
}

/******************************************************************************
 * EnumColorProfilesW               [MSCMS.@]
 *
 * Enumerate profiles that match given criteria.
 *
 * PARAMS
 *  machine  [I]   Name of the machine for which to enumerate profiles.
 *                 Must be NULL, which indicates the local machine.
 *  record   [I]   Record of criteria that a profile must match.
 *  buffer   [O]   Buffer to receive a string array of profile filenames.
 *  size     [I/O] Size of the filename buffer in bytes.
 *  number   [O]   Number of filenames copied into buffer.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI EnumColorProfilesW( PCWSTR machine, PENUMTYPEW record, PBYTE buffer,
                                PDWORD size, PDWORD number )
{
    BOOL match, ret = FALSE;
    WCHAR spec[] = {'\\','*','i','c','m',0};
    WCHAR colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL;
    DWORD i, len = sizeof(colordir), count = 0, totalsize = 0;
    PROFILEHEADER header;
    WIN32_FIND_DATAW data;
    HANDLE find;

    TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number );

    if (machine || !record || !size ||
        record->dwSize != sizeof(ENUMTYPEW) ||
        record->dwVersion != ENUM_TYPE_VERSION) return FALSE;

    ret = GetColorDirectoryW( machine, colordir, &len );
    if (!ret || len + sizeof(spec) > MAX_PATH)
    {
        WARN( "Can't retrieve color directory\n" );
        return FALSE;
    }

    lstrcpyW( glob, colordir );
    lstrcatW( glob, spec );

    find = FindFirstFileW( glob, &data );
    if (find == INVALID_HANDLE_VALUE) return FALSE;

    profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR *) + 1 );
    if (!profiles) goto exit;

    ret = MSCMS_header_from_file( data.cFileName, &header );
    if (ret)
    {
        match = MSCMS_match_profile( record, &header );
        if (match)
        {
            len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1);
            profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );

            if (!profiles[count]) goto exit;
            else
            {
                TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) );
                lstrcpyW( profiles[count], data.cFileName );
                totalsize += len;
                count++;
            }
        }
    }

    while (FindNextFileW( find, &data ))
    {
        ret = MSCMS_header_from_file( data.cFileName, &header );
        if (!ret) continue;

        match = MSCMS_match_profile( record, &header );
        if (match)
        {
            WCHAR **tmp = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
                                       profiles, sizeof(WCHAR *) * (count + 1) );
            if (!tmp) goto exit;
            else profiles = tmp;

            len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1);
            profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );

            if (!profiles[count]) goto exit;
            else
            {
                TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) );
                lstrcpyW( profiles[count], data.cFileName );
                totalsize += len;
                count++;
            }
        }
    }

    totalsize++;
    if (buffer && *size >= totalsize)
    {
        WCHAR *p = (WCHAR *)buffer;

        for (i = 0; i < count; i++)
        {
            lstrcpyW( p, profiles[i] );
            p += lstrlenW( profiles[i] ) + 1;
        }
        *p = 0;
        ret = TRUE;
    }
    else ret = FALSE;

    *size = totalsize;
    if (number) *number = count;

exit:
    for (i = 0; i < count; i++)
        HeapFree( GetProcessHeap(), 0, profiles[i] );
    HeapFree( GetProcessHeap(), 0, profiles );
    FindClose( find );

    return ret;
}

/******************************************************************************
 * InstallColorProfileA               [MSCMS.@]
 *
 * See InstallColorProfileW.
 */
BOOL WINAPI InstallColorProfileA( PCSTR machine, PCSTR profile )
{
    UINT len;
    LPWSTR profileW;
    BOOL ret = FALSE;

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

    if (machine || !profile) return FALSE;

    len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
    profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );

    if (profileW)
    {
        MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );

        ret = InstallColorProfileW( NULL, profileW );
        HeapFree( GetProcessHeap(), 0, profileW );
    }
    return ret;
}

/******************************************************************************
 * InstallColorProfileW               [MSCMS.@]
 *
 * Install a color profile.
 *
 * PARAMS
 *  machine  [I] Name of the machine to install the profile on. Must be NULL,
 *               which indicates the local machine.
 *  profile  [I] Full path name of the profile to install.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile )
{
    WCHAR dest[MAX_PATH], base[MAX_PATH];
    DWORD size = sizeof(dest);
    static const WCHAR slash[] = { '\\', 0 };

    TRACE( "( %s )\n", debugstr_w(profile) );

    if (machine || !profile) return FALSE;

    if (!GetColorDirectoryW( machine, dest, &size )) return FALSE;

    MSCMS_basename( profile, base );

    lstrcatW( dest, slash );
    lstrcatW( dest, base );

    /* Is source equal to destination? */
    if (!lstrcmpW( profile, dest )) return TRUE;

    return CopyFileW( profile, dest, TRUE );
}

/******************************************************************************
 * IsColorProfileTagPresent               [MSCMS.@]
 *
 * Determine if a given ICC tag type is present in a color profile.
 *
 * PARAMS
 *  profile  [I] Color profile handle.
 *  tag      [I] ICC tag type.
 *  present  [O] Pointer to a BOOL variable. Set to TRUE if tag type is present,
 *               FALSE otherwise.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL present )
{
    BOOL ret = FALSE;
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );
    DWORD i, count;
    icTag tag;

    TRACE( "( %p, 0x%08x, %p )\n", handle, type, present );

    if (!profile) return FALSE;

    if (!present)
    {
        release_profile( profile );
        return FALSE;
    }
    count = MSCMS_get_tag_count( profile->iccprofile );

    for (i = 0; i < count; i++)
    {
        MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );

        if (tag.sig == type)
        {
            *present = ret = TRUE;
            break;
        }
    }
    release_profile( profile );

#endif /* HAVE_LCMS */
    return ret;
}

/******************************************************************************
 * IsColorProfileValid               [MSCMS.@]
 *
 * Determine if a given color profile is valid.
 *
 * PARAMS
 *  profile  [I] Color profile handle.
 *  valid    [O] Pointer to a BOOL variable. Set to TRUE if profile is valid,
 *               FALSE otherwise.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE 
 */
BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
{
    BOOL ret = FALSE;
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );

    TRACE( "( %p, %p )\n", handle, valid );

    if (!profile) return FALSE;

    if (!valid)
    {
        release_profile( profile );
        return FALSE;
    }
    if (profile->iccprofile) ret = *valid = TRUE;
    release_profile( profile );

#endif /* HAVE_LCMS */
    return ret;
}

/******************************************************************************
 * SetColorProfileElement               [MSCMS.@]
 *
 * Set data for a specified tag type.
 *
 * PARAMS
 *  profile  [I]   Handle to a color profile.
 *  type     [I]   ICC tag type.
 *  offset   [I]   Offset in bytes to start copying to.
 *  size     [I/O] Size of the buffer in bytes. On return the variable holds the
 *                 number of bytes actually needed.
 *  buffer   [O]   Buffer holding the tag data.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
                                    PVOID buffer )
{
    BOOL ret = FALSE;
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );
    DWORD i, count;
    icTag tag;

    TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer );

    if (!profile) return FALSE;

    if (!size || !buffer || !(profile->access & PROFILE_READWRITE))
    {
        release_profile( profile );
        return FALSE;
    }
    count = MSCMS_get_tag_count( profile->iccprofile );

    for (i = 0; i < count; i++)
    {
        MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );

        if (tag.sig == type)
        {
            if (offset > tag.size)
            {
                release_profile( profile );
                return FALSE;
            }
            MSCMS_set_tag_data( profile->iccprofile, &tag, offset, buffer );

            release_profile( profile );
            return TRUE;
        }
    }
    release_profile( profile );

#endif /* HAVE_LCMS */
    return ret;
}

/******************************************************************************
 * SetColorProfileHeader               [MSCMS.@]
 *
 * Set header data for a given profile.
 *
 * PARAMS
 *  profile  [I] Handle to a color profile.
 *  header   [I] Buffer holding the header data.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
{
#ifdef HAVE_LCMS
    struct profile *profile = grab_profile( handle );

    TRACE( "( %p, %p )\n", handle, header );

    if (!profile) return FALSE;

    if (!header || !(profile->access & PROFILE_READWRITE))
    {
        release_profile( profile );
        return FALSE;
    }
    MSCMS_set_profile_header( profile->iccprofile, header );

    release_profile( profile );
    return TRUE;

#else
    return FALSE;
#endif /* HAVE_LCMS */
}

/******************************************************************************
 * UninstallColorProfileA               [MSCMS.@]
 *
 * See UninstallColorProfileW.
 */
BOOL WINAPI UninstallColorProfileA( PCSTR machine, PCSTR profile, BOOL delete )
{
    UINT len;
    LPWSTR profileW;
    BOOL ret = FALSE;

    TRACE( "( %s, %x )\n", debugstr_a(profile), delete );

    if (machine || !profile) return FALSE;

    len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
    profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );

    if (profileW)
    {
        MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );

        ret = UninstallColorProfileW( NULL, profileW , delete );

        HeapFree( GetProcessHeap(), 0, profileW );
    }
    return ret;
}

/******************************************************************************
 * UninstallColorProfileW               [MSCMS.@]
 *
 * Uninstall a color profile.
 *
 * PARAMS
 *  machine  [I] Name of the machine to uninstall the profile on. Must be NULL,
 *               which indicates the local machine.
 *  profile  [I] Full path name of the profile to uninstall.
 *  delete   [I] Bool that specifies whether the profile file should be deleted.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI UninstallColorProfileW( PCWSTR machine, PCWSTR profile, BOOL delete )
{
    TRACE( "( %s, %x )\n", debugstr_w(profile), delete );

    if (machine || !profile) return FALSE;

    if (delete) return DeleteFileW( profile );

    return TRUE;
}

/******************************************************************************
 * OpenColorProfileA               [MSCMS.@]
 *
 * See OpenColorProfileW.
 */
HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
{
    HPROFILE handle = NULL;

    TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation );

    if (!profile || !profile->pProfileData) return NULL;

    /* No AW conversion needed for memory based profiles */
    if (profile->dwType & PROFILE_MEMBUFFER)
        return OpenColorProfileW( profile, access, sharing, creation );

    if (profile->dwType & PROFILE_FILENAME)
    {
        UINT len;
        PROFILE profileW;

        profileW.dwType = profile->dwType;
 
        len = MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, NULL, 0 );
        profileW.pProfileData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );

        if (profileW.pProfileData)
        {
            profileW.cbDataSize = len * sizeof(WCHAR);
            MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, profileW.pProfileData, len );

            handle = OpenColorProfileW( &profileW, access, sharing, creation );
            HeapFree( GetProcessHeap(), 0, profileW.pProfileData );
        }
    }
    return handle;
}

/******************************************************************************
 * OpenColorProfileW               [MSCMS.@]
 *
 * Open a color profile.
 *
 * PARAMS
 *  profile   [I] Pointer to a color profile structure.
 *  access    [I] Desired access.
 *  sharing   [I] Sharing mode.
 *  creation  [I] Creation mode.
 *
 * RETURNS
 *  Success: Handle to the opened profile.
 *  Failure: NULL
 *
 * NOTES
 *  Values for access:   PROFILE_READ or PROFILE_READWRITE.
 *  Values for sharing:  0 (no sharing), FILE_SHARE_READ and/or FILE_SHARE_WRITE.
 *  Values for creation: one of CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING,
 *                       OPEN_ALWAYS, TRUNCATE_EXISTING.
 *  Sharing and creation flags are ignored for memory based profiles.
 */
HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
{
#ifdef HAVE_LCMS
    cmsHPROFILE cmsprofile = NULL;
    icProfile *iccprofile = NULL;
    HANDLE handle = INVALID_HANDLE_VALUE;

    TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation );

    if (!profile || !profile->pProfileData) return NULL;

    if (profile->dwType == PROFILE_MEMBUFFER)
    {
        /* FIXME: access flags not implemented for memory based profiles */

        if (!(iccprofile = HeapAlloc( GetProcessHeap(), 0, profile->cbDataSize ))) return NULL;
        memcpy( iccprofile, profile->pProfileData, profile->cbDataSize );

        cmsprofile = cmsOpenProfileFromMem( iccprofile, profile->cbDataSize );
    }
    else if (profile->dwType == PROFILE_FILENAME)
    {
        DWORD size, read, flags = 0;

        TRACE( "profile file: %s\n", debugstr_w( profile->pProfileData ) );

        if (access & PROFILE_READ) flags = GENERIC_READ;
        if (access & PROFILE_READWRITE) flags = GENERIC_READ|GENERIC_WRITE;

        if (!flags) return NULL;
        if (!sharing) sharing = FILE_SHARE_READ;

        handle = CreateFileW( profile->pProfileData, flags, sharing, NULL, creation, 0, NULL );
        if (handle == INVALID_HANDLE_VALUE)
        {
            WARN( "Unable to open color profile %u\n", GetLastError() );
            return NULL;
        }

        if ((size = GetFileSize( handle, NULL )) == INVALID_FILE_SIZE)
        {
            ERR( "Unable to retrieve size of color profile\n" );
            CloseHandle( handle );
            return NULL;
        }

        iccprofile = HeapAlloc( GetProcessHeap(), 0, size );
        if (!iccprofile)
        {
            ERR( "Unable to allocate memory for color profile\n" );
            CloseHandle( handle );
            return NULL;
        }

        if (!ReadFile( handle, iccprofile, size, &read, NULL ) || read != size)
        {
            ERR( "Unable to read color profile\n" );

            CloseHandle( handle );
            HeapFree( GetProcessHeap(), 0, iccprofile );
            return NULL;
        }

        cmsprofile = cmsOpenProfileFromMem( iccprofile, size );
    }
    else
    {
        ERR( "Invalid profile type %u\n", profile->dwType );
        return NULL;
    }

    if (cmsprofile)
    {
        struct profile profile;

        profile.file = handle;
        profile.access = access;
        profile.iccprofile = iccprofile;
        profile.cmsprofile = cmsprofile;

        return create_profile( &profile );
    }

#endif /* HAVE_LCMS */
    return NULL;
}

/******************************************************************************
 * CloseColorProfile               [MSCMS.@]
 *
 * Close a color profile.
 *
 * PARAMS
 *  profile  [I] Handle to the profile.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI CloseColorProfile( HPROFILE profile )
{
    BOOL ret = FALSE;
#ifdef HAVE_LCMS

    TRACE( "( %p )\n", profile );
    ret = close_profile( profile );

#endif /* HAVE_LCMS */
    return ret;
}
