crypt32: Make sure we show Unicode characters (Dutch translation).
[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 || dwType == REG_DWORD, "RegEnumValueA() returned unexpected value type (%d)\n", dwType );
585
586         if (dwType == REG_SZ)
587             trace(" found string value '%s' containing '%s' (%d chars)\n", szName, szData, lstrlenA(szData));
588         else if (dwType == REG_DWORD)
589             trace(" found DWORD value '%s' containing '%x'\n", szName, *(DWORD *)szData);
590         else
591             break;
592     } 
593
594     RegCloseKey( hkIcmKey );
595 }
596
597 static void test_GetStandardColorSpaceProfileA(BOOL has_space_rgb)
598 {
599     BOOL ret;
600     DWORD size;
601     CHAR oldprofile[MAX_PATH];
602     CHAR newprofile[MAX_PATH];
603     const CHAR emptyA[] = "";
604     DWORD zero = 0;
605     DWORD sizeP = sizeof(newprofile);
606
607     /* Parameter checks */
608
609     /* Single invalid parameter checks: */
610
611     SetLastError(0xfaceabee); /* 1st param, */
612     ret = pGetStandardColorSpaceProfileA(machine, SPACE_RGB, newprofile, &sizeP);
613     ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
614
615     SetLastError(0xfaceabee); /* 2nd param, */
616     ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &sizeP);
617     ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
618
619     SetLastError(0xfaceabee); /* 4th param, */
620     ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, NULL);
621     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
622
623     if (query_colorspace(SPACE_RGB)) 
624     {
625         SetLastError(0xfaceabee); /* 3rd param, */
626         ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
627         ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
628
629         SetLastError(0xfaceabee); /* dereferenced 4th param, */
630         ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &zero);
631         ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
632     } else {
633         SetLastError(0xfaceabee); /* 3rd param, */
634         ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
635         ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
636
637         SetLastError(0xfaceabee); /* dereferenced 4th param. */
638         ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &sizeP);
639         ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
640     }
641
642     /* Several invalid parameter checks: */
643
644     SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
645     ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &zero);
646     ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
647
648     SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
649     ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
650     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
651
652     SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
653     ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &zero);
654     ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
655
656     SetLastError(0xfaceabee); /* maybe 2nd param. */
657     ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &sizeP);
658     if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
659     else ok( !lstrcmpiA( newprofile, emptyA ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
660
661     /* Functional checks */
662
663     if (has_space_rgb)
664     {
665         size = sizeof(oldprofile);
666
667         ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
668         ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
669
670         SetLastError(0xdeadbeef);
671         ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
672         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
673         {
674             skip("Not enough rights for SetStandardColorSpaceProfileA\n");
675             return;
676         }
677         ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
678
679         size = sizeof(newprofile);
680
681         ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
682         ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
683
684         ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
685
686         ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
687         ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
688     }
689 }
690
691 static void test_GetStandardColorSpaceProfileW(BOOL has_space_rgb)
692 {
693     BOOL ret;
694     DWORD size;
695     WCHAR oldprofile[MAX_PATH];
696     WCHAR newprofile[MAX_PATH];
697     const WCHAR emptyW[] = {0};
698     DWORD zero = 0;
699     DWORD sizeP = sizeof(newprofile);
700
701     /* Parameter checks */
702
703     /* Single invalid parameter checks: */
704
705     SetLastError(0xfaceabee); /* 1st param, */
706     ret = pGetStandardColorSpaceProfileW(machineW, SPACE_RGB, newprofile, &sizeP);
707     ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
708
709     SetLastError(0xfaceabee); /* 2nd param, */
710     ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &sizeP);
711     ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
712
713     SetLastError(0xfaceabee); /* 3rd param, */
714     ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, NULL, &sizeP);
715     if (has_space_rgb)
716         ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
717     else
718         todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
719
720     SetLastError(0xfaceabee); /* 4th param, */
721     ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, NULL);
722     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
723
724     SetLastError(0xfaceabee); /* dereferenced 4th param. */
725     ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, &zero);
726     if (has_space_rgb)
727         ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
728     else
729         todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
730
731
732     /* Several invalid parameter checks: */
733
734     SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
735     ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &zero);
736     ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
737
738     SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
739     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
740     ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
741
742     SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
743     ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &zero);
744     ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
745
746     SetLastError(0xfaceabee); /* maybe 2nd param. */
747     ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
748     if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
749     else ok( !lstrcmpiW( newprofile, emptyW ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
750
751     /* Functional checks */
752
753     if (has_space_rgb)
754     {
755         size = sizeof(oldprofile);
756
757         ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
758         ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
759
760         SetLastError(0xdeadbeef);
761         ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
762         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
763         {
764             skip("Not enough rights for SetStandardColorSpaceProfileW\n");
765             return;
766         }
767         ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
768
769         size = sizeof(newprofile);
770
771         ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
772         ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
773
774         ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
775
776         ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
777         ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
778     }
779 }
780
781 static void test_EnumColorProfilesA(void)
782 {
783     BOOL ret;
784     DWORD total, size, number;
785     ENUMTYPEA record;
786     BYTE *buffer;
787
788     /* Parameter checks */
789
790     memset( &record, 0, sizeof(ENUMTYPEA) );
791
792     record.dwSize = sizeof(ENUMTYPEA);
793     record.dwVersion = ENUM_TYPE_VERSION;
794     record.dwFields |= ET_DATACOLORSPACE;
795     record.dwDataColorSpace = SPACE_RGB;
796
797     total = 0;
798     ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number );
799     ok( !ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
800     buffer = HeapAlloc( GetProcessHeap(), 0, total );
801
802     size = total;
803     ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number );
804     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
805
806     ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number );
807     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
808
809     ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number );
810     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
811
812     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
813     if (standardprofile)
814         ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
815     else
816         todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
817
818     size = 0;
819
820     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
821     ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() );
822
823     /* Functional checks */
824
825     size = total;
826     ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number );
827     if (standardprofile)
828         ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
829     else
830         todo_wine ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() );
831
832     HeapFree( GetProcessHeap(), 0, buffer );
833 }
834
835 static void test_EnumColorProfilesW(void)
836 {
837     BOOL ret;
838     DWORD total, size, number;
839     ENUMTYPEW record;
840     BYTE *buffer;
841
842     /* Parameter checks */
843
844     memset( &record, 0, sizeof(ENUMTYPEW) );
845
846     record.dwSize = sizeof(ENUMTYPEW);
847     record.dwVersion = ENUM_TYPE_VERSION;
848     record.dwFields |= ET_DATACOLORSPACE;
849     record.dwDataColorSpace = SPACE_RGB;
850
851     total = 0;
852     ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number );
853     ok( !ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
854     buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
855
856     size = total;
857     ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number );
858     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
859
860     ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number );
861     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
862
863     ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number );
864     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
865
866     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
867     if (standardprofileW)
868         ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
869     else
870         todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
871
872     size = 0;
873     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
874     ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() );
875
876     /* Functional checks */
877
878     size = total;
879     ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number );
880     if (standardprofileW)
881         ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
882     else
883         todo_wine ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() );
884
885     HeapFree( GetProcessHeap(), 0, buffer );
886 }
887
888 static void test_InstallColorProfileA(void)
889 {
890     BOOL ret;
891
892     /* Parameter checks */
893
894     ret = pInstallColorProfileA( NULL, NULL );
895     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
896
897     ret = pInstallColorProfileA( machine, NULL );
898     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
899
900     ret = pInstallColorProfileA( NULL, machine );
901     ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() );
902
903     if (standardprofile)
904     {
905         ret = pInstallColorProfileA( NULL, standardprofile );
906         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
907     }
908
909     /* Functional checks */
910
911     if (testprofile)
912     {
913         CHAR dest[MAX_PATH], base[MAX_PATH];
914         DWORD size = sizeof(dest);
915         CHAR slash[] = "\\";
916         HANDLE handle;
917
918         SetLastError(0xdeadbeef);
919         ret = pInstallColorProfileA( NULL, testprofile );
920         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
921         {
922             skip("Not enough rights for InstallColorProfileA\n");
923             return;
924         }
925         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
926
927         ret = pGetColorDirectoryA( NULL, dest, &size );
928         ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
929
930         MSCMS_basenameA( testprofile, base );
931
932         lstrcatA( dest, slash );
933         lstrcatA( dest, base );
934
935         /* Check if the profile is really there */ 
936         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
937         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
938         CloseHandle( handle );
939         
940         ret = pUninstallColorProfileA( NULL, dest, TRUE );
941         ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
942     }
943 }
944
945 static void test_InstallColorProfileW(void)
946 {
947     BOOL ret;
948
949     /* Parameter checks */
950
951     ret = pInstallColorProfileW( NULL, NULL );
952     ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
953
954     ret = pInstallColorProfileW( machineW, NULL );
955     ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() );
956
957     ret = pInstallColorProfileW( NULL, machineW );
958     ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
959
960     if (standardprofileW)
961     {
962         ret = pInstallColorProfileW( NULL, standardprofileW );
963         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
964     }
965
966     /* Functional checks */
967
968     if (testprofileW)
969     {
970         WCHAR dest[MAX_PATH], base[MAX_PATH];
971         DWORD size = sizeof(dest);
972         WCHAR slash[] = { '\\', 0 };
973         HANDLE handle;
974
975         SetLastError(0xdeadbeef);
976         ret = pInstallColorProfileW( NULL, testprofileW );
977         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
978         {
979             skip("Not enough rights for InstallColorProfileW\n");
980             return;
981         }
982         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
983
984         ret = pGetColorDirectoryW( NULL, dest, &size );
985         ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
986
987         MSCMS_basenameW( testprofileW, base );
988
989         lstrcatW( dest, slash );
990         lstrcatW( dest, base );
991
992         /* Check if the profile is really there */
993         handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
994         ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() );
995         CloseHandle( handle );
996
997         ret = pUninstallColorProfileW( NULL, dest, TRUE );
998         ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
999     }
1000 }
1001
1002 static void test_IsColorProfileTagPresent(void)
1003 {
1004     if (standardprofile)
1005     {
1006         PROFILE profile;
1007         HPROFILE handle;
1008         BOOL ret, present;
1009         TAGTYPE tag;
1010
1011         profile.dwType = PROFILE_FILENAME;
1012         profile.pProfileData = standardprofile;
1013         profile.cbDataSize = strlen(standardprofile);
1014
1015         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1016         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1017
1018         /* Parameter checks */
1019
1020         tag = 0;
1021
1022         ret = pIsColorProfileTagPresent( handle, tag, &present );
1023         ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1024
1025         tag = 0x63707274;  /* 'cprt' */
1026
1027         ret = pIsColorProfileTagPresent( NULL, tag, &present );
1028         ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1029
1030         ret = pIsColorProfileTagPresent( handle, tag, NULL );
1031         ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() );
1032
1033         /* Functional checks */
1034
1035         ret = pIsColorProfileTagPresent( handle, tag, &present );
1036         ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() );
1037
1038         pCloseColorProfile( handle );
1039     }
1040 }
1041
1042 static void test_OpenColorProfileA(void)
1043 {
1044     PROFILE profile;
1045     HPROFILE handle;
1046     BOOL ret;
1047
1048     profile.dwType = PROFILE_FILENAME;
1049     profile.pProfileData = NULL;
1050     profile.cbDataSize = 0;
1051
1052     /* Parameter checks */
1053
1054     handle = pOpenColorProfileA( NULL, 0, 0, 0 );
1055     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1056
1057     handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1058     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1059
1060     handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1061     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1062
1063     handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
1064     ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1065
1066     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1067
1068     if (standardprofile)
1069     {
1070         profile.pProfileData = standardprofile;
1071         profile.cbDataSize = strlen(standardprofile);
1072
1073         handle = pOpenColorProfileA( &profile, 0, 0, 0 );
1074         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1075
1076         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
1077         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1078
1079         handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1080         ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1081
1082         /* Functional checks */
1083
1084         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1085         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1086
1087         ret = pCloseColorProfile( handle );
1088         ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1089     }
1090 }
1091
1092 static void test_OpenColorProfileW(void)
1093 {
1094     PROFILE profile;
1095     HPROFILE handle;
1096     BOOL ret;
1097
1098     profile.dwType = PROFILE_FILENAME;
1099     profile.pProfileData = NULL;
1100     profile.cbDataSize = 0;
1101
1102     /* Parameter checks */
1103
1104     handle = pOpenColorProfileW( NULL, 0, 0, 0 );
1105     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1106
1107     handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1108     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1109
1110     handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1111     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1112
1113     handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
1114     ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1115
1116     ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" );
1117
1118     if (standardprofileW)
1119     {
1120         profile.pProfileData = standardprofileW;
1121         profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
1122
1123         handle = pOpenColorProfileW( &profile, 0, 0, 0 );
1124         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1125
1126         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
1127         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1128
1129         handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
1130         ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1131
1132         /* Functional checks */
1133
1134         handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1135         ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() );
1136
1137         ret = pCloseColorProfile( handle );
1138         ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() );
1139     }
1140 }
1141
1142 static void test_SetColorProfileElement(void)
1143 {
1144     if (testprofile)
1145     {
1146         PROFILE profile;
1147         HPROFILE handle;
1148         DWORD size;
1149         BOOL ret, ref;
1150
1151         TAGTYPE tag = 0x63707274;  /* 'cprt' */
1152         static char data[] = "(c) The Wine Project";
1153         static char buffer[51];
1154
1155         profile.dwType = PROFILE_FILENAME;
1156         profile.pProfileData = testprofile;
1157         profile.cbDataSize = strlen(testprofile);
1158
1159         /* Parameter checks */
1160
1161         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1162         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1163
1164         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1165         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1166
1167         pCloseColorProfile( handle );
1168
1169         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1170         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1171
1172         ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL );
1173         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1174
1175         ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL );
1176         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1177
1178         ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL );
1179         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1180
1181         ret = pSetColorProfileElement( handle, tag, 0, &size, NULL );
1182         ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() );
1183
1184         /* Functional checks */
1185
1186         size = sizeof(data);
1187
1188         ret = pSetColorProfileElement( handle, tag, 0, &size, data );
1189         ok( ret, "SetColorProfileElement() failed (%d)\n", GetLastError() );
1190
1191         size = sizeof(buffer);
1192
1193         ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
1194         ok( ret && size > 0, "GetColorProfileElement() failed (%d)\n", GetLastError() );
1195
1196         ok( !memcmp( data, buffer, sizeof(data) ),
1197             "Unexpected tag data, expected %s, got %s (%d)\n",
1198             data, buffer, GetLastError() );
1199
1200         pCloseColorProfile( handle );
1201     }
1202 }
1203
1204 static void test_SetColorProfileHeader(void)
1205 {
1206     if (testprofile)
1207     {
1208         PROFILE profile;
1209         HPROFILE handle;
1210         BOOL ret;
1211         PROFILEHEADER header;
1212
1213         profile.dwType = PROFILE_FILENAME;
1214         profile.pProfileData = testprofile;
1215         profile.cbDataSize = strlen(testprofile);
1216
1217         header.phSize = 0x00000c48;
1218         header.phCMMType = 0x4c696e6f;
1219         header.phVersion = 0x02100000;
1220         header.phClass = 0x6d6e7472;
1221         header.phDataColorSpace = 0x52474220;
1222         header.phConnectionSpace  = 0x58595a20;
1223         header.phDateTime[0] = 0x07ce0002;
1224         header.phDateTime[1] = 0x00090006;
1225         header.phDateTime[2] = 0x00310000;
1226         header.phSignature = 0x61637370;
1227         header.phPlatform = 0x4d534654;
1228         header.phProfileFlags = 0x00000000;
1229         header.phManufacturer = 0x49454320;
1230         header.phModel = 0x73524742;
1231         header.phAttributes[0] = 0x00000000;
1232         header.phAttributes[1] = 0x00000000;
1233         header.phRenderingIntent = 0x00000000;
1234         header.phIlluminant.ciexyzX = 0x0000f6d6;
1235         header.phIlluminant.ciexyzY = 0x00010000;
1236         header.phIlluminant.ciexyzZ = 0x0000d32d;
1237         header.phCreator = 0x48502020;
1238
1239         /* Parameter checks */
1240
1241         handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
1242         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1243
1244         ret = pSetColorProfileHeader( handle, &header );
1245         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1246
1247         pCloseColorProfile( handle );
1248
1249         handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
1250         ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() );
1251
1252         ret = pSetColorProfileHeader( NULL, NULL );
1253         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1254
1255         ret = pSetColorProfileHeader( handle, NULL );
1256         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1257
1258         ret = pSetColorProfileHeader( NULL, &header );
1259         ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() );
1260
1261         /* Functional checks */
1262
1263         ret = pSetColorProfileHeader( handle, &header );
1264         ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() );
1265
1266         ret = pGetColorProfileHeader( handle, &header );
1267         ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() );
1268
1269         ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
1270
1271         pCloseColorProfile( handle );
1272     }
1273 }
1274
1275 static void test_UninstallColorProfileA(void)
1276 {
1277     BOOL ret;
1278
1279     /* Parameter checks */
1280
1281     ret = pUninstallColorProfileA( NULL, NULL, FALSE );
1282     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1283
1284     ret = pUninstallColorProfileA( machine, NULL, FALSE );
1285     ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() );
1286
1287     /* Functional checks */
1288
1289     if (testprofile)
1290     {
1291         CHAR dest[MAX_PATH], base[MAX_PATH];
1292         DWORD size = sizeof(dest);
1293         CHAR slash[] = "\\";
1294         HANDLE handle;
1295
1296         SetLastError(0xdeadbeef);
1297         ret = pInstallColorProfileA( NULL, testprofile );
1298         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1299         {
1300             skip("Not enough rights for InstallColorProfileA\n");
1301             return;
1302         }
1303         ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() );
1304
1305         ret = pGetColorDirectoryA( NULL, dest, &size );
1306         ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1307
1308         MSCMS_basenameA( testprofile, base );
1309
1310         lstrcatA( dest, slash );
1311         lstrcatA( dest, base );
1312
1313         ret = pUninstallColorProfileA( NULL, dest, TRUE );
1314         ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1315
1316         /* Check if the profile is really gone */
1317         handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1318         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1319         CloseHandle( handle );
1320     }
1321 }
1322
1323 static void test_UninstallColorProfileW(void)
1324 {
1325     BOOL ret;
1326
1327     /* Parameter checks */
1328
1329     ret = pUninstallColorProfileW( NULL, NULL, FALSE );
1330     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1331
1332     ret = pUninstallColorProfileW( machineW, NULL, FALSE );
1333     ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() );
1334
1335     /* Functional checks */
1336
1337     if (testprofileW)
1338     {
1339         WCHAR dest[MAX_PATH], base[MAX_PATH];
1340         char destA[MAX_PATH];
1341         DWORD size = sizeof(dest);
1342         WCHAR slash[] = { '\\', 0 };
1343         HANDLE handle;
1344         int bytes_copied;
1345
1346         SetLastError(0xdeadbeef);
1347         ret = pInstallColorProfileW( NULL, testprofileW );
1348         if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
1349         {
1350             skip("Not enough rights for InstallColorProfileW\n");
1351             return;
1352         }
1353         ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() );
1354
1355         ret = pGetColorDirectoryW( NULL, dest, &size );
1356         ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() );
1357
1358         MSCMS_basenameW( testprofileW, base );
1359
1360         lstrcatW( dest, slash );
1361         lstrcatW( dest, base );
1362
1363         ret = pUninstallColorProfileW( NULL, dest, TRUE );
1364         ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() );
1365
1366         bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL);
1367         ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied);
1368         /* Check if the profile is really gone */
1369         handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1370         ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() );
1371         CloseHandle( handle );
1372     }
1373 }
1374
1375 static void test_AssociateColorProfileWithDeviceA(void)
1376 {
1377     BOOL ret;
1378     char profile[MAX_PATH], basename[MAX_PATH];
1379     DWORD error, size = sizeof(profile);
1380     DISPLAY_DEVICE display;
1381     BOOL res;
1382     DISPLAY_DEVICE monitor;
1383
1384     if (testprofile && pEnumDisplayDevicesA)
1385     {
1386         display.cb = sizeof( DISPLAY_DEVICE );
1387         res = pEnumDisplayDevicesA( NULL, 0, &display, 0 );
1388         ok( res, "Can't get display info\n" );
1389
1390         monitor.cb = sizeof( DISPLAY_DEVICE );
1391         res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 );
1392         if (res)
1393         {
1394             SetLastError(0xdeadbeef);
1395             ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL );
1396             error = GetLastError();
1397             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1398             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1399
1400             SetLastError(0xdeadbeef);
1401             ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID );
1402             error = GetLastError();
1403             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1404             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1405
1406             SetLastError(0xdeadbeef);
1407             ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID );
1408             error = GetLastError();
1409             ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" );
1410             ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1411
1412             ret = pInstallColorProfileA( NULL, testprofile );
1413             ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() );
1414
1415             ret = pGetColorDirectoryA( NULL, profile, &size );
1416             ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() );
1417
1418             MSCMS_basenameA( testprofile, basename );
1419             lstrcatA( profile, "\\" );
1420             lstrcatA( profile, basename );
1421
1422             ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID );
1423             ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() );
1424
1425             SetLastError(0xdeadbeef);
1426             ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL );
1427             error = GetLastError();
1428             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1429             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1430
1431             SetLastError(0xdeadbeef);
1432             ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID );
1433             error = GetLastError();
1434             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1435             ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error );
1436
1437             SetLastError(0xdeadbeef);
1438             ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID );
1439             error = GetLastError();
1440             ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" );
1441             ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error );
1442
1443             ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID );
1444             ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() );
1445
1446             ret = pUninstallColorProfileA( NULL, profile, TRUE );
1447             ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() );
1448         }
1449         else
1450             skip("Unable to obtain monitor name\n");
1451     }
1452 }
1453
1454 START_TEST(profile)
1455 {
1456     UINT len;
1457     HANDLE handle;
1458     char path[MAX_PATH], file[MAX_PATH];
1459     char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
1460     WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
1461     BOOL has_space_rgb;
1462     WCHAR fileW[MAX_PATH];
1463     UINT ret;
1464
1465     hmscms = LoadLibraryA( "mscms.dll" );
1466     if (!hmscms) return;
1467
1468     huser32 = LoadLibraryA( "user32.dll" );
1469     if (!huser32)
1470     {
1471         FreeLibrary( hmscms );
1472         return;
1473     }
1474
1475     if (!init_function_ptrs())
1476     {
1477         FreeLibrary( huser32 );
1478         FreeLibrary( hmscms );
1479         return;
1480     }
1481
1482     /* See if we can find the standard color profile */
1483     ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) );
1484     ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1485     ok( lstrlenA(profilefile1) > 0 && lstrlenA(profilefile1) < MAX_PATH, 
1486         "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1487     MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH);
1488     ok( lstrlenW(profilefile1W) > 0 && lstrlenW(profilefile1W) < MAX_PATH, 
1489         "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError());
1490     lstrcpyA(profilefile2, profilefile1);
1491     lstrcpyW(profilefile2W, profilefile1W);
1492
1493     lstrcatA( profilefile1, profile1 );
1494     lstrcatW( profilefile1W, profile1W );
1495     handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1496
1497     if (handle != INVALID_HANDLE_VALUE)
1498     {
1499         standardprofile = profilefile1;
1500         standardprofileW = profilefile1W;
1501         CloseHandle( handle );
1502     }
1503
1504     lstrcatA( profilefile2, profile2 );
1505     lstrcatW( profilefile2W, profile2W );
1506     handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
1507
1508     if (handle != INVALID_HANDLE_VALUE)
1509     {
1510         standardprofile = profilefile2;
1511         standardprofileW = profilefile2W;
1512         CloseHandle( handle );
1513     }
1514
1515     /* If found, create a temporary copy for testing purposes */
1516     if (standardprofile && GetTempPath( sizeof(path), path ))
1517     {
1518         if (GetTempFileName( path, "rgb", 0, file ))
1519         {
1520             if (CopyFileA( standardprofile, file, FALSE ))
1521             {
1522                 testprofile = (LPSTR)&file;
1523
1524                 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
1525                 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
1526
1527                 testprofileW = (LPWSTR)&fileW;
1528             }
1529         }
1530     }
1531
1532     test_GetColorDirectoryA();
1533     test_GetColorDirectoryW();
1534
1535     test_GetColorProfileElement();
1536     test_GetColorProfileElementTag();
1537
1538     test_GetColorProfileFromHandle();
1539     test_GetColorProfileHeader();
1540
1541     test_GetCountColorProfileElements();
1542
1543     enum_registered_color_profiles();
1544     check_registry(&has_space_rgb);
1545
1546     test_GetStandardColorSpaceProfileA(has_space_rgb);
1547     test_GetStandardColorSpaceProfileW(has_space_rgb);
1548
1549     test_EnumColorProfilesA();
1550     test_EnumColorProfilesW();
1551
1552     test_InstallColorProfileA();
1553     test_InstallColorProfileW();
1554
1555     test_IsColorProfileTagPresent();
1556
1557     test_OpenColorProfileA();
1558     test_OpenColorProfileW();
1559
1560     test_SetColorProfileElement();
1561     test_SetColorProfileHeader();
1562
1563     test_UninstallColorProfileA();
1564     test_UninstallColorProfileW();
1565
1566     test_AssociateColorProfileWithDeviceA();
1567
1568     /* Clean up */
1569     if (testprofile)
1570         DeleteFileA( testprofile );
1571     
1572     FreeLibrary( huser32 );
1573     FreeLibrary( hmscms );
1574 }