secur32: Update ntlm_auth version detection to detect new samba4 version numbers.
[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., 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 "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 (%ld)\n", GetLastError() );
162
163     size = 0;
164
165     ret = pGetColorDirectoryA( NULL, NULL, &size );
166     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
167
168     size = 0;
169
170     ret = pGetColorDirectoryA( NULL, buffer, &size );
171     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
172
173     size = 1;
174
175     ret = pGetColorDirectoryA( NULL, buffer, &size );
176     ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\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 (%ld)\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 (%ld)\n", GetLastError() );
198
199      */
200
201     size = 0;
202
203     ret = pGetColorDirectoryW( NULL, NULL, &size );
204     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
205
206     size = 0;
207
208     ret = pGetColorDirectoryW( NULL, buffer, &size );
209     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
210
211     size = 1;
212
213     ret = pGetColorDirectoryW( NULL, buffer, &size );
214     ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\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 (%ld)\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 (%ld)\n", GetLastError() );
247
248         /* Parameter checks */
249
250         ret = pGetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
251         ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
252
253         ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
254         ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
255
256         size = 0;
257
258         ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
259         ok( !ret && size > 0, "GetColorProfileElement() succeeded (%ld)\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 (%ld)\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 (%ld)\n", GetLastError() );
290
291         /* Parameter checks */
292
293         ret = pGetColorProfileElementTag( NULL, index, &tag );
294         ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
295
296         ret = pGetColorProfileElementTag( handle, 0, &tag );
297         ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
298
299         ret = pGetColorProfileElementTag( handle, index, NULL );
300         ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
301
302         ret = pGetColorProfileElementTag( handle, 18, NULL );
303         ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
304
305         /* Functional checks */
306
307         ret = pGetColorProfileElementTag( handle, index, &tag );
308         ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld)\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 (%ld)\n", GetLastError() );
341
342         /* Parameter checks */
343
344         size = 0;
345
346         ret = pGetColorProfileFromHandle( handle, NULL, &size );
347         ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%ld)\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 (%ld)\n", GetLastError() );
355
356             ret = pGetColorProfileFromHandle( handle, buffer, NULL );
357             ok( !ret, "GetColorProfileFromHandle() succeeded (%ld)\n", GetLastError() );
358
359             /* Functional checks */
360
361             ret = pGetColorProfileFromHandle( handle, buffer, &size );
362             ok( ret && size > 0, "GetColorProfileFromHandle() failed (%ld)\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 (%ld)\n", GetLastError() );
388
389         /* Parameter checks */
390
391         ret = pGetColorProfileHeader( NULL, NULL );
392         ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
393
394         ret = pGetColorProfileHeader( NULL, &header );
395         ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
396
397         ret = pGetColorProfileHeader( handle, NULL );
398         ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
399
400         /* Functional checks */
401
402         ret = pGetColorProfileHeader( handle, &header );
403         ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
404
405         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
406
407         pCloseColorProfile( handle );
408     }
409 }
410
411 static void test_GetCountColorProfileElements(void)
412 {
413     if (standardprofile)
414     {
415         PROFILE profile;
416         HPROFILE handle;
417         BOOL ret;
418         DWORD count, expect = 17;
419
420         profile.dwType = PROFILE_FILENAME;
421         profile.pProfileData = standardprofile;
422         profile.cbDataSize = strlen(standardprofile);
423
424         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
425         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
426
427         /* Parameter checks */
428
429         ret = pGetCountColorProfileElements( NULL, &count );
430         ok( !ret, "GetCountColorProfileElements() succeeded (%ld)\n",
431             GetLastError() );
432
433         ret = pGetCountColorProfileElements( handle, NULL );
434         ok( !ret, "GetCountColorProfileElements() succeeded (%ld)\n",
435             GetLastError() );
436
437         /* Functional checks */
438
439         ret = pGetCountColorProfileElements( handle, &count );
440         ok( ret && count == expect,
441             "GetCountColorProfileElements() failed (%ld)\n", GetLastError() );
442
443         pCloseColorProfile( handle );
444     }
445 }
446
447 typedef struct colorspace_description_struct {
448     DWORD dwID;
449     char *szName;
450     BOOL registered;
451     char filename[MAX_PATH];
452 } colorspace_descr;
453
454 #define describe_colorspace(id) {id, #id, FALSE, ""}
455
456 colorspace_descr known_colorspaces[] = { 
457     describe_colorspace(SPACE_XYZ),
458     describe_colorspace(SPACE_Lab),
459     describe_colorspace(SPACE_Luv),
460     describe_colorspace(SPACE_YCbCr),
461     describe_colorspace(SPACE_Yxy),
462     describe_colorspace(SPACE_RGB),
463     describe_colorspace(SPACE_GRAY),
464     describe_colorspace(SPACE_HSV),
465     describe_colorspace(SPACE_HLS),
466     describe_colorspace(SPACE_CMYK),
467     describe_colorspace(SPACE_CMY),
468     describe_colorspace(SPACE_2_CHANNEL),
469     describe_colorspace(SPACE_3_CHANNEL),
470     describe_colorspace(SPACE_4_CHANNEL),
471     describe_colorspace(SPACE_5_CHANNEL),
472     describe_colorspace(SPACE_6_CHANNEL),
473     describe_colorspace(SPACE_7_CHANNEL),
474     describe_colorspace(SPACE_8_CHANNEL)
475 };
476
477 static void enum_registered_color_profiles(void)
478 {
479     BOOL ret;
480     DWORD size, count, i, present;
481     CHAR profile[MAX_PATH];
482
483     size = sizeof(profile);
484     count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
485
486     present = 0;
487     trace("\n");
488     trace("Querying registered standard colorspace profiles via GetStandardColorSpaceProfileA():\n");
489     for (i=0; i<count; i++)
490     {
491         ret = pGetStandardColorSpaceProfileA(NULL, known_colorspaces[i].dwID, profile, &size);
492         if (ret) 
493         {
494             lstrcpynA(known_colorspaces[i].filename, profile, MAX_PATH);
495             known_colorspaces[i].registered = TRUE;
496             present++;
497             trace(" found %s, pointing to '%s' (%d chars)\n", known_colorspaces[i].szName, profile, strlen(profile));
498         }
499     }
500     trace("Total profiles found: %ld.\n", present);
501     trace("\n");
502 }
503
504 static colorspace_descr *query_colorspace(DWORD dwID)
505 {
506     DWORD count, i;
507
508     count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
509
510     for (i=0; i<count; i++)
511         if (known_colorspaces[i].dwID == dwID)
512         {
513             if (!known_colorspaces[i].registered) break;
514             return &known_colorspaces[i];
515         }
516     return NULL;
517 }
518
519 static HKEY reg_open_mscms_key(void)
520 {
521     char win9x[] = "SOFTWARE\\Microsoft\\Windows";
522     char winNT[] = "SOFTWARE\\Microsoft\\Windows NT";
523     char ICM[] = "CurrentVersion\\ICM\\RegisteredProfiles";
524     HKEY win9x_key, winNT_key, ICM_key;
525
526     RegOpenKeyExA( HKEY_LOCAL_MACHINE, win9x, 0, KEY_READ, &win9x_key );
527     RegOpenKeyExA( HKEY_LOCAL_MACHINE, winNT, 0, KEY_READ, &winNT_key );
528
529     if (RegOpenKeyExA( winNT_key, ICM, 0, KEY_READ, &ICM_key )) 
530         RegOpenKeyExA( win9x_key, ICM, 0, KEY_READ, &ICM_key );
531     RegCloseKey( win9x_key );
532     RegCloseKey( winNT_key );
533
534     return ICM_key;
535 }
536
537 static void check_registry(void)
538 {
539     HKEY hkIcmKey;
540     LONG res;
541     DWORD i, dwValCount;
542     char szName[16383];
543     char szData[MAX_PATH+1];
544     DWORD dwNameLen, dwDataLen, dwType;
545
546     hkIcmKey = reg_open_mscms_key();
547     if (!hkIcmKey)
548     {
549         trace("Key 'HKLM\\SOFTWARE\\Microsoft\\Windows*\\CurrentVersion\\ICM\\RegisteredProfiles' not found\n" );
550         return;
551     }
552
553     res = RegQueryInfoKeyA(hkIcmKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValCount, NULL, NULL, NULL, NULL);
554     if (!res) 
555     {
556         trace("RegQueryInfoKeyA() failed\n");
557         return;
558     }
559
560     trace("Count of profile entries found directly in the registry: %ld\n", dwValCount);
561
562     for (i = 0; i<dwValCount; i++) 
563     {
564         dwNameLen = sizeof(szName);
565         dwDataLen = sizeof(szData);
566         res = RegEnumValueA( hkIcmKey, i, szName, &dwNameLen, NULL, &dwType, (LPBYTE)szData, &dwDataLen );
567         if (res != ERROR_SUCCESS) 
568         {
569             trace("RegEnumValueA() failed (%ld), cannot enumerate profiles\n", res);
570             break;
571         }
572         ok( dwType == REG_SZ, "RegEnumValueA() returned unexpected value type (%ld)\n", dwType );
573         if (dwType != REG_SZ) break;
574         trace(" found '%s' value containing '%s' (%d chars)\n", szName, szData, strlen(szData));
575     } 
576
577     RegCloseKey( hkIcmKey );
578 }
579
580 #define fail_GSCSP(AW, pMachName, dwProfID, pProfName, pdwSz, dwSz, bCanSucceed, GLE_MATCHES)\
581 do {                                                                                         \
582     size = dwSz;                                                                             \
583     SetLastError(0xfaceabad);                                                                \
584     ret = pGetStandardColorSpaceProfile##AW(pMachName, dwProfID, pProfName, pdwSz);          \
585     GLE = GetLastError();                                                                    \
586     ok( (!ret && GLE_MATCHES) ||                                                             \
587         (bCanSucceed && ret && !lstrcmpi##AW( pProfName, empty##AW ) && GLE == 0xfaceabad),  \
588         "GetStandardColorSpaceProfile%s() returns %d (GLE=%ld)\n", #AW, ret, GLE );          \
589 } while (0)
590
591 static void test_GetStandardColorSpaceProfileA(void)
592 {
593     BOOL ret;
594     DWORD size, sizeP, GLE;
595     CHAR oldprofile[MAX_PATH];
596     CHAR newprofile[MAX_PATH];
597     CHAR emptyA[] = "";
598
599     sizeP = sizeof(newprofile);
600
601     /* Parameter checks */
602
603 #define A
604     /* Single invalid parameter checks */
605     fail_GSCSP(A, machine, SPACE_RGB, newprofile, &size, sizeP, FALSE, (GLE == ERROR_NOT_SUPPORTED));
606     todo_wine
607     fail_GSCSP(A, NULL,    (DWORD)-1, newprofile, &size, sizeP, FALSE, (GLE == ERROR_FILE_NOT_FOUND));
608     fail_GSCSP(A, NULL,    SPACE_RGB, newprofile, NULL,  sizeP, FALSE, (GLE == ERROR_INVALID_PARAMETER));
609
610     if (query_colorspace(SPACE_RGB)) 
611     {
612         fail_GSCSP(A, NULL,    SPACE_RGB, NULL,       &size, sizeP, FALSE, (GLE == ERROR_INSUFFICIENT_BUFFER));
613         todo_wine
614         fail_GSCSP(A, NULL,    SPACE_RGB, newprofile, &size, 0,     FALSE, (GLE == ERROR_MORE_DATA || GLE == ERROR_INSUFFICIENT_BUFFER));
615     } else {
616         todo_wine
617         fail_GSCSP(A, NULL,    SPACE_RGB, NULL,       &size, sizeP, FALSE, (GLE == ERROR_FILE_NOT_FOUND));
618         todo_wine
619         fail_GSCSP(A, NULL,    SPACE_RGB, newprofile, &size, 0,     FALSE, (GLE == ERROR_FILE_NOT_FOUND));
620     }
621
622     /* Several invalid parameter checks */
623     fail_GSCSP(A, machine,  0, newprofile, &size, 0,     FALSE, (GLE == ERROR_INVALID_PARAMETER || GLE == ERROR_NOT_SUPPORTED));
624     fail_GSCSP(A, NULL,     0, newprofile, NULL,  0,     FALSE, (GLE == ERROR_INVALID_PARAMETER));
625     fail_GSCSP(A, NULL,     0, NULL,       &size, 0,     FALSE, (GLE == ERROR_INSUFFICIENT_BUFFER || GLE == ERROR_FILE_NOT_FOUND));
626     todo_wine 
627     fail_GSCSP(A, NULL,     0, newprofile, &size, sizeP, TRUE,  (GLE == ERROR_FILE_NOT_FOUND));
628     #undef A
629
630     /* Functional checks */
631
632     if (standardprofile)
633     {
634         size = sizeof(oldprofile);
635
636         ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
637         ok( ret, "GetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
638
639         ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
640         ok( ret, "SetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
641
642         size = sizeof(newprofile);
643
644         ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
645         ok( ret, "GetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
646
647         ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
648
649         ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
650         ok( ret, "SetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
651     }
652 }
653
654 static void test_GetStandardColorSpaceProfileW(void)
655 {
656     BOOL ret;
657     DWORD size, sizeP, GLE;
658     WCHAR oldprofile[MAX_PATH];
659     WCHAR newprofile[MAX_PATH];
660     WCHAR emptyW[] = {0};
661
662     sizeP = sizeof(newprofile);
663
664     /* Parameter checks */
665
666 #define W
667     /* Single invalid parameter checks */
668     fail_GSCSP(W, machineW, SPACE_RGB, newprofile, &size, sizeP, FALSE, (GLE == ERROR_NOT_SUPPORTED));
669     todo_wine
670     fail_GSCSP(W, NULL,     (DWORD)-1, newprofile, &size, sizeP, FALSE, (GLE == ERROR_FILE_NOT_FOUND));
671     fail_GSCSP(W, NULL,     SPACE_RGB, NULL,       &size, sizeP, FALSE, (GLE == ERROR_INSUFFICIENT_BUFFER));
672     fail_GSCSP(W, NULL,     SPACE_RGB, newprofile, NULL,  sizeP, FALSE, (GLE == ERROR_INVALID_PARAMETER));
673     todo_wine
674     fail_GSCSP(W, NULL,     SPACE_RGB, newprofile, &size, 0,     FALSE, (GLE == ERROR_MORE_DATA || GLE == ERROR_INSUFFICIENT_BUFFER));
675
676     /* Several invalid parameter checks */
677     fail_GSCSP(W, machineW,  0, newprofile, &size, 0,     FALSE, (GLE == ERROR_INVALID_PARAMETER || GLE == ERROR_NOT_SUPPORTED));
678     fail_GSCSP(W, NULL,      0, newprofile, NULL,  0,     FALSE, (GLE == ERROR_INVALID_PARAMETER));
679     fail_GSCSP(W, NULL,      0, NULL,       &size, 0,     FALSE, (GLE == ERROR_INSUFFICIENT_BUFFER || GLE == ERROR_FILE_NOT_FOUND));
680     todo_wine 
681     fail_GSCSP(W, NULL,      0, newprofile, &size, sizeP, TRUE,  (GLE == ERROR_FILE_NOT_FOUND));
682     #undef W
683
684     /* Functional checks */
685
686     if (standardprofileW)
687     {
688         size = sizeof(oldprofile);
689
690         ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
691         ok( ret, "GetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
692
693         ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
694         ok( ret, "SetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
695
696         size = sizeof(newprofile);
697
698         ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
699         ok( ret, "GetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
700
701         ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
702
703         ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
704         ok( ret, "SetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
705     }
706 }
707
708 static void test_EnumColorProfilesA(void)
709 {
710     BOOL ret;
711     DWORD size, number;
712     ENUMTYPEA record;
713     BYTE buffer[MAX_PATH];
714
715     /* Parameter checks */
716
717     size = sizeof(buffer);
718     memset( &record, 0, sizeof(ENUMTYPEA) );
719
720     record.dwSize = sizeof(ENUMTYPEA);
721     record.dwVersion = ENUM_TYPE_VERSION;
722     record.dwFields |= ET_DATACOLORSPACE;
723     record.dwDataColorSpace = SPACE_RGB;
724
725     ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
726     ok( !ret, "EnumColorProfilesA() succeeded (%ld)\n", GetLastError() );
727
728     ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
729     ok( !ret, "EnumColorProfilesA() succeeded (%ld)\n", GetLastError() );
730
731     ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
732     ok( !ret, "EnumColorProfilesA() succeeded (%ld)\n", GetLastError() );
733
734     if (standardprofile)
735     {
736         ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
737         ok( ret, "EnumColorProfilesA() failed (%ld)\n", GetLastError() );
738     }
739
740     size = 0;
741
742     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
743     ok( !ret, "EnumColorProfilesA() succeeded (%ld)\n", GetLastError() );
744
745     /* Functional checks */
746
747     if (standardprofile)
748     {
749         size = sizeof(buffer);
750
751         ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
752         ok( ret, "EnumColorProfilesA() failed (%ld)\n", GetLastError() );
753     }
754 }
755
756 static void test_EnumColorProfilesW(void)
757 {
758     BOOL ret;
759     DWORD size, number;
760     ENUMTYPEW record;
761     BYTE buffer[MAX_PATH * sizeof(WCHAR)];
762
763     /* Parameter checks */
764
765     size = sizeof(buffer);
766     memset( &record, 0, sizeof(ENUMTYPEW) );
767
768     record.dwSize = sizeof(ENUMTYPEW);
769     record.dwVersion = ENUM_TYPE_VERSION;
770     record.dwFields |= ET_DATACOLORSPACE;
771     record.dwDataColorSpace = SPACE_RGB;
772
773     ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
774     ok( !ret, "EnumColorProfilesW() succeeded (%ld)\n", GetLastError() );
775
776     ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
777     ok( !ret, "EnumColorProfilesW() succeeded (%ld)\n", GetLastError() );
778
779     ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
780     ok( !ret, "EnumColorProfilesW() succeeded (%ld)\n", GetLastError() );
781
782     if (standardprofileW)
783     {
784         ret = pEnumColorProfilesW( NULL, &record, buffer, &size, NULL );
785         ok( ret, "EnumColorProfilesW() failed (%ld)\n", GetLastError() );
786     }
787
788     size = 0;
789
790     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
791     ok( !ret, "EnumColorProfilesW() succeeded (%ld)\n", GetLastError() );
792
793     /* Functional checks */
794
795     if (standardprofileW)
796     {
797         size = sizeof(buffer);
798
799         ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
800         ok( ret, "EnumColorProfilesW() failed (%ld)\n", GetLastError() );
801     }
802 }
803
804 static void test_InstallColorProfileA(void)
805 {
806     BOOL ret;
807
808     /* Parameter checks */
809
810     ret = pInstallColorProfileA( NULL, NULL );
811     ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
812
813     ret = pInstallColorProfileA( machine, NULL );
814     ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
815
816     ret = pInstallColorProfileA( NULL, machine );
817     ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
818
819     if (standardprofile)
820     {
821         ret = pInstallColorProfileA( NULL, standardprofile );
822         ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
823     }
824
825     /* Functional checks */
826
827     if (testprofile)
828     {
829         CHAR dest[MAX_PATH], base[MAX_PATH];
830         DWORD size = sizeof(dest);
831         CHAR slash[] = "\\";
832         HANDLE handle;
833
834         ret = pInstallColorProfileA( NULL, testprofile );
835         ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
836
837         ret = pGetColorDirectoryA( NULL, dest, &size );
838         ok( ret, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
839
840         MSCMS_basenameA( testprofile, base );
841
842         lstrcatA( dest, slash );
843         lstrcatA( dest, base );
844
845         /* Check if the profile is really there */ 
846         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
847         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%ld)\n", GetLastError() );
848         CloseHandle( handle );
849         
850         ret = pUninstallColorProfileA( NULL, dest, TRUE );
851         ok( ret, "UninstallColorProfileA() failed (%ld)\n", GetLastError() );
852     }
853 }
854
855 static void test_InstallColorProfileW(void)
856 {
857     BOOL ret;
858
859     /* Parameter checks */
860
861     ret = pInstallColorProfileW( NULL, NULL );
862     ok( !ret, "InstallColorProfileW() succeeded (%ld)\n", GetLastError() );
863
864     ret = pInstallColorProfileW( machineW, NULL );
865     ok( !ret, "InstallColorProfileW() succeeded (%ld)\n", GetLastError() );
866
867     ret = pInstallColorProfileW( NULL, machineW );
868     ok( !ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
869
870     if (standardprofileW)
871     {
872         ret = pInstallColorProfileW( NULL, standardprofileW );
873         ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
874     }
875
876     /* Functional checks */
877
878     if (testprofileW)
879     {
880         WCHAR dest[MAX_PATH], base[MAX_PATH];
881         DWORD size = sizeof(dest);
882         WCHAR slash[] = { '\\', 0 };
883         HANDLE handle;
884
885         ret = pInstallColorProfileW( NULL, testprofileW );
886         ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
887
888         ret = pGetColorDirectoryW( NULL, dest, &size );
889         ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
890
891         MSCMS_basenameW( testprofileW, base );
892
893         lstrcatW( dest, slash );
894         lstrcatW( dest, base );
895
896         /* Check if the profile is really there */
897         handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
898         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%ld)\n", GetLastError() );
899         CloseHandle( handle );
900
901         ret = pUninstallColorProfileW( NULL, dest, TRUE );
902         ok( ret, "UninstallColorProfileW() failed (%ld)\n", GetLastError() );
903     }
904 }
905
906 static void test_IsColorProfileTagPresent(void)
907 {
908     if (standardprofile)
909     {
910         PROFILE profile;
911         HPROFILE handle;
912         BOOL ret, present;
913         TAGTYPE tag;
914
915         profile.dwType = PROFILE_FILENAME;
916         profile.pProfileData = standardprofile;
917         profile.cbDataSize = strlen(standardprofile);
918
919         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
920         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
921
922         /* Parameter checks */
923
924         tag = 0;
925
926         ret = pIsColorProfileTagPresent( handle, tag, &present );
927         ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
928
929         tag = 0x63707274;  /* 'cprt' */
930
931         ret = pIsColorProfileTagPresent( NULL, tag, &present );
932         ok( !ret, "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
933
934         ret = pIsColorProfileTagPresent( handle, tag, NULL );
935         ok( !ret, "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
936
937         /* Functional checks */
938
939         ret = pIsColorProfileTagPresent( handle, tag, &present );
940         ok( ret && present, "IsColorProfileTagPresent() failed (%ld)\n", GetLastError() );
941
942         pCloseColorProfile( handle );
943     }
944 }
945
946 static void test_OpenColorProfileA(void)
947 {
948     PROFILE profile;
949     HPROFILE handle;
950     BOOL ret;
951
952     profile.dwType = PROFILE_FILENAME;
953     profile.pProfileData = NULL;
954     profile.cbDataSize = 0;
955
956     /* Parameter checks */
957
958     handle = pOpenColorProfileA( NULL, 0, 0, 0 );
959     ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
960
961     handle = pOpenColorProfileA( &profile, 0, 0, 0 );
962     ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
963
964     handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
965     ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
966
967     handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
968     ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
969
970     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
971
972     if (standardprofile)
973     {
974         profile.pProfileData = standardprofile;
975         profile.cbDataSize = strlen(standardprofile);
976
977         handle = pOpenColorProfileA( &profile, 0, 0, 0 );
978         ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
979
980         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
981         ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
982
983         handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
984         ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
985
986         /* Functional checks */
987
988         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
989         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
990
991         ret = pCloseColorProfile( handle );
992         ok( ret, "CloseColorProfile() failed (%ld)\n", GetLastError() );
993     }
994 }
995
996 static void test_OpenColorProfileW(void)
997 {
998     PROFILE profile;
999     HPROFILE handle;
1000     BOOL ret;
1001
1002     profile.dwType = PROFILE_FILENAME;
1003     profile.pProfileData = NULL;
1004     profile.cbDataSize = 0;
1005
1006     /* Parameter checks */
1007
1008     handle = pOpenColorProfileW( NULL, 0, 0, 0 );
1009     ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
1010
1011     handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1012     ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
1013
1014     handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1015     ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
1016
1017     handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
1018     ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
1019
1020     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1021
1022     if (standardprofileW)
1023     {
1024         profile.pProfileData = standardprofileW;
1025         profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
1026
1027         handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1028         ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
1029
1030         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1031         ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
1032
1033         handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1034         ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
1035
1036         /* Functional checks */
1037
1038         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1039         ok( handle != NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
1040
1041         ret = pCloseColorProfile( handle );
1042         ok( ret, "CloseColorProfile() failed (%ld)\n", GetLastError() );
1043     }
1044 }
1045
1046 static void test_SetColorProfileElement(void)
1047 {
1048     if (testprofile)
1049     {
1050         PROFILE profile;
1051         HPROFILE handle;
1052         DWORD size;
1053         BOOL ret, ref;
1054
1055         TAGTYPE tag = 0x63707274;  /* 'cprt' */
1056         static char data[] = "(c) The Wine Project";
1057         static char buffer[51];
1058
1059         profile.dwType = PROFILE_FILENAME;
1060         profile.pProfileData = testprofile;
1061         profile.cbDataSize = strlen(testprofile);
1062
1063         /* Parameter checks */
1064
1065         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1066         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
1067
1068         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1069         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
1070
1071         pCloseColorProfile( handle );
1072
1073         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1074         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
1075
1076         ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1077         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
1078
1079         ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1080         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
1081
1082         ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1083         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
1084
1085         ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1086         ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() );
1087
1088         /* Functional checks */
1089
1090         size = sizeof(data);
1091
1092         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1093         ok( ret, "SetColorProfileElement() failed (%ld)\n", GetLastError() );
1094
1095         size = sizeof(buffer);
1096
1097         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1098         ok( ret && size > 0, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
1099
1100         ok( !memcmp( data, buffer, sizeof(data) ),
1101             "Unexpected tag data, expected %s, got %s (%ld)\n",
1102             data, buffer, GetLastError() );
1103
1104         pCloseColorProfile( handle );
1105     }
1106 }
1107
1108 static void test_SetColorProfileHeader(void)
1109 {
1110     if (testprofile)
1111     {
1112         PROFILE profile;
1113         HPROFILE handle;
1114         BOOL ret;
1115         PROFILEHEADER header;
1116
1117         profile.dwType = PROFILE_FILENAME;
1118         profile.pProfileData = testprofile;
1119         profile.cbDataSize = strlen(testprofile);
1120
1121         header.phSize = 0x00000c48;
1122         header.phCMMType = 0x4c696e6f;
1123         header.phVersion = 0x02100000;
1124         header.phClass = 0x6d6e7472;
1125         header.phDataColorSpace = 0x52474220;
1126         header.phConnectionSpace  = 0x58595a20;
1127         header.phDateTime[0] = 0x07ce0002;
1128         header.phDateTime[1] = 0x00090006;
1129         header.phDateTime[2] = 0x00310000;
1130         header.phSignature = 0x61637370;
1131         header.phPlatform = 0x4d534654;
1132         header.phProfileFlags = 0x00000000;
1133         header.phManufacturer = 0x49454320;
1134         header.phModel = 0x73524742;
1135         header.phAttributes[0] = 0x00000000;
1136         header.phAttributes[1] = 0x00000000;
1137         header.phRenderingIntent = 0x00000000;
1138         header.phIlluminant.ciexyzX = 0x0000f6d6;
1139         header.phIlluminant.ciexyzY = 0x00010000;
1140         header.phIlluminant.ciexyzZ = 0x0000d32d;
1141         header.phCreator = 0x48502020;
1142
1143         /* Parameter checks */
1144
1145         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1146         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
1147
1148         ret = pSetColorProfileHeader( handle, &header );
1149         ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
1150
1151         pCloseColorProfile( handle );
1152
1153         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1154         ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
1155
1156         ret = pSetColorProfileHeader( NULL, NULL );
1157         ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
1158
1159         ret = pSetColorProfileHeader( handle, NULL );
1160         ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
1161
1162         ret = pSetColorProfileHeader( NULL, &header );
1163         ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
1164
1165         /* Functional checks */
1166
1167         ret = pSetColorProfileHeader( handle, &header );
1168         ok( ret, "SetColorProfileHeader() failed (%ld)\n", GetLastError() );
1169
1170         ret = pGetColorProfileHeader( handle, &header );
1171         ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
1172
1173         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1174
1175         pCloseColorProfile( handle );
1176     }
1177 }
1178
1179 static void test_UninstallColorProfileA(void)
1180 {
1181     BOOL ret;
1182
1183     /* Parameter checks */
1184
1185     ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1186     ok( !ret, "UninstallColorProfileA() succeeded (%ld)\n", GetLastError() );
1187
1188     ret = pUninstallColorProfileA( machine, NULL, FALSE );
1189     ok( !ret, "UninstallColorProfileA() succeeded (%ld)\n", GetLastError() );
1190
1191     /* Functional checks */
1192
1193     if (testprofile)
1194     {
1195         CHAR dest[MAX_PATH], base[MAX_PATH];
1196         DWORD size = sizeof(dest);
1197         CHAR slash[] = "\\";
1198         HANDLE handle;
1199
1200         ret = pInstallColorProfileA( NULL, testprofile );
1201         ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
1202
1203         ret = pGetColorDirectoryA( NULL, dest, &size );
1204         ok( ret, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
1205
1206         MSCMS_basenameA( testprofile, base );
1207
1208         lstrcatA( dest, slash );
1209         lstrcatA( dest, base );
1210
1211         ret = pUninstallColorProfileA( NULL, dest, TRUE );
1212         ok( ret, "UninstallColorProfileA() failed (%ld)\n", GetLastError() );
1213
1214         /* Check if the profile is really gone */
1215         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1216         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%ld)\n", GetLastError() );
1217         CloseHandle( handle );
1218     }
1219 }
1220
1221 static void test_UninstallColorProfileW(void)
1222 {
1223     BOOL ret;
1224
1225     /* Parameter checks */
1226
1227     ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1228     ok( !ret, "UninstallColorProfileW() succeeded (%ld)\n", GetLastError() );
1229
1230     ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1231     ok( !ret, "UninstallColorProfileW() succeeded (%ld)\n", GetLastError() );
1232
1233     /* Functional checks */
1234
1235     if (testprofileW)
1236     {
1237         WCHAR dest[MAX_PATH], base[MAX_PATH];
1238         char destA[MAX_PATH];
1239         DWORD size = sizeof(dest);
1240         WCHAR slash[] = { '\\', 0 };
1241         HANDLE handle;
1242         int bytes_copied;
1243
1244         ret = pInstallColorProfileW( NULL, testprofileW );
1245         ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
1246
1247         ret = pGetColorDirectoryW( NULL, dest, &size );
1248         ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
1249
1250         MSCMS_basenameW( testprofileW, base );
1251
1252         lstrcatW( dest, slash );
1253         lstrcatW( dest, base );
1254
1255         ret = pUninstallColorProfileW( NULL, dest, TRUE );
1256         ok( ret, "UninstallColorProfileW() failed (%ld)\n", GetLastError() );
1257
1258         bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1259         ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1260         /* Check if the profile is really gone */
1261         handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1262         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%ld)\n", GetLastError() );
1263         CloseHandle( handle );
1264     }
1265 }
1266
1267 START_TEST(profile)
1268 {
1269     UINT len;
1270     HANDLE handle;
1271     char path[MAX_PATH], file[MAX_PATH];
1272     char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1273     WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1274     WCHAR fileW[MAX_PATH];
1275     UINT ret;
1276
1277     hmscms = LoadLibraryA( "mscms.dll" );
1278     if (!hmscms) return;
1279
1280     if (!init_function_ptrs())
1281     {
1282         FreeLibrary( hmscms );
1283         return;
1284     }
1285
1286     /* See if we can find the standard color profile */
1287     ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1288     ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %ld\n", ret, GetLastError());
1289     ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH, 
1290         "GetSystemDirectoryA() returns %d, LastError = %ld\n", ret, GetLastError());
1291     MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1292     ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH, 
1293         "GetSystemDirectoryA() returns %d, LastError = %ld\n", ret, GetLastError());
1294     lstrcpyA(profilefile2, profilefile1);
1295     lstrcpyW(profilefile2W, profilefile1W);
1296
1297     lstrcatA( profilefile1, profile1 );
1298     lstrcatW( profilefile1W, profile1W );
1299     handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1300
1301     if (handle != INVALID_HANDLE_VALUE)
1302     {
1303         standardprofile = profilefile1;
1304         standardprofileW = profilefile1W;
1305         CloseHandle( handle );
1306     }
1307
1308     lstrcatA( profilefile2, profile2 );
1309     lstrcatW( profilefile2W, profile2W );
1310     handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1311
1312     if (handle != INVALID_HANDLE_VALUE)
1313     {
1314         standardprofile = profilefile2;
1315         standardprofileW = profilefile2W;
1316         CloseHandle( handle );
1317     }
1318
1319     /* If found, create a temporary copy for testing purposes */
1320     if (standardprofile && GetTempPath( sizeof(path), path ))
1321     {
1322         if (GetTempFileName( path, "rgb", 0, file ))
1323         {
1324             if (CopyFileA( standardprofile, file, FALSE ))
1325             {
1326                 testprofile = (LPSTR)&file;
1327
1328                 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1329                 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1330
1331                 testprofileW = (LPWSTR)&fileW;
1332             }
1333         }
1334     }
1335
1336     test_GetColorDirectoryA();
1337     test_GetColorDirectoryW();
1338
1339     test_GetColorProfileElement();
1340     test_GetColorProfileElementTag();
1341
1342     test_GetColorProfileFromHandle();
1343     test_GetColorProfileHeader();
1344
1345     test_GetCountColorProfileElements();
1346
1347     enum_registered_color_profiles();
1348     check_registry();
1349
1350     test_GetStandardColorSpaceProfileA();
1351     test_GetStandardColorSpaceProfileW();
1352
1353     test_EnumColorProfilesA();
1354     test_EnumColorProfilesW();
1355
1356     test_InstallColorProfileA();
1357     test_InstallColorProfileW();
1358
1359     test_IsColorProfileTagPresent();
1360
1361     test_OpenColorProfileA();
1362     test_OpenColorProfileW();
1363
1364     test_SetColorProfileElement();
1365     test_SetColorProfileHeader();
1366
1367     test_UninstallColorProfileA();
1368     test_UninstallColorProfileW();
1369
1370     /* Clean up */
1371     if (testprofile)
1372         DeleteFileA( testprofile );
1373     
1374     FreeLibrary( hmscms );
1375 }