Elevate for CacheVerifyContainer/Payload.
Sean Hall committed
Apr 16, 2021 at 10:48 UTC
8c77de737aaea1b4857c724c730446bca8da2dd0
5 files changed
+209
-31
src/engine/apply.cpp
+8
-7
@@ -538,6 +538,9 @@ extern "C" HRESULT ApplyCache(
538
539
if (!pPackage->fPerMachine && !cacheContext.wzLayoutDirectory)
540
{
541
+ hr = CacheGetCompletedPath(FALSE, pPackage->sczCacheId, &pPackage->sczCacheFolder);
542
+ ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId);
543
+
544
cacheContext.hPipe = INVALID_HANDLE_VALUE;
545
}
546
@@ -800,12 +803,6 @@ static HRESULT ApplyCachePackage(
803
HRESULT hr = S_OK;
804
BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
805
803
- if (!pPackage->sczCacheFolder && !pContext->wzLayoutDirectory)
804
- {
805
- hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &pPackage->sczCacheFolder);
806
- ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId);
807
- }
808
-
806
for (;;)
807
{
808
hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cPayloads, pPackage->payloads.qwTotalSize);
@@ -1038,7 +1035,11 @@ static HRESULT ApplyCacheVerifyContainerOrPayload(
1035
hr = UserExperienceOnCacheContainerOrPayloadVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId);
1036
ExitOnRootFailure(hr, "BA aborted cache container or payload verify begin.");
1037
1041
- if (pContainer)
1038
+ if (INVALID_HANDLE_VALUE != pContext->hPipe)
1039
+ {
1040
+ hr = ElevationCacheVerifyContainerOrPayload(pContext->hPipe, pContainer, pPackage, pPayload, pContext->wzLayoutDirectory);
1041
+ }
1042
+ else if (pContainer)
1043
{
1044
hr = CacheVerifyContainer(pContainer, pContext->wzLayoutDirectory);
1045
}
src/engine/cache.cpp
+45
-23
@@ -59,11 +59,13 @@ static HRESULT TransferWorkingPathToUnverifiedPath(
59
);
60
static HRESULT VerifyFileAgainstContainer(
61
__in BURN_CONTAINER* pContainer,
62
- __in_z LPCWSTR wzVerifyPath
62
+ __in_z LPCWSTR wzVerifyPath,
63
+ __in BOOL fAlreadyCached
64
);
65
static HRESULT VerifyFileAgainstPayload(
66
__in BURN_PAYLOAD* pPayload,
66
- __in_z LPCWSTR wzVerifyPath
67
+ __in_z LPCWSTR wzVerifyPath,
68
+ __in BOOL fAlreadyCached
69
);
70
static HRESULT ResetPathPermissions(
71
__in BOOL fPerMachine,
@@ -896,19 +898,11 @@ extern "C" HRESULT CacheCompletePayload(
898
ExitOnFailure(hr, "Failed to concat complete cached path.");
899
900
// If the cached file matches what we expected, we're good.
899
- hr = VerifyFileAgainstPayload(pPayload, sczCachedPath);
901
+ hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE);
902
if (SUCCEEDED(hr))
903
{
902
- ::DecryptFileW(sczCachedPath, 0); // Let's try to make sure it's not encrypted.
903
- LogId(REPORT_STANDARD, MSG_VERIFIED_EXISTING_PAYLOAD, pPayload->sczKey, sczCachedPath);
904
ExitFunction();
905
}
906
- else if (E_PATHNOTFOUND != hr && E_FILENOTFOUND != hr)
907
- {
908
- LogErrorId(hr, MSG_FAILED_VERIFY_PAYLOAD, pPayload->sczKey, sczCachedPath, NULL);
909
-
910
- FileEnsureDelete(sczCachedPath); // if the file existed but did not verify correctly, make it go away.
911
- }
906
907
hr = CreateUnverifiedPath(fPerMachine, pPayload->sczKey, &sczUnverifiedPayloadPath);
908
ExitOnFailure(hr, "Failed to create unverified path.");
@@ -928,14 +922,8 @@ extern "C" HRESULT CacheCompletePayload(
922
hr = ResetPathPermissions(fPerMachine, sczUnverifiedPayloadPath);
923
ExitOnFailure(hr, "Failed to reset permissions on unverified cached payload: %ls", pPayload->sczKey);
924
931
- hr = VerifyFileAgainstPayload(pPayload, sczUnverifiedPayloadPath);
932
- if (FAILED(hr))
933
- {
934
- LogErrorId(hr, MSG_FAILED_VERIFY_PAYLOAD, pPayload->sczKey, sczUnverifiedPayloadPath, NULL);
935
-
936
- FileEnsureDelete(sczUnverifiedPayloadPath); // if the file did not verify correctly, make it go away.
937
- ExitFunction();
938
- }
925
+ hr = VerifyFileAgainstPayload(pPayload, sczUnverifiedPayloadPath, FALSE);
926
+ LogExitOnFailure(hr, MSG_FAILED_VERIFY_PAYLOAD, "Failed to verify payload: %ls at path: %ls", pPayload->sczKey, sczUnverifiedPayloadPath, NULL);
927
928
LogId(REPORT_STANDARD, MSG_VERIFIED_ACQUIRED_PAYLOAD, pPayload->sczKey, sczUnverifiedPayloadPath, fMove ? "moving" : "copying", sczCachedPath);
929
@@ -963,7 +951,7 @@ extern "C" HRESULT CacheVerifyContainer(
951
hr = PathConcat(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath);
952
ExitOnFailure(hr, "Failed to concat complete cached path.");
953
966
- hr = VerifyFileAgainstContainer(pContainer, sczCachedPath);
954
+ hr = VerifyFileAgainstContainer(pContainer, sczCachedPath, TRUE);
955
956
LExit:
957
ReleaseStr(sczCachedPath);
@@ -982,7 +970,7 @@ extern "C" HRESULT CacheVerifyPayload(
970
hr = PathConcat(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath);
971
ExitOnFailure(hr, "Failed to concat complete cached path.");
972
985
- hr = VerifyFileAgainstPayload(pPayload, sczCachedPath);
973
+ hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE);
974
975
LExit:
976
ReleaseStr(sczCachedPath);
@@ -1460,7 +1448,8 @@ LExit:
1448
1449
static HRESULT VerifyFileAgainstContainer(
1450
__in BURN_CONTAINER* pContainer,
1463
- __in_z LPCWSTR wzVerifyPath
1451
+ __in_z LPCWSTR wzVerifyPath,
1452
+ __in BOOL fAlreadyCached
1453
)
1454
{
1455
HRESULT hr = S_OK;
@@ -1484,15 +1473,32 @@ static HRESULT VerifyFileAgainstContainer(
1473
ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId);
1474
}
1475
1476
+ if (fAlreadyCached)
1477
+ {
1478
+ LogId(REPORT_STANDARD, MSG_VERIFIED_EXISTING_CONTAINER, pContainer->sczId, wzVerifyPath);
1479
+ ::DecryptFileW(wzVerifyPath, 0); // Let's try to make sure it's not encrypted.
1480
+ }
1481
+
1482
LExit:
1483
ReleaseFileHandle(hFile);
1484
1485
+ if (FAILED(hr) && E_PATHNOTFOUND != hr && E_FILENOTFOUND != hr)
1486
+ {
1487
+ if (fAlreadyCached)
1488
+ {
1489
+ LogErrorId(hr, MSG_FAILED_VERIFY_CONTAINER, pContainer->sczId, wzVerifyPath, NULL);
1490
+ }
1491
+
1492
+ FileEnsureDelete(wzVerifyPath); // if the file existed but did not verify correctly, make it go away.
1493
+ }
1494
+
1495
return hr;
1496
}
1497
1498
static HRESULT VerifyFileAgainstPayload(
1499
__in BURN_PAYLOAD* pPayload,
1495
- __in_z LPCWSTR wzVerifyPath
1500
+ __in_z LPCWSTR wzVerifyPath,
1501
+ __in BOOL fAlreadyCached
1502
)
1503
{
1504
HRESULT hr = S_OK;
@@ -1516,9 +1522,25 @@ static HRESULT VerifyFileAgainstPayload(
1522
ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey);
1523
}
1524
1525
+ if (fAlreadyCached)
1526
+ {
1527
+ LogId(REPORT_STANDARD, MSG_VERIFIED_EXISTING_PAYLOAD, pPayload->sczKey, wzVerifyPath);
1528
+ ::DecryptFileW(wzVerifyPath, 0); // Let's try to make sure it's not encrypted.
1529
+ }
1530
+
1531
LExit:
1532
ReleaseFileHandle(hFile);
1533
1534
+ if (FAILED(hr) && E_PATHNOTFOUND != hr && E_FILENOTFOUND != hr)
1535
+ {
1536
+ if (fAlreadyCached)
1537
+ {
1538
+ LogErrorId(hr, MSG_FAILED_VERIFY_PAYLOAD, pPayload->sczKey, wzVerifyPath, NULL);
1539
+ }
1540
+
1541
+ FileEnsureDelete(wzVerifyPath); // if the file existed but did not verify correctly, make it go away.
1542
+ }
1543
+
1544
return hr;
1545
}
1546
src/engine/elevation.cpp
+135
-1
@@ -16,6 +16,7 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
16
BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE,
17
BURN_ELEVATION_MESSAGE_TYPE_LAYOUT_BUNDLE,
18
BURN_ELEVATION_MESSAGE_TYPE_CACHE_OR_LAYOUT_CONTAINER_OR_PAYLOAD,
19
+ BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_CONTAINER_OR_PAYLOAD,
20
BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP,
21
BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION,
22
BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE,
@@ -176,6 +177,13 @@ static HRESULT OnCacheOrLayoutContainerOrPayload(
177
__in BYTE* pbData,
178
__in DWORD cbData
179
);
180
+static HRESULT OnCacheVerifyContainerOrPayload(
181
+ __in BURN_CONTAINERS* pContainers,
182
+ __in BURN_PACKAGES* pPackages,
183
+ __in BURN_PAYLOADS* pPayloads,
184
+ __in BYTE* pbData,
185
+ __in DWORD cbData
186
+ );
187
static void OnCacheCleanup(
188
__in_z LPCWSTR wzBundleId
189
);
@@ -657,6 +665,44 @@ LExit:
665
return hr;
666
}
667
668
+extern "C" HRESULT ElevationCacheVerifyContainerOrPayload(
669
+ __in HANDLE hPipe,
670
+ __in_opt BURN_CONTAINER* pContainer,
671
+ __in_opt BURN_PACKAGE* pPackage,
672
+ __in_opt BURN_PAYLOAD* pPayload,
673
+ __in_z_opt LPCWSTR wzLayoutDirectory
674
+ )
675
+{
676
+ HRESULT hr = S_OK;
677
+ BYTE* pbData = NULL;
678
+ SIZE_T cbData = 0;
679
+ DWORD dwResult = 0;
680
+
681
+ // serialize message data
682
+ hr = BuffWriteString(&pbData, &cbData, pContainer ? pContainer->sczId : NULL);
683
+ ExitOnFailure(hr, "Failed to write container id to message buffer.");
684
+
685
+ hr = BuffWriteString(&pbData, &cbData, pPackage ? pPackage->sczId : NULL);
686
+ ExitOnFailure(hr, "Failed to write package id to message buffer.");
687
+
688
+ hr = BuffWriteString(&pbData, &cbData, pPayload ? pPayload->sczKey : NULL);
689
+ ExitOnFailure(hr, "Failed to write payload id to message buffer.");
690
+
691
+ hr = BuffWriteString(&pbData, &cbData, wzLayoutDirectory);
692
+ ExitOnFailure(hr, "Failed to write layout directory to message buffer.");
693
+
694
+ // send message
695
+ hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_CONTAINER_OR_PAYLOAD, pbData, cbData, NULL, NULL, &dwResult);
696
+ ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_CONTAINER_OR_PAYLOAD message to per-machine process.");
697
+
698
+ hr = (HRESULT)dwResult;
699
+
700
+LExit:
701
+ ReleaseBuffer(pbData);
702
+
703
+ return hr;
704
+}
705
+
706
/*******************************************************************
707
ElevationCacheCleanup -
708
@@ -1724,6 +1770,10 @@ static HRESULT ProcessElevatedChildCacheMessage(
1770
hrResult = OnCacheOrLayoutContainerOrPayload(pContext->pContainers, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
1771
break;
1772
1773
+ case BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_CONTAINER_OR_PAYLOAD:
1774
+ hrResult = OnCacheVerifyContainerOrPayload(pContext->pContainers, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
1775
+ break;
1776
+
1777
case BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP:
1778
OnCacheCleanup(pContext->pRegistration->sczId);
1779
hrResult = S_OK;
@@ -2062,7 +2112,7 @@ static HRESULT OnCacheOrLayoutContainerOrPayload(
2112
2113
// Deserialize message data.
2114
hr = BuffReadString(pbData, cbData, &iData, &scz);
2065
- ExitOnFailure(hr, "Failed to read package id.");
2115
+ ExitOnFailure(hr, "Failed to read container id.");
2116
2117
if (scz && *scz)
2118
{
@@ -2135,6 +2185,90 @@ LExit:
2185
return hr;
2186
}
2187
2188
+static HRESULT OnCacheVerifyContainerOrPayload(
2189
+ __in BURN_CONTAINERS* pContainers,
2190
+ __in BURN_PACKAGES* pPackages,
2191
+ __in BURN_PAYLOADS* pPayloads,
2192
+ __in BYTE* pbData,
2193
+ __in DWORD cbData
2194
+ )
2195
+{
2196
+ HRESULT hr = S_OK;
2197
+ SIZE_T iData = 0;
2198
+ LPWSTR scz = NULL;
2199
+ BURN_CONTAINER* pContainer = NULL;
2200
+ BURN_PACKAGE* pPackage = NULL;
2201
+ BURN_PAYLOAD* pPayload = NULL;
2202
+ LPWSTR sczCacheDirectory = NULL;
2203
+
2204
+ // Deserialize message data.
2205
+ hr = BuffReadString(pbData, cbData, &iData, &scz);
2206
+ ExitOnFailure(hr, "Failed to read container id.");
2207
+
2208
+ if (scz && *scz)
2209
+ {
2210
+ hr = ContainerFindById(pContainers, scz, &pContainer);
2211
+ ExitOnFailure(hr, "Failed to find container: %ls", scz);
2212
+ }
2213
+
2214
+ hr = BuffReadString(pbData, cbData, &iData, &scz);
2215
+ ExitOnFailure(hr, "Failed to read package id.");
2216
+
2217
+ if (scz && *scz)
2218
+ {
2219
+ hr = PackageFindById(pPackages, scz, &pPackage);
2220
+ ExitOnFailure(hr, "Failed to find package: %ls", scz);
2221
+ }
2222
+
2223
+ hr = BuffReadString(pbData, cbData, &iData, &scz);
2224
+ ExitOnFailure(hr, "Failed to read payload id.");
2225
+
2226
+ if (scz && *scz)
2227
+ {
2228
+ hr = PayloadFindById(pPayloads, scz, &pPayload);
2229
+ ExitOnFailure(hr, "Failed to find payload: %ls", scz);
2230
+ }
2231
+
2232
+ hr = BuffReadString(pbData, cbData, &iData, &sczCacheDirectory);
2233
+ ExitOnFailure(hr, "Failed to read layout directory.");
2234
+
2235
+ if (!sczCacheDirectory || !*sczCacheDirectory)
2236
+ {
2237
+ if (!pPackage)
2238
+ {
2239
+ hr = E_INVALIDARG;
2240
+ ExitOnRootFailure(hr, "Invalid data passed to cache verify payload.");
2241
+ }
2242
+
2243
+ hr = CacheGetCompletedPath(TRUE, pPackage->sczCacheId, &sczCacheDirectory);
2244
+ ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId);
2245
+ }
2246
+
2247
+ if (pContainer)
2248
+ {
2249
+ Assert(!pPackage);
2250
+ Assert(!pPayload);
2251
+
2252
+ hr = CacheVerifyContainer(pContainer, sczCacheDirectory);
2253
+ }
2254
+ else if (pPayload)
2255
+ {
2256
+ hr = CacheVerifyPayload(pPayload, sczCacheDirectory);
2257
+ }
2258
+ else
2259
+ {
2260
+ hr = E_INVALIDARG;
2261
+ ExitOnRootFailure(hr, "Invalid data passed to cache or layout payload.");
2262
+ }
2263
+ // Nothing should be logged on failure.
2264
+
2265
+LExit:
2266
+ ReleaseStr(sczCacheDirectory);
2267
+ ReleaseStr(scz);
2268
+
2269
+ return hr;
2270
+}
2271
+
2272
static void OnCacheCleanup(
2273
__in_z LPCWSTR wzBundleId
2274
)
src/engine/elevation.h
+7
@@ -64,6 +64,13 @@ HRESULT ElevationCacheOrLayoutContainerOrPayload(
64
__in_z LPCWSTR wzUnverifiedPath,
65
__in BOOL fMove
66
);
67
+HRESULT ElevationCacheVerifyContainerOrPayload(
68
+ __in HANDLE hPipe,
69
+ __in_opt BURN_CONTAINER* pContainer,
70
+ __in_opt BURN_PACKAGE* pPackage,
71
+ __in_opt BURN_PAYLOAD* pPayload,
72
+ __in_z_opt LPCWSTR wzLayoutDirectory
73
+ );
74
HRESULT ElevationCacheCleanup(
75
__in HANDLE hPipe
76
);
src/engine/engine.mc
+14
@@ -478,6 +478,13 @@ Language=English
478
Acquired payload: %1!ls! to working path: %2!ls! from: %4!ls!.
479
.
480
481
+MessageId=303
482
+Severity=Success
483
+SymbolicName=MSG_VERIFIED_EXISTING_CONTAINER
484
+Language=English
485
+Verified existing container: %1!ls! at path: %2!ls!.
486
+.
487
+
488
MessageId=304
489
Severity=Success
490
SymbolicName=MSG_VERIFIED_EXISTING_PAYLOAD
@@ -724,6 +731,13 @@ Language=English
731
Acquiring package: %1!ls!, payload: %2!ls!, %3!hs! from: %4!ls!
732
.
733
734
+MessageId=339
735
+Severity=Error
736
+SymbolicName=MSG_FAILED_VERIFY_CONTAINER
737
+Language=English
738
+Failed to verify container: %2!ls! at path: %3!ls!, error: %1!ls!. Deleting file.
739
+.
740
+
741
MessageId=347
742
Severity=Warning
743
SymbolicName=MSG_APPLY_RETRYING_CONTAINER