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);