@joebigelow / wix-1 / commits / 61a8d39f

Allow setting source from OnCacheAcquireResolving.

Sean Hall committed Apr 19, 2021 at 17:11 UTC 61a8d39f689222faa677e4bd79475cd77795c57a
6 files changed +92 -43
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+16 -2
@@ -64,6 +64,20 @@ enum BOOTSTRAPPER_CACHE_OPERATION
64 BOOTSTRAPPER_CACHE_OPERATION_EXTRACT,
65 };
66
67 +enum BOOTSTRAPPER_CACHE_RESOLVE_OPERATION
68 +{
69 + // There is no source available.
70 + BOOTSTRAPPER_CACHE_RESOLVE_NONE,
71 + // Copy the payload or container from the chosen local source.
72 + BOOTSTRAPPER_CACHE_RESOLVE_LOCAL,
73 + // Download the payload or container from the download URL.
74 + BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD,
75 + // Extract the payload from the container.
76 + BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER,
77 + // Look again for the payload or container locally.
78 + BOOTSTRAPPER_CACHE_RESOLVE_RETRY,
79 +};
80 +
81 enum BOOTSTRAPPER_CACHE_VERIFY_STEP
82 {
83 BOOTSTRAPPER_CACHE_VERIFY_STEP_STAGE,
@@ -379,14 +393,14 @@ struct BA_ONCACHEACQUIRERESOLVING_ARGS
393 DWORD dwRecommendedSearchPath;
394 LPCWSTR wzDownloadUrl;
395 LPCWSTR wzPayloadContainerId;
382 - BOOTSTRAPPER_CACHE_OPERATION recommendation;
396 + BOOTSTRAPPER_CACHE_RESOLVE_OPERATION recommendation;
397 };
398
399 struct BA_ONCACHEACQUIRERESOLVING_RESULTS
400 {
401 DWORD cbSize;
402 DWORD dwChosenSearchPath;
389 - BOOTSTRAPPER_CACHE_OPERATION action;
403 + BOOTSTRAPPER_CACHE_RESOLVE_OPERATION action;
404 BOOL fCancel;
405 };
406
src/engine/apply.cpp
+53 -29
@@ -1390,6 +1390,7 @@ static HRESULT AcquireContainerOrPayload(
1390 LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath;
1391 DWORD dwChosenSearchPath = 0;
1392 BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE;
1393 + BOOTSTRAPPER_CACHE_RESOLVE_OPERATION resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_NONE;
1394 LPWSTR* pwzDownloadUrl = pContainer ? &pContainer->downloadSource.sczUrl : &pPayload->downloadSource.sczUrl;
1395 LPWSTR* pwzSourcePath = pContainer ? &pContainer->sczSourcePath : &pPayload->sczSourcePath;
1396 BOOL fFoundLocal = FALSE;
@@ -1405,47 +1406,70 @@ static HRESULT AcquireContainerOrPayload(
1406 if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD != cacheOperation &&
1407 BOOTSTRAPPER_CACHE_OPERATION_EXTRACT != cacheOperation)
1408 {
1408 - hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths);
1409 - ExitOnFailure(hr, "Failed to search local source.");
1410 -
1411 - for (DWORD i = 0; i < pContext->cSearchPaths; ++i)
1409 + do
1410 {
1413 - // If the file exists locally, choose it.
1414 - if (FileExistsEx(pContext->rgSearchPaths[i], NULL))
1415 - {
1416 - dwChosenSearchPath = i;
1411 + fFoundLocal = FALSE;
1412 + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_NONE;
1413 + dwChosenSearchPath = 0;
1414
1418 - fFoundLocal = TRUE;
1419 - break;
1420 - }
1421 - }
1415 + hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths, &dwChosenSearchPath);
1416 + ExitOnFailure(hr, "Failed to search local source.");
1417
1423 - if (BOOTSTRAPPER_CACHE_OPERATION_COPY == cacheOperation)
1424 - {
1425 - if (!fFoundLocal)
1418 + for (DWORD i = 0; i < pContext->cSearchPaths; ++i)
1419 {
1427 - cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE;
1420 + // If the file exists locally, choose it.
1421 + if (FileExistsEx(pContext->rgSearchPaths[i], NULL))
1422 + {
1423 + dwChosenSearchPath = i;
1424 +
1425 + fFoundLocal = TRUE;
1426 + break;
1427 + }
1428 }
1429 - }
1430 - else
1431 - {
1432 - if (fFoundLocal) // the file exists locally, so copy it.
1429 +
1430 + if (BOOTSTRAPPER_CACHE_OPERATION_COPY == cacheOperation)
1431 {
1434 - cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_COPY;
1432 + if (fFoundLocal)
1433 + {
1434 + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_LOCAL;
1435 + }
1436 }
1436 - else if (wzPayloadContainerId)
1437 + else
1438 {
1438 - cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_EXTRACT;
1439 + if (fFoundLocal) // the file exists locally, so copy it.
1440 + {
1441 + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_LOCAL;
1442 + }
1443 + else if (wzPayloadContainerId)
1444 + {
1445 + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER;
1446 + }
1447 + else if (*pwzDownloadUrl && **pwzDownloadUrl)
1448 + {
1449 + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD;
1450 + }
1451 }
1440 - else if (*pwzDownloadUrl && **pwzDownloadUrl)
1452 +
1453 + // Let the BA have a chance to override the source.
1454 + hr = UserExperienceOnCacheAcquireResolving(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pContext->rgSearchPaths, pContext->cSearchPaths, fFoundLocal, &dwChosenSearchPath, pwzDownloadUrl, wzPayloadContainerId, &resolveOperation);
1455 + ExitOnRootFailure(hr, "BA aborted cache acquire resolving.");
1456 +
1457 + switch (resolveOperation)
1458 {
1459 + case BOOTSTRAPPER_CACHE_RESOLVE_LOCAL:
1460 + cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_COPY;
1461 + break;
1462 + case BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD:
1463 cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD;
1464 + break;
1465 + case BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER:
1466 + cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_EXTRACT;
1467 + break;
1468 + case BOOTSTRAPPER_CACHE_RESOLVE_RETRY:
1469 + pContext->cSearchPathsMax = max(pContext->cSearchPaths, pContext->cSearchPathsMax);
1470 + break;
1471 }
1444 - }
1445 -
1446 - // Let the BA have a chance to override the action, but their chance to change the source is during begin or complete.
1447 - hr = UserExperienceOnCacheAcquireResolving(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pContext->rgSearchPaths, pContext->cSearchPaths, fFoundLocal, &dwChosenSearchPath, *pwzDownloadUrl, wzPayloadContainerId, &cacheOperation);
1448 - ExitOnRootFailure(hr, "BA aborted cache acquire resolving.");
1472 + } while (BOOTSTRAPPER_CACHE_RESOLVE_RETRY == resolveOperation);
1473 }
1474
1475 switch (cacheOperation)
src/engine/cache.cpp
+10 -1
@@ -440,7 +440,8 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
440 __in_z_opt LPCWSTR wzLayoutDirectory,
441 __in BURN_VARIABLES* pVariables,
442 __inout LPWSTR** prgSearchPaths,
443 - __out DWORD* pcSearchPaths
443 + __out DWORD* pcSearchPaths,
444 + __out DWORD* pdwLikelySearchPath
445 )
446 {
447 HRESULT hr = S_OK;
@@ -452,6 +453,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
453 BOOL fTryRelativePath = FALSE;
454 BOOL fSourceIsAbsolute = FALSE;
455 DWORD cSearchPaths = 0;
456 + DWORD dwLikelySearchPath = 0;
457
458 AssertSz(vfInitializedCache, "Cache wasn't initialized");
459
@@ -473,6 +475,12 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
475 hr = StrAllocString(psczPath, wzSourcePath, 0);
476 ExitOnFailure(hr, "Failed to copy absolute source path.");
477 }
478 + else
479 + {
480 + // If none of the paths exist, then most BAs will want to prompt the user with a possible path.
481 + // The destination path is a temporary location and so not really a possible path.
482 + dwLikelySearchPath = 1;
483 + }
484
485 // Try the destination path next.
486 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
@@ -593,6 +601,7 @@ LExit:
601
602 AssertSz(cSearchPaths <= BURN_CACHE_MAX_SEARCH_PATHS, "Got more than BURN_CACHE_MAX_SEARCH_PATHS search paths");
603 *pcSearchPaths = cSearchPaths;
604 + *pdwLikelySearchPath = dwLikelySearchPath;
605
606 return hr;
607 }
src/engine/cache.h
+2 -1
@@ -101,7 +101,8 @@ HRESULT CacheGetLocalSourcePaths(
101 __in_z_opt LPCWSTR wzLayoutDirectory,
102 __in BURN_VARIABLES* pVariables,
103 __inout LPWSTR** prgSearchPaths,
104 - __out DWORD* pcSearchPaths
104 + __out DWORD* pcSearchPaths,
105 + __out DWORD* pdwLikelySearchPath
106 );
107 HRESULT CacheSetLastUsedSource(
108 __in BURN_VARIABLES* pVariables,
src/engine/userexperience.cpp
+9 -8
@@ -515,9 +515,9 @@ EXTERN_C BAAPI UserExperienceOnCacheAcquireResolving(
515 __in DWORD cSearchPaths,
516 __in BOOL fFoundLocal,
517 __in DWORD* pdwChosenSearchPath,
518 - __in_z_opt LPCWSTR wzDownloadUrl,
518 + __in_z_opt LPWSTR* pwzDownloadUrl,
519 __in_z_opt LPCWSTR wzPayloadContainerId,
520 - __inout BOOTSTRAPPER_CACHE_OPERATION* pCacheOperation
520 + __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pCacheOperation
521 )
522 {
523 HRESULT hr = S_OK;
@@ -531,14 +531,14 @@ EXTERN_C BAAPI UserExperienceOnCacheAcquireResolving(
531 args.cSearchPaths = cSearchPaths;
532 args.fFoundLocal = fFoundLocal;
533 args.dwRecommendedSearchPath = *pdwChosenSearchPath;
534 - args.wzDownloadUrl = wzDownloadUrl;
534 + args.wzDownloadUrl = *pwzDownloadUrl;
535 args.recommendation = *pCacheOperation;
536
537 results.cbSize = sizeof(results);
538 results.dwChosenSearchPath = *pdwChosenSearchPath;
539 results.action = *pCacheOperation;
540
541 - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING, &args, &results);
541 + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING, &args, &results);
542 ExitOnFailure(hr, "BA OnCacheAcquireResolving failed.");
543
544 if (results.fCancel)
@@ -548,13 +548,14 @@ EXTERN_C BAAPI UserExperienceOnCacheAcquireResolving(
548 else
549 {
550 // Verify the BA requested an action that is possible.
551 - if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD == results.action && wzDownloadUrl && *wzDownloadUrl ||
552 - BOOTSTRAPPER_CACHE_OPERATION_EXTRACT == results.action && wzPayloadContainerId ||
553 - BOOTSTRAPPER_CACHE_OPERATION_NONE == results.action)
551 + if (BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD == results.action && *pwzDownloadUrl && **pwzDownloadUrl ||
552 + BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER == results.action && wzPayloadContainerId ||
553 + BOOTSTRAPPER_CACHE_RESOLVE_RETRY == results.action ||
554 + BOOTSTRAPPER_CACHE_RESOLVE_NONE == results.action)
555 {
556 *pCacheOperation = results.action;
557 }
557 - else if (BOOTSTRAPPER_CACHE_OPERATION_COPY == results.action && results.dwChosenSearchPath < cSearchPaths)
558 + else if (BOOTSTRAPPER_CACHE_RESOLVE_LOCAL == results.action && results.dwChosenSearchPath < cSearchPaths)
559 {
560 *pdwChosenSearchPath = results.dwChosenSearchPath;
561 *pCacheOperation = results.action;
src/engine/userexperience.h
+2 -2
@@ -154,9 +154,9 @@ BAAPI UserExperienceOnCacheAcquireResolving(
154 __in DWORD cSearchPaths,
155 __in BOOL fFoundLocal,
156 __in DWORD* pdwChosenSearchPath,
157 - __in_z_opt LPCWSTR wzDownloadUrl,
157 + __in_z_opt LPWSTR* pwzDownloadUrl,
158 __in_z_opt LPCWSTR wzPayloadContainerId,
159 - __inout BOOTSTRAPPER_CACHE_OPERATION* pCacheOperation
159 + __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pCacheOperation
160 );
161 BAAPI UserExperienceOnCacheBegin(
162 __in BURN_USER_EXPERIENCE* pUserExperience