push a6a7df41ae272b3b1bf5fcfb544267c1e96afa99
[wine/hacks.git] / dlls / mscms / tests / profile.c
blob56d773265636e31a06465043943b9626c6102ff8
1 /*
2 * Tests for color profile functions
4 * Copyright 2004, 2005, 2006 Hans Leidekker
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.
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.
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
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winreg.h"
26 #include "winnls.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "icm.h"
31 #include "wine/test.h"
33 HMODULE hmscms;
35 static BOOL (WINAPI *pAssociateColorProfileWithDeviceA)(PCSTR,PCSTR,PCSTR);
36 static BOOL (WINAPI *pCloseColorProfile)(HPROFILE);
37 static BOOL (WINAPI *pDisassociateColorProfileFromDeviceA)(PCSTR,PCSTR,PCSTR);
38 static BOOL (WINAPI *pGetColorDirectoryA)(PCHAR,PCHAR,PDWORD);
39 static BOOL (WINAPI *pGetColorDirectoryW)(PWCHAR,PWCHAR,PDWORD);
40 static BOOL (WINAPI *pGetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL);
41 static BOOL (WINAPI *pGetColorProfileElementTag)(HPROFILE,DWORD,PTAGTYPE);
42 static BOOL (WINAPI *pGetColorProfileFromHandle)(HPROFILE,PBYTE,PDWORD);
43 static BOOL (WINAPI *pGetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
44 static BOOL (WINAPI *pGetCountColorProfileElements)(HPROFILE,PDWORD);
45 static BOOL (WINAPI *pGetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR,PDWORD);
46 static BOOL (WINAPI *pGetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR,PDWORD);
47 static BOOL (WINAPI *pEnumColorProfilesA)(PCSTR,PENUMTYPEA,PBYTE,PDWORD,PDWORD);
48 static BOOL (WINAPI *pEnumColorProfilesW)(PCWSTR,PENUMTYPEW,PBYTE,PDWORD,PDWORD);
49 static BOOL (WINAPI *pInstallColorProfileA)(PCSTR,PCSTR);
50 static BOOL (WINAPI *pInstallColorProfileW)(PCWSTR,PCWSTR);
51 static BOOL (WINAPI *pIsColorProfileTagPresent)(HPROFILE,TAGTYPE,PBOOL);
52 static HPROFILE (WINAPI *pOpenColorProfileA)(PPROFILE,DWORD,DWORD,DWORD);
53 static HPROFILE (WINAPI *pOpenColorProfileW)(PPROFILE,DWORD,DWORD,DWORD);
54 static BOOL (WINAPI *pSetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID);
55 static BOOL (WINAPI *pSetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
56 static BOOL (WINAPI *pSetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR);
57 static BOOL (WINAPI *pSetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR);
58 static BOOL (WINAPI *pUninstallColorProfileA)(PCSTR,PCSTR,BOOL);
59 static BOOL (WINAPI *pUninstallColorProfileW)(PCWSTR,PCWSTR,BOOL);
61 #define GETFUNCPTR(func) p##func = (void *)GetProcAddress( hmscms, #func ); \
62 if (!p##func) return FALSE;
64 static BOOL init_function_ptrs( void )
66 GETFUNCPTR( AssociateColorProfileWithDeviceA )
67 GETFUNCPTR( CloseColorProfile )
68 GETFUNCPTR( DisassociateColorProfileFromDeviceA )
69 GETFUNCPTR( GetColorDirectoryA )
70 GETFUNCPTR( GetColorDirectoryW )
71 GETFUNCPTR( GetColorProfileElement )
72 GETFUNCPTR( GetColorProfileElementTag )
73 GETFUNCPTR( GetColorProfileFromHandle )
74 GETFUNCPTR( GetColorProfileHeader )
75 GETFUNCPTR( GetCountColorProfileElements )
76 GETFUNCPTR( GetStandardColorSpaceProfileA )
77 GETFUNCPTR( GetStandardColorSpaceProfileW )
78 GETFUNCPTR( EnumColorProfilesA )
79 GETFUNCPTR( EnumColorProfilesW )
80 GETFUNCPTR( InstallColorProfileA )
81 GETFUNCPTR( InstallColorProfileW )
82 GETFUNCPTR( IsColorProfileTagPresent )
83 GETFUNCPTR( OpenColorProfileA )
84 GETFUNCPTR( OpenColorProfileW )
85 GETFUNCPTR( SetColorProfileElement )
86 GETFUNCPTR( SetColorProfileHeader )
87 GETFUNCPTR( SetStandardColorSpaceProfileA )
88 GETFUNCPTR( SetStandardColorSpaceProfileW )
89 GETFUNCPTR( UninstallColorProfileA )
90 GETFUNCPTR( UninstallColorProfileW )
92 return TRUE;
95 static const char machine[] = "dummy";
96 static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
98 /* To do any real functionality testing with this suite you need a copy of
99 * the freely distributable standard RGB color space profile. It comes
100 * standard with Windows, but on Wine you probably need to install it yourself
101 * in one of the locations mentioned below.
104 /* Two common places to find the standard color space profile, relative
105 * to the system directory.
107 static const char profile1[] =
108 "\\color\\srgb color space profile.icm";
109 static const char profile2[] =
110 "\\spool\\drivers\\color\\srgb color space profile.icm";
112 static const WCHAR profile1W[] =
113 { '\\','c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
114 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
115 static const WCHAR profile2W[] =
116 { '\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',
117 'c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
118 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
120 static const unsigned char rgbheader[] =
121 { 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02,
122 0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58,
123 0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00,
124 0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00,
125 0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00,
127 0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 };
129 static LPSTR standardprofile;
130 static LPWSTR standardprofileW;
132 static LPSTR testprofile;
133 static LPWSTR testprofileW;
135 #define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
137 static void MSCMS_basenameA( LPCSTR path, LPSTR name )
139 INT i = strlen( path );
141 while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
142 strcpy( name, &path[i] );
145 static void MSCMS_basenameW( LPCWSTR path, LPWSTR name )
147 INT i = lstrlenW( path );
149 while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
150 lstrcpyW( name, &path[i] );
153 static void test_GetColorDirectoryA(void)
155 BOOL ret;
156 DWORD size;
157 char buffer[MAX_PATH];
159 /* Parameter checks */
161 ret = pGetColorDirectoryA( NULL, NULL, NULL );
162 ok( !ret, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
164 size = 0;
166 ret = pGetColorDirectoryA( NULL, NULL, &size );
167 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
169 size = 0;
171 ret = pGetColorDirectoryA( NULL, buffer, &size );
172 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
174 size = 1;
176 ret = pGetColorDirectoryA( NULL, buffer, &size );
177 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
179 /* Functional checks */
181 size = sizeof(buffer);
183 ret = pGetColorDirectoryA( NULL, buffer, &size );
184 ok( ret && size > 0, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
187 static void test_GetColorDirectoryW(void)
189 BOOL ret;
190 DWORD size;
191 WCHAR buffer[MAX_PATH];
193 /* Parameter checks */
195 /* This one crashes win2k
197 ret = pGetColorDirectoryW( NULL, NULL, NULL );
198 ok( !ret, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
202 size = 0;
204 ret = pGetColorDirectoryW( NULL, NULL, &size );
205 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
207 size = 0;
209 ret = pGetColorDirectoryW( NULL, buffer, &size );
210 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
212 size = 1;
214 ret = pGetColorDirectoryW( NULL, buffer, &size );
215 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
217 /* Functional checks */
219 size = sizeof(buffer);
221 ret = pGetColorDirectoryW( NULL, buffer, &size );
222 ok( ret && size > 0, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
225 static void test_GetColorProfileElement(void)
227 if (standardprofile)
229 PROFILE profile;
230 HPROFILE handle;
231 BOOL ret, ref;
232 DWORD size;
233 TAGTYPE tag = 0x63707274; /* 'cprt' */
234 static char buffer[51];
235 static const char expect[] =
236 { 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70,
237 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
238 0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74,
239 0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43,
240 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x00 };
242 profile.dwType = PROFILE_FILENAME;
243 profile.pProfileData = standardprofile;
244 profile.cbDataSize = strlen(standardprofile);
246 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
247 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
249 /* Parameter checks */
251 ret = pGetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
252 ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
254 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
255 ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
257 size = 0;
259 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
260 ok( !ret && size > 0, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
262 size = sizeof(buffer);
264 /* Functional checks */
266 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
267 ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
269 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
271 pCloseColorProfile( handle );
275 static void test_GetColorProfileElementTag(void)
277 if (standardprofile)
279 PROFILE profile;
280 HPROFILE handle;
281 BOOL ret;
282 DWORD index = 1;
283 TAGTYPE tag, expect = 0x63707274; /* 'cprt' */
285 profile.dwType = PROFILE_FILENAME;
286 profile.pProfileData = standardprofile;
287 profile.cbDataSize = strlen(standardprofile);
289 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
290 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
292 /* Parameter checks */
294 ret = pGetColorProfileElementTag( NULL, index, &tag );
295 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
297 ret = pGetColorProfileElementTag( handle, 0, &tag );
298 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
300 ret = pGetColorProfileElementTag( handle, index, NULL );
301 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
303 ret = pGetColorProfileElementTag( handle, 18, NULL );
304 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
306 /* Functional checks */
308 ret = pGetColorProfileElementTag( handle, index, &tag );
309 ok( ret && tag == expect, "GetColorProfileElementTag() failed (%d)\n",
310 GetLastError() );
312 pCloseColorProfile( handle );
316 static void test_GetColorProfileFromHandle(void)
318 if (testprofile)
320 PROFILE profile;
321 HPROFILE handle;
322 DWORD size;
323 BOOL ret;
324 static const unsigned char expect[] =
325 { 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
326 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
327 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
328 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
329 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
330 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
332 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 };
334 unsigned char *buffer;
336 profile.dwType = PROFILE_FILENAME;
337 profile.pProfileData = testprofile;
338 profile.cbDataSize = strlen(testprofile);
340 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
341 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
343 /* Parameter checks */
345 size = 0;
347 ret = pGetColorProfileFromHandle( handle, NULL, &size );
348 ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
350 buffer = HeapAlloc( GetProcessHeap(), 0, size );
352 if (buffer)
354 ret = pGetColorProfileFromHandle( NULL, buffer, &size );
355 ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
357 ret = pGetColorProfileFromHandle( handle, buffer, NULL );
358 ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
360 /* Functional checks */
362 ret = pGetColorProfileFromHandle( handle, buffer, &size );
363 ok( ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
365 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" );
367 HeapFree( GetProcessHeap(), 0, buffer );
370 pCloseColorProfile( handle );
374 static void test_GetColorProfileHeader(void)
376 if (testprofile)
378 PROFILE profile;
379 HPROFILE handle;
380 BOOL ret;
381 PROFILEHEADER header;
383 profile.dwType = PROFILE_FILENAME;
384 profile.pProfileData = testprofile;
385 profile.cbDataSize = strlen(testprofile);
387 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
388 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
390 /* Parameter checks */
392 ret = pGetColorProfileHeader( NULL, NULL );
393 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
395 ret = pGetColorProfileHeader( NULL, &header );
396 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
398 if (0) /* Crashes on Vista */
400 ret = pGetColorProfileHeader( handle, NULL );
401 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
404 /* Functional checks */
406 ret = pGetColorProfileHeader( handle, &header );
407 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
409 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
411 pCloseColorProfile( handle );
415 static void test_GetCountColorProfileElements(void)
417 if (standardprofile)
419 PROFILE profile;
420 HPROFILE handle;
421 BOOL ret;
422 DWORD count, expect = 17;
424 profile.dwType = PROFILE_FILENAME;
425 profile.pProfileData = standardprofile;
426 profile.cbDataSize = strlen(standardprofile);
428 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
429 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
431 /* Parameter checks */
433 ret = pGetCountColorProfileElements( NULL, &count );
434 ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
435 GetLastError() );
437 ret = pGetCountColorProfileElements( handle, NULL );
438 ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
439 GetLastError() );
441 /* Functional checks */
443 ret = pGetCountColorProfileElements( handle, &count );
444 ok( ret && count == expect,
445 "GetCountColorProfileElements() failed (%d)\n", GetLastError() );
447 pCloseColorProfile( handle );
451 typedef struct colorspace_description_struct {
452 DWORD dwID;
453 const char *szName;
454 BOOL registered;
455 char filename[MAX_PATH];
456 } colorspace_descr;
458 #define describe_colorspace(id) {id, #id, FALSE, ""}
460 colorspace_descr known_colorspaces[] = {
461 describe_colorspace(SPACE_XYZ),
462 describe_colorspace(SPACE_Lab),
463 describe_colorspace(SPACE_Luv),
464 describe_colorspace(SPACE_YCbCr),
465 describe_colorspace(SPACE_Yxy),
466 describe_colorspace(SPACE_RGB),
467 describe_colorspace(SPACE_GRAY),
468 describe_colorspace(SPACE_HSV),
469 describe_colorspace(SPACE_HLS),
470 describe_colorspace(SPACE_CMYK),
471 describe_colorspace(SPACE_CMY),
472 describe_colorspace(SPACE_2_CHANNEL),
473 describe_colorspace(SPACE_3_CHANNEL),
474 describe_colorspace(SPACE_4_CHANNEL),
475 describe_colorspace(SPACE_5_CHANNEL),
476 describe_colorspace(SPACE_6_CHANNEL),
477 describe_colorspace(SPACE_7_CHANNEL),
478 describe_colorspace(SPACE_8_CHANNEL)
481 static void enum_registered_color_profiles(void)
483 BOOL ret;
484 DWORD size, count, i, present;
485 CHAR profile[MAX_PATH];
487 size = sizeof(profile);
488 count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
490 present = 0;
491 trace("\n");
492 trace("Querying registered standard colorspace profiles via GetStandardColorSpaceProfileA():\n");
493 for (i=0; i<count; i++)
495 ret = pGetStandardColorSpaceProfileA(NULL, known_colorspaces[i].dwID, profile, &size);
496 if (ret)
498 lstrcpynA(known_colorspaces[i].filename, profile, MAX_PATH);
499 known_colorspaces[i].registered = TRUE;
500 present++;
501 trace(" found %s, pointing to '%s' (%d chars)\n", known_colorspaces[i].szName, profile, lstrlenA(profile));
504 trace("Total profiles found: %d.\n", present);
505 trace("\n");
508 static colorspace_descr *query_colorspace(DWORD dwID)
510 DWORD count, i;
512 count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
514 for (i=0; i<count; i++)
515 if (known_colorspaces[i].dwID == dwID)
517 if (!known_colorspaces[i].registered) break;
518 return &known_colorspaces[i];
520 return NULL;
523 static HKEY reg_open_mscms_key(void)
525 char win9x[] = "SOFTWARE\\Microsoft\\Windows";
526 char winNT[] = "SOFTWARE\\Microsoft\\Windows NT";
527 char ICM[] = "CurrentVersion\\ICM\\RegisteredProfiles";
528 HKEY win9x_key, winNT_key, ICM_key;
530 RegOpenKeyExA( HKEY_LOCAL_MACHINE, win9x, 0, KEY_READ, &win9x_key );
531 RegOpenKeyExA( HKEY_LOCAL_MACHINE, winNT, 0, KEY_READ, &winNT_key );
533 if (RegOpenKeyExA( winNT_key, ICM, 0, KEY_READ, &ICM_key ))
534 RegOpenKeyExA( win9x_key, ICM, 0, KEY_READ, &ICM_key );
535 RegCloseKey( win9x_key );
536 RegCloseKey( winNT_key );
538 return ICM_key;
541 static void check_registry(BOOL *has_space_rgb)
543 HKEY hkIcmKey;
544 LONG res;
545 DWORD i, dwValCount;
546 char szName[16383];
547 char szData[MAX_PATH+1];
548 DWORD dwNameLen, dwDataLen, dwType;
550 *has_space_rgb = FALSE;
551 hkIcmKey = reg_open_mscms_key();
552 if (!hkIcmKey)
554 trace("Key 'HKLM\\SOFTWARE\\Microsoft\\Windows*\\CurrentVersion\\ICM\\RegisteredProfiles' not found\n" );
555 return;
558 res = RegQueryInfoKeyA(hkIcmKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValCount, NULL, NULL, NULL, NULL);
559 if (res)
561 trace("RegQueryInfoKeyA() failed : %d\n", res);
562 return;
565 trace("Count of profile entries found directly in the registry: %d\n", dwValCount);
567 for (i = 0; i<dwValCount; i++)
569 dwNameLen = sizeof(szName);
570 dwDataLen = sizeof(szData);
571 res = RegEnumValueA( hkIcmKey, i, szName, &dwNameLen, NULL, &dwType, (LPBYTE)szData, &dwDataLen );
572 if (!strncmp(szName, "RGB", 3))
573 *has_space_rgb = TRUE;
574 if (res != ERROR_SUCCESS)
576 trace("RegEnumValueA() failed (%d), cannot enumerate profiles\n", res);
577 break;
579 ok( dwType == REG_SZ, "RegEnumValueA() returned unexpected value type (%d)\n", dwType );
580 if (dwType != REG_SZ) break;
581 trace(" found '%s' value containing '%s' (%d chars)\n", szName, szData, lstrlenA(szData));
584 RegCloseKey( hkIcmKey );
587 static void test_GetStandardColorSpaceProfileA(BOOL has_space_rgb)
589 BOOL ret;
590 DWORD size;
591 CHAR oldprofile[MAX_PATH];
592 CHAR newprofile[MAX_PATH];
593 const CHAR emptyA[] = "";
594 DWORD zero = 0;
595 DWORD sizeP = sizeof(newprofile);
597 /* Parameter checks */
599 /* Single invalid parameter checks: */
601 SetLastError(0xfaceabee); /* 1st param, */
602 ret = pGetStandardColorSpaceProfileA(machine, SPACE_RGB, newprofile, &sizeP);
603 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
605 SetLastError(0xfaceabee); /* 2nd param, */
606 ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &sizeP);
607 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
609 SetLastError(0xfaceabee); /* 4th param, */
610 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, NULL);
611 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
613 if (query_colorspace(SPACE_RGB))
615 SetLastError(0xfaceabee); /* 3rd param, */
616 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
617 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
619 SetLastError(0xfaceabee); /* dereferenced 4th param, */
620 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &zero);
621 ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
622 } else {
623 SetLastError(0xfaceabee); /* 3rd param, */
624 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
625 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
627 SetLastError(0xfaceabee); /* dereferenced 4th param. */
628 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &sizeP);
629 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
632 /* Several invalid parameter checks: */
634 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
635 ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &zero);
636 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
638 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
639 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
640 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
642 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
643 ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &zero);
644 ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
646 SetLastError(0xfaceabee); /* maybe 2nd param. */
647 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &sizeP);
648 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
649 else ok( !lstrcmpiA( newprofile, emptyA ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
651 /* Functional checks */
653 if (has_space_rgb)
655 size = sizeof(oldprofile);
657 ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
658 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
660 SetLastError(0xdeadbeef);
661 ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
662 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
664 skip("Not enough rights for SetStandardColorSpaceProfileA\n");
665 return;
667 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
669 size = sizeof(newprofile);
671 ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
672 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
674 ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
676 ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
677 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
681 static void test_GetStandardColorSpaceProfileW(BOOL has_space_rgb)
683 BOOL ret;
684 DWORD size;
685 WCHAR oldprofile[MAX_PATH];
686 WCHAR newprofile[MAX_PATH];
687 const WCHAR emptyW[] = {0};
688 DWORD zero = 0;
689 DWORD sizeP = sizeof(newprofile);
691 /* Parameter checks */
693 /* Single invalid parameter checks: */
695 SetLastError(0xfaceabee); /* 1st param, */
696 ret = pGetStandardColorSpaceProfileW(machineW, SPACE_RGB, newprofile, &sizeP);
697 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
699 SetLastError(0xfaceabee); /* 2nd param, */
700 ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &sizeP);
701 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
703 SetLastError(0xfaceabee); /* 3rd param, */
704 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, NULL, &sizeP);
705 if (has_space_rgb)
706 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
707 else
708 todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
710 SetLastError(0xfaceabee); /* 4th param, */
711 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, NULL);
712 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
714 SetLastError(0xfaceabee); /* dereferenced 4th param. */
715 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, &zero);
716 if (has_space_rgb)
717 ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
718 else
719 todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
722 /* Several invalid parameter checks: */
724 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
725 ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &zero);
726 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
728 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
729 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
730 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
732 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
733 ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &zero);
734 ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
736 SetLastError(0xfaceabee); /* maybe 2nd param. */
737 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
738 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
739 else ok( !lstrcmpiW( newprofile, emptyW ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
741 /* Functional checks */
743 if (has_space_rgb)
745 size = sizeof(oldprofile);
747 ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
748 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
750 SetLastError(0xdeadbeef);
751 ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
752 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
754 skip("Not enough rights for SetStandardColorSpaceProfileW\n");
755 return;
757 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
759 size = sizeof(newprofile);
761 ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
762 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
764 ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
766 ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
767 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
771 static void test_EnumColorProfilesA(void)
773 BOOL ret;
774 DWORD total, size, number;
775 ENUMTYPEA record;
776 BYTE *buffer;
778 /* Parameter checks */
780 memset( &record, 0, sizeof(ENUMTYPEA) );
782 record.dwSize = sizeof(ENUMTYPEA);
783 record.dwVersion = ENUM_TYPE_VERSION;
784 record.dwFields |= ET_DATACOLORSPACE;
785 record.dwDataColorSpace = SPACE_RGB;
787 total = 0;
788 ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number );
789 ok( !ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
790 buffer = HeapAlloc( GetProcessHeap(), 0, total );
792 size = total;
793 ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
794 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
796 ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
797 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
799 ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
800 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
802 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
803 if (standardprofile)
804 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
805 else
806 todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
808 size = 0;
810 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
811 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
813 /* Functional checks */
815 size = total;
816 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
817 if (standardprofile)
818 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
819 else
820 todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
822 HeapFree( GetProcessHeap(), 0, buffer );
825 static void test_EnumColorProfilesW(void)
827 BOOL ret;
828 DWORD total, size, number;
829 ENUMTYPEW record;
830 BYTE *buffer;
832 /* Parameter checks */
834 memset( &record, 0, sizeof(ENUMTYPEW) );
836 record.dwSize = sizeof(ENUMTYPEW);
837 record.dwVersion = ENUM_TYPE_VERSION;
838 record.dwFields |= ET_DATACOLORSPACE;
839 record.dwDataColorSpace = SPACE_RGB;
841 total = 0;
842 ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number );
843 ok( !ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
844 buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
846 size = total;
847 ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
848 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
850 ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
851 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
853 ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
854 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
856 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
857 if (standardprofileW)
858 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
859 else
860 todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
862 size = 0;
863 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
864 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
866 /* Functional checks */
868 size = total;
869 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
870 if (standardprofileW)
871 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
872 else
873 todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
875 HeapFree( GetProcessHeap(), 0, buffer );
878 static void test_InstallColorProfileA(void)
880 BOOL ret;
882 /* Parameter checks */
884 ret = pInstallColorProfileA( NULL, NULL );
885 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
887 ret = pInstallColorProfileA( machine, NULL );
888 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
890 ret = pInstallColorProfileA( NULL, machine );
891 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
893 if (standardprofile)
895 ret = pInstallColorProfileA( NULL, standardprofile );
896 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
899 /* Functional checks */
901 if (testprofile)
903 CHAR dest[MAX_PATH], base[MAX_PATH];
904 DWORD size = sizeof(dest);
905 CHAR slash[] = "\\";
906 HANDLE handle;
908 SetLastError(0xdeadbeef);
909 ret = pInstallColorProfileA( NULL, testprofile );
910 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
912 skip("Not enough rights for InstallColorProfileA\n");
913 return;
915 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
917 ret = pGetColorDirectoryA( NULL, dest, &size );
918 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
920 MSCMS_basenameA( testprofile, base );
922 lstrcatA( dest, slash );
923 lstrcatA( dest, base );
925 /* Check if the profile is really there */
926 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
927 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
928 CloseHandle( handle );
930 ret = pUninstallColorProfileA( NULL, dest, TRUE );
931 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
935 static void test_InstallColorProfileW(void)
937 BOOL ret;
939 /* Parameter checks */
941 ret = pInstallColorProfileW( NULL, NULL );
942 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
944 ret = pInstallColorProfileW( machineW, NULL );
945 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
947 ret = pInstallColorProfileW( NULL, machineW );
948 ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
950 if (standardprofileW)
952 ret = pInstallColorProfileW( NULL, standardprofileW );
953 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
956 /* Functional checks */
958 if (testprofileW)
960 WCHAR dest[MAX_PATH], base[MAX_PATH];
961 DWORD size = sizeof(dest);
962 WCHAR slash[] = { '\\', 0 };
963 HANDLE handle;
965 SetLastError(0xdeadbeef);
966 ret = pInstallColorProfileW( NULL, testprofileW );
967 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
969 skip("Not enough rights for InstallColorProfileW\n");
970 return;
972 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
974 ret = pGetColorDirectoryW( NULL, dest, &size );
975 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
977 MSCMS_basenameW( testprofileW, base );
979 lstrcatW( dest, slash );
980 lstrcatW( dest, base );
982 /* Check if the profile is really there */
983 handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
984 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
985 CloseHandle( handle );
987 ret = pUninstallColorProfileW( NULL, dest, TRUE );
988 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
992 static void test_IsColorProfileTagPresent(void)
994 if (standardprofile)
996 PROFILE profile;
997 HPROFILE handle;
998 BOOL ret, present;
999 TAGTYPE tag;
1001 profile.dwType = PROFILE_FILENAME;
1002 profile.pProfileData = standardprofile;
1003 profile.cbDataSize = strlen(standardprofile);
1005 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1006 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1008 /* Parameter checks */
1010 tag = 0;
1012 ret = pIsColorProfileTagPresent( handle, tag, &present );
1013 ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1015 tag = 0x63707274; /* 'cprt' */
1017 ret = pIsColorProfileTagPresent( NULL, tag, &present );
1018 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1020 ret = pIsColorProfileTagPresent( handle, tag, NULL );
1021 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1023 /* Functional checks */
1025 ret = pIsColorProfileTagPresent( handle, tag, &present );
1026 ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() );
1028 pCloseColorProfile( handle );
1032 static void test_OpenColorProfileA(void)
1034 PROFILE profile;
1035 HPROFILE handle;
1036 BOOL ret;
1038 profile.dwType = PROFILE_FILENAME;
1039 profile.pProfileData = NULL;
1040 profile.cbDataSize = 0;
1042 /* Parameter checks */
1044 handle = pOpenColorProfileA( NULL, 0, 0, 0 );
1045 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1047 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1048 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1050 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1051 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1053 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
1054 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1056 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1058 if (standardprofile)
1060 profile.pProfileData = standardprofile;
1061 profile.cbDataSize = strlen(standardprofile);
1063 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1064 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1066 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1067 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1069 handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1070 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1072 /* Functional checks */
1074 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1075 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1077 ret = pCloseColorProfile( handle );
1078 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1082 static void test_OpenColorProfileW(void)
1084 PROFILE profile;
1085 HPROFILE handle;
1086 BOOL ret;
1088 profile.dwType = PROFILE_FILENAME;
1089 profile.pProfileData = NULL;
1090 profile.cbDataSize = 0;
1092 /* Parameter checks */
1094 handle = pOpenColorProfileW( NULL, 0, 0, 0 );
1095 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1097 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1098 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1100 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1101 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1103 handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
1104 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1106 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1108 if (standardprofileW)
1110 profile.pProfileData = standardprofileW;
1111 profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
1113 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1114 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1116 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1117 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1119 handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1120 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1122 /* Functional checks */
1124 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1125 ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1127 ret = pCloseColorProfile( handle );
1128 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1132 static void test_SetColorProfileElement(void)
1134 if (testprofile)
1136 PROFILE profile;
1137 HPROFILE handle;
1138 DWORD size;
1139 BOOL ret, ref;
1141 TAGTYPE tag = 0x63707274; /* 'cprt' */
1142 static char data[] = "(c) The Wine Project";
1143 static char buffer[51];
1145 profile.dwType = PROFILE_FILENAME;
1146 profile.pProfileData = testprofile;
1147 profile.cbDataSize = strlen(testprofile);
1149 /* Parameter checks */
1151 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1152 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1154 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1155 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1157 pCloseColorProfile( handle );
1159 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1160 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1162 ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1163 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1165 ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1166 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1168 ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1169 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1171 ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1172 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1174 /* Functional checks */
1176 size = sizeof(data);
1178 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1179 ok( ret, "SetColorProfileElement() failed (%d)\n", GetLastError() );
1181 size = sizeof(buffer);
1183 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1184 ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
1186 ok( !memcmp( data, buffer, sizeof(data) ),
1187 "Unexpected tag data, expected %s, got %s (%d)\n",
1188 data, buffer, GetLastError() );
1190 pCloseColorProfile( handle );
1194 static void test_SetColorProfileHeader(void)
1196 if (testprofile)
1198 PROFILE profile;
1199 HPROFILE handle;
1200 BOOL ret;
1201 PROFILEHEADER header;
1203 profile.dwType = PROFILE_FILENAME;
1204 profile.pProfileData = testprofile;
1205 profile.cbDataSize = strlen(testprofile);
1207 header.phSize = 0x00000c48;
1208 header.phCMMType = 0x4c696e6f;
1209 header.phVersion = 0x02100000;
1210 header.phClass = 0x6d6e7472;
1211 header.phDataColorSpace = 0x52474220;
1212 header.phConnectionSpace = 0x58595a20;
1213 header.phDateTime[0] = 0x07ce0002;
1214 header.phDateTime[1] = 0x00090006;
1215 header.phDateTime[2] = 0x00310000;
1216 header.phSignature = 0x61637370;
1217 header.phPlatform = 0x4d534654;
1218 header.phProfileFlags = 0x00000000;
1219 header.phManufacturer = 0x49454320;
1220 header.phModel = 0x73524742;
1221 header.phAttributes[0] = 0x00000000;
1222 header.phAttributes[1] = 0x00000000;
1223 header.phRenderingIntent = 0x00000000;
1224 header.phIlluminant.ciexyzX = 0x0000f6d6;
1225 header.phIlluminant.ciexyzY = 0x00010000;
1226 header.phIlluminant.ciexyzZ = 0x0000d32d;
1227 header.phCreator = 0x48502020;
1229 /* Parameter checks */
1231 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1232 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1234 ret = pSetColorProfileHeader( handle, &header );
1235 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1237 pCloseColorProfile( handle );
1239 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1240 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1242 ret = pSetColorProfileHeader( NULL, NULL );
1243 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1245 ret = pSetColorProfileHeader( handle, NULL );
1246 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1248 ret = pSetColorProfileHeader( NULL, &header );
1249 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1251 /* Functional checks */
1253 ret = pSetColorProfileHeader( handle, &header );
1254 ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1256 ret = pGetColorProfileHeader( handle, &header );
1257 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1259 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1261 pCloseColorProfile( handle );
1265 static void test_UninstallColorProfileA(void)
1267 BOOL ret;
1269 /* Parameter checks */
1271 ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1272 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1274 ret = pUninstallColorProfileA( machine, NULL, FALSE );
1275 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1277 /* Functional checks */
1279 if (testprofile)
1281 CHAR dest[MAX_PATH], base[MAX_PATH];
1282 DWORD size = sizeof(dest);
1283 CHAR slash[] = "\\";
1284 HANDLE handle;
1286 SetLastError(0xdeadbeef);
1287 ret = pInstallColorProfileA( NULL, testprofile );
1288 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1290 skip("Not enough rights for InstallColorProfileA\n");
1291 return;
1293 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1295 ret = pGetColorDirectoryA( NULL, dest, &size );
1296 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1298 MSCMS_basenameA( testprofile, base );
1300 lstrcatA( dest, slash );
1301 lstrcatA( dest, base );
1303 ret = pUninstallColorProfileA( NULL, dest, TRUE );
1304 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1306 /* Check if the profile is really gone */
1307 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1308 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1309 CloseHandle( handle );
1313 static void test_UninstallColorProfileW(void)
1315 BOOL ret;
1317 /* Parameter checks */
1319 ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1320 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1322 ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1323 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1325 /* Functional checks */
1327 if (testprofileW)
1329 WCHAR dest[MAX_PATH], base[MAX_PATH];
1330 char destA[MAX_PATH];
1331 DWORD size = sizeof(dest);
1332 WCHAR slash[] = { '\\', 0 };
1333 HANDLE handle;
1334 int bytes_copied;
1336 SetLastError(0xdeadbeef);
1337 ret = pInstallColorProfileW( NULL, testprofileW );
1338 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1340 skip("Not enough rights for InstallColorProfileW\n");
1341 return;
1343 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1345 ret = pGetColorDirectoryW( NULL, dest, &size );
1346 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1348 MSCMS_basenameW( testprofileW, base );
1350 lstrcatW( dest, slash );
1351 lstrcatW( dest, base );
1353 ret = pUninstallColorProfileW( NULL, dest, TRUE );
1354 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1356 bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1357 ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1358 /* Check if the profile is really gone */
1359 handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1360 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1361 CloseHandle( handle );
1365 static void test_AssociateColorProfileWithDeviceA(void)
1367 BOOL ret;
1368 char profile[MAX_PATH], basename[MAX_PATH];
1369 DWORD error, size = sizeof(profile);
1371 if (testprofile)
1373 SetLastError(0xdeadbeef);
1374 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1375 error = GetLastError();
1376 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1377 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1379 SetLastError(0xdeadbeef);
1380 ret = pAssociateColorProfileWithDeviceA( "machine", NULL, "DISPLAY" );
1381 error = GetLastError();
1382 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1383 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1385 SetLastError(0xdeadbeef);
1386 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, "DISPLAY" );
1387 error = GetLastError();
1388 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1389 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1391 ret = pInstallColorProfileA( NULL, testprofile );
1392 ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1394 ret = pGetColorDirectoryA( NULL, profile, &size );
1395 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1397 MSCMS_basenameA( testprofile, basename );
1398 lstrcatA( profile, "\\" );
1399 lstrcatA( profile, basename );
1401 ret = pAssociateColorProfileWithDeviceA( NULL, profile, "DISPLAY" );
1402 ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1404 SetLastError(0xdeadbeef);
1405 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1406 error = GetLastError();
1407 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1408 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1410 SetLastError(0xdeadbeef);
1411 ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, "DISPLAY" );
1412 error = GetLastError();
1413 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1414 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1416 SetLastError(0xdeadbeef);
1417 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, "DISPLAY" );
1418 error = GetLastError();
1419 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1420 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1422 ret = pDisassociateColorProfileFromDeviceA( NULL, profile, "DISPLAY" );
1423 ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1425 ret = pUninstallColorProfileA( NULL, profile, TRUE );
1426 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1430 START_TEST(profile)
1432 UINT len;
1433 HANDLE handle;
1434 char path[MAX_PATH], file[MAX_PATH];
1435 char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1436 WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1437 BOOL has_space_rgb;
1438 WCHAR fileW[MAX_PATH];
1439 UINT ret;
1441 hmscms = LoadLibraryA( "mscms.dll" );
1442 if (!hmscms) return;
1444 if (!init_function_ptrs())
1446 FreeLibrary( hmscms );
1447 return;
1450 /* See if we can find the standard color profile */
1451 ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1452 ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1453 ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH,
1454 "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1455 MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1456 ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH,
1457 "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1458 lstrcpyA(profilefile2, profilefile1);
1459 lstrcpyW(profilefile2W, profilefile1W);
1461 lstrcatA( profilefile1, profile1 );
1462 lstrcatW( profilefile1W, profile1W );
1463 handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1465 if (handle != INVALID_HANDLE_VALUE)
1467 standardprofile = profilefile1;
1468 standardprofileW = profilefile1W;
1469 CloseHandle( handle );
1472 lstrcatA( profilefile2, profile2 );
1473 lstrcatW( profilefile2W, profile2W );
1474 handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1476 if (handle != INVALID_HANDLE_VALUE)
1478 standardprofile = profilefile2;
1479 standardprofileW = profilefile2W;
1480 CloseHandle( handle );
1483 /* If found, create a temporary copy for testing purposes */
1484 if (standardprofile && GetTempPath( sizeof(path), path ))
1486 if (GetTempFileName( path, "rgb", 0, file ))
1488 if (CopyFileA( standardprofile, file, FALSE ))
1490 testprofile = (LPSTR)&file;
1492 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1493 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1495 testprofileW = (LPWSTR)&fileW;
1500 test_GetColorDirectoryA();
1501 test_GetColorDirectoryW();
1503 test_GetColorProfileElement();
1504 test_GetColorProfileElementTag();
1506 test_GetColorProfileFromHandle();
1507 test_GetColorProfileHeader();
1509 test_GetCountColorProfileElements();
1511 enum_registered_color_profiles();
1512 check_registry(&has_space_rgb);
1514 test_GetStandardColorSpaceProfileA(has_space_rgb);
1515 test_GetStandardColorSpaceProfileW(has_space_rgb);
1517 test_EnumColorProfilesA();
1518 test_EnumColorProfilesW();
1520 test_InstallColorProfileA();
1521 test_InstallColorProfileW();
1523 test_IsColorProfileTagPresent();
1525 test_OpenColorProfileA();
1526 test_OpenColorProfileW();
1528 test_SetColorProfileElement();
1529 test_SetColorProfileHeader();
1531 test_UninstallColorProfileA();
1532 test_UninstallColorProfileW();
1534 test_AssociateColorProfileWithDeviceA();
1536 /* Clean up */
1537 if (testprofile)
1538 DeleteFileA( testprofile );
1540 FreeLibrary( hmscms );