winex11.drv: Print clipboard formats in hex.
[wine/multimedia.git] / dlls / mscms / tests / profile.c
blob100c15c4f1f764592c89890384d78068aa09e94b
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 || dwType == REG_DWORD, "RegEnumValueA() returned unexpected value type (%d)\n", dwType );
586 if (dwType == REG_SZ)
587 trace(" found string value '%s' containing '%s' (%d chars)\n", szName, szData, lstrlenA(szData));
588 else if (dwType == REG_DWORD)
589 trace(" found DWORD value '%s' containing '%x'\n", szName, *(DWORD *)szData);
590 else
591 break;
594 RegCloseKey( hkIcmKey );
597 static void test_GetStandardColorSpaceProfileA(BOOL has_space_rgb)
599 BOOL ret;
600 DWORD size;
601 CHAR oldprofile[MAX_PATH];
602 CHAR newprofile[MAX_PATH];
603 const CHAR emptyA[] = "";
604 DWORD zero = 0;
605 DWORD sizeP = sizeof(newprofile);
607 /* Parameter checks */
609 /* Single invalid parameter checks: */
611 SetLastError(0xfaceabee); /* 1st param, */
612 ret = pGetStandardColorSpaceProfileA(machine, SPACE_RGB, newprofile, &sizeP);
613 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
615 SetLastError(0xfaceabee); /* 2nd param, */
616 ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &sizeP);
617 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
619 SetLastError(0xfaceabee); /* 4th param, */
620 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, NULL);
621 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
623 if (query_colorspace(SPACE_RGB))
625 SetLastError(0xfaceabee); /* 3rd param, */
626 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
627 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
629 SetLastError(0xfaceabee); /* dereferenced 4th param, */
630 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &zero);
631 ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
632 } else {
633 SetLastError(0xfaceabee); /* 3rd param, */
634 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
635 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
637 SetLastError(0xfaceabee); /* dereferenced 4th param. */
638 ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &sizeP);
639 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
642 /* Several invalid parameter checks: */
644 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
645 ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &zero);
646 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
648 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
649 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
650 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
652 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
653 ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &zero);
654 ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
656 SetLastError(0xfaceabee); /* maybe 2nd param. */
657 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &sizeP);
658 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
659 else ok( !lstrcmpiA( newprofile, emptyA ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
661 /* Functional checks */
663 if (has_space_rgb)
665 size = sizeof(oldprofile);
667 ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
668 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
670 SetLastError(0xdeadbeef);
671 ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
672 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
674 skip("Not enough rights for SetStandardColorSpaceProfileA\n");
675 return;
677 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
679 size = sizeof(newprofile);
681 ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
682 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
684 ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
686 ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
687 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
691 static void test_GetStandardColorSpaceProfileW(BOOL has_space_rgb)
693 BOOL ret;
694 DWORD size;
695 WCHAR oldprofile[MAX_PATH];
696 WCHAR newprofile[MAX_PATH];
697 const WCHAR emptyW[] = {0};
698 DWORD zero = 0;
699 DWORD sizeP = sizeof(newprofile);
701 /* Parameter checks */
703 /* Single invalid parameter checks: */
705 SetLastError(0xfaceabee); /* 1st param, */
706 ret = pGetStandardColorSpaceProfileW(machineW, SPACE_RGB, newprofile, &sizeP);
707 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
709 SetLastError(0xfaceabee); /* 2nd param, */
710 ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &sizeP);
711 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
713 SetLastError(0xfaceabee); /* 3rd param, */
714 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, NULL, &sizeP);
715 if (has_space_rgb)
716 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
717 else
718 todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
720 SetLastError(0xfaceabee); /* 4th param, */
721 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, NULL);
722 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
724 SetLastError(0xfaceabee); /* dereferenced 4th param. */
725 ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, &zero);
726 if (has_space_rgb)
727 ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
728 else
729 todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
732 /* Several invalid parameter checks: */
734 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
735 ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &zero);
736 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
738 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
739 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
740 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
742 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
743 ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &zero);
744 ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
746 SetLastError(0xfaceabee); /* maybe 2nd param. */
747 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
748 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
749 else ok( !lstrcmpiW( newprofile, emptyW ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
751 /* Functional checks */
753 if (has_space_rgb)
755 size = sizeof(oldprofile);
757 ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
758 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
760 SetLastError(0xdeadbeef);
761 ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
762 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
764 skip("Not enough rights for SetStandardColorSpaceProfileW\n");
765 return;
767 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
769 size = sizeof(newprofile);
771 ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
772 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
774 ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
776 ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
777 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
781 static void test_EnumColorProfilesA(void)
783 BOOL ret;
784 DWORD total, size, number;
785 ENUMTYPEA record;
786 BYTE *buffer;
788 /* Parameter checks */
790 memset( &record, 0, sizeof(ENUMTYPEA) );
792 record.dwSize = sizeof(ENUMTYPEA);
793 record.dwVersion = ENUM_TYPE_VERSION;
794 record.dwFields |= ET_DATACOLORSPACE;
795 record.dwDataColorSpace = SPACE_RGB;
797 total = 0;
798 ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number );
799 ok( !ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
800 buffer = HeapAlloc( GetProcessHeap(), 0, total );
802 size = total;
803 ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
804 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
806 ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
807 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
809 ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
810 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
812 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
813 if (standardprofile)
814 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
815 else
816 todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
818 size = 0;
820 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
821 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
823 /* Functional checks */
825 size = total;
826 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
827 if (standardprofile)
828 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
829 else
830 todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
832 HeapFree( GetProcessHeap(), 0, buffer );
835 static void test_EnumColorProfilesW(void)
837 BOOL ret;
838 DWORD total, size, number;
839 ENUMTYPEW record;
840 BYTE *buffer;
842 /* Parameter checks */
844 memset( &record, 0, sizeof(ENUMTYPEW) );
846 record.dwSize = sizeof(ENUMTYPEW);
847 record.dwVersion = ENUM_TYPE_VERSION;
848 record.dwFields |= ET_DATACOLORSPACE;
849 record.dwDataColorSpace = SPACE_RGB;
851 total = 0;
852 ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number );
853 ok( !ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
854 buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
856 size = total;
857 ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
858 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
860 ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
861 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
863 ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
864 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
866 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
867 if (standardprofileW)
868 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
869 else
870 todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
872 size = 0;
873 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
874 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
876 /* Functional checks */
878 size = total;
879 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
880 if (standardprofileW)
881 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
882 else
883 todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
885 HeapFree( GetProcessHeap(), 0, buffer );
888 static void test_InstallColorProfileA(void)
890 BOOL ret;
892 /* Parameter checks */
894 ret = pInstallColorProfileA( NULL, NULL );
895 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
897 ret = pInstallColorProfileA( machine, NULL );
898 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
900 ret = pInstallColorProfileA( NULL, machine );
901 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
903 if (standardprofile)
905 ret = pInstallColorProfileA( NULL, standardprofile );
906 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
909 /* Functional checks */
911 if (testprofile)
913 CHAR dest[MAX_PATH], base[MAX_PATH];
914 DWORD size = sizeof(dest);
915 CHAR slash[] = "\\";
916 HANDLE handle;
918 SetLastError(0xdeadbeef);
919 ret = pInstallColorProfileA( NULL, testprofile );
920 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
922 skip("Not enough rights for InstallColorProfileA\n");
923 return;
925 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
927 ret = pGetColorDirectoryA( NULL, dest, &size );
928 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
930 MSCMS_basenameA( testprofile, base );
932 lstrcatA( dest, slash );
933 lstrcatA( dest, base );
935 /* Check if the profile is really there */
936 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
937 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
938 CloseHandle( handle );
940 ret = pUninstallColorProfileA( NULL, dest, TRUE );
941 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
945 static void test_InstallColorProfileW(void)
947 BOOL ret;
949 /* Parameter checks */
951 ret = pInstallColorProfileW( NULL, NULL );
952 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
954 ret = pInstallColorProfileW( machineW, NULL );
955 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
957 ret = pInstallColorProfileW( NULL, machineW );
958 ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
960 if (standardprofileW)
962 ret = pInstallColorProfileW( NULL, standardprofileW );
963 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
966 /* Functional checks */
968 if (testprofileW)
970 WCHAR dest[MAX_PATH], base[MAX_PATH];
971 DWORD size = sizeof(dest);
972 WCHAR slash[] = { '\\', 0 };
973 HANDLE handle;
975 SetLastError(0xdeadbeef);
976 ret = pInstallColorProfileW( NULL, testprofileW );
977 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
979 skip("Not enough rights for InstallColorProfileW\n");
980 return;
982 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
984 ret = pGetColorDirectoryW( NULL, dest, &size );
985 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
987 MSCMS_basenameW( testprofileW, base );
989 lstrcatW( dest, slash );
990 lstrcatW( dest, base );
992 /* Check if the profile is really there */
993 handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
994 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
995 CloseHandle( handle );
997 ret = pUninstallColorProfileW( NULL, dest, TRUE );
998 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1002 static void test_IsColorProfileTagPresent(void)
1004 if (standardprofile)
1006 PROFILE profile;
1007 HPROFILE handle;
1008 BOOL ret, present;
1009 TAGTYPE tag;
1011 profile.dwType = PROFILE_FILENAME;
1012 profile.pProfileData = standardprofile;
1013 profile.cbDataSize = strlen(standardprofile);
1015 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1016 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1018 /* Parameter checks */
1020 tag = 0;
1022 ret = pIsColorProfileTagPresent( handle, tag, &present );
1023 ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1025 tag = 0x63707274; /* 'cprt' */
1027 ret = pIsColorProfileTagPresent( NULL, tag, &present );
1028 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1030 ret = pIsColorProfileTagPresent( handle, tag, NULL );
1031 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1033 /* Functional checks */
1035 ret = pIsColorProfileTagPresent( handle, tag, &present );
1036 ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() );
1038 pCloseColorProfile( handle );
1042 static void test_OpenColorProfileA(void)
1044 PROFILE profile;
1045 HPROFILE handle;
1046 BOOL ret;
1048 profile.dwType = PROFILE_FILENAME;
1049 profile.pProfileData = NULL;
1050 profile.cbDataSize = 0;
1052 /* Parameter checks */
1054 handle = pOpenColorProfileA( NULL, 0, 0, 0 );
1055 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1057 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1058 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1060 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1061 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1063 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
1064 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1066 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1068 if (standardprofile)
1070 profile.pProfileData = standardprofile;
1071 profile.cbDataSize = strlen(standardprofile);
1073 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1074 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1076 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1077 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1079 handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1080 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1082 /* Functional checks */
1084 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1085 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1087 ret = pCloseColorProfile( handle );
1088 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1092 static void test_OpenColorProfileW(void)
1094 PROFILE profile;
1095 HPROFILE handle;
1096 BOOL ret;
1098 profile.dwType = PROFILE_FILENAME;
1099 profile.pProfileData = NULL;
1100 profile.cbDataSize = 0;
1102 /* Parameter checks */
1104 handle = pOpenColorProfileW( NULL, 0, 0, 0 );
1105 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1107 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1108 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1110 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1111 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1113 handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
1114 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1116 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1118 if (standardprofileW)
1120 profile.pProfileData = standardprofileW;
1121 profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
1123 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1124 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1126 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1127 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1129 handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1130 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1132 /* Functional checks */
1134 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1135 ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1137 ret = pCloseColorProfile( handle );
1138 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1142 static void test_SetColorProfileElement(void)
1144 if (testprofile)
1146 PROFILE profile;
1147 HPROFILE handle;
1148 DWORD size;
1149 BOOL ret, ref;
1151 TAGTYPE tag = 0x63707274; /* 'cprt' */
1152 static char data[] = "(c) The Wine Project";
1153 static char buffer[51];
1155 profile.dwType = PROFILE_FILENAME;
1156 profile.pProfileData = testprofile;
1157 profile.cbDataSize = strlen(testprofile);
1159 /* Parameter checks */
1161 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1162 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1164 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1165 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1167 pCloseColorProfile( handle );
1169 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1170 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1172 ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1173 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1175 ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1176 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1178 ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1179 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1181 ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1182 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1184 /* Functional checks */
1186 size = sizeof(data);
1188 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1189 ok( ret, "SetColorProfileElement() failed (%d)\n", GetLastError() );
1191 size = sizeof(buffer);
1193 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1194 ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
1196 ok( !memcmp( data, buffer, sizeof(data) ),
1197 "Unexpected tag data, expected %s, got %s (%d)\n",
1198 data, buffer, GetLastError() );
1200 pCloseColorProfile( handle );
1204 static void test_SetColorProfileHeader(void)
1206 if (testprofile)
1208 PROFILE profile;
1209 HPROFILE handle;
1210 BOOL ret;
1211 PROFILEHEADER header;
1213 profile.dwType = PROFILE_FILENAME;
1214 profile.pProfileData = testprofile;
1215 profile.cbDataSize = strlen(testprofile);
1217 header.phSize = 0x00000c48;
1218 header.phCMMType = 0x4c696e6f;
1219 header.phVersion = 0x02100000;
1220 header.phClass = 0x6d6e7472;
1221 header.phDataColorSpace = 0x52474220;
1222 header.phConnectionSpace = 0x58595a20;
1223 header.phDateTime[0] = 0x07ce0002;
1224 header.phDateTime[1] = 0x00090006;
1225 header.phDateTime[2] = 0x00310000;
1226 header.phSignature = 0x61637370;
1227 header.phPlatform = 0x4d534654;
1228 header.phProfileFlags = 0x00000000;
1229 header.phManufacturer = 0x49454320;
1230 header.phModel = 0x73524742;
1231 header.phAttributes[0] = 0x00000000;
1232 header.phAttributes[1] = 0x00000000;
1233 header.phRenderingIntent = 0x00000000;
1234 header.phIlluminant.ciexyzX = 0x0000f6d6;
1235 header.phIlluminant.ciexyzY = 0x00010000;
1236 header.phIlluminant.ciexyzZ = 0x0000d32d;
1237 header.phCreator = 0x48502020;
1239 /* Parameter checks */
1241 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1242 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1244 ret = pSetColorProfileHeader( handle, &header );
1245 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1247 pCloseColorProfile( handle );
1249 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1250 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1252 ret = pSetColorProfileHeader( NULL, NULL );
1253 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1255 ret = pSetColorProfileHeader( handle, NULL );
1256 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1258 ret = pSetColorProfileHeader( NULL, &header );
1259 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1261 /* Functional checks */
1263 ret = pSetColorProfileHeader( handle, &header );
1264 ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1266 ret = pGetColorProfileHeader( handle, &header );
1267 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1269 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1271 pCloseColorProfile( handle );
1275 static void test_UninstallColorProfileA(void)
1277 BOOL ret;
1279 /* Parameter checks */
1281 ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1282 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1284 ret = pUninstallColorProfileA( machine, NULL, FALSE );
1285 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1287 /* Functional checks */
1289 if (testprofile)
1291 CHAR dest[MAX_PATH], base[MAX_PATH];
1292 DWORD size = sizeof(dest);
1293 CHAR slash[] = "\\";
1294 HANDLE handle;
1296 SetLastError(0xdeadbeef);
1297 ret = pInstallColorProfileA( NULL, testprofile );
1298 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1300 skip("Not enough rights for InstallColorProfileA\n");
1301 return;
1303 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1305 ret = pGetColorDirectoryA( NULL, dest, &size );
1306 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1308 MSCMS_basenameA( testprofile, base );
1310 lstrcatA( dest, slash );
1311 lstrcatA( dest, base );
1313 ret = pUninstallColorProfileA( NULL, dest, TRUE );
1314 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1316 /* Check if the profile is really gone */
1317 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1318 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1319 CloseHandle( handle );
1323 static void test_UninstallColorProfileW(void)
1325 BOOL ret;
1327 /* Parameter checks */
1329 ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1330 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1332 ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1333 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1335 /* Functional checks */
1337 if (testprofileW)
1339 WCHAR dest[MAX_PATH], base[MAX_PATH];
1340 char destA[MAX_PATH];
1341 DWORD size = sizeof(dest);
1342 WCHAR slash[] = { '\\', 0 };
1343 HANDLE handle;
1344 int bytes_copied;
1346 SetLastError(0xdeadbeef);
1347 ret = pInstallColorProfileW( NULL, testprofileW );
1348 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1350 skip("Not enough rights for InstallColorProfileW\n");
1351 return;
1353 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1355 ret = pGetColorDirectoryW( NULL, dest, &size );
1356 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1358 MSCMS_basenameW( testprofileW, base );
1360 lstrcatW( dest, slash );
1361 lstrcatW( dest, base );
1363 ret = pUninstallColorProfileW( NULL, dest, TRUE );
1364 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1366 bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1367 ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1368 /* Check if the profile is really gone */
1369 handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1370 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1371 CloseHandle( handle );
1375 static void test_AssociateColorProfileWithDeviceA(void)
1377 BOOL ret;
1378 char profile[MAX_PATH], basename[MAX_PATH];
1379 DWORD error, size = sizeof(profile);
1380 DISPLAY_DEVICE display;
1381 BOOL res;
1382 DISPLAY_DEVICE monitor;
1384 if (testprofile && pEnumDisplayDevicesA)
1386 display.cb = sizeof( DISPLAY_DEVICE );
1387 res = pEnumDisplayDevicesA( NULL, 0, &display, 0 );
1388 ok( res, "Can't get display info\n" );
1390 monitor.cb = sizeof( DISPLAY_DEVICE );
1391 res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 );
1392 if (res)
1394 SetLastError(0xdeadbeef);
1395 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1396 error = GetLastError();
1397 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1398 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1400 SetLastError(0xdeadbeef);
1401 ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID );
1402 error = GetLastError();
1403 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1404 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1406 SetLastError(0xdeadbeef);
1407 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID );
1408 error = GetLastError();
1409 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1410 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1412 ret = pInstallColorProfileA( NULL, testprofile );
1413 ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1415 ret = pGetColorDirectoryA( NULL, profile, &size );
1416 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1418 MSCMS_basenameA( testprofile, basename );
1419 lstrcatA( profile, "\\" );
1420 lstrcatA( profile, basename );
1422 ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID );
1423 ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1425 SetLastError(0xdeadbeef);
1426 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1427 error = GetLastError();
1428 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1429 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1431 SetLastError(0xdeadbeef);
1432 ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID );
1433 error = GetLastError();
1434 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1435 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1437 SetLastError(0xdeadbeef);
1438 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID );
1439 error = GetLastError();
1440 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1441 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1443 ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID );
1444 ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1446 ret = pUninstallColorProfileA( NULL, profile, TRUE );
1447 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1449 else
1450 skip("Unable to obtain monitor name\n");
1454 START_TEST(profile)
1456 UINT len;
1457 HANDLE handle;
1458 char path[MAX_PATH], file[MAX_PATH];
1459 char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1460 WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1461 BOOL has_space_rgb;
1462 WCHAR fileW[MAX_PATH];
1463 UINT ret;
1465 hmscms = LoadLibraryA( "mscms.dll" );
1466 if (!hmscms) return;
1468 huser32 = LoadLibraryA( "user32.dll" );
1469 if (!huser32)
1471 FreeLibrary( hmscms );
1472 return;
1475 if (!init_function_ptrs())
1477 FreeLibrary( huser32 );
1478 FreeLibrary( hmscms );
1479 return;
1482 /* See if we can find the standard color profile */
1483 ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1484 ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1485 ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH,
1486 "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1487 MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1488 ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH,
1489 "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1490 lstrcpyA(profilefile2, profilefile1);
1491 lstrcpyW(profilefile2W, profilefile1W);
1493 lstrcatA( profilefile1, profile1 );
1494 lstrcatW( profilefile1W, profile1W );
1495 handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1497 if (handle != INVALID_HANDLE_VALUE)
1499 standardprofile = profilefile1;
1500 standardprofileW = profilefile1W;
1501 CloseHandle( handle );
1504 lstrcatA( profilefile2, profile2 );
1505 lstrcatW( profilefile2W, profile2W );
1506 handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1508 if (handle != INVALID_HANDLE_VALUE)
1510 standardprofile = profilefile2;
1511 standardprofileW = profilefile2W;
1512 CloseHandle( handle );
1515 /* If found, create a temporary copy for testing purposes */
1516 if (standardprofile && GetTempPath( sizeof(path), path ))
1518 if (GetTempFileName( path, "rgb", 0, file ))
1520 if (CopyFileA( standardprofile, file, FALSE ))
1522 testprofile = (LPSTR)&file;
1524 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1525 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1527 testprofileW = (LPWSTR)&fileW;
1532 test_GetColorDirectoryA();
1533 test_GetColorDirectoryW();
1535 test_GetColorProfileElement();
1536 test_GetColorProfileElementTag();
1538 test_GetColorProfileFromHandle();
1539 test_GetColorProfileHeader();
1541 test_GetCountColorProfileElements();
1543 enum_registered_color_profiles();
1544 check_registry(&has_space_rgb);
1546 test_GetStandardColorSpaceProfileA(has_space_rgb);
1547 test_GetStandardColorSpaceProfileW(has_space_rgb);
1549 test_EnumColorProfilesA();
1550 test_EnumColorProfilesW();
1552 test_InstallColorProfileA();
1553 test_InstallColorProfileW();
1555 test_IsColorProfileTagPresent();
1557 test_OpenColorProfileA();
1558 test_OpenColorProfileW();
1560 test_SetColorProfileElement();
1561 test_SetColorProfileHeader();
1563 test_UninstallColorProfileA();
1564 test_UninstallColorProfileW();
1566 test_AssociateColorProfileWithDeviceA();
1568 /* Clean up */
1569 if (testprofile)
1570 DeleteFileA( testprofile );
1572 FreeLibrary( huser32 );
1573 FreeLibrary( hmscms );