@joebigelow / wix-1 / commits / 8c77de73

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