2 * Tests for color profile functions
4 * Copyright 2004, 2005 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "wine/test.h"
34 static BOOL (WINAPI *pCloseColorProfile)(HPROFILE);
35 static BOOL (WINAPI *pGetColorDirectoryA)(PCHAR,PCHAR,PDWORD);
36 static BOOL (WINAPI *pGetColorDirectoryW)(PWCHAR,PWCHAR,PDWORD);
37 static BOOL (WINAPI *pGetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL);
38 static BOOL (WINAPI *pGetColorProfileElementTag)(HPROFILE,DWORD,PTAGTYPE);
39 static BOOL (WINAPI *pGetColorProfileFromHandle)(HPROFILE,PBYTE,PDWORD);
40 static BOOL (WINAPI *pGetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
41 static BOOL (WINAPI *pGetCountColorProfileElements)(HPROFILE,PDWORD);
42 static BOOL (WINAPI *pGetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR,PDWORD);
43 static BOOL (WINAPI *pGetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR,PDWORD);
44 static BOOL (WINAPI *pInstallColorProfileA)(PCSTR,PCSTR);
45 static BOOL (WINAPI *pInstallColorProfileW)(PCWSTR,PCWSTR);
46 static BOOL (WINAPI *pIsColorProfileTagPresent)(HPROFILE,TAGTYPE,PBOOL);
47 static HPROFILE (WINAPI *pOpenColorProfileA)(PPROFILE,DWORD,DWORD,DWORD);
48 static HPROFILE (WINAPI *pOpenColorProfileW)(PPROFILE,DWORD,DWORD,DWORD);
49 static BOOL (WINAPI *pSetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID);
50 static BOOL (WINAPI *pSetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
51 static BOOL (WINAPI *pSetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR);
52 static BOOL (WINAPI *pSetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR);
53 static BOOL (WINAPI *pUninstallColorProfileA)(PCSTR,PCSTR,BOOL);
54 static BOOL (WINAPI *pUninstallColorProfileW)(PCWSTR,PCWSTR,BOOL);
56 #define GETFUNCPTR(func) p##func = (void *)GetProcAddress( hmscms, #func ); \
57 if (!p##func) return FALSE;
59 static BOOL init_function_ptrs( void )
61 GETFUNCPTR( CloseColorProfile )
62 GETFUNCPTR( GetColorDirectoryA )
63 GETFUNCPTR( GetColorDirectoryW )
64 GETFUNCPTR( GetColorProfileElement )
65 GETFUNCPTR( GetColorProfileElementTag )
66 GETFUNCPTR( GetColorProfileFromHandle )
67 GETFUNCPTR( GetColorProfileHeader )
68 GETFUNCPTR( GetCountColorProfileElements )
69 GETFUNCPTR( GetStandardColorSpaceProfileA )
70 GETFUNCPTR( GetStandardColorSpaceProfileW )
71 GETFUNCPTR( InstallColorProfileA )
72 GETFUNCPTR( InstallColorProfileW )
73 GETFUNCPTR( IsColorProfileTagPresent )
74 GETFUNCPTR( OpenColorProfileA )
75 GETFUNCPTR( OpenColorProfileW )
76 GETFUNCPTR( SetColorProfileElement )
77 GETFUNCPTR( SetColorProfileHeader )
78 GETFUNCPTR( SetStandardColorSpaceProfileA )
79 GETFUNCPTR( SetStandardColorSpaceProfileW )
80 GETFUNCPTR( UninstallColorProfileA )
81 GETFUNCPTR( UninstallColorProfileW )
86 static const char machine[] = "dummy";
87 static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
89 /* To do any real functionality testing with this suite you need a copy of
90 * the freely distributable standard RGB color space profile. It comes
91 * standard with Windows, but on Wine you probably need to install it yourself
92 * in one of the locations mentioned below. Here's a link to the profile in
93 * a self extracting zip file:
95 * http://download.microsoft.com/download/whistler/hwdev1/1.0/wxp/en-us/ColorProfile.exe
98 /* Two common places to find the standard color space profile, relative
99 * to the system directory.
101 static const char profile1[] =
102 "\\color\\srgb color space profile.icm";
103 static const char profile2[] =
104 "\\spool\\drivers\\color\\srgb color space profile.icm";
106 static const WCHAR profile1W[] =
107 { '\\','c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
108 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
109 static const WCHAR profile2W[] =
110 { '\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',
111 'c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
112 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
114 static const unsigned char rgbheader[] =
115 { 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02,
116 0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58,
117 0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00,
118 0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00,
119 0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00,
121 0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 };
123 static LPSTR standardprofile;
124 static LPWSTR standardprofileW;
126 static LPSTR testprofile;
127 static LPWSTR testprofileW;
129 #define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
131 static void MSCMS_basenameA( LPCSTR path, LPSTR name )
133 INT i = strlen( path );
135 while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
136 strcpy( name, &path[i] );
139 static void MSCMS_basenameW( LPCWSTR path, LPWSTR name )
141 INT i = lstrlenW( path );
143 while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
144 lstrcpyW( name, &path[i] );
147 static void test_GetColorDirectoryA(void)
151 char buffer[MAX_PATH];
153 /* Parameter checks */
155 ret = pGetColorDirectoryA( NULL, NULL, NULL );
156 ok( !ret, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
160 ret = pGetColorDirectoryA( NULL, NULL, &size );
161 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
165 ret = pGetColorDirectoryA( NULL, buffer, &size );
166 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
170 ret = pGetColorDirectoryA( NULL, buffer, &size );
171 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
173 /* Functional checks */
175 size = sizeof(buffer);
177 ret = pGetColorDirectoryA( NULL, buffer, &size );
178 ok( ret && size > 0, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
181 static void test_GetColorDirectoryW(void)
185 WCHAR buffer[MAX_PATH];
187 /* Parameter checks */
189 /* This one crashes win2k
191 ret = pGetColorDirectoryW( NULL, NULL, NULL );
192 ok( !ret, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
198 ret = pGetColorDirectoryW( NULL, NULL, &size );
199 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
203 ret = pGetColorDirectoryW( NULL, buffer, &size );
204 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
208 ret = pGetColorDirectoryW( NULL, buffer, &size );
209 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
211 /* Functional checks */
213 size = sizeof(buffer);
215 ret = pGetColorDirectoryW( NULL, buffer, &size );
216 ok( ret && size > 0, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
219 static void test_GetColorProfileElement(void)
227 TAGTYPE tag = 0x63707274; /* 'cprt' */
228 static char buffer[51];
229 static const char expect[] =
230 { 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70,
231 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
232 0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74,
233 0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43,
234 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x00 };
236 profile.dwType = PROFILE_FILENAME;
237 profile.pProfileData = standardprofile;
238 profile.cbDataSize = strlen(standardprofile);
240 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
241 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
243 /* Parameter checks */
245 ret = pGetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
246 ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
248 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
249 ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
253 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
254 ok( !ret && size > 0, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
256 size = sizeof(buffer);
258 /* Functional checks */
260 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
261 ok( ret && size > 0, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
263 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
265 pCloseColorProfile( handle );
269 static void test_GetColorProfileElementTag(void)
277 TAGTYPE tag, expect = 0x63707274; /* 'cprt' */
279 profile.dwType = PROFILE_FILENAME;
280 profile.pProfileData = standardprofile;
281 profile.cbDataSize = strlen(standardprofile);
283 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
284 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
286 /* Parameter checks */
288 ret = pGetColorProfileElementTag( NULL, index, &tag );
289 ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
291 ret = pGetColorProfileElementTag( handle, 0, &tag );
292 ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
294 ret = pGetColorProfileElementTag( handle, index, NULL );
295 ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
297 ret = pGetColorProfileElementTag( handle, 18, NULL );
298 ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
300 /* Functional checks */
302 ret = pGetColorProfileElementTag( handle, index, &tag );
303 ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld)\n",
306 pCloseColorProfile( handle );
310 static void test_GetColorProfileFromHandle(void)
318 static const unsigned char expect[] =
319 { 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
320 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
321 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
322 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
323 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
324 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
326 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 };
328 unsigned char *buffer;
330 profile.dwType = PROFILE_FILENAME;
331 profile.pProfileData = testprofile;
332 profile.cbDataSize = strlen(testprofile);
334 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
335 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
337 /* Parameter checks */
341 ret = pGetColorProfileFromHandle( handle, NULL, &size );
342 ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%ld)\n", GetLastError() );
344 buffer = HeapAlloc( GetProcessHeap(), 0, size );
348 ret = pGetColorProfileFromHandle( NULL, buffer, &size );
349 ok( !ret, "GetColorProfileFromHandle() succeeded (%ld)\n", GetLastError() );
351 ret = pGetColorProfileFromHandle( handle, buffer, NULL );
352 ok( !ret, "GetColorProfileFromHandle() succeeded (%ld)\n", GetLastError() );
354 /* Functional checks */
356 ret = pGetColorProfileFromHandle( handle, buffer, &size );
357 ok( ret && size > 0, "GetColorProfileFromHandle() failed (%ld)\n", GetLastError() );
359 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" );
361 HeapFree( GetProcessHeap(), 0, buffer );
364 pCloseColorProfile( handle );
368 static void test_GetColorProfileHeader(void)
375 PROFILEHEADER header;
377 profile.dwType = PROFILE_FILENAME;
378 profile.pProfileData = testprofile;
379 profile.cbDataSize = strlen(testprofile);
381 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
382 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
384 /* Parameter checks */
386 ret = pGetColorProfileHeader( NULL, NULL );
387 ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
389 ret = pGetColorProfileHeader( NULL, &header );
390 ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
392 ret = pGetColorProfileHeader( handle, NULL );
393 ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
395 /* Functional checks */
397 ret = pGetColorProfileHeader( handle, &header );
398 ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
400 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
402 pCloseColorProfile( handle );
406 static void test_GetCountColorProfileElements(void)
413 DWORD count, expect = 17;
415 profile.dwType = PROFILE_FILENAME;
416 profile.pProfileData = standardprofile;
417 profile.cbDataSize = strlen(standardprofile);
419 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
420 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
422 /* Parameter checks */
424 ret = pGetCountColorProfileElements( NULL, &count );
425 ok( !ret, "GetCountColorProfileElements() succeeded (%ld)\n",
428 ret = pGetCountColorProfileElements( handle, NULL );
429 ok( !ret, "GetCountColorProfileElements() succeeded (%ld)\n",
432 /* Functional checks */
434 ret = pGetCountColorProfileElements( handle, &count );
435 ok( ret && count == expect,
436 "GetCountColorProfileElements() failed (%ld)\n", GetLastError() );
438 pCloseColorProfile( handle );
442 typedef struct colorspace_description_struct {
447 #define describe_colorspace(id) {id, #id}
449 colorspace_descr known_colorspaces[] = {
450 describe_colorspace(SPACE_XYZ),
451 describe_colorspace(SPACE_Lab),
452 describe_colorspace(SPACE_Luv),
453 describe_colorspace(SPACE_YCbCr),
454 describe_colorspace(SPACE_Yxy),
455 describe_colorspace(SPACE_RGB),
456 describe_colorspace(SPACE_GRAY),
457 describe_colorspace(SPACE_HSV),
458 describe_colorspace(SPACE_HLS),
459 describe_colorspace(SPACE_CMYK),
460 describe_colorspace(SPACE_CMY),
461 describe_colorspace(SPACE_2_CHANNEL),
462 describe_colorspace(SPACE_3_CHANNEL),
463 describe_colorspace(SPACE_4_CHANNEL),
464 describe_colorspace(SPACE_5_CHANNEL),
465 describe_colorspace(SPACE_6_CHANNEL),
466 describe_colorspace(SPACE_7_CHANNEL),
467 describe_colorspace(SPACE_8_CHANNEL)
470 static void enum_registered_color_profiles(void)
473 DWORD size, count, i, present;
474 CHAR profile[MAX_PATH];
476 size = sizeof(profile);
477 count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
481 trace("Searching for registered standard colorspace profiles:\n");
482 for (i=0; i<count; i++)
484 ret = pGetStandardColorSpaceProfileA(NULL, known_colorspaces[i].dwID, profile, &size);
488 trace(" found %s, pointing to '%s' (%d chars)\n", known_colorspaces[i].szName, profile, strlen(profile));
491 trace("Total profiles found: %ld.\n", present);
495 #define fail_GSCSPA(pMachName, dwProfID, pProfName, pdwSz, dwSz, GLE_OK) \
498 SetLastError(0xfaceabad); \
499 ret = pGetStandardColorSpaceProfileA(pMachName, dwProfID, pProfName, pdwSz);\
500 GLE = GetLastError(); \
501 ok( !ret && GLE_OK, \
502 "GetStandardColorSpaceProfileA() returns %d (GLE=%ld)\n", ret, GLE ); \
505 #define test_GSCSPA(pMachName, dwProfID, pProfName, pdwSz, dwSz, GLE_OK) \
509 ret = pGetStandardColorSpaceProfileA(pMachName, dwProfID, pProfName, pdwSz);\
510 GLE = GetLastError(); \
511 ok( (!ret && GLE_OK) || (ret && !lstrcmpiA( pProfName, "" )), \
512 "GetStandardColorSpaceProfileA() returns %d (GLE=%ld)\n", ret, GLE ); \
515 static void test_GetStandardColorSpaceProfileA(void)
518 DWORD size, sizeP, GLE;
519 CHAR oldprofile[MAX_PATH];
520 CHAR newprofile[MAX_PATH];
522 sizeP = sizeof(newprofile);
524 /* Parameter checks */
526 /* Single invalid parameter checks */
528 fail_GSCSPA(machine, SPACE_RGB, newprofile, &size, sizeP, (GLE == ERROR_NOT_SUPPORTED));
530 fail_GSCSPA(NULL, (DWORD)-1, newprofile, &size, sizeP, (GLE == ERROR_FILE_NOT_FOUND));
532 fail_GSCSPA(NULL, SPACE_RGB, NULL, &size, sizeP, (GLE == ERROR_INSUFFICIENT_BUFFER));
534 fail_GSCSPA(NULL, SPACE_RGB, newprofile, NULL, sizeP, (GLE == ERROR_INVALID_PARAMETER));
536 fail_GSCSPA(NULL, SPACE_RGB, newprofile, &size, 0, (GLE == ERROR_MORE_DATA || GLE == ERROR_INSUFFICIENT_BUFFER));
538 /* Several invalid parameter checks */
540 fail_GSCSPA(machine, 0, newprofile, &size, 0, (GLE == ERROR_INVALID_PARAMETER || GLE == ERROR_NOT_SUPPORTED));
542 fail_GSCSPA(NULL, 0, newprofile, NULL, 0, (GLE == ERROR_INVALID_PARAMETER));
544 fail_GSCSPA(NULL, 0, NULL, &size, 0, (GLE == ERROR_INSUFFICIENT_BUFFER || GLE == ERROR_FILE_NOT_FOUND));
546 test_GSCSPA(NULL, 0, newprofile, &size, sizeP, (GLE == ERROR_FILE_NOT_FOUND));
548 /* Functional checks */
552 size = sizeof(oldprofile);
554 ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
555 ok( ret, "GetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
557 ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
558 ok( ret, "SetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
560 size = sizeof(newprofile);
562 ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
563 ok( ret, "GetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
565 ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
567 ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
568 ok( ret, "SetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
572 #define fail_GSCSPW(pMachName, dwProfID, pProfName, pdwSz, dwSz, GLE_OK) \
575 SetLastError(0xfaceabad); \
576 ret = pGetStandardColorSpaceProfileW(pMachName, dwProfID, pProfName, pdwSz);\
577 GLE = GetLastError(); \
578 ok( !ret && GLE_OK, \
579 "GetStandardColorSpaceProfileW() returns %d (GLE=%ld)\n", ret, GLE ); \
582 #define test_GSCSPW(pMachName, dwProfID, pProfName, pdwSz, dwSz, GLE_OK) \
586 ret = pGetStandardColorSpaceProfileW(pMachName, dwProfID, pProfName, pdwSz);\
587 GLE = GetLastError(); \
588 ok( (!ret && GLE_OK) || (ret && !lstrcmpiW( pProfName, emptyW )), \
589 "GetStandardColorSpaceProfileA() returns %d (GLE=%ld)\n", ret, GLE ); \
592 static void test_GetStandardColorSpaceProfileW(void)
595 DWORD size, sizeP, GLE;
596 WCHAR oldprofile[MAX_PATH];
597 WCHAR newprofile[MAX_PATH];
598 WCHAR emptyW[] = {0};
600 sizeP = sizeof(newprofile);
602 /* Parameter checks */
604 /* Single invalid parameter checks */
606 fail_GSCSPW(machineW, SPACE_RGB, newprofile, &size, sizeP, (GLE == ERROR_NOT_SUPPORTED));
608 fail_GSCSPW(NULL, (DWORD)-1, newprofile, &size, sizeP, (GLE == ERROR_FILE_NOT_FOUND));
610 fail_GSCSPW(NULL, SPACE_RGB, NULL, &size, sizeP, (GLE == ERROR_INSUFFICIENT_BUFFER));
612 fail_GSCSPW(NULL, SPACE_RGB, newprofile, NULL, sizeP, (GLE == ERROR_INVALID_PARAMETER));
614 fail_GSCSPW(NULL, SPACE_RGB, newprofile, &size, 0, (GLE == ERROR_MORE_DATA || GLE == ERROR_INSUFFICIENT_BUFFER));
616 /* Several invalid parameter checks */
618 fail_GSCSPW(machineW, 0, newprofile, &size, 0, (GLE == ERROR_INVALID_PARAMETER || GLE == ERROR_NOT_SUPPORTED));
620 fail_GSCSPW(NULL, 0, newprofile, NULL, 0, (GLE == ERROR_INVALID_PARAMETER));
622 fail_GSCSPW(NULL, 0, NULL, &size, 0, (GLE == ERROR_INSUFFICIENT_BUFFER || GLE == ERROR_FILE_NOT_FOUND));
624 test_GSCSPW(NULL, 0, newprofile, &size, sizeP, (GLE == ERROR_FILE_NOT_FOUND));
626 /* Functional checks */
628 if (standardprofileW)
630 size = sizeof(oldprofile);
632 ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
633 ok( ret, "GetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
635 ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
636 ok( ret, "SetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
638 size = sizeof(newprofile);
640 ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
641 ok( ret, "GetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
643 ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
645 ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
646 ok( ret, "SetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
650 static void test_InstallColorProfileA(void)
654 /* Parameter checks */
656 ret = pInstallColorProfileA( NULL, NULL );
657 ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
659 ret = pInstallColorProfileA( machine, NULL );
660 ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
662 ret = pInstallColorProfileA( NULL, machine );
663 ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
667 ret = pInstallColorProfileA( NULL, standardprofile );
668 ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
671 /* Functional checks */
675 CHAR dest[MAX_PATH], base[MAX_PATH];
676 DWORD size = sizeof(dest);
680 ret = pInstallColorProfileA( NULL, testprofile );
681 ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
683 ret = pGetColorDirectoryA( NULL, dest, &size );
684 ok( ret, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
686 MSCMS_basenameA( testprofile, base );
688 lstrcatA( dest, slash );
689 lstrcatA( dest, base );
691 /* Check if the profile is really there */
692 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
693 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%ld)\n", GetLastError() );
694 CloseHandle( handle );
696 ret = pUninstallColorProfileA( NULL, dest, TRUE );
697 ok( ret, "UninstallColorProfileA() failed (%ld)\n", GetLastError() );
701 static void test_InstallColorProfileW(void)
705 /* Parameter checks */
707 ret = pInstallColorProfileW( NULL, NULL );
708 ok( !ret, "InstallColorProfileW() succeeded (%ld)\n", GetLastError() );
710 ret = pInstallColorProfileW( machineW, NULL );
711 ok( !ret, "InstallColorProfileW() succeeded (%ld)\n", GetLastError() );
713 ret = pInstallColorProfileW( NULL, machineW );
714 ok( !ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
716 if (standardprofileW)
718 ret = pInstallColorProfileW( NULL, standardprofileW );
719 ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
722 /* Functional checks */
726 WCHAR dest[MAX_PATH], base[MAX_PATH];
727 DWORD size = sizeof(dest);
728 WCHAR slash[] = { '\\', 0 };
731 ret = pInstallColorProfileW( NULL, testprofileW );
732 ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
734 ret = pGetColorDirectoryW( NULL, dest, &size );
735 ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
737 MSCMS_basenameW( testprofileW, base );
739 lstrcatW( dest, slash );
740 lstrcatW( dest, base );
742 /* Check if the profile is really there */
743 handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
744 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%ld)\n", GetLastError() );
745 CloseHandle( handle );
747 ret = pUninstallColorProfileW( NULL, dest, TRUE );
748 ok( ret, "UninstallColorProfileW() failed (%ld)\n", GetLastError() );
752 static void test_IsColorProfileTagPresent(void)
761 profile.dwType = PROFILE_FILENAME;
762 profile.pProfileData = standardprofile;
763 profile.cbDataSize = strlen(standardprofile);
765 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
766 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
768 /* Parameter checks */
772 ret = pIsColorProfileTagPresent( handle, tag, &present );
773 ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
775 tag = 0x63707274; /* 'cprt' */
777 ret = pIsColorProfileTagPresent( NULL, tag, &present );
778 ok( !ret, "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
780 ret = pIsColorProfileTagPresent( handle, tag, NULL );
781 ok( !ret, "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
783 /* Functional checks */
785 ret = pIsColorProfileTagPresent( handle, tag, &present );
786 ok( ret && present, "IsColorProfileTagPresent() failed (%ld)\n", GetLastError() );
788 pCloseColorProfile( handle );
792 static void test_OpenColorProfileA(void)
798 profile.dwType = PROFILE_FILENAME;
799 profile.pProfileData = NULL;
800 profile.cbDataSize = 0;
802 /* Parameter checks */
804 handle = pOpenColorProfileA( NULL, 0, 0, 0 );
805 ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
807 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
808 ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
810 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
811 ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
813 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
814 ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
816 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
820 profile.pProfileData = standardprofile;
821 profile.cbDataSize = strlen(standardprofile);
823 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
824 ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
826 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
827 ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
829 handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
830 ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
832 /* Functional checks */
834 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
835 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
837 ret = pCloseColorProfile( handle );
838 ok( ret, "CloseColorProfile() failed (%ld)\n", GetLastError() );
842 static void test_OpenColorProfileW(void)
848 profile.dwType = PROFILE_FILENAME;
849 profile.pProfileData = NULL;
850 profile.cbDataSize = 0;
852 /* Parameter checks */
854 handle = pOpenColorProfileW( NULL, 0, 0, 0 );
855 ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
857 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
858 ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
860 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
861 ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
863 handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
864 ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
866 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
868 if (standardprofileW)
870 profile.pProfileData = standardprofileW;
871 profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
873 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
874 ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
876 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
877 ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
879 handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
880 ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
882 /* Functional checks */
884 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
885 ok( handle != NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
887 ret = pCloseColorProfile( handle );
888 ok( ret, "CloseColorProfile() failed (%ld)\n", GetLastError() );
892 static void test_SetColorProfileElement(void)
901 TAGTYPE tag = 0x63707274; /* 'cprt' */
902 static char data[] = "(c) The Wine Project";
903 static char buffer[51];
905 profile.dwType = PROFILE_FILENAME;
906 profile.pProfileData = testprofile;
907 profile.cbDataSize = strlen(testprofile);
909 /* Parameter checks */
911 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
912 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
914 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
915 ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
917 pCloseColorProfile( handle );
919 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
920 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
922 ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
923 ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
925 ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
926 ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
928 ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
929 ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
931 ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
932 ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
934 /* Functional checks */
938 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
939 ok( ret, "SetColorProfileElement() failed (%ld)\n", GetLastError() );
941 size = sizeof(buffer);
943 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
944 ok( ret && size > 0, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
946 ok( !memcmp( data, buffer, sizeof(data) ),
947 "Unexpected tag data, expected %s, got %s (%ld)\n",
948 data, buffer, GetLastError() );
950 pCloseColorProfile( handle );
954 static void test_SetColorProfileHeader(void)
961 PROFILEHEADER header;
963 profile.dwType = PROFILE_FILENAME;
964 profile.pProfileData = testprofile;
965 profile.cbDataSize = strlen(testprofile);
967 header.phSize = 0x00000c48;
968 header.phCMMType = 0x4c696e6f;
969 header.phVersion = 0x02100000;
970 header.phClass = 0x6d6e7472;
971 header.phDataColorSpace = 0x52474220;
972 header.phConnectionSpace = 0x58595a20;
973 header.phDateTime[0] = 0x07ce0002;
974 header.phDateTime[1] = 0x00090006;
975 header.phDateTime[2] = 0x00310000;
976 header.phSignature = 0x61637370;
977 header.phPlatform = 0x4d534654;
978 header.phProfileFlags = 0x00000000;
979 header.phManufacturer = 0x49454320;
980 header.phModel = 0x73524742;
981 header.phAttributes[0] = 0x00000000;
982 header.phAttributes[1] = 0x00000000;
983 header.phRenderingIntent = 0x00000000;
984 header.phIlluminant.ciexyzX = 0x0000f6d6;
985 header.phIlluminant.ciexyzY = 0x00010000;
986 header.phIlluminant.ciexyzZ = 0x0000d32d;
987 header.phCreator = 0x48502020;
989 /* Parameter checks */
991 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
992 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
994 ret = pSetColorProfileHeader( handle, &header );
995 ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
997 pCloseColorProfile( handle );
999 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1000 ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
1002 ret = pSetColorProfileHeader( NULL, NULL );
1003 ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
1005 ret = pSetColorProfileHeader( handle, NULL );
1006 ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
1008 ret = pSetColorProfileHeader( NULL, &header );
1009 ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
1011 /* Functional checks */
1013 ret = pSetColorProfileHeader( handle, &header );
1014 ok( ret, "SetColorProfileHeader() failed (%ld)\n", GetLastError() );
1016 ret = pGetColorProfileHeader( handle, &header );
1017 ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
1019 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1021 pCloseColorProfile( handle );
1025 static void test_UninstallColorProfileA(void)
1029 /* Parameter checks */
1031 ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1032 ok( !ret, "UninstallColorProfileA() succeeded (%ld)\n", GetLastError() );
1034 ret = pUninstallColorProfileA( machine, NULL, FALSE );
1035 ok( !ret, "UninstallColorProfileA() succeeded (%ld)\n", GetLastError() );
1037 /* Functional checks */
1041 CHAR dest[MAX_PATH], base[MAX_PATH];
1042 DWORD size = sizeof(dest);
1043 CHAR slash[] = "\\";
1046 ret = pInstallColorProfileA( NULL, testprofile );
1047 ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
1049 ret = pGetColorDirectoryA( NULL, dest, &size );
1050 ok( ret, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
1052 MSCMS_basenameA( testprofile, base );
1054 lstrcatA( dest, slash );
1055 lstrcatA( dest, base );
1057 ret = pUninstallColorProfileA( NULL, dest, TRUE );
1058 ok( ret, "UninstallColorProfileA() failed (%ld)\n", GetLastError() );
1060 /* Check if the profile is really gone */
1061 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1062 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%ld)\n", GetLastError() );
1063 CloseHandle( handle );
1067 static void test_UninstallColorProfileW(void)
1071 /* Parameter checks */
1073 ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1074 ok( !ret, "UninstallColorProfileW() succeeded (%ld)\n", GetLastError() );
1076 ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1077 ok( !ret, "UninstallColorProfileW() succeeded (%ld)\n", GetLastError() );
1079 /* Functional checks */
1083 WCHAR dest[MAX_PATH], base[MAX_PATH];
1084 char destA[MAX_PATH];
1085 DWORD size = sizeof(dest);
1086 WCHAR slash[] = { '\\', 0 };
1090 ret = pInstallColorProfileW( NULL, testprofileW );
1091 ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
1093 ret = pGetColorDirectoryW( NULL, dest, &size );
1094 ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
1096 MSCMS_basenameW( testprofileW, base );
1098 lstrcatW( dest, slash );
1099 lstrcatW( dest, base );
1101 ret = pUninstallColorProfileW( NULL, dest, TRUE );
1102 ok( ret, "UninstallColorProfileW() failed (%ld)\n", GetLastError() );
1104 bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1105 ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1106 /* Check if the profile is really gone */
1107 handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1108 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%ld)\n", GetLastError() );
1109 CloseHandle( handle );
1117 char path[MAX_PATH], file[MAX_PATH];
1118 char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1119 WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1120 WCHAR fileW[MAX_PATH];
1123 hmscms = LoadLibraryA( "mscms.dll" );
1124 if (!hmscms) return;
1126 if (!init_function_ptrs())
1128 FreeLibrary( hmscms );
1132 /* See if we can find the standard color profile */
1133 ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1134 ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %ld\n", ret, GetLastError());
1135 ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH,
1136 "GetSystemDirectoryA() returns %d, LastError = %ld\n", ret, GetLastError());
1137 MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1138 ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH,
1139 "GetSystemDirectoryA() returns %d, LastError = %ld\n", ret, GetLastError());
1140 lstrcpyA(profilefile2, profilefile1);
1141 lstrcpyW(profilefile2W, profilefile1W);
1143 lstrcatA( profilefile1, profile1 );
1144 lstrcatW( profilefile1W, profile1W );
1145 handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1147 if (handle != INVALID_HANDLE_VALUE)
1149 standardprofile = profilefile1;
1150 standardprofileW = profilefile1W;
1151 CloseHandle( handle );
1154 lstrcatA( profilefile2, profile2 );
1155 lstrcatW( profilefile2W, profile2W );
1156 handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1158 if (handle != INVALID_HANDLE_VALUE)
1160 standardprofile = profilefile2;
1161 standardprofileW = profilefile2W;
1162 CloseHandle( handle );
1165 /* If found, create a temporary copy for testing purposes */
1166 if (standardprofile && GetTempPath( sizeof(path), path ))
1168 if (GetTempFileName( path, "rgb", 0, file ))
1170 if (CopyFileA( standardprofile, file, FALSE ))
1172 testprofile = (LPSTR)&file;
1174 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1175 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1177 testprofileW = (LPWSTR)&fileW;
1182 test_GetColorDirectoryA();
1183 test_GetColorDirectoryW();
1185 test_GetColorProfileElement();
1186 test_GetColorProfileElementTag();
1188 test_GetColorProfileFromHandle();
1189 test_GetColorProfileHeader();
1191 test_GetCountColorProfileElements();
1193 enum_registered_color_profiles();
1195 test_GetStandardColorSpaceProfileA();
1196 test_GetStandardColorSpaceProfileW();
1198 test_InstallColorProfileA();
1199 test_InstallColorProfileW();
1201 test_IsColorProfileTagPresent();
1203 test_OpenColorProfileA();
1204 test_OpenColorProfileW();
1206 test_SetColorProfileElement();
1207 test_SetColorProfileHeader();
1209 test_UninstallColorProfileA();
1210 test_UninstallColorProfileW();
1214 DeleteFileA( testprofile );
1216 FreeLibrary( hmscms );