mscms: Implement EnumColorProfiles{A,W}.
This commit is contained in:
parent
f1a0835267
commit
05b073da0d
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* MSCMS - Color Management System for Wine
|
||||
*
|
||||
* Copyright 2004, 2005 Hans Leidekker
|
||||
* Copyright 2004, 2005, 2006 Hans Leidekker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -42,6 +42,24 @@ static void MSCMS_basename( LPCWSTR path, LPWSTR name )
|
|||
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;
|
||||
}
|
||||
|
||||
static 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);
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -452,6 +470,397 @@ BOOL WINAPI GetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profi
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL MSCMS_header_from_file( LPWSTR 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%08lx\n", rec->dwMediaType );
|
||||
}
|
||||
if (rec->dwFields & ET_DITHERMODE)
|
||||
{
|
||||
FIXME( "ET_DITHERMODE: 0x%08lx\n", rec->dwDitheringMode );
|
||||
}
|
||||
if (rec->dwFields & ET_RESOLUTION)
|
||||
{
|
||||
FIXME( "ET_RESOLUTION: 0x%08lx, 0x%08lx\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%08lx\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%08lx, 0x%08lx\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%08lx\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[] = "\\*";
|
||||
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;
|
||||
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)
|
||||
{
|
||||
recordW.pDeviceName = MSCMS_strdupW( record->pDeviceName );
|
||||
if (!recordW.pDeviceName) 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, (WCHAR *)recordW.pDeviceName );
|
||||
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[] = {'\\','*',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.@]
|
||||
*
|
||||
|
|
|
@ -114,22 +114,6 @@ BOOL WINAPI DisassociateColorProfileFromDeviceW( PCWSTR machine, PCWSTR profile,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI EnumColorProfilesA( PCSTR machine, PENUMTYPEA record, PBYTE buffer, PDWORD size,
|
||||
PDWORD number )
|
||||
{
|
||||
FIXME( "( %p, %p, %p, %p, %p ) stub\n", machine, record, buffer, size, number );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI EnumColorProfilesW( PCWSTR machine, PENUMTYPEW record, PBYTE buffer, PDWORD size,
|
||||
PDWORD number )
|
||||
{
|
||||
FIXME( "( %p, %p, %p, %p, %p ) stub\n", machine, record, buffer, size, number );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD WINAPI GenerateCopyFilePaths( LPCWSTR printer, LPCWSTR directory, LPBYTE clientinfo,
|
||||
DWORD level, LPWSTR sourcedir, LPDWORD sourcedirsize,
|
||||
LPWSTR targetdir, LPDWORD targetdirsize, DWORD flags )
|
||||
|
|
|
@ -207,6 +207,8 @@ typedef struct tagPROFILE
|
|||
DWORD cbDataSize;
|
||||
} PROFILE, *PPROFILE, *LPPROFILE;
|
||||
|
||||
#define ENUM_TYPE_VERSION 0x0300
|
||||
|
||||
typedef struct tagENUMTYPEA
|
||||
{
|
||||
DWORD dwSize;
|
||||
|
@ -255,6 +257,24 @@ typedef struct tagENUMTYPEW
|
|||
DWORD dwDeviceClass;
|
||||
} ENUMTYPEW, *PENUMTYPEW, *LPENUMTYPEW;
|
||||
|
||||
#define ET_DEVICENAME 0x00000001
|
||||
#define ET_MEDIATYPE 0x00000002
|
||||
#define ET_DITHERMODE 0x00000004
|
||||
#define ET_RESOLUTION 0x00000008
|
||||
#define ET_CMMTYPE 0x00000010
|
||||
#define ET_CLASS 0x00000020
|
||||
#define ET_DATACOLORSPACE 0x00000040
|
||||
#define ET_CONNECTIONSPACE 0x00000080
|
||||
#define ET_SIGNATURE 0x00000100
|
||||
#define ET_PLATFORM 0x00000200
|
||||
#define ET_PROFILEFLAGS 0x00000400
|
||||
#define ET_MANUFACTURER 0x00000800
|
||||
#define ET_MODEL 0x00001000
|
||||
#define ET_ATTRIBUTES 0x00002000
|
||||
#define ET_RENDERINGINTENT 0x00004000
|
||||
#define ET_CREATOR 0x00008000
|
||||
#define ET_DEVICECLASS 0x00010000
|
||||
|
||||
struct _tagCOLORMATCHSETUPA;
|
||||
struct _tagCOLORMATCHSETUPW;
|
||||
|
||||
|
|
Loading…
Reference in New Issue