mscms/tests: Mark some win98 test results as broken.
[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 HMODULE hmscms;
34 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 }
957
958 static void test_OpenColorProfileW(void)
959 {
960     PROFILE profile;
961     HPROFILE handle;
962     BOOL ret;
963
964     profile.dwType = PROFILE_FILENAME;
965     profile.pProfileData = NULL;
966     profile.cbDataSize = 0;
967
968     /* Parameter checks */
969
970     handle = pOpenColorProfileW( NULL, 0, 0, 0 );
971     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
972
973     handle = pOpenColorProfileW( &profile, 0, 0, 0 );
974     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
975
976     handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
977     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
978
979     handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
980     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
981
982     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
983
984     if (standardprofileW)
985     {
986         profile.pProfileData = standardprofileW;
987         profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
988
989         handle = pOpenColorProfileW( &profile, 0, 0, 0 );
990         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
991
992         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
993         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
994
995         handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
996         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
997
998         /* Functional checks */
999
1000         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1001         ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1002
1003         ret = pCloseColorProfile( handle );
1004         ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1005     }
1006 }
1007
1008 static void test_SetColorProfileElement(void)
1009 {
1010     if (testprofile)
1011     {
1012         PROFILE profile;
1013         HPROFILE handle;
1014         DWORD size;
1015         BOOL ret, ref;
1016
1017         TAGTYPE tag = 0x63707274;  /* 'cprt' */
1018         static char data[] = "(c) The Wine Project";
1019         static char buffer[51];
1020
1021         profile.dwType = PROFILE_FILENAME;
1022         profile.pProfileData = testprofile;
1023         profile.cbDataSize = strlen(testprofile);
1024
1025         /* Parameter checks */
1026
1027         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1028         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1029
1030         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1031         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1032
1033         pCloseColorProfile( handle );
1034
1035         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1036         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1037
1038         ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1039         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1040
1041         ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1042         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1043
1044         ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1045         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1046
1047         ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1048         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1049
1050         /* Functional checks */
1051
1052         size = sizeof(data);
1053
1054         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1055         ok( ret, "SetColorProfileElement() failed (%d)\n", GetLastError() );
1056
1057         size = sizeof(buffer);
1058
1059         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1060         ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
1061
1062         ok( !memcmp( data, buffer, sizeof(data) ),
1063             "Unexpected tag data, expected %s, got %s (%d)\n",
1064             data, buffer, GetLastError() );
1065
1066         pCloseColorProfile( handle );
1067     }
1068 }
1069
1070 static void test_SetColorProfileHeader(void)
1071 {
1072     if (testprofile)
1073     {
1074         PROFILE profile;
1075         HPROFILE handle;
1076         BOOL ret;
1077         PROFILEHEADER header;
1078
1079         profile.dwType = PROFILE_FILENAME;
1080         profile.pProfileData = testprofile;
1081         profile.cbDataSize = strlen(testprofile);
1082
1083         header.phSize = 0x00000c48;
1084         header.phCMMType = 0x4c696e6f;
1085         header.phVersion = 0x02100000;
1086         header.phClass = 0x6d6e7472;
1087         header.phDataColorSpace = 0x52474220;
1088         header.phConnectionSpace  = 0x58595a20;
1089         header.phDateTime[0] = 0x07ce0002;
1090         header.phDateTime[1] = 0x00090006;
1091         header.phDateTime[2] = 0x00310000;
1092         header.phSignature = 0x61637370;
1093         header.phPlatform = 0x4d534654;
1094         header.phProfileFlags = 0x00000000;
1095         header.phManufacturer = 0x49454320;
1096         header.phModel = 0x73524742;
1097         header.phAttributes[0] = 0x00000000;
1098         header.phAttributes[1] = 0x00000000;
1099         header.phRenderingIntent = 0x00000000;
1100         header.phIlluminant.ciexyzX = 0x0000f6d6;
1101         header.phIlluminant.ciexyzY = 0x00010000;
1102         header.phIlluminant.ciexyzZ = 0x0000d32d;
1103         header.phCreator = 0x48502020;
1104
1105         /* Parameter checks */
1106
1107         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1108         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1109
1110         ret = pSetColorProfileHeader( handle, &header );
1111         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1112
1113         pCloseColorProfile( handle );
1114
1115         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1116         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1117
1118         ret = pSetColorProfileHeader( NULL, NULL );
1119         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1120
1121         ret = pSetColorProfileHeader( handle, NULL );
1122         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1123
1124         ret = pSetColorProfileHeader( NULL, &header );
1125         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1126
1127         /* Functional checks */
1128
1129         ret = pSetColorProfileHeader( handle, &header );
1130         ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1131
1132         ret = pGetColorProfileHeader( handle, &header );
1133         ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1134
1135         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1136
1137         pCloseColorProfile( handle );
1138     }
1139 }
1140
1141 static void test_UninstallColorProfileA(void)
1142 {
1143     BOOL ret;
1144
1145     /* Parameter checks */
1146
1147     ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1148     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1149
1150     ret = pUninstallColorProfileA( machine, NULL, FALSE );
1151     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1152
1153     /* Functional checks */
1154
1155     if (testprofile)
1156     {
1157         CHAR dest[MAX_PATH], base[MAX_PATH];
1158         DWORD size = sizeof(dest);
1159         CHAR slash[] = "\\";
1160         HANDLE handle;
1161
1162         SetLastError(0xdeadbeef);
1163         ret = pInstallColorProfileA( NULL, testprofile );
1164         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1165         {
1166             skip("Not enough rights for InstallColorProfileA\n");
1167             return;
1168         }
1169         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1170
1171         ret = pGetColorDirectoryA( NULL, dest, &size );
1172         ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1173
1174         MSCMS_basenameA( testprofile, base );
1175
1176         lstrcatA( dest, slash );
1177         lstrcatA( dest, base );
1178
1179         ret = pUninstallColorProfileA( NULL, dest, TRUE );
1180         ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1181
1182         /* Check if the profile is really gone */
1183         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1184         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1185         CloseHandle( handle );
1186     }
1187 }
1188
1189 static void test_UninstallColorProfileW(void)
1190 {
1191     BOOL ret;
1192
1193     /* Parameter checks */
1194
1195     ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1196     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1197
1198     ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1199     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1200
1201     /* Functional checks */
1202
1203     if (testprofileW)
1204     {
1205         WCHAR dest[MAX_PATH], base[MAX_PATH];
1206         char destA[MAX_PATH];
1207         DWORD size = sizeof(dest);
1208         WCHAR slash[] = { '\\', 0 };
1209         HANDLE handle;
1210         int bytes_copied;
1211
1212         SetLastError(0xdeadbeef);
1213         ret = pInstallColorProfileW( NULL, testprofileW );
1214         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1215         {
1216             skip("Not enough rights for InstallColorProfileW\n");
1217             return;
1218         }
1219         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1220
1221         ret = pGetColorDirectoryW( NULL, dest, &size );
1222         ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1223
1224         MSCMS_basenameW( testprofileW, base );
1225
1226         lstrcatW( dest, slash );
1227         lstrcatW( dest, base );
1228
1229         ret = pUninstallColorProfileW( NULL, dest, TRUE );
1230         ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1231
1232         bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1233         ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1234         /* Check if the profile is really gone */
1235         handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1236         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1237         CloseHandle( handle );
1238     }
1239 }
1240
1241 static void test_AssociateColorProfileWithDeviceA(void)
1242 {
1243     BOOL ret;
1244     char profile[MAX_PATH], basename[MAX_PATH];
1245     DWORD error, size = sizeof(profile);
1246     DISPLAY_DEVICE display;
1247     BOOL res;
1248     DISPLAY_DEVICE monitor;
1249
1250     if (testprofile && pEnumDisplayDevicesA)
1251     {
1252         display.cb = sizeof( DISPLAY_DEVICE );
1253         res = pEnumDisplayDevicesA( NULL, 0, &display, 0 );
1254         ok( res, "Can't get display info\n" );
1255
1256         monitor.cb = sizeof( DISPLAY_DEVICE );
1257         res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 );
1258         if (res)
1259         {
1260             SetLastError(0xdeadbeef);
1261             ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1262             error = GetLastError();
1263             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1264             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1265
1266             SetLastError(0xdeadbeef);
1267             ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID );
1268             error = GetLastError();
1269             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1270             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1271
1272             SetLastError(0xdeadbeef);
1273             ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID );
1274             error = GetLastError();
1275             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1276             ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1277
1278             ret = pInstallColorProfileA( NULL, testprofile );
1279             ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1280
1281             ret = pGetColorDirectoryA( NULL, profile, &size );
1282             ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1283
1284             MSCMS_basenameA( testprofile, basename );
1285             lstrcatA( profile, "\\" );
1286             lstrcatA( profile, basename );
1287
1288             ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID );
1289             ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1290
1291             SetLastError(0xdeadbeef);
1292             ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1293             error = GetLastError();
1294             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1295             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1296
1297             SetLastError(0xdeadbeef);
1298             ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID );
1299             error = GetLastError();
1300             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1301             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1302
1303             SetLastError(0xdeadbeef);
1304             ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID );
1305             error = GetLastError();
1306             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1307             ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1308
1309             ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID );
1310             ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1311
1312             ret = pUninstallColorProfileA( NULL, profile, TRUE );
1313             ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1314         }
1315         else
1316             skip("Unable to obtain monitor name\n");
1317     }
1318 }
1319
1320 START_TEST(profile)
1321 {
1322     UINT len;
1323     HANDLE handle;
1324     char path[MAX_PATH], file[MAX_PATH];
1325     char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1326     WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1327     WCHAR fileW[MAX_PATH];
1328     UINT ret;
1329
1330     hmscms = LoadLibraryA( "mscms.dll" );
1331     if (!hmscms) return;
1332
1333     huser32 = LoadLibraryA( "user32.dll" );
1334     if (!huser32)
1335     {
1336         FreeLibrary( hmscms );
1337         return;
1338     }
1339
1340     if (!init_function_ptrs())
1341     {
1342         FreeLibrary( huser32 );
1343         FreeLibrary( hmscms );
1344         return;
1345     }
1346
1347     /* See if we can find the standard color profile */
1348     ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1349     ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1350     ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH, 
1351         "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1352     MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1353     ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH, 
1354         "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1355     lstrcpyA(profilefile2, profilefile1);
1356     lstrcpyW(profilefile2W, profilefile1W);
1357
1358     lstrcatA( profilefile1, profile1 );
1359     lstrcatW( profilefile1W, profile1W );
1360     handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1361
1362     if (handle != INVALID_HANDLE_VALUE)
1363     {
1364         standardprofile = profilefile1;
1365         standardprofileW = profilefile1W;
1366         CloseHandle( handle );
1367     }
1368
1369     lstrcatA( profilefile2, profile2 );
1370     lstrcatW( profilefile2W, profile2W );
1371     handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1372
1373     if (handle != INVALID_HANDLE_VALUE)
1374     {
1375         standardprofile = profilefile2;
1376         standardprofileW = profilefile2W;
1377         CloseHandle( handle );
1378     }
1379
1380     /* If found, create a temporary copy for testing purposes */
1381     if (standardprofile && GetTempPath( sizeof(path), path ))
1382     {
1383         if (GetTempFileName( path, "rgb", 0, file ))
1384         {
1385             if (CopyFileA( standardprofile, file, FALSE ))
1386             {
1387                 testprofile = (LPSTR)&file;
1388
1389                 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1390                 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1391
1392                 testprofileW = (LPWSTR)&fileW;
1393             }
1394         }
1395     }
1396
1397     test_GetColorDirectoryA();
1398     test_GetColorDirectoryW();
1399
1400     test_GetColorProfileElement();
1401     test_GetColorProfileElementTag();
1402
1403     test_GetColorProfileFromHandle();
1404     test_GetColorProfileHeader();
1405
1406     test_GetCountColorProfileElements();
1407
1408     test_GetStandardColorSpaceProfileA();
1409     test_GetStandardColorSpaceProfileW();
1410
1411     test_EnumColorProfilesA();
1412     test_EnumColorProfilesW();
1413
1414     test_InstallColorProfileA();
1415     test_InstallColorProfileW();
1416
1417     test_IsColorProfileTagPresent();
1418
1419     test_OpenColorProfileA();
1420     test_OpenColorProfileW();
1421
1422     test_SetColorProfileElement();
1423     test_SetColorProfileHeader();
1424
1425     test_UninstallColorProfileA();
1426     test_UninstallColorProfileW();
1427
1428     test_AssociateColorProfileWithDeviceA();
1429
1430     /* Clean up */
1431     if (testprofile)
1432         DeleteFileA( testprofile );
1433     
1434     FreeLibrary( huser32 );
1435     FreeLibrary( hmscms );
1436 }