ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

profile.c
Go to the documentation of this file.
00001 /*
00002  * MSCMS - Color Management System for Wine
00003  *
00004  * Copyright 2004, 2005, 2006, 2008 Hans Leidekker
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 #include "wine/debug.h"
00023 #include "wine/unicode.h"
00024 
00025 #include <stdarg.h>
00026 
00027 #include "windef.h"
00028 #include "winbase.h"
00029 #include "winnls.h"
00030 #include "wingdi.h"
00031 #include "winuser.h"
00032 #include "winreg.h"
00033 #include "shlwapi.h"
00034 #include "icm.h"
00035 
00036 #include "mscms_priv.h"
00037 
00038 #define IS_SEPARATOR(ch)  ((ch) == '\\' || (ch) == '/')
00039 
00040 static void MSCMS_basename( LPCWSTR path, LPWSTR name )
00041 {
00042     INT i = lstrlenW( path );
00043 
00044     while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
00045     lstrcpyW( name, &path[i] );
00046 }
00047 
00048 static inline LPWSTR MSCMS_strdupW( LPCSTR str )
00049 {
00050     LPWSTR ret = NULL;
00051     if (str)
00052     {
00053         DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
00054         if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
00055             MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
00056     }
00057     return ret;
00058 }
00059 
00060 const char *MSCMS_dbgstr_tag( DWORD tag )
00061 {
00062     return wine_dbg_sprintf( "'%c%c%c%c'",
00063         (char)(tag >> 24), (char)(tag >> 16), (char)(tag >> 8), (char)(tag) );
00064 }
00065 
00066 WINE_DEFAULT_DEBUG_CHANNEL(mscms);
00067 
00068 /******************************************************************************
00069  * AssociateColorProfileWithDeviceA               [MSCMS.@]
00070  */
00071 BOOL WINAPI AssociateColorProfileWithDeviceA( PCSTR machine, PCSTR profile, PCSTR device )
00072 {
00073     int len;
00074     BOOL ret = FALSE;
00075     WCHAR *profileW, *deviceW;
00076 
00077     TRACE( "( %s, %s, %s )\n", debugstr_a(machine), debugstr_a(profile), debugstr_a(device) );
00078 
00079     if (!profile || !device)
00080     {
00081         SetLastError( ERROR_INVALID_PARAMETER );
00082         return FALSE;
00083     }
00084     if (machine)
00085     {
00086         SetLastError( ERROR_NOT_SUPPORTED );
00087         return FALSE;
00088     }
00089 
00090     len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
00091     if (!(profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
00092 
00093     MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
00094 
00095     len = MultiByteToWideChar( CP_ACP, 0, device, -1, NULL, 0 );
00096     if ((deviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
00097     {
00098         MultiByteToWideChar( CP_ACP, 0, device, -1, deviceW, len );
00099         ret = AssociateColorProfileWithDeviceW( NULL, profileW, deviceW );
00100     }
00101 
00102     HeapFree( GetProcessHeap(), 0, profileW );
00103     HeapFree( GetProcessHeap(), 0, deviceW );
00104     return ret;
00105 }
00106 
00107 static BOOL set_profile_device_key( PCWSTR file, const BYTE *value, DWORD size )
00108 {
00109     static const WCHAR fmtW[] = {'%','c','%','c','%','c','%','c',0};
00110     static const WCHAR icmW[] = {'S','o','f','t','w','a','r','e','\\',
00111                                  'M','i','c','r','o','s','o','f','t','\\',
00112                                  'W','i','n','d','o','w','s',' ','N','T','\\',
00113                                  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
00114                                  'I','C','M',0};
00115     PROFILEHEADER header;
00116     PROFILE profile;
00117     HPROFILE handle;
00118     HKEY icm_key, class_key;
00119     WCHAR basenameW[MAX_PATH], classW[5];
00120 
00121     profile.dwType = PROFILE_FILENAME;
00122     profile.pProfileData = (PVOID)file;
00123     profile.cbDataSize = (lstrlenW( file ) + 1) * sizeof(WCHAR);
00124 
00125     /* FIXME is the profile installed? */
00126     if (!(handle = OpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING )))
00127     {
00128         SetLastError( ERROR_INVALID_PROFILE );
00129         return FALSE;
00130     }
00131     if (!GetColorProfileHeader( handle, &header ))
00132     {
00133         CloseColorProfile( handle );
00134         SetLastError( ERROR_INVALID_PROFILE );
00135         return FALSE;
00136     }
00137     RegCreateKeyExW( HKEY_LOCAL_MACHINE, icmW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &icm_key, NULL );
00138 
00139     MSCMS_basename( file, basenameW );
00140     sprintfW( classW, fmtW, (header.phClass >> 24) & 0xff, (header.phClass >> 16) & 0xff,
00141                             (header.phClass >> 8) & 0xff,  header.phClass & 0xff );
00142 
00143     RegCreateKeyExW( icm_key, classW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &class_key, NULL );
00144     if (value) RegSetValueExW( class_key, basenameW, 0, REG_BINARY, value, size );
00145     else RegDeleteValueW( class_key, basenameW );
00146 
00147     RegCloseKey( class_key );
00148     RegCloseKey( icm_key );
00149     CloseColorProfile( handle );
00150     return TRUE;
00151 }
00152 
00153 /******************************************************************************
00154  * AssociateColorProfileWithDeviceW               [MSCMS.@]
00155  */
00156 BOOL WINAPI AssociateColorProfileWithDeviceW( PCWSTR machine, PCWSTR profile, PCWSTR device )
00157 {
00158     static const BYTE dummy_value[12];
00159 
00160     TRACE( "( %s, %s, %s )\n", debugstr_w(machine), debugstr_w(profile), debugstr_w(device) );
00161 
00162     if (!profile || !device)
00163     {
00164         SetLastError( ERROR_INVALID_PARAMETER );
00165         return FALSE;
00166     }
00167     if (machine)
00168     {
00169         SetLastError( ERROR_NOT_SUPPORTED );
00170         return FALSE;
00171     }
00172 
00173     return set_profile_device_key( profile, dummy_value, sizeof(dummy_value) );
00174 }
00175 
00176 /******************************************************************************
00177  * DisassociateColorProfileFromDeviceA            [MSCMS.@]
00178  */
00179 BOOL WINAPI DisassociateColorProfileFromDeviceA( PCSTR machine, PCSTR profile, PCSTR device )
00180 {
00181     int len;
00182     BOOL ret = FALSE;
00183     WCHAR *profileW, *deviceW;
00184 
00185     TRACE( "( %s, %s, %s )\n", debugstr_a(machine), debugstr_a(profile), debugstr_a(device) );
00186 
00187     if (!profile || !device)
00188     {
00189         SetLastError( ERROR_INVALID_PARAMETER );
00190         return FALSE;
00191     }
00192     if (machine)
00193     {
00194         SetLastError( ERROR_NOT_SUPPORTED );
00195         return FALSE;
00196     }
00197 
00198     len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
00199     if (!(profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
00200 
00201     MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
00202 
00203     len = MultiByteToWideChar( CP_ACP, 0, device, -1, NULL, 0 );
00204     if ((deviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
00205     {
00206         MultiByteToWideChar( CP_ACP, 0, device, -1, deviceW, len );
00207         ret = DisassociateColorProfileFromDeviceW( NULL, profileW, deviceW );
00208     }
00209 
00210     HeapFree( GetProcessHeap(), 0, profileW );
00211     HeapFree( GetProcessHeap(), 0, deviceW );
00212     return ret;
00213 }
00214 
00215 /******************************************************************************
00216  * DisassociateColorProfileFromDeviceW            [MSCMS.@]
00217  */
00218 BOOL WINAPI DisassociateColorProfileFromDeviceW( PCWSTR machine, PCWSTR profile, PCWSTR device )
00219 {
00220     TRACE( "( %s, %s, %s )\n", debugstr_w(machine), debugstr_w(profile), debugstr_w(device) );
00221 
00222     if (!profile || !device)
00223     {
00224         SetLastError( ERROR_INVALID_PARAMETER );
00225         return FALSE;
00226     }
00227     if (machine)
00228     {
00229         SetLastError( ERROR_NOT_SUPPORTED );
00230         return FALSE;
00231     }
00232 
00233     return set_profile_device_key( profile, NULL, 0 );
00234 }
00235 
00236 /******************************************************************************
00237  * GetColorDirectoryA               [MSCMS.@]
00238  *
00239  * See GetColorDirectoryW.
00240  */
00241 BOOL WINAPI GetColorDirectoryA( PCSTR machine, PSTR buffer, PDWORD size )
00242 {
00243     INT len;
00244     LPWSTR bufferW;
00245     BOOL ret = FALSE;
00246     DWORD sizeW;
00247 
00248     TRACE( "( %p, %p )\n", buffer, size );
00249 
00250     if (machine || !size) return FALSE;
00251 
00252     if (!buffer)
00253     {
00254         ret = GetColorDirectoryW( NULL, NULL, &sizeW );
00255         *size = sizeW / sizeof(WCHAR);
00256         return ret;
00257     }
00258 
00259     sizeW = *size * sizeof(WCHAR);
00260 
00261     bufferW = HeapAlloc( GetProcessHeap(), 0, sizeW );
00262     if (bufferW)
00263     {
00264         if ((ret = GetColorDirectoryW( NULL, bufferW, &sizeW )))
00265         {
00266             *size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
00267             len = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, *size, NULL, NULL );
00268             if (!len) ret = FALSE;
00269         }
00270         else *size = sizeW / sizeof(WCHAR);
00271 
00272         HeapFree( GetProcessHeap(), 0, bufferW );
00273     }
00274     return ret;
00275 }
00276 
00277 /******************************************************************************
00278  * GetColorDirectoryW               [MSCMS.@]
00279  *
00280  * Get the directory where color profiles are stored.
00281  *
00282  * PARAMS
00283  *  machine  [I]   Name of the machine for which to get the color directory.
00284  *                 Must be NULL, which indicates the local machine.
00285  *  buffer   [I]   Buffer to receive the path name.
00286  *  size     [I/O] Size of the buffer in bytes. On return the variable holds
00287  *                 the number of bytes actually needed.
00288  */
00289 BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
00290 {
00291     WCHAR colordir[MAX_PATH];
00292     static const WCHAR colorsubdir[] =
00293         {'\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\','c','o','l','o','r',0};
00294     DWORD len;
00295 
00296     TRACE( "( %p, %p )\n", buffer, size );
00297 
00298     if (machine || !size) return FALSE;
00299 
00300     GetSystemDirectoryW( colordir, sizeof(colordir) / sizeof(WCHAR) );
00301     lstrcatW( colordir, colorsubdir );
00302 
00303     len = lstrlenW( colordir ) * sizeof(WCHAR);
00304 
00305     if (buffer && len <= *size)
00306     {
00307         lstrcpyW( buffer, colordir );
00308         *size = len;
00309         return TRUE;
00310     }
00311 
00312     SetLastError( ERROR_MORE_DATA );
00313     *size = len;
00314     return FALSE;
00315 }
00316 
00317 /******************************************************************************
00318  * GetColorProfileElement               [MSCMS.@]
00319  *
00320  * Retrieve data for a specified tag type.
00321  *
00322  * PARAMS
00323  *  profile  [I]   Handle to a color profile.
00324  *  type     [I]   ICC tag type. 
00325  *  offset   [I]   Offset in bytes to start copying from. 
00326  *  size     [I/O] Size of the buffer in bytes. On return the variable holds
00327  *                 the number of bytes actually needed.
00328  *  buffer   [O]   Buffer to receive the tag data.
00329  *  ref      [O]   Pointer to a BOOL that specifies whether more than one tag
00330  *                 references the data.
00331  *
00332  * RETURNS
00333  *  Success: TRUE
00334  *  Failure: FALSE
00335  */
00336 BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
00337                                     PVOID buffer, PBOOL ref )
00338 {
00339     BOOL ret = FALSE;
00340 #ifdef HAVE_LCMS
00341     struct profile *profile = grab_profile( handle );
00342     DWORD i, count;
00343     icTag tag;
00344 
00345     TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", handle, type, offset, size, buffer, ref );
00346 
00347     if (!profile) return FALSE;
00348 
00349     if (!size || !ref)
00350     {
00351         release_profile( profile );
00352         return FALSE;
00353     }
00354     count = MSCMS_get_tag_count( profile->iccprofile );
00355 
00356     for (i = 0; i < count; i++)
00357     {
00358         MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
00359 
00360         if (tag.sig == type)
00361         {
00362             if ((tag.size - offset) > *size || !buffer)
00363             {
00364                 *size = (tag.size - offset);
00365                 release_profile( profile );
00366                 return FALSE;
00367             }
00368             MSCMS_get_tag_data( profile->iccprofile, &tag, offset, buffer );
00369 
00370             *ref = FALSE; /* FIXME: calculate properly */
00371             release_profile( profile );
00372             return TRUE;
00373         }
00374     }
00375     release_profile( profile );
00376 
00377 #endif /* HAVE_LCMS */
00378     return ret;
00379 }
00380 
00381 /******************************************************************************
00382  * GetColorProfileElementTag               [MSCMS.@]
00383  *
00384  * Get the tag type from a color profile by index. 
00385  *
00386  * PARAMS
00387  *  profile  [I]   Handle to a color profile.
00388  *  index    [I]   Index into the tag table of the color profile.
00389  *  type     [O]   Pointer to a variable that holds the ICC tag type on return.
00390  *
00391  * RETURNS
00392  *  Success: TRUE
00393  *  Failure: FALSE
00394  *
00395  * NOTES
00396  *  The tag table index starts at 1.
00397  *  Use GetCountColorProfileElements to retrieve a count of tagged elements.
00398  */
00399 BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE type )
00400 {
00401     BOOL ret = FALSE;
00402 #ifdef HAVE_LCMS
00403     struct profile *profile = grab_profile( handle );
00404     DWORD count;
00405     icTag tag;
00406 
00407     TRACE( "( %p, %d, %p )\n", handle, index, type );
00408 
00409     if (!profile) return FALSE;
00410 
00411     if (!type)
00412     {
00413         release_profile( profile );
00414         return FALSE;
00415     }
00416     count = MSCMS_get_tag_count( profile->iccprofile );
00417     if (index > count || index < 1)
00418     {
00419         release_profile( profile );
00420         return FALSE;
00421     }
00422     MSCMS_get_tag_by_index( profile->iccprofile, index - 1, &tag );
00423     *type = tag.sig;
00424 
00425     release_profile( profile );
00426     ret = TRUE;
00427 
00428 #endif /* HAVE_LCMS */
00429     return ret;
00430 }
00431 
00432 /******************************************************************************
00433  * GetColorProfileFromHandle               [MSCMS.@]
00434  *
00435  * Retrieve an ICC color profile by handle.
00436  *
00437  * PARAMS
00438  *  profile  [I]   Handle to a color profile.
00439  *  buffer   [O]   Buffer to receive the ICC profile.
00440  *  size     [I/O] Size of the buffer in bytes. On return the variable holds the
00441  *                 number of bytes actually needed.
00442  *
00443  * RETURNS
00444  *  Success: TRUE
00445  *  Failure: FALSE
00446  *
00447  * NOTES
00448  *  The profile returned will be in big-endian format.
00449  */
00450 BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD size )
00451 {
00452     BOOL ret = FALSE;
00453 #ifdef HAVE_LCMS
00454     struct profile *profile = grab_profile( handle );
00455     PROFILEHEADER header;
00456 
00457     TRACE( "( %p, %p, %p )\n", handle, buffer, size );
00458 
00459     if (!profile) return FALSE;
00460 
00461     if (!size)
00462     {
00463         release_profile( profile );
00464         return FALSE;
00465     }
00466     MSCMS_get_profile_header( profile->iccprofile, &header );
00467 
00468     if (!buffer || header.phSize > *size)
00469     {
00470         *size = header.phSize;
00471         release_profile( profile );
00472         return FALSE;
00473     }
00474 
00475     /* No endian conversion needed */
00476     memcpy( buffer, profile->iccprofile, header.phSize );
00477     *size = header.phSize;
00478 
00479     release_profile( profile );
00480     ret = TRUE;
00481 
00482 #endif /* HAVE_LCMS */
00483     return ret;
00484 }
00485 
00486 /******************************************************************************
00487  * GetColorProfileHeader               [MSCMS.@]
00488  *
00489  * Retrieve a color profile header by handle.
00490  *
00491  * PARAMS
00492  *  profile  [I]   Handle to a color profile.
00493  *  header   [O]   Buffer to receive the ICC profile header.
00494  *
00495  * RETURNS
00496  *  Success: TRUE
00497  *  Failure: FALSE
00498  *
00499  * NOTES
00500  *  The profile header returned will be adjusted for endianness.
00501  */
00502 BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
00503 {
00504 #ifdef HAVE_LCMS
00505     struct profile *profile = grab_profile( handle );
00506 
00507     TRACE( "( %p, %p )\n", handle, header );
00508 
00509     if (!profile) return FALSE;
00510 
00511     if (!header)
00512     {
00513         release_profile( profile );
00514         return FALSE;
00515     }
00516     MSCMS_get_profile_header( profile->iccprofile, header );
00517 
00518     release_profile( profile );
00519     return TRUE;
00520 
00521 #else
00522     return FALSE;
00523 #endif /* HAVE_LCMS */
00524 }
00525 
00526 /******************************************************************************
00527  * GetCountColorProfileElements               [MSCMS.@]
00528  *
00529  * Retrieve the number of elements in a color profile.
00530  *
00531  * PARAMS
00532  *  profile  [I] Handle to a color profile.
00533  *  count    [O] Pointer to a variable which is set to the number of elements
00534  *               in the color profile.
00535  *
00536  * RETURNS
00537  *  Success: TRUE
00538  *  Failure: FALSE
00539  */
00540 BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
00541 {
00542     BOOL ret = FALSE;
00543 #ifdef HAVE_LCMS
00544     struct profile *profile = grab_profile( handle );
00545 
00546     TRACE( "( %p, %p )\n", handle, count );
00547 
00548     if (!profile) return FALSE;
00549 
00550     if (!count)
00551     {
00552         release_profile( profile );
00553         return FALSE;
00554     }
00555     *count = MSCMS_get_tag_count( profile->iccprofile );
00556 
00557     release_profile( profile );
00558     ret = TRUE;
00559 
00560 #endif /* HAVE_LCMS */
00561     return ret;
00562 }
00563 
00564 /******************************************************************************
00565  * GetStandardColorSpaceProfileA               [MSCMS.@]
00566  *
00567  * See GetStandardColorSpaceProfileW.
00568  */
00569 BOOL WINAPI GetStandardColorSpaceProfileA( PCSTR machine, DWORD id, PSTR profile, PDWORD size )
00570 {
00571     INT len;
00572     LPWSTR profileW;
00573     BOOL ret = FALSE;
00574     DWORD sizeW;
00575 
00576     TRACE( "( 0x%08x, %p, %p )\n", id, profile, size );
00577 
00578     if (machine) 
00579     {
00580         SetLastError( ERROR_NOT_SUPPORTED );
00581         return FALSE;
00582     }
00583 
00584     if (!size) 
00585     {
00586         SetLastError( ERROR_INVALID_PARAMETER );
00587         return FALSE;
00588     }
00589 
00590     sizeW = *size * sizeof(WCHAR);
00591 
00592     if (!profile)
00593     {
00594         ret = GetStandardColorSpaceProfileW( NULL, id, NULL, &sizeW );
00595         *size = sizeW / sizeof(WCHAR);
00596         return ret;
00597     }
00598 
00599     profileW = HeapAlloc( GetProcessHeap(), 0, sizeW );
00600     if (profileW)
00601     {
00602         if ((ret = GetStandardColorSpaceProfileW( NULL, id, profileW, &sizeW )))
00603         {
00604             *size = WideCharToMultiByte( CP_ACP, 0, profileW, -1, NULL, 0, NULL, NULL );
00605             len = WideCharToMultiByte( CP_ACP, 0, profileW, -1, profile, *size, NULL, NULL );
00606             if (!len) ret = FALSE;
00607         }
00608         else *size = sizeW / sizeof(WCHAR);
00609 
00610         HeapFree( GetProcessHeap(), 0, profileW );
00611     }
00612     return ret;
00613 }
00614 
00615 /******************************************************************************
00616  * GetStandardColorSpaceProfileW               [MSCMS.@]
00617  *
00618  * Retrieve the profile filename for a given standard color space id.
00619  *
00620  * PARAMS
00621  *  machine  [I]   Name of the machine for which to get the standard color space.
00622  *                 Must be NULL, which indicates the local machine.
00623  *  id       [I]   Id of a standard color space.
00624  *  profile  [O]   Buffer to receive the profile filename.
00625  *  size     [I/O] Size of the filename buffer in bytes.
00626  *
00627  * RETURNS
00628  *  Success: TRUE
00629  *  Failure: FALSE
00630  */
00631 BOOL WINAPI GetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profile, PDWORD size )
00632 {
00633     static const WCHAR rgbprofilefile[] =
00634         { '\\','s','r','g','b',' ','c','o','l','o','r',' ',
00635           's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
00636     WCHAR rgbprofile[MAX_PATH];
00637     DWORD len = sizeof(rgbprofile);
00638 
00639     TRACE( "( 0x%08x, %p, %p )\n", id, profile, size );
00640 
00641     if (machine) 
00642     {
00643         SetLastError( ERROR_NOT_SUPPORTED );
00644         return FALSE;
00645     }
00646 
00647     if (!size) 
00648     {
00649         SetLastError( ERROR_INVALID_PARAMETER );
00650         return FALSE;
00651     }
00652 
00653     if (!profile)
00654     {
00655         SetLastError( ERROR_INSUFFICIENT_BUFFER );
00656         return FALSE;
00657     }
00658 
00659     GetColorDirectoryW( machine, rgbprofile, &len );
00660 
00661     switch (id)
00662     {
00663         case LCS_sRGB:
00664         case LCS_WINDOWS_COLOR_SPACE: /* FIXME */
00665             lstrcatW( rgbprofile, rgbprofilefile );
00666             len = lstrlenW( rgbprofile ) * sizeof(WCHAR);
00667 
00668             if (*size < len || !profile)
00669             {
00670                 *size = len;
00671                 SetLastError( ERROR_MORE_DATA );
00672                 return FALSE;
00673             }
00674 
00675             lstrcpyW( profile, rgbprofile );
00676             break;
00677 
00678         default:
00679             SetLastError( ERROR_FILE_NOT_FOUND );
00680             return FALSE;
00681     }
00682     return TRUE;
00683 }
00684 
00685 static BOOL MSCMS_header_from_file( LPCWSTR file, PPROFILEHEADER header )
00686 {
00687     BOOL ret;
00688     PROFILE profile;
00689     WCHAR path[MAX_PATH], slash[] = {'\\',0};
00690     DWORD size = sizeof(path);
00691     HANDLE handle;
00692 
00693     ret = GetColorDirectoryW( NULL, path, &size );
00694     if (!ret)
00695     {
00696         WARN( "Can't retrieve color directory\n" );
00697         return FALSE;
00698     }
00699     if (size + sizeof(slash) + sizeof(WCHAR) * lstrlenW( file ) > sizeof(path))
00700     {
00701         WARN( "Filename too long\n" );
00702         return FALSE;
00703     }
00704 
00705     lstrcatW( path, slash );
00706     lstrcatW( path, file );
00707 
00708     profile.dwType = PROFILE_FILENAME;
00709     profile.pProfileData = path;
00710     profile.cbDataSize = lstrlenW( path ) + 1;
00711 
00712     handle = OpenColorProfileW( &profile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING );
00713     if (!handle)
00714     {
00715         WARN( "Can't open color profile\n" );
00716         return FALSE;
00717     }
00718 
00719     ret = GetColorProfileHeader( handle, header );
00720     if (!ret)
00721         WARN( "Can't retrieve color profile header\n" );
00722 
00723     CloseColorProfile( handle );
00724     return ret;
00725 }
00726 
00727 static BOOL MSCMS_match_profile( PENUMTYPEW rec, PPROFILEHEADER hdr )
00728 {
00729     if (rec->dwFields & ET_DEVICENAME)
00730     {
00731         FIXME( "ET_DEVICENAME: %s\n", debugstr_w(rec->pDeviceName) );
00732     }
00733     if (rec->dwFields & ET_MEDIATYPE)
00734     {
00735         FIXME( "ET_MEDIATYPE: 0x%08x\n", rec->dwMediaType );
00736     }
00737     if (rec->dwFields & ET_DITHERMODE)
00738     {
00739         FIXME( "ET_DITHERMODE: 0x%08x\n", rec->dwDitheringMode );
00740     }
00741     if (rec->dwFields & ET_RESOLUTION)
00742     {
00743         FIXME( "ET_RESOLUTION: 0x%08x, 0x%08x\n",
00744                rec->dwResolution[0], rec->dwResolution[1] );
00745     }
00746     if (rec->dwFields & ET_DEVICECLASS)
00747     {
00748         FIXME( "ET_DEVICECLASS: %s\n", MSCMS_dbgstr_tag(rec->dwMediaType) );
00749     }
00750     if (rec->dwFields & ET_CMMTYPE)
00751     {
00752         TRACE( "ET_CMMTYPE: %s\n", MSCMS_dbgstr_tag(rec->dwCMMType) );
00753         if (rec->dwCMMType != hdr->phCMMType) return FALSE;
00754     }
00755     if (rec->dwFields & ET_CLASS)
00756     {
00757         TRACE( "ET_CLASS: %s\n", MSCMS_dbgstr_tag(rec->dwClass) );
00758         if (rec->dwClass != hdr->phClass) return FALSE;
00759     }
00760     if (rec->dwFields & ET_DATACOLORSPACE)
00761     {
00762         TRACE( "ET_DATACOLORSPACE: %s\n", MSCMS_dbgstr_tag(rec->dwDataColorSpace) );
00763         if (rec->dwDataColorSpace != hdr->phDataColorSpace) return FALSE;
00764     }
00765     if (rec->dwFields & ET_CONNECTIONSPACE)
00766     {
00767         TRACE( "ET_CONNECTIONSPACE: %s\n", MSCMS_dbgstr_tag(rec->dwConnectionSpace) );
00768         if (rec->dwConnectionSpace != hdr->phConnectionSpace) return FALSE;
00769     }
00770     if (rec->dwFields & ET_SIGNATURE)
00771     {
00772         TRACE( "ET_SIGNATURE: %s\n", MSCMS_dbgstr_tag(rec->dwSignature) );
00773         if (rec->dwSignature != hdr->phSignature) return FALSE;
00774     }
00775     if (rec->dwFields & ET_PLATFORM)
00776     {
00777         TRACE( "ET_PLATFORM: %s\n", MSCMS_dbgstr_tag(rec->dwPlatform) );
00778         if (rec->dwPlatform != hdr->phPlatform) return FALSE;
00779     }
00780     if (rec->dwFields & ET_PROFILEFLAGS)
00781     {
00782         TRACE( "ET_PROFILEFLAGS: 0x%08x\n", rec->dwProfileFlags );
00783         if (rec->dwProfileFlags != hdr->phProfileFlags) return FALSE;
00784     }
00785     if (rec->dwFields & ET_MANUFACTURER)
00786     {
00787         TRACE( "ET_MANUFACTURER: %s\n", MSCMS_dbgstr_tag(rec->dwManufacturer) );
00788         if (rec->dwManufacturer != hdr->phManufacturer) return FALSE;
00789     }
00790     if (rec->dwFields & ET_MODEL)
00791     {
00792         TRACE( "ET_MODEL: %s\n", MSCMS_dbgstr_tag(rec->dwModel) );
00793         if (rec->dwModel != hdr->phModel) return FALSE;
00794     }
00795     if (rec->dwFields & ET_ATTRIBUTES)
00796     {
00797         TRACE( "ET_ATTRIBUTES: 0x%08x, 0x%08x\n",
00798                rec->dwAttributes[0], rec->dwAttributes[1] );
00799         if (rec->dwAttributes[0] != hdr->phAttributes[0] || 
00800             rec->dwAttributes[1] != hdr->phAttributes[1]) return FALSE;
00801     }
00802     if (rec->dwFields & ET_RENDERINGINTENT)
00803     {
00804         TRACE( "ET_RENDERINGINTENT: 0x%08x\n", rec->dwRenderingIntent );
00805         if (rec->dwRenderingIntent != hdr->phRenderingIntent) return FALSE;
00806     }
00807     if (rec->dwFields & ET_CREATOR)
00808     {
00809         TRACE( "ET_CREATOR: %s\n", MSCMS_dbgstr_tag(rec->dwCreator) );
00810         if (rec->dwCreator != hdr->phCreator) return FALSE;
00811     }
00812     return TRUE;
00813 }
00814 
00815 /******************************************************************************
00816  * EnumColorProfilesA               [MSCMS.@]
00817  *
00818  * See EnumColorProfilesW.
00819  */
00820 BOOL WINAPI EnumColorProfilesA( PCSTR machine, PENUMTYPEA record, PBYTE buffer,
00821                                 PDWORD size, PDWORD number )
00822 {
00823     BOOL match, ret = FALSE;
00824     char spec[] = "\\*.icm";
00825     char colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL;
00826     DWORD i, len = sizeof(colordir), count = 0, totalsize = 0;
00827     PROFILEHEADER header;
00828     WIN32_FIND_DATAA data;
00829     ENUMTYPEW recordW;
00830     WCHAR *fileW = NULL, *deviceW = NULL;
00831     HANDLE find;
00832 
00833     TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number );
00834 
00835     if (machine || !record || !size ||
00836         record->dwSize != sizeof(ENUMTYPEA) ||
00837         record->dwVersion != ENUM_TYPE_VERSION) return FALSE;
00838 
00839     ret = GetColorDirectoryA( machine, colordir, &len );
00840     if (!ret || len + sizeof(spec) > MAX_PATH)
00841     {
00842         WARN( "can't retrieve color directory\n" );
00843         return FALSE;
00844     }
00845 
00846     lstrcpyA( glob, colordir );
00847     lstrcatA( glob, spec );
00848 
00849     find = FindFirstFileA( glob, &data );
00850     if (find == INVALID_HANDLE_VALUE) return FALSE;
00851 
00852     profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(char *) + 1 );
00853     if (!profiles) goto exit;
00854 
00855     memcpy( &recordW, record, sizeof(ENUMTYPEA) );
00856     if (record->pDeviceName)
00857     {
00858         deviceW = MSCMS_strdupW( record->pDeviceName );
00859         if (!(recordW.pDeviceName = deviceW)) goto exit;
00860     }
00861 
00862     fileW = MSCMS_strdupW( data.cFileName );
00863     if (!fileW) goto exit;
00864 
00865     ret = MSCMS_header_from_file( fileW, &header );
00866     if (ret)
00867     {
00868         match = MSCMS_match_profile( &recordW, &header );
00869         if (match)
00870         {
00871             len = sizeof(char) * (lstrlenA( data.cFileName ) + 1);
00872             profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
00873 
00874             if (!profiles[count]) goto exit;
00875             else
00876             {
00877                 TRACE( "matching profile: %s\n", debugstr_a(data.cFileName) );
00878                 lstrcpyA( profiles[count], data.cFileName );
00879                 totalsize += len;
00880                 count++;
00881             }
00882         }
00883     }
00884     HeapFree( GetProcessHeap(), 0, fileW );
00885     fileW = NULL;
00886 
00887     while (FindNextFileA( find, &data ))
00888     {
00889         fileW = MSCMS_strdupW( data.cFileName );
00890         if (!fileW) goto exit;
00891 
00892         ret = MSCMS_header_from_file( fileW, &header );
00893         if (!ret)
00894         {
00895             HeapFree( GetProcessHeap(), 0, fileW );
00896             continue;
00897         }
00898 
00899         match = MSCMS_match_profile( &recordW, &header );
00900         if (match)
00901         {
00902             char **tmp = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
00903                                       profiles, sizeof(char *) * (count + 1) );
00904             if (!tmp) goto exit;
00905             else profiles = tmp;
00906 
00907             len = sizeof(char) * (lstrlenA( data.cFileName ) + 1);
00908             profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
00909 
00910             if (!profiles[count]) goto exit;
00911             else
00912             {
00913                 TRACE( "matching profile: %s\n", debugstr_a(data.cFileName) );
00914                 lstrcpyA( profiles[count], data.cFileName );
00915                 totalsize += len;
00916                 count++;
00917             }
00918         }
00919         HeapFree( GetProcessHeap(), 0, fileW );
00920         fileW = NULL;
00921     }
00922 
00923     totalsize++;
00924     if (buffer && *size >= totalsize)
00925     {
00926         char *p = (char *)buffer;
00927 
00928         for (i = 0; i < count; i++)
00929         {
00930             lstrcpyA( p, profiles[i] );
00931             p += lstrlenA( profiles[i] ) + 1;
00932         }
00933         *p = 0;
00934         ret = TRUE;
00935     }
00936     else ret = FALSE;
00937 
00938     *size = totalsize;
00939     if (number) *number = count;
00940 
00941 exit:
00942     for (i = 0; i < count; i++)
00943         HeapFree( GetProcessHeap(), 0, profiles[i] );
00944     HeapFree( GetProcessHeap(), 0, profiles );
00945     HeapFree( GetProcessHeap(), 0, deviceW );
00946     HeapFree( GetProcessHeap(), 0, fileW );
00947     FindClose( find );
00948 
00949     return ret;
00950 }
00951 
00952 /******************************************************************************
00953  * EnumColorProfilesW               [MSCMS.@]
00954  *
00955  * Enumerate profiles that match given criteria.
00956  *
00957  * PARAMS
00958  *  machine  [I]   Name of the machine for which to enumerate profiles.
00959  *                 Must be NULL, which indicates the local machine.
00960  *  record   [I]   Record of criteria that a profile must match.
00961  *  buffer   [O]   Buffer to receive a string array of profile filenames.
00962  *  size     [I/O] Size of the filename buffer in bytes.
00963  *  number   [O]   Number of filenames copied into buffer.
00964  *
00965  * RETURNS
00966  *  Success: TRUE
00967  *  Failure: FALSE
00968  */
00969 BOOL WINAPI EnumColorProfilesW( PCWSTR machine, PENUMTYPEW record, PBYTE buffer,
00970                                 PDWORD size, PDWORD number )
00971 {
00972     BOOL match, ret = FALSE;
00973     WCHAR spec[] = {'\\','*','i','c','m',0};
00974     WCHAR colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL;
00975     DWORD i, len = sizeof(colordir), count = 0, totalsize = 0;
00976     PROFILEHEADER header;
00977     WIN32_FIND_DATAW data;
00978     HANDLE find;
00979 
00980     TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number );
00981 
00982     if (machine || !record || !size ||
00983         record->dwSize != sizeof(ENUMTYPEW) ||
00984         record->dwVersion != ENUM_TYPE_VERSION) return FALSE;
00985 
00986     ret = GetColorDirectoryW( machine, colordir, &len );
00987     if (!ret || len + sizeof(spec) > MAX_PATH)
00988     {
00989         WARN( "Can't retrieve color directory\n" );
00990         return FALSE;
00991     }
00992 
00993     lstrcpyW( glob, colordir );
00994     lstrcatW( glob, spec );
00995 
00996     find = FindFirstFileW( glob, &data );
00997     if (find == INVALID_HANDLE_VALUE) return FALSE;
00998 
00999     profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR *) + 1 );
01000     if (!profiles) goto exit;
01001 
01002     ret = MSCMS_header_from_file( data.cFileName, &header );
01003     if (ret)
01004     {
01005         match = MSCMS_match_profile( record, &header );
01006         if (match)
01007         {
01008             len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1);
01009             profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
01010 
01011             if (!profiles[count]) goto exit;
01012             else
01013             {
01014                 TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) );
01015                 lstrcpyW( profiles[count], data.cFileName );
01016                 totalsize += len;
01017                 count++;
01018             }
01019         }
01020     }
01021 
01022     while (FindNextFileW( find, &data ))
01023     {
01024         ret = MSCMS_header_from_file( data.cFileName, &header );
01025         if (!ret) continue;
01026 
01027         match = MSCMS_match_profile( record, &header );
01028         if (match)
01029         {
01030             WCHAR **tmp = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
01031                                        profiles, sizeof(WCHAR *) * (count + 1) );
01032             if (!tmp) goto exit;
01033             else profiles = tmp;
01034 
01035             len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1);
01036             profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
01037 
01038             if (!profiles[count]) goto exit;
01039             else
01040             {
01041                 TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) );
01042                 lstrcpyW( profiles[count], data.cFileName );
01043                 totalsize += len;
01044                 count++;
01045             }
01046         }
01047     }
01048 
01049     totalsize++;
01050     if (buffer && *size >= totalsize)
01051     {
01052         WCHAR *p = (WCHAR *)buffer;
01053 
01054         for (i = 0; i < count; i++)
01055         {
01056             lstrcpyW( p, profiles[i] );
01057             p += lstrlenW( profiles[i] ) + 1;
01058         }
01059         *p = 0;
01060         ret = TRUE;
01061     }
01062     else ret = FALSE;
01063 
01064     *size = totalsize;
01065     if (number) *number = count;
01066 
01067 exit:
01068     for (i = 0; i < count; i++)
01069         HeapFree( GetProcessHeap(), 0, profiles[i] );
01070     HeapFree( GetProcessHeap(), 0, profiles );
01071     FindClose( find );
01072 
01073     return ret;
01074 }
01075 
01076 /******************************************************************************
01077  * InstallColorProfileA               [MSCMS.@]
01078  *
01079  * See InstallColorProfileW.
01080  */
01081 BOOL WINAPI InstallColorProfileA( PCSTR machine, PCSTR profile )
01082 {
01083     UINT len;
01084     LPWSTR profileW;
01085     BOOL ret = FALSE;
01086 
01087     TRACE( "( %s )\n", debugstr_a(profile) );
01088 
01089     if (machine || !profile) return FALSE;
01090 
01091     len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
01092     profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
01093 
01094     if (profileW)
01095     {
01096         MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
01097 
01098         ret = InstallColorProfileW( NULL, profileW );
01099         HeapFree( GetProcessHeap(), 0, profileW );
01100     }
01101     return ret;
01102 }
01103 
01104 /******************************************************************************
01105  * InstallColorProfileW               [MSCMS.@]
01106  *
01107  * Install a color profile.
01108  *
01109  * PARAMS
01110  *  machine  [I] Name of the machine to install the profile on. Must be NULL,
01111  *               which indicates the local machine.
01112  *  profile  [I] Full path name of the profile to install.
01113  *
01114  * RETURNS
01115  *  Success: TRUE
01116  *  Failure: FALSE
01117  */
01118 BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile )
01119 {
01120     WCHAR dest[MAX_PATH], base[MAX_PATH];
01121     DWORD size = sizeof(dest);
01122     static const WCHAR slash[] = { '\\', 0 };
01123 
01124     TRACE( "( %s )\n", debugstr_w(profile) );
01125 
01126     if (machine || !profile) return FALSE;
01127 
01128     if (!GetColorDirectoryW( machine, dest, &size )) return FALSE;
01129 
01130     MSCMS_basename( profile, base );
01131 
01132     lstrcatW( dest, slash );
01133     lstrcatW( dest, base );
01134 
01135     /* Is source equal to destination? */
01136     if (!lstrcmpW( profile, dest )) return TRUE;
01137 
01138     return CopyFileW( profile, dest, TRUE );
01139 }
01140 
01141 /******************************************************************************
01142  * IsColorProfileTagPresent               [MSCMS.@]
01143  *
01144  * Determine if a given ICC tag type is present in a color profile.
01145  *
01146  * PARAMS
01147  *  profile  [I] Color profile handle.
01148  *  tag      [I] ICC tag type.
01149  *  present  [O] Pointer to a BOOL variable. Set to TRUE if tag type is present,
01150  *               FALSE otherwise.
01151  *
01152  * RETURNS
01153  *  Success: TRUE
01154  *  Failure: FALSE
01155  */
01156 BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL present )
01157 {
01158     BOOL ret = FALSE;
01159 #ifdef HAVE_LCMS
01160     struct profile *profile = grab_profile( handle );
01161     DWORD i, count;
01162     icTag tag;
01163 
01164     TRACE( "( %p, 0x%08x, %p )\n", handle, type, present );
01165 
01166     if (!profile) return FALSE;
01167 
01168     if (!present)
01169     {
01170         release_profile( profile );
01171         return FALSE;
01172     }
01173     count = MSCMS_get_tag_count( profile->iccprofile );
01174 
01175     for (i = 0; i < count; i++)
01176     {
01177         MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
01178 
01179         if (tag.sig == type)
01180         {
01181             *present = ret = TRUE;
01182             break;
01183         }
01184     }
01185     release_profile( profile );
01186 
01187 #endif /* HAVE_LCMS */
01188     return ret;
01189 }
01190 
01191 /******************************************************************************
01192  * IsColorProfileValid               [MSCMS.@]
01193  *
01194  * Determine if a given color profile is valid.
01195  *
01196  * PARAMS
01197  *  profile  [I] Color profile handle.
01198  *  valid    [O] Pointer to a BOOL variable. Set to TRUE if profile is valid,
01199  *               FALSE otherwise.
01200  *
01201  * RETURNS
01202  *  Success: TRUE
01203  *  Failure: FALSE 
01204  */
01205 BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
01206 {
01207     BOOL ret = FALSE;
01208 #ifdef HAVE_LCMS
01209     struct profile *profile = grab_profile( handle );
01210 
01211     TRACE( "( %p, %p )\n", handle, valid );
01212 
01213     if (!profile) return FALSE;
01214 
01215     if (!valid)
01216     {
01217         release_profile( profile );
01218         return FALSE;
01219     }
01220     if (profile->iccprofile) ret = *valid = TRUE;
01221     release_profile( profile );
01222 
01223 #endif /* HAVE_LCMS */
01224     return ret;
01225 }
01226 
01227 /******************************************************************************
01228  * SetColorProfileElement               [MSCMS.@]
01229  *
01230  * Set data for a specified tag type.
01231  *
01232  * PARAMS
01233  *  profile  [I]   Handle to a color profile.
01234  *  type     [I]   ICC tag type.
01235  *  offset   [I]   Offset in bytes to start copying to.
01236  *  size     [I/O] Size of the buffer in bytes. On return the variable holds the
01237  *                 number of bytes actually needed.
01238  *  buffer   [O]   Buffer holding the tag data.
01239  *
01240  * RETURNS
01241  *  Success: TRUE
01242  *  Failure: FALSE
01243  */
01244 BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
01245                                     PVOID buffer )
01246 {
01247     BOOL ret = FALSE;
01248 #ifdef HAVE_LCMS
01249     struct profile *profile = grab_profile( handle );
01250     DWORD i, count;
01251     icTag tag;
01252 
01253     TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer );
01254 
01255     if (!profile) return FALSE;
01256 
01257     if (!size || !buffer || !(profile->access & PROFILE_READWRITE))
01258     {
01259         release_profile( profile );
01260         return FALSE;
01261     }
01262     count = MSCMS_get_tag_count( profile->iccprofile );
01263 
01264     for (i = 0; i < count; i++)
01265     {
01266         MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
01267 
01268         if (tag.sig == type)
01269         {
01270             if (offset > tag.size)
01271             {
01272                 release_profile( profile );
01273                 return FALSE;
01274             }
01275             MSCMS_set_tag_data( profile->iccprofile, &tag, offset, buffer );
01276 
01277             release_profile( profile );
01278             return TRUE;
01279         }
01280     }
01281     release_profile( profile );
01282 
01283 #endif /* HAVE_LCMS */
01284     return ret;
01285 }
01286 
01287 /******************************************************************************
01288  * SetColorProfileHeader               [MSCMS.@]
01289  *
01290  * Set header data for a given profile.
01291  *
01292  * PARAMS
01293  *  profile  [I] Handle to a color profile.
01294  *  header   [I] Buffer holding the header data.
01295  *
01296  * RETURNS
01297  *  Success: TRUE
01298  *  Failure: FALSE
01299  */
01300 BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
01301 {
01302 #ifdef HAVE_LCMS
01303     struct profile *profile = grab_profile( handle );
01304 
01305     TRACE( "( %p, %p )\n", handle, header );
01306 
01307     if (!profile) return FALSE;
01308 
01309     if (!header || !(profile->access & PROFILE_READWRITE))
01310     {
01311         release_profile( profile );
01312         return FALSE;
01313     }
01314     MSCMS_set_profile_header( profile->iccprofile, header );
01315 
01316     release_profile( profile );
01317     return TRUE;
01318 
01319 #else
01320     return FALSE;
01321 #endif /* HAVE_LCMS */
01322 }
01323 
01324 /******************************************************************************
01325  * UninstallColorProfileA               [MSCMS.@]
01326  *
01327  * See UninstallColorProfileW.
01328  */
01329 BOOL WINAPI UninstallColorProfileA( PCSTR machine, PCSTR profile, BOOL delete )
01330 {
01331     UINT len;
01332     LPWSTR profileW;
01333     BOOL ret = FALSE;
01334 
01335     TRACE( "( %s, %x )\n", debugstr_a(profile), delete );
01336 
01337     if (machine || !profile) return FALSE;
01338 
01339     len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
01340     profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
01341 
01342     if (profileW)
01343     {
01344         MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
01345 
01346         ret = UninstallColorProfileW( NULL, profileW , delete );
01347 
01348         HeapFree( GetProcessHeap(), 0, profileW );
01349     }
01350     return ret;
01351 }
01352 
01353 /******************************************************************************
01354  * UninstallColorProfileW               [MSCMS.@]
01355  *
01356  * Uninstall a color profile.
01357  *
01358  * PARAMS
01359  *  machine  [I] Name of the machine to uninstall the profile on. Must be NULL,
01360  *               which indicates the local machine.
01361  *  profile  [I] Full path name of the profile to uninstall.
01362  *  delete   [I] Bool that specifies whether the profile file should be deleted.
01363  *
01364  * RETURNS
01365  *  Success: TRUE
01366  *  Failure: FALSE
01367  */
01368 BOOL WINAPI UninstallColorProfileW( PCWSTR machine, PCWSTR profile, BOOL delete )
01369 {
01370     TRACE( "( %s, %x )\n", debugstr_w(profile), delete );
01371 
01372     if (machine || !profile) return FALSE;
01373 
01374     if (delete) return DeleteFileW( profile );
01375 
01376     return TRUE;
01377 }
01378 
01379 /******************************************************************************
01380  * OpenColorProfileA               [MSCMS.@]
01381  *
01382  * See OpenColorProfileW.
01383  */
01384 HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
01385 {
01386     HPROFILE handle = NULL;
01387 
01388     TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation );
01389 
01390     if (!profile || !profile->pProfileData) return NULL;
01391 
01392     /* No AW conversion needed for memory based profiles */
01393     if (profile->dwType & PROFILE_MEMBUFFER)
01394         return OpenColorProfileW( profile, access, sharing, creation );
01395 
01396     if (profile->dwType & PROFILE_FILENAME)
01397     {
01398         UINT len;
01399         PROFILE profileW;
01400 
01401         profileW.dwType = profile->dwType;
01402  
01403         len = MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, NULL, 0 );
01404         profileW.pProfileData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
01405 
01406         if (profileW.pProfileData)
01407         {
01408             profileW.cbDataSize = len * sizeof(WCHAR);
01409             MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, profileW.pProfileData, len );
01410 
01411             handle = OpenColorProfileW( &profileW, access, sharing, creation );
01412             HeapFree( GetProcessHeap(), 0, profileW.pProfileData );
01413         }
01414     }
01415     return handle;
01416 }
01417 
01418 /******************************************************************************
01419  * OpenColorProfileW               [MSCMS.@]
01420  *
01421  * Open a color profile.
01422  *
01423  * PARAMS
01424  *  profile   [I] Pointer to a color profile structure.
01425  *  access    [I] Desired access.
01426  *  sharing   [I] Sharing mode.
01427  *  creation  [I] Creation mode.
01428  *
01429  * RETURNS
01430  *  Success: Handle to the opened profile.
01431  *  Failure: NULL
01432  *
01433  * NOTES
01434  *  Values for access:   PROFILE_READ or PROFILE_READWRITE.
01435  *  Values for sharing:  0 (no sharing), FILE_SHARE_READ and/or FILE_SHARE_WRITE.
01436  *  Values for creation: one of CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING,
01437  *                       OPEN_ALWAYS, TRUNCATE_EXISTING.
01438  *  Sharing and creation flags are ignored for memory based profiles.
01439  */
01440 HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
01441 {
01442 #ifdef HAVE_LCMS
01443     cmsHPROFILE cmsprofile = NULL;
01444     icProfile *iccprofile = NULL;
01445     HANDLE handle = INVALID_HANDLE_VALUE;
01446 
01447     TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation );
01448 
01449     if (!profile || !profile->pProfileData) return NULL;
01450 
01451     if (profile->dwType == PROFILE_MEMBUFFER)
01452     {
01453         /* FIXME: access flags not implemented for memory based profiles */
01454 
01455         if (!(iccprofile = HeapAlloc( GetProcessHeap(), 0, profile->cbDataSize ))) return NULL;
01456         memcpy( iccprofile, profile->pProfileData, profile->cbDataSize );
01457 
01458         cmsprofile = cmsOpenProfileFromMem( iccprofile, profile->cbDataSize );
01459     }
01460     else if (profile->dwType == PROFILE_FILENAME)
01461     {
01462         DWORD size, read, flags = 0;
01463 
01464         TRACE( "profile file: %s\n", debugstr_w( profile->pProfileData ) );
01465 
01466         if (access & PROFILE_READ) flags = GENERIC_READ;
01467         if (access & PROFILE_READWRITE) flags = GENERIC_READ|GENERIC_WRITE;
01468 
01469         if (!flags) return NULL;
01470         if (!sharing) sharing = FILE_SHARE_READ;
01471 
01472         if (!PathIsRelativeW( profile->pProfileData ))
01473             handle = CreateFileW( profile->pProfileData, flags, sharing, NULL, creation, 0, NULL );
01474         else
01475         {
01476             WCHAR *path;
01477 
01478             if (!GetColorDirectoryW( NULL, NULL, &size ) && GetLastError() == ERROR_MORE_DATA)
01479             {
01480                 size += (strlenW( profile->pProfileData ) + 2) * sizeof(WCHAR);
01481                 if (!(path = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
01482                 GetColorDirectoryW( NULL, path, &size );
01483                 PathAddBackslashW( path );
01484                 strcatW( path, profile->pProfileData );
01485             }
01486             else return NULL;
01487             handle = CreateFileW( path, flags, sharing, NULL, creation, 0, NULL );
01488             HeapFree( GetProcessHeap(), 0, path );
01489         }
01490         if (handle == INVALID_HANDLE_VALUE)
01491         {
01492             WARN( "Unable to open color profile %u\n", GetLastError() );
01493             return NULL;
01494         }
01495 
01496         if ((size = GetFileSize( handle, NULL )) == INVALID_FILE_SIZE)
01497         {
01498             ERR( "Unable to retrieve size of color profile\n" );
01499             CloseHandle( handle );
01500             return NULL;
01501         }
01502 
01503         iccprofile = HeapAlloc( GetProcessHeap(), 0, size );
01504         if (!iccprofile)
01505         {
01506             ERR( "Unable to allocate memory for color profile\n" );
01507             CloseHandle( handle );
01508             return NULL;
01509         }
01510 
01511         if (!ReadFile( handle, iccprofile, size, &read, NULL ) || read != size)
01512         {
01513             ERR( "Unable to read color profile\n" );
01514 
01515             CloseHandle( handle );
01516             HeapFree( GetProcessHeap(), 0, iccprofile );
01517             return NULL;
01518         }
01519 
01520         cmsprofile = cmsOpenProfileFromMem( iccprofile, size );
01521     }
01522     else
01523     {
01524         ERR( "Invalid profile type %u\n", profile->dwType );
01525         return NULL;
01526     }
01527 
01528     if (cmsprofile)
01529     {
01530         struct profile profile;
01531 
01532         profile.file = handle;
01533         profile.access = access;
01534         profile.iccprofile = iccprofile;
01535         profile.cmsprofile = cmsprofile;
01536 
01537         return create_profile( &profile );
01538     }
01539 
01540 #endif /* HAVE_LCMS */
01541     return NULL;
01542 }
01543 
01544 /******************************************************************************
01545  * CloseColorProfile               [MSCMS.@]
01546  *
01547  * Close a color profile.
01548  *
01549  * PARAMS
01550  *  profile  [I] Handle to the profile.
01551  *
01552  * RETURNS
01553  *  Success: TRUE
01554  *  Failure: FALSE
01555  */
01556 BOOL WINAPI CloseColorProfile( HPROFILE profile )
01557 {
01558     BOOL ret = FALSE;
01559 #ifdef HAVE_LCMS
01560 
01561     TRACE( "( %p )\n", profile );
01562     ret = close_profile( profile );
01563 
01564 #endif /* HAVE_LCMS */
01565     return ret;
01566 }

Generated on Sun May 27 2012 04:24:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.