1 /* 2 * tests for Microsoft Installer functionality 3 * 4 * Copyright 2005 Mike McCormack for CodeWeavers 5 * Copyright 2005 Aric Stewart for CodeWeavers 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #define COBJMACROS 23 24 #include <assert.h> 25 #include <stdio.h> 26 #include <windows.h> 27 #include <msidefs.h> 28 #include <msi.h> 29 #include <msiquery.h> 30 #include <srrestoreptapi.h> 31 #include <shlobj.h> 32 #include <sddl.h> 33 34 #include "wine/test.h" 35 36 static BOOL is_wow64; 37 static const char msifile[] = "winetest-package.msi"; 38 static const WCHAR msifileW[] = L"winetest-package.msi"; 39 static char CURR_DIR[MAX_PATH]; 40 41 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD); 42 43 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); 44 static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD); 45 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); 46 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD); 47 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*); 48 49 static void init_functionpointers(void) 50 { 51 HMODULE hmsi = GetModuleHandleA("msi.dll"); 52 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); 53 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); 54 HMODULE hsrclient = LoadLibraryA("srclient.dll"); 55 56 #define GET_PROC(mod, func) \ 57 p ## func = (void*)GetProcAddress(mod, #func); 58 59 GET_PROC(hmsi, MsiGetComponentPathExA); 60 61 GET_PROC(hadvapi32, RegDeleteKeyExA) 62 GET_PROC(hadvapi32, RegDeleteKeyExW) 63 GET_PROC(hkernel32, IsWow64Process) 64 65 GET_PROC(hsrclient, SRRemoveRestorePoint); 66 GET_PROC(hsrclient, SRSetRestorePointA); 67 68 #undef GET_PROC 69 } 70 71 static BOOL is_process_limited(void) 72 { 73 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; 74 PSID Group = NULL; 75 BOOL IsInGroup; 76 HANDLE token; 77 78 if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, 79 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) || 80 !CheckTokenMembership(NULL, Group, &IsInGroup)) 81 { 82 trace("Could not check if the current user is an administrator\n"); 83 FreeSid(Group); 84 return FALSE; 85 } 86 FreeSid(Group); 87 88 if (!IsInGroup) 89 { 90 if (!AllocateAndInitializeSid(&NtAuthority, 2, 91 SECURITY_BUILTIN_DOMAIN_RID, 92 DOMAIN_ALIAS_RID_POWER_USERS, 93 0, 0, 0, 0, 0, 0, &Group) || 94 !CheckTokenMembership(NULL, Group, &IsInGroup)) 95 { 96 trace("Could not check if the current user is a power user\n"); 97 return FALSE; 98 } 99 if (!IsInGroup) 100 { 101 /* Only administrators and power users can be powerful */ 102 return TRUE; 103 } 104 } 105 106 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) 107 { 108 BOOL ret; 109 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault; 110 DWORD size; 111 112 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size); 113 CloseHandle(token); 114 return (ret && type == TokenElevationTypeLimited); 115 } 116 return FALSE; 117 } 118 119 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access ) 120 { 121 if (pRegDeleteKeyExA) 122 return pRegDeleteKeyExA( key, subkey, access, 0 ); 123 return RegDeleteKeyA( key, subkey ); 124 } 125 126 static char *get_user_sid(void) 127 { 128 HANDLE token; 129 DWORD size = 0; 130 TOKEN_USER *user; 131 char *usersid = NULL; 132 133 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); 134 GetTokenInformation(token, TokenUser, NULL, size, &size); 135 136 user = malloc(size); 137 GetTokenInformation(token, TokenUser, user, size, &size); 138 ConvertSidToStringSidA(user->User.Sid, &usersid); 139 free(user); 140 141 CloseHandle(token); 142 return usersid; 143 } 144 145 /* RegDeleteTreeW from dlls/advapi32/registry.c */ 146 static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access) 147 { 148 LONG ret; 149 DWORD dwMaxSubkeyLen, dwMaxValueLen; 150 DWORD dwMaxLen, dwSize; 151 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf; 152 HKEY hSubKey = hKey; 153 154 if(lpszSubKey) 155 { 156 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey); 157 if (ret) return ret; 158 } 159 160 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, 161 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL); 162 if (ret) goto cleanup; 163 164 dwMaxSubkeyLen++; 165 dwMaxValueLen++; 166 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen); 167 if (dwMaxLen > ARRAY_SIZE(szNameBuf)) 168 { 169 /* Name too big: alloc a buffer for it */ 170 if (!(lpszName = malloc(dwMaxLen * sizeof(WCHAR)))) 171 { 172 ret = ERROR_NOT_ENOUGH_MEMORY; 173 goto cleanup; 174 } 175 } 176 177 /* Recursively delete all the subkeys */ 178 while (TRUE) 179 { 180 dwSize = dwMaxLen; 181 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, 182 NULL, NULL, NULL)) break; 183 184 ret = package_RegDeleteTreeW(hSubKey, lpszName, access); 185 if (ret) goto cleanup; 186 } 187 188 if (lpszSubKey) 189 { 190 if (pRegDeleteKeyExW) 191 ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0); 192 else 193 ret = RegDeleteKeyW(hKey, lpszSubKey); 194 } 195 else 196 while (TRUE) 197 { 198 dwSize = dwMaxLen; 199 if (RegEnumValueW(hKey, 0, lpszName, &dwSize, 200 NULL, NULL, NULL, NULL)) break; 201 202 ret = RegDeleteValueW(hKey, lpszName); 203 if (ret) goto cleanup; 204 } 205 206 cleanup: 207 if (lpszName != szNameBuf) free(lpszName); 208 if (lpszSubKey) RegCloseKey(hSubKey); 209 return ret; 210 } 211 212 static BOOL squash_guid(LPCWSTR in, LPWSTR out) 213 { 214 DWORD i,n=1; 215 GUID guid; 216 217 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid))) 218 return FALSE; 219 220 for(i=0; i<8; i++) 221 out[7-i] = in[n++]; 222 n++; 223 for(i=0; i<4; i++) 224 out[11-i] = in[n++]; 225 n++; 226 for(i=0; i<4; i++) 227 out[15-i] = in[n++]; 228 n++; 229 for(i=0; i<2; i++) 230 { 231 out[17+i*2] = in[n++]; 232 out[16+i*2] = in[n++]; 233 } 234 n++; 235 for( ; i<8; i++) 236 { 237 out[17+i*2] = in[n++]; 238 out[16+i*2] = in[n++]; 239 } 240 out[32]=0; 241 return TRUE; 242 } 243 244 static void create_test_guid(LPSTR prodcode, LPSTR squashed) 245 { 246 WCHAR guidW[MAX_PATH]; 247 WCHAR squashedW[MAX_PATH]; 248 GUID guid; 249 HRESULT hr; 250 int size; 251 252 hr = CoCreateGuid(&guid); 253 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr); 254 255 size = StringFromGUID2(&guid, guidW, MAX_PATH); 256 ok(size == 39, "Expected 39, got %#lx\n", hr); 257 258 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL); 259 squash_guid(guidW, squashedW); 260 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); 261 } 262 263 static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context, 264 LPCSTR guid, LPSTR usersid, BOOL dir) 265 { 266 WCHAR guidW[MAX_PATH]; 267 WCHAR squashedW[MAX_PATH]; 268 CHAR squashed[MAX_PATH]; 269 CHAR comppath[MAX_PATH + 81]; 270 CHAR prodpath[MAX_PATH]; 271 CHAR path[MAX_PATH]; 272 LPCSTR prod = NULL; 273 HKEY hkey; 274 REGSAM access = KEY_ALL_ACCESS; 275 276 if (is_wow64) 277 access |= KEY_WOW64_64KEY; 278 279 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH); 280 squash_guid(guidW, squashedW); 281 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); 282 283 if (context == MSIINSTALLCONTEXT_MACHINE) 284 { 285 prod = "3D0DAE300FACA1300AD792060BCDAA92"; 286 sprintf(comppath, 287 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 288 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed); 289 lstrcpyA(prodpath, 290 "SOFTWARE\\Classes\\Installer\\" 291 "Products\\3D0DAE300FACA1300AD792060BCDAA92"); 292 } 293 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED) 294 { 295 prod = "7D2F387510109040002000060BECB6AB"; 296 sprintf(comppath, 297 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 298 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed); 299 sprintf(prodpath, 300 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 301 "Installer\\%s\\Installer\\Products\\" 302 "7D2F387510109040002000060BECB6AB", usersid); 303 } 304 else if (context == MSIINSTALLCONTEXT_USERMANAGED) 305 { 306 prod = "7D2F387510109040002000060BECB6AB"; 307 sprintf(comppath, 308 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 309 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed); 310 sprintf(prodpath, 311 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 312 "Installer\\Managed\\%s\\Installer\\Products\\" 313 "7D2F387510109040002000060BECB6AB", usersid); 314 } 315 316 RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL); 317 318 lstrcpyA(path, CURR_DIR); 319 lstrcatA(path, "\\"); 320 if (!dir) lstrcatA(path, filename); 321 322 RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path)); 323 RegCloseKey(hkey); 324 325 RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL); 326 RegCloseKey(hkey); 327 } 328 329 static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid) 330 { 331 WCHAR guidW[MAX_PATH]; 332 WCHAR squashedW[MAX_PATH]; 333 WCHAR substrW[MAX_PATH]; 334 CHAR squashed[MAX_PATH]; 335 CHAR comppath[MAX_PATH + 81]; 336 CHAR prodpath[MAX_PATH]; 337 REGSAM access = KEY_ALL_ACCESS; 338 339 if (is_wow64) 340 access |= KEY_WOW64_64KEY; 341 342 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH); 343 squash_guid(guidW, squashedW); 344 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); 345 346 if (context == MSIINSTALLCONTEXT_MACHINE) 347 { 348 sprintf(comppath, 349 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 350 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed); 351 lstrcpyA(prodpath, 352 "SOFTWARE\\Classes\\Installer\\" 353 "Products\\3D0DAE300FACA1300AD792060BCDAA92"); 354 } 355 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED) 356 { 357 sprintf(comppath, 358 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 359 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed); 360 sprintf(prodpath, 361 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 362 "Installer\\%s\\Installer\\Products\\" 363 "7D2F387510109040002000060BECB6AB", usersid); 364 } 365 else if (context == MSIINSTALLCONTEXT_USERMANAGED) 366 { 367 sprintf(comppath, 368 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 369 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed); 370 sprintf(prodpath, 371 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 372 "Installer\\Managed\\%s\\Installer\\Products\\" 373 "7D2F387510109040002000060BECB6AB", usersid); 374 } 375 376 MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH); 377 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access); 378 379 MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH); 380 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access); 381 } 382 383 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec) 384 { 385 MSIHANDLE hview = 0; 386 UINT r, ret; 387 388 /* open a select query */ 389 r = MsiDatabaseOpenViewA(hdb, query, &hview); 390 if (r != ERROR_SUCCESS) 391 return r; 392 r = MsiViewExecute(hview, 0); 393 if (r != ERROR_SUCCESS) 394 return r; 395 ret = MsiViewFetch(hview, phrec); 396 r = MsiViewClose(hview); 397 if (r != ERROR_SUCCESS) 398 return r; 399 r = MsiCloseHandle(hview); 400 if (r != ERROR_SUCCESS) 401 return r; 402 return ret; 403 } 404 405 static UINT run_query( MSIHANDLE hdb, const char *query ) 406 { 407 MSIHANDLE hview = 0; 408 UINT r; 409 410 r = MsiDatabaseOpenViewA(hdb, query, &hview); 411 if( r != ERROR_SUCCESS ) 412 return r; 413 414 r = MsiViewExecute(hview, 0); 415 if( r == ERROR_SUCCESS ) 416 r = MsiViewClose(hview); 417 MsiCloseHandle(hview); 418 return r; 419 } 420 421 static UINT create_component_table( MSIHANDLE hdb ) 422 { 423 UINT r = run_query( hdb, 424 "CREATE TABLE `Component` ( " 425 "`Component` CHAR(72) NOT NULL, " 426 "`ComponentId` CHAR(38), " 427 "`Directory_` CHAR(72) NOT NULL, " 428 "`Attributes` SHORT NOT NULL, " 429 "`Condition` CHAR(255), " 430 "`KeyPath` CHAR(72) " 431 "PRIMARY KEY `Component`)" ); 432 ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r); 433 return r; 434 } 435 436 static UINT create_feature_table( MSIHANDLE hdb ) 437 { 438 UINT r = run_query( hdb, 439 "CREATE TABLE `Feature` ( " 440 "`Feature` CHAR(38) NOT NULL, " 441 "`Feature_Parent` CHAR(38), " 442 "`Title` CHAR(64), " 443 "`Description` CHAR(255), " 444 "`Display` SHORT NOT NULL, " 445 "`Level` SHORT NOT NULL, " 446 "`Directory_` CHAR(72), " 447 "`Attributes` SHORT NOT NULL " 448 "PRIMARY KEY `Feature`)" ); 449 ok(r == ERROR_SUCCESS, "Failed to create Feature table: %u\n", r); 450 return r; 451 } 452 453 static UINT create_feature_components_table( MSIHANDLE hdb ) 454 { 455 UINT r = run_query( hdb, 456 "CREATE TABLE `FeatureComponents` ( " 457 "`Feature_` CHAR(38) NOT NULL, " 458 "`Component_` CHAR(72) NOT NULL " 459 "PRIMARY KEY `Feature_`, `Component_` )" ); 460 ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r); 461 return r; 462 } 463 464 static UINT create_file_table( MSIHANDLE hdb ) 465 { 466 UINT r = run_query( hdb, 467 "CREATE TABLE `File` (" 468 "`File` CHAR(72) NOT NULL, " 469 "`Component_` CHAR(72) NOT NULL, " 470 "`FileName` CHAR(255) NOT NULL, " 471 "`FileSize` LONG NOT NULL, " 472 "`Version` CHAR(72), " 473 "`Language` CHAR(20), " 474 "`Attributes` SHORT, " 475 "`Sequence` SHORT NOT NULL " 476 "PRIMARY KEY `File`)" ); 477 ok(r == ERROR_SUCCESS, "Failed to create File table: %u\n", r); 478 return r; 479 } 480 481 static UINT create_remove_file_table( MSIHANDLE hdb ) 482 { 483 UINT r = run_query( hdb, 484 "CREATE TABLE `RemoveFile` (" 485 "`FileKey` CHAR(72) NOT NULL, " 486 "`Component_` CHAR(72) NOT NULL, " 487 "`FileName` CHAR(255) LOCALIZABLE, " 488 "`DirProperty` CHAR(72) NOT NULL, " 489 "`InstallMode` SHORT NOT NULL " 490 "PRIMARY KEY `FileKey`)" ); 491 ok(r == ERROR_SUCCESS, "Failed to create RemoveFile table: %u\n", r); 492 return r; 493 } 494 495 static UINT create_appsearch_table( MSIHANDLE hdb ) 496 { 497 UINT r = run_query( hdb, 498 "CREATE TABLE `AppSearch` (" 499 "`Property` CHAR(72) NOT NULL, " 500 "`Signature_` CHAR(72) NOT NULL " 501 "PRIMARY KEY `Property`, `Signature_`)" ); 502 ok(r == ERROR_SUCCESS, "Failed to create AppSearch table: %u\n", r); 503 return r; 504 } 505 506 static UINT create_reglocator_table( MSIHANDLE hdb ) 507 { 508 UINT r = run_query( hdb, 509 "CREATE TABLE `RegLocator` (" 510 "`Signature_` CHAR(72) NOT NULL, " 511 "`Root` SHORT NOT NULL, " 512 "`Key` CHAR(255) NOT NULL, " 513 "`Name` CHAR(255), " 514 "`Type` SHORT " 515 "PRIMARY KEY `Signature_`)" ); 516 ok(r == ERROR_SUCCESS, "Failed to create RegLocator table: %u\n", r); 517 return r; 518 } 519 520 static UINT create_signature_table( MSIHANDLE hdb ) 521 { 522 UINT r = run_query( hdb, 523 "CREATE TABLE `Signature` (" 524 "`Signature` CHAR(72) NOT NULL, " 525 "`FileName` CHAR(255) NOT NULL, " 526 "`MinVersion` CHAR(20), " 527 "`MaxVersion` CHAR(20), " 528 "`MinSize` LONG, " 529 "`MaxSize` LONG, " 530 "`MinDate` LONG, " 531 "`MaxDate` LONG, " 532 "`Languages` CHAR(255) " 533 "PRIMARY KEY `Signature`)" ); 534 ok(r == ERROR_SUCCESS, "Failed to create Signature table: %u\n", r); 535 return r; 536 } 537 538 static UINT create_launchcondition_table( MSIHANDLE hdb ) 539 { 540 UINT r = run_query( hdb, 541 "CREATE TABLE `LaunchCondition` (" 542 "`Condition` CHAR(255) NOT NULL, " 543 "`Description` CHAR(255) NOT NULL " 544 "PRIMARY KEY `Condition`)" ); 545 ok(r == ERROR_SUCCESS, "Failed to create LaunchCondition table: %u\n", r); 546 return r; 547 } 548 549 static UINT create_property_table( MSIHANDLE hdb ) 550 { 551 UINT r = run_query( hdb, 552 "CREATE TABLE `Property` (" 553 "`Property` CHAR(72) NOT NULL, " 554 "`Value` CHAR(0) " 555 "PRIMARY KEY `Property`)" ); 556 ok(r == ERROR_SUCCESS, "Failed to create Property table: %u\n", r); 557 return r; 558 } 559 560 static UINT create_install_execute_sequence_table( MSIHANDLE hdb ) 561 { 562 UINT r = run_query( hdb, 563 "CREATE TABLE `InstallExecuteSequence` (" 564 "`Action` CHAR(72) NOT NULL, " 565 "`Condition` CHAR(255), " 566 "`Sequence` SHORT " 567 "PRIMARY KEY `Action`)" ); 568 ok(r == ERROR_SUCCESS, "Failed to create InstallExecuteSequence table: %u\n", r); 569 return r; 570 } 571 572 static UINT create_install_ui_sequence_table( MSIHANDLE hdb ) 573 { 574 UINT r = run_query( hdb, 575 "CREATE TABLE `InstallUISequence` (" 576 "`Action` CHAR(72) NOT NULL, " 577 "`Condition` CHAR(255), " 578 "`Sequence` SHORT " 579 "PRIMARY KEY `Action`)" ); 580 ok(r == ERROR_SUCCESS, "Failed to create InstallUISequence table: %u\n", r); 581 return r; 582 } 583 584 static UINT create_media_table( MSIHANDLE hdb ) 585 { 586 UINT r = run_query( hdb, 587 "CREATE TABLE `Media` (" 588 "`DiskId` SHORT NOT NULL, " 589 "`LastSequence` SHORT NOT NULL, " 590 "`DiskPrompt` CHAR(64), " 591 "`Cabinet` CHAR(255), " 592 "`VolumeLabel` CHAR(32), " 593 "`Source` CHAR(72) " 594 "PRIMARY KEY `DiskId`)" ); 595 ok(r == ERROR_SUCCESS, "Failed to create Media table: %u\n", r); 596 return r; 597 } 598 599 static UINT create_ccpsearch_table( MSIHANDLE hdb ) 600 { 601 UINT r = run_query( hdb, 602 "CREATE TABLE `CCPSearch` (" 603 "`Signature_` CHAR(72) NOT NULL " 604 "PRIMARY KEY `Signature_`)" ); 605 ok(r == ERROR_SUCCESS, "Failed to create CCPSearch table: %u\n", r); 606 return r; 607 } 608 609 static UINT create_drlocator_table( MSIHANDLE hdb ) 610 { 611 UINT r = run_query( hdb, 612 "CREATE TABLE `DrLocator` (" 613 "`Signature_` CHAR(72) NOT NULL, " 614 "`Parent` CHAR(72), " 615 "`Path` CHAR(255), " 616 "`Depth` SHORT " 617 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" ); 618 ok(r == ERROR_SUCCESS, "Failed to create DrLocator table: %u\n", r); 619 return r; 620 } 621 622 static UINT create_complocator_table( MSIHANDLE hdb ) 623 { 624 UINT r = run_query( hdb, 625 "CREATE TABLE `CompLocator` (" 626 "`Signature_` CHAR(72) NOT NULL, " 627 "`ComponentId` CHAR(38) NOT NULL, " 628 "`Type` SHORT " 629 "PRIMARY KEY `Signature_`)" ); 630 ok(r == ERROR_SUCCESS, "Failed to create CompLocator table: %u\n", r); 631 return r; 632 } 633 634 static UINT create_inilocator_table( MSIHANDLE hdb ) 635 { 636 UINT r = run_query( hdb, 637 "CREATE TABLE `IniLocator` (" 638 "`Signature_` CHAR(72) NOT NULL, " 639 "`FileName` CHAR(255) NOT NULL, " 640 "`Section` CHAR(96)NOT NULL, " 641 "`Key` CHAR(128)NOT NULL, " 642 "`Field` SHORT, " 643 "`Type` SHORT " 644 "PRIMARY KEY `Signature_`)" ); 645 ok(r == ERROR_SUCCESS, "Failed to create IniLocator table: %u\n", r); 646 return r; 647 } 648 649 static UINT create_custom_action_table( MSIHANDLE hdb ) 650 { 651 UINT r = run_query( hdb, 652 "CREATE TABLE `CustomAction` (" 653 "`Action` CHAR(72) NOT NULL, " 654 "`Type` SHORT NOT NULL, " 655 "`Source` CHAR(75), " 656 "`Target` CHAR(255) " 657 "PRIMARY KEY `Action`)" ); 658 ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r); 659 return r; 660 } 661 662 static UINT create_dialog_table( MSIHANDLE hdb ) 663 { 664 UINT r = run_query(hdb, 665 "CREATE TABLE `Dialog` (" 666 "`Dialog` CHAR(72) NOT NULL, " 667 "`HCentering` SHORT NOT NULL, " 668 "`VCentering` SHORT NOT NULL, " 669 "`Width` SHORT NOT NULL, " 670 "`Height` SHORT NOT NULL, " 671 "`Attributes` LONG, " 672 "`Title` CHAR(128) LOCALIZABLE, " 673 "`Control_First` CHAR(50) NOT NULL, " 674 "`Control_Default` CHAR(50), " 675 "`Control_Cancel` CHAR(50) " 676 "PRIMARY KEY `Dialog`)"); 677 ok(r == ERROR_SUCCESS, "Failed to create Dialog table: %u\n", r); 678 return r; 679 } 680 681 static UINT create_control_table( MSIHANDLE hdb ) 682 { 683 UINT r = run_query(hdb, 684 "CREATE TABLE `Control` (" 685 "`Dialog_` CHAR(72) NOT NULL, " 686 "`Control` CHAR(50) NOT NULL, " 687 "`Type` CHAR(20) NOT NULL, " 688 "`X` SHORT NOT NULL, " 689 "`Y` SHORT NOT NULL, " 690 "`Width` SHORT NOT NULL, " 691 "`Height` SHORT NOT NULL, " 692 "`Attributes` LONG, " 693 "`Property` CHAR(50), " 694 "`Text` CHAR(0) LOCALIZABLE, " 695 "`Control_Next` CHAR(50), " 696 "`Help` CHAR(255) LOCALIZABLE " 697 "PRIMARY KEY `Dialog_`, `Control`)"); 698 ok(r == ERROR_SUCCESS, "Failed to create Control table: %u\n", r); 699 return r; 700 } 701 702 static UINT create_controlevent_table( MSIHANDLE hdb ) 703 { 704 UINT r = run_query(hdb, 705 "CREATE TABLE `ControlEvent` (" 706 "`Dialog_` CHAR(72) NOT NULL, " 707 "`Control_` CHAR(50) NOT NULL, " 708 "`Event` CHAR(50) NOT NULL, " 709 "`Argument` CHAR(255) NOT NULL, " 710 "`Condition` CHAR(255), " 711 "`Ordering` SHORT " 712 "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)"); 713 ok(r == ERROR_SUCCESS, "Failed to create ControlEvent table: %u\n", r); 714 return r; 715 } 716 717 static UINT create_actiontext_table( MSIHANDLE hdb ) 718 { 719 UINT r = run_query(hdb, 720 "CREATE TABLE `ActionText` (" 721 "`Action` CHAR(72) NOT NULL, " 722 "`Description` CHAR(64) LOCALIZABLE, " 723 "`Template` CHAR(128) LOCALIZABLE " 724 "PRIMARY KEY `Action`)"); 725 ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r); 726 return r; 727 } 728 729 static UINT create_upgrade_table( MSIHANDLE hdb ) 730 { 731 UINT r = run_query( hdb, 732 "CREATE TABLE `Upgrade` (" 733 "`UpgradeCode` CHAR(38) NOT NULL, " 734 "`VersionMin` CHAR(20), " 735 "`VersionMax` CHAR(20), " 736 "`Language` CHAR(255), " 737 "`Attributes` SHORT, " 738 "`Remove` CHAR(255), " 739 "`ActionProperty` CHAR(72) NOT NULL " 740 "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" ); 741 ok(r == ERROR_SUCCESS, "Failed to create Upgrade table: %u\n", r); 742 return r; 743 } 744 745 static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert) 746 { 747 char *query; 748 UINT sz, r; 749 750 sz = strlen(values) + strlen(insert) + 1; 751 query = malloc(sz); 752 sprintf(query, insert, values); 753 r = run_query(hdb, query); 754 free(query); 755 ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r); 756 return r; 757 } 758 759 #define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \ 760 "INSERT INTO `Component` " \ 761 "(`Component`, `ComponentId`, `Directory_`, " \ 762 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )") 763 764 #define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \ 765 "INSERT INTO `Directory` " \ 766 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )") 767 768 #define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \ 769 "INSERT INTO `Feature` " \ 770 "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \ 771 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )") 772 773 #define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \ 774 "INSERT INTO `FeatureComponents` " \ 775 "(`Feature_`, `Component_`) VALUES( %s )") 776 777 #define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \ 778 "INSERT INTO `File` " \ 779 "(`File`, `Component_`, `FileName`, `FileSize`, " \ 780 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )") 781 782 #define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \ 783 "INSERT INTO `AppSearch` " \ 784 "(`Property`, `Signature_`) VALUES( %s )") 785 786 #define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \ 787 "INSERT INTO `Signature` " \ 788 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \ 789 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \ 790 "VALUES( %s )") 791 792 #define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \ 793 "INSERT INTO `LaunchCondition` " \ 794 "(`Condition`, `Description`) VALUES( %s )") 795 796 #define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \ 797 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )") 798 799 #define update_ProductVersion_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \ 800 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'") 801 802 #define update_ProductCode_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \ 803 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'") 804 805 #define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \ 806 "INSERT INTO `InstallExecuteSequence` " \ 807 "(`Action`, `Condition`, `Sequence`) VALUES( %s )") 808 809 #define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \ 810 "INSERT INTO `InstallUISequence` " \ 811 "(`Action`, `Condition`, `Sequence`) VALUES( %s )") 812 813 #define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \ 814 "INSERT INTO `Media` " \ 815 "(`DiskId`, `LastSequence`, `DiskPrompt`, " \ 816 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )") 817 818 #define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \ 819 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )") 820 821 #define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \ 822 "INSERT INTO `DrLocator` " \ 823 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )") 824 825 #define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \ 826 "INSERT INTO `CompLocator` " \ 827 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )") 828 829 #define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \ 830 "INSERT INTO `IniLocator` " \ 831 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \ 832 "VALUES( %s )") 833 834 #define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \ 835 "INSERT INTO `CustomAction` " \ 836 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )") 837 838 #define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \ 839 "INSERT INTO `Dialog` " \ 840 "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )") 841 842 #define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \ 843 "INSERT INTO `Control` " \ 844 "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )"); 845 846 #define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \ 847 "INSERT INTO `ControlEvent` " \ 848 "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )"); 849 850 #define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \ 851 "INSERT INTO `ActionText` " \ 852 "(`Action`, `Description`, `Template`) VALUES( %s )"); 853 854 #define add_upgrade_entry(hdb, values) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \ 855 "INSERT INTO `Upgrade` " \ 856 "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )"); 857 858 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path, 859 const char *name, UINT type ) 860 { 861 const char insert[] = 862 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) " 863 "VALUES( '%s', %u, '%s', '%s', %u )"; 864 char *query; 865 UINT sz, r; 866 867 sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert ); 868 query = malloc( sz ); 869 sprintf( query, insert, sig, root, path, name, type ); 870 r = run_query( hdb, query ); 871 free( query ); 872 ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \ 873 return r; 874 } 875 876 static UINT set_summary_info(MSIHANDLE hdb) 877 { 878 UINT res; 879 MSIHANDLE suminfo; 880 881 /* build summary info */ 882 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo); 883 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" ); 884 885 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL, 886 "Installation Database"); 887 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 888 889 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL, 890 "Installation Database"); 891 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 892 893 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL, 894 "Wine Hackers"); 895 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 896 897 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL, 898 ";1033"); 899 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 900 901 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL, 902 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}"); 903 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 904 905 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL); 906 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 907 908 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL); 909 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 910 911 res = MsiSummaryInfoPersist(suminfo); 912 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" ); 913 914 res = MsiCloseHandle( suminfo); 915 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" ); 916 917 return res; 918 } 919 920 921 static MSIHANDLE create_package_db(void) 922 { 923 MSIHANDLE hdb = 0; 924 UINT res; 925 926 DeleteFileA(msifile); 927 928 /* create an empty database */ 929 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 930 ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res ); 931 if( res != ERROR_SUCCESS ) 932 return hdb; 933 934 res = MsiDatabaseCommit( hdb ); 935 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 936 937 res = set_summary_info(hdb); 938 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res); 939 940 res = run_query( hdb, 941 "CREATE TABLE `Directory` ( " 942 "`Directory` CHAR(255) NOT NULL, " 943 "`Directory_Parent` CHAR(255), " 944 "`DefaultDir` CHAR(255) NOT NULL " 945 "PRIMARY KEY `Directory`)" ); 946 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" ); 947 948 return hdb; 949 } 950 951 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) 952 { 953 UINT res; 954 CHAR szPackage[12]; 955 MSIHANDLE hPackage; 956 957 sprintf(szPackage, "#%lu", hdb); 958 res = MsiOpenPackageA(szPackage, &hPackage); 959 if (res != ERROR_SUCCESS) 960 { 961 MsiCloseHandle(hdb); 962 return res; 963 } 964 965 res = MsiCloseHandle(hdb); 966 if (res != ERROR_SUCCESS) 967 { 968 MsiCloseHandle(hPackage); 969 return res; 970 } 971 972 *handle = hPackage; 973 return ERROR_SUCCESS; 974 } 975 976 static void create_file_data(LPCSTR name, LPCSTR data) 977 { 978 HANDLE file; 979 DWORD written; 980 981 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); 982 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name); 983 if (file == INVALID_HANDLE_VALUE) 984 return; 985 986 WriteFile(file, data, strlen(data), &written, NULL); 987 WriteFile(file, "\n", strlen("\n"), &written, NULL); 988 989 CloseHandle(file); 990 } 991 992 static void create_test_file(const CHAR *name) 993 { 994 create_file_data(name, name); 995 } 996 997 typedef struct _tagVS_VERSIONINFO 998 { 999 WORD wLength; 1000 WORD wValueLength; 1001 WORD wType; 1002 WCHAR szKey[1]; 1003 WORD wPadding1[1]; 1004 VS_FIXEDFILEINFO Value; 1005 WORD wPadding2[1]; 1006 WORD wChildren[1]; 1007 } VS_VERSIONINFO; 1008 1009 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1)) 1010 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r)) 1011 1012 static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls) 1013 { 1014 VS_VERSIONINFO *pVerInfo; 1015 VS_FIXEDFILEINFO *pFixedInfo; 1016 LPBYTE buffer, ofs; 1017 CHAR path[MAX_PATH]; 1018 DWORD handle, size; 1019 HANDLE resource; 1020 BOOL ret = FALSE; 1021 1022 GetSystemDirectoryA(path, MAX_PATH); 1023 /* Some dlls can't be updated on Vista/W2K8 */ 1024 lstrcatA(path, "\\version.dll"); 1025 1026 CopyFileA(path, name, FALSE); 1027 1028 size = GetFileVersionInfoSizeA(path, &handle); 1029 buffer = malloc(size); 1030 1031 GetFileVersionInfoA(path, 0, size, buffer); 1032 1033 pVerInfo = (VS_VERSIONINFO *)buffer; 1034 ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1]; 1035 pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4); 1036 1037 pFixedInfo->dwFileVersionMS = ms; 1038 pFixedInfo->dwFileVersionLS = ls; 1039 pFixedInfo->dwProductVersionMS = ms; 1040 pFixedInfo->dwProductVersionLS = ls; 1041 1042 resource = BeginUpdateResourceA(name, FALSE); 1043 if (!resource) 1044 goto done; 1045 1046 if (!UpdateResourceA(resource, (LPCSTR)RT_VERSION, (LPCSTR)MAKEINTRESOURCE(VS_VERSION_INFO), 1047 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size)) 1048 goto done; 1049 1050 if (!EndUpdateResourceA(resource, FALSE)) 1051 goto done; 1052 1053 ret = TRUE; 1054 1055 done: 1056 free(buffer); 1057 return ret; 1058 } 1059 1060 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status) 1061 { 1062 RESTOREPOINTINFOA spec; 1063 1064 spec.dwEventType = event_type; 1065 spec.dwRestorePtType = APPLICATION_INSTALL; 1066 spec.llSequenceNumber = status->llSequenceNumber; 1067 lstrcpyA(spec.szDescription, "msitest restore point"); 1068 1069 return pSRSetRestorePointA(&spec, status); 1070 } 1071 1072 static void remove_restore_point(DWORD seq_number) 1073 { 1074 DWORD res; 1075 1076 res = pSRRemoveRestorePoint(seq_number); 1077 if (res != ERROR_SUCCESS) 1078 trace("Failed to remove the restore point: %#lx\n", res); 1079 } 1080 1081 static BOOL is_root(const char *path) 1082 { 1083 return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]); 1084 } 1085 1086 static void test_createpackage(void) 1087 { 1088 MSIHANDLE hPackage = 0; 1089 UINT res; 1090 1091 res = package_from_db(create_package_db(), &hPackage); 1092 if (res == ERROR_INSTALL_PACKAGE_REJECTED) 1093 { 1094 skip("Not enough rights to perform tests\n"); 1095 DeleteFileA(msifile); 1096 return; 1097 } 1098 ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res ); 1099 1100 res = MsiCloseHandle( hPackage); 1101 ok( res == ERROR_SUCCESS , "Failed to close package\n" ); 1102 DeleteFileA(msifile); 1103 } 1104 1105 static void test_doaction( void ) 1106 { 1107 MSIHANDLE hpkg; 1108 UINT r; 1109 1110 r = MsiDoActionA( -1, NULL ); 1111 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1112 1113 r = package_from_db(create_package_db(), &hpkg); 1114 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 1115 { 1116 skip("Not enough rights to perform tests\n"); 1117 DeleteFileA(msifile); 1118 return; 1119 } 1120 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 1121 1122 r = MsiDoActionA(hpkg, NULL); 1123 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1124 1125 r = MsiDoActionA(0, "boo"); 1126 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1127 1128 r = MsiDoActionA(hpkg, "boo"); 1129 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n"); 1130 1131 MsiCloseHandle( hpkg ); 1132 DeleteFileA(msifile); 1133 } 1134 1135 static void test_gettargetpath_bad(void) 1136 { 1137 char buffer[0x80]; 1138 WCHAR bufferW[0x80]; 1139 MSIHANDLE hpkg; 1140 DWORD sz; 1141 UINT r; 1142 1143 r = package_from_db(create_package_db(), &hpkg); 1144 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 1145 { 1146 skip("Not enough rights to perform tests\n"); 1147 DeleteFileA(msifile); 1148 return; 1149 } 1150 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 1151 1152 r = MsiGetTargetPathA( 0, NULL, NULL, NULL ); 1153 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1154 1155 r = MsiGetTargetPathA( 0, NULL, NULL, &sz ); 1156 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1157 1158 r = MsiGetTargetPathA( 0, "boo", NULL, NULL ); 1159 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1160 1161 r = MsiGetTargetPathA( 0, "boo", NULL, NULL ); 1162 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1163 1164 r = MsiGetTargetPathA( hpkg, "boo", NULL, NULL ); 1165 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1166 1167 r = MsiGetTargetPathA( hpkg, "boo", buffer, NULL ); 1168 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1169 1170 sz = 0; 1171 r = MsiGetTargetPathA( hpkg, "", buffer, &sz ); 1172 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1173 1174 r = MsiGetTargetPathW( 0, NULL, NULL, NULL ); 1175 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1176 1177 r = MsiGetTargetPathW( 0, NULL, NULL, &sz ); 1178 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1179 1180 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL ); 1181 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1182 1183 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL ); 1184 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1185 1186 r = MsiGetTargetPathW( hpkg, L"boo", NULL, NULL ); 1187 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1188 1189 r = MsiGetTargetPathW( hpkg, L"boo", bufferW, NULL ); 1190 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1191 1192 sz = 0; 1193 r = MsiGetTargetPathW( hpkg, L"", bufferW, &sz ); 1194 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1195 1196 MsiCloseHandle( hpkg ); 1197 DeleteFileA(msifile); 1198 } 1199 1200 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff) 1201 { 1202 UINT r; 1203 DWORD size; 1204 MSIHANDLE rec; 1205 1206 rec = MsiCreateRecord( 1 ); 1207 ok(rec, "MsiCreate record failed\n"); 1208 1209 r = MsiRecordSetStringA( rec, 0, file ); 1210 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 1211 1212 size = MAX_PATH; 1213 r = MsiFormatRecordA( hpkg, rec, buff, &size ); 1214 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 1215 1216 MsiCloseHandle( rec ); 1217 } 1218 1219 static void test_settargetpath(void) 1220 { 1221 char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH + 20]; 1222 DWORD sz; 1223 MSIHANDLE hpkg; 1224 UINT r; 1225 MSIHANDLE hdb; 1226 1227 hdb = create_package_db(); 1228 ok ( hdb, "failed to create package database\n" ); 1229 1230 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); 1231 1232 create_component_table( hdb ); 1233 add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" ); 1234 add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" ); 1235 1236 create_feature_table( hdb ); 1237 add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" ); 1238 1239 create_feature_components_table( hdb ); 1240 add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" ); 1241 add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" ); 1242 1243 add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" ); 1244 add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" ); 1245 1246 create_file_table( hdb ); 1247 add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" ); 1248 add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" ); 1249 1250 r = package_from_db( hdb, &hpkg ); 1251 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 1252 { 1253 skip("Not enough rights to perform tests\n"); 1254 DeleteFileA(msifile); 1255 return; 1256 } 1257 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 1258 1259 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 1260 1261 r = MsiDoActionA( hpkg, "CostInitialize"); 1262 ok( r == ERROR_SUCCESS, "cost init failed\n"); 1263 1264 r = MsiDoActionA( hpkg, "FileCost"); 1265 ok( r == ERROR_SUCCESS, "file cost failed\n"); 1266 1267 r = MsiDoActionA( hpkg, "CostFinalize"); 1268 ok( r == ERROR_SUCCESS, "cost finalize failed\n"); 1269 1270 buffer[0] = 0; 1271 sz = sizeof(buffer); 1272 r = MsiGetPropertyA( hpkg, "OutOfNoRbDiskSpace", buffer, &sz ); 1273 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); 1274 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer ); 1275 1276 r = MsiSetTargetPathA( 0, NULL, NULL ); 1277 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1278 1279 r = MsiSetTargetPathA( 0, "boo", "C:\\bogusx" ); 1280 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1281 1282 r = MsiSetTargetPathA( hpkg, "boo", NULL ); 1283 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1284 1285 r = MsiSetTargetPathA( hpkg, "boo", "c:\\bogusx" ); 1286 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1287 1288 sz = sizeof tempdir - 1; 1289 r = MsiGetTargetPathA( hpkg, "TARGETDIR", tempdir, &sz ); 1290 sprintf( file, "%srootfile.txt", tempdir ); 1291 buffer[0] = 0; 1292 query_file_path( hpkg, "[#RootFile]", buffer ); 1293 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1294 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer ); 1295 1296 GetTempFileNameA( tempdir, "_wt", 0, buffer ); 1297 sprintf( tempdir, "%s\\subdir", buffer ); 1298 1299 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer ); 1300 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY, 1301 "MsiSetTargetPath on file returned %d\n", r ); 1302 1303 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir ); 1304 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY, 1305 "MsiSetTargetPath on 'subdir' of file returned %d\n", r ); 1306 1307 DeleteFileA( buffer ); 1308 1309 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer ); 1310 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1311 1312 r = GetFileAttributesA( buffer ); 1313 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r ); 1314 1315 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir ); 1316 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r ); 1317 1318 buffer[0] = 0; 1319 sz = sizeof buffer - 1; 1320 lstrcatA( tempdir, "\\" ); 1321 r = MsiGetTargetPathA( hpkg, "TARGETDIR", buffer, &sz ); 1322 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1323 ok( !lstrcmpA(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer); 1324 1325 sprintf( file, "%srootfile.txt", tempdir ); 1326 query_file_path( hpkg, "[#RootFile]", buffer ); 1327 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer); 1328 1329 buffer[0] = 0; 1330 sz = sizeof(buffer); 1331 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz ); 1332 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); 1333 lstrcatA( tempdir, "TestParent\\" ); 1334 ok( !lstrcmpiA(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer ); 1335 1336 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two" ); 1337 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1338 1339 buffer[0] = 0; 1340 sz = sizeof(buffer); 1341 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz ); 1342 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); 1343 ok( lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\"), 1344 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer ); 1345 1346 buffer[0] = 0; 1347 query_file_path( hpkg, "[#TestFile]", buffer ); 1348 ok( !lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\testfile.txt"), 1349 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer ); 1350 1351 buffer[0] = 0; 1352 sz = sizeof buffer - 1; 1353 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz ); 1354 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1355 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer); 1356 1357 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two\\three" ); 1358 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1359 1360 buffer[0] = 0; 1361 sz = sizeof buffer - 1; 1362 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz ); 1363 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1364 ok( !lstrcmpiA(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer); 1365 1366 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\one\\\\two " ); 1367 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1368 1369 buffer[0] = 0; 1370 sz = sizeof buffer - 1; 1371 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz ); 1372 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1373 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer); 1374 1375 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " ); 1376 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1377 1378 buffer[0] = 0; 1379 sz = sizeof buffer - 1; 1380 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz ); 1381 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1382 ok( !lstrcmpiA(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer); 1383 1384 MsiCloseHandle( hpkg ); 1385 } 1386 1387 static void test_condition(void) 1388 { 1389 MSICONDITION r; 1390 MSIHANDLE hpkg; 1391 1392 r = package_from_db(create_package_db(), &hpkg); 1393 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 1394 { 1395 skip("Not enough rights to perform tests\n"); 1396 DeleteFileA(msifile); 1397 return; 1398 } 1399 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 1400 1401 r = MsiEvaluateConditionA(0, NULL); 1402 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1403 1404 r = MsiEvaluateConditionA(hpkg, NULL); 1405 ok( r == MSICONDITION_NONE, "wrong return val\n"); 1406 1407 r = MsiEvaluateConditionA(hpkg, ""); 1408 ok( r == MSICONDITION_NONE, "wrong return val\n"); 1409 1410 r = MsiEvaluateConditionA(hpkg, "1"); 1411 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1412 1413 r = MsiEvaluateConditionA(hpkg, "0"); 1414 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1415 1416 r = MsiEvaluateConditionA(hpkg, "-1"); 1417 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1418 1419 r = MsiEvaluateConditionA(hpkg, "0 = 0"); 1420 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1421 1422 r = MsiEvaluateConditionA(hpkg, "0 <> 0"); 1423 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1424 1425 r = MsiEvaluateConditionA(hpkg, "0 = 1"); 1426 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1427 1428 r = MsiEvaluateConditionA(hpkg, "0 > 1"); 1429 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1430 1431 r = MsiEvaluateConditionA(hpkg, "0 ~> 1"); 1432 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1433 1434 r = MsiEvaluateConditionA(hpkg, "1 > 1"); 1435 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1436 1437 r = MsiEvaluateConditionA(hpkg, "1 ~> 1"); 1438 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1439 1440 r = MsiEvaluateConditionA(hpkg, "0 >= 1"); 1441 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1442 1443 r = MsiEvaluateConditionA(hpkg, "0 ~>= 1"); 1444 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1445 1446 r = MsiEvaluateConditionA(hpkg, "1 >= 1"); 1447 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1448 1449 r = MsiEvaluateConditionA(hpkg, "1 ~>= 1"); 1450 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1451 1452 r = MsiEvaluateConditionA(hpkg, "0 < 1"); 1453 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1454 1455 r = MsiEvaluateConditionA(hpkg, "0 ~< 1"); 1456 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1457 1458 r = MsiEvaluateConditionA(hpkg, "1 < 1"); 1459 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1460 1461 r = MsiEvaluateConditionA(hpkg, "1 ~< 1"); 1462 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1463 1464 r = MsiEvaluateConditionA(hpkg, "0 <= 1"); 1465 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1466 1467 r = MsiEvaluateConditionA(hpkg, "0 ~<= 1"); 1468 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1469 1470 r = MsiEvaluateConditionA(hpkg, "1 <= 1"); 1471 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1472 1473 r = MsiEvaluateConditionA(hpkg, "1 ~<= 1"); 1474 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1475 1476 r = MsiEvaluateConditionA(hpkg, "0 >="); 1477 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1478 1479 r = MsiEvaluateConditionA(hpkg, " "); 1480 ok( r == MSICONDITION_NONE, "wrong return val\n"); 1481 1482 r = MsiEvaluateConditionA(hpkg, "LicView <> \"1\""); 1483 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1484 1485 r = MsiEvaluateConditionA(hpkg, "LicView <> \"0\""); 1486 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1487 1488 r = MsiEvaluateConditionA(hpkg, "LicView <> LicView"); 1489 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1490 1491 r = MsiEvaluateConditionA(hpkg, "not 0"); 1492 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1493 1494 r = MsiEvaluateConditionA(hpkg, "not LicView"); 1495 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1496 1497 r = MsiEvaluateConditionA(hpkg, "\"Testing\" ~<< \"Testing\""); 1498 ok (r == MSICONDITION_TRUE, "wrong return val\n"); 1499 1500 r = MsiEvaluateConditionA(hpkg, "LicView ~<< \"Testing\""); 1501 ok (r == MSICONDITION_FALSE, "wrong return val\n"); 1502 1503 r = MsiEvaluateConditionA(hpkg, "Not LicView ~<< \"Testing\""); 1504 ok (r == MSICONDITION_TRUE, "wrong return val\n"); 1505 1506 r = MsiEvaluateConditionA(hpkg, "not \"A\""); 1507 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1508 1509 r = MsiEvaluateConditionA(hpkg, "~not \"A\""); 1510 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1511 1512 r = MsiEvaluateConditionA(hpkg, "\"0\""); 1513 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1514 1515 r = MsiEvaluateConditionA(hpkg, "1 and 2"); 1516 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1517 1518 r = MsiEvaluateConditionA(hpkg, "not 0 and 3"); 1519 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1520 1521 r = MsiEvaluateConditionA(hpkg, "not 0 and 0"); 1522 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1523 1524 r = MsiEvaluateConditionA(hpkg, "not 0 or 1"); 1525 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1526 1527 r = MsiEvaluateConditionA(hpkg, "(0)"); 1528 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1529 1530 r = MsiEvaluateConditionA(hpkg, "(((((1))))))"); 1531 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1532 1533 r = MsiEvaluateConditionA(hpkg, "(((((1)))))"); 1534 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1535 1536 r = MsiEvaluateConditionA(hpkg, " \"A\" < \"B\" "); 1537 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1538 1539 r = MsiEvaluateConditionA(hpkg, " \"A\" > \"B\" "); 1540 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1541 1542 r = MsiEvaluateConditionA(hpkg, " \"1\" > \"12\" "); 1543 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1544 1545 r = MsiEvaluateConditionA(hpkg, " \"100\" < \"21\" "); 1546 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1547 1548 r = MsiEvaluateConditionA(hpkg, "0 < > 0"); 1549 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1550 1551 r = MsiEvaluateConditionA(hpkg, "(1<<1) == 2"); 1552 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1553 1554 r = MsiEvaluateConditionA(hpkg, " \"A\" = \"a\" "); 1555 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1556 1557 r = MsiEvaluateConditionA(hpkg, " \"A\" ~ = \"a\" "); 1558 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1559 1560 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= \"a\" "); 1561 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1562 1563 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= 1 "); 1564 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1565 1566 r = MsiEvaluateConditionA(hpkg, " \"A\" = 1 "); 1567 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1568 1569 r = MsiEvaluateConditionA(hpkg, " 1 ~= 1 "); 1570 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1571 1572 r = MsiEvaluateConditionA(hpkg, " 1 ~= \"1\" "); 1573 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1574 1575 r = MsiEvaluateConditionA(hpkg, " 1 = \"1\" "); 1576 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1577 1578 r = MsiEvaluateConditionA(hpkg, " 0 = \"1\" "); 1579 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1580 1581 r = MsiEvaluateConditionA(hpkg, " 0 < \"100\" "); 1582 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1583 1584 r = MsiEvaluateConditionA(hpkg, " 100 > \"0\" "); 1585 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1586 1587 r = MsiEvaluateConditionA(hpkg, "1 XOR 1"); 1588 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1589 1590 r = MsiEvaluateConditionA(hpkg, "1 IMP 1"); 1591 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1592 1593 r = MsiEvaluateConditionA(hpkg, "1 IMP 0"); 1594 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1595 1596 r = MsiEvaluateConditionA(hpkg, "0 IMP 0"); 1597 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1598 1599 r = MsiEvaluateConditionA(hpkg, "0 EQV 0"); 1600 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1601 1602 r = MsiEvaluateConditionA(hpkg, "0 EQV 1"); 1603 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1604 1605 r = MsiEvaluateConditionA(hpkg, "1 IMP 1 OR 0"); 1606 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1607 1608 r = MsiEvaluateConditionA(hpkg, "1 IMPL 1"); 1609 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1610 1611 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" >< \"S\" "); 1612 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1613 1614 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"s\" "); 1615 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1616 1617 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"\" "); 1618 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1619 1620 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"sss\" "); 1621 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1622 1623 MsiSetPropertyA(hpkg, "mm", "5" ); 1624 1625 r = MsiEvaluateConditionA(hpkg, "mm = 5"); 1626 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1627 1628 r = MsiEvaluateConditionA(hpkg, "mm < 6"); 1629 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1630 1631 r = MsiEvaluateConditionA(hpkg, "mm <= 5"); 1632 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1633 1634 r = MsiEvaluateConditionA(hpkg, "mm > 4"); 1635 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1636 1637 r = MsiEvaluateConditionA(hpkg, "mm < 12"); 1638 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1639 1640 r = MsiEvaluateConditionA(hpkg, "mm = \"5\""); 1641 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1642 1643 r = MsiEvaluateConditionA(hpkg, "0 = \"\""); 1644 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1645 1646 r = MsiEvaluateConditionA(hpkg, "0 AND \"\""); 1647 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1648 1649 r = MsiEvaluateConditionA(hpkg, "1 AND \"\""); 1650 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1651 1652 r = MsiEvaluateConditionA(hpkg, "1 AND \"1\""); 1653 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1654 1655 r = MsiEvaluateConditionA(hpkg, "3 >< 1"); 1656 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1657 1658 r = MsiEvaluateConditionA(hpkg, "3 >< 4"); 1659 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1660 1661 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 0"); 1662 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1663 1664 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1"); 1665 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1666 1667 r = MsiEvaluateConditionA(hpkg, "NOT 1 OR 0"); 1668 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1669 1670 r = MsiEvaluateConditionA(hpkg, "0 AND 1 OR 1"); 1671 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1672 1673 r = MsiEvaluateConditionA(hpkg, "0 AND 0 OR 1"); 1674 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1675 1676 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1 OR 0"); 1677 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1678 1679 r = MsiEvaluateConditionA(hpkg, "_1 = _1"); 1680 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1681 1682 r = MsiEvaluateConditionA(hpkg, "( 1 AND 1 ) = 2"); 1683 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1684 1685 r = MsiEvaluateConditionA(hpkg, "NOT ( 1 AND 1 )"); 1686 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1687 1688 r = MsiEvaluateConditionA(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd"); 1689 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1690 1691 r = MsiEvaluateConditionA(hpkg, "Installed<>\"\""); 1692 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1693 1694 r = MsiEvaluateConditionA(hpkg, "NOT 1 AND 0"); 1695 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1696 1697 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1698 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1699 1700 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0"); 1701 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1702 1703 r = MsiEvaluateConditionA(hpkg, "bandalmael<0"); 1704 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1705 1706 r = MsiEvaluateConditionA(hpkg, "bandalmael>0"); 1707 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1708 1709 r = MsiEvaluateConditionA(hpkg, "bandalmael>=0"); 1710 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1711 1712 r = MsiEvaluateConditionA(hpkg, "bandalmael<=0"); 1713 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1714 1715 r = MsiEvaluateConditionA(hpkg, "bandalmael~<>0"); 1716 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1717 1718 MsiSetPropertyA(hpkg, "bandalmael", "0" ); 1719 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1720 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1721 1722 MsiSetPropertyA(hpkg, "bandalmael", "" ); 1723 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1724 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1725 1726 MsiSetPropertyA(hpkg, "bandalmael", "asdf" ); 1727 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1728 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1729 1730 MsiSetPropertyA(hpkg, "bandalmael", "0asdf" ); 1731 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1732 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1733 1734 MsiSetPropertyA(hpkg, "bandalmael", "0 " ); 1735 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1736 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1737 1738 MsiSetPropertyA(hpkg, "bandalmael", "-0" ); 1739 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1740 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1741 1742 MsiSetPropertyA(hpkg, "bandalmael", "0000000000000" ); 1743 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1744 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1745 1746 MsiSetPropertyA(hpkg, "bandalmael", "--0" ); 1747 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1748 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1749 1750 MsiSetPropertyA(hpkg, "bandalmael", "0x00" ); 1751 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1752 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1753 1754 MsiSetPropertyA(hpkg, "bandalmael", "-" ); 1755 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1756 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1757 1758 MsiSetPropertyA(hpkg, "bandalmael", "+0" ); 1759 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1760 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1761 1762 MsiSetPropertyA(hpkg, "bandalmael", "0.0" ); 1763 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1764 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1765 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0"); 1766 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1767 1768 MsiSetPropertyA(hpkg, "one", "hi"); 1769 MsiSetPropertyA(hpkg, "two", "hithere"); 1770 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1771 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1772 1773 MsiSetPropertyA(hpkg, "one", "hithere"); 1774 MsiSetPropertyA(hpkg, "two", "hi"); 1775 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1776 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1777 1778 MsiSetPropertyA(hpkg, "one", "hello"); 1779 MsiSetPropertyA(hpkg, "two", "hi"); 1780 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1781 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1782 1783 MsiSetPropertyA(hpkg, "one", "hellohithere"); 1784 MsiSetPropertyA(hpkg, "two", "hi"); 1785 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1786 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1787 1788 MsiSetPropertyA(hpkg, "one", ""); 1789 MsiSetPropertyA(hpkg, "two", "hi"); 1790 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1791 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1792 1793 MsiSetPropertyA(hpkg, "one", "hi"); 1794 MsiSetPropertyA(hpkg, "two", ""); 1795 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1796 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1797 1798 MsiSetPropertyA(hpkg, "one", ""); 1799 MsiSetPropertyA(hpkg, "two", ""); 1800 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1801 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1802 1803 MsiSetPropertyA(hpkg, "one", "1234"); 1804 MsiSetPropertyA(hpkg, "two", "1"); 1805 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1806 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1807 1808 MsiSetPropertyA(hpkg, "one", "one 1234"); 1809 MsiSetPropertyA(hpkg, "two", "1"); 1810 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1811 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1812 1813 MsiSetPropertyA(hpkg, "one", "hithere"); 1814 MsiSetPropertyA(hpkg, "two", "hi"); 1815 r = MsiEvaluateConditionA(hpkg, "one << two"); 1816 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1817 1818 MsiSetPropertyA(hpkg, "one", "hi"); 1819 MsiSetPropertyA(hpkg, "two", "hithere"); 1820 r = MsiEvaluateConditionA(hpkg, "one << two"); 1821 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1822 1823 MsiSetPropertyA(hpkg, "one", "hi"); 1824 MsiSetPropertyA(hpkg, "two", "hi"); 1825 r = MsiEvaluateConditionA(hpkg, "one << two"); 1826 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1827 1828 MsiSetPropertyA(hpkg, "one", "abcdhithere"); 1829 MsiSetPropertyA(hpkg, "two", "hi"); 1830 r = MsiEvaluateConditionA(hpkg, "one << two"); 1831 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1832 1833 MsiSetPropertyA(hpkg, "one", ""); 1834 MsiSetPropertyA(hpkg, "two", "hi"); 1835 r = MsiEvaluateConditionA(hpkg, "one << two"); 1836 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1837 1838 MsiSetPropertyA(hpkg, "one", "hithere"); 1839 MsiSetPropertyA(hpkg, "two", ""); 1840 r = MsiEvaluateConditionA(hpkg, "one << two"); 1841 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1842 1843 MsiSetPropertyA(hpkg, "one", ""); 1844 MsiSetPropertyA(hpkg, "two", ""); 1845 r = MsiEvaluateConditionA(hpkg, "one << two"); 1846 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1847 1848 MsiSetPropertyA(hpkg, "one", "1234"); 1849 MsiSetPropertyA(hpkg, "two", "1"); 1850 r = MsiEvaluateConditionA(hpkg, "one << two"); 1851 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1852 1853 MsiSetPropertyA(hpkg, "one", "1234 one"); 1854 MsiSetPropertyA(hpkg, "two", "1"); 1855 r = MsiEvaluateConditionA(hpkg, "one << two"); 1856 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1857 1858 MsiSetPropertyA(hpkg, "one", "hithere"); 1859 MsiSetPropertyA(hpkg, "two", "there"); 1860 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1861 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1862 1863 MsiSetPropertyA(hpkg, "one", "hithere"); 1864 MsiSetPropertyA(hpkg, "two", "hi"); 1865 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1866 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1867 1868 MsiSetPropertyA(hpkg, "one", "there"); 1869 MsiSetPropertyA(hpkg, "two", "hithere"); 1870 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1871 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1872 1873 MsiSetPropertyA(hpkg, "one", "there"); 1874 MsiSetPropertyA(hpkg, "two", "there"); 1875 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1876 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1877 1878 MsiSetPropertyA(hpkg, "one", "abcdhithere"); 1879 MsiSetPropertyA(hpkg, "two", "hi"); 1880 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1881 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1882 1883 MsiSetPropertyA(hpkg, "one", ""); 1884 MsiSetPropertyA(hpkg, "two", "there"); 1885 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1886 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1887 1888 MsiSetPropertyA(hpkg, "one", "there"); 1889 MsiSetPropertyA(hpkg, "two", ""); 1890 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1891 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1892 1893 MsiSetPropertyA(hpkg, "one", ""); 1894 MsiSetPropertyA(hpkg, "two", ""); 1895 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1896 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1897 1898 MsiSetPropertyA(hpkg, "one", "1234"); 1899 MsiSetPropertyA(hpkg, "two", "4"); 1900 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1901 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1902 1903 MsiSetPropertyA(hpkg, "one", "one 1234"); 1904 MsiSetPropertyA(hpkg, "two", "4"); 1905 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1906 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1907 1908 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", NULL); /* make sure it's empty */ 1909 1910 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\""); 1911 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1912 1913 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport > \"1.1.4322\""); 1914 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1915 1916 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\""); 1917 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1918 1919 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\""); 1920 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1921 1922 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\""); 1923 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1924 1925 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\""); 1926 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1927 1928 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"abcd\""); 1929 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1930 1931 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\""); 1932 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1933 1934 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\""); 1935 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1936 1937 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\""); 1938 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1939 1940 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\""); 1941 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1942 1943 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\""); 1944 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1945 1946 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1"); 1947 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r); 1948 1949 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1\""); 1950 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1951 1952 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"12.1\""); 1953 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1954 1955 r = MsiEvaluateConditionA(hpkg, "\"02.1\" < \"2.11\""); 1956 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1957 1958 r = MsiEvaluateConditionA(hpkg, "\"02.1.1\" < \"2.1\""); 1959 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1960 1961 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\""); 1962 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1963 1964 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\""); 1965 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1966 1967 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0\""); 1968 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1969 1970 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"-1\""); 1971 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1972 1973 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a\""); 1974 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1975 1976 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\""); 1977 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1978 1979 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\""); 1980 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1981 1982 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"/\""); 1983 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1984 1985 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \" \""); 1986 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1987 1988 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"azAZ_\""); 1989 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1990 1991 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]\""); 1992 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1993 1994 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]a\""); 1995 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1996 1997 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]\""); 1998 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1999 2000 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]a\""); 2001 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2002 2003 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a}\""); 2004 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2005 2006 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a\""); 2007 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2008 2009 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a\""); 2010 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2011 2012 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a{\""); 2013 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2014 2015 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a]\""); 2016 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2017 2018 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"A\""); 2019 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2020 2021 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", "1.1.4322"); 2022 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\""); 2023 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2024 2025 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.14322\""); 2026 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2027 2028 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.5\""); 2029 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2030 2031 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\""); 2032 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2033 2034 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\""); 2035 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2036 2037 MsiSetPropertyA(hpkg, "one", "1"); 2038 r = MsiEvaluateConditionA(hpkg, "one < \"1\""); 2039 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 2040 2041 MsiSetPropertyA(hpkg, "X", "5.0"); 2042 2043 r = MsiEvaluateConditionA(hpkg, "X != \"\""); 2044 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r); 2045 2046 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\""); 2047 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2048 2049 r = MsiEvaluateConditionA(hpkg, "X =\"5.1\""); 2050 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2051 2052 r = MsiEvaluateConditionA(hpkg, "X =\"6.0\""); 2053 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2054 2055 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\""); 2056 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2057 2058 r = MsiEvaluateConditionA(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")"); 2059 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2060 2061 r = MsiEvaluateConditionA(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")"); 2062 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r); 2063 2064 /* feature doesn't exist */ 2065 r = MsiEvaluateConditionA(hpkg, "&nofeature"); 2066 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2067 r = MsiEvaluateConditionA(hpkg, "&nofeature=\"\""); 2068 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2069 r = MsiEvaluateConditionA(hpkg, "&nofeature<>3"); 2070 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2071 r = MsiEvaluateConditionA(hpkg, "\"\"<>3"); 2072 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2073 r = MsiEvaluateConditionA(hpkg, "!nofeature=\"\""); 2074 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2075 r = MsiEvaluateConditionA(hpkg, "$nocomponent=\"\""); 2076 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2077 r = MsiEvaluateConditionA(hpkg, "?nocomponent=\"\""); 2078 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2079 2080 MsiSetPropertyA(hpkg, "A", "2"); 2081 MsiSetPropertyA(hpkg, "X", "50"); 2082 2083 r = MsiEvaluateConditionA(hpkg, "2 <= X"); 2084 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2085 2086 r = MsiEvaluateConditionA(hpkg, "A <= X"); 2087 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2088 2089 r = MsiEvaluateConditionA(hpkg, "A <= 50"); 2090 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2091 2092 MsiSetPropertyA(hpkg, "X", "50val"); 2093 2094 r = MsiEvaluateConditionA(hpkg, "2 <= X"); 2095 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2096 2097 r = MsiEvaluateConditionA(hpkg, "A <= X"); 2098 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2099 2100 MsiSetPropertyA(hpkg, "A", "7"); 2101 MsiSetPropertyA(hpkg, "X", "50"); 2102 2103 r = MsiEvaluateConditionA(hpkg, "7 <= X"); 2104 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2105 2106 r = MsiEvaluateConditionA(hpkg, "A <= X"); 2107 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2108 2109 r = MsiEvaluateConditionA(hpkg, "A <= 50"); 2110 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 2111 2112 MsiSetPropertyA(hpkg, "X", "50val"); 2113 2114 r = MsiEvaluateConditionA(hpkg, "2 <= X"); 2115 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2116 2117 r = MsiEvaluateConditionA(hpkg, "A <= X"); 2118 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 2119 2120 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<\"\xe5\""); 2121 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE), 2122 "wrong return val (%d)\n", r); 2123 2124 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\">\"\xe5\""); 2125 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE), 2126 "wrong return val (%d)\n", r); 2127 2128 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<>\"\xe5\""); 2129 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE), 2130 "wrong return val (%d)\n", r); 2131 2132 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"=\"\xe5\""); 2133 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE), 2134 "wrong return val (%d)\n", r); 2135 2136 MsiCloseHandle( hpkg ); 2137 DeleteFileA(msifile); 2138 } 2139 2140 static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case) 2141 { 2142 char buffer[MAX_PATH] = "x"; 2143 DWORD sz = sizeof(buffer); 2144 UINT r = MsiGetPropertyA(hpkg, prop, buffer, &sz); 2145 ok(!r, "'%s': got %u\n", prop, r); 2146 ok(sz == lstrlenA(buffer), "'%s': expected %u, got %lu\n", prop, lstrlenA(buffer), sz); 2147 if (match_case) 2148 ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer); 2149 else 2150 ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer); 2151 } 2152 2153 static void test_props(void) 2154 { 2155 MSIHANDLE hpkg, hdb; 2156 UINT r; 2157 DWORD sz; 2158 char buffer[0x100]; 2159 WCHAR bufferW[10]; 2160 2161 hdb = create_package_db(); 2162 2163 create_property_table(hdb); 2164 add_property_entry(hdb, "'MetadataCompName', 'Photoshop.dll'"); 2165 2166 r = package_from_db( hdb, &hpkg ); 2167 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2168 { 2169 skip("Not enough rights to perform tests\n"); 2170 DeleteFileA(msifile); 2171 return; 2172 } 2173 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 2174 2175 /* test invalid values */ 2176 r = MsiGetPropertyA( 0, NULL, NULL, NULL ); 2177 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2178 2179 r = MsiGetPropertyA( hpkg, NULL, NULL, NULL ); 2180 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2181 2182 r = MsiGetPropertyA( hpkg, "boo", NULL, NULL ); 2183 ok(!r, "got %u\n", r); 2184 2185 r = MsiGetPropertyA( hpkg, "boo", buffer, NULL ); 2186 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2187 2188 /* test retrieving an empty/nonexistent property */ 2189 sz = sizeof buffer; 2190 r = MsiGetPropertyA( hpkg, "boo", NULL, &sz ); 2191 ok(!r, "got %u\n", r); 2192 ok(sz == 0, "got size %lu\n", sz); 2193 2194 sz = 0; 2195 strcpy(buffer,"x"); 2196 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2197 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2198 ok(!strcmp(buffer,"x"), "got \"%s\"\n", buffer); 2199 ok(sz == 0, "got size %lu\n", sz); 2200 2201 sz = 1; 2202 strcpy(buffer,"x"); 2203 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2204 ok(!r, "got %u\n", r); 2205 ok(!buffer[0], "got \"%s\"\n", buffer); 2206 ok(sz == 0, "got size %lu\n", sz); 2207 2208 /* set the property to something */ 2209 r = MsiSetPropertyA( 0, NULL, NULL ); 2210 ok(r == ERROR_INVALID_HANDLE, "got %u\n", r); 2211 2212 r = MsiSetPropertyA( hpkg, NULL, NULL ); 2213 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2214 2215 r = MsiSetPropertyA( hpkg, "", NULL ); 2216 ok(!r, "got %u\n", r); 2217 2218 r = MsiSetPropertyA( hpkg, "", "asdf" ); 2219 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); 2220 2221 r = MsiSetPropertyA( hpkg, "=", "asdf" ); 2222 ok(!r, "got %u\n", r); 2223 check_prop(hpkg, "=", "asdf", 1); 2224 2225 r = MsiSetPropertyA( hpkg, " ", "asdf" ); 2226 ok(!r, "got %u\n", r); 2227 check_prop(hpkg, " ", "asdf", 1); 2228 2229 r = MsiSetPropertyA( hpkg, "'", "asdf" ); 2230 ok(!r, "got %u\n", r); 2231 check_prop(hpkg, "'", "asdf", 1); 2232 2233 /* set empty values */ 2234 r = MsiSetPropertyA( hpkg, "boo", NULL ); 2235 ok(!r, "got %u\n", r); 2236 check_prop(hpkg, "boo", "", 1); 2237 2238 r = MsiSetPropertyA( hpkg, "boo", "" ); 2239 ok(!r, "got %u\n", r); 2240 check_prop(hpkg, "boo", "", 1); 2241 2242 /* set a non-empty value */ 2243 r = MsiSetPropertyA( hpkg, "boo", "xyz" ); 2244 ok(!r, "got %u\n", r); 2245 check_prop(hpkg, "boo", "xyz", 1); 2246 2247 r = MsiGetPropertyA(hpkg, "boo", NULL, NULL); 2248 ok(!r, "got %u\n", r); 2249 2250 r = MsiGetPropertyA(hpkg, "boo", buffer, NULL); 2251 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2252 2253 sz = 0; 2254 r = MsiGetPropertyA(hpkg, "boo", NULL, &sz); 2255 ok(!r, "got %u\n", r); 2256 ok(sz == 3, "got size %lu\n", sz); 2257 2258 sz = 0; 2259 strcpy(buffer, "q"); 2260 r = MsiGetPropertyA(hpkg, "boo", buffer, &sz); 2261 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2262 ok(!strcmp(buffer, "q"), "got \"%s\"", buffer); 2263 ok(sz == 3, "got size %lu\n", sz); 2264 2265 sz = 1; 2266 strcpy(buffer,"x"); 2267 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2268 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2269 ok(!buffer[0], "got \"%s\"\n", buffer); 2270 ok(sz == 3, "got size %lu\n", sz); 2271 2272 sz = 3; 2273 strcpy(buffer,"x"); 2274 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2275 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2276 ok(!strcmp(buffer,"xy"), "got \"%s\"\n", buffer); 2277 ok(sz == 3, "got size %lu\n", sz); 2278 2279 sz = 4; 2280 strcpy(buffer,"x"); 2281 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2282 ok(!r, "got %u\n", r); 2283 ok(!strcmp(buffer,"xyz"), "got \"%s\"\n", buffer); 2284 ok(sz == 3, "got size %lu\n", sz); 2285 2286 sz = 0; 2287 r = MsiGetPropertyW(hpkg, L"boo", NULL, &sz); 2288 ok(!r, "got %u\n", r); 2289 ok(sz == 3, "got size %lu\n", sz); 2290 2291 sz = 0; 2292 lstrcpyW(bufferW, L"boo"); 2293 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz); 2294 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2295 ok(!lstrcmpW(bufferW, L"boo"), "got %s\n", wine_dbgstr_w(bufferW)); 2296 ok(sz == 3, "got size %lu\n", sz); 2297 2298 sz = 1; 2299 lstrcpyW(bufferW, L"boo"); 2300 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz ); 2301 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2302 ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW)); 2303 ok(sz == 3, "got size %lu\n", sz); 2304 2305 sz = 3; 2306 lstrcpyW(bufferW, L"boo"); 2307 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz ); 2308 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2309 ok(!lstrcmpW(bufferW, L"xy"), "got %s\n", wine_dbgstr_w(bufferW)); 2310 ok(sz == 3, "got size %lu\n", sz); 2311 2312 sz = 4; 2313 lstrcpyW(bufferW, L"boo"); 2314 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz ); 2315 ok(!r, "got %u\n", r); 2316 ok(!lstrcmpW(bufferW, L"xyz"), "got %s\n", wine_dbgstr_w(bufferW)); 2317 ok(sz == 3, "got size %lu\n", sz); 2318 2319 /* properties are case-sensitive */ 2320 check_prop(hpkg, "BOO", "", 1); 2321 2322 /* properties set in Property table should work */ 2323 check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1); 2324 2325 MsiCloseHandle( hpkg ); 2326 DeleteFileA(msifile); 2327 } 2328 2329 static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len) 2330 { 2331 MSIHANDLE hview, hrec; 2332 BOOL found = FALSE; 2333 CHAR buffer[MAX_PATH]; 2334 DWORD sz; 2335 UINT r; 2336 2337 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview); 2338 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 2339 r = MsiViewExecute(hview, 0); 2340 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 2341 2342 if (len < 0) len = lstrlenA(val); 2343 2344 while (r == ERROR_SUCCESS && !found) 2345 { 2346 r = MsiViewFetch(hview, &hrec); 2347 if (r != ERROR_SUCCESS) break; 2348 2349 sz = MAX_PATH; 2350 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 2351 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop)) 2352 { 2353 sz = MAX_PATH; 2354 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 2355 if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len]) 2356 { 2357 ok(sz == len, "wrong size %lu\n", sz); 2358 found = TRUE; 2359 } 2360 } 2361 2362 MsiCloseHandle(hrec); 2363 } 2364 MsiViewClose(hview); 2365 MsiCloseHandle(hview); 2366 return found; 2367 } 2368 2369 static void test_property_table(void) 2370 { 2371 const char *query; 2372 UINT r; 2373 MSIHANDLE hpkg, hdb, hrec; 2374 char buffer[MAX_PATH], package[10]; 2375 DWORD sz; 2376 BOOL found; 2377 2378 hdb = create_package_db(); 2379 ok( hdb, "failed to create package\n"); 2380 2381 r = package_from_db(hdb, &hpkg); 2382 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2383 { 2384 skip("Not enough rights to perform tests\n"); 2385 DeleteFileA(msifile); 2386 return; 2387 } 2388 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 2389 2390 MsiCloseHandle(hdb); 2391 2392 hdb = MsiGetActiveDatabase(hpkg); 2393 2394 query = "CREATE TABLE `_Property` ( " 2395 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 2396 r = run_query(hdb, query); 2397 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2398 2399 MsiCloseHandle(hdb); 2400 MsiCloseHandle(hpkg); 2401 DeleteFileA(msifile); 2402 2403 hdb = create_package_db(); 2404 ok( hdb, "failed to create package\n"); 2405 2406 query = "CREATE TABLE `_Property` ( " 2407 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 2408 r = run_query(hdb, query); 2409 ok(r == ERROR_SUCCESS, "failed to create table\n"); 2410 2411 query = "ALTER `_Property` ADD `foo` INTEGER"; 2412 r = run_query(hdb, query); 2413 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n"); 2414 2415 query = "ALTER TABLE `_Property` ADD `foo` INTEGER"; 2416 r = run_query(hdb, query); 2417 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n"); 2418 2419 query = "ALTER TABLE `_Property` ADD `extra` INTEGER"; 2420 r = run_query(hdb, query); 2421 ok(r == ERROR_SUCCESS, "failed to add column\n"); 2422 2423 sprintf(package, "#%lu", hdb); 2424 r = MsiOpenPackageA(package, &hpkg); 2425 ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n"); 2426 if (r == ERROR_SUCCESS) 2427 MsiCloseHandle(hpkg); 2428 2429 r = MsiCloseHandle(hdb); 2430 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r); 2431 2432 hdb = create_package_db(); 2433 ok (hdb, "failed to create package database\n"); 2434 2435 create_property_table(hdb); 2436 add_property_entry(hdb, "'prop', 'val'"); 2437 2438 create_custom_action_table(hdb); 2439 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" ); 2440 2441 r = package_from_db(hdb, &hpkg); 2442 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 2443 2444 MsiCloseHandle(hdb); 2445 2446 sz = MAX_PATH; 2447 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz); 2448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2449 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer); 2450 2451 hdb = MsiGetActiveDatabase(hpkg); 2452 2453 found = find_prop_in_property(hdb, "prop", "val", -1); 2454 ok(found, "prop should be in the _Property table\n"); 2455 2456 add_property_entry(hdb, "'dantes', 'mercedes'"); 2457 2458 query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'"; 2459 r = do_query(hdb, query, &hrec); 2460 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2461 2462 found = find_prop_in_property(hdb, "dantes", "mercedes", -1); 2463 ok(found == FALSE, "dantes should not be in the _Property table\n"); 2464 2465 sz = MAX_PATH; 2466 lstrcpyA(buffer, "aaa"); 2467 r = MsiGetPropertyA(hpkg, "dantes", buffer, &sz); 2468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2469 ok(!buffer[0], "Expected empty string, got %s\n", buffer); 2470 2471 r = MsiSetPropertyA(hpkg, "dantes", "mercedes"); 2472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2473 2474 found = find_prop_in_property(hdb, "dantes", "mercedes", -1); 2475 ok(found == TRUE, "dantes should be in the _Property table\n"); 2476 2477 r = MsiDoActionA( hpkg, "EmbedNull" ); 2478 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r); 2479 2480 sz = MAX_PATH; 2481 memset( buffer, 'a', sizeof(buffer) ); 2482 r = MsiGetPropertyA( hpkg, "prop2", buffer, &sz ); 2483 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2484 ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n"); 2485 ok( sz == sizeof("\0np") - 1, "got %lu\n", sz ); 2486 2487 found = find_prop_in_property(hdb, "prop2", "\0np", 3); 2488 ok(found == TRUE, "prop2 should be in the _Property table\n"); 2489 2490 MsiCloseHandle(hdb); 2491 MsiCloseHandle(hpkg); 2492 DeleteFileA(msifile); 2493 } 2494 2495 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec ) 2496 { 2497 MSIHANDLE htab = 0; 2498 UINT res; 2499 2500 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab ); 2501 if( res == ERROR_SUCCESS ) 2502 { 2503 UINT r; 2504 2505 r = MsiViewExecute( htab, hrec ); 2506 if( r != ERROR_SUCCESS ) 2507 { 2508 res = r; 2509 fprintf(stderr,"MsiViewExecute failed %08x\n", res); 2510 } 2511 2512 r = MsiViewClose( htab ); 2513 if( r != ERROR_SUCCESS ) 2514 res = r; 2515 2516 r = MsiCloseHandle( htab ); 2517 if( r != ERROR_SUCCESS ) 2518 res = r; 2519 } 2520 return res; 2521 } 2522 2523 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery ) 2524 { 2525 return try_query_param( hdb, szQuery, 0 ); 2526 } 2527 2528 static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value) 2529 { 2530 MSIHANDLE summary; 2531 UINT r; 2532 2533 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary); 2534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2535 2536 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value); 2537 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2538 2539 r = MsiSummaryInfoPersist(summary); 2540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2541 2542 MsiCloseHandle(summary); 2543 } 2544 2545 static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value) 2546 { 2547 MSIHANDLE summary; 2548 UINT r; 2549 2550 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary); 2551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2552 2553 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL); 2554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2555 2556 r = MsiSummaryInfoPersist(summary); 2557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2558 2559 MsiCloseHandle(summary); 2560 } 2561 2562 static void test_msipackage(void) 2563 { 2564 MSIHANDLE hdb = 0, hpack = 100; 2565 UINT r; 2566 const char *query; 2567 char name[10]; 2568 2569 /* NULL szPackagePath */ 2570 r = MsiOpenPackageA(NULL, &hpack); 2571 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 2572 2573 /* empty szPackagePath */ 2574 r = MsiOpenPackageA("", &hpack); 2575 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2576 { 2577 skip("Not enough rights to perform tests\n"); 2578 return; 2579 } 2580 todo_wine 2581 { 2582 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2583 } 2584 2585 if (r == ERROR_SUCCESS) 2586 MsiCloseHandle(hpack); 2587 2588 /* nonexistent szPackagePath */ 2589 r = MsiOpenPackageA("nonexistent", &hpack); 2590 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r); 2591 2592 /* NULL hProduct */ 2593 r = MsiOpenPackageA(msifile, NULL); 2594 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 2595 2596 name[0]='#'; 2597 name[1]=0; 2598 r = MsiOpenPackageA(name, &hpack); 2599 ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r); 2600 2601 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2603 2604 /* database exists, but is empty */ 2605 sprintf(name, "#%lu", hdb); 2606 r = MsiOpenPackageA(name, &hpack); 2607 ok(r == ERROR_INSTALL_PACKAGE_INVALID, 2608 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r); 2609 2610 query = "CREATE TABLE `Property` ( " 2611 "`Property` CHAR(72), `Value` CHAR(0) " 2612 "PRIMARY KEY `Property`)"; 2613 r = try_query(hdb, query); 2614 ok(r == ERROR_SUCCESS, "failed to create Properties table\n"); 2615 2616 query = "CREATE TABLE `InstallExecuteSequence` (" 2617 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER " 2618 "PRIMARY KEY `Action`)"; 2619 r = try_query(hdb, query); 2620 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n"); 2621 2622 /* a few key tables exist */ 2623 sprintf(name, "#%lu", hdb); 2624 r = MsiOpenPackageA(name, &hpack); 2625 ok(r == ERROR_INSTALL_PACKAGE_INVALID, 2626 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r); 2627 2628 MsiCloseHandle(hdb); 2629 DeleteFileA(msifile); 2630 2631 /* start with a clean database to show what constitutes a valid package */ 2632 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2634 2635 sprintf(name, "#%lu", hdb); 2636 2637 /* The following summary information props must exist: 2638 * - PID_REVNUMBER 2639 * - PID_PAGECOUNT 2640 */ 2641 2642 set_summary_dword(hdb, PID_PAGECOUNT, 100); 2643 r = MsiOpenPackageA(name, &hpack); 2644 ok(r == ERROR_INSTALL_PACKAGE_INVALID, 2645 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r); 2646 2647 set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}"); 2648 r = MsiOpenPackageA(name, &hpack); 2649 ok(r == ERROR_SUCCESS, 2650 "Expected ERROR_SUCCESS, got %d\n", r); 2651 2652 MsiCloseHandle(hpack); 2653 MsiCloseHandle(hdb); 2654 DeleteFileA(msifile); 2655 } 2656 2657 static void test_formatrecord2(void) 2658 { 2659 MSIHANDLE hpkg, hrec ; 2660 char buffer[0x100]; 2661 DWORD sz; 2662 UINT r; 2663 2664 r = package_from_db(create_package_db(), &hpkg); 2665 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2666 { 2667 skip("Not enough rights to perform tests\n"); 2668 DeleteFileA(msifile); 2669 return; 2670 } 2671 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 2672 2673 r = MsiSetPropertyA(hpkg, "Manufacturer", " " ); 2674 ok( r == ERROR_SUCCESS, "set property failed\n"); 2675 2676 hrec = MsiCreateRecord(2); 2677 ok(hrec, "create record failed\n"); 2678 2679 r = MsiRecordSetStringA( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf"); 2680 ok( r == ERROR_SUCCESS, "format record failed\n"); 2681 2682 buffer[0] = 0; 2683 sz = sizeof buffer; 2684 r = MsiFormatRecordA( hpkg, hrec, buffer, &sz ); 2685 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2686 2687 r = MsiRecordSetStringA(hrec, 0, "[foo][1]"); 2688 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2689 r = MsiRecordSetStringA(hrec, 1, "hoo"); 2690 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2691 sz = sizeof buffer; 2692 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2693 ok( sz == 3, "size wrong\n"); 2694 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer); 2695 ok( r == ERROR_SUCCESS, "format failed\n"); 2696 2697 r = MsiRecordSetStringA(hrec, 0, "x[~]x"); 2698 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2699 sz = sizeof buffer; 2700 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2701 ok( sz == 3, "size wrong\n"); 2702 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer); 2703 ok( r == ERROR_SUCCESS, "format failed\n"); 2704 2705 r = MsiRecordSetStringA(hrec, 0, "[foo.$%}][1]"); 2706 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2707 r = MsiRecordSetStringA(hrec, 1, "hoo"); 2708 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2709 sz = sizeof buffer; 2710 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2711 ok( sz == 3, "size wrong\n"); 2712 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer); 2713 ok( r == ERROR_SUCCESS, "format failed\n"); 2714 2715 r = MsiRecordSetStringA(hrec, 0, "[\\[]"); 2716 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2717 sz = sizeof buffer; 2718 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2719 ok( sz == 1, "size wrong\n"); 2720 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer); 2721 ok( r == ERROR_SUCCESS, "format failed\n"); 2722 2723 SetEnvironmentVariableA("FOO", "BAR"); 2724 r = MsiRecordSetStringA(hrec, 0, "[%FOO]"); 2725 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2726 sz = sizeof buffer; 2727 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2728 ok( sz == 3, "size wrong\n"); 2729 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer); 2730 ok( r == ERROR_SUCCESS, "format failed\n"); 2731 2732 r = MsiRecordSetStringA(hrec, 0, "[[1]]"); 2733 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2734 r = MsiRecordSetStringA(hrec, 1, "%FOO"); 2735 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2736 sz = sizeof buffer; 2737 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2738 ok( sz == 3, "size wrong\n"); 2739 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer); 2740 ok( r == ERROR_SUCCESS, "format failed\n"); 2741 2742 MsiCloseHandle( hrec ); 2743 MsiCloseHandle( hpkg ); 2744 DeleteFileA(msifile); 2745 } 2746 2747 static void test_formatrecord_tables(void) 2748 { 2749 MSIHANDLE hdb, hrec, hpkg = 0; 2750 CHAR buf[MAX_PATH + 41]; 2751 CHAR curr_dir[MAX_PATH]; 2752 CHAR expected[MAX_PATH + 45]; 2753 CHAR root[MAX_PATH]; 2754 DWORD size; 2755 UINT r; 2756 2757 GetCurrentDirectoryA( MAX_PATH, curr_dir ); 2758 2759 hdb = create_package_db(); 2760 ok ( hdb, "failed to create package database\n"); 2761 2762 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); 2763 add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', " 2764 "'I am a really long directory'" ); 2765 2766 create_feature_table( hdb ); 2767 add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" ); 2768 2769 create_component_table( hdb ); 2770 add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" ); 2771 add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" ); 2772 add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" ); 2773 2774 create_feature_components_table( hdb ); 2775 add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" ); 2776 add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" ); 2777 add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" ); 2778 2779 create_file_table( hdb ); 2780 add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" ); 2781 add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" ); 2782 add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" ); 2783 2784 create_custom_action_table( hdb ); 2785 add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" ); 2786 add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" ); 2787 add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" ); 2788 add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" ); 2789 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" ); 2790 2791 r = package_from_db( hdb, &hpkg ); 2792 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2793 { 2794 skip("Not enough rights to perform tests\n"); 2795 MsiCloseHandle( hdb ); 2796 DeleteFileA( msifile ); 2797 return; 2798 } 2799 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 2800 2801 MsiCloseHandle( hdb ); 2802 2803 r = MsiSetPropertyA( hpkg, "imaprop", "ringer" ); 2804 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r); 2805 2806 hrec = MsiCreateRecord( 1 ); 2807 2808 /* property doesn't exist */ 2809 size = MAX_PATH; 2810 /*MsiRecordSetStringA( hrec, 0, "[1]" ); */ 2811 MsiRecordSetStringA( hrec, 1, "[idontexist]" ); 2812 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2813 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2814 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); 2815 2816 /* property exists */ 2817 size = MAX_PATH; 2818 MsiRecordSetStringA( hrec, 1, "[imaprop]" ); 2819 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2820 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2821 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf ); 2822 2823 size = MAX_PATH; 2824 MsiRecordSetStringA( hrec, 0, "1: [1] " ); 2825 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2826 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2827 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf ); 2828 2829 /* environment variable doesn't exist */ 2830 size = MAX_PATH; 2831 MsiRecordSetStringA( hrec, 1, "[%idontexist]" ); 2832 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2833 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2834 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); 2835 2836 /* environment variable exists */ 2837 size = MAX_PATH; 2838 SetEnvironmentVariableA( "crazyvar", "crazyval" ); 2839 MsiRecordSetStringA( hrec, 1, "[%crazyvar]" ); 2840 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2841 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2842 ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf ); 2843 2844 /* file key before CostInitialize */ 2845 size = MAX_PATH; 2846 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" ); 2847 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2848 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2849 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); 2850 2851 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 2852 2853 r = MsiDoActionA(hpkg, "CostInitialize"); 2854 ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r); 2855 2856 r = MsiDoActionA(hpkg, "FileCost"); 2857 ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r); 2858 2859 r = MsiDoActionA(hpkg, "CostFinalize"); 2860 ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r); 2861 2862 size = MAX_PATH; 2863 MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size ); 2864 2865 sprintf( expected, "1: %sfrontal.txt ", root); 2866 2867 /* frontal full file key */ 2868 size = MAX_PATH; 2869 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" ); 2870 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2871 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2872 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2873 2874 /* frontal short file key */ 2875 size = MAX_PATH; 2876 MsiRecordSetStringA( hrec, 1, "[!frontal_file]" ); 2877 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2878 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2879 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2880 2881 sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root); 2882 2883 /* temporal full file key */ 2884 size = MAX_PATH; 2885 MsiRecordSetStringA( hrec, 1, "[#temporal_file]" ); 2886 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2887 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2888 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2889 2890 /* temporal short file key */ 2891 size = MAX_PATH; 2892 MsiRecordSetStringA( hrec, 1, "[!temporal_file]" ); 2893 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2894 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2895 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2896 2897 /* custom action 51, files don't exist */ 2898 r = MsiDoActionA( hpkg, "MyCustom" ); 2899 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r); 2900 2901 sprintf( expected, "%sI am a really long directory\\temporal.txt", root); 2902 2903 size = MAX_PATH; 2904 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2905 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2906 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2907 2908 sprintf( buf, "%sI am a really long directory", root ); 2909 CreateDirectoryA( buf, NULL ); 2910 2911 lstrcatA( buf, "\\temporal.txt" ); 2912 create_test_file( buf ); 2913 2914 /* custom action 51, files exist */ 2915 r = MsiDoActionA( hpkg, "MyCustom" ); 2916 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r); 2917 2918 size = MAX_PATH; 2919 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2920 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2921 todo_wine 2922 { 2923 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2924 } 2925 2926 /* custom action 51, escaped text 1 */ 2927 r = MsiDoActionA( hpkg, "EscapeIt1" ); 2928 ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r); 2929 2930 size = MAX_PATH; 2931 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2932 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2933 ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf); 2934 2935 /* custom action 51, escaped text 2 */ 2936 r = MsiDoActionA( hpkg, "EscapeIt2" ); 2937 ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r); 2938 2939 size = MAX_PATH; 2940 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2941 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2942 ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf); 2943 2944 /* custom action 51, escaped text 3 */ 2945 r = MsiDoActionA( hpkg, "EscapeIt3" ); 2946 ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r); 2947 2948 size = MAX_PATH; 2949 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2950 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2951 ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf); 2952 2953 /* custom action 51, embedded null */ 2954 r = MsiDoActionA( hpkg, "EmbedNull" ); 2955 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r); 2956 2957 size = MAX_PATH; 2958 memset( buf, 'a', sizeof(buf) ); 2959 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2960 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2961 ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n"); 2962 ok( size == sizeof("\0np") - 1, "got %lu\n", size ); 2963 2964 r = MsiSetPropertyA( hpkg, "prop", "[~]np" ); 2965 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r); 2966 2967 size = MAX_PATH; 2968 memset( buf, 'a', sizeof(buf) ); 2969 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2970 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2971 ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf); 2972 2973 sprintf( expected, "1: %sI am a really long directory\\ ", root); 2974 2975 /* component with INSTALLSTATE_LOCAL */ 2976 size = MAX_PATH; 2977 MsiRecordSetStringA( hrec, 1, "[$temporal]" ); 2978 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2979 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2980 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2981 2982 r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE ); 2983 ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r); 2984 2985 /* component with INSTALLSTATE_SOURCE */ 2986 lstrcpyA( expected, "1: " ); 2987 lstrcatA( expected, curr_dir ); 2988 if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" ); 2989 lstrcatA( expected, " " ); 2990 size = MAX_PATH; 2991 MsiRecordSetStringA( hrec, 1, "[$parietal]" ); 2992 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2993 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2994 ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf); 2995 2996 sprintf( buf, "%sI am a really long directory\\temporal.txt", root ); 2997 DeleteFileA( buf ); 2998 2999 sprintf( buf, "%sI am a really long directory", root ); 3000 RemoveDirectoryA( buf ); 3001 3002 MsiCloseHandle( hrec ); 3003 MsiCloseHandle( hpkg ); 3004 DeleteFileA( msifile ); 3005 } 3006 3007 static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error, 3008 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo ) 3009 { 3010 UINT r; 3011 INSTALLSTATE state = 0xdeadbee; 3012 INSTALLSTATE action = 0xdeadbee; 3013 3014 r = MsiGetFeatureStateA( package, feature, &state, &action ); 3015 ok( r == error, "%u: expected %d got %d\n", line, error, r ); 3016 if (r == ERROR_SUCCESS) 3017 { 3018 ok( state == expected_state, "%u: expected state %d got %d\n", 3019 line, expected_state, state ); 3020 todo_wine_if (todo) 3021 ok( action == expected_action, "%u: expected action %d got %d\n", 3022 line, expected_action, action ); 3023 } 3024 else 3025 { 3026 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state ); 3027 todo_wine_if (todo) 3028 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action ); 3029 3030 } 3031 } 3032 3033 static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error, 3034 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo ) 3035 { 3036 UINT r; 3037 INSTALLSTATE state = 0xdeadbee; 3038 INSTALLSTATE action = 0xdeadbee; 3039 3040 r = MsiGetComponentStateA( package, component, &state, &action ); 3041 ok( r == error, "%u: expected %d got %d\n", line, error, r ); 3042 if (r == ERROR_SUCCESS) 3043 { 3044 ok( state == expected_state, "%u: expected state %d got %d\n", 3045 line, expected_state, state ); 3046 todo_wine_if (todo) 3047 ok( action == expected_action, "%u: expected action %d got %d\n", 3048 line, expected_action, action ); 3049 } 3050 else 3051 { 3052 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", 3053 line, state ); 3054 todo_wine_if (todo) 3055 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", 3056 line, action ); 3057 } 3058 } 3059 3060 static void test_states(void) 3061 { 3062 static const char msifile2[] = "winetest2-package.msi"; 3063 static const char msifile3[] = "winetest3-package.msi"; 3064 static const char msifile4[] = "winetest4-package.msi"; 3065 static const WCHAR msifile2W[] = L"winetest2-package.msi"; 3066 static const WCHAR msifile3W[] = L"winetest3-package.msi"; 3067 static const WCHAR msifile4W[] = L"winetest4-package.msi"; 3068 char msi_cache_file[MAX_PATH]; 3069 DWORD cache_file_name_len; 3070 INSTALLSTATE state; 3071 MSIHANDLE hpkg, hprod; 3072 UINT r; 3073 MSIHANDLE hdb; 3074 BOOL is_broken; 3075 char value[MAX_PATH]; 3076 DWORD size; 3077 3078 if (is_process_limited()) 3079 { 3080 skip("process is limited\n"); 3081 return; 3082 } 3083 3084 hdb = create_package_db(); 3085 ok ( hdb, "failed to create package database\n" ); 3086 3087 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); 3088 3089 create_property_table( hdb ); 3090 add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" ); 3091 add_property_entry( hdb, "'ProductLanguage', '1033'" ); 3092 add_property_entry( hdb, "'ProductName', 'MSITEST'" ); 3093 add_property_entry( hdb, "'ProductVersion', '1.1.1'" ); 3094 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); 3095 add_property_entry( hdb, "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" ); 3096 3097 create_install_execute_sequence_table( hdb ); 3098 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); 3099 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); 3100 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); 3101 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" ); 3102 add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" ); 3103 add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" ); 3104 add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" ); 3105 add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" ); 3106 add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" ); 3107 add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" ); 3108 add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" ); 3109 3110 create_media_table( hdb ); 3111 add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''"); 3112 3113 create_feature_table( hdb ); 3114 3115 create_component_table( hdb ); 3116 3117 /* msidbFeatureAttributesFavorLocal */ 3118 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" ); 3119 3120 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ 3121 add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" ); 3122 3123 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ 3124 add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" ); 3125 3126 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ 3127 add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" ); 3128 3129 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */ 3130 add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" ); 3131 3132 /* msidbFeatureAttributesFavorSource */ 3133 add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" ); 3134 3135 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */ 3136 add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" ); 3137 3138 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ 3139 add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" ); 3140 3141 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */ 3142 add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" ); 3143 3144 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */ 3145 add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" ); 3146 3147 /* msidbFeatureAttributesFavorSource */ 3148 add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" ); 3149 3150 /* msidbFeatureAttributesFavorLocal */ 3151 add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" ); 3152 3153 /* disabled */ 3154 add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" ); 3155 3156 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ 3157 add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" ); 3158 3159 /* no feature parent:msidbComponentAttributesLocalOnly */ 3160 add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" ); 3161 3162 /* msidbFeatureAttributesFavorLocal:removed */ 3163 add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" ); 3164 3165 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */ 3166 add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" ); 3167 3168 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */ 3169 add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" ); 3170 3171 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */ 3172 add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" ); 3173 3174 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */ 3175 add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" ); 3176 3177 /* msidbFeatureAttributesFavorSource:removed */ 3178 add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" ); 3179 3180 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */ 3181 add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" ); 3182 3183 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */ 3184 add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" ); 3185 3186 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */ 3187 add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" ); 3188 3189 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */ 3190 add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" ); 3191 3192 /* msidbFeatureAttributesFavorLocal */ 3193 add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" ); 3194 3195 add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" ); 3196 3197 /* msidbFeatureAttributesFavorSource */ 3198 add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" ); 3199 3200 add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" ); 3201 3202 /* msidbFeatureAttributesFavorAdvertise */ 3203 add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" ); 3204 3205 add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" ); 3206 3207 /* msidbFeatureAttributesUIDisallowAbsent */ 3208 add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" ); 3209 3210 add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" ); 3211 3212 /* high install level */ 3213 add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" ); 3214 3215 add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" ); 3216 3217 /* msidbFeatureAttributesFollowParent */ 3218 add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" ); 3219 3220 create_feature_components_table( hdb ); 3221 add_feature_components_entry( hdb, "'one', 'alpha'" ); 3222 add_feature_components_entry( hdb, "'one', 'beta'" ); 3223 add_feature_components_entry( hdb, "'one', 'gamma'" ); 3224 add_feature_components_entry( hdb, "'one', 'theta'" ); 3225 add_feature_components_entry( hdb, "'two', 'delta'" ); 3226 add_feature_components_entry( hdb, "'two', 'epsilon'" ); 3227 add_feature_components_entry( hdb, "'two', 'zeta'" ); 3228 add_feature_components_entry( hdb, "'two', 'iota'" ); 3229 add_feature_components_entry( hdb, "'three', 'eta'" ); 3230 add_feature_components_entry( hdb, "'four', 'eta'" ); 3231 add_feature_components_entry( hdb, "'five', 'eta'" ); 3232 add_feature_components_entry( hdb, "'six', 'lambda'" ); 3233 add_feature_components_entry( hdb, "'six', 'mu'" ); 3234 add_feature_components_entry( hdb, "'six', 'nu'" ); 3235 add_feature_components_entry( hdb, "'six', 'xi'" ); 3236 add_feature_components_entry( hdb, "'seven', 'omicron'" ); 3237 add_feature_components_entry( hdb, "'seven', 'pi'" ); 3238 add_feature_components_entry( hdb, "'seven', 'rho'" ); 3239 add_feature_components_entry( hdb, "'seven', 'sigma'" ); 3240 add_feature_components_entry( hdb, "'eight', 'tau'" ); 3241 add_feature_components_entry( hdb, "'nine', 'phi'" ); 3242 add_feature_components_entry( hdb, "'ten', 'chi'" ); 3243 add_feature_components_entry( hdb, "'eleven', 'psi'" ); 3244 add_feature_components_entry( hdb, "'twelve', 'upsilon'" ); 3245 add_feature_components_entry( hdb, "'thirteen', 'upsilon'" ); 3246 3247 create_file_table( hdb ); 3248 add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" ); 3249 add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" ); 3250 add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" ); 3251 add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" ); 3252 add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" ); 3253 add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" ); 3254 add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" ); 3255 add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" ); 3256 3257 /* compressed file */ 3258 add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" ); 3259 3260 add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" ); 3261 add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" ); 3262 add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" ); 3263 add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" ); 3264 add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" ); 3265 add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" ); 3266 add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" ); 3267 add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" ); 3268 add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" ); 3269 add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" ); 3270 add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" ); 3271 add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" ); 3272 add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" ); 3273 add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" ); 3274 3275 r = MsiDatabaseCommit(hdb); 3276 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); 3277 3278 /* these properties must not be in the saved msi file */ 3279 add_property_entry( hdb, "'ADDLOCAL', 'one,four'"); 3280 add_property_entry( hdb, "'ADDSOURCE', 'two,three'"); 3281 add_property_entry( hdb, "'REMOVE', 'six,seven'"); 3282 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); 3283 add_property_entry( hdb, "'REINSTALLMODE', 'omus'"); 3284 3285 r = package_from_db( hdb, &hpkg ); 3286 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 3287 { 3288 skip("Not enough rights to perform tests\n"); 3289 DeleteFileA(msifile); 3290 return; 3291 } 3292 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3293 3294 MsiCloseHandle(hdb); 3295 3296 CopyFileA(msifile, msifile2, FALSE); 3297 CopyFileA(msifile, msifile3, FALSE); 3298 CopyFileA(msifile, msifile4, FALSE); 3299 3300 size = sizeof(value); 3301 memset(value, 0, sizeof(value)); 3302 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size); 3303 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3304 ok(!value[0], "ProductToBeRegistered = %s\n", value); 3305 3306 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3307 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3308 3309 r = MsiDoActionA( hpkg, "CostInitialize"); 3310 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3311 3312 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3313 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3314 3315 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 3316 3317 r = MsiDoActionA( hpkg, "FileCost"); 3318 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3319 3320 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3321 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3322 3323 r = MsiDoActionA( hpkg, "CostFinalize"); 3324 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3325 3326 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3327 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 3328 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3329 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3330 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3331 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3332 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3333 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3334 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3335 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3336 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3337 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3338 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3339 3340 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3341 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 3342 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3343 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3344 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3345 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 3346 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 3347 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3348 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3349 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3350 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3351 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3352 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3353 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3354 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3355 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3356 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3357 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3358 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3359 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3360 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3361 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3362 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3363 3364 MsiCloseHandle( hpkg ); 3365 3366 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 3367 3368 /* publish the features and components */ 3369 r = MsiInstallProductA(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten"); 3370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3371 3372 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 3373 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3374 3375 /* these properties must not be in the saved msi file */ 3376 add_property_entry( hdb, "'ADDLOCAL', 'one,four'"); 3377 add_property_entry( hdb, "'ADDSOURCE', 'two,three'"); 3378 add_property_entry( hdb, "'REMOVE', 'six,seven'"); 3379 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); 3380 3381 r = package_from_db( hdb, &hpkg ); 3382 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3383 3384 MsiCloseHandle(hdb); 3385 3386 size = sizeof(value); 3387 memset(value, 0, sizeof(value)); 3388 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size); 3389 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3390 ok(value[0]=='1' && !value[1], "ProductToBeRegistered = %s\n", value); 3391 3392 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3393 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3394 3395 r = MsiDoActionA( hpkg, "CostInitialize"); 3396 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3397 3398 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3399 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3400 3401 r = MsiDoActionA( hpkg, "FileCost"); 3402 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3403 3404 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3405 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3406 3407 r = MsiDoActionA( hpkg, "CostFinalize"); 3408 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3409 3410 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3411 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3412 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3413 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3414 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3415 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3416 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3417 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3418 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3419 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3420 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3421 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3422 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3423 3424 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3425 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3426 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3427 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3428 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3429 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3430 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3431 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3432 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3433 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3434 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3435 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3436 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3437 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3438 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3439 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3440 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3441 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3442 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3443 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3444 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3445 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3446 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3447 3448 MsiCloseHandle(hpkg); 3449 3450 /* uninstall the product */ 3451 r = MsiInstallProductA(msifile, "REMOVE=ALL"); 3452 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3453 3454 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); 3455 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3456 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve"); 3457 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3458 3459 /* all features installed locally */ 3460 r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL"); 3461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3462 3463 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); 3464 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3465 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve"); 3466 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state); 3467 3468 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_DIRECT, &hdb); 3469 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3470 3471 /* these properties must not be in the saved msi file */ 3472 add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'"); 3473 3474 r = package_from_db( hdb, &hpkg ); 3475 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3476 3477 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3478 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3479 3480 r = MsiDoActionA( hpkg, "CostInitialize"); 3481 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3482 3483 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3484 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3485 3486 r = MsiDoActionA( hpkg, "CostFinalize"); 3487 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3488 3489 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3490 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3491 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3492 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3493 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3494 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3495 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3496 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE ); 3497 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE ); 3498 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE ); 3499 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3500 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3501 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3502 3503 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3504 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3505 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3506 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3507 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3508 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3509 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3510 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3511 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3512 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3513 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3514 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3515 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3516 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3517 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3518 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3519 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3520 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3521 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3522 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3523 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3524 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3525 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3526 3527 MsiCloseHandle(hpkg); 3528 3529 /* uninstall the product */ 3530 r = MsiInstallProductA(msifile2, "REMOVE=ALL"); 3531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3532 3533 /* all features installed from source */ 3534 r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL"); 3535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3536 3537 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); 3538 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3539 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve"); 3540 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state); 3541 3542 r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb); 3543 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3544 3545 /* this property must not be in the saved msi file */ 3546 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); 3547 3548 r = package_from_db( hdb, &hpkg ); 3549 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3550 3551 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3552 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3553 3554 r = MsiDoActionA( hpkg, "CostInitialize"); 3555 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3556 3557 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3558 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3559 3560 r = MsiDoActionA( hpkg, "FileCost"); 3561 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3562 3563 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3564 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3565 3566 r = MsiDoActionA( hpkg, "CostFinalize"); 3567 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3568 3569 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3570 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3571 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3572 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3573 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3574 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3575 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3576 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3577 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3578 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3579 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3580 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3581 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3582 3583 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3584 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3585 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3586 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3587 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3588 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3589 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3590 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3591 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3592 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3593 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3594 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3595 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3596 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3597 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3598 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3599 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3600 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3601 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3602 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3603 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3604 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3605 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3606 3607 MsiCloseHandle(hpkg); 3608 3609 /* reinstall the product */ 3610 r = MsiInstallProductA(msifile3, "REINSTALL=ALL"); 3611 is_broken = (r == ERROR_INSTALL_FAILURE); 3612 ok(r == ERROR_SUCCESS || broken(is_broken) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r); 3613 3614 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); 3615 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3616 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve"); 3617 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state); 3618 3619 r = MsiOpenDatabaseW(msifile4W, MSIDBOPEN_DIRECT, &hdb); 3620 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3621 3622 /* this property must not be in the saved msi file */ 3623 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); 3624 3625 r = package_from_db( hdb, &hpkg ); 3626 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3627 3628 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3629 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3630 3631 r = MsiDoActionA( hpkg, "CostInitialize"); 3632 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3633 3634 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3635 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3636 3637 r = MsiDoActionA( hpkg, "FileCost"); 3638 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3639 3640 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3641 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3642 3643 r = MsiDoActionA( hpkg, "CostFinalize"); 3644 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3645 3646 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3647 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3648 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3649 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3650 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3651 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3652 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3653 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3654 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3655 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3656 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3657 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3658 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3659 3660 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3661 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3662 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3663 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3664 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3665 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3666 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3667 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3668 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3669 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3670 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3671 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3672 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3673 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3674 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3675 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3676 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3677 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3678 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3679 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3680 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3681 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3682 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3683 3684 MsiCloseHandle(hpkg); 3685 3686 /* test source only install */ 3687 r = MsiInstallProductA(msifile, "REMOVE=ALL"); 3688 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3689 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); 3690 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3691 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); 3692 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3693 3694 r = MsiInstallProductA(msifile, "ADDSOURCE=one"); 3695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3696 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); 3697 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state); 3698 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); 3699 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state); 3700 3701 /* no arguments test */ 3702 cache_file_name_len = sizeof(msi_cache_file); 3703 r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", 3704 INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len); 3705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3706 r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb); 3707 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3708 3709 create_custom_action_table( hdb ); 3710 add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" ); 3711 add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" ); 3712 add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" ); 3713 add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" ); 3714 add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" ); 3715 add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" ); 3716 add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" ); 3717 add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" ); 3718 add_custom_action_entry( hdb, 3719 "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" ); 3720 3721 add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" ); 3722 add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" ); 3723 add_install_execute_sequence_entry( hdb, "'VBFeatureRequest', 'NOT REMOVE', '1001'" ); 3724 add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" ); 3725 add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" ); 3726 add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" ); 3727 add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" ); 3728 /* Add "one" feature action tests */ 3729 add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" ); 3730 add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" ); 3731 r = MsiDatabaseCommit(hdb); 3732 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r); 3733 r = package_from_db( hdb, &hpkg ); 3734 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3735 MsiCloseHandle(hdb); 3736 3737 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3738 test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3739 r = MsiDoActionA( hpkg, "CostInitialize"); 3740 ok( r == ERROR_SUCCESS, "CostInitialize failed\n"); 3741 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3742 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3743 3744 r = MsiDoActionA( hpkg, "FileCost"); 3745 ok( r == ERROR_SUCCESS, "FileCost failed\n"); 3746 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3747 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3748 3749 r = MsiDoActionA( hpkg, "CostFinalize"); 3750 ok( r == ERROR_SUCCESS, "CostFinalize failed\n"); 3751 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3752 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3753 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3754 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3755 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3756 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3757 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3758 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3759 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3760 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3761 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3762 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3763 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3764 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3765 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3766 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3767 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3768 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3769 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3770 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3771 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3772 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3773 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3774 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3775 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3776 3777 r = MsiDoActionA( hpkg, "InstallValidate"); 3778 ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r); 3779 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3780 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3781 MsiCloseHandle( hpkg ); 3782 3783 r = MsiInstallProductA(msifile, ""); 3784 ok(r == ERROR_SUCCESS || (is_broken && r == ERROR_INSTALL_FAILURE) /* win2k3 */, 3785 "Expected ERROR_SUCCESS, got %d\n", r); 3786 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); 3787 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state); 3788 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); 3789 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state); 3790 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three"); 3791 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state); 3792 3793 /* minor upgrade test with no REINSTALL argument */ 3794 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod); 3795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3796 size = MAX_PATH; 3797 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size); 3798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3799 ok(!strcmp(value, "1.1.1"), "ProductVersion = %s\n", value); 3800 MsiCloseHandle(hprod); 3801 3802 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb); 3803 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3804 update_ProductVersion_property( hdb, "1.1.2" ); 3805 set_summary_str(hdb, PID_REVNUMBER, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}"); 3806 r = MsiDatabaseCommit(hdb); 3807 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r); 3808 MsiCloseHandle(hdb); 3809 3810 r = MsiInstallProductA(msifile2, ""); 3811 ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r); 3812 3813 r = MsiInstallProductA(msifile2, "REINSTALLMODe=V"); 3814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3815 3816 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod); 3817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3818 size = MAX_PATH; 3819 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size); 3820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3821 ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value); 3822 MsiCloseHandle(hprod); 3823 3824 /* major upgrade test */ 3825 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb); 3826 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3827 add_install_execute_sequence_entry( hdb, "'FindRelatedProducts', '', '100'" ); 3828 add_install_execute_sequence_entry( hdb, "'RemoveExistingProducts', '', '1401'" ); 3829 create_upgrade_table( hdb ); 3830 add_upgrade_entry( hdb, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'"); 3831 update_ProductCode_property( hdb, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" ); 3832 update_ProductVersion_property( hdb, "1.1.3" ); 3833 set_summary_str(hdb, PID_REVNUMBER, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}"); 3834 r = MsiDatabaseCommit(hdb); 3835 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r); 3836 MsiCloseHandle(hdb); 3837 3838 r = MsiInstallProductA(msifile2, ""); 3839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3840 3841 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod); 3842 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); 3843 r = MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod); 3844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3845 size = MAX_PATH; 3846 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size); 3847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3848 ok(!strcmp(value, "1.1.3"), "ProductVersion = %s\n", value); 3849 MsiCloseHandle(hprod); 3850 3851 /* uninstall the product */ 3852 r = MsiInstallProductA(msifile2, "REMOVE=ALL"); 3853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3854 3855 DeleteFileA(msifile); 3856 DeleteFileA(msifile2); 3857 DeleteFileA(msifile3); 3858 DeleteFileA(msifile4); 3859 } 3860 3861 static void test_removefiles(void) 3862 { 3863 MSIHANDLE hpkg; 3864 UINT r; 3865 MSIHANDLE hdb; 3866 INSTALLSTATE installed, action; 3867 3868 hdb = create_package_db(); 3869 ok ( hdb, "failed to create package database\n" ); 3870 3871 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); 3872 3873 create_feature_table( hdb ); 3874 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" ); 3875 3876 create_component_table( hdb ); 3877 add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" ); 3878 add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" ); 3879 add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" ); 3880 add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" ); 3881 add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" ); 3882 add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" ); 3883 add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" ); 3884 3885 create_feature_components_table( hdb ); 3886 add_feature_components_entry( hdb, "'one', 'hydrogen'" ); 3887 add_feature_components_entry( hdb, "'one', 'helium'" ); 3888 add_feature_components_entry( hdb, "'one', 'lithium'" ); 3889 add_feature_components_entry( hdb, "'one', 'beryllium'" ); 3890 add_feature_components_entry( hdb, "'one', 'boron'" ); 3891 add_feature_components_entry( hdb, "'one', 'carbon'" ); 3892 add_feature_components_entry( hdb, "'one', 'oxygen'" ); 3893 3894 create_file_table( hdb ); 3895 add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" ); 3896 add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" ); 3897 add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" ); 3898 add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" ); 3899 add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" ); 3900 add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" ); 3901 add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" ); 3902 3903 create_remove_file_table( hdb ); 3904 3905 r = package_from_db( hdb, &hpkg ); 3906 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 3907 { 3908 skip("Not enough rights to perform tests\n"); 3909 DeleteFileA(msifile); 3910 return; 3911 } 3912 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3913 3914 MsiCloseHandle( hdb ); 3915 3916 create_test_file( "hydrogen.txt" ); 3917 create_test_file( "helium.txt" ); 3918 create_test_file( "lithium.txt" ); 3919 create_test_file( "beryllium.txt" ); 3920 create_test_file( "boron.txt" ); 3921 create_test_file( "carbon.txt" ); 3922 create_test_file( "oxygen.txt" ); 3923 3924 r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR ); 3925 ok( r == ERROR_SUCCESS, "set property failed\n"); 3926 3927 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 3928 3929 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3930 ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r ); 3931 3932 r = MsiDoActionA( hpkg, "CostInitialize"); 3933 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3934 3935 r = MsiDoActionA( hpkg, "FileCost"); 3936 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3937 3938 installed = action = 0xdeadbeef; 3939 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3940 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3941 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3942 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3943 3944 r = MsiDoActionA( hpkg, "CostFinalize"); 3945 ok( r == ERROR_SUCCESS, "cost finalize failed\n"); 3946 3947 r = MsiDoActionA( hpkg, "InstallValidate"); 3948 ok( r == ERROR_SUCCESS, "install validate failed\n"); 3949 3950 r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT ); 3951 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3952 3953 installed = action = 0xdeadbeef; 3954 r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action ); 3955 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3956 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3957 todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3958 3959 r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL ); 3960 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3961 3962 r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE ); 3963 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3964 3965 r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT ); 3966 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3967 3968 r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL ); 3969 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3970 3971 r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE ); 3972 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3973 3974 installed = action = 0xdeadbeef; 3975 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3976 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3977 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3978 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3979 3980 r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT ); 3981 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3982 3983 installed = action = 0xdeadbeef; 3984 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3985 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3986 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3987 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3988 3989 r = MsiDoActionA( hpkg, "RemoveFiles"); 3990 ok( r == ERROR_SUCCESS, "remove files failed\n"); 3991 3992 installed = action = 0xdeadbeef; 3993 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3994 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3995 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3996 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3997 3998 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n"); 3999 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n"); 4000 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n"); 4001 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n"); 4002 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n"); 4003 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n"); 4004 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n"); 4005 4006 MsiCloseHandle( hpkg ); 4007 DeleteFileA(msifile); 4008 } 4009 4010 static void test_appsearch(void) 4011 { 4012 MSIHANDLE hpkg; 4013 UINT r; 4014 MSIHANDLE hdb; 4015 CHAR prop[MAX_PATH]; 4016 DWORD size; 4017 HKEY hkey; 4018 const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe"; 4019 4020 hdb = create_package_db(); 4021 ok ( hdb, "failed to create package database\n" ); 4022 4023 create_appsearch_table( hdb ); 4024 add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" ); 4025 add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" ); 4026 add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" ); 4027 add_appsearch_entry( hdb, "'32KEYVAL', 'NewSignature4'" ); 4028 add_appsearch_entry( hdb, "'64KEYVAL', 'NewSignature5'" ); 4029 4030 create_reglocator_table( hdb ); 4031 add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 ); 4032 4033 r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL); 4034 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r ); 4035 r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1); 4036 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r); 4037 RegCloseKey(hkey); 4038 add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName ); 4039 4040 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, 4041 NULL, &hkey, NULL); 4042 if (r == ERROR_ACCESS_DENIED) 4043 { 4044 skip("insufficient rights\n"); 4045 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi"); 4046 MsiCloseHandle(hdb); 4047 DeleteFileA(msifile); 4048 return; 4049 } 4050 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r ); 4051 4052 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe", 4053 sizeof("c:\\windows\\system32\\notepad.exe")); 4054 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r); 4055 RegCloseKey(hkey); 4056 add_reglocator_entry( hdb, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName ); 4057 4058 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, 4059 NULL, &hkey, NULL); 4060 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r ); 4061 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe", 4062 sizeof("c:\\windows\\system32\\notepad.exe")); 4063 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r); 4064 RegCloseKey(hkey); 4065 add_reglocator_entry( hdb, "NewSignature5", 2, "Software\\Winetest_msi", "", 4066 msidbLocatorTypeFileName|msidbLocatorType64bit ); 4067 4068 create_drlocator_table( hdb ); 4069 add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" ); 4070 4071 create_signature_table( hdb ); 4072 add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" ); 4073 add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); 4074 add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); 4075 add_signature_entry( hdb, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); 4076 add_signature_entry( hdb, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); 4077 4078 r = package_from_db( hdb, &hpkg ); 4079 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 4080 { 4081 skip("Not enough rights to perform tests\n"); 4082 DeleteFileA(msifile); 4083 return; 4084 } 4085 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 4086 MsiCloseHandle( hdb ); 4087 if (r != ERROR_SUCCESS) 4088 goto done; 4089 4090 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 4091 4092 r = MsiDoActionA( hpkg, "AppSearch" ); 4093 ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r); 4094 4095 size = sizeof(prop); 4096 r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size ); 4097 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 4098 ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); 4099 4100 size = sizeof(prop); 4101 r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size ); 4102 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 4103 4104 size = sizeof(prop); 4105 r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size ); 4106 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 4107 ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); 4108 4109 size = sizeof(prop); 4110 r = MsiGetPropertyA( hpkg, "32KEYVAL", prop, &size ); 4111 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 4112 ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); 4113 4114 size = sizeof(prop); 4115 r = MsiGetPropertyA( hpkg, "64KEYVAL", prop, &size ); 4116 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 4117 ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); 4118 4119 done: 4120 MsiCloseHandle( hpkg ); 4121 DeleteFileA(msifile); 4122 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi"); 4123 delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY); 4124 delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY); 4125 } 4126 4127 static void test_appsearch_complocator(void) 4128 { 4129 MSIHANDLE hpkg, hdb; 4130 char path[MAX_PATH + 15], expected[MAX_PATH], prop[MAX_PATH]; 4131 LPSTR usersid; 4132 DWORD size; 4133 UINT r; 4134 4135 if (!(usersid = get_user_sid())) 4136 return; 4137 4138 if (is_process_limited()) 4139 { 4140 skip("process is limited\n"); 4141 return; 4142 } 4143 4144 create_test_file("FileName1"); 4145 create_test_file("FileName4"); 4146 set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE, 4147 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE); 4148 4149 create_test_file("FileName2"); 4150 set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED, 4151 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE); 4152 4153 create_test_file("FileName3"); 4154 set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED, 4155 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE); 4156 4157 create_test_file("FileName5"); 4158 set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE, 4159 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE); 4160 4161 create_test_file("FileName6"); 4162 set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE, 4163 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE); 4164 4165 create_test_file("FileName7"); 4166 set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE, 4167 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE); 4168 4169 /* dir is FALSE, but we're pretending it's a directory */ 4170 set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE, 4171 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE); 4172 4173 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4174 set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE, 4175 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE); 4176 4177 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4)); 4178 set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE, 4179 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE); 4180 4181 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4182 set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE, 4183 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE); 4184 4185 hdb = create_package_db(); 4186 ok(hdb, "Expected a valid database handle\n"); 4187 4188 create_appsearch_table(hdb); 4189 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); 4190 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); 4191 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); 4192 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); 4193 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); 4194 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); 4195 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); 4196 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); 4197 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); 4198 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); 4199 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); 4200 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); 4201 4202 create_complocator_table(hdb); 4203 4204 /* published component, machine, file, signature, misdbLocatorTypeFile */ 4205 add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1"); 4206 4207 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */ 4208 add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1"); 4209 4210 /* published component, user-managed, file, signature, misdbLocatorTypeFile */ 4211 add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1"); 4212 4213 /* published component, machine, file, signature, misdbLocatorTypeDirectory */ 4214 add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0"); 4215 4216 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */ 4217 add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0"); 4218 4219 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */ 4220 add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0"); 4221 4222 /* published component, machine, file, no signature, misdbLocatorTypeFile */ 4223 add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1"); 4224 4225 /* unpublished component, no signature, misdbLocatorTypeDir */ 4226 add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0"); 4227 4228 /* published component, no signature, dir does not exist misdbLocatorTypeDir */ 4229 add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0"); 4230 4231 /* published component, signature w/ ver, misdbLocatorTypeFile */ 4232 add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1"); 4233 4234 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */ 4235 add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1"); 4236 4237 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */ 4238 add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1"); 4239 4240 create_signature_table(hdb); 4241 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''"); 4242 add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''"); 4243 add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''"); 4244 add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''"); 4245 add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''"); 4246 add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4247 add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4248 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4249 4250 r = package_from_db(hdb, &hpkg); 4251 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 4252 { 4253 skip("Not enough rights to perform tests\n"); 4254 goto error; 4255 } 4256 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); 4257 4258 r = MsiSetPropertyA(hpkg, "SIGPROP8", "october"); 4259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4260 4261 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 4262 4263 r = MsiDoActionA(hpkg, "AppSearch"); 4264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4265 4266 strcpy(expected, CURR_DIR); 4267 if (is_root(CURR_DIR)) expected[2] = 0; 4268 4269 size = MAX_PATH; 4270 sprintf(path, "%s\\FileName1", expected); 4271 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size); 4272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4273 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4274 4275 size = MAX_PATH; 4276 sprintf(path, "%s\\FileName2", expected); 4277 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size); 4278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4279 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4280 4281 size = MAX_PATH; 4282 sprintf(path, "%s\\FileName3", expected); 4283 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size); 4284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4285 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4286 4287 size = MAX_PATH; 4288 sprintf(path, "%s\\FileName4", expected); 4289 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size); 4290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4291 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4292 4293 size = MAX_PATH; 4294 sprintf(path, "%s\\FileName5", expected); 4295 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); 4296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4297 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4298 4299 size = MAX_PATH; 4300 sprintf(path, "%s\\", expected); 4301 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size); 4302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4303 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4304 4305 size = MAX_PATH; 4306 sprintf(path, "%s\\", expected); 4307 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size); 4308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4309 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4310 4311 size = MAX_PATH; 4312 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size); 4313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4314 ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop); 4315 4316 size = MAX_PATH; 4317 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size); 4318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4319 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4320 4321 size = MAX_PATH; 4322 sprintf(path, "%s\\FileName8.dll", expected); 4323 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size); 4324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4325 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4326 4327 size = MAX_PATH; 4328 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size); 4329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4330 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4331 4332 size = MAX_PATH; 4333 sprintf(path, "%s\\FileName10.dll", expected); 4334 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size); 4335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4336 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4337 4338 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", 4339 MSIINSTALLCONTEXT_MACHINE, NULL); 4340 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", 4341 MSIINSTALLCONTEXT_USERUNMANAGED, usersid); 4342 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", 4343 MSIINSTALLCONTEXT_USERMANAGED, usersid); 4344 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", 4345 MSIINSTALLCONTEXT_MACHINE, NULL); 4346 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}", 4347 MSIINSTALLCONTEXT_MACHINE, NULL); 4348 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", 4349 MSIINSTALLCONTEXT_MACHINE, NULL); 4350 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", 4351 MSIINSTALLCONTEXT_MACHINE, NULL); 4352 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", 4353 MSIINSTALLCONTEXT_MACHINE, NULL); 4354 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}", 4355 MSIINSTALLCONTEXT_MACHINE, NULL); 4356 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", 4357 MSIINSTALLCONTEXT_MACHINE, NULL); 4358 4359 MsiCloseHandle(hpkg); 4360 4361 error: 4362 DeleteFileA("FileName1"); 4363 DeleteFileA("FileName2"); 4364 DeleteFileA("FileName3"); 4365 DeleteFileA("FileName4"); 4366 DeleteFileA("FileName5"); 4367 DeleteFileA("FileName6"); 4368 DeleteFileA("FileName7"); 4369 DeleteFileA("FileName8.dll"); 4370 DeleteFileA("FileName9.dll"); 4371 DeleteFileA("FileName10.dll"); 4372 DeleteFileA(msifile); 4373 LocalFree(usersid); 4374 } 4375 4376 static void test_appsearch_reglocator(void) 4377 { 4378 MSIHANDLE hpkg, hdb; 4379 char path[MAX_PATH + 20], expected[MAX_PATH], prop[MAX_PATH]; 4380 DWORD binary[2], size, val; 4381 BOOL space, version, is_64bit = sizeof(void *) > sizeof(int); 4382 HKEY hklm, classes, hkcu, users; 4383 LPSTR pathdata, pathvar, ptr; 4384 LONG res; 4385 UINT r, type = 0; 4386 SYSTEM_INFO si; 4387 4388 version = TRUE; 4389 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3))) 4390 version = FALSE; 4391 4392 DeleteFileA("test.dll"); 4393 4394 res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes); 4395 if (res == ERROR_ACCESS_DENIED) 4396 { 4397 skip("Not enough rights to perform tests\n"); 4398 return; 4399 } 4400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4401 4402 res = RegSetValueExA(classes, "Value1", 0, REG_SZ, 4403 (const BYTE *)"regszdata", 10); 4404 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4405 4406 res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu); 4407 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4408 4409 res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ, 4410 (const BYTE *)"regszdata", 10); 4411 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4412 4413 users = 0; 4414 res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users); 4415 ok(res == ERROR_SUCCESS || 4416 broken(res == ERROR_INVALID_PARAMETER), 4417 "Expected ERROR_SUCCESS, got %ld\n", res); 4418 4419 if (res == ERROR_SUCCESS) 4420 { 4421 res = RegSetValueExA(users, "Value1", 0, REG_SZ, 4422 (const BYTE *)"regszdata", 10); 4423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4424 } 4425 4426 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm); 4427 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4428 4429 res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8); 4430 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4431 4432 res = RegSetValueExA(hklm, "Value1", 0, REG_SZ, 4433 (const BYTE *)"regszdata", 10); 4434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4435 4436 val = 42; 4437 res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD, 4438 (const BYTE *)&val, sizeof(DWORD)); 4439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4440 4441 val = -42; 4442 res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD, 4443 (const BYTE *)&val, sizeof(DWORD)); 4444 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4445 4446 res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ, 4447 (const BYTE *)"%PATH%", 7); 4448 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4449 4450 res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ, 4451 (const BYTE *)"my%NOVAR%", 10); 4452 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4453 4454 res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ, 4455 (const BYTE *)"one\0two\0", 9); 4456 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4457 4458 binary[0] = 0x1234abcd; 4459 binary[1] = 0x567890ef; 4460 res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY, 4461 (const BYTE *)binary, sizeof(binary)); 4462 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4463 4464 res = RegSetValueExA(hklm, "Value8", 0, REG_SZ, 4465 (const BYTE *)"#regszdata", 11); 4466 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4467 4468 strcpy(expected, CURR_DIR); 4469 if (is_root(CURR_DIR)) expected[2] = 0; 4470 4471 create_test_file("FileName1"); 4472 sprintf(path, "%s\\FileName1", expected); 4473 res = RegSetValueExA(hklm, "Value9", 0, REG_SZ, 4474 (const BYTE *)path, lstrlenA(path) + 1); 4475 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4476 4477 sprintf(path, "%s\\FileName2", expected); 4478 res = RegSetValueExA(hklm, "Value10", 0, REG_SZ, 4479 (const BYTE *)path, lstrlenA(path) + 1); 4480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4481 4482 lstrcpyA(path, expected); 4483 res = RegSetValueExA(hklm, "Value11", 0, REG_SZ, 4484 (const BYTE *)path, lstrlenA(path) + 1); 4485 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4486 4487 res = RegSetValueExA(hklm, "Value12", 0, REG_SZ, 4488 (const BYTE *)"", 1); 4489 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4490 4491 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4492 sprintf(path, "%s\\FileName3.dll", expected); 4493 res = RegSetValueExA(hklm, "Value13", 0, REG_SZ, 4494 (const BYTE *)path, lstrlenA(path) + 1); 4495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4496 4497 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4)); 4498 sprintf(path, "%s\\FileName4.dll", expected); 4499 res = RegSetValueExA(hklm, "Value14", 0, REG_SZ, 4500 (const BYTE *)path, lstrlenA(path) + 1); 4501 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4502 4503 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4504 sprintf(path, "%s\\FileName5.dll", expected); 4505 res = RegSetValueExA(hklm, "Value15", 0, REG_SZ, 4506 (const BYTE *)path, lstrlenA(path) + 1); 4507 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4508 4509 sprintf(path, "\"%s\\FileName1\" -option", expected); 4510 res = RegSetValueExA(hklm, "value16", 0, REG_SZ, 4511 (const BYTE *)path, lstrlenA(path) + 1); 4512 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res); 4513 4514 space = strchr(expected, ' ') != NULL; 4515 sprintf(path, "%s\\FileName1 -option", expected); 4516 res = RegSetValueExA(hklm, "value17", 0, REG_SZ, 4517 (const BYTE *)path, lstrlenA(path) + 1); 4518 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res); 4519 4520 hdb = create_package_db(); 4521 ok(hdb, "Expected a valid database handle\n"); 4522 4523 create_appsearch_table(hdb); 4524 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); 4525 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); 4526 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); 4527 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); 4528 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); 4529 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); 4530 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); 4531 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); 4532 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); 4533 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); 4534 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); 4535 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); 4536 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'"); 4537 add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'"); 4538 add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'"); 4539 add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'"); 4540 add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'"); 4541 add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'"); 4542 add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'"); 4543 add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'"); 4544 add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'"); 4545 add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'"); 4546 add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'"); 4547 add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'"); 4548 add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'"); 4549 add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'"); 4550 add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'"); 4551 add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'"); 4552 add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'"); 4553 add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'"); 4554 4555 create_reglocator_table(hdb); 4556 4557 type = msidbLocatorTypeRawValue; 4558 if (is_64bit) 4559 type |= msidbLocatorType64bit; 4560 4561 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */ 4562 add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type); 4563 4564 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */ 4565 add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type); 4566 4567 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */ 4568 add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type); 4569 4570 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */ 4571 add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type); 4572 4573 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */ 4574 add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type); 4575 4576 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */ 4577 add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type); 4578 4579 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */ 4580 add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type); 4581 4582 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */ 4583 add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type); 4584 4585 type = msidbLocatorTypeFileName; 4586 if (is_64bit) 4587 type |= msidbLocatorType64bit; 4588 4589 /* HKLM, msidbLocatorTypeFileName, signature, file exists */ 4590 add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type); 4591 4592 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */ 4593 add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type); 4594 4595 /* HKLM, msidbLocatorTypeFileName, no signature */ 4596 add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type); 4597 4598 type = msidbLocatorTypeDirectory; 4599 if (is_64bit) 4600 type |= msidbLocatorType64bit; 4601 4602 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */ 4603 add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type); 4604 4605 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */ 4606 add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type); 4607 4608 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */ 4609 add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type); 4610 4611 type = msidbLocatorTypeRawValue; 4612 if (is_64bit) 4613 type |= msidbLocatorType64bit; 4614 4615 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */ 4616 add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type); 4617 4618 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */ 4619 add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type); 4620 4621 /* HKU, msidbLocatorTypeRawValue, REG_SZ */ 4622 add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type); 4623 4624 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */ 4625 add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type); 4626 4627 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */ 4628 add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type); 4629 4630 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */ 4631 add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type); 4632 4633 type = msidbLocatorTypeFileName; 4634 if (is_64bit) 4635 type |= msidbLocatorType64bit; 4636 4637 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */ 4638 add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type); 4639 4640 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */ 4641 add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type); 4642 4643 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */ 4644 add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type); 4645 4646 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */ 4647 add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type); 4648 4649 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */ 4650 add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type); 4651 4652 type = msidbLocatorTypeDirectory; 4653 if (is_64bit) 4654 type |= msidbLocatorType64bit; 4655 4656 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */ 4657 add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type); 4658 4659 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */ 4660 add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type); 4661 4662 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */ 4663 add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type); 4664 4665 type = msidbLocatorTypeFileName; 4666 if (is_64bit) 4667 type |= msidbLocatorType64bit; 4668 4669 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */ 4670 add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type); 4671 4672 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */ 4673 add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type); 4674 4675 create_signature_table(hdb); 4676 add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''"); 4677 add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''"); 4678 add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''"); 4679 add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4680 add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4681 add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4682 4683 if (!is_root(CURR_DIR)) 4684 { 4685 ptr = strrchr(expected, '\\') + 1; 4686 sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr); 4687 add_signature_entry(hdb, path); 4688 } 4689 add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''"); 4690 add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''"); 4691 add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''"); 4692 4693 r = package_from_db(hdb, &hpkg); 4694 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); 4695 4696 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 4697 4698 r = MsiDoActionA(hpkg, "AppSearch"); 4699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4700 4701 size = MAX_PATH; 4702 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size); 4703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4704 ok(!lstrcmpA(prop, "regszdata"), 4705 "Expected \"regszdata\", got \"%s\"\n", prop); 4706 4707 size = MAX_PATH; 4708 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size); 4709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4710 ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop); 4711 4712 size = MAX_PATH; 4713 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size); 4714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4715 ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop); 4716 4717 memset(&si, 0, sizeof(si)); 4718 GetNativeSystemInfo(&si); 4719 4720 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) 4721 { 4722 size = ExpandEnvironmentStringsA("%PATH%", NULL, 0); 4723 pathvar = malloc(size); 4724 ExpandEnvironmentStringsA("%PATH%", pathvar, size); 4725 4726 size = 0; 4727 r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size); 4728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4729 4730 pathdata = malloc(++size); 4731 r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size); 4732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4733 ok(!lstrcmpA(pathdata, pathvar), 4734 "Expected \"%s\", got \"%s\"\n", pathvar, pathdata); 4735 4736 free(pathvar); 4737 free(pathdata); 4738 } 4739 4740 size = MAX_PATH; 4741 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); 4742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4743 ok(!lstrcmpA(prop, 4744 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop); 4745 4746 size = MAX_PATH; 4747 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size); 4748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4749 todo_wine 4750 { 4751 ok(!memcmp(prop, "\0one\0two\0\0", 10), 4752 "Expected \"\\0one\\0two\\0\\0\"\n"); 4753 } 4754 4755 size = MAX_PATH; 4756 lstrcpyA(path, "#xCDAB3412EF907856"); 4757 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size); 4758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4759 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4760 4761 size = MAX_PATH; 4762 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size); 4763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4764 ok(!lstrcmpA(prop, "##regszdata"), 4765 "Expected \"##regszdata\", got \"%s\"\n", prop); 4766 4767 size = MAX_PATH; 4768 sprintf(path, "%s\\FileName1", expected); 4769 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size); 4770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4771 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4772 4773 size = MAX_PATH; 4774 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size); 4775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4776 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4777 4778 size = MAX_PATH; 4779 sprintf(path, "%s\\", expected); 4780 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size); 4781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4782 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4783 4784 size = MAX_PATH; 4785 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size); 4786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4787 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4788 4789 size = MAX_PATH; 4790 sprintf(path, "%s\\", expected); 4791 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size); 4792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4793 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4794 4795 size = MAX_PATH; 4796 r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size); 4797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4798 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4799 4800 size = MAX_PATH; 4801 r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size); 4802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4803 ok(!lstrcmpA(prop, "regszdata"), 4804 "Expected \"regszdata\", got \"%s\"\n", prop); 4805 4806 size = MAX_PATH; 4807 r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size); 4808 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4809 ok(!lstrcmpA(prop, "regszdata"), 4810 "Expected \"regszdata\", got \"%s\"\n", prop); 4811 4812 if (users) 4813 { 4814 size = MAX_PATH; 4815 r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size); 4816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4817 ok(!lstrcmpA(prop, "regszdata"), 4818 "Expected \"regszdata\", got \"%s\"\n", prop); 4819 } 4820 4821 size = MAX_PATH; 4822 r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size); 4823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4824 ok(!lstrcmpA(prop, "defvalue"), 4825 "Expected \"defvalue\", got \"%s\"\n", prop); 4826 4827 size = MAX_PATH; 4828 r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size); 4829 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4830 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4831 4832 size = MAX_PATH; 4833 r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size); 4834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4835 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4836 4837 if (version) 4838 { 4839 size = MAX_PATH; 4840 sprintf(path, "%s\\FileName3.dll", expected); 4841 r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size); 4842 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4843 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4844 4845 size = MAX_PATH; 4846 r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size); 4847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4848 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4849 4850 size = MAX_PATH; 4851 sprintf(path, "%s\\FileName5.dll", expected); 4852 r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size); 4853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4854 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4855 } 4856 4857 if (!is_root(CURR_DIR)) 4858 { 4859 size = MAX_PATH; 4860 lstrcpyA(path, expected); 4861 ptr = strrchr(path, '\\') + 1; 4862 *ptr = '\0'; 4863 r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size); 4864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4865 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4866 } 4867 size = MAX_PATH; 4868 sprintf(path, "%s\\", expected); 4869 r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size); 4870 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4871 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4872 4873 size = MAX_PATH; 4874 r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size); 4875 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4876 if (is_root(CURR_DIR)) 4877 ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop); 4878 else 4879 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4880 4881 size = MAX_PATH; 4882 r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size); 4883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4884 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4885 4886 size = MAX_PATH; 4887 r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size); 4888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4889 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4890 4891 size = MAX_PATH; 4892 sprintf(path, "%s\\FileName1", expected); 4893 r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size); 4894 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4895 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4896 4897 size = MAX_PATH; 4898 sprintf(path, "%s\\FileName1", expected); 4899 r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size); 4900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4901 if (space) 4902 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4903 else 4904 todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4905 4906 RegSetValueA(hklm, NULL, REG_SZ, "", 0); 4907 RegDeleteValueA(hklm, "Value1"); 4908 RegDeleteValueA(hklm, "Value2"); 4909 RegDeleteValueA(hklm, "Value3"); 4910 RegDeleteValueA(hklm, "Value4"); 4911 RegDeleteValueA(hklm, "Value5"); 4912 RegDeleteValueA(hklm, "Value6"); 4913 RegDeleteValueA(hklm, "Value7"); 4914 RegDeleteValueA(hklm, "Value8"); 4915 RegDeleteValueA(hklm, "Value9"); 4916 RegDeleteValueA(hklm, "Value10"); 4917 RegDeleteValueA(hklm, "Value11"); 4918 RegDeleteValueA(hklm, "Value12"); 4919 RegDeleteValueA(hklm, "Value13"); 4920 RegDeleteValueA(hklm, "Value14"); 4921 RegDeleteValueA(hklm, "Value15"); 4922 RegDeleteValueA(hklm, "Value16"); 4923 RegDeleteValueA(hklm, "Value17"); 4924 RegDeleteKeyA(hklm, ""); 4925 RegCloseKey(hklm); 4926 4927 RegDeleteValueA(classes, "Value1"); 4928 RegDeleteKeyA(classes, ""); 4929 RegCloseKey(classes); 4930 4931 RegDeleteValueA(hkcu, "Value1"); 4932 RegDeleteKeyA(hkcu, ""); 4933 RegCloseKey(hkcu); 4934 4935 RegDeleteValueA(users, "Value1"); 4936 RegDeleteKeyA(users, ""); 4937 RegCloseKey(users); 4938 4939 DeleteFileA("FileName1"); 4940 DeleteFileA("FileName3.dll"); 4941 DeleteFileA("FileName4.dll"); 4942 DeleteFileA("FileName5.dll"); 4943 MsiCloseHandle(hpkg); 4944 DeleteFileA(msifile); 4945 } 4946 4947 static void delete_win_ini(LPCSTR file) 4948 { 4949 CHAR path[MAX_PATH]; 4950 4951 GetWindowsDirectoryA(path, MAX_PATH); 4952 lstrcatA(path, "\\"); 4953 lstrcatA(path, file); 4954 4955 DeleteFileA(path); 4956 } 4957 4958 static void test_appsearch_inilocator(void) 4959 { 4960 MSIHANDLE hpkg, hdb; 4961 char path[MAX_PATH + 14], expected[MAX_PATH], prop[MAX_PATH]; 4962 BOOL version; 4963 LPSTR ptr; 4964 DWORD size; 4965 UINT r; 4966 4967 version = TRUE; 4968 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3))) 4969 version = FALSE; 4970 4971 DeleteFileA("test.dll"); 4972 4973 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini"); 4974 4975 strcpy(expected, CURR_DIR); 4976 if (is_root(CURR_DIR)) expected[2] = 0; 4977 4978 create_test_file("FileName1"); 4979 sprintf(path, "%s\\FileName1", expected); 4980 WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini"); 4981 4982 WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini"); 4983 4984 sprintf(path, "%s\\IDontExist", expected); 4985 WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini"); 4986 4987 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4988 sprintf(path, "%s\\FileName2.dll", expected); 4989 WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini"); 4990 4991 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4)); 4992 sprintf(path, "%s\\FileName3.dll", expected); 4993 WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini"); 4994 4995 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4996 sprintf(path, "%s\\FileName4.dll", expected); 4997 WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini"); 4998 4999 hdb = create_package_db(); 5000 ok(hdb, "Expected a valid database handle\n"); 5001 5002 create_appsearch_table(hdb); 5003 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); 5004 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); 5005 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); 5006 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); 5007 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); 5008 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); 5009 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); 5010 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); 5011 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); 5012 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); 5013 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); 5014 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); 5015 5016 create_inilocator_table(hdb); 5017 5018 /* msidbLocatorTypeRawValue, field 1 */ 5019 add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2"); 5020 5021 /* msidbLocatorTypeRawValue, field 2 */ 5022 add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2"); 5023 5024 /* msidbLocatorTypeRawValue, entire field */ 5025 add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2"); 5026 5027 /* msidbLocatorTypeFile */ 5028 add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1"); 5029 5030 /* msidbLocatorTypeDirectory, file */ 5031 add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0"); 5032 5033 /* msidbLocatorTypeDirectory, directory */ 5034 add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0"); 5035 5036 /* msidbLocatorTypeFile, file, no signature */ 5037 add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1"); 5038 5039 /* msidbLocatorTypeFile, dir, no signature */ 5040 add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1"); 5041 5042 /* msidbLocatorTypeFile, file does not exist */ 5043 add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1"); 5044 5045 /* msidbLocatorTypeFile, signature with version */ 5046 add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1"); 5047 5048 /* msidbLocatorTypeFile, signature with version, ver > max */ 5049 add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1"); 5050 5051 /* msidbLocatorTypeFile, signature with version, sig->name ignored */ 5052 add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1"); 5053 5054 create_signature_table(hdb); 5055 add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''"); 5056 add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''"); 5057 add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5058 add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5059 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5060 5061 r = package_from_db(hdb, &hpkg); 5062 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5063 { 5064 skip("Not enough rights to perform tests\n"); 5065 goto error; 5066 } 5067 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); 5068 5069 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5070 5071 r = MsiDoActionA(hpkg, "AppSearch"); 5072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5073 5074 size = MAX_PATH; 5075 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size); 5076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5077 ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop); 5078 5079 size = MAX_PATH; 5080 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size); 5081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5082 ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop); 5083 5084 size = MAX_PATH; 5085 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size); 5086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5087 ok(!lstrcmpA(prop, "keydata,field2"), 5088 "Expected \"keydata,field2\", got \"%s\"\n", prop); 5089 5090 size = MAX_PATH; 5091 sprintf(path, "%s\\FileName1", expected); 5092 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size); 5093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5094 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5095 5096 size = MAX_PATH; 5097 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); 5098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5099 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5100 5101 size = MAX_PATH; 5102 sprintf(path, "%s\\", expected); 5103 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size); 5104 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5105 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5106 5107 size = MAX_PATH; 5108 sprintf(path, "%s\\", expected); 5109 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size); 5110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5111 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5112 5113 if (!is_root(CURR_DIR)) 5114 { 5115 size = MAX_PATH; 5116 lstrcpyA(path, expected); 5117 ptr = strrchr(path, '\\'); 5118 *(ptr + 1) = 0; 5119 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size); 5120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5121 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5122 } 5123 size = MAX_PATH; 5124 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size); 5125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5126 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5127 5128 if (version) 5129 { 5130 size = MAX_PATH; 5131 sprintf(path, "%s\\FileName2.dll", expected); 5132 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size); 5133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5134 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5135 5136 size = MAX_PATH; 5137 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size); 5138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5139 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5140 5141 size = MAX_PATH; 5142 sprintf(path, "%s\\FileName4.dll", expected); 5143 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size); 5144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5145 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5146 } 5147 5148 MsiCloseHandle(hpkg); 5149 5150 error: 5151 delete_win_ini("IniFile.ini"); 5152 DeleteFileA("FileName1"); 5153 DeleteFileA("FileName2.dll"); 5154 DeleteFileA("FileName3.dll"); 5155 DeleteFileA("FileName4.dll"); 5156 DeleteFileA(msifile); 5157 } 5158 5159 /* 5160 * MSI AppSearch action on DrLocator table always returns absolute paths. 5161 * If a relative path was set, it returns the first absolute path that 5162 * matches or an empty string if it didn't find anything. 5163 * This helper function replicates this behaviour. 5164 */ 5165 static void search_absolute_directory(LPSTR absolute, LPCSTR relative) 5166 { 5167 int i, size; 5168 DWORD attr, drives; 5169 5170 size = lstrlenA(relative); 5171 drives = GetLogicalDrives(); 5172 lstrcpyA(absolute, "A:\\"); 5173 for (i = 0; i < 26; absolute[0] = '\0', i++) 5174 { 5175 if (!(drives & (1 << i))) 5176 continue; 5177 5178 absolute[0] = 'A' + i; 5179 if (GetDriveTypeA(absolute) != DRIVE_FIXED) 5180 continue; 5181 5182 lstrcpynA(absolute + 3, relative, size + 1); 5183 attr = GetFileAttributesA(absolute); 5184 if (attr != INVALID_FILE_ATTRIBUTES && 5185 (attr & FILE_ATTRIBUTE_DIRECTORY)) 5186 { 5187 if (absolute[3 + size - 1] != '\\') 5188 lstrcatA(absolute, "\\"); 5189 break; 5190 } 5191 absolute[3] = '\0'; 5192 } 5193 } 5194 5195 static void test_appsearch_drlocator(void) 5196 { 5197 MSIHANDLE hpkg, hdb; 5198 char path[MAX_PATH + 27], expected[MAX_PATH], prop[MAX_PATH]; 5199 BOOL version; 5200 DWORD size; 5201 UINT r; 5202 5203 version = TRUE; 5204 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3))) 5205 version = FALSE; 5206 5207 DeleteFileA("test.dll"); 5208 5209 create_test_file("FileName1"); 5210 CreateDirectoryA("one", NULL); 5211 CreateDirectoryA("one\\two", NULL); 5212 CreateDirectoryA("one\\two\\three", NULL); 5213 create_test_file("one\\two\\three\\FileName2"); 5214 CreateDirectoryA("another", NULL); 5215 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 5216 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4)); 5217 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 5218 5219 hdb = create_package_db(); 5220 ok(hdb, "Expected a valid database handle\n"); 5221 5222 create_appsearch_table(hdb); 5223 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); 5224 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); 5225 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); 5226 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); 5227 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); 5228 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); 5229 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); 5230 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); 5231 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); 5232 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); 5233 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); 5234 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'"); 5235 5236 create_drlocator_table(hdb); 5237 5238 strcpy(expected, CURR_DIR); 5239 if (is_root(CURR_DIR)) expected[2] = 0; 5240 5241 /* no parent, full path, depth 0, signature */ 5242 sprintf(path, "'NewSignature1', '', '%s', 0", expected); 5243 add_drlocator_entry(hdb, path); 5244 5245 /* no parent, full path, depth 0, no signature */ 5246 sprintf(path, "'NewSignature2', '', '%s', 0", expected); 5247 add_drlocator_entry(hdb, path); 5248 5249 /* no parent, relative path, depth 0, no signature */ 5250 sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3); 5251 add_drlocator_entry(hdb, path); 5252 5253 /* no parent, full path, depth 2, signature */ 5254 sprintf(path, "'NewSignature4', '', '%s', 2", expected); 5255 add_drlocator_entry(hdb, path); 5256 5257 /* no parent, full path, depth 3, signature */ 5258 sprintf(path, "'NewSignature5', '', '%s', 3", expected); 5259 add_drlocator_entry(hdb, path); 5260 5261 /* no parent, full path, depth 1, signature is dir */ 5262 sprintf(path, "'NewSignature6', '', '%s', 1", expected); 5263 add_drlocator_entry(hdb, path); 5264 5265 /* parent is in DrLocator, relative path, depth 0, signature */ 5266 sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1"); 5267 add_drlocator_entry(hdb, path); 5268 5269 /* no parent, full path, depth 0, signature w/ version */ 5270 sprintf(path, "'NewSignature8', '', '%s', 0", expected); 5271 add_drlocator_entry(hdb, path); 5272 5273 /* no parent, full path, depth 0, signature w/ version, ver > max */ 5274 sprintf(path, "'NewSignature9', '', '%s', 0", expected); 5275 add_drlocator_entry(hdb, path); 5276 5277 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */ 5278 sprintf(path, "'NewSignature10', '', '%s', 0", expected); 5279 add_drlocator_entry(hdb, path); 5280 5281 /* no parent, relative empty path, depth 0, no signature */ 5282 sprintf(path, "'NewSignature11', '', '', 0"); 5283 add_drlocator_entry(hdb, path); 5284 5285 create_reglocator_table(hdb); 5286 5287 /* parent */ 5288 add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1); 5289 5290 /* parent is in RegLocator, no path, depth 0, no signature */ 5291 sprintf(path, "'NewSignature13', 'NewSignature12', '', 0"); 5292 add_drlocator_entry(hdb, path); 5293 5294 create_signature_table(hdb); 5295 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''"); 5296 add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''"); 5297 add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''"); 5298 add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''"); 5299 add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''"); 5300 add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5301 add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5302 add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5303 5304 r = package_from_db(hdb, &hpkg); 5305 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5306 { 5307 skip("Not enough rights to perform tests\n"); 5308 goto error; 5309 } 5310 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); 5311 5312 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5313 5314 r = MsiDoActionA(hpkg, "AppSearch"); 5315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5316 5317 size = MAX_PATH; 5318 sprintf(path, "%s\\FileName1", expected); 5319 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size); 5320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5321 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5322 5323 size = MAX_PATH; 5324 sprintf(path, "%s\\", expected); 5325 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size); 5326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5327 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5328 5329 size = MAX_PATH; 5330 search_absolute_directory(path, expected + 3); 5331 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size); 5332 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5333 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5334 5335 size = MAX_PATH; 5336 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size); 5337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5338 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5339 5340 size = MAX_PATH; 5341 sprintf(path, "%s\\one\\two\\three\\FileName2", expected); 5342 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); 5343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5344 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5345 5346 size = MAX_PATH; 5347 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size); 5348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5349 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5350 5351 size = MAX_PATH; 5352 sprintf(path, "%s\\one\\two\\three\\FileName2", expected); 5353 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size); 5354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5355 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5356 5357 if (version) 5358 { 5359 size = MAX_PATH; 5360 sprintf(path, "%s\\FileName3.dll", expected); 5361 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size); 5362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5363 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5364 5365 size = MAX_PATH; 5366 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size); 5367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5368 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5369 5370 size = MAX_PATH; 5371 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size); 5372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5373 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5374 } 5375 5376 size = MAX_PATH; 5377 search_absolute_directory(path, ""); 5378 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size); 5379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5380 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5381 5382 size = MAX_PATH; 5383 strcpy(path, "c:\\"); 5384 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size); 5385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5386 ok(!prop[0], "Expected \"\", got \"%s\"\n", prop); 5387 5388 MsiCloseHandle(hpkg); 5389 5390 error: 5391 DeleteFileA("FileName1"); 5392 DeleteFileA("FileName3.dll"); 5393 DeleteFileA("FileName4.dll"); 5394 DeleteFileA("FileName5.dll"); 5395 DeleteFileA("one\\two\\three\\FileName2"); 5396 RemoveDirectoryA("one\\two\\three"); 5397 RemoveDirectoryA("one\\two"); 5398 RemoveDirectoryA("one"); 5399 RemoveDirectoryA("another"); 5400 DeleteFileA(msifile); 5401 } 5402 5403 static void test_featureparents(void) 5404 { 5405 MSIHANDLE hpkg; 5406 UINT r; 5407 MSIHANDLE hdb; 5408 5409 hdb = create_package_db(); 5410 ok ( hdb, "failed to create package database\n" ); 5411 5412 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); 5413 5414 create_feature_table( hdb ); 5415 create_component_table( hdb ); 5416 create_feature_components_table( hdb ); 5417 create_file_table( hdb ); 5418 5419 /* msidbFeatureAttributesFavorLocal */ 5420 add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" ); 5421 5422 /* msidbFeatureAttributesFavorSource */ 5423 add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" ); 5424 5425 /* msidbFeatureAttributesFavorLocal */ 5426 add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" ); 5427 5428 /* msidbFeatureAttributesUIDisallowAbsent */ 5429 add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" ); 5430 5431 /* disabled because of install level */ 5432 add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" ); 5433 5434 /* child feature of disabled feature */ 5435 add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" ); 5436 5437 /* component of disabled feature (install level) */ 5438 add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" ); 5439 5440 /* component of disabled child feature (install level) */ 5441 add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" ); 5442 5443 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ 5444 add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" ); 5445 5446 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ 5447 add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" ); 5448 5449 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ 5450 add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" ); 5451 5452 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */ 5453 add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" ); 5454 5455 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ 5456 add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" ); 5457 5458 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */ 5459 add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" ); 5460 5461 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ 5462 add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" ); 5463 5464 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ 5465 add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" ); 5466 5467 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ 5468 add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" ); 5469 5470 add_feature_components_entry( hdb, "'zodiac', 'leo'" ); 5471 add_feature_components_entry( hdb, "'zodiac', 'virgo'" ); 5472 add_feature_components_entry( hdb, "'zodiac', 'libra'" ); 5473 add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" ); 5474 add_feature_components_entry( hdb, "'perseus', 'cepheus'" ); 5475 add_feature_components_entry( hdb, "'perseus', 'andromeda'" ); 5476 add_feature_components_entry( hdb, "'orion', 'leo'" ); 5477 add_feature_components_entry( hdb, "'orion', 'virgo'" ); 5478 add_feature_components_entry( hdb, "'orion', 'libra'" ); 5479 add_feature_components_entry( hdb, "'orion', 'cassiopeia'" ); 5480 add_feature_components_entry( hdb, "'orion', 'cepheus'" ); 5481 add_feature_components_entry( hdb, "'orion', 'andromeda'" ); 5482 add_feature_components_entry( hdb, "'orion', 'canis'" ); 5483 add_feature_components_entry( hdb, "'orion', 'monoceros'" ); 5484 add_feature_components_entry( hdb, "'orion', 'lepus'" ); 5485 add_feature_components_entry( hdb, "'waters', 'delphinus'" ); 5486 add_feature_components_entry( hdb, "'bayer', 'hydrus'" ); 5487 5488 add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" ); 5489 add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" ); 5490 add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" ); 5491 add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" ); 5492 add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" ); 5493 add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" ); 5494 add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" ); 5495 add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" ); 5496 add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" ); 5497 add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" ); 5498 add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" ); 5499 5500 r = package_from_db( hdb, &hpkg ); 5501 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5502 { 5503 skip("Not enough rights to perform tests\n"); 5504 DeleteFileA(msifile); 5505 return; 5506 } 5507 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 5508 5509 MsiCloseHandle( hdb ); 5510 5511 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5512 5513 r = MsiDoActionA( hpkg, "CostInitialize"); 5514 ok( r == ERROR_SUCCESS, "cost init failed\n"); 5515 5516 r = MsiDoActionA( hpkg, "FileCost"); 5517 ok( r == ERROR_SUCCESS, "file cost failed\n"); 5518 5519 r = MsiDoActionA( hpkg, "CostFinalize"); 5520 ok( r == ERROR_SUCCESS, "cost finalize failed\n"); 5521 5522 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 5523 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 5524 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 5525 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 5526 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 5527 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 5528 5529 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5530 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5531 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5532 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5533 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5534 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5535 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5536 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5537 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5538 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5539 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5540 5541 r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT); 5542 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r); 5543 5544 r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT); 5545 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r); 5546 5547 r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT); 5548 ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r); 5549 5550 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 5551 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 5552 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE ); 5553 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE ); 5554 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 5555 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 5556 5557 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5558 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5559 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5560 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5561 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5562 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5563 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5564 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5565 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5566 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5567 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5568 5569 MsiCloseHandle(hpkg); 5570 DeleteFileA(msifile); 5571 } 5572 5573 static void test_installprops(void) 5574 { 5575 MSIHANDLE hpkg, hdb; 5576 CHAR path[MAX_PATH], buf[MAX_PATH]; 5577 DWORD size, type; 5578 LANGID langid; 5579 HKEY hkey1, hkey2, pathkey; 5580 int res; 5581 UINT r; 5582 REGSAM access = KEY_ALL_ACCESS; 5583 SYSTEM_INFO si; 5584 INSTALLUILEVEL uilevel; 5585 5586 if (is_wow64) 5587 access |= KEY_WOW64_64KEY; 5588 5589 lstrcpyA(path, CURR_DIR); 5590 if (!is_root(CURR_DIR)) lstrcatA(path, "\\"); 5591 lstrcatA(path, msifile); 5592 5593 uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL); 5594 5595 hdb = create_package_db(); 5596 ok( hdb, "failed to create database\n"); 5597 5598 r = package_from_db(hdb, &hpkg); 5599 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5600 { 5601 skip("Not enough rights to perform tests\n"); 5602 MsiSetInternalUI(uilevel, NULL); 5603 DeleteFileA(msifile); 5604 return; 5605 } 5606 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 5607 5608 MsiCloseHandle(hdb); 5609 5610 buf[0] = 0; 5611 size = MAX_PATH; 5612 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size); 5613 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5614 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf); 5615 5616 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5617 5618 buf[0] = 0; 5619 size = MAX_PATH; 5620 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size); 5621 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5622 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf); 5623 5624 buf[0] = 0; 5625 size = MAX_PATH; 5626 r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size); 5627 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5628 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf); 5629 5630 RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1); 5631 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2); 5632 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 5633 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey); 5634 5635 size = MAX_PATH; 5636 type = REG_SZ; 5637 *path = '\0'; 5638 if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS) 5639 { 5640 size = MAX_PATH; 5641 type = REG_SZ; 5642 RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size); 5643 } 5644 5645 buf[0] = 0; 5646 size = MAX_PATH; 5647 r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size); 5648 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5649 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf); 5650 5651 size = MAX_PATH; 5652 type = REG_SZ; 5653 *path = '\0'; 5654 if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS) 5655 { 5656 size = MAX_PATH; 5657 type = REG_SZ; 5658 RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size); 5659 } 5660 5661 if (*path) 5662 { 5663 buf[0] = 0; 5664 size = MAX_PATH; 5665 r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size); 5666 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5667 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf); 5668 } 5669 5670 buf[0] = 0; 5671 size = MAX_PATH; 5672 r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size); 5673 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5674 trace("VersionDatabase = %s\n", buf); 5675 5676 buf[0] = 0; 5677 size = MAX_PATH; 5678 r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size); 5679 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5680 trace("VersionMsi = %s\n", buf); 5681 5682 buf[0] = 0; 5683 size = MAX_PATH; 5684 r = MsiGetPropertyA(hpkg, "Date", buf, &size); 5685 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5686 trace("Date = %s\n", buf); 5687 5688 buf[0] = 0; 5689 size = MAX_PATH; 5690 r = MsiGetPropertyA(hpkg, "Time", buf, &size); 5691 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5692 trace("Time = %s\n", buf); 5693 5694 buf[0] = 0; 5695 size = MAX_PATH; 5696 r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size); 5697 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5698 trace("PackageCode = %s\n", buf); 5699 5700 buf[0] = 0; 5701 size = MAX_PATH; 5702 r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size); 5703 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 5704 trace("ComputerName = %s\n", buf); 5705 5706 langid = GetUserDefaultLangID(); 5707 sprintf(path, "%d", langid); 5708 5709 buf[0] = 0; 5710 size = MAX_PATH; 5711 r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size); 5712 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 5713 ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf); 5714 5715 res = GetSystemMetrics(SM_CXSCREEN); 5716 buf[0] = 0; 5717 size = MAX_PATH; 5718 r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size); 5719 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 5720 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf); 5721 5722 res = GetSystemMetrics(SM_CYSCREEN); 5723 buf[0] = 0; 5724 size = MAX_PATH; 5725 r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size); 5726 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 5727 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf); 5728 5729 buf[0] = 0; 5730 size = MAX_PATH; 5731 r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size); 5732 if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf ); 5733 5734 GetNativeSystemInfo(&si); 5735 5736 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion()))); 5737 check_prop(hpkg, "VersionNT", buf, 1); 5738 5739 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) 5740 { 5741 sprintf(buf, "%d", si.wProcessorLevel); 5742 check_prop(hpkg, "Intel", buf, 1); 5743 check_prop(hpkg, "MsiAMD64", buf, 1); 5744 check_prop(hpkg, "Msix64", buf, 1); 5745 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion()))); 5746 check_prop(hpkg, "VersionNT64", buf, 1); 5747 5748 GetSystemDirectoryA(path, MAX_PATH); 5749 strcat(path, "\\"); 5750 check_prop(hpkg, "System64Folder", path, 0); 5751 5752 GetSystemWow64DirectoryA(path, MAX_PATH); 5753 strcat(path, "\\"); 5754 check_prop(hpkg, "SystemFolder", path, 0); 5755 5756 size = MAX_PATH; 5757 r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size); 5758 strcat(path, "\\"); 5759 check_prop(hpkg, "ProgramFilesFolder", path, 0); 5760 5761 size = MAX_PATH; 5762 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size); 5763 strcat(path, "\\"); 5764 check_prop(hpkg, "ProgramFiles64Folder", path, 0); 5765 5766 size = MAX_PATH; 5767 RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size); 5768 strcat(path, "\\"); 5769 check_prop(hpkg, "CommonFilesFolder", path, 0); 5770 5771 size = MAX_PATH; 5772 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size); 5773 strcat(path, "\\"); 5774 check_prop(hpkg, "CommonFiles64Folder", path, 0); 5775 } 5776 else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) 5777 { 5778 sprintf(buf, "%d", si.wProcessorLevel); 5779 check_prop(hpkg, "Intel", buf, 1); 5780 5781 GetSystemDirectoryA(path, MAX_PATH); 5782 strcat(path, "\\"); 5783 check_prop(hpkg, "SystemFolder", path, 0); 5784 5785 size = MAX_PATH; 5786 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size); 5787 strcat(path, "\\"); 5788 check_prop(hpkg, "ProgramFilesFolder", path, 0); 5789 5790 size = MAX_PATH; 5791 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size); 5792 strcat(path, "\\"); 5793 check_prop(hpkg, "CommonFilesFolder", path, 0); 5794 5795 check_prop(hpkg, "MsiAMD64", "", 1); 5796 check_prop(hpkg, "Msix64", "", 1); 5797 check_prop(hpkg, "VersionNT64", "", 1); 5798 check_prop(hpkg, "System64Folder", "", 0); 5799 check_prop(hpkg, "ProgramFiles64Dir", "", 0); 5800 check_prop(hpkg, "CommonFiles64Dir", "", 0); 5801 } 5802 5803 CloseHandle(hkey1); 5804 CloseHandle(hkey2); 5805 RegCloseKey(pathkey); 5806 MsiCloseHandle(hpkg); 5807 DeleteFileA(msifile); 5808 MsiSetInternalUI(uilevel, NULL); 5809 } 5810 5811 static void test_launchconditions(void) 5812 { 5813 MSIHANDLE hpkg; 5814 MSIHANDLE hdb; 5815 UINT r; 5816 5817 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5818 5819 hdb = create_package_db(); 5820 ok( hdb, "failed to create package database\n" ); 5821 5822 create_launchcondition_table( hdb ); 5823 5824 add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" ); 5825 5826 /* invalid condition */ 5827 add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" ); 5828 5829 r = package_from_db( hdb, &hpkg ); 5830 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5831 { 5832 skip("Not enough rights to perform tests\n"); 5833 DeleteFileA(msifile); 5834 return; 5835 } 5836 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 5837 5838 MsiCloseHandle( hdb ); 5839 5840 r = MsiSetPropertyA( hpkg, "X", "1" ); 5841 ok( r == ERROR_SUCCESS, "failed to set property\n" ); 5842 5843 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5844 5845 /* invalid conditions are ignored */ 5846 r = MsiDoActionA( hpkg, "LaunchConditions" ); 5847 ok( r == ERROR_SUCCESS, "cost init failed\n" ); 5848 5849 /* verify LaunchConditions still does some verification */ 5850 r = MsiSetPropertyA( hpkg, "X", "2" ); 5851 ok( r == ERROR_SUCCESS, "failed to set property\n" ); 5852 5853 r = MsiDoActionA( hpkg, "LaunchConditions" ); 5854 ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r ); 5855 5856 MsiCloseHandle( hpkg ); 5857 DeleteFileA( msifile ); 5858 } 5859 5860 static void test_ccpsearch(void) 5861 { 5862 MSIHANDLE hdb, hpkg; 5863 CHAR prop[MAX_PATH]; 5864 DWORD size = MAX_PATH; 5865 UINT r; 5866 5867 hdb = create_package_db(); 5868 ok(hdb, "failed to create package database\n"); 5869 5870 create_ccpsearch_table(hdb); 5871 add_ccpsearch_entry(hdb, "'CCP_random'"); 5872 add_ccpsearch_entry(hdb, "'RMCCP_random'"); 5873 5874 create_reglocator_table(hdb); 5875 add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1); 5876 5877 create_drlocator_table(hdb); 5878 add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'"); 5879 5880 create_signature_table(hdb); 5881 5882 r = package_from_db(hdb, &hpkg); 5883 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5884 { 5885 skip("Not enough rights to perform tests\n"); 5886 DeleteFileA(msifile); 5887 return; 5888 } 5889 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 5890 5891 MsiCloseHandle(hdb); 5892 5893 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5894 5895 r = MsiDoActionA(hpkg, "CCPSearch"); 5896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5897 5898 r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size); 5899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5900 ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop); 5901 5902 MsiCloseHandle(hpkg); 5903 DeleteFileA(msifile); 5904 } 5905 5906 static void test_complocator(void) 5907 { 5908 MSIHANDLE hdb, hpkg; 5909 UINT r; 5910 CHAR prop[MAX_PATH]; 5911 CHAR expected[MAX_PATH]; 5912 DWORD size = MAX_PATH; 5913 5914 hdb = create_package_db(); 5915 ok(hdb, "failed to create package database\n"); 5916 5917 create_appsearch_table(hdb); 5918 add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'"); 5919 add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'"); 5920 add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'"); 5921 add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'"); 5922 add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'"); 5923 add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'"); 5924 add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'"); 5925 add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'"); 5926 add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'"); 5927 add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'"); 5928 add_appsearch_entry(hdb, "'KAKURU', 'kakuru'"); 5929 add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'"); 5930 add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'"); 5931 add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'"); 5932 add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'"); 5933 add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'"); 5934 5935 create_complocator_table(hdb); 5936 add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1"); 5937 add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0"); 5938 add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1"); 5939 add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0"); 5940 add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1"); 5941 add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0"); 5942 add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1"); 5943 add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0"); 5944 add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1"); 5945 add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0"); 5946 add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1"); 5947 add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0"); 5948 add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1"); 5949 add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0"); 5950 add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1"); 5951 add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0"); 5952 5953 create_signature_table(hdb); 5954 add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''"); 5955 add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''"); 5956 add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''"); 5957 add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''"); 5958 add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''"); 5959 add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''"); 5960 add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''"); 5961 add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''"); 5962 5963 r = package_from_db(hdb, &hpkg); 5964 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5965 { 5966 skip("Not enough rights to perform tests\n"); 5967 DeleteFileA(msifile); 5968 return; 5969 } 5970 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 5971 5972 MsiCloseHandle(hdb); 5973 5974 create_test_file("abelisaurus"); 5975 create_test_file("bactrosaurus"); 5976 create_test_file("camelotia"); 5977 create_test_file("diclonius"); 5978 create_test_file("echinodon"); 5979 create_test_file("falcarius"); 5980 create_test_file("gallimimus"); 5981 create_test_file("hagryphus"); 5982 CreateDirectoryA("iguanodon", NULL); 5983 CreateDirectoryA("jobaria", NULL); 5984 CreateDirectoryA("kakuru", NULL); 5985 CreateDirectoryA("labocania", NULL); 5986 CreateDirectoryA("megaraptor", NULL); 5987 CreateDirectoryA("neosodon", NULL); 5988 CreateDirectoryA("olorotitan", NULL); 5989 CreateDirectoryA("pantydraco", NULL); 5990 5991 set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE, 5992 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE); 5993 set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE, 5994 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE); 5995 set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE, 5996 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE); 5997 set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE, 5998 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE); 5999 set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE, 6000 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE); 6001 set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE, 6002 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE); 6003 set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE, 6004 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE); 6005 set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE, 6006 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE); 6007 6008 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 6009 6010 r = MsiDoActionA(hpkg, "AppSearch"); 6011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6012 6013 size = MAX_PATH; 6014 r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size); 6015 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6016 6017 lstrcpyA(expected, CURR_DIR); 6018 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\"); 6019 lstrcatA(expected, "abelisaurus"); 6020 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""), 6021 "Expected %s or empty string, got %s\n", expected, prop); 6022 6023 size = MAX_PATH; 6024 r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size); 6025 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6026 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6027 6028 size = MAX_PATH; 6029 r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size); 6030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6031 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6032 6033 size = MAX_PATH; 6034 r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size); 6035 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6036 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6037 6038 size = MAX_PATH; 6039 r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size); 6040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6041 6042 lstrcpyA(expected, CURR_DIR); 6043 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\"); 6044 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""), 6045 "Expected %s or empty string, got %s\n", expected, prop); 6046 6047 size = MAX_PATH; 6048 r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size); 6049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6050 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6051 6052 size = MAX_PATH; 6053 r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size); 6054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6055 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6056 6057 size = MAX_PATH; 6058 r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size); 6059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6060 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6061 6062 size = MAX_PATH; 6063 r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size); 6064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6065 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6066 6067 size = MAX_PATH; 6068 r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size); 6069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6070 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6071 6072 size = MAX_PATH; 6073 r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size); 6074 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6075 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6076 6077 size = MAX_PATH; 6078 r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size); 6079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6080 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6081 6082 size = MAX_PATH; 6083 r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size); 6084 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6085 6086 lstrcpyA(expected, CURR_DIR); 6087 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\"); 6088 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""), 6089 "Expected %s or empty string, got %s\n", expected, prop); 6090 6091 size = MAX_PATH; 6092 r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size); 6093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6094 6095 lstrcpyA(expected, CURR_DIR); 6096 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\"); 6097 lstrcatA(expected, "neosodon\\"); 6098 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""), 6099 "Expected %s or empty string, got %s\n", expected, prop); 6100 6101 size = MAX_PATH; 6102 r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size); 6103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6104 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6105 6106 size = MAX_PATH; 6107 r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size); 6108 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6109 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 6110 6111 MsiCloseHandle(hpkg); 6112 DeleteFileA("abelisaurus"); 6113 DeleteFileA("bactrosaurus"); 6114 DeleteFileA("camelotia"); 6115 DeleteFileA("diclonius"); 6116 DeleteFileA("echinodon"); 6117 DeleteFileA("falcarius"); 6118 DeleteFileA("gallimimus"); 6119 DeleteFileA("hagryphus"); 6120 RemoveDirectoryA("iguanodon"); 6121 RemoveDirectoryA("jobaria"); 6122 RemoveDirectoryA("kakuru"); 6123 RemoveDirectoryA("labocania"); 6124 RemoveDirectoryA("megaraptor"); 6125 RemoveDirectoryA("neosodon"); 6126 RemoveDirectoryA("olorotitan"); 6127 RemoveDirectoryA("pantydraco"); 6128 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}", 6129 MSIINSTALLCONTEXT_MACHINE, NULL); 6130 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", 6131 MSIINSTALLCONTEXT_MACHINE, NULL); 6132 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}", 6133 MSIINSTALLCONTEXT_MACHINE, NULL); 6134 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}", 6135 MSIINSTALLCONTEXT_MACHINE, NULL); 6136 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", 6137 MSIINSTALLCONTEXT_MACHINE, NULL); 6138 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}", 6139 MSIINSTALLCONTEXT_MACHINE, NULL); 6140 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", 6141 MSIINSTALLCONTEXT_MACHINE, NULL); 6142 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}", 6143 MSIINSTALLCONTEXT_MACHINE, NULL); 6144 DeleteFileA(msifile); 6145 } 6146 6147 static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val) 6148 { 6149 MSIHANDLE summary; 6150 UINT r; 6151 6152 r = MsiGetSummaryInformationA(db, NULL, 1, &summary); 6153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6154 6155 r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL); 6156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6157 6158 r = MsiSummaryInfoPersist(summary); 6159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 6160 6161 MsiCloseHandle(summary); 6162 } 6163 6164 static void test_MsiGetSourcePath(void) 6165 { 6166 MSIHANDLE hdb, hpkg; 6167 CHAR path[MAX_PATH]; 6168 CHAR cwd[MAX_PATH]; 6169 CHAR subsrc[MAX_PATH]; 6170 CHAR sub2[MAX_PATH]; 6171 DWORD size; 6172 UINT r; 6173 6174 lstrcpyA(cwd, CURR_DIR); 6175 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\"); 6176 6177 lstrcpyA(subsrc, cwd); 6178 lstrcatA(subsrc, "subsource"); 6179 lstrcatA(subsrc, "\\"); 6180 6181 lstrcpyA(sub2, subsrc); 6182 lstrcatA(sub2, "sub2"); 6183 lstrcatA(sub2, "\\"); 6184 6185 /* uncompressed source */ 6186 6187 hdb = create_package_db(); 6188 ok( hdb, "failed to create database\n"); 6189 6190 set_suminfo_prop(hdb, PID_WORDCOUNT, 0); 6191 6192 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); 6193 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'"); 6194 add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'"); 6195 6196 r = MsiDatabaseCommit(hdb); 6197 ok(r == ERROR_SUCCESS , "Failed to commit database\n"); 6198 6199 r = package_from_db(hdb, &hpkg); 6200 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 6201 { 6202 skip("Not enough rights to perform tests\n"); 6203 DeleteFileA(msifile); 6204 return; 6205 } 6206 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 6207 6208 MsiCloseHandle(hdb); 6209 6210 /* invalid database handle */ 6211 size = MAX_PATH; 6212 lstrcpyA(path, "kiwi"); 6213 r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size); 6214 ok(r == ERROR_INVALID_HANDLE, 6215 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 6216 ok(!lstrcmpA(path, "kiwi"), 6217 "Expected path to be unchanged, got \"%s\"\n", path); 6218 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6219 6220 /* NULL szFolder */ 6221 size = MAX_PATH; 6222 lstrcpyA(path, "kiwi"); 6223 r = MsiGetSourcePathA(hpkg, NULL, path, &size); 6224 ok(r == ERROR_INVALID_PARAMETER, 6225 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 6226 ok(!lstrcmpA(path, "kiwi"), 6227 "Expected path to be unchanged, got \"%s\"\n", path); 6228 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6229 6230 /* empty szFolder */ 6231 size = MAX_PATH; 6232 lstrcpyA(path, "kiwi"); 6233 r = MsiGetSourcePathA(hpkg, "", path, &size); 6234 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6235 ok(!lstrcmpA(path, "kiwi"), 6236 "Expected path to be unchanged, got \"%s\"\n", path); 6237 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6238 6239 /* try TARGETDIR */ 6240 size = MAX_PATH; 6241 lstrcpyA(path, "kiwi"); 6242 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6243 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6244 ok(!lstrcmpA(path, "kiwi"), 6245 "Expected path to be unchanged, got \"%s\"\n", path); 6246 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6247 6248 size = MAX_PATH; 6249 lstrcpyA(path, "kiwi"); 6250 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6252 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6253 ok(size == 0, "Expected 0, got %lu\n", size); 6254 6255 size = MAX_PATH; 6256 lstrcpyA(path, "kiwi"); 6257 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6258 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6259 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6260 ok(size == 0, "Expected 0, got %lu\n", size); 6261 6262 /* try SourceDir */ 6263 size = MAX_PATH; 6264 lstrcpyA(path, "kiwi"); 6265 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6266 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6267 ok(!lstrcmpA(path, "kiwi"), 6268 "Expected path to be unchanged, got \"%s\"\n", path); 6269 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6270 6271 /* try SOURCEDIR */ 6272 size = MAX_PATH; 6273 lstrcpyA(path, "kiwi"); 6274 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6275 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6276 ok(!lstrcmpA(path, "kiwi"), 6277 "Expected path to be unchanged, got \"%s\"\n", path); 6278 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6279 6280 /* source path does not exist, but the property exists */ 6281 size = MAX_PATH; 6282 lstrcpyA(path, "kiwi"); 6283 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6285 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6286 ok(size == 0, "Expected 0, got %lu\n", size); 6287 6288 size = MAX_PATH; 6289 lstrcpyA(path, "kiwi"); 6290 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6292 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6293 ok(size == 0, "Expected 0, got %lu\n", size); 6294 6295 /* try SubDir */ 6296 size = MAX_PATH; 6297 lstrcpyA(path, "kiwi"); 6298 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6299 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6300 ok(!lstrcmpA(path, "kiwi"), 6301 "Expected path to be unchanged, got \"%s\"\n", path); 6302 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6303 6304 /* try SubDir2 */ 6305 size = MAX_PATH; 6306 lstrcpyA(path, "kiwi"); 6307 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6308 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6309 ok(!lstrcmpA(path, "kiwi"), 6310 "Expected path to be unchanged, got \"%s\"\n", path); 6311 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6312 6313 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 6314 6315 r = MsiDoActionA(hpkg, "CostInitialize"); 6316 ok(r == ERROR_SUCCESS, "cost init failed\n"); 6317 6318 /* try TARGETDIR after CostInitialize */ 6319 size = MAX_PATH; 6320 lstrcpyA(path, "kiwi"); 6321 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6323 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6324 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6325 6326 /* try SourceDir after CostInitialize */ 6327 size = MAX_PATH; 6328 lstrcpyA(path, "kiwi"); 6329 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6331 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6332 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6333 6334 /* try SOURCEDIR after CostInitialize */ 6335 size = MAX_PATH; 6336 lstrcpyA(path, "kiwi"); 6337 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6338 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6339 ok(!lstrcmpA(path, "kiwi"), 6340 "Expected path to be unchanged, got \"%s\"\n", path); 6341 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6342 6343 /* source path does not exist, but the property exists */ 6344 size = MAX_PATH; 6345 lstrcpyA(path, "kiwi"); 6346 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6348 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6349 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6350 6351 size = MAX_PATH; 6352 lstrcpyA(path, "kiwi"); 6353 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6355 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6356 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6357 6358 /* try SubDir after CostInitialize */ 6359 size = MAX_PATH; 6360 lstrcpyA(path, "kiwi"); 6361 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6363 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6364 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6365 6366 /* try SubDir2 after CostInitialize */ 6367 size = MAX_PATH; 6368 lstrcpyA(path, "kiwi"); 6369 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6371 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); 6372 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size); 6373 6374 r = MsiDoActionA(hpkg, "ResolveSource"); 6375 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6376 6377 /* try TARGETDIR after ResolveSource */ 6378 size = MAX_PATH; 6379 lstrcpyA(path, "kiwi"); 6380 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6382 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6383 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6384 6385 /* try SourceDir after ResolveSource */ 6386 size = MAX_PATH; 6387 lstrcpyA(path, "kiwi"); 6388 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6390 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6391 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6392 6393 /* try SOURCEDIR after ResolveSource */ 6394 size = MAX_PATH; 6395 lstrcpyA(path, "kiwi"); 6396 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6397 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6398 ok(!lstrcmpA(path, "kiwi"), 6399 "Expected path to be unchanged, got \"%s\"\n", path); 6400 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6401 6402 /* source path does not exist, but the property exists */ 6403 size = MAX_PATH; 6404 lstrcpyA(path, "kiwi"); 6405 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6407 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6408 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6409 6410 size = MAX_PATH; 6411 lstrcpyA(path, "kiwi"); 6412 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6414 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6415 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6416 6417 /* try SubDir after ResolveSource */ 6418 size = MAX_PATH; 6419 lstrcpyA(path, "kiwi"); 6420 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6422 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6423 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6424 6425 /* try SubDir2 after ResolveSource */ 6426 size = MAX_PATH; 6427 lstrcpyA(path, "kiwi"); 6428 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6430 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); 6431 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size); 6432 6433 r = MsiDoActionA(hpkg, "FileCost"); 6434 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6435 6436 /* try TARGETDIR after FileCost */ 6437 size = MAX_PATH; 6438 lstrcpyA(path, "kiwi"); 6439 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6441 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6442 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6443 6444 /* try SourceDir after FileCost */ 6445 size = MAX_PATH; 6446 lstrcpyA(path, "kiwi"); 6447 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6449 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6450 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6451 6452 /* try SOURCEDIR after FileCost */ 6453 size = MAX_PATH; 6454 lstrcpyA(path, "kiwi"); 6455 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6456 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6457 ok(!lstrcmpA(path, "kiwi"), 6458 "Expected path to be unchanged, got \"%s\"\n", path); 6459 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6460 6461 /* source path does not exist, but the property exists */ 6462 size = MAX_PATH; 6463 lstrcpyA(path, "kiwi"); 6464 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6466 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6467 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6468 6469 size = MAX_PATH; 6470 lstrcpyA(path, "kiwi"); 6471 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6473 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6474 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6475 6476 /* try SubDir after FileCost */ 6477 size = MAX_PATH; 6478 lstrcpyA(path, "kiwi"); 6479 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6481 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6482 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6483 6484 /* try SubDir2 after FileCost */ 6485 size = MAX_PATH; 6486 lstrcpyA(path, "kiwi"); 6487 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6489 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); 6490 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size); 6491 6492 r = MsiDoActionA(hpkg, "CostFinalize"); 6493 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6494 6495 /* try TARGETDIR after CostFinalize */ 6496 size = MAX_PATH; 6497 lstrcpyA(path, "kiwi"); 6498 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6500 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6501 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6502 6503 /* try SourceDir after CostFinalize */ 6504 size = MAX_PATH; 6505 lstrcpyA(path, "kiwi"); 6506 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6507 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6508 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6509 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6510 6511 /* try SOURCEDIR after CostFinalize */ 6512 size = MAX_PATH; 6513 lstrcpyA(path, "kiwi"); 6514 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6515 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6516 ok(!lstrcmpA(path, "kiwi"), 6517 "Expected path to be unchanged, got \"%s\"\n", path); 6518 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6519 6520 /* source path does not exist, but the property exists */ 6521 size = MAX_PATH; 6522 lstrcpyA(path, "kiwi"); 6523 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6525 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6526 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6527 6528 size = MAX_PATH; 6529 lstrcpyA(path, "kiwi"); 6530 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6532 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6533 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6534 6535 /* try SubDir after CostFinalize */ 6536 size = MAX_PATH; 6537 lstrcpyA(path, "kiwi"); 6538 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6540 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6541 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6542 6543 /* try SubDir2 after CostFinalize */ 6544 size = MAX_PATH; 6545 lstrcpyA(path, "kiwi"); 6546 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6548 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); 6549 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size); 6550 6551 /* nonexistent directory */ 6552 size = MAX_PATH; 6553 lstrcpyA(path, "kiwi"); 6554 r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size); 6555 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6556 ok(!lstrcmpA(path, "kiwi"), 6557 "Expected path to be unchanged, got \"%s\"\n", path); 6558 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6559 6560 /* NULL szPathBuf */ 6561 size = MAX_PATH; 6562 r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size); 6563 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6564 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6565 6566 /* NULL pcchPathBuf */ 6567 lstrcpyA(path, "kiwi"); 6568 r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL); 6569 ok(r == ERROR_INVALID_PARAMETER, 6570 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 6571 ok(!lstrcmpA(path, "kiwi"), 6572 "Expected path to be unchanged, got \"%s\"\n", path); 6573 6574 /* pcchPathBuf is 0 */ 6575 size = 0; 6576 lstrcpyA(path, "kiwi"); 6577 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6578 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 6579 ok(!lstrcmpA(path, "kiwi"), 6580 "Expected path to be unchanged, got \"%s\"\n", path); 6581 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6582 6583 /* pcchPathBuf does not have room for NULL terminator */ 6584 size = lstrlenA(cwd); 6585 lstrcpyA(path, "kiwi"); 6586 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6587 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 6588 ok(!strncmp(path, cwd, lstrlenA(cwd) - 1), 6589 "Expected path with no backslash, got \"%s\"\n", path); 6590 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6591 6592 /* pcchPathBuf has room for NULL terminator */ 6593 size = lstrlenA(cwd) + 1; 6594 lstrcpyA(path, "kiwi"); 6595 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6597 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6598 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6599 6600 /* remove property */ 6601 r = MsiSetPropertyA(hpkg, "SourceDir", NULL); 6602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6603 6604 /* try SourceDir again */ 6605 size = MAX_PATH; 6606 lstrcpyA(path, "kiwi"); 6607 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6608 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6609 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6610 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6611 6612 /* set property to a valid directory */ 6613 r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd); 6614 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6615 6616 /* try SOURCEDIR again */ 6617 size = MAX_PATH; 6618 lstrcpyA(path, "kiwi"); 6619 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6620 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6621 ok(!lstrcmpA(path, "kiwi"), 6622 "Expected path to be unchanged, got \"%s\"\n", path); 6623 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6624 6625 MsiCloseHandle(hpkg); 6626 6627 /* compressed source */ 6628 6629 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 6630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6631 6632 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed); 6633 6634 r = package_from_db(hdb, &hpkg); 6635 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 6636 6637 /* try TARGETDIR */ 6638 size = MAX_PATH; 6639 lstrcpyA(path, "kiwi"); 6640 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6641 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6642 ok(!lstrcmpA(path, "kiwi"), 6643 "Expected path to be unchanged, got \"%s\"\n", path); 6644 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6645 6646 /* try SourceDir */ 6647 size = MAX_PATH; 6648 lstrcpyA(path, "kiwi"); 6649 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6650 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6651 ok(!lstrcmpA(path, "kiwi"), 6652 "Expected path to be unchanged, got \"%s\"\n", path); 6653 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6654 6655 /* try SOURCEDIR */ 6656 size = MAX_PATH; 6657 lstrcpyA(path, "kiwi"); 6658 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6659 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6660 ok(!lstrcmpA(path, "kiwi"), 6661 "Expected path to be unchanged, got \"%s\"\n", path); 6662 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6663 6664 /* source path nor the property exist */ 6665 size = MAX_PATH; 6666 lstrcpyA(path, "kiwi"); 6667 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6669 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6670 ok(size == 0, "Expected 0, got %lu\n", size); 6671 6672 size = MAX_PATH; 6673 lstrcpyA(path, "kiwi"); 6674 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6675 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6676 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6677 ok(size == 0, "Expected 0, got %lu\n", size); 6678 6679 /* try SubDir */ 6680 size = MAX_PATH; 6681 lstrcpyA(path, "kiwi"); 6682 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6683 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6684 ok(!lstrcmpA(path, "kiwi"), 6685 "Expected path to be unchanged, got \"%s\"\n", path); 6686 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6687 6688 /* try SubDir2 */ 6689 size = MAX_PATH; 6690 lstrcpyA(path, "kiwi"); 6691 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6692 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6693 ok(!lstrcmpA(path, "kiwi"), 6694 "Expected path to be unchanged, got \"%s\"\n", path); 6695 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6696 6697 r = MsiDoActionA(hpkg, "CostInitialize"); 6698 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6699 6700 /* try TARGETDIR after CostInitialize */ 6701 size = MAX_PATH; 6702 lstrcpyA(path, "kiwi"); 6703 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6704 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6705 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6706 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6707 6708 /* try SourceDir after CostInitialize */ 6709 size = MAX_PATH; 6710 lstrcpyA(path, "kiwi"); 6711 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6713 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6714 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6715 6716 /* try SOURCEDIR after CostInitialize */ 6717 size = MAX_PATH; 6718 lstrcpyA(path, "kiwi"); 6719 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6720 todo_wine 6721 { 6722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6723 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6724 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6725 } 6726 6727 /* source path does not exist, but the property exists */ 6728 size = MAX_PATH; 6729 lstrcpyA(path, "kiwi"); 6730 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6732 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6733 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6734 6735 size = MAX_PATH; 6736 lstrcpyA(path, "kiwi"); 6737 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6739 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6740 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6741 6742 /* try SubDir after CostInitialize */ 6743 size = MAX_PATH; 6744 lstrcpyA(path, "kiwi"); 6745 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6747 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6748 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6749 6750 /* try SubDir2 after CostInitialize */ 6751 size = MAX_PATH; 6752 lstrcpyA(path, "kiwi"); 6753 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6755 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6756 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6757 6758 r = MsiDoActionA(hpkg, "ResolveSource"); 6759 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6760 6761 /* try TARGETDIR after ResolveSource */ 6762 size = MAX_PATH; 6763 lstrcpyA(path, "kiwi"); 6764 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6766 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6767 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6768 6769 /* try SourceDir after ResolveSource */ 6770 size = MAX_PATH; 6771 lstrcpyA(path, "kiwi"); 6772 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6774 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6775 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6776 6777 /* try SOURCEDIR after ResolveSource */ 6778 size = MAX_PATH; 6779 lstrcpyA(path, "kiwi"); 6780 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6781 todo_wine 6782 { 6783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6784 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6785 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6786 } 6787 6788 /* source path and the property exist */ 6789 size = MAX_PATH; 6790 lstrcpyA(path, "kiwi"); 6791 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6793 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6794 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6795 6796 size = MAX_PATH; 6797 lstrcpyA(path, "kiwi"); 6798 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6800 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6801 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6802 6803 /* try SubDir after ResolveSource */ 6804 size = MAX_PATH; 6805 lstrcpyA(path, "kiwi"); 6806 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6808 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6809 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6810 6811 /* try SubDir2 after ResolveSource */ 6812 size = MAX_PATH; 6813 lstrcpyA(path, "kiwi"); 6814 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6816 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6817 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6818 6819 r = MsiDoActionA(hpkg, "FileCost"); 6820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6821 6822 /* try TARGETDIR after CostFinalize */ 6823 size = MAX_PATH; 6824 lstrcpyA(path, "kiwi"); 6825 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6827 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6828 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6829 6830 /* try SourceDir after CostFinalize */ 6831 size = MAX_PATH; 6832 lstrcpyA(path, "kiwi"); 6833 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6835 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6836 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6837 6838 /* try SOURCEDIR after CostFinalize */ 6839 size = MAX_PATH; 6840 lstrcpyA(path, "kiwi"); 6841 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6842 todo_wine 6843 { 6844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6845 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6846 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6847 } 6848 6849 /* source path and the property exist */ 6850 size = MAX_PATH; 6851 lstrcpyA(path, "kiwi"); 6852 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6854 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6855 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6856 6857 size = MAX_PATH; 6858 lstrcpyA(path, "kiwi"); 6859 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6861 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6862 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6863 6864 /* try SubDir after CostFinalize */ 6865 size = MAX_PATH; 6866 lstrcpyA(path, "kiwi"); 6867 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6869 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6870 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6871 6872 /* try SubDir2 after CostFinalize */ 6873 size = MAX_PATH; 6874 lstrcpyA(path, "kiwi"); 6875 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6877 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6878 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6879 6880 r = MsiDoActionA(hpkg, "CostFinalize"); 6881 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6882 6883 /* try TARGETDIR after CostFinalize */ 6884 size = MAX_PATH; 6885 lstrcpyA(path, "kiwi"); 6886 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6888 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6889 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6890 6891 /* try SourceDir after CostFinalize */ 6892 size = MAX_PATH; 6893 lstrcpyA(path, "kiwi"); 6894 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6896 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6897 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6898 6899 /* try SOURCEDIR after CostFinalize */ 6900 size = MAX_PATH; 6901 lstrcpyA(path, "kiwi"); 6902 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6903 todo_wine 6904 { 6905 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6906 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6907 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6908 } 6909 6910 /* source path and the property exist */ 6911 size = MAX_PATH; 6912 lstrcpyA(path, "kiwi"); 6913 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6914 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6915 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6916 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6917 6918 size = MAX_PATH; 6919 lstrcpyA(path, "kiwi"); 6920 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6922 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6923 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6924 6925 /* try SubDir after CostFinalize */ 6926 size = MAX_PATH; 6927 lstrcpyA(path, "kiwi"); 6928 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6930 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6931 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6932 6933 /* try SubDir2 after CostFinalize */ 6934 size = MAX_PATH; 6935 lstrcpyA(path, "kiwi"); 6936 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6938 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6939 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6940 6941 MsiCloseHandle(hpkg); 6942 DeleteFileA(msifile); 6943 } 6944 6945 static void test_shortlongsource(void) 6946 { 6947 MSIHANDLE hdb, hpkg; 6948 CHAR path[MAX_PATH]; 6949 CHAR cwd[MAX_PATH]; 6950 CHAR subsrc[MAX_PATH]; 6951 DWORD size; 6952 UINT r; 6953 6954 lstrcpyA(cwd, CURR_DIR); 6955 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\"); 6956 6957 lstrcpyA(subsrc, cwd); 6958 lstrcatA(subsrc, "long"); 6959 lstrcatA(subsrc, "\\"); 6960 6961 /* long file names */ 6962 6963 hdb = create_package_db(); 6964 ok( hdb, "failed to create database\n"); 6965 6966 set_suminfo_prop(hdb, PID_WORDCOUNT, 0); 6967 6968 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); 6969 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'"); 6970 6971 /* CostInitialize:short */ 6972 add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'"); 6973 6974 /* CostInitialize:long */ 6975 add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'"); 6976 6977 /* FileCost:short */ 6978 add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'"); 6979 6980 /* FileCost:long */ 6981 add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'"); 6982 6983 /* CostFinalize:short */ 6984 add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'"); 6985 6986 /* CostFinalize:long */ 6987 add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'"); 6988 6989 r = MsiDatabaseCommit(hdb); 6990 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 6991 6992 r = package_from_db(hdb, &hpkg); 6993 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 6994 { 6995 skip("Not enough rights to perform tests\n"); 6996 DeleteFileA(msifile); 6997 return; 6998 } 6999 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 7000 7001 MsiCloseHandle(hdb); 7002 7003 CreateDirectoryA("one", NULL); 7004 CreateDirectoryA("four", NULL); 7005 7006 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 7007 7008 r = MsiDoActionA(hpkg, "CostInitialize"); 7009 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7010 7011 CreateDirectoryA("five", NULL); 7012 CreateDirectoryA("eight", NULL); 7013 7014 r = MsiDoActionA(hpkg, "FileCost"); 7015 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7016 7017 CreateDirectoryA("nine", NULL); 7018 CreateDirectoryA("twelve", NULL); 7019 7020 r = MsiDoActionA(hpkg, "CostFinalize"); 7021 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7022 7023 /* neither short nor long source directories exist */ 7024 size = MAX_PATH; 7025 lstrcpyA(path, "kiwi"); 7026 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7027 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7028 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7029 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7030 7031 CreateDirectoryA("short", NULL); 7032 7033 /* short source directory exists */ 7034 size = MAX_PATH; 7035 lstrcpyA(path, "kiwi"); 7036 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7038 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7039 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7040 7041 CreateDirectoryA("long", NULL); 7042 7043 /* both short and long source directories exist */ 7044 size = MAX_PATH; 7045 lstrcpyA(path, "kiwi"); 7046 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7048 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7049 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7050 7051 lstrcpyA(subsrc, cwd); 7052 lstrcatA(subsrc, "two"); 7053 lstrcatA(subsrc, "\\"); 7054 7055 /* short dir exists before CostInitialize */ 7056 size = MAX_PATH; 7057 lstrcpyA(path, "kiwi"); 7058 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 7059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7060 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7061 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7062 7063 lstrcpyA(subsrc, cwd); 7064 lstrcatA(subsrc, "four"); 7065 lstrcatA(subsrc, "\\"); 7066 7067 /* long dir exists before CostInitialize */ 7068 size = MAX_PATH; 7069 lstrcpyA(path, "kiwi"); 7070 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size); 7071 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7072 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7073 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7074 7075 lstrcpyA(subsrc, cwd); 7076 lstrcatA(subsrc, "six"); 7077 lstrcatA(subsrc, "\\"); 7078 7079 /* short dir exists before FileCost */ 7080 size = MAX_PATH; 7081 lstrcpyA(path, "kiwi"); 7082 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size); 7083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7084 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7085 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7086 7087 lstrcpyA(subsrc, cwd); 7088 lstrcatA(subsrc, "eight"); 7089 lstrcatA(subsrc, "\\"); 7090 7091 /* long dir exists before FileCost */ 7092 size = MAX_PATH; 7093 lstrcpyA(path, "kiwi"); 7094 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size); 7095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7096 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7097 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7098 7099 lstrcpyA(subsrc, cwd); 7100 lstrcatA(subsrc, "ten"); 7101 lstrcatA(subsrc, "\\"); 7102 7103 /* short dir exists before CostFinalize */ 7104 size = MAX_PATH; 7105 lstrcpyA(path, "kiwi"); 7106 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size); 7107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7108 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7109 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7110 7111 lstrcpyA(subsrc, cwd); 7112 lstrcatA(subsrc, "twelve"); 7113 lstrcatA(subsrc, "\\"); 7114 7115 /* long dir exists before CostFinalize */ 7116 size = MAX_PATH; 7117 lstrcpyA(path, "kiwi"); 7118 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size); 7119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7120 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7121 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7122 7123 MsiCloseHandle(hpkg); 7124 RemoveDirectoryA("short"); 7125 RemoveDirectoryA("long"); 7126 RemoveDirectoryA("one"); 7127 RemoveDirectoryA("four"); 7128 RemoveDirectoryA("five"); 7129 RemoveDirectoryA("eight"); 7130 RemoveDirectoryA("nine"); 7131 RemoveDirectoryA("twelve"); 7132 7133 /* short file names */ 7134 7135 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 7136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7137 7138 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN); 7139 7140 r = package_from_db(hdb, &hpkg); 7141 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 7142 7143 MsiCloseHandle(hdb); 7144 7145 CreateDirectoryA("one", NULL); 7146 CreateDirectoryA("four", NULL); 7147 7148 r = MsiDoActionA(hpkg, "CostInitialize"); 7149 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7150 7151 CreateDirectoryA("five", NULL); 7152 CreateDirectoryA("eight", NULL); 7153 7154 r = MsiDoActionA(hpkg, "FileCost"); 7155 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7156 7157 CreateDirectoryA("nine", NULL); 7158 CreateDirectoryA("twelve", NULL); 7159 7160 r = MsiDoActionA(hpkg, "CostFinalize"); 7161 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7162 7163 lstrcpyA(subsrc, cwd); 7164 lstrcatA(subsrc, "short"); 7165 lstrcatA(subsrc, "\\"); 7166 7167 /* neither short nor long source directories exist */ 7168 size = MAX_PATH; 7169 lstrcpyA(path, "kiwi"); 7170 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7172 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7173 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7174 7175 CreateDirectoryA("short", NULL); 7176 7177 /* short source directory exists */ 7178 size = MAX_PATH; 7179 lstrcpyA(path, "kiwi"); 7180 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7182 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7183 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7184 7185 CreateDirectoryA("long", NULL); 7186 7187 /* both short and long source directories exist */ 7188 size = MAX_PATH; 7189 lstrcpyA(path, "kiwi"); 7190 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7192 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7193 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7194 7195 lstrcpyA(subsrc, cwd); 7196 lstrcatA(subsrc, "one"); 7197 lstrcatA(subsrc, "\\"); 7198 7199 /* short dir exists before CostInitialize */ 7200 size = MAX_PATH; 7201 lstrcpyA(path, "kiwi"); 7202 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 7203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7204 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7205 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7206 7207 lstrcpyA(subsrc, cwd); 7208 lstrcatA(subsrc, "three"); 7209 lstrcatA(subsrc, "\\"); 7210 7211 /* long dir exists before CostInitialize */ 7212 size = MAX_PATH; 7213 lstrcpyA(path, "kiwi"); 7214 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size); 7215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7216 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7217 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7218 7219 lstrcpyA(subsrc, cwd); 7220 lstrcatA(subsrc, "five"); 7221 lstrcatA(subsrc, "\\"); 7222 7223 /* short dir exists before FileCost */ 7224 size = MAX_PATH; 7225 lstrcpyA(path, "kiwi"); 7226 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size); 7227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7228 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7229 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7230 7231 lstrcpyA(subsrc, cwd); 7232 lstrcatA(subsrc, "seven"); 7233 lstrcatA(subsrc, "\\"); 7234 7235 /* long dir exists before FileCost */ 7236 size = MAX_PATH; 7237 lstrcpyA(path, "kiwi"); 7238 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size); 7239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7240 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7241 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7242 7243 lstrcpyA(subsrc, cwd); 7244 lstrcatA(subsrc, "nine"); 7245 lstrcatA(subsrc, "\\"); 7246 7247 /* short dir exists before CostFinalize */ 7248 size = MAX_PATH; 7249 lstrcpyA(path, "kiwi"); 7250 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size); 7251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7252 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7253 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7254 7255 lstrcpyA(subsrc, cwd); 7256 lstrcatA(subsrc, "eleven"); 7257 lstrcatA(subsrc, "\\"); 7258 7259 /* long dir exists before CostFinalize */ 7260 size = MAX_PATH; 7261 lstrcpyA(path, "kiwi"); 7262 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size); 7263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7264 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7265 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7266 7267 MsiCloseHandle(hpkg); 7268 RemoveDirectoryA("short"); 7269 RemoveDirectoryA("long"); 7270 RemoveDirectoryA("one"); 7271 RemoveDirectoryA("four"); 7272 RemoveDirectoryA("five"); 7273 RemoveDirectoryA("eight"); 7274 RemoveDirectoryA("nine"); 7275 RemoveDirectoryA("twelve"); 7276 DeleteFileA(msifile); 7277 } 7278 7279 static void test_sourcedir(void) 7280 { 7281 MSIHANDLE hdb, hpkg; 7282 CHAR package[12]; 7283 CHAR path[MAX_PATH]; 7284 CHAR cwd[MAX_PATH]; 7285 CHAR subsrc[MAX_PATH]; 7286 DWORD size; 7287 UINT r; 7288 7289 lstrcpyA(cwd, CURR_DIR); 7290 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\"); 7291 7292 lstrcpyA(subsrc, cwd); 7293 lstrcatA(subsrc, "long"); 7294 lstrcatA(subsrc, "\\"); 7295 7296 hdb = create_package_db(); 7297 ok( hdb, "failed to create database\n"); 7298 7299 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); 7300 7301 sprintf(package, "#%lu", hdb); 7302 r = MsiOpenPackageA(package, &hpkg); 7303 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 7304 { 7305 skip("Not enough rights to perform tests\n"); 7306 goto error; 7307 } 7308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7309 7310 /* properties only */ 7311 7312 /* SourceDir prop */ 7313 size = MAX_PATH; 7314 lstrcpyA(path, "kiwi"); 7315 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7317 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7318 ok(size == 0, "Expected 0, got %lu\n", size); 7319 7320 /* SOURCEDIR prop */ 7321 size = MAX_PATH; 7322 lstrcpyA(path, "kiwi"); 7323 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7325 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7326 ok(size == 0, "Expected 0, got %lu\n", size); 7327 7328 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 7329 7330 r = MsiDoActionA(hpkg, "CostInitialize"); 7331 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7332 7333 /* SourceDir after CostInitialize */ 7334 size = MAX_PATH; 7335 lstrcpyA(path, "kiwi"); 7336 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7338 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7339 ok(size == 0, "Expected 0, got %lu\n", size); 7340 7341 /* SOURCEDIR after CostInitialize */ 7342 size = MAX_PATH; 7343 lstrcpyA(path, "kiwi"); 7344 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7346 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7347 ok(size == 0, "Expected 0, got %lu\n", size); 7348 7349 r = MsiDoActionA(hpkg, "FileCost"); 7350 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7351 7352 /* SourceDir after FileCost */ 7353 size = MAX_PATH; 7354 lstrcpyA(path, "kiwi"); 7355 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7357 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7358 ok(size == 0, "Expected 0, got %lu\n", size); 7359 7360 /* SOURCEDIR after FileCost */ 7361 size = MAX_PATH; 7362 lstrcpyA(path, "kiwi"); 7363 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7365 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7366 ok(size == 0, "Expected 0, got %lu\n", size); 7367 7368 r = MsiDoActionA(hpkg, "CostFinalize"); 7369 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7370 7371 /* SourceDir after CostFinalize */ 7372 size = MAX_PATH; 7373 lstrcpyA(path, "kiwi"); 7374 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7376 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7377 ok(size == 0, "Expected 0, got %lu\n", size); 7378 7379 /* SOURCEDIR after CostFinalize */ 7380 size = MAX_PATH; 7381 lstrcpyA(path, "kiwi"); 7382 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7384 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7385 ok(size == 0, "Expected 0, got %lu\n", size); 7386 7387 size = MAX_PATH; 7388 lstrcpyA(path, "kiwi"); 7389 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7390 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7391 ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path); 7392 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size); 7393 7394 /* SOURCEDIR after calling MsiGetSourcePath */ 7395 size = MAX_PATH; 7396 lstrcpyA(path, "kiwi"); 7397 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7399 todo_wine { 7400 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7401 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7402 } 7403 7404 r = MsiDoActionA(hpkg, "ResolveSource"); 7405 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7406 7407 /* SourceDir after ResolveSource */ 7408 size = MAX_PATH; 7409 lstrcpyA(path, "kiwi"); 7410 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7412 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7413 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7414 7415 /* SOURCEDIR after ResolveSource */ 7416 size = MAX_PATH; 7417 lstrcpyA(path, "kiwi"); 7418 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7419 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7420 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7421 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7422 7423 /* random casing */ 7424 size = MAX_PATH; 7425 lstrcpyA(path, "kiwi"); 7426 r = MsiGetPropertyA(hpkg, "SoUrCeDiR", path, &size); 7427 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7428 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7429 ok(size == 0, "Expected 0, got %lu\n", size); 7430 7431 MsiCloseHandle(hpkg); 7432 7433 /* reset the package state */ 7434 sprintf(package, "#%lu", hdb); 7435 r = MsiOpenPackageA(package, &hpkg); 7436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7437 7438 /* test how MsiGetSourcePath affects the properties */ 7439 7440 /* SourceDir prop */ 7441 size = MAX_PATH; 7442 lstrcpyA(path, "kiwi"); 7443 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7444 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7445 todo_wine 7446 { 7447 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7448 ok(size == 0, "Expected 0, got %lu\n", size); 7449 } 7450 7451 size = MAX_PATH; 7452 lstrcpyA(path, "kiwi"); 7453 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 7454 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7455 ok(!lstrcmpA(path, "kiwi"), 7456 "Expected path to be unchanged, got \"%s\"\n", path); 7457 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7458 7459 /* SourceDir after MsiGetSourcePath */ 7460 size = MAX_PATH; 7461 lstrcpyA(path, "kiwi"); 7462 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7464 todo_wine 7465 { 7466 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7467 ok(size == 0, "Expected 0, got %lu\n", size); 7468 } 7469 7470 /* SOURCEDIR prop */ 7471 size = MAX_PATH; 7472 lstrcpyA(path, "kiwi"); 7473 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7475 todo_wine 7476 { 7477 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7478 ok(size == 0, "Expected 0, got %lu\n", size); 7479 } 7480 7481 size = MAX_PATH; 7482 lstrcpyA(path, "kiwi"); 7483 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7484 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7485 ok(!lstrcmpA(path, "kiwi"), 7486 "Expected path to be unchanged, got \"%s\"\n", path); 7487 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7488 7489 /* SOURCEDIR prop after MsiGetSourcePath */ 7490 size = MAX_PATH; 7491 lstrcpyA(path, "kiwi"); 7492 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7494 todo_wine 7495 { 7496 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7497 ok(size == 0, "Expected 0, got %lu\n", size); 7498 } 7499 7500 r = MsiDoActionA(hpkg, "CostInitialize"); 7501 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7502 7503 /* SourceDir after CostInitialize */ 7504 size = MAX_PATH; 7505 lstrcpyA(path, "kiwi"); 7506 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7507 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7508 todo_wine 7509 { 7510 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7511 ok(size == 0, "Expected 0, got %lu\n", size); 7512 } 7513 7514 size = MAX_PATH; 7515 lstrcpyA(path, "kiwi"); 7516 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 7517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7518 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7519 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7520 7521 /* SourceDir after MsiGetSourcePath */ 7522 size = MAX_PATH; 7523 lstrcpyA(path, "kiwi"); 7524 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7525 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7526 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7527 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7528 7529 /* SOURCEDIR after CostInitialize */ 7530 size = MAX_PATH; 7531 lstrcpyA(path, "kiwi"); 7532 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7534 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7535 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7536 7537 /* SOURCEDIR source path still does not exist */ 7538 size = MAX_PATH; 7539 lstrcpyA(path, "kiwi"); 7540 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7541 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7542 ok(!lstrcmpA(path, "kiwi"), 7543 "Expected path to be unchanged, got \"%s\"\n", path); 7544 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7545 7546 r = MsiDoActionA(hpkg, "FileCost"); 7547 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7548 7549 /* SourceDir after FileCost */ 7550 size = MAX_PATH; 7551 lstrcpyA(path, "kiwi"); 7552 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7554 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7555 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7556 7557 /* SOURCEDIR after FileCost */ 7558 size = MAX_PATH; 7559 lstrcpyA(path, "kiwi"); 7560 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7562 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7563 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7564 7565 /* SOURCEDIR source path still does not exist */ 7566 size = MAX_PATH; 7567 lstrcpyA(path, "kiwi"); 7568 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7569 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7570 ok(!lstrcmpA(path, "kiwi"), 7571 "Expected path to be unchanged, got \"%s\"\n", path); 7572 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7573 7574 r = MsiDoActionA(hpkg, "CostFinalize"); 7575 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7576 7577 /* SourceDir after CostFinalize */ 7578 size = MAX_PATH; 7579 lstrcpyA(path, "kiwi"); 7580 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7581 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7582 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7583 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7584 7585 /* SOURCEDIR after CostFinalize */ 7586 size = MAX_PATH; 7587 lstrcpyA(path, "kiwi"); 7588 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7589 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7590 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7591 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7592 7593 /* SOURCEDIR source path still does not exist */ 7594 size = MAX_PATH; 7595 lstrcpyA(path, "kiwi"); 7596 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7597 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7598 ok(!lstrcmpA(path, "kiwi"), 7599 "Expected path to be unchanged, got \"%s\"\n", path); 7600 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7601 7602 r = MsiDoActionA(hpkg, "ResolveSource"); 7603 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7604 7605 /* SourceDir after ResolveSource */ 7606 size = MAX_PATH; 7607 lstrcpyA(path, "kiwi"); 7608 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7610 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7611 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7612 7613 /* SOURCEDIR after ResolveSource */ 7614 size = MAX_PATH; 7615 lstrcpyA(path, "kiwi"); 7616 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7618 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7619 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7620 7621 /* SOURCEDIR source path still does not exist */ 7622 size = MAX_PATH; 7623 lstrcpyA(path, "kiwi"); 7624 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7625 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7626 ok(!lstrcmpA(path, "kiwi"), 7627 "Expected path to be unchanged, got \"%s\"\n", path); 7628 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7629 7630 MsiCloseHandle(hpkg); 7631 7632 error: 7633 MsiCloseHandle(hdb); 7634 DeleteFileA(msifile); 7635 } 7636 7637 struct access_res 7638 { 7639 BOOL gothandle; 7640 DWORD lasterr; 7641 BOOL ignore; 7642 }; 7643 7644 static const struct access_res create[16] = 7645 { 7646 { TRUE, ERROR_SUCCESS, TRUE }, 7647 { TRUE, ERROR_SUCCESS, TRUE }, 7648 { TRUE, ERROR_SUCCESS, FALSE }, 7649 { TRUE, ERROR_SUCCESS, FALSE }, 7650 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7651 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7652 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7653 { TRUE, ERROR_SUCCESS, FALSE }, 7654 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7655 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7656 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7657 { TRUE, ERROR_SUCCESS, TRUE }, 7658 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7659 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7660 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7661 { TRUE, ERROR_SUCCESS, TRUE } 7662 }; 7663 7664 static const struct access_res create_commit[16] = 7665 { 7666 { TRUE, ERROR_SUCCESS, TRUE }, 7667 { TRUE, ERROR_SUCCESS, TRUE }, 7668 { TRUE, ERROR_SUCCESS, FALSE }, 7669 { TRUE, ERROR_SUCCESS, FALSE }, 7670 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7671 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7672 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7673 { TRUE, ERROR_SUCCESS, FALSE }, 7674 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7675 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7676 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7677 { TRUE, ERROR_SUCCESS, TRUE }, 7678 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7679 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7680 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7681 { TRUE, ERROR_SUCCESS, TRUE } 7682 }; 7683 7684 static const struct access_res create_close[16] = 7685 { 7686 { TRUE, ERROR_SUCCESS, FALSE }, 7687 { TRUE, ERROR_SUCCESS, FALSE }, 7688 { TRUE, ERROR_SUCCESS, FALSE }, 7689 { TRUE, ERROR_SUCCESS, FALSE }, 7690 { TRUE, ERROR_SUCCESS, FALSE }, 7691 { TRUE, ERROR_SUCCESS, FALSE }, 7692 { TRUE, ERROR_SUCCESS, FALSE }, 7693 { TRUE, ERROR_SUCCESS, FALSE }, 7694 { TRUE, ERROR_SUCCESS, FALSE }, 7695 { TRUE, ERROR_SUCCESS, FALSE }, 7696 { TRUE, ERROR_SUCCESS, FALSE }, 7697 { TRUE, ERROR_SUCCESS, FALSE }, 7698 { TRUE, ERROR_SUCCESS, FALSE }, 7699 { TRUE, ERROR_SUCCESS, FALSE }, 7700 { TRUE, ERROR_SUCCESS, FALSE }, 7701 { TRUE, ERROR_SUCCESS } 7702 }; 7703 7704 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line) 7705 { 7706 DWORD access = 0, share = 0; 7707 DWORD lasterr; 7708 HANDLE hfile; 7709 int i, j, idx = 0; 7710 7711 for (i = 0; i < 4; i++) 7712 { 7713 if (i == 0) access = 0; 7714 if (i == 1) access = GENERIC_READ; 7715 if (i == 2) access = GENERIC_WRITE; 7716 if (i == 3) access = GENERIC_READ | GENERIC_WRITE; 7717 7718 for (j = 0; j < 4; j++) 7719 { 7720 if (ares[idx].ignore) 7721 continue; 7722 7723 if (j == 0) share = 0; 7724 if (j == 1) share = FILE_SHARE_READ; 7725 if (j == 2) share = FILE_SHARE_WRITE; 7726 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE; 7727 7728 SetLastError(0xdeadbeef); 7729 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING, 7730 FILE_ATTRIBUTE_NORMAL, 0); 7731 lasterr = GetLastError(); 7732 7733 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle, 7734 "(%lu, handle, %d): Expected %d, got %d\n", 7735 line, idx, ares[idx].gothandle, 7736 (hfile != INVALID_HANDLE_VALUE)); 7737 7738 ok(lasterr == ares[idx].lasterr, "(%lu, lasterr, %u): Expected %lu, got %lu\n", 7739 line, idx, ares[idx].lasterr, lasterr); 7740 7741 CloseHandle(hfile); 7742 idx++; 7743 } 7744 } 7745 } 7746 7747 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__) 7748 7749 static void test_access(void) 7750 { 7751 MSIHANDLE hdb; 7752 UINT r; 7753 7754 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7756 7757 test_file_access(msifile, create); 7758 7759 r = MsiDatabaseCommit(hdb); 7760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7761 7762 test_file_access(msifile, create_commit); 7763 MsiCloseHandle(hdb); 7764 7765 test_file_access(msifile, create_close); 7766 DeleteFileA(msifile); 7767 7768 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb); 7769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7770 7771 test_file_access(msifile, create); 7772 7773 r = MsiDatabaseCommit(hdb); 7774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7775 7776 test_file_access(msifile, create_commit); 7777 MsiCloseHandle(hdb); 7778 7779 test_file_access(msifile, create_close); 7780 DeleteFileA(msifile); 7781 } 7782 7783 static void test_emptypackage(void) 7784 { 7785 MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0; 7786 MSIHANDLE hview = 0, hrec = 0; 7787 MSICONDITION condition; 7788 CHAR buffer[MAX_PATH]; 7789 DWORD size; 7790 UINT r; 7791 7792 r = MsiOpenPackageA("", &hpkg); 7793 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 7794 { 7795 skip("Not enough rights to perform tests\n"); 7796 return; 7797 } 7798 todo_wine 7799 { 7800 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7801 } 7802 7803 hdb = MsiGetActiveDatabase(hpkg); 7804 todo_wine 7805 { 7806 ok(hdb != 0, "Expected a valid database handle\n"); 7807 } 7808 7809 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview); 7810 todo_wine 7811 { 7812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7813 } 7814 r = MsiViewExecute(hview, 0); 7815 todo_wine 7816 { 7817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7818 } 7819 7820 r = MsiViewFetch(hview, &hrec); 7821 todo_wine 7822 { 7823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7824 } 7825 7826 buffer[0] = 0; 7827 size = MAX_PATH; 7828 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7829 todo_wine 7830 { 7831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7832 ok(!lstrcmpA(buffer, "_Property"), 7833 "Expected \"_Property\", got \"%s\"\n", buffer); 7834 } 7835 7836 MsiCloseHandle(hrec); 7837 7838 r = MsiViewFetch(hview, &hrec); 7839 todo_wine 7840 { 7841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7842 } 7843 7844 size = MAX_PATH; 7845 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7846 todo_wine 7847 { 7848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7849 ok(!lstrcmpA(buffer, "#_FolderCache"), 7850 "Expected \"_Property\", got \"%s\"\n", buffer); 7851 } 7852 7853 MsiCloseHandle(hrec); 7854 MsiViewClose(hview); 7855 MsiCloseHandle(hview); 7856 7857 condition = MsiDatabaseIsTablePersistentA(hdb, "_Property"); 7858 todo_wine 7859 { 7860 ok(condition == MSICONDITION_FALSE, 7861 "Expected MSICONDITION_FALSE, got %d\n", condition); 7862 } 7863 7864 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview); 7865 todo_wine 7866 { 7867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7868 } 7869 r = MsiViewExecute(hview, 0); 7870 todo_wine 7871 { 7872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7873 } 7874 7875 /* _Property table is not empty */ 7876 r = MsiViewFetch(hview, &hrec); 7877 todo_wine 7878 { 7879 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7880 } 7881 7882 MsiCloseHandle(hrec); 7883 MsiViewClose(hview); 7884 MsiCloseHandle(hview); 7885 7886 condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache"); 7887 todo_wine 7888 { 7889 ok(condition == MSICONDITION_FALSE, 7890 "Expected MSICONDITION_FALSE, got %d\n", condition); 7891 } 7892 7893 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview); 7894 todo_wine 7895 { 7896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7897 } 7898 r = MsiViewExecute(hview, 0); 7899 todo_wine 7900 { 7901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7902 } 7903 7904 /* #_FolderCache is not empty */ 7905 r = MsiViewFetch(hview, &hrec); 7906 todo_wine 7907 { 7908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7909 } 7910 7911 MsiCloseHandle(hrec); 7912 MsiViewClose(hview); 7913 MsiCloseHandle(hview); 7914 7915 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview); 7916 todo_wine 7917 { 7918 ok(r == ERROR_BAD_QUERY_SYNTAX, 7919 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7920 } 7921 7922 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview); 7923 todo_wine 7924 { 7925 ok(r == ERROR_BAD_QUERY_SYNTAX, 7926 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7927 } 7928 7929 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo); 7930 todo_wine 7931 { 7932 ok(r == ERROR_INSTALL_PACKAGE_INVALID, 7933 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r); 7934 } 7935 7936 MsiCloseHandle(hsuminfo); 7937 7938 r = MsiDatabaseCommit(hdb); 7939 todo_wine 7940 { 7941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7942 } 7943 7944 MsiCloseHandle(hdb); 7945 MsiCloseHandle(hpkg); 7946 } 7947 7948 static void test_MsiGetProductProperty(void) 7949 { 7950 WCHAR valW[MAX_PATH]; 7951 MSIHANDLE hprod, hdb; 7952 CHAR val[MAX_PATH]; 7953 CHAR path[MAX_PATH]; 7954 CHAR query[MAX_PATH + 17]; 7955 CHAR keypath[MAX_PATH*2]; 7956 CHAR prodcode[MAX_PATH]; 7957 WCHAR prodcodeW[MAX_PATH]; 7958 CHAR prod_squashed[MAX_PATH]; 7959 WCHAR prod_squashedW[MAX_PATH]; 7960 HKEY prodkey, userkey, props; 7961 DWORD size; 7962 LONG res; 7963 UINT r; 7964 REGSAM access = KEY_ALL_ACCESS; 7965 7966 GetCurrentDirectoryA(MAX_PATH, path); 7967 lstrcatA(path, "\\"); 7968 7969 create_test_guid(prodcode, prod_squashed); 7970 MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH); 7971 squash_guid(prodcodeW, prod_squashedW); 7972 7973 if (is_wow64) 7974 access |= KEY_WOW64_64KEY; 7975 7976 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7977 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7978 7979 r = MsiDatabaseCommit(hdb); 7980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7981 7982 r = set_summary_info(hdb); 7983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7984 7985 r = run_query(hdb, 7986 "CREATE TABLE `Directory` ( " 7987 "`Directory` CHAR(255) NOT NULL, " 7988 "`Directory_Parent` CHAR(255), " 7989 "`DefaultDir` CHAR(255) NOT NULL " 7990 "PRIMARY KEY `Directory`)"); 7991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7992 7993 create_property_table(hdb); 7994 7995 sprintf(query, "'ProductCode', '%s'", prodcode); 7996 r = add_property_entry(hdb, query); 7997 7998 r = MsiDatabaseCommit(hdb); 7999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8000 8001 MsiCloseHandle(hdb); 8002 8003 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); 8004 lstrcatA(keypath, prod_squashed); 8005 8006 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); 8007 if (res == ERROR_ACCESS_DENIED) 8008 { 8009 skip("Not enough rights to perform tests\n"); 8010 DeleteFileA(msifile); 8011 return; 8012 } 8013 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 8014 8015 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\"); 8016 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\"); 8017 lstrcatA(keypath, prod_squashed); 8018 8019 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); 8020 if (res == ERROR_ACCESS_DENIED) 8021 { 8022 skip("Not enough rights to perform tests\n"); 8023 RegDeleteKeyA(prodkey, ""); 8024 RegCloseKey(prodkey); 8025 return; 8026 } 8027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 8028 8029 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); 8030 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 8031 8032 lstrcpyA(val, path); 8033 lstrcatA(val, "\\"); 8034 lstrcatA(val, msifile); 8035 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, 8036 (const BYTE *)val, lstrlenA(val) + 1); 8037 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 8038 8039 hprod = 0xdeadbeef; 8040 r = MsiOpenProductA(prodcode, &hprod); 8041 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8042 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n"); 8043 8044 /* hProduct is invalid */ 8045 size = MAX_PATH; 8046 lstrcpyA(val, "apple"); 8047 r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size); 8048 ok(r == ERROR_INVALID_HANDLE, 8049 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8050 ok(!lstrcmpA(val, "apple"), 8051 "Expected val to be unchanged, got \"%s\"\n", val); 8052 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 8053 8054 size = MAX_PATH; 8055 lstrcpyW(valW, L"apple"); 8056 r = MsiGetProductPropertyW(0xdeadbeef, L"ProductCode", valW, &size); 8057 ok(r == ERROR_INVALID_HANDLE, 8058 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8059 ok(!lstrcmpW(valW, L"apple"), 8060 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); 8061 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 8062 8063 /* szProperty is NULL */ 8064 size = MAX_PATH; 8065 lstrcpyA(val, "apple"); 8066 r = MsiGetProductPropertyA(hprod, NULL, val, &size); 8067 ok(r == ERROR_INVALID_PARAMETER, 8068 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8069 ok(!lstrcmpA(val, "apple"), 8070 "Expected val to be unchanged, got \"%s\"\n", val); 8071 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 8072 8073 size = MAX_PATH; 8074 lstrcpyW(valW, L"apple"); 8075 r = MsiGetProductPropertyW(hprod, NULL, valW, &size); 8076 ok(r == ERROR_INVALID_PARAMETER, 8077 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8078 ok(!lstrcmpW(valW, L"apple"), 8079 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); 8080 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 8081 8082 /* szProperty is empty */ 8083 size = MAX_PATH; 8084 lstrcpyA(val, "apple"); 8085 r = MsiGetProductPropertyA(hprod, "", val, &size); 8086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8087 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); 8088 ok(size == 0, "Expected 0, got %lu\n", size); 8089 8090 size = MAX_PATH; 8091 lstrcpyW(valW, L"apple"); 8092 r = MsiGetProductPropertyW(hprod, L"", valW, &size); 8093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8094 ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW)); 8095 ok(size == 0, "Expected 0, got %lu\n", size); 8096 8097 /* get the property */ 8098 size = MAX_PATH; 8099 lstrcpyA(val, "apple"); 8100 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8102 ok(!lstrcmpA(val, prodcode), 8103 "Expected \"%s\", got \"%s\"\n", prodcode, val); 8104 ok(size == lstrlenA(prodcode), 8105 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8106 8107 size = MAX_PATH; 8108 lstrcpyW(valW, L"apple"); 8109 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8111 ok(!lstrcmpW(valW, prodcodeW), 8112 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8113 ok(size == lstrlenW(prodcodeW), 8114 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8115 8116 /* lpValueBuf is NULL */ 8117 size = MAX_PATH; 8118 r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size); 8119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8120 ok(size == lstrlenA(prodcode), 8121 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8122 8123 size = MAX_PATH; 8124 r = MsiGetProductPropertyW(hprod, L"ProductCode", NULL, &size); 8125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8126 ok(size == lstrlenW(prodcodeW), 8127 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8128 8129 /* pcchValueBuf is NULL */ 8130 lstrcpyA(val, "apple"); 8131 r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL); 8132 ok(r == ERROR_INVALID_PARAMETER, 8133 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8134 ok(!lstrcmpA(val, "apple"), 8135 "Expected val to be unchanged, got \"%s\"\n", val); 8136 ok(size == lstrlenA(prodcode), 8137 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8138 8139 lstrcpyW(valW, L"apple"); 8140 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, NULL); 8141 ok(r == ERROR_INVALID_PARAMETER, 8142 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8143 ok(!lstrcmpW(valW, L"apple"), 8144 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); 8145 ok(size == lstrlenW(prodcodeW), 8146 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8147 8148 /* pcchValueBuf is too small */ 8149 size = 4; 8150 lstrcpyA(val, "apple"); 8151 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8152 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 8153 ok(!strncmp(val, prodcode, 3), 8154 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val); 8155 ok(size == lstrlenA(prodcode), 8156 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8157 8158 size = 4; 8159 lstrcpyW(valW, L"apple"); 8160 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8161 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 8162 ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)), 8163 "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8164 ok(size == lstrlenW(prodcodeW), 8165 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8166 8167 /* pcchValueBuf does not leave room for NULL terminator */ 8168 size = lstrlenA(prodcode); 8169 lstrcpyA(val, "apple"); 8170 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8171 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 8172 ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1), 8173 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val); 8174 ok(size == lstrlenA(prodcode), 8175 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8176 8177 size = lstrlenW(prodcodeW); 8178 lstrcpyW(valW, L"apple"); 8179 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8180 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 8181 ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1), 8182 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8183 ok(size == lstrlenW(prodcodeW), 8184 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8185 8186 /* pcchValueBuf has enough room for NULL terminator */ 8187 size = lstrlenA(prodcode) + 1; 8188 lstrcpyA(val, "apple"); 8189 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8191 ok(!lstrcmpA(val, prodcode), 8192 "Expected \"%s\", got \"%s\"\n", prodcode, val); 8193 ok(size == lstrlenA(prodcode), 8194 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8195 8196 size = lstrlenW(prodcodeW) + 1; 8197 lstrcpyW(valW, L"apple"); 8198 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8199 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8200 ok(!lstrcmpW(valW, prodcodeW), 8201 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8202 ok(size == lstrlenW(prodcodeW), 8203 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8204 8205 /* nonexistent property */ 8206 size = MAX_PATH; 8207 lstrcpyA(val, "apple"); 8208 r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size); 8209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8210 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); 8211 ok(size == 0, "Expected 0, got %lu\n", size); 8212 8213 size = MAX_PATH; 8214 lstrcpyW(valW, L"apple"); 8215 r = MsiGetProductPropertyW(hprod, L"IDontExist", valW, &size); 8216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8217 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW)); 8218 ok(size == 0, "Expected 0, got %lu\n", size); 8219 8220 r = MsiSetPropertyA(hprod, "NewProperty", "value"); 8221 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8222 8223 /* non-product property set */ 8224 size = MAX_PATH; 8225 lstrcpyA(val, "apple"); 8226 r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size); 8227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8228 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); 8229 ok(size == 0, "Expected 0, got %lu\n", size); 8230 8231 size = MAX_PATH; 8232 lstrcpyW(valW, L"apple"); 8233 r = MsiGetProductPropertyW(hprod, L"NewProperty", valW, &size); 8234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8235 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW)); 8236 ok(size == 0, "Expected 0, got %lu\n", size); 8237 8238 r = MsiSetPropertyA(hprod, "ProductCode", "value"); 8239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8240 8241 /* non-product property that is also a product property set */ 8242 size = MAX_PATH; 8243 lstrcpyA(val, "apple"); 8244 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8246 ok(!lstrcmpA(val, prodcode), 8247 "Expected \"%s\", got \"%s\"\n", prodcode, val); 8248 ok(size == lstrlenA(prodcode), 8249 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8250 8251 size = MAX_PATH; 8252 lstrcpyW(valW, L"apple"); 8253 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8255 ok(!lstrcmpW(valW, prodcodeW), 8256 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8257 ok(size == lstrlenW(prodcodeW), 8258 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8259 8260 MsiCloseHandle(hprod); 8261 8262 RegDeleteValueA(props, "LocalPackage"); 8263 delete_key(props, "", access); 8264 RegCloseKey(props); 8265 delete_key(userkey, "", access); 8266 RegCloseKey(userkey); 8267 delete_key(prodkey, "", access); 8268 RegCloseKey(prodkey); 8269 DeleteFileA(msifile); 8270 } 8271 8272 static void test_MsiSetProperty(void) 8273 { 8274 MSIHANDLE hpkg, hdb, hrec; 8275 CHAR buf[MAX_PATH]; 8276 LPCSTR query; 8277 DWORD size; 8278 UINT r; 8279 8280 r = package_from_db(create_package_db(), &hpkg); 8281 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 8282 { 8283 skip("Not enough rights to perform tests\n"); 8284 DeleteFileA(msifile); 8285 return; 8286 } 8287 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r); 8288 8289 /* invalid hInstall */ 8290 r = MsiSetPropertyA(0, "Prop", "Val"); 8291 ok(r == ERROR_INVALID_HANDLE, 8292 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8293 8294 /* invalid hInstall */ 8295 r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val"); 8296 ok(r == ERROR_INVALID_HANDLE, 8297 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8298 8299 /* szName is NULL */ 8300 r = MsiSetPropertyA(hpkg, NULL, "Val"); 8301 ok(r == ERROR_INVALID_PARAMETER, 8302 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8303 8304 /* both szName and szValue are NULL */ 8305 r = MsiSetPropertyA(hpkg, NULL, NULL); 8306 ok(r == ERROR_INVALID_PARAMETER, 8307 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8308 8309 /* szName is empty */ 8310 r = MsiSetPropertyA(hpkg, "", "Val"); 8311 ok(r == ERROR_FUNCTION_FAILED, 8312 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8313 8314 /* szName is empty and szValue is NULL */ 8315 r = MsiSetPropertyA(hpkg, "", NULL); 8316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8317 8318 /* set a property */ 8319 r = MsiSetPropertyA(hpkg, "Prop", "Val"); 8320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8321 8322 /* get the property */ 8323 size = MAX_PATH; 8324 r = MsiGetPropertyA(hpkg, "Prop", buf, &size); 8325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8326 ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf); 8327 ok(size == 3, "Expected 3, got %lu\n", size); 8328 8329 /* update the property */ 8330 r = MsiSetPropertyA(hpkg, "Prop", "Nuvo"); 8331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8332 8333 /* get the property */ 8334 size = MAX_PATH; 8335 r = MsiGetPropertyA(hpkg, "Prop", buf, &size); 8336 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8337 ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf); 8338 ok(size == 4, "Expected 4, got %lu\n", size); 8339 8340 hdb = MsiGetActiveDatabase(hpkg); 8341 ok(hdb != 0, "Expected a valid database handle\n"); 8342 8343 /* set prop is not in the _Property table */ 8344 query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'"; 8345 r = do_query(hdb, query, &hrec); 8346 ok(r == ERROR_BAD_QUERY_SYNTAX, 8347 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8348 8349 /* set prop is not in the Property table */ 8350 query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'"; 8351 r = do_query(hdb, query, &hrec); 8352 ok(r == ERROR_BAD_QUERY_SYNTAX, 8353 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8354 8355 MsiCloseHandle(hdb); 8356 8357 /* szValue is an empty string */ 8358 r = MsiSetPropertyA(hpkg, "Prop", ""); 8359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8360 8361 /* try to get the property */ 8362 size = MAX_PATH; 8363 r = MsiGetPropertyA(hpkg, "Prop", buf, &size); 8364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8365 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 8366 ok(size == 0, "Expected 0, got %lu\n", size); 8367 8368 /* reset the property */ 8369 r = MsiSetPropertyA(hpkg, "Prop", "BlueTap"); 8370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8371 8372 /* delete the property */ 8373 r = MsiSetPropertyA(hpkg, "Prop", NULL); 8374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8375 8376 /* try to get the property */ 8377 size = MAX_PATH; 8378 r = MsiGetPropertyA(hpkg, "Prop", buf, &size); 8379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8380 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 8381 ok(size == 0, "Expected 0, got %lu\n", size); 8382 8383 MsiCloseHandle(hpkg); 8384 DeleteFileA(msifile); 8385 } 8386 8387 static void test_MsiApplyMultiplePatches(void) 8388 { 8389 UINT r, type = GetDriveTypeW(NULL); 8390 8391 r = MsiApplyMultiplePatchesA(NULL, NULL, NULL); 8392 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); 8393 8394 r = MsiApplyMultiplePatchesA("", NULL, NULL); 8395 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); 8396 8397 r = MsiApplyMultiplePatchesA(";", NULL, NULL); 8398 if (type == DRIVE_FIXED) 8399 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); 8400 else 8401 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); 8402 8403 r = MsiApplyMultiplePatchesA(" ;", NULL, NULL); 8404 if (type == DRIVE_FIXED) 8405 todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r); 8406 else 8407 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); 8408 8409 r = MsiApplyMultiplePatchesA(";;", NULL, NULL); 8410 if (type == DRIVE_FIXED) 8411 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); 8412 else 8413 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); 8414 8415 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL); 8416 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); 8417 8418 r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL); 8419 if (type == DRIVE_FIXED) 8420 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); 8421 else 8422 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); 8423 8424 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL); 8425 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); 8426 8427 r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL); 8428 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); 8429 } 8430 8431 static void test_MsiApplyPatch(void) 8432 { 8433 UINT r; 8434 8435 r = MsiApplyPatchA(NULL, NULL, INSTALLTYPE_DEFAULT, NULL); 8436 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); 8437 8438 r = MsiApplyPatchA("", NULL, INSTALLTYPE_DEFAULT, NULL); 8439 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); 8440 } 8441 8442 static void test_costs(void) 8443 { 8444 MSIHANDLE hdb, hpkg; 8445 char package[12], drive[3]; 8446 DWORD len; 8447 UINT r; 8448 int cost, temp; 8449 8450 hdb = create_package_db(); 8451 ok( hdb, "failed to create database\n" ); 8452 8453 create_property_table( hdb ); 8454 add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" ); 8455 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); 8456 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); 8457 8458 create_media_table( hdb ); 8459 add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''"); 8460 8461 create_file_table( hdb ); 8462 add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" ); 8463 8464 create_component_table( hdb ); 8465 add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" ); 8466 add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" ); 8467 8468 create_feature_table( hdb ); 8469 add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" ); 8470 add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" ); 8471 8472 create_feature_components_table( hdb ); 8473 add_feature_components_entry( hdb, "'one', 'one'" ); 8474 add_feature_components_entry( hdb, "'two', 'two'" ); 8475 8476 create_install_execute_sequence_table( hdb ); 8477 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); 8478 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); 8479 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); 8480 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" ); 8481 8482 r = MsiDatabaseCommit( hdb ); 8483 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8484 8485 sprintf( package, "#%lu", hdb ); 8486 r = MsiOpenPackageA( package, &hpkg ); 8487 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 8488 { 8489 skip("Not enough rights to perform tests\n"); 8490 goto error; 8491 } 8492 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8493 8494 r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8495 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8496 8497 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8498 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8499 8500 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8501 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8502 8503 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8504 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8505 8506 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8507 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8508 8509 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL ); 8510 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8511 8512 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL ); 8513 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8514 8515 len = sizeof(drive); 8516 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL ); 8517 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8518 8519 len = sizeof(drive); 8520 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL ); 8521 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8522 8523 len = sizeof(drive); 8524 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8525 todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r ); 8526 8527 len = sizeof(drive); 8528 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp ); 8529 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8530 8531 MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL ); 8532 8533 r = MsiDoActionA( hpkg, "CostInitialize" ); 8534 ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r ); 8535 8536 r = MsiDoActionA( hpkg, "FileCost" ); 8537 ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r ); 8538 8539 len = sizeof(drive); 8540 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8541 ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r ); 8542 8543 r = MsiDoActionA( hpkg, "CostFinalize" ); 8544 ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r ); 8545 8546 /* contrary to what msdn says InstallValidate must be called too */ 8547 len = sizeof(drive); 8548 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8549 todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r ); 8550 8551 r = MsiDoActionA( hpkg, "InstallValidate" ); 8552 ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r ); 8553 8554 len = 0; 8555 r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8556 ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r ); 8557 8558 len = 0; 8559 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8560 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); 8561 ok( len == 2, "expected len == 2, got %lu\n", len ); 8562 8563 len = 2; 8564 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8565 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); 8566 ok( len == 2, "expected len == 2, got %lu\n", len ); 8567 8568 len = 2; 8569 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); 8570 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); 8571 ok( len == 2, "expected len == 2, got %lu\n", len ); 8572 8573 /* install state doesn't seem to matter */ 8574 len = sizeof(drive); 8575 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); 8576 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8577 8578 len = sizeof(drive); 8579 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp ); 8580 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8581 8582 len = sizeof(drive); 8583 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp ); 8584 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8585 8586 len = sizeof(drive); 8587 drive[0] = 0; 8588 cost = temp = 0xdead; 8589 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8590 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8591 ok( len == 2, "expected len == 2, got %lu\n", len ); 8592 ok( drive[0], "expected a drive\n" ); 8593 ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost ); 8594 ok( !temp, "expected temp == 0, got %d\n", temp ); 8595 8596 len = sizeof(drive); 8597 drive[0] = 0; 8598 cost = temp = 0xdead; 8599 r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8600 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8601 ok( len == 2, "expected len == 2, got %lu\n", len ); 8602 ok( drive[0], "expected a drive\n" ); 8603 ok( !cost, "expected cost == 0, got %d\n", cost ); 8604 ok( !temp, "expected temp == 0, got %d\n", temp ); 8605 8606 len = sizeof(drive); 8607 drive[0] = 0; 8608 cost = temp = 0xdead; 8609 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); 8610 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8611 ok( len == 2, "expected len == 2, got %lu\n", len ); 8612 ok( drive[0], "expected a drive\n" ); 8613 ok( !cost, "expected cost == 0, got %d\n", cost ); 8614 ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp ); 8615 8616 /* increased index */ 8617 len = sizeof(drive); 8618 r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8619 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r ); 8620 8621 len = sizeof(drive); 8622 r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); 8623 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r ); 8624 8625 /* test MsiGetFeatureCost */ 8626 cost = 0xdead; 8627 r = MsiGetFeatureCostA( hpkg, NULL, MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost ); 8628 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r); 8629 ok( cost == 0xdead, "got %d\n", cost ); 8630 8631 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, NULL ); 8632 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r); 8633 8634 cost = 0xdead; 8635 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost ); 8636 ok( !r, "got %u\n", r); 8637 ok( cost == 8, "got %d\n", cost ); 8638 8639 MsiCloseHandle( hpkg ); 8640 error: 8641 MsiCloseHandle( hdb ); 8642 DeleteFileA( msifile ); 8643 } 8644 8645 static void test_MsiDatabaseCommit(void) 8646 { 8647 UINT r; 8648 MSIHANDLE hdb, hpkg = 0; 8649 char buf[32], package[12]; 8650 DWORD sz; 8651 8652 hdb = create_package_db(); 8653 ok( hdb, "failed to create database\n" ); 8654 8655 create_property_table( hdb ); 8656 8657 sprintf( package, "#%lu", hdb ); 8658 r = MsiOpenPackageA( package, &hpkg ); 8659 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 8660 { 8661 skip("Not enough rights to perform tests\n"); 8662 goto error; 8663 } 8664 ok( r == ERROR_SUCCESS, "got %u\n", r ); 8665 8666 r = MsiSetPropertyA( hpkg, "PROP", "value" ); 8667 ok( r == ERROR_SUCCESS, "got %u\n", r ); 8668 8669 buf[0] = 0; 8670 sz = sizeof(buf); 8671 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz ); 8672 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r ); 8673 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf ); 8674 8675 r = MsiDatabaseCommit( hdb ); 8676 ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r ); 8677 8678 buf[0] = 0; 8679 sz = sizeof(buf); 8680 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz ); 8681 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r ); 8682 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf ); 8683 8684 MsiCloseHandle( hpkg ); 8685 error: 8686 MsiCloseHandle( hdb ); 8687 DeleteFileA( msifile ); 8688 } 8689 8690 static int externalui_ran; 8691 8692 static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message) 8693 { 8694 externalui_ran = 1; 8695 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type); 8696 return 0; 8697 } 8698 8699 static int externalui_record_ran; 8700 8701 static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord) 8702 { 8703 INT retval = context ? *((INT *)context) : 0; 8704 UINT r; 8705 externalui_record_ran = 1; 8706 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type); 8707 r = MsiRecordGetFieldCount(hrecord); 8708 ok(r == 1, "expected 1, got %u\n", r); 8709 r = MsiRecordGetInteger(hrecord, 1); 8710 ok(r == 12345, "expected 12345, got %u\n", r); 8711 return retval; 8712 } 8713 8714 static void test_externalui(void) 8715 { 8716 /* test that external UI handlers work correctly */ 8717 8718 INSTALLUI_HANDLERA prev; 8719 INSTALLUI_HANDLER_RECORD prev_record; 8720 MSIHANDLE hpkg, hrecord; 8721 UINT r; 8722 INT retval = 0; 8723 8724 prev = MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL); 8725 8726 r = package_from_db(create_package_db(), &hpkg); 8727 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 8728 { 8729 skip("Not enough rights to perform tests\n"); 8730 DeleteFileA(msifile); 8731 return; 8732 } 8733 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r); 8734 8735 hrecord = MsiCreateRecord(1); 8736 ok(hrecord, "Expected a valid record\n"); 8737 r = MsiRecordSetStringA(hrecord, 0, "test message [1]"); 8738 ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r); 8739 r = MsiRecordSetInteger(hrecord, 1, 12345); 8740 ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r); 8741 8742 externalui_ran = 0; 8743 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8744 ok(r == 0, "expected 0, got %u\n", r); 8745 ok(externalui_ran == 1, "external UI callback did not run\n"); 8746 8747 prev = MsiSetExternalUIA(prev, 0, NULL); 8748 ok(prev == externalui_callback, "wrong callback function %p\n", prev); 8749 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_USER, &retval, &prev_record); 8750 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r); 8751 8752 externalui_ran = externalui_record_ran = 0; 8753 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8754 ok(r == 0, "expected 0, got %u\n", r); 8755 ok(externalui_ran == 0, "external UI callback should not have run\n"); 8756 ok(externalui_record_ran == 1, "external UI record callback did not run\n"); 8757 8758 MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL); 8759 8760 externalui_ran = externalui_record_ran = 0; 8761 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8762 ok(r == 0, "expected 0, got %u\n", r); 8763 ok(externalui_ran == 1, "external UI callback did not run\n"); 8764 ok(externalui_record_ran == 1, "external UI record callback did not run\n"); 8765 8766 retval = 1; 8767 externalui_ran = externalui_record_ran = 0; 8768 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8769 ok(r == 1, "expected 1, got %u\n", r); 8770 ok(externalui_ran == 0, "external UI callback should not have run\n"); 8771 ok(externalui_record_ran == 1, "external UI record callback did not run\n"); 8772 8773 /* filter and context should be kept separately */ 8774 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_ERROR, &retval, &prev_record); 8775 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r); 8776 8777 externalui_ran = externalui_record_ran = 0; 8778 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8779 ok(r == 0, "expected 0, got %u\n", r); 8780 ok(externalui_ran == 1, "external UI callback did not run\n"); 8781 ok(externalui_record_ran == 0, "external UI record callback should not have run\n"); 8782 8783 MsiCloseHandle(hpkg); 8784 DeleteFileA(msifile); 8785 } 8786 8787 struct externalui_message { 8788 UINT message; 8789 int field_count; 8790 char field[4][100]; 8791 int match[4]; /* should we test for a match */ 8792 int optional; 8793 }; 8794 8795 static struct externalui_message *sequence; 8796 static int sequence_count, sequence_size; 8797 8798 static void add_message(const struct externalui_message *msg) 8799 { 8800 if (!sequence) 8801 { 8802 sequence_size = 10; 8803 sequence = malloc(sequence_size * sizeof(*sequence)); 8804 } 8805 if (sequence_count == sequence_size) 8806 { 8807 sequence_size *= 2; 8808 sequence = realloc(sequence, sequence_size * sizeof(*sequence)); 8809 } 8810 8811 assert(sequence); 8812 sequence[sequence_count++] = *msg; 8813 } 8814 8815 static void flush_sequence(void) 8816 { 8817 free(sequence); 8818 sequence = NULL; 8819 sequence_count = sequence_size = 0; 8820 } 8821 8822 static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo, 8823 const char *file, int line) 8824 { 8825 static const struct externalui_message end_of_sequence = {0}; 8826 const struct externalui_message *actual; 8827 int failcount = 0; 8828 int i; 8829 8830 add_message(&end_of_sequence); 8831 8832 actual = sequence; 8833 8834 while (expected->message && actual->message) 8835 { 8836 if (expected->message == actual->message) 8837 { 8838 if (expected->field_count < actual->field_count) 8839 { 8840 todo_wine_if (todo) 8841 ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n", 8842 context, expected->message, expected->field_count, actual->field_count); 8843 failcount++; 8844 } 8845 8846 for (i = 0; i <= actual->field_count; i++) 8847 { 8848 if (expected->match[i] && strcmp(expected->field[i], actual->field[i])) 8849 { 8850 todo_wine_if (todo) 8851 ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n", 8852 context, expected->message, i, expected->field[i], actual->field[i]); 8853 failcount++; 8854 } 8855 } 8856 8857 expected++; 8858 actual++; 8859 } 8860 else if (expected->optional) 8861 { 8862 expected++; 8863 } 8864 else 8865 { 8866 todo_wine_if (todo) 8867 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n", 8868 context, expected->message, actual->message); 8869 failcount++; 8870 if (todo) 8871 goto done; 8872 expected++; 8873 actual++; 8874 } 8875 } 8876 8877 if (expected->message || actual->message) 8878 { 8879 todo_wine_if (todo) 8880 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n", 8881 context, expected->message, actual->message); 8882 failcount++; 8883 } 8884 8885 if(todo && !failcount) /* succeeded yet marked todo */ 8886 { 8887 todo_wine 8888 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context); 8889 } 8890 8891 done: 8892 flush_sequence(); 8893 } 8894 8895 #define ok_sequence(exp, contx, todo) \ 8896 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__) 8897 8898 /* don't use PROGRESS, which is timing-dependent, 8899 * or SHOWDIALOG, which due to a bug causes a hang on XP */ 8900 static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE = 8901 INSTALLLOGMODE_FATALEXIT | 8902 INSTALLLOGMODE_ERROR | 8903 INSTALLLOGMODE_WARNING | 8904 INSTALLLOGMODE_USER | 8905 INSTALLLOGMODE_INFO | 8906 INSTALLLOGMODE_FILESINUSE | 8907 INSTALLLOGMODE_RESOLVESOURCE | 8908 INSTALLLOGMODE_OUTOFDISKSPACE | 8909 INSTALLLOGMODE_ACTIONSTART | 8910 INSTALLLOGMODE_ACTIONDATA | 8911 INSTALLLOGMODE_COMMONDATA | 8912 INSTALLLOGMODE_INITIALIZE | 8913 INSTALLLOGMODE_TERMINATE | 8914 INSTALLLOGMODE_RMFILESINUSE | 8915 INSTALLLOGMODE_INSTALLSTART | 8916 INSTALLLOGMODE_INSTALLEND; 8917 8918 static const struct externalui_message empty_sequence[] = { 8919 {0} 8920 }; 8921 8922 static const struct externalui_message openpackage_nonexistent_sequence[] = { 8923 {INSTALLMESSAGE_INITIALIZE, -1}, 8924 {INSTALLMESSAGE_TERMINATE, -1}, 8925 {0} 8926 }; 8927 8928 static const struct externalui_message openpackage_sequence[] = { 8929 {INSTALLMESSAGE_INITIALIZE, -1}, 8930 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 8931 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 8932 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 8933 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 8934 {0} 8935 }; 8936 8937 static const struct externalui_message processmessage_info_sequence[] = { 8938 {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}}, 8939 {0} 8940 }; 8941 8942 static const struct externalui_message processmessage_actionstart_sequence[] = { 8943 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}}, 8944 {0} 8945 }; 8946 8947 static const struct externalui_message processmessage_actiondata_sequence[] = { 8948 {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}}, 8949 {0} 8950 }; 8951 8952 static const struct externalui_message processmessage_error_sequence[] = { 8953 {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}}, 8954 {0} 8955 }; 8956 8957 static const struct externalui_message processmessage_internal_error_sequence[] = { 8958 {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}}, 8959 {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}}, 8960 {0} 8961 }; 8962 8963 static const struct externalui_message processmessage_error_format_sequence[] = { 8964 {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}}, 8965 {0} 8966 }; 8967 8968 static const struct externalui_message doaction_costinitialize_sequence[] = { 8969 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}}, 8970 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}}, 8971 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, 8972 {0} 8973 }; 8974 8975 static const struct externalui_message doaction_custom_sequence[] = { 8976 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}}, 8977 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 8978 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}}, 8979 {0} 8980 }; 8981 8982 static const struct externalui_message doaction_custom_fullui_sequence[] = { 8983 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 8984 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}}, 8985 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}}, 8986 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 8987 {0} 8988 }; 8989 8990 static const struct externalui_message doaction_custom_cancel_sequence[] = { 8991 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 8992 {0} 8993 }; 8994 8995 static const struct externalui_message doaction_dialog_nonexistent_sequence[] = { 8996 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 8997 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 8998 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}}, 8999 {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}}, 9000 {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}}, 9001 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}}, 9002 {0} 9003 }; 9004 9005 static const struct externalui_message doaction_dialog_sequence[] = { 9006 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}}, 9007 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}}, 9008 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}}, 9009 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}}, 9010 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}}, 9011 {0} 9012 }; 9013 9014 static const struct externalui_message doaction_dialog_error_sequence[] = { 9015 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}}, 9016 {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}}, 9017 {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}}, 9018 {0} 9019 }; 9020 9021 static const struct externalui_message doaction_dialog_3_sequence[] = { 9022 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}}, 9023 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}}, 9024 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}}, 9025 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}}, 9026 {0} 9027 }; 9028 9029 static const struct externalui_message doaction_dialog_12345_sequence[] = { 9030 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}}, 9031 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}}, 9032 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}}, 9033 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}}, 9034 {0} 9035 }; 9036 9037 static const struct externalui_message closehandle_sequence[] = { 9038 {INSTALLMESSAGE_TERMINATE, -1}, 9039 {0} 9040 }; 9041 9042 static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string) 9043 { 9044 INT retval = context ? *((INT *)context) : 0; 9045 struct externalui_message msg; 9046 9047 msg.message = message; 9048 msg.field_count = 0; 9049 strcpy(msg.field[0], string); 9050 add_message(&msg); 9051 9052 return retval; 9053 } 9054 9055 static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord) 9056 { 9057 INT retval = context ? *((INT *)context) : 0; 9058 struct externalui_message msg; 9059 char buffer[256]; 9060 DWORD length; 9061 UINT r; 9062 int i; 9063 9064 msg.message = message; 9065 if (message == INSTALLMESSAGE_TERMINATE) 9066 { 9067 /* trying to access the record seems to hang on some versions of Windows */ 9068 msg.field_count = -1; 9069 add_message(&msg); 9070 return 1; 9071 } 9072 msg.field_count = MsiRecordGetFieldCount(hrecord); 9073 for (i = 0; i <= msg.field_count; i++) 9074 { 9075 length = sizeof(buffer); 9076 r = MsiRecordGetStringA(hrecord, i, buffer, &length); 9077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 9078 memcpy(msg.field[i], buffer, min(100, length+1)); 9079 } 9080 9081 /* top-level actions dump a list of all set properties; skip them since they're inconsistent */ 9082 if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8)) 9083 return retval; 9084 9085 add_message(&msg); 9086 9087 return retval; 9088 } 9089 9090 static void test_externalui_message(void) 9091 { 9092 /* test that events trigger the correct sequence of messages */ 9093 9094 INSTALLUI_HANDLER_RECORD prev; 9095 MSIHANDLE hdb, hpkg, hrecord; 9096 INT retval = 1; 9097 UINT r; 9098 9099 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); 9100 9101 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, &retval); 9102 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, &retval, &prev); 9103 9104 flush_sequence(); 9105 9106 CoInitialize(NULL); 9107 9108 hdb = create_package_db(); 9109 ok(hdb, "failed to create database\n"); 9110 9111 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n"); 9112 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 9113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9114 9115 r = run_query(hdb, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)"); 9116 ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r); 9117 r = run_query(hdb, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')"); 9118 ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r); 9119 9120 create_actiontext_table(hdb); 9121 add_actiontext_entry(hdb, "'custom', 'description', 'template'"); 9122 add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'"); 9123 9124 r = MsiOpenPackageA(NULL, &hpkg); 9125 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 9126 ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE); 9127 9128 r = MsiOpenPackageA("nonexistent", &hpkg); 9129 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r); 9130 ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE); 9131 9132 r = package_from_db(hdb, &hpkg); 9133 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 9134 { 9135 skip("Not enough rights to perform tests\n"); 9136 DeleteFileA(msifile); 9137 return; 9138 } 9139 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 9140 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE); 9141 9142 /* Test MsiProcessMessage */ 9143 hrecord = MsiCreateRecord(3); 9144 ok(hrecord, "failed to create record\n"); 9145 9146 MsiRecordSetStringA(hrecord, 0, "zero"); 9147 MsiRecordSetStringA(hrecord, 1, "one"); 9148 MsiRecordSetStringA(hrecord, 2, "two"); 9149 MsiRecordSetStringA(hrecord, 3, "three"); 9150 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord); 9151 ok(r == 1, "Expected 1, got %d\n", r); 9152 ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE); 9153 9154 MsiRecordSetStringA(hrecord, 1, "name"); 9155 MsiRecordSetStringA(hrecord, 2, "description"); 9156 MsiRecordSetStringA(hrecord, 3, "template"); 9157 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONSTART, hrecord); 9158 ok(r == 1, "Expected 1, got %d\n", r); 9159 ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE); 9160 9161 MsiRecordSetStringA(hrecord, 0, "apple"); 9162 MsiRecordSetStringA(hrecord, 1, "cherry"); 9163 MsiRecordSetStringA(hrecord, 2, "banana"); 9164 MsiRecordSetStringA(hrecord, 3, "guava"); 9165 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONDATA, hrecord); 9166 ok(r == 1, "Expected 1, got %d\n", r); 9167 ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE); 9168 9169 /* non-internal error */ 9170 MsiRecordSetStringA(hrecord, 0, NULL); 9171 MsiRecordSetInteger(hrecord, 1, 1311); 9172 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 9173 ok(r == 1, "Expected 1, got %d\n", r); 9174 ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE); 9175 9176 /* internal error */ 9177 MsiRecordSetStringA(hrecord, 0, NULL); 9178 MsiRecordSetInteger(hrecord, 1, 2726); 9179 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 9180 ok(r == 0, "Expected 0, got %d\n", r); 9181 ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE); 9182 9183 /* with format field */ 9184 MsiRecordSetStringA(hrecord, 0, "starfruit"); 9185 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 9186 ok(r == 1, "Expected 1, got %d\n", r); 9187 ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE); 9188 9189 /* Test a standard action */ 9190 r = MsiDoActionA(hpkg, "CostInitialize"); 9191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9192 ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE); 9193 9194 /* Test a custom action */ 9195 r = MsiDoActionA(hpkg, "custom"); 9196 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r); 9197 ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE); 9198 9199 /* close the package */ 9200 MsiCloseHandle(hpkg); 9201 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9202 9203 /* Test dialogs */ 9204 hdb = create_package_db(); 9205 ok(hdb, "failed to create database\n"); 9206 9207 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 9208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9209 9210 create_dialog_table(hdb); 9211 add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'"); 9212 9213 create_control_table(hdb); 9214 add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'"); 9215 9216 r = package_from_db(hdb, &hpkg); 9217 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 9218 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE); 9219 9220 /* Test a custom action */ 9221 r = MsiDoActionA(hpkg, "custom"); 9222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9223 ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE); 9224 9225 retval = 2; 9226 r = MsiDoActionA(hpkg, "custom"); 9227 ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r); 9228 ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE); 9229 9230 retval = 0; 9231 r = MsiDoActionA(hpkg, "custom"); 9232 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r); 9233 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE); 9234 9235 r = MsiDoActionA(hpkg, "dialog"); 9236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9237 ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE); 9238 9239 retval = -1; 9240 r = MsiDoActionA(hpkg, "error"); 9241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9242 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE); 9243 9244 r = MsiDoActionA(hpkg, "error"); 9245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9246 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE); 9247 9248 retval = -2; 9249 r = MsiDoActionA(hpkg, "custom"); 9250 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r); 9251 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE); 9252 9253 retval = 3; 9254 r = MsiDoActionA(hpkg, "dialog"); 9255 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r); 9256 ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE); 9257 9258 retval = 12345; 9259 r = MsiDoActionA(hpkg, "dialog"); 9260 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r); 9261 ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE); 9262 9263 MsiCloseHandle(hpkg); 9264 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9265 9266 MsiCloseHandle(hrecord); 9267 CoUninitialize(); 9268 DeleteFileA(msifile); 9269 DeleteFileA("forcecodepage.idt"); 9270 } 9271 9272 static const struct externalui_message controlevent_spawn_sequence[] = { 9273 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}}, 9274 {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}}, 9275 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}}, 9276 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}}, 9277 9278 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 9279 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}}, 9280 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 9281 9282 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}}, 9283 9284 {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}}, 9285 {0} 9286 }; 9287 9288 static const struct externalui_message controlevent_spawn2_sequence[] = { 9289 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}}, 9290 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}}, 9291 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}}, 9292 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}}, 9293 9294 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 9295 {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}}, 9296 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 9297 9298 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}}, 9299 9300 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}}, 9301 {0} 9302 }; 9303 9304 static void test_controlevent(void) 9305 { 9306 INSTALLUI_HANDLER_RECORD prev; 9307 MSIHANDLE hdb, hpkg; 9308 UINT r; 9309 9310 if (!winetest_interactive) 9311 { 9312 skip("interactive ControlEvent tests\n"); 9313 return; 9314 } 9315 9316 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); 9317 9318 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL); 9319 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev); 9320 9321 flush_sequence(); 9322 9323 CoInitialize(NULL); 9324 9325 hdb = create_package_db(); 9326 ok(hdb, "failed to create database\n"); 9327 9328 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n"); 9329 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 9330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9331 9332 create_dialog_table(hdb); 9333 add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'"); 9334 add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'"); 9335 add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'"); 9336 add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'"); 9337 9338 create_control_table(hdb); 9339 add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); 9340 add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); 9341 add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); 9342 add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); 9343 9344 create_controlevent_table(hdb); 9345 add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1"); 9346 add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1"); 9347 9348 create_custom_action_table(hdb); 9349 add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'"); 9350 9351 /* SpawnDialog and EndDialog should trigger after all other events */ 9352 add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1"); 9353 add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2"); 9354 9355 /* Multiple dialog events cause only the last one to be triggered */ 9356 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1"); 9357 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2"); 9358 add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3"); 9359 9360 r = package_from_db(hdb, &hpkg); 9361 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r); 9362 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE); 9363 9364 r = MsiDoActionA(hpkg, "spawn"); 9365 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r); 9366 ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE); 9367 9368 r = MsiDoActionA(hpkg, "spawn2"); 9369 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r); 9370 ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE); 9371 9372 MsiCloseHandle(hpkg); 9373 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9374 9375 CoUninitialize(); 9376 DeleteFileA(msifile); 9377 DeleteFileA("forcecodepage.idt"); 9378 } 9379 9380 static const struct externalui_message toplevel_install_sequence[] = { 9381 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9382 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9383 9384 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9385 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9386 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9387 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9388 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9389 9390 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9391 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9392 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1}, 9393 9394 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, 9395 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}}, 9396 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, 9397 9398 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}}, 9399 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, 9400 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, 9401 9402 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}}, 9403 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, 9404 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, 9405 9406 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9407 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1}, 9408 9409 /* property dump */ 9410 9411 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, 9412 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, 9413 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9414 {0} 9415 }; 9416 9417 static const struct externalui_message toplevel_install_ui_sequence[] = { 9418 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9419 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9420 9421 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}}, 9422 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}}, 9423 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}}, 9424 9425 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9426 {0} 9427 }; 9428 9429 static const struct externalui_message toplevel_executeaction_install_sequence[] = { 9430 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}}, 9431 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, 9432 9433 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9434 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9435 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9436 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9437 9438 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9439 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9440 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1}, 9441 9442 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, 9443 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}}, 9444 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, 9445 9446 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}}, 9447 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, 9448 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, 9449 9450 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}}, 9451 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, 9452 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, 9453 9454 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9455 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1}, 9456 9457 /* property dump */ 9458 9459 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, 9460 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, 9461 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, 9462 {0} 9463 }; 9464 9465 static const struct externalui_message toplevel_executeaction_costinitialize_sequence[] = { 9466 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}}, 9467 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, 9468 9469 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9470 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9471 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9472 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9473 9474 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, 9475 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}}, 9476 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, 9477 9478 /* property dump */ 9479 9480 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, 9481 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, 9482 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, 9483 {0} 9484 }; 9485 9486 static const struct externalui_message toplevel_msiinstallproduct_sequence[] = { 9487 {INSTALLMESSAGE_INITIALIZE, -1}, 9488 9489 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9490 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9491 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9492 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9493 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9494 9495 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9496 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9497 9498 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}}, 9499 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}}, 9500 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}}, 9501 9502 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9503 9504 /* property dump */ 9505 9506 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9507 {INSTALLMESSAGE_TERMINATE, -1}, 9508 {0} 9509 }; 9510 9511 static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[] = { 9512 {INSTALLMESSAGE_INITIALIZE, -1}, 9513 9514 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9515 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9516 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9517 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9518 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9519 9520 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}}, 9521 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}}, 9522 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}}, 9523 9524 /* property dump */ 9525 9526 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9527 {INSTALLMESSAGE_TERMINATE, -1}, 9528 {0} 9529 }; 9530 9531 /* tests involving top-level actions: INSTALL, ExecuteAction */ 9532 static void test_top_level_action(void) 9533 { 9534 INSTALLUI_HANDLER_RECORD prev; 9535 MSIHANDLE hdb, hpkg; 9536 UINT r; 9537 char msifile_absolute[MAX_PATH]; 9538 9539 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 9540 9541 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL); 9542 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev); 9543 9544 flush_sequence(); 9545 9546 CoInitialize(NULL); 9547 9548 hdb = create_package_db(); 9549 ok(hdb, "failed to create database\n"); 9550 9551 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n"); 9552 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 9553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9554 9555 create_property_table(hdb); 9556 add_property_entry(hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'"); 9557 9558 create_install_execute_sequence_table(hdb); 9559 add_install_execute_sequence_entry(hdb, "'CostInitialize', '', 1"); 9560 add_install_execute_sequence_entry(hdb, "'FileCost', '', 2"); 9561 add_install_execute_sequence_entry(hdb, "'CostFinalize', '', 3"); 9562 9563 create_install_ui_sequence_table(hdb); 9564 add_install_ui_sequence_entry(hdb, "'AppSearch', '', 1"); 9565 9566 MsiDatabaseCommit(hdb); 9567 9568 /* for some reason we have to open the package from file using an absolute path */ 9569 MsiCloseHandle(hdb); 9570 GetFullPathNameA(msifile, MAX_PATH, msifile_absolute, NULL); 9571 r = MsiOpenPackageA(msifile_absolute, &hpkg); 9572 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r); 9573 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE); 9574 9575 /* test INSTALL */ 9576 r = MsiDoActionA(hpkg, "INSTALL"); 9577 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9578 ok_sequence(toplevel_install_sequence, "INSTALL (no UI)", FALSE); 9579 9580 /* test INSTALL with reduced+ UI */ 9581 /* for some reason we need to re-open the package to change the internal UI */ 9582 MsiCloseHandle(hpkg); 9583 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9584 MsiSetInternalUI(INSTALLUILEVEL_REDUCED, NULL); 9585 r = MsiOpenPackageA(msifile_absolute, &hpkg); 9586 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r); 9587 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE); 9588 9589 r = MsiDoActionA(hpkg, "INSTALL"); 9590 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9591 ok_sequence(toplevel_install_ui_sequence, "INSTALL (reduced+ UI)", TRUE); 9592 9593 /* test ExecuteAction with EXECUTEACTION property unset */ 9594 MsiSetPropertyA(hpkg, "EXECUTEACTION", NULL); 9595 r = MsiDoActionA(hpkg, "ExecuteAction"); 9596 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9597 ok_sequence(toplevel_executeaction_install_sequence, "ExecuteAction: INSTALL", FALSE); 9598 9599 /* test ExecuteAction with EXECUTEACTION property set */ 9600 MsiSetPropertyA(hpkg, "EXECUTEACTION", "CostInitialize"); 9601 r = MsiDoActionA(hpkg, "ExecuteAction"); 9602 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9603 ok_sequence(toplevel_executeaction_costinitialize_sequence, "ExecuteAction: CostInitialize", FALSE); 9604 9605 MsiCloseHandle(hpkg); 9606 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9607 9608 /* test MsiInstallProduct() */ 9609 r = MsiInstallProductA(msifile_absolute, NULL); 9610 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9611 ok_sequence(toplevel_msiinstallproduct_sequence, "MsiInstallProduct()", TRUE); 9612 9613 r = MsiInstallProductA(msifile_absolute, "ACTION=custom"); 9614 todo_wine 9615 ok(r == ERROR_INSTALL_FAILURE, "expected ERROR_INSTALL_FAILURE, got %u\n", r); 9616 ok_sequence(toplevel_msiinstallproduct_custom_sequence, "MsiInstallProduct(ACTION=custom)", TRUE); 9617 9618 CoUninitialize(); 9619 DeleteFileA(msifile); 9620 DeleteFileA("forcecodepage.idt"); 9621 } 9622 9623 START_TEST(package) 9624 { 9625 char temp_path[MAX_PATH], prev_path[MAX_PATH]; 9626 STATEMGRSTATUS status; 9627 BOOL ret = FALSE; 9628 DWORD len; 9629 9630 init_functionpointers(); 9631 9632 if (pIsWow64Process) 9633 pIsWow64Process(GetCurrentProcess(), &is_wow64); 9634 9635 GetCurrentDirectoryA(MAX_PATH, prev_path); 9636 GetTempPathA(MAX_PATH, temp_path); 9637 SetCurrentDirectoryA(temp_path); 9638 9639 lstrcpyA(CURR_DIR, temp_path); 9640 len = lstrlenA(CURR_DIR); 9641 9642 if (len && (CURR_DIR[len - 1] == '\\')) 9643 CURR_DIR[len - 1] = 0; 9644 9645 /* Create a restore point ourselves so we circumvent the multitude of restore points 9646 * that would have been created by all the installation and removal tests. 9647 * 9648 * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the 9649 * creation of restore points. 9650 */ 9651 if (pSRSetRestorePointA && !pMsiGetComponentPathExA) 9652 { 9653 memset(&status, 0, sizeof(status)); 9654 ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status); 9655 } 9656 9657 test_createpackage(); 9658 test_doaction(); 9659 test_gettargetpath_bad(); 9660 test_settargetpath(); 9661 test_props(); 9662 test_property_table(); 9663 test_condition(); 9664 test_msipackage(); 9665 test_formatrecord2(); 9666 test_formatrecord_tables(); 9667 test_states(); 9668 test_removefiles(); 9669 test_appsearch(); 9670 test_appsearch_complocator(); 9671 test_appsearch_reglocator(); 9672 test_appsearch_inilocator(); 9673 test_appsearch_drlocator(); 9674 test_featureparents(); 9675 test_installprops(); 9676 test_launchconditions(); 9677 test_ccpsearch(); 9678 test_complocator(); 9679 test_MsiGetSourcePath(); 9680 test_shortlongsource(); 9681 test_sourcedir(); 9682 test_access(); 9683 test_emptypackage(); 9684 test_MsiGetProductProperty(); 9685 test_MsiSetProperty(); 9686 test_MsiApplyMultiplePatches(); 9687 test_MsiApplyPatch(); 9688 test_costs(); 9689 test_MsiDatabaseCommit(); 9690 test_externalui(); 9691 test_externalui_message(); 9692 test_controlevent(); 9693 test_top_level_action(); 9694 9695 if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret) 9696 { 9697 ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status); 9698 if (ret) 9699 remove_restore_point(status.llSequenceNumber); 9700 } 9701 9702 SetCurrentDirectoryA(prev_path); 9703 } 9704