ReactOS  0.4.15-dev-440-g5f37b68
profile.c
Go to the documentation of this file.
1 /*
2  * MSCMS - Color Management System for Wine
3  *
4  * Copyright 2004, 2005, 2006, 2008 Hans Leidekker
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "config.h"
22 #include "wine/debug.h"
23 #include "wine/unicode.h"
24 
25 #include <stdarg.h>
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "winreg.h"
33 #include "shlwapi.h"
34 #include "icm.h"
35 
36 #include "mscms_priv.h"
37 
38 static void basename( LPCWSTR path, LPWSTR name )
39 {
40  INT i = lstrlenW( path );
41 
42  while (i > 0 && path[i - 1] != '\\' && path[i - 1] != '/') i--;
43  lstrcpyW( name, &path[i] );
44 }
45 
46 static inline LPWSTR strdupW( LPCSTR str )
47 {
48  LPWSTR ret = NULL;
49  if (str)
50  {
51  DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
52  if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
53  MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
54  }
55  return ret;
56 }
57 
58 const char *dbgstr_tag( DWORD tag )
59 {
60  return wine_dbg_sprintf( "'%c%c%c%c'",
61  (char)(tag >> 24), (char)(tag >> 16), (char)(tag >> 8), (char)(tag) );
62 }
63 
65 
66 /******************************************************************************
67  * AssociateColorProfileWithDeviceA [MSCMS.@]
68  */
70 {
71  int len;
72  BOOL ret = FALSE;
73  WCHAR *profileW, *deviceW;
74 
75  TRACE( "( %s, %s, %s )\n", debugstr_a(machine), debugstr_a(profile), debugstr_a(device) );
76 
77  if (!profile || !device)
78  {
80  return FALSE;
81  }
82  if (machine)
83  {
85  return FALSE;
86  }
87 
88  len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
89  if (!(profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
90 
91  MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
92 
93  len = MultiByteToWideChar( CP_ACP, 0, device, -1, NULL, 0 );
94  if ((deviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
95  {
98  }
99 
100  HeapFree( GetProcessHeap(), 0, profileW );
102  return ret;
103 }
104 
106 {
107  static const WCHAR fmtW[] = {'%','c','%','c','%','c','%','c',0};
108  static const WCHAR icmW[] = {'S','o','f','t','w','a','r','e','\\',
109  'M','i','c','r','o','s','o','f','t','\\',
110  'W','i','n','d','o','w','s',' ','N','T','\\',
111  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
112  'I','C','M',0};
116  HKEY icm_key, class_key;
117  WCHAR basenameW[MAX_PATH], classW[5];
118 
119  profile.dwType = PROFILE_FILENAME;
120  profile.pProfileData = (PVOID)file;
121  profile.cbDataSize = (lstrlenW( file ) + 1) * sizeof(WCHAR);
122 
123  /* FIXME is the profile installed? */
125  {
127  return FALSE;
128  }
130  {
133  return FALSE;
134  }
135  RegCreateKeyExW( HKEY_LOCAL_MACHINE, icmW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &icm_key, NULL );
136 
137  basename( file, basenameW );
138  sprintfW( classW, fmtW, (header.phClass >> 24) & 0xff, (header.phClass >> 16) & 0xff,
139  (header.phClass >> 8) & 0xff, header.phClass & 0xff );
140 
141  RegCreateKeyExW( icm_key, classW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &class_key, NULL );
142  if (value) RegSetValueExW( class_key, basenameW, 0, REG_BINARY, value, size );
143  else RegDeleteValueW( class_key, basenameW );
144 
145  RegCloseKey( class_key );
146  RegCloseKey( icm_key );
148  return TRUE;
149 }
150 
151 /******************************************************************************
152  * AssociateColorProfileWithDeviceW [MSCMS.@]
153  */
155 {
156  static const BYTE dummy_value[12];
157 
158  TRACE( "( %s, %s, %s )\n", debugstr_w(machine), debugstr_w(profile), debugstr_w(device) );
159 
160  if (!profile || !device)
161  {
163  return FALSE;
164  }
165  if (machine)
166  {
168  return FALSE;
169  }
170 
171  return set_profile_device_key( profile, dummy_value, sizeof(dummy_value) );
172 }
173 
174 /******************************************************************************
175  * DisassociateColorProfileFromDeviceA [MSCMS.@]
176  */
178 {
179  int len;
180  BOOL ret = FALSE;
181  WCHAR *profileW, *deviceW;
182 
183  TRACE( "( %s, %s, %s )\n", debugstr_a(machine), debugstr_a(profile), debugstr_a(device) );
184 
185  if (!profile || !device)
186  {
188  return FALSE;
189  }
190  if (machine)
191  {
193  return FALSE;
194  }
195 
196  len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
197  if (!(profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
198 
199  MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
200 
201  len = MultiByteToWideChar( CP_ACP, 0, device, -1, NULL, 0 );
202  if ((deviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
203  {
206  }
207 
208  HeapFree( GetProcessHeap(), 0, profileW );
210  return ret;
211 }
212 
213 /******************************************************************************
214  * DisassociateColorProfileFromDeviceW [MSCMS.@]
215  */
217 {
218  TRACE( "( %s, %s, %s )\n", debugstr_w(machine), debugstr_w(profile), debugstr_w(device) );
219 
220  if (!profile || !device)
221  {
223  return FALSE;
224  }
225  if (machine)
226  {
228  return FALSE;
229  }
230 
231  return set_profile_device_key( profile, NULL, 0 );
232 }
233 
234 /******************************************************************************
235  * GetColorDirectoryA [MSCMS.@]
236  *
237  * See GetColorDirectoryW.
238  */
240 {
241  INT len;
242  LPWSTR bufferW;
243  BOOL ret = FALSE;
244  DWORD sizeW;
245 
246  TRACE( "( %p, %p )\n", buffer, size );
247 
248  if (machine || !size) return FALSE;
249 
250  if (!buffer)
251  {
253  *size = sizeW / sizeof(WCHAR);
254  return ret;
255  }
256 
257  sizeW = *size * sizeof(WCHAR);
258 
259  bufferW = HeapAlloc( GetProcessHeap(), 0, sizeW );
260  if (bufferW)
261  {
262  if ((ret = GetColorDirectoryW( NULL, bufferW, &sizeW )))
263  {
264  *size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
265  len = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, *size, NULL, NULL );
266  if (!len) ret = FALSE;
267  }
268  else *size = sizeW / sizeof(WCHAR);
269 
270  HeapFree( GetProcessHeap(), 0, bufferW );
271  }
272  return ret;
273 }
274 
275 /******************************************************************************
276  * GetColorDirectoryW [MSCMS.@]
277  *
278  * Get the directory where color profiles are stored.
279  *
280  * PARAMS
281  * machine [I] Name of the machine for which to get the color directory.
282  * Must be NULL, which indicates the local machine.
283  * buffer [I] Buffer to receive the path name.
284  * size [I/O] Size of the buffer in bytes. On return the variable holds
285  * the number of bytes actually needed.
286  */
288 {
289  WCHAR colordir[MAX_PATH];
290  static const WCHAR colorsubdir[] =
291  {'\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\','c','o','l','o','r',0};
292  DWORD len;
293 
294  TRACE( "( %p, %p )\n", buffer, size );
295 
296  if (machine || !size) return FALSE;
297 
298  GetSystemDirectoryW( colordir, ARRAY_SIZE( colordir ));
299  lstrcatW( colordir, colorsubdir );
300 
301  len = lstrlenW( colordir ) * sizeof(WCHAR);
302 
303  if (buffer && len <= *size)
304  {
305  lstrcpyW( buffer, colordir );
306  *size = len;
307  return TRUE;
308  }
309 
311  *size = len;
312  return FALSE;
313 }
314 
315 /******************************************************************************
316  * GetColorProfileElement [MSCMS.@]
317  *
318  * Retrieve data for a specified tag type.
319  *
320  * PARAMS
321  * profile [I] Handle to a color profile.
322  * type [I] ICC tag type.
323  * offset [I] Offset in bytes to start copying from.
324  * size [I/O] Size of the buffer in bytes. On return the variable holds
325  * the number of bytes actually needed.
326  * buffer [O] Buffer to receive the tag data.
327  * ref [O] Pointer to a BOOL that specifies whether more than one tag
328  * references the data.
329  *
330  * RETURNS
331  * Success: TRUE
332  * Failure: FALSE
333  */
335  PVOID buffer, PBOOL ref )
336 {
337  BOOL ret = FALSE;
338 #ifdef HAVE_LCMS2
339  struct profile *profile = grab_profile( handle );
340 
341  TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", handle, type, offset, size, buffer, ref );
342 
343  if (!profile) return FALSE;
344 
345  if (!size || !ref)
346  {
347  release_profile( profile );
348  return FALSE;
349  }
350  if (!get_tag_data( profile, type, offset, buffer, size ))
351  {
352  release_profile( profile );
353  return FALSE;
354  }
355  ret = get_tag_data( profile, type, offset, buffer, size );
356  *ref = cmsTagLinkedTo( profile->cmsprofile, type ) != 0;
357  release_profile( profile );
358 #endif /* HAVE_LCMS2 */
359  return ret;
360 }
361 
362 /******************************************************************************
363  * GetColorProfileElementTag [MSCMS.@]
364  *
365  * Get the tag type from a color profile by index.
366  *
367  * PARAMS
368  * profile [I] Handle to a color profile.
369  * index [I] Index into the tag table of the color profile.
370  * type [O] Pointer to a variable that holds the ICC tag type on return.
371  *
372  * RETURNS
373  * Success: TRUE
374  * Failure: FALSE
375  *
376  * NOTES
377  * The tag table index starts at 1.
378  * Use GetCountColorProfileElements to retrieve a count of tagged elements.
379  */
381 {
382  BOOL ret = FALSE;
383 #ifdef HAVE_LCMS2
384  struct profile *profile = grab_profile( handle );
385  cmsInt32Number num_tags;
386  cmsTagSignature sig;
387 
388  TRACE( "( %p, %d, %p )\n", handle, index, type );
389 
390  if (!profile) return FALSE;
391 
392  if (!type)
393  {
394  release_profile( profile );
395  return FALSE;
396  }
397  num_tags = cmsGetTagCount( profile->cmsprofile );
398  if (num_tags < 0 || index > num_tags || index < 1)
399  {
400  release_profile( profile );
401  return FALSE;
402  }
403  if ((sig = cmsGetTagSignature( profile->cmsprofile, index - 1 )))
404  {
405  *type = sig;
406  ret = TRUE;
407  }
408  release_profile( profile );
409 
410 #endif /* HAVE_LCMS2 */
411  return ret;
412 }
413 
414 /******************************************************************************
415  * GetColorProfileFromHandle [MSCMS.@]
416  *
417  * Retrieve an ICC color profile by handle.
418  *
419  * PARAMS
420  * profile [I] Handle to a color profile.
421  * buffer [O] Buffer to receive the ICC profile.
422  * size [I/O] Size of the buffer in bytes. On return the variable holds the
423  * number of bytes actually needed.
424  *
425  * RETURNS
426  * Success: TRUE
427  * Failure: FALSE
428  *
429  * NOTES
430  * The profile returned will be in big-endian format.
431  */
433 {
434  BOOL ret = FALSE;
435 #ifdef HAVE_LCMS2
436  struct profile *profile = grab_profile( handle );
438 
439  TRACE( "( %p, %p, %p )\n", handle, buffer, size );
440 
441  if (!profile) return FALSE;
442 
443  if (!size)
444  {
445  release_profile( profile );
446  return FALSE;
447  }
448  get_profile_header( profile, &header );
449 
450  if (!buffer || header.phSize > *size)
451  {
452  *size = header.phSize;
453  release_profile( profile );
454  return FALSE;
455  }
456 
457  /* No endian conversion needed */
458  memcpy( buffer, profile->data, profile->size );
459  *size = profile->size;
460 
461  release_profile( profile );
462  ret = TRUE;
463 
464 #endif /* HAVE_LCMS2 */
465  return ret;
466 }
467 
468 /******************************************************************************
469  * GetColorProfileHeader [MSCMS.@]
470  *
471  * Retrieve a color profile header by handle.
472  *
473  * PARAMS
474  * profile [I] Handle to a color profile.
475  * header [O] Buffer to receive the ICC profile header.
476  *
477  * RETURNS
478  * Success: TRUE
479  * Failure: FALSE
480  *
481  * NOTES
482  * The profile header returned will be adjusted for endianness.
483  */
485 {
486 #ifdef HAVE_LCMS2
487  struct profile *profile = grab_profile( handle );
488 
489  TRACE( "( %p, %p )\n", handle, header );
490 
491  if (!profile) return FALSE;
492 
493  if (!header)
494  {
495  release_profile( profile );
496  return FALSE;
497  }
498  get_profile_header( profile, header );
499  release_profile( profile );
500  return TRUE;
501 
502 #else
503  return FALSE;
504 #endif /* HAVE_LCMS2 */
505 }
506 
507 /******************************************************************************
508  * GetCountColorProfileElements [MSCMS.@]
509  *
510  * Retrieve the number of elements in a color profile.
511  *
512  * PARAMS
513  * profile [I] Handle to a color profile.
514  * count [O] Pointer to a variable which is set to the number of elements
515  * in the color profile.
516  *
517  * RETURNS
518  * Success: TRUE
519  * Failure: FALSE
520  */
522 {
523  BOOL ret = FALSE;
524 #ifdef HAVE_LCMS2
525  struct profile *profile = grab_profile( handle );
526  cmsInt32Number num_tags;
527 
528  TRACE( "( %p, %p )\n", handle, count );
529 
530  if (!profile) return FALSE;
531 
532  if (!count)
533  {
534  release_profile( profile );
535  return FALSE;
536  }
537  if ((num_tags = cmsGetTagCount( profile->cmsprofile )) >= 0)
538  {
539  *count = num_tags;
540  ret = TRUE;
541  }
542  release_profile( profile );
543 
544 #endif /* HAVE_LCMS2 */
545  return ret;
546 }
547 
548 /******************************************************************************
549  * GetStandardColorSpaceProfileA [MSCMS.@]
550  *
551  * See GetStandardColorSpaceProfileW.
552  */
554 {
555  INT len;
556  LPWSTR profileW;
557  BOOL ret = FALSE;
558  DWORD sizeW;
559 
560  TRACE( "( 0x%08x, %p, %p )\n", id, profile, size );
561 
562  if (machine)
563  {
565  return FALSE;
566  }
567 
568  if (!size)
569  {
571  return FALSE;
572  }
573 
574  sizeW = *size * sizeof(WCHAR);
575 
576  if (!profile)
577  {
579  *size = sizeW / sizeof(WCHAR);
580  return ret;
581  }
582 
583  profileW = HeapAlloc( GetProcessHeap(), 0, sizeW );
584  if (profileW)
585  {
586  if ((ret = GetStandardColorSpaceProfileW( NULL, id, profileW, &sizeW )))
587  {
588  *size = WideCharToMultiByte( CP_ACP, 0, profileW, -1, NULL, 0, NULL, NULL );
589  len = WideCharToMultiByte( CP_ACP, 0, profileW, -1, profile, *size, NULL, NULL );
590  if (!len) ret = FALSE;
591  }
592  else *size = sizeW / sizeof(WCHAR);
593 
594  HeapFree( GetProcessHeap(), 0, profileW );
595  }
596  return ret;
597 }
598 
599 /******************************************************************************
600  * GetStandardColorSpaceProfileW [MSCMS.@]
601  *
602  * Retrieve the profile filename for a given standard color space id.
603  *
604  * PARAMS
605  * machine [I] Name of the machine for which to get the standard color space.
606  * Must be NULL, which indicates the local machine.
607  * id [I] Id of a standard color space.
608  * profile [O] Buffer to receive the profile filename.
609  * size [I/O] Size of the filename buffer in bytes.
610  *
611  * RETURNS
612  * Success: TRUE
613  * Failure: FALSE
614  */
616 {
617  static const WCHAR rgbprofilefile[] =
618  { '\\','s','r','g','b',' ','c','o','l','o','r',' ',
619  's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
620  WCHAR rgbprofile[MAX_PATH];
621  DWORD len = sizeof(rgbprofile);
622 
623  TRACE( "( 0x%08x, %p, %p )\n", id, profile, size );
624 
625  if (machine)
626  {
628  return FALSE;
629  }
630 
631  if (!size)
632  {
634  return FALSE;
635  }
636 
637  if (!profile)
638  {
640  return FALSE;
641  }
642 
643  GetColorDirectoryW( machine, rgbprofile, &len );
644 
645  switch (id)
646  {
647  case LCS_sRGB:
648  case LCS_WINDOWS_COLOR_SPACE: /* FIXME */
649  lstrcatW( rgbprofile, rgbprofilefile );
650  len = lstrlenW( rgbprofile ) * sizeof(WCHAR);
651 
652  if (*size < len)
653  {
654  *size = len;
656  return FALSE;
657  }
658 
659  lstrcpyW( profile, rgbprofile );
660  break;
661 
662  default:
664  return FALSE;
665  }
666  return TRUE;
667 }
668 
670 {
671  static const WCHAR slash[] = {'\\',0};
672  BOOL ret;
675  DWORD size = sizeof(path);
676  HANDLE handle;
677 
679  if (!ret)
680  {
681  WARN( "Can't retrieve color directory\n" );
682  return FALSE;
683  }
684  if (size + sizeof(slash) + sizeof(WCHAR) * lstrlenW( file ) > sizeof(path))
685  {
686  WARN( "Filename too long\n" );
687  return FALSE;
688  }
689 
690  lstrcatW( path, slash );
691  lstrcatW( path, file );
692 
693  profile.dwType = PROFILE_FILENAME;
694  profile.pProfileData = path;
695  profile.cbDataSize = lstrlenW( path ) + 1;
696 
698  if (!handle)
699  {
700  WARN( "Can't open color profile\n" );
701  return FALSE;
702  }
703 
705  if (!ret)
706  WARN( "Can't retrieve color profile header\n" );
707 
709  return ret;
710 }
711 
713 {
714  if (rec->dwFields & ET_DEVICENAME)
715  {
716  FIXME( "ET_DEVICENAME: %s\n", debugstr_w(rec->pDeviceName) );
717  }
718  if (rec->dwFields & ET_MEDIATYPE)
719  {
720  FIXME( "ET_MEDIATYPE: 0x%08x\n", rec->dwMediaType );
721  }
722  if (rec->dwFields & ET_DITHERMODE)
723  {
724  FIXME( "ET_DITHERMODE: 0x%08x\n", rec->dwDitheringMode );
725  }
726  if (rec->dwFields & ET_RESOLUTION)
727  {
728  FIXME( "ET_RESOLUTION: 0x%08x, 0x%08x\n",
729  rec->dwResolution[0], rec->dwResolution[1] );
730  }
731  if (rec->dwFields & ET_DEVICECLASS)
732  {
733  FIXME( "ET_DEVICECLASS: %s\n", dbgstr_tag(rec->dwMediaType) );
734  }
735  if (rec->dwFields & ET_CMMTYPE)
736  {
737  TRACE( "ET_CMMTYPE: %s\n", dbgstr_tag(rec->dwCMMType) );
738  if (rec->dwCMMType != hdr->phCMMType) return FALSE;
739  }
740  if (rec->dwFields & ET_CLASS)
741  {
742  TRACE( "ET_CLASS: %s\n", dbgstr_tag(rec->dwClass) );
743  if (rec->dwClass != hdr->phClass) return FALSE;
744  }
745  if (rec->dwFields & ET_DATACOLORSPACE)
746  {
747  TRACE( "ET_DATACOLORSPACE: %s\n", dbgstr_tag(rec->dwDataColorSpace) );
748  if (rec->dwDataColorSpace != hdr->phDataColorSpace) return FALSE;
749  }
750  if (rec->dwFields & ET_CONNECTIONSPACE)
751  {
752  TRACE( "ET_CONNECTIONSPACE: %s\n", dbgstr_tag(rec->dwConnectionSpace) );
753  if (rec->dwConnectionSpace != hdr->phConnectionSpace) return FALSE;
754  }
755  if (rec->dwFields & ET_SIGNATURE)
756  {
757  TRACE( "ET_SIGNATURE: %s\n", dbgstr_tag(rec->dwSignature) );
758  if (rec->dwSignature != hdr->phSignature) return FALSE;
759  }
760  if (rec->dwFields & ET_PLATFORM)
761  {
762  TRACE( "ET_PLATFORM: %s\n", dbgstr_tag(rec->dwPlatform) );
763  if (rec->dwPlatform != hdr->phPlatform) return FALSE;
764  }
765  if (rec->dwFields & ET_PROFILEFLAGS)
766  {
767  TRACE( "ET_PROFILEFLAGS: 0x%08x\n", rec->dwProfileFlags );
768  if (rec->dwProfileFlags != hdr->phProfileFlags) return FALSE;
769  }
770  if (rec->dwFields & ET_MANUFACTURER)
771  {
772  TRACE( "ET_MANUFACTURER: %s\n", dbgstr_tag(rec->dwManufacturer) );
773  if (rec->dwManufacturer != hdr->phManufacturer) return FALSE;
774  }
775  if (rec->dwFields & ET_MODEL)
776  {
777  TRACE( "ET_MODEL: %s\n", dbgstr_tag(rec->dwModel) );
778  if (rec->dwModel != hdr->phModel) return FALSE;
779  }
780  if (rec->dwFields & ET_ATTRIBUTES)
781  {
782  TRACE( "ET_ATTRIBUTES: 0x%08x, 0x%08x\n",
783  rec->dwAttributes[0], rec->dwAttributes[1] );
784  if (rec->dwAttributes[0] != hdr->phAttributes[0] ||
785  rec->dwAttributes[1] != hdr->phAttributes[1]) return FALSE;
786  }
787  if (rec->dwFields & ET_RENDERINGINTENT)
788  {
789  TRACE( "ET_RENDERINGINTENT: 0x%08x\n", rec->dwRenderingIntent );
790  if (rec->dwRenderingIntent != hdr->phRenderingIntent) return FALSE;
791  }
792  if (rec->dwFields & ET_CREATOR)
793  {
794  TRACE( "ET_CREATOR: %s\n", dbgstr_tag(rec->dwCreator) );
795  if (rec->dwCreator != hdr->phCreator) return FALSE;
796  }
797  return TRUE;
798 }
799 
800 /******************************************************************************
801  * EnumColorProfilesA [MSCMS.@]
802  *
803  * See EnumColorProfilesW.
804  */
807 {
808  BOOL match, ret = FALSE;
809  char spec[] = "\\*.icm";
810  char colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL;
811  DWORD i, len = sizeof(colordir), count = 0, totalsize = 0;
814  ENUMTYPEW recordW;
815  WCHAR *fileW = NULL, *deviceW = NULL;
816  HANDLE find;
817 
818  TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number );
819 
820  if (machine || !record || !size ||
821  record->dwSize != sizeof(ENUMTYPEA) ||
822  record->dwVersion != ENUM_TYPE_VERSION) return FALSE;
823 
824  ret = GetColorDirectoryA( machine, colordir, &len );
825  if (!ret || len + sizeof(spec) > MAX_PATH)
826  {
827  WARN( "can't retrieve color directory\n" );
828  return FALSE;
829  }
830 
831  lstrcpyA( glob, colordir );
832  lstrcatA( glob, spec );
833 
834  find = FindFirstFileA( glob, &data );
835  if (find == INVALID_HANDLE_VALUE) return FALSE;
836 
837  profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(char *) + 1 );
838  if (!profiles) goto exit;
839 
840  memcpy( &recordW, record, sizeof(ENUMTYPEA) );
841  if (record->pDeviceName)
842  {
843  deviceW = strdupW( record->pDeviceName );
844  if (!(recordW.pDeviceName = deviceW)) goto exit;
845  }
846 
847  fileW = strdupW( data.cFileName );
848  if (!fileW) goto exit;
849 
851  if (ret)
852  {
853  match = match_profile( &recordW, &header );
854  if (match)
855  {
856  len = sizeof(char) * (lstrlenA( data.cFileName ) + 1);
857  profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
858 
859  if (!profiles[count]) goto exit;
860  else
861  {
862  TRACE( "matching profile: %s\n", debugstr_a(data.cFileName) );
863  lstrcpyA( profiles[count], data.cFileName );
864  totalsize += len;
865  count++;
866  }
867  }
868  }
869  HeapFree( GetProcessHeap(), 0, fileW );
870  fileW = NULL;
871 
872  while (FindNextFileA( find, &data ))
873  {
874  fileW = strdupW( data.cFileName );
875  if (!fileW) goto exit;
876 
878  if (!ret)
879  {
880  HeapFree( GetProcessHeap(), 0, fileW );
881  continue;
882  }
883 
884  match = match_profile( &recordW, &header );
885  if (match)
886  {
888  profiles, sizeof(char *) * (count + 1) );
889  if (!tmp) goto exit;
890  else profiles = tmp;
891 
892  len = sizeof(char) * (lstrlenA( data.cFileName ) + 1);
893  profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
894 
895  if (!profiles[count]) goto exit;
896  else
897  {
898  TRACE( "matching profile: %s\n", debugstr_a(data.cFileName) );
899  lstrcpyA( profiles[count], data.cFileName );
900  totalsize += len;
901  count++;
902  }
903  }
904  HeapFree( GetProcessHeap(), 0, fileW );
905  fileW = NULL;
906  }
907 
908  totalsize++;
909  if (buffer && *size >= totalsize)
910  {
911  char *p = (char *)buffer;
912 
913  for (i = 0; i < count; i++)
914  {
915  lstrcpyA( p, profiles[i] );
916  p += lstrlenA( profiles[i] ) + 1;
917  }
918  *p = 0;
919  ret = TRUE;
920  }
921  else
922  {
924  ret = FALSE;
925  }
926 
927  *size = totalsize;
928  if (number) *number = count;
929 
930 exit:
931  for (i = 0; i < count; i++)
932  HeapFree( GetProcessHeap(), 0, profiles[i] );
933  HeapFree( GetProcessHeap(), 0, profiles );
935  HeapFree( GetProcessHeap(), 0, fileW );
936  FindClose( find );
937 
938  return ret;
939 }
940 
941 /******************************************************************************
942  * EnumColorProfilesW [MSCMS.@]
943  *
944  * Enumerate profiles that match given criteria.
945  *
946  * PARAMS
947  * machine [I] Name of the machine for which to enumerate profiles.
948  * Must be NULL, which indicates the local machine.
949  * record [I] Record of criteria that a profile must match.
950  * buffer [O] Buffer to receive a string array of profile filenames.
951  * size [I/O] Size of the filename buffer in bytes.
952  * number [O] Number of filenames copied into buffer.
953  *
954  * RETURNS
955  * Success: TRUE
956  * Failure: FALSE
957  */
960 {
961  static const WCHAR spec[] = {'\\','*','i','c','m',0};
962  BOOL match, ret = FALSE;
963  WCHAR colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL;
964  DWORD i, len = sizeof(colordir), count = 0, totalsize = 0;
967  HANDLE find;
968 
969  TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number );
970 
971  if (machine || !record || !size ||
972  record->dwSize != sizeof(ENUMTYPEW) ||
973  record->dwVersion != ENUM_TYPE_VERSION) return FALSE;
974 
975  ret = GetColorDirectoryW( machine, colordir, &len );
976  if (!ret || len + sizeof(spec) > MAX_PATH)
977  {
978  WARN( "Can't retrieve color directory\n" );
979  return FALSE;
980  }
981 
982  lstrcpyW( glob, colordir );
983  lstrcatW( glob, spec );
984 
985  find = FindFirstFileW( glob, &data );
986  if (find == INVALID_HANDLE_VALUE) return FALSE;
987 
988  profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR *) + 1 );
989  if (!profiles) goto exit;
990 
991  ret = header_from_file( data.cFileName, &header );
992  if (ret)
993  {
995  if (match)
996  {
997  len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1);
998  profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
999 
1000  if (!profiles[count]) goto exit;
1001  else
1002  {
1003  TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) );
1004  lstrcpyW( profiles[count], data.cFileName );
1005  totalsize += len;
1006  count++;
1007  }
1008  }
1009  }
1010 
1011  while (FindNextFileW( find, &data ))
1012  {
1013  ret = header_from_file( data.cFileName, &header );
1014  if (!ret) continue;
1015 
1017  if (match)
1018  {
1020  profiles, sizeof(WCHAR *) * (count + 1) );
1021  if (!tmp) goto exit;
1022  else profiles = tmp;
1023 
1024  len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1);
1025  profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
1026 
1027  if (!profiles[count]) goto exit;
1028  else
1029  {
1030  TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) );
1031  lstrcpyW( profiles[count], data.cFileName );
1032  totalsize += len;
1033  count++;
1034  }
1035  }
1036  }
1037 
1038  totalsize++;
1039  if (buffer && *size >= totalsize)
1040  {
1041  WCHAR *p = (WCHAR *)buffer;
1042 
1043  for (i = 0; i < count; i++)
1044  {
1045  lstrcpyW( p, profiles[i] );
1046  p += lstrlenW( profiles[i] ) + 1;
1047  }
1048  *p = 0;
1049  ret = TRUE;
1050  }
1051  else
1052  {
1054  ret = FALSE;
1055  }
1056 
1057  *size = totalsize;
1058  if (number) *number = count;
1059 
1060 exit:
1061  for (i = 0; i < count; i++)
1062  HeapFree( GetProcessHeap(), 0, profiles[i] );
1063  HeapFree( GetProcessHeap(), 0, profiles );
1064  FindClose( find );
1065 
1066  return ret;
1067 }
1068 
1069 /******************************************************************************
1070  * InstallColorProfileA [MSCMS.@]
1071  *
1072  * See InstallColorProfileW.
1073  */
1075 {
1076  UINT len;
1077  LPWSTR profileW;
1078  BOOL ret = FALSE;
1079 
1080  TRACE( "( %s )\n", debugstr_a(profile) );
1081 
1082  if (machine || !profile) return FALSE;
1083 
1084  len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
1085  profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1086 
1087  if (profileW)
1088  {
1089  MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
1090 
1091  ret = InstallColorProfileW( NULL, profileW );
1092  HeapFree( GetProcessHeap(), 0, profileW );
1093  }
1094  return ret;
1095 }
1096 
1097 /******************************************************************************
1098  * InstallColorProfileW [MSCMS.@]
1099  *
1100  * Install a color profile.
1101  *
1102  * PARAMS
1103  * machine [I] Name of the machine to install the profile on. Must be NULL,
1104  * which indicates the local machine.
1105  * profile [I] Full path name of the profile to install.
1106  *
1107  * RETURNS
1108  * Success: TRUE
1109  * Failure: FALSE
1110  */
1112 {
1114  DWORD size = sizeof(dest);
1115  static const WCHAR slash[] = { '\\', 0 };
1116 
1117  TRACE( "( %s )\n", debugstr_w(profile) );
1118 
1119  if (machine || !profile) return FALSE;
1120 
1121  if (!GetColorDirectoryW( machine, dest, &size )) return FALSE;
1122 
1123  basename( profile, base );
1124 
1125  lstrcatW( dest, slash );
1126  lstrcatW( dest, base );
1127 
1128  /* Is source equal to destination? */
1129  if (!lstrcmpW( profile, dest )) return TRUE;
1130 
1131  return CopyFileW( profile, dest, TRUE );
1132 }
1133 
1134 /******************************************************************************
1135  * IsColorProfileTagPresent [MSCMS.@]
1136  *
1137  * Determine if a given ICC tag type is present in a color profile.
1138  *
1139  * PARAMS
1140  * profile [I] Color profile handle.
1141  * tag [I] ICC tag type.
1142  * present [O] Pointer to a BOOL variable. Set to TRUE if tag type is present,
1143  * FALSE otherwise.
1144  *
1145  * RETURNS
1146  * Success: TRUE
1147  * Failure: FALSE
1148  */
1150 {
1151  BOOL ret = FALSE;
1152 #ifdef HAVE_LCMS2
1153  struct profile *profile = grab_profile( handle );
1154 
1155  TRACE( "( %p, 0x%08x, %p )\n", handle, type, present );
1156 
1157  if (!profile) return FALSE;
1158 
1159  if (!present)
1160  {
1161  release_profile( profile );
1162  return FALSE;
1163  }
1164  *present = (cmsIsTag( profile->cmsprofile, type ) != 0);
1165  release_profile( profile );
1166  ret = TRUE;
1167 
1168 #endif /* HAVE_LCMS2 */
1169  return ret;
1170 }
1171 
1172 /******************************************************************************
1173  * IsColorProfileValid [MSCMS.@]
1174  *
1175  * Determine if a given color profile is valid.
1176  *
1177  * PARAMS
1178  * profile [I] Color profile handle.
1179  * valid [O] Pointer to a BOOL variable. Set to TRUE if profile is valid,
1180  * FALSE otherwise.
1181  *
1182  * RETURNS
1183  * Success: TRUE
1184  * Failure: FALSE
1185  */
1187 {
1188  BOOL ret = FALSE;
1189 #ifdef HAVE_LCMS2
1190  struct profile *profile = grab_profile( handle );
1191 
1192  TRACE( "( %p, %p )\n", handle, valid );
1193 
1194  if (!profile) return FALSE;
1195 
1196  if (!valid)
1197  {
1198  release_profile( profile );
1199  return FALSE;
1200  }
1201  if (profile->data) ret = *valid = TRUE;
1202  release_profile( profile );
1203 
1204 #endif /* HAVE_LCMS2 */
1205  return ret;
1206 }
1207 
1208 /******************************************************************************
1209  * SetColorProfileElement [MSCMS.@]
1210  *
1211  * Set data for a specified tag type.
1212  *
1213  * PARAMS
1214  * profile [I] Handle to a color profile.
1215  * type [I] ICC tag type.
1216  * offset [I] Offset in bytes to start copying to.
1217  * size [I/O] Size of the buffer in bytes. On return the variable holds the
1218  * number of bytes actually needed.
1219  * buffer [O] Buffer holding the tag data.
1220  *
1221  * RETURNS
1222  * Success: TRUE
1223  * Failure: FALSE
1224  */
1226  PVOID buffer )
1227 {
1228  BOOL ret = FALSE;
1229 #ifdef HAVE_LCMS2
1230  struct profile *profile = grab_profile( handle );
1231 
1232  TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer );
1233 
1234  if (!profile) return FALSE;
1235 
1236  if (!size || !buffer || !(profile->access & PROFILE_READWRITE))
1237  {
1238  release_profile( profile );
1239  return FALSE;
1240  }
1241  ret = set_tag_data( profile, type, offset, buffer, size );
1242  release_profile( profile );
1243 #endif /* HAVE_LCMS2 */
1244  return ret;
1245 }
1246 
1247 /******************************************************************************
1248  * SetColorProfileHeader [MSCMS.@]
1249  *
1250  * Set header data for a given profile.
1251  *
1252  * PARAMS
1253  * profile [I] Handle to a color profile.
1254  * header [I] Buffer holding the header data.
1255  *
1256  * RETURNS
1257  * Success: TRUE
1258  * Failure: FALSE
1259  */
1261 {
1262 #ifdef HAVE_LCMS2
1263  struct profile *profile = grab_profile( handle );
1264 
1265  TRACE( "( %p, %p )\n", handle, header );
1266 
1267  if (!profile) return FALSE;
1268 
1269  if (!header || !(profile->access & PROFILE_READWRITE))
1270  {
1271  release_profile( profile );
1272  return FALSE;
1273  }
1274  set_profile_header( profile, header );
1275  release_profile( profile );
1276  return TRUE;
1277 
1278 #else
1279  return FALSE;
1280 #endif /* HAVE_LCMS2 */
1281 }
1282 
1283 /******************************************************************************
1284  * UninstallColorProfileA [MSCMS.@]
1285  *
1286  * See UninstallColorProfileW.
1287  */
1289 {
1290  UINT len;
1291  LPWSTR profileW;
1292  BOOL ret = FALSE;
1293 
1294  TRACE( "( %s, %x )\n", debugstr_a(profile), delete );
1295 
1296  if (machine || !profile) return FALSE;
1297 
1298  len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
1299  profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1300 
1301  if (profileW)
1302  {
1303  MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
1304 
1305  ret = UninstallColorProfileW( NULL, profileW , delete );
1306 
1307  HeapFree( GetProcessHeap(), 0, profileW );
1308  }
1309  return ret;
1310 }
1311 
1312 /******************************************************************************
1313  * UninstallColorProfileW [MSCMS.@]
1314  *
1315  * Uninstall a color profile.
1316  *
1317  * PARAMS
1318  * machine [I] Name of the machine to uninstall the profile on. Must be NULL,
1319  * which indicates the local machine.
1320  * profile [I] Full path name of the profile to uninstall.
1321  * delete [I] Bool that specifies whether the profile file should be deleted.
1322  *
1323  * RETURNS
1324  * Success: TRUE
1325  * Failure: FALSE
1326  */
1328 {
1329  TRACE( "( %s, %x )\n", debugstr_w(profile), delete );
1330 
1331  if (machine || !profile) return FALSE;
1332 
1333  if (delete) return DeleteFileW( profile );
1334 
1335  return TRUE;
1336 }
1337 
1339 {
1340  int len;
1341  if (!in->pProfileData) return FALSE;
1342  len = MultiByteToWideChar( CP_ACP, 0, in->pProfileData, -1, NULL, 0 );
1343  if (!(out->pProfileData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
1344  out->cbDataSize = len * sizeof(WCHAR);
1345  MultiByteToWideChar( CP_ACP, 0, in->pProfileData, -1, out->pProfileData, len );
1346  out->dwType = in->dwType;
1347  return TRUE;
1348 }
1349 
1350 /******************************************************************************
1351  * OpenColorProfileA [MSCMS.@]
1352  *
1353  * See OpenColorProfileW.
1354  */
1356 {
1357  HPROFILE handle = NULL;
1358  PROFILE profileW;
1359 
1360  TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation );
1361 
1362  if (!profile || !profile->pProfileData) return NULL;
1363 
1364  /* No AW conversion needed for memory based profiles */
1365  if (profile->dwType & PROFILE_MEMBUFFER)
1366  return OpenColorProfileW( profile, access, sharing, creation );
1367 
1368  if (!profile_AtoW( profile, &profileW )) return FALSE;
1369  handle = OpenColorProfileW( &profileW, access, sharing, creation );
1370  HeapFree( GetProcessHeap(), 0, profileW.pProfileData );
1371  return handle;
1372 }
1373 
1374 /******************************************************************************
1375  * OpenColorProfileW [MSCMS.@]
1376  *
1377  * Open a color profile.
1378  *
1379  * PARAMS
1380  * profile [I] Pointer to a color profile structure.
1381  * access [I] Desired access.
1382  * sharing [I] Sharing mode.
1383  * creation [I] Creation mode.
1384  *
1385  * RETURNS
1386  * Success: Handle to the opened profile.
1387  * Failure: NULL
1388  *
1389  * NOTES
1390  * Values for access: PROFILE_READ or PROFILE_READWRITE.
1391  * Values for sharing: 0 (no sharing), FILE_SHARE_READ and/or FILE_SHARE_WRITE.
1392  * Values for creation: one of CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING,
1393  * OPEN_ALWAYS, TRUNCATE_EXISTING.
1394  * Sharing and creation flags are ignored for memory based profiles.
1395  */
1397 {
1398 #ifdef HAVE_LCMS2
1399  cmsHPROFILE cmsprofile = NULL;
1400  char *data = NULL;
1402  DWORD size;
1403 
1404  TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation );
1405 
1406  if (!profile || !profile->pProfileData) return NULL;
1407 
1408  if (profile->dwType == PROFILE_MEMBUFFER)
1409  {
1410  /* FIXME: access flags not implemented for memory based profiles */
1411 
1412  if (!(data = HeapAlloc( GetProcessHeap(), 0, profile->cbDataSize ))) return NULL;
1413  memcpy( data, profile->pProfileData, profile->cbDataSize );
1414 
1415  if (!(cmsprofile = cmsOpenProfileFromMem( data, profile->cbDataSize )))
1416  {
1417  HeapFree( GetProcessHeap(), 0, data );
1418  return FALSE;
1419  }
1420  size = profile->cbDataSize;
1421  }
1422  else if (profile->dwType == PROFILE_FILENAME)
1423  {
1424  DWORD read, flags = 0;
1425 
1426  TRACE( "profile file: %s\n", debugstr_w( profile->pProfileData ) );
1427 
1430 
1431  if (!flags) return NULL;
1433 
1434  if (!PathIsRelativeW( profile->pProfileData ))
1435  handle = CreateFileW( profile->pProfileData, flags, sharing, NULL, creation, 0, NULL );
1436  else
1437  {
1438  WCHAR *path;
1439 
1441  {
1442  size += (strlenW( profile->pProfileData ) + 2) * sizeof(WCHAR);
1443  if (!(path = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
1446  strcatW( path, profile->pProfileData );
1447  }
1448  else return NULL;
1449  handle = CreateFileW( path, flags, sharing, NULL, creation, 0, NULL );
1450  HeapFree( GetProcessHeap(), 0, path );
1451  }
1453  {
1454  WARN( "Unable to open color profile %u\n", GetLastError() );
1455  return NULL;
1456  }
1457  if ((size = GetFileSize( handle, NULL )) == INVALID_FILE_SIZE)
1458  {
1459  ERR( "Unable to retrieve size of color profile\n" );
1460  CloseHandle( handle );
1461  return NULL;
1462  }
1463  if (!(data = HeapAlloc( GetProcessHeap(), 0, size )))
1464  {
1465  ERR( "Unable to allocate memory for color profile\n" );
1466  CloseHandle( handle );
1467  return NULL;
1468  }
1469  if (!ReadFile( handle, data, size, &read, NULL ) || read != size)
1470  {
1471  ERR( "Unable to read color profile\n" );
1472 
1473  CloseHandle( handle );
1474  HeapFree( GetProcessHeap(), 0, data );
1475  return NULL;
1476  }
1477  if (!(cmsprofile = cmsOpenProfileFromMem( data, size )))
1478  {
1479  CloseHandle( handle );
1480  HeapFree( GetProcessHeap(), 0, data );
1481  return NULL;
1482  }
1483  }
1484  else
1485  {
1486  ERR( "Invalid profile type %u\n", profile->dwType );
1487  return NULL;
1488  }
1489 
1490  if (cmsprofile)
1491  {
1492  struct profile profile;
1493  HPROFILE hprof;
1494 
1495  profile.file = handle;
1496  profile.access = access;
1497  profile.data = data;
1498  profile.size = size;
1499  profile.cmsprofile = cmsprofile;
1500 
1501  if ((hprof = create_profile( &profile ))) return hprof;
1502  HeapFree( GetProcessHeap(), 0, data );
1503  cmsCloseProfile( cmsprofile );
1504  }
1505  CloseHandle( handle );
1506 
1507 #endif /* HAVE_LCMS2 */
1508  return NULL;
1509 }
1510 
1511 /******************************************************************************
1512  * CloseColorProfile [MSCMS.@]
1513  *
1514  * Close a color profile.
1515  *
1516  * PARAMS
1517  * profile [I] Handle to the profile.
1518  *
1519  * RETURNS
1520  * Success: TRUE
1521  * Failure: FALSE
1522  */
1524 {
1525  BOOL ret = FALSE;
1526 #ifdef HAVE_LCMS2
1527 
1528  TRACE( "( %p )\n", profile );
1529  ret = close_profile( profile );
1530 
1531 #endif /* HAVE_LCMS2 */
1532  return ret;
1533 }
1534 
1535 /******************************************************************************
1536  * WcsGetUsePerUserProfiles [MSCMS.@]
1537  */
1538 BOOL WINAPI WcsGetUsePerUserProfiles( const WCHAR* name, DWORD class, BOOL* use_per_user_profile )
1539 {
1540  FIXME( "%s %s %p\n", debugstr_w(name), dbgstr_tag(class), use_per_user_profile );
1542  return FALSE;
1543 }
1544 
1545 /******************************************************************************
1546  * WcsEnumColorProfilesSize [MSCMS.@]
1547  */
1549 {
1550  FIXME( "%d %p %p\n", scope, record, size );
1552  return FALSE;
1553 }
1554 
1555 /******************************************************************************
1556  * WcsOpenColorProfileA [MSCMS.@]
1557  */
1559  DWORD creation, DWORD flags )
1560 {
1561  PROFILE cdmW, campW = {0}, gmmpW = {0};
1562  HPROFILE ret = NULL;
1563 
1564  TRACE( "%p, %p, %p, %08x, %08x, %08x, %08x\n", cdm, camp, gmmp, access, sharing, creation, flags );
1565 
1566  if (!cdm || !profile_AtoW( cdm, &cdmW )) return NULL;
1567  if (camp && !profile_AtoW( camp, &campW )) goto done;
1568  if (gmmp && !profile_AtoW( gmmp, &gmmpW )) goto done;
1569 
1570  ret = WcsOpenColorProfileW( &cdmW, &campW, &gmmpW, access, sharing, creation, flags );
1571 
1572 done:
1573  HeapFree( GetProcessHeap(), 0, cdmW.pProfileData );
1574  HeapFree( GetProcessHeap(), 0, campW.pProfileData );
1575  HeapFree( GetProcessHeap(), 0, gmmpW.pProfileData );
1576  return ret;
1577 }
1578 
1579 /******************************************************************************
1580  * WcsOpenColorProfileW [MSCMS.@]
1581  */
1583  DWORD creation, DWORD flags )
1584 {
1585  TRACE( "%p, %p, %p, %08x, %08x, %08x, %08x\n", cdm, camp, gmmp, access, sharing, creation, flags );
1586  FIXME("no support for WCS profiles\n" );
1587 
1588  return OpenColorProfileW( cdm, access, sharing, creation );
1589 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define ET_RENDERINGINTENT
Definition: icm.h:285
static const WCHAR classW[]
Definition: lex.c:40
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
#define PROFILE_READ
Definition: icm.h:420
DWORD dwConnectionSpace
Definition: icm.h:259
const uint16_t * PCWSTR
Definition: typedefs.h:56
static ULONG POBJECT_ATTRIBUTES PIO_STATUS_BLOCK ULONG sharing
Definition: pipe.c:68
static BOOL header_from_file(LPCWSTR file, PPROFILEHEADER header)
Definition: profile.c:669
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
BOOL WINAPI AssociateColorProfileWithDeviceW(PCWSTR machine, PCWSTR profile, PCWSTR device)
Definition: profile.c:154
DWORD dwCreator
Definition: icm.h:267
#define TRUE
Definition: types.h:120
#define ET_MEDIATYPE
Definition: icm.h:272
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1558
#define CloseHandle
Definition: compat.h:407
char hdr[14]
Definition: iptest.cpp:33
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
DWORD dwMediaType
Definition: icm.h:253
#define ENUM_TYPE_VERSION
Definition: icm.h:221
PCWSTR pDeviceName
Definition: icm.h:252
#define WideCharToMultiByte
Definition: compat.h:101
#define ET_CMMTYPE
Definition: icm.h:275
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define REG_BINARY
Definition: nt_native.h:1496
Definition: match.c:28
GLsizei const GLchar ** path
Definition: glext.h:7234
static void basename(LPCWSTR path, LPWSTR name)
Definition: profile.c:38
uint16_t * PWSTR
Definition: typedefs.h:55
DWORD dwResolution[2]
Definition: icm.h:255
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define WARN(fmt,...)
Definition: debug.h:112
GLintptr offset
Definition: glext.h:5920
DWORD dwPlatform
Definition: icm.h:261
DWORD dwSignature
Definition: icm.h:260
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:400
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI GetColorProfileHeader(HPROFILE handle, PPROFILEHEADER header)
Definition: profile.c:484
Definition: ecma_167.h:138
#define ERROR_INVALID_PROFILE
Definition: winerror.h:1186
HPROFILE WINAPI OpenColorProfileW(PPROFILE profile, DWORD access, DWORD sharing, DWORD creation)
Definition: profile.c:1396
GLuint buffer
Definition: glext.h:5915
#define PROFILE_FILENAME
Definition: icm.h:417
#define ET_PROFILEFLAGS
Definition: icm.h:281
#define ET_ATTRIBUTES
Definition: icm.h:284
static LPWSTR strdupW(LPCSTR str)
Definition: profile.c:46
BOOL WINAPI GetStandardColorSpaceProfileW(PCWSTR machine, DWORD id, PWSTR profile, PDWORD size)
Definition: profile.c:615
#define INVALID_FILE_SIZE
Definition: winbase.h:529
BOOL WINAPI FindNextFileA(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:336
BOOL WINAPI IsColorProfileValid(HPROFILE handle, PBOOL valid)
Definition: profile.c:1186
HPROFILE WINAPI WcsOpenColorProfileW(PROFILE *cdm, PROFILE *camp, PROFILE *gmmp, DWORD access, DWORD sharing, DWORD creation, DWORD flags)
Definition: profile.c:1582
#define lstrlenW
Definition: compat.h:416
int32_t INT
Definition: typedefs.h:57
DWORD dwManufacturer
Definition: icm.h:263
Definition: send.c:48
static const WCHAR deviceW[]
#define ET_DEVICENAME
Definition: icm.h:271
#define FILE_SHARE_READ
Definition: compat.h:125
#define ET_CLASS
Definition: icm.h:276
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
BOOL WINAPI UninstallColorProfileW(PCWSTR machine, PCWSTR profile, BOOL delete)
Definition: profile.c:1327
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:271
#define ET_DITHERMODE
Definition: icm.h:273
#define ET_CREATOR
Definition: icm.h:286
BOOL WINAPI WcsEnumColorProfilesSize(WCS_PROFILE_MANAGEMENT_SCOPE scope, ENUMTYPEW *record, DWORD *size)
Definition: profile.c:1548
BOOL WINAPI GetColorProfileElement(HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size, PVOID buffer, PBOOL ref)
Definition: profile.c:334
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BOOL WINAPI GetStandardColorSpaceProfileA(PCSTR machine, DWORD id, PSTR profile, PDWORD size)
Definition: profile.c:553
static PVOID
Definition: profile.c:43
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
Definition: path.c:289
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: devices.h:37
BOOL WINAPI InstallColorProfileW(PCWSTR machine, PCWSTR profile)
Definition: profile.c:1111
WINE_DEFAULT_DEBUG_CHANNEL(hnetcfg)
static size_t double number
Definition: printf.c:69
DWORD TAGTYPE
Definition: icm.h:30
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:111
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
static const WCHAR sizeW[]
Definition: editor.c:79
struct match match
Definition: match.c:33
GLuint index
Definition: glext.h:6031
DWORD dwFields
Definition: icm.h:251
const char * LPCSTR
Definition: xmlstorage.h:183
BOOL * PBOOL
Definition: windef.h:161
#define ET_DATACOLORSPACE
Definition: icm.h:277
static BOOL match_profile(PENUMTYPEW rec, PPROFILEHEADER hdr)
Definition: profile.c:712
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define OPEN_EXISTING
Definition: compat.h:435
DWORD dwDitheringMode
Definition: icm.h:254
WCS_PROFILE_MANAGEMENT_SCOPE
Definition: icm.h:179
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define debugstr_a
Definition: kernel32.h:31
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
#define PROFILE_MEMBUFFER
Definition: icm.h:418
BOOL WINAPI GetColorDirectoryW(PCWSTR machine, PWSTR buffer, PDWORD size)
Definition: profile.c:287
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
HPROFILE WINAPI WcsOpenColorProfileA(PROFILE *cdm, PROFILE *camp, PROFILE *gmmp, DWORD access, DWORD sharing, DWORD creation, DWORD flags)
Definition: profile.c:1558
BOOL WINAPI IsColorProfileTagPresent(HPROFILE handle, TAGTYPE type, PBOOL present)
Definition: profile.c:1149
static FILE * out
Definition: regtests2xml.c:44
static BOOL set_profile_device_key(PCWSTR file, const BYTE *value, DWORD size)
Definition: profile.c:105
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
#define SetLastError(x)
Definition: compat.h:418
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BOOL WINAPI SetColorProfileHeader(HPROFILE handle, PPROFILEHEADER header)
Definition: profile.c:1260
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
BOOL WINAPI InstallColorProfileA(PCSTR machine, PCSTR profile)
Definition: profile.c:1074
GLbitfield flags
Definition: glext.h:7161
BOOL WINAPI GetColorProfileElementTag(HPROFILE handle, DWORD index, PTAGTYPE type)
Definition: profile.c:380
int ret
BOOL WINAPI AssociateColorProfileWithDeviceA(PCSTR machine, PCSTR profile, PCSTR device)
Definition: profile.c:69
static BOOL profile_AtoW(const PROFILE *in, PROFILE *out)
Definition: profile.c:1338
DWORD dwAttributes[2]
Definition: icm.h:265
static const char machine[]
Definition: profile.c:104
#define ET_RESOLUTION
Definition: icm.h:274
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define ET_DEVICECLASS
Definition: icm.h:287
#define GENERIC_READ
Definition: compat.h:124
BOOL WINAPI SetColorProfileElement(HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size, PVOID buffer)
Definition: profile.c:1225
DWORD * PTAGTYPE
Definition: icm.h:30
#define ERROR_MORE_DATA
Definition: dderror.h:13
HPROFILE WINAPI OpenColorProfileA(PPROFILE profile, DWORD access, DWORD sharing, DWORD creation)
Definition: profile.c:1355
unsigned char BYTE
Definition: xxhash.c:193
BOOL WINAPI GetColorDirectoryA(PCSTR machine, PSTR buffer, PDWORD size)
Definition: profile.c:239
#define ET_MODEL
Definition: icm.h:283
#define ET_MANUFACTURER
Definition: icm.h:282
#define ERR(fmt,...)
Definition: debug.h:110
DWORD dwDataColorSpace
Definition: icm.h:258
#define ET_CONNECTIONSPACE
Definition: icm.h:278
const char * dbgstr_tag(DWORD tag)
Definition: profile.c:58
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
GLuint in
Definition: glext.h:9616
#define lstrcpyW
Definition: compat.h:415
DWORD dwRenderingIntent
Definition: icm.h:266
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2355
BOOL WINAPI UninstallColorProfileA(PCSTR machine, PCSTR profile, BOOL delete)
Definition: profile.c:1288
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
BOOL WINAPI DisassociateColorProfileFromDeviceA(PCSTR machine, PCSTR profile, PCSTR device)
Definition: profile.c:177
#define ARRAY_SIZE(a)
Definition: main.h:24
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define HeapReAlloc
Definition: compat.h:402
signed char * PSTR
Definition: retypes.h:7
#define sprintfW
Definition: unicode.h:58
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
BOOL WINAPI WcsGetUsePerUserProfiles(const WCHAR *name, DWORD class, BOOL *use_per_user_profile)
Definition: profile.c:1538
char ** glob(const char *v)
Definition: fake.c:36
#define ET_PLATFORM
Definition: icm.h:280
#define LCS_sRGB
Definition: wingdi.h:1104
unsigned int UINT
Definition: ndis.h:50
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
BOOL WINAPI EnumColorProfilesW(PCWSTR machine, PENUMTYPEW record, PBYTE buffer, PDWORD size, PDWORD number)
Definition: profile.c:958
DWORD * PDWORD
Definition: pedump.c:68
#define PROFILE_READWRITE
Definition: icm.h:421
BOOL WINAPI GetCountColorProfileElements(HPROFILE handle, PDWORD count)
Definition: profile.c:521
#define MultiByteToWideChar
Definition: compat.h:100
#define CreateFileW
Definition: compat.h:409
DWORD dwModel
Definition: icm.h:264
DWORD dwProfileFlags
Definition: icm.h:262
static TAGID TAGID find
Definition: db.cpp:153
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
Definition: name.c:38
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
BOOL WINAPI DisassociateColorProfileFromDeviceW(PCWSTR machine, PCWSTR profile, PCWSTR device)
Definition: profile.c:216
#define profile
Definition: kernel32.h:12
BOOL WINAPI CloseColorProfile(HPROFILE profile)
Definition: profile.c:1523
#define ET_SIGNATURE
Definition: icm.h:279
static char * dest
Definition: rtl.c:135
DWORD dwClass
Definition: icm.h:257
const char * PCSTR
Definition: typedefs.h:52
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define LCS_WINDOWS_COLOR_SPACE
Definition: wingdi.h:1105
void exit(int exitcode)
Definition: _exit.c:33
BOOL WINAPI EnumColorProfilesA(PCSTR machine, PENUMTYPEA record, PBYTE buffer, PDWORD size, PDWORD number)
Definition: profile.c:805
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
static const WCHAR fileW[]
Definition: url.c:111
DWORD dwCMMType
Definition: icm.h:256
BYTE * PBYTE
Definition: pedump.c:66
HANDLE WINAPI FindFirstFileA(IN LPCSTR lpFileName, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:263
#define HeapFree(x, y, z)
Definition: compat.h:403
struct CFHEADER header
Definition: fdi.c:101
BOOL WINAPI GetColorProfileFromHandle(HPROFILE handle, PBYTE buffer, PDWORD size)
Definition: profile.c:432
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
Definition: fci.c:126
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502