mscms/tests: Fix wrong test for failure.
[wine] / dlls / mscms / tests / profile.c
1 /*
2  * Tests for color profile functions
3  *
4  * Copyright 2004, 2005, 2006 Hans Leidekker
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winreg.h"
26 #include "winnls.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "icm.h"
30
31 #include "wine/test.h"
32
33 HMODULE hmscms;
34
35 static BOOL     (WINAPI *pCloseColorProfile)(HPROFILE);
36 static BOOL     (WINAPI *pGetColorDirectoryA)(PCHAR,PCHAR,PDWORD);
37 static BOOL     (WINAPI *pGetColorDirectoryW)(PWCHAR,PWCHAR,PDWORD);
38 static BOOL     (WINAPI *pGetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL);
39 static BOOL     (WINAPI *pGetColorProfileElementTag)(HPROFILE,DWORD,PTAGTYPE);
40 static BOOL     (WINAPI *pGetColorProfileFromHandle)(HPROFILE,PBYTE,PDWORD);
41 static BOOL     (WINAPI *pGetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
42 static BOOL     (WINAPI *pGetCountColorProfileElements)(HPROFILE,PDWORD);
43 static BOOL     (WINAPI *pGetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR,PDWORD);
44 static BOOL     (WINAPI *pGetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR,PDWORD);
45 static BOOL     (WINAPI *pEnumColorProfilesA)(PCSTR,PENUMTYPEA,PBYTE,PDWORD,PDWORD);
46 static BOOL     (WINAPI *pEnumColorProfilesW)(PCWSTR,PENUMTYPEW,PBYTE,PDWORD,PDWORD);
47 static BOOL     (WINAPI *pInstallColorProfileA)(PCSTR,PCSTR);
48 static BOOL     (WINAPI *pInstallColorProfileW)(PCWSTR,PCWSTR);
49 static BOOL     (WINAPI *pIsColorProfileTagPresent)(HPROFILE,TAGTYPE,PBOOL);
50 static HPROFILE (WINAPI *pOpenColorProfileA)(PPROFILE,DWORD,DWORD,DWORD);
51 static HPROFILE (WINAPI *pOpenColorProfileW)(PPROFILE,DWORD,DWORD,DWORD);
52 static BOOL     (WINAPI *pSetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID);
53 static BOOL     (WINAPI *pSetColorProfileHeader)(HPROFILE,PPROFILEHEADER);
54 static BOOL     (WINAPI *pSetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR);
55 static BOOL     (WINAPI *pSetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR);
56 static BOOL     (WINAPI *pUninstallColorProfileA)(PCSTR,PCSTR,BOOL);
57 static BOOL     (WINAPI *pUninstallColorProfileW)(PCWSTR,PCWSTR,BOOL);
58
59 #define GETFUNCPTR(func) p##func = (void *)GetProcAddress( hmscms, #func ); \
60     if (!p##func) return FALSE;
61
62 static BOOL init_function_ptrs( void )
63 {
64     GETFUNCPTR( CloseColorProfile )
65     GETFUNCPTR( GetColorDirectoryA )
66     GETFUNCPTR( GetColorDirectoryW )
67     GETFUNCPTR( GetColorProfileElement )
68     GETFUNCPTR( GetColorProfileElementTag )
69     GETFUNCPTR( GetColorProfileFromHandle )
70     GETFUNCPTR( GetColorProfileHeader )
71     GETFUNCPTR( GetCountColorProfileElements )
72     GETFUNCPTR( GetStandardColorSpaceProfileA )
73     GETFUNCPTR( GetStandardColorSpaceProfileW )
74     GETFUNCPTR( EnumColorProfilesA )
75     GETFUNCPTR( EnumColorProfilesW )
76     GETFUNCPTR( InstallColorProfileA )
77     GETFUNCPTR( InstallColorProfileW )
78     GETFUNCPTR( IsColorProfileTagPresent )
79     GETFUNCPTR( OpenColorProfileA )
80     GETFUNCPTR( OpenColorProfileW )
81     GETFUNCPTR( SetColorProfileElement )
82     GETFUNCPTR( SetColorProfileHeader )
83     GETFUNCPTR( SetStandardColorSpaceProfileA )
84     GETFUNCPTR( SetStandardColorSpaceProfileW )
85     GETFUNCPTR( UninstallColorProfileA )
86     GETFUNCPTR( UninstallColorProfileW )
87
88     return TRUE;
89 }
90
91 static const char machine[] = "dummy";
92 static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
93
94 /*  To do any real functionality testing with this suite you need a copy of
95  *  the freely distributable standard RGB color space profile. It comes
96  *  standard with Windows, but on Wine you probably need to install it yourself
97  *  in one of the locations mentioned below. Here's a link to the profile in
98  *  a self extracting zip file:
99  *
100  *  http://download.microsoft.com/download/whistler/hwdev1/1.0/wxp/en-us/ColorProfile.exe
101  */
102
103 /* Two common places to find the standard color space profile, relative
104  * to the system directory.
105  */
106 static const char profile1[] =
107 "\\color\\srgb color space profile.icm";
108 static const char profile2[] =
109 "\\spool\\drivers\\color\\srgb color space profile.icm";
110
111 static const WCHAR profile1W[] =
112 { '\\','c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
113   's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
114 static const WCHAR profile2W[] =
115 { '\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',
116   'c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
117   's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
118
119 static const unsigned char rgbheader[] =
120 { 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02,
121   0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58,
122   0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00,
123   0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00,
124   0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00,
125   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00,
126   0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 };
127
128 static LPSTR standardprofile;
129 static LPWSTR standardprofileW;
130
131 static LPSTR testprofile;
132 static LPWSTR testprofileW;
133
134 #define IS_SEPARATOR(ch)  ((ch) == '\\' || (ch) == '/')
135
136 static void MSCMS_basenameA( LPCSTR path, LPSTR name )
137 {
138     INT i = strlen( path );
139
140     while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
141     strcpy( name, &path[i] );
142 }
143
144 static void MSCMS_basenameW( LPCWSTR path, LPWSTR name )
145 {
146     INT i = lstrlenW( path );
147
148     while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--;
149     lstrcpyW( name, &path[i] );
150 }
151
152 static void test_GetColorDirectoryA(void)
153 {
154     BOOL ret;
155     DWORD size;
156     char buffer[MAX_PATH];
157
158     /* Parameter checks */
159
160     ret = pGetColorDirectoryA( NULL, NULL, NULL );
161     ok( !ret, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
162
163     size = 0;
164
165     ret = pGetColorDirectoryA( NULL, NULL, &size );
166     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
167
168     size = 0;
169
170     ret = pGetColorDirectoryA( NULL, buffer, &size );
171     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
172
173     size = 1;
174
175     ret = pGetColorDirectoryA( NULL, buffer, &size );
176     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%d)\n", GetLastError() );
177
178     /* Functional checks */
179
180     size = sizeof(buffer);
181
182     ret = pGetColorDirectoryA( NULL, buffer, &size );
183     ok( ret && size > 0, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
184 }
185
186 static void test_GetColorDirectoryW(void)
187 {
188     BOOL ret;
189     DWORD size;
190     WCHAR buffer[MAX_PATH];
191
192     /* Parameter checks */
193
194     /* This one crashes win2k
195     
196     ret = pGetColorDirectoryW( NULL, NULL, NULL );
197     ok( !ret, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
198
199      */
200
201     size = 0;
202
203     ret = pGetColorDirectoryW( NULL, NULL, &size );
204     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
205
206     size = 0;
207
208     ret = pGetColorDirectoryW( NULL, buffer, &size );
209     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
210
211     size = 1;
212
213     ret = pGetColorDirectoryW( NULL, buffer, &size );
214     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%d)\n", GetLastError() );
215
216     /* Functional checks */
217
218     size = sizeof(buffer);
219
220     ret = pGetColorDirectoryW( NULL, buffer, &size );
221     ok( ret && size > 0, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
222 }
223
224 static void test_GetColorProfileElement(void)
225 {
226     if (standardprofile)
227     {
228         PROFILE profile;
229         HPROFILE handle;
230         BOOL ret, ref;
231         DWORD size;
232         TAGTYPE tag = 0x63707274;  /* 'cprt' */
233         static char buffer[51];
234         static const char expect[] =
235             { 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70,
236               0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
237               0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74,
238               0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43,
239               0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x00 };
240
241         profile.dwType = PROFILE_FILENAME;
242         profile.pProfileData = standardprofile;
243         profile.cbDataSize = strlen(standardprofile);
244
245         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
246         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
247
248         /* Parameter checks */
249
250         ret = pGetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
251         ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
252
253         ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
254         ok( !ret, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
255
256         size = 0;
257
258         ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
259         ok( !ret && size > 0, "GetColorProfileElement() succeeded (%d)\n", GetLastError() );
260
261         size = sizeof(buffer);
262
263         /* Functional checks */
264
265         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
266         ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
267
268         ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
269
270         pCloseColorProfile( handle );
271     }
272 }
273
274 static void test_GetColorProfileElementTag(void)
275 {
276     if (standardprofile)
277     {
278         PROFILE profile;
279         HPROFILE handle;
280         BOOL ret;
281         DWORD index = 1;
282         TAGTYPE tag, expect = 0x63707274;  /* 'cprt' */
283
284         profile.dwType = PROFILE_FILENAME;
285         profile.pProfileData = standardprofile;
286         profile.cbDataSize = strlen(standardprofile);
287
288         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
289         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
290
291         /* Parameter checks */
292
293         ret = pGetColorProfileElementTag( NULL, index, &tag );
294         ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
295
296         ret = pGetColorProfileElementTag( handle, 0, &tag );
297         ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
298
299         ret = pGetColorProfileElementTag( handle, index, NULL );
300         ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
301
302         ret = pGetColorProfileElementTag( handle, 18, NULL );
303         ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() );
304
305         /* Functional checks */
306
307         ret = pGetColorProfileElementTag( handle, index, &tag );
308         ok( ret && tag == expect, "GetColorProfileElementTag() failed (%d)\n",
309             GetLastError() );
310
311         pCloseColorProfile( handle );
312     }
313 }
314
315 static void test_GetColorProfileFromHandle(void)
316 {
317     if (testprofile)
318     {
319         PROFILE profile;
320         HPROFILE handle;
321         DWORD size;
322         BOOL ret;
323         static const unsigned char expect[] =
324             { 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
325               0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
326               0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
327               0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
328               0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
329               0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330               0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
331               0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 };
332
333         unsigned char *buffer;
334
335         profile.dwType = PROFILE_FILENAME;
336         profile.pProfileData = testprofile;
337         profile.cbDataSize = strlen(testprofile);
338
339         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
340         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
341
342         /* Parameter checks */
343
344         size = 0;
345
346         ret = pGetColorProfileFromHandle( handle, NULL, &size );
347         ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
348
349         buffer = HeapAlloc( GetProcessHeap(), 0, size );
350
351         if (buffer)
352         {
353             ret = pGetColorProfileFromHandle( NULL, buffer, &size );
354             ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
355
356             ret = pGetColorProfileFromHandle( handle, buffer, NULL );
357             ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() );
358
359             /* Functional checks */
360
361             ret = pGetColorProfileFromHandle( handle, buffer, &size );
362             ok( ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() );
363
364             ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" );
365
366             HeapFree( GetProcessHeap(), 0, buffer );
367         }
368
369         pCloseColorProfile( handle );
370     }
371 }
372
373 static void test_GetColorProfileHeader(void)
374 {
375     if (testprofile)
376     {
377         PROFILE profile;
378         HPROFILE handle;
379         BOOL ret;
380         PROFILEHEADER header;
381
382         profile.dwType = PROFILE_FILENAME;
383         profile.pProfileData = testprofile;
384         profile.cbDataSize = strlen(testprofile);
385
386         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
387         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
388
389         /* Parameter checks */
390
391         ret = pGetColorProfileHeader( NULL, NULL );
392         ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
393
394         ret = pGetColorProfileHeader( NULL, &header );
395         ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
396
397         if (0) /* Crashes on Vista */
398         {
399             ret = pGetColorProfileHeader( handle, NULL );
400             ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() );
401         }
402
403         /* Functional checks */
404
405         ret = pGetColorProfileHeader( handle, &header );
406         ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
407
408         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
409
410         pCloseColorProfile( handle );
411     }
412 }
413
414 static void test_GetCountColorProfileElements(void)
415 {
416     if (standardprofile)
417     {
418         PROFILE profile;
419         HPROFILE handle;
420         BOOL ret;
421         DWORD count, expect = 17;
422
423         profile.dwType = PROFILE_FILENAME;
424         profile.pProfileData = standardprofile;
425         profile.cbDataSize = strlen(standardprofile);
426
427         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
428         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
429
430         /* Parameter checks */
431
432         ret = pGetCountColorProfileElements( NULL, &count );
433         ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
434             GetLastError() );
435
436         ret = pGetCountColorProfileElements( handle, NULL );
437         ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n",
438             GetLastError() );
439
440         /* Functional checks */
441
442         ret = pGetCountColorProfileElements( handle, &count );
443         ok( ret && count == expect,
444             "GetCountColorProfileElements() failed (%d)\n", GetLastError() );
445
446         pCloseColorProfile( handle );
447     }
448 }
449
450 typedef struct colorspace_description_struct {
451     DWORD dwID;
452     const char *szName;
453     BOOL registered;
454     char filename[MAX_PATH];
455 } colorspace_descr;
456
457 #define describe_colorspace(id) {id, #id, FALSE, ""}
458
459 colorspace_descr known_colorspaces[] = { 
460     describe_colorspace(SPACE_XYZ),
461     describe_colorspace(SPACE_Lab),
462     describe_colorspace(SPACE_Luv),
463     describe_colorspace(SPACE_YCbCr),
464     describe_colorspace(SPACE_Yxy),
465     describe_colorspace(SPACE_RGB),
466     describe_colorspace(SPACE_GRAY),
467     describe_colorspace(SPACE_HSV),
468     describe_colorspace(SPACE_HLS),
469     describe_colorspace(SPACE_CMYK),
470     describe_colorspace(SPACE_CMY),
471     describe_colorspace(SPACE_2_CHANNEL),
472     describe_colorspace(SPACE_3_CHANNEL),
473     describe_colorspace(SPACE_4_CHANNEL),
474     describe_colorspace(SPACE_5_CHANNEL),
475     describe_colorspace(SPACE_6_CHANNEL),
476     describe_colorspace(SPACE_7_CHANNEL),
477     describe_colorspace(SPACE_8_CHANNEL)
478 };
479
480 static void enum_registered_color_profiles(void)
481 {
482     BOOL ret;
483     DWORD size, count, i, present;
484     CHAR profile[MAX_PATH];
485
486     size = sizeof(profile);
487     count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
488
489     present = 0;
490     trace("\n");
491     trace("Querying registered standard colorspace profiles via GetStandardColorSpaceProfileA():\n");
492     for (i=0; i<count; i++)
493     {
494         ret = pGetStandardColorSpaceProfileA(NULL, known_colorspaces[i].dwID, profile, &size);
495         if (ret) 
496         {
497             lstrcpynA(known_colorspaces[i].filename, profile, MAX_PATH);
498             known_colorspaces[i].registered = TRUE;
499             present++;
500             trace(" found %s, pointing to '%s' (%d chars)\n", known_colorspaces[i].szName, profile, lstrlenA(profile));
501         }
502     }
503     trace("Total profiles found: %d.\n", present);
504     trace("\n");
505 }
506
507 static colorspace_descr *query_colorspace(DWORD dwID)
508 {
509     DWORD count, i;
510
511     count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
512
513     for (i=0; i<count; i++)
514         if (known_colorspaces[i].dwID == dwID)
515         {
516             if (!known_colorspaces[i].registered) break;
517             return &known_colorspaces[i];
518         }
519     return NULL;
520 }
521
522 static HKEY reg_open_mscms_key(void)
523 {
524     char win9x[] = "SOFTWARE\\Microsoft\\Windows";
525     char winNT[] = "SOFTWARE\\Microsoft\\Windows NT";
526     char ICM[] = "CurrentVersion\\ICM\\RegisteredProfiles";
527     HKEY win9x_key, winNT_key, ICM_key;
528
529     RegOpenKeyExA( HKEY_LOCAL_MACHINE, win9x, 0, KEY_READ, &win9x_key );
530     RegOpenKeyExA( HKEY_LOCAL_MACHINE, winNT, 0, KEY_READ, &winNT_key );
531
532     if (RegOpenKeyExA( winNT_key, ICM, 0, KEY_READ, &ICM_key )) 
533         RegOpenKeyExA( win9x_key, ICM, 0, KEY_READ, &ICM_key );
534     RegCloseKey( win9x_key );
535     RegCloseKey( winNT_key );
536
537     return ICM_key;
538 }
539
540 static void check_registry(void)
541 {
542     HKEY hkIcmKey;
543     LONG res;
544     DWORD i, dwValCount;
545     char szName[16383];
546     char szData[MAX_PATH+1];
547     DWORD dwNameLen, dwDataLen, dwType;
548
549     hkIcmKey = reg_open_mscms_key();
550     if (!hkIcmKey)
551     {
552         trace("Key 'HKLM\\SOFTWARE\\Microsoft\\Windows*\\CurrentVersion\\ICM\\RegisteredProfiles' not found\n" );
553         return;
554     }
555
556     res = RegQueryInfoKeyA(hkIcmKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValCount, NULL, NULL, NULL, NULL);
557     if (res) 
558     {
559         trace("RegQueryInfoKeyA() failed : %d\n", res);
560         return;
561     }
562
563     trace("Count of profile entries found directly in the registry: %d\n", dwValCount);
564
565     for (i = 0; i<dwValCount; i++) 
566     {
567         dwNameLen = sizeof(szName);
568         dwDataLen = sizeof(szData);
569         res = RegEnumValueA( hkIcmKey, i, szName, &dwNameLen, NULL, &dwType, (LPBYTE)szData, &dwDataLen );
570         if (res != ERROR_SUCCESS) 
571         {
572             trace("RegEnumValueA() failed (%d), cannot enumerate profiles\n", res);
573             break;
574         }
575         ok( dwType == REG_SZ, "RegEnumValueA() returned unexpected value type (%d)\n", dwType );
576         if (dwType != REG_SZ) break;
577         trace(" found '%s' value containing '%s' (%d chars)\n", szName, szData, lstrlenA(szData));
578     } 
579
580     RegCloseKey( hkIcmKey );
581 }
582
583 static void test_GetStandardColorSpaceProfileA(void)
584 {
585     BOOL ret;
586     DWORD size;
587     CHAR oldprofile[MAX_PATH];
588     CHAR newprofile[MAX_PATH];
589     const CHAR emptyA[] = "";
590     DWORD zero = 0;
591     DWORD sizeP = sizeof(newprofile);
592
593     /* Parameter checks */
594
595     /* Single invalid parameter checks: */
596
597     SetLastError(0xfaceabee); /* 1st param, */
598     ret = pGetStandardColorSpaceProfileA(machine, SPACE_RGB, newprofile, &sizeP);
599     ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
600
601     SetLastError(0xfaceabee); /* 2nd param, */
602     ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &sizeP);
603     ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
604
605     SetLastError(0xfaceabee); /* 4th param, */
606     ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, NULL);
607     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
608
609     if (query_colorspace(SPACE_RGB)) 
610     {
611         SetLastError(0xfaceabee); /* 3rd param, */
612         ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
613         ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
614
615         SetLastError(0xfaceabee); /* dereferenced 4th param, */
616         ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &zero);
617         ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
618     } else {
619         SetLastError(0xfaceabee); /* 3rd param, */
620         ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
621         ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
622
623         SetLastError(0xfaceabee); /* dereferenced 4th param. */
624         ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &sizeP);
625         ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
626     }
627
628     /* Several invalid parameter checks: */
629
630     SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
631     ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &zero);
632     ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
633
634     SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
635     ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
636     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
637
638     SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
639     ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &zero);
640     ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
641
642     SetLastError(0xfaceabee); /* maybe 2nd param. */
643     ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &sizeP);
644     if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
645     else ok( !lstrcmpiA( newprofile, emptyA ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
646
647     /* Functional checks */
648
649     if (standardprofile)
650     {
651         size = sizeof(oldprofile);
652
653         ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
654         ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
655
656         ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
657         ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
658
659         size = sizeof(newprofile);
660
661         ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
662         ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
663
664         ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
665
666         ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
667         ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
668     }
669 }
670
671 static void test_GetStandardColorSpaceProfileW(void)
672 {
673     BOOL ret;
674     DWORD size;
675     WCHAR oldprofile[MAX_PATH];
676     WCHAR newprofile[MAX_PATH];
677     const WCHAR emptyW[] = {0};
678     DWORD zero = 0;
679     DWORD sizeP = sizeof(newprofile);
680
681     /* Parameter checks */
682
683     /* Single invalid parameter checks: */
684
685     SetLastError(0xfaceabee); /* 1st param, */
686     ret = pGetStandardColorSpaceProfileW(machineW, SPACE_RGB, newprofile, &sizeP);
687     ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
688
689     SetLastError(0xfaceabee); /* 2nd param, */
690     ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &sizeP);
691     ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
692
693     SetLastError(0xfaceabee); /* 3th param, */
694     ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, NULL, &sizeP);
695     ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
696
697     SetLastError(0xfaceabee); /* 4th param, */
698     ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, NULL);
699     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
700
701     SetLastError(0xfaceabee); /* dereferenced 4th param. */
702     ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, &zero);
703     ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
704
705     /* Several invalid parameter checks: */
706
707     SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
708     ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &zero);
709     ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
710
711     SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
712     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
713     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
714
715     SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
716     ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &zero);
717     ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
718
719     SetLastError(0xfaceabee); /* maybe 2nd param. */
720     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
721     if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
722     else ok( !lstrcmpiW( newprofile, emptyW ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
723
724     /* Functional checks */
725
726     if (standardprofileW)
727     {
728         size = sizeof(oldprofile);
729
730         ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
731         ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
732
733         ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
734         ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
735
736         size = sizeof(newprofile);
737
738         ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
739         ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
740
741         ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
742
743         ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
744         ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
745     }
746 }
747
748 static void test_EnumColorProfilesA(void)
749 {
750     BOOL ret;
751     DWORD size, number;
752     ENUMTYPEA record;
753     BYTE buffer[MAX_PATH];
754
755     /* Parameter checks */
756
757     size = sizeof(buffer);
758     memset( &record, 0, sizeof(ENUMTYPEA) );
759
760     record.dwSize = sizeof(ENUMTYPEA);
761     record.dwVersion = ENUM_TYPE_VERSION;
762     record.dwFields |= ET_DATACOLORSPACE;
763     record.dwDataColorSpace = SPACE_RGB;
764
765     ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
766     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
767
768     ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
769     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
770
771     ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
772     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
773
774     if (standardprofile)
775     {
776         ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
777         ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
778     }
779
780     size = 0;
781
782     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
783     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
784
785     /* Functional checks */
786
787     if (standardprofile)
788     {
789         size = sizeof(buffer);
790
791         ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
792         ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
793     }
794 }
795
796 static void test_EnumColorProfilesW(void)
797 {
798     BOOL ret;
799     DWORD size, number;
800     ENUMTYPEW record;
801     BYTE buffer[MAX_PATH * sizeof(WCHAR)];
802
803     /* Parameter checks */
804
805     size = sizeof(buffer);
806     memset( &record, 0, sizeof(ENUMTYPEW) );
807
808     record.dwSize = sizeof(ENUMTYPEW);
809     record.dwVersion = ENUM_TYPE_VERSION;
810     record.dwFields |= ET_DATACOLORSPACE;
811     record.dwDataColorSpace = SPACE_RGB;
812
813     ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
814     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
815
816     ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
817     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
818
819     ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
820     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
821
822     if (standardprofileW)
823     {
824         ret = pEnumColorProfilesW( NULL, &record, buffer, &size, NULL );
825         ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
826     }
827
828     size = 0;
829
830     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
831     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
832
833     /* Functional checks */
834
835     if (standardprofileW)
836     {
837         size = sizeof(buffer);
838
839         ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
840         ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
841     }
842 }
843
844 static void test_InstallColorProfileA(void)
845 {
846     BOOL ret;
847
848     /* Parameter checks */
849
850     ret = pInstallColorProfileA( NULL, NULL );
851     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
852
853     ret = pInstallColorProfileA( machine, NULL );
854     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
855
856     ret = pInstallColorProfileA( NULL, machine );
857     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
858
859     if (standardprofile)
860     {
861         ret = pInstallColorProfileA( NULL, standardprofile );
862         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
863     }
864
865     /* Functional checks */
866
867     if (testprofile)
868     {
869         CHAR dest[MAX_PATH], base[MAX_PATH];
870         DWORD size = sizeof(dest);
871         CHAR slash[] = "\\";
872         HANDLE handle;
873
874         ret = pInstallColorProfileA( NULL, testprofile );
875         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
876
877         ret = pGetColorDirectoryA( NULL, dest, &size );
878         ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
879
880         MSCMS_basenameA( testprofile, base );
881
882         lstrcatA( dest, slash );
883         lstrcatA( dest, base );
884
885         /* Check if the profile is really there */ 
886         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
887         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
888         CloseHandle( handle );
889         
890         ret = pUninstallColorProfileA( NULL, dest, TRUE );
891         ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
892     }
893 }
894
895 static void test_InstallColorProfileW(void)
896 {
897     BOOL ret;
898
899     /* Parameter checks */
900
901     ret = pInstallColorProfileW( NULL, NULL );
902     ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
903
904     ret = pInstallColorProfileW( machineW, NULL );
905     ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
906
907     ret = pInstallColorProfileW( NULL, machineW );
908     ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
909
910     if (standardprofileW)
911     {
912         ret = pInstallColorProfileW( NULL, standardprofileW );
913         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
914     }
915
916     /* Functional checks */
917
918     if (testprofileW)
919     {
920         WCHAR dest[MAX_PATH], base[MAX_PATH];
921         DWORD size = sizeof(dest);
922         WCHAR slash[] = { '\\', 0 };
923         HANDLE handle;
924
925         ret = pInstallColorProfileW( NULL, testprofileW );
926         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
927
928         ret = pGetColorDirectoryW( NULL, dest, &size );
929         ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
930
931         MSCMS_basenameW( testprofileW, base );
932
933         lstrcatW( dest, slash );
934         lstrcatW( dest, base );
935
936         /* Check if the profile is really there */
937         handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
938         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
939         CloseHandle( handle );
940
941         ret = pUninstallColorProfileW( NULL, dest, TRUE );
942         ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
943     }
944 }
945
946 static void test_IsColorProfileTagPresent(void)
947 {
948     if (standardprofile)
949     {
950         PROFILE profile;
951         HPROFILE handle;
952         BOOL ret, present;
953         TAGTYPE tag;
954
955         profile.dwType = PROFILE_FILENAME;
956         profile.pProfileData = standardprofile;
957         profile.cbDataSize = strlen(standardprofile);
958
959         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
960         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
961
962         /* Parameter checks */
963
964         tag = 0;
965
966         ret = pIsColorProfileTagPresent( handle, tag, &present );
967         ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
968
969         tag = 0x63707274;  /* 'cprt' */
970
971         ret = pIsColorProfileTagPresent( NULL, tag, &present );
972         ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
973
974         ret = pIsColorProfileTagPresent( handle, tag, NULL );
975         ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
976
977         /* Functional checks */
978
979         ret = pIsColorProfileTagPresent( handle, tag, &present );
980         ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() );
981
982         pCloseColorProfile( handle );
983     }
984 }
985
986 static void test_OpenColorProfileA(void)
987 {
988     PROFILE profile;
989     HPROFILE handle;
990     BOOL ret;
991
992     profile.dwType = PROFILE_FILENAME;
993     profile.pProfileData = NULL;
994     profile.cbDataSize = 0;
995
996     /* Parameter checks */
997
998     handle = pOpenColorProfileA( NULL, 0, 0, 0 );
999     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1000
1001     handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1002     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1003
1004     handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1005     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1006
1007     handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
1008     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1009
1010     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1011
1012     if (standardprofile)
1013     {
1014         profile.pProfileData = standardprofile;
1015         profile.cbDataSize = strlen(standardprofile);
1016
1017         handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1018         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1019
1020         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1021         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1022
1023         handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1024         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1025
1026         /* Functional checks */
1027
1028         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1029         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1030
1031         ret = pCloseColorProfile( handle );
1032         ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1033     }
1034 }
1035
1036 static void test_OpenColorProfileW(void)
1037 {
1038     PROFILE profile;
1039     HPROFILE handle;
1040     BOOL ret;
1041
1042     profile.dwType = PROFILE_FILENAME;
1043     profile.pProfileData = NULL;
1044     profile.cbDataSize = 0;
1045
1046     /* Parameter checks */
1047
1048     handle = pOpenColorProfileW( NULL, 0, 0, 0 );
1049     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1050
1051     handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1052     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1053
1054     handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1055     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1056
1057     handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
1058     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1059
1060     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1061
1062     if (standardprofileW)
1063     {
1064         profile.pProfileData = standardprofileW;
1065         profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
1066
1067         handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1068         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1069
1070         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1071         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1072
1073         handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1074         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1075
1076         /* Functional checks */
1077
1078         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1079         ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1080
1081         ret = pCloseColorProfile( handle );
1082         ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1083     }
1084 }
1085
1086 static void test_SetColorProfileElement(void)
1087 {
1088     if (testprofile)
1089     {
1090         PROFILE profile;
1091         HPROFILE handle;
1092         DWORD size;
1093         BOOL ret, ref;
1094
1095         TAGTYPE tag = 0x63707274;  /* 'cprt' */
1096         static char data[] = "(c) The Wine Project";
1097         static char buffer[51];
1098
1099         profile.dwType = PROFILE_FILENAME;
1100         profile.pProfileData = testprofile;
1101         profile.cbDataSize = strlen(testprofile);
1102
1103         /* Parameter checks */
1104
1105         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1106         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1107
1108         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1109         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1110
1111         pCloseColorProfile( handle );
1112
1113         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1114         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1115
1116         ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1117         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1118
1119         ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1120         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1121
1122         ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1123         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1124
1125         ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1126         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1127
1128         /* Functional checks */
1129
1130         size = sizeof(data);
1131
1132         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1133         ok( ret, "SetColorProfileElement() failed (%d)\n", GetLastError() );
1134
1135         size = sizeof(buffer);
1136
1137         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1138         ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
1139
1140         ok( !memcmp( data, buffer, sizeof(data) ),
1141             "Unexpected tag data, expected %s, got %s (%d)\n",
1142             data, buffer, GetLastError() );
1143
1144         pCloseColorProfile( handle );
1145     }
1146 }
1147
1148 static void test_SetColorProfileHeader(void)
1149 {
1150     if (testprofile)
1151     {
1152         PROFILE profile;
1153         HPROFILE handle;
1154         BOOL ret;
1155         PROFILEHEADER header;
1156
1157         profile.dwType = PROFILE_FILENAME;
1158         profile.pProfileData = testprofile;
1159         profile.cbDataSize = strlen(testprofile);
1160
1161         header.phSize = 0x00000c48;
1162         header.phCMMType = 0x4c696e6f;
1163         header.phVersion = 0x02100000;
1164         header.phClass = 0x6d6e7472;
1165         header.phDataColorSpace = 0x52474220;
1166         header.phConnectionSpace  = 0x58595a20;
1167         header.phDateTime[0] = 0x07ce0002;
1168         header.phDateTime[1] = 0x00090006;
1169         header.phDateTime[2] = 0x00310000;
1170         header.phSignature = 0x61637370;
1171         header.phPlatform = 0x4d534654;
1172         header.phProfileFlags = 0x00000000;
1173         header.phManufacturer = 0x49454320;
1174         header.phModel = 0x73524742;
1175         header.phAttributes[0] = 0x00000000;
1176         header.phAttributes[1] = 0x00000000;
1177         header.phRenderingIntent = 0x00000000;
1178         header.phIlluminant.ciexyzX = 0x0000f6d6;
1179         header.phIlluminant.ciexyzY = 0x00010000;
1180         header.phIlluminant.ciexyzZ = 0x0000d32d;
1181         header.phCreator = 0x48502020;
1182
1183         /* Parameter checks */
1184
1185         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1186         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1187
1188         ret = pSetColorProfileHeader( handle, &header );
1189         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1190
1191         pCloseColorProfile( handle );
1192
1193         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1194         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1195
1196         ret = pSetColorProfileHeader( NULL, NULL );
1197         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1198
1199         ret = pSetColorProfileHeader( handle, NULL );
1200         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1201
1202         ret = pSetColorProfileHeader( NULL, &header );
1203         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1204
1205         /* Functional checks */
1206
1207         ret = pSetColorProfileHeader( handle, &header );
1208         ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1209
1210         ret = pGetColorProfileHeader( handle, &header );
1211         ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1212
1213         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1214
1215         pCloseColorProfile( handle );
1216     }
1217 }
1218
1219 static void test_UninstallColorProfileA(void)
1220 {
1221     BOOL ret;
1222
1223     /* Parameter checks */
1224
1225     ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1226     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1227
1228     ret = pUninstallColorProfileA( machine, NULL, FALSE );
1229     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1230
1231     /* Functional checks */
1232
1233     if (testprofile)
1234     {
1235         CHAR dest[MAX_PATH], base[MAX_PATH];
1236         DWORD size = sizeof(dest);
1237         CHAR slash[] = "\\";
1238         HANDLE handle;
1239
1240         ret = pInstallColorProfileA( NULL, testprofile );
1241         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1242
1243         ret = pGetColorDirectoryA( NULL, dest, &size );
1244         ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1245
1246         MSCMS_basenameA( testprofile, base );
1247
1248         lstrcatA( dest, slash );
1249         lstrcatA( dest, base );
1250
1251         ret = pUninstallColorProfileA( NULL, dest, TRUE );
1252         ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1253
1254         /* Check if the profile is really gone */
1255         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1256         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1257         CloseHandle( handle );
1258     }
1259 }
1260
1261 static void test_UninstallColorProfileW(void)
1262 {
1263     BOOL ret;
1264
1265     /* Parameter checks */
1266
1267     ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1268     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1269
1270     ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1271     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1272
1273     /* Functional checks */
1274
1275     if (testprofileW)
1276     {
1277         WCHAR dest[MAX_PATH], base[MAX_PATH];
1278         char destA[MAX_PATH];
1279         DWORD size = sizeof(dest);
1280         WCHAR slash[] = { '\\', 0 };
1281         HANDLE handle;
1282         int bytes_copied;
1283
1284         ret = pInstallColorProfileW( NULL, testprofileW );
1285         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1286
1287         ret = pGetColorDirectoryW( NULL, dest, &size );
1288         ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1289
1290         MSCMS_basenameW( testprofileW, base );
1291
1292         lstrcatW( dest, slash );
1293         lstrcatW( dest, base );
1294
1295         ret = pUninstallColorProfileW( NULL, dest, TRUE );
1296         ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1297
1298         bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1299         ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1300         /* Check if the profile is really gone */
1301         handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1302         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1303         CloseHandle( handle );
1304     }
1305 }
1306
1307 START_TEST(profile)
1308 {
1309     UINT len;
1310     HANDLE handle;
1311     char path[MAX_PATH], file[MAX_PATH];
1312     char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1313     WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1314     WCHAR fileW[MAX_PATH];
1315     UINT ret;
1316
1317     hmscms = LoadLibraryA( "mscms.dll" );
1318     if (!hmscms) return;
1319
1320     if (!init_function_ptrs())
1321     {
1322         FreeLibrary( hmscms );
1323         return;
1324     }
1325
1326     /* See if we can find the standard color profile */
1327     ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1328     ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1329     ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH, 
1330         "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1331     MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1332     ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH, 
1333         "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1334     lstrcpyA(profilefile2, profilefile1);
1335     lstrcpyW(profilefile2W, profilefile1W);
1336
1337     lstrcatA( profilefile1, profile1 );
1338     lstrcatW( profilefile1W, profile1W );
1339     handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1340
1341     if (handle != INVALID_HANDLE_VALUE)
1342     {
1343         standardprofile = profilefile1;
1344         standardprofileW = profilefile1W;
1345         CloseHandle( handle );
1346     }
1347
1348     lstrcatA( profilefile2, profile2 );
1349     lstrcatW( profilefile2W, profile2W );
1350     handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1351
1352     if (handle != INVALID_HANDLE_VALUE)
1353     {
1354         standardprofile = profilefile2;
1355         standardprofileW = profilefile2W;
1356         CloseHandle( handle );
1357     }
1358
1359     /* If found, create a temporary copy for testing purposes */
1360     if (standardprofile && GetTempPath( sizeof(path), path ))
1361     {
1362         if (GetTempFileName( path, "rgb", 0, file ))
1363         {
1364             if (CopyFileA( standardprofile, file, FALSE ))
1365             {
1366                 testprofile = (LPSTR)&file;
1367
1368                 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1369                 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1370
1371                 testprofileW = (LPWSTR)&fileW;
1372             }
1373         }
1374     }
1375
1376     test_GetColorDirectoryA();
1377     test_GetColorDirectoryW();
1378
1379     test_GetColorProfileElement();
1380     test_GetColorProfileElementTag();
1381
1382     test_GetColorProfileFromHandle();
1383     test_GetColorProfileHeader();
1384
1385     test_GetCountColorProfileElements();
1386
1387     enum_registered_color_profiles();
1388     check_registry();
1389
1390     test_GetStandardColorSpaceProfileA();
1391     test_GetStandardColorSpaceProfileW();
1392
1393     test_EnumColorProfilesA();
1394     test_EnumColorProfilesW();
1395
1396     test_InstallColorProfileA();
1397     test_InstallColorProfileW();
1398
1399     test_IsColorProfileTagPresent();
1400
1401     test_OpenColorProfileA();
1402     test_OpenColorProfileW();
1403
1404     test_SetColorProfileElement();
1405     test_SetColorProfileHeader();
1406
1407     test_UninstallColorProfileA();
1408     test_UninstallColorProfileW();
1409
1410     /* Clean up */
1411     if (testprofile)
1412         DeleteFileA( testprofile );
1413     
1414     FreeLibrary( hmscms );
1415 }