diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-04-16 10:20:41 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-04-19 23:12:55 -0500 |
commit | 5d6046bee5021052da4a666c1e2ceeb0f16af349 (patch) | |
tree | 589ddcbe270e2e4df8cffdbd26792bcee4c29e1c /src/engine/cache.cpp | |
parent | b941c2754748251520dc5032d11396c9844fad8e (diff) | |
download | wix-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.cpp | 203 |
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 | ||
12 | static BOOL vfInitializedCache = FALSE; | 12 | static BOOL vfInitializedCache = FALSE; |
13 | static BOOL vfRunningFromCache = FALSE; | 13 | static BOOL vfRunningFromCache = FALSE; |
14 | static LPWSTR vsczSourceProcessPath = NULL; | 14 | static LPWSTR vsczSourceProcessFolder = NULL; |
15 | static LPWSTR vsczWorkingFolder = NULL; | 15 | static LPWSTR vsczWorkingFolder = NULL; |
16 | static LPWSTR vsczDefaultUserPackageCache = NULL; | 16 | static LPWSTR vsczDefaultUserPackageCache = NULL; |
17 | static LPWSTR vsczDefaultMachinePackageCache = NULL; | 17 | static 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 | ||
396 | extern "C" HRESULT CacheFindLocalSource( | 396 | extern "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 | ||
495 | LExit: | 550 | LExit: |
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; |