[MSCMS_WINETEST] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / rostests / winetests / mscms / profile.c
1 /*
2 * Tests for color profile functions
3 *
4 * Copyright 2004, 2005, 2006 Hans Leidekker
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <stdarg.h>
22
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"
30
31 #include "wine/test.h"
32
33 static HMODULE hmscms;
34 static HMODULE huser32;
35
36 static BOOL (WINAPI *pAssociateColorProfileWithDeviceA)(PCSTR,PCSTR,PCSTR);
37 static BOOL (WINAPI *pCloseColorProfile)(HPROFILE);
38 static HTRANSFORM (WINAPI *pCreateMultiProfileTransform)(PHPROFILE,DWORD,PDWORD,DWORD,DWORD,DWORD);
39 static BOOL (WINAPI *pDeleteColorTransform)(HTRANSFORM);
40 static BOOL (WINAPI *pDisassociateColorProfileFromDeviceA)(PCSTR,PCSTR,PCSTR);
41 static BOOL (WINAPI *pGetColorDirectoryA)(PCHAR,PCHAR,PDWORD);
42 static BOOL (WINAPI *pGetColorDirectoryW)(PWCHAR,PWCHAR,PDWORD);
43 static BOOL (WINAPI *pGetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL);
44 static BOOL (WINAPI *pGetColorProfileElementTag)(HPROFILE,DWORD,PTAGTYPE);
45 static BOOL (WINAPI *pGetColorProfileFromHandle)(HPROFILE,PBYTE,PDWORD);
46 static BOOL (WINAPI *pGetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
47 static BOOL (WINAPI *pGetCountColorProfileElements)(HPROFILE,PDWORD);
48 static BOOL (WINAPI *pGetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR,PDWORD);
49 static BOOL (WINAPI *pGetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR,PDWORD);
50 static BOOL (WINAPI *pEnumColorProfilesA)(PCSTR,PENUMTYPEA,PBYTE,PDWORD,PDWORD);
51 static BOOL (WINAPI *pEnumColorProfilesW)(PCWSTR,PENUMTYPEW,PBYTE,PDWORD,PDWORD);
52 static BOOL (WINAPI *pInstallColorProfileA)(PCSTR,PCSTR);
53 static BOOL (WINAPI *pInstallColorProfileW)(PCWSTR,PCWSTR);
54 static BOOL (WINAPI *pIsColorProfileTagPresent)(HPROFILE,TAGTYPE,PBOOL);
55 static HPROFILE (WINAPI *pOpenColorProfileA)(PPROFILE,DWORD,DWORD,DWORD);
56 static HPROFILE (WINAPI *pOpenColorProfileW)(PPROFILE,DWORD,DWORD,DWORD);
57 static BOOL (WINAPI *pSetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID);
58 static BOOL (WINAPI *pSetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
59 static BOOL (WINAPI *pSetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR);
60 static BOOL (WINAPI *pSetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR);
61 static BOOL (WINAPI *pUninstallColorProfileA)(PCSTR,PCSTR,BOOL);
62 static BOOL (WINAPI *pUninstallColorProfileW)(PCWSTR,PCWSTR,BOOL);
63
64 static BOOL (WINAPI *pEnumDisplayDevicesA)(LPCSTR,DWORD,PDISPLAY_DEVICEA,DWORD);
65
66 #define GETFUNCPTR(func) p##func = (void *)GetProcAddress( hmscms, #func ); \
67 if (!p##func) return FALSE;
68
69 static BOOL init_function_ptrs( void )
70 {
71 GETFUNCPTR( AssociateColorProfileWithDeviceA )
72 GETFUNCPTR( CloseColorProfile )
73 GETFUNCPTR( CreateMultiProfileTransform )
74 GETFUNCPTR( DeleteColorTransform )
75 GETFUNCPTR( DisassociateColorProfileFromDeviceA )
76 GETFUNCPTR( GetColorDirectoryA )
77 GETFUNCPTR( GetColorDirectoryW )
78 GETFUNCPTR( GetColorProfileElement )
79 GETFUNCPTR( GetColorProfileElementTag )
80 GETFUNCPTR( GetColorProfileFromHandle )
81 GETFUNCPTR( GetColorProfileHeader )
82 GETFUNCPTR( GetCountColorProfileElements )
83 GETFUNCPTR( GetStandardColorSpaceProfileA )
84 GETFUNCPTR( GetStandardColorSpaceProfileW )
85 GETFUNCPTR( EnumColorProfilesA )
86 GETFUNCPTR( EnumColorProfilesW )
87 GETFUNCPTR( InstallColorProfileA )
88 GETFUNCPTR( InstallColorProfileW )
89 GETFUNCPTR( IsColorProfileTagPresent )
90 GETFUNCPTR( OpenColorProfileA )
91 GETFUNCPTR( OpenColorProfileW )
92 GETFUNCPTR( SetColorProfileElement )
93 GETFUNCPTR( SetColorProfileHeader )
94 GETFUNCPTR( SetStandardColorSpaceProfileA )
95 GETFUNCPTR( SetStandardColorSpaceProfileW )
96 GETFUNCPTR( UninstallColorProfileA )
97 GETFUNCPTR( UninstallColorProfileW )
98
99 pEnumDisplayDevicesA = (void *)GetProcAddress( huser32, "EnumDisplayDevicesA" );
100
101 return TRUE;
102 }
103
104 static const char machine[] = "dummy";
105 static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
106
107 /* To do any real functionality testing with this suite you need a copy of
108 * the freely distributable standard RGB color space profile. It comes
109 * standard with Windows, but on Wine you probably need to install it yourself
110 * in one of the locations mentioned below.
111 */
112
113 /* Two common places to find the standard color space profile, relative
114 * to the system directory.
115 */
116 static const char profile1[] =
117 "\\color\\srgb color space profile.icm";
118 static const char profile2[] =
119 "\\spool\\drivers\\color\\srgb color space profile.icm";
120
121 static const WCHAR profile1W[] =
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 };
124 static const WCHAR profile2W[] =
125 { '\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',
126 'c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
127 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
128
129 static BOOL have_color_profile;
130
131 static const unsigned char rgbheader[] =
132 { 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02,
133 0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58,
134 0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00,
135 0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00,
136 0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00,
138 0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 };
139
140 #define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
141
142 static void MSCMS_basenameA( LPCSTR path, LPSTR name )
143 {
144 INT i = strlen( path );
145
146 while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
147 strcpy( name, &path[i] );
148 }
149
150 static void MSCMS_basenameW( LPCWSTR path, LPWSTR name )
151 {
152 INT i = lstrlenW( path );
153
154 while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
155 lstrcpyW( name, &path[i] );
156 }
157
158 static void test_GetColorDirectoryA(void)
159 {
160 BOOL ret;
161 DWORD size;
162 char buffer[MAX_PATH];
163
164 /* Parameter checks */
165
166 ret = pGetColorDirectoryA( NULL, NULL, NULL );
167 ok( !ret, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
168
169 size = 0;
170
171 ret = pGetColorDirectoryA( NULL, NULL, &size );
172 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
173
174 size = 0;
175
176 ret = pGetColorDirectoryA( NULL, buffer, &size );
177 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
178
179 size = 1;
180
181 ret = pGetColorDirectoryA( NULL, buffer, &size );
182 ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
183
184 /* Functional checks */
185
186 size = sizeof(buffer);
187
188 ret = pGetColorDirectoryA( NULL, buffer, &size );
189 ok( ret && size > 0, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
190 }
191
192 static void test_GetColorDirectoryW(void)
193 {
194 BOOL ret;
195 DWORD size;
196 WCHAR buffer[MAX_PATH];
197
198 /* Parameter checks */
199
200 /* This one crashes win2k
201
202 ret = pGetColorDirectoryW( NULL, NULL, NULL );
203 ok( !ret, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
204
205 */
206
207 size = 0;
208
209 ret = pGetColorDirectoryW( NULL, NULL, &size );
210 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
211
212 size = 0;
213
214 ret = pGetColorDirectoryW( NULL, buffer, &size );
215 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
216
217 size = 1;
218
219 ret = pGetColorDirectoryW( NULL, buffer, &size );
220 ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
221
222 /* Functional checks */
223
224 size = sizeof(buffer);
225
226 ret = pGetColorDirectoryW( NULL, buffer, &size );
227 ok( ret && size > 0, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
228 }
229
230 static void test_GetColorProfileElement( char *standardprofile )
231 {
232 if (standardprofile)
233 {
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 };
246
247 profile.dwType = PROFILE_FILENAME;
248 profile.pProfileData = standardprofile;
249 profile.cbDataSize = strlen(standardprofile);
250
251 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
252 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
253
254 /* Parameter checks */
255
256 ret = pGetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
257 ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
258
259 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
260 ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
261
262 size = 0;
263 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
264 ok( !ret, "GetColorProfileElement() succeeded\n" );
265 ok( size > 0, "wrong size\n" );
266
267 /* Functional checks */
268
269 size = sizeof(buffer);
270 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
271 ok( ret, "GetColorProfileElement() failed %u\n", GetLastError() );
272 ok( size > 0, "wrong size\n" );
273 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
274
275 pCloseColorProfile( handle );
276 }
277 }
278
279 static void test_GetColorProfileElementTag( char *standardprofile )
280 {
281 if (standardprofile)
282 {
283 PROFILE profile;
284 HPROFILE handle;
285 BOOL ret;
286 DWORD index = 1;
287 TAGTYPE tag, expect = 0x63707274; /* 'cprt' */
288
289 profile.dwType = PROFILE_FILENAME;
290 profile.pProfileData = standardprofile;
291 profile.cbDataSize = strlen(standardprofile);
292
293 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
294 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
295
296 /* Parameter checks */
297
298 ret = pGetColorProfileElementTag( NULL, index, &tag );
299 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
300
301 ret = pGetColorProfileElementTag( handle, 0, &tag );
302 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
303
304 ret = pGetColorProfileElementTag( handle, index, NULL );
305 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
306
307 ret = pGetColorProfileElementTag( handle, 18, NULL );
308 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
309
310 /* Functional checks */
311
312 ret = pGetColorProfileElementTag( handle, index, &tag );
313 ok( ret && tag == expect, "GetColorProfileElementTag() failed (%d)\n",
314 GetLastError() );
315
316 pCloseColorProfile( handle );
317 }
318 }
319
320 static void test_GetColorProfileFromHandle( char *testprofile )
321 {
322 if (testprofile)
323 {
324 PROFILE profile;
325 HPROFILE handle;
326 DWORD size;
327 BOOL ret;
328 static const unsigned char expect[] =
329 { 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
330 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
331 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
332 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
333 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
334 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
336 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 };
337
338 unsigned char *buffer;
339
340 profile.dwType = PROFILE_FILENAME;
341 profile.pProfileData = testprofile;
342 profile.cbDataSize = strlen(testprofile);
343
344 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
345 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
346
347 /* Parameter checks */
348
349 size = 0;
350
351 ret = pGetColorProfileFromHandle( handle, NULL, &size );
352 ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
353
354 buffer = HeapAlloc( GetProcessHeap(), 0, size );
355
356 if (buffer)
357 {
358 ret = pGetColorProfileFromHandle( NULL, buffer, &size );
359 ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
360
361 ret = pGetColorProfileFromHandle( handle, buffer, NULL );
362 ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
363
364 /* Functional checks */
365
366 ret = pGetColorProfileFromHandle( handle, buffer, &size );
367 ok( ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
368
369 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" );
370
371 HeapFree( GetProcessHeap(), 0, buffer );
372 }
373
374 pCloseColorProfile( handle );
375 }
376 }
377
378 static void test_GetColorProfileHeader( char *testprofile )
379 {
380 if (testprofile)
381 {
382 PROFILE profile;
383 HPROFILE handle;
384 BOOL ret;
385 PROFILEHEADER header;
386
387 profile.dwType = PROFILE_FILENAME;
388 profile.pProfileData = testprofile;
389 profile.cbDataSize = strlen(testprofile);
390
391 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
392 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
393
394 /* Parameter checks */
395
396 ret = pGetColorProfileHeader( NULL, NULL );
397 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
398
399 ret = pGetColorProfileHeader( NULL, &header );
400 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
401
402 if (0) /* Crashes on Vista */
403 {
404 ret = pGetColorProfileHeader( handle, NULL );
405 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
406 }
407
408 /* Functional checks */
409
410 ret = pGetColorProfileHeader( handle, &header );
411 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
412
413 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
414
415 pCloseColorProfile( handle );
416 }
417 }
418
419 static void test_GetCountColorProfileElements( char *standardprofile )
420 {
421 if (standardprofile)
422 {
423 PROFILE profile;
424 HPROFILE handle;
425 BOOL ret;
426 DWORD count, expect = 17;
427
428 profile.dwType = PROFILE_FILENAME;
429 profile.pProfileData = standardprofile;
430 profile.cbDataSize = strlen(standardprofile);
431
432 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
433 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
434
435 /* Parameter checks */
436
437 ret = pGetCountColorProfileElements( NULL, &count );
438 ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
439 GetLastError() );
440
441 ret = pGetCountColorProfileElements( handle, NULL );
442 ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
443 GetLastError() );
444
445 /* Functional checks */
446
447 ret = pGetCountColorProfileElements( handle, &count );
448 ok( ret && count == expect,
449 "GetCountColorProfileElements() failed (%d)\n", GetLastError() );
450
451 pCloseColorProfile( handle );
452 }
453 }
454
455 static void test_GetStandardColorSpaceProfileA( char *standardprofile )
456 {
457 BOOL ret;
458 DWORD size;
459 CHAR oldprofile[MAX_PATH];
460 CHAR newprofile[MAX_PATH];
461
462 /* Parameter checks */
463
464 /* Single invalid parameter checks: */
465
466 size = sizeof(newprofile);
467 SetLastError(0xfaceabee); /* 1st param, */
468 ret = pGetStandardColorSpaceProfileA(machine, LCS_sRGB, newprofile, &size);
469 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
470
471 size = sizeof(newprofile);
472 SetLastError(0xfaceabee); /* 2nd param, */
473 ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &size);
474 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
475
476 size = sizeof(newprofile);
477 SetLastError(0xfaceabee); /* 4th param, */
478 ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, NULL);
479 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
480
481 size = sizeof(newprofile);
482 SetLastError(0xfaceabee); /* 3rd param, */
483 ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, NULL, &size);
484 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
485
486 size = 0;
487 SetLastError(0xfaceabee); /* dereferenced 4th param, */
488 ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, &size);
489 ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER),
490 "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
491
492 /* Several invalid parameter checks: */
493
494 size = 0;
495 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
496 ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &size);
497 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED),
498 "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
499
500 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
501 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
502 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
503
504 size = 0;
505 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
506 ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &size);
507 ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND),
508 "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
509
510 size = sizeof(newprofile);
511 SetLastError(0xfaceabee); /* maybe 2nd param. */
512 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &size);
513 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
514 else ok( !lstrcmpiA( newprofile, "" ) && GetLastError() == 0xfaceabee,
515 "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
516
517 /* Functional checks */
518
519 size = sizeof(oldprofile);
520 ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile, &size );
521 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
522
523 SetLastError(0xdeadbeef);
524 ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, standardprofile );
525 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
526 {
527 skip("Not enough rights for SetStandardColorSpaceProfileA\n");
528 return;
529 }
530 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
531
532 size = sizeof(newprofile);
533 ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, newprofile, &size );
534 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
535
536 ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile );
537 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
538 }
539
540 static void test_GetStandardColorSpaceProfileW( WCHAR *standardprofileW )
541 {
542 BOOL ret;
543 DWORD size;
544 WCHAR oldprofile[MAX_PATH];
545 WCHAR newprofile[MAX_PATH];
546 CHAR newprofileA[MAX_PATH];
547
548 /* Parameter checks */
549
550 /* Single invalid parameter checks: */
551
552 size = sizeof(newprofile);
553 SetLastError(0xfaceabee); /* 1st param, */
554 ret = pGetStandardColorSpaceProfileW(machineW, LCS_sRGB, newprofile, &size);
555 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
556
557 size = sizeof(newprofile);
558 SetLastError(0xfaceabee); /* 2nd param, */
559 ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &size);
560 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
561
562 size = sizeof(newprofile);
563 SetLastError(0xfaceabee); /* 2nd param, */
564 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &size);
565 ok( (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) ||
566 broken(ret), /* Win98 and WinME */
567 "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
568
569 size = sizeof(newprofile);
570 SetLastError(0xfaceabee); /* 3rd param, */
571 ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, NULL, &size);
572 ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" );
573 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
574 broken(GetLastError() == 0xfaceabee) /* win98 */,
575 "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() );
576
577 size = sizeof(newprofile);
578 SetLastError(0xfaceabee); /* 4th param, */
579 ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, NULL);
580 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
581
582 size = 0;
583 SetLastError(0xfaceabee); /* dereferenced 4th param. */
584 ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, &size);
585 ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" );
586 ok( GetLastError() == ERROR_MORE_DATA ||
587 GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
588 broken(GetLastError() == 0xfaceabee) /* win98 */,
589 "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() );
590
591 /* Several invalid parameter checks: */
592
593 size = 0;
594 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
595 ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &size);
596 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED),
597 "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
598
599 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
600 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
601 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
602
603 size = 0;
604 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
605 ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &size);
606 ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" );
607 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
608 GetLastError() == ERROR_FILE_NOT_FOUND ||
609 broken(GetLastError() == 0xfaceabee) /* win98 */,
610 "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() );
611
612 size = sizeof(newprofile);
613 SetLastError(0xfaceabee); /* maybe 2nd param. */
614 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &size);
615 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
616 else
617 {
618 WideCharToMultiByte(CP_ACP, 0, newprofile, -1, newprofileA, sizeof(newprofileA), NULL, NULL);
619 ok( !lstrcmpiA( newprofileA, "" ) && GetLastError() == 0xfaceabee,
620 "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
621 }
622
623 /* Functional checks */
624
625 size = sizeof(oldprofile);
626 ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile, &size );
627 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
628
629 SetLastError(0xdeadbeef);
630 ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, standardprofileW );
631 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
632 {
633 skip("Not enough rights for SetStandardColorSpaceProfileW\n");
634 return;
635 }
636 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
637
638 size = sizeof(newprofile);
639 ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, newprofile, &size );
640 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
641
642 ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile );
643 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
644 }
645
646 static void test_EnumColorProfilesA( char *standardprofile )
647 {
648 BOOL ret;
649 DWORD total, size, number;
650 ENUMTYPEA record;
651 BYTE *buffer;
652
653 /* Parameter checks */
654
655 memset( &record, 0, sizeof(ENUMTYPEA) );
656
657 record.dwSize = sizeof(ENUMTYPEA);
658 record.dwVersion = ENUM_TYPE_VERSION;
659 record.dwFields |= ET_DATACOLORSPACE;
660 record.dwDataColorSpace = SPACE_RGB;
661
662 total = 0;
663 ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number );
664 ok( !ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
665 buffer = HeapAlloc( GetProcessHeap(), 0, total );
666
667 size = total;
668 ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
669 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
670
671 ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
672 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
673
674 ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
675 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
676
677 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
678 if (have_color_profile)
679 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
680 else
681 todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
682
683 size = 0;
684
685 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
686 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
687
688 /* Functional checks */
689
690 size = total;
691 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
692 if (have_color_profile)
693 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
694 else
695 todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
696
697 HeapFree( GetProcessHeap(), 0, buffer );
698 }
699
700 static void test_EnumColorProfilesW( WCHAR *standardprofileW )
701 {
702 BOOL ret;
703 DWORD total, size, number;
704 ENUMTYPEW record;
705 BYTE *buffer;
706
707 /* Parameter checks */
708
709 memset( &record, 0, sizeof(ENUMTYPEW) );
710
711 record.dwSize = sizeof(ENUMTYPEW);
712 record.dwVersion = ENUM_TYPE_VERSION;
713 record.dwFields |= ET_DATACOLORSPACE;
714 record.dwDataColorSpace = SPACE_RGB;
715
716 total = 0;
717 ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number );
718 ok( !ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
719 buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
720
721 size = total;
722 ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
723 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
724
725 ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
726 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
727
728 ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
729 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
730
731 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
732 if (have_color_profile)
733 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
734 else
735 todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
736
737 size = 0;
738 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
739 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
740
741 /* Functional checks */
742
743 size = total;
744 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
745 if (have_color_profile)
746 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
747 else
748 todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
749
750 HeapFree( GetProcessHeap(), 0, buffer );
751 }
752
753 static void test_InstallColorProfileA( char *standardprofile, char *testprofile )
754 {
755 BOOL ret;
756
757 /* Parameter checks */
758
759 ret = pInstallColorProfileA( NULL, NULL );
760 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
761
762 ret = pInstallColorProfileA( machine, NULL );
763 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
764
765 ret = pInstallColorProfileA( NULL, machine );
766 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
767
768 if (standardprofile)
769 {
770 ret = pInstallColorProfileA( NULL, standardprofile );
771 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
772 }
773
774 /* Functional checks */
775
776 if (testprofile)
777 {
778 CHAR dest[MAX_PATH], base[MAX_PATH];
779 DWORD size = sizeof(dest);
780 CHAR slash[] = "\\";
781 HANDLE handle;
782
783 SetLastError(0xdeadbeef);
784 ret = pInstallColorProfileA( NULL, testprofile );
785 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
786 {
787 skip("Not enough rights for InstallColorProfileA\n");
788 return;
789 }
790 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
791
792 ret = pGetColorDirectoryA( NULL, dest, &size );
793 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
794
795 MSCMS_basenameA( testprofile, base );
796
797 lstrcatA( dest, slash );
798 lstrcatA( dest, base );
799
800 /* Check if the profile is really there */
801 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
802 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
803 CloseHandle( handle );
804
805 ret = pUninstallColorProfileA( NULL, dest, TRUE );
806 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
807 }
808 }
809
810 static void test_InstallColorProfileW( WCHAR *standardprofileW, WCHAR *testprofileW )
811 {
812 BOOL ret;
813
814 /* Parameter checks */
815
816 ret = pInstallColorProfileW( NULL, NULL );
817 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
818
819 ret = pInstallColorProfileW( machineW, NULL );
820 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
821
822 ret = pInstallColorProfileW( NULL, machineW );
823 ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
824
825 if (standardprofileW)
826 {
827 ret = pInstallColorProfileW( NULL, standardprofileW );
828 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
829 }
830
831 /* Functional checks */
832
833 if (testprofileW)
834 {
835 WCHAR dest[MAX_PATH], base[MAX_PATH];
836 DWORD size = sizeof(dest);
837 WCHAR slash[] = { '\\', 0 };
838 HANDLE handle;
839
840 SetLastError(0xdeadbeef);
841 ret = pInstallColorProfileW( NULL, testprofileW );
842 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
843 {
844 skip("Not enough rights for InstallColorProfileW\n");
845 return;
846 }
847 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
848
849 ret = pGetColorDirectoryW( NULL, dest, &size );
850 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
851
852 MSCMS_basenameW( testprofileW, base );
853
854 lstrcatW( dest, slash );
855 lstrcatW( dest, base );
856
857 /* Check if the profile is really there */
858 handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
859 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
860 CloseHandle( handle );
861
862 ret = pUninstallColorProfileW( NULL, dest, TRUE );
863 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
864 }
865 }
866
867 static void test_IsColorProfileTagPresent( char *standardprofile )
868 {
869 if (standardprofile)
870 {
871 PROFILE profile;
872 HPROFILE handle;
873 BOOL ret, present;
874 TAGTYPE tag;
875
876 profile.dwType = PROFILE_FILENAME;
877 profile.pProfileData = standardprofile;
878 profile.cbDataSize = strlen(standardprofile);
879
880 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
881 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
882
883 /* Parameter checks */
884
885 tag = 0;
886
887 ret = pIsColorProfileTagPresent( handle, tag, &present );
888 ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
889
890 tag = 0x63707274; /* 'cprt' */
891
892 ret = pIsColorProfileTagPresent( NULL, tag, &present );
893 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
894
895 ret = pIsColorProfileTagPresent( handle, tag, NULL );
896 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
897
898 /* Functional checks */
899
900 ret = pIsColorProfileTagPresent( handle, tag, &present );
901 ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() );
902
903 pCloseColorProfile( handle );
904 }
905 }
906
907 static void test_OpenColorProfileA( char *standardprofile )
908 {
909 PROFILE profile;
910 HPROFILE handle;
911 BOOL ret;
912
913 profile.dwType = PROFILE_FILENAME;
914 profile.pProfileData = NULL;
915 profile.cbDataSize = 0;
916
917 /* Parameter checks */
918
919 handle = pOpenColorProfileA( NULL, 0, 0, 0 );
920 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
921
922 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
923 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
924
925 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
926 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
927
928 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
929 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
930
931 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
932
933 if (standardprofile)
934 {
935 profile.pProfileData = standardprofile;
936 profile.cbDataSize = strlen(standardprofile);
937
938 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
939 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
940
941 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
942 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
943
944 handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
945 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
946
947 /* Functional checks */
948
949 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
950 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
951
952 ret = pCloseColorProfile( handle );
953 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
954
955 profile.dwType = PROFILE_FILENAME;
956 profile.pProfileData = (void *)"sRGB Color Space Profile.icm";
957 profile.cbDataSize = sizeof("sRGB Color Space Profile.icm");
958
959 handle = pOpenColorProfileA( &profile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING );
960 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
961
962 ret = pCloseColorProfile( handle );
963 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
964 }
965 }
966
967 static void test_OpenColorProfileW( WCHAR *standardprofileW )
968 {
969 PROFILE profile;
970 HPROFILE handle;
971 BOOL ret;
972
973 profile.dwType = PROFILE_FILENAME;
974 profile.pProfileData = NULL;
975 profile.cbDataSize = 0;
976
977 /* Parameter checks */
978
979 handle = pOpenColorProfileW( NULL, 0, 0, 0 );
980 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
981
982 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
983 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
984
985 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
986 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
987
988 handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
989 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
990
991 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
992
993 if (standardprofileW)
994 {
995 profile.pProfileData = standardprofileW;
996 profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
997
998 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
999 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1000
1001 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1002 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1003
1004 handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1005 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1006
1007 /* Functional checks */
1008
1009 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1010 ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1011
1012 ret = pCloseColorProfile( handle );
1013 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1014 }
1015 }
1016
1017 static void test_SetColorProfileElement( char *testprofile )
1018 {
1019 if (testprofile)
1020 {
1021 PROFILE profile;
1022 HPROFILE handle;
1023 DWORD size;
1024 BOOL ret, ref;
1025
1026 TAGTYPE tag = 0x63707274; /* 'cprt' */
1027 static char data[] = "(c) The Wine Project";
1028 static char buffer[51];
1029
1030 profile.dwType = PROFILE_FILENAME;
1031 profile.pProfileData = testprofile;
1032 profile.cbDataSize = strlen(testprofile);
1033
1034 /* Parameter checks */
1035
1036 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1037 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1038
1039 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1040 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1041
1042 pCloseColorProfile( handle );
1043
1044 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1045 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1046
1047 ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1048 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1049
1050 ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1051 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1052
1053 ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1054 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1055
1056 ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1057 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1058
1059 /* Functional checks */
1060
1061 size = sizeof(data);
1062 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1063 ok( ret, "SetColorProfileElement() failed %u\n", GetLastError() );
1064
1065 size = sizeof(buffer);
1066 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1067 ok( ret, "GetColorProfileElement() failed %u\n", GetLastError() );
1068 ok( size > 0, "wrong size\n" );
1069
1070 ok( !memcmp( data, buffer, sizeof(data) ),
1071 "Unexpected tag data, expected %s, got %s (%u)\n", data, buffer, GetLastError() );
1072
1073 pCloseColorProfile( handle );
1074 }
1075 }
1076
1077 static void test_SetColorProfileHeader( char *testprofile )
1078 {
1079 if (testprofile)
1080 {
1081 PROFILE profile;
1082 HPROFILE handle;
1083 BOOL ret;
1084 PROFILEHEADER header;
1085
1086 profile.dwType = PROFILE_FILENAME;
1087 profile.pProfileData = testprofile;
1088 profile.cbDataSize = strlen(testprofile);
1089
1090 header.phSize = 0x00000c48;
1091 header.phCMMType = 0x4c696e6f;
1092 header.phVersion = 0x02100000;
1093 header.phClass = 0x6d6e7472;
1094 header.phDataColorSpace = 0x52474220;
1095 header.phConnectionSpace = 0x58595a20;
1096 header.phDateTime[0] = 0x07ce0002;
1097 header.phDateTime[1] = 0x00090006;
1098 header.phDateTime[2] = 0x00310000;
1099 header.phSignature = 0x61637370;
1100 header.phPlatform = 0x4d534654;
1101 header.phProfileFlags = 0x00000000;
1102 header.phManufacturer = 0x49454320;
1103 header.phModel = 0x73524742;
1104 header.phAttributes[0] = 0x00000000;
1105 header.phAttributes[1] = 0x00000000;
1106 header.phRenderingIntent = 0x00000000;
1107 header.phIlluminant.ciexyzX = 0x0000f6d6;
1108 header.phIlluminant.ciexyzY = 0x00010000;
1109 header.phIlluminant.ciexyzZ = 0x0000d32d;
1110 header.phCreator = 0x48502020;
1111
1112 /* Parameter checks */
1113
1114 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1115 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1116
1117 ret = pSetColorProfileHeader( handle, &header );
1118 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1119
1120 pCloseColorProfile( handle );
1121
1122 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1123 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1124
1125 ret = pSetColorProfileHeader( NULL, NULL );
1126 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1127
1128 ret = pSetColorProfileHeader( handle, NULL );
1129 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1130
1131 ret = pSetColorProfileHeader( NULL, &header );
1132 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1133
1134 /* Functional checks */
1135
1136 ret = pSetColorProfileHeader( handle, &header );
1137 ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1138
1139 ret = pGetColorProfileHeader( handle, &header );
1140 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1141
1142 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1143
1144 pCloseColorProfile( handle );
1145 }
1146 }
1147
1148 static void test_UninstallColorProfileA( char *testprofile )
1149 {
1150 BOOL ret;
1151
1152 /* Parameter checks */
1153
1154 ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1155 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1156
1157 ret = pUninstallColorProfileA( machine, NULL, FALSE );
1158 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1159
1160 /* Functional checks */
1161
1162 if (testprofile)
1163 {
1164 CHAR dest[MAX_PATH], base[MAX_PATH];
1165 DWORD size = sizeof(dest);
1166 CHAR slash[] = "\\";
1167 HANDLE handle;
1168
1169 SetLastError(0xdeadbeef);
1170 ret = pInstallColorProfileA( NULL, testprofile );
1171 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1172 {
1173 skip("Not enough rights for InstallColorProfileA\n");
1174 return;
1175 }
1176 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1177
1178 ret = pGetColorDirectoryA( NULL, dest, &size );
1179 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1180
1181 MSCMS_basenameA( testprofile, base );
1182
1183 lstrcatA( dest, slash );
1184 lstrcatA( dest, base );
1185
1186 ret = pUninstallColorProfileA( NULL, dest, TRUE );
1187 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1188
1189 /* Check if the profile is really gone */
1190 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1191 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1192 CloseHandle( handle );
1193 }
1194 }
1195
1196 static void test_UninstallColorProfileW( WCHAR *testprofileW )
1197 {
1198 BOOL ret;
1199
1200 /* Parameter checks */
1201
1202 ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1203 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1204
1205 ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1206 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1207
1208 /* Functional checks */
1209
1210 if (testprofileW)
1211 {
1212 WCHAR dest[MAX_PATH], base[MAX_PATH];
1213 char destA[MAX_PATH];
1214 DWORD size = sizeof(dest);
1215 WCHAR slash[] = { '\\', 0 };
1216 HANDLE handle;
1217 int bytes_copied;
1218
1219 SetLastError(0xdeadbeef);
1220 ret = pInstallColorProfileW( NULL, testprofileW );
1221 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1222 {
1223 skip("Not enough rights for InstallColorProfileW\n");
1224 return;
1225 }
1226 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1227
1228 ret = pGetColorDirectoryW( NULL, dest, &size );
1229 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1230
1231 MSCMS_basenameW( testprofileW, base );
1232
1233 lstrcatW( dest, slash );
1234 lstrcatW( dest, base );
1235
1236 ret = pUninstallColorProfileW( NULL, dest, TRUE );
1237 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1238
1239 bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1240 ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1241 /* Check if the profile is really gone */
1242 handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1243 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1244 CloseHandle( handle );
1245 }
1246 }
1247
1248 static void test_AssociateColorProfileWithDeviceA( char *testprofile )
1249 {
1250 BOOL ret;
1251 char profile[MAX_PATH], basename[MAX_PATH];
1252 DWORD error, size = sizeof(profile);
1253 DISPLAY_DEVICEA display, monitor;
1254 BOOL res;
1255
1256 if (testprofile && pEnumDisplayDevicesA)
1257 {
1258 display.cb = sizeof( DISPLAY_DEVICEA );
1259 res = pEnumDisplayDevicesA( NULL, 0, &display, 0 );
1260 ok( res, "Can't get display info\n" );
1261
1262 monitor.cb = sizeof( DISPLAY_DEVICEA );
1263 res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 );
1264 if (res)
1265 {
1266 SetLastError(0xdeadbeef);
1267 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1268 error = GetLastError();
1269 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1270 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1271
1272 SetLastError(0xdeadbeef);
1273 ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID );
1274 error = GetLastError();
1275 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1276 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1277
1278 SetLastError(0xdeadbeef);
1279 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID );
1280 error = GetLastError();
1281 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1282 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1283
1284 ret = pInstallColorProfileA( NULL, testprofile );
1285 ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1286
1287 ret = pGetColorDirectoryA( NULL, profile, &size );
1288 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1289
1290 MSCMS_basenameA( testprofile, basename );
1291 lstrcatA( profile, "\\" );
1292 lstrcatA( profile, basename );
1293
1294 ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID );
1295 ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1296
1297 SetLastError(0xdeadbeef);
1298 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1299 error = GetLastError();
1300 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1301 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1302
1303 SetLastError(0xdeadbeef);
1304 ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID );
1305 error = GetLastError();
1306 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1307 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1308
1309 SetLastError(0xdeadbeef);
1310 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID );
1311 error = GetLastError();
1312 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1313 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1314
1315 ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID );
1316 ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1317
1318 ret = pUninstallColorProfileA( NULL, profile, TRUE );
1319 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1320 }
1321 else
1322 skip("Unable to obtain monitor name\n");
1323 }
1324 }
1325
1326 static BOOL have_profile(void)
1327 {
1328 char glob[MAX_PATH + sizeof("\\*.icm")];
1329 DWORD size = MAX_PATH;
1330 HANDLE handle;
1331 WIN32_FIND_DATAA data;
1332
1333 if (!pGetColorDirectoryA( NULL, glob, &size )) return FALSE;
1334 lstrcatA( glob, "\\*.icm" );
1335 handle = FindFirstFileA( glob, &data );
1336 if (handle == INVALID_HANDLE_VALUE) return FALSE;
1337 FindClose( handle );
1338 return TRUE;
1339 }
1340
1341 static void test_CreateMultiProfileTransform( char *standardprofile, char *testprofile )
1342 {
1343 PROFILE profile;
1344 HPROFILE handle[2];
1345 HTRANSFORM transform;
1346 DWORD intents[2] = { INTENT_PERCEPTUAL, INTENT_PERCEPTUAL };
1347
1348 if (testprofile)
1349 {
1350 profile.dwType = PROFILE_FILENAME;
1351 profile.pProfileData = standardprofile;
1352 profile.cbDataSize = strlen(standardprofile);
1353
1354 handle[0] = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1355 ok( handle[0] != NULL, "got %u\n", GetLastError() );
1356
1357 profile.dwType = PROFILE_FILENAME;
1358 profile.pProfileData = testprofile;
1359 profile.cbDataSize = strlen(testprofile);
1360
1361 handle[1] = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1362 ok( handle[1] != NULL, "got %u\n", GetLastError() );
1363
1364 transform = pCreateMultiProfileTransform( handle, 2, intents, 2, 0, 0 );
1365 ok( transform != NULL, "got %u\n", GetLastError() );
1366
1367 pDeleteColorTransform( transform );
1368 pCloseColorProfile( handle[0] );
1369 pCloseColorProfile( handle[1] );
1370 }
1371 }
1372
1373 START_TEST(profile)
1374 {
1375 UINT len;
1376 HANDLE handle;
1377 char path[MAX_PATH], file[MAX_PATH], profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1378 WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH], fileW[MAX_PATH];
1379 char *standardprofile = NULL, *testprofile = NULL;
1380 WCHAR *standardprofileW = NULL, *testprofileW = NULL;
1381 UINT ret;
1382
1383 hmscms = LoadLibraryA( "mscms.dll" );
1384 if (!hmscms) return;
1385
1386 huser32 = LoadLibraryA( "user32.dll" );
1387 if (!huser32)
1388 {
1389 FreeLibrary( hmscms );
1390 return;
1391 }
1392
1393 if (!init_function_ptrs())
1394 {
1395 FreeLibrary( huser32 );
1396 FreeLibrary( hmscms );
1397 return;
1398 }
1399
1400 /* See if we can find the standard color profile */
1401 ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1402 ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1403 ok(profilefile1[0] && lstrlenA(profilefile1) < MAX_PATH,
1404 "Expected length between 0 and MAX_PATH, got %d\n", lstrlenA(profilefile1));
1405 MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1406 ok(profilefile1W[0] && lstrlenW(profilefile1W) < MAX_PATH,
1407 "Expected length between 0 and MAX_PATH, got %d\n", lstrlenW(profilefile1W));
1408 lstrcpyA(profilefile2, profilefile1);
1409 lstrcpyW(profilefile2W, profilefile1W);
1410
1411 lstrcatA( profilefile1, profile1 );
1412 lstrcatW( profilefile1W, profile1W );
1413 handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1414
1415 if (handle != INVALID_HANDLE_VALUE)
1416 {
1417 standardprofile = profilefile1;
1418 standardprofileW = profilefile1W;
1419 CloseHandle( handle );
1420 }
1421
1422 lstrcatA( profilefile2, profile2 );
1423 lstrcatW( profilefile2W, profile2W );
1424 handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1425
1426 if (handle != INVALID_HANDLE_VALUE)
1427 {
1428 standardprofile = profilefile2;
1429 standardprofileW = profilefile2W;
1430 CloseHandle( handle );
1431 }
1432
1433 /* If found, create a temporary copy for testing purposes */
1434 if (standardprofile && GetTempPathA( sizeof(path), path ))
1435 {
1436 if (GetTempFileNameA( path, "rgb", 0, file ))
1437 {
1438 if (CopyFileA( standardprofile, file, FALSE ))
1439 {
1440 testprofile = (LPSTR)&file;
1441 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1442 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1443 testprofileW = (LPWSTR)&fileW;
1444 }
1445 }
1446 }
1447
1448 have_color_profile = have_profile();
1449
1450 test_GetColorDirectoryA();
1451 test_GetColorDirectoryW();
1452
1453 test_GetColorProfileElement( standardprofile );
1454 test_GetColorProfileElementTag( standardprofile );
1455
1456 test_GetColorProfileFromHandle( testprofile );
1457 test_GetColorProfileHeader( testprofile );
1458
1459 test_GetCountColorProfileElements( standardprofile );
1460
1461 test_GetStandardColorSpaceProfileA( standardprofile );
1462 test_GetStandardColorSpaceProfileW( standardprofileW );
1463
1464 test_EnumColorProfilesA( standardprofile );
1465 test_EnumColorProfilesW( standardprofileW );
1466
1467 test_InstallColorProfileA( standardprofile, testprofile );
1468 test_InstallColorProfileW( standardprofileW, testprofileW );
1469
1470 test_IsColorProfileTagPresent( standardprofile );
1471
1472 test_OpenColorProfileA( standardprofile );
1473 test_OpenColorProfileW( standardprofileW );
1474
1475 test_SetColorProfileElement( testprofile );
1476 test_SetColorProfileHeader( testprofile );
1477
1478 test_UninstallColorProfileA( testprofile );
1479 test_UninstallColorProfileW( testprofileW );
1480
1481 test_AssociateColorProfileWithDeviceA( testprofile );
1482 test_CreateMultiProfileTransform( standardprofile, testprofile );
1483
1484 if (testprofile) DeleteFileA( testprofile );
1485 FreeLibrary( huser32 );
1486 FreeLibrary( hmscms );
1487 }