From 666196071cf29d9b489e598a604ae0998c98b6de Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sun, 25 Apr 2021 21:44:40 -0500 Subject: 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 --- src/engine/apply.cpp | 45 ++++++++++++++++++++++++++++++++++++--------- src/engine/cache.cpp | 6 +++++- src/engine/cache.h | 3 ++- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index 9cba0483..b831be9c 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp @@ -1359,8 +1359,8 @@ static HRESULT ApplyAcquireContainerOrPayload( if (fRetry) { - hr = S_OK; LogErrorId(hr, pContainer ? MSG_APPLY_RETRYING_ACQUIRE_CONTAINER : MSG_APPLY_RETRYING_ACQUIRE_PAYLOAD, pContainer ? pContainer->sczId : pPayloadGroupItem->pPayload->sczKey, NULL, NULL); + hr = S_OK; } ExitOnFailure(hr, "Failed to acquire %hs: %ls", pContainer ? "container" : "payload", pContainer ? pContainer->sczId : pPayloadGroupItem->pPayload->sczKey); @@ -1389,11 +1389,13 @@ static HRESULT AcquireContainerOrPayload( LPCWSTR wzDestinationPath = pContainer ? pContainer->sczUnverifiedPath: pPayload->sczUnverifiedPath; LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath; DWORD dwChosenSearchPath = 0; + DWORD dwDestinationSearchPath = 0; BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; BOOTSTRAPPER_CACHE_RESOLVE_OPERATION resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_NONE; LPWSTR* pwzDownloadUrl = pContainer ? &pContainer->downloadSource.sczUrl : &pPayload->downloadSource.sczUrl; LPWSTR* pwzSourcePath = pContainer ? &pContainer->sczSourcePath : &pPayload->sczSourcePath; BOOL fFoundLocal = FALSE; + BOOL fPreferExtract = FALSE; pContext->cSearchPaths = 0; *pfRetry = FALSE; @@ -1409,21 +1411,42 @@ static HRESULT AcquireContainerOrPayload( do { fFoundLocal = FALSE; + fPreferExtract = FALSE; resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_NONE; dwChosenSearchPath = 0; + dwDestinationSearchPath = 0; - hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths, &dwChosenSearchPath); + hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths, &dwChosenSearchPath, &dwDestinationSearchPath); ExitOnFailure(hr, "Failed to search local source."); - for (DWORD i = 0; i < pContext->cSearchPaths; ++i) + // When a payload comes from a container, the container has the highest chance of being correct. + // But we want to avoid extracting the container multiple times. + // So only consider the destination path, which means the container was already extracted. + if (wzPayloadContainerId) { - // If the file exists locally, choose it. - if (FileExistsEx(pContext->rgSearchPaths[i], NULL)) + if (FileExistsEx(pContext->rgSearchPaths[dwDestinationSearchPath], NULL)) { - dwChosenSearchPath = i; - fFoundLocal = TRUE; - break; + dwChosenSearchPath = dwDestinationSearchPath; + } + else + { + fPreferExtract = TRUE; + } + } + + if (!fFoundLocal) + { + for (DWORD i = 0; i < pContext->cSearchPaths; ++i) + { + // If the file exists locally, choose it. + if (FileExistsEx(pContext->rgSearchPaths[i], NULL)) + { + dwChosenSearchPath = i; + + fFoundLocal = TRUE; + break; + } } } @@ -1436,7 +1459,11 @@ static HRESULT AcquireContainerOrPayload( } else { - if (fFoundLocal) // the file exists locally, so copy it. + if (fPreferExtract) // the file comes from a container which hasn't been extracted yet, so extract it. + { + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER; + } + else if (fFoundLocal) // the file exists locally, so copy it. { resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_LOCAL; } diff --git a/src/engine/cache.cpp b/src/engine/cache.cpp index 764de065..2a40010d 100644 --- a/src/engine/cache.cpp +++ b/src/engine/cache.cpp @@ -441,7 +441,8 @@ extern "C" HRESULT CacheGetLocalSourcePaths( __in BURN_VARIABLES* pVariables, __inout LPWSTR** prgSearchPaths, __out DWORD* pcSearchPaths, - __out DWORD* pdwLikelySearchPath + __out DWORD* pdwLikelySearchPath, + __out DWORD* pdwDestinationSearchPath ) { HRESULT hr = S_OK; @@ -454,6 +455,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths( BOOL fSourceIsAbsolute = FALSE; DWORD cSearchPaths = 0; DWORD dwLikelySearchPath = 0; + DWORD dwDestinationSearchPath = 0; AssertSz(vfInitializedCache, "Cache wasn't initialized"); @@ -486,6 +488,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths( hr = MemEnsureArraySize(reinterpret_cast(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS); ExitOnFailure(hr, "Failed to ensure size for search paths array."); + dwDestinationSearchPath = cSearchPaths; psczPath = *prgSearchPaths + cSearchPaths; ++cSearchPaths; @@ -602,6 +605,7 @@ LExit: AssertSz(cSearchPaths <= BURN_CACHE_MAX_SEARCH_PATHS, "Got more than BURN_CACHE_MAX_SEARCH_PATHS search paths"); *pcSearchPaths = cSearchPaths; *pdwLikelySearchPath = dwLikelySearchPath; + *pdwDestinationSearchPath = dwDestinationSearchPath; return hr; } diff --git a/src/engine/cache.h b/src/engine/cache.h index afa18e47..a2ac1696 100644 --- a/src/engine/cache.h +++ b/src/engine/cache.h @@ -102,7 +102,8 @@ HRESULT CacheGetLocalSourcePaths( __in BURN_VARIABLES* pVariables, __inout LPWSTR** prgSearchPaths, __out DWORD* pcSearchPaths, - __out DWORD* pdwLikelySearchPath + __out DWORD* pdwLikelySearchPath, + __out DWORD* pdwDestinationSearchPath ); HRESULT CacheSetLastUsedSource( __in BURN_VARIABLES* pVariables, -- cgit v1.2.3-55-g6feb