For payloads in a container, prefer the container over local paths. Still consider the destination path to avoid extracting the container for every payload.
For payloads in a container, prefer the container over local paths. Still consider the destination path to avoid extracting the container for every payload. #3640
Sean Hall committed
Apr 25, 2021 at 21:44 UTC
666196071cf29d9b489e598a604ae0998c98b6de
3 files changed
+43
-11
src/engine/apply.cpp
+36
-9
@@ -1359,8 +1359,8 @@ static HRESULT ApplyAcquireContainerOrPayload(
1359
1360
if (fRetry)
1361
{
1362
- hr = S_OK;
1362
LogErrorId(hr, pContainer ? MSG_APPLY_RETRYING_ACQUIRE_CONTAINER : MSG_APPLY_RETRYING_ACQUIRE_PAYLOAD, pContainer ? pContainer->sczId : pPayloadGroupItem->pPayload->sczKey, NULL, NULL);
1363
+ hr = S_OK;
1364
}
1365
1366
ExitOnFailure(hr, "Failed to acquire %hs: %ls", pContainer ? "container" : "payload", pContainer ? pContainer->sczId : pPayloadGroupItem->pPayload->sczKey);
@@ -1389,11 +1389,13 @@ static HRESULT AcquireContainerOrPayload(
1389
LPCWSTR wzDestinationPath = pContainer ? pContainer->sczUnverifiedPath: pPayload->sczUnverifiedPath;
1390
LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath;
1391
DWORD dwChosenSearchPath = 0;
1392
+ DWORD dwDestinationSearchPath = 0;
1393
BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE;
1394
BOOTSTRAPPER_CACHE_RESOLVE_OPERATION resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_NONE;
1395
LPWSTR* pwzDownloadUrl = pContainer ? &pContainer->downloadSource.sczUrl : &pPayload->downloadSource.sczUrl;
1396
LPWSTR* pwzSourcePath = pContainer ? &pContainer->sczSourcePath : &pPayload->sczSourcePath;
1397
BOOL fFoundLocal = FALSE;
1398
+ BOOL fPreferExtract = FALSE;
1399
1400
pContext->cSearchPaths = 0;
1401
*pfRetry = FALSE;
@@ -1409,21 +1411,42 @@ static HRESULT AcquireContainerOrPayload(
1411
do
1412
{
1413
fFoundLocal = FALSE;
1414
+ fPreferExtract = FALSE;
1415
resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_NONE;
1416
dwChosenSearchPath = 0;
1417
+ dwDestinationSearchPath = 0;
1418
1415
- hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths, &dwChosenSearchPath);
1419
+ hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths, &dwChosenSearchPath, &dwDestinationSearchPath);
1420
ExitOnFailure(hr, "Failed to search local source.");
1421
1418
- for (DWORD i = 0; i < pContext->cSearchPaths; ++i)
1422
+ // When a payload comes from a container, the container has the highest chance of being correct.
1423
+ // But we want to avoid extracting the container multiple times.
1424
+ // So only consider the destination path, which means the container was already extracted.
1425
+ if (wzPayloadContainerId)
1426
{
1420
- // If the file exists locally, choose it.
1421
- if (FileExistsEx(pContext->rgSearchPaths[i], NULL))
1427
+ if (FileExistsEx(pContext->rgSearchPaths[dwDestinationSearchPath], NULL))
1428
{
1423
- dwChosenSearchPath = i;
1424
-
1429
fFoundLocal = TRUE;
1426
- break;
1430
+ dwChosenSearchPath = dwDestinationSearchPath;
1431
+ }
1432
+ else
1433
+ {
1434
+ fPreferExtract = TRUE;
1435
+ }
1436
+ }
1437
+
1438
+ if (!fFoundLocal)
1439
+ {
1440
+ for (DWORD i = 0; i < pContext->cSearchPaths; ++i)
1441
+ {
1442
+ // If the file exists locally, choose it.
1443
+ if (FileExistsEx(pContext->rgSearchPaths[i], NULL))
1444
+ {
1445
+ dwChosenSearchPath = i;
1446
+
1447
+ fFoundLocal = TRUE;
1448
+ break;
1449
+ }
1450
}
1451
}
1452
@@ -1436,7 +1459,11 @@ static HRESULT AcquireContainerOrPayload(
1459
}
1460
else
1461
{
1439
- if (fFoundLocal) // the file exists locally, so copy it.
1462
+ if (fPreferExtract) // the file comes from a container which hasn't been extracted yet, so extract it.
1463
+ {
1464
+ resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER;
1465
+ }
1466
+ else if (fFoundLocal) // the file exists locally, so copy it.
1467
{
1468
resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_LOCAL;
1469
}
src/engine/cache.cpp
+5
-1
@@ -441,7 +441,8 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
441
__in BURN_VARIABLES* pVariables,
442
__inout LPWSTR** prgSearchPaths,
443
__out DWORD* pcSearchPaths,
444
- __out DWORD* pdwLikelySearchPath
444
+ __out DWORD* pdwLikelySearchPath,
445
+ __out DWORD* pdwDestinationSearchPath
446
)
447
{
448
HRESULT hr = S_OK;
@@ -454,6 +455,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
455
BOOL fSourceIsAbsolute = FALSE;
456
DWORD cSearchPaths = 0;
457
DWORD dwLikelySearchPath = 0;
458
+ DWORD dwDestinationSearchPath = 0;
459
460
AssertSz(vfInitializedCache, "Cache wasn't initialized");
461
@@ -486,6 +488,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
488
hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
489
ExitOnFailure(hr, "Failed to ensure size for search paths array.");
490
491
+ dwDestinationSearchPath = cSearchPaths;
492
psczPath = *prgSearchPaths + cSearchPaths;
493
++cSearchPaths;
494
@@ -602,6 +605,7 @@ LExit:
605
AssertSz(cSearchPaths <= BURN_CACHE_MAX_SEARCH_PATHS, "Got more than BURN_CACHE_MAX_SEARCH_PATHS search paths");
606
*pcSearchPaths = cSearchPaths;
607
*pdwLikelySearchPath = dwLikelySearchPath;
608
+ *pdwDestinationSearchPath = dwDestinationSearchPath;
609
610
return hr;
611
}
src/engine/cache.h
+2
-1
@@ -102,7 +102,8 @@ HRESULT CacheGetLocalSourcePaths(
102
__in BURN_VARIABLES* pVariables,
103
__inout LPWSTR** prgSearchPaths,
104
__out DWORD* pcSearchPaths,
105
- __out DWORD* pdwLikelySearchPath
105
+ __out DWORD* pdwLikelySearchPath,
106
+ __out DWORD* pdwDestinationSearchPath
107
);
108
HRESULT CacheSetLastUsedSource(
109
__in BURN_VARIABLES* pVariables,