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
init_function_ptrs(void)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
MSCMS_basenameA(LPCSTR path,LPSTR name)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
MSCMS_basenameW(LPCWSTR path,LPWSTR name)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
test_GetColorDirectoryA(void)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
test_GetColorDirectoryW(void)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
test_GetColorProfileElement(char * standardprofile)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
test_GetColorProfileElementTag(char * standardprofile)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
test_GetColorProfileFromHandle(char * testprofile)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
test_GetColorProfileHeader(char * testprofile)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
test_GetCountColorProfileElements(char * standardprofile)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
test_GetStandardColorSpaceProfileA(char * standardprofile)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
test_GetStandardColorSpaceProfileW(WCHAR * standardprofileW)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
test_EnumColorProfilesA(char * standardprofile)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 SetLastError( 0xdeadbeef );
664 ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number );
665 ok( !ret, "EnumColorProfilesA succeeded\n" );
666 if (have_color_profile) ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError() );
667 buffer = HeapAlloc( GetProcessHeap(), 0, total );
668
669 size = total;
670 ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
671 ok( !ret, "EnumColorProfilesA succeeded\n" );
672
673 ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
674 ok( !ret, "EnumColorProfilesA succeeded\n" );
675
676 ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
677 ok( !ret, "EnumColorProfilesA succeeded\n" );
678
679 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
680 todo_wine_if (!have_color_profile)
681 ok( ret, "EnumColorProfilesA failed %u\n", GetLastError() );
682
683 size = 0;
684 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
685 ok( !ret, "EnumColorProfilesA succeeded\n" );
686
687 /* Functional checks */
688
689 size = total;
690 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
691 todo_wine_if (!have_color_profile)
692 ok( ret, "EnumColorProfilesA failed %u\n", GetLastError() );
693
694 HeapFree( GetProcessHeap(), 0, buffer );
695 }
696
test_EnumColorProfilesW(WCHAR * standardprofileW)697 static void test_EnumColorProfilesW( WCHAR *standardprofileW )
698 {
699 BOOL ret;
700 DWORD total, size, number;
701 ENUMTYPEW record;
702 BYTE *buffer;
703
704 /* Parameter checks */
705
706 memset( &record, 0, sizeof(ENUMTYPEW) );
707
708 record.dwSize = sizeof(ENUMTYPEW);
709 record.dwVersion = ENUM_TYPE_VERSION;
710 record.dwFields |= ET_DATACOLORSPACE;
711 record.dwDataColorSpace = SPACE_RGB;
712
713 total = 0;
714 SetLastError( 0xdeadbeef );
715 ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number );
716 ok( !ret, "EnumColorProfilesW succeeded\n" );
717 if (have_color_profile) ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError() );
718 buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
719
720 size = total;
721 ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
722 ok( !ret, "EnumColorProfilesW succeeded\n" );
723
724 ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
725 ok( !ret, "EnumColorProfilesW succeeded\n" );
726
727 ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
728 ok( !ret, "EnumColorProfilesW succeeded\n" );
729
730 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
731 todo_wine_if (!have_color_profile)
732 ok( ret, "EnumColorProfilesW failed %u\n", GetLastError() );
733
734 size = 0;
735 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
736 ok( !ret, "EnumColorProfilesW succeeded\n" );
737
738 /* Functional checks */
739
740 size = total;
741 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
742 todo_wine_if (!have_color_profile)
743 ok( ret, "EnumColorProfilesW failed %u\n", GetLastError() );
744
745 HeapFree( GetProcessHeap(), 0, buffer );
746 }
747
test_InstallColorProfileA(char * standardprofile,char * testprofile)748 static void test_InstallColorProfileA( char *standardprofile, char *testprofile )
749 {
750 BOOL ret;
751
752 /* Parameter checks */
753
754 ret = pInstallColorProfileA( NULL, NULL );
755 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
756
757 ret = pInstallColorProfileA( machine, NULL );
758 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
759
760 ret = pInstallColorProfileA( NULL, machine );
761 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
762
763 if (standardprofile)
764 {
765 ret = pInstallColorProfileA( NULL, standardprofile );
766 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
767 }
768
769 /* Functional checks */
770
771 if (testprofile)
772 {
773 CHAR dest[MAX_PATH], base[MAX_PATH];
774 DWORD size = sizeof(dest);
775 CHAR slash[] = "\\";
776 HANDLE handle;
777
778 SetLastError(0xdeadbeef);
779 ret = pInstallColorProfileA( NULL, testprofile );
780 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
781 {
782 skip("Not enough rights for InstallColorProfileA\n");
783 return;
784 }
785 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
786
787 ret = pGetColorDirectoryA( NULL, dest, &size );
788 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
789
790 MSCMS_basenameA( testprofile, base );
791
792 lstrcatA( dest, slash );
793 lstrcatA( dest, base );
794
795 /* Check if the profile is really there */
796 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
797 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
798 CloseHandle( handle );
799
800 ret = pUninstallColorProfileA( NULL, dest, TRUE );
801 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
802 }
803 }
804
test_InstallColorProfileW(WCHAR * standardprofileW,WCHAR * testprofileW)805 static void test_InstallColorProfileW( WCHAR *standardprofileW, WCHAR *testprofileW )
806 {
807 BOOL ret;
808
809 /* Parameter checks */
810
811 ret = pInstallColorProfileW( NULL, NULL );
812 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
813
814 ret = pInstallColorProfileW( machineW, NULL );
815 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
816
817 ret = pInstallColorProfileW( NULL, machineW );
818 ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
819
820 if (standardprofileW)
821 {
822 ret = pInstallColorProfileW( NULL, standardprofileW );
823 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
824 }
825
826 /* Functional checks */
827
828 if (testprofileW)
829 {
830 WCHAR dest[MAX_PATH], base[MAX_PATH];
831 DWORD size = sizeof(dest);
832 WCHAR slash[] = { '\\', 0 };
833 HANDLE handle;
834
835 SetLastError(0xdeadbeef);
836 ret = pInstallColorProfileW( NULL, testprofileW );
837 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
838 {
839 skip("Not enough rights for InstallColorProfileW\n");
840 return;
841 }
842 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
843
844 ret = pGetColorDirectoryW( NULL, dest, &size );
845 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
846
847 MSCMS_basenameW( testprofileW, base );
848
849 lstrcatW( dest, slash );
850 lstrcatW( dest, base );
851
852 /* Check if the profile is really there */
853 handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
854 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
855 CloseHandle( handle );
856
857 ret = pUninstallColorProfileW( NULL, dest, TRUE );
858 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
859 }
860 }
861
test_IsColorProfileTagPresent(char * standardprofile)862 static void test_IsColorProfileTagPresent( char *standardprofile )
863 {
864 if (standardprofile)
865 {
866 PROFILE profile;
867 HPROFILE handle;
868 BOOL ret, present;
869 TAGTYPE tag;
870
871 profile.dwType = PROFILE_FILENAME;
872 profile.pProfileData = standardprofile;
873 profile.cbDataSize = strlen(standardprofile);
874
875 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
876 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
877
878 /* Parameter checks */
879
880 tag = 0;
881
882 ret = pIsColorProfileTagPresent( handle, tag, &present );
883 ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
884
885 tag = 0x63707274; /* 'cprt' */
886
887 ret = pIsColorProfileTagPresent( NULL, tag, &present );
888 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
889
890 ret = pIsColorProfileTagPresent( handle, tag, NULL );
891 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
892
893 /* Functional checks */
894
895 ret = pIsColorProfileTagPresent( handle, tag, &present );
896 ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() );
897
898 pCloseColorProfile( handle );
899 }
900 }
901
test_OpenColorProfileA(char * standardprofile)902 static void test_OpenColorProfileA( char *standardprofile )
903 {
904 PROFILE profile;
905 HPROFILE handle;
906 BOOL ret;
907
908 profile.dwType = PROFILE_FILENAME;
909 profile.pProfileData = NULL;
910 profile.cbDataSize = 0;
911
912 /* Parameter checks */
913
914 handle = pOpenColorProfileA( NULL, 0, 0, 0 );
915 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
916
917 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
918 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
919
920 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
921 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
922
923 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
924 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
925
926 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
927
928 if (standardprofile)
929 {
930 profile.pProfileData = standardprofile;
931 profile.cbDataSize = strlen(standardprofile);
932
933 handle = pOpenColorProfileA( &profile, 0, 0, 0 );
934 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
935
936 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
937 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
938
939 handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
940 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
941
942 /* Functional checks */
943
944 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
945 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
946
947 ret = pCloseColorProfile( handle );
948 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
949
950 profile.dwType = PROFILE_FILENAME;
951 profile.pProfileData = (void *)"sRGB Color Space Profile.icm";
952 profile.cbDataSize = sizeof("sRGB Color Space Profile.icm");
953
954 handle = pOpenColorProfileA( &profile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING );
955 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
956
957 ret = pCloseColorProfile( handle );
958 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
959 }
960 }
961
test_OpenColorProfileW(WCHAR * standardprofileW)962 static void test_OpenColorProfileW( WCHAR *standardprofileW )
963 {
964 PROFILE profile;
965 HPROFILE handle;
966 BOOL ret;
967
968 profile.dwType = PROFILE_FILENAME;
969 profile.pProfileData = NULL;
970 profile.cbDataSize = 0;
971
972 /* Parameter checks */
973
974 handle = pOpenColorProfileW( NULL, 0, 0, 0 );
975 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
976
977 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
978 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
979
980 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
981 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
982
983 handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
984 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
985
986 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
987
988 if (standardprofileW)
989 {
990 profile.pProfileData = standardprofileW;
991 profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
992
993 handle = pOpenColorProfileW( &profile, 0, 0, 0 );
994 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
995
996 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
997 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
998
999 handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1000 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1001
1002 /* Functional checks */
1003
1004 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1005 ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1006
1007 ret = pCloseColorProfile( handle );
1008 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1009 }
1010 }
1011
test_SetColorProfileElement(char * testprofile)1012 static void test_SetColorProfileElement( char *testprofile )
1013 {
1014 if (testprofile)
1015 {
1016 PROFILE profile;
1017 HPROFILE handle;
1018 DWORD size;
1019 BOOL ret, ref;
1020
1021 TAGTYPE tag = 0x63707274; /* 'cprt' */
1022 static char data[] = "(c) The Wine Project";
1023 static char buffer[51];
1024
1025 profile.dwType = PROFILE_FILENAME;
1026 profile.pProfileData = testprofile;
1027 profile.cbDataSize = strlen(testprofile);
1028
1029 /* Parameter checks */
1030
1031 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1032 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1033
1034 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1035 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1036
1037 pCloseColorProfile( handle );
1038
1039 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1040 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1041
1042 ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1043 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1044
1045 ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1046 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1047
1048 ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1049 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1050
1051 ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1052 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1053
1054 /* Functional checks */
1055
1056 size = sizeof(data);
1057 ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1058 ok( ret, "SetColorProfileElement() failed %u\n", GetLastError() );
1059
1060 size = sizeof(buffer);
1061 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1062 ok( ret, "GetColorProfileElement() failed %u\n", GetLastError() );
1063 ok( size > 0, "wrong size\n" );
1064
1065 ok( !memcmp( data, buffer, sizeof(data) ),
1066 "Unexpected tag data, expected %s, got %s (%u)\n", data, buffer, GetLastError() );
1067
1068 pCloseColorProfile( handle );
1069 }
1070 }
1071
test_SetColorProfileHeader(char * testprofile)1072 static void test_SetColorProfileHeader( char *testprofile )
1073 {
1074 if (testprofile)
1075 {
1076 PROFILE profile;
1077 HPROFILE handle;
1078 BOOL ret;
1079 PROFILEHEADER header;
1080
1081 profile.dwType = PROFILE_FILENAME;
1082 profile.pProfileData = testprofile;
1083 profile.cbDataSize = strlen(testprofile);
1084
1085 header.phSize = 0x00000c48;
1086 header.phCMMType = 0x4c696e6f;
1087 header.phVersion = 0x02100000;
1088 header.phClass = 0x6d6e7472;
1089 header.phDataColorSpace = 0x52474220;
1090 header.phConnectionSpace = 0x58595a20;
1091 header.phDateTime[0] = 0x07ce0002;
1092 header.phDateTime[1] = 0x00090006;
1093 header.phDateTime[2] = 0x00310000;
1094 header.phSignature = 0x61637370;
1095 header.phPlatform = 0x4d534654;
1096 header.phProfileFlags = 0x00000000;
1097 header.phManufacturer = 0x49454320;
1098 header.phModel = 0x73524742;
1099 header.phAttributes[0] = 0x00000000;
1100 header.phAttributes[1] = 0x00000000;
1101 header.phRenderingIntent = 0x00000000;
1102 header.phIlluminant.ciexyzX = 0x0000f6d6;
1103 header.phIlluminant.ciexyzY = 0x00010000;
1104 header.phIlluminant.ciexyzZ = 0x0000d32d;
1105 header.phCreator = 0x48502020;
1106
1107 /* Parameter checks */
1108
1109 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1110 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1111
1112 ret = pSetColorProfileHeader( handle, &header );
1113 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1114
1115 pCloseColorProfile( handle );
1116
1117 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1118 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1119
1120 ret = pSetColorProfileHeader( NULL, NULL );
1121 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1122
1123 ret = pSetColorProfileHeader( handle, NULL );
1124 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1125
1126 ret = pSetColorProfileHeader( NULL, &header );
1127 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1128
1129 /* Functional checks */
1130
1131 ret = pSetColorProfileHeader( handle, &header );
1132 ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1133
1134 ret = pGetColorProfileHeader( handle, &header );
1135 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1136
1137 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1138
1139 pCloseColorProfile( handle );
1140 }
1141 }
1142
test_UninstallColorProfileA(char * testprofile)1143 static void test_UninstallColorProfileA( char *testprofile )
1144 {
1145 BOOL ret;
1146
1147 /* Parameter checks */
1148
1149 ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1150 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1151
1152 ret = pUninstallColorProfileA( machine, NULL, FALSE );
1153 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1154
1155 /* Functional checks */
1156
1157 if (testprofile)
1158 {
1159 CHAR dest[MAX_PATH], base[MAX_PATH];
1160 DWORD size = sizeof(dest);
1161 CHAR slash[] = "\\";
1162 HANDLE handle;
1163
1164 SetLastError(0xdeadbeef);
1165 ret = pInstallColorProfileA( NULL, testprofile );
1166 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1167 {
1168 skip("Not enough rights for InstallColorProfileA\n");
1169 return;
1170 }
1171 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1172
1173 ret = pGetColorDirectoryA( NULL, dest, &size );
1174 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1175
1176 MSCMS_basenameA( testprofile, base );
1177
1178 lstrcatA( dest, slash );
1179 lstrcatA( dest, base );
1180
1181 ret = pUninstallColorProfileA( NULL, dest, TRUE );
1182 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1183
1184 /* Check if the profile is really gone */
1185 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1186 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1187 CloseHandle( handle );
1188 }
1189 }
1190
test_UninstallColorProfileW(WCHAR * testprofileW)1191 static void test_UninstallColorProfileW( WCHAR *testprofileW )
1192 {
1193 BOOL ret;
1194
1195 /* Parameter checks */
1196
1197 ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1198 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1199
1200 ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1201 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1202
1203 /* Functional checks */
1204
1205 if (testprofileW)
1206 {
1207 WCHAR dest[MAX_PATH], base[MAX_PATH];
1208 char destA[MAX_PATH];
1209 DWORD size = sizeof(dest);
1210 WCHAR slash[] = { '\\', 0 };
1211 HANDLE handle;
1212 int bytes_copied;
1213
1214 SetLastError(0xdeadbeef);
1215 ret = pInstallColorProfileW( NULL, testprofileW );
1216 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1217 {
1218 skip("Not enough rights for InstallColorProfileW\n");
1219 return;
1220 }
1221 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1222
1223 ret = pGetColorDirectoryW( NULL, dest, &size );
1224 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1225
1226 MSCMS_basenameW( testprofileW, base );
1227
1228 lstrcatW( dest, slash );
1229 lstrcatW( dest, base );
1230
1231 ret = pUninstallColorProfileW( NULL, dest, TRUE );
1232 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1233
1234 bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1235 ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1236 /* Check if the profile is really gone */
1237 handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1238 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1239 CloseHandle( handle );
1240 }
1241 }
1242
test_AssociateColorProfileWithDeviceA(char * testprofile)1243 static void test_AssociateColorProfileWithDeviceA( char *testprofile )
1244 {
1245 BOOL ret;
1246 char profile[MAX_PATH], basename[MAX_PATH];
1247 DWORD error, size = sizeof(profile);
1248 DISPLAY_DEVICEA display, monitor;
1249 BOOL res;
1250
1251 if (testprofile && pEnumDisplayDevicesA)
1252 {
1253 display.cb = sizeof( DISPLAY_DEVICEA );
1254 res = pEnumDisplayDevicesA( NULL, 0, &display, 0 );
1255 ok( res, "Can't get display info\n" );
1256
1257 monitor.cb = sizeof( DISPLAY_DEVICEA );
1258 res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 );
1259 if (res)
1260 {
1261 SetLastError(0xdeadbeef);
1262 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1263 error = GetLastError();
1264 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1265 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1266
1267 SetLastError(0xdeadbeef);
1268 ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID );
1269 error = GetLastError();
1270 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1271 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1272
1273 SetLastError(0xdeadbeef);
1274 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID );
1275 error = GetLastError();
1276 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1277 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1278
1279 ret = pInstallColorProfileA( NULL, testprofile );
1280 ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1281
1282 ret = pGetColorDirectoryA( NULL, profile, &size );
1283 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1284
1285 MSCMS_basenameA( testprofile, basename );
1286 lstrcatA( profile, "\\" );
1287 lstrcatA( profile, basename );
1288
1289 ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID );
1290 ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1291
1292 SetLastError(0xdeadbeef);
1293 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1294 error = GetLastError();
1295 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1296 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1297
1298 SetLastError(0xdeadbeef);
1299 ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID );
1300 error = GetLastError();
1301 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1302 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1303
1304 SetLastError(0xdeadbeef);
1305 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID );
1306 error = GetLastError();
1307 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1308 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1309
1310 ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID );
1311 ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1312
1313 ret = pUninstallColorProfileA( NULL, profile, TRUE );
1314 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1315 }
1316 else
1317 skip("Unable to obtain monitor name\n");
1318 }
1319 }
1320
have_profile(void)1321 static BOOL have_profile(void)
1322 {
1323 char glob[MAX_PATH + sizeof("\\*.icm")];
1324 DWORD size = MAX_PATH;
1325 HANDLE handle;
1326 WIN32_FIND_DATAA data;
1327
1328 if (!pGetColorDirectoryA( NULL, glob, &size )) return FALSE;
1329 lstrcatA( glob, "\\*.icm" );
1330 handle = FindFirstFileA( glob, &data );
1331 if (handle == INVALID_HANDLE_VALUE) return FALSE;
1332 FindClose( handle );
1333 return TRUE;
1334 }
1335
test_CreateMultiProfileTransform(char * standardprofile,char * testprofile)1336 static void test_CreateMultiProfileTransform( char *standardprofile, char *testprofile )
1337 {
1338 PROFILE profile;
1339 HPROFILE handle[2];
1340 HTRANSFORM transform;
1341 DWORD intents[2] = { INTENT_PERCEPTUAL, INTENT_PERCEPTUAL };
1342
1343 if (testprofile)
1344 {
1345 profile.dwType = PROFILE_FILENAME;
1346 profile.pProfileData = standardprofile;
1347 profile.cbDataSize = strlen(standardprofile);
1348
1349 handle[0] = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1350 ok( handle[0] != NULL, "got %u\n", GetLastError() );
1351
1352 profile.dwType = PROFILE_FILENAME;
1353 profile.pProfileData = testprofile;
1354 profile.cbDataSize = strlen(testprofile);
1355
1356 handle[1] = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1357 ok( handle[1] != NULL, "got %u\n", GetLastError() );
1358
1359 transform = pCreateMultiProfileTransform( handle, 2, intents, 2, 0, 0 );
1360 ok( transform != NULL, "got %u\n", GetLastError() );
1361
1362 pDeleteColorTransform( transform );
1363 pCloseColorProfile( handle[0] );
1364 pCloseColorProfile( handle[1] );
1365 }
1366 }
1367
START_TEST(profile)1368 START_TEST(profile)
1369 {
1370 UINT len;
1371 HANDLE handle;
1372 char path[MAX_PATH], file[MAX_PATH], profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1373 WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH], fileW[MAX_PATH];
1374 char *standardprofile = NULL, *testprofile = NULL;
1375 WCHAR *standardprofileW = NULL, *testprofileW = NULL;
1376 UINT ret;
1377
1378 hmscms = LoadLibraryA( "mscms.dll" );
1379 if (!hmscms) return;
1380
1381 huser32 = LoadLibraryA( "user32.dll" );
1382 if (!huser32)
1383 {
1384 FreeLibrary( hmscms );
1385 return;
1386 }
1387
1388 if (!init_function_ptrs())
1389 {
1390 FreeLibrary( huser32 );
1391 FreeLibrary( hmscms );
1392 return;
1393 }
1394
1395 /* See if we can find the standard color profile */
1396 ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1397 ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1398 ok(profilefile1[0] && lstrlenA(profilefile1) < MAX_PATH,
1399 "Expected length between 0 and MAX_PATH, got %d\n", lstrlenA(profilefile1));
1400 MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1401 ok(profilefile1W[0] && lstrlenW(profilefile1W) < MAX_PATH,
1402 "Expected length between 0 and MAX_PATH, got %d\n", lstrlenW(profilefile1W));
1403 lstrcpyA(profilefile2, profilefile1);
1404 lstrcpyW(profilefile2W, profilefile1W);
1405
1406 lstrcatA( profilefile1, profile1 );
1407 lstrcatW( profilefile1W, profile1W );
1408 handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1409
1410 if (handle != INVALID_HANDLE_VALUE)
1411 {
1412 standardprofile = profilefile1;
1413 standardprofileW = profilefile1W;
1414 CloseHandle( handle );
1415 }
1416
1417 lstrcatA( profilefile2, profile2 );
1418 lstrcatW( profilefile2W, profile2W );
1419 handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1420
1421 if (handle != INVALID_HANDLE_VALUE)
1422 {
1423 standardprofile = profilefile2;
1424 standardprofileW = profilefile2W;
1425 CloseHandle( handle );
1426 }
1427
1428 /* If found, create a temporary copy for testing purposes */
1429 if (standardprofile && GetTempPathA( sizeof(path), path ))
1430 {
1431 if (GetTempFileNameA( path, "rgb", 0, file ))
1432 {
1433 if (CopyFileA( standardprofile, file, FALSE ))
1434 {
1435 testprofile = (LPSTR)&file;
1436 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1437 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1438 testprofileW = (LPWSTR)&fileW;
1439 }
1440 }
1441 }
1442
1443 have_color_profile = have_profile();
1444
1445 test_GetColorDirectoryA();
1446 test_GetColorDirectoryW();
1447
1448 test_GetColorProfileElement( standardprofile );
1449 test_GetColorProfileElementTag( standardprofile );
1450
1451 test_GetColorProfileFromHandle( testprofile );
1452 test_GetColorProfileHeader( testprofile );
1453
1454 test_GetCountColorProfileElements( standardprofile );
1455
1456 test_GetStandardColorSpaceProfileA( standardprofile );
1457 test_GetStandardColorSpaceProfileW( standardprofileW );
1458
1459 test_EnumColorProfilesA( standardprofile );
1460 test_EnumColorProfilesW( standardprofileW );
1461
1462 test_InstallColorProfileA( standardprofile, testprofile );
1463 test_InstallColorProfileW( standardprofileW, testprofileW );
1464
1465 test_IsColorProfileTagPresent( standardprofile );
1466
1467 test_OpenColorProfileA( standardprofile );
1468 test_OpenColorProfileW( standardprofileW );
1469
1470 test_SetColorProfileElement( testprofile );
1471 test_SetColorProfileHeader( testprofile );
1472
1473 test_UninstallColorProfileA( testprofile );
1474 test_UninstallColorProfileW( testprofileW );
1475
1476 test_AssociateColorProfileWithDeviceA( testprofile );
1477 test_CreateMultiProfileTransform( standardprofile, testprofile );
1478
1479 if (testprofile) DeleteFileA( testprofile );
1480 FreeLibrary( huser32 );
1481 FreeLibrary( hmscms );
1482 }
1483