push c22b4aa826b27f0c6bc5101b378e6e68716a85d9
[wine/hacks.git] / dlls / mscms / tests / profile.c
blobe33280ab857d4b41922218db0f656affe0a60be5
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;
34 HMODULE huser32;
36 static BOOL (WINAPI *pAssociateColorProfileWithDeviceA)(PCSTR,PCSTR,PCSTR);
37 static BOOL (WINAPI *pCloseColorProfile)(HPROFILE);
38 static BOOL (WINAPI *pDisassociateColorProfileFromDeviceA)(PCSTR,PCSTR,PCSTR);
39 static BOOL (WINAPI *pGetColorDirectoryA)(PCHAR,PCHAR,PDWORD);
40 static BOOL (WINAPI *pGetColorDirectoryW)(PWCHAR,PWCHAR,PDWORD);
41 static BOOL (WINAPI *pGetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL);
42 static BOOL (WINAPI *pGetColorProfileElementTag)(HPROFILE,DWORD,PTAGTYPE);
43 static BOOL (WINAPI *pGetColorProfileFromHandle)(HPROFILE,PBYTE,PDWORD);
44 static BOOL (WINAPI *pGetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
45 static BOOL (WINAPI *pGetCountColorProfileElements)(HPROFILE,PDWORD);
46 static BOOL (WINAPI *pGetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR,PDWORD);
47 static BOOL (WINAPI *pGetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR,PDWORD);
48 static BOOL (WINAPI *pEnumColorProfilesA)(PCSTR,PENUMTYPEA,PBYTE,PDWORD,PDWORD);
49 static BOOL (WINAPI *pEnumColorProfilesW)(PCWSTR,PENUMTYPEW,PBYTE,PDWORD,PDWORD);
50 static BOOL (WINAPI *pInstallColorProfileA)(PCSTR,PCSTR);
51 static BOOL (WINAPI *pInstallColorProfileW)(PCWSTR,PCWSTR);
52 static BOOL (WINAPI *pIsColorProfileTagPresent)(HPROFILE,TAGTYPE,PBOOL);
53 static HPROFILE (WINAPI *pOpenColorProfileA)(PPROFILE,DWORD,DWORD,DWORD);
54 static HPROFILE (WINAPI *pOpenColorProfileW)(PPROFILE,DWORD,DWORD,DWORD);
55 static BOOL (WINAPI *pSetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID);
56 static BOOL (WINAPI *pSetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
57 static BOOL (WINAPI *pSetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR);
58 static BOOL (WINAPI *pSetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR);
59 static BOOL (WINAPI *pUninstallColorProfileA)(PCSTR,PCSTR,BOOL);
60 static BOOL (WINAPI *pUninstallColorProfileW)(PCWSTR,PCWSTR,BOOL);
62 static BOOL (WINAPI *pEnumDisplayDevicesA)(LPCSTR,DWORD,PDISPLAY_DEVICE,DWORD);
64 #define GETFUNCPTR(func) p##func = (void *)GetProcAddress( hmscms, #func ); \
65 if (!p##func) return FALSE;
67 static BOOL init_function_ptrs( void )
69 GETFUNCPTR( AssociateColorProfileWithDeviceA )
70 GETFUNCPTR( CloseColorProfile )
71 GETFUNCPTR( DisassociateColorProfileFromDeviceA )
72 GETFUNCPTR( GetColorDirectoryA )
73 GETFUNCPTR( GetColorDirectoryW )
74 GETFUNCPTR( GetColorProfileElement )
75 GETFUNCPTR( GetColorProfileElementTag )
76 GETFUNCPTR( GetColorProfileFromHandle )
77 GETFUNCPTR( GetColorProfileHeader )
78 GETFUNCPTR( GetCountColorProfileElements )
79 GETFUNCPTR( GetStandardColorSpaceProfileA )
80 GETFUNCPTR( GetStandardColorSpaceProfileW )
81 GETFUNCPTR( EnumColorProfilesA )
82 GETFUNCPTR( EnumColorProfilesW )
83 GETFUNCPTR( InstallColorProfileA )
84 GETFUNCPTR( InstallColorProfileW )
85 GETFUNCPTR( IsColorProfileTagPresent )
86 GETFUNCPTR( OpenColorProfileA )
87 GETFUNCPTR( OpenColorProfileW )
88 GETFUNCPTR( SetColorProfileElement )
89 GETFUNCPTR( SetColorProfileHeader )
90 GETFUNCPTR( SetStandardColorSpaceProfileA )
91 GETFUNCPTR( SetStandardColorSpaceProfileW )
92 GETFUNCPTR( UninstallColorProfileA )
93 GETFUNCPTR( UninstallColorProfileW )
95 pEnumDisplayDevicesA = (void *)GetProcAddress( huser32, "EnumDisplayDevicesA" );
97 return TRUE;
100 static const char machine[] = "dummy";
101 static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
103 /* To do any real functionality testing with this suite you need a copy of
104 * the freely distributable standard RGB color space profile. It comes
105 * standard with Windows, but on Wine you probably need to install it yourself
106 * in one of the locations mentioned below.
109 /* Two common places to find the standard color space profile, relative
110 * to the system directory.
112 static const char profile1[] =
113 "\\color\\srgb color space profile.icm";
114 static const char profile2[] =
115 "\\spool\\drivers\\color\\srgb color space profile.icm";
117 static const WCHAR profile1W[] =
118 { '\\','c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
119 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
120 static const WCHAR profile2W[] =
121 { '\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',
122 'c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
123 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
125 static const unsigned char rgbheader[] =
126 { 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02,
127 0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58,
128 0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00,
129 0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00,
130 0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00,
132 0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 };
134 static LPSTR standardprofile;
135 static LPWSTR standardprofileW;
137 static LPSTR testprofile;
138 static LPWSTR testprofileW;
140 #define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
142 static void MSCMS_basenameA( LPCSTR path, LPSTR name )
144 INT i = strlen( path );
146 while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
147 strcpy( name, &path[i] );
150 static void MSCMS_basenameW( LPCWSTR path, LPWSTR name )
152 INT i = lstrlenW( path );
154 while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
155 lstrcpyW( name, &path[i] );
158 static void test_GetColorDirectoryA(void)
160 BOOL ret;
161 DWORD size;
162 char buffer[MAX_PATH];
164 /* Parameter checks */
166 ret = pGetColorDirectoryA( NULL, NULL, NULL );
167 ok( !ret, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
169 size = 0;
171 ret = pGetColorDirectoryA( NULL, NULL, &size );
172 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
174 size = 0;
176 ret = pGetColorDirectoryA( NULL, buffer, &size );
177 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
179 size = 1;
181 ret = pGetColorDirectoryA( NULL, buffer, &size );
182 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
184 /* Functional checks */
186 size = sizeof(buffer);
188 ret = pGetColorDirectoryA( NULL, buffer, &size );
189 ok( ret && size > 0, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
192 static void test_GetColorDirectoryW(void)
194 BOOL ret;
195 DWORD size;
196 WCHAR buffer[MAX_PATH];
198 /* Parameter checks */
200 /* This one crashes win2k
202 ret = pGetColorDirectoryW( NULL, NULL, NULL );
203 ok( !ret, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
207 size = 0;
209 ret = pGetColorDirectoryW( NULL, NULL, &size );
210 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
212 size = 0;
214 ret = pGetColorDirectoryW( NULL, buffer, &size );
215 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
217 size = 1;
219 ret = pGetColorDirectoryW( NULL, buffer, &size );
220 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
222 /* Functional checks */
224 size = sizeof(buffer);
226 ret = pGetColorDirectoryW( NULL, buffer, &size );
227 ok( ret && size > 0, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
230 static void test_GetColorProfileElement(void)
232 if (standardprofile)
234 PROFILE profile;
235 HPROFILE handle;
236 BOOL ret, ref;
237 DWORD size;
238 TAGTYPE tag = 0x63707274; /* 'cprt' */
239 static char buffer[51];
240 static const char expect[] =
241 { 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70,
242 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
243 0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74,
244 0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43,
245 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x00 };
247 profile.dwType = PROFILE_FILENAME;
248 profile.pProfileData = standardprofile;
249 profile.cbDataSize = strlen(standardprofile);
251 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
252 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
254 /* Parameter checks */
256 ret = pGetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
257 ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
259 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
260 ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
262 size = 0;
264 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
265 ok( !ret && size > 0, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
267 size = sizeof(buffer);
269 /* Functional checks */
271 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
272 ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
274 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
276 pCloseColorProfile( handle );
280 static void test_GetColorProfileElementTag(void)
282 if (standardprofile)
284 PROFILE profile;
285 HPROFILE handle;
286 BOOL ret;
287 DWORD index = 1;
288 TAGTYPE tag, expect = 0x63707274; /* 'cprt' */
290 profile.dwType = PROFILE_FILENAME;
291 profile.pProfileData = standardprofile;
292 profile.cbDataSize = strlen(standardprofile);
294 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
295 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
297 /* Parameter checks */
299 ret = pGetColorProfileElementTag( NULL, index, &tag );
300 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
302 ret = pGetColorProfileElementTag( handle, 0, &tag );
303 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
305 ret = pGetColorProfileElementTag( handle, index, NULL );
306 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
308 ret = pGetColorProfileElementTag( handle, 18, NULL );
309 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
311 /* Functional checks */
313 ret = pGetColorProfileElementTag( handle, index, &tag );
314 ok( ret && tag == expect, "GetColorProfileElementTag() failed (%d)\n",
315 GetLastError() );
317 pCloseColorProfile( handle );
321 static void test_GetColorProfileFromHandle(void)
323 if (testprofile)
325 PROFILE profile;
326 HPROFILE handle;
327 DWORD size;
328 BOOL ret;
329 static const unsigned char expect[] =
330 { 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
331 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
332 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
333 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
334 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
335 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
337 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 };
339 unsigned char *buffer;
341 profile.dwType = PROFILE_FILENAME;
342 profile.pProfileData = testprofile;
343 profile.cbDataSize = strlen(testprofile);
345 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
346 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
348 /* Parameter checks */
350 size = 0;
352 ret = pGetColorProfileFromHandle( handle, NULL, &size );
353 ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
355 buffer = HeapAlloc( GetProcessHeap(), 0, size );
357 if (buffer)
359 ret = pGetColorProfileFromHandle( NULL, buffer, &size );
360 ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
362 ret = pGetColorProfileFromHandle( handle, buffer, NULL );
363 ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
365 /* Functional checks */
367 ret = pGetColorProfileFromHandle( handle, buffer, &size );
368 ok( ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
370 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" );
372 HeapFree( GetProcessHeap(), 0, buffer );
375 pCloseColorProfile( handle );
379 static void test_GetColorProfileHeader(void)
381 if (testprofile)
383 PROFILE profile;
384 HPROFILE handle;
385 BOOL ret;
386 PROFILEHEADER header;
388 profile.dwType = PROFILE_FILENAME;
389 profile.pProfileData = testprofile;
390 profile.cbDataSize = strlen(testprofile);
392 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
393 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
395 /* Parameter checks */
397 ret = pGetColorProfileHeader( NULL, NULL );
398 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
400 ret = pGetColorProfileHeader( NULL, &header );
401 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
403 if (0) /* Crashes on Vista */
405 ret = pGetColorProfileHeader( handle, NULL );
406 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
409 /* Functional checks */
411 ret = pGetColorProfileHeader( handle, &header );
412 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
414 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
416 pCloseColorProfile( handle );
420 static void test_GetCountColorProfileElements(void)
422 if (standardprofile)
424 PROFILE profile;
425 HPROFILE handle;
426 BOOL ret;
427 DWORD count, expect = 17;
429 profile.dwType = PROFILE_FILENAME;
430 profile.pProfileData = standardprofile;
431 profile.cbDataSize = strlen(standardprofile);
433 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
434 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
436 /* Parameter checks */
438 ret = pGetCountColorProfileElements( NULL, &count );
439 ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
440 GetLastError() );
442 ret = pGetCountColorProfileElements( handle, NULL );
443 ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
444 GetLastError() );
446 /* Functional checks */
448 ret = pGetCountColorProfileElements( handle, &count );
449 ok( ret && count == expect,
450 "GetCountColorProfileElements() failed (%d)\n", GetLastError() );
452 pCloseColorProfile( handle );
456 typedef struct colorspace_description_struct {
457 DWORD dwID;
458 const char *szName;
459 BOOL registered;
460 char filename[MAX_PATH];
461 } colorspace_descr;
463 #define describe_colorspace(id) {id, #id, FALSE, ""}
465 colorspace_descr known_colorspaces[] = {
466 describe_colorspace(SPACE_XYZ),
467 describe_colorspace(SPACE_Lab),
468 describe_colorspace(SPACE_Luv),
469 describe_colorspace(SPACE_YCbCr),
470 describe_colorspace(SPACE_Yxy),
471 describe_colorspace(SPACE_RGB),
472 describe_colorspace(SPACE_GRAY),
473 describe_colorspace(SPACE_HSV),
474 describe_colorspace(SPACE_HLS),
475 describe_colorspace(SPACE_CMYK),
476 describe_colorspace(SPACE_CMY),
477 describe_colorspace(SPACE_2_CHANNEL),
478 describe_colorspace(SPACE_3_CHANNEL),
479 describe_colorspace(SPACE_4_CHANNEL),
480 describe_colorspace(SPACE_5_CHANNEL),
481 describe_colorspace(SPACE_6_CHANNEL),
482 describe_colorspace(SPACE_7_CHANNEL),
483 describe_colorspace(SPACE_8_CHANNEL)
486 static void enum_registered_color_profiles(void)
488 BOOL ret;
489 DWORD size, count, i, present;
490 CHAR profile[MAX_PATH];
492 size = sizeof(profile);
493 count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
495 present = 0;
496 trace("\n");
497 trace("Querying registered standard colorspace profiles via GetStandardColorSpaceProfileA():\n");
498 for (i=0; i<count; i++)
500 ret = pGetStandardColorSpaceProfileA(NULL, known_colorspaces[i].dwID, profile, &size);
501 if (ret)
503 lstrcpynA(known_colorspaces[i].filename, profile, MAX_PATH);
504 known_colorspaces[i].registered = TRUE;
505 present++;
506 trace(" found %s, pointing to '%s' (%d chars)\n", known_colorspaces[i].szName, profile, lstrlenA(profile));
509 trace("Total profiles found: %d.\n", present);
510 trace("\n");
513 static colorspace_descr *query_colorspace(DWORD dwID)
515 DWORD count, i;
517 count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
519 for (i=0; i<count; i++)
520 if (known_colorspaces[i].dwID == dwID)
522 if (!known_colorspaces[i].registered) break;
523 return &known_colorspaces[i];
525 return NULL;
528 static HKEY reg_open_mscms_key(void)
530 char win9x[] = "SOFTWARE\\Microsoft\\Windows";
531 char winNT[] = "SOFTWARE\\Microsoft\\Windows NT";
532 char ICM[] = "CurrentVersion\\ICM\\RegisteredProfiles";
533 HKEY win9x_key, winNT_key, ICM_key;
535 RegOpenKeyExA( HKEY_LOCAL_MACHINE, win9x, 0, KEY_READ, &win9x_key );
536 RegOpenKeyExA( HKEY_LOCAL_MACHINE, winNT, 0, KEY_READ, &winNT_key );
538 if (RegOpenKeyExA( winNT_key, ICM, 0, KEY_READ, &ICM_key ))
539 RegOpenKeyExA( win9x_key, ICM, 0, KEY_READ, &ICM_key );
540 RegCloseKey( win9x_key );
541 RegCloseKey( winNT_key );
543 return ICM_key;
546 static void check_registry(BOOL *has_space_rgb)
548 HKEY hkIcmKey;
549 LONG res;
550 DWORD i, dwValCount;
551 char szName[16383];
552 char szData[MAX_PATH+1];
553 DWORD dwNameLen, dwDataLen, dwType;
555 *has_space_rgb = FALSE;
556 hkIcmKey = reg_open_mscms_key();
557 if (!hkIcmKey)
559 trace("Key 'HKLM\\SOFTWARE\\Microsoft\\Windows*\\CurrentVersion\\ICM\\RegisteredProfiles' not found\n" );
560 return;
563 res = RegQueryInfoKeyA(hkIcmKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValCount, NULL, NULL, NULL, NULL);
564 if (res)
566 trace("RegQueryInfoKeyA() failed : %d\n", res);
567 return;
570 trace("Count of profile entries found directly in the registry: %d\n", dwValCount);
572 for (i = 0; i<dwValCount; i++)
574 dwNameLen = sizeof(szName);
575 dwDataLen = sizeof(szData);
576 res = RegEnumValueA( hkIcmKey, i, szName, &dwNameLen, NULL, &dwType, (LPBYTE)szData, &dwDataLen );
577 if (!strncmp(szName, "RGB", 3))
578 *has_space_rgb = TRUE;
579 if (res != ERROR_SUCCESS)
581 trace("RegEnumValueA() failed (%d), cannot enumerate profiles\n", res);
582 break;
584 ok( dwType == REG_SZ, "RegEnumValueA() returned unexpected value type (%d)\n", dwType );
585 if (dwType != REG_SZ) break;
586 trace(" found '%s' value containing '%s' (%d chars)\n", szName, szData, lstrlenA(szData));
589 RegCloseKey( hkIcmKey );
592 static void test_GetStandardColorSpaceProfileA(BOOL has_space_rgb)
594 BOOL ret;
595 DWORD size;
596 CHAR oldprofile[MAX_PATH];
597 CHAR newprofile[MAX_PATH];
598 const CHAR emptyA[] = "";
599 DWORD zero = 0;
600 DWORD sizeP = sizeof(newprofile);
602 /* Parameter checks */
604 /* Single invalid parameter checks: */
606 SetLastError(0xfaceabee); /* 1st param, */
607 ret = pGetStandardColorSpaceProfileA(machine, SPACE_RGB, newprofile, &sizeP);
608 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
610 SetLastError(0xfaceabee); /* 2nd param, */
611 ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &sizeP);
612 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
614 SetLastError(0xfaceabee); /* 4th param, */
615 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, NULL);
616 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
618 if (query_colorspace(SPACE_RGB))
620 SetLastError(0xfaceabee); /* 3rd param, */
621 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
622 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
624 SetLastError(0xfaceabee); /* dereferenced 4th param, */
625 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &zero);
626 ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
627 } else {
628 SetLastError(0xfaceabee); /* 3rd param, */
629 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
630 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
632 SetLastError(0xfaceabee); /* dereferenced 4th param. */
633 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &sizeP);
634 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
637 /* Several invalid parameter checks: */
639 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
640 ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &zero);
641 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
643 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
644 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
645 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
647 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
648 ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &zero);
649 ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
651 SetLastError(0xfaceabee); /* maybe 2nd param. */
652 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &sizeP);
653 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
654 else ok( !lstrcmpiA( newprofile, emptyA ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
656 /* Functional checks */
658 if (has_space_rgb)
660 size = sizeof(oldprofile);
662 ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
663 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
665 SetLastError(0xdeadbeef);
666 ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
667 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
669 skip("Not enough rights for SetStandardColorSpaceProfileA\n");
670 return;
672 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
674 size = sizeof(newprofile);
676 ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
677 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
679 ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
681 ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
682 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
686 static void test_GetStandardColorSpaceProfileW(BOOL has_space_rgb)
688 BOOL ret;
689 DWORD size;
690 WCHAR oldprofile[MAX_PATH];
691 WCHAR newprofile[MAX_PATH];
692 const WCHAR emptyW[] = {0};
693 DWORD zero = 0;
694 DWORD sizeP = sizeof(newprofile);
696 /* Parameter checks */
698 /* Single invalid parameter checks: */
700 SetLastError(0xfaceabee); /* 1st param, */
701 ret = pGetStandardColorSpaceProfileW(machineW, SPACE_RGB, newprofile, &sizeP);
702 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
704 SetLastError(0xfaceabee); /* 2nd param, */
705 ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &sizeP);
706 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
708 SetLastError(0xfaceabee); /* 3rd param, */
709 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, NULL, &sizeP);
710 if (has_space_rgb)
711 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
712 else
713 todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
715 SetLastError(0xfaceabee); /* 4th param, */
716 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, NULL);
717 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
719 SetLastError(0xfaceabee); /* dereferenced 4th param. */
720 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, &zero);
721 if (has_space_rgb)
722 ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
723 else
724 todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
727 /* Several invalid parameter checks: */
729 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
730 ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &zero);
731 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
733 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
734 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
735 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
737 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
738 ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &zero);
739 ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
741 SetLastError(0xfaceabee); /* maybe 2nd param. */
742 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
743 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
744 else ok( !lstrcmpiW( newprofile, emptyW ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
746 /* Functional checks */
748 if (has_space_rgb)
750 size = sizeof(oldprofile);
752 ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
753 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
755 SetLastError(0xdeadbeef);
756 ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
757 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
759 skip("Not enough rights for SetStandardColorSpaceProfileW\n");
760 return;
762 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
764 size = sizeof(newprofile);
766 ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
767 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
769 ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
771 ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
772 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
776 static void test_EnumColorProfilesA(void)
778 BOOL ret;
779 DWORD total, size, number;
780 ENUMTYPEA record;
781 BYTE *buffer;
783 /* Parameter checks */
785 memset( &record, 0, sizeof(ENUMTYPEA) );
787 record.dwSize = sizeof(ENUMTYPEA);
788 record.dwVersion = ENUM_TYPE_VERSION;
789 record.dwFields |= ET_DATACOLORSPACE;
790 record.dwDataColorSpace = SPACE_RGB;
792 total = 0;
793 ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number );
794 ok( !ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
795 buffer = HeapAlloc( GetProcessHeap(), 0, total );
797 size = total;
798 ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
799 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
801 ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
802 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
804 ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
805 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
807 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
808 if (standardprofile)
809 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
810 else
811 todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
813 size = 0;
815 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
816 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
818 /* Functional checks */
820 size = total;
821 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
822 if (standardprofile)
823 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
824 else
825 todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
827 HeapFree( GetProcessHeap(), 0, buffer );
830 static void test_EnumColorProfilesW(void)
832 BOOL ret;
833 DWORD total, size, number;
834 ENUMTYPEW record;
835 BYTE *buffer;
837 /* Parameter checks */
839 memset( &record, 0, sizeof(ENUMTYPEW) );
841 record.dwSize = sizeof(ENUMTYPEW);
842 record.dwVersion = ENUM_TYPE_VERSION;
843 record.dwFields |= ET_DATACOLORSPACE;
844 record.dwDataColorSpace = SPACE_RGB;
846 total = 0;
847 ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number );
848 ok( !ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
849 buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
851 size = total;
852 ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
853 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
855 ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
856 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
858 ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
859 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
861 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
862 if (standardprofileW)
863 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
864 else
865 todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
867 size = 0;
868 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
869 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
871 /* Functional checks */
873 size = total;
874 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
875 if (standardprofileW)
876 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
877 else
878 todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
880 HeapFree( GetProcessHeap(), 0, buffer );
883 static void test_InstallColorProfileA(void)
885 BOOL ret;
887 /* Parameter checks */
889 ret = pInstallColorProfileA( NULL, NULL );
890 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
892 ret = pInstallColorProfileA( machine, NULL );
893 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
895 ret = pInstallColorProfileA( NULL, machine );
896 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
898 if (standardprofile)
900 ret = pInstallColorProfileA( NULL, standardprofile );
901 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
904 /* Functional checks */
906 if (testprofile)
908 CHAR dest[MAX_PATH], base[MAX_PATH];
909 DWORD size = sizeof(dest);
910 CHAR slash[] = "\\";
911 HANDLE handle;
913 SetLastError(0xdeadbeef);
914 ret = pInstallColorProfileA( NULL, testprofile );
915 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
917 skip("Not enough rights for InstallColorProfileA\n");
918 return;
920 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
922 ret = pGetColorDirectoryA( NULL, dest, &size );
923 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
925 MSCMS_basenameA( testprofile, base );
927 lstrcatA( dest, slash );
928 lstrcatA( dest, base );
930 /* Check if the profile is really there */
931 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
932 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
933 CloseHandle( handle );
935 ret = pUninstallColorProfileA( NULL, dest, TRUE );
936 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
940 static void test_InstallColorProfileW(void)
942 BOOL ret;
944 /* Parameter checks */
946 ret = pInstallColorProfileW( NULL, NULL );
947 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
949 ret = pInstallColorProfileW( machineW, NULL );
950 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
952 ret = pInstallColorProfileW( NULL, machineW );
953 ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
955 if (standardprofileW)
957 ret = pInstallColorProfileW( NULL, standardprofileW );
958 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
961 /* Functional checks */
963 if (testprofileW)
965 WCHAR dest[MAX_PATH], base[MAX_PATH];
966 DWORD size = sizeof(dest);
967 WCHAR slash[] = { '\\', 0 };
968 HANDLE handle;
970 SetLastError(0xdeadbeef);
971 ret = pInstallColorProfileW( NULL, testprofileW );
972 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
974 skip("Not enough rights for InstallColorProfileW\n");
975 return;
977 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
979 ret = pGetColorDirectoryW( NULL, dest, &size );
980 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
982 MSCMS_basenameW( testprofileW, base );
984 lstrcatW( dest, slash );
985 lstrcatW( dest, base );
987 /* Check if the profile is really there */
988 handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
989 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
990 CloseHandle( handle );
992 ret = pUninstallColorProfileW( NULL, dest, TRUE );
993 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
997 static void test_IsColorProfileTagPresent(void)
999 if (standardprofile)
1001 PROFILE profile;
1002 HPROFILE handle;
1003 BOOL ret, present;
1004 TAGTYPE tag;
1006 profile.dwType = PROFILE_FILENAME;
1007 profile.pProfileData = standardprofile;
1008 profile.cbDataSize = strlen(standardprofile);
1010 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1011 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1013 /* Parameter checks */
1015 tag = 0;
1017 ret = pIsColorProfileTagPresent( handle, tag, &present );
1018 ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1020 tag = 0x63707274; /* 'cprt' */
1022 ret = pIsColorProfileTagPresent( NULL, tag, &present );
1023 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1025 ret = pIsColorProfileTagPresent( handle, tag, NULL );
1026 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1028 /* Functional checks */
1030 ret = pIsColorProfileTagPresent( handle, tag, &present );
1031 ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() );
1033 pCloseColorProfile( handle );
1037 static void test_OpenColorProfileA(void)
1039 PROFILE profile;
1040 HPROFILE handle;
1041 BOOL ret;
1043 profile.dwType = PROFILE_FILENAME;
1044 profile.pProfileData = NULL;
1045 profile.cbDataSize = 0;
1047 /* Parameter checks */
1049 handle = pOpenColorProfileA( NULL, 0, 0, 0 );
1050 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1052 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1053 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1055 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1056 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1058 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
1059 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1061 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1063 if (standardprofile)
1065 profile.pProfileData = standardprofile;
1066 profile.cbDataSize = strlen(standardprofile);
1068 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1069 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1071 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1072 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1074 handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1075 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1077 /* Functional checks */
1079 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1080 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1082 ret = pCloseColorProfile( handle );
1083 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1087 static void test_OpenColorProfileW(void)
1089 PROFILE profile;
1090 HPROFILE handle;
1091 BOOL ret;
1093 profile.dwType = PROFILE_FILENAME;
1094 profile.pProfileData = NULL;
1095 profile.cbDataSize = 0;
1097 /* Parameter checks */
1099 handle = pOpenColorProfileW( NULL, 0, 0, 0 );
1100 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1102 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1103 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1105 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1106 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1108 handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
1109 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1111 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1113 if (standardprofileW)
1115 profile.pProfileData = standardprofileW;
1116 profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
1118 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1119 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1121 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1122 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1124 handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1125 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1127 /* Functional checks */
1129 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1130 ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1132 ret = pCloseColorProfile( handle );
1133 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1137 static void test_SetColorProfileElement(void)
1139 if (testprofile)
1141 PROFILE profile;
1142 HPROFILE handle;
1143 DWORD size;
1144 BOOL ret, ref;
1146 TAGTYPE tag = 0x63707274; /* 'cprt' */
1147 static char data[] = "(c) The Wine Project";
1148 static char buffer[51];
1150 profile.dwType = PROFILE_FILENAME;
1151 profile.pProfileData = testprofile;
1152 profile.cbDataSize = strlen(testprofile);
1154 /* Parameter checks */
1156 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1157 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1159 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1160 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1162 pCloseColorProfile( handle );
1164 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1165 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1167 ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1168 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1170 ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1171 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1173 ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1174 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1176 ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1177 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1179 /* Functional checks */
1181 size = sizeof(data);
1183 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1184 ok( ret, "SetColorProfileElement() failed (%d)\n", GetLastError() );
1186 size = sizeof(buffer);
1188 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1189 ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
1191 ok( !memcmp( data, buffer, sizeof(data) ),
1192 "Unexpected tag data, expected %s, got %s (%d)\n",
1193 data, buffer, GetLastError() );
1195 pCloseColorProfile( handle );
1199 static void test_SetColorProfileHeader(void)
1201 if (testprofile)
1203 PROFILE profile;
1204 HPROFILE handle;
1205 BOOL ret;
1206 PROFILEHEADER header;
1208 profile.dwType = PROFILE_FILENAME;
1209 profile.pProfileData = testprofile;
1210 profile.cbDataSize = strlen(testprofile);
1212 header.phSize = 0x00000c48;
1213 header.phCMMType = 0x4c696e6f;
1214 header.phVersion = 0x02100000;
1215 header.phClass = 0x6d6e7472;
1216 header.phDataColorSpace = 0x52474220;
1217 header.phConnectionSpace = 0x58595a20;
1218 header.phDateTime[0] = 0x07ce0002;
1219 header.phDateTime[1] = 0x00090006;
1220 header.phDateTime[2] = 0x00310000;
1221 header.phSignature = 0x61637370;
1222 header.phPlatform = 0x4d534654;
1223 header.phProfileFlags = 0x00000000;
1224 header.phManufacturer = 0x49454320;
1225 header.phModel = 0x73524742;
1226 header.phAttributes[0] = 0x00000000;
1227 header.phAttributes[1] = 0x00000000;
1228 header.phRenderingIntent = 0x00000000;
1229 header.phIlluminant.ciexyzX = 0x0000f6d6;
1230 header.phIlluminant.ciexyzY = 0x00010000;
1231 header.phIlluminant.ciexyzZ = 0x0000d32d;
1232 header.phCreator = 0x48502020;
1234 /* Parameter checks */
1236 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1237 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1239 ret = pSetColorProfileHeader( handle, &header );
1240 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1242 pCloseColorProfile( handle );
1244 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1245 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1247 ret = pSetColorProfileHeader( NULL, NULL );
1248 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1250 ret = pSetColorProfileHeader( handle, NULL );
1251 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1253 ret = pSetColorProfileHeader( NULL, &header );
1254 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1256 /* Functional checks */
1258 ret = pSetColorProfileHeader( handle, &header );
1259 ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1261 ret = pGetColorProfileHeader( handle, &header );
1262 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1264 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1266 pCloseColorProfile( handle );
1270 static void test_UninstallColorProfileA(void)
1272 BOOL ret;
1274 /* Parameter checks */
1276 ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1277 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1279 ret = pUninstallColorProfileA( machine, NULL, FALSE );
1280 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1282 /* Functional checks */
1284 if (testprofile)
1286 CHAR dest[MAX_PATH], base[MAX_PATH];
1287 DWORD size = sizeof(dest);
1288 CHAR slash[] = "\\";
1289 HANDLE handle;
1291 SetLastError(0xdeadbeef);
1292 ret = pInstallColorProfileA( NULL, testprofile );
1293 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1295 skip("Not enough rights for InstallColorProfileA\n");
1296 return;
1298 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1300 ret = pGetColorDirectoryA( NULL, dest, &size );
1301 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1303 MSCMS_basenameA( testprofile, base );
1305 lstrcatA( dest, slash );
1306 lstrcatA( dest, base );
1308 ret = pUninstallColorProfileA( NULL, dest, TRUE );
1309 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1311 /* Check if the profile is really gone */
1312 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1313 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1314 CloseHandle( handle );
1318 static void test_UninstallColorProfileW(void)
1320 BOOL ret;
1322 /* Parameter checks */
1324 ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1325 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1327 ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1328 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1330 /* Functional checks */
1332 if (testprofileW)
1334 WCHAR dest[MAX_PATH], base[MAX_PATH];
1335 char destA[MAX_PATH];
1336 DWORD size = sizeof(dest);
1337 WCHAR slash[] = { '\\', 0 };
1338 HANDLE handle;
1339 int bytes_copied;
1341 SetLastError(0xdeadbeef);
1342 ret = pInstallColorProfileW( NULL, testprofileW );
1343 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1345 skip("Not enough rights for InstallColorProfileW\n");
1346 return;
1348 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1350 ret = pGetColorDirectoryW( NULL, dest, &size );
1351 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1353 MSCMS_basenameW( testprofileW, base );
1355 lstrcatW( dest, slash );
1356 lstrcatW( dest, base );
1358 ret = pUninstallColorProfileW( NULL, dest, TRUE );
1359 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1361 bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1362 ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1363 /* Check if the profile is really gone */
1364 handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1365 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1366 CloseHandle( handle );
1370 static void test_AssociateColorProfileWithDeviceA(void)
1372 BOOL ret;
1373 char profile[MAX_PATH], basename[MAX_PATH];
1374 DWORD error, size = sizeof(profile);
1375 DISPLAY_DEVICE display;
1376 BOOL res;
1377 DISPLAY_DEVICE monitor;
1379 if (testprofile && pEnumDisplayDevicesA)
1381 display.cb = sizeof( DISPLAY_DEVICE );
1382 res = pEnumDisplayDevicesA( NULL, 0, &display, 0 );
1383 ok( res, "Can't get display info\n" );
1385 monitor.cb = sizeof( DISPLAY_DEVICE );
1386 res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 );
1387 if (res)
1389 SetLastError(0xdeadbeef);
1390 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1391 error = GetLastError();
1392 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1393 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1395 SetLastError(0xdeadbeef);
1396 ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID );
1397 error = GetLastError();
1398 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1399 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1401 SetLastError(0xdeadbeef);
1402 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID );
1403 error = GetLastError();
1404 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1405 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1407 ret = pInstallColorProfileA( NULL, testprofile );
1408 ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1410 ret = pGetColorDirectoryA( NULL, profile, &size );
1411 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1413 MSCMS_basenameA( testprofile, basename );
1414 lstrcatA( profile, "\\" );
1415 lstrcatA( profile, basename );
1417 ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID );
1418 ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1420 SetLastError(0xdeadbeef);
1421 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1422 error = GetLastError();
1423 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1424 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1426 SetLastError(0xdeadbeef);
1427 ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID );
1428 error = GetLastError();
1429 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1430 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1432 SetLastError(0xdeadbeef);
1433 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID );
1434 error = GetLastError();
1435 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1436 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1438 ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID );
1439 ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1441 ret = pUninstallColorProfileA( NULL, profile, TRUE );
1442 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1444 else
1445 skip("Unable to obtain monitor name\n");
1449 START_TEST(profile)
1451 UINT len;
1452 HANDLE handle;
1453 char path[MAX_PATH], file[MAX_PATH];
1454 char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1455 WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1456 BOOL has_space_rgb;
1457 WCHAR fileW[MAX_PATH];
1458 UINT ret;
1460 hmscms = LoadLibraryA( "mscms.dll" );
1461 if (!hmscms) return;
1463 huser32 = LoadLibraryA( "user32.dll" );
1464 if (!huser32)
1466 FreeLibrary( hmscms );
1467 return;
1470 if (!init_function_ptrs())
1472 FreeLibrary( huser32 );
1473 FreeLibrary( hmscms );
1474 return;
1477 /* See if we can find the standard color profile */
1478 ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1479 ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1480 ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH,
1481 "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1482 MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1483 ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH,
1484 "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1485 lstrcpyA(profilefile2, profilefile1);
1486 lstrcpyW(profilefile2W, profilefile1W);
1488 lstrcatA( profilefile1, profile1 );
1489 lstrcatW( profilefile1W, profile1W );
1490 handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1492 if (handle != INVALID_HANDLE_VALUE)
1494 standardprofile = profilefile1;
1495 standardprofileW = profilefile1W;
1496 CloseHandle( handle );
1499 lstrcatA( profilefile2, profile2 );
1500 lstrcatW( profilefile2W, profile2W );
1501 handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1503 if (handle != INVALID_HANDLE_VALUE)
1505 standardprofile = profilefile2;
1506 standardprofileW = profilefile2W;
1507 CloseHandle( handle );
1510 /* If found, create a temporary copy for testing purposes */
1511 if (standardprofile && GetTempPath( sizeof(path), path ))
1513 if (GetTempFileName( path, "rgb", 0, file ))
1515 if (CopyFileA( standardprofile, file, FALSE ))
1517 testprofile = (LPSTR)&file;
1519 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1520 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1522 testprofileW = (LPWSTR)&fileW;
1527 test_GetColorDirectoryA();
1528 test_GetColorDirectoryW();
1530 test_GetColorProfileElement();
1531 test_GetColorProfileElementTag();
1533 test_GetColorProfileFromHandle();
1534 test_GetColorProfileHeader();
1536 test_GetCountColorProfileElements();
1538 enum_registered_color_profiles();
1539 check_registry(&has_space_rgb);
1541 test_GetStandardColorSpaceProfileA(has_space_rgb);
1542 test_GetStandardColorSpaceProfileW(has_space_rgb);
1544 test_EnumColorProfilesA();
1545 test_EnumColorProfilesW();
1547 test_InstallColorProfileA();
1548 test_InstallColorProfileW();
1550 test_IsColorProfileTagPresent();
1552 test_OpenColorProfileA();
1553 test_OpenColorProfileW();
1555 test_SetColorProfileElement();
1556 test_SetColorProfileHeader();
1558 test_UninstallColorProfileA();
1559 test_UninstallColorProfileW();
1561 test_AssociateColorProfileWithDeviceA();
1563 /* Clean up */
1564 if (testprofile)
1565 DeleteFileA( testprofile );
1567 FreeLibrary( huser32 );
1568 FreeLibrary( hmscms );