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