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