EnumThemeColors() and EnumThemeSizes() actually do not return a single
[wine] / dlls / mscms / tests / profile.c
1 /*
2  * Tests for color profile functions
3  *
4  * Copyright 2004, 2005 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winnls.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "icm.h"
29
30 #include "wine/test.h"
31
32 HMODULE hmscms;
33
34 static BOOL     (WINAPI *pCloseColorProfile)(HPROFILE);
35 static BOOL     (WINAPI *pGetColorDirectoryA)(PCHAR,PCHAR,PDWORD);
36 static BOOL     (WINAPI *pGetColorDirectoryW)(PWCHAR,PWCHAR,PDWORD);
37 static BOOL     (WINAPI *pGetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL);
38 static BOOL     (WINAPI *pGetColorProfileElementTag)(HPROFILE,DWORD,PTAGTYPE);
39 static BOOL     (WINAPI *pGetColorProfileFromHandle)(HPROFILE,PBYTE,PDWORD);
40 static BOOL     (WINAPI *pGetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
41 static BOOL     (WINAPI *pGetCountColorProfileElements)(HPROFILE,PDWORD);
42 static BOOL     (WINAPI *pGetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR,PDWORD);
43 static BOOL     (WINAPI *pGetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR,PDWORD);
44 static BOOL     (WINAPI *pInstallColorProfileA)(PCSTR,PCSTR);
45 static BOOL     (WINAPI *pInstallColorProfileW)(PCWSTR,PCWSTR);
46 static BOOL     (WINAPI *pIsColorProfileTagPresent)(HPROFILE,TAGTYPE,PBOOL);
47 static HPROFILE (WINAPI *pOpenColorProfileA)(PPROFILE,DWORD,DWORD,DWORD);
48 static HPROFILE (WINAPI *pOpenColorProfileW)(PPROFILE,DWORD,DWORD,DWORD);
49 static BOOL     (WINAPI *pSetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID);
50 static BOOL     (WINAPI *pSetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
51 static BOOL     (WINAPI *pSetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR);
52 static BOOL     (WINAPI *pSetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR);
53 static BOOL     (WINAPI *pUninstallColorProfileA)(PCSTR,PCSTR,BOOL);
54 static BOOL     (WINAPI *pUninstallColorProfileW)(PCWSTR,PCWSTR,BOOL);
55
56 #define GETFUNCPTR(func) p##func = (void *)GetProcAddress( hmscms, #func ); \
57     if (!p##func) return FALSE;
58
59 static BOOL init_function_ptrs( void )
60 {
61     GETFUNCPTR( CloseColorProfile )
62     GETFUNCPTR( GetColorDirectoryA )
63     GETFUNCPTR( GetColorDirectoryW )
64     GETFUNCPTR( GetColorProfileElement )
65     GETFUNCPTR( GetColorProfileElementTag )
66     GETFUNCPTR( GetColorProfileFromHandle )
67     GETFUNCPTR( GetColorProfileHeader )
68     GETFUNCPTR( GetCountColorProfileElements )
69     GETFUNCPTR( GetStandardColorSpaceProfileA )
70     GETFUNCPTR( GetStandardColorSpaceProfileW )
71     GETFUNCPTR( InstallColorProfileA )
72     GETFUNCPTR( InstallColorProfileW )
73     GETFUNCPTR( IsColorProfileTagPresent )
74     GETFUNCPTR( OpenColorProfileA )
75     GETFUNCPTR( OpenColorProfileW )
76     GETFUNCPTR( SetColorProfileElement )
77     GETFUNCPTR( SetColorProfileHeader )
78     GETFUNCPTR( SetStandardColorSpaceProfileA )
79     GETFUNCPTR( SetStandardColorSpaceProfileW )
80     GETFUNCPTR( UninstallColorProfileA )
81     GETFUNCPTR( UninstallColorProfileW )
82
83     return TRUE;
84 }
85
86 static const char machine[] = "dummy";
87 static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
88
89 /*  To do any real functionality testing with this suite you need a copy of
90  *  the freely distributable standard RGB color space profile. It comes
91  *  standard with Windows, but on Wine you probably need to install it yourself
92  *  in one of the locations mentioned below. Here's a link to the profile in
93  *  a self extracting zip file:
94  *
95  *  http://download.microsoft.com/download/whistler/hwdev1/1.0/wxp/en-us/ColorProfile.exe
96  */
97
98 /* Two common places to find the standard color space profile, relative
99  * to the system directory.
100  */
101 static const char profile1[] =
102 "\\color\\srgb color space profile.icm";
103 static const char profile2[] =
104 "\\spool\\drivers\\color\\srgb color space profile.icm";
105
106 static const WCHAR profile1W[] =
107 { '\\','c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
108   's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
109 static const WCHAR profile2W[] =
110 { '\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',
111   'c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
112   's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
113
114 static const unsigned char rgbheader[] =
115 { 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02,
116   0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58,
117   0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00,
118   0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00,
119   0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00,
120   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00,
121   0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 };
122
123 static LPSTR standardprofile;
124 static LPWSTR standardprofileW;
125
126 static LPSTR testprofile;
127 static LPWSTR testprofileW;
128
129 #define IS_SEPARATOR(ch)  ((ch) == '\\' || (ch) == '/')
130
131 static void MSCMS_basenameA( LPCSTR path, LPSTR name )
132 {
133     INT i = strlen( path );
134
135     while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
136     strcpy( name, &path[i] );
137 }
138
139 static void MSCMS_basenameW( LPCWSTR path, LPWSTR name )
140 {
141     INT i = lstrlenW( path );
142
143     while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
144     lstrcpyW( name, &path[i] );
145 }
146
147 static void test_GetColorDirectoryA(void)
148 {
149     BOOL ret;
150     DWORD size;
151     char buffer[MAX_PATH];
152
153     /* Parameter checks */
154
155     ret = pGetColorDirectoryA( NULL, NULL, NULL );
156     ok( !ret, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
157
158     size = 0;
159
160     ret = pGetColorDirectoryA( NULL, NULL, &size );
161     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
162
163     size = 0;
164
165     ret = pGetColorDirectoryA( NULL, buffer, &size );
166     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
167
168     size = 1;
169
170     ret = pGetColorDirectoryA( NULL, buffer, &size );
171     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
172
173     /* Functional checks */
174
175     size = sizeof(buffer);
176
177     ret = pGetColorDirectoryA( NULL, buffer, &size );
178     ok( ret && size > 0, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
179 }
180
181 static void test_GetColorDirectoryW(void)
182 {
183     BOOL ret;
184     DWORD size;
185     WCHAR buffer[MAX_PATH];
186
187     /* Parameter checks */
188
189     /* This one crashes win2k
190     
191     ret = pGetColorDirectoryW( NULL, NULL, NULL );
192     ok( !ret, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
193
194      */
195
196     size = 0;
197
198     ret = pGetColorDirectoryW( NULL, NULL, &size );
199     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
200
201     size = 0;
202
203     ret = pGetColorDirectoryW( NULL, buffer, &size );
204     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
205
206     size = 1;
207
208     ret = pGetColorDirectoryW( NULL, buffer, &size );
209     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
210
211     /* Functional checks */
212
213     size = sizeof(buffer);
214
215     ret = pGetColorDirectoryW( NULL, buffer, &size );
216     ok( ret && size > 0, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
217 }
218
219 static void test_GetColorProfileElement(void)
220 {
221     if (standardprofile)
222     {
223         PROFILE profile;
224         HPROFILE handle;
225         BOOL ret, ref;
226         DWORD size;
227         TAGTYPE tag = 0x63707274;  /* 'cprt' */
228         static char buffer[51];
229         static const char expect[] =
230             { 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70,
231               0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
232               0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74,
233               0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43,
234               0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x00 };
235
236         profile.dwType = PROFILE_FILENAME;
237         profile.pProfileData = standardprofile;
238         profile.cbDataSize = strlen(standardprofile);
239
240         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
241         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
242
243         /* Parameter checks */
244
245         ret = pGetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
246         ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
247
248         ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
249         ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
250
251         size = 0;
252
253         ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
254         ok( !ret && size > 0, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
255
256         size = sizeof(buffer);
257
258         /* Functional checks */
259
260         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
261         ok( ret && size > 0, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
262
263         ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
264
265         pCloseColorProfile( handle );
266     }
267 }
268
269 static void test_GetColorProfileElementTag(void)
270 {
271     if (standardprofile)
272     {
273         PROFILE profile;
274         HPROFILE handle;
275         BOOL ret;
276         DWORD index = 1;
277         TAGTYPE tag, expect = 0x63707274;  /* 'cprt' */
278
279         profile.dwType = PROFILE_FILENAME;
280         profile.pProfileData = standardprofile;
281         profile.cbDataSize = strlen(standardprofile);
282
283         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
284         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
285
286         /* Parameter checks */
287
288         ret = pGetColorProfileElementTag( NULL, index, &tag );
289         ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
290
291         ret = pGetColorProfileElementTag( handle, 0, &tag );
292         ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
293
294         ret = pGetColorProfileElementTag( handle, index, NULL );
295         ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
296
297         ret = pGetColorProfileElementTag( handle, 18, NULL );
298         ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
299
300         /* Functional checks */
301
302         ret = pGetColorProfileElementTag( handle, index, &tag );
303         ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld)\n",
304             GetLastError() );
305
306         pCloseColorProfile( handle );
307     }
308 }
309
310 static void test_GetColorProfileFromHandle(void)
311 {
312     if (testprofile)
313     {
314         PROFILE profile;
315         HPROFILE handle;
316         DWORD size;
317         BOOL ret;
318         static const unsigned char expect[] =
319             { 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
320               0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
321               0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
322               0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
323               0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
324               0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325               0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
326               0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 };
327
328         unsigned char *buffer;
329
330         profile.dwType = PROFILE_FILENAME;
331         profile.pProfileData = testprofile;
332         profile.cbDataSize = strlen(testprofile);
333
334         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
335         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
336
337         /* Parameter checks */
338
339         size = 0;
340
341         ret = pGetColorProfileFromHandle( handle, NULL, &size );
342         ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%ld)\n", GetLastError() );
343
344         buffer = HeapAlloc( GetProcessHeap(), 0, size );
345
346         if (buffer)
347         {
348             ret = pGetColorProfileFromHandle( NULL, buffer, &size );
349             ok( !ret, "GetColorProfileFromHandle() succeeded (%ld)\n", GetLastError() );
350
351             ret = pGetColorProfileFromHandle( handle, buffer, NULL );
352             ok( !ret, "GetColorProfileFromHandle() succeeded (%ld)\n", GetLastError() );
353
354             /* Functional checks */
355
356             ret = pGetColorProfileFromHandle( handle, buffer, &size );
357             ok( ret && size > 0, "GetColorProfileFromHandle() failed (%ld)\n", GetLastError() );
358
359             ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" );
360
361             HeapFree( GetProcessHeap(), 0, buffer );
362         }
363
364         pCloseColorProfile( handle );
365     }
366 }
367
368 static void test_GetColorProfileHeader(void)
369 {
370     if (testprofile)
371     {
372         PROFILE profile;
373         HPROFILE handle;
374         BOOL ret;
375         PROFILEHEADER header;
376
377         profile.dwType = PROFILE_FILENAME;
378         profile.pProfileData = testprofile;
379         profile.cbDataSize = strlen(testprofile);
380
381         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
382         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
383
384         /* Parameter checks */
385
386         ret = pGetColorProfileHeader( NULL, NULL );
387         ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
388
389         ret = pGetColorProfileHeader( NULL, &header );
390         ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
391
392         ret = pGetColorProfileHeader( handle, NULL );
393         ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
394
395         /* Functional checks */
396
397         ret = pGetColorProfileHeader( handle, &header );
398         ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
399
400         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
401
402         pCloseColorProfile( handle );
403     }
404 }
405
406 static void test_GetCountColorProfileElements(void)
407 {
408     if (standardprofile)
409     {
410         PROFILE profile;
411         HPROFILE handle;
412         BOOL ret;
413         DWORD count, expect = 17;
414
415         profile.dwType = PROFILE_FILENAME;
416         profile.pProfileData = standardprofile;
417         profile.cbDataSize = strlen(standardprofile);
418
419         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
420         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
421
422         /* Parameter checks */
423
424         ret = pGetCountColorProfileElements( NULL, &count );
425         ok( !ret, "GetCountColorProfileElements() succeeded (%ld)\n",
426             GetLastError() );
427
428         ret = pGetCountColorProfileElements( handle, NULL );
429         ok( !ret, "GetCountColorProfileElements() succeeded (%ld)\n",
430             GetLastError() );
431
432         /* Functional checks */
433
434         ret = pGetCountColorProfileElements( handle, &count );
435         ok( ret && count == expect,
436             "GetCountColorProfileElements() failed (%ld)\n", GetLastError() );
437
438         pCloseColorProfile( handle );
439     }
440 }
441
442 static void test_GetStandardColorSpaceProfileA(void)
443 {
444     BOOL ret;
445     DWORD size;
446     CHAR oldprofile[MAX_PATH];
447     CHAR newprofile[MAX_PATH];
448
449     /* Parameter checks */
450
451     ret = pGetStandardColorSpaceProfileA( NULL, 0, newprofile, NULL );
452     ok( !ret, "GetStandardColorSpaceProfileA() succeeded (%ld)\n", GetLastError() );
453
454     ret = pGetStandardColorSpaceProfileA( machine, 0, newprofile, &size );
455     ok( !ret, "GetStandardColorSpaceProfileA() succeeded (%ld)\n", GetLastError() );
456
457     size = 0;
458
459     ret = pGetStandardColorSpaceProfileA( NULL, 0, NULL, &size );
460     ok( !ret, "GetStandardColorSpaceProfileA() succeeded (%ld)\n", GetLastError() );
461
462     size = sizeof(newprofile);
463
464     ret = pGetStandardColorSpaceProfileA( NULL, 0, newprofile, &size );
465     ok( !ret, "GetStandardColorSpaceProfileA() succeeded (%ld)\n", GetLastError() );
466
467     /* Functional checks */
468
469     if (standardprofile)
470     {
471         size = sizeof(oldprofile);
472
473         ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
474         ok( ret, "GetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
475
476         ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
477         ok( ret, "SetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
478
479         size = sizeof(newprofile);
480
481         ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
482         ok( ret, "GetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
483
484         ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
485
486         ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
487         ok( ret, "SetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
488     }
489 }
490
491 static void test_GetStandardColorSpaceProfileW(void)
492 {
493     BOOL ret;
494     DWORD size;
495     WCHAR oldprofile[MAX_PATH];
496     WCHAR newprofile[MAX_PATH];
497
498     /* Parameter checks */
499
500     ret = pGetStandardColorSpaceProfileW( NULL, 0, newprofile, NULL );
501     ok( !ret, "GetStandardColorSpaceProfileW() succeeded (%ld)\n", GetLastError() );
502
503     ret = pGetStandardColorSpaceProfileW( machineW, 0, newprofile, &size );
504     ok( !ret, "GetStandardColorSpaceProfileW() succeeded (%ld)\n", GetLastError() );
505
506     size = 0;
507
508     ret = pGetStandardColorSpaceProfileW( NULL, 0, NULL, &size );
509     ok( !ret, "GetStandardColorSpaceProfileW() succeeded (%ld)\n", GetLastError() );
510
511     size = sizeof(newprofile);
512
513     ret = pGetStandardColorSpaceProfileW( NULL, 0, newprofile, &size );
514     ok( !ret, "GetStandardColorSpaceProfileW() succeeded (%ld)\n", GetLastError() );
515
516     /* Functional checks */
517
518     if (standardprofileW)
519     {
520         size = sizeof(oldprofile);
521
522         ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
523         ok( ret, "GetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
524
525         ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
526         ok( ret, "SetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
527
528         size = sizeof(newprofile);
529
530         ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
531         ok( ret, "GetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
532
533         ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
534
535         ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
536         ok( ret, "SetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
537     }
538 }
539
540 static void test_InstallColorProfileA(void)
541 {
542     BOOL ret;
543
544     /* Parameter checks */
545
546     ret = pInstallColorProfileA( NULL, NULL );
547     ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
548
549     ret = pInstallColorProfileA( machine, NULL );
550     ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
551
552     ret = pInstallColorProfileA( NULL, machine );
553     ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
554
555     if (standardprofile)
556     {
557         ret = pInstallColorProfileA( NULL, standardprofile );
558         ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
559     }
560
561     /* Functional checks */
562
563     if (testprofile)
564     {
565         CHAR dest[MAX_PATH], base[MAX_PATH];
566         DWORD size = sizeof(dest);
567         CHAR slash[] = "\\";
568         HANDLE handle;
569
570         ret = pInstallColorProfileA( NULL, testprofile );
571         ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
572
573         ret = pGetColorDirectoryA( NULL, dest, &size );
574         ok( ret, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
575
576         MSCMS_basenameA( testprofile, base );
577
578         lstrcatA( dest, slash );
579         lstrcatA( dest, base );
580
581         /* Check if the profile is really there */ 
582         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
583         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%ld)\n", GetLastError() );
584         CloseHandle( handle );
585         
586         ret = pUninstallColorProfileA( NULL, dest, TRUE );
587         ok( ret, "UninstallColorProfileA() failed (%ld)\n", GetLastError() );
588     }
589 }
590
591 static void test_InstallColorProfileW(void)
592 {
593     BOOL ret;
594
595     /* Parameter checks */
596
597     ret = pInstallColorProfileW( NULL, NULL );
598     ok( !ret, "InstallColorProfileW() succeeded (%ld)\n", GetLastError() );
599
600     ret = pInstallColorProfileW( machineW, NULL );
601     ok( !ret, "InstallColorProfileW() succeeded (%ld)\n", GetLastError() );
602
603     ret = pInstallColorProfileW( NULL, machineW );
604     ok( !ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
605
606     if (standardprofileW)
607     {
608         ret = pInstallColorProfileW( NULL, standardprofileW );
609         ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
610     }
611
612     /* Functional checks */
613
614     if (testprofileW)
615     {
616         WCHAR dest[MAX_PATH], base[MAX_PATH];
617         DWORD size = sizeof(dest);
618         WCHAR slash[] = { '\\', 0 };
619         HANDLE handle;
620
621         ret = pInstallColorProfileW( NULL, testprofileW );
622         ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
623
624         ret = pGetColorDirectoryW( NULL, dest, &size );
625         ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
626
627         MSCMS_basenameW( testprofileW, base );
628
629         lstrcatW( dest, slash );
630         lstrcatW( dest, base );
631
632         /* Check if the profile is really there */
633         handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
634         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%ld)\n", GetLastError() );
635         CloseHandle( handle );
636
637         ret = pUninstallColorProfileW( NULL, dest, TRUE );
638         ok( ret, "UninstallColorProfileW() failed (%ld)\n", GetLastError() );
639     }
640 }
641
642 static void test_IsColorProfileTagPresent(void)
643 {
644     if (standardprofile)
645     {
646         PROFILE profile;
647         HPROFILE handle;
648         BOOL ret, present;
649         TAGTYPE tag;
650
651         profile.dwType = PROFILE_FILENAME;
652         profile.pProfileData = standardprofile;
653         profile.cbDataSize = strlen(standardprofile);
654
655         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
656         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
657
658         /* Parameter checks */
659
660         tag = 0;
661
662         ret = pIsColorProfileTagPresent( handle, tag, &present );
663         ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
664
665         tag = 0x63707274;  /* 'cprt' */
666
667         ret = pIsColorProfileTagPresent( NULL, tag, &present );
668         ok( !ret, "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
669
670         ret = pIsColorProfileTagPresent( handle, tag, NULL );
671         ok( !ret, "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
672
673         /* Functional checks */
674
675         ret = pIsColorProfileTagPresent( handle, tag, &present );
676         ok( ret && present, "IsColorProfileTagPresent() failed (%ld)\n", GetLastError() );
677
678         pCloseColorProfile( handle );
679     }
680 }
681
682 static void test_OpenColorProfileA(void)
683 {
684     PROFILE profile;
685     HPROFILE handle;
686     BOOL ret;
687
688     profile.dwType = PROFILE_FILENAME;
689     profile.pProfileData = NULL;
690     profile.cbDataSize = 0;
691
692     /* Parameter checks */
693
694     handle = pOpenColorProfileA( NULL, 0, 0, 0 );
695     ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
696
697     handle = pOpenColorProfileA( &profile, 0, 0, 0 );
698     ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
699
700     handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
701     ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
702
703     handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
704     ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
705
706     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
707
708     if (standardprofile)
709     {
710         profile.pProfileData = standardprofile;
711         profile.cbDataSize = strlen(standardprofile);
712
713         handle = pOpenColorProfileA( &profile, 0, 0, 0 );
714         ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
715
716         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
717         ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
718
719         handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
720         ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
721
722         /* Functional checks */
723
724         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
725         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
726
727         ret = pCloseColorProfile( handle );
728         ok( ret, "CloseColorProfile() failed (%ld)\n", GetLastError() );
729     }
730 }
731
732 static void test_OpenColorProfileW(void)
733 {
734     PROFILE profile;
735     HPROFILE handle;
736     BOOL ret;
737
738     profile.dwType = PROFILE_FILENAME;
739     profile.pProfileData = NULL;
740     profile.cbDataSize = 0;
741
742     /* Parameter checks */
743
744     handle = pOpenColorProfileW( NULL, 0, 0, 0 );
745     ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
746
747     handle = pOpenColorProfileW( &profile, 0, 0, 0 );
748     ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
749
750     handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
751     ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
752
753     handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
754     ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
755
756     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
757
758     if (standardprofileW)
759     {
760         profile.pProfileData = standardprofileW;
761         profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
762
763         handle = pOpenColorProfileW( &profile, 0, 0, 0 );
764         ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
765
766         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
767         ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
768
769         handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
770         ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
771
772         /* Functional checks */
773
774         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
775         ok( handle != NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
776
777         ret = pCloseColorProfile( handle );
778         ok( ret, "CloseColorProfile() failed (%ld)\n", GetLastError() );
779     }
780 }
781
782 static void test_SetColorProfileElement(void)
783 {
784     if (testprofile)
785     {
786         PROFILE profile;
787         HPROFILE handle;
788         DWORD size;
789         BOOL ret, ref;
790
791         TAGTYPE tag = 0x63707274;  /* 'cprt' */
792         static char data[] = "(c) The Wine Project";
793         static char buffer[51];
794
795         profile.dwType = PROFILE_FILENAME;
796         profile.pProfileData = testprofile;
797         profile.cbDataSize = strlen(testprofile);
798
799         /* Parameter checks */
800
801         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
802         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
803
804         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
805         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
806
807         pCloseColorProfile( handle );
808
809         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
810         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
811
812         ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
813         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
814
815         ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
816         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
817
818         ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
819         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
820
821         ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
822         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
823
824         /* Functional checks */
825
826         size = sizeof(data);
827
828         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
829         ok( ret, "SetColorProfileElement() failed (%ld)\n", GetLastError() );
830
831         size = sizeof(buffer);
832
833         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
834         ok( ret && size > 0, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
835
836         ok( !memcmp( data, buffer, sizeof(data) ),
837             "Unexpected tag data, expected %s, got %s (%ld)\n",
838             data, buffer, GetLastError() );
839
840         pCloseColorProfile( handle );
841     }
842 }
843
844 static void test_SetColorProfileHeader(void)
845 {
846     if (testprofile)
847     {
848         PROFILE profile;
849         HPROFILE handle;
850         BOOL ret;
851         PROFILEHEADER header;
852
853         profile.dwType = PROFILE_FILENAME;
854         profile.pProfileData = testprofile;
855         profile.cbDataSize = strlen(testprofile);
856
857         header.phSize = 0x00000c48;
858         header.phCMMType = 0x4c696e6f;
859         header.phVersion = 0x02100000;
860         header.phClass = 0x6d6e7472;
861         header.phDataColorSpace = 0x52474220;
862         header.phConnectionSpace  = 0x58595a20;
863         header.phDateTime[0] = 0x07ce0002;
864         header.phDateTime[1] = 0x00090006;
865         header.phDateTime[2] = 0x00310000;
866         header.phSignature = 0x61637370;
867         header.phPlatform = 0x4d534654;
868         header.phProfileFlags = 0x00000000;
869         header.phManufacturer = 0x49454320;
870         header.phModel = 0x73524742;
871         header.phAttributes[0] = 0x00000000;
872         header.phAttributes[1] = 0x00000000;
873         header.phRenderingIntent = 0x00000000;
874         header.phIlluminant.ciexyzX = 0x0000f6d6;
875         header.phIlluminant.ciexyzY = 0x00010000;
876         header.phIlluminant.ciexyzZ = 0x0000d32d;
877         header.phCreator = 0x48502020;
878
879         /* Parameter checks */
880
881         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
882         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
883
884         ret = pSetColorProfileHeader( handle, &header );
885         ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
886
887         pCloseColorProfile( handle );
888
889         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
890         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
891
892         ret = pSetColorProfileHeader( NULL, NULL );
893         ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
894
895         ret = pSetColorProfileHeader( handle, NULL );
896         ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
897
898         ret = pSetColorProfileHeader( NULL, &header );
899         ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
900
901         /* Functional checks */
902
903         ret = pSetColorProfileHeader( handle, &header );
904         ok( ret, "SetColorProfileHeader() failed (%ld)\n", GetLastError() );
905
906         ret = pGetColorProfileHeader( handle, &header );
907         ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
908
909         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
910
911         pCloseColorProfile( handle );
912     }
913 }
914
915 static void test_UninstallColorProfileA(void)
916 {
917     BOOL ret;
918
919     /* Parameter checks */
920
921     ret = pUninstallColorProfileA( NULL, NULL, FALSE );
922     ok( !ret, "UninstallColorProfileA() succeeded (%ld)\n", GetLastError() );
923
924     ret = pUninstallColorProfileA( machine, NULL, FALSE );
925     ok( !ret, "UninstallColorProfileA() succeeded (%ld)\n", GetLastError() );
926
927     /* Functional checks */
928
929     if (testprofile)
930     {
931         CHAR dest[MAX_PATH], base[MAX_PATH];
932         DWORD size = sizeof(dest);
933         CHAR slash[] = "\\";
934         HANDLE handle;
935
936         ret = pInstallColorProfileA( NULL, testprofile );
937         ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
938
939         ret = pGetColorDirectoryA( NULL, dest, &size );
940         ok( ret, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
941
942         MSCMS_basenameA( testprofile, base );
943
944         lstrcatA( dest, slash );
945         lstrcatA( dest, base );
946
947         ret = pUninstallColorProfileA( NULL, dest, TRUE );
948         ok( ret, "UninstallColorProfileA() failed (%ld)\n", GetLastError() );
949
950         /* Check if the profile is really gone */
951         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
952         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%ld)\n", GetLastError() );
953         CloseHandle( handle );
954     }
955 }
956
957 static void test_UninstallColorProfileW(void)
958 {
959     BOOL ret;
960
961     /* Parameter checks */
962
963     ret = pUninstallColorProfileW( NULL, NULL, FALSE );
964     ok( !ret, "UninstallColorProfileW() succeeded (%ld)\n", GetLastError() );
965
966     ret = pUninstallColorProfileW( machineW, NULL, FALSE );
967     ok( !ret, "UninstallColorProfileW() succeeded (%ld)\n", GetLastError() );
968
969     /* Functional checks */
970
971     if (testprofileW)
972     {
973         WCHAR dest[MAX_PATH], base[MAX_PATH];
974         DWORD size = sizeof(dest);
975         WCHAR slash[] = { '\\', 0 };
976         HANDLE handle;
977
978         ret = pInstallColorProfileW( NULL, testprofileW );
979         ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
980
981         ret = pGetColorDirectoryW( NULL, dest, &size );
982         ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
983
984         MSCMS_basenameW( testprofileW, base );
985
986         lstrcatW( dest, slash );
987         lstrcatW( dest, base );
988
989         ret = pUninstallColorProfileW( NULL, dest, TRUE );
990         ok( ret, "UninstallColorProfileW() failed (%ld)\n", GetLastError() );
991
992         /* Check if the profile is really gone */
993         handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
994         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%ld)\n", GetLastError() );
995         CloseHandle( handle );
996     }
997 }
998
999 START_TEST(profile)
1000 {
1001     UINT len;
1002     HANDLE handle;
1003     char path[MAX_PATH], file[MAX_PATH];
1004     char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1005     WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1006     WCHAR fileW[MAX_PATH];
1007
1008     hmscms = LoadLibraryA( "mscms.dll" );
1009     if (!hmscms) return;
1010
1011     if (!init_function_ptrs())
1012     {
1013         FreeLibrary( hmscms );
1014         return;
1015     }
1016
1017     /* See if we can find the standard color profile */
1018     GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1019     GetSystemDirectoryW( profilefile1W, sizeof(profilefile1W) / sizeof(WCHAR) );
1020     lstrcatA( profilefile1, profile1 );
1021     lstrcatW( profilefile1W, profile1W );
1022     handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1023
1024     if (handle != INVALID_HANDLE_VALUE)
1025     {
1026         standardprofile = profilefile1;
1027         standardprofileW = profilefile1W;
1028         CloseHandle( handle );
1029     }
1030
1031     GetSystemDirectoryA( profilefile2, sizeof(profilefile2) );
1032     GetSystemDirectoryW( profilefile2W, sizeof(profilefile2W) / sizeof(WCHAR) );
1033     lstrcatA( profilefile2, profile2 );
1034     lstrcatW( profilefile2W, profile2W );
1035     handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1036
1037     if (handle != INVALID_HANDLE_VALUE)
1038     {
1039         standardprofile = profilefile2;
1040         standardprofileW = profilefile2W;
1041         CloseHandle( handle );
1042     }
1043
1044     /* If found, create a temporary copy for testing purposes */
1045     if (standardprofile && GetTempPath( sizeof(path), path ))
1046     {
1047         if (GetTempFileName( path, "rgb", 0, file ))
1048         {
1049             if (CopyFileA( standardprofile, file, FALSE ))
1050             {
1051                 testprofile = (LPSTR)&file;
1052
1053                 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1054                 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1055
1056                 testprofileW = (LPWSTR)&fileW;
1057             }
1058         }
1059     }
1060
1061     test_GetColorDirectoryA();
1062     test_GetColorDirectoryW();
1063
1064     test_GetColorProfileElement();
1065     test_GetColorProfileElementTag();
1066
1067     test_GetColorProfileFromHandle();
1068     test_GetColorProfileHeader();
1069
1070     test_GetCountColorProfileElements();
1071
1072     test_GetStandardColorSpaceProfileA();
1073     test_GetStandardColorSpaceProfileW();
1074
1075     test_InstallColorProfileA();
1076     test_InstallColorProfileW();
1077
1078     test_IsColorProfileTagPresent();
1079
1080     test_OpenColorProfileA();
1081     test_OpenColorProfileW();
1082
1083     test_SetColorProfileElement();
1084     test_SetColorProfileHeader();
1085
1086     test_UninstallColorProfileA();
1087     test_UninstallColorProfileW();
1088
1089     /* Clean up */
1090     if (testprofile)
1091         DeleteFileA( testprofile );
1092     
1093     FreeLibrary( hmscms );
1094 }