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