fltlib: Add a stub dll.
[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()
457 {
458     BOOL ret;
459     DWORD size;
460     CHAR oldprofile[MAX_PATH];
461     CHAR newprofile[MAX_PATH];
462     const CHAR emptyA[] = "";
463     DWORD zero = 0;
464     DWORD sizeP = sizeof(newprofile);
465
466     /* Parameter checks */
467
468     /* Single invalid parameter checks: */
469
470     SetLastError(0xfaceabee); /* 1st param, */
471     ret = pGetStandardColorSpaceProfileA(machine, LCS_sRGB, newprofile, &sizeP);
472     ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
473
474     SetLastError(0xfaceabee); /* 2nd param, */
475     ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &sizeP);
476     ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
477
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     SetLastError(0xfaceabee); /* 3rd param, */
483     ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, NULL, &sizeP);
484     ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
485
486     SetLastError(0xfaceabee); /* dereferenced 4th param, */
487     ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, &zero);
488     ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER),
489         "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
490
491     /* Several invalid parameter checks: */
492
493     SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
494     ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &zero);
495     ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED),
496         "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
497
498     SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
499     ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
500     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
501
502     SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
503     ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &zero);
504     ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND),
505         "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
506
507     SetLastError(0xfaceabee); /* maybe 2nd param. */
508     ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &sizeP);
509     if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
510     else ok( !lstrcmpiA( newprofile, emptyA ) && GetLastError() == 0xfaceabee,
511              "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
512
513     /* Functional checks */
514
515     size = sizeof(oldprofile);
516     ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile, &size );
517     ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
518
519     SetLastError(0xdeadbeef);
520     ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, standardprofile );
521     if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
522     {
523         skip("Not enough rights for SetStandardColorSpaceProfileA\n");
524         return;
525     }
526     ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
527
528     size = sizeof(newprofile);
529     ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, newprofile, &size );
530     ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
531
532     ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile );
533     ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
534 }
535
536 static void test_GetStandardColorSpaceProfileW()
537 {
538     BOOL ret;
539     DWORD size;
540     WCHAR oldprofile[MAX_PATH];
541     WCHAR newprofile[MAX_PATH];
542     CHAR newprofileA[MAX_PATH];
543     const CHAR empty[] = "";
544     DWORD zero = 0;
545     DWORD sizeP = sizeof(newprofile);
546
547     /* Parameter checks */
548
549     /* Single invalid parameter checks: */
550
551     SetLastError(0xfaceabee); /* 1st param, */
552     ret = pGetStandardColorSpaceProfileW(machineW, LCS_sRGB, newprofile, &sizeP);
553     ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
554
555     SetLastError(0xfaceabee); /* 2nd param, */
556     ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &sizeP);
557     ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
558
559     SetLastError(0xfaceabee); /* 2nd param, */
560     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
561     ok( (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) ||
562         broken(ret), /* Win98 and WinME */
563         "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
564
565     SetLastError(0xfaceabee); /* 3rd param, */
566     ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, NULL, &sizeP);
567     ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
568
569     SetLastError(0xfaceabee); /* 4th param, */
570     ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, NULL);
571     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
572
573     SetLastError(0xfaceabee); /* dereferenced 4th param. */
574     ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, &zero);
575     ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER),
576         "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
577
578     /* Several invalid parameter checks: */
579
580     SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
581     ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &zero);
582     ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED),
583         "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
584
585     SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
586     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
587     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
588
589     SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
590     ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &zero);
591     ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND),
592         "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
593
594     SetLastError(0xfaceabee); /* maybe 2nd param. */
595     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
596     WideCharToMultiByte(CP_ACP, 0, newprofile, -1, newprofileA, sizeof(newprofileA), NULL, NULL);
597     if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
598     else ok( !lstrcmpiA( newprofileA, empty ) && GetLastError() == 0xfaceabee,
599              "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
600
601     /* Functional checks */
602
603     size = sizeof(oldprofile);
604     ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile, &size );
605     ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
606
607     SetLastError(0xdeadbeef);
608     ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, standardprofileW );
609     if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
610     {
611         skip("Not enough rights for SetStandardColorSpaceProfileW\n");
612         return;
613     }
614     ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
615
616     size = sizeof(newprofile);
617     ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, newprofile, &size );
618     ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
619
620     ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile );
621     ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
622 }
623
624 static void test_EnumColorProfilesA(void)
625 {
626     BOOL ret;
627     DWORD total, size, number;
628     ENUMTYPEA record;
629     BYTE *buffer;
630
631     /* Parameter checks */
632
633     memset( &record, 0, sizeof(ENUMTYPEA) );
634
635     record.dwSize = sizeof(ENUMTYPEA);
636     record.dwVersion = ENUM_TYPE_VERSION;
637     record.dwFields |= ET_DATACOLORSPACE;
638     record.dwDataColorSpace = SPACE_RGB;
639
640     total = 0;
641     ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number );
642     ok( !ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
643     buffer = HeapAlloc( GetProcessHeap(), 0, total );
644
645     size = total;
646     ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
647     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
648
649     ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
650     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
651
652     ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
653     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
654
655     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
656     if (standardprofile)
657         ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
658     else
659         todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
660
661     size = 0;
662
663     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
664     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
665
666     /* Functional checks */
667
668     size = total;
669     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
670     if (standardprofile)
671         ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
672     else
673         todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
674
675     HeapFree( GetProcessHeap(), 0, buffer );
676 }
677
678 static void test_EnumColorProfilesW(void)
679 {
680     BOOL ret;
681     DWORD total, size, number;
682     ENUMTYPEW record;
683     BYTE *buffer;
684
685     /* Parameter checks */
686
687     memset( &record, 0, sizeof(ENUMTYPEW) );
688
689     record.dwSize = sizeof(ENUMTYPEW);
690     record.dwVersion = ENUM_TYPE_VERSION;
691     record.dwFields |= ET_DATACOLORSPACE;
692     record.dwDataColorSpace = SPACE_RGB;
693
694     total = 0;
695     ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number );
696     ok( !ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
697     buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
698
699     size = total;
700     ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
701     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
702
703     ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
704     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
705
706     ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
707     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
708
709     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
710     if (standardprofileW)
711         ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
712     else
713         todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
714
715     size = 0;
716     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
717     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
718
719     /* Functional checks */
720
721     size = total;
722     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
723     if (standardprofileW)
724         ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
725     else
726         todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
727
728     HeapFree( GetProcessHeap(), 0, buffer );
729 }
730
731 static void test_InstallColorProfileA(void)
732 {
733     BOOL ret;
734
735     /* Parameter checks */
736
737     ret = pInstallColorProfileA( NULL, NULL );
738     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
739
740     ret = pInstallColorProfileA( machine, NULL );
741     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
742
743     ret = pInstallColorProfileA( NULL, machine );
744     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
745
746     if (standardprofile)
747     {
748         ret = pInstallColorProfileA( NULL, standardprofile );
749         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
750     }
751
752     /* Functional checks */
753
754     if (testprofile)
755     {
756         CHAR dest[MAX_PATH], base[MAX_PATH];
757         DWORD size = sizeof(dest);
758         CHAR slash[] = "\\";
759         HANDLE handle;
760
761         SetLastError(0xdeadbeef);
762         ret = pInstallColorProfileA( NULL, testprofile );
763         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
764         {
765             skip("Not enough rights for InstallColorProfileA\n");
766             return;
767         }
768         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
769
770         ret = pGetColorDirectoryA( NULL, dest, &size );
771         ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
772
773         MSCMS_basenameA( testprofile, base );
774
775         lstrcatA( dest, slash );
776         lstrcatA( dest, base );
777
778         /* Check if the profile is really there */ 
779         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
780         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
781         CloseHandle( handle );
782         
783         ret = pUninstallColorProfileA( NULL, dest, TRUE );
784         ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
785     }
786 }
787
788 static void test_InstallColorProfileW(void)
789 {
790     BOOL ret;
791
792     /* Parameter checks */
793
794     ret = pInstallColorProfileW( NULL, NULL );
795     ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
796
797     ret = pInstallColorProfileW( machineW, NULL );
798     ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
799
800     ret = pInstallColorProfileW( NULL, machineW );
801     ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
802
803     if (standardprofileW)
804     {
805         ret = pInstallColorProfileW( NULL, standardprofileW );
806         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
807     }
808
809     /* Functional checks */
810
811     if (testprofileW)
812     {
813         WCHAR dest[MAX_PATH], base[MAX_PATH];
814         DWORD size = sizeof(dest);
815         WCHAR slash[] = { '\\', 0 };
816         HANDLE handle;
817
818         SetLastError(0xdeadbeef);
819         ret = pInstallColorProfileW( NULL, testprofileW );
820         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
821         {
822             skip("Not enough rights for InstallColorProfileW\n");
823             return;
824         }
825         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
826
827         ret = pGetColorDirectoryW( NULL, dest, &size );
828         ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
829
830         MSCMS_basenameW( testprofileW, base );
831
832         lstrcatW( dest, slash );
833         lstrcatW( dest, base );
834
835         /* Check if the profile is really there */
836         handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
837         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
838         CloseHandle( handle );
839
840         ret = pUninstallColorProfileW( NULL, dest, TRUE );
841         ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
842     }
843 }
844
845 static void test_IsColorProfileTagPresent(void)
846 {
847     if (standardprofile)
848     {
849         PROFILE profile;
850         HPROFILE handle;
851         BOOL ret, present;
852         TAGTYPE tag;
853
854         profile.dwType = PROFILE_FILENAME;
855         profile.pProfileData = standardprofile;
856         profile.cbDataSize = strlen(standardprofile);
857
858         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
859         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
860
861         /* Parameter checks */
862
863         tag = 0;
864
865         ret = pIsColorProfileTagPresent( handle, tag, &present );
866         ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
867
868         tag = 0x63707274;  /* 'cprt' */
869
870         ret = pIsColorProfileTagPresent( NULL, tag, &present );
871         ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
872
873         ret = pIsColorProfileTagPresent( handle, tag, NULL );
874         ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
875
876         /* Functional checks */
877
878         ret = pIsColorProfileTagPresent( handle, tag, &present );
879         ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() );
880
881         pCloseColorProfile( handle );
882     }
883 }
884
885 static void test_OpenColorProfileA(void)
886 {
887     PROFILE profile;
888     HPROFILE handle;
889     BOOL ret;
890
891     profile.dwType = PROFILE_FILENAME;
892     profile.pProfileData = NULL;
893     profile.cbDataSize = 0;
894
895     /* Parameter checks */
896
897     handle = pOpenColorProfileA( NULL, 0, 0, 0 );
898     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
899
900     handle = pOpenColorProfileA( &profile, 0, 0, 0 );
901     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
902
903     handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
904     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
905
906     handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
907     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
908
909     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
910
911     if (standardprofile)
912     {
913         profile.pProfileData = standardprofile;
914         profile.cbDataSize = strlen(standardprofile);
915
916         handle = pOpenColorProfileA( &profile, 0, 0, 0 );
917         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
918
919         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
920         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
921
922         handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
923         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
924
925         /* Functional checks */
926
927         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
928         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
929
930         ret = pCloseColorProfile( handle );
931         ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
932     }
933 }
934
935 static void test_OpenColorProfileW(void)
936 {
937     PROFILE profile;
938     HPROFILE handle;
939     BOOL ret;
940
941     profile.dwType = PROFILE_FILENAME;
942     profile.pProfileData = NULL;
943     profile.cbDataSize = 0;
944
945     /* Parameter checks */
946
947     handle = pOpenColorProfileW( NULL, 0, 0, 0 );
948     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
949
950     handle = pOpenColorProfileW( &profile, 0, 0, 0 );
951     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
952
953     handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
954     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
955
956     handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
957     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
958
959     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
960
961     if (standardprofileW)
962     {
963         profile.pProfileData = standardprofileW;
964         profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
965
966         handle = pOpenColorProfileW( &profile, 0, 0, 0 );
967         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
968
969         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
970         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
971
972         handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
973         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
974
975         /* Functional checks */
976
977         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
978         ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
979
980         ret = pCloseColorProfile( handle );
981         ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
982     }
983 }
984
985 static void test_SetColorProfileElement(void)
986 {
987     if (testprofile)
988     {
989         PROFILE profile;
990         HPROFILE handle;
991         DWORD size;
992         BOOL ret, ref;
993
994         TAGTYPE tag = 0x63707274;  /* 'cprt' */
995         static char data[] = "(c) The Wine Project";
996         static char buffer[51];
997
998         profile.dwType = PROFILE_FILENAME;
999         profile.pProfileData = testprofile;
1000         profile.cbDataSize = strlen(testprofile);
1001
1002         /* Parameter checks */
1003
1004         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1005         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1006
1007         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1008         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1009
1010         pCloseColorProfile( handle );
1011
1012         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1013         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1014
1015         ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1016         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1017
1018         ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1019         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1020
1021         ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1022         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1023
1024         ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1025         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1026
1027         /* Functional checks */
1028
1029         size = sizeof(data);
1030
1031         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1032         ok( ret, "SetColorProfileElement() failed (%d)\n", GetLastError() );
1033
1034         size = sizeof(buffer);
1035
1036         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1037         ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
1038
1039         ok( !memcmp( data, buffer, sizeof(data) ),
1040             "Unexpected tag data, expected %s, got %s (%d)\n",
1041             data, buffer, GetLastError() );
1042
1043         pCloseColorProfile( handle );
1044     }
1045 }
1046
1047 static void test_SetColorProfileHeader(void)
1048 {
1049     if (testprofile)
1050     {
1051         PROFILE profile;
1052         HPROFILE handle;
1053         BOOL ret;
1054         PROFILEHEADER header;
1055
1056         profile.dwType = PROFILE_FILENAME;
1057         profile.pProfileData = testprofile;
1058         profile.cbDataSize = strlen(testprofile);
1059
1060         header.phSize = 0x00000c48;
1061         header.phCMMType = 0x4c696e6f;
1062         header.phVersion = 0x02100000;
1063         header.phClass = 0x6d6e7472;
1064         header.phDataColorSpace = 0x52474220;
1065         header.phConnectionSpace  = 0x58595a20;
1066         header.phDateTime[0] = 0x07ce0002;
1067         header.phDateTime[1] = 0x00090006;
1068         header.phDateTime[2] = 0x00310000;
1069         header.phSignature = 0x61637370;
1070         header.phPlatform = 0x4d534654;
1071         header.phProfileFlags = 0x00000000;
1072         header.phManufacturer = 0x49454320;
1073         header.phModel = 0x73524742;
1074         header.phAttributes[0] = 0x00000000;
1075         header.phAttributes[1] = 0x00000000;
1076         header.phRenderingIntent = 0x00000000;
1077         header.phIlluminant.ciexyzX = 0x0000f6d6;
1078         header.phIlluminant.ciexyzY = 0x00010000;
1079         header.phIlluminant.ciexyzZ = 0x0000d32d;
1080         header.phCreator = 0x48502020;
1081
1082         /* Parameter checks */
1083
1084         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1085         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1086
1087         ret = pSetColorProfileHeader( handle, &header );
1088         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1089
1090         pCloseColorProfile( handle );
1091
1092         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1093         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1094
1095         ret = pSetColorProfileHeader( NULL, NULL );
1096         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1097
1098         ret = pSetColorProfileHeader( handle, NULL );
1099         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1100
1101         ret = pSetColorProfileHeader( NULL, &header );
1102         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1103
1104         /* Functional checks */
1105
1106         ret = pSetColorProfileHeader( handle, &header );
1107         ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1108
1109         ret = pGetColorProfileHeader( handle, &header );
1110         ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1111
1112         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1113
1114         pCloseColorProfile( handle );
1115     }
1116 }
1117
1118 static void test_UninstallColorProfileA(void)
1119 {
1120     BOOL ret;
1121
1122     /* Parameter checks */
1123
1124     ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1125     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1126
1127     ret = pUninstallColorProfileA( machine, NULL, FALSE );
1128     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1129
1130     /* Functional checks */
1131
1132     if (testprofile)
1133     {
1134         CHAR dest[MAX_PATH], base[MAX_PATH];
1135         DWORD size = sizeof(dest);
1136         CHAR slash[] = "\\";
1137         HANDLE handle;
1138
1139         SetLastError(0xdeadbeef);
1140         ret = pInstallColorProfileA( NULL, testprofile );
1141         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1142         {
1143             skip("Not enough rights for InstallColorProfileA\n");
1144             return;
1145         }
1146         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1147
1148         ret = pGetColorDirectoryA( NULL, dest, &size );
1149         ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1150
1151         MSCMS_basenameA( testprofile, base );
1152
1153         lstrcatA( dest, slash );
1154         lstrcatA( dest, base );
1155
1156         ret = pUninstallColorProfileA( NULL, dest, TRUE );
1157         ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1158
1159         /* Check if the profile is really gone */
1160         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1161         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1162         CloseHandle( handle );
1163     }
1164 }
1165
1166 static void test_UninstallColorProfileW(void)
1167 {
1168     BOOL ret;
1169
1170     /* Parameter checks */
1171
1172     ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1173     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1174
1175     ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1176     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1177
1178     /* Functional checks */
1179
1180     if (testprofileW)
1181     {
1182         WCHAR dest[MAX_PATH], base[MAX_PATH];
1183         char destA[MAX_PATH];
1184         DWORD size = sizeof(dest);
1185         WCHAR slash[] = { '\\', 0 };
1186         HANDLE handle;
1187         int bytes_copied;
1188
1189         SetLastError(0xdeadbeef);
1190         ret = pInstallColorProfileW( NULL, testprofileW );
1191         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1192         {
1193             skip("Not enough rights for InstallColorProfileW\n");
1194             return;
1195         }
1196         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1197
1198         ret = pGetColorDirectoryW( NULL, dest, &size );
1199         ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1200
1201         MSCMS_basenameW( testprofileW, base );
1202
1203         lstrcatW( dest, slash );
1204         lstrcatW( dest, base );
1205
1206         ret = pUninstallColorProfileW( NULL, dest, TRUE );
1207         ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1208
1209         bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1210         ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1211         /* Check if the profile is really gone */
1212         handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1213         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1214         CloseHandle( handle );
1215     }
1216 }
1217
1218 static void test_AssociateColorProfileWithDeviceA(void)
1219 {
1220     BOOL ret;
1221     char profile[MAX_PATH], basename[MAX_PATH];
1222     DWORD error, size = sizeof(profile);
1223     DISPLAY_DEVICE display;
1224     BOOL res;
1225     DISPLAY_DEVICE monitor;
1226
1227     if (testprofile && pEnumDisplayDevicesA)
1228     {
1229         display.cb = sizeof( DISPLAY_DEVICE );
1230         res = pEnumDisplayDevicesA( NULL, 0, &display, 0 );
1231         ok( res, "Can't get display info\n" );
1232
1233         monitor.cb = sizeof( DISPLAY_DEVICE );
1234         res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 );
1235         if (res)
1236         {
1237             SetLastError(0xdeadbeef);
1238             ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1239             error = GetLastError();
1240             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1241             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1242
1243             SetLastError(0xdeadbeef);
1244             ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID );
1245             error = GetLastError();
1246             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1247             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1248
1249             SetLastError(0xdeadbeef);
1250             ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID );
1251             error = GetLastError();
1252             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1253             ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1254
1255             ret = pInstallColorProfileA( NULL, testprofile );
1256             ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1257
1258             ret = pGetColorDirectoryA( NULL, profile, &size );
1259             ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1260
1261             MSCMS_basenameA( testprofile, basename );
1262             lstrcatA( profile, "\\" );
1263             lstrcatA( profile, basename );
1264
1265             ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID );
1266             ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1267
1268             SetLastError(0xdeadbeef);
1269             ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1270             error = GetLastError();
1271             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1272             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1273
1274             SetLastError(0xdeadbeef);
1275             ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID );
1276             error = GetLastError();
1277             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1278             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1279
1280             SetLastError(0xdeadbeef);
1281             ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID );
1282             error = GetLastError();
1283             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1284             ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1285
1286             ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID );
1287             ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1288
1289             ret = pUninstallColorProfileA( NULL, profile, TRUE );
1290             ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1291         }
1292         else
1293             skip("Unable to obtain monitor name\n");
1294     }
1295 }
1296
1297 START_TEST(profile)
1298 {
1299     UINT len;
1300     HANDLE handle;
1301     char path[MAX_PATH], file[MAX_PATH];
1302     char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1303     WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1304     WCHAR fileW[MAX_PATH];
1305     UINT ret;
1306
1307     hmscms = LoadLibraryA( "mscms.dll" );
1308     if (!hmscms) return;
1309
1310     huser32 = LoadLibraryA( "user32.dll" );
1311     if (!huser32)
1312     {
1313         FreeLibrary( hmscms );
1314         return;
1315     }
1316
1317     if (!init_function_ptrs())
1318     {
1319         FreeLibrary( huser32 );
1320         FreeLibrary( hmscms );
1321         return;
1322     }
1323
1324     /* See if we can find the standard color profile */
1325     ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1326     ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1327     ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH, 
1328         "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1329     MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1330     ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH, 
1331         "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1332     lstrcpyA(profilefile2, profilefile1);
1333     lstrcpyW(profilefile2W, profilefile1W);
1334
1335     lstrcatA( profilefile1, profile1 );
1336     lstrcatW( profilefile1W, profile1W );
1337     handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1338
1339     if (handle != INVALID_HANDLE_VALUE)
1340     {
1341         standardprofile = profilefile1;
1342         standardprofileW = profilefile1W;
1343         CloseHandle( handle );
1344     }
1345
1346     lstrcatA( profilefile2, profile2 );
1347     lstrcatW( profilefile2W, profile2W );
1348     handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1349
1350     if (handle != INVALID_HANDLE_VALUE)
1351     {
1352         standardprofile = profilefile2;
1353         standardprofileW = profilefile2W;
1354         CloseHandle( handle );
1355     }
1356
1357     /* If found, create a temporary copy for testing purposes */
1358     if (standardprofile && GetTempPath( sizeof(path), path ))
1359     {
1360         if (GetTempFileName( path, "rgb", 0, file ))
1361         {
1362             if (CopyFileA( standardprofile, file, FALSE ))
1363             {
1364                 testprofile = (LPSTR)&file;
1365
1366                 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1367                 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1368
1369                 testprofileW = (LPWSTR)&fileW;
1370             }
1371         }
1372     }
1373
1374     test_GetColorDirectoryA();
1375     test_GetColorDirectoryW();
1376
1377     test_GetColorProfileElement();
1378     test_GetColorProfileElementTag();
1379
1380     test_GetColorProfileFromHandle();
1381     test_GetColorProfileHeader();
1382
1383     test_GetCountColorProfileElements();
1384
1385     test_GetStandardColorSpaceProfileA();
1386     test_GetStandardColorSpaceProfileW();
1387
1388     test_EnumColorProfilesA();
1389     test_EnumColorProfilesW();
1390
1391     test_InstallColorProfileA();
1392     test_InstallColorProfileW();
1393
1394     test_IsColorProfileTagPresent();
1395
1396     test_OpenColorProfileA();
1397     test_OpenColorProfileW();
1398
1399     test_SetColorProfileElement();
1400     test_SetColorProfileHeader();
1401
1402     test_UninstallColorProfileA();
1403     test_UninstallColorProfileW();
1404
1405     test_AssociateColorProfileWithDeviceA();
1406
1407     /* Clean up */
1408     if (testprofile)
1409         DeleteFileA( testprofile );
1410     
1411     FreeLibrary( huser32 );
1412     FreeLibrary( hmscms );
1413 }