ReactOS  0.4.13-dev-39-g8b6696f
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 ret = FALSE;
922 
923  *size = totalsize;
924  if (number) *number = count;
925 
926 exit:
927  for (i = 0; i < count; i++)
928  HeapFree( GetProcessHeap(), 0, profiles[i] );
929  HeapFree( GetProcessHeap(), 0, profiles );
931  HeapFree( GetProcessHeap(), 0, fileW );
932  FindClose( find );
933 
934  return ret;
935 }
936 
937 /******************************************************************************
938  * EnumColorProfilesW [MSCMS.@]
939  *
940  * Enumerate profiles that match given criteria.
941  *
942  * PARAMS
943  * machine [I] Name of the machine for which to enumerate profiles.
944  * Must be NULL, which indicates the local machine.
945  * record [I] Record of criteria that a profile must match.
946  * buffer [O] Buffer to receive a string array of profile filenames.
947  * size [I/O] Size of the filename buffer in bytes.
948  * number [O] Number of filenames copied into buffer.
949  *
950  * RETURNS
951  * Success: TRUE
952  * Failure: FALSE
953  */
956 {
957  static const WCHAR spec[] = {'\\','*','i','c','m',0};
958  BOOL match, ret = FALSE;
959  WCHAR colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL;
960  DWORD i, len = sizeof(colordir), count = 0, totalsize = 0;
963  HANDLE find;
964 
965  TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number );
966 
967  if (machine || !record || !size ||
968  record->dwSize != sizeof(ENUMTYPEW) ||
969  record->dwVersion != ENUM_TYPE_VERSION) return FALSE;
970 
971  ret = GetColorDirectoryW( machine, colordir, &len );
972  if (!ret || len + sizeof(spec) > MAX_PATH)
973  {
974  WARN( "Can't retrieve color directory\n" );
975  return FALSE;
976  }
977 
978  lstrcpyW( glob, colordir );
979  lstrcatW( glob, spec );
980 
981  find = FindFirstFileW( glob, &data );
982  if (find == INVALID_HANDLE_VALUE) return FALSE;
983 
984  profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR *) + 1 );
985  if (!profiles) goto exit;
986 
987  ret = header_from_file( data.cFileName, &header );
988  if (ret)
989  {
991  if (match)
992  {
993  len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1);
994  profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
995 
996  if (!profiles[count]) goto exit;
997  else
998  {
999  TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) );
1000  lstrcpyW( profiles[count], data.cFileName );
1001  totalsize += len;
1002  count++;
1003  }
1004  }
1005  }
1006 
1007  while (FindNextFileW( find, &data ))
1008  {
1009  ret = header_from_file( data.cFileName, &header );
1010  if (!ret) continue;
1011 
1013  if (match)
1014  {
1016  profiles, sizeof(WCHAR *) * (count + 1) );
1017  if (!tmp) goto exit;
1018  else profiles = tmp;
1019 
1020  len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1);
1021  profiles[count] = HeapAlloc( GetProcessHeap(), 0, len );
1022 
1023  if (!profiles[count]) goto exit;
1024  else
1025  {
1026  TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) );
1027  lstrcpyW( profiles[count], data.cFileName );
1028  totalsize += len;
1029  count++;
1030  }
1031  }
1032  }
1033 
1034  totalsize++;
1035  if (buffer && *size >= totalsize)
1036  {
1037  WCHAR *p = (WCHAR *)buffer;
1038 
1039  for (i = 0; i < count; i++)
1040  {
1041  lstrcpyW( p, profiles[i] );
1042  p += lstrlenW( profiles[i] ) + 1;
1043  }
1044  *p = 0;
1045  ret = TRUE;
1046  }
1047  else ret = FALSE;
1048 
1049  *size = totalsize;
1050  if (number) *number = count;
1051 
1052 exit:
1053  for (i = 0; i < count; i++)
1054  HeapFree( GetProcessHeap(), 0, profiles[i] );
1055  HeapFree( GetProcessHeap(), 0, profiles );
1056  FindClose( find );
1057 
1058  return ret;
1059 }
1060 
1061 /******************************************************************************
1062  * InstallColorProfileA [MSCMS.@]
1063  *
1064  * See InstallColorProfileW.
1065  */
1067 {
1068  UINT len;
1069  LPWSTR profileW;
1070  BOOL ret = FALSE;
1071 
1072  TRACE( "( %s )\n", debugstr_a(profile) );
1073 
1074  if (machine || !profile) return FALSE;
1075 
1076  len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
1077  profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1078 
1079  if (profileW)
1080  {
1081  MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
1082 
1083  ret = InstallColorProfileW( NULL, profileW );
1084  HeapFree( GetProcessHeap(), 0, profileW );
1085  }
1086  return ret;
1087 }
1088 
1089 /******************************************************************************
1090  * InstallColorProfileW [MSCMS.@]
1091  *
1092  * Install a color profile.
1093  *
1094  * PARAMS
1095  * machine [I] Name of the machine to install the profile on. Must be NULL,
1096  * which indicates the local machine.
1097  * profile [I] Full path name of the profile to install.
1098  *
1099  * RETURNS
1100  * Success: TRUE
1101  * Failure: FALSE
1102  */
1104 {
1106  DWORD size = sizeof(dest);
1107  static const WCHAR slash[] = { '\\', 0 };
1108 
1109  TRACE( "( %s )\n", debugstr_w(profile) );
1110 
1111  if (machine || !profile) return FALSE;
1112 
1113  if (!GetColorDirectoryW( machine, dest, &size )) return FALSE;
1114 
1115  basename( profile, base );
1116 
1117  lstrcatW( dest, slash );
1118  lstrcatW( dest, base );
1119 
1120  /* Is source equal to destination? */
1121  if (!lstrcmpW( profile, dest )) return TRUE;
1122 
1123  return CopyFileW( profile, dest, TRUE );
1124 }
1125 
1126 /******************************************************************************
1127  * IsColorProfileTagPresent [MSCMS.@]
1128  *
1129  * Determine if a given ICC tag type is present in a color profile.
1130  *
1131  * PARAMS
1132  * profile [I] Color profile handle.
1133  * tag [I] ICC tag type.
1134  * present [O] Pointer to a BOOL variable. Set to TRUE if tag type is present,
1135  * FALSE otherwise.
1136  *
1137  * RETURNS
1138  * Success: TRUE
1139  * Failure: FALSE
1140  */
1142 {
1143  BOOL ret = FALSE;
1144 #ifdef HAVE_LCMS2
1145  struct profile *profile = grab_profile( handle );
1146 
1147  TRACE( "( %p, 0x%08x, %p )\n", handle, type, present );
1148 
1149  if (!profile) return FALSE;
1150 
1151  if (!present)
1152  {
1153  release_profile( profile );
1154  return FALSE;
1155  }
1156  *present = (cmsIsTag( profile->cmsprofile, type ) != 0);
1157  release_profile( profile );
1158  ret = TRUE;
1159 
1160 #endif /* HAVE_LCMS2 */
1161  return ret;
1162 }
1163 
1164 /******************************************************************************
1165  * IsColorProfileValid [MSCMS.@]
1166  *
1167  * Determine if a given color profile is valid.
1168  *
1169  * PARAMS
1170  * profile [I] Color profile handle.
1171  * valid [O] Pointer to a BOOL variable. Set to TRUE if profile is valid,
1172  * FALSE otherwise.
1173  *
1174  * RETURNS
1175  * Success: TRUE
1176  * Failure: FALSE
1177  */
1179 {
1180  BOOL ret = FALSE;
1181 #ifdef HAVE_LCMS2
1182  struct profile *profile = grab_profile( handle );
1183 
1184  TRACE( "( %p, %p )\n", handle, valid );
1185 
1186  if (!profile) return FALSE;
1187 
1188  if (!valid)
1189  {
1190  release_profile( profile );
1191  return FALSE;
1192  }
1193  if (profile->data) ret = *valid = TRUE;
1194  release_profile( profile );
1195 
1196 #endif /* HAVE_LCMS2 */
1197  return ret;
1198 }
1199 
1200 /******************************************************************************
1201  * SetColorProfileElement [MSCMS.@]
1202  *
1203  * Set data for a specified tag type.
1204  *
1205  * PARAMS
1206  * profile [I] Handle to a color profile.
1207  * type [I] ICC tag type.
1208  * offset [I] Offset in bytes to start copying to.
1209  * size [I/O] Size of the buffer in bytes. On return the variable holds the
1210  * number of bytes actually needed.
1211  * buffer [O] Buffer holding the tag data.
1212  *
1213  * RETURNS
1214  * Success: TRUE
1215  * Failure: FALSE
1216  */
1218  PVOID buffer )
1219 {
1220  BOOL ret = FALSE;
1221 #ifdef HAVE_LCMS2
1222  struct profile *profile = grab_profile( handle );
1223 
1224  TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer );
1225 
1226  if (!profile) return FALSE;
1227 
1228  if (!size || !buffer || !(profile->access & PROFILE_READWRITE))
1229  {
1230  release_profile( profile );
1231  return FALSE;
1232  }
1233  ret = set_tag_data( profile, type, offset, buffer, size );
1234  release_profile( profile );
1235 #endif /* HAVE_LCMS2 */
1236  return ret;
1237 }
1238 
1239 /******************************************************************************
1240  * SetColorProfileHeader [MSCMS.@]
1241  *
1242  * Set header data for a given profile.
1243  *
1244  * PARAMS
1245  * profile [I] Handle to a color profile.
1246  * header [I] Buffer holding the header data.
1247  *
1248  * RETURNS
1249  * Success: TRUE
1250  * Failure: FALSE
1251  */
1253 {
1254 #ifdef HAVE_LCMS2
1255  struct profile *profile = grab_profile( handle );
1256 
1257  TRACE( "( %p, %p )\n", handle, header );
1258 
1259  if (!profile) return FALSE;
1260 
1261  if (!header || !(profile->access & PROFILE_READWRITE))
1262  {
1263  release_profile( profile );
1264  return FALSE;
1265  }
1266  set_profile_header( profile, header );
1267  release_profile( profile );
1268  return TRUE;
1269 
1270 #else
1271  return FALSE;
1272 #endif /* HAVE_LCMS2 */
1273 }
1274 
1275 /******************************************************************************
1276  * UninstallColorProfileA [MSCMS.@]
1277  *
1278  * See UninstallColorProfileW.
1279  */
1281 {
1282  UINT len;
1283  LPWSTR profileW;
1284  BOOL ret = FALSE;
1285 
1286  TRACE( "( %s, %x )\n", debugstr_a(profile), delete );
1287 
1288  if (machine || !profile) return FALSE;
1289 
1290  len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
1291  profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1292 
1293  if (profileW)
1294  {
1295  MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
1296 
1297  ret = UninstallColorProfileW( NULL, profileW , delete );
1298 
1299  HeapFree( GetProcessHeap(), 0, profileW );
1300  }
1301  return ret;
1302 }
1303 
1304 /******************************************************************************
1305  * UninstallColorProfileW [MSCMS.@]
1306  *
1307  * Uninstall a color profile.
1308  *
1309  * PARAMS
1310  * machine [I] Name of the machine to uninstall the profile on. Must be NULL,
1311  * which indicates the local machine.
1312  * profile [I] Full path name of the profile to uninstall.
1313  * delete [I] Bool that specifies whether the profile file should be deleted.
1314  *
1315  * RETURNS
1316  * Success: TRUE
1317  * Failure: FALSE
1318  */
1320 {
1321  TRACE( "( %s, %x )\n", debugstr_w(profile), delete );
1322 
1323  if (machine || !profile) return FALSE;
1324 
1325  if (delete) return DeleteFileW( profile );
1326 
1327  return TRUE;
1328 }
1329 
1330 /******************************************************************************
1331  * OpenColorProfileA [MSCMS.@]
1332  *
1333  * See OpenColorProfileW.
1334  */
1336 {
1337  HPROFILE handle = NULL;
1338 
1339  TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation );
1340 
1341  if (!profile || !profile->pProfileData) return NULL;
1342 
1343  /* No AW conversion needed for memory based profiles */
1344  if (profile->dwType & PROFILE_MEMBUFFER)
1345  return OpenColorProfileW( profile, access, sharing, creation );
1346 
1347  if (profile->dwType & PROFILE_FILENAME)
1348  {
1349  UINT len;
1350  PROFILE profileW;
1351 
1352  profileW.dwType = profile->dwType;
1353 
1354  len = MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, NULL, 0 );
1355  profileW.pProfileData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1356 
1357  if (profileW.pProfileData)
1358  {
1359  profileW.cbDataSize = len * sizeof(WCHAR);
1360  MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, profileW.pProfileData, len );
1361 
1362  handle = OpenColorProfileW( &profileW, access, sharing, creation );
1363  HeapFree( GetProcessHeap(), 0, profileW.pProfileData );
1364  }
1365  }
1366  return handle;
1367 }
1368 
1369 /******************************************************************************
1370  * OpenColorProfileW [MSCMS.@]
1371  *
1372  * Open a color profile.
1373  *
1374  * PARAMS
1375  * profile [I] Pointer to a color profile structure.
1376  * access [I] Desired access.
1377  * sharing [I] Sharing mode.
1378  * creation [I] Creation mode.
1379  *
1380  * RETURNS
1381  * Success: Handle to the opened profile.
1382  * Failure: NULL
1383  *
1384  * NOTES
1385  * Values for access: PROFILE_READ or PROFILE_READWRITE.
1386  * Values for sharing: 0 (no sharing), FILE_SHARE_READ and/or FILE_SHARE_WRITE.
1387  * Values for creation: one of CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING,
1388  * OPEN_ALWAYS, TRUNCATE_EXISTING.
1389  * Sharing and creation flags are ignored for memory based profiles.
1390  */
1392 {
1393 #ifdef HAVE_LCMS2
1394  cmsHPROFILE cmsprofile = NULL;
1395  char *data = NULL;
1397  DWORD size;
1398 
1399  TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation );
1400 
1401  if (!profile || !profile->pProfileData) return NULL;
1402 
1403  if (profile->dwType == PROFILE_MEMBUFFER)
1404  {
1405  /* FIXME: access flags not implemented for memory based profiles */
1406 
1407  if (!(data = HeapAlloc( GetProcessHeap(), 0, profile->cbDataSize ))) return NULL;
1408  memcpy( data, profile->pProfileData, profile->cbDataSize );
1409 
1410  if (!(cmsprofile = cmsOpenProfileFromMem( data, profile->cbDataSize )))
1411  {
1412  HeapFree( GetProcessHeap(), 0, data );
1413  return FALSE;
1414  }
1415  size = profile->cbDataSize;
1416  }
1417  else if (profile->dwType == PROFILE_FILENAME)
1418  {
1419  DWORD read, flags = 0;
1420 
1421  TRACE( "profile file: %s\n", debugstr_w( profile->pProfileData ) );
1422 
1425 
1426  if (!flags) return NULL;
1428 
1429  if (!PathIsRelativeW( profile->pProfileData ))
1430  handle = CreateFileW( profile->pProfileData, flags, sharing, NULL, creation, 0, NULL );
1431  else
1432  {
1433  WCHAR *path;
1434 
1436  {
1437  size += (strlenW( profile->pProfileData ) + 2) * sizeof(WCHAR);
1438  if (!(path = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
1441  strcatW( path, profile->pProfileData );
1442  }
1443  else return NULL;
1444  handle = CreateFileW( path, flags, sharing, NULL, creation, 0, NULL );
1445  HeapFree( GetProcessHeap(), 0, path );
1446  }
1448  {
1449  WARN( "Unable to open color profile %u\n", GetLastError() );
1450  return NULL;
1451  }
1452  if ((size = GetFileSize( handle, NULL )) == INVALID_FILE_SIZE)
1453  {
1454  ERR( "Unable to retrieve size of color profile\n" );
1455  CloseHandle( handle );
1456  return NULL;
1457  }
1458  if (!(data = HeapAlloc( GetProcessHeap(), 0, size )))
1459  {
1460  ERR( "Unable to allocate memory for color profile\n" );
1461  CloseHandle( handle );
1462  return NULL;
1463  }
1464  if (!ReadFile( handle, data, size, &read, NULL ) || read != size)
1465  {
1466  ERR( "Unable to read color profile\n" );
1467 
1468  CloseHandle( handle );
1469  HeapFree( GetProcessHeap(), 0, data );
1470  return NULL;
1471  }
1472  if (!(cmsprofile = cmsOpenProfileFromMem( data, size )))
1473  {
1474  CloseHandle( handle );
1475  HeapFree( GetProcessHeap(), 0, data );
1476  return NULL;
1477  }
1478  }
1479  else
1480  {
1481  ERR( "Invalid profile type %u\n", profile->dwType );
1482  return NULL;
1483  }
1484 
1485  if (cmsprofile)
1486  {
1487  struct profile profile;
1488  HPROFILE hprof;
1489 
1490  profile.file = handle;
1491  profile.access = access;
1492  profile.data = data;
1493  profile.size = size;
1494  profile.cmsprofile = cmsprofile;
1495 
1496  if ((hprof = create_profile( &profile ))) return hprof;
1497  HeapFree( GetProcessHeap(), 0, data );
1498  cmsCloseProfile( cmsprofile );
1499  }
1500  CloseHandle( handle );
1501 
1502 #endif /* HAVE_LCMS2 */
1503  return NULL;
1504 }
1505 
1506 /******************************************************************************
1507  * CloseColorProfile [MSCMS.@]
1508  *
1509  * Close a color profile.
1510  *
1511  * PARAMS
1512  * profile [I] Handle to the profile.
1513  *
1514  * RETURNS
1515  * Success: TRUE
1516  * Failure: FALSE
1517  */
1519 {
1520  BOOL ret = FALSE;
1521 #ifdef HAVE_LCMS2
1522 
1523  TRACE( "( %p )\n", profile );
1524  ret = close_profile( profile );
1525 
1526 #endif /* HAVE_LCMS2 */
1527  return ret;
1528 }
1529 
1530 /******************************************************************************
1531  * WcsGetUsePerUserProfiles [MSCMS.@]
1532  */
1533 BOOL WINAPI WcsGetUsePerUserProfiles( const WCHAR* name, DWORD class, BOOL* use_per_user_profile )
1534 {
1535  FIXME( "%s %s %p\n", debugstr_w(name), dbgstr_tag(class), use_per_user_profile );
1537  return FALSE;
1538 }
1539 
1540 /******************************************************************************
1541  * WcsEnumColorProfilesSize [MSCMS.@]
1542  */
1544 {
1545  FIXME( "%d %p %p\n", scope, record, size );
1547  return FALSE;
1548 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define ET_RENDERINGINTENT
Definition: icm.h:285
static const WCHAR classW[]
Definition: lex.c:38
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
#define PROFILE_READ
Definition: icm.h:418
DWORD dwConnectionSpace
Definition: icm.h:259
const uint16_t * PCWSTR
Definition: typedefs.h:55
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:398
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:54
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:111
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:391
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:1391
GLuint buffer
Definition: glext.h:5915
#define PROFILE_FILENAME
Definition: icm.h:415
#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:1178
#define lstrlenW
Definition: compat.h:407
int32_t INT
Definition: typedefs.h:56
DWORD dwManufacturer
Definition: icm.h:263
Definition: send.c:47
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:1094
BOOL WINAPI UninstallColorProfileW(PCWSTR machine, PCWSTR profile, BOOL delete)
Definition: profile.c:1319
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:1543
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:1103
WINE_DEFAULT_DEBUG_CHANNEL(hnetcfg)
static size_t double number
Definition: printf.c:64
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:110
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:426
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:4917
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:395
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:416
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:8
BOOL WINAPI IsColorProfileTagPresent(HPROFILE handle, TAGTYPE type, PBOOL present)
Definition: profile.c:1141
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:409
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BOOL WINAPI SetColorProfileHeader(HPROFILE handle, PPROFILEHEADER header)
Definition: profile.c:1252
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
BOOL WINAPI InstallColorProfileA(PCSTR machine, PCSTR profile)
Definition: profile.c:1066
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
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
unsigned char BYTE
Definition: mem.h:68
#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:1217
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:1335
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:109
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
#define lstrcpyW
Definition: compat.h:406
DWORD dwRenderingIntent
Definition: icm.h:266
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2368
BOOL WINAPI UninstallColorProfileA(PCSTR machine, PCSTR profile, BOOL delete)
Definition: profile.c:1280
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:393
Definition: services.c:325
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:1533
char ** glob(const char *v)
Definition: fake.c:36
#define ET_PLATFORM
Definition: icm.h:280
#define LCS_sRGB
Definition: wingdi.h:1087
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:954
DWORD * PDWORD
Definition: pedump.c:68
#define PROFILE_READWRITE
Definition: icm.h:419
BOOL WINAPI GetCountColorProfileElements(HPROFILE handle, PDWORD count)
Definition: profile.c:521
#define MultiByteToWideChar
Definition: compat.h:100
#define CreateFileW
Definition: compat.h:400
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:36
#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:1518
#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:51
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define LCS_WINDOWS_COLOR_SPACE
Definition: wingdi.h:1088
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:394
struct CFHEADER header
Definition: fdi.c:109
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