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