aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-05-02 16:48:40 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-05-11 19:11:19 -0500
commit4e2054b3ee31b2b9fae3269d76e08817a36fb51f (patch)
treee8c1f89225061d1fc253b444f9c3cac50118eeb9
parent5cb01b477d85920662112d63b5a44b75c03762a9 (diff)
downloadwix-4e2054b3ee31b2b9fae3269d76e08817a36fb51f.tar.gz
wix-4e2054b3ee31b2b9fae3269d76e08817a36fb51f.tar.bz2
wix-4e2054b3ee31b2b9fae3269d76e08817a36fb51f.zip
Reset the package's cache folder only once.
This behavior makes it work similar to the root package cache folder and avoids performance problems when there are many payloads in the package. #4774
-rw-r--r--src/burn/engine/apply.cpp15
-rw-r--r--src/burn/engine/cache.cpp58
-rw-r--r--src/burn/engine/cache.h3
-rw-r--r--src/burn/engine/elevation.cpp82
-rw-r--r--src/burn/engine/elevation.h4
-rw-r--r--src/burn/engine/engine.mc7
6 files changed, 145 insertions, 24 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp
index 58d41b28..f0b78e81 100644
--- a/src/burn/engine/apply.cpp
+++ b/src/burn/engine/apply.cpp
@@ -549,12 +549,19 @@ extern "C" HRESULT ApplyCache(
549 case BURN_CACHE_ACTION_TYPE_PACKAGE: 549 case BURN_CACHE_ACTION_TYPE_PACKAGE:
550 pPackage = pCacheAction->package.pPackage; 550 pPackage = pCacheAction->package.pPackage;
551 551
552 if (!pPackage->fPerMachine && !cacheContext.wzLayoutDirectory) 552 if (!cacheContext.wzLayoutDirectory)
553 { 553 {
554 hr = CacheGetCompletedPath(FALSE, pPackage->sczCacheId, &pPackage->sczCacheFolder); 554 if (!pPackage->fPerMachine || INVALID_HANDLE_VALUE == cacheContext.hPipe)
555 ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId); 555 {
556 hr = CachePreparePackage(pPackage);
556 557
557 cacheContext.hPipe = INVALID_HANDLE_VALUE; 558 cacheContext.hPipe = INVALID_HANDLE_VALUE;
559 }
560 else
561 {
562 hr = ElevationCachePreparePackage(hPipe, pPackage);
563 }
564 LogExitOnFailure(hr, MSG_CACHE_PREPARE_PACKAGE_FAILED, "Cache prepare package failed: %ls", pPackage->sczId, NULL, NULL);
558 } 565 }
559 566
560 hr = ApplyCachePackage(&cacheContext, pPackage); 567 hr = ApplyCachePackage(&cacheContext, pPackage);
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp
index d1999a0d..02cad4a5 100644
--- a/src/burn/engine/cache.cpp
+++ b/src/burn/engine/cache.cpp
@@ -29,7 +29,8 @@ static HRESULT SecurePerMachineCacheRoot();
29static HRESULT CreateCompletedPath( 29static HRESULT CreateCompletedPath(
30 __in BOOL fPerMachine, 30 __in BOOL fPerMachine,
31 __in LPCWSTR wzCacheId, 31 __in LPCWSTR wzCacheId,
32 __out_z LPWSTR* psczCacheDirectory 32 __in LPCWSTR wzFilePath,
33 __out_z LPWSTR* psczCachePath
33 ); 34 );
34static HRESULT CreateUnverifiedPath( 35static HRESULT CreateUnverifiedPath(
35 __in BOOL fPerMachine, 36 __in BOOL fPerMachine,
@@ -750,6 +751,20 @@ extern "C" BOOL CacheBundleRunningFromCache()
750 return vfRunningFromCache; 751 return vfRunningFromCache;
751} 752}
752 753
754HRESULT CachePreparePackage(
755 __in BURN_PACKAGE* pPackage
756 )
757{
758 HRESULT hr = S_OK;
759
760 if (!pPackage->sczCacheFolder)
761 {
762 hr = CreateCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, NULL, &pPackage->sczCacheFolder);
763 }
764
765 return hr;
766}
767
753extern "C" HRESULT CacheBundleToCleanRoom( 768extern "C" HRESULT CacheBundleToCleanRoom(
754 __in BURN_SECTION* pSection, 769 __in BURN_SECTION* pSection,
755 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath 770 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath
@@ -852,7 +867,7 @@ extern "C" HRESULT CacheCompleteBundle(
852 LPWSTR sczSourceDirectory = NULL; 867 LPWSTR sczSourceDirectory = NULL;
853 LPWSTR sczPayloadSourcePath = NULL; 868 LPWSTR sczPayloadSourcePath = NULL;
854 869
855 hr = CreateCompletedPath(fPerMachine, wzBundleId, &sczTargetDirectory); 870 hr = CreateCompletedPath(fPerMachine, wzBundleId, NULL, &sczTargetDirectory);
856 ExitOnFailure(hr, "Failed to create completed cache path for bundle."); 871 ExitOnFailure(hr, "Failed to create completed cache path for bundle.");
857 872
858 hr = PathConcat(sczTargetDirectory, wzExecutableName, &sczTargetPath); 873 hr = PathConcat(sczTargetDirectory, wzExecutableName, &sczTargetPath);
@@ -957,16 +972,12 @@ extern "C" HRESULT CacheCompletePayload(
957 ) 972 )
958{ 973{
959 HRESULT hr = S_OK; 974 HRESULT hr = S_OK;
960 LPWSTR sczCachedDirectory = NULL;
961 LPWSTR sczCachedPath = NULL; 975 LPWSTR sczCachedPath = NULL;
962 LPWSTR sczUnverifiedPayloadPath = NULL; 976 LPWSTR sczUnverifiedPayloadPath = NULL;
963 977
964 hr = CreateCompletedPath(fPerMachine, wzCacheId, &sczCachedDirectory); 978 hr = CreateCompletedPath(fPerMachine, wzCacheId, pPayload->sczFilePath, &sczCachedPath);
965 ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", wzCacheId); 979 ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", wzCacheId);
966 980
967 hr = PathConcat(sczCachedDirectory, pPayload->sczFilePath, &sczCachedPath);
968 ExitOnFailure(hr, "Failed to concat complete cached path.");
969
970 // If the cached file matches what we expected, we're good. 981 // If the cached file matches what we expected, we're good.
971 hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY, pfnCacheMessageHandler, pfnProgress, pContext); 982 hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY, pfnCacheMessageHandler, pfnProgress, pContext);
972 if (SUCCEEDED(hr)) 983 if (SUCCEEDED(hr))
@@ -1016,7 +1027,6 @@ extern "C" HRESULT CacheCompletePayload(
1016LExit: 1027LExit:
1017 ReleaseStr(sczUnverifiedPayloadPath); 1028 ReleaseStr(sczUnverifiedPayloadPath);
1018 ReleaseStr(sczCachedPath); 1029 ReleaseStr(sczCachedPath);
1019 ReleaseStr(sczCachedDirectory);
1020 1030
1021 return hr; 1031 return hr;
1022} 1032}
@@ -1403,11 +1413,13 @@ LExit:
1403static HRESULT CreateCompletedPath( 1413static HRESULT CreateCompletedPath(
1404 __in BOOL fPerMachine, 1414 __in BOOL fPerMachine,
1405 __in LPCWSTR wzId, 1415 __in LPCWSTR wzId,
1406 __out_z LPWSTR* psczCacheDirectory 1416 __in LPCWSTR wzFilePath,
1417 __out_z LPWSTR* psczCachePath
1407 ) 1418 )
1408{ 1419{
1409 HRESULT hr = S_OK; 1420 HRESULT hr = S_OK;
1410 LPWSTR sczCacheDirectory = NULL; 1421 LPWSTR sczCacheDirectory = NULL;
1422 LPWSTR sczCacheFile = NULL;
1411 1423
1412 if (fPerMachine) 1424 if (fPerMachine)
1413 { 1425 {
@@ -1415,22 +1427,38 @@ static HRESULT CreateCompletedPath(
1415 ExitOnFailure(hr, "Failed to secure per-machine cache root."); 1427 ExitOnFailure(hr, "Failed to secure per-machine cache root.");
1416 } 1428 }
1417 1429
1418 // Get the cache completed path, ensure it exists, and reset any permissions people 1430 // Get the cache completed path.
1419 // might have tried to set on the directory so we inherit the (correct!) security
1420 // permissions from the parent directory.
1421 hr = CacheGetCompletedPath(fPerMachine, wzId, &sczCacheDirectory); 1431 hr = CacheGetCompletedPath(fPerMachine, wzId, &sczCacheDirectory);
1422 ExitOnFailure(hr, "Failed to get cache directory."); 1432 ExitOnFailure(hr, "Failed to get cache directory.");
1423 1433
1434 // Ensure it exists.
1424 hr = DirEnsureExists(sczCacheDirectory, NULL); 1435 hr = DirEnsureExists(sczCacheDirectory, NULL);
1425 ExitOnFailure(hr, "Failed to create cache directory: %ls", sczCacheDirectory); 1436 ExitOnFailure(hr, "Failed to create cache directory: %ls", sczCacheDirectory);
1426 1437
1427 ResetPathPermissions(fPerMachine, sczCacheDirectory); 1438 if (!wzFilePath)
1439 {
1440 // Reset any permissions people might have tried to set on the directory
1441 // so we inherit the (correct!) security permissions from the parent directory.
1442 ResetPathPermissions(fPerMachine, sczCacheDirectory);
1428 1443
1429 *psczCacheDirectory = sczCacheDirectory; 1444 *psczCachePath = sczCacheDirectory;
1430 sczCacheDirectory = NULL; 1445 sczCacheDirectory = NULL;
1446 }
1447 else
1448 {
1449 // Get the cache completed file path.
1450 hr = PathConcat(sczCacheDirectory, wzFilePath, &sczCacheFile);
1451 ExitOnFailure(hr, "Failed to construct cache file.");
1452
1453 // Don't reset permissions here. The payload's package must reset its cache folder when it starts caching.
1454
1455 *psczCachePath = sczCacheFile;
1456 sczCacheFile = NULL;
1457 }
1431 1458
1432LExit: 1459LExit:
1433 ReleaseStr(sczCacheDirectory); 1460 ReleaseStr(sczCacheDirectory);
1461 ReleaseStr(sczCacheFile);
1434 return hr; 1462 return hr;
1435} 1463}
1436 1464
diff --git a/src/burn/engine/cache.h b/src/burn/engine/cache.h
index a300e99d..dfb4f69f 100644
--- a/src/burn/engine/cache.h
+++ b/src/burn/engine/cache.h
@@ -122,6 +122,9 @@ void CacheSendErrorCallback(
122 __out_opt BOOL* pfRetry 122 __out_opt BOOL* pfRetry
123 ); 123 );
124BOOL CacheBundleRunningFromCache(); 124BOOL CacheBundleRunningFromCache();
125HRESULT CachePreparePackage(
126 __in BURN_PACKAGE* pPackage
127 );
125HRESULT CacheBundleToCleanRoom( 128HRESULT CacheBundleToCleanRoom(
126 __in BURN_SECTION* pSection, 129 __in BURN_SECTION* pSection,
127 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath 130 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp
index 9d1b8fc7..85e4b692 100644
--- a/src/burn/engine/elevation.cpp
+++ b/src/burn/engine/elevation.cpp
@@ -14,6 +14,7 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
14 BURN_ELEVATION_MESSAGE_TYPE_SESSION_RESUME, 14 BURN_ELEVATION_MESSAGE_TYPE_SESSION_RESUME,
15 BURN_ELEVATION_MESSAGE_TYPE_SESSION_END, 15 BURN_ELEVATION_MESSAGE_TYPE_SESSION_END,
16 BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE, 16 BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE,
17 BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE,
17 BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD, 18 BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD,
18 BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, 19 BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD,
19 BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP, 20 BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP,
@@ -186,6 +187,11 @@ static HRESULT OnSaveState(
186 __in BYTE* pbData, 187 __in BYTE* pbData,
187 __in SIZE_T cbData 188 __in SIZE_T cbData
188 ); 189 );
190static HRESULT OnCachePreparePackage(
191 __in BURN_PACKAGES* pPackages,
192 __in BYTE* pbData,
193 __in SIZE_T cbData
194 );
189static HRESULT OnCacheCompletePayload( 195static HRESULT OnCacheCompletePayload(
190 __in HANDLE hPipe, 196 __in HANDLE hPipe,
191 __in BURN_PACKAGES* pPackages, 197 __in BURN_PACKAGES* pPackages,
@@ -612,6 +618,32 @@ LExit:
612 return hr; 618 return hr;
613} 619}
614 620
621extern "C" HRESULT ElevationCachePreparePackage(
622 __in HANDLE hPipe,
623 __in BURN_PACKAGE* pPackage
624 )
625{
626 HRESULT hr = S_OK;
627 BYTE* pbData = NULL;
628 SIZE_T cbData = 0;
629 DWORD dwResult = 0;
630
631 // Serialize message data.
632 hr = BuffWriteString(&pbData, &cbData, pPackage ? pPackage->sczId : NULL);
633 ExitOnFailure(hr, "Failed to write package id to message buffer.");
634
635 // Send message.
636 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE, pbData, cbData, NULL, NULL, &dwResult);
637 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE message to per-machine process.");
638
639 hr = (HRESULT)dwResult;
640
641LExit:
642 ReleaseBuffer(pbData);
643
644 return hr;
645}
646
615/******************************************************************* 647/*******************************************************************
616 ElevationCacheCompletePayload - 648 ElevationCacheCompletePayload -
617 649
@@ -1856,6 +1888,10 @@ static HRESULT ProcessElevatedChildCacheMessage(
1856 1888
1857 switch (pMsg->dwMessage) 1889 switch (pMsg->dwMessage)
1858 { 1890 {
1891 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE:
1892 hrResult = OnCachePreparePackage(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
1893 break;
1894
1859 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD: 1895 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD:
1860 hrResult = OnCacheCompletePayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData); 1896 hrResult = OnCacheCompletePayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
1861 break; 1897 break;
@@ -2153,6 +2189,41 @@ LExit:
2153 return hr; 2189 return hr;
2154} 2190}
2155 2191
2192static HRESULT OnCachePreparePackage(
2193 __in BURN_PACKAGES* pPackages,
2194 __in BYTE* pbData,
2195 __in SIZE_T cbData
2196 )
2197{
2198 HRESULT hr = S_OK;
2199 SIZE_T iData = 0;
2200 LPWSTR scz = NULL;
2201 BURN_PACKAGE* pPackage = NULL;
2202
2203 // Deserialize message data.
2204 hr = BuffReadString(pbData, cbData, &iData, &scz);
2205 ExitOnFailure(hr, "Failed to read package id.");
2206
2207 if (scz && *scz)
2208 {
2209 hr = PackageFindById(pPackages, scz, &pPackage);
2210 ExitOnFailure(hr, "Failed to find package: %ls", scz);
2211 }
2212 else
2213 {
2214 hr = E_INVALIDARG;
2215 ExitOnRootFailure(hr, "Invalid data passed to cache prepare package.");
2216 }
2217
2218 hr = CachePreparePackage(pPackage);
2219 ExitOnFailure(hr, "Failed to prepare cache package.");
2220
2221LExit:
2222 ReleaseStr(scz);
2223
2224 return hr;
2225}
2226
2156static HRESULT OnCacheCompletePayload( 2227static HRESULT OnCacheCompletePayload(
2157 __in HANDLE hPipe, 2228 __in HANDLE hPipe,
2158 __in BURN_PACKAGES* pPackages, 2229 __in BURN_PACKAGES* pPackages,
@@ -2225,7 +2296,6 @@ static HRESULT OnCacheVerifyPayload(
2225 LPWSTR scz = NULL; 2296 LPWSTR scz = NULL;
2226 BURN_PACKAGE* pPackage = NULL; 2297 BURN_PACKAGE* pPackage = NULL;
2227 BURN_PAYLOAD* pPayload = NULL; 2298 BURN_PAYLOAD* pPayload = NULL;
2228 LPWSTR sczCacheDirectory = NULL;
2229 2299
2230 // Deserialize message data. 2300 // Deserialize message data.
2231 hr = BuffReadString(pbData, cbData, &iData, &scz); 2301 hr = BuffReadString(pbData, cbData, &iData, &scz);
@@ -2248,10 +2318,13 @@ static HRESULT OnCacheVerifyPayload(
2248 2318
2249 if (pPackage && pPayload) 2319 if (pPackage && pPayload)
2250 { 2320 {
2251 hr = CacheGetCompletedPath(TRUE, pPackage->sczCacheId, &sczCacheDirectory); 2321 if (!pPackage->sczCacheFolder)
2252 ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId); 2322 {
2323 hr = E_INVALIDSTATE;
2324 ExitOnRootFailure(hr, "Cache verify payload called without starting its package.");
2325 }
2253 2326
2254 hr = CacheVerifyPayload(pPayload, sczCacheDirectory, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe); 2327 hr = CacheVerifyPayload(pPayload, pPackage->sczCacheFolder, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe);
2255 } 2328 }
2256 else 2329 else
2257 { 2330 {
@@ -2261,7 +2334,6 @@ static HRESULT OnCacheVerifyPayload(
2261 // Nothing should be logged on failure. 2334 // Nothing should be logged on failure.
2262 2335
2263LExit: 2336LExit:
2264 ReleaseStr(sczCacheDirectory);
2265 ReleaseStr(scz); 2337 ReleaseStr(scz);
2266 2338
2267 return hr; 2339 return hr;
diff --git a/src/burn/engine/elevation.h b/src/burn/engine/elevation.h
index 9244f36c..af2dec8b 100644
--- a/src/burn/engine/elevation.h
+++ b/src/burn/engine/elevation.h
@@ -50,6 +50,10 @@ HRESULT ElevationSaveState(
50 __in_bcount(cbBuffer) BYTE* pbBuffer, 50 __in_bcount(cbBuffer) BYTE* pbBuffer,
51 __in SIZE_T cbBuffer 51 __in SIZE_T cbBuffer
52 ); 52 );
53HRESULT ElevationCachePreparePackage(
54 __in HANDLE hPipe,
55 __in BURN_PACKAGE* pPackage
56 );
53HRESULT ElevationCacheCompletePayload( 57HRESULT ElevationCacheCompletePayload(
54 __in HANDLE hPipe, 58 __in HANDLE hPipe,
55 __in BURN_PACKAGE* pPackage, 59 __in BURN_PACKAGE* pPackage,
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc
index 25d5b4e4..84046314 100644
--- a/src/burn/engine/engine.mc
+++ b/src/burn/engine/engine.mc
@@ -717,6 +717,13 @@ Language=English
717Acquiring container: %1!ls!, %3!hs! from: %4!ls! 717Acquiring container: %1!ls!, %3!hs! from: %4!ls!
718. 718.
719 719
720MessageId=337
721Severity=Error
722SymbolicName=MSG_CACHE_PREPARE_PACKAGE_FAILED
723Language=English
724Failed to prepare package: %2!ls!, error: 0x%1!ls!
725.
726
720MessageId=338 727MessageId=338
721Severity=Success 728Severity=Success
722SymbolicName=MSG_ACQUIRE_PACKAGE_PAYLOAD 729SymbolicName=MSG_ACQUIRE_PACKAGE_PAYLOAD