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 #include "utils.h" 36 37 static BOOL is_wow64; 38 static const char msifile[] = "winetest-package.msi"; 39 static const WCHAR msifileW[] = L"winetest-package.msi"; 40 41 static char *get_user_sid(void) 42 { 43 HANDLE token; 44 DWORD size = 0; 45 TOKEN_USER *user; 46 char *usersid = NULL; 47 48 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); 49 GetTokenInformation(token, TokenUser, NULL, size, &size); 50 51 user = malloc(size); 52 GetTokenInformation(token, TokenUser, user, size, &size); 53 ConvertSidToStringSidA(user->User.Sid, &usersid); 54 free(user); 55 56 CloseHandle(token); 57 return usersid; 58 } 59 60 /* RegDeleteTreeW from dlls/advapi32/registry.c */ 61 static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access) 62 { 63 LONG ret; 64 DWORD dwMaxSubkeyLen, dwMaxValueLen; 65 DWORD dwMaxLen, dwSize; 66 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf; 67 HKEY hSubKey = hKey; 68 69 if(lpszSubKey) 70 { 71 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey); 72 if (ret) return ret; 73 } 74 75 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, 76 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL); 77 if (ret) goto cleanup; 78 79 dwMaxSubkeyLen++; 80 dwMaxValueLen++; 81 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen); 82 if (dwMaxLen > ARRAY_SIZE(szNameBuf)) 83 { 84 /* Name too big: alloc a buffer for it */ 85 if (!(lpszName = malloc(dwMaxLen * sizeof(WCHAR)))) 86 { 87 ret = ERROR_NOT_ENOUGH_MEMORY; 88 goto cleanup; 89 } 90 } 91 92 /* Recursively delete all the subkeys */ 93 while (TRUE) 94 { 95 dwSize = dwMaxLen; 96 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, 97 NULL, NULL, NULL)) break; 98 99 ret = package_RegDeleteTreeW(hSubKey, lpszName, access); 100 if (ret) goto cleanup; 101 } 102 103 if (lpszSubKey) 104 ret = RegDeleteKeyExW(hKey, lpszSubKey, access, 0); 105 else 106 while (TRUE) 107 { 108 dwSize = dwMaxLen; 109 if (RegEnumValueW(hKey, 0, lpszName, &dwSize, 110 NULL, NULL, NULL, NULL)) break; 111 112 ret = RegDeleteValueW(hKey, lpszName); 113 if (ret) goto cleanup; 114 } 115 116 cleanup: 117 if (lpszName != szNameBuf) free(lpszName); 118 if (lpszSubKey) RegCloseKey(hSubKey); 119 return ret; 120 } 121 122 static BOOL squash_guid(LPCWSTR in, LPWSTR out) 123 { 124 DWORD i,n=1; 125 GUID guid; 126 127 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid))) 128 return FALSE; 129 130 for(i=0; i<8; i++) 131 out[7-i] = in[n++]; 132 n++; 133 for(i=0; i<4; i++) 134 out[11-i] = in[n++]; 135 n++; 136 for(i=0; i<4; i++) 137 out[15-i] = in[n++]; 138 n++; 139 for(i=0; i<2; i++) 140 { 141 out[17+i*2] = in[n++]; 142 out[16+i*2] = in[n++]; 143 } 144 n++; 145 for( ; i<8; i++) 146 { 147 out[17+i*2] = in[n++]; 148 out[16+i*2] = in[n++]; 149 } 150 out[32]=0; 151 return TRUE; 152 } 153 154 static void create_test_guid(LPSTR prodcode, LPSTR squashed) 155 { 156 WCHAR guidW[MAX_PATH]; 157 WCHAR squashedW[MAX_PATH]; 158 GUID guid; 159 HRESULT hr; 160 int size; 161 162 hr = CoCreateGuid(&guid); 163 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr); 164 165 size = StringFromGUID2(&guid, guidW, MAX_PATH); 166 ok(size == 39, "Expected 39, got %#lx\n", hr); 167 168 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL); 169 squash_guid(guidW, squashedW); 170 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); 171 } 172 173 static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context, 174 LPCSTR guid, LPSTR usersid, BOOL dir) 175 { 176 WCHAR guidW[MAX_PATH]; 177 WCHAR squashedW[MAX_PATH]; 178 CHAR squashed[MAX_PATH]; 179 CHAR comppath[MAX_PATH + 81]; 180 CHAR prodpath[MAX_PATH]; 181 CHAR path[MAX_PATH]; 182 LPCSTR prod = NULL; 183 HKEY hkey; 184 REGSAM access = KEY_ALL_ACCESS; 185 186 if (is_wow64) 187 access |= KEY_WOW64_64KEY; 188 189 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH); 190 squash_guid(guidW, squashedW); 191 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); 192 193 if (context == MSIINSTALLCONTEXT_MACHINE) 194 { 195 prod = "3D0DAE300FACA1300AD792060BCDAA92"; 196 sprintf(comppath, 197 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 198 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed); 199 lstrcpyA(prodpath, 200 "SOFTWARE\\Classes\\Installer\\" 201 "Products\\3D0DAE300FACA1300AD792060BCDAA92"); 202 } 203 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED) 204 { 205 prod = "7D2F387510109040002000060BECB6AB"; 206 sprintf(comppath, 207 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 208 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed); 209 sprintf(prodpath, 210 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 211 "Installer\\%s\\Installer\\Products\\" 212 "7D2F387510109040002000060BECB6AB", usersid); 213 } 214 else if (context == MSIINSTALLCONTEXT_USERMANAGED) 215 { 216 prod = "7D2F387510109040002000060BECB6AB"; 217 sprintf(comppath, 218 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 219 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed); 220 sprintf(prodpath, 221 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 222 "Installer\\Managed\\%s\\Installer\\Products\\" 223 "7D2F387510109040002000060BECB6AB", usersid); 224 } 225 226 RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL); 227 228 lstrcpyA(path, CURR_DIR); 229 lstrcatA(path, "\\"); 230 if (!dir) lstrcatA(path, filename); 231 232 RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path)); 233 RegCloseKey(hkey); 234 235 RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL); 236 RegCloseKey(hkey); 237 } 238 239 static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid) 240 { 241 WCHAR guidW[MAX_PATH]; 242 WCHAR squashedW[MAX_PATH]; 243 WCHAR substrW[MAX_PATH]; 244 CHAR squashed[MAX_PATH]; 245 CHAR comppath[MAX_PATH + 81]; 246 CHAR prodpath[MAX_PATH]; 247 REGSAM access = KEY_ALL_ACCESS; 248 249 if (is_wow64) 250 access |= KEY_WOW64_64KEY; 251 252 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH); 253 squash_guid(guidW, squashedW); 254 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); 255 256 if (context == MSIINSTALLCONTEXT_MACHINE) 257 { 258 sprintf(comppath, 259 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 260 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed); 261 lstrcpyA(prodpath, 262 "SOFTWARE\\Classes\\Installer\\" 263 "Products\\3D0DAE300FACA1300AD792060BCDAA92"); 264 } 265 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED) 266 { 267 sprintf(comppath, 268 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 269 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed); 270 sprintf(prodpath, 271 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 272 "Installer\\%s\\Installer\\Products\\" 273 "7D2F387510109040002000060BECB6AB", usersid); 274 } 275 else if (context == MSIINSTALLCONTEXT_USERMANAGED) 276 { 277 sprintf(comppath, 278 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 279 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed); 280 sprintf(prodpath, 281 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 282 "Installer\\Managed\\%s\\Installer\\Products\\" 283 "7D2F387510109040002000060BECB6AB", usersid); 284 } 285 286 MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH); 287 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access); 288 289 MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH); 290 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access); 291 } 292 293 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec) 294 { 295 MSIHANDLE hview = 0; 296 UINT r, ret; 297 298 /* open a select query */ 299 r = MsiDatabaseOpenViewA(hdb, query, &hview); 300 if (r != ERROR_SUCCESS) 301 return r; 302 r = MsiViewExecute(hview, 0); 303 if (r != ERROR_SUCCESS) 304 return r; 305 ret = MsiViewFetch(hview, phrec); 306 r = MsiViewClose(hview); 307 if (r != ERROR_SUCCESS) 308 return r; 309 r = MsiCloseHandle(hview); 310 if (r != ERROR_SUCCESS) 311 return r; 312 return ret; 313 } 314 315 static UINT create_component_table( MSIHANDLE hdb ) 316 { 317 UINT r = run_query( hdb, 0, 318 "CREATE TABLE `Component` ( " 319 "`Component` CHAR(72) NOT NULL, " 320 "`ComponentId` CHAR(38), " 321 "`Directory_` CHAR(72) NOT NULL, " 322 "`Attributes` SHORT NOT NULL, " 323 "`Condition` CHAR(255), " 324 "`KeyPath` CHAR(72) " 325 "PRIMARY KEY `Component`)" ); 326 ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r); 327 return r; 328 } 329 330 static UINT create_feature_table( MSIHANDLE hdb ) 331 { 332 UINT r = run_query( hdb, 0, 333 "CREATE TABLE `Feature` ( " 334 "`Feature` CHAR(38) NOT NULL, " 335 "`Feature_Parent` CHAR(38), " 336 "`Title` CHAR(64), " 337 "`Description` CHAR(255), " 338 "`Display` SHORT NOT NULL, " 339 "`Level` SHORT NOT NULL, " 340 "`Directory_` CHAR(72), " 341 "`Attributes` SHORT NOT NULL " 342 "PRIMARY KEY `Feature`)" ); 343 ok(r == ERROR_SUCCESS, "Failed to create Feature table: %u\n", r); 344 return r; 345 } 346 347 static UINT create_feature_components_table( MSIHANDLE hdb ) 348 { 349 UINT r = run_query( hdb, 0, 350 "CREATE TABLE `FeatureComponents` ( " 351 "`Feature_` CHAR(38) NOT NULL, " 352 "`Component_` CHAR(72) NOT NULL " 353 "PRIMARY KEY `Feature_`, `Component_` )" ); 354 ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r); 355 return r; 356 } 357 358 static UINT create_file_table( MSIHANDLE hdb ) 359 { 360 UINT r = run_query( hdb, 0, 361 "CREATE TABLE `File` (" 362 "`File` CHAR(72) NOT NULL, " 363 "`Component_` CHAR(72) NOT NULL, " 364 "`FileName` CHAR(255) NOT NULL, " 365 "`FileSize` LONG NOT NULL, " 366 "`Version` CHAR(72), " 367 "`Language` CHAR(20), " 368 "`Attributes` SHORT, " 369 "`Sequence` SHORT NOT NULL " 370 "PRIMARY KEY `File`)" ); 371 ok(r == ERROR_SUCCESS, "Failed to create File table: %u\n", r); 372 return r; 373 } 374 375 static UINT create_remove_file_table( MSIHANDLE hdb ) 376 { 377 UINT r = run_query( hdb, 0, 378 "CREATE TABLE `RemoveFile` (" 379 "`FileKey` CHAR(72) NOT NULL, " 380 "`Component_` CHAR(72) NOT NULL, " 381 "`FileName` CHAR(255) LOCALIZABLE, " 382 "`DirProperty` CHAR(72) NOT NULL, " 383 "`InstallMode` SHORT NOT NULL " 384 "PRIMARY KEY `FileKey`)" ); 385 ok(r == ERROR_SUCCESS, "Failed to create RemoveFile table: %u\n", r); 386 return r; 387 } 388 389 static UINT create_appsearch_table( MSIHANDLE hdb ) 390 { 391 UINT r = run_query( hdb, 0, 392 "CREATE TABLE `AppSearch` (" 393 "`Property` CHAR(72) NOT NULL, " 394 "`Signature_` CHAR(72) NOT NULL " 395 "PRIMARY KEY `Property`, `Signature_`)" ); 396 ok(r == ERROR_SUCCESS, "Failed to create AppSearch table: %u\n", r); 397 return r; 398 } 399 400 static UINT create_reglocator_table( MSIHANDLE hdb ) 401 { 402 UINT r = run_query( hdb, 0, 403 "CREATE TABLE `RegLocator` (" 404 "`Signature_` CHAR(72) NOT NULL, " 405 "`Root` SHORT NOT NULL, " 406 "`Key` CHAR(255) NOT NULL, " 407 "`Name` CHAR(255), " 408 "`Type` SHORT " 409 "PRIMARY KEY `Signature_`)" ); 410 ok(r == ERROR_SUCCESS, "Failed to create RegLocator table: %u\n", r); 411 return r; 412 } 413 414 static UINT create_signature_table( MSIHANDLE hdb ) 415 { 416 UINT r = run_query( hdb, 0, 417 "CREATE TABLE `Signature` (" 418 "`Signature` CHAR(72) NOT NULL, " 419 "`FileName` CHAR(255) NOT NULL, " 420 "`MinVersion` CHAR(20), " 421 "`MaxVersion` CHAR(20), " 422 "`MinSize` LONG, " 423 "`MaxSize` LONG, " 424 "`MinDate` LONG, " 425 "`MaxDate` LONG, " 426 "`Languages` CHAR(255) " 427 "PRIMARY KEY `Signature`)" ); 428 ok(r == ERROR_SUCCESS, "Failed to create Signature table: %u\n", r); 429 return r; 430 } 431 432 static UINT create_launchcondition_table( MSIHANDLE hdb ) 433 { 434 UINT r = run_query( hdb, 0, 435 "CREATE TABLE `LaunchCondition` (" 436 "`Condition` CHAR(255) NOT NULL, " 437 "`Description` CHAR(255) NOT NULL " 438 "PRIMARY KEY `Condition`)" ); 439 ok(r == ERROR_SUCCESS, "Failed to create LaunchCondition table: %u\n", r); 440 return r; 441 } 442 443 static UINT create_property_table( MSIHANDLE hdb ) 444 { 445 UINT r = run_query( hdb, 0, 446 "CREATE TABLE `Property` (" 447 "`Property` CHAR(72) NOT NULL, " 448 "`Value` CHAR(0) " 449 "PRIMARY KEY `Property`)" ); 450 ok(r == ERROR_SUCCESS, "Failed to create Property table: %u\n", r); 451 return r; 452 } 453 454 static UINT create_install_execute_sequence_table( MSIHANDLE hdb ) 455 { 456 UINT r = run_query( hdb, 0, 457 "CREATE TABLE `InstallExecuteSequence` (" 458 "`Action` CHAR(72) NOT NULL, " 459 "`Condition` CHAR(255), " 460 "`Sequence` SHORT " 461 "PRIMARY KEY `Action`)" ); 462 ok(r == ERROR_SUCCESS, "Failed to create InstallExecuteSequence table: %u\n", r); 463 return r; 464 } 465 466 static UINT create_install_ui_sequence_table( MSIHANDLE hdb ) 467 { 468 UINT r = run_query( hdb, 0, 469 "CREATE TABLE `InstallUISequence` (" 470 "`Action` CHAR(72) NOT NULL, " 471 "`Condition` CHAR(255), " 472 "`Sequence` SHORT " 473 "PRIMARY KEY `Action`)" ); 474 ok(r == ERROR_SUCCESS, "Failed to create InstallUISequence table: %u\n", r); 475 return r; 476 } 477 478 static UINT create_media_table( MSIHANDLE hdb ) 479 { 480 UINT r = run_query( hdb, 0, 481 "CREATE TABLE `Media` (" 482 "`DiskId` SHORT NOT NULL, " 483 "`LastSequence` SHORT NOT NULL, " 484 "`DiskPrompt` CHAR(64), " 485 "`Cabinet` CHAR(255), " 486 "`VolumeLabel` CHAR(32), " 487 "`Source` CHAR(72) " 488 "PRIMARY KEY `DiskId`)" ); 489 ok(r == ERROR_SUCCESS, "Failed to create Media table: %u\n", r); 490 return r; 491 } 492 493 static UINT create_ccpsearch_table( MSIHANDLE hdb ) 494 { 495 UINT r = run_query( hdb, 0, 496 "CREATE TABLE `CCPSearch` (" 497 "`Signature_` CHAR(72) NOT NULL " 498 "PRIMARY KEY `Signature_`)" ); 499 ok(r == ERROR_SUCCESS, "Failed to create CCPSearch table: %u\n", r); 500 return r; 501 } 502 503 static UINT create_drlocator_table( MSIHANDLE hdb ) 504 { 505 UINT r = run_query( hdb, 0, 506 "CREATE TABLE `DrLocator` (" 507 "`Signature_` CHAR(72) NOT NULL, " 508 "`Parent` CHAR(72), " 509 "`Path` CHAR(255), " 510 "`Depth` SHORT " 511 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" ); 512 ok(r == ERROR_SUCCESS, "Failed to create DrLocator table: %u\n", r); 513 return r; 514 } 515 516 static UINT create_complocator_table( MSIHANDLE hdb ) 517 { 518 UINT r = run_query( hdb, 0, 519 "CREATE TABLE `CompLocator` (" 520 "`Signature_` CHAR(72) NOT NULL, " 521 "`ComponentId` CHAR(38) NOT NULL, " 522 "`Type` SHORT " 523 "PRIMARY KEY `Signature_`)" ); 524 ok(r == ERROR_SUCCESS, "Failed to create CompLocator table: %u\n", r); 525 return r; 526 } 527 528 static UINT create_inilocator_table( MSIHANDLE hdb ) 529 { 530 UINT r = run_query( hdb, 0, 531 "CREATE TABLE `IniLocator` (" 532 "`Signature_` CHAR(72) NOT NULL, " 533 "`FileName` CHAR(255) NOT NULL, " 534 "`Section` CHAR(96)NOT NULL, " 535 "`Key` CHAR(128)NOT NULL, " 536 "`Field` SHORT, " 537 "`Type` SHORT " 538 "PRIMARY KEY `Signature_`)" ); 539 ok(r == ERROR_SUCCESS, "Failed to create IniLocator table: %u\n", r); 540 return r; 541 } 542 543 static UINT create_custom_action_table( MSIHANDLE hdb ) 544 { 545 UINT r = run_query( hdb, 0, 546 "CREATE TABLE `CustomAction` (" 547 "`Action` CHAR(72) NOT NULL, " 548 "`Type` SHORT NOT NULL, " 549 "`Source` CHAR(75), " 550 "`Target` CHAR(255) " 551 "PRIMARY KEY `Action`)" ); 552 ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r); 553 return r; 554 } 555 556 static UINT create_dialog_table( MSIHANDLE hdb ) 557 { 558 UINT r = run_query(hdb, 0, 559 "CREATE TABLE `Dialog` (" 560 "`Dialog` CHAR(72) NOT NULL, " 561 "`HCentering` SHORT NOT NULL, " 562 "`VCentering` SHORT NOT NULL, " 563 "`Width` SHORT NOT NULL, " 564 "`Height` SHORT NOT NULL, " 565 "`Attributes` LONG, " 566 "`Title` CHAR(128) LOCALIZABLE, " 567 "`Control_First` CHAR(50) NOT NULL, " 568 "`Control_Default` CHAR(50), " 569 "`Control_Cancel` CHAR(50) " 570 "PRIMARY KEY `Dialog`)"); 571 ok(r == ERROR_SUCCESS, "Failed to create Dialog table: %u\n", r); 572 return r; 573 } 574 575 static UINT create_control_table( MSIHANDLE hdb ) 576 { 577 UINT r = run_query(hdb, 0, 578 "CREATE TABLE `Control` (" 579 "`Dialog_` CHAR(72) NOT NULL, " 580 "`Control` CHAR(50) NOT NULL, " 581 "`Type` CHAR(20) NOT NULL, " 582 "`X` SHORT NOT NULL, " 583 "`Y` SHORT NOT NULL, " 584 "`Width` SHORT NOT NULL, " 585 "`Height` SHORT NOT NULL, " 586 "`Attributes` LONG, " 587 "`Property` CHAR(50), " 588 "`Text` CHAR(0) LOCALIZABLE, " 589 "`Control_Next` CHAR(50), " 590 "`Help` CHAR(255) LOCALIZABLE " 591 "PRIMARY KEY `Dialog_`, `Control`)"); 592 ok(r == ERROR_SUCCESS, "Failed to create Control table: %u\n", r); 593 return r; 594 } 595 596 static UINT create_controlevent_table( MSIHANDLE hdb ) 597 { 598 UINT r = run_query(hdb, 0, 599 "CREATE TABLE `ControlEvent` (" 600 "`Dialog_` CHAR(72) NOT NULL, " 601 "`Control_` CHAR(50) NOT NULL, " 602 "`Event` CHAR(50) NOT NULL, " 603 "`Argument` CHAR(255) NOT NULL, " 604 "`Condition` CHAR(255), " 605 "`Ordering` SHORT " 606 "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)"); 607 ok(r == ERROR_SUCCESS, "Failed to create ControlEvent table: %u\n", r); 608 return r; 609 } 610 611 static UINT create_actiontext_table( MSIHANDLE hdb ) 612 { 613 UINT r = run_query(hdb, 0, 614 "CREATE TABLE `ActionText` (" 615 "`Action` CHAR(72) NOT NULL, " 616 "`Description` CHAR(64) LOCALIZABLE, " 617 "`Template` CHAR(128) LOCALIZABLE " 618 "PRIMARY KEY `Action`)"); 619 ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r); 620 return r; 621 } 622 623 static UINT create_upgrade_table( MSIHANDLE hdb ) 624 { 625 UINT r = run_query( hdb, 0, 626 "CREATE TABLE `Upgrade` (" 627 "`UpgradeCode` CHAR(38) NOT NULL, " 628 "`VersionMin` CHAR(20), " 629 "`VersionMax` CHAR(20), " 630 "`Language` CHAR(255), " 631 "`Attributes` SHORT, " 632 "`Remove` CHAR(255), " 633 "`ActionProperty` CHAR(72) NOT NULL " 634 "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" ); 635 ok(r == ERROR_SUCCESS, "Failed to create Upgrade table: %u\n", r); 636 return r; 637 } 638 639 static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert) 640 { 641 char *query; 642 UINT sz, r; 643 644 sz = strlen(values) + strlen(insert) + 1; 645 query = malloc(sz); 646 sprintf(query, insert, values); 647 r = run_query(hdb, 0, query); 648 free(query); 649 ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r); 650 return r; 651 } 652 653 #define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \ 654 "INSERT INTO `Component` " \ 655 "(`Component`, `ComponentId`, `Directory_`, " \ 656 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )") 657 658 #define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \ 659 "INSERT INTO `Directory` " \ 660 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )") 661 662 #define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \ 663 "INSERT INTO `Feature` " \ 664 "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \ 665 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )") 666 667 #define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \ 668 "INSERT INTO `FeatureComponents` " \ 669 "(`Feature_`, `Component_`) VALUES( %s )") 670 671 #define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \ 672 "INSERT INTO `File` " \ 673 "(`File`, `Component_`, `FileName`, `FileSize`, " \ 674 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )") 675 676 #define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \ 677 "INSERT INTO `AppSearch` " \ 678 "(`Property`, `Signature_`) VALUES( %s )") 679 680 #define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \ 681 "INSERT INTO `Signature` " \ 682 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \ 683 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \ 684 "VALUES( %s )") 685 686 #define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \ 687 "INSERT INTO `LaunchCondition` " \ 688 "(`Condition`, `Description`) VALUES( %s )") 689 690 #define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \ 691 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )") 692 693 #define update_ProductVersion_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \ 694 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'") 695 696 #define update_ProductCode_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \ 697 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'") 698 699 #define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \ 700 "INSERT INTO `InstallExecuteSequence` " \ 701 "(`Action`, `Condition`, `Sequence`) VALUES( %s )") 702 703 #define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \ 704 "INSERT INTO `InstallUISequence` " \ 705 "(`Action`, `Condition`, `Sequence`) VALUES( %s )") 706 707 #define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \ 708 "INSERT INTO `Media` " \ 709 "(`DiskId`, `LastSequence`, `DiskPrompt`, " \ 710 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )") 711 712 #define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \ 713 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )") 714 715 #define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \ 716 "INSERT INTO `DrLocator` " \ 717 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )") 718 719 #define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \ 720 "INSERT INTO `CompLocator` " \ 721 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )") 722 723 #define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \ 724 "INSERT INTO `IniLocator` " \ 725 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \ 726 "VALUES( %s )") 727 728 #define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \ 729 "INSERT INTO `CustomAction` " \ 730 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )") 731 732 #define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \ 733 "INSERT INTO `Dialog` " \ 734 "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )") 735 736 #define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \ 737 "INSERT INTO `Control` " \ 738 "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )"); 739 740 #define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \ 741 "INSERT INTO `ControlEvent` " \ 742 "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )"); 743 744 #define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \ 745 "INSERT INTO `ActionText` " \ 746 "(`Action`, `Description`, `Template`) VALUES( %s )"); 747 748 #define add_upgrade_entry(hdb, values) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \ 749 "INSERT INTO `Upgrade` " \ 750 "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )"); 751 752 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path, 753 const char *name, UINT type ) 754 { 755 const char insert[] = 756 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) " 757 "VALUES( '%s', %u, '%s', '%s', %u )"; 758 char *query; 759 UINT sz, r; 760 761 sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert ); 762 query = malloc( sz ); 763 sprintf( query, insert, sig, root, path, name, type ); 764 r = run_query( hdb, 0, query ); 765 free( query ); 766 ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \ 767 return r; 768 } 769 770 static UINT set_summary_info(MSIHANDLE hdb) 771 { 772 UINT res; 773 MSIHANDLE suminfo; 774 775 /* build summary info */ 776 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo); 777 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" ); 778 779 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL, 780 "Installation Database"); 781 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 782 783 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL, 784 "Installation Database"); 785 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 786 787 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL, 788 "Wine Hackers"); 789 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 790 791 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL, 792 ";1033"); 793 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 794 795 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL, 796 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}"); 797 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 798 799 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL); 800 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 801 802 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL); 803 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 804 805 res = MsiSummaryInfoPersist(suminfo); 806 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" ); 807 808 res = MsiCloseHandle( suminfo); 809 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" ); 810 811 return res; 812 } 813 814 815 static MSIHANDLE create_package_db(void) 816 { 817 MSIHANDLE hdb = 0; 818 UINT res; 819 820 DeleteFileA(msifile); 821 822 /* create an empty database */ 823 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 824 ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res ); 825 if( res != ERROR_SUCCESS ) 826 return hdb; 827 828 res = MsiDatabaseCommit( hdb ); 829 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 830 831 res = set_summary_info(hdb); 832 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res); 833 834 res = run_query( hdb, 0, 835 "CREATE TABLE `Directory` ( " 836 "`Directory` CHAR(255) NOT NULL, " 837 "`Directory_Parent` CHAR(255), " 838 "`DefaultDir` CHAR(255) NOT NULL " 839 "PRIMARY KEY `Directory`)" ); 840 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" ); 841 842 return hdb; 843 } 844 845 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) 846 { 847 UINT res; 848 CHAR szPackage[12]; 849 MSIHANDLE hPackage; 850 851 sprintf(szPackage, "#%lu", hdb); 852 res = MsiOpenPackageA(szPackage, &hPackage); 853 if (res != ERROR_SUCCESS) 854 { 855 MsiCloseHandle(hdb); 856 return res; 857 } 858 859 res = MsiCloseHandle(hdb); 860 if (res != ERROR_SUCCESS) 861 { 862 MsiCloseHandle(hPackage); 863 return res; 864 } 865 866 *handle = hPackage; 867 return ERROR_SUCCESS; 868 } 869 870 static void create_test_file(const CHAR *name) 871 { 872 create_file_data(name, name, strlen(name)); 873 } 874 875 typedef struct _tagVS_VERSIONINFO 876 { 877 WORD wLength; 878 WORD wValueLength; 879 WORD wType; 880 WCHAR szKey[1]; 881 WORD wPadding1[1]; 882 VS_FIXEDFILEINFO Value; 883 WORD wPadding2[1]; 884 WORD wChildren[1]; 885 } VS_VERSIONINFO; 886 887 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1)) 888 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r)) 889 890 static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls) 891 { 892 VS_VERSIONINFO *pVerInfo; 893 VS_FIXEDFILEINFO *pFixedInfo; 894 LPBYTE buffer, ofs; 895 CHAR path[MAX_PATH]; 896 DWORD handle, size; 897 HANDLE resource; 898 BOOL ret = FALSE; 899 900 GetSystemDirectoryA(path, MAX_PATH); 901 /* Some dlls can't be updated on Vista/W2K8 */ 902 lstrcatA(path, "\\version.dll"); 903 904 CopyFileA(path, name, FALSE); 905 906 size = GetFileVersionInfoSizeA(path, &handle); 907 buffer = malloc(size); 908 909 GetFileVersionInfoA(path, 0, size, buffer); 910 911 pVerInfo = (VS_VERSIONINFO *)buffer; 912 ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1]; 913 pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4); 914 915 pFixedInfo->dwFileVersionMS = ms; 916 pFixedInfo->dwFileVersionLS = ls; 917 pFixedInfo->dwProductVersionMS = ms; 918 pFixedInfo->dwProductVersionLS = ls; 919 920 resource = BeginUpdateResourceA(name, FALSE); 921 if (!resource) 922 goto done; 923 924 if (!UpdateResourceA(resource, (LPCSTR)RT_VERSION, (LPCSTR)MAKEINTRESOURCE(VS_VERSION_INFO), 925 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size)) 926 goto done; 927 928 if (!EndUpdateResourceA(resource, FALSE)) 929 goto done; 930 931 ret = TRUE; 932 933 done: 934 free(buffer); 935 return ret; 936 } 937 938 static BOOL is_root(const char *path) 939 { 940 return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]); 941 } 942 943 static void test_createpackage(void) 944 { 945 MSIHANDLE hPackage = 0; 946 UINT res; 947 948 res = package_from_db(create_package_db(), &hPackage); 949 if (res == ERROR_INSTALL_PACKAGE_REJECTED) 950 { 951 skip("Not enough rights to perform tests\n"); 952 DeleteFileA(msifile); 953 return; 954 } 955 ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res ); 956 957 res = MsiCloseHandle( hPackage); 958 ok( res == ERROR_SUCCESS , "Failed to close package\n" ); 959 DeleteFileA(msifile); 960 } 961 962 static void test_doaction( void ) 963 { 964 MSIHANDLE hpkg; 965 UINT r; 966 967 r = MsiDoActionA( -1, NULL ); 968 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 969 970 r = package_from_db(create_package_db(), &hpkg); 971 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 972 { 973 skip("Not enough rights to perform tests\n"); 974 DeleteFileA(msifile); 975 return; 976 } 977 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 978 979 r = MsiDoActionA(hpkg, NULL); 980 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 981 982 r = MsiDoActionA(0, "boo"); 983 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 984 985 r = MsiDoActionA(hpkg, "boo"); 986 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n"); 987 988 MsiCloseHandle( hpkg ); 989 DeleteFileA(msifile); 990 } 991 992 static void test_gettargetpath_bad(void) 993 { 994 char buffer[0x80]; 995 WCHAR bufferW[0x80]; 996 MSIHANDLE hpkg; 997 DWORD sz; 998 UINT r; 999 1000 r = package_from_db(create_package_db(), &hpkg); 1001 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 1002 { 1003 skip("Not enough rights to perform tests\n"); 1004 DeleteFileA(msifile); 1005 return; 1006 } 1007 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 1008 1009 r = MsiGetTargetPathA( 0, NULL, NULL, NULL ); 1010 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1011 1012 r = MsiGetTargetPathA( 0, NULL, NULL, &sz ); 1013 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1014 1015 r = MsiGetTargetPathA( 0, "boo", NULL, NULL ); 1016 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1017 1018 r = MsiGetTargetPathA( 0, "boo", NULL, NULL ); 1019 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1020 1021 r = MsiGetTargetPathA( hpkg, "boo", NULL, NULL ); 1022 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1023 1024 r = MsiGetTargetPathA( hpkg, "boo", buffer, NULL ); 1025 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1026 1027 sz = 0; 1028 r = MsiGetTargetPathA( hpkg, "", buffer, &sz ); 1029 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1030 1031 r = MsiGetTargetPathW( 0, NULL, NULL, NULL ); 1032 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1033 1034 r = MsiGetTargetPathW( 0, NULL, NULL, &sz ); 1035 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1036 1037 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL ); 1038 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1039 1040 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL ); 1041 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1042 1043 r = MsiGetTargetPathW( hpkg, L"boo", NULL, NULL ); 1044 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1045 1046 r = MsiGetTargetPathW( hpkg, L"boo", bufferW, NULL ); 1047 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1048 1049 sz = 0; 1050 r = MsiGetTargetPathW( hpkg, L"", bufferW, &sz ); 1051 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1052 1053 MsiCloseHandle( hpkg ); 1054 DeleteFileA(msifile); 1055 } 1056 1057 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff) 1058 { 1059 UINT r; 1060 DWORD size; 1061 MSIHANDLE rec; 1062 1063 rec = MsiCreateRecord( 1 ); 1064 ok(rec, "MsiCreate record failed\n"); 1065 1066 r = MsiRecordSetStringA( rec, 0, file ); 1067 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 1068 1069 size = MAX_PATH; 1070 r = MsiFormatRecordA( hpkg, rec, buff, &size ); 1071 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 1072 1073 MsiCloseHandle( rec ); 1074 } 1075 1076 static void test_settargetpath(void) 1077 { 1078 char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH + 20]; 1079 DWORD sz; 1080 MSIHANDLE hpkg; 1081 UINT r; 1082 MSIHANDLE hdb; 1083 1084 hdb = create_package_db(); 1085 ok ( hdb, "failed to create package database\n" ); 1086 1087 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); 1088 1089 create_component_table( hdb ); 1090 add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" ); 1091 add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" ); 1092 1093 create_feature_table( hdb ); 1094 add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" ); 1095 1096 create_feature_components_table( hdb ); 1097 add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" ); 1098 add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" ); 1099 1100 add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" ); 1101 add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" ); 1102 1103 create_file_table( hdb ); 1104 add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" ); 1105 add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" ); 1106 1107 r = package_from_db( hdb, &hpkg ); 1108 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 1109 { 1110 skip("Not enough rights to perform tests\n"); 1111 DeleteFileA(msifile); 1112 return; 1113 } 1114 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 1115 1116 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 1117 1118 r = MsiDoActionA( hpkg, "CostInitialize"); 1119 ok( r == ERROR_SUCCESS, "cost init failed\n"); 1120 1121 r = MsiDoActionA( hpkg, "FileCost"); 1122 ok( r == ERROR_SUCCESS, "file cost failed\n"); 1123 1124 r = MsiDoActionA( hpkg, "CostFinalize"); 1125 ok( r == ERROR_SUCCESS, "cost finalize failed\n"); 1126 1127 buffer[0] = 0; 1128 sz = sizeof(buffer); 1129 r = MsiGetPropertyA( hpkg, "OutOfNoRbDiskSpace", buffer, &sz ); 1130 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); 1131 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer ); 1132 1133 r = MsiSetTargetPathA( 0, NULL, NULL ); 1134 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1135 1136 r = MsiSetTargetPathA( 0, "boo", "C:\\bogusx" ); 1137 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n"); 1138 1139 r = MsiSetTargetPathA( hpkg, "boo", NULL ); 1140 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); 1141 1142 r = MsiSetTargetPathA( hpkg, "boo", "c:\\bogusx" ); 1143 ok( r == ERROR_DIRECTORY, "wrong return val\n"); 1144 1145 sz = sizeof tempdir - 1; 1146 r = MsiGetTargetPathA( hpkg, "TARGETDIR", tempdir, &sz ); 1147 sprintf( file, "%srootfile.txt", tempdir ); 1148 buffer[0] = 0; 1149 query_file_path( hpkg, "[#RootFile]", buffer ); 1150 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1151 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer ); 1152 1153 GetTempFileNameA( tempdir, "_wt", 0, buffer ); 1154 sprintf( tempdir, "%s\\subdir", buffer ); 1155 1156 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer ); 1157 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY, 1158 "MsiSetTargetPath on file returned %d\n", r ); 1159 1160 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir ); 1161 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY, 1162 "MsiSetTargetPath on 'subdir' of file returned %d\n", r ); 1163 1164 DeleteFileA( buffer ); 1165 1166 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer ); 1167 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1168 1169 r = GetFileAttributesA( buffer ); 1170 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r ); 1171 1172 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir ); 1173 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r ); 1174 1175 buffer[0] = 0; 1176 sz = sizeof buffer - 1; 1177 lstrcatA( tempdir, "\\" ); 1178 r = MsiGetTargetPathA( hpkg, "TARGETDIR", buffer, &sz ); 1179 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1180 ok( !lstrcmpA(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer); 1181 1182 sprintf( file, "%srootfile.txt", tempdir ); 1183 query_file_path( hpkg, "[#RootFile]", buffer ); 1184 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer); 1185 1186 buffer[0] = 0; 1187 sz = sizeof(buffer); 1188 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz ); 1189 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); 1190 lstrcatA( tempdir, "TestParent\\" ); 1191 ok( !lstrcmpiA(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer ); 1192 1193 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two" ); 1194 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1195 1196 buffer[0] = 0; 1197 sz = sizeof(buffer); 1198 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz ); 1199 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); 1200 ok( lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\"), 1201 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer ); 1202 1203 buffer[0] = 0; 1204 query_file_path( hpkg, "[#TestFile]", buffer ); 1205 ok( !lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\testfile.txt"), 1206 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer ); 1207 1208 buffer[0] = 0; 1209 sz = sizeof buffer - 1; 1210 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz ); 1211 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1212 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer); 1213 1214 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two\\three" ); 1215 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1216 1217 buffer[0] = 0; 1218 sz = sizeof buffer - 1; 1219 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz ); 1220 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1221 ok( !lstrcmpiA(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer); 1222 1223 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\one\\\\two " ); 1224 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1225 1226 buffer[0] = 0; 1227 sz = sizeof buffer - 1; 1228 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz ); 1229 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1230 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer); 1231 1232 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " ); 1233 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); 1234 1235 buffer[0] = 0; 1236 sz = sizeof buffer - 1; 1237 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz ); 1238 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); 1239 ok( !lstrcmpiA(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer); 1240 1241 MsiCloseHandle( hpkg ); 1242 } 1243 1244 static void test_condition(void) 1245 { 1246 MSICONDITION r; 1247 MSIHANDLE hpkg; 1248 1249 r = package_from_db(create_package_db(), &hpkg); 1250 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 1251 { 1252 skip("Not enough rights to perform tests\n"); 1253 DeleteFileA(msifile); 1254 return; 1255 } 1256 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 1257 1258 r = MsiEvaluateConditionA(0, NULL); 1259 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1260 1261 r = MsiEvaluateConditionA(hpkg, NULL); 1262 ok( r == MSICONDITION_NONE, "wrong return val\n"); 1263 1264 r = MsiEvaluateConditionA(hpkg, ""); 1265 ok( r == MSICONDITION_NONE, "wrong return val\n"); 1266 1267 r = MsiEvaluateConditionA(hpkg, "1"); 1268 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1269 1270 r = MsiEvaluateConditionA(hpkg, "0"); 1271 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1272 1273 r = MsiEvaluateConditionA(hpkg, "-1"); 1274 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1275 1276 r = MsiEvaluateConditionA(hpkg, "0 = 0"); 1277 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1278 1279 r = MsiEvaluateConditionA(hpkg, "0 <> 0"); 1280 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1281 1282 r = MsiEvaluateConditionA(hpkg, "0 = 1"); 1283 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1284 1285 r = MsiEvaluateConditionA(hpkg, "0 > 1"); 1286 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1287 1288 r = MsiEvaluateConditionA(hpkg, "0 ~> 1"); 1289 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1290 1291 r = MsiEvaluateConditionA(hpkg, "1 > 1"); 1292 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1293 1294 r = MsiEvaluateConditionA(hpkg, "1 ~> 1"); 1295 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1296 1297 r = MsiEvaluateConditionA(hpkg, "0 >= 1"); 1298 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1299 1300 r = MsiEvaluateConditionA(hpkg, "0 ~>= 1"); 1301 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1302 1303 r = MsiEvaluateConditionA(hpkg, "1 >= 1"); 1304 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1305 1306 r = MsiEvaluateConditionA(hpkg, "1 ~>= 1"); 1307 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1308 1309 r = MsiEvaluateConditionA(hpkg, "0 < 1"); 1310 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1311 1312 r = MsiEvaluateConditionA(hpkg, "0 ~< 1"); 1313 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1314 1315 r = MsiEvaluateConditionA(hpkg, "1 < 1"); 1316 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1317 1318 r = MsiEvaluateConditionA(hpkg, "1 ~< 1"); 1319 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1320 1321 r = MsiEvaluateConditionA(hpkg, "0 <= 1"); 1322 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1323 1324 r = MsiEvaluateConditionA(hpkg, "0 ~<= 1"); 1325 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1326 1327 r = MsiEvaluateConditionA(hpkg, "1 <= 1"); 1328 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1329 1330 r = MsiEvaluateConditionA(hpkg, "1 ~<= 1"); 1331 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1332 1333 r = MsiEvaluateConditionA(hpkg, "0 >="); 1334 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1335 1336 r = MsiEvaluateConditionA(hpkg, " "); 1337 ok( r == MSICONDITION_NONE, "wrong return val\n"); 1338 1339 r = MsiEvaluateConditionA(hpkg, "LicView <> \"1\""); 1340 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1341 1342 r = MsiEvaluateConditionA(hpkg, "LicView <> \"0\""); 1343 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1344 1345 r = MsiEvaluateConditionA(hpkg, "LicView <> LicView"); 1346 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1347 1348 r = MsiEvaluateConditionA(hpkg, "not 0"); 1349 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1350 1351 r = MsiEvaluateConditionA(hpkg, "not LicView"); 1352 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1353 1354 r = MsiEvaluateConditionA(hpkg, "\"Testing\" ~<< \"Testing\""); 1355 ok (r == MSICONDITION_TRUE, "wrong return val\n"); 1356 1357 r = MsiEvaluateConditionA(hpkg, "LicView ~<< \"Testing\""); 1358 ok (r == MSICONDITION_FALSE, "wrong return val\n"); 1359 1360 r = MsiEvaluateConditionA(hpkg, "Not LicView ~<< \"Testing\""); 1361 ok (r == MSICONDITION_TRUE, "wrong return val\n"); 1362 1363 r = MsiEvaluateConditionA(hpkg, "not \"A\""); 1364 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1365 1366 r = MsiEvaluateConditionA(hpkg, "~not \"A\""); 1367 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1368 1369 r = MsiEvaluateConditionA(hpkg, "\"0\""); 1370 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1371 1372 r = MsiEvaluateConditionA(hpkg, "1 and 2"); 1373 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1374 1375 r = MsiEvaluateConditionA(hpkg, "not 0 and 3"); 1376 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1377 1378 r = MsiEvaluateConditionA(hpkg, "not 0 and 0"); 1379 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1380 1381 r = MsiEvaluateConditionA(hpkg, "not 0 or 1"); 1382 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1383 1384 r = MsiEvaluateConditionA(hpkg, "(0)"); 1385 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1386 1387 r = MsiEvaluateConditionA(hpkg, "(((((1))))))"); 1388 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1389 1390 r = MsiEvaluateConditionA(hpkg, "(((((1)))))"); 1391 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1392 1393 r = MsiEvaluateConditionA(hpkg, " \"A\" < \"B\" "); 1394 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1395 1396 r = MsiEvaluateConditionA(hpkg, " \"A\" > \"B\" "); 1397 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1398 1399 r = MsiEvaluateConditionA(hpkg, " \"1\" > \"12\" "); 1400 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1401 1402 r = MsiEvaluateConditionA(hpkg, " \"100\" < \"21\" "); 1403 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1404 1405 r = MsiEvaluateConditionA(hpkg, "0 < > 0"); 1406 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1407 1408 r = MsiEvaluateConditionA(hpkg, "(1<<1) == 2"); 1409 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1410 1411 r = MsiEvaluateConditionA(hpkg, " \"A\" = \"a\" "); 1412 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1413 1414 r = MsiEvaluateConditionA(hpkg, " \"A\" ~ = \"a\" "); 1415 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1416 1417 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= \"a\" "); 1418 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1419 1420 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= 1 "); 1421 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1422 1423 r = MsiEvaluateConditionA(hpkg, " \"A\" = 1 "); 1424 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1425 1426 r = MsiEvaluateConditionA(hpkg, " 1 ~= 1 "); 1427 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1428 1429 r = MsiEvaluateConditionA(hpkg, " 1 ~= \"1\" "); 1430 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1431 1432 r = MsiEvaluateConditionA(hpkg, " 1 = \"1\" "); 1433 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1434 1435 r = MsiEvaluateConditionA(hpkg, " 0 = \"1\" "); 1436 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1437 1438 r = MsiEvaluateConditionA(hpkg, " 0 < \"100\" "); 1439 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1440 1441 r = MsiEvaluateConditionA(hpkg, " 100 > \"0\" "); 1442 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1443 1444 r = MsiEvaluateConditionA(hpkg, "1 XOR 1"); 1445 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1446 1447 r = MsiEvaluateConditionA(hpkg, "1 IMP 1"); 1448 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1449 1450 r = MsiEvaluateConditionA(hpkg, "1 IMP 0"); 1451 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1452 1453 r = MsiEvaluateConditionA(hpkg, "0 IMP 0"); 1454 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1455 1456 r = MsiEvaluateConditionA(hpkg, "0 EQV 0"); 1457 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1458 1459 r = MsiEvaluateConditionA(hpkg, "0 EQV 1"); 1460 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1461 1462 r = MsiEvaluateConditionA(hpkg, "1 IMP 1 OR 0"); 1463 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1464 1465 r = MsiEvaluateConditionA(hpkg, "1 IMPL 1"); 1466 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1467 1468 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" >< \"S\" "); 1469 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1470 1471 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"s\" "); 1472 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1473 1474 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"\" "); 1475 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1476 1477 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"sss\" "); 1478 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1479 1480 MsiSetPropertyA(hpkg, "mm", "5" ); 1481 1482 r = MsiEvaluateConditionA(hpkg, "mm = 5"); 1483 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1484 1485 r = MsiEvaluateConditionA(hpkg, "mm < 6"); 1486 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1487 1488 r = MsiEvaluateConditionA(hpkg, "mm <= 5"); 1489 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1490 1491 r = MsiEvaluateConditionA(hpkg, "mm > 4"); 1492 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1493 1494 r = MsiEvaluateConditionA(hpkg, "mm < 12"); 1495 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1496 1497 r = MsiEvaluateConditionA(hpkg, "mm = \"5\""); 1498 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1499 1500 r = MsiEvaluateConditionA(hpkg, "0 = \"\""); 1501 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1502 1503 r = MsiEvaluateConditionA(hpkg, "0 AND \"\""); 1504 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1505 1506 r = MsiEvaluateConditionA(hpkg, "1 AND \"\""); 1507 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1508 1509 r = MsiEvaluateConditionA(hpkg, "1 AND \"1\""); 1510 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1511 1512 r = MsiEvaluateConditionA(hpkg, "3 >< 1"); 1513 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1514 1515 r = MsiEvaluateConditionA(hpkg, "3 >< 4"); 1516 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1517 1518 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 0"); 1519 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1520 1521 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1"); 1522 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1523 1524 r = MsiEvaluateConditionA(hpkg, "NOT 1 OR 0"); 1525 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1526 1527 r = MsiEvaluateConditionA(hpkg, "0 AND 1 OR 1"); 1528 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1529 1530 r = MsiEvaluateConditionA(hpkg, "0 AND 0 OR 1"); 1531 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1532 1533 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1 OR 0"); 1534 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1535 1536 r = MsiEvaluateConditionA(hpkg, "_1 = _1"); 1537 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1538 1539 r = MsiEvaluateConditionA(hpkg, "( 1 AND 1 ) = 2"); 1540 ok( r == MSICONDITION_ERROR, "wrong return val\n"); 1541 1542 r = MsiEvaluateConditionA(hpkg, "NOT ( 1 AND 1 )"); 1543 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1544 1545 r = MsiEvaluateConditionA(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd"); 1546 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1547 1548 r = MsiEvaluateConditionA(hpkg, "Installed<>\"\""); 1549 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1550 1551 r = MsiEvaluateConditionA(hpkg, "NOT 1 AND 0"); 1552 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1553 1554 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1555 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1556 1557 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0"); 1558 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1559 1560 r = MsiEvaluateConditionA(hpkg, "bandalmael<0"); 1561 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1562 1563 r = MsiEvaluateConditionA(hpkg, "bandalmael>0"); 1564 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1565 1566 r = MsiEvaluateConditionA(hpkg, "bandalmael>=0"); 1567 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1568 1569 r = MsiEvaluateConditionA(hpkg, "bandalmael<=0"); 1570 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1571 1572 r = MsiEvaluateConditionA(hpkg, "bandalmael~<>0"); 1573 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1574 1575 MsiSetPropertyA(hpkg, "bandalmael", "0" ); 1576 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1577 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1578 1579 MsiSetPropertyA(hpkg, "bandalmael", "" ); 1580 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1581 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1582 1583 MsiSetPropertyA(hpkg, "bandalmael", "asdf" ); 1584 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1585 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1586 1587 MsiSetPropertyA(hpkg, "bandalmael", "0asdf" ); 1588 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1589 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1590 1591 MsiSetPropertyA(hpkg, "bandalmael", "0 " ); 1592 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1593 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1594 1595 MsiSetPropertyA(hpkg, "bandalmael", "-0" ); 1596 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1597 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1598 1599 MsiSetPropertyA(hpkg, "bandalmael", "0000000000000" ); 1600 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1601 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1602 1603 MsiSetPropertyA(hpkg, "bandalmael", "--0" ); 1604 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1605 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1606 1607 MsiSetPropertyA(hpkg, "bandalmael", "0x00" ); 1608 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1609 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1610 1611 MsiSetPropertyA(hpkg, "bandalmael", "-" ); 1612 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1613 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1614 1615 MsiSetPropertyA(hpkg, "bandalmael", "+0" ); 1616 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1617 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1618 1619 MsiSetPropertyA(hpkg, "bandalmael", "0.0" ); 1620 r = MsiEvaluateConditionA(hpkg, "bandalmael=0"); 1621 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1622 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0"); 1623 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1624 1625 MsiSetPropertyA(hpkg, "one", "hi"); 1626 MsiSetPropertyA(hpkg, "two", "hithere"); 1627 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1628 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1629 1630 MsiSetPropertyA(hpkg, "one", "hithere"); 1631 MsiSetPropertyA(hpkg, "two", "hi"); 1632 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1633 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1634 1635 MsiSetPropertyA(hpkg, "one", "hello"); 1636 MsiSetPropertyA(hpkg, "two", "hi"); 1637 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1638 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1639 1640 MsiSetPropertyA(hpkg, "one", "hellohithere"); 1641 MsiSetPropertyA(hpkg, "two", "hi"); 1642 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1643 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1644 1645 MsiSetPropertyA(hpkg, "one", ""); 1646 MsiSetPropertyA(hpkg, "two", "hi"); 1647 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1648 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1649 1650 MsiSetPropertyA(hpkg, "one", "hi"); 1651 MsiSetPropertyA(hpkg, "two", ""); 1652 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1653 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1654 1655 MsiSetPropertyA(hpkg, "one", ""); 1656 MsiSetPropertyA(hpkg, "two", ""); 1657 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1658 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1659 1660 MsiSetPropertyA(hpkg, "one", "1234"); 1661 MsiSetPropertyA(hpkg, "two", "1"); 1662 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1663 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1664 1665 MsiSetPropertyA(hpkg, "one", "one 1234"); 1666 MsiSetPropertyA(hpkg, "two", "1"); 1667 r = MsiEvaluateConditionA(hpkg, "one >< two"); 1668 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1669 1670 MsiSetPropertyA(hpkg, "one", "hithere"); 1671 MsiSetPropertyA(hpkg, "two", "hi"); 1672 r = MsiEvaluateConditionA(hpkg, "one << two"); 1673 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1674 1675 MsiSetPropertyA(hpkg, "one", "hi"); 1676 MsiSetPropertyA(hpkg, "two", "hithere"); 1677 r = MsiEvaluateConditionA(hpkg, "one << two"); 1678 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1679 1680 MsiSetPropertyA(hpkg, "one", "hi"); 1681 MsiSetPropertyA(hpkg, "two", "hi"); 1682 r = MsiEvaluateConditionA(hpkg, "one << two"); 1683 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1684 1685 MsiSetPropertyA(hpkg, "one", "abcdhithere"); 1686 MsiSetPropertyA(hpkg, "two", "hi"); 1687 r = MsiEvaluateConditionA(hpkg, "one << two"); 1688 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1689 1690 MsiSetPropertyA(hpkg, "one", ""); 1691 MsiSetPropertyA(hpkg, "two", "hi"); 1692 r = MsiEvaluateConditionA(hpkg, "one << two"); 1693 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1694 1695 MsiSetPropertyA(hpkg, "one", "hithere"); 1696 MsiSetPropertyA(hpkg, "two", ""); 1697 r = MsiEvaluateConditionA(hpkg, "one << two"); 1698 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1699 1700 MsiSetPropertyA(hpkg, "one", ""); 1701 MsiSetPropertyA(hpkg, "two", ""); 1702 r = MsiEvaluateConditionA(hpkg, "one << two"); 1703 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1704 1705 MsiSetPropertyA(hpkg, "one", "1234"); 1706 MsiSetPropertyA(hpkg, "two", "1"); 1707 r = MsiEvaluateConditionA(hpkg, "one << two"); 1708 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1709 1710 MsiSetPropertyA(hpkg, "one", "1234 one"); 1711 MsiSetPropertyA(hpkg, "two", "1"); 1712 r = MsiEvaluateConditionA(hpkg, "one << two"); 1713 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1714 1715 MsiSetPropertyA(hpkg, "one", "hithere"); 1716 MsiSetPropertyA(hpkg, "two", "there"); 1717 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1718 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1719 1720 MsiSetPropertyA(hpkg, "one", "hithere"); 1721 MsiSetPropertyA(hpkg, "two", "hi"); 1722 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1723 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1724 1725 MsiSetPropertyA(hpkg, "one", "there"); 1726 MsiSetPropertyA(hpkg, "two", "hithere"); 1727 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1728 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1729 1730 MsiSetPropertyA(hpkg, "one", "there"); 1731 MsiSetPropertyA(hpkg, "two", "there"); 1732 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1733 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1734 1735 MsiSetPropertyA(hpkg, "one", "abcdhithere"); 1736 MsiSetPropertyA(hpkg, "two", "hi"); 1737 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1738 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1739 1740 MsiSetPropertyA(hpkg, "one", ""); 1741 MsiSetPropertyA(hpkg, "two", "there"); 1742 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1743 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1744 1745 MsiSetPropertyA(hpkg, "one", "there"); 1746 MsiSetPropertyA(hpkg, "two", ""); 1747 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1748 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1749 1750 MsiSetPropertyA(hpkg, "one", ""); 1751 MsiSetPropertyA(hpkg, "two", ""); 1752 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1753 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1754 1755 MsiSetPropertyA(hpkg, "one", "1234"); 1756 MsiSetPropertyA(hpkg, "two", "4"); 1757 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1758 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1759 1760 MsiSetPropertyA(hpkg, "one", "one 1234"); 1761 MsiSetPropertyA(hpkg, "two", "4"); 1762 r = MsiEvaluateConditionA(hpkg, "one >> two"); 1763 ok( r == MSICONDITION_TRUE, "wrong return val\n"); 1764 1765 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", NULL); /* make sure it's empty */ 1766 1767 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\""); 1768 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1769 1770 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport > \"1.1.4322\""); 1771 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1772 1773 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\""); 1774 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1775 1776 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\""); 1777 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1778 1779 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\""); 1780 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1781 1782 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\""); 1783 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1784 1785 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"abcd\""); 1786 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1787 1788 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\""); 1789 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1790 1791 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\""); 1792 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1793 1794 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\""); 1795 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1796 1797 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\""); 1798 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1799 1800 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\""); 1801 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1802 1803 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1"); 1804 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r); 1805 1806 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1\""); 1807 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1808 1809 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"12.1\""); 1810 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1811 1812 r = MsiEvaluateConditionA(hpkg, "\"02.1\" < \"2.11\""); 1813 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1814 1815 r = MsiEvaluateConditionA(hpkg, "\"02.1.1\" < \"2.1\""); 1816 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1817 1818 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\""); 1819 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1820 1821 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\""); 1822 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1823 1824 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0\""); 1825 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1826 1827 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"-1\""); 1828 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1829 1830 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a\""); 1831 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1832 1833 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\""); 1834 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1835 1836 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\""); 1837 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1838 1839 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"/\""); 1840 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1841 1842 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \" \""); 1843 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1844 1845 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"azAZ_\""); 1846 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1847 1848 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]\""); 1849 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1850 1851 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]a\""); 1852 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1853 1854 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]\""); 1855 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1856 1857 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]a\""); 1858 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1859 1860 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a}\""); 1861 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1862 1863 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a\""); 1864 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1865 1866 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a\""); 1867 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1868 1869 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a{\""); 1870 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1871 1872 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a]\""); 1873 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1874 1875 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"A\""); 1876 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1877 1878 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", "1.1.4322"); 1879 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\""); 1880 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1881 1882 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.14322\""); 1883 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1884 1885 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.5\""); 1886 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1887 1888 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\""); 1889 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1890 1891 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\""); 1892 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1893 1894 MsiSetPropertyA(hpkg, "one", "1"); 1895 r = MsiEvaluateConditionA(hpkg, "one < \"1\""); 1896 ok( r == MSICONDITION_FALSE, "wrong return val\n"); 1897 1898 MsiSetPropertyA(hpkg, "X", "5.0"); 1899 1900 r = MsiEvaluateConditionA(hpkg, "X != \"\""); 1901 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r); 1902 1903 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\""); 1904 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1905 1906 r = MsiEvaluateConditionA(hpkg, "X =\"5.1\""); 1907 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1908 1909 r = MsiEvaluateConditionA(hpkg, "X =\"6.0\""); 1910 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1911 1912 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\""); 1913 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1914 1915 r = MsiEvaluateConditionA(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")"); 1916 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1917 1918 r = MsiEvaluateConditionA(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")"); 1919 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r); 1920 1921 /* feature doesn't exist */ 1922 r = MsiEvaluateConditionA(hpkg, "&nofeature"); 1923 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1924 r = MsiEvaluateConditionA(hpkg, "&nofeature=\"\""); 1925 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1926 r = MsiEvaluateConditionA(hpkg, "&nofeature<>3"); 1927 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1928 r = MsiEvaluateConditionA(hpkg, "\"\"<>3"); 1929 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1930 r = MsiEvaluateConditionA(hpkg, "!nofeature=\"\""); 1931 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1932 r = MsiEvaluateConditionA(hpkg, "$nocomponent=\"\""); 1933 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1934 r = MsiEvaluateConditionA(hpkg, "?nocomponent=\"\""); 1935 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1936 1937 MsiSetPropertyA(hpkg, "A", "2"); 1938 MsiSetPropertyA(hpkg, "X", "50"); 1939 1940 r = MsiEvaluateConditionA(hpkg, "2 <= X"); 1941 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1942 1943 r = MsiEvaluateConditionA(hpkg, "A <= X"); 1944 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1945 1946 r = MsiEvaluateConditionA(hpkg, "A <= 50"); 1947 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1948 1949 MsiSetPropertyA(hpkg, "X", "50val"); 1950 1951 r = MsiEvaluateConditionA(hpkg, "2 <= X"); 1952 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1953 1954 r = MsiEvaluateConditionA(hpkg, "A <= X"); 1955 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1956 1957 MsiSetPropertyA(hpkg, "A", "7"); 1958 MsiSetPropertyA(hpkg, "X", "50"); 1959 1960 r = MsiEvaluateConditionA(hpkg, "7 <= X"); 1961 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1962 1963 r = MsiEvaluateConditionA(hpkg, "A <= X"); 1964 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1965 1966 r = MsiEvaluateConditionA(hpkg, "A <= 50"); 1967 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1968 1969 MsiSetPropertyA(hpkg, "X", "50val"); 1970 1971 r = MsiEvaluateConditionA(hpkg, "2 <= X"); 1972 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1973 1974 r = MsiEvaluateConditionA(hpkg, "A <= X"); 1975 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1976 1977 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<\"\xe5\""); 1978 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1979 1980 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\">\"\xe5\""); 1981 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1982 1983 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<>\"\xe5\""); 1984 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); 1985 1986 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"=\"\xe5\""); 1987 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); 1988 1989 MsiCloseHandle( hpkg ); 1990 DeleteFileA(msifile); 1991 } 1992 1993 static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case, int todo_value) 1994 { 1995 char buffer[MAX_PATH] = "x"; 1996 DWORD sz = sizeof(buffer); 1997 UINT r = MsiGetPropertyA(hpkg, prop, buffer, &sz); 1998 ok(!r, "'%s': got %u\n", prop, r); 1999 ok(sz == lstrlenA(buffer), "'%s': expected %u, got %lu\n", prop, lstrlenA(buffer), sz); 2000 if (match_case) 2001 todo_wine_if (todo_value) ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer); 2002 else 2003 todo_wine_if (todo_value) ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer); 2004 } 2005 2006 static void test_props(void) 2007 { 2008 MSIHANDLE hpkg, hdb; 2009 UINT r; 2010 DWORD sz; 2011 char buffer[0x100]; 2012 WCHAR bufferW[10]; 2013 2014 hdb = create_package_db(); 2015 2016 create_property_table(hdb); 2017 add_property_entry(hdb, "'MetadataCompName', 'Photoshop.dll'"); 2018 2019 r = package_from_db( hdb, &hpkg ); 2020 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2021 { 2022 skip("Not enough rights to perform tests\n"); 2023 DeleteFileA(msifile); 2024 return; 2025 } 2026 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 2027 2028 /* test invalid values */ 2029 r = MsiGetPropertyA( 0, NULL, NULL, NULL ); 2030 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2031 2032 r = MsiGetPropertyA( hpkg, NULL, NULL, NULL ); 2033 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2034 2035 r = MsiGetPropertyA( hpkg, "boo", NULL, NULL ); 2036 ok(!r, "got %u\n", r); 2037 2038 r = MsiGetPropertyA( hpkg, "boo", buffer, NULL ); 2039 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2040 2041 /* test retrieving an empty/nonexistent property */ 2042 sz = sizeof buffer; 2043 r = MsiGetPropertyA( hpkg, "boo", NULL, &sz ); 2044 ok(!r, "got %u\n", r); 2045 ok(sz == 0, "got size %lu\n", sz); 2046 2047 sz = 0; 2048 strcpy(buffer,"x"); 2049 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2050 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2051 ok(!strcmp(buffer,"x"), "got \"%s\"\n", buffer); 2052 ok(sz == 0, "got size %lu\n", sz); 2053 2054 sz = 1; 2055 strcpy(buffer,"x"); 2056 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2057 ok(!r, "got %u\n", r); 2058 ok(!buffer[0], "got \"%s\"\n", buffer); 2059 ok(sz == 0, "got size %lu\n", sz); 2060 2061 /* set the property to something */ 2062 r = MsiSetPropertyA( 0, NULL, NULL ); 2063 ok(r == ERROR_INVALID_HANDLE, "got %u\n", r); 2064 2065 r = MsiSetPropertyA( hpkg, NULL, NULL ); 2066 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2067 2068 r = MsiSetPropertyA( hpkg, "", NULL ); 2069 ok(!r, "got %u\n", r); 2070 2071 r = MsiSetPropertyA( hpkg, "", "asdf" ); 2072 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); 2073 2074 r = MsiSetPropertyA( hpkg, "=", "asdf" ); 2075 ok(!r, "got %u\n", r); 2076 check_prop(hpkg, "=", "asdf", 1, 0); 2077 2078 r = MsiSetPropertyA( hpkg, " ", "asdf" ); 2079 ok(!r, "got %u\n", r); 2080 check_prop(hpkg, " ", "asdf", 1, 0); 2081 2082 r = MsiSetPropertyA( hpkg, "'", "asdf" ); 2083 ok(!r, "got %u\n", r); 2084 check_prop(hpkg, "'", "asdf", 1, 0); 2085 2086 /* set empty values */ 2087 r = MsiSetPropertyA( hpkg, "boo", NULL ); 2088 ok(!r, "got %u\n", r); 2089 check_prop(hpkg, "boo", "", 1, 0); 2090 2091 r = MsiSetPropertyA( hpkg, "boo", "" ); 2092 ok(!r, "got %u\n", r); 2093 check_prop(hpkg, "boo", "", 1, 0); 2094 2095 /* set a non-empty value */ 2096 r = MsiSetPropertyA( hpkg, "boo", "xyz" ); 2097 ok(!r, "got %u\n", r); 2098 check_prop(hpkg, "boo", "xyz", 1, 0); 2099 2100 r = MsiGetPropertyA(hpkg, "boo", NULL, NULL); 2101 ok(!r, "got %u\n", r); 2102 2103 r = MsiGetPropertyA(hpkg, "boo", buffer, NULL); 2104 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r); 2105 2106 sz = 0; 2107 r = MsiGetPropertyA(hpkg, "boo", NULL, &sz); 2108 ok(!r, "got %u\n", r); 2109 ok(sz == 3, "got size %lu\n", sz); 2110 2111 sz = 0; 2112 strcpy(buffer, "q"); 2113 r = MsiGetPropertyA(hpkg, "boo", buffer, &sz); 2114 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2115 ok(!strcmp(buffer, "q"), "got \"%s\"", buffer); 2116 ok(sz == 3, "got size %lu\n", sz); 2117 2118 sz = 1; 2119 strcpy(buffer,"x"); 2120 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2121 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2122 ok(!buffer[0], "got \"%s\"\n", buffer); 2123 ok(sz == 3, "got size %lu\n", sz); 2124 2125 sz = 3; 2126 strcpy(buffer,"x"); 2127 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2128 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2129 ok(!strcmp(buffer,"xy"), "got \"%s\"\n", buffer); 2130 ok(sz == 3, "got size %lu\n", sz); 2131 2132 sz = 4; 2133 strcpy(buffer,"x"); 2134 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz ); 2135 ok(!r, "got %u\n", r); 2136 ok(!strcmp(buffer,"xyz"), "got \"%s\"\n", buffer); 2137 ok(sz == 3, "got size %lu\n", sz); 2138 2139 sz = 0; 2140 r = MsiGetPropertyW(hpkg, L"boo", NULL, &sz); 2141 ok(!r, "got %u\n", r); 2142 ok(sz == 3, "got size %lu\n", sz); 2143 2144 sz = 0; 2145 lstrcpyW(bufferW, L"boo"); 2146 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz); 2147 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2148 ok(!lstrcmpW(bufferW, L"boo"), "got %s\n", wine_dbgstr_w(bufferW)); 2149 ok(sz == 3, "got size %lu\n", sz); 2150 2151 sz = 1; 2152 lstrcpyW(bufferW, L"boo"); 2153 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz ); 2154 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2155 ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW)); 2156 ok(sz == 3, "got size %lu\n", sz); 2157 2158 sz = 3; 2159 lstrcpyW(bufferW, L"boo"); 2160 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz ); 2161 ok(r == ERROR_MORE_DATA, "got %u\n", r); 2162 ok(!lstrcmpW(bufferW, L"xy"), "got %s\n", wine_dbgstr_w(bufferW)); 2163 ok(sz == 3, "got size %lu\n", sz); 2164 2165 sz = 4; 2166 lstrcpyW(bufferW, L"boo"); 2167 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz ); 2168 ok(!r, "got %u\n", r); 2169 ok(!lstrcmpW(bufferW, L"xyz"), "got %s\n", wine_dbgstr_w(bufferW)); 2170 ok(sz == 3, "got size %lu\n", sz); 2171 2172 /* properties are case-sensitive */ 2173 check_prop(hpkg, "BOO", "", 1, 0); 2174 2175 /* properties set in Property table should work */ 2176 check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1, 0); 2177 2178 MsiCloseHandle( hpkg ); 2179 DeleteFileA(msifile); 2180 } 2181 2182 static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len) 2183 { 2184 MSIHANDLE hview, hrec; 2185 BOOL found = FALSE; 2186 CHAR buffer[MAX_PATH]; 2187 DWORD sz; 2188 UINT r; 2189 2190 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview); 2191 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 2192 r = MsiViewExecute(hview, 0); 2193 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 2194 2195 if (len < 0) len = lstrlenA(val); 2196 2197 while (r == ERROR_SUCCESS && !found) 2198 { 2199 r = MsiViewFetch(hview, &hrec); 2200 if (r != ERROR_SUCCESS) break; 2201 2202 sz = MAX_PATH; 2203 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 2204 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop)) 2205 { 2206 sz = MAX_PATH; 2207 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 2208 if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len]) 2209 { 2210 ok(sz == len, "wrong size %lu\n", sz); 2211 found = TRUE; 2212 } 2213 } 2214 2215 MsiCloseHandle(hrec); 2216 } 2217 MsiViewClose(hview); 2218 MsiCloseHandle(hview); 2219 return found; 2220 } 2221 2222 static void test_property_table(void) 2223 { 2224 const char *query; 2225 UINT r; 2226 MSIHANDLE hpkg, hdb, hrec; 2227 char buffer[MAX_PATH], package[10]; 2228 DWORD sz; 2229 BOOL found; 2230 2231 hdb = create_package_db(); 2232 ok( hdb, "failed to create package\n"); 2233 2234 r = package_from_db(hdb, &hpkg); 2235 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2236 { 2237 skip("Not enough rights to perform tests\n"); 2238 DeleteFileA(msifile); 2239 return; 2240 } 2241 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 2242 2243 MsiCloseHandle(hdb); 2244 2245 hdb = MsiGetActiveDatabase(hpkg); 2246 2247 query = "CREATE TABLE `_Property` ( " 2248 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 2249 r = run_query(hdb, 0, query); 2250 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2251 2252 MsiCloseHandle(hdb); 2253 MsiCloseHandle(hpkg); 2254 DeleteFileA(msifile); 2255 2256 hdb = create_package_db(); 2257 ok( hdb, "failed to create package\n"); 2258 2259 query = "CREATE TABLE `_Property` ( " 2260 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 2261 r = run_query(hdb, 0, query); 2262 ok(r == ERROR_SUCCESS, "failed to create table\n"); 2263 2264 query = "ALTER `_Property` ADD `foo` INTEGER"; 2265 r = run_query(hdb, 0, query); 2266 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n"); 2267 2268 query = "ALTER TABLE `_Property` ADD `foo` INTEGER"; 2269 r = run_query(hdb, 0, query); 2270 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n"); 2271 2272 query = "ALTER TABLE `_Property` ADD `extra` INTEGER"; 2273 r = run_query(hdb, 0, query); 2274 ok(r == ERROR_SUCCESS, "failed to add column\n"); 2275 2276 sprintf(package, "#%lu", hdb); 2277 r = MsiOpenPackageA(package, &hpkg); 2278 ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n"); 2279 if (r == ERROR_SUCCESS) 2280 MsiCloseHandle(hpkg); 2281 2282 r = MsiCloseHandle(hdb); 2283 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r); 2284 2285 hdb = create_package_db(); 2286 ok (hdb, "failed to create package database\n"); 2287 2288 create_property_table(hdb); 2289 add_property_entry(hdb, "'prop', 'val'"); 2290 2291 create_custom_action_table(hdb); 2292 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" ); 2293 2294 r = package_from_db(hdb, &hpkg); 2295 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 2296 2297 MsiCloseHandle(hdb); 2298 2299 sz = MAX_PATH; 2300 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz); 2301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2302 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer); 2303 2304 hdb = MsiGetActiveDatabase(hpkg); 2305 2306 found = find_prop_in_property(hdb, "prop", "val", -1); 2307 ok(found, "prop should be in the _Property table\n"); 2308 2309 add_property_entry(hdb, "'dantes', 'mercedes'"); 2310 2311 query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'"; 2312 r = do_query(hdb, query, &hrec); 2313 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2314 2315 found = find_prop_in_property(hdb, "dantes", "mercedes", -1); 2316 ok(found == FALSE, "dantes should not be in the _Property table\n"); 2317 2318 sz = MAX_PATH; 2319 lstrcpyA(buffer, "aaa"); 2320 r = MsiGetPropertyA(hpkg, "dantes", buffer, &sz); 2321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2322 ok(!buffer[0], "Expected empty string, got %s\n", buffer); 2323 2324 r = MsiSetPropertyA(hpkg, "dantes", "mercedes"); 2325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2326 2327 found = find_prop_in_property(hdb, "dantes", "mercedes", -1); 2328 ok(found == TRUE, "dantes should be in the _Property table\n"); 2329 2330 r = MsiDoActionA( hpkg, "EmbedNull" ); 2331 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r); 2332 2333 sz = MAX_PATH; 2334 memset( buffer, 'a', sizeof(buffer) ); 2335 r = MsiGetPropertyA( hpkg, "prop2", buffer, &sz ); 2336 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2337 ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n"); 2338 ok( sz == sizeof("\0np") - 1, "got %lu\n", sz ); 2339 2340 found = find_prop_in_property(hdb, "prop2", "\0np", 3); 2341 ok(found == TRUE, "prop2 should be in the _Property table\n"); 2342 2343 MsiCloseHandle(hdb); 2344 MsiCloseHandle(hpkg); 2345 DeleteFileA(msifile); 2346 } 2347 2348 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec ) 2349 { 2350 MSIHANDLE htab = 0; 2351 UINT res; 2352 2353 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab ); 2354 if( res == ERROR_SUCCESS ) 2355 { 2356 UINT r; 2357 2358 r = MsiViewExecute( htab, hrec ); 2359 if( r != ERROR_SUCCESS ) 2360 { 2361 res = r; 2362 fprintf(stderr,"MsiViewExecute failed %08x\n", res); 2363 } 2364 2365 r = MsiViewClose( htab ); 2366 if( r != ERROR_SUCCESS ) 2367 res = r; 2368 2369 r = MsiCloseHandle( htab ); 2370 if( r != ERROR_SUCCESS ) 2371 res = r; 2372 } 2373 return res; 2374 } 2375 2376 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery ) 2377 { 2378 return try_query_param( hdb, szQuery, 0 ); 2379 } 2380 2381 static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value) 2382 { 2383 MSIHANDLE summary; 2384 UINT r; 2385 2386 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary); 2387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2388 2389 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value); 2390 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2391 2392 r = MsiSummaryInfoPersist(summary); 2393 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2394 2395 MsiCloseHandle(summary); 2396 } 2397 2398 static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value) 2399 { 2400 MSIHANDLE summary; 2401 UINT r; 2402 2403 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary); 2404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2405 2406 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL); 2407 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2408 2409 r = MsiSummaryInfoPersist(summary); 2410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2411 2412 MsiCloseHandle(summary); 2413 } 2414 2415 static void test_msipackage(void) 2416 { 2417 MSIHANDLE hdb = 0, hpack = 100; 2418 UINT r; 2419 const char *query; 2420 char name[10]; 2421 2422 /* NULL szPackagePath */ 2423 r = MsiOpenPackageA(NULL, &hpack); 2424 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 2425 2426 /* empty szPackagePath */ 2427 r = MsiOpenPackageA("", &hpack); 2428 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2429 { 2430 skip("Not enough rights to perform tests\n"); 2431 return; 2432 } 2433 todo_wine 2434 { 2435 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2436 } 2437 2438 if (r == ERROR_SUCCESS) 2439 MsiCloseHandle(hpack); 2440 2441 /* nonexistent szPackagePath */ 2442 r = MsiOpenPackageA("nonexistent", &hpack); 2443 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r); 2444 2445 /* NULL hProduct */ 2446 r = MsiOpenPackageA(msifile, NULL); 2447 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 2448 2449 name[0]='#'; 2450 name[1]=0; 2451 r = MsiOpenPackageA(name, &hpack); 2452 ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r); 2453 2454 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2456 2457 /* database exists, but is empty */ 2458 sprintf(name, "#%lu", hdb); 2459 r = MsiOpenPackageA(name, &hpack); 2460 ok(r == ERROR_INSTALL_PACKAGE_INVALID, 2461 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r); 2462 2463 query = "CREATE TABLE `Property` ( " 2464 "`Property` CHAR(72), `Value` CHAR(0) " 2465 "PRIMARY KEY `Property`)"; 2466 r = try_query(hdb, query); 2467 ok(r == ERROR_SUCCESS, "failed to create Properties table\n"); 2468 2469 query = "CREATE TABLE `InstallExecuteSequence` (" 2470 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER " 2471 "PRIMARY KEY `Action`)"; 2472 r = try_query(hdb, query); 2473 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n"); 2474 2475 /* a few key tables exist */ 2476 sprintf(name, "#%lu", hdb); 2477 r = MsiOpenPackageA(name, &hpack); 2478 ok(r == ERROR_INSTALL_PACKAGE_INVALID, 2479 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r); 2480 2481 MsiCloseHandle(hdb); 2482 DeleteFileA(msifile); 2483 2484 /* start with a clean database to show what constitutes a valid package */ 2485 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2487 2488 sprintf(name, "#%lu", hdb); 2489 2490 /* The following summary information props must exist: 2491 * - PID_REVNUMBER 2492 * - PID_PAGECOUNT 2493 */ 2494 2495 set_summary_dword(hdb, PID_PAGECOUNT, 100); 2496 r = MsiOpenPackageA(name, &hpack); 2497 ok(r == ERROR_INSTALL_PACKAGE_INVALID, 2498 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r); 2499 2500 set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}"); 2501 r = MsiOpenPackageA(name, &hpack); 2502 ok(r == ERROR_SUCCESS, 2503 "Expected ERROR_SUCCESS, got %d\n", r); 2504 2505 MsiCloseHandle(hpack); 2506 MsiCloseHandle(hdb); 2507 DeleteFileA(msifile); 2508 } 2509 2510 static void test_formatrecord2(void) 2511 { 2512 MSIHANDLE hpkg, hrec ; 2513 char buffer[0x100]; 2514 DWORD sz; 2515 UINT r; 2516 2517 r = package_from_db(create_package_db(), &hpkg); 2518 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2519 { 2520 skip("Not enough rights to perform tests\n"); 2521 DeleteFileA(msifile); 2522 return; 2523 } 2524 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); 2525 2526 r = MsiSetPropertyA(hpkg, "Manufacturer", " " ); 2527 ok( r == ERROR_SUCCESS, "set property failed\n"); 2528 2529 hrec = MsiCreateRecord(2); 2530 ok(hrec, "create record failed\n"); 2531 2532 r = MsiRecordSetStringA( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf"); 2533 ok( r == ERROR_SUCCESS, "format record failed\n"); 2534 2535 buffer[0] = 0; 2536 sz = sizeof buffer; 2537 r = MsiFormatRecordA( hpkg, hrec, buffer, &sz ); 2538 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2539 2540 r = MsiRecordSetStringA(hrec, 0, "[foo][1]"); 2541 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2542 r = MsiRecordSetStringA(hrec, 1, "hoo"); 2543 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2544 sz = sizeof buffer; 2545 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2546 ok( sz == 3, "size wrong\n"); 2547 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer); 2548 ok( r == ERROR_SUCCESS, "format failed\n"); 2549 2550 r = MsiRecordSetStringA(hrec, 0, "x[~]x"); 2551 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2552 sz = sizeof buffer; 2553 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2554 ok( sz == 3, "size wrong\n"); 2555 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer); 2556 ok( r == ERROR_SUCCESS, "format failed\n"); 2557 2558 r = MsiRecordSetStringA(hrec, 0, "[foo.$%}][1]"); 2559 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2560 r = MsiRecordSetStringA(hrec, 1, "hoo"); 2561 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2562 sz = sizeof buffer; 2563 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2564 ok( sz == 3, "size wrong\n"); 2565 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer); 2566 ok( r == ERROR_SUCCESS, "format failed\n"); 2567 2568 r = MsiRecordSetStringA(hrec, 0, "[\\[]"); 2569 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2570 sz = sizeof buffer; 2571 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2572 ok( sz == 1, "size wrong\n"); 2573 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer); 2574 ok( r == ERROR_SUCCESS, "format failed\n"); 2575 2576 SetEnvironmentVariableA("FOO", "BAR"); 2577 r = MsiRecordSetStringA(hrec, 0, "[%FOO]"); 2578 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2579 sz = sizeof buffer; 2580 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2581 ok( sz == 3, "size wrong\n"); 2582 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer); 2583 ok( r == ERROR_SUCCESS, "format failed\n"); 2584 2585 r = MsiRecordSetStringA(hrec, 0, "[[1]]"); 2586 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2587 r = MsiRecordSetStringA(hrec, 1, "%FOO"); 2588 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 2589 sz = sizeof buffer; 2590 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz); 2591 ok( sz == 3, "size wrong\n"); 2592 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer); 2593 ok( r == ERROR_SUCCESS, "format failed\n"); 2594 2595 MsiCloseHandle( hrec ); 2596 MsiCloseHandle( hpkg ); 2597 DeleteFileA(msifile); 2598 } 2599 2600 static void test_formatrecord_tables(void) 2601 { 2602 MSIHANDLE hdb, hrec, hpkg = 0; 2603 CHAR buf[MAX_PATH + 41]; 2604 CHAR curr_dir[MAX_PATH]; 2605 CHAR expected[MAX_PATH + 45]; 2606 CHAR root[MAX_PATH]; 2607 DWORD size; 2608 UINT r; 2609 2610 GetCurrentDirectoryA( MAX_PATH, curr_dir ); 2611 2612 hdb = create_package_db(); 2613 ok ( hdb, "failed to create package database\n"); 2614 2615 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); 2616 add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', " 2617 "'I am a really long directory'" ); 2618 2619 create_feature_table( hdb ); 2620 add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" ); 2621 2622 create_component_table( hdb ); 2623 add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" ); 2624 add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" ); 2625 add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" ); 2626 2627 create_feature_components_table( hdb ); 2628 add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" ); 2629 add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" ); 2630 add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" ); 2631 2632 create_file_table( hdb ); 2633 add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" ); 2634 add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" ); 2635 add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" ); 2636 2637 create_custom_action_table( hdb ); 2638 add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" ); 2639 add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" ); 2640 add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" ); 2641 add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" ); 2642 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" ); 2643 2644 r = package_from_db( hdb, &hpkg ); 2645 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 2646 { 2647 skip("Not enough rights to perform tests\n"); 2648 MsiCloseHandle( hdb ); 2649 DeleteFileA( msifile ); 2650 return; 2651 } 2652 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 2653 2654 MsiCloseHandle( hdb ); 2655 2656 r = MsiSetPropertyA( hpkg, "imaprop", "ringer" ); 2657 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r); 2658 2659 hrec = MsiCreateRecord( 1 ); 2660 2661 /* property doesn't exist */ 2662 size = MAX_PATH; 2663 /*MsiRecordSetStringA( hrec, 0, "[1]" ); */ 2664 MsiRecordSetStringA( hrec, 1, "[idontexist]" ); 2665 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2666 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2667 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); 2668 2669 /* property exists */ 2670 size = MAX_PATH; 2671 MsiRecordSetStringA( hrec, 1, "[imaprop]" ); 2672 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2673 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2674 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf ); 2675 2676 size = MAX_PATH; 2677 MsiRecordSetStringA( hrec, 0, "1: [1] " ); 2678 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2679 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2680 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf ); 2681 2682 /* environment variable doesn't exist */ 2683 size = MAX_PATH; 2684 MsiRecordSetStringA( hrec, 1, "[%idontexist]" ); 2685 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2686 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2687 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); 2688 2689 /* environment variable exists */ 2690 size = MAX_PATH; 2691 SetEnvironmentVariableA( "crazyvar", "crazyval" ); 2692 MsiRecordSetStringA( hrec, 1, "[%crazyvar]" ); 2693 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2694 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2695 ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf ); 2696 2697 /* file key before CostInitialize */ 2698 size = MAX_PATH; 2699 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" ); 2700 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2701 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2702 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); 2703 2704 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 2705 2706 r = MsiDoActionA(hpkg, "CostInitialize"); 2707 ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r); 2708 2709 r = MsiDoActionA(hpkg, "FileCost"); 2710 ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r); 2711 2712 r = MsiDoActionA(hpkg, "CostFinalize"); 2713 ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r); 2714 2715 size = MAX_PATH; 2716 MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size ); 2717 2718 sprintf( expected, "1: %sfrontal.txt ", root); 2719 2720 /* frontal full file key */ 2721 size = MAX_PATH; 2722 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" ); 2723 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2724 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2725 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2726 2727 /* frontal short file key */ 2728 size = MAX_PATH; 2729 MsiRecordSetStringA( hrec, 1, "[!frontal_file]" ); 2730 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2731 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2732 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2733 2734 sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root); 2735 2736 /* temporal full file key */ 2737 size = MAX_PATH; 2738 MsiRecordSetStringA( hrec, 1, "[#temporal_file]" ); 2739 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2740 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2741 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2742 2743 /* temporal short file key */ 2744 size = MAX_PATH; 2745 MsiRecordSetStringA( hrec, 1, "[!temporal_file]" ); 2746 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2747 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2748 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2749 2750 /* custom action 51, files don't exist */ 2751 r = MsiDoActionA( hpkg, "MyCustom" ); 2752 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r); 2753 2754 sprintf( expected, "%sI am a really long directory\\temporal.txt", root); 2755 2756 size = MAX_PATH; 2757 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2758 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2759 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2760 2761 sprintf( buf, "%sI am a really long directory", root ); 2762 CreateDirectoryA( buf, NULL ); 2763 2764 lstrcatA( buf, "\\temporal.txt" ); 2765 create_test_file( buf ); 2766 2767 /* custom action 51, files exist */ 2768 r = MsiDoActionA( hpkg, "MyCustom" ); 2769 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r); 2770 2771 size = MAX_PATH; 2772 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2773 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2774 todo_wine 2775 { 2776 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2777 } 2778 2779 /* custom action 51, escaped text 1 */ 2780 r = MsiDoActionA( hpkg, "EscapeIt1" ); 2781 ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r); 2782 2783 size = MAX_PATH; 2784 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2785 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2786 ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf); 2787 2788 /* custom action 51, escaped text 2 */ 2789 r = MsiDoActionA( hpkg, "EscapeIt2" ); 2790 ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r); 2791 2792 size = MAX_PATH; 2793 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2794 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2795 ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf); 2796 2797 /* custom action 51, escaped text 3 */ 2798 r = MsiDoActionA( hpkg, "EscapeIt3" ); 2799 ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r); 2800 2801 size = MAX_PATH; 2802 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2803 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2804 ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf); 2805 2806 /* custom action 51, embedded null */ 2807 r = MsiDoActionA( hpkg, "EmbedNull" ); 2808 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r); 2809 2810 size = MAX_PATH; 2811 memset( buf, 'a', sizeof(buf) ); 2812 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2813 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2814 ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n"); 2815 ok( size == sizeof("\0np") - 1, "got %lu\n", size ); 2816 2817 r = MsiSetPropertyA( hpkg, "prop", "[~]np" ); 2818 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r); 2819 2820 size = MAX_PATH; 2821 memset( buf, 'a', sizeof(buf) ); 2822 r = MsiGetPropertyA( hpkg, "prop", buf, &size ); 2823 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 2824 ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf); 2825 2826 sprintf( expected, "1: %sI am a really long directory\\ ", root); 2827 2828 /* component with INSTALLSTATE_LOCAL */ 2829 size = MAX_PATH; 2830 MsiRecordSetStringA( hrec, 1, "[$temporal]" ); 2831 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2832 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2833 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); 2834 2835 r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE ); 2836 ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r); 2837 2838 /* component with INSTALLSTATE_SOURCE */ 2839 lstrcpyA( expected, "1: " ); 2840 lstrcatA( expected, curr_dir ); 2841 if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" ); 2842 lstrcatA( expected, " " ); 2843 size = MAX_PATH; 2844 MsiRecordSetStringA( hrec, 1, "[$parietal]" ); 2845 r = MsiFormatRecordA( hpkg, hrec, buf, &size ); 2846 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); 2847 ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf); 2848 2849 sprintf( buf, "%sI am a really long directory\\temporal.txt", root ); 2850 DeleteFileA( buf ); 2851 2852 sprintf( buf, "%sI am a really long directory", root ); 2853 RemoveDirectoryA( buf ); 2854 2855 MsiCloseHandle( hrec ); 2856 MsiCloseHandle( hpkg ); 2857 DeleteFileA( msifile ); 2858 } 2859 2860 static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error, 2861 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo ) 2862 { 2863 UINT r; 2864 INSTALLSTATE state = 0xdeadbee; 2865 INSTALLSTATE action = 0xdeadbee; 2866 2867 r = MsiGetFeatureStateA( package, feature, &state, &action ); 2868 ok( r == error, "%u: expected %d got %d\n", line, error, r ); 2869 if (r == ERROR_SUCCESS) 2870 { 2871 ok( state == expected_state, "%u: expected state %d got %d\n", 2872 line, expected_state, state ); 2873 todo_wine_if (todo) 2874 ok( action == expected_action, "%u: expected action %d got %d\n", 2875 line, expected_action, action ); 2876 } 2877 else 2878 { 2879 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state ); 2880 todo_wine_if (todo) 2881 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action ); 2882 2883 } 2884 } 2885 2886 static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error, 2887 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo ) 2888 { 2889 UINT r; 2890 INSTALLSTATE state = 0xdeadbee; 2891 INSTALLSTATE action = 0xdeadbee; 2892 2893 r = MsiGetComponentStateA( package, component, &state, &action ); 2894 ok( r == error, "%u: expected %d got %d\n", line, error, r ); 2895 if (r == ERROR_SUCCESS) 2896 { 2897 ok( state == expected_state, "%u: expected state %d got %d\n", 2898 line, expected_state, state ); 2899 todo_wine_if (todo) 2900 ok( action == expected_action, "%u: expected action %d got %d\n", 2901 line, expected_action, action ); 2902 } 2903 else 2904 { 2905 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", 2906 line, state ); 2907 todo_wine_if (todo) 2908 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", 2909 line, action ); 2910 } 2911 } 2912 2913 static void test_states(void) 2914 { 2915 static const char msifile2[] = "winetest2-package.msi"; 2916 static const char msifile3[] = "winetest3-package.msi"; 2917 static const char msifile4[] = "winetest4-package.msi"; 2918 static const WCHAR msifile2W[] = L"winetest2-package.msi"; 2919 static const WCHAR msifile3W[] = L"winetest3-package.msi"; 2920 static const WCHAR msifile4W[] = L"winetest4-package.msi"; 2921 char msi_cache_file[MAX_PATH]; 2922 DWORD cache_file_name_len; 2923 INSTALLSTATE state; 2924 MSIHANDLE hpkg, hprod; 2925 UINT r; 2926 MSIHANDLE hdb; 2927 char value[MAX_PATH]; 2928 DWORD size; 2929 2930 if (!is_process_elevated()) 2931 { 2932 skip("process is limited\n"); 2933 return; 2934 } 2935 2936 hdb = create_package_db(); 2937 ok ( hdb, "failed to create package database\n" ); 2938 2939 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); 2940 2941 create_property_table( hdb ); 2942 add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" ); 2943 add_property_entry( hdb, "'ProductLanguage', '1033'" ); 2944 add_property_entry( hdb, "'ProductName', 'MSITEST'" ); 2945 add_property_entry( hdb, "'ProductVersion', '1.1.1'" ); 2946 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); 2947 add_property_entry( hdb, "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" ); 2948 2949 create_install_execute_sequence_table( hdb ); 2950 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); 2951 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); 2952 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); 2953 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" ); 2954 add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" ); 2955 add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" ); 2956 add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" ); 2957 add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" ); 2958 add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" ); 2959 add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" ); 2960 add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" ); 2961 2962 create_media_table( hdb ); 2963 add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''"); 2964 2965 create_feature_table( hdb ); 2966 2967 create_component_table( hdb ); 2968 2969 /* msidbFeatureAttributesFavorLocal */ 2970 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" ); 2971 2972 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ 2973 add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" ); 2974 2975 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ 2976 add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" ); 2977 2978 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ 2979 add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" ); 2980 2981 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */ 2982 add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" ); 2983 2984 /* msidbFeatureAttributesFavorSource */ 2985 add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" ); 2986 2987 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */ 2988 add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" ); 2989 2990 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ 2991 add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" ); 2992 2993 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */ 2994 add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" ); 2995 2996 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */ 2997 add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" ); 2998 2999 /* msidbFeatureAttributesFavorSource */ 3000 add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" ); 3001 3002 /* msidbFeatureAttributesFavorLocal */ 3003 add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" ); 3004 3005 /* disabled */ 3006 add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" ); 3007 3008 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ 3009 add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" ); 3010 3011 /* no feature parent:msidbComponentAttributesLocalOnly */ 3012 add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" ); 3013 3014 /* msidbFeatureAttributesFavorLocal:removed */ 3015 add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" ); 3016 3017 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */ 3018 add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" ); 3019 3020 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */ 3021 add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" ); 3022 3023 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */ 3024 add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" ); 3025 3026 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */ 3027 add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" ); 3028 3029 /* msidbFeatureAttributesFavorSource:removed */ 3030 add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" ); 3031 3032 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */ 3033 add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" ); 3034 3035 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */ 3036 add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" ); 3037 3038 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */ 3039 add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" ); 3040 3041 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */ 3042 add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" ); 3043 3044 /* msidbFeatureAttributesFavorLocal */ 3045 add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" ); 3046 3047 add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" ); 3048 3049 /* msidbFeatureAttributesFavorSource */ 3050 add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" ); 3051 3052 add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" ); 3053 3054 /* msidbFeatureAttributesFavorAdvertise */ 3055 add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" ); 3056 3057 add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" ); 3058 3059 /* msidbFeatureAttributesUIDisallowAbsent */ 3060 add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" ); 3061 3062 add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" ); 3063 3064 /* high install level */ 3065 add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" ); 3066 3067 add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" ); 3068 3069 /* msidbFeatureAttributesFollowParent */ 3070 add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" ); 3071 3072 create_feature_components_table( hdb ); 3073 add_feature_components_entry( hdb, "'one', 'alpha'" ); 3074 add_feature_components_entry( hdb, "'one', 'beta'" ); 3075 add_feature_components_entry( hdb, "'one', 'gamma'" ); 3076 add_feature_components_entry( hdb, "'one', 'theta'" ); 3077 add_feature_components_entry( hdb, "'two', 'delta'" ); 3078 add_feature_components_entry( hdb, "'two', 'epsilon'" ); 3079 add_feature_components_entry( hdb, "'two', 'zeta'" ); 3080 add_feature_components_entry( hdb, "'two', 'iota'" ); 3081 add_feature_components_entry( hdb, "'three', 'eta'" ); 3082 add_feature_components_entry( hdb, "'four', 'eta'" ); 3083 add_feature_components_entry( hdb, "'five', 'eta'" ); 3084 add_feature_components_entry( hdb, "'six', 'lambda'" ); 3085 add_feature_components_entry( hdb, "'six', 'mu'" ); 3086 add_feature_components_entry( hdb, "'six', 'nu'" ); 3087 add_feature_components_entry( hdb, "'six', 'xi'" ); 3088 add_feature_components_entry( hdb, "'seven', 'omicron'" ); 3089 add_feature_components_entry( hdb, "'seven', 'pi'" ); 3090 add_feature_components_entry( hdb, "'seven', 'rho'" ); 3091 add_feature_components_entry( hdb, "'seven', 'sigma'" ); 3092 add_feature_components_entry( hdb, "'eight', 'tau'" ); 3093 add_feature_components_entry( hdb, "'nine', 'phi'" ); 3094 add_feature_components_entry( hdb, "'ten', 'chi'" ); 3095 add_feature_components_entry( hdb, "'eleven', 'psi'" ); 3096 add_feature_components_entry( hdb, "'twelve', 'upsilon'" ); 3097 add_feature_components_entry( hdb, "'thirteen', 'upsilon'" ); 3098 3099 create_file_table( hdb ); 3100 add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" ); 3101 add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" ); 3102 add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" ); 3103 add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" ); 3104 add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" ); 3105 add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" ); 3106 add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" ); 3107 add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" ); 3108 3109 /* compressed file */ 3110 add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" ); 3111 3112 add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" ); 3113 add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" ); 3114 add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" ); 3115 add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" ); 3116 add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" ); 3117 add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" ); 3118 add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" ); 3119 add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" ); 3120 add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" ); 3121 add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" ); 3122 add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" ); 3123 add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" ); 3124 add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" ); 3125 add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" ); 3126 3127 r = MsiDatabaseCommit(hdb); 3128 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); 3129 3130 /* these properties must not be in the saved msi file */ 3131 add_property_entry( hdb, "'ADDLOCAL', 'one,four'"); 3132 add_property_entry( hdb, "'ADDSOURCE', 'two,three'"); 3133 add_property_entry( hdb, "'REMOVE', 'six,seven'"); 3134 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); 3135 add_property_entry( hdb, "'REINSTALLMODE', 'omus'"); 3136 3137 r = package_from_db( hdb, &hpkg ); 3138 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 3139 { 3140 skip("Not enough rights to perform tests\n"); 3141 DeleteFileA(msifile); 3142 return; 3143 } 3144 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3145 3146 MsiCloseHandle(hdb); 3147 3148 CopyFileA(msifile, msifile2, FALSE); 3149 CopyFileA(msifile, msifile3, FALSE); 3150 CopyFileA(msifile, msifile4, FALSE); 3151 3152 size = sizeof(value); 3153 memset(value, 0, sizeof(value)); 3154 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size); 3155 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3156 ok(!value[0], "ProductToBeRegistered = %s\n", value); 3157 3158 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3159 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3160 3161 r = MsiDoActionA( hpkg, "CostInitialize"); 3162 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3163 3164 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3165 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3166 3167 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 3168 3169 r = MsiDoActionA( hpkg, "FileCost"); 3170 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3171 3172 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3173 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3174 3175 r = MsiDoActionA( hpkg, "CostFinalize"); 3176 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3177 3178 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3179 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 3180 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3181 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3182 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3183 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3184 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3185 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3186 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3187 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3188 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3189 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3190 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3191 3192 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3193 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 3194 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3195 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3196 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3197 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 3198 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 3199 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3200 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 3201 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3202 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3203 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3204 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3205 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3206 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3207 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3208 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3209 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3210 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3211 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3212 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3213 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3214 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3215 3216 MsiCloseHandle( hpkg ); 3217 3218 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 3219 3220 /* publish the features and components */ 3221 r = MsiInstallProductA(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten"); 3222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3223 3224 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 3225 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3226 3227 /* these properties must not be in the saved msi file */ 3228 add_property_entry( hdb, "'ADDLOCAL', 'one,four'"); 3229 add_property_entry( hdb, "'ADDSOURCE', 'two,three'"); 3230 add_property_entry( hdb, "'REMOVE', 'six,seven'"); 3231 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); 3232 3233 r = package_from_db( hdb, &hpkg ); 3234 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3235 3236 MsiCloseHandle(hdb); 3237 3238 size = sizeof(value); 3239 memset(value, 0, sizeof(value)); 3240 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size); 3241 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3242 ok(value[0]=='1' && !value[1], "ProductToBeRegistered = %s\n", value); 3243 3244 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3245 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3246 3247 r = MsiDoActionA( hpkg, "CostInitialize"); 3248 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3249 3250 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3251 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3252 3253 r = MsiDoActionA( hpkg, "FileCost"); 3254 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3255 3256 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3257 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3258 3259 r = MsiDoActionA( hpkg, "CostFinalize"); 3260 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3261 3262 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3263 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3264 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3265 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3266 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3267 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3268 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3269 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3270 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3271 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3272 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3273 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3274 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3275 3276 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3277 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3278 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3279 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3280 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3281 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3282 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3283 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3284 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3285 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3286 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3287 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3288 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3289 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3290 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3291 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3292 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3293 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3294 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3295 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3296 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3297 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3298 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3299 3300 MsiCloseHandle(hpkg); 3301 3302 /* uninstall the product */ 3303 r = MsiInstallProductA(msifile, "REMOVE=ALL"); 3304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3305 3306 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); 3307 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3308 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve"); 3309 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3310 3311 /* all features installed locally */ 3312 r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL"); 3313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3314 3315 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); 3316 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3317 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve"); 3318 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state); 3319 3320 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_DIRECT, &hdb); 3321 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3322 3323 /* these properties must not be in the saved msi file */ 3324 add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'"); 3325 3326 r = package_from_db( hdb, &hpkg ); 3327 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3328 3329 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3330 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3331 3332 r = MsiDoActionA( hpkg, "CostInitialize"); 3333 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3334 3335 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3336 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3337 3338 r = MsiDoActionA( hpkg, "CostFinalize"); 3339 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3340 3341 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3342 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3343 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3344 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3345 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3346 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3347 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE ); 3348 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE ); 3349 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE ); 3350 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE ); 3351 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3352 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3353 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3354 3355 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3356 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3357 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3358 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3359 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3360 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3361 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3362 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3363 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3364 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3365 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3366 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3367 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3368 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3369 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3370 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3371 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3372 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3373 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3374 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3375 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3376 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3377 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3378 3379 MsiCloseHandle(hpkg); 3380 3381 /* uninstall the product */ 3382 r = MsiInstallProductA(msifile2, "REMOVE=ALL"); 3383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3384 3385 /* all features installed from source */ 3386 r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL"); 3387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3388 3389 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); 3390 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3391 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve"); 3392 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state); 3393 3394 r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb); 3395 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3396 3397 /* this property must not be in the saved msi file */ 3398 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); 3399 3400 r = package_from_db( hdb, &hpkg ); 3401 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3402 3403 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3404 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3405 3406 r = MsiDoActionA( hpkg, "CostInitialize"); 3407 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3408 3409 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3410 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3411 3412 r = MsiDoActionA( hpkg, "FileCost"); 3413 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3414 3415 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3416 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3417 3418 r = MsiDoActionA( hpkg, "CostFinalize"); 3419 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3420 3421 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3422 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3423 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3424 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3425 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3426 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3427 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3428 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3429 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3430 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3431 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3432 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3433 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3434 3435 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3436 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3437 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3438 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3439 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3440 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3441 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3442 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3443 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3444 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3445 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3446 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3447 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3448 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3449 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3450 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3451 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3452 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3453 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3454 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3455 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3456 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3457 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3458 3459 MsiCloseHandle(hpkg); 3460 3461 /* reinstall the product */ 3462 r = MsiInstallProductA(msifile3, "REINSTALL=ALL"); 3463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3464 3465 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); 3466 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3467 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve"); 3468 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state); 3469 3470 r = MsiOpenDatabaseW(msifile4W, MSIDBOPEN_DIRECT, &hdb); 3471 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3472 3473 /* this property must not be in the saved msi file */ 3474 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); 3475 3476 r = package_from_db( hdb, &hpkg ); 3477 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3478 3479 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3480 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE ); 3481 3482 r = MsiDoActionA( hpkg, "CostInitialize"); 3483 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3484 3485 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3486 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3487 3488 r = MsiDoActionA( hpkg, "FileCost"); 3489 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3490 3491 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3492 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3493 3494 r = MsiDoActionA( hpkg, "CostFinalize"); 3495 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); 3496 3497 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3498 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3499 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3500 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3501 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3502 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3503 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3504 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3505 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3506 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE ); 3507 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE ); 3508 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3509 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE ); 3510 3511 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3512 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3513 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3514 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3515 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3516 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3517 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3518 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3519 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3520 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3521 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3522 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3523 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3524 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3525 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3526 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3527 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3528 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3529 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3530 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3531 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3532 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3533 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3534 3535 MsiCloseHandle(hpkg); 3536 3537 /* test source only install */ 3538 r = MsiInstallProductA(msifile, "REMOVE=ALL"); 3539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3540 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); 3541 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3542 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); 3543 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); 3544 3545 r = MsiInstallProductA(msifile, "ADDSOURCE=one"); 3546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3547 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); 3548 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state); 3549 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); 3550 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state); 3551 3552 /* no arguments test */ 3553 cache_file_name_len = sizeof(msi_cache_file); 3554 r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", 3555 INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len); 3556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3557 r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb); 3558 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3559 3560 create_custom_action_table( hdb ); 3561 add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" ); 3562 add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" ); 3563 add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" ); 3564 add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" ); 3565 add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" ); 3566 add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" ); 3567 add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" ); 3568 add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" ); 3569 add_custom_action_entry( hdb, 3570 "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" ); 3571 3572 add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" ); 3573 add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" ); 3574 add_install_execute_sequence_entry( hdb, "'VBFeatureRequest', 'NOT REMOVE', '1001'" ); 3575 add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" ); 3576 add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" ); 3577 add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" ); 3578 add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" ); 3579 /* Add "one" feature action tests */ 3580 add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" ); 3581 add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" ); 3582 r = MsiDatabaseCommit(hdb); 3583 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r); 3584 r = package_from_db( hdb, &hpkg ); 3585 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3586 MsiCloseHandle(hdb); 3587 3588 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3589 test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); 3590 r = MsiDoActionA( hpkg, "CostInitialize"); 3591 ok( r == ERROR_SUCCESS, "CostInitialize failed\n"); 3592 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3593 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3594 3595 r = MsiDoActionA( hpkg, "FileCost"); 3596 ok( r == ERROR_SUCCESS, "FileCost failed\n"); 3597 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3598 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 3599 3600 r = MsiDoActionA( hpkg, "CostFinalize"); 3601 ok( r == ERROR_SUCCESS, "CostFinalize failed\n"); 3602 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3603 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3604 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3605 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3606 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3607 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); 3608 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3609 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3610 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3611 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3612 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3613 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3614 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3615 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3616 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3617 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3618 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3619 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3620 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3621 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3622 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3623 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3624 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3625 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3626 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3627 3628 r = MsiDoActionA( hpkg, "InstallValidate"); 3629 ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r); 3630 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); 3631 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 3632 MsiCloseHandle( hpkg ); 3633 3634 r = MsiInstallProductA(msifile, ""); 3635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3636 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); 3637 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state); 3638 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); 3639 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state); 3640 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three"); 3641 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state); 3642 3643 /* minor upgrade test with no REINSTALL argument */ 3644 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod); 3645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3646 size = MAX_PATH; 3647 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size); 3648 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3649 ok(!strcmp(value, "1.1.1"), "ProductVersion = %s\n", value); 3650 MsiCloseHandle(hprod); 3651 3652 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb); 3653 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3654 update_ProductVersion_property( hdb, "1.1.2" ); 3655 set_summary_str(hdb, PID_REVNUMBER, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}"); 3656 r = MsiDatabaseCommit(hdb); 3657 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r); 3658 MsiCloseHandle(hdb); 3659 3660 r = MsiInstallProductA(msifile2, ""); 3661 ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r); 3662 3663 r = MsiInstallProductA(msifile2, "REINSTALLMODe=V"); 3664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3665 3666 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod); 3667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3668 size = MAX_PATH; 3669 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size); 3670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3671 ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value); 3672 MsiCloseHandle(hprod); 3673 3674 /* major upgrade test */ 3675 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb); 3676 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); 3677 add_install_execute_sequence_entry( hdb, "'FindRelatedProducts', '', '100'" ); 3678 add_install_execute_sequence_entry( hdb, "'RemoveExistingProducts', '', '1401'" ); 3679 create_upgrade_table( hdb ); 3680 add_upgrade_entry( hdb, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'"); 3681 update_ProductCode_property( hdb, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" ); 3682 update_ProductVersion_property( hdb, "1.1.3" ); 3683 set_summary_str(hdb, PID_REVNUMBER, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}"); 3684 r = MsiDatabaseCommit(hdb); 3685 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r); 3686 MsiCloseHandle(hdb); 3687 3688 r = MsiInstallProductA(msifile2, ""); 3689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3690 3691 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod); 3692 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); 3693 r = MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod); 3694 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3695 size = MAX_PATH; 3696 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size); 3697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3698 ok(!strcmp(value, "1.1.3"), "ProductVersion = %s\n", value); 3699 MsiCloseHandle(hprod); 3700 3701 /* uninstall the product */ 3702 r = MsiInstallProductA(msifile2, "REMOVE=ALL"); 3703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3704 3705 DeleteFileA(msifile); 3706 DeleteFileA(msifile2); 3707 DeleteFileA(msifile3); 3708 DeleteFileA(msifile4); 3709 } 3710 3711 static void test_removefiles(void) 3712 { 3713 MSIHANDLE hpkg; 3714 UINT r; 3715 MSIHANDLE hdb; 3716 INSTALLSTATE installed, action; 3717 3718 hdb = create_package_db(); 3719 ok ( hdb, "failed to create package database\n" ); 3720 3721 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); 3722 3723 create_feature_table( hdb ); 3724 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" ); 3725 3726 create_component_table( hdb ); 3727 add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" ); 3728 add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" ); 3729 add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" ); 3730 add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" ); 3731 add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" ); 3732 add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" ); 3733 add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" ); 3734 3735 create_feature_components_table( hdb ); 3736 add_feature_components_entry( hdb, "'one', 'hydrogen'" ); 3737 add_feature_components_entry( hdb, "'one', 'helium'" ); 3738 add_feature_components_entry( hdb, "'one', 'lithium'" ); 3739 add_feature_components_entry( hdb, "'one', 'beryllium'" ); 3740 add_feature_components_entry( hdb, "'one', 'boron'" ); 3741 add_feature_components_entry( hdb, "'one', 'carbon'" ); 3742 add_feature_components_entry( hdb, "'one', 'oxygen'" ); 3743 3744 create_file_table( hdb ); 3745 add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" ); 3746 add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" ); 3747 add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" ); 3748 add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" ); 3749 add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" ); 3750 add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" ); 3751 add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" ); 3752 3753 create_remove_file_table( hdb ); 3754 3755 r = package_from_db( hdb, &hpkg ); 3756 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 3757 { 3758 skip("Not enough rights to perform tests\n"); 3759 DeleteFileA(msifile); 3760 return; 3761 } 3762 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3763 3764 MsiCloseHandle( hdb ); 3765 3766 create_test_file( "hydrogen.txt" ); 3767 create_test_file( "helium.txt" ); 3768 create_test_file( "lithium.txt" ); 3769 create_test_file( "beryllium.txt" ); 3770 create_test_file( "boron.txt" ); 3771 create_test_file( "carbon.txt" ); 3772 create_test_file( "oxygen.txt" ); 3773 3774 r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR ); 3775 ok( r == ERROR_SUCCESS, "set property failed\n"); 3776 3777 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 3778 3779 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3780 ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r ); 3781 3782 r = MsiDoActionA( hpkg, "CostInitialize"); 3783 ok( r == ERROR_SUCCESS, "cost init failed\n"); 3784 3785 r = MsiDoActionA( hpkg, "FileCost"); 3786 ok( r == ERROR_SUCCESS, "file cost failed\n"); 3787 3788 installed = action = 0xdeadbeef; 3789 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3790 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3791 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3792 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3793 3794 r = MsiDoActionA( hpkg, "CostFinalize"); 3795 ok( r == ERROR_SUCCESS, "cost finalize failed\n"); 3796 3797 r = MsiDoActionA( hpkg, "InstallValidate"); 3798 ok( r == ERROR_SUCCESS, "install validate failed\n"); 3799 3800 r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT ); 3801 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3802 3803 installed = action = 0xdeadbeef; 3804 r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action ); 3805 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3806 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3807 todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3808 3809 r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL ); 3810 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3811 3812 r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE ); 3813 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3814 3815 r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT ); 3816 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3817 3818 r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL ); 3819 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3820 3821 r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE ); 3822 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3823 3824 installed = action = 0xdeadbeef; 3825 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3826 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3827 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3828 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3829 3830 r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT ); 3831 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); 3832 3833 installed = action = 0xdeadbeef; 3834 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3835 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3836 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3837 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3838 3839 r = MsiDoActionA( hpkg, "RemoveFiles"); 3840 ok( r == ERROR_SUCCESS, "remove files failed\n"); 3841 3842 installed = action = 0xdeadbeef; 3843 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action ); 3844 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); 3845 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); 3846 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); 3847 3848 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n"); 3849 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n"); 3850 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n"); 3851 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n"); 3852 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n"); 3853 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n"); 3854 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n"); 3855 3856 MsiCloseHandle( hpkg ); 3857 DeleteFileA(msifile); 3858 } 3859 3860 static void test_appsearch(void) 3861 { 3862 MSIHANDLE hpkg; 3863 UINT r; 3864 MSIHANDLE hdb; 3865 CHAR prop[MAX_PATH]; 3866 DWORD size; 3867 HKEY hkey; 3868 const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe"; 3869 3870 hdb = create_package_db(); 3871 ok ( hdb, "failed to create package database\n" ); 3872 3873 create_appsearch_table( hdb ); 3874 add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" ); 3875 add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" ); 3876 add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" ); 3877 add_appsearch_entry( hdb, "'32KEYVAL', 'NewSignature4'" ); 3878 add_appsearch_entry( hdb, "'64KEYVAL', 'NewSignature5'" ); 3879 3880 create_reglocator_table( hdb ); 3881 add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 ); 3882 3883 r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL); 3884 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r ); 3885 r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1); 3886 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r); 3887 RegCloseKey(hkey); 3888 add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName ); 3889 3890 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, 3891 NULL, &hkey, NULL); 3892 if (r == ERROR_ACCESS_DENIED) 3893 { 3894 skip("insufficient rights\n"); 3895 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi"); 3896 MsiCloseHandle(hdb); 3897 DeleteFileA(msifile); 3898 return; 3899 } 3900 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r ); 3901 3902 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe", 3903 sizeof("c:\\windows\\system32\\notepad.exe")); 3904 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r); 3905 RegCloseKey(hkey); 3906 add_reglocator_entry( hdb, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName ); 3907 3908 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, 3909 NULL, &hkey, NULL); 3910 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r ); 3911 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe", 3912 sizeof("c:\\windows\\system32\\notepad.exe")); 3913 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r); 3914 RegCloseKey(hkey); 3915 add_reglocator_entry( hdb, "NewSignature5", 2, "Software\\Winetest_msi", "", 3916 msidbLocatorTypeFileName|msidbLocatorType64bit ); 3917 3918 create_drlocator_table( hdb ); 3919 add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" ); 3920 3921 create_signature_table( hdb ); 3922 add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" ); 3923 add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); 3924 add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); 3925 add_signature_entry( hdb, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); 3926 add_signature_entry( hdb, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); 3927 3928 r = package_from_db( hdb, &hpkg ); 3929 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 3930 { 3931 skip("Not enough rights to perform tests\n"); 3932 DeleteFileA(msifile); 3933 return; 3934 } 3935 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 3936 MsiCloseHandle( hdb ); 3937 if (r != ERROR_SUCCESS) 3938 goto done; 3939 3940 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 3941 3942 r = MsiDoActionA( hpkg, "AppSearch" ); 3943 ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r); 3944 3945 size = sizeof(prop); 3946 r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size ); 3947 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3948 ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); 3949 3950 size = sizeof(prop); 3951 r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size ); 3952 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3953 3954 size = sizeof(prop); 3955 r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size ); 3956 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3957 ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); 3958 3959 size = sizeof(prop); 3960 r = MsiGetPropertyA( hpkg, "32KEYVAL", prop, &size ); 3961 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3962 ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); 3963 3964 size = sizeof(prop); 3965 r = MsiGetPropertyA( hpkg, "64KEYVAL", prop, &size ); 3966 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); 3967 ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); 3968 3969 done: 3970 MsiCloseHandle( hpkg ); 3971 DeleteFileA(msifile); 3972 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi"); 3973 RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY, 0); 3974 RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY, 0); 3975 } 3976 3977 static void test_appsearch_complocator(void) 3978 { 3979 MSIHANDLE hpkg, hdb; 3980 char path[MAX_PATH + 15], expected[MAX_PATH], prop[MAX_PATH]; 3981 LPSTR usersid; 3982 DWORD size; 3983 UINT r; 3984 3985 if (!(usersid = get_user_sid())) 3986 return; 3987 3988 if (!is_process_elevated()) 3989 { 3990 skip("process is limited\n"); 3991 return; 3992 } 3993 3994 create_test_file("FileName1"); 3995 create_test_file("FileName4"); 3996 set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE, 3997 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE); 3998 3999 create_test_file("FileName2"); 4000 set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED, 4001 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE); 4002 4003 create_test_file("FileName3"); 4004 set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED, 4005 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE); 4006 4007 create_test_file("FileName5"); 4008 set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE, 4009 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE); 4010 4011 create_test_file("FileName6"); 4012 set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE, 4013 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE); 4014 4015 create_test_file("FileName7"); 4016 set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE, 4017 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE); 4018 4019 /* dir is FALSE, but we're pretending it's a directory */ 4020 set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE, 4021 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE); 4022 4023 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4024 set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE, 4025 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE); 4026 4027 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4)); 4028 set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE, 4029 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE); 4030 4031 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4032 set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE, 4033 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE); 4034 4035 hdb = create_package_db(); 4036 ok(hdb, "Expected a valid database handle\n"); 4037 4038 create_appsearch_table(hdb); 4039 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); 4040 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); 4041 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); 4042 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); 4043 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); 4044 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); 4045 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); 4046 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); 4047 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); 4048 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); 4049 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); 4050 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); 4051 4052 create_complocator_table(hdb); 4053 4054 /* published component, machine, file, signature, misdbLocatorTypeFile */ 4055 add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1"); 4056 4057 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */ 4058 add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1"); 4059 4060 /* published component, user-managed, file, signature, misdbLocatorTypeFile */ 4061 add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1"); 4062 4063 /* published component, machine, file, signature, misdbLocatorTypeDirectory */ 4064 add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0"); 4065 4066 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */ 4067 add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0"); 4068 4069 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */ 4070 add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0"); 4071 4072 /* published component, machine, file, no signature, misdbLocatorTypeFile */ 4073 add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1"); 4074 4075 /* unpublished component, no signature, misdbLocatorTypeDir */ 4076 add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0"); 4077 4078 /* published component, no signature, dir does not exist misdbLocatorTypeDir */ 4079 add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0"); 4080 4081 /* published component, signature w/ ver, misdbLocatorTypeFile */ 4082 add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1"); 4083 4084 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */ 4085 add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1"); 4086 4087 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */ 4088 add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1"); 4089 4090 create_signature_table(hdb); 4091 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''"); 4092 add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''"); 4093 add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''"); 4094 add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''"); 4095 add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''"); 4096 add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4097 add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4098 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4099 4100 r = package_from_db(hdb, &hpkg); 4101 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 4102 { 4103 skip("Not enough rights to perform tests\n"); 4104 goto error; 4105 } 4106 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); 4107 4108 r = MsiSetPropertyA(hpkg, "SIGPROP8", "october"); 4109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4110 4111 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 4112 4113 r = MsiDoActionA(hpkg, "AppSearch"); 4114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4115 4116 strcpy(expected, CURR_DIR); 4117 if (is_root(CURR_DIR)) expected[2] = 0; 4118 4119 size = MAX_PATH; 4120 sprintf(path, "%s\\FileName1", expected); 4121 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size); 4122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4123 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4124 4125 size = MAX_PATH; 4126 sprintf(path, "%s\\FileName2", expected); 4127 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size); 4128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4129 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4130 4131 size = MAX_PATH; 4132 sprintf(path, "%s\\FileName3", expected); 4133 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size); 4134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4135 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4136 4137 size = MAX_PATH; 4138 sprintf(path, "%s\\FileName4", expected); 4139 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size); 4140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4141 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4142 4143 size = MAX_PATH; 4144 sprintf(path, "%s\\FileName5", expected); 4145 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); 4146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4147 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4148 4149 size = MAX_PATH; 4150 sprintf(path, "%s\\", expected); 4151 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size); 4152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4153 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4154 4155 size = MAX_PATH; 4156 sprintf(path, "%s\\", expected); 4157 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size); 4158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4159 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4160 4161 size = MAX_PATH; 4162 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size); 4163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4164 ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop); 4165 4166 size = MAX_PATH; 4167 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size); 4168 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4169 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4170 4171 size = MAX_PATH; 4172 sprintf(path, "%s\\FileName8.dll", expected); 4173 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size); 4174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4175 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4176 4177 size = MAX_PATH; 4178 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size); 4179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4180 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4181 4182 size = MAX_PATH; 4183 sprintf(path, "%s\\FileName10.dll", expected); 4184 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size); 4185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4186 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4187 4188 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", 4189 MSIINSTALLCONTEXT_MACHINE, NULL); 4190 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", 4191 MSIINSTALLCONTEXT_USERUNMANAGED, usersid); 4192 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", 4193 MSIINSTALLCONTEXT_USERMANAGED, usersid); 4194 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", 4195 MSIINSTALLCONTEXT_MACHINE, NULL); 4196 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}", 4197 MSIINSTALLCONTEXT_MACHINE, NULL); 4198 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", 4199 MSIINSTALLCONTEXT_MACHINE, NULL); 4200 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", 4201 MSIINSTALLCONTEXT_MACHINE, NULL); 4202 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", 4203 MSIINSTALLCONTEXT_MACHINE, NULL); 4204 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}", 4205 MSIINSTALLCONTEXT_MACHINE, NULL); 4206 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", 4207 MSIINSTALLCONTEXT_MACHINE, NULL); 4208 4209 MsiCloseHandle(hpkg); 4210 4211 error: 4212 DeleteFileA("FileName1"); 4213 DeleteFileA("FileName2"); 4214 DeleteFileA("FileName3"); 4215 DeleteFileA("FileName4"); 4216 DeleteFileA("FileName5"); 4217 DeleteFileA("FileName6"); 4218 DeleteFileA("FileName7"); 4219 DeleteFileA("FileName8.dll"); 4220 DeleteFileA("FileName9.dll"); 4221 DeleteFileA("FileName10.dll"); 4222 DeleteFileA(msifile); 4223 LocalFree(usersid); 4224 } 4225 4226 static void test_appsearch_reglocator(void) 4227 { 4228 MSIHANDLE hpkg, hdb; 4229 char path[MAX_PATH + 20], expected[MAX_PATH], prop[MAX_PATH]; 4230 DWORD binary[2], size, val; 4231 BOOL space, version, is_64bit = sizeof(void *) > sizeof(int); 4232 HKEY hklm, classes, hkcu, users; 4233 LPSTR pathdata, pathvar, ptr; 4234 LONG res; 4235 UINT r, type = 0; 4236 SYSTEM_INFO si; 4237 4238 version = TRUE; 4239 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3))) 4240 version = FALSE; 4241 4242 DeleteFileA("test.dll"); 4243 4244 res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes); 4245 if (res == ERROR_ACCESS_DENIED) 4246 { 4247 skip("Not enough rights to perform tests\n"); 4248 return; 4249 } 4250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4251 4252 res = RegSetValueExA(classes, "Value1", 0, REG_SZ, 4253 (const BYTE *)"regszdata", 10); 4254 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4255 4256 res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu); 4257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4258 4259 res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ, 4260 (const BYTE *)"regszdata", 10); 4261 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4262 4263 users = 0; 4264 res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users); 4265 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4266 4267 if (res == ERROR_SUCCESS) 4268 { 4269 res = RegSetValueExA(users, "Value1", 0, REG_SZ, 4270 (const BYTE *)"regszdata", 10); 4271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4272 } 4273 4274 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm); 4275 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4276 4277 res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8); 4278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4279 4280 res = RegSetValueExA(hklm, "Value1", 0, REG_SZ, 4281 (const BYTE *)"regszdata", 10); 4282 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4283 4284 val = 42; 4285 res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD, 4286 (const BYTE *)&val, sizeof(DWORD)); 4287 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4288 4289 val = -42; 4290 res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD, 4291 (const BYTE *)&val, sizeof(DWORD)); 4292 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4293 4294 res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ, 4295 (const BYTE *)"%PATH%", 7); 4296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4297 4298 res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ, 4299 (const BYTE *)"my%NOVAR%", 10); 4300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4301 4302 res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ, 4303 (const BYTE *)"one\0two\0", 9); 4304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4305 4306 binary[0] = 0x1234abcd; 4307 binary[1] = 0x567890ef; 4308 res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY, 4309 (const BYTE *)binary, sizeof(binary)); 4310 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4311 4312 res = RegSetValueExA(hklm, "Value8", 0, REG_SZ, 4313 (const BYTE *)"#regszdata", 11); 4314 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4315 4316 strcpy(expected, CURR_DIR); 4317 if (is_root(CURR_DIR)) expected[2] = 0; 4318 4319 create_test_file("FileName1"); 4320 sprintf(path, "%s\\FileName1", expected); 4321 res = RegSetValueExA(hklm, "Value9", 0, REG_SZ, 4322 (const BYTE *)path, lstrlenA(path) + 1); 4323 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4324 4325 sprintf(path, "%s\\FileName2", expected); 4326 res = RegSetValueExA(hklm, "Value10", 0, REG_SZ, 4327 (const BYTE *)path, lstrlenA(path) + 1); 4328 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4329 4330 lstrcpyA(path, expected); 4331 res = RegSetValueExA(hklm, "Value11", 0, REG_SZ, 4332 (const BYTE *)path, lstrlenA(path) + 1); 4333 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4334 4335 res = RegSetValueExA(hklm, "Value12", 0, REG_SZ, 4336 (const BYTE *)"", 1); 4337 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4338 4339 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4340 sprintf(path, "%s\\FileName3.dll", expected); 4341 res = RegSetValueExA(hklm, "Value13", 0, REG_SZ, 4342 (const BYTE *)path, lstrlenA(path) + 1); 4343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4344 4345 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4)); 4346 sprintf(path, "%s\\FileName4.dll", expected); 4347 res = RegSetValueExA(hklm, "Value14", 0, REG_SZ, 4348 (const BYTE *)path, lstrlenA(path) + 1); 4349 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4350 4351 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4352 sprintf(path, "%s\\FileName5.dll", expected); 4353 res = RegSetValueExA(hklm, "Value15", 0, REG_SZ, 4354 (const BYTE *)path, lstrlenA(path) + 1); 4355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 4356 4357 sprintf(path, "\"%s\\FileName1\" -option", expected); 4358 res = RegSetValueExA(hklm, "value16", 0, REG_SZ, 4359 (const BYTE *)path, lstrlenA(path) + 1); 4360 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res); 4361 4362 space = strchr(expected, ' ') != NULL; 4363 sprintf(path, "%s\\FileName1 -option", expected); 4364 res = RegSetValueExA(hklm, "value17", 0, REG_SZ, 4365 (const BYTE *)path, lstrlenA(path) + 1); 4366 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res); 4367 4368 hdb = create_package_db(); 4369 ok(hdb, "Expected a valid database handle\n"); 4370 4371 create_appsearch_table(hdb); 4372 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); 4373 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); 4374 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); 4375 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); 4376 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); 4377 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); 4378 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); 4379 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); 4380 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); 4381 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); 4382 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); 4383 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); 4384 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'"); 4385 add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'"); 4386 add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'"); 4387 add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'"); 4388 add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'"); 4389 add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'"); 4390 add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'"); 4391 add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'"); 4392 add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'"); 4393 add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'"); 4394 add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'"); 4395 add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'"); 4396 add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'"); 4397 add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'"); 4398 add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'"); 4399 add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'"); 4400 add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'"); 4401 add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'"); 4402 4403 create_reglocator_table(hdb); 4404 4405 type = msidbLocatorTypeRawValue; 4406 if (is_64bit) 4407 type |= msidbLocatorType64bit; 4408 4409 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */ 4410 add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type); 4411 4412 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */ 4413 add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type); 4414 4415 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */ 4416 add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type); 4417 4418 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */ 4419 add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type); 4420 4421 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */ 4422 add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type); 4423 4424 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */ 4425 add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type); 4426 4427 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */ 4428 add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type); 4429 4430 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */ 4431 add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type); 4432 4433 type = msidbLocatorTypeFileName; 4434 if (is_64bit) 4435 type |= msidbLocatorType64bit; 4436 4437 /* HKLM, msidbLocatorTypeFileName, signature, file exists */ 4438 add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type); 4439 4440 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */ 4441 add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type); 4442 4443 /* HKLM, msidbLocatorTypeFileName, no signature */ 4444 add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type); 4445 4446 type = msidbLocatorTypeDirectory; 4447 if (is_64bit) 4448 type |= msidbLocatorType64bit; 4449 4450 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */ 4451 add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type); 4452 4453 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */ 4454 add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type); 4455 4456 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */ 4457 add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type); 4458 4459 type = msidbLocatorTypeRawValue; 4460 if (is_64bit) 4461 type |= msidbLocatorType64bit; 4462 4463 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */ 4464 add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type); 4465 4466 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */ 4467 add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type); 4468 4469 /* HKU, msidbLocatorTypeRawValue, REG_SZ */ 4470 add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type); 4471 4472 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */ 4473 add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type); 4474 4475 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */ 4476 add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type); 4477 4478 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */ 4479 add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type); 4480 4481 type = msidbLocatorTypeFileName; 4482 if (is_64bit) 4483 type |= msidbLocatorType64bit; 4484 4485 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */ 4486 add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type); 4487 4488 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */ 4489 add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type); 4490 4491 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */ 4492 add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type); 4493 4494 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */ 4495 add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type); 4496 4497 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */ 4498 add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type); 4499 4500 type = msidbLocatorTypeDirectory; 4501 if (is_64bit) 4502 type |= msidbLocatorType64bit; 4503 4504 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */ 4505 add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type); 4506 4507 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */ 4508 add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type); 4509 4510 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */ 4511 add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type); 4512 4513 type = msidbLocatorTypeFileName; 4514 if (is_64bit) 4515 type |= msidbLocatorType64bit; 4516 4517 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */ 4518 add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type); 4519 4520 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */ 4521 add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type); 4522 4523 create_signature_table(hdb); 4524 add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''"); 4525 add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''"); 4526 add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''"); 4527 add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4528 add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4529 add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4530 4531 if (!is_root(CURR_DIR)) 4532 { 4533 ptr = strrchr(expected, '\\') + 1; 4534 sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr); 4535 add_signature_entry(hdb, path); 4536 } 4537 add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''"); 4538 add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''"); 4539 add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''"); 4540 4541 r = package_from_db(hdb, &hpkg); 4542 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); 4543 4544 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 4545 4546 r = MsiDoActionA(hpkg, "AppSearch"); 4547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4548 4549 size = MAX_PATH; 4550 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size); 4551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4552 ok(!lstrcmpA(prop, "regszdata"), 4553 "Expected \"regszdata\", got \"%s\"\n", prop); 4554 4555 size = MAX_PATH; 4556 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size); 4557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4558 ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop); 4559 4560 size = MAX_PATH; 4561 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size); 4562 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4563 ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop); 4564 4565 memset(&si, 0, sizeof(si)); 4566 GetNativeSystemInfo(&si); 4567 4568 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) 4569 { 4570 size = ExpandEnvironmentStringsA("%PATH%", NULL, 0); 4571 pathvar = malloc(size); 4572 ExpandEnvironmentStringsA("%PATH%", pathvar, size); 4573 4574 size = 0; 4575 r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size); 4576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4577 4578 pathdata = malloc(++size); 4579 r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size); 4580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4581 ok(!lstrcmpA(pathdata, pathvar), 4582 "Expected \"%s\", got \"%s\"\n", pathvar, pathdata); 4583 4584 free(pathvar); 4585 free(pathdata); 4586 } 4587 4588 size = MAX_PATH; 4589 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); 4590 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4591 ok(!lstrcmpA(prop, 4592 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop); 4593 4594 size = MAX_PATH; 4595 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size); 4596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4597 todo_wine 4598 { 4599 ok(!memcmp(prop, "\0one\0two\0\0", 10), 4600 "Expected \"\\0one\\0two\\0\\0\"\n"); 4601 } 4602 4603 size = MAX_PATH; 4604 lstrcpyA(path, "#xCDAB3412EF907856"); 4605 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size); 4606 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4607 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4608 4609 size = MAX_PATH; 4610 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size); 4611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4612 ok(!lstrcmpA(prop, "##regszdata"), 4613 "Expected \"##regszdata\", got \"%s\"\n", prop); 4614 4615 size = MAX_PATH; 4616 sprintf(path, "%s\\FileName1", expected); 4617 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size); 4618 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4619 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4620 4621 size = MAX_PATH; 4622 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size); 4623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4624 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4625 4626 size = MAX_PATH; 4627 sprintf(path, "%s\\", expected); 4628 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size); 4629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4630 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4631 4632 size = MAX_PATH; 4633 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size); 4634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4635 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4636 4637 size = MAX_PATH; 4638 sprintf(path, "%s\\", expected); 4639 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size); 4640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4641 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4642 4643 size = MAX_PATH; 4644 r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size); 4645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4646 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4647 4648 size = MAX_PATH; 4649 r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size); 4650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4651 ok(!lstrcmpA(prop, "regszdata"), 4652 "Expected \"regszdata\", got \"%s\"\n", prop); 4653 4654 size = MAX_PATH; 4655 r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size); 4656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4657 ok(!lstrcmpA(prop, "regszdata"), 4658 "Expected \"regszdata\", got \"%s\"\n", prop); 4659 4660 if (users) 4661 { 4662 size = MAX_PATH; 4663 r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size); 4664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4665 ok(!lstrcmpA(prop, "regszdata"), 4666 "Expected \"regszdata\", got \"%s\"\n", prop); 4667 } 4668 4669 size = MAX_PATH; 4670 r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size); 4671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4672 ok(!lstrcmpA(prop, "defvalue"), 4673 "Expected \"defvalue\", got \"%s\"\n", prop); 4674 4675 size = MAX_PATH; 4676 r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size); 4677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4678 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4679 4680 size = MAX_PATH; 4681 r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size); 4682 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4683 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4684 4685 if (version) 4686 { 4687 size = MAX_PATH; 4688 sprintf(path, "%s\\FileName3.dll", expected); 4689 r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size); 4690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4691 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4692 4693 size = MAX_PATH; 4694 r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size); 4695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4696 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4697 4698 size = MAX_PATH; 4699 sprintf(path, "%s\\FileName5.dll", expected); 4700 r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size); 4701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4702 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4703 } 4704 4705 if (!is_root(CURR_DIR)) 4706 { 4707 size = MAX_PATH; 4708 lstrcpyA(path, expected); 4709 ptr = strrchr(path, '\\') + 1; 4710 *ptr = '\0'; 4711 r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size); 4712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4713 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4714 } 4715 size = MAX_PATH; 4716 sprintf(path, "%s\\", expected); 4717 r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size); 4718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4719 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4720 4721 size = MAX_PATH; 4722 r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size); 4723 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4724 if (is_root(CURR_DIR)) 4725 ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop); 4726 else 4727 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4728 4729 size = MAX_PATH; 4730 r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size); 4731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4732 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4733 4734 size = MAX_PATH; 4735 r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size); 4736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4737 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4738 4739 size = MAX_PATH; 4740 sprintf(path, "%s\\FileName1", expected); 4741 r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size); 4742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4743 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4744 4745 size = MAX_PATH; 4746 sprintf(path, "%s\\FileName1", expected); 4747 r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size); 4748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4749 if (space) 4750 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4751 else 4752 todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4753 4754 RegSetValueA(hklm, NULL, REG_SZ, "", 0); 4755 RegDeleteValueA(hklm, "Value1"); 4756 RegDeleteValueA(hklm, "Value2"); 4757 RegDeleteValueA(hklm, "Value3"); 4758 RegDeleteValueA(hklm, "Value4"); 4759 RegDeleteValueA(hklm, "Value5"); 4760 RegDeleteValueA(hklm, "Value6"); 4761 RegDeleteValueA(hklm, "Value7"); 4762 RegDeleteValueA(hklm, "Value8"); 4763 RegDeleteValueA(hklm, "Value9"); 4764 RegDeleteValueA(hklm, "Value10"); 4765 RegDeleteValueA(hklm, "Value11"); 4766 RegDeleteValueA(hklm, "Value12"); 4767 RegDeleteValueA(hklm, "Value13"); 4768 RegDeleteValueA(hklm, "Value14"); 4769 RegDeleteValueA(hklm, "Value15"); 4770 RegDeleteValueA(hklm, "Value16"); 4771 RegDeleteValueA(hklm, "Value17"); 4772 RegDeleteKeyA(hklm, ""); 4773 RegCloseKey(hklm); 4774 4775 RegDeleteValueA(classes, "Value1"); 4776 RegDeleteKeyA(classes, ""); 4777 RegCloseKey(classes); 4778 4779 RegDeleteValueA(hkcu, "Value1"); 4780 RegDeleteKeyA(hkcu, ""); 4781 RegCloseKey(hkcu); 4782 4783 RegDeleteValueA(users, "Value1"); 4784 RegDeleteKeyA(users, ""); 4785 RegCloseKey(users); 4786 4787 DeleteFileA("FileName1"); 4788 DeleteFileA("FileName3.dll"); 4789 DeleteFileA("FileName4.dll"); 4790 DeleteFileA("FileName5.dll"); 4791 MsiCloseHandle(hpkg); 4792 DeleteFileA(msifile); 4793 } 4794 4795 static void delete_win_ini(LPCSTR file) 4796 { 4797 CHAR path[MAX_PATH]; 4798 4799 GetWindowsDirectoryA(path, MAX_PATH); 4800 lstrcatA(path, "\\"); 4801 lstrcatA(path, file); 4802 4803 DeleteFileA(path); 4804 } 4805 4806 static void test_appsearch_inilocator(void) 4807 { 4808 MSIHANDLE hpkg, hdb; 4809 char path[MAX_PATH + 14], expected[MAX_PATH], prop[MAX_PATH]; 4810 BOOL version; 4811 LPSTR ptr; 4812 DWORD size; 4813 UINT r; 4814 4815 version = TRUE; 4816 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3))) 4817 version = FALSE; 4818 4819 DeleteFileA("test.dll"); 4820 4821 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini"); 4822 4823 strcpy(expected, CURR_DIR); 4824 if (is_root(CURR_DIR)) expected[2] = 0; 4825 4826 create_test_file("FileName1"); 4827 sprintf(path, "%s\\FileName1", expected); 4828 WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini"); 4829 4830 WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini"); 4831 4832 sprintf(path, "%s\\IDontExist", expected); 4833 WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini"); 4834 4835 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4836 sprintf(path, "%s\\FileName2.dll", expected); 4837 WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini"); 4838 4839 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4)); 4840 sprintf(path, "%s\\FileName3.dll", expected); 4841 WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini"); 4842 4843 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 4844 sprintf(path, "%s\\FileName4.dll", expected); 4845 WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini"); 4846 4847 hdb = create_package_db(); 4848 ok(hdb, "Expected a valid database handle\n"); 4849 4850 create_appsearch_table(hdb); 4851 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); 4852 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); 4853 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); 4854 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); 4855 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); 4856 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); 4857 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); 4858 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); 4859 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); 4860 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); 4861 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); 4862 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); 4863 4864 create_inilocator_table(hdb); 4865 4866 /* msidbLocatorTypeRawValue, field 1 */ 4867 add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2"); 4868 4869 /* msidbLocatorTypeRawValue, field 2 */ 4870 add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2"); 4871 4872 /* msidbLocatorTypeRawValue, entire field */ 4873 add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2"); 4874 4875 /* msidbLocatorTypeFile */ 4876 add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1"); 4877 4878 /* msidbLocatorTypeDirectory, file */ 4879 add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0"); 4880 4881 /* msidbLocatorTypeDirectory, directory */ 4882 add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0"); 4883 4884 /* msidbLocatorTypeFile, file, no signature */ 4885 add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1"); 4886 4887 /* msidbLocatorTypeFile, dir, no signature */ 4888 add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1"); 4889 4890 /* msidbLocatorTypeFile, file does not exist */ 4891 add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1"); 4892 4893 /* msidbLocatorTypeFile, signature with version */ 4894 add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1"); 4895 4896 /* msidbLocatorTypeFile, signature with version, ver > max */ 4897 add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1"); 4898 4899 /* msidbLocatorTypeFile, signature with version, sig->name ignored */ 4900 add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1"); 4901 4902 create_signature_table(hdb); 4903 add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''"); 4904 add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''"); 4905 add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4906 add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4907 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 4908 4909 r = package_from_db(hdb, &hpkg); 4910 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 4911 { 4912 skip("Not enough rights to perform tests\n"); 4913 goto error; 4914 } 4915 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); 4916 4917 MsiCloseHandle( hdb ); 4918 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 4919 4920 r = MsiDoActionA(hpkg, "AppSearch"); 4921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4922 4923 size = MAX_PATH; 4924 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size); 4925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4926 if (!prop[0]) 4927 { 4928 win_skip("broken result\n"); 4929 MsiCloseHandle(hpkg); 4930 goto error; 4931 } 4932 ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop); 4933 4934 size = MAX_PATH; 4935 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size); 4936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4937 ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop); 4938 4939 size = MAX_PATH; 4940 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size); 4941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4942 ok(!lstrcmpA(prop, "keydata,field2"), 4943 "Expected \"keydata,field2\", got \"%s\"\n", prop); 4944 4945 size = MAX_PATH; 4946 sprintf(path, "%s\\FileName1", expected); 4947 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size); 4948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4949 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4950 4951 size = MAX_PATH; 4952 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); 4953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4954 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4955 4956 size = MAX_PATH; 4957 sprintf(path, "%s\\", expected); 4958 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size); 4959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4960 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4961 4962 size = MAX_PATH; 4963 sprintf(path, "%s\\", expected); 4964 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size); 4965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4966 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4967 4968 if (!is_root(CURR_DIR)) 4969 { 4970 size = MAX_PATH; 4971 lstrcpyA(path, expected); 4972 ptr = strrchr(path, '\\'); 4973 *(ptr + 1) = 0; 4974 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size); 4975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4976 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4977 } 4978 size = MAX_PATH; 4979 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size); 4980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4981 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4982 4983 if (version) 4984 { 4985 size = MAX_PATH; 4986 sprintf(path, "%s\\FileName2.dll", expected); 4987 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size); 4988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4989 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 4990 4991 size = MAX_PATH; 4992 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size); 4993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4994 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 4995 4996 size = MAX_PATH; 4997 sprintf(path, "%s\\FileName4.dll", expected); 4998 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size); 4999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5000 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5001 } 5002 5003 MsiCloseHandle(hpkg); 5004 5005 error: 5006 delete_win_ini("IniFile.ini"); 5007 DeleteFileA("FileName1"); 5008 DeleteFileA("FileName2.dll"); 5009 DeleteFileA("FileName3.dll"); 5010 DeleteFileA("FileName4.dll"); 5011 DeleteFileA(msifile); 5012 } 5013 5014 /* 5015 * MSI AppSearch action on DrLocator table always returns absolute paths. 5016 * If a relative path was set, it returns the first absolute path that 5017 * matches or an empty string if it didn't find anything. 5018 * This helper function replicates this behaviour. 5019 */ 5020 static void search_absolute_directory(LPSTR absolute, LPCSTR relative) 5021 { 5022 int i, size; 5023 DWORD attr, drives; 5024 5025 size = lstrlenA(relative); 5026 drives = GetLogicalDrives(); 5027 lstrcpyA(absolute, "A:\\"); 5028 for (i = 0; i < 26; absolute[0] = '\0', i++) 5029 { 5030 if (!(drives & (1 << i))) 5031 continue; 5032 5033 absolute[0] = 'A' + i; 5034 if (GetDriveTypeA(absolute) != DRIVE_FIXED) 5035 continue; 5036 5037 lstrcpynA(absolute + 3, relative, size + 1); 5038 attr = GetFileAttributesA(absolute); 5039 if (attr != INVALID_FILE_ATTRIBUTES && 5040 (attr & FILE_ATTRIBUTE_DIRECTORY)) 5041 { 5042 if (absolute[3 + size - 1] != '\\') 5043 lstrcatA(absolute, "\\"); 5044 break; 5045 } 5046 absolute[3] = '\0'; 5047 } 5048 } 5049 5050 static void test_appsearch_drlocator(void) 5051 { 5052 MSIHANDLE hpkg, hdb; 5053 char path[MAX_PATH + 27], expected[MAX_PATH], prop[MAX_PATH]; 5054 BOOL version; 5055 DWORD size; 5056 UINT r; 5057 5058 version = TRUE; 5059 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3))) 5060 version = FALSE; 5061 5062 DeleteFileA("test.dll"); 5063 5064 create_test_file("FileName1"); 5065 CreateDirectoryA("one", NULL); 5066 CreateDirectoryA("one\\two", NULL); 5067 CreateDirectoryA("one\\two\\three", NULL); 5068 create_test_file("one\\two\\three\\FileName2"); 5069 CreateDirectoryA("another", NULL); 5070 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 5071 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4)); 5072 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3)); 5073 5074 hdb = create_package_db(); 5075 ok(hdb, "Expected a valid database handle\n"); 5076 5077 create_appsearch_table(hdb); 5078 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); 5079 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); 5080 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); 5081 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); 5082 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); 5083 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); 5084 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); 5085 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); 5086 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); 5087 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); 5088 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); 5089 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'"); 5090 5091 create_drlocator_table(hdb); 5092 5093 strcpy(expected, CURR_DIR); 5094 if (is_root(CURR_DIR)) expected[2] = 0; 5095 5096 /* no parent, full path, depth 0, signature */ 5097 sprintf(path, "'NewSignature1', '', '%s', 0", expected); 5098 add_drlocator_entry(hdb, path); 5099 5100 /* no parent, full path, depth 0, no signature */ 5101 sprintf(path, "'NewSignature2', '', '%s', 0", expected); 5102 add_drlocator_entry(hdb, path); 5103 5104 /* no parent, relative path, depth 0, no signature */ 5105 sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3); 5106 add_drlocator_entry(hdb, path); 5107 5108 /* no parent, full path, depth 2, signature */ 5109 sprintf(path, "'NewSignature4', '', '%s', 2", expected); 5110 add_drlocator_entry(hdb, path); 5111 5112 /* no parent, full path, depth 3, signature */ 5113 sprintf(path, "'NewSignature5', '', '%s', 3", expected); 5114 add_drlocator_entry(hdb, path); 5115 5116 /* no parent, full path, depth 1, signature is dir */ 5117 sprintf(path, "'NewSignature6', '', '%s', 1", expected); 5118 add_drlocator_entry(hdb, path); 5119 5120 /* parent is in DrLocator, relative path, depth 0, signature */ 5121 sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1"); 5122 add_drlocator_entry(hdb, path); 5123 5124 /* no parent, full path, depth 0, signature w/ version */ 5125 sprintf(path, "'NewSignature8', '', '%s', 0", expected); 5126 add_drlocator_entry(hdb, path); 5127 5128 /* no parent, full path, depth 0, signature w/ version, ver > max */ 5129 sprintf(path, "'NewSignature9', '', '%s', 0", expected); 5130 add_drlocator_entry(hdb, path); 5131 5132 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */ 5133 sprintf(path, "'NewSignature10', '', '%s', 0", expected); 5134 add_drlocator_entry(hdb, path); 5135 5136 /* no parent, relative empty path, depth 0, no signature */ 5137 sprintf(path, "'NewSignature11', '', '', 0"); 5138 add_drlocator_entry(hdb, path); 5139 5140 create_reglocator_table(hdb); 5141 5142 /* parent */ 5143 add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1); 5144 5145 /* parent is in RegLocator, no path, depth 0, no signature */ 5146 sprintf(path, "'NewSignature13', 'NewSignature12', '', 0"); 5147 add_drlocator_entry(hdb, path); 5148 5149 create_signature_table(hdb); 5150 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''"); 5151 add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''"); 5152 add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''"); 5153 add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''"); 5154 add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''"); 5155 add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5156 add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5157 add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); 5158 5159 r = package_from_db(hdb, &hpkg); 5160 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5161 { 5162 skip("Not enough rights to perform tests\n"); 5163 goto error; 5164 } 5165 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); 5166 5167 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5168 5169 r = MsiDoActionA(hpkg, "AppSearch"); 5170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5171 5172 size = MAX_PATH; 5173 sprintf(path, "%s\\FileName1", expected); 5174 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size); 5175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5176 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5177 5178 size = MAX_PATH; 5179 sprintf(path, "%s\\", expected); 5180 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size); 5181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5182 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5183 5184 size = MAX_PATH; 5185 search_absolute_directory(path, expected + 3); 5186 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size); 5187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5188 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5189 5190 size = MAX_PATH; 5191 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size); 5192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5193 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5194 5195 size = MAX_PATH; 5196 sprintf(path, "%s\\one\\two\\three\\FileName2", expected); 5197 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); 5198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5199 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5200 5201 size = MAX_PATH; 5202 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size); 5203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5204 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5205 5206 size = MAX_PATH; 5207 sprintf(path, "%s\\one\\two\\three\\FileName2", expected); 5208 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size); 5209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5210 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5211 5212 if (version) 5213 { 5214 size = MAX_PATH; 5215 sprintf(path, "%s\\FileName3.dll", expected); 5216 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size); 5217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5218 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5219 5220 size = MAX_PATH; 5221 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size); 5222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5223 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5224 5225 size = MAX_PATH; 5226 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size); 5227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5228 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop); 5229 } 5230 5231 size = MAX_PATH; 5232 search_absolute_directory(path, ""); 5233 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size); 5234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5235 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); 5236 5237 size = MAX_PATH; 5238 strcpy(path, "c:\\"); 5239 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size); 5240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5241 ok(!prop[0], "Expected \"\", got \"%s\"\n", prop); 5242 5243 MsiCloseHandle(hpkg); 5244 5245 error: 5246 DeleteFileA("FileName1"); 5247 DeleteFileA("FileName3.dll"); 5248 DeleteFileA("FileName4.dll"); 5249 DeleteFileA("FileName5.dll"); 5250 DeleteFileA("one\\two\\three\\FileName2"); 5251 RemoveDirectoryA("one\\two\\three"); 5252 RemoveDirectoryA("one\\two"); 5253 RemoveDirectoryA("one"); 5254 RemoveDirectoryA("another"); 5255 DeleteFileA(msifile); 5256 } 5257 5258 static void test_featureparents(void) 5259 { 5260 MSIHANDLE hpkg; 5261 UINT r; 5262 MSIHANDLE hdb; 5263 5264 hdb = create_package_db(); 5265 ok ( hdb, "failed to create package database\n" ); 5266 5267 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); 5268 5269 create_feature_table( hdb ); 5270 create_component_table( hdb ); 5271 create_feature_components_table( hdb ); 5272 create_file_table( hdb ); 5273 5274 /* msidbFeatureAttributesFavorLocal */ 5275 add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" ); 5276 5277 /* msidbFeatureAttributesFavorSource */ 5278 add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" ); 5279 5280 /* msidbFeatureAttributesFavorLocal */ 5281 add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" ); 5282 5283 /* msidbFeatureAttributesUIDisallowAbsent */ 5284 add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" ); 5285 5286 /* disabled because of install level */ 5287 add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" ); 5288 5289 /* child feature of disabled feature */ 5290 add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" ); 5291 5292 /* component of disabled feature (install level) */ 5293 add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" ); 5294 5295 /* component of disabled child feature (install level) */ 5296 add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" ); 5297 5298 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ 5299 add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" ); 5300 5301 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ 5302 add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" ); 5303 5304 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ 5305 add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" ); 5306 5307 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */ 5308 add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" ); 5309 5310 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ 5311 add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" ); 5312 5313 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */ 5314 add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" ); 5315 5316 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ 5317 add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" ); 5318 5319 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ 5320 add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" ); 5321 5322 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ 5323 add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" ); 5324 5325 add_feature_components_entry( hdb, "'zodiac', 'leo'" ); 5326 add_feature_components_entry( hdb, "'zodiac', 'virgo'" ); 5327 add_feature_components_entry( hdb, "'zodiac', 'libra'" ); 5328 add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" ); 5329 add_feature_components_entry( hdb, "'perseus', 'cepheus'" ); 5330 add_feature_components_entry( hdb, "'perseus', 'andromeda'" ); 5331 add_feature_components_entry( hdb, "'orion', 'leo'" ); 5332 add_feature_components_entry( hdb, "'orion', 'virgo'" ); 5333 add_feature_components_entry( hdb, "'orion', 'libra'" ); 5334 add_feature_components_entry( hdb, "'orion', 'cassiopeia'" ); 5335 add_feature_components_entry( hdb, "'orion', 'cepheus'" ); 5336 add_feature_components_entry( hdb, "'orion', 'andromeda'" ); 5337 add_feature_components_entry( hdb, "'orion', 'canis'" ); 5338 add_feature_components_entry( hdb, "'orion', 'monoceros'" ); 5339 add_feature_components_entry( hdb, "'orion', 'lepus'" ); 5340 add_feature_components_entry( hdb, "'waters', 'delphinus'" ); 5341 add_feature_components_entry( hdb, "'bayer', 'hydrus'" ); 5342 5343 add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" ); 5344 add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" ); 5345 add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" ); 5346 add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" ); 5347 add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" ); 5348 add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" ); 5349 add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" ); 5350 add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" ); 5351 add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" ); 5352 add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" ); 5353 add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" ); 5354 5355 r = package_from_db( hdb, &hpkg ); 5356 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5357 { 5358 skip("Not enough rights to perform tests\n"); 5359 DeleteFileA(msifile); 5360 return; 5361 } 5362 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 5363 5364 MsiCloseHandle( hdb ); 5365 5366 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5367 5368 r = MsiDoActionA( hpkg, "CostInitialize"); 5369 ok( r == ERROR_SUCCESS, "cost init failed\n"); 5370 5371 r = MsiDoActionA( hpkg, "FileCost"); 5372 ok( r == ERROR_SUCCESS, "file cost failed\n"); 5373 5374 r = MsiDoActionA( hpkg, "CostFinalize"); 5375 ok( r == ERROR_SUCCESS, "cost finalize failed\n"); 5376 5377 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 5378 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 5379 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 5380 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 5381 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 5382 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 5383 5384 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5385 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5386 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5387 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5388 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5389 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5390 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5391 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5392 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5393 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5394 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5395 5396 r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT); 5397 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r); 5398 5399 r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT); 5400 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r); 5401 5402 r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT); 5403 ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r); 5404 5405 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE ); 5406 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE ); 5407 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE ); 5408 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE ); 5409 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 5410 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); 5411 5412 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5413 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5414 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5415 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE ); 5416 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5417 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE ); 5418 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5419 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5420 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5421 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5422 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); 5423 5424 MsiCloseHandle(hpkg); 5425 DeleteFileA(msifile); 5426 } 5427 5428 static void test_installprops(void) 5429 { 5430 MSIHANDLE hpkg, hdb; 5431 CHAR path[MAX_PATH], buf[MAX_PATH]; 5432 DWORD size, type; 5433 LANGID langid; 5434 HKEY hkey1, hkey2, pathkey = NULL; 5435 int res; 5436 UINT r; 5437 REGSAM access = KEY_ALL_ACCESS; 5438 SYSTEM_INFO si; 5439 INSTALLUILEVEL uilevel; 5440 5441 if (is_wow64) 5442 access |= KEY_WOW64_64KEY; 5443 5444 lstrcpyA(path, CURR_DIR); 5445 if (!is_root(CURR_DIR)) lstrcatA(path, "\\"); 5446 lstrcatA(path, msifile); 5447 5448 uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL); 5449 5450 hdb = create_package_db(); 5451 ok( hdb, "failed to create database\n"); 5452 5453 r = package_from_db(hdb, &hpkg); 5454 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5455 { 5456 skip("Not enough rights to perform tests\n"); 5457 MsiSetInternalUI(uilevel, NULL); 5458 DeleteFileA(msifile); 5459 return; 5460 } 5461 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 5462 5463 MsiCloseHandle(hdb); 5464 5465 buf[0] = 0; 5466 size = MAX_PATH; 5467 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size); 5468 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5469 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf); 5470 5471 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5472 5473 buf[0] = 0; 5474 size = MAX_PATH; 5475 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size); 5476 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5477 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf); 5478 5479 buf[0] = 0; 5480 size = MAX_PATH; 5481 r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size); 5482 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5483 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf); 5484 5485 RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1); 5486 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2); 5487 if (res == ERROR_ACCESS_DENIED) 5488 { 5489 win_skip("no access\n"); 5490 goto done; 5491 } 5492 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 5493 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey); 5494 5495 size = MAX_PATH; 5496 type = REG_SZ; 5497 *path = '\0'; 5498 if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS) 5499 { 5500 size = MAX_PATH; 5501 type = REG_SZ; 5502 RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size); 5503 } 5504 5505 buf[0] = 0; 5506 size = MAX_PATH; 5507 r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size); 5508 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5509 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf); 5510 5511 size = MAX_PATH; 5512 type = REG_SZ; 5513 *path = '\0'; 5514 if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS) 5515 { 5516 size = MAX_PATH; 5517 type = REG_SZ; 5518 RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size); 5519 } 5520 5521 if (*path) 5522 { 5523 buf[0] = 0; 5524 size = MAX_PATH; 5525 r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size); 5526 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5527 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf); 5528 } 5529 5530 buf[0] = 0; 5531 size = MAX_PATH; 5532 r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size); 5533 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5534 trace("VersionDatabase = %s\n", buf); 5535 5536 buf[0] = 0; 5537 size = MAX_PATH; 5538 r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size); 5539 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5540 trace("VersionMsi = %s\n", buf); 5541 5542 buf[0] = 0; 5543 size = MAX_PATH; 5544 r = MsiGetPropertyA(hpkg, "Date", buf, &size); 5545 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5546 trace("Date = %s\n", buf); 5547 5548 buf[0] = 0; 5549 size = MAX_PATH; 5550 r = MsiGetPropertyA(hpkg, "Time", buf, &size); 5551 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5552 trace("Time = %s\n", buf); 5553 5554 buf[0] = 0; 5555 size = MAX_PATH; 5556 r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size); 5557 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); 5558 trace("PackageCode = %s\n", buf); 5559 5560 buf[0] = 0; 5561 size = MAX_PATH; 5562 r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size); 5563 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 5564 trace("ComputerName = %s\n", buf); 5565 5566 langid = GetUserDefaultLangID(); 5567 sprintf(path, "%d", langid); 5568 5569 buf[0] = 0; 5570 size = MAX_PATH; 5571 r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size); 5572 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 5573 ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf); 5574 5575 res = GetSystemMetrics(SM_CXSCREEN); 5576 buf[0] = 0; 5577 size = MAX_PATH; 5578 r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size); 5579 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 5580 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf); 5581 5582 res = GetSystemMetrics(SM_CYSCREEN); 5583 buf[0] = 0; 5584 size = MAX_PATH; 5585 r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size); 5586 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); 5587 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf); 5588 5589 buf[0] = 0; 5590 size = MAX_PATH; 5591 r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size); 5592 if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf ); 5593 5594 GetNativeSystemInfo(&si); 5595 5596 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion()))); 5597 check_prop(hpkg, "VersionNT", buf, 1, 1); 5598 5599 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) 5600 { 5601 sprintf(buf, "%d", si.wProcessorLevel); 5602 check_prop(hpkg, "Intel", buf, 1, 0); 5603 check_prop(hpkg, "MsiAMD64", buf, 1, 0); 5604 check_prop(hpkg, "Msix64", buf, 1, 0); 5605 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion()))); 5606 check_prop(hpkg, "VersionNT64", buf, 1, 1); 5607 5608 GetSystemDirectoryA(path, MAX_PATH); 5609 strcat(path, "\\"); 5610 check_prop(hpkg, "System64Folder", path, 0, 0); 5611 5612 GetSystemWow64DirectoryA(path, MAX_PATH); 5613 strcat(path, "\\"); 5614 check_prop(hpkg, "SystemFolder", path, 0, 0); 5615 5616 size = MAX_PATH; 5617 r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size); 5618 strcat(path, "\\"); 5619 check_prop(hpkg, "ProgramFilesFolder", path, 0, 0); 5620 5621 size = MAX_PATH; 5622 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size); 5623 strcat(path, "\\"); 5624 check_prop(hpkg, "ProgramFiles64Folder", path, 0, 0); 5625 5626 size = MAX_PATH; 5627 RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size); 5628 strcat(path, "\\"); 5629 check_prop(hpkg, "CommonFilesFolder", path, 0, 0); 5630 5631 size = MAX_PATH; 5632 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size); 5633 strcat(path, "\\"); 5634 check_prop(hpkg, "CommonFiles64Folder", path, 0, 0); 5635 } 5636 else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) 5637 { 5638 sprintf(buf, "%d", si.wProcessorLevel); 5639 check_prop(hpkg, "Intel", buf, 1, 0); 5640 5641 GetSystemDirectoryA(path, MAX_PATH); 5642 strcat(path, "\\"); 5643 check_prop(hpkg, "SystemFolder", path, 0, 0); 5644 5645 size = MAX_PATH; 5646 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size); 5647 strcat(path, "\\"); 5648 check_prop(hpkg, "ProgramFilesFolder", path, 0, 0); 5649 5650 size = MAX_PATH; 5651 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size); 5652 strcat(path, "\\"); 5653 check_prop(hpkg, "CommonFilesFolder", path, 0, 0); 5654 5655 check_prop(hpkg, "MsiAMD64", "", 1, 0); 5656 check_prop(hpkg, "Msix64", "", 1, 0); 5657 check_prop(hpkg, "VersionNT64", "", 1, 0); 5658 check_prop(hpkg, "System64Folder", "", 0, 0); 5659 check_prop(hpkg, "ProgramFiles64Dir", "", 0, 0); 5660 check_prop(hpkg, "CommonFiles64Dir", "", 0, 0); 5661 } 5662 5663 done: 5664 CloseHandle(hkey1); 5665 CloseHandle(hkey2); 5666 RegCloseKey(pathkey); 5667 MsiCloseHandle(hpkg); 5668 DeleteFileA(msifile); 5669 MsiSetInternalUI(uilevel, NULL); 5670 } 5671 5672 static void test_launchconditions(void) 5673 { 5674 MSIHANDLE hpkg; 5675 MSIHANDLE hdb; 5676 UINT r; 5677 5678 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5679 5680 hdb = create_package_db(); 5681 ok( hdb, "failed to create package database\n" ); 5682 5683 create_launchcondition_table( hdb ); 5684 5685 add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" ); 5686 5687 /* invalid condition */ 5688 add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" ); 5689 5690 r = package_from_db( hdb, &hpkg ); 5691 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5692 { 5693 skip("Not enough rights to perform tests\n"); 5694 DeleteFileA(msifile); 5695 return; 5696 } 5697 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); 5698 5699 MsiCloseHandle( hdb ); 5700 5701 r = MsiSetPropertyA( hpkg, "X", "1" ); 5702 ok( r == ERROR_SUCCESS, "failed to set property\n" ); 5703 5704 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5705 5706 /* invalid conditions are ignored */ 5707 r = MsiDoActionA( hpkg, "LaunchConditions" ); 5708 ok( r == ERROR_SUCCESS, "cost init failed\n" ); 5709 5710 /* verify LaunchConditions still does some verification */ 5711 r = MsiSetPropertyA( hpkg, "X", "2" ); 5712 ok( r == ERROR_SUCCESS, "failed to set property\n" ); 5713 5714 r = MsiDoActionA( hpkg, "LaunchConditions" ); 5715 ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r ); 5716 5717 MsiCloseHandle( hpkg ); 5718 DeleteFileA( msifile ); 5719 } 5720 5721 static void test_ccpsearch(void) 5722 { 5723 MSIHANDLE hdb, hpkg; 5724 CHAR prop[MAX_PATH]; 5725 DWORD size = MAX_PATH; 5726 UINT r; 5727 5728 hdb = create_package_db(); 5729 ok(hdb, "failed to create package database\n"); 5730 5731 create_ccpsearch_table(hdb); 5732 add_ccpsearch_entry(hdb, "'CCP_random'"); 5733 add_ccpsearch_entry(hdb, "'RMCCP_random'"); 5734 5735 create_reglocator_table(hdb); 5736 add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1); 5737 5738 create_drlocator_table(hdb); 5739 add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'"); 5740 5741 create_signature_table(hdb); 5742 5743 r = package_from_db(hdb, &hpkg); 5744 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5745 { 5746 skip("Not enough rights to perform tests\n"); 5747 DeleteFileA(msifile); 5748 return; 5749 } 5750 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 5751 5752 MsiCloseHandle(hdb); 5753 5754 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5755 5756 r = MsiDoActionA(hpkg, "CCPSearch"); 5757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5758 5759 r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size); 5760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5761 ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop); 5762 5763 MsiCloseHandle(hpkg); 5764 DeleteFileA(msifile); 5765 } 5766 5767 static void test_complocator(void) 5768 { 5769 MSIHANDLE hdb, hpkg; 5770 UINT r; 5771 CHAR prop[MAX_PATH]; 5772 CHAR expected[MAX_PATH]; 5773 DWORD size = MAX_PATH; 5774 5775 hdb = create_package_db(); 5776 ok(hdb, "failed to create package database\n"); 5777 5778 create_appsearch_table(hdb); 5779 add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'"); 5780 add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'"); 5781 add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'"); 5782 add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'"); 5783 add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'"); 5784 add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'"); 5785 add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'"); 5786 add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'"); 5787 add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'"); 5788 add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'"); 5789 add_appsearch_entry(hdb, "'KAKURU', 'kakuru'"); 5790 add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'"); 5791 add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'"); 5792 add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'"); 5793 add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'"); 5794 add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'"); 5795 5796 create_complocator_table(hdb); 5797 add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1"); 5798 add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0"); 5799 add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1"); 5800 add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0"); 5801 add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1"); 5802 add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0"); 5803 add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1"); 5804 add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0"); 5805 add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1"); 5806 add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0"); 5807 add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1"); 5808 add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0"); 5809 add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1"); 5810 add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0"); 5811 add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1"); 5812 add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0"); 5813 5814 create_signature_table(hdb); 5815 add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''"); 5816 add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''"); 5817 add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''"); 5818 add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''"); 5819 add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''"); 5820 add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''"); 5821 add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''"); 5822 add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''"); 5823 5824 r = package_from_db(hdb, &hpkg); 5825 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 5826 { 5827 skip("Not enough rights to perform tests\n"); 5828 DeleteFileA(msifile); 5829 return; 5830 } 5831 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 5832 5833 MsiCloseHandle(hdb); 5834 5835 create_test_file("abelisaurus"); 5836 create_test_file("bactrosaurus"); 5837 create_test_file("camelotia"); 5838 create_test_file("diclonius"); 5839 create_test_file("echinodon"); 5840 create_test_file("falcarius"); 5841 create_test_file("gallimimus"); 5842 create_test_file("hagryphus"); 5843 CreateDirectoryA("iguanodon", NULL); 5844 CreateDirectoryA("jobaria", NULL); 5845 CreateDirectoryA("kakuru", NULL); 5846 CreateDirectoryA("labocania", NULL); 5847 CreateDirectoryA("megaraptor", NULL); 5848 CreateDirectoryA("neosodon", NULL); 5849 CreateDirectoryA("olorotitan", NULL); 5850 CreateDirectoryA("pantydraco", NULL); 5851 5852 set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE, 5853 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE); 5854 set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE, 5855 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE); 5856 set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE, 5857 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE); 5858 set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE, 5859 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE); 5860 set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE, 5861 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE); 5862 set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE, 5863 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE); 5864 set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE, 5865 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE); 5866 set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE, 5867 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE); 5868 5869 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 5870 5871 r = MsiDoActionA(hpkg, "AppSearch"); 5872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5873 5874 size = MAX_PATH; 5875 r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size); 5876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5877 5878 lstrcpyA(expected, CURR_DIR); 5879 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\"); 5880 lstrcatA(expected, "abelisaurus"); 5881 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""), 5882 "Expected %s or empty string, got %s\n", expected, prop); 5883 5884 size = MAX_PATH; 5885 r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size); 5886 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5887 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5888 5889 size = MAX_PATH; 5890 r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size); 5891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5892 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5893 5894 size = MAX_PATH; 5895 r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size); 5896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5897 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5898 5899 size = MAX_PATH; 5900 r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size); 5901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5902 5903 lstrcpyA(expected, CURR_DIR); 5904 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\"); 5905 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""), 5906 "Expected %s or empty string, got %s\n", expected, prop); 5907 5908 size = MAX_PATH; 5909 r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size); 5910 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5911 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5912 5913 size = MAX_PATH; 5914 r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size); 5915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5916 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5917 5918 size = MAX_PATH; 5919 r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size); 5920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5921 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5922 5923 size = MAX_PATH; 5924 r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size); 5925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5926 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5927 5928 size = MAX_PATH; 5929 r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size); 5930 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5931 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5932 5933 size = MAX_PATH; 5934 r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size); 5935 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5936 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5937 5938 size = MAX_PATH; 5939 r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size); 5940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5941 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5942 5943 size = MAX_PATH; 5944 r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size); 5945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5946 5947 lstrcpyA(expected, CURR_DIR); 5948 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\"); 5949 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""), 5950 "Expected %s or empty string, got %s\n", expected, prop); 5951 5952 size = MAX_PATH; 5953 r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size); 5954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5955 5956 lstrcpyA(expected, CURR_DIR); 5957 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\"); 5958 lstrcatA(expected, "neosodon\\"); 5959 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""), 5960 "Expected %s or empty string, got %s\n", expected, prop); 5961 5962 size = MAX_PATH; 5963 r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size); 5964 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5965 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5966 5967 size = MAX_PATH; 5968 r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size); 5969 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5970 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop); 5971 5972 MsiCloseHandle(hpkg); 5973 DeleteFileA("abelisaurus"); 5974 DeleteFileA("bactrosaurus"); 5975 DeleteFileA("camelotia"); 5976 DeleteFileA("diclonius"); 5977 DeleteFileA("echinodon"); 5978 DeleteFileA("falcarius"); 5979 DeleteFileA("gallimimus"); 5980 DeleteFileA("hagryphus"); 5981 RemoveDirectoryA("iguanodon"); 5982 RemoveDirectoryA("jobaria"); 5983 RemoveDirectoryA("kakuru"); 5984 RemoveDirectoryA("labocania"); 5985 RemoveDirectoryA("megaraptor"); 5986 RemoveDirectoryA("neosodon"); 5987 RemoveDirectoryA("olorotitan"); 5988 RemoveDirectoryA("pantydraco"); 5989 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}", 5990 MSIINSTALLCONTEXT_MACHINE, NULL); 5991 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", 5992 MSIINSTALLCONTEXT_MACHINE, NULL); 5993 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}", 5994 MSIINSTALLCONTEXT_MACHINE, NULL); 5995 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}", 5996 MSIINSTALLCONTEXT_MACHINE, NULL); 5997 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", 5998 MSIINSTALLCONTEXT_MACHINE, NULL); 5999 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}", 6000 MSIINSTALLCONTEXT_MACHINE, NULL); 6001 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", 6002 MSIINSTALLCONTEXT_MACHINE, NULL); 6003 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}", 6004 MSIINSTALLCONTEXT_MACHINE, NULL); 6005 DeleteFileA(msifile); 6006 } 6007 6008 static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val) 6009 { 6010 MSIHANDLE summary; 6011 UINT r; 6012 6013 r = MsiGetSummaryInformationA(db, NULL, 1, &summary); 6014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6015 6016 r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL); 6017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6018 6019 r = MsiSummaryInfoPersist(summary); 6020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 6021 6022 MsiCloseHandle(summary); 6023 } 6024 6025 static void test_MsiGetSourcePath(void) 6026 { 6027 MSIHANDLE hdb, hpkg; 6028 CHAR path[MAX_PATH]; 6029 CHAR cwd[MAX_PATH]; 6030 CHAR subsrc[MAX_PATH]; 6031 CHAR sub2[MAX_PATH]; 6032 DWORD size; 6033 UINT r; 6034 6035 lstrcpyA(cwd, CURR_DIR); 6036 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\"); 6037 6038 lstrcpyA(subsrc, cwd); 6039 lstrcatA(subsrc, "subsource"); 6040 lstrcatA(subsrc, "\\"); 6041 6042 lstrcpyA(sub2, subsrc); 6043 lstrcatA(sub2, "sub2"); 6044 lstrcatA(sub2, "\\"); 6045 6046 /* uncompressed source */ 6047 6048 hdb = create_package_db(); 6049 ok( hdb, "failed to create database\n"); 6050 6051 set_suminfo_prop(hdb, PID_WORDCOUNT, 0); 6052 6053 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); 6054 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'"); 6055 add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'"); 6056 6057 r = MsiDatabaseCommit(hdb); 6058 ok(r == ERROR_SUCCESS , "Failed to commit database\n"); 6059 6060 r = package_from_db(hdb, &hpkg); 6061 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 6062 { 6063 skip("Not enough rights to perform tests\n"); 6064 DeleteFileA(msifile); 6065 return; 6066 } 6067 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 6068 6069 MsiCloseHandle(hdb); 6070 6071 /* invalid database handle */ 6072 size = MAX_PATH; 6073 lstrcpyA(path, "kiwi"); 6074 r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size); 6075 ok(r == ERROR_INVALID_HANDLE, 6076 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 6077 ok(!lstrcmpA(path, "kiwi"), 6078 "Expected path to be unchanged, got \"%s\"\n", path); 6079 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6080 6081 /* NULL szFolder */ 6082 size = MAX_PATH; 6083 lstrcpyA(path, "kiwi"); 6084 r = MsiGetSourcePathA(hpkg, NULL, path, &size); 6085 ok(r == ERROR_INVALID_PARAMETER, 6086 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 6087 ok(!lstrcmpA(path, "kiwi"), 6088 "Expected path to be unchanged, got \"%s\"\n", path); 6089 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6090 6091 /* empty szFolder */ 6092 size = MAX_PATH; 6093 lstrcpyA(path, "kiwi"); 6094 r = MsiGetSourcePathA(hpkg, "", path, &size); 6095 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6096 ok(!lstrcmpA(path, "kiwi"), 6097 "Expected path to be unchanged, got \"%s\"\n", path); 6098 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6099 6100 /* try TARGETDIR */ 6101 size = MAX_PATH; 6102 lstrcpyA(path, "kiwi"); 6103 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6104 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6105 ok(!lstrcmpA(path, "kiwi"), 6106 "Expected path to be unchanged, got \"%s\"\n", path); 6107 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6108 6109 size = MAX_PATH; 6110 lstrcpyA(path, "kiwi"); 6111 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6113 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6114 ok(size == 0, "Expected 0, got %lu\n", size); 6115 6116 size = MAX_PATH; 6117 lstrcpyA(path, "kiwi"); 6118 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6120 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6121 ok(size == 0, "Expected 0, got %lu\n", size); 6122 6123 /* try SourceDir */ 6124 size = MAX_PATH; 6125 lstrcpyA(path, "kiwi"); 6126 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6127 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6128 ok(!lstrcmpA(path, "kiwi"), 6129 "Expected path to be unchanged, got \"%s\"\n", path); 6130 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6131 6132 /* try SOURCEDIR */ 6133 size = MAX_PATH; 6134 lstrcpyA(path, "kiwi"); 6135 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6136 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6137 ok(!lstrcmpA(path, "kiwi"), 6138 "Expected path to be unchanged, got \"%s\"\n", path); 6139 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6140 6141 /* source path does not exist, but the property exists */ 6142 size = MAX_PATH; 6143 lstrcpyA(path, "kiwi"); 6144 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6146 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6147 ok(size == 0, "Expected 0, got %lu\n", size); 6148 6149 size = MAX_PATH; 6150 lstrcpyA(path, "kiwi"); 6151 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6153 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6154 ok(size == 0, "Expected 0, got %lu\n", size); 6155 6156 /* try SubDir */ 6157 size = MAX_PATH; 6158 lstrcpyA(path, "kiwi"); 6159 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6160 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6161 ok(!lstrcmpA(path, "kiwi"), 6162 "Expected path to be unchanged, got \"%s\"\n", path); 6163 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6164 6165 /* try SubDir2 */ 6166 size = MAX_PATH; 6167 lstrcpyA(path, "kiwi"); 6168 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6169 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6170 ok(!lstrcmpA(path, "kiwi"), 6171 "Expected path to be unchanged, got \"%s\"\n", path); 6172 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6173 6174 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 6175 6176 r = MsiDoActionA(hpkg, "CostInitialize"); 6177 ok(r == ERROR_SUCCESS, "cost init failed\n"); 6178 6179 /* try TARGETDIR after CostInitialize */ 6180 size = MAX_PATH; 6181 lstrcpyA(path, "kiwi"); 6182 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6184 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6185 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6186 6187 /* try SourceDir after CostInitialize */ 6188 size = MAX_PATH; 6189 lstrcpyA(path, "kiwi"); 6190 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6192 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6193 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6194 6195 /* try SOURCEDIR after CostInitialize */ 6196 size = MAX_PATH; 6197 lstrcpyA(path, "kiwi"); 6198 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6199 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6200 ok(!lstrcmpA(path, "kiwi"), 6201 "Expected path to be unchanged, got \"%s\"\n", path); 6202 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6203 6204 /* source path does not exist, but the property exists */ 6205 size = MAX_PATH; 6206 lstrcpyA(path, "kiwi"); 6207 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6209 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6210 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6211 6212 size = MAX_PATH; 6213 lstrcpyA(path, "kiwi"); 6214 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6216 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6217 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6218 6219 /* try SubDir after CostInitialize */ 6220 size = MAX_PATH; 6221 lstrcpyA(path, "kiwi"); 6222 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6224 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6225 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6226 6227 /* try SubDir2 after CostInitialize */ 6228 size = MAX_PATH; 6229 lstrcpyA(path, "kiwi"); 6230 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6231 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6232 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); 6233 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size); 6234 6235 r = MsiDoActionA(hpkg, "ResolveSource"); 6236 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6237 6238 /* try TARGETDIR after ResolveSource */ 6239 size = MAX_PATH; 6240 lstrcpyA(path, "kiwi"); 6241 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6243 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6244 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6245 6246 /* try SourceDir after ResolveSource */ 6247 size = MAX_PATH; 6248 lstrcpyA(path, "kiwi"); 6249 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6250 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6251 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6252 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6253 6254 /* try SOURCEDIR after ResolveSource */ 6255 size = MAX_PATH; 6256 lstrcpyA(path, "kiwi"); 6257 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6258 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6259 ok(!lstrcmpA(path, "kiwi"), 6260 "Expected path to be unchanged, got \"%s\"\n", path); 6261 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6262 6263 /* source path does not exist, but the property exists */ 6264 size = MAX_PATH; 6265 lstrcpyA(path, "kiwi"); 6266 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6268 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6269 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6270 6271 size = MAX_PATH; 6272 lstrcpyA(path, "kiwi"); 6273 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6275 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6276 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6277 6278 /* try SubDir after ResolveSource */ 6279 size = MAX_PATH; 6280 lstrcpyA(path, "kiwi"); 6281 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6282 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6283 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6284 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6285 6286 /* try SubDir2 after ResolveSource */ 6287 size = MAX_PATH; 6288 lstrcpyA(path, "kiwi"); 6289 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6291 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); 6292 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size); 6293 6294 r = MsiDoActionA(hpkg, "FileCost"); 6295 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6296 6297 /* try TARGETDIR after FileCost */ 6298 size = MAX_PATH; 6299 lstrcpyA(path, "kiwi"); 6300 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6302 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6303 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6304 6305 /* try SourceDir after FileCost */ 6306 size = MAX_PATH; 6307 lstrcpyA(path, "kiwi"); 6308 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6309 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6310 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6311 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6312 6313 /* try SOURCEDIR after FileCost */ 6314 size = MAX_PATH; 6315 lstrcpyA(path, "kiwi"); 6316 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6317 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6318 ok(!lstrcmpA(path, "kiwi"), 6319 "Expected path to be unchanged, got \"%s\"\n", path); 6320 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6321 6322 /* source path does not exist, but the property exists */ 6323 size = MAX_PATH; 6324 lstrcpyA(path, "kiwi"); 6325 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6327 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6328 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6329 6330 size = MAX_PATH; 6331 lstrcpyA(path, "kiwi"); 6332 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6334 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6335 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6336 6337 /* try SubDir after FileCost */ 6338 size = MAX_PATH; 6339 lstrcpyA(path, "kiwi"); 6340 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6342 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6343 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6344 6345 /* try SubDir2 after FileCost */ 6346 size = MAX_PATH; 6347 lstrcpyA(path, "kiwi"); 6348 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6350 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); 6351 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size); 6352 6353 r = MsiDoActionA(hpkg, "CostFinalize"); 6354 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6355 6356 /* try TARGETDIR after CostFinalize */ 6357 size = MAX_PATH; 6358 lstrcpyA(path, "kiwi"); 6359 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6360 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6361 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6362 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6363 6364 /* try SourceDir after CostFinalize */ 6365 size = MAX_PATH; 6366 lstrcpyA(path, "kiwi"); 6367 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6369 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6370 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6371 6372 /* try SOURCEDIR after CostFinalize */ 6373 size = MAX_PATH; 6374 lstrcpyA(path, "kiwi"); 6375 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6376 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6377 ok(!lstrcmpA(path, "kiwi"), 6378 "Expected path to be unchanged, got \"%s\"\n", path); 6379 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6380 6381 /* source path does not exist, but the property exists */ 6382 size = MAX_PATH; 6383 lstrcpyA(path, "kiwi"); 6384 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6386 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6387 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6388 6389 size = MAX_PATH; 6390 lstrcpyA(path, "kiwi"); 6391 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6393 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6394 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6395 6396 /* try SubDir after CostFinalize */ 6397 size = MAX_PATH; 6398 lstrcpyA(path, "kiwi"); 6399 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6400 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6401 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6402 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6403 6404 /* try SubDir2 after CostFinalize */ 6405 size = MAX_PATH; 6406 lstrcpyA(path, "kiwi"); 6407 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6409 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); 6410 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size); 6411 6412 /* nonexistent directory */ 6413 size = MAX_PATH; 6414 lstrcpyA(path, "kiwi"); 6415 r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size); 6416 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6417 ok(!lstrcmpA(path, "kiwi"), 6418 "Expected path to be unchanged, got \"%s\"\n", path); 6419 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6420 6421 /* NULL szPathBuf */ 6422 size = MAX_PATH; 6423 r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size); 6424 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6425 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6426 6427 /* NULL pcchPathBuf */ 6428 lstrcpyA(path, "kiwi"); 6429 r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL); 6430 ok(r == ERROR_INVALID_PARAMETER, 6431 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 6432 ok(!lstrcmpA(path, "kiwi"), 6433 "Expected path to be unchanged, got \"%s\"\n", path); 6434 6435 /* pcchPathBuf is 0 */ 6436 size = 0; 6437 lstrcpyA(path, "kiwi"); 6438 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6439 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 6440 ok(!lstrcmpA(path, "kiwi"), 6441 "Expected path to be unchanged, got \"%s\"\n", path); 6442 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6443 6444 /* pcchPathBuf does not have room for NULL terminator */ 6445 size = lstrlenA(cwd); 6446 lstrcpyA(path, "kiwi"); 6447 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6448 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 6449 ok(!strncmp(path, cwd, lstrlenA(cwd) - 1), 6450 "Expected path with no backslash, got \"%s\"\n", path); 6451 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6452 6453 /* pcchPathBuf has room for NULL terminator */ 6454 size = lstrlenA(cwd) + 1; 6455 lstrcpyA(path, "kiwi"); 6456 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6458 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6459 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6460 6461 /* remove property */ 6462 r = MsiSetPropertyA(hpkg, "SourceDir", NULL); 6463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6464 6465 /* try SourceDir again */ 6466 size = MAX_PATH; 6467 lstrcpyA(path, "kiwi"); 6468 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6469 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6470 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6471 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6472 6473 /* set property to a valid directory */ 6474 r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd); 6475 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6476 6477 /* try SOURCEDIR again */ 6478 size = MAX_PATH; 6479 lstrcpyA(path, "kiwi"); 6480 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6481 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6482 ok(!lstrcmpA(path, "kiwi"), 6483 "Expected path to be unchanged, got \"%s\"\n", path); 6484 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6485 6486 MsiCloseHandle(hpkg); 6487 6488 /* compressed source */ 6489 6490 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 6491 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6492 6493 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed); 6494 6495 r = package_from_db(hdb, &hpkg); 6496 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 6497 6498 /* try TARGETDIR */ 6499 size = MAX_PATH; 6500 lstrcpyA(path, "kiwi"); 6501 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6502 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6503 ok(!lstrcmpA(path, "kiwi"), 6504 "Expected path to be unchanged, got \"%s\"\n", path); 6505 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6506 6507 /* try SourceDir */ 6508 size = MAX_PATH; 6509 lstrcpyA(path, "kiwi"); 6510 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6511 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6512 ok(!lstrcmpA(path, "kiwi"), 6513 "Expected path to be unchanged, got \"%s\"\n", path); 6514 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6515 6516 /* try SOURCEDIR */ 6517 size = MAX_PATH; 6518 lstrcpyA(path, "kiwi"); 6519 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6520 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6521 ok(!lstrcmpA(path, "kiwi"), 6522 "Expected path to be unchanged, got \"%s\"\n", path); 6523 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6524 6525 /* source path nor the property exist */ 6526 size = MAX_PATH; 6527 lstrcpyA(path, "kiwi"); 6528 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6529 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6530 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6531 ok(size == 0, "Expected 0, got %lu\n", size); 6532 6533 size = MAX_PATH; 6534 lstrcpyA(path, "kiwi"); 6535 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6537 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 6538 ok(size == 0, "Expected 0, got %lu\n", size); 6539 6540 /* try SubDir */ 6541 size = MAX_PATH; 6542 lstrcpyA(path, "kiwi"); 6543 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6544 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6545 ok(!lstrcmpA(path, "kiwi"), 6546 "Expected path to be unchanged, got \"%s\"\n", path); 6547 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6548 6549 /* try SubDir2 */ 6550 size = MAX_PATH; 6551 lstrcpyA(path, "kiwi"); 6552 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6553 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 6554 ok(!lstrcmpA(path, "kiwi"), 6555 "Expected path to be unchanged, got \"%s\"\n", path); 6556 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 6557 6558 r = MsiDoActionA(hpkg, "CostInitialize"); 6559 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6560 6561 /* try TARGETDIR after CostInitialize */ 6562 size = MAX_PATH; 6563 lstrcpyA(path, "kiwi"); 6564 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6566 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6567 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6568 6569 /* try SourceDir after CostInitialize */ 6570 size = MAX_PATH; 6571 lstrcpyA(path, "kiwi"); 6572 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6573 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6574 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6575 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6576 6577 /* try SOURCEDIR after CostInitialize */ 6578 size = MAX_PATH; 6579 lstrcpyA(path, "kiwi"); 6580 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6581 todo_wine 6582 { 6583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6584 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6585 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6586 } 6587 6588 /* source path does not exist, but the property exists */ 6589 size = MAX_PATH; 6590 lstrcpyA(path, "kiwi"); 6591 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6592 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6593 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6594 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6595 6596 size = MAX_PATH; 6597 lstrcpyA(path, "kiwi"); 6598 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6600 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6601 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6602 6603 /* try SubDir after CostInitialize */ 6604 size = MAX_PATH; 6605 lstrcpyA(path, "kiwi"); 6606 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6607 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6608 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6609 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6610 6611 /* try SubDir2 after CostInitialize */ 6612 size = MAX_PATH; 6613 lstrcpyA(path, "kiwi"); 6614 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6615 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6616 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6617 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6618 6619 r = MsiDoActionA(hpkg, "ResolveSource"); 6620 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6621 6622 /* try TARGETDIR after ResolveSource */ 6623 size = MAX_PATH; 6624 lstrcpyA(path, "kiwi"); 6625 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6627 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6628 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6629 6630 /* try SourceDir after ResolveSource */ 6631 size = MAX_PATH; 6632 lstrcpyA(path, "kiwi"); 6633 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6635 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6636 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6637 6638 /* try SOURCEDIR after ResolveSource */ 6639 size = MAX_PATH; 6640 lstrcpyA(path, "kiwi"); 6641 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6642 todo_wine 6643 { 6644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6645 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6646 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6647 } 6648 6649 /* source path and the property exist */ 6650 size = MAX_PATH; 6651 lstrcpyA(path, "kiwi"); 6652 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6653 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6654 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6655 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6656 6657 size = MAX_PATH; 6658 lstrcpyA(path, "kiwi"); 6659 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6660 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6661 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6662 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6663 6664 /* try SubDir after ResolveSource */ 6665 size = MAX_PATH; 6666 lstrcpyA(path, "kiwi"); 6667 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6669 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6670 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6671 6672 /* try SubDir2 after ResolveSource */ 6673 size = MAX_PATH; 6674 lstrcpyA(path, "kiwi"); 6675 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6677 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6678 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6679 6680 r = MsiDoActionA(hpkg, "FileCost"); 6681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6682 6683 /* try TARGETDIR after CostFinalize */ 6684 size = MAX_PATH; 6685 lstrcpyA(path, "kiwi"); 6686 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6687 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6688 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6689 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6690 6691 /* try SourceDir after CostFinalize */ 6692 size = MAX_PATH; 6693 lstrcpyA(path, "kiwi"); 6694 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6696 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6697 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6698 6699 /* try SOURCEDIR after CostFinalize */ 6700 size = MAX_PATH; 6701 lstrcpyA(path, "kiwi"); 6702 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6703 todo_wine 6704 { 6705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6706 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6707 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6708 } 6709 6710 /* source path and the property exist */ 6711 size = MAX_PATH; 6712 lstrcpyA(path, "kiwi"); 6713 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6715 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6716 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6717 6718 size = MAX_PATH; 6719 lstrcpyA(path, "kiwi"); 6720 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6722 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6723 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6724 6725 /* try SubDir after CostFinalize */ 6726 size = MAX_PATH; 6727 lstrcpyA(path, "kiwi"); 6728 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6730 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6731 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6732 6733 /* try SubDir2 after CostFinalize */ 6734 size = MAX_PATH; 6735 lstrcpyA(path, "kiwi"); 6736 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6738 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6739 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6740 6741 r = MsiDoActionA(hpkg, "CostFinalize"); 6742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6743 6744 /* try TARGETDIR after CostFinalize */ 6745 size = MAX_PATH; 6746 lstrcpyA(path, "kiwi"); 6747 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size); 6748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6749 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6750 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6751 6752 /* try SourceDir after CostFinalize */ 6753 size = MAX_PATH; 6754 lstrcpyA(path, "kiwi"); 6755 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 6756 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6757 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6758 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6759 6760 /* try SOURCEDIR after CostFinalize */ 6761 size = MAX_PATH; 6762 lstrcpyA(path, "kiwi"); 6763 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 6764 todo_wine 6765 { 6766 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6767 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6768 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6769 } 6770 6771 /* source path and the property exist */ 6772 size = MAX_PATH; 6773 lstrcpyA(path, "kiwi"); 6774 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 6775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6776 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6777 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6778 6779 size = MAX_PATH; 6780 lstrcpyA(path, "kiwi"); 6781 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 6782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6783 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6784 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6785 6786 /* try SubDir after CostFinalize */ 6787 size = MAX_PATH; 6788 lstrcpyA(path, "kiwi"); 6789 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6790 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6791 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6792 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6793 6794 /* try SubDir2 after CostFinalize */ 6795 size = MAX_PATH; 6796 lstrcpyA(path, "kiwi"); 6797 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6799 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 6800 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 6801 6802 MsiCloseHandle(hpkg); 6803 DeleteFileA(msifile); 6804 } 6805 6806 static void test_shortlongsource(void) 6807 { 6808 MSIHANDLE hdb, hpkg; 6809 CHAR path[MAX_PATH]; 6810 CHAR cwd[MAX_PATH]; 6811 CHAR subsrc[MAX_PATH]; 6812 DWORD size; 6813 UINT r; 6814 6815 lstrcpyA(cwd, CURR_DIR); 6816 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\"); 6817 6818 lstrcpyA(subsrc, cwd); 6819 lstrcatA(subsrc, "long"); 6820 lstrcatA(subsrc, "\\"); 6821 6822 /* long file names */ 6823 6824 hdb = create_package_db(); 6825 ok( hdb, "failed to create database\n"); 6826 6827 set_suminfo_prop(hdb, PID_WORDCOUNT, 0); 6828 6829 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); 6830 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'"); 6831 6832 /* CostInitialize:short */ 6833 add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'"); 6834 6835 /* CostInitialize:long */ 6836 add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'"); 6837 6838 /* FileCost:short */ 6839 add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'"); 6840 6841 /* FileCost:long */ 6842 add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'"); 6843 6844 /* CostFinalize:short */ 6845 add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'"); 6846 6847 /* CostFinalize:long */ 6848 add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'"); 6849 6850 r = MsiDatabaseCommit(hdb); 6851 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 6852 6853 r = package_from_db(hdb, &hpkg); 6854 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 6855 { 6856 skip("Not enough rights to perform tests\n"); 6857 DeleteFileA(msifile); 6858 return; 6859 } 6860 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 6861 6862 MsiCloseHandle(hdb); 6863 6864 CreateDirectoryA("one", NULL); 6865 CreateDirectoryA("four", NULL); 6866 6867 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 6868 6869 r = MsiDoActionA(hpkg, "CostInitialize"); 6870 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6871 6872 CreateDirectoryA("five", NULL); 6873 CreateDirectoryA("eight", NULL); 6874 6875 r = MsiDoActionA(hpkg, "FileCost"); 6876 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6877 6878 CreateDirectoryA("nine", NULL); 6879 CreateDirectoryA("twelve", NULL); 6880 6881 r = MsiDoActionA(hpkg, "CostFinalize"); 6882 ok(r == ERROR_SUCCESS, "file cost failed\n"); 6883 6884 /* neither short nor long source directories exist */ 6885 size = MAX_PATH; 6886 lstrcpyA(path, "kiwi"); 6887 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6889 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6890 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6891 6892 CreateDirectoryA("short", NULL); 6893 6894 /* short source directory exists */ 6895 size = MAX_PATH; 6896 lstrcpyA(path, "kiwi"); 6897 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6899 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6900 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6901 6902 CreateDirectoryA("long", NULL); 6903 6904 /* both short and long source directories exist */ 6905 size = MAX_PATH; 6906 lstrcpyA(path, "kiwi"); 6907 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 6908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6909 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6910 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6911 6912 lstrcpyA(subsrc, cwd); 6913 lstrcatA(subsrc, "two"); 6914 lstrcatA(subsrc, "\\"); 6915 6916 /* short dir exists before CostInitialize */ 6917 size = MAX_PATH; 6918 lstrcpyA(path, "kiwi"); 6919 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 6920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6921 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6922 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6923 6924 lstrcpyA(subsrc, cwd); 6925 lstrcatA(subsrc, "four"); 6926 lstrcatA(subsrc, "\\"); 6927 6928 /* long dir exists before CostInitialize */ 6929 size = MAX_PATH; 6930 lstrcpyA(path, "kiwi"); 6931 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size); 6932 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6933 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6934 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6935 6936 lstrcpyA(subsrc, cwd); 6937 lstrcatA(subsrc, "six"); 6938 lstrcatA(subsrc, "\\"); 6939 6940 /* short dir exists before FileCost */ 6941 size = MAX_PATH; 6942 lstrcpyA(path, "kiwi"); 6943 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size); 6944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6945 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6946 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6947 6948 lstrcpyA(subsrc, cwd); 6949 lstrcatA(subsrc, "eight"); 6950 lstrcatA(subsrc, "\\"); 6951 6952 /* long dir exists before FileCost */ 6953 size = MAX_PATH; 6954 lstrcpyA(path, "kiwi"); 6955 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size); 6956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6957 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6958 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6959 6960 lstrcpyA(subsrc, cwd); 6961 lstrcatA(subsrc, "ten"); 6962 lstrcatA(subsrc, "\\"); 6963 6964 /* short dir exists before CostFinalize */ 6965 size = MAX_PATH; 6966 lstrcpyA(path, "kiwi"); 6967 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size); 6968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6969 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6970 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6971 6972 lstrcpyA(subsrc, cwd); 6973 lstrcatA(subsrc, "twelve"); 6974 lstrcatA(subsrc, "\\"); 6975 6976 /* long dir exists before CostFinalize */ 6977 size = MAX_PATH; 6978 lstrcpyA(path, "kiwi"); 6979 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size); 6980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6981 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 6982 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 6983 6984 MsiCloseHandle(hpkg); 6985 RemoveDirectoryA("short"); 6986 RemoveDirectoryA("long"); 6987 RemoveDirectoryA("one"); 6988 RemoveDirectoryA("four"); 6989 RemoveDirectoryA("five"); 6990 RemoveDirectoryA("eight"); 6991 RemoveDirectoryA("nine"); 6992 RemoveDirectoryA("twelve"); 6993 6994 /* short file names */ 6995 6996 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 6997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6998 6999 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN); 7000 7001 r = package_from_db(hdb, &hpkg); 7002 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 7003 7004 MsiCloseHandle(hdb); 7005 7006 CreateDirectoryA("one", NULL); 7007 CreateDirectoryA("four", NULL); 7008 7009 r = MsiDoActionA(hpkg, "CostInitialize"); 7010 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7011 7012 CreateDirectoryA("five", NULL); 7013 CreateDirectoryA("eight", NULL); 7014 7015 r = MsiDoActionA(hpkg, "FileCost"); 7016 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7017 7018 CreateDirectoryA("nine", NULL); 7019 CreateDirectoryA("twelve", NULL); 7020 7021 r = MsiDoActionA(hpkg, "CostFinalize"); 7022 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7023 7024 lstrcpyA(subsrc, cwd); 7025 lstrcatA(subsrc, "short"); 7026 lstrcatA(subsrc, "\\"); 7027 7028 /* neither short nor long source directories exist */ 7029 size = MAX_PATH; 7030 lstrcpyA(path, "kiwi"); 7031 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7032 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7033 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7034 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7035 7036 CreateDirectoryA("short", NULL); 7037 7038 /* short source directory exists */ 7039 size = MAX_PATH; 7040 lstrcpyA(path, "kiwi"); 7041 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7042 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7043 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7044 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7045 7046 CreateDirectoryA("long", NULL); 7047 7048 /* both short and long source directories exist */ 7049 size = MAX_PATH; 7050 lstrcpyA(path, "kiwi"); 7051 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size); 7052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7053 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7054 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7055 7056 lstrcpyA(subsrc, cwd); 7057 lstrcatA(subsrc, "one"); 7058 lstrcatA(subsrc, "\\"); 7059 7060 /* short dir exists before CostInitialize */ 7061 size = MAX_PATH; 7062 lstrcpyA(path, "kiwi"); 7063 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size); 7064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7065 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7066 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7067 7068 lstrcpyA(subsrc, cwd); 7069 lstrcatA(subsrc, "three"); 7070 lstrcatA(subsrc, "\\"); 7071 7072 /* long dir exists before CostInitialize */ 7073 size = MAX_PATH; 7074 lstrcpyA(path, "kiwi"); 7075 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size); 7076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7077 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7078 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7079 7080 lstrcpyA(subsrc, cwd); 7081 lstrcatA(subsrc, "five"); 7082 lstrcatA(subsrc, "\\"); 7083 7084 /* short dir exists before FileCost */ 7085 size = MAX_PATH; 7086 lstrcpyA(path, "kiwi"); 7087 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size); 7088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7089 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7090 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7091 7092 lstrcpyA(subsrc, cwd); 7093 lstrcatA(subsrc, "seven"); 7094 lstrcatA(subsrc, "\\"); 7095 7096 /* long dir exists before FileCost */ 7097 size = MAX_PATH; 7098 lstrcpyA(path, "kiwi"); 7099 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size); 7100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7101 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7102 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7103 7104 lstrcpyA(subsrc, cwd); 7105 lstrcatA(subsrc, "nine"); 7106 lstrcatA(subsrc, "\\"); 7107 7108 /* short dir exists before CostFinalize */ 7109 size = MAX_PATH; 7110 lstrcpyA(path, "kiwi"); 7111 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size); 7112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7113 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7114 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7115 7116 lstrcpyA(subsrc, cwd); 7117 lstrcatA(subsrc, "eleven"); 7118 lstrcatA(subsrc, "\\"); 7119 7120 /* long dir exists before CostFinalize */ 7121 size = MAX_PATH; 7122 lstrcpyA(path, "kiwi"); 7123 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size); 7124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7125 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); 7126 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size); 7127 7128 MsiCloseHandle(hpkg); 7129 RemoveDirectoryA("short"); 7130 RemoveDirectoryA("long"); 7131 RemoveDirectoryA("one"); 7132 RemoveDirectoryA("four"); 7133 RemoveDirectoryA("five"); 7134 RemoveDirectoryA("eight"); 7135 RemoveDirectoryA("nine"); 7136 RemoveDirectoryA("twelve"); 7137 DeleteFileA(msifile); 7138 } 7139 7140 static void test_sourcedir(void) 7141 { 7142 MSIHANDLE hdb, hpkg; 7143 CHAR package[12]; 7144 CHAR path[MAX_PATH]; 7145 CHAR cwd[MAX_PATH]; 7146 CHAR subsrc[MAX_PATH]; 7147 DWORD size; 7148 UINT r; 7149 7150 lstrcpyA(cwd, CURR_DIR); 7151 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\"); 7152 7153 lstrcpyA(subsrc, cwd); 7154 lstrcatA(subsrc, "long"); 7155 lstrcatA(subsrc, "\\"); 7156 7157 hdb = create_package_db(); 7158 ok( hdb, "failed to create database\n"); 7159 7160 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); 7161 7162 sprintf(package, "#%lu", hdb); 7163 r = MsiOpenPackageA(package, &hpkg); 7164 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 7165 { 7166 skip("Not enough rights to perform tests\n"); 7167 goto error; 7168 } 7169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7170 7171 /* properties only */ 7172 7173 /* SourceDir prop */ 7174 size = MAX_PATH; 7175 lstrcpyA(path, "kiwi"); 7176 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7177 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7178 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7179 ok(size == 0, "Expected 0, got %lu\n", size); 7180 7181 /* SOURCEDIR prop */ 7182 size = MAX_PATH; 7183 lstrcpyA(path, "kiwi"); 7184 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7186 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7187 ok(size == 0, "Expected 0, got %lu\n", size); 7188 7189 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 7190 7191 r = MsiDoActionA(hpkg, "CostInitialize"); 7192 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7193 7194 /* SourceDir after CostInitialize */ 7195 size = MAX_PATH; 7196 lstrcpyA(path, "kiwi"); 7197 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7199 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7200 ok(size == 0, "Expected 0, got %lu\n", size); 7201 7202 /* SOURCEDIR after CostInitialize */ 7203 size = MAX_PATH; 7204 lstrcpyA(path, "kiwi"); 7205 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7206 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7207 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7208 ok(size == 0, "Expected 0, got %lu\n", size); 7209 7210 r = MsiDoActionA(hpkg, "FileCost"); 7211 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7212 7213 /* SourceDir after FileCost */ 7214 size = MAX_PATH; 7215 lstrcpyA(path, "kiwi"); 7216 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7218 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7219 ok(size == 0, "Expected 0, got %lu\n", size); 7220 7221 /* SOURCEDIR after FileCost */ 7222 size = MAX_PATH; 7223 lstrcpyA(path, "kiwi"); 7224 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7226 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7227 ok(size == 0, "Expected 0, got %lu\n", size); 7228 7229 r = MsiDoActionA(hpkg, "CostFinalize"); 7230 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7231 7232 /* SourceDir after CostFinalize */ 7233 size = MAX_PATH; 7234 lstrcpyA(path, "kiwi"); 7235 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7237 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7238 ok(size == 0, "Expected 0, got %lu\n", size); 7239 7240 /* SOURCEDIR after CostFinalize */ 7241 size = MAX_PATH; 7242 lstrcpyA(path, "kiwi"); 7243 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7245 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7246 ok(size == 0, "Expected 0, got %lu\n", size); 7247 7248 size = MAX_PATH; 7249 lstrcpyA(path, "kiwi"); 7250 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7251 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7252 ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path); 7253 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size); 7254 7255 /* SOURCEDIR after calling MsiGetSourcePath */ 7256 size = MAX_PATH; 7257 lstrcpyA(path, "kiwi"); 7258 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7260 todo_wine { 7261 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7262 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7263 } 7264 7265 r = MsiDoActionA(hpkg, "ResolveSource"); 7266 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7267 7268 /* SourceDir after ResolveSource */ 7269 size = MAX_PATH; 7270 lstrcpyA(path, "kiwi"); 7271 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7273 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7274 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7275 7276 /* SOURCEDIR after ResolveSource */ 7277 size = MAX_PATH; 7278 lstrcpyA(path, "kiwi"); 7279 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7281 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7282 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7283 7284 /* random casing */ 7285 size = MAX_PATH; 7286 lstrcpyA(path, "kiwi"); 7287 r = MsiGetPropertyA(hpkg, "SoUrCeDiR", path, &size); 7288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7289 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7290 ok(size == 0, "Expected 0, got %lu\n", size); 7291 7292 MsiCloseHandle(hpkg); 7293 7294 /* reset the package state */ 7295 sprintf(package, "#%lu", hdb); 7296 r = MsiOpenPackageA(package, &hpkg); 7297 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7298 7299 /* test how MsiGetSourcePath affects the properties */ 7300 7301 /* SourceDir prop */ 7302 size = MAX_PATH; 7303 lstrcpyA(path, "kiwi"); 7304 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7305 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7306 todo_wine 7307 { 7308 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7309 ok(size == 0, "Expected 0, got %lu\n", size); 7310 } 7311 7312 size = MAX_PATH; 7313 lstrcpyA(path, "kiwi"); 7314 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 7315 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7316 ok(!lstrcmpA(path, "kiwi"), 7317 "Expected path to be unchanged, got \"%s\"\n", path); 7318 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7319 7320 /* SourceDir after MsiGetSourcePath */ 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 todo_wine 7326 { 7327 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7328 ok(size == 0, "Expected 0, got %lu\n", size); 7329 } 7330 7331 /* SOURCEDIR prop */ 7332 size = MAX_PATH; 7333 lstrcpyA(path, "kiwi"); 7334 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7336 todo_wine 7337 { 7338 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7339 ok(size == 0, "Expected 0, got %lu\n", size); 7340 } 7341 7342 size = MAX_PATH; 7343 lstrcpyA(path, "kiwi"); 7344 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7345 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7346 ok(!lstrcmpA(path, "kiwi"), 7347 "Expected path to be unchanged, got \"%s\"\n", path); 7348 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7349 7350 /* SOURCEDIR prop after MsiGetSourcePath */ 7351 size = MAX_PATH; 7352 lstrcpyA(path, "kiwi"); 7353 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7355 todo_wine 7356 { 7357 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7358 ok(size == 0, "Expected 0, got %lu\n", size); 7359 } 7360 7361 r = MsiDoActionA(hpkg, "CostInitialize"); 7362 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7363 7364 /* SourceDir after CostInitialize */ 7365 size = MAX_PATH; 7366 lstrcpyA(path, "kiwi"); 7367 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7369 todo_wine 7370 { 7371 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); 7372 ok(size == 0, "Expected 0, got %lu\n", size); 7373 } 7374 7375 size = MAX_PATH; 7376 lstrcpyA(path, "kiwi"); 7377 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size); 7378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7379 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7380 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7381 7382 /* SourceDir after MsiGetSourcePath */ 7383 size = MAX_PATH; 7384 lstrcpyA(path, "kiwi"); 7385 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7387 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7388 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7389 7390 /* SOURCEDIR after CostInitialize */ 7391 size = MAX_PATH; 7392 lstrcpyA(path, "kiwi"); 7393 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7394 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7395 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7396 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7397 7398 /* SOURCEDIR source path still does not exist */ 7399 size = MAX_PATH; 7400 lstrcpyA(path, "kiwi"); 7401 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7402 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7403 ok(!lstrcmpA(path, "kiwi"), 7404 "Expected path to be unchanged, got \"%s\"\n", path); 7405 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7406 7407 r = MsiDoActionA(hpkg, "FileCost"); 7408 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7409 7410 /* SourceDir after FileCost */ 7411 size = MAX_PATH; 7412 lstrcpyA(path, "kiwi"); 7413 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7414 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7415 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7416 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7417 7418 /* SOURCEDIR after FileCost */ 7419 size = MAX_PATH; 7420 lstrcpyA(path, "kiwi"); 7421 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7423 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7424 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7425 7426 /* SOURCEDIR source path still does not exist */ 7427 size = MAX_PATH; 7428 lstrcpyA(path, "kiwi"); 7429 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7430 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7431 ok(!lstrcmpA(path, "kiwi"), 7432 "Expected path to be unchanged, got \"%s\"\n", path); 7433 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7434 7435 r = MsiDoActionA(hpkg, "CostFinalize"); 7436 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7437 7438 /* SourceDir after CostFinalize */ 7439 size = MAX_PATH; 7440 lstrcpyA(path, "kiwi"); 7441 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7443 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7444 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7445 7446 /* SOURCEDIR after CostFinalize */ 7447 size = MAX_PATH; 7448 lstrcpyA(path, "kiwi"); 7449 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7451 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7452 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7453 7454 /* SOURCEDIR source path still does not exist */ 7455 size = MAX_PATH; 7456 lstrcpyA(path, "kiwi"); 7457 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7458 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7459 ok(!lstrcmpA(path, "kiwi"), 7460 "Expected path to be unchanged, got \"%s\"\n", path); 7461 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7462 7463 r = MsiDoActionA(hpkg, "ResolveSource"); 7464 ok(r == ERROR_SUCCESS, "file cost failed\n"); 7465 7466 /* SourceDir after ResolveSource */ 7467 size = MAX_PATH; 7468 lstrcpyA(path, "kiwi"); 7469 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size); 7470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7471 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7472 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7473 7474 /* SOURCEDIR after ResolveSource */ 7475 size = MAX_PATH; 7476 lstrcpyA(path, "kiwi"); 7477 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size); 7478 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7479 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); 7480 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size); 7481 7482 /* SOURCEDIR source path still does not exist */ 7483 size = MAX_PATH; 7484 lstrcpyA(path, "kiwi"); 7485 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size); 7486 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); 7487 ok(!lstrcmpA(path, "kiwi"), 7488 "Expected path to be unchanged, got \"%s\"\n", path); 7489 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7490 7491 MsiCloseHandle(hpkg); 7492 7493 error: 7494 MsiCloseHandle(hdb); 7495 DeleteFileA(msifile); 7496 } 7497 7498 struct access_res 7499 { 7500 BOOL gothandle; 7501 DWORD lasterr; 7502 BOOL ignore; 7503 }; 7504 7505 static const struct access_res create[16] = 7506 { 7507 { TRUE, ERROR_SUCCESS, TRUE }, 7508 { TRUE, ERROR_SUCCESS, TRUE }, 7509 { TRUE, ERROR_SUCCESS, FALSE }, 7510 { TRUE, ERROR_SUCCESS, FALSE }, 7511 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7512 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7513 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7514 { TRUE, ERROR_SUCCESS, FALSE }, 7515 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7516 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7517 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7518 { TRUE, ERROR_SUCCESS, TRUE }, 7519 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7520 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7521 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7522 { TRUE, ERROR_SUCCESS, TRUE } 7523 }; 7524 7525 static const struct access_res create_commit[16] = 7526 { 7527 { TRUE, ERROR_SUCCESS, TRUE }, 7528 { TRUE, ERROR_SUCCESS, TRUE }, 7529 { TRUE, ERROR_SUCCESS, FALSE }, 7530 { TRUE, ERROR_SUCCESS, FALSE }, 7531 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7532 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7533 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7534 { TRUE, ERROR_SUCCESS, FALSE }, 7535 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7536 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7537 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7538 { TRUE, ERROR_SUCCESS, TRUE }, 7539 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7540 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7541 { FALSE, ERROR_SHARING_VIOLATION, FALSE }, 7542 { TRUE, ERROR_SUCCESS, TRUE } 7543 }; 7544 7545 static const struct access_res create_close[16] = 7546 { 7547 { TRUE, ERROR_SUCCESS, FALSE }, 7548 { TRUE, ERROR_SUCCESS, FALSE }, 7549 { TRUE, ERROR_SUCCESS, FALSE }, 7550 { TRUE, ERROR_SUCCESS, FALSE }, 7551 { TRUE, ERROR_SUCCESS, FALSE }, 7552 { TRUE, ERROR_SUCCESS, FALSE }, 7553 { TRUE, ERROR_SUCCESS, FALSE }, 7554 { TRUE, ERROR_SUCCESS, FALSE }, 7555 { TRUE, ERROR_SUCCESS, FALSE }, 7556 { TRUE, ERROR_SUCCESS, FALSE }, 7557 { TRUE, ERROR_SUCCESS, FALSE }, 7558 { TRUE, ERROR_SUCCESS, FALSE }, 7559 { TRUE, ERROR_SUCCESS, FALSE }, 7560 { TRUE, ERROR_SUCCESS, FALSE }, 7561 { TRUE, ERROR_SUCCESS, FALSE }, 7562 { TRUE, ERROR_SUCCESS } 7563 }; 7564 7565 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line) 7566 { 7567 DWORD access = 0, share = 0; 7568 DWORD lasterr; 7569 HANDLE hfile; 7570 int i, j, idx = 0; 7571 7572 for (i = 0; i < 4; i++) 7573 { 7574 if (i == 0) access = 0; 7575 if (i == 1) access = GENERIC_READ; 7576 if (i == 2) access = GENERIC_WRITE; 7577 if (i == 3) access = GENERIC_READ | GENERIC_WRITE; 7578 7579 for (j = 0; j < 4; j++) 7580 { 7581 if (ares[idx].ignore) 7582 continue; 7583 7584 if (j == 0) share = 0; 7585 if (j == 1) share = FILE_SHARE_READ; 7586 if (j == 2) share = FILE_SHARE_WRITE; 7587 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE; 7588 7589 SetLastError(0xdeadbeef); 7590 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING, 7591 FILE_ATTRIBUTE_NORMAL, 0); 7592 lasterr = GetLastError(); 7593 7594 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle, 7595 "(%lu, handle, %d): Expected %d, got %d\n", 7596 line, idx, ares[idx].gothandle, 7597 (hfile != INVALID_HANDLE_VALUE)); 7598 7599 ok(lasterr == ares[idx].lasterr, "(%lu, lasterr, %u): Expected %lu, got %lu\n", 7600 line, idx, ares[idx].lasterr, lasterr); 7601 7602 CloseHandle(hfile); 7603 idx++; 7604 } 7605 } 7606 } 7607 7608 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__) 7609 7610 static void test_access(void) 7611 { 7612 MSIHANDLE hdb; 7613 UINT r; 7614 7615 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7616 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7617 7618 test_file_access(msifile, create); 7619 7620 r = MsiDatabaseCommit(hdb); 7621 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7622 7623 test_file_access(msifile, create_commit); 7624 MsiCloseHandle(hdb); 7625 7626 test_file_access(msifile, create_close); 7627 DeleteFileA(msifile); 7628 7629 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb); 7630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7631 7632 test_file_access(msifile, create); 7633 7634 r = MsiDatabaseCommit(hdb); 7635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7636 7637 test_file_access(msifile, create_commit); 7638 MsiCloseHandle(hdb); 7639 7640 test_file_access(msifile, create_close); 7641 DeleteFileA(msifile); 7642 } 7643 7644 static void test_emptypackage(void) 7645 { 7646 MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0; 7647 MSIHANDLE hview = 0, hrec = 0; 7648 MSICONDITION condition; 7649 CHAR buffer[MAX_PATH]; 7650 DWORD size; 7651 UINT r; 7652 7653 r = MsiOpenPackageA("", &hpkg); 7654 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 7655 { 7656 skip("Not enough rights to perform tests\n"); 7657 return; 7658 } 7659 todo_wine 7660 { 7661 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7662 } 7663 7664 hdb = MsiGetActiveDatabase(hpkg); 7665 todo_wine 7666 { 7667 ok(hdb != 0, "Expected a valid database handle\n"); 7668 } 7669 7670 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview); 7671 todo_wine 7672 { 7673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7674 } 7675 r = MsiViewExecute(hview, 0); 7676 todo_wine 7677 { 7678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7679 } 7680 7681 r = MsiViewFetch(hview, &hrec); 7682 todo_wine 7683 { 7684 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7685 } 7686 7687 buffer[0] = 0; 7688 size = MAX_PATH; 7689 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7690 todo_wine 7691 { 7692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7693 ok(!lstrcmpA(buffer, "_Property"), 7694 "Expected \"_Property\", got \"%s\"\n", buffer); 7695 } 7696 7697 MsiCloseHandle(hrec); 7698 7699 r = MsiViewFetch(hview, &hrec); 7700 todo_wine 7701 { 7702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7703 } 7704 7705 size = MAX_PATH; 7706 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7707 todo_wine 7708 { 7709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7710 ok(!lstrcmpA(buffer, "#_FolderCache"), 7711 "Expected \"_Property\", got \"%s\"\n", buffer); 7712 } 7713 7714 MsiCloseHandle(hrec); 7715 MsiViewClose(hview); 7716 MsiCloseHandle(hview); 7717 7718 condition = MsiDatabaseIsTablePersistentA(hdb, "_Property"); 7719 todo_wine 7720 { 7721 ok(condition == MSICONDITION_FALSE, 7722 "Expected MSICONDITION_FALSE, got %d\n", condition); 7723 } 7724 7725 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview); 7726 todo_wine 7727 { 7728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7729 } 7730 r = MsiViewExecute(hview, 0); 7731 todo_wine 7732 { 7733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7734 } 7735 7736 /* _Property table is not empty */ 7737 r = MsiViewFetch(hview, &hrec); 7738 todo_wine 7739 { 7740 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7741 } 7742 7743 MsiCloseHandle(hrec); 7744 MsiViewClose(hview); 7745 MsiCloseHandle(hview); 7746 7747 condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache"); 7748 todo_wine 7749 { 7750 ok(condition == MSICONDITION_FALSE, 7751 "Expected MSICONDITION_FALSE, got %d\n", condition); 7752 } 7753 7754 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview); 7755 todo_wine 7756 { 7757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7758 } 7759 r = MsiViewExecute(hview, 0); 7760 todo_wine 7761 { 7762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7763 } 7764 7765 /* #_FolderCache is not empty */ 7766 r = MsiViewFetch(hview, &hrec); 7767 todo_wine 7768 { 7769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7770 } 7771 7772 MsiCloseHandle(hrec); 7773 MsiViewClose(hview); 7774 MsiCloseHandle(hview); 7775 7776 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview); 7777 todo_wine 7778 { 7779 ok(r == ERROR_BAD_QUERY_SYNTAX, 7780 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7781 } 7782 7783 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview); 7784 todo_wine 7785 { 7786 ok(r == ERROR_BAD_QUERY_SYNTAX, 7787 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7788 } 7789 7790 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo); 7791 todo_wine 7792 { 7793 ok(r == ERROR_INSTALL_PACKAGE_INVALID, 7794 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r); 7795 } 7796 7797 MsiCloseHandle(hsuminfo); 7798 7799 r = MsiDatabaseCommit(hdb); 7800 todo_wine 7801 { 7802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7803 } 7804 7805 MsiCloseHandle(hdb); 7806 MsiCloseHandle(hpkg); 7807 } 7808 7809 static void test_MsiGetProductProperty(void) 7810 { 7811 WCHAR valW[MAX_PATH]; 7812 MSIHANDLE hprod, hdb; 7813 CHAR val[MAX_PATH]; 7814 CHAR path[MAX_PATH]; 7815 CHAR query[MAX_PATH + 17]; 7816 CHAR keypath[MAX_PATH*2]; 7817 CHAR prodcode[MAX_PATH]; 7818 WCHAR prodcodeW[MAX_PATH]; 7819 CHAR prod_squashed[MAX_PATH]; 7820 WCHAR prod_squashedW[MAX_PATH]; 7821 HKEY prodkey, userkey, props; 7822 DWORD size; 7823 LONG res; 7824 UINT r; 7825 REGSAM access = KEY_ALL_ACCESS; 7826 7827 GetCurrentDirectoryA(MAX_PATH, path); 7828 lstrcatA(path, "\\"); 7829 7830 create_test_guid(prodcode, prod_squashed); 7831 MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH); 7832 squash_guid(prodcodeW, prod_squashedW); 7833 7834 if (is_wow64) 7835 access |= KEY_WOW64_64KEY; 7836 7837 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7838 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7839 7840 r = MsiDatabaseCommit(hdb); 7841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7842 7843 r = set_summary_info(hdb); 7844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7845 7846 r = run_query(hdb, 0, 7847 "CREATE TABLE `Directory` ( " 7848 "`Directory` CHAR(255) NOT NULL, " 7849 "`Directory_Parent` CHAR(255), " 7850 "`DefaultDir` CHAR(255) NOT NULL " 7851 "PRIMARY KEY `Directory`)"); 7852 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7853 7854 create_property_table(hdb); 7855 7856 sprintf(query, "'ProductCode', '%s'", prodcode); 7857 r = add_property_entry(hdb, query); 7858 7859 r = MsiDatabaseCommit(hdb); 7860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7861 7862 MsiCloseHandle(hdb); 7863 7864 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); 7865 lstrcatA(keypath, prod_squashed); 7866 7867 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); 7868 if (res == ERROR_ACCESS_DENIED) 7869 { 7870 skip("Not enough rights to perform tests\n"); 7871 DeleteFileA(msifile); 7872 return; 7873 } 7874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 7875 7876 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\"); 7877 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\"); 7878 lstrcatA(keypath, prod_squashed); 7879 7880 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); 7881 if (res == ERROR_ACCESS_DENIED) 7882 { 7883 skip("Not enough rights to perform tests\n"); 7884 RegDeleteKeyA(prodkey, ""); 7885 RegCloseKey(prodkey); 7886 DeleteFileA(msifile); 7887 return; 7888 } 7889 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 7890 7891 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); 7892 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 7893 7894 lstrcpyA(val, path); 7895 lstrcatA(val, "\\"); 7896 lstrcatA(val, msifile); 7897 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, (const BYTE *)val, lstrlenA(val) + 1); 7898 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res); 7899 7900 hprod = 0xdeadbeef; 7901 r = MsiOpenProductA(prodcode, &hprod); 7902 if (r == ERROR_UNKNOWN_PRODUCT) 7903 { 7904 win_skip("broken result, skipping tests\n"); 7905 goto done; 7906 } 7907 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7908 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n"); 7909 7910 /* hProduct is invalid */ 7911 size = MAX_PATH; 7912 lstrcpyA(val, "apple"); 7913 r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size); 7914 ok(r == ERROR_INVALID_HANDLE, 7915 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 7916 ok(!lstrcmpA(val, "apple"), 7917 "Expected val to be unchanged, got \"%s\"\n", val); 7918 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7919 7920 size = MAX_PATH; 7921 lstrcpyW(valW, L"apple"); 7922 r = MsiGetProductPropertyW(0xdeadbeef, L"ProductCode", valW, &size); 7923 ok(r == ERROR_INVALID_HANDLE, 7924 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 7925 ok(!lstrcmpW(valW, L"apple"), 7926 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); 7927 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7928 7929 /* szProperty is NULL */ 7930 size = MAX_PATH; 7931 lstrcpyA(val, "apple"); 7932 r = MsiGetProductPropertyA(hprod, NULL, val, &size); 7933 ok(r == ERROR_INVALID_PARAMETER, 7934 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 7935 ok(!lstrcmpA(val, "apple"), 7936 "Expected val to be unchanged, got \"%s\"\n", val); 7937 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7938 7939 size = MAX_PATH; 7940 lstrcpyW(valW, L"apple"); 7941 r = MsiGetProductPropertyW(hprod, NULL, valW, &size); 7942 ok(r == ERROR_INVALID_PARAMETER, 7943 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 7944 ok(!lstrcmpW(valW, L"apple"), 7945 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); 7946 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size); 7947 7948 /* szProperty is empty */ 7949 size = MAX_PATH; 7950 lstrcpyA(val, "apple"); 7951 r = MsiGetProductPropertyA(hprod, "", val, &size); 7952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7953 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); 7954 ok(size == 0, "Expected 0, got %lu\n", size); 7955 7956 size = MAX_PATH; 7957 lstrcpyW(valW, L"apple"); 7958 r = MsiGetProductPropertyW(hprod, L"", valW, &size); 7959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7960 ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW)); 7961 ok(size == 0, "Expected 0, got %lu\n", size); 7962 7963 /* get the property */ 7964 size = MAX_PATH; 7965 lstrcpyA(val, "apple"); 7966 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 7967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7968 ok(!lstrcmpA(val, prodcode), 7969 "Expected \"%s\", got \"%s\"\n", prodcode, val); 7970 ok(size == lstrlenA(prodcode), 7971 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 7972 7973 size = MAX_PATH; 7974 lstrcpyW(valW, L"apple"); 7975 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 7976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7977 ok(!lstrcmpW(valW, prodcodeW), 7978 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 7979 ok(size == lstrlenW(prodcodeW), 7980 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 7981 7982 /* lpValueBuf is NULL */ 7983 size = MAX_PATH; 7984 r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size); 7985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7986 ok(size == lstrlenA(prodcode), 7987 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 7988 7989 size = MAX_PATH; 7990 r = MsiGetProductPropertyW(hprod, L"ProductCode", NULL, &size); 7991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7992 ok(size == lstrlenW(prodcodeW), 7993 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 7994 7995 /* pcchValueBuf is NULL */ 7996 lstrcpyA(val, "apple"); 7997 r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL); 7998 ok(r == ERROR_INVALID_PARAMETER, 7999 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8000 ok(!lstrcmpA(val, "apple"), 8001 "Expected val to be unchanged, got \"%s\"\n", val); 8002 ok(size == lstrlenA(prodcode), 8003 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8004 8005 lstrcpyW(valW, L"apple"); 8006 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, NULL); 8007 ok(r == ERROR_INVALID_PARAMETER, 8008 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8009 ok(!lstrcmpW(valW, L"apple"), 8010 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); 8011 ok(size == lstrlenW(prodcodeW), 8012 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8013 8014 /* pcchValueBuf is too small */ 8015 size = 4; 8016 lstrcpyA(val, "apple"); 8017 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8018 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 8019 ok(!strncmp(val, prodcode, 3), 8020 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val); 8021 ok(size == lstrlenA(prodcode), 8022 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8023 8024 size = 4; 8025 lstrcpyW(valW, L"apple"); 8026 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8027 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 8028 ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)), 8029 "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8030 ok(size == lstrlenW(prodcodeW), 8031 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8032 8033 /* pcchValueBuf does not leave room for NULL terminator */ 8034 size = lstrlenA(prodcode); 8035 lstrcpyA(val, "apple"); 8036 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8037 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 8038 ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1), 8039 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val); 8040 ok(size == lstrlenA(prodcode), 8041 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8042 8043 size = lstrlenW(prodcodeW); 8044 lstrcpyW(valW, L"apple"); 8045 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8046 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); 8047 ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1), 8048 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8049 ok(size == lstrlenW(prodcodeW), 8050 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8051 8052 /* pcchValueBuf has enough room for NULL terminator */ 8053 size = lstrlenA(prodcode) + 1; 8054 lstrcpyA(val, "apple"); 8055 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8057 ok(!lstrcmpA(val, prodcode), 8058 "Expected \"%s\", got \"%s\"\n", prodcode, val); 8059 ok(size == lstrlenA(prodcode), 8060 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8061 8062 size = lstrlenW(prodcodeW) + 1; 8063 lstrcpyW(valW, L"apple"); 8064 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8065 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8066 ok(!lstrcmpW(valW, prodcodeW), 8067 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8068 ok(size == lstrlenW(prodcodeW), 8069 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8070 8071 /* nonexistent property */ 8072 size = MAX_PATH; 8073 lstrcpyA(val, "apple"); 8074 r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size); 8075 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8076 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); 8077 ok(size == 0, "Expected 0, got %lu\n", size); 8078 8079 size = MAX_PATH; 8080 lstrcpyW(valW, L"apple"); 8081 r = MsiGetProductPropertyW(hprod, L"IDontExist", valW, &size); 8082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8083 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW)); 8084 ok(size == 0, "Expected 0, got %lu\n", size); 8085 8086 r = MsiSetPropertyA(hprod, "NewProperty", "value"); 8087 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8088 8089 /* non-product property set */ 8090 size = MAX_PATH; 8091 lstrcpyA(val, "apple"); 8092 r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size); 8093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8094 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); 8095 ok(size == 0, "Expected 0, got %lu\n", size); 8096 8097 size = MAX_PATH; 8098 lstrcpyW(valW, L"apple"); 8099 r = MsiGetProductPropertyW(hprod, L"NewProperty", valW, &size); 8100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8101 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW)); 8102 ok(size == 0, "Expected 0, got %lu\n", size); 8103 8104 r = MsiSetPropertyA(hprod, "ProductCode", "value"); 8105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8106 8107 /* non-product property that is also a product property set */ 8108 size = MAX_PATH; 8109 lstrcpyA(val, "apple"); 8110 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size); 8111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8112 ok(!lstrcmpA(val, prodcode), 8113 "Expected \"%s\", got \"%s\"\n", prodcode, val); 8114 ok(size == lstrlenA(prodcode), 8115 "Expected %d, got %lu\n", lstrlenA(prodcode), size); 8116 8117 size = MAX_PATH; 8118 lstrcpyW(valW, L"apple"); 8119 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size); 8120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8121 ok(!lstrcmpW(valW, prodcodeW), 8122 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); 8123 ok(size == lstrlenW(prodcodeW), 8124 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size); 8125 8126 MsiCloseHandle(hprod); 8127 done: 8128 RegDeleteValueA(props, "LocalPackage"); 8129 RegDeleteKeyExA(props, "", access, 0); 8130 RegCloseKey(props); 8131 RegDeleteKeyExA(userkey, "", access, 0); 8132 RegCloseKey(userkey); 8133 RegDeleteKeyExA(prodkey, "", access, 0); 8134 RegCloseKey(prodkey); 8135 DeleteFileA(msifile); 8136 } 8137 8138 static void test_MsiSetProperty(void) 8139 { 8140 MSIHANDLE hpkg, hdb, hrec; 8141 CHAR buf[MAX_PATH]; 8142 LPCSTR query; 8143 DWORD size; 8144 UINT r; 8145 8146 r = package_from_db(create_package_db(), &hpkg); 8147 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 8148 { 8149 skip("Not enough rights to perform tests\n"); 8150 DeleteFileA(msifile); 8151 return; 8152 } 8153 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r); 8154 8155 /* invalid hInstall */ 8156 r = MsiSetPropertyA(0, "Prop", "Val"); 8157 ok(r == ERROR_INVALID_HANDLE, 8158 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8159 8160 /* invalid hInstall */ 8161 r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val"); 8162 ok(r == ERROR_INVALID_HANDLE, 8163 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8164 8165 /* szName is NULL */ 8166 r = MsiSetPropertyA(hpkg, NULL, "Val"); 8167 ok(r == ERROR_INVALID_PARAMETER, 8168 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8169 8170 /* both szName and szValue are NULL */ 8171 r = MsiSetPropertyA(hpkg, NULL, NULL); 8172 ok(r == ERROR_INVALID_PARAMETER, 8173 "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8174 8175 /* szName is empty */ 8176 r = MsiSetPropertyA(hpkg, "", "Val"); 8177 ok(r == ERROR_FUNCTION_FAILED, 8178 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8179 8180 /* szName is empty and szValue is NULL */ 8181 r = MsiSetPropertyA(hpkg, "", NULL); 8182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8183 8184 /* set a property */ 8185 r = MsiSetPropertyA(hpkg, "Prop", "Val"); 8186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8187 8188 /* get the property */ 8189 size = MAX_PATH; 8190 r = MsiGetPropertyA(hpkg, "Prop", buf, &size); 8191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8192 ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf); 8193 ok(size == 3, "Expected 3, got %lu\n", size); 8194 8195 /* update the property */ 8196 r = MsiSetPropertyA(hpkg, "Prop", "Nuvo"); 8197 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8198 8199 /* get the property */ 8200 size = MAX_PATH; 8201 r = MsiGetPropertyA(hpkg, "Prop", buf, &size); 8202 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8203 ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf); 8204 ok(size == 4, "Expected 4, got %lu\n", size); 8205 8206 hdb = MsiGetActiveDatabase(hpkg); 8207 ok(hdb != 0, "Expected a valid database handle\n"); 8208 8209 /* set prop is not in the _Property table */ 8210 query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'"; 8211 r = do_query(hdb, query, &hrec); 8212 ok(r == ERROR_BAD_QUERY_SYNTAX, 8213 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8214 8215 /* set prop is not in the Property table */ 8216 query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'"; 8217 r = do_query(hdb, query, &hrec); 8218 ok(r == ERROR_BAD_QUERY_SYNTAX, 8219 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8220 8221 MsiCloseHandle(hdb); 8222 8223 /* szValue is an empty string */ 8224 r = MsiSetPropertyA(hpkg, "Prop", ""); 8225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8226 8227 /* try to get the property */ 8228 size = MAX_PATH; 8229 r = MsiGetPropertyA(hpkg, "Prop", buf, &size); 8230 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8231 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 8232 ok(size == 0, "Expected 0, got %lu\n", size); 8233 8234 /* reset the property */ 8235 r = MsiSetPropertyA(hpkg, "Prop", "BlueTap"); 8236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8237 8238 /* delete the property */ 8239 r = MsiSetPropertyA(hpkg, "Prop", NULL); 8240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8241 8242 /* try to get the property */ 8243 size = MAX_PATH; 8244 r = MsiGetPropertyA(hpkg, "Prop", buf, &size); 8245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8246 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 8247 ok(size == 0, "Expected 0, got %lu\n", size); 8248 8249 MsiCloseHandle(hpkg); 8250 DeleteFileA(msifile); 8251 } 8252 8253 static void test_MsiApplyMultiplePatches(void) 8254 { 8255 UINT r, type = GetDriveTypeW(NULL); 8256 8257 r = MsiApplyMultiplePatchesA(NULL, NULL, NULL); 8258 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); 8259 8260 r = MsiApplyMultiplePatchesA("", NULL, NULL); 8261 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); 8262 8263 r = MsiApplyMultiplePatchesA(";", NULL, NULL); 8264 if (type == DRIVE_FIXED) 8265 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); 8266 else 8267 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); 8268 8269 r = MsiApplyMultiplePatchesA(" ;", NULL, NULL); 8270 if (type == DRIVE_FIXED) 8271 todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r); 8272 else 8273 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); 8274 8275 r = MsiApplyMultiplePatchesA(";;", NULL, NULL); 8276 if (type == DRIVE_FIXED) 8277 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); 8278 else 8279 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); 8280 8281 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL); 8282 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); 8283 8284 r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL); 8285 if (type == DRIVE_FIXED) 8286 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); 8287 else 8288 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); 8289 8290 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL); 8291 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); 8292 8293 r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL); 8294 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); 8295 } 8296 8297 static void test_MsiApplyPatch(void) 8298 { 8299 UINT r; 8300 8301 r = MsiApplyPatchA(NULL, NULL, INSTALLTYPE_DEFAULT, NULL); 8302 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); 8303 8304 r = MsiApplyPatchA("", NULL, INSTALLTYPE_DEFAULT, NULL); 8305 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); 8306 } 8307 8308 static void test_costs(void) 8309 { 8310 MSIHANDLE hdb, hpkg; 8311 char package[12], drive[3]; 8312 DWORD len; 8313 UINT r; 8314 int cost, temp; 8315 8316 hdb = create_package_db(); 8317 ok( hdb, "failed to create database\n" ); 8318 8319 create_property_table( hdb ); 8320 add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" ); 8321 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); 8322 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); 8323 8324 create_media_table( hdb ); 8325 add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''"); 8326 8327 create_file_table( hdb ); 8328 add_file_entry( hdb, "'a.txt', 'one', 'a.txt', 2048000000, '', '', 8192, 1" ); 8329 add_file_entry( hdb, "'b.txt', 'one', 'b.txt', 2048000000, '', '', 8192, 1" ); 8330 add_file_entry( hdb, "'c.txt', 'one', 'c.txt', 2048000000, '', '', 8192, 1" ); 8331 add_file_entry( hdb, "'d.txt', 'one', 'd.txt', 4097, '', '', 8192, 1" ); 8332 add_file_entry( hdb, "'e.txt', 'one', 'e.txt', 1, '', '', 8192, 1" ); 8333 8334 create_component_table( hdb ); 8335 add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'a.txt'" ); 8336 add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" ); 8337 8338 create_feature_table( hdb ); 8339 add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" ); 8340 add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" ); 8341 8342 create_feature_components_table( hdb ); 8343 add_feature_components_entry( hdb, "'one', 'one'" ); 8344 add_feature_components_entry( hdb, "'two', 'two'" ); 8345 8346 create_install_execute_sequence_table( hdb ); 8347 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); 8348 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); 8349 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); 8350 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" ); 8351 8352 r = MsiDatabaseCommit( hdb ); 8353 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8354 8355 sprintf( package, "#%lu", hdb ); 8356 r = MsiOpenPackageA( package, &hpkg ); 8357 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 8358 { 8359 skip("Not enough rights to perform tests\n"); 8360 goto error; 8361 } 8362 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8363 8364 r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8365 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8366 8367 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8368 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8369 8370 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8371 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8372 8373 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8374 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8375 8376 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); 8377 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8378 8379 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL ); 8380 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8381 8382 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL ); 8383 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8384 8385 len = sizeof(drive); 8386 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL ); 8387 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8388 8389 len = sizeof(drive); 8390 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL ); 8391 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8392 8393 len = sizeof(drive); 8394 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8395 todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r ); 8396 8397 len = sizeof(drive); 8398 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp ); 8399 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); 8400 8401 MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL ); 8402 8403 r = MsiDoActionA( hpkg, "CostInitialize" ); 8404 ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r ); 8405 8406 r = MsiDoActionA( hpkg, "FileCost" ); 8407 ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r ); 8408 8409 len = sizeof(drive); 8410 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8411 ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r ); 8412 8413 r = MsiDoActionA( hpkg, "CostFinalize" ); 8414 ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r ); 8415 8416 /* contrary to what msdn says InstallValidate must be called too */ 8417 len = sizeof(drive); 8418 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8419 todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r ); 8420 8421 r = MsiDoActionA( hpkg, "InstallValidate" ); 8422 ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r ); 8423 8424 len = 0; 8425 r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8426 ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r ); 8427 8428 len = 0; 8429 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8430 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); 8431 ok( len == 2, "expected len == 2, got %lu\n", len ); 8432 8433 len = 2; 8434 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8435 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); 8436 ok( len == 2, "expected len == 2, got %lu\n", len ); 8437 8438 len = 2; 8439 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); 8440 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); 8441 ok( len == 2, "expected len == 2, got %lu\n", len ); 8442 8443 /* install state doesn't seem to matter */ 8444 len = sizeof(drive); 8445 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); 8446 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8447 8448 len = sizeof(drive); 8449 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp ); 8450 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8451 8452 len = sizeof(drive); 8453 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp ); 8454 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8455 8456 len = sizeof(drive); 8457 drive[0] = 0; 8458 cost = temp = 0xdead; 8459 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8460 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8461 ok( len == 2, "expected len == 2, got %lu\n", len ); 8462 ok( drive[0], "expected a drive\n" ); 8463 ok( cost == 12000024, "got %d\n", cost ); 8464 ok( !temp, "expected temp == 0, got %d\n", temp ); 8465 8466 len = sizeof(drive); 8467 drive[0] = 0; 8468 cost = temp = 0xdead; 8469 r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8470 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8471 ok( len == 2, "expected len == 2, got %lu\n", len ); 8472 ok( drive[0], "expected a drive\n" ); 8473 ok( !cost, "expected cost == 0, got %d\n", cost ); 8474 ok( !temp, "expected temp == 0, got %d\n", temp ); 8475 8476 len = sizeof(drive); 8477 drive[0] = 0; 8478 cost = temp = 0xdead; 8479 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); 8480 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); 8481 ok( len == 2, "expected len == 2, got %lu\n", len ); 8482 ok( drive[0], "expected a drive\n" ); 8483 ok( !cost, "expected cost == 0, got %d\n", cost ); 8484 todo_wine ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp ); 8485 8486 /* increased index */ 8487 len = sizeof(drive); 8488 r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); 8489 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r ); 8490 8491 len = sizeof(drive); 8492 r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); 8493 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r ); 8494 8495 /* test MsiGetFeatureCost */ 8496 cost = 0xdead; 8497 r = MsiGetFeatureCostA( hpkg, NULL, MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost ); 8498 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r); 8499 ok( cost == 0xdead, "got %d\n", cost ); 8500 8501 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, NULL ); 8502 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r); 8503 8504 cost = 0xdead; 8505 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost ); 8506 ok( !r, "got %u\n", r); 8507 ok( cost == 12000024, "got %d\n", cost ); 8508 8509 MsiCloseHandle( hpkg ); 8510 error: 8511 MsiCloseHandle( hdb ); 8512 DeleteFileA( msifile ); 8513 } 8514 8515 static void test_MsiDatabaseCommit(void) 8516 { 8517 UINT r; 8518 MSIHANDLE hdb, hpkg = 0; 8519 char buf[32], package[12]; 8520 DWORD sz; 8521 8522 hdb = create_package_db(); 8523 ok( hdb, "failed to create database\n" ); 8524 8525 create_property_table( hdb ); 8526 8527 sprintf( package, "#%lu", hdb ); 8528 r = MsiOpenPackageA( package, &hpkg ); 8529 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 8530 { 8531 skip("Not enough rights to perform tests\n"); 8532 goto error; 8533 } 8534 ok( r == ERROR_SUCCESS, "got %u\n", r ); 8535 8536 r = MsiSetPropertyA( hpkg, "PROP", "value" ); 8537 ok( r == ERROR_SUCCESS, "got %u\n", r ); 8538 8539 buf[0] = 0; 8540 sz = sizeof(buf); 8541 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz ); 8542 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r ); 8543 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf ); 8544 8545 r = MsiDatabaseCommit( hdb ); 8546 ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r ); 8547 8548 buf[0] = 0; 8549 sz = sizeof(buf); 8550 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz ); 8551 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r ); 8552 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf ); 8553 8554 MsiCloseHandle( hpkg ); 8555 error: 8556 MsiCloseHandle( hdb ); 8557 DeleteFileA( msifile ); 8558 } 8559 8560 static int externalui_ran; 8561 8562 static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message) 8563 { 8564 externalui_ran = 1; 8565 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type); 8566 return 0; 8567 } 8568 8569 static int externalui_record_ran; 8570 8571 static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord) 8572 { 8573 INT retval = context ? *((INT *)context) : 0; 8574 UINT r; 8575 externalui_record_ran = 1; 8576 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type); 8577 r = MsiRecordGetFieldCount(hrecord); 8578 ok(r == 1, "expected 1, got %u\n", r); 8579 r = MsiRecordGetInteger(hrecord, 1); 8580 ok(r == 12345, "expected 12345, got %u\n", r); 8581 return retval; 8582 } 8583 8584 static void test_externalui(void) 8585 { 8586 /* test that external UI handlers work correctly */ 8587 8588 INSTALLUI_HANDLERA prev; 8589 INSTALLUI_HANDLER_RECORD prev_record; 8590 MSIHANDLE hpkg, hrecord; 8591 UINT r; 8592 INT retval = 0; 8593 8594 prev = MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL); 8595 8596 r = package_from_db(create_package_db(), &hpkg); 8597 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 8598 { 8599 skip("Not enough rights to perform tests\n"); 8600 DeleteFileA(msifile); 8601 return; 8602 } 8603 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r); 8604 8605 hrecord = MsiCreateRecord(1); 8606 ok(hrecord, "Expected a valid record\n"); 8607 r = MsiRecordSetStringA(hrecord, 0, "test message [1]"); 8608 ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r); 8609 r = MsiRecordSetInteger(hrecord, 1, 12345); 8610 ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r); 8611 8612 externalui_ran = 0; 8613 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8614 ok(r == 0, "expected 0, got %u\n", r); 8615 ok(externalui_ran == 1, "external UI callback did not run\n"); 8616 8617 prev = MsiSetExternalUIA(prev, 0, NULL); 8618 ok(prev == externalui_callback, "wrong callback function %p\n", prev); 8619 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_USER, &retval, &prev_record); 8620 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r); 8621 8622 externalui_ran = externalui_record_ran = 0; 8623 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8624 ok(r == 0, "expected 0, got %u\n", r); 8625 ok(externalui_ran == 0, "external UI callback should not have run\n"); 8626 ok(externalui_record_ran == 1, "external UI record callback did not run\n"); 8627 8628 MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL); 8629 8630 externalui_ran = externalui_record_ran = 0; 8631 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8632 ok(r == 0, "expected 0, got %u\n", r); 8633 ok(externalui_ran == 1, "external UI callback did not run\n"); 8634 ok(externalui_record_ran == 1, "external UI record callback did not run\n"); 8635 8636 retval = 1; 8637 externalui_ran = externalui_record_ran = 0; 8638 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8639 ok(r == 1, "expected 1, got %u\n", r); 8640 ok(externalui_ran == 0, "external UI callback should not have run\n"); 8641 ok(externalui_record_ran == 1, "external UI record callback did not run\n"); 8642 8643 /* filter and context should be kept separately */ 8644 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_ERROR, &retval, &prev_record); 8645 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r); 8646 8647 externalui_ran = externalui_record_ran = 0; 8648 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 8649 ok(r == 0, "expected 0, got %u\n", r); 8650 ok(externalui_ran == 1, "external UI callback did not run\n"); 8651 ok(externalui_record_ran == 0, "external UI record callback should not have run\n"); 8652 8653 MsiCloseHandle(hpkg); 8654 DeleteFileA(msifile); 8655 } 8656 8657 struct externalui_message { 8658 UINT message; 8659 int field_count; 8660 char field[4][100]; 8661 int match[4]; /* should we test for a match */ 8662 int optional; 8663 }; 8664 8665 static struct externalui_message *sequence; 8666 static int sequence_count, sequence_size; 8667 8668 static void add_message(const struct externalui_message *msg) 8669 { 8670 if (!sequence) 8671 { 8672 sequence_size = 10; 8673 sequence = malloc(sequence_size * sizeof(*sequence)); 8674 } 8675 if (sequence_count == sequence_size) 8676 { 8677 sequence_size *= 2; 8678 sequence = realloc(sequence, sequence_size * sizeof(*sequence)); 8679 } 8680 8681 assert(sequence); 8682 sequence[sequence_count++] = *msg; 8683 } 8684 8685 static void flush_sequence(void) 8686 { 8687 free(sequence); 8688 sequence = NULL; 8689 sequence_count = sequence_size = 0; 8690 } 8691 8692 static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo, 8693 const char *file, int line) 8694 { 8695 static const struct externalui_message end_of_sequence = {0}; 8696 const struct externalui_message *actual; 8697 int failcount = 0; 8698 int i; 8699 8700 add_message(&end_of_sequence); 8701 8702 actual = sequence; 8703 8704 while (expected->message && actual->message) 8705 { 8706 if (expected->message == actual->message) 8707 { 8708 if (expected->field_count < actual->field_count) 8709 { 8710 todo_wine_if (todo) 8711 ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n", 8712 context, expected->message, expected->field_count, actual->field_count); 8713 failcount++; 8714 } 8715 8716 for (i = 0; i <= actual->field_count; i++) 8717 { 8718 if (expected->match[i] && strcmp(expected->field[i], actual->field[i])) 8719 { 8720 todo_wine_if (todo) 8721 ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n", 8722 context, expected->message, i, expected->field[i], actual->field[i]); 8723 failcount++; 8724 } 8725 } 8726 8727 expected++; 8728 actual++; 8729 } 8730 else if (expected->optional) 8731 { 8732 expected++; 8733 } 8734 else 8735 { 8736 todo_wine_if (todo) 8737 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n", 8738 context, expected->message, actual->message); 8739 failcount++; 8740 if (todo) 8741 goto done; 8742 expected++; 8743 actual++; 8744 } 8745 } 8746 8747 if (expected->message || actual->message) 8748 { 8749 todo_wine_if (todo) 8750 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n", 8751 context, expected->message, actual->message); 8752 failcount++; 8753 } 8754 8755 if(todo && !failcount) /* succeeded yet marked todo */ 8756 { 8757 todo_wine 8758 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context); 8759 } 8760 8761 done: 8762 flush_sequence(); 8763 } 8764 8765 #define ok_sequence(exp, contx, todo) \ 8766 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__) 8767 8768 /* don't use PROGRESS, which is timing-dependent, 8769 * or SHOWDIALOG, which due to a bug causes a hang on XP */ 8770 static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE = 8771 INSTALLLOGMODE_FATALEXIT | 8772 INSTALLLOGMODE_ERROR | 8773 INSTALLLOGMODE_WARNING | 8774 INSTALLLOGMODE_USER | 8775 INSTALLLOGMODE_INFO | 8776 INSTALLLOGMODE_FILESINUSE | 8777 INSTALLLOGMODE_RESOLVESOURCE | 8778 INSTALLLOGMODE_OUTOFDISKSPACE | 8779 INSTALLLOGMODE_ACTIONSTART | 8780 INSTALLLOGMODE_ACTIONDATA | 8781 INSTALLLOGMODE_COMMONDATA | 8782 INSTALLLOGMODE_INITIALIZE | 8783 INSTALLLOGMODE_TERMINATE | 8784 INSTALLLOGMODE_RMFILESINUSE | 8785 INSTALLLOGMODE_INSTALLSTART | 8786 INSTALLLOGMODE_INSTALLEND; 8787 8788 static const struct externalui_message empty_sequence[] = { 8789 {0} 8790 }; 8791 8792 static const struct externalui_message openpackage_nonexistent_sequence[] = { 8793 {INSTALLMESSAGE_INITIALIZE, -1}, 8794 {INSTALLMESSAGE_TERMINATE, -1}, 8795 {0} 8796 }; 8797 8798 static const struct externalui_message openpackage_sequence[] = { 8799 {INSTALLMESSAGE_INITIALIZE, -1}, 8800 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 8801 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 8802 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 8803 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 8804 {0} 8805 }; 8806 8807 static const struct externalui_message processmessage_info_sequence[] = { 8808 {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}}, 8809 {0} 8810 }; 8811 8812 static const struct externalui_message processmessage_actionstart_sequence[] = { 8813 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}}, 8814 {0} 8815 }; 8816 8817 static const struct externalui_message processmessage_actiondata_sequence[] = { 8818 {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}}, 8819 {0} 8820 }; 8821 8822 static const struct externalui_message processmessage_error_sequence[] = { 8823 {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}}, 8824 {0} 8825 }; 8826 8827 static const struct externalui_message processmessage_internal_error_sequence[] = { 8828 {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}}, 8829 {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}}, 8830 {0} 8831 }; 8832 8833 static const struct externalui_message processmessage_error_format_sequence[] = { 8834 {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}}, 8835 {0} 8836 }; 8837 8838 static const struct externalui_message doaction_costinitialize_sequence[] = { 8839 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}}, 8840 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}}, 8841 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, 8842 {0} 8843 }; 8844 8845 static const struct externalui_message doaction_custom_sequence[] = { 8846 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}}, 8847 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 8848 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}}, 8849 {0} 8850 }; 8851 8852 static const struct externalui_message doaction_custom_fullui_sequence[] = { 8853 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 8854 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}}, 8855 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}}, 8856 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 8857 {0} 8858 }; 8859 8860 static const struct externalui_message doaction_custom_cancel_sequence[] = { 8861 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 8862 {0} 8863 }; 8864 8865 static const struct externalui_message doaction_dialog_nonexistent_sequence[] = { 8866 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 8867 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 8868 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}}, 8869 {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}}, 8870 {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}}, 8871 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}}, 8872 {0} 8873 }; 8874 8875 static const struct externalui_message doaction_dialog_sequence[] = { 8876 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}}, 8877 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}}, 8878 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}}, 8879 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}}, 8880 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}}, 8881 {0} 8882 }; 8883 8884 static const struct externalui_message doaction_dialog_error_sequence[] = { 8885 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}}, 8886 {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}}, 8887 {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}}, 8888 {0} 8889 }; 8890 8891 static const struct externalui_message doaction_dialog_3_sequence[] = { 8892 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}}, 8893 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}}, 8894 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}}, 8895 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}}, 8896 {0} 8897 }; 8898 8899 static const struct externalui_message doaction_dialog_12345_sequence[] = { 8900 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}}, 8901 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}}, 8902 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}}, 8903 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}}, 8904 {0} 8905 }; 8906 8907 static const struct externalui_message closehandle_sequence[] = { 8908 {INSTALLMESSAGE_TERMINATE, -1}, 8909 {0} 8910 }; 8911 8912 static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string) 8913 { 8914 INT retval = context ? *((INT *)context) : 0; 8915 struct externalui_message msg; 8916 8917 msg.message = message; 8918 msg.field_count = 0; 8919 strcpy(msg.field[0], string); 8920 add_message(&msg); 8921 8922 return retval; 8923 } 8924 8925 static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord) 8926 { 8927 INT retval = context ? *((INT *)context) : 0; 8928 struct externalui_message msg; 8929 char buffer[256]; 8930 DWORD length; 8931 UINT r; 8932 int i; 8933 8934 msg.message = message; 8935 if (message == INSTALLMESSAGE_TERMINATE) 8936 { 8937 /* trying to access the record seems to hang on some versions of Windows */ 8938 msg.field_count = -1; 8939 add_message(&msg); 8940 return 1; 8941 } 8942 msg.field_count = MsiRecordGetFieldCount(hrecord); 8943 for (i = 0; i <= msg.field_count; i++) 8944 { 8945 length = sizeof(buffer); 8946 r = MsiRecordGetStringA(hrecord, i, buffer, &length); 8947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 8948 memcpy(msg.field[i], buffer, min(100, length+1)); 8949 } 8950 8951 /* top-level actions dump a list of all set properties; skip them since they're inconsistent */ 8952 if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8)) 8953 return retval; 8954 8955 add_message(&msg); 8956 8957 return retval; 8958 } 8959 8960 static void test_externalui_message(void) 8961 { 8962 /* test that events trigger the correct sequence of messages */ 8963 8964 INSTALLUI_HANDLER_RECORD prev; 8965 MSIHANDLE hdb, hpkg, hrecord; 8966 INT retval = 1; 8967 UINT r; 8968 8969 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); 8970 8971 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, &retval); 8972 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, &retval, &prev); 8973 8974 flush_sequence(); 8975 8976 CoInitialize(NULL); 8977 8978 hdb = create_package_db(); 8979 ok(hdb, "failed to create database\n"); 8980 8981 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1); 8982 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 8983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8984 8985 r = run_query(hdb, 0, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)"); 8986 ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r); 8987 r = run_query(hdb, 0, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')"); 8988 ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r); 8989 8990 create_actiontext_table(hdb); 8991 add_actiontext_entry(hdb, "'custom', 'description', 'template'"); 8992 add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'"); 8993 8994 r = MsiOpenPackageA(NULL, &hpkg); 8995 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 8996 ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE); 8997 8998 r = MsiOpenPackageA("nonexistent", &hpkg); 8999 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r); 9000 ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE); 9001 9002 r = package_from_db(hdb, &hpkg); 9003 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 9004 { 9005 skip("Not enough rights to perform tests\n"); 9006 DeleteFileA(msifile); 9007 return; 9008 } 9009 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 9010 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE); 9011 9012 /* Test MsiProcessMessage */ 9013 hrecord = MsiCreateRecord(3); 9014 ok(hrecord, "failed to create record\n"); 9015 9016 MsiRecordSetStringA(hrecord, 0, "zero"); 9017 MsiRecordSetStringA(hrecord, 1, "one"); 9018 MsiRecordSetStringA(hrecord, 2, "two"); 9019 MsiRecordSetStringA(hrecord, 3, "three"); 9020 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord); 9021 ok(r == 1, "Expected 1, got %d\n", r); 9022 ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE); 9023 9024 MsiRecordSetStringA(hrecord, 1, "name"); 9025 MsiRecordSetStringA(hrecord, 2, "description"); 9026 MsiRecordSetStringA(hrecord, 3, "template"); 9027 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONSTART, hrecord); 9028 ok(r == 1, "Expected 1, got %d\n", r); 9029 ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE); 9030 9031 MsiRecordSetStringA(hrecord, 0, "apple"); 9032 MsiRecordSetStringA(hrecord, 1, "cherry"); 9033 MsiRecordSetStringA(hrecord, 2, "banana"); 9034 MsiRecordSetStringA(hrecord, 3, "guava"); 9035 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONDATA, hrecord); 9036 ok(r == 1, "Expected 1, got %d\n", r); 9037 ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE); 9038 9039 /* non-internal error */ 9040 MsiRecordSetStringA(hrecord, 0, NULL); 9041 MsiRecordSetInteger(hrecord, 1, 1311); 9042 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 9043 ok(r == 1, "Expected 1, got %d\n", r); 9044 ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE); 9045 9046 /* internal error */ 9047 MsiRecordSetStringA(hrecord, 0, NULL); 9048 MsiRecordSetInteger(hrecord, 1, 2726); 9049 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 9050 ok(r == 0, "Expected 0, got %d\n", r); 9051 ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE); 9052 9053 /* with format field */ 9054 MsiRecordSetStringA(hrecord, 0, "starfruit"); 9055 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord); 9056 ok(r == 1, "Expected 1, got %d\n", r); 9057 ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE); 9058 9059 /* Test a standard action */ 9060 r = MsiDoActionA(hpkg, "CostInitialize"); 9061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9062 ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE); 9063 9064 /* Test a custom action */ 9065 r = MsiDoActionA(hpkg, "custom"); 9066 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r); 9067 ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE); 9068 9069 /* close the package */ 9070 MsiCloseHandle(hpkg); 9071 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9072 9073 /* Test dialogs */ 9074 hdb = create_package_db(); 9075 ok(hdb, "failed to create database\n"); 9076 9077 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 9078 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9079 9080 create_dialog_table(hdb); 9081 add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'"); 9082 9083 create_control_table(hdb); 9084 add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'"); 9085 9086 r = package_from_db(hdb, &hpkg); 9087 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); 9088 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE); 9089 9090 /* Test a custom action */ 9091 r = MsiDoActionA(hpkg, "custom"); 9092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9093 ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE); 9094 9095 retval = 2; 9096 r = MsiDoActionA(hpkg, "custom"); 9097 ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r); 9098 ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE); 9099 9100 retval = 0; 9101 r = MsiDoActionA(hpkg, "custom"); 9102 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r); 9103 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE); 9104 9105 r = MsiDoActionA(hpkg, "dialog"); 9106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9107 ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE); 9108 9109 retval = -1; 9110 r = MsiDoActionA(hpkg, "error"); 9111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9112 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE); 9113 9114 r = MsiDoActionA(hpkg, "error"); 9115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9116 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE); 9117 9118 retval = -2; 9119 r = MsiDoActionA(hpkg, "custom"); 9120 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r); 9121 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE); 9122 9123 retval = 3; 9124 r = MsiDoActionA(hpkg, "dialog"); 9125 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r); 9126 ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE); 9127 9128 retval = 12345; 9129 r = MsiDoActionA(hpkg, "dialog"); 9130 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r); 9131 ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE); 9132 9133 MsiCloseHandle(hpkg); 9134 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9135 9136 MsiCloseHandle(hrecord); 9137 CoUninitialize(); 9138 DeleteFileA(msifile); 9139 DeleteFileA("forcecodepage.idt"); 9140 } 9141 9142 static const struct externalui_message controlevent_spawn_sequence[] = { 9143 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}}, 9144 {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}}, 9145 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}}, 9146 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}}, 9147 9148 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 9149 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}}, 9150 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 9151 9152 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}}, 9153 9154 {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}}, 9155 {0} 9156 }; 9157 9158 static const struct externalui_message controlevent_spawn2_sequence[] = { 9159 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}}, 9160 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}}, 9161 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}}, 9162 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}}, 9163 9164 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}}, 9165 {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}}, 9166 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}}, 9167 9168 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}}, 9169 9170 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}}, 9171 {0} 9172 }; 9173 9174 static void test_controlevent(void) 9175 { 9176 INSTALLUI_HANDLER_RECORD prev; 9177 MSIHANDLE hdb, hpkg; 9178 UINT r; 9179 9180 if (!winetest_interactive) 9181 { 9182 skip("interactive ControlEvent tests\n"); 9183 return; 9184 } 9185 9186 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); 9187 9188 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL); 9189 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev); 9190 9191 flush_sequence(); 9192 9193 CoInitialize(NULL); 9194 9195 hdb = create_package_db(); 9196 ok(hdb, "failed to create database\n"); 9197 9198 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1); 9199 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 9200 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9201 9202 create_dialog_table(hdb); 9203 add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'"); 9204 add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'"); 9205 add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'"); 9206 add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'"); 9207 9208 create_control_table(hdb); 9209 add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); 9210 add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); 9211 add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); 9212 add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); 9213 9214 create_controlevent_table(hdb); 9215 add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1"); 9216 add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1"); 9217 9218 create_custom_action_table(hdb); 9219 add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'"); 9220 9221 /* SpawnDialog and EndDialog should trigger after all other events */ 9222 add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1"); 9223 add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2"); 9224 9225 /* Multiple dialog events cause only the last one to be triggered */ 9226 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1"); 9227 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2"); 9228 add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3"); 9229 9230 r = package_from_db(hdb, &hpkg); 9231 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r); 9232 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE); 9233 9234 r = MsiDoActionA(hpkg, "spawn"); 9235 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r); 9236 ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE); 9237 9238 r = MsiDoActionA(hpkg, "spawn2"); 9239 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r); 9240 ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE); 9241 9242 MsiCloseHandle(hpkg); 9243 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9244 9245 CoUninitialize(); 9246 DeleteFileA(msifile); 9247 DeleteFileA("forcecodepage.idt"); 9248 } 9249 9250 static const struct externalui_message toplevel_install_sequence[] = { 9251 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9252 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9253 9254 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9255 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9256 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9257 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9258 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9259 9260 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9261 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9262 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1}, 9263 9264 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, 9265 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}}, 9266 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, 9267 9268 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}}, 9269 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, 9270 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, 9271 9272 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}}, 9273 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, 9274 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, 9275 9276 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9277 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1}, 9278 9279 /* property dump */ 9280 9281 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, 9282 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, 9283 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9284 {0} 9285 }; 9286 9287 static const struct externalui_message toplevel_install_ui_sequence[] = { 9288 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9289 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9290 9291 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}}, 9292 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}}, 9293 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}}, 9294 9295 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9296 {0} 9297 }; 9298 9299 static const struct externalui_message toplevel_executeaction_install_sequence[] = { 9300 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}}, 9301 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, 9302 9303 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9304 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9305 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9306 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9307 9308 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9309 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9310 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1}, 9311 9312 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, 9313 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}}, 9314 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, 9315 9316 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}}, 9317 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, 9318 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, 9319 9320 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}}, 9321 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, 9322 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, 9323 9324 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9325 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1}, 9326 9327 /* property dump */ 9328 9329 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, 9330 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, 9331 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, 9332 {0} 9333 }; 9334 9335 static const struct externalui_message toplevel_executeaction_costinitialize_sequence[] = { 9336 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}}, 9337 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, 9338 9339 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9340 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9341 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9342 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9343 9344 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, 9345 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}}, 9346 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, 9347 9348 /* property dump */ 9349 9350 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, 9351 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, 9352 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, 9353 {0} 9354 }; 9355 9356 static const struct externalui_message toplevel_msiinstallproduct_sequence[] = { 9357 {INSTALLMESSAGE_INITIALIZE, -1}, 9358 9359 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9360 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, 9361 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9362 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, 9363 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, 9364 9365 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, 9366 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, 9367 9368 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}}, 9369 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}}, 9370 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}}, 9371 9372 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, 9373 9374 /* property dump */ 9375 9376 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9377 {INSTALLMESSAGE_TERMINATE, -1}, 9378 {0} 9379 }; 9380 9381 static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[] = { 9382 {INSTALLMESSAGE_INITIALIZE, -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, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}}, 9391 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}}, 9392 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}}, 9393 9394 /* property dump */ 9395 9396 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, 9397 {INSTALLMESSAGE_TERMINATE, -1}, 9398 {0} 9399 }; 9400 9401 /* tests involving top-level actions: INSTALL, ExecuteAction */ 9402 static void test_top_level_action(void) 9403 { 9404 INSTALLUI_HANDLER_RECORD prev; 9405 MSIHANDLE hdb, hpkg; 9406 UINT r; 9407 char msifile_absolute[MAX_PATH]; 9408 9409 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 9410 9411 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL); 9412 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev); 9413 9414 flush_sequence(); 9415 9416 CoInitialize(NULL); 9417 9418 hdb = create_package_db(); 9419 ok(hdb, "failed to create database\n"); 9420 9421 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") -1 ); 9422 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 9423 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9424 9425 create_property_table(hdb); 9426 add_property_entry(hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'"); 9427 9428 create_install_execute_sequence_table(hdb); 9429 add_install_execute_sequence_entry(hdb, "'CostInitialize', '', 1"); 9430 add_install_execute_sequence_entry(hdb, "'FileCost', '', 2"); 9431 add_install_execute_sequence_entry(hdb, "'CostFinalize', '', 3"); 9432 9433 create_install_ui_sequence_table(hdb); 9434 add_install_ui_sequence_entry(hdb, "'AppSearch', '', 1"); 9435 9436 MsiDatabaseCommit(hdb); 9437 9438 /* for some reason we have to open the package from file using an absolute path */ 9439 MsiCloseHandle(hdb); 9440 GetFullPathNameA(msifile, MAX_PATH, msifile_absolute, NULL); 9441 r = MsiOpenPackageA(msifile_absolute, &hpkg); 9442 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r); 9443 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE); 9444 9445 /* test INSTALL */ 9446 r = MsiDoActionA(hpkg, "INSTALL"); 9447 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9448 ok_sequence(toplevel_install_sequence, "INSTALL (no UI)", FALSE); 9449 9450 /* test INSTALL with reduced+ UI */ 9451 /* for some reason we need to re-open the package to change the internal UI */ 9452 MsiCloseHandle(hpkg); 9453 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9454 MsiSetInternalUI(INSTALLUILEVEL_REDUCED, NULL); 9455 r = MsiOpenPackageA(msifile_absolute, &hpkg); 9456 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r); 9457 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE); 9458 9459 r = MsiDoActionA(hpkg, "INSTALL"); 9460 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9461 ok_sequence(toplevel_install_ui_sequence, "INSTALL (reduced+ UI)", TRUE); 9462 9463 /* test ExecuteAction with EXECUTEACTION property unset */ 9464 MsiSetPropertyA(hpkg, "EXECUTEACTION", NULL); 9465 r = MsiDoActionA(hpkg, "ExecuteAction"); 9466 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9467 ok_sequence(toplevel_executeaction_install_sequence, "ExecuteAction: INSTALL", FALSE); 9468 9469 /* test ExecuteAction with EXECUTEACTION property set */ 9470 MsiSetPropertyA(hpkg, "EXECUTEACTION", "CostInitialize"); 9471 r = MsiDoActionA(hpkg, "ExecuteAction"); 9472 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9473 ok_sequence(toplevel_executeaction_costinitialize_sequence, "ExecuteAction: CostInitialize", FALSE); 9474 9475 MsiCloseHandle(hpkg); 9476 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE); 9477 9478 /* test MsiInstallProduct() */ 9479 r = MsiInstallProductA(msifile_absolute, NULL); 9480 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); 9481 ok_sequence(toplevel_msiinstallproduct_sequence, "MsiInstallProduct()", TRUE); 9482 9483 r = MsiInstallProductA(msifile_absolute, "ACTION=custom"); 9484 todo_wine 9485 ok(r == ERROR_INSTALL_FAILURE, "expected ERROR_INSTALL_FAILURE, got %u\n", r); 9486 ok_sequence(toplevel_msiinstallproduct_custom_sequence, "MsiInstallProduct(ACTION=custom)", TRUE); 9487 9488 CoUninitialize(); 9489 DeleteFileA(msifile); 9490 DeleteFileA("forcecodepage.idt"); 9491 } 9492 9493 START_TEST(package) 9494 { 9495 char temp_path[MAX_PATH], prev_path[MAX_PATH]; 9496 DWORD len; 9497 9498 if (!is_process_elevated()) restart_as_admin_elevated(); 9499 9500 IsWow64Process(GetCurrentProcess(), &is_wow64); 9501 9502 GetCurrentDirectoryA(MAX_PATH, prev_path); 9503 GetTempPathA(MAX_PATH, temp_path); 9504 SetCurrentDirectoryA(temp_path); 9505 9506 lstrcpyA(CURR_DIR, temp_path); 9507 len = lstrlenA(CURR_DIR); 9508 9509 if (len && (CURR_DIR[len - 1] == '\\')) 9510 CURR_DIR[len - 1] = 0; 9511 9512 test_createpackage(); 9513 test_doaction(); 9514 test_gettargetpath_bad(); 9515 test_settargetpath(); 9516 test_props(); 9517 test_property_table(); 9518 test_condition(); 9519 test_msipackage(); 9520 test_formatrecord2(); 9521 test_formatrecord_tables(); 9522 test_states(); 9523 test_removefiles(); 9524 test_appsearch(); 9525 test_appsearch_complocator(); 9526 test_appsearch_reglocator(); 9527 test_appsearch_inilocator(); 9528 test_appsearch_drlocator(); 9529 test_featureparents(); 9530 test_installprops(); 9531 test_launchconditions(); 9532 test_ccpsearch(); 9533 test_complocator(); 9534 test_MsiGetSourcePath(); 9535 test_shortlongsource(); 9536 test_sourcedir(); 9537 test_access(); 9538 test_emptypackage(); 9539 test_MsiGetProductProperty(); 9540 test_MsiSetProperty(); 9541 test_MsiApplyMultiplePatches(); 9542 test_MsiApplyPatch(); 9543 test_costs(); 9544 test_MsiDatabaseCommit(); 9545 test_externalui(); 9546 test_externalui_message(); 9547 test_controlevent(); 9548 test_top_level_action(); 9549 9550 SetCurrentDirectoryA(prev_path); 9551 } 9552