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