Release 1.4.1.
[wine] / dlls / mscms / tests / 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_DEVICE,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 const unsigned char rgbheader[] =
126 { 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02,
127   0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58,
128   0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00,
129   0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00,
130   0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00,
131   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00,
132   0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 };
133
134 #define IS_SEPARATOR(ch)  ((ch) == '\\' || (ch) == '/')
135
136 static void MSCMS_basenameA( LPCSTR path, LPSTR name )
137 {
138     INT i = strlen( path );
139
140     while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
141     strcpy( name, &path[i] );
142 }
143
144 static void MSCMS_basenameW( LPCWSTR path, LPWSTR name )
145 {
146     INT i = lstrlenW( path );
147
148     while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
149     lstrcpyW( name, &path[i] );
150 }
151
152 static void test_GetColorDirectoryA(void)
153 {
154     BOOL ret;
155     DWORD size;
156     char buffer[MAX_PATH];
157
158     /* Parameter checks */
159
160     ret = pGetColorDirectoryA( NULL, NULL, NULL );
161     ok( !ret, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
162
163     size = 0;
164
165     ret = pGetColorDirectoryA( NULL, NULL, &size );
166     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
167
168     size = 0;
169
170     ret = pGetColorDirectoryA( NULL, buffer, &size );
171     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
172
173     size = 1;
174
175     ret = pGetColorDirectoryA( NULL, buffer, &size );
176     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
177
178     /* Functional checks */
179
180     size = sizeof(buffer);
181
182     ret = pGetColorDirectoryA( NULL, buffer, &size );
183     ok( ret && size > 0, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
184 }
185
186 static void test_GetColorDirectoryW(void)
187 {
188     BOOL ret;
189     DWORD size;
190     WCHAR buffer[MAX_PATH];
191
192     /* Parameter checks */
193
194     /* This one crashes win2k
195     
196     ret = pGetColorDirectoryW( NULL, NULL, NULL );
197     ok( !ret, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
198
199      */
200
201     size = 0;
202
203     ret = pGetColorDirectoryW( NULL, NULL, &size );
204     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
205
206     size = 0;
207
208     ret = pGetColorDirectoryW( NULL, buffer, &size );
209     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
210
211     size = 1;
212
213     ret = pGetColorDirectoryW( NULL, buffer, &size );
214     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
215
216     /* Functional checks */
217
218     size = sizeof(buffer);
219
220     ret = pGetColorDirectoryW( NULL, buffer, &size );
221     ok( ret && size > 0, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
222 }
223
224 static void test_GetColorProfileElement( char *standardprofile )
225 {
226     if (standardprofile)
227     {
228         PROFILE profile;
229         HPROFILE handle;
230         BOOL ret, ref;
231         DWORD size;
232         TAGTYPE tag = 0x63707274;  /* 'cprt' */
233         static char buffer[51];
234         static const char expect[] =
235             { 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70,
236               0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
237               0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74,
238               0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43,
239               0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x00 };
240
241         profile.dwType = PROFILE_FILENAME;
242         profile.pProfileData = standardprofile;
243         profile.cbDataSize = strlen(standardprofile);
244
245         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
246         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
247
248         /* Parameter checks */
249
250         ret = pGetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
251         ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
252
253         ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
254         ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
255
256         size = 0;
257
258         ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
259         ok( !ret && size > 0, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
260
261         size = sizeof(buffer);
262
263         /* Functional checks */
264
265         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
266         ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
267
268         ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
269
270         pCloseColorProfile( handle );
271     }
272 }
273
274 static void test_GetColorProfileElementTag( char *standardprofile )
275 {
276     if (standardprofile)
277     {
278         PROFILE profile;
279         HPROFILE handle;
280         BOOL ret;
281         DWORD index = 1;
282         TAGTYPE tag, expect = 0x63707274;  /* 'cprt' */
283
284         profile.dwType = PROFILE_FILENAME;
285         profile.pProfileData = standardprofile;
286         profile.cbDataSize = strlen(standardprofile);
287
288         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
289         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
290
291         /* Parameter checks */
292
293         ret = pGetColorProfileElementTag( NULL, index, &tag );
294         ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
295
296         ret = pGetColorProfileElementTag( handle, 0, &tag );
297         ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
298
299         ret = pGetColorProfileElementTag( handle, index, NULL );
300         ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
301
302         ret = pGetColorProfileElementTag( handle, 18, NULL );
303         ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
304
305         /* Functional checks */
306
307         ret = pGetColorProfileElementTag( handle, index, &tag );
308         ok( ret && tag == expect, "GetColorProfileElementTag() failed (%d)\n",
309             GetLastError() );
310
311         pCloseColorProfile( handle );
312     }
313 }
314
315 static void test_GetColorProfileFromHandle( char *testprofile )
316 {
317     if (testprofile)
318     {
319         PROFILE profile;
320         HPROFILE handle;
321         DWORD size;
322         BOOL ret;
323         static const unsigned char expect[] =
324             { 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
325               0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
326               0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
327               0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
328               0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
329               0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330               0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
331               0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 };
332
333         unsigned char *buffer;
334
335         profile.dwType = PROFILE_FILENAME;
336         profile.pProfileData = testprofile;
337         profile.cbDataSize = strlen(testprofile);
338
339         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
340         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
341
342         /* Parameter checks */
343
344         size = 0;
345
346         ret = pGetColorProfileFromHandle( handle, NULL, &size );
347         ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
348
349         buffer = HeapAlloc( GetProcessHeap(), 0, size );
350
351         if (buffer)
352         {
353             ret = pGetColorProfileFromHandle( NULL, buffer, &size );
354             ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
355
356             ret = pGetColorProfileFromHandle( handle, buffer, NULL );
357             ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
358
359             /* Functional checks */
360
361             ret = pGetColorProfileFromHandle( handle, buffer, &size );
362             ok( ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
363
364             ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" );
365
366             HeapFree( GetProcessHeap(), 0, buffer );
367         }
368
369         pCloseColorProfile( handle );
370     }
371 }
372
373 static void test_GetColorProfileHeader( char *testprofile )
374 {
375     if (testprofile)
376     {
377         PROFILE profile;
378         HPROFILE handle;
379         BOOL ret;
380         PROFILEHEADER header;
381
382         profile.dwType = PROFILE_FILENAME;
383         profile.pProfileData = testprofile;
384         profile.cbDataSize = strlen(testprofile);
385
386         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
387         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
388
389         /* Parameter checks */
390
391         ret = pGetColorProfileHeader( NULL, NULL );
392         ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
393
394         ret = pGetColorProfileHeader( NULL, &header );
395         ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
396
397         if (0) /* Crashes on Vista */
398         {
399             ret = pGetColorProfileHeader( handle, NULL );
400             ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
401         }
402
403         /* Functional checks */
404
405         ret = pGetColorProfileHeader( handle, &header );
406         ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
407
408         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
409
410         pCloseColorProfile( handle );
411     }
412 }
413
414 static void test_GetCountColorProfileElements( char *standardprofile )
415 {
416     if (standardprofile)
417     {
418         PROFILE profile;
419         HPROFILE handle;
420         BOOL ret;
421         DWORD count, expect = 17;
422
423         profile.dwType = PROFILE_FILENAME;
424         profile.pProfileData = standardprofile;
425         profile.cbDataSize = strlen(standardprofile);
426
427         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
428         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
429
430         /* Parameter checks */
431
432         ret = pGetCountColorProfileElements( NULL, &count );
433         ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
434             GetLastError() );
435
436         ret = pGetCountColorProfileElements( handle, NULL );
437         ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
438             GetLastError() );
439
440         /* Functional checks */
441
442         ret = pGetCountColorProfileElements( handle, &count );
443         ok( ret && count == expect,
444             "GetCountColorProfileElements() failed (%d)\n", GetLastError() );
445
446         pCloseColorProfile( handle );
447     }
448 }
449
450 static void test_GetStandardColorSpaceProfileA( char *standardprofile )
451 {
452     BOOL ret;
453     DWORD size;
454     CHAR oldprofile[MAX_PATH];
455     CHAR newprofile[MAX_PATH];
456
457     /* Parameter checks */
458
459     /* Single invalid parameter checks: */
460
461     size = sizeof(newprofile);
462     SetLastError(0xfaceabee); /* 1st param, */
463     ret = pGetStandardColorSpaceProfileA(machine, LCS_sRGB, newprofile, &size);
464     ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
465
466     size = sizeof(newprofile);
467     SetLastError(0xfaceabee); /* 2nd param, */
468     ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &size);
469     ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
470
471     size = sizeof(newprofile);
472     SetLastError(0xfaceabee); /* 4th param, */
473     ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, NULL);
474     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
475
476     size = sizeof(newprofile);
477     SetLastError(0xfaceabee); /* 3rd param, */
478     ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, NULL, &size);
479     ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
480
481     size = 0;
482     SetLastError(0xfaceabee); /* dereferenced 4th param, */
483     ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, &size);
484     ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER),
485         "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
486
487     /* Several invalid parameter checks: */
488
489     size = 0;
490     SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
491     ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &size);
492     ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED),
493         "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
494
495     SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
496     ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
497     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
498
499     size = 0;
500     SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
501     ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &size);
502     ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND),
503         "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
504
505     size = sizeof(newprofile);
506     SetLastError(0xfaceabee); /* maybe 2nd param. */
507     ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &size);
508     if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
509     else ok( !lstrcmpiA( newprofile, "" ) && GetLastError() == 0xfaceabee,
510              "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
511
512     /* Functional checks */
513
514     size = sizeof(oldprofile);
515     ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile, &size );
516     ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
517
518     SetLastError(0xdeadbeef);
519     ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, standardprofile );
520     if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
521     {
522         skip("Not enough rights for SetStandardColorSpaceProfileA\n");
523         return;
524     }
525     ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
526
527     size = sizeof(newprofile);
528     ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, newprofile, &size );
529     ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
530
531     ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile );
532     ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
533 }
534
535 static void test_GetStandardColorSpaceProfileW( WCHAR *standardprofileW )
536 {
537     BOOL ret;
538     DWORD size;
539     WCHAR oldprofile[MAX_PATH];
540     WCHAR newprofile[MAX_PATH];
541     CHAR newprofileA[MAX_PATH];
542
543     /* Parameter checks */
544
545     /* Single invalid parameter checks: */
546
547     size = sizeof(newprofile);
548     SetLastError(0xfaceabee); /* 1st param, */
549     ret = pGetStandardColorSpaceProfileW(machineW, LCS_sRGB, newprofile, &size);
550     ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
551
552     size = sizeof(newprofile);
553     SetLastError(0xfaceabee); /* 2nd param, */
554     ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &size);
555     ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
556
557     size = sizeof(newprofile);
558     SetLastError(0xfaceabee); /* 2nd param, */
559     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &size);
560     ok( (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) ||
561         broken(ret), /* Win98 and WinME */
562         "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
563
564     size = sizeof(newprofile);
565     SetLastError(0xfaceabee); /* 3rd param, */
566     ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, NULL, &size);
567     ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" );
568     ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
569         broken(GetLastError() == 0xfaceabee) /* win98 */,
570         "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() );
571
572     size = sizeof(newprofile);
573     SetLastError(0xfaceabee); /* 4th param, */
574     ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, NULL);
575     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
576
577     size = 0;
578     SetLastError(0xfaceabee); /* dereferenced 4th param. */
579     ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, &size);
580     ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" );
581     ok( GetLastError() == ERROR_MORE_DATA ||
582         GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
583         broken(GetLastError() == 0xfaceabee) /* win98 */,
584         "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() );
585
586     /* Several invalid parameter checks: */
587
588     size = 0;
589     SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
590     ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &size);
591     ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED),
592         "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
593
594     SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
595     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
596     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
597
598     size = 0;
599     SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
600     ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &size);
601     ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" );
602     ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
603         GetLastError() == ERROR_FILE_NOT_FOUND ||
604         broken(GetLastError() == 0xfaceabee) /* win98 */,
605         "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() );
606
607     size = sizeof(newprofile);
608     SetLastError(0xfaceabee); /* maybe 2nd param. */
609     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &size);
610     if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
611     else
612     {
613         WideCharToMultiByte(CP_ACP, 0, newprofile, -1, newprofileA, sizeof(newprofileA), NULL, NULL);
614         ok( !lstrcmpiA( newprofileA, "" ) && GetLastError() == 0xfaceabee,
615              "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
616     }
617
618     /* Functional checks */
619
620     size = sizeof(oldprofile);
621     ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile, &size );
622     ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
623
624     SetLastError(0xdeadbeef);
625     ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, standardprofileW );
626     if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
627     {
628         skip("Not enough rights for SetStandardColorSpaceProfileW\n");
629         return;
630     }
631     ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
632
633     size = sizeof(newprofile);
634     ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, newprofile, &size );
635     ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
636
637     ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile );
638     ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
639 }
640
641 static void test_EnumColorProfilesA( char *standardprofile )
642 {
643     BOOL ret;
644     DWORD total, size, number;
645     ENUMTYPEA record;
646     BYTE *buffer;
647
648     /* Parameter checks */
649
650     memset( &record, 0, sizeof(ENUMTYPEA) );
651
652     record.dwSize = sizeof(ENUMTYPEA);
653     record.dwVersion = ENUM_TYPE_VERSION;
654     record.dwFields |= ET_DATACOLORSPACE;
655     record.dwDataColorSpace = SPACE_RGB;
656
657     total = 0;
658     ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number );
659     ok( !ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
660     buffer = HeapAlloc( GetProcessHeap(), 0, total );
661
662     size = total;
663     ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
664     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
665
666     ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
667     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
668
669     ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
670     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
671
672     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
673     if (standardprofile)
674         ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
675     else
676         todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
677
678     size = 0;
679
680     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
681     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
682
683     /* Functional checks */
684
685     size = total;
686     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
687     if (standardprofile)
688         ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
689     else
690         todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
691
692     HeapFree( GetProcessHeap(), 0, buffer );
693 }
694
695 static void test_EnumColorProfilesW( WCHAR *standardprofileW )
696 {
697     BOOL ret;
698     DWORD total, size, number;
699     ENUMTYPEW record;
700     BYTE *buffer;
701
702     /* Parameter checks */
703
704     memset( &record, 0, sizeof(ENUMTYPEW) );
705
706     record.dwSize = sizeof(ENUMTYPEW);
707     record.dwVersion = ENUM_TYPE_VERSION;
708     record.dwFields |= ET_DATACOLORSPACE;
709     record.dwDataColorSpace = SPACE_RGB;
710
711     total = 0;
712     ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number );
713     ok( !ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
714     buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
715
716     size = total;
717     ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
718     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
719
720     ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
721     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
722
723     ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
724     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
725
726     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
727     if (standardprofileW)
728         ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
729     else
730         todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
731
732     size = 0;
733     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
734     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
735
736     /* Functional checks */
737
738     size = total;
739     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
740     if (standardprofileW)
741         ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
742     else
743         todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
744
745     HeapFree( GetProcessHeap(), 0, buffer );
746 }
747
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
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
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
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
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
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
1058         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1059         ok( ret, "SetColorProfileElement() failed (%d)\n", GetLastError() );
1060
1061         size = sizeof(buffer);
1062
1063         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1064         ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
1065
1066         ok( !memcmp( data, buffer, sizeof(data) ),
1067             "Unexpected tag data, expected %s, got %s (%d)\n",
1068             data, buffer, GetLastError() );
1069
1070         pCloseColorProfile( handle );
1071     }
1072 }
1073
1074 static void test_SetColorProfileHeader( char *testprofile )
1075 {
1076     if (testprofile)
1077     {
1078         PROFILE profile;
1079         HPROFILE handle;
1080         BOOL ret;
1081         PROFILEHEADER header;
1082
1083         profile.dwType = PROFILE_FILENAME;
1084         profile.pProfileData = testprofile;
1085         profile.cbDataSize = strlen(testprofile);
1086
1087         header.phSize = 0x00000c48;
1088         header.phCMMType = 0x4c696e6f;
1089         header.phVersion = 0x02100000;
1090         header.phClass = 0x6d6e7472;
1091         header.phDataColorSpace = 0x52474220;
1092         header.phConnectionSpace  = 0x58595a20;
1093         header.phDateTime[0] = 0x07ce0002;
1094         header.phDateTime[1] = 0x00090006;
1095         header.phDateTime[2] = 0x00310000;
1096         header.phSignature = 0x61637370;
1097         header.phPlatform = 0x4d534654;
1098         header.phProfileFlags = 0x00000000;
1099         header.phManufacturer = 0x49454320;
1100         header.phModel = 0x73524742;
1101         header.phAttributes[0] = 0x00000000;
1102         header.phAttributes[1] = 0x00000000;
1103         header.phRenderingIntent = 0x00000000;
1104         header.phIlluminant.ciexyzX = 0x0000f6d6;
1105         header.phIlluminant.ciexyzY = 0x00010000;
1106         header.phIlluminant.ciexyzZ = 0x0000d32d;
1107         header.phCreator = 0x48502020;
1108
1109         /* Parameter checks */
1110
1111         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1112         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1113
1114         ret = pSetColorProfileHeader( handle, &header );
1115         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1116
1117         pCloseColorProfile( handle );
1118
1119         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1120         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1121
1122         ret = pSetColorProfileHeader( NULL, NULL );
1123         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1124
1125         ret = pSetColorProfileHeader( handle, NULL );
1126         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1127
1128         ret = pSetColorProfileHeader( NULL, &header );
1129         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1130
1131         /* Functional checks */
1132
1133         ret = pSetColorProfileHeader( handle, &header );
1134         ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1135
1136         ret = pGetColorProfileHeader( handle, &header );
1137         ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1138
1139         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1140
1141         pCloseColorProfile( handle );
1142     }
1143 }
1144
1145 static void test_UninstallColorProfileA( char *testprofile )
1146 {
1147     BOOL ret;
1148
1149     /* Parameter checks */
1150
1151     ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1152     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1153
1154     ret = pUninstallColorProfileA( machine, NULL, FALSE );
1155     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1156
1157     /* Functional checks */
1158
1159     if (testprofile)
1160     {
1161         CHAR dest[MAX_PATH], base[MAX_PATH];
1162         DWORD size = sizeof(dest);
1163         CHAR slash[] = "\\";
1164         HANDLE handle;
1165
1166         SetLastError(0xdeadbeef);
1167         ret = pInstallColorProfileA( NULL, testprofile );
1168         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1169         {
1170             skip("Not enough rights for InstallColorProfileA\n");
1171             return;
1172         }
1173         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1174
1175         ret = pGetColorDirectoryA( NULL, dest, &size );
1176         ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1177
1178         MSCMS_basenameA( testprofile, base );
1179
1180         lstrcatA( dest, slash );
1181         lstrcatA( dest, base );
1182
1183         ret = pUninstallColorProfileA( NULL, dest, TRUE );
1184         ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1185
1186         /* Check if the profile is really gone */
1187         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1188         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1189         CloseHandle( handle );
1190     }
1191 }
1192
1193 static void test_UninstallColorProfileW( WCHAR *testprofileW )
1194 {
1195     BOOL ret;
1196
1197     /* Parameter checks */
1198
1199     ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1200     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1201
1202     ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1203     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1204
1205     /* Functional checks */
1206
1207     if (testprofileW)
1208     {
1209         WCHAR dest[MAX_PATH], base[MAX_PATH];
1210         char destA[MAX_PATH];
1211         DWORD size = sizeof(dest);
1212         WCHAR slash[] = { '\\', 0 };
1213         HANDLE handle;
1214         int bytes_copied;
1215
1216         SetLastError(0xdeadbeef);
1217         ret = pInstallColorProfileW( NULL, testprofileW );
1218         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1219         {
1220             skip("Not enough rights for InstallColorProfileW\n");
1221             return;
1222         }
1223         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1224
1225         ret = pGetColorDirectoryW( NULL, dest, &size );
1226         ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1227
1228         MSCMS_basenameW( testprofileW, base );
1229
1230         lstrcatW( dest, slash );
1231         lstrcatW( dest, base );
1232
1233         ret = pUninstallColorProfileW( NULL, dest, TRUE );
1234         ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1235
1236         bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1237         ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1238         /* Check if the profile is really gone */
1239         handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1240         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1241         CloseHandle( handle );
1242     }
1243 }
1244
1245 static void test_AssociateColorProfileWithDeviceA( char *testprofile )
1246 {
1247     BOOL ret;
1248     char profile[MAX_PATH], basename[MAX_PATH];
1249     DWORD error, size = sizeof(profile);
1250     DISPLAY_DEVICE display;
1251     BOOL res;
1252     DISPLAY_DEVICE monitor;
1253
1254     if (testprofile && pEnumDisplayDevicesA)
1255     {
1256         display.cb = sizeof( DISPLAY_DEVICE );
1257         res = pEnumDisplayDevicesA( NULL, 0, &display, 0 );
1258         ok( res, "Can't get display info\n" );
1259
1260         monitor.cb = sizeof( DISPLAY_DEVICE );
1261         res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 );
1262         if (res)
1263         {
1264             SetLastError(0xdeadbeef);
1265             ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1266             error = GetLastError();
1267             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1268             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1269
1270             SetLastError(0xdeadbeef);
1271             ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID );
1272             error = GetLastError();
1273             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1274             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1275
1276             SetLastError(0xdeadbeef);
1277             ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID );
1278             error = GetLastError();
1279             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1280             ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1281
1282             ret = pInstallColorProfileA( NULL, testprofile );
1283             ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1284
1285             ret = pGetColorDirectoryA( NULL, profile, &size );
1286             ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1287
1288             MSCMS_basenameA( testprofile, basename );
1289             lstrcatA( profile, "\\" );
1290             lstrcatA( profile, basename );
1291
1292             ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID );
1293             ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1294
1295             SetLastError(0xdeadbeef);
1296             ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1297             error = GetLastError();
1298             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1299             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1300
1301             SetLastError(0xdeadbeef);
1302             ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID );
1303             error = GetLastError();
1304             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1305             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1306
1307             SetLastError(0xdeadbeef);
1308             ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID );
1309             error = GetLastError();
1310             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1311             ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1312
1313             ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID );
1314             ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1315
1316             ret = pUninstallColorProfileA( NULL, profile, TRUE );
1317             ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1318         }
1319         else
1320             skip("Unable to obtain monitor name\n");
1321     }
1322 }
1323
1324 START_TEST(profile)
1325 {
1326     UINT len;
1327     HANDLE handle;
1328     char path[MAX_PATH], file[MAX_PATH], profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1329     WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH], fileW[MAX_PATH];
1330     char *standardprofile = NULL, *testprofile = NULL;
1331     WCHAR *standardprofileW = NULL, *testprofileW = NULL;
1332     UINT ret;
1333
1334     hmscms = LoadLibraryA( "mscms.dll" );
1335     if (!hmscms) return;
1336
1337     huser32 = LoadLibraryA( "user32.dll" );
1338     if (!huser32)
1339     {
1340         FreeLibrary( hmscms );
1341         return;
1342     }
1343
1344     if (!init_function_ptrs())
1345     {
1346         FreeLibrary( huser32 );
1347         FreeLibrary( hmscms );
1348         return;
1349     }
1350
1351     /* See if we can find the standard color profile */
1352     ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1353     ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1354     ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH, 
1355         "Expected length between 0 and MAX_PATH, got %d\n", lstrlenA(profilefile1));
1356     MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1357     ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH, 
1358         "Expected length between 0 and MAX_PATH, got %d\n", lstrlenW(profilefile1W));
1359     lstrcpyA(profilefile2, profilefile1);
1360     lstrcpyW(profilefile2W, profilefile1W);
1361
1362     lstrcatA( profilefile1, profile1 );
1363     lstrcatW( profilefile1W, profile1W );
1364     handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1365
1366     if (handle != INVALID_HANDLE_VALUE)
1367     {
1368         standardprofile = profilefile1;
1369         standardprofileW = profilefile1W;
1370         CloseHandle( handle );
1371     }
1372
1373     lstrcatA( profilefile2, profile2 );
1374     lstrcatW( profilefile2W, profile2W );
1375     handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1376
1377     if (handle != INVALID_HANDLE_VALUE)
1378     {
1379         standardprofile = profilefile2;
1380         standardprofileW = profilefile2W;
1381         CloseHandle( handle );
1382     }
1383
1384     /* If found, create a temporary copy for testing purposes */
1385     if (standardprofile && GetTempPath( sizeof(path), path ))
1386     {
1387         if (GetTempFileName( path, "rgb", 0, file ))
1388         {
1389             if (CopyFileA( standardprofile, file, FALSE ))
1390             {
1391                 testprofile = (LPSTR)&file;
1392                 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1393                 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1394                 testprofileW = (LPWSTR)&fileW;
1395             }
1396         }
1397     }
1398
1399     test_GetColorDirectoryA();
1400     test_GetColorDirectoryW();
1401
1402     test_GetColorProfileElement( standardprofile );
1403     test_GetColorProfileElementTag( standardprofile );
1404
1405     test_GetColorProfileFromHandle( testprofile );
1406     test_GetColorProfileHeader( testprofile );
1407
1408     test_GetCountColorProfileElements( standardprofile );
1409
1410     test_GetStandardColorSpaceProfileA( standardprofile );
1411     test_GetStandardColorSpaceProfileW( standardprofileW );
1412
1413     test_EnumColorProfilesA( standardprofile );
1414     test_EnumColorProfilesW( standardprofileW );
1415
1416     test_InstallColorProfileA( standardprofile, testprofile );
1417     test_InstallColorProfileW( standardprofileW, testprofileW );
1418
1419     test_IsColorProfileTagPresent( standardprofile );
1420
1421     test_OpenColorProfileA( standardprofile );
1422     test_OpenColorProfileW( standardprofileW );
1423
1424     test_SetColorProfileElement( testprofile );
1425     test_SetColorProfileHeader( testprofile );
1426
1427     test_UninstallColorProfileA( testprofile );
1428     test_UninstallColorProfileW( testprofileW );
1429
1430     test_AssociateColorProfileWithDeviceA( testprofile );
1431
1432     if (testprofile) DeleteFileA( testprofile );
1433     FreeLibrary( huser32 );
1434     FreeLibrary( hmscms );
1435 }