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