aboutsummaryrefslogtreecommitdiff
path: root/src/engine/cache.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-04-16 10:20:41 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-04-19 23:12:55 -0500
commit5d6046bee5021052da4a666c1e2ceeb0f16af349 (patch)
tree589ddcbe270e2e4df8cffdbd26792bcee4c29e1c /src/engine/cache.cpp
parentb941c2754748251520dc5032d11396c9844fad8e (diff)
downloadwix-5d6046bee5021052da4a666c1e2ceeb0f16af349.tar.gz
wix-5d6046bee5021052da4a666c1e2ceeb0f16af349.tar.bz2
wix-5d6046bee5021052da4a666c1e2ceeb0f16af349.zip
Replace OnResolveSource with OnCacheAcquireResolving
Inactivate the engine during OnCacheAcquireBegin and Complete to allow setting the source from there. Fixes #3640 Contributes to #5253
Diffstat (limited to 'src/engine/cache.cpp')
-rw-r--r--src/engine/cache.cpp203
1 files changed, 126 insertions, 77 deletions
diff --git a/src/engine/cache.cpp b/src/engine/cache.cpp
index 6ac313e0..84b7f131 100644
--- a/src/engine/cache.cpp
+++ b/src/engine/cache.cpp
@@ -11,7 +11,7 @@ static const DWORD FILE_OPERATION_RETRY_WAIT = 2000;
11 11
12static BOOL vfInitializedCache = FALSE; 12static BOOL vfInitializedCache = FALSE;
13static BOOL vfRunningFromCache = FALSE; 13static BOOL vfRunningFromCache = FALSE;
14static LPWSTR vsczSourceProcessPath = NULL; 14static LPWSTR vsczSourceProcessFolder = NULL;
15static LPWSTR vsczWorkingFolder = NULL; 15static LPWSTR vsczWorkingFolder = NULL;
16static LPWSTR vsczDefaultUserPackageCache = NULL; 16static LPWSTR vsczDefaultUserPackageCache = NULL;
17static LPWSTR vsczDefaultMachinePackageCache = NULL; 17static LPWSTR vsczDefaultMachinePackageCache = NULL;
@@ -140,8 +140,8 @@ extern "C" HRESULT CacheInitialize(
140 wzSourceProcessPath = sczCurrentPath; 140 wzSourceProcessPath = sczCurrentPath;
141 } 141 }
142 142
143 hr = StrAllocString(&vsczSourceProcessPath, wzSourceProcessPath, 0); 143 hr = PathGetDirectory(wzSourceProcessPath, &vsczSourceProcessFolder);
144 ExitOnFailure(hr, "Failed to initialize cache source path."); 144 ExitOnFailure(hr, "Failed to initialize cache source folder.");
145 145
146 // If we're not running from the cache, ensure the original source is set. 146 // If we're not running from the cache, ensure the original source is set.
147 if (!vfRunningFromCache) 147 if (!vfRunningFromCache)
@@ -393,112 +393,166 @@ LExit:
393 return hr; 393 return hr;
394} 394}
395 395
396extern "C" HRESULT CacheFindLocalSource( 396extern "C" HRESULT CacheGetLocalSourcePaths(
397 __in_z LPCWSTR wzRelativePath,
397 __in_z LPCWSTR wzSourcePath, 398 __in_z LPCWSTR wzSourcePath,
398 __in_z LPCWSTR wzDestinationPath, 399 __in_z LPCWSTR wzDestinationPath,
400 __in_z_opt LPCWSTR wzLayoutDirectory,
399 __in BURN_VARIABLES* pVariables, 401 __in BURN_VARIABLES* pVariables,
400 __out BOOL* pfFound, 402 __inout LPWSTR** prgSearchPaths,
401 __out_z LPWSTR* psczSourceFullPath 403 __out DWORD* pcSearchPaths
402 ) 404 )
403{ 405{
404 HRESULT hr = S_OK; 406 HRESULT hr = S_OK;
405 LPWSTR sczSourceProcessFolder = NULL;
406 LPWSTR sczCurrentPath = NULL; 407 LPWSTR sczCurrentPath = NULL;
407 LPWSTR sczLastSourcePath = NULL;
408 LPWSTR sczLastSourceFolder = NULL; 408 LPWSTR sczLastSourceFolder = NULL;
409 LPWSTR sczLayoutPath = NULL; 409 LPWSTR* psczPath = NULL;
410 LPWSTR sczLayoutFolder = NULL; 410 BOOL fPreferSourcePathLocation = FALSE;
411 LPCWSTR rgwzSearchPaths[4] = { }; 411 BOOL fTryLastFolder = FALSE;
412 BOOL fTryRelativePath = FALSE;
413 BOOL fSourceIsAbsolute = FALSE;
412 DWORD cSearchPaths = 0; 414 DWORD cSearchPaths = 0;
413 415
414 // If the source path provided is a full path, obviously that is where we should be looking. 416 AssertSz(vfInitializedCache, "Cache wasn't initialized");
415 if (PathIsAbsolute(wzSourcePath)) 417
418 hr = GetLastUsedSourceFolder(pVariables, &sczLastSourceFolder);
419 fPreferSourcePathLocation = !vfRunningFromCache || FAILED(hr);
420 fTryLastFolder = SUCCEEDED(hr) && sczLastSourceFolder && *sczLastSourceFolder && CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, vsczSourceProcessFolder, -1, sczLastSourceFolder, -1);
421 fTryRelativePath = CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzSourcePath, -1, wzRelativePath, -1);
422 fSourceIsAbsolute = PathIsAbsolute(wzSourcePath);
423
424 // If the source path provided is a full path, try that first.
425 if (fSourceIsAbsolute)
416 { 426 {
417 rgwzSearchPaths[0] = wzSourcePath; 427 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
418 cSearchPaths = 1; 428 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
429
430 psczPath = *prgSearchPaths + cSearchPaths;
431 ++cSearchPaths;
432
433 hr = StrAllocString(psczPath, wzSourcePath, 0);
434 ExitOnFailure(hr, "Failed to copy absolute source path.");
419 } 435 }
420 else 436
437 // Try the destination path next.
438 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
439 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
440
441 psczPath = *prgSearchPaths + cSearchPaths;
442 ++cSearchPaths;
443
444 hr = StrAllocString(psczPath, wzDestinationPath, 0);
445 ExitOnFailure(hr, "Failed to copy absolute source path.");
446
447 if (!fSourceIsAbsolute)
421 { 448 {
422 // Use the destination path first. 449 // Calculate the source path location.
423 rgwzSearchPaths[0] = wzDestinationPath; 450 // In the case where we are in the bundle's package cache and
424 cSearchPaths = 1; 451 // couldn't find a last used source that will be the package cache path
425 452 // which isn't likely to have what we are looking for.
426 // If we're not running from cache or we couldn't get the last source, use 453 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
427 // the source path location. In the case where we are in the bundle's 454 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
428 // package cache and couldn't find a last used source we unfortunately will 455
429 // be picking the package cache path which isn't likely to have what we are 456 hr = PathConcat(vsczSourceProcessFolder, wzSourcePath, &sczCurrentPath);
430 // looking for. 457 ExitOnFailure(hr, "Failed to combine source process folder with source.");
431 hr = GetLastUsedSourceFolder(pVariables, &sczLastSourceFolder); 458
432 if (!vfRunningFromCache || FAILED(hr)) 459 // If we're not running from cache or we couldn't get the last source,
460 // try the source path location next.
461 if (fPreferSourcePathLocation)
433 { 462 {
434 hr = PathGetDirectory(vsczSourceProcessPath, &sczSourceProcessFolder); 463 (*prgSearchPaths)[cSearchPaths] = sczCurrentPath;
435 ExitOnFailure(hr, "Failed to get current process directory."); 464 ++cSearchPaths;
465 sczCurrentPath = NULL;
466 }
436 467
437 hr = PathConcat(sczSourceProcessFolder, wzSourcePath, &sczCurrentPath); 468 // If we have a last used source and it is not the source path location,
469 // add the last used source to the search path next.
470 if (fTryLastFolder)
471 {
472 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
473 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
474
475 psczPath = *prgSearchPaths + cSearchPaths;
476 ++cSearchPaths;
477
478 hr = PathConcat(sczLastSourceFolder, wzSourcePath, psczPath);
438 ExitOnFailure(hr, "Failed to combine last source with source."); 479 ExitOnFailure(hr, "Failed to combine last source with source.");
480 }
439 481
440 rgwzSearchPaths[cSearchPaths] = sczCurrentPath; 482 if (!fPreferSourcePathLocation)
483 {
484 (*prgSearchPaths)[cSearchPaths] = sczCurrentPath;
441 ++cSearchPaths; 485 ++cSearchPaths;
486 sczCurrentPath = NULL;
442 } 487 }
443 488
444 // If we have a last used source and it does not duplicate the existing search path, 489 // Also consider the layout directory if doing Layout.
445 // add the last used source to the search path second. 490 if (wzLayoutDirectory)
446 if (sczLastSourceFolder && *sczLastSourceFolder)
447 { 491 {
448 hr = PathConcat(sczLastSourceFolder, wzSourcePath, &sczLastSourcePath); 492 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
449 ExitOnFailure(hr, "Failed to combine last source with source."); 493 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
450 494
451 if (1 == cSearchPaths || CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, rgwzSearchPaths[1], -1, sczLastSourcePath, -1)) 495 psczPath = *prgSearchPaths + cSearchPaths;
452 { 496 ++cSearchPaths;
453 rgwzSearchPaths[cSearchPaths] = sczLastSourcePath; 497
454 ++cSearchPaths; 498 hr = PathConcat(wzLayoutDirectory, wzSourcePath, psczPath);
455 } 499 ExitOnFailure(hr, "Failed to combine layout source with source.");
456 } 500 }
501 }
457 502
458 // Also consider the layout directory if set on the command line or by the BA. 503 if (fTryRelativePath)
459 hr = VariableGetString(pVariables, BURN_BUNDLE_LAYOUT_DIRECTORY, &sczLayoutFolder); 504 {
460 if (E_NOTFOUND != hr) 505 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
506 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
507
508 hr = PathConcat(vsczSourceProcessFolder, wzRelativePath, &sczCurrentPath);
509 ExitOnFailure(hr, "Failed to combine source process folder with relative.");
510
511 if (fPreferSourcePathLocation)
461 { 512 {
462 ExitOnFailure(hr, "Failed to get bundle layout directory property."); 513 (*prgSearchPaths)[cSearchPaths] = sczCurrentPath;
514 ++cSearchPaths;
515 sczCurrentPath = NULL;
516 }
463 517
464 hr = PathConcat(sczLayoutFolder, wzSourcePath, &sczLayoutPath); 518 if (fTryLastFolder)
465 ExitOnFailure(hr, "Failed to combine layout source with source."); 519 {
520 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
521 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
466 522
467 rgwzSearchPaths[cSearchPaths] = sczLayoutPath; 523 psczPath = *prgSearchPaths + cSearchPaths;
468 ++cSearchPaths; 524 ++cSearchPaths;
525
526 hr = PathConcat(sczLastSourceFolder, wzRelativePath, psczPath);
527 ExitOnFailure(hr, "Failed to combine last source with relative.");
469 } 528 }
470 }
471 529
472 *pfFound = FALSE; // assume we won't find the file locally. 530 if (!fPreferSourcePathLocation)
531 {
532 (*prgSearchPaths)[cSearchPaths] = sczCurrentPath;
533 ++cSearchPaths;
534 sczCurrentPath = NULL;
535 }
473 536
474 for (DWORD i = 0; i < cSearchPaths; ++i) 537 if (wzLayoutDirectory)
475 {
476 // If the file exists locally, copy its path.
477 if (FileExistsEx(rgwzSearchPaths[i], NULL))
478 { 538 {
479 hr = StrAllocString(psczSourceFullPath, rgwzSearchPaths[i], 0); 539 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
480 ExitOnFailure(hr, "Failed to copy source path."); 540 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
481 541
482 *pfFound = TRUE; 542 psczPath = *prgSearchPaths + cSearchPaths;
483 break; 543 ++cSearchPaths;
484 }
485 }
486 544
487 // If nothing was found, return the first thing in our search path as the 545 hr = PathConcat(wzLayoutDirectory, wzSourcePath, psczPath);
488 // best path where we thought we should have found the file. 546 ExitOnFailure(hr, "Failed to combine layout source with relative.");
489 if (!*pfFound) 547 }
490 {
491 hr = StrAllocString(psczSourceFullPath, rgwzSearchPaths[0], 0);
492 ExitOnFailure(hr, "Failed to copy source path.");
493 } 548 }
494 549
495LExit: 550LExit:
496 ReleaseStr(sczCurrentPath); 551 ReleaseStr(sczCurrentPath);
497 ReleaseStr(sczSourceProcessFolder);
498 ReleaseStr(sczLastSourceFolder); 552 ReleaseStr(sczLastSourceFolder);
499 ReleaseStr(sczLastSourcePath); 553
500 ReleaseStr(sczLayoutFolder); 554 AssertSz(cSearchPaths <= BURN_CACHE_MAX_SEARCH_PATHS, "Got more than BURN_CACHE_MAX_SEARCH_PATHS search paths");
501 ReleaseStr(sczLayoutPath); 555 *pcSearchPaths = cSearchPaths;
502 556
503 return hr; 557 return hr;
504} 558}
@@ -1079,7 +1133,7 @@ extern "C" void CacheUninitialize()
1079 ReleaseNullStr(vsczDefaultMachinePackageCache); 1133 ReleaseNullStr(vsczDefaultMachinePackageCache);
1080 ReleaseNullStr(vsczDefaultUserPackageCache); 1134 ReleaseNullStr(vsczDefaultUserPackageCache);
1081 ReleaseNullStr(vsczWorkingFolder); 1135 ReleaseNullStr(vsczWorkingFolder);
1082 ReleaseNullStr(vsczSourceProcessPath); 1136 ReleaseNullStr(vsczSourceProcessFolder);
1083 1137
1084 vfRunningFromCache = FALSE; 1138 vfRunningFromCache = FALSE;
1085 vfInitializedCache = FALSE; 1139 vfInitializedCache = FALSE;
@@ -1224,17 +1278,12 @@ static HRESULT GetLastUsedSourceFolder(
1224 ) 1278 )
1225{ 1279{
1226 HRESULT hr = S_OK; 1280 HRESULT hr = S_OK;
1227 LPWSTR sczOriginalSource = NULL;
1228 1281
1229 hr = VariableGetString(pVariables, BURN_BUNDLE_LAST_USED_SOURCE, psczLastSource); 1282 hr = VariableGetString(pVariables, BURN_BUNDLE_LAST_USED_SOURCE, psczLastSource);
1230 if (E_NOTFOUND == hr) 1283 if (E_NOTFOUND == hr)
1231 { 1284 {
1232 // Try the original source folder. 1285 // Try the original source folder.
1233 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, &sczOriginalSource); 1286 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, psczLastSource);
1234 if (SUCCEEDED(hr))
1235 {
1236 hr = PathGetDirectory(sczOriginalSource, psczLastSource);
1237 }
1238 } 1287 }
1239 1288
1240 return hr; 1289 return hr;