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