From 61a8d39f689222faa677e4bd79475cd77795c57a Mon Sep 17 00:00:00 2001 From: Sean Hall <r.sean.hall@gmail.com> Date: Mon, 19 Apr 2021 17:11:46 -0500 Subject: Allow setting source from OnCacheAcquireResolving. --- .../inc/BootstrapperApplication.h | 18 ++++- src/engine/apply.cpp | 82 ++++++++++++++-------- src/engine/cache.cpp | 11 ++- src/engine/cache.h | 3 +- src/engine/userexperience.cpp | 17 ++--- src/engine/userexperience.h | 4 +- 6 files changed, 92 insertions(+), 43 deletions(-) diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h index d8994c26..603df890 100644 --- a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h +++ b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h @@ -64,6 +64,20 @@ enum BOOTSTRAPPER_CACHE_OPERATION BOOTSTRAPPER_CACHE_OPERATION_EXTRACT, }; +enum BOOTSTRAPPER_CACHE_RESOLVE_OPERATION +{ + // There is no source available. + BOOTSTRAPPER_CACHE_RESOLVE_NONE, + // Copy the payload or container from the chosen local source. + BOOTSTRAPPER_CACHE_RESOLVE_LOCAL, + // Download the payload or container from the download URL. + BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD, + // Extract the payload from the container. + BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER, + // Look again for the payload or container locally. + BOOTSTRAPPER_CACHE_RESOLVE_RETRY, +}; + enum BOOTSTRAPPER_CACHE_VERIFY_STEP { BOOTSTRAPPER_CACHE_VERIFY_STEP_STAGE, @@ -379,14 +393,14 @@ struct BA_ONCACHEACQUIRERESOLVING_ARGS DWORD dwRecommendedSearchPath; LPCWSTR wzDownloadUrl; LPCWSTR wzPayloadContainerId; - BOOTSTRAPPER_CACHE_OPERATION recommendation; + BOOTSTRAPPER_CACHE_RESOLVE_OPERATION recommendation; }; struct BA_ONCACHEACQUIRERESOLVING_RESULTS { DWORD cbSize; DWORD dwChosenSearchPath; - BOOTSTRAPPER_CACHE_OPERATION action; + BOOTSTRAPPER_CACHE_RESOLVE_OPERATION action; BOOL fCancel; }; diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index 1bc01d44..9cba0483 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp @@ -1390,6 +1390,7 @@ static HRESULT AcquireContainerOrPayload( LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath; DWORD dwChosenSearchPath = 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; @@ -1405,47 +1406,70 @@ static HRESULT AcquireContainerOrPayload( if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD != cacheOperation && BOOTSTRAPPER_CACHE_OPERATION_EXTRACT != cacheOperation) { - hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths); - ExitOnFailure(hr, "Failed to search local source."); - - for (DWORD i = 0; i < pContext->cSearchPaths; ++i) + do { - // If the file exists locally, choose it. - if (FileExistsEx(pContext->rgSearchPaths[i], NULL)) - { - dwChosenSearchPath = i; + fFoundLocal = FALSE; + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_NONE; + dwChosenSearchPath = 0; - fFoundLocal = TRUE; - break; - } - } + hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths, &dwChosenSearchPath); + ExitOnFailure(hr, "Failed to search local source."); - if (BOOTSTRAPPER_CACHE_OPERATION_COPY == cacheOperation) - { - if (!fFoundLocal) + for (DWORD i = 0; i < pContext->cSearchPaths; ++i) { - cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; + // If the file exists locally, choose it. + if (FileExistsEx(pContext->rgSearchPaths[i], NULL)) + { + dwChosenSearchPath = i; + + fFoundLocal = TRUE; + break; + } } - } - else - { - if (fFoundLocal) // the file exists locally, so copy it. + + if (BOOTSTRAPPER_CACHE_OPERATION_COPY == cacheOperation) { - cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_COPY; + if (fFoundLocal) + { + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_LOCAL; + } } - else if (wzPayloadContainerId) + else { - cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_EXTRACT; + if (fFoundLocal) // the file exists locally, so copy it. + { + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_LOCAL; + } + else if (wzPayloadContainerId) + { + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER; + } + else if (*pwzDownloadUrl && **pwzDownloadUrl) + { + resolveOperation = BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD; + } } - else if (*pwzDownloadUrl && **pwzDownloadUrl) + + // Let the BA have a chance to override the source. + hr = UserExperienceOnCacheAcquireResolving(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pContext->rgSearchPaths, pContext->cSearchPaths, fFoundLocal, &dwChosenSearchPath, pwzDownloadUrl, wzPayloadContainerId, &resolveOperation); + ExitOnRootFailure(hr, "BA aborted cache acquire resolving."); + + switch (resolveOperation) { + case BOOTSTRAPPER_CACHE_RESOLVE_LOCAL: + cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_COPY; + break; + case BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD: cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD; + break; + case BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER: + cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_EXTRACT; + break; + case BOOTSTRAPPER_CACHE_RESOLVE_RETRY: + pContext->cSearchPathsMax = max(pContext->cSearchPaths, pContext->cSearchPathsMax); + break; } - } - - // Let the BA have a chance to override the action, but their chance to change the source is during begin or complete. - hr = UserExperienceOnCacheAcquireResolving(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pContext->rgSearchPaths, pContext->cSearchPaths, fFoundLocal, &dwChosenSearchPath, *pwzDownloadUrl, wzPayloadContainerId, &cacheOperation); - ExitOnRootFailure(hr, "BA aborted cache acquire resolving."); + } while (BOOTSTRAPPER_CACHE_RESOLVE_RETRY == resolveOperation); } switch (cacheOperation) diff --git a/src/engine/cache.cpp b/src/engine/cache.cpp index 16f2c1e5..764de065 100644 --- a/src/engine/cache.cpp +++ b/src/engine/cache.cpp @@ -440,7 +440,8 @@ extern "C" HRESULT CacheGetLocalSourcePaths( __in_z_opt LPCWSTR wzLayoutDirectory, __in BURN_VARIABLES* pVariables, __inout LPWSTR** prgSearchPaths, - __out DWORD* pcSearchPaths + __out DWORD* pcSearchPaths, + __out DWORD* pdwLikelySearchPath ) { HRESULT hr = S_OK; @@ -452,6 +453,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths( BOOL fTryRelativePath = FALSE; BOOL fSourceIsAbsolute = FALSE; DWORD cSearchPaths = 0; + DWORD dwLikelySearchPath = 0; AssertSz(vfInitializedCache, "Cache wasn't initialized"); @@ -473,6 +475,12 @@ extern "C" HRESULT CacheGetLocalSourcePaths( hr = StrAllocString(psczPath, wzSourcePath, 0); ExitOnFailure(hr, "Failed to copy absolute source path."); } + else + { + // If none of the paths exist, then most BAs will want to prompt the user with a possible path. + // The destination path is a temporary location and so not really a possible path. + dwLikelySearchPath = 1; + } // Try the destination path next. hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS); @@ -593,6 +601,7 @@ LExit: AssertSz(cSearchPaths <= BURN_CACHE_MAX_SEARCH_PATHS, "Got more than BURN_CACHE_MAX_SEARCH_PATHS search paths"); *pcSearchPaths = cSearchPaths; + *pdwLikelySearchPath = dwLikelySearchPath; return hr; } diff --git a/src/engine/cache.h b/src/engine/cache.h index cd964649..afa18e47 100644 --- a/src/engine/cache.h +++ b/src/engine/cache.h @@ -101,7 +101,8 @@ HRESULT CacheGetLocalSourcePaths( __in_z_opt LPCWSTR wzLayoutDirectory, __in BURN_VARIABLES* pVariables, __inout LPWSTR** prgSearchPaths, - __out DWORD* pcSearchPaths + __out DWORD* pcSearchPaths, + __out DWORD* pdwLikelySearchPath ); HRESULT CacheSetLastUsedSource( __in BURN_VARIABLES* pVariables, diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp index 8c6f29f3..7e68d664 100644 --- a/src/engine/userexperience.cpp +++ b/src/engine/userexperience.cpp @@ -515,9 +515,9 @@ EXTERN_C BAAPI UserExperienceOnCacheAcquireResolving( __in DWORD cSearchPaths, __in BOOL fFoundLocal, __in DWORD* pdwChosenSearchPath, - __in_z_opt LPCWSTR wzDownloadUrl, + __in_z_opt LPWSTR* pwzDownloadUrl, __in_z_opt LPCWSTR wzPayloadContainerId, - __inout BOOTSTRAPPER_CACHE_OPERATION* pCacheOperation + __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pCacheOperation ) { HRESULT hr = S_OK; @@ -531,14 +531,14 @@ EXTERN_C BAAPI UserExperienceOnCacheAcquireResolving( args.cSearchPaths = cSearchPaths; args.fFoundLocal = fFoundLocal; args.dwRecommendedSearchPath = *pdwChosenSearchPath; - args.wzDownloadUrl = wzDownloadUrl; + args.wzDownloadUrl = *pwzDownloadUrl; args.recommendation = *pCacheOperation; results.cbSize = sizeof(results); results.dwChosenSearchPath = *pdwChosenSearchPath; results.action = *pCacheOperation; - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING, &args, &results); + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING, &args, &results); ExitOnFailure(hr, "BA OnCacheAcquireResolving failed."); if (results.fCancel) @@ -548,13 +548,14 @@ EXTERN_C BAAPI UserExperienceOnCacheAcquireResolving( else { // Verify the BA requested an action that is possible. - if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD == results.action && wzDownloadUrl && *wzDownloadUrl || - BOOTSTRAPPER_CACHE_OPERATION_EXTRACT == results.action && wzPayloadContainerId || - BOOTSTRAPPER_CACHE_OPERATION_NONE == results.action) + if (BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD == results.action && *pwzDownloadUrl && **pwzDownloadUrl || + BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER == results.action && wzPayloadContainerId || + BOOTSTRAPPER_CACHE_RESOLVE_RETRY == results.action || + BOOTSTRAPPER_CACHE_RESOLVE_NONE == results.action) { *pCacheOperation = results.action; } - else if (BOOTSTRAPPER_CACHE_OPERATION_COPY == results.action && results.dwChosenSearchPath < cSearchPaths) + else if (BOOTSTRAPPER_CACHE_RESOLVE_LOCAL == results.action && results.dwChosenSearchPath < cSearchPaths) { *pdwChosenSearchPath = results.dwChosenSearchPath; *pCacheOperation = results.action; diff --git a/src/engine/userexperience.h b/src/engine/userexperience.h index 58e0431e..e1041624 100644 --- a/src/engine/userexperience.h +++ b/src/engine/userexperience.h @@ -154,9 +154,9 @@ BAAPI UserExperienceOnCacheAcquireResolving( __in DWORD cSearchPaths, __in BOOL fFoundLocal, __in DWORD* pdwChosenSearchPath, - __in_z_opt LPCWSTR wzDownloadUrl, + __in_z_opt LPWSTR* pwzDownloadUrl, __in_z_opt LPCWSTR wzPayloadContainerId, - __inout BOOTSTRAPPER_CACHE_OPERATION* pCacheOperation + __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pCacheOperation ); BAAPI UserExperienceOnCacheBegin( __in BURN_USER_EXPERIENCE* pUserExperience -- cgit v1.2.3-55-g6feb