Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprofile.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
1.7.6.1
|