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