Verify file in the cache before trying to acquire it.
Sean Hall committed
Apr 16, 2021 at 10:18 UTC
b941c2754748251520dc5032d11396c9844fad8e
5 files changed
+116
-9
src/engine/apply.cpp
+29
-7
@@ -768,6 +768,12 @@ static HRESULT ApplyCachePackage(
768
HRESULT hr = S_OK;
769
BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
770
771
+ if (!pPackage->sczCacheFolder && !pContext->wzLayoutDirectory)
772
+ {
773
+ hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &pPackage->sczCacheFolder);
774
+ ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId);
775
+ }
776
+
777
for (;;)
778
{
779
hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cPayloads, pPackage->payloads.qwTotalSize);
@@ -872,6 +878,14 @@ static HRESULT ApplyLayoutContainer(
878
879
Assert(!pContainer->fAttached);
880
881
+ hr = CacheVerifyContainer(pContainer, pContext->wzLayoutDirectory);
882
+ if (SUCCEEDED(hr))
883
+ {
884
+ // TODO: send Acquire and Verify messages to BA?
885
+ pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize * 2;
886
+ ExitFunction();
887
+ }
888
+
889
for (;;)
890
{
891
fRetry = FALSE;
@@ -916,7 +930,20 @@ static HRESULT ApplyProcessPayload(
930
DWORD cTryAgainAttempts = 0;
931
BOOL fRetry = FALSE;
932
919
- Assert(pContext->pPayloads || pContext->wzLayoutDirectory);
933
+ Assert(pContext->pPayloads && pPackage || pContext->wzLayoutDirectory);
934
+
935
+ if (pPayload->pContainer && pContext->wzLayoutDirectory)
936
+ {
937
+ ExitFunction();
938
+ }
939
+
940
+ hr = CacheVerifyPayload(pPayload, pContext->wzLayoutDirectory ? pContext->wzLayoutDirectory : pPackage->sczCacheFolder);
941
+ if (SUCCEEDED(hr))
942
+ {
943
+ // TODO: send Acquire and Verify messages to BA?
944
+ pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize * 2;
945
+ ExitFunction();
946
+ }
947
948
for (;;)
949
{
@@ -924,12 +951,7 @@ static HRESULT ApplyProcessPayload(
951
952
if (pPayload->pContainer)
953
{
927
- if (pContext->wzLayoutDirectory)
928
- {
929
- ExitFunction();
930
- }
931
-
932
- // TODO: only extract container if payload isn't already cached and isn't already extracted
954
+ // TODO: only extract container if payload isn't already extracted
955
hr = ApplyExtractContainer(pContext, pPayload->pContainer);
956
ExitOnFailure(hr, "Failed to extract container for payload: %ls", pPayload->sczKey);
957
}
src/engine/cache.cpp
+75
-1
@@ -57,6 +57,10 @@ static HRESULT TransferWorkingPathToUnverifiedPath(
57
__in_z LPCWSTR wzUnverifiedPayloadPath,
58
__in BOOL fMove
59
);
60
+static HRESULT VerifyFileAgainstContainer(
61
+ __in BURN_CONTAINER* pContainer,
62
+ __in_z LPCWSTR wzVerifyPath
63
+ );
64
static HRESULT VerifyFileAgainstPayload(
65
__in BURN_PAYLOAD* pPayload,
66
__in_z LPCWSTR wzVerifyPath
@@ -837,7 +841,7 @@ LExit:
841
extern "C" HRESULT CacheCompletePayload(
842
__in BOOL fPerMachine,
843
__in BURN_PAYLOAD* pPayload,
840
- __in_z_opt LPCWSTR wzCacheId,
844
+ __in_z LPCWSTR wzCacheId,
845
__in_z LPCWSTR wzWorkingPayloadPath,
846
__in BOOL fMove
847
)
@@ -910,6 +914,44 @@ LExit:
914
return hr;
915
}
916
917
+extern "C" HRESULT CacheVerifyContainer(
918
+ __in BURN_CONTAINER* pContainer,
919
+ __in_z LPCWSTR wzCachedDirectory
920
+ )
921
+{
922
+ HRESULT hr = S_OK;
923
+ LPWSTR sczCachedPath = NULL;
924
+
925
+ hr = PathConcat(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath);
926
+ ExitOnFailure(hr, "Failed to concat complete cached path.");
927
+
928
+ hr = VerifyFileAgainstContainer(pContainer, sczCachedPath);
929
+
930
+LExit:
931
+ ReleaseStr(sczCachedPath);
932
+
933
+ return hr;
934
+}
935
+
936
+extern "C" HRESULT CacheVerifyPayload(
937
+ __in BURN_PAYLOAD* pPayload,
938
+ __in_z LPCWSTR wzCachedDirectory
939
+ )
940
+{
941
+ HRESULT hr = S_OK;
942
+ LPWSTR sczCachedPath = NULL;
943
+
944
+ hr = PathConcat(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath);
945
+ ExitOnFailure(hr, "Failed to concat complete cached path.");
946
+
947
+ hr = VerifyFileAgainstPayload(pPayload, sczCachedPath);
948
+
949
+LExit:
950
+ ReleaseStr(sczCachedPath);
951
+
952
+ return hr;
953
+}
954
+
955
extern "C" HRESULT CacheRemoveWorkingFolder(
956
__in_z_opt LPCWSTR wzBundleId
957
)
@@ -1383,6 +1425,38 @@ LExit:
1425
return hr;
1426
}
1427
1428
+static HRESULT VerifyFileAgainstContainer(
1429
+ __in BURN_CONTAINER* pContainer,
1430
+ __in_z LPCWSTR wzVerifyPath
1431
+ )
1432
+{
1433
+ HRESULT hr = S_OK;
1434
+ HANDLE hFile = INVALID_HANDLE_VALUE;
1435
+
1436
+ // Get the container on disk actual hash.
1437
+ hFile = ::CreateFileW(wzVerifyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1438
+ if (INVALID_HANDLE_VALUE == hFile)
1439
+ {
1440
+ hr = HRESULT_FROM_WIN32(::GetLastError());
1441
+ if (E_PATHNOTFOUND == hr || E_FILENOTFOUND == hr)
1442
+ {
1443
+ ExitFunction(); // do not log error when the file was not found.
1444
+ }
1445
+ ExitOnRootFailure(hr, "Failed to open container at path: %ls", wzVerifyPath);
1446
+ }
1447
+
1448
+ if (pContainer->pbHash) // the container should have a hash we can use to verify it.
1449
+ {
1450
+ hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzVerifyPath, hFile);
1451
+ ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId);
1452
+ }
1453
+
1454
+LExit:
1455
+ ReleaseFileHandle(hFile);
1456
+
1457
+ return hr;
1458
+}
1459
+
1460
static HRESULT VerifyFileAgainstPayload(
1461
__in BURN_PAYLOAD* pPayload,
1462
__in_z LPCWSTR wzVerifyPath
src/engine/cache.h
+9
-1
@@ -119,10 +119,18 @@ HRESULT CacheLayoutPayload(
119
HRESULT CacheCompletePayload(
120
__in BOOL fPerMachine,
121
__in BURN_PAYLOAD* pPayload,
122
- __in_z_opt LPCWSTR wzCacheId,
122
+ __in_z LPCWSTR wzCacheId,
123
__in_z LPCWSTR wzUnverifiedPayloadPath,
124
__in BOOL fMove
125
);
126
+HRESULT CacheVerifyContainer(
127
+ __in BURN_CONTAINER* pContainer,
128
+ __in_z LPCWSTR wzCachedDirectory
129
+ );
130
+HRESULT CacheVerifyPayload(
131
+ __in BURN_PAYLOAD* pPayload,
132
+ __in_z LPCWSTR wzCachedDirectory
133
+ );
134
HRESULT CacheRemoveWorkingFolder(
135
__in_z_opt LPCWSTR wzBundleId
136
);
src/engine/package.h
+1
@@ -246,6 +246,7 @@ typedef struct _BURN_PACKAGE
246
BURN_DEPENDENCY_ACTION dependencyExecute; // only valid during Plan.
247
BURN_DEPENDENCY_ACTION dependencyRollback; // only valid during Plan.
248
BOOL fDependencyManagerWasHere; // only valid during Plan.
249
+ LPWSTR sczCacheFolder; // only valid during Apply.
250
HRESULT hrCacheResult; // only valid during Apply.
251
252
BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply.
src/engine/plan.cpp
+2
@@ -1863,6 +1863,8 @@ static void ResetPlannedPackageState(
1863
pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1864
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1865
1866
+ ReleaseNullStr(pPackage->sczCacheFolder);
1867
+
1868
if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
1869
{
1870
for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i)