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 static HMODULE hmscms; 34 static HMODULE huser32; 35 36 static BOOL (WINAPI *pAssociateColorProfileWithDeviceA)(PCSTR,PCSTR,PCSTR); 37 static BOOL (WINAPI *pCloseColorProfile)(HPROFILE); 38 static HTRANSFORM (WINAPI *pCreateMultiProfileTransform)(PHPROFILE,DWORD,PDWORD,DWORD,DWORD,DWORD); 39 static BOOL (WINAPI *pDeleteColorTransform)(HTRANSFORM); 40 static BOOL (WINAPI *pDisassociateColorProfileFromDeviceA)(PCSTR,PCSTR,PCSTR); 41 static BOOL (WINAPI *pGetColorDirectoryA)(PCHAR,PCHAR,PDWORD); 42 static BOOL (WINAPI *pGetColorDirectoryW)(PWCHAR,PWCHAR,PDWORD); 43 static BOOL (WINAPI *pGetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL); 44 static BOOL (WINAPI *pGetColorProfileElementTag)(HPROFILE,DWORD,PTAGTYPE); 45 static BOOL (WINAPI *pGetColorProfileFromHandle)(HPROFILE,PBYTE,PDWORD); 46 static BOOL (WINAPI *pGetColorProfileHeader)(HPROFILE,PPROFILEHEADER); 47 static BOOL (WINAPI *pGetCountColorProfileElements)(HPROFILE,PDWORD); 48 static BOOL (WINAPI *pGetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR,PDWORD); 49 static BOOL (WINAPI *pGetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR,PDWORD); 50 static BOOL (WINAPI *pEnumColorProfilesA)(PCSTR,PENUMTYPEA,PBYTE,PDWORD,PDWORD); 51 static BOOL (WINAPI *pEnumColorProfilesW)(PCWSTR,PENUMTYPEW,PBYTE,PDWORD,PDWORD); 52 static BOOL (WINAPI *pInstallColorProfileA)(PCSTR,PCSTR); 53 static BOOL (WINAPI *pInstallColorProfileW)(PCWSTR,PCWSTR); 54 static BOOL (WINAPI *pIsColorProfileTagPresent)(HPROFILE,TAGTYPE,PBOOL); 55 static HPROFILE (WINAPI *pOpenColorProfileA)(PPROFILE,DWORD,DWORD,DWORD); 56 static HPROFILE (WINAPI *pOpenColorProfileW)(PPROFILE,DWORD,DWORD,DWORD); 57 static BOOL (WINAPI *pSetColorProfileElement)(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID); 58 static BOOL (WINAPI *pSetColorProfileHeader)(HPROFILE,PPROFILEHEADER); 59 static BOOL (WINAPI *pSetStandardColorSpaceProfileA)(PCSTR,DWORD,PSTR); 60 static BOOL (WINAPI *pSetStandardColorSpaceProfileW)(PCWSTR,DWORD,PWSTR); 61 static BOOL (WINAPI *pUninstallColorProfileA)(PCSTR,PCSTR,BOOL); 62 static BOOL (WINAPI *pUninstallColorProfileW)(PCWSTR,PCWSTR,BOOL); 63 64 static BOOL (WINAPI *pEnumDisplayDevicesA)(LPCSTR,DWORD,PDISPLAY_DEVICEA,DWORD); 65 66 #define GETFUNCPTR(func) p##func = (void *)GetProcAddress( hmscms, #func ); \ 67 if (!p##func) return FALSE; 68 69 static BOOL init_function_ptrs( void ) 70 { 71 GETFUNCPTR( AssociateColorProfileWithDeviceA ) 72 GETFUNCPTR( CloseColorProfile ) 73 GETFUNCPTR( CreateMultiProfileTransform ) 74 GETFUNCPTR( DeleteColorTransform ) 75 GETFUNCPTR( DisassociateColorProfileFromDeviceA ) 76 GETFUNCPTR( GetColorDirectoryA ) 77 GETFUNCPTR( GetColorDirectoryW ) 78 GETFUNCPTR( GetColorProfileElement ) 79 GETFUNCPTR( GetColorProfileElementTag ) 80 GETFUNCPTR( GetColorProfileFromHandle ) 81 GETFUNCPTR( GetColorProfileHeader ) 82 GETFUNCPTR( GetCountColorProfileElements ) 83 GETFUNCPTR( GetStandardColorSpaceProfileA ) 84 GETFUNCPTR( GetStandardColorSpaceProfileW ) 85 GETFUNCPTR( EnumColorProfilesA ) 86 GETFUNCPTR( EnumColorProfilesW ) 87 GETFUNCPTR( InstallColorProfileA ) 88 GETFUNCPTR( InstallColorProfileW ) 89 GETFUNCPTR( IsColorProfileTagPresent ) 90 GETFUNCPTR( OpenColorProfileA ) 91 GETFUNCPTR( OpenColorProfileW ) 92 GETFUNCPTR( SetColorProfileElement ) 93 GETFUNCPTR( SetColorProfileHeader ) 94 GETFUNCPTR( SetStandardColorSpaceProfileA ) 95 GETFUNCPTR( SetStandardColorSpaceProfileW ) 96 GETFUNCPTR( UninstallColorProfileA ) 97 GETFUNCPTR( UninstallColorProfileW ) 98 99 pEnumDisplayDevicesA = (void *)GetProcAddress( huser32, "EnumDisplayDevicesA" ); 100 101 return TRUE; 102 } 103 104 static const char machine[] = "dummy"; 105 static const WCHAR machineW[] = { 'd','u','m','m','y',0 }; 106 107 /* To do any real functionality testing with this suite you need a copy of 108 * the freely distributable standard RGB color space profile. It comes 109 * standard with Windows, but on Wine you probably need to install it yourself 110 * in one of the locations mentioned below. 111 */ 112 113 /* Two common places to find the standard color space profile, relative 114 * to the system directory. 115 */ 116 static const char profile1[] = 117 "\\color\\srgb color space profile.icm"; 118 static const char profile2[] = 119 "\\spool\\drivers\\color\\srgb color space profile.icm"; 120 121 static const WCHAR profile1W[] = 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 static const WCHAR profile2W[] = 125 { '\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\', 126 'c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ', 127 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 }; 128 129 static BOOL have_color_profile; 130 131 static const unsigned char rgbheader[] = 132 { 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02, 133 0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58, 134 0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00, 135 0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00, 136 0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00, 138 0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 }; 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( char *standardprofile ) 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 ret = pGetColorProfileElement( handle, tag, 0, &size, NULL, &ref ); 264 ok( !ret, "GetColorProfileElement() succeeded\n" ); 265 ok( size > 0, "wrong size\n" ); 266 267 /* Functional checks */ 268 269 size = sizeof(buffer); 270 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref ); 271 ok( ret, "GetColorProfileElement() failed %u\n", GetLastError() ); 272 ok( size > 0, "wrong size\n" ); 273 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" ); 274 275 pCloseColorProfile( handle ); 276 } 277 } 278 279 static void test_GetColorProfileElementTag( char *standardprofile ) 280 { 281 if (standardprofile) 282 { 283 PROFILE profile; 284 HPROFILE handle; 285 BOOL ret; 286 DWORD index = 1; 287 TAGTYPE tag, expect = 0x63707274; /* 'cprt' */ 288 289 profile.dwType = PROFILE_FILENAME; 290 profile.pProfileData = standardprofile; 291 profile.cbDataSize = strlen(standardprofile); 292 293 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 294 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 295 296 /* Parameter checks */ 297 298 ret = pGetColorProfileElementTag( NULL, index, &tag ); 299 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() ); 300 301 ret = pGetColorProfileElementTag( handle, 0, &tag ); 302 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() ); 303 304 ret = pGetColorProfileElementTag( handle, index, NULL ); 305 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() ); 306 307 ret = pGetColorProfileElementTag( handle, 18, NULL ); 308 ok( !ret, "GetColorProfileElementTag() succeeded (%d)\n", GetLastError() ); 309 310 /* Functional checks */ 311 312 ret = pGetColorProfileElementTag( handle, index, &tag ); 313 ok( ret && tag == expect, "GetColorProfileElementTag() failed (%d)\n", 314 GetLastError() ); 315 316 pCloseColorProfile( handle ); 317 } 318 } 319 320 static void test_GetColorProfileFromHandle( char *testprofile ) 321 { 322 if (testprofile) 323 { 324 PROFILE profile; 325 HPROFILE handle; 326 DWORD size; 327 BOOL ret; 328 static const unsigned char expect[] = 329 { 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00, 330 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 331 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00, 332 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 333 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 334 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 335 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 336 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 }; 337 338 unsigned char *buffer; 339 340 profile.dwType = PROFILE_FILENAME; 341 profile.pProfileData = testprofile; 342 profile.cbDataSize = strlen(testprofile); 343 344 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 345 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 346 347 /* Parameter checks */ 348 349 size = 0; 350 351 ret = pGetColorProfileFromHandle( handle, NULL, &size ); 352 ok( !ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() ); 353 354 buffer = HeapAlloc( GetProcessHeap(), 0, size ); 355 356 if (buffer) 357 { 358 ret = pGetColorProfileFromHandle( NULL, buffer, &size ); 359 ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() ); 360 361 ret = pGetColorProfileFromHandle( handle, buffer, NULL ); 362 ok( !ret, "GetColorProfileFromHandle() succeeded (%d)\n", GetLastError() ); 363 364 /* Functional checks */ 365 366 ret = pGetColorProfileFromHandle( handle, buffer, &size ); 367 ok( ret && size > 0, "GetColorProfileFromHandle() failed (%d)\n", GetLastError() ); 368 369 ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" ); 370 371 HeapFree( GetProcessHeap(), 0, buffer ); 372 } 373 374 pCloseColorProfile( handle ); 375 } 376 } 377 378 static void test_GetColorProfileHeader( char *testprofile ) 379 { 380 if (testprofile) 381 { 382 PROFILE profile; 383 HPROFILE handle; 384 BOOL ret; 385 PROFILEHEADER header; 386 387 profile.dwType = PROFILE_FILENAME; 388 profile.pProfileData = testprofile; 389 profile.cbDataSize = strlen(testprofile); 390 391 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 392 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 393 394 /* Parameter checks */ 395 396 ret = pGetColorProfileHeader( NULL, NULL ); 397 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() ); 398 399 ret = pGetColorProfileHeader( NULL, &header ); 400 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() ); 401 402 if (0) /* Crashes on Vista */ 403 { 404 ret = pGetColorProfileHeader( handle, NULL ); 405 ok( !ret, "GetColorProfileHeader() succeeded (%d)\n", GetLastError() ); 406 } 407 408 /* Functional checks */ 409 410 ret = pGetColorProfileHeader( handle, &header ); 411 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() ); 412 413 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" ); 414 415 pCloseColorProfile( handle ); 416 } 417 } 418 419 static void test_GetCountColorProfileElements( char *standardprofile ) 420 { 421 if (standardprofile) 422 { 423 PROFILE profile; 424 HPROFILE handle; 425 BOOL ret; 426 DWORD count, expect = 17; 427 428 profile.dwType = PROFILE_FILENAME; 429 profile.pProfileData = standardprofile; 430 profile.cbDataSize = strlen(standardprofile); 431 432 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 433 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 434 435 /* Parameter checks */ 436 437 ret = pGetCountColorProfileElements( NULL, &count ); 438 ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n", 439 GetLastError() ); 440 441 ret = pGetCountColorProfileElements( handle, NULL ); 442 ok( !ret, "GetCountColorProfileElements() succeeded (%d)\n", 443 GetLastError() ); 444 445 /* Functional checks */ 446 447 ret = pGetCountColorProfileElements( handle, &count ); 448 ok( ret && count == expect, 449 "GetCountColorProfileElements() failed (%d)\n", GetLastError() ); 450 451 pCloseColorProfile( handle ); 452 } 453 } 454 455 static void test_GetStandardColorSpaceProfileA( char *standardprofile ) 456 { 457 BOOL ret; 458 DWORD size; 459 CHAR oldprofile[MAX_PATH]; 460 CHAR newprofile[MAX_PATH]; 461 462 /* Parameter checks */ 463 464 /* Single invalid parameter checks: */ 465 466 size = sizeof(newprofile); 467 SetLastError(0xfaceabee); /* 1st param, */ 468 ret = pGetStandardColorSpaceProfileA(machine, LCS_sRGB, newprofile, &size); 469 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 470 471 size = sizeof(newprofile); 472 SetLastError(0xfaceabee); /* 2nd param, */ 473 ret = pGetStandardColorSpaceProfileA(NULL, (DWORD)-1, newprofile, &size); 474 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 475 476 size = sizeof(newprofile); 477 SetLastError(0xfaceabee); /* 4th param, */ 478 ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, NULL); 479 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 480 481 size = sizeof(newprofile); 482 SetLastError(0xfaceabee); /* 3rd param, */ 483 ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, NULL, &size); 484 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 485 486 size = 0; 487 SetLastError(0xfaceabee); /* dereferenced 4th param, */ 488 ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, &size); 489 ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), 490 "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 491 492 /* Several invalid parameter checks: */ 493 494 size = 0; 495 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */ 496 ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &size); 497 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), 498 "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 499 500 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */ 501 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL); 502 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 503 504 size = 0; 505 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */ 506 ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &size); 507 ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), 508 "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 509 510 size = sizeof(newprofile); 511 SetLastError(0xfaceabee); /* maybe 2nd param. */ 512 ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &size); 513 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 514 else ok( !lstrcmpiA( newprofile, "" ) && GetLastError() == 0xfaceabee, 515 "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() ); 516 517 /* Functional checks */ 518 519 size = sizeof(oldprofile); 520 ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile, &size ); 521 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() ); 522 523 SetLastError(0xdeadbeef); 524 ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, standardprofile ); 525 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED)) 526 { 527 skip("Not enough rights for SetStandardColorSpaceProfileA\n"); 528 return; 529 } 530 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() ); 531 532 size = sizeof(newprofile); 533 ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, newprofile, &size ); 534 ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() ); 535 536 ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile ); 537 ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() ); 538 } 539 540 static void test_GetStandardColorSpaceProfileW( WCHAR *standardprofileW ) 541 { 542 BOOL ret; 543 DWORD size; 544 WCHAR oldprofile[MAX_PATH]; 545 WCHAR newprofile[MAX_PATH]; 546 CHAR newprofileA[MAX_PATH]; 547 548 /* Parameter checks */ 549 550 /* Single invalid parameter checks: */ 551 552 size = sizeof(newprofile); 553 SetLastError(0xfaceabee); /* 1st param, */ 554 ret = pGetStandardColorSpaceProfileW(machineW, LCS_sRGB, newprofile, &size); 555 ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() ); 556 557 size = sizeof(newprofile); 558 SetLastError(0xfaceabee); /* 2nd param, */ 559 ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &size); 560 ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() ); 561 562 size = sizeof(newprofile); 563 SetLastError(0xfaceabee); /* 2nd param, */ 564 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &size); 565 ok( (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) || 566 broken(ret), /* Win98 and WinME */ 567 "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() ); 568 569 size = sizeof(newprofile); 570 SetLastError(0xfaceabee); /* 3rd param, */ 571 ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, NULL, &size); 572 ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" ); 573 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER || 574 broken(GetLastError() == 0xfaceabee) /* win98 */, 575 "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() ); 576 577 size = sizeof(newprofile); 578 SetLastError(0xfaceabee); /* 4th param, */ 579 ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, NULL); 580 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() ); 581 582 size = 0; 583 SetLastError(0xfaceabee); /* dereferenced 4th param. */ 584 ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, &size); 585 ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" ); 586 ok( GetLastError() == ERROR_MORE_DATA || 587 GetLastError() == ERROR_INSUFFICIENT_BUFFER || 588 broken(GetLastError() == 0xfaceabee) /* win98 */, 589 "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() ); 590 591 /* Several invalid parameter checks: */ 592 593 size = 0; 594 SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */ 595 ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &size); 596 ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), 597 "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() ); 598 599 SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */ 600 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL); 601 ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() ); 602 603 size = 0; 604 SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */ 605 ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &size); 606 ok( !ret || broken(ret) /* win98 */, "GetStandardColorSpaceProfileW succeeded\n" ); 607 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER || 608 GetLastError() == ERROR_FILE_NOT_FOUND || 609 broken(GetLastError() == 0xfaceabee) /* win98 */, 610 "GetStandardColorSpaceProfileW() returns GLE=%u\n", GetLastError() ); 611 612 size = sizeof(newprofile); 613 SetLastError(0xfaceabee); /* maybe 2nd param. */ 614 ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &size); 615 if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() ); 616 else 617 { 618 WideCharToMultiByte(CP_ACP, 0, newprofile, -1, newprofileA, sizeof(newprofileA), NULL, NULL); 619 ok( !lstrcmpiA( newprofileA, "" ) && GetLastError() == 0xfaceabee, 620 "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() ); 621 } 622 623 /* Functional checks */ 624 625 size = sizeof(oldprofile); 626 ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile, &size ); 627 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() ); 628 629 SetLastError(0xdeadbeef); 630 ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, standardprofileW ); 631 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED)) 632 { 633 skip("Not enough rights for SetStandardColorSpaceProfileW\n"); 634 return; 635 } 636 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() ); 637 638 size = sizeof(newprofile); 639 ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, newprofile, &size ); 640 ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() ); 641 642 ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile ); 643 ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() ); 644 } 645 646 static void test_EnumColorProfilesA( char *standardprofile ) 647 { 648 BOOL ret; 649 DWORD total, size, number; 650 ENUMTYPEA record; 651 BYTE *buffer; 652 653 /* Parameter checks */ 654 655 memset( &record, 0, sizeof(ENUMTYPEA) ); 656 657 record.dwSize = sizeof(ENUMTYPEA); 658 record.dwVersion = ENUM_TYPE_VERSION; 659 record.dwFields |= ET_DATACOLORSPACE; 660 record.dwDataColorSpace = SPACE_RGB; 661 662 total = 0; 663 ret = pEnumColorProfilesA( NULL, &record, NULL, &total, &number ); 664 ok( !ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() ); 665 buffer = HeapAlloc( GetProcessHeap(), 0, total ); 666 667 size = total; 668 ret = pEnumColorProfilesA( machine, &record, buffer, &size, &number ); 669 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() ); 670 671 ret = pEnumColorProfilesA( NULL, NULL, buffer, &size, &number ); 672 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() ); 673 674 ret = pEnumColorProfilesA( NULL, &record, buffer, NULL, &number ); 675 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() ); 676 677 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number ); 678 todo_wine_if (!have_color_profile) 679 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() ); 680 681 size = 0; 682 683 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number ); 684 ok( !ret, "EnumColorProfilesA() succeeded (%d)\n", GetLastError() ); 685 686 /* Functional checks */ 687 688 size = total; 689 ret = pEnumColorProfilesA( NULL, &record, buffer, &size, &number ); 690 todo_wine_if (!have_color_profile) 691 ok( ret, "EnumColorProfilesA() failed (%d)\n", GetLastError() ); 692 693 HeapFree( GetProcessHeap(), 0, buffer ); 694 } 695 696 static void test_EnumColorProfilesW( WCHAR *standardprofileW ) 697 { 698 BOOL ret; 699 DWORD total, size, number; 700 ENUMTYPEW record; 701 BYTE *buffer; 702 703 /* Parameter checks */ 704 705 memset( &record, 0, sizeof(ENUMTYPEW) ); 706 707 record.dwSize = sizeof(ENUMTYPEW); 708 record.dwVersion = ENUM_TYPE_VERSION; 709 record.dwFields |= ET_DATACOLORSPACE; 710 record.dwDataColorSpace = SPACE_RGB; 711 712 total = 0; 713 ret = pEnumColorProfilesW( NULL, &record, NULL, &total, &number ); 714 ok( !ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() ); 715 buffer = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) ); 716 717 size = total; 718 ret = pEnumColorProfilesW( machineW, &record, buffer, &size, &number ); 719 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() ); 720 721 ret = pEnumColorProfilesW( NULL, NULL, buffer, &size, &number ); 722 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() ); 723 724 ret = pEnumColorProfilesW( NULL, &record, buffer, NULL, &number ); 725 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() ); 726 727 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number ); 728 todo_wine_if (!have_color_profile) 729 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() ); 730 731 size = 0; 732 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number ); 733 ok( !ret, "EnumColorProfilesW() succeeded (%d)\n", GetLastError() ); 734 735 /* Functional checks */ 736 737 size = total; 738 ret = pEnumColorProfilesW( NULL, &record, buffer, &size, &number ); 739 todo_wine_if (!have_color_profile) 740 ok( ret, "EnumColorProfilesW() failed (%d)\n", GetLastError() ); 741 742 HeapFree( GetProcessHeap(), 0, buffer ); 743 } 744 745 static void test_InstallColorProfileA( char *standardprofile, char *testprofile ) 746 { 747 BOOL ret; 748 749 /* Parameter checks */ 750 751 ret = pInstallColorProfileA( NULL, NULL ); 752 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() ); 753 754 ret = pInstallColorProfileA( machine, NULL ); 755 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() ); 756 757 ret = pInstallColorProfileA( NULL, machine ); 758 ok( !ret, "InstallColorProfileA() succeeded (%d)\n", GetLastError() ); 759 760 if (standardprofile) 761 { 762 ret = pInstallColorProfileA( NULL, standardprofile ); 763 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() ); 764 } 765 766 /* Functional checks */ 767 768 if (testprofile) 769 { 770 CHAR dest[MAX_PATH], base[MAX_PATH]; 771 DWORD size = sizeof(dest); 772 CHAR slash[] = "\\"; 773 HANDLE handle; 774 775 SetLastError(0xdeadbeef); 776 ret = pInstallColorProfileA( NULL, testprofile ); 777 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED)) 778 { 779 skip("Not enough rights for InstallColorProfileA\n"); 780 return; 781 } 782 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() ); 783 784 ret = pGetColorDirectoryA( NULL, dest, &size ); 785 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() ); 786 787 MSCMS_basenameA( testprofile, base ); 788 789 lstrcatA( dest, slash ); 790 lstrcatA( dest, base ); 791 792 /* Check if the profile is really there */ 793 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL ); 794 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() ); 795 CloseHandle( handle ); 796 797 ret = pUninstallColorProfileA( NULL, dest, TRUE ); 798 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() ); 799 } 800 } 801 802 static void test_InstallColorProfileW( WCHAR *standardprofileW, WCHAR *testprofileW ) 803 { 804 BOOL ret; 805 806 /* Parameter checks */ 807 808 ret = pInstallColorProfileW( NULL, NULL ); 809 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() ); 810 811 ret = pInstallColorProfileW( machineW, NULL ); 812 ok( !ret, "InstallColorProfileW() succeeded (%d)\n", GetLastError() ); 813 814 ret = pInstallColorProfileW( NULL, machineW ); 815 ok( !ret, "InstallColorProfileW() failed (%d)\n", GetLastError() ); 816 817 if (standardprofileW) 818 { 819 ret = pInstallColorProfileW( NULL, standardprofileW ); 820 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() ); 821 } 822 823 /* Functional checks */ 824 825 if (testprofileW) 826 { 827 WCHAR dest[MAX_PATH], base[MAX_PATH]; 828 DWORD size = sizeof(dest); 829 WCHAR slash[] = { '\\', 0 }; 830 HANDLE handle; 831 832 SetLastError(0xdeadbeef); 833 ret = pInstallColorProfileW( NULL, testprofileW ); 834 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED)) 835 { 836 skip("Not enough rights for InstallColorProfileW\n"); 837 return; 838 } 839 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() ); 840 841 ret = pGetColorDirectoryW( NULL, dest, &size ); 842 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() ); 843 844 MSCMS_basenameW( testprofileW, base ); 845 846 lstrcatW( dest, slash ); 847 lstrcatW( dest, base ); 848 849 /* Check if the profile is really there */ 850 handle = CreateFileW( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL ); 851 ok( handle != INVALID_HANDLE_VALUE, "Couldn't find the profile (%d)\n", GetLastError() ); 852 CloseHandle( handle ); 853 854 ret = pUninstallColorProfileW( NULL, dest, TRUE ); 855 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() ); 856 } 857 } 858 859 static void test_IsColorProfileTagPresent( char *standardprofile ) 860 { 861 if (standardprofile) 862 { 863 PROFILE profile; 864 HPROFILE handle; 865 BOOL ret, present; 866 TAGTYPE tag; 867 868 profile.dwType = PROFILE_FILENAME; 869 profile.pProfileData = standardprofile; 870 profile.cbDataSize = strlen(standardprofile); 871 872 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 873 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 874 875 /* Parameter checks */ 876 877 tag = 0; 878 879 ret = pIsColorProfileTagPresent( handle, tag, &present ); 880 ok( !(ret && present), "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() ); 881 882 tag = 0x63707274; /* 'cprt' */ 883 884 ret = pIsColorProfileTagPresent( NULL, tag, &present ); 885 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() ); 886 887 ret = pIsColorProfileTagPresent( handle, tag, NULL ); 888 ok( !ret, "IsColorProfileTagPresent() succeeded (%d)\n", GetLastError() ); 889 890 /* Functional checks */ 891 892 ret = pIsColorProfileTagPresent( handle, tag, &present ); 893 ok( ret && present, "IsColorProfileTagPresent() failed (%d)\n", GetLastError() ); 894 895 pCloseColorProfile( handle ); 896 } 897 } 898 899 static void test_OpenColorProfileA( char *standardprofile ) 900 { 901 PROFILE profile; 902 HPROFILE handle; 903 BOOL ret; 904 905 profile.dwType = PROFILE_FILENAME; 906 profile.pProfileData = NULL; 907 profile.cbDataSize = 0; 908 909 /* Parameter checks */ 910 911 handle = pOpenColorProfileA( NULL, 0, 0, 0 ); 912 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 913 914 handle = pOpenColorProfileA( &profile, 0, 0, 0 ); 915 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 916 917 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 ); 918 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 919 920 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 ); 921 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 922 923 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" ); 924 925 if (standardprofile) 926 { 927 profile.pProfileData = standardprofile; 928 profile.cbDataSize = strlen(standardprofile); 929 930 handle = pOpenColorProfileA( &profile, 0, 0, 0 ); 931 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 932 933 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, 0 ); 934 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 935 936 handle = pOpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 ); 937 ok( handle == NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 938 939 /* Functional checks */ 940 941 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 942 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 943 944 ret = pCloseColorProfile( handle ); 945 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() ); 946 947 profile.dwType = PROFILE_FILENAME; 948 profile.pProfileData = (void *)"sRGB Color Space Profile.icm"; 949 profile.cbDataSize = sizeof("sRGB Color Space Profile.icm"); 950 951 handle = pOpenColorProfileA( &profile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING ); 952 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 953 954 ret = pCloseColorProfile( handle ); 955 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() ); 956 } 957 } 958 959 static void test_OpenColorProfileW( WCHAR *standardprofileW ) 960 { 961 PROFILE profile; 962 HPROFILE handle; 963 BOOL ret; 964 965 profile.dwType = PROFILE_FILENAME; 966 profile.pProfileData = NULL; 967 profile.cbDataSize = 0; 968 969 /* Parameter checks */ 970 971 handle = pOpenColorProfileW( NULL, 0, 0, 0 ); 972 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() ); 973 974 handle = pOpenColorProfileW( &profile, 0, 0, 0 ); 975 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() ); 976 977 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 ); 978 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() ); 979 980 handle = pOpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 ); 981 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() ); 982 983 ok ( !pCloseColorProfile( NULL ), "CloseColorProfile() succeeded\n" ); 984 985 if (standardprofileW) 986 { 987 profile.pProfileData = standardprofileW; 988 profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR); 989 990 handle = pOpenColorProfileW( &profile, 0, 0, 0 ); 991 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() ); 992 993 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, 0 ); 994 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() ); 995 996 handle = pOpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 ); 997 ok( handle == NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() ); 998 999 /* Functional checks */ 1000 1001 handle = pOpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 1002 ok( handle != NULL, "OpenColorProfileW() failed (%d)\n", GetLastError() ); 1003 1004 ret = pCloseColorProfile( handle ); 1005 ok( ret, "CloseColorProfile() failed (%d)\n", GetLastError() ); 1006 } 1007 } 1008 1009 static void test_SetColorProfileElement( char *testprofile ) 1010 { 1011 if (testprofile) 1012 { 1013 PROFILE profile; 1014 HPROFILE handle; 1015 DWORD size; 1016 BOOL ret, ref; 1017 1018 TAGTYPE tag = 0x63707274; /* 'cprt' */ 1019 static char data[] = "(c) The Wine Project"; 1020 static char buffer[51]; 1021 1022 profile.dwType = PROFILE_FILENAME; 1023 profile.pProfileData = testprofile; 1024 profile.cbDataSize = strlen(testprofile); 1025 1026 /* Parameter checks */ 1027 1028 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 1029 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 1030 1031 ret = pSetColorProfileElement( handle, tag, 0, &size, data ); 1032 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() ); 1033 1034 pCloseColorProfile( handle ); 1035 1036 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING ); 1037 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 1038 1039 ret = pSetColorProfileElement( NULL, 0, 0, NULL, NULL ); 1040 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() ); 1041 1042 ret = pSetColorProfileElement( handle, 0, 0, NULL, NULL ); 1043 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() ); 1044 1045 ret = pSetColorProfileElement( handle, tag, 0, NULL, NULL ); 1046 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() ); 1047 1048 ret = pSetColorProfileElement( handle, tag, 0, &size, NULL ); 1049 ok( !ret, "SetColorProfileElement() succeeded (%d)\n", GetLastError() ); 1050 1051 /* Functional checks */ 1052 1053 size = sizeof(data); 1054 ret = pSetColorProfileElement( handle, tag, 0, &size, data ); 1055 ok( ret, "SetColorProfileElement() failed %u\n", GetLastError() ); 1056 1057 size = sizeof(buffer); 1058 ret = pGetColorProfileElement( handle, tag, 0, &size, buffer, &ref ); 1059 ok( ret, "GetColorProfileElement() failed %u\n", GetLastError() ); 1060 ok( size > 0, "wrong size\n" ); 1061 1062 ok( !memcmp( data, buffer, sizeof(data) ), 1063 "Unexpected tag data, expected %s, got %s (%u)\n", data, buffer, GetLastError() ); 1064 1065 pCloseColorProfile( handle ); 1066 } 1067 } 1068 1069 static void test_SetColorProfileHeader( char *testprofile ) 1070 { 1071 if (testprofile) 1072 { 1073 PROFILE profile; 1074 HPROFILE handle; 1075 BOOL ret; 1076 PROFILEHEADER header; 1077 1078 profile.dwType = PROFILE_FILENAME; 1079 profile.pProfileData = testprofile; 1080 profile.cbDataSize = strlen(testprofile); 1081 1082 header.phSize = 0x00000c48; 1083 header.phCMMType = 0x4c696e6f; 1084 header.phVersion = 0x02100000; 1085 header.phClass = 0x6d6e7472; 1086 header.phDataColorSpace = 0x52474220; 1087 header.phConnectionSpace = 0x58595a20; 1088 header.phDateTime[0] = 0x07ce0002; 1089 header.phDateTime[1] = 0x00090006; 1090 header.phDateTime[2] = 0x00310000; 1091 header.phSignature = 0x61637370; 1092 header.phPlatform = 0x4d534654; 1093 header.phProfileFlags = 0x00000000; 1094 header.phManufacturer = 0x49454320; 1095 header.phModel = 0x73524742; 1096 header.phAttributes[0] = 0x00000000; 1097 header.phAttributes[1] = 0x00000000; 1098 header.phRenderingIntent = 0x00000000; 1099 header.phIlluminant.ciexyzX = 0x0000f6d6; 1100 header.phIlluminant.ciexyzY = 0x00010000; 1101 header.phIlluminant.ciexyzZ = 0x0000d32d; 1102 header.phCreator = 0x48502020; 1103 1104 /* Parameter checks */ 1105 1106 handle = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 1107 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 1108 1109 ret = pSetColorProfileHeader( handle, &header ); 1110 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() ); 1111 1112 pCloseColorProfile( handle ); 1113 1114 handle = pOpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING ); 1115 ok( handle != NULL, "OpenColorProfileA() failed (%d)\n", GetLastError() ); 1116 1117 ret = pSetColorProfileHeader( NULL, NULL ); 1118 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() ); 1119 1120 ret = pSetColorProfileHeader( handle, NULL ); 1121 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() ); 1122 1123 ret = pSetColorProfileHeader( NULL, &header ); 1124 ok( !ret, "SetColorProfileHeader() succeeded (%d)\n", GetLastError() ); 1125 1126 /* Functional checks */ 1127 1128 ret = pSetColorProfileHeader( handle, &header ); 1129 ok( ret, "SetColorProfileHeader() failed (%d)\n", GetLastError() ); 1130 1131 ret = pGetColorProfileHeader( handle, &header ); 1132 ok( ret, "GetColorProfileHeader() failed (%d)\n", GetLastError() ); 1133 1134 ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" ); 1135 1136 pCloseColorProfile( handle ); 1137 } 1138 } 1139 1140 static void test_UninstallColorProfileA( char *testprofile ) 1141 { 1142 BOOL ret; 1143 1144 /* Parameter checks */ 1145 1146 ret = pUninstallColorProfileA( NULL, NULL, FALSE ); 1147 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() ); 1148 1149 ret = pUninstallColorProfileA( machine, NULL, FALSE ); 1150 ok( !ret, "UninstallColorProfileA() succeeded (%d)\n", GetLastError() ); 1151 1152 /* Functional checks */ 1153 1154 if (testprofile) 1155 { 1156 CHAR dest[MAX_PATH], base[MAX_PATH]; 1157 DWORD size = sizeof(dest); 1158 CHAR slash[] = "\\"; 1159 HANDLE handle; 1160 1161 SetLastError(0xdeadbeef); 1162 ret = pInstallColorProfileA( NULL, testprofile ); 1163 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED)) 1164 { 1165 skip("Not enough rights for InstallColorProfileA\n"); 1166 return; 1167 } 1168 ok( ret, "InstallColorProfileA() failed (%d)\n", GetLastError() ); 1169 1170 ret = pGetColorDirectoryA( NULL, dest, &size ); 1171 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() ); 1172 1173 MSCMS_basenameA( testprofile, base ); 1174 1175 lstrcatA( dest, slash ); 1176 lstrcatA( dest, base ); 1177 1178 ret = pUninstallColorProfileA( NULL, dest, TRUE ); 1179 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() ); 1180 1181 /* Check if the profile is really gone */ 1182 handle = CreateFileA( dest, 0 , 0, NULL, OPEN_EXISTING, 0, NULL ); 1183 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() ); 1184 CloseHandle( handle ); 1185 } 1186 } 1187 1188 static void test_UninstallColorProfileW( WCHAR *testprofileW ) 1189 { 1190 BOOL ret; 1191 1192 /* Parameter checks */ 1193 1194 ret = pUninstallColorProfileW( NULL, NULL, FALSE ); 1195 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() ); 1196 1197 ret = pUninstallColorProfileW( machineW, NULL, FALSE ); 1198 ok( !ret, "UninstallColorProfileW() succeeded (%d)\n", GetLastError() ); 1199 1200 /* Functional checks */ 1201 1202 if (testprofileW) 1203 { 1204 WCHAR dest[MAX_PATH], base[MAX_PATH]; 1205 char destA[MAX_PATH]; 1206 DWORD size = sizeof(dest); 1207 WCHAR slash[] = { '\\', 0 }; 1208 HANDLE handle; 1209 int bytes_copied; 1210 1211 SetLastError(0xdeadbeef); 1212 ret = pInstallColorProfileW( NULL, testprofileW ); 1213 if (!ret && (GetLastError() == ERROR_ACCESS_DENIED)) 1214 { 1215 skip("Not enough rights for InstallColorProfileW\n"); 1216 return; 1217 } 1218 ok( ret, "InstallColorProfileW() failed (%d)\n", GetLastError() ); 1219 1220 ret = pGetColorDirectoryW( NULL, dest, &size ); 1221 ok( ret, "GetColorDirectoryW() failed (%d)\n", GetLastError() ); 1222 1223 MSCMS_basenameW( testprofileW, base ); 1224 1225 lstrcatW( dest, slash ); 1226 lstrcatW( dest, base ); 1227 1228 ret = pUninstallColorProfileW( NULL, dest, TRUE ); 1229 ok( ret, "UninstallColorProfileW() failed (%d)\n", GetLastError() ); 1230 1231 bytes_copied = WideCharToMultiByte(CP_ACP, 0, dest, -1, destA, MAX_PATH, NULL, NULL); 1232 ok( bytes_copied > 0 , "WideCharToMultiByte() returns %d\n", bytes_copied); 1233 /* Check if the profile is really gone */ 1234 handle = CreateFileA( destA, 0 , 0, NULL, OPEN_EXISTING, 0, NULL ); 1235 ok( handle == INVALID_HANDLE_VALUE, "Found the profile (%d)\n", GetLastError() ); 1236 CloseHandle( handle ); 1237 } 1238 } 1239 1240 static void test_AssociateColorProfileWithDeviceA( char *testprofile ) 1241 { 1242 BOOL ret; 1243 char profile[MAX_PATH], basename[MAX_PATH]; 1244 DWORD error, size = sizeof(profile); 1245 DISPLAY_DEVICEA display, monitor; 1246 BOOL res; 1247 1248 if (testprofile && pEnumDisplayDevicesA) 1249 { 1250 display.cb = sizeof( DISPLAY_DEVICEA ); 1251 res = pEnumDisplayDevicesA( NULL, 0, &display, 0 ); 1252 ok( res, "Can't get display info\n" ); 1253 1254 monitor.cb = sizeof( DISPLAY_DEVICEA ); 1255 res = pEnumDisplayDevicesA( display.DeviceName, 0, &monitor, 0 ); 1256 if (res) 1257 { 1258 SetLastError(0xdeadbeef); 1259 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, NULL ); 1260 error = GetLastError(); 1261 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" ); 1262 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error ); 1263 1264 SetLastError(0xdeadbeef); 1265 ret = pAssociateColorProfileWithDeviceA( "machine", NULL, monitor.DeviceID ); 1266 error = GetLastError(); 1267 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" ); 1268 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error ); 1269 1270 SetLastError(0xdeadbeef); 1271 ret = pAssociateColorProfileWithDeviceA( "machine", testprofile, monitor.DeviceID ); 1272 error = GetLastError(); 1273 ok( !ret, "AssociateColorProfileWithDevice() succeeded\n" ); 1274 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error ); 1275 1276 ret = pInstallColorProfileA( NULL, testprofile ); 1277 ok( ret, "InstallColorProfileA() failed (%u)\n", GetLastError() ); 1278 1279 ret = pGetColorDirectoryA( NULL, profile, &size ); 1280 ok( ret, "GetColorDirectoryA() failed (%d)\n", GetLastError() ); 1281 1282 MSCMS_basenameA( testprofile, basename ); 1283 lstrcatA( profile, "\\" ); 1284 lstrcatA( profile, basename ); 1285 1286 ret = pAssociateColorProfileWithDeviceA( NULL, profile, monitor.DeviceID ); 1287 ok( ret, "AssociateColorProfileWithDevice() failed (%u)\n", GetLastError() ); 1288 1289 SetLastError(0xdeadbeef); 1290 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, NULL ); 1291 error = GetLastError(); 1292 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" ); 1293 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error ); 1294 1295 SetLastError(0xdeadbeef); 1296 ret = pDisassociateColorProfileFromDeviceA( "machine", NULL, monitor.DeviceID ); 1297 error = GetLastError(); 1298 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" ); 1299 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error ); 1300 1301 SetLastError(0xdeadbeef); 1302 ret = pDisassociateColorProfileFromDeviceA( "machine", profile, monitor.DeviceID ); 1303 error = GetLastError(); 1304 ok( !ret, "DisassociateColorProfileFromDeviceA() succeeded\n" ); 1305 ok( error == ERROR_NOT_SUPPORTED, "expected ERROR_NOT_SUPPORTED, got %u\n", error ); 1306 1307 ret = pDisassociateColorProfileFromDeviceA( NULL, profile, monitor.DeviceID ); 1308 ok( ret, "DisassociateColorProfileFromDeviceA() failed (%u)\n", GetLastError() ); 1309 1310 ret = pUninstallColorProfileA( NULL, profile, TRUE ); 1311 ok( ret, "UninstallColorProfileA() failed (%d)\n", GetLastError() ); 1312 } 1313 else 1314 skip("Unable to obtain monitor name\n"); 1315 } 1316 } 1317 1318 static BOOL have_profile(void) 1319 { 1320 char glob[MAX_PATH + sizeof("\\*.icm")]; 1321 DWORD size = MAX_PATH; 1322 HANDLE handle; 1323 WIN32_FIND_DATAA data; 1324 1325 if (!pGetColorDirectoryA( NULL, glob, &size )) return FALSE; 1326 lstrcatA( glob, "\\*.icm" ); 1327 handle = FindFirstFileA( glob, &data ); 1328 if (handle == INVALID_HANDLE_VALUE) return FALSE; 1329 FindClose( handle ); 1330 return TRUE; 1331 } 1332 1333 static void test_CreateMultiProfileTransform( char *standardprofile, char *testprofile ) 1334 { 1335 PROFILE profile; 1336 HPROFILE handle[2]; 1337 HTRANSFORM transform; 1338 DWORD intents[2] = { INTENT_PERCEPTUAL, INTENT_PERCEPTUAL }; 1339 1340 if (testprofile) 1341 { 1342 profile.dwType = PROFILE_FILENAME; 1343 profile.pProfileData = standardprofile; 1344 profile.cbDataSize = strlen(standardprofile); 1345 1346 handle[0] = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 1347 ok( handle[0] != NULL, "got %u\n", GetLastError() ); 1348 1349 profile.dwType = PROFILE_FILENAME; 1350 profile.pProfileData = testprofile; 1351 profile.cbDataSize = strlen(testprofile); 1352 1353 handle[1] = pOpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); 1354 ok( handle[1] != NULL, "got %u\n", GetLastError() ); 1355 1356 transform = pCreateMultiProfileTransform( handle, 2, intents, 2, 0, 0 ); 1357 ok( transform != NULL, "got %u\n", GetLastError() ); 1358 1359 pDeleteColorTransform( transform ); 1360 pCloseColorProfile( handle[0] ); 1361 pCloseColorProfile( handle[1] ); 1362 } 1363 } 1364 1365 START_TEST(profile) 1366 { 1367 UINT len; 1368 HANDLE handle; 1369 char path[MAX_PATH], file[MAX_PATH], profilefile1[MAX_PATH], profilefile2[MAX_PATH]; 1370 WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH], fileW[MAX_PATH]; 1371 char *standardprofile = NULL, *testprofile = NULL; 1372 WCHAR *standardprofileW = NULL, *testprofileW = NULL; 1373 UINT ret; 1374 1375 hmscms = LoadLibraryA( "mscms.dll" ); 1376 if (!hmscms) return; 1377 1378 huser32 = LoadLibraryA( "user32.dll" ); 1379 if (!huser32) 1380 { 1381 FreeLibrary( hmscms ); 1382 return; 1383 } 1384 1385 if (!init_function_ptrs()) 1386 { 1387 FreeLibrary( huser32 ); 1388 FreeLibrary( hmscms ); 1389 return; 1390 } 1391 1392 /* See if we can find the standard color profile */ 1393 ret = GetSystemDirectoryA( profilefile1, sizeof(profilefile1) ); 1394 ok( ret > 0, "GetSystemDirectoryA() returns %d, LastError = %d\n", ret, GetLastError()); 1395 ok(profilefile1[0] && lstrlenA(profilefile1) < MAX_PATH, 1396 "Expected length between 0 and MAX_PATH, got %d\n", lstrlenA(profilefile1)); 1397 MultiByteToWideChar(CP_ACP, 0, profilefile1, -1, profilefile1W, MAX_PATH); 1398 ok(profilefile1W[0] && lstrlenW(profilefile1W) < MAX_PATH, 1399 "Expected length between 0 and MAX_PATH, got %d\n", lstrlenW(profilefile1W)); 1400 lstrcpyA(profilefile2, profilefile1); 1401 lstrcpyW(profilefile2W, profilefile1W); 1402 1403 lstrcatA( profilefile1, profile1 ); 1404 lstrcatW( profilefile1W, profile1W ); 1405 handle = CreateFileA( profilefile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL ); 1406 1407 if (handle != INVALID_HANDLE_VALUE) 1408 { 1409 standardprofile = profilefile1; 1410 standardprofileW = profilefile1W; 1411 CloseHandle( handle ); 1412 } 1413 1414 lstrcatA( profilefile2, profile2 ); 1415 lstrcatW( profilefile2W, profile2W ); 1416 handle = CreateFileA( profilefile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL ); 1417 1418 if (handle != INVALID_HANDLE_VALUE) 1419 { 1420 standardprofile = profilefile2; 1421 standardprofileW = profilefile2W; 1422 CloseHandle( handle ); 1423 } 1424 1425 /* If found, create a temporary copy for testing purposes */ 1426 if (standardprofile && GetTempPathA( sizeof(path), path )) 1427 { 1428 if (GetTempFileNameA( path, "rgb", 0, file )) 1429 { 1430 if (CopyFileA( standardprofile, file, FALSE )) 1431 { 1432 testprofile = (LPSTR)&file; 1433 len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 ); 1434 MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len ); 1435 testprofileW = (LPWSTR)&fileW; 1436 } 1437 } 1438 } 1439 1440 have_color_profile = have_profile(); 1441 1442 test_GetColorDirectoryA(); 1443 test_GetColorDirectoryW(); 1444 1445 test_GetColorProfileElement( standardprofile ); 1446 test_GetColorProfileElementTag( standardprofile ); 1447 1448 test_GetColorProfileFromHandle( testprofile ); 1449 test_GetColorProfileHeader( testprofile ); 1450 1451 test_GetCountColorProfileElements( standardprofile ); 1452 1453 test_GetStandardColorSpaceProfileA( standardprofile ); 1454 test_GetStandardColorSpaceProfileW( standardprofileW ); 1455 1456 test_EnumColorProfilesA( standardprofile ); 1457 test_EnumColorProfilesW( standardprofileW ); 1458 1459 test_InstallColorProfileA( standardprofile, testprofile ); 1460 test_InstallColorProfileW( standardprofileW, testprofileW ); 1461 1462 test_IsColorProfileTagPresent( standardprofile ); 1463 1464 test_OpenColorProfileA( standardprofile ); 1465 test_OpenColorProfileW( standardprofileW ); 1466 1467 test_SetColorProfileElement( testprofile ); 1468 test_SetColorProfileHeader( testprofile ); 1469 1470 test_UninstallColorProfileA( testprofile ); 1471 test_UninstallColorProfileW( testprofileW ); 1472 1473 test_AssociateColorProfileWithDeviceA( testprofile ); 1474 test_CreateMultiProfileTransform( standardprofile, testprofile ); 1475 1476 if (testprofile) DeleteFileA( testprofile ); 1477 FreeLibrary( huser32 ); 1478 FreeLibrary( hmscms ); 1479 } 1480