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