@joebigelow / wix / commits / 22fb11c0

Add BURN_PAYLOAD_GROUP_ITEM to be able to move payloads during caching.

Sean Hall committed Apr 16, 2021 at 10:52 UTC 22fb11c03329380fcffff253c7b2d4d1fccd23b4
12 files changed +98 -50
src/engine/apply.cpp
+44 -17
@@ -100,7 +100,7 @@ static HRESULT ApplyLayoutContainer(
100 static HRESULT ApplyProcessPayload(
101 __in BURN_CACHE_CONTEXT* pContext,
102 __in_opt BURN_PACKAGE* pPackage,
103 - __in BURN_PAYLOAD* pPayload
103 + __in BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem
104 );
105 static HRESULT ApplyCacheVerifyContainerOrPayload(
106 __in BURN_CACHE_CONTEXT* pContext,
@@ -132,8 +132,7 @@ static HRESULT LayoutOrCacheContainerOrPayload(
132 __in BURN_CACHE_CONTEXT* pContext,
133 __in_opt BURN_CONTAINER* pContainer,
134 __in_opt BURN_PACKAGE* pPackage,
135 - __in_opt BURN_PAYLOAD* pPayload,
136 - __in BOOL fMove,
135 + __in_opt BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem,
136 __in DWORD cTryAgainAttempts,
137 __out BOOL* pfRetry
138 );
@@ -805,14 +804,14 @@ static HRESULT ApplyCachePackage(
804
805 for (;;)
806 {
808 - hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cPayloads, pPackage->payloads.qwTotalSize);
807 + hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cItems, pPackage->payloads.qwTotalSize);
808 LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls: %ls", L"begin cache package", pPackage->sczId);
809
811 - for (DWORD i = 0; i < pPackage->payloads.cPayloads; ++i)
810 + for (DWORD i = 0; i < pPackage->payloads.cItems; ++i)
811 {
813 - BURN_PAYLOAD* pPayload = pPackage->payloads.rgpPayloads[i];
812 + BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem = pPackage->payloads.rgItems + i;
813
815 - hr = ApplyProcessPayload(pContext, pPackage, pPayload);
814 + hr = ApplyProcessPayload(pContext, pPackage, pPayloadGroupItem);
815 if (FAILED(hr))
816 {
817 break;
@@ -831,6 +830,16 @@ static HRESULT ApplyCachePackage(
830 if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_RETRY == cachePackageCompleteAction)
831 {
832 // TODO: the progress needs to account for the payloads (potentially) being recached.
833 + for (DWORD i = 0; i < pPackage->payloads.cItems; ++i)
834 + {
835 + BURN_PAYLOAD_GROUP_ITEM* pItem = pPackage->payloads.rgItems + i;
836 + if (pItem->fCached)
837 + {
838 + pItem->pPayload->cRemainingInstances += 1;
839 + pItem->fCached = FALSE;
840 + }
841 + }
842 +
843 LogErrorId(hr, MSG_APPLY_RETRYING_PACKAGE, pPackage->sczId, NULL, NULL);
844
845 continue;
@@ -891,12 +900,12 @@ static HRESULT ApplyLayoutBundle(
900 hr = LayoutBundle(pContext, wzExecutableName, wzUnverifiedPath, qwBundleSize);
901 ExitOnFailure(hr, "Failed to layout bundle.");
902
894 - for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
903 + for (DWORD i = 0; i < pPayloads->cItems; ++i)
904 {
896 - BURN_PAYLOAD* pPayload = pPayloads->rgpPayloads[i];
905 + BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem = pPayloads->rgItems + i;
906
898 - hr = ApplyProcessPayload(pContext, NULL, pPayload);
899 - ExitOnFailure(hr, "Failed to layout bundle payload: %ls", pPayload->sczKey);
907 + hr = ApplyProcessPayload(pContext, NULL, pPayloadGroupItem);
908 + ExitOnFailure(hr, "Failed to layout bundle payload: %ls", pPayloadGroupItem->pPayload->sczKey);
909 }
910
911 LExit:
@@ -927,7 +936,7 @@ static HRESULT ApplyLayoutContainer(
936 hr = ApplyAcquireContainerOrPayload(pContext, pContainer, NULL, NULL);
937 LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath);
938
930 - hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry);
939 + hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, cTryAgainAttempts, &fRetry);
940 if (SUCCEEDED(hr))
941 {
942 break;
@@ -957,12 +966,13 @@ LExit:
966 static HRESULT ApplyProcessPayload(
967 __in BURN_CACHE_CONTEXT* pContext,
968 __in_opt BURN_PACKAGE* pPackage,
960 - __in BURN_PAYLOAD* pPayload
969 + __in BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem
970 )
971 {
972 HRESULT hr = S_OK;
973 DWORD cTryAgainAttempts = 0;
974 BOOL fRetry = FALSE;
975 + BURN_PAYLOAD* pPayload = pPayloadGroupItem->pPayload;
976
977 Assert(pContext->pPayloads && pPackage || pContext->wzLayoutDirectory);
978
@@ -984,8 +994,7 @@ static HRESULT ApplyProcessPayload(
994 hr = ApplyAcquireContainerOrPayload(pContext, NULL, pPackage, pPayload);
995 LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_PAYLOAD, "Failed to acquire payload: %ls to working path: %ls", pPayload->sczKey, pPayload->sczUnverifiedPath);
996
987 - // TODO: set fMove to TRUE appropriately
988 - hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry);
997 + hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayloadGroupItem, cTryAgainAttempts, &fRetry);
998 if (SUCCEEDED(hr))
999 {
1000 break;
@@ -1426,18 +1435,30 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1435 __in BURN_CACHE_CONTEXT* pContext,
1436 __in_opt BURN_CONTAINER* pContainer,
1437 __in_opt BURN_PACKAGE* pPackage,
1429 - __in_opt BURN_PAYLOAD* pPayload,
1430 - __in BOOL fMove,
1438 + __in_opt BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem,
1439 __in DWORD cTryAgainAttempts,
1440 __out BOOL* pfRetry
1441 )
1442 {
1443 HRESULT hr = S_OK;
1444 + BURN_PAYLOAD* pPayload = pPayloadGroupItem ? pPayloadGroupItem->pPayload : NULL;
1445 LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : L"";
1446 LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath;
1447 LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L"";
1448 BOOL fCanAffectRegistration = FALSE;
1449 BURN_CACHE_PROGRESS_CONTEXT progress = { };
1450 + BOOL fMove = !pPayload || 1 == pPayload->cRemainingInstances;
1451 +
1452 + if (pContainer)
1453 + {
1454 + Assert(!pPayloadGroupItem);
1455 + }
1456 + else
1457 + {
1458 + Assert(pPayload);
1459 + AssertSz(0 < pPayload->cRemainingInstances, "Laying out payload more times than planned.");
1460 + AssertSz(!pPayloadGroupItem->fCached, "Laying out payload group item that was already cached.");
1461 + }
1462
1463 if (!pContext->wzLayoutDirectory)
1464 {
@@ -1501,6 +1522,12 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1522 }
1523 } while (S_FALSE == hr);
1524
1525 + if (SUCCEEDED(hr) && pPayloadGroupItem)
1526 + {
1527 + pPayload->cRemainingInstances -= 1;
1528 + pPayloadGroupItem->fCached = TRUE;
1529 + }
1530 +
1531 LExit:
1532 return hr;
1533 }
src/engine/core.cpp
+2 -2
@@ -1679,9 +1679,9 @@ static HRESULT DetectPackagePayloadsCached(
1679 if (DirExists(sczCachePath, NULL))
1680 {
1681 // Check all payloads to see if any exist.
1682 - for (DWORD i = 0; i < pPackage->payloads.cPayloads; ++i)
1682 + for (DWORD i = 0; i < pPackage->payloads.cItems; ++i)
1683 {
1684 - BURN_PAYLOAD* pPayload = pPackage->payloads.rgpPayloads[i];
1684 + BURN_PAYLOAD* pPayload = pPackage->payloads.rgItems[i].pPayload;
1685
1686 hr = PathConcat(sczCachePath, pPayload->sczFilePath, &sczPayloadCachePath);
1687 ExitOnFailure(hr, "Failed to concat payload cache path.");
src/engine/exeengine.cpp
+1 -1
@@ -373,7 +373,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
373 DWORD dwExitCode = 0;
374 GENERIC_EXECUTE_MESSAGE message = { };
375 BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage;
376 - BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0];
376 + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload;
377
378 // get cached executable path
379 hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
src/engine/msiengine.cpp
+2 -2
@@ -1100,7 +1100,7 @@ extern "C" HRESULT MsiEngineExecutePackage(
1100 LPWSTR sczProperties = NULL;
1101 LPWSTR sczObfuscatedProperties = NULL;
1102 BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage;
1103 - BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0];
1103 + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload;
1104
1105 // During rollback, if the package is already in the rollback state we expect don't
1106 // touch it again.
@@ -1981,7 +1981,7 @@ static HRESULT ConcatPatchProperty(
1981 {
1982 BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pPackage->Msi.rgSlipstreamMsps + i;
1983 BURN_PACKAGE* pMspPackage = pSlipstreamMsp->pMspPackage;
1984 - BURN_PAYLOAD* pMspPackagePayload = pMspPackage->payloads.rgpPayloads[0];
1984 + BURN_PAYLOAD* pMspPackagePayload = pMspPackage->payloads.rgItems[0].pPayload;
1985 BOOTSTRAPPER_ACTION_STATE patchExecuteAction = fRollback ? pSlipstreamMsp->rollback : pSlipstreamMsp->execute;
1986
1987 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < patchExecuteAction)
src/engine/mspengine.cpp
+1 -1
@@ -581,7 +581,7 @@ extern "C" HRESULT MspEngineExecutePackage(
581 {
582 LPCWSTR wzAppend = NULL;
583 BURN_PACKAGE* pMspPackage = pExecuteAction->mspTarget.rgOrderedPatches[i].pPackage;
584 - BURN_PAYLOAD* pMspPackagePayload = pMspPackage->payloads.rgpPayloads[0];
584 + BURN_PAYLOAD* pMspPackagePayload = pMspPackage->payloads.rgItems[0].pPayload;
585 AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Invalid package type added to ordered patches.");
586
587 if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->mspTarget.action)
src/engine/msuengine.cpp
+1 -1
@@ -265,7 +265,7 @@ extern "C" HRESULT MsuEngineExecutePackage(
265 DWORD dwExitCode = 0;
266 BOOL fUseSysNativePath = FALSE;
267 BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage;
268 - BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0];
268 + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload;
269
270 #if !defined(_WIN64)
271 hr = ProcWow64(::GetCurrentProcess(), &fUseSysNativePath);
src/engine/package.cpp
+8 -6
@@ -349,7 +349,7 @@ extern "C" void PackageUninitialize(
349 MemFree(pPackage->rgDependencyProviders);
350 }
351
352 - ReleaseMem(pPackage->payloads.rgpPayloads);
352 + ReleaseMem(pPackage->payloads.rgItems);
353
354 switch (pPackage->type)
355 {
@@ -567,14 +567,16 @@ static HRESULT ParsePayloadRefsFromXml(
567 }
568
569 // allocate memory for payload pointers
570 - pPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*) * cNodes, TRUE);
571 - ExitOnNull(pPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for package payloads.");
570 + pPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM) * cNodes, TRUE);
571 + ExitOnNull(pPackage->payloads.rgItems, hr, E_OUTOFMEMORY, "Failed to allocate memory for package payloads.");
572
573 - pPackage->payloads.cPayloads = cNodes;
573 + pPackage->payloads.cItems = cNodes;
574
575 // parse package elements
576 for (DWORD i = 0; i < cNodes; ++i)
577 {
578 + BURN_PAYLOAD_GROUP_ITEM* pPackagePayload = pPackage->payloads.rgItems + i;
579 +
580 hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
581 ExitOnFailure(hr, "Failed to get next node.");
582
@@ -583,10 +585,10 @@ static HRESULT ParsePayloadRefsFromXml(
585 ExitOnFailure(hr, "Failed to get Id attribute.");
586
587 // find payload
586 - hr = PayloadFindById(pPayloads, sczId, &pPackage->payloads.rgpPayloads[i]);
588 + hr = PayloadFindById(pPayloads, sczId, &pPackagePayload->pPayload);
589 ExitOnFailure(hr, "Failed to find payload.");
590
589 - pPackage->payloads.qwTotalSize += pPackage->payloads.rgpPayloads[i]->qwFileSize;
591 + pPackage->payloads.qwTotalSize += pPackagePayload->pPayload->qwFileSize;
592
593 // prepare next iteration
594 ReleaseNullObject(pixnNode);
src/engine/payload.cpp
+4 -4
@@ -139,11 +139,11 @@ extern "C" HRESULT PayloadsParseFromXml(
139
140 if (pPayload->fLayoutOnly && pLayoutPayloads)
141 {
142 - hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pLayoutPayloads->rgpPayloads), pLayoutPayloads->cPayloads + 1, sizeof(BURN_PAYLOAD*), 5);
143 - ExitOnNull(pPayloads->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for layout payloads.");
142 + hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pLayoutPayloads->rgItems), pLayoutPayloads->cItems + 1, sizeof(BURN_PAYLOAD_GROUP_ITEM), 5);
143 + ExitOnFailure(hr, "Failed to allocate memory for layout payloads.");
144
145 - pLayoutPayloads->rgpPayloads[pLayoutPayloads->cPayloads] = pPayload;
146 - ++pLayoutPayloads->cPayloads;
145 + pLayoutPayloads->rgItems[pLayoutPayloads->cItems].pPayload = pPayload;
146 + ++pLayoutPayloads->cItems;
147
148 pLayoutPayloads->qwTotalSize += pPayload->qwFileSize;
149 }
src/engine/payload.h
+11 -2
@@ -47,6 +47,7 @@ typedef struct _BURN_PAYLOAD
47 LPWSTR sczLocalFilePath; // location of extracted or downloaded copy
48
49 LPWSTR sczUnverifiedPath;
50 + DWORD cRemainingInstances;
51 } BURN_PAYLOAD;
52
53 typedef struct _BURN_PAYLOADS
@@ -55,10 +56,18 @@ typedef struct _BURN_PAYLOADS
56 DWORD cPayloads;
57 } BURN_PAYLOADS;
58
59 +typedef struct _BURN_PAYLOAD_GROUP_ITEM
60 +{
61 + BURN_PAYLOAD* pPayload;
62 +
63 + // mutable members
64 + BOOL fCached;
65 +} BURN_PAYLOAD_GROUP_ITEM;
66 +
67 typedef struct _BURN_PAYLOAD_GROUP
68 {
60 - BURN_PAYLOAD** rgpPayloads;
61 - DWORD cPayloads;
69 + BURN_PAYLOAD_GROUP_ITEM* rgItems;
70 + DWORD cItems;
71 DWORD64 qwTotalSize;
72 } BURN_PAYLOAD_GROUP;
73
src/engine/plan.cpp
+13 -3
@@ -1839,15 +1839,22 @@ static void ResetPlannedPayloadsState(
1839 {
1840 BURN_PAYLOAD* pPayload = pPayloads->rgPayloads + i;
1841
1842 + pPayload->cRemainingInstances = 0;
1843 pPayload->state = BURN_PAYLOAD_STATE_NONE;
1844 ReleaseNullStr(pPayload->sczLocalFilePath);
1845 }
1846 }
1847
1848 static void ResetPlannedPayloadGroupState(
1848 - __in BURN_PAYLOAD_GROUP* /*pPayloadGroup*/
1849 + __in BURN_PAYLOAD_GROUP* pPayloadGroup
1850 )
1851 {
1852 + for (DWORD i = 0; i < pPayloadGroup->cItems; ++i)
1853 + {
1854 + BURN_PAYLOAD_GROUP_ITEM* pItem = pPayloadGroup->rgItems + i;
1855 +
1856 + pItem->fCached = FALSE;
1857 + }
1858 }
1859
1860 static void ResetPlannedPackageState(
@@ -2223,9 +2230,12 @@ static HRESULT ProcessPayloadGroup(
2230 {
2231 HRESULT hr = S_OK;
2232
2226 - for (DWORD i = 0; i < pPayloadGroup->cPayloads; ++i)
2233 + for (DWORD i = 0; i < pPayloadGroup->cItems; ++i)
2234 {
2228 - BURN_PAYLOAD* pPayload = pPayloadGroup->rgpPayloads[i];
2235 + BURN_PAYLOAD_GROUP_ITEM* pItem = pPayloadGroup->rgItems + i;
2236 + BURN_PAYLOAD* pPayload = pItem->pPayload;
2237 +
2238 + pPayload->cRemainingInstances += 1;
2239
2240 if (pPayload->pContainer && !pPayload->pContainer->fPlanned)
2241 {
src/engine/pseudobundle.cpp
+9 -9
@@ -35,13 +35,13 @@ extern "C" HRESULT PseudoBundleInitialize(
35 }
36
37 // Initialize the single payload, and fill out all the necessary fields
38 - pPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*), TRUE);
39 - ExitOnNull(pPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload group inside of related bundle struct");
40 - pPackage->payloads.cPayloads = 1;
38 + pPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM), TRUE);
39 + ExitOnNull(pPackage->payloads.rgItems, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload group inside of related bundle struct");
40 + pPackage->payloads.cItems = 1;
41
42 pPayload = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD), TRUE);
43 ExitOnNull(pPayload, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct");
44 - pPackage->payloads.rgpPayloads[0] = pPayload;
44 + pPackage->payloads.rgItems[0].pPayload = pPayload;
45 pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL;
46 pPayload->qwFileSize = qwSize;
47
@@ -171,13 +171,13 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
171 LPWSTR sczArguments = NULL;
172
173 // Initialize the payloads, and copy the necessary fields.
174 - pPassthroughPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*) * pPackage->payloads.cPayloads, TRUE);
175 - ExitOnNull(pPassthroughPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of passthrough bundle.");
176 - pPassthroughPackage->payloads.cPayloads = pPackage->payloads.cPayloads;
174 + pPassthroughPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM) * pPackage->payloads.cItems, TRUE);
175 + ExitOnNull(pPassthroughPackage->payloads.rgItems, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of passthrough bundle.");
176 + pPassthroughPackage->payloads.cItems = pPackage->payloads.cItems;
177
178 - for (DWORD iPayload = 0; iPayload < pPackage->payloads.cPayloads; ++iPayload)
178 + for (DWORD iPayload = 0; iPayload < pPackage->payloads.cItems; ++iPayload)
179 {
180 - pPassthroughPackage->payloads.rgpPayloads[iPayload] = pPackage->payloads.rgpPayloads[iPayload];
180 + pPassthroughPackage->payloads.rgItems[iPayload].pPayload = pPackage->payloads.rgItems[iPayload].pPayload;
181 }
182
183 pPassthroughPackage->Exe.fPseudoBundle = TRUE;
src/engine/relatedbundle.cpp
+2 -2
@@ -82,9 +82,9 @@ extern "C" void RelatedBundlesUninitialize(
82 {
83 BURN_PACKAGE* pPackage = &pRelatedBundles->rgRelatedBundles[i].package;
84
85 - for (DWORD j = 0; j < pPackage->payloads.cPayloads; ++j)
85 + for (DWORD j = 0; j < pPackage->payloads.cItems; ++j)
86 {
87 - PayloadUninitialize(pPackage->payloads.rgpPayloads[j]);
87 + PayloadUninitialize(pPackage->payloads.rgItems[j].pPayload);
88 }
89
90 PackageUninitialize(pPackage);