Send more progress during cache verification. Add verifyStep to OnCacheVerifyProgress. Send OnContainerOrPayloadVerify events only if file existed in cache.
Send more progress during cache verification. Add verifyStep to OnCacheVerifyProgress. Send OnContainerOrPayloadVerify events only if file existed in cache.
Sean Hall committed
Apr 17, 2021 at 20:58 UTC
d4c76dd11f5a096b4fd3ee9c5efc1f44559ac3da
11 files changed
+712
-148
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+8
@@ -64,6 +64,13 @@ enum BOOTSTRAPPER_CACHE_OPERATION
64
BOOTSTRAPPER_CACHE_OPERATION_EXTRACT,
65
};
66
67
+enum BOOTSTRAPPER_CACHE_VERIFY_STEP
68
+{
69
+ BOOTSTRAPPER_CACHE_VERIFY_STEP_STAGE,
70
+ BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH,
71
+ BOOTSTRAPPER_CACHE_VERIFY_STEP_FINALIZE,
72
+};
73
+
74
enum BOOTSTRAPPER_APPLY_RESTART
75
{
76
BOOTSTRAPPER_APPLY_RESTART_NONE,
@@ -553,6 +560,7 @@ struct BA_ONCACHEVERIFYPROGRESS_ARGS
560
DWORD64 dw64Progress;
561
DWORD64 dw64Total;
562
DWORD dwOverallPercentage;
563
+ BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep;
564
};
565
566
struct BA_ONCACHEVERIFYPROGRESS_RESULTS
src/engine/apply.cpp
+117
-54
@@ -14,9 +14,12 @@ const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2;
14
enum BURN_CACHE_PROGRESS_TYPE
15
{
16
BURN_CACHE_PROGRESS_TYPE_ACQUIRE,
17
- BURN_CACHE_PROGRESS_TYPE_VERIFY,
17
BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY,
18
BURN_CACHE_PROGRESS_TYPE_EXTRACT,
19
+ BURN_CACHE_PROGRESS_TYPE_FINALIZE,
20
+ BURN_CACHE_PROGRESS_TYPE_HASH,
21
+ BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY,
22
+ BURN_CACHE_PROGRESS_TYPE_STAGE,
23
};
24
25
// structs
@@ -151,6 +154,10 @@ static HRESULT DownloadPayload(
154
__in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
155
__in_z LPCWSTR wzDestinationPath
156
);
157
+static HRESULT CALLBACK CacheMessageHandler(
158
+ __in BURN_CACHE_MESSAGE* pMessage,
159
+ __in LPVOID pvContext
160
+ );
161
static HRESULT CompleteCacheProgress(
162
__in BURN_CACHE_PROGRESS_CONTEXT* pContext,
163
__in DWORD64 qwFileSize
@@ -993,7 +1000,8 @@ static HRESULT ApplyLayoutContainer(
1000
}
1001
1002
++cTryAgainAttempts;
996
- pContext->qwSuccessfulCacheProgress -= pContainer->qwFileSize;
1003
+ pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedCacheProgress;
1004
+ pContainer->qwCommittedCacheProgress = 0;
1005
ReleaseNullStr(pContext->sczLastUsedFolderCandidate);
1006
LogErrorId(hr, MSG_APPLY_RETRYING_CONTAINER, pContainer->sczId, NULL, NULL);
1007
}
@@ -1075,49 +1083,25 @@ static HRESULT ApplyCacheVerifyContainerOrPayload(
1083
1084
HRESULT hr = S_OK;
1085
BURN_CACHE_PROGRESS_CONTEXT progress = { };
1078
- LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : NULL;
1079
- LPCWSTR wzPayloadId = pPayloadGroupItem ? pPayloadGroupItem->pPayload->sczKey : NULL;
1080
- DWORD64 qwFileSize = pContainer ? pContainer->qwFileSize : pPayloadGroupItem->pPayload->qwFileSize;
1086
1087
progress.pCacheContext = pContext;
1088
progress.pContainer = pContainer;
1089
progress.pPackage = pPackage;
1090
progress.pPayloadGroupItem = pPayloadGroupItem;
1086
- progress.type = BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY;
1087
-
1088
- hr = UserExperienceOnCacheContainerOrPayloadVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId);
1089
- ExitOnRootFailure(hr, "BA aborted cache container or payload verify begin.");
1091
1092
if (pContainer)
1093
{
1093
- hr = CacheVerifyContainer(pContainer, pContext->wzLayoutDirectory);
1094
+ hr = CacheVerifyContainer(pContainer, pContext->wzLayoutDirectory, CacheMessageHandler, CacheProgressRoutine, &progress);
1095
}
1096
else if (!pContext->wzLayoutDirectory && INVALID_HANDLE_VALUE != pContext->hPipe)
1097
{
1097
- hr = ElevationCacheVerifyPayload(pContext->hPipe, pPackage, pPayloadGroupItem->pPayload);
1098
+ hr = ElevationCacheVerifyPayload(pContext->hPipe, pPackage, pPayloadGroupItem->pPayload, CacheMessageHandler, CacheProgressRoutine, &progress);
1099
}
1100
else
1101
{
1101
- hr = CacheVerifyPayload(pPayloadGroupItem->pPayload, pContext->wzLayoutDirectory ? pContext->wzLayoutDirectory : pPackage->sczCacheFolder);
1102
- }
1103
-
1104
- // This was best effort to avoid acquiring the container or payload.
1105
- if (FAILED(hr))
1106
- {
1107
- ExitFunction();
1102
+ hr = CacheVerifyPayload(pPayloadGroupItem->pPayload, pContext->wzLayoutDirectory ? pContext->wzLayoutDirectory : pPackage->sczCacheFolder, CacheMessageHandler, CacheProgressRoutine, &progress);
1103
}
1104
1110
- pContext->qwSuccessfulCacheProgress += qwFileSize;
1111
- if (pPayloadGroupItem)
1112
- {
1113
- pPayloadGroupItem->qwCommittedCacheProgress += qwFileSize;
1114
- }
1115
-
1116
- hr = CompleteCacheProgress(&progress, qwFileSize);
1117
-
1118
-LExit:
1119
- UserExperienceOnCacheContainerOrPayloadVerifyComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr);
1120
-
1105
return hr;
1106
}
1107
@@ -1252,8 +1236,6 @@ static HRESULT LayoutBundle(
1236
ExitOnRootFailure(hr, "BA aborted cache payload verify begin.");
1237
}
1238
1255
- pContext->qwSuccessfulCacheProgress += qwBundleSize;
1256
-
1239
progress.type = BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY;
1240
hr = CompleteCacheProgress(&progress, qwBundleSize);
1241
@@ -1306,8 +1288,6 @@ static HRESULT LayoutBundle(
1288
break;
1289
}
1290
1309
- progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY;
1310
-
1291
do
1292
{
1293
fCanceledBegin = FALSE;
@@ -1320,12 +1300,7 @@ static HRESULT LayoutBundle(
1300
}
1301
else
1302
{
1323
- hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath);
1324
-
1325
- if (SUCCEEDED(hr))
1326
- {
1327
- hr = CompleteCacheProgress(&progress, qwBundleSize);
1328
- }
1303
+ hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath, qwBundleSize, CacheMessageHandler, CacheProgressRoutine, &progress);
1304
}
1305
1306
BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
@@ -1346,7 +1321,7 @@ static HRESULT LayoutBundle(
1321
1322
if (fRetry)
1323
{
1349
- pContext->qwSuccessfulCacheProgress -= qwBundleSize;
1324
+ pContext->qwSuccessfulCacheProgress -= qwBundleSize; // Acquire
1325
}
1326
} while (fRetry);
1327
LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, pContext->wzLayoutDirectory);
@@ -1559,7 +1534,6 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1534
1535
*pfRetry = FALSE;
1536
progress.pCacheContext = pContext;
1562
- progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY;
1537
progress.pContainer = pContainer;
1538
progress.pPackage = pPackage;
1539
progress.pPayloadGroupItem = pPayloadGroupItem;
@@ -1580,28 +1554,23 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1554
{
1555
if (pContainer)
1556
{
1583
- hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1557
+ hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress);
1558
}
1559
else
1560
{
1587
- hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1561
+ hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress);
1562
}
1563
}
1564
else if (INVALID_HANDLE_VALUE != pContext->hPipe) // pass the decision off to the elevated process.
1565
{
1592
- hr = ElevationCacheCompletePayload(pContext->hPipe, pPackage, pPayload, wzUnverifiedPath, fMove);
1566
+ hr = ElevationCacheCompletePayload(pContext->hPipe, pPackage, pPayload, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress);
1567
}
1568
else // complete the payload.
1569
{
1596
- hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove);
1570
+ hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress);
1571
}
1572
}
1573
1600
- if (SUCCEEDED(hr))
1601
- {
1602
- hr = CompleteCacheProgress(&progress, pContainer ? pContainer->qwFileSize : pPayload->qwFileSize);
1603
- }
1604
-
1574
if (SUCCEEDED(hr) && fCanAffectRegistration)
1575
{
1576
pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
@@ -1820,6 +1789,54 @@ LExit:
1789
return hr;
1790
}
1791
1792
+static HRESULT CALLBACK CacheMessageHandler(
1793
+ __in BURN_CACHE_MESSAGE* pMessage,
1794
+ __in LPVOID pvContext
1795
+ )
1796
+{
1797
+ HRESULT hr = S_OK;
1798
+ BURN_CACHE_PROGRESS_CONTEXT* pProgress = static_cast<BURN_CACHE_PROGRESS_CONTEXT*>(pvContext);
1799
+ LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL;
1800
+ LPCWSTR wzPayloadId = pProgress->pPayloadGroupItem ? pProgress->pPayloadGroupItem->pPayload->sczKey : pProgress->pPayload ? pProgress->pPayload->sczKey : NULL;
1801
+
1802
+ switch (pMessage->type)
1803
+ {
1804
+ case BURN_CACHE_MESSAGE_BEGIN:
1805
+ switch (pMessage->begin.cacheStep)
1806
+ {
1807
+ case BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE:
1808
+ pProgress->type = BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY;
1809
+ hr = UserExperienceOnCacheContainerOrPayloadVerifyBegin(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId);
1810
+ break;
1811
+ case BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY:
1812
+ pProgress->type = BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY;
1813
+ break;
1814
+ case BURN_CACHE_STEP_STAGE:
1815
+ pProgress->type = BURN_CACHE_PROGRESS_TYPE_STAGE;
1816
+ break;
1817
+ case BURN_CACHE_STEP_HASH:
1818
+ pProgress->type = BURN_CACHE_PROGRESS_TYPE_HASH;
1819
+ break;
1820
+ case BURN_CACHE_STEP_FINALIZE:
1821
+ pProgress->type = BURN_CACHE_PROGRESS_TYPE_FINALIZE;
1822
+ break;
1823
+ }
1824
+ break;
1825
+ case BURN_CACHE_MESSAGE_SUCCESS:
1826
+ hr = CompleteCacheProgress(pProgress, pMessage->success.qwFileSize);
1827
+ break;
1828
+ case BURN_CACHE_MESSAGE_COMPLETE:
1829
+ switch (pProgress->type)
1830
+ {
1831
+ case BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY:
1832
+ hr = UserExperienceOnCacheContainerOrPayloadVerifyComplete(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, hr);
1833
+ break;
1834
+ }
1835
+ }
1836
+
1837
+ return hr;
1838
+}
1839
+
1840
static HRESULT CompleteCacheProgress(
1841
__in BURN_CACHE_PROGRESS_CONTEXT* pContext,
1842
__in DWORD64 qwFileSize
@@ -1829,9 +1846,29 @@ static HRESULT CompleteCacheProgress(
1846
LARGE_INTEGER liContainerOrPayloadSize = { };
1847
LARGE_INTEGER liZero = { };
1848
DWORD dwResult = 0;
1849
+ DWORD64 qwCommitSize = 0;
1850
1851
liContainerOrPayloadSize.QuadPart = qwFileSize;
1852
1853
+ // Need to commit the steps that were skipped.
1854
+ if (BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY == pContext->type || BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY == pContext->type)
1855
+ {
1856
+ Assert(!pContext->pPayload);
1857
+
1858
+ qwCommitSize = qwFileSize * (pContext->pCacheContext->wzLayoutDirectory ? 2 : 3); // Acquire (+ Stage) + Hash + Finalize - 1 (that's added later)
1859
+
1860
+ pContext->pCacheContext->qwSuccessfulCacheProgress += qwCommitSize;
1861
+
1862
+ if (pContext->pContainer)
1863
+ {
1864
+ pContext->pContainer->qwCommittedCacheProgress += qwCommitSize;
1865
+ }
1866
+ else if (pContext->pPayloadGroupItem)
1867
+ {
1868
+ pContext->pPayloadGroupItem->qwCommittedCacheProgress += qwCommitSize;
1869
+ }
1870
+ }
1871
+
1872
dwResult = CacheProgressRoutine(liContainerOrPayloadSize, liContainerOrPayloadSize, liZero, liZero, 0, 0, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, pContext);
1873
1874
if (PROGRESS_CONTINUE == dwResult)
@@ -1851,7 +1888,7 @@ static HRESULT CompleteCacheProgress(
1888
pContext->pPayloadGroupItem->qwCommittedCacheProgress += qwFileSize;
1889
}
1890
1854
- if (BURN_CACHE_PROGRESS_TYPE_VERIFY == pContext->type && pContext->pCacheContext->sczLastUsedFolderCandidate)
1891
+ if (BURN_CACHE_PROGRESS_TYPE_FINALIZE == pContext->type && pContext->pCacheContext->sczLastUsedFolderCandidate)
1892
{
1893
// We successfully copied from a source location, set that as the last used source.
1894
CacheSetLastUsedSource(pContext->pCacheContext->pVariables, pContext->pCacheContext->sczLastUsedFolderCandidate, pContext->pContainer ? pContext->pContainer->sczFilePath : pContext->pPayloadGroupItem->pPayload->sczFilePath);
@@ -1867,6 +1904,20 @@ static HRESULT CompleteCacheProgress(
1904
{
1905
hr = pContext->hrError;
1906
}
1907
+
1908
+ if (qwCommitSize)
1909
+ {
1910
+ pContext->pCacheContext->qwSuccessfulCacheProgress -= qwCommitSize;
1911
+
1912
+ if (pContext->pContainer)
1913
+ {
1914
+ pContext->pContainer->qwCommittedCacheProgress -= qwCommitSize;
1915
+ }
1916
+ else if (pContext->pPayloadGroupItem)
1917
+ {
1918
+ pContext->pPayloadGroupItem->qwCommittedCacheProgress -= qwCommitSize;
1919
+ }
1920
+ }
1921
}
1922
1923
return hr;
@@ -1903,9 +1954,21 @@ static DWORD CALLBACK CacheProgressRoutine(
1954
hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1955
ExitOnRootFailure(hr, "BA aborted acquire of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1956
break;
1906
- case BURN_CACHE_PROGRESS_TYPE_VERIFY:
1907
- hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1908
- ExitOnRootFailure(hr, "BA aborted verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1957
+ case BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY:
1958
+ hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH);
1959
+ ExitOnRootFailure(hr, "BA aborted payload verify step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1960
+ break;
1961
+ case BURN_CACHE_PROGRESS_TYPE_STAGE:
1962
+ hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_STAGE);
1963
+ ExitOnRootFailure(hr, "BA aborted stage step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1964
+ break;
1965
+ case BURN_CACHE_PROGRESS_TYPE_HASH:
1966
+ hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH);
1967
+ ExitOnRootFailure(hr, "BA aborted hash step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1968
+ break;
1969
+ case BURN_CACHE_PROGRESS_TYPE_FINALIZE:
1970
+ hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_FINALIZE);
1971
+ ExitOnRootFailure(hr, "BA aborted finalize step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1972
break;
1973
case BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY:
1974
hr = UserExperienceOnCacheContainerOrPayloadVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
src/engine/cache.cpp
+201
-62
@@ -44,28 +44,47 @@ static HRESULT VerifyThenTransferContainer(
44
__in BURN_CONTAINER* pContainer,
45
__in_z LPCWSTR wzCachedPath,
46
__in_z LPCWSTR wzUnverifiedContainerPath,
47
- __in BOOL fMove
47
+ __in BOOL fMove,
48
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
49
+ __in LPPROGRESS_ROUTINE pfnProgress,
50
+ __in LPVOID pContext
51
);
52
static HRESULT VerifyThenTransferPayload(
53
__in BURN_PAYLOAD* pPayload,
54
__in_z LPCWSTR wzCachedPath,
55
__in_z LPCWSTR wzUnverifiedPayloadPath,
53
- __in BOOL fMove
56
+ __in BOOL fMove,
57
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
58
+ __in LPPROGRESS_ROUTINE pfnProgress,
59
+ __in LPVOID pContext
60
);
55
-static HRESULT TransferWorkingPathToUnverifiedPath(
56
- __in_z LPCWSTR wzWorkingPath,
57
- __in_z LPCWSTR wzUnverifiedPayloadPath,
58
- __in BOOL fMove
61
+static HRESULT CacheTransferFileWithRetry(
62
+ __in_z LPCWSTR wzSourcePath,
63
+ __in_z LPCWSTR wzDestinationPath,
64
+ __in BOOL fMove,
65
+ __in BURN_CACHE_STEP cacheStep,
66
+ __in DWORD64 qwFileSize,
67
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
68
+ __in LPPROGRESS_ROUTINE pfnProgress,
69
+ __in LPVOID pContext
70
);
71
static HRESULT VerifyFileAgainstContainer(
72
__in BURN_CONTAINER* pContainer,
73
__in_z LPCWSTR wzVerifyPath,
63
- __in BOOL fAlreadyCached
74
+ __in BOOL fAlreadyCached,
75
+ __in BURN_CACHE_STEP cacheStep,
76
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
77
+ __in LPPROGRESS_ROUTINE pfnProgress,
78
+ __in LPVOID pContext
79
);
80
static HRESULT VerifyFileAgainstPayload(
81
__in BURN_PAYLOAD* pPayload,
82
__in_z LPCWSTR wzVerifyPath,
68
- __in BOOL fAlreadyCached
83
+ __in BOOL fAlreadyCached,
84
+ __in BURN_CACHE_STEP cacheStep,
85
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
86
+ __in LPPROGRESS_ROUTINE pfnProgress,
87
+ __in LPVOID pContext
88
);
89
static HRESULT ResetPathPermissions(
90
__in BOOL fPerMachine,
@@ -99,7 +118,26 @@ static HRESULT VerifyHash(
118
__in DWORD cbHash,
119
__in DWORD64 qwFileSize,
120
__in_z LPCWSTR wzUnverifiedPayloadPath,
102
- __in HANDLE hFile
121
+ __in HANDLE hFile,
122
+ __in BURN_CACHE_STEP cacheStep,
123
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
124
+ __in LPPROGRESS_ROUTINE pfnProgress,
125
+ __in LPVOID pContext
126
+ );
127
+static HRESULT SendCacheBeginMessage(
128
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
129
+ __in LPVOID pContext,
130
+ __in BURN_CACHE_STEP cacheStep
131
+ );
132
+static HRESULT SendCacheSuccessMessage(
133
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
134
+ __in LPVOID pContext,
135
+ __in DWORD64 qwFileSize
136
+ );
137
+static HRESULT SendCacheCompleteMessage(
138
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
139
+ __in LPVOID pContext,
140
+ __in HRESULT hrStatus
141
);
142
143
@@ -754,7 +792,11 @@ LExit:
792
extern "C" HRESULT CacheLayoutBundle(
793
__in_z LPCWSTR wzExecutableName,
794
__in_z LPCWSTR wzLayoutDirectory,
757
- __in_z LPCWSTR wzSourceBundlePath
795
+ __in_z LPCWSTR wzSourceBundlePath,
796
+ __in DWORD64 qwBundleSize,
797
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
798
+ __in LPPROGRESS_ROUTINE pfnProgress,
799
+ __in LPVOID pContext
800
)
801
{
802
HRESULT hr = S_OK;
@@ -765,7 +807,7 @@ extern "C" HRESULT CacheLayoutBundle(
807
808
LogStringLine(REPORT_STANDARD, "Layout bundle from: '%ls' to: '%ls'", wzSourceBundlePath, sczTargetPath);
809
768
- hr = FileEnsureMoveWithRetry(wzSourceBundlePath, sczTargetPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
810
+ hr = CacheTransferFileWithRetry(wzSourceBundlePath, sczTargetPath, TRUE, BURN_CACHE_STEP_FINALIZE, qwBundleSize, pfnCacheMessageHandler, pfnProgress, pContext);
811
ExitOnFailure(hr, "Failed to layout bundle from: '%ls' to '%ls'", wzSourceBundlePath, sczTargetPath);
812
813
LExit:
@@ -838,7 +880,10 @@ extern "C" HRESULT CacheLayoutContainer(
880
__in BURN_CONTAINER* pContainer,
881
__in_z_opt LPCWSTR wzLayoutDirectory,
882
__in_z LPCWSTR wzUnverifiedContainerPath,
841
- __in BOOL fMove
883
+ __in BOOL fMove,
884
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
885
+ __in LPPROGRESS_ROUTINE pfnProgress,
886
+ __in LPVOID pContext
887
)
888
{
889
HRESULT hr = S_OK;
@@ -847,7 +892,7 @@ extern "C" HRESULT CacheLayoutContainer(
892
hr = PathConcat(wzLayoutDirectory, pContainer->sczFilePath, &sczCachedPath);
893
ExitOnFailure(hr, "Failed to concat complete cached path.");
894
850
- hr = VerifyThenTransferContainer(pContainer, sczCachedPath, wzUnverifiedContainerPath, fMove);
895
+ hr = VerifyThenTransferContainer(pContainer, sczCachedPath, wzUnverifiedContainerPath, fMove, pfnCacheMessageHandler, pfnProgress, pContext);
896
ExitOnFailure(hr, "Failed to layout container from cached path: %ls", sczCachedPath);
897
898
LExit:
@@ -860,7 +905,10 @@ extern "C" HRESULT CacheLayoutPayload(
905
__in BURN_PAYLOAD* pPayload,
906
__in_z_opt LPCWSTR wzLayoutDirectory,
907
__in_z LPCWSTR wzUnverifiedPayloadPath,
863
- __in BOOL fMove
908
+ __in BOOL fMove,
909
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
910
+ __in LPPROGRESS_ROUTINE pfnProgress,
911
+ __in LPVOID pContext
912
)
913
{
914
HRESULT hr = S_OK;
@@ -869,7 +917,7 @@ extern "C" HRESULT CacheLayoutPayload(
917
hr = PathConcat(wzLayoutDirectory, pPayload->sczFilePath, &sczCachedPath);
918
ExitOnFailure(hr, "Failed to concat complete cached path.");
919
872
- hr = VerifyThenTransferPayload(pPayload, sczCachedPath, wzUnverifiedPayloadPath, fMove);
920
+ hr = VerifyThenTransferPayload(pPayload, sczCachedPath, wzUnverifiedPayloadPath, fMove, pfnCacheMessageHandler, pfnProgress, pContext);
921
ExitOnFailure(hr, "Failed to layout payload from cached payload: %ls", sczCachedPath);
922
923
LExit:
@@ -883,7 +931,10 @@ extern "C" HRESULT CacheCompletePayload(
931
__in BURN_PAYLOAD* pPayload,
932
__in_z LPCWSTR wzCacheId,
933
__in_z LPCWSTR wzWorkingPayloadPath,
886
- __in BOOL fMove
934
+ __in BOOL fMove,
935
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
936
+ __in LPPROGRESS_ROUTINE pfnProgress,
937
+ __in LPVOID pContext
938
)
939
{
940
HRESULT hr = S_OK;
@@ -898,7 +949,7 @@ extern "C" HRESULT CacheCompletePayload(
949
ExitOnFailure(hr, "Failed to concat complete cached path.");
950
951
// If the cached file matches what we expected, we're good.
901
- hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE);
952
+ hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY, pfnCacheMessageHandler, pfnProgress, pContext);
953
if (SUCCEEDED(hr))
954
{
955
ExitFunction();
@@ -910,10 +961,21 @@ extern "C" HRESULT CacheCompletePayload(
961
// If the working path exists, let's get it into the unverified path so we can reset the ACLs and verify the file.
962
if (FileExistsEx(wzWorkingPayloadPath, NULL))
963
{
913
- hr = TransferWorkingPathToUnverifiedPath(wzWorkingPayloadPath, sczUnverifiedPayloadPath, fMove);
964
+ hr = CacheTransferFileWithRetry(wzWorkingPayloadPath, sczUnverifiedPayloadPath, fMove, BURN_CACHE_STEP_STAGE, pPayload->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext);
965
ExitOnFailure(hr, "Failed to transfer working path to unverified path for payload: %ls.", pPayload->sczKey);
966
}
916
- else if (!FileExistsEx(sczUnverifiedPayloadPath, NULL)) // if the working path and unverified path do not exist, nothing we can do.
967
+ else if (FileExistsEx(sczUnverifiedPayloadPath, NULL))
968
+ {
969
+ // Make sure the staging progress is sent even though there was nothing to do.
970
+ hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, BURN_CACHE_STEP_STAGE);
971
+ if (SUCCEEDED(hr))
972
+ {
973
+ hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, pPayload->qwFileSize);
974
+ }
975
+ SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr);
976
+ ExitOnFailure(hr, "Aborted transferring working path to unverified path for payload: %ls.", pPayload->sczKey);
977
+ }
978
+ else // if the working path and unverified path do not exist, nothing we can do.
979
{
980
hr = E_FILENOTFOUND;
981
ExitOnFailure(hr, "Failed to find payload: %ls in working path: %ls and unverified path: %ls", pPayload->sczKey, wzWorkingPayloadPath, sczUnverifiedPayloadPath);
@@ -922,12 +984,12 @@ extern "C" HRESULT CacheCompletePayload(
984
hr = ResetPathPermissions(fPerMachine, sczUnverifiedPayloadPath);
985
ExitOnFailure(hr, "Failed to reset permissions on unverified cached payload: %ls", pPayload->sczKey);
986
925
- hr = VerifyFileAgainstPayload(pPayload, sczUnverifiedPayloadPath, FALSE);
987
+ hr = VerifyFileAgainstPayload(pPayload, sczUnverifiedPayloadPath, FALSE, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext);
988
LogExitOnFailure(hr, MSG_FAILED_VERIFY_PAYLOAD, "Failed to verify payload: %ls at path: %ls", pPayload->sczKey, sczUnverifiedPayloadPath, NULL);
989
990
LogId(REPORT_STANDARD, MSG_VERIFIED_ACQUIRED_PAYLOAD, pPayload->sczKey, sczUnverifiedPayloadPath, fMove ? "moving" : "copying", sczCachedPath);
991
930
- hr = FileEnsureMoveWithRetry(sczUnverifiedPayloadPath, sczCachedPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
992
+ hr = CacheTransferFileWithRetry(sczUnverifiedPayloadPath, sczCachedPath, TRUE, BURN_CACHE_STEP_FINALIZE, pPayload->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext);
993
ExitOnFailure(hr, "Failed to move verified file to complete payload path: %ls", sczCachedPath);
994
995
::DecryptFileW(sczCachedPath, 0); // Let's try to make sure it's not encrypted.
@@ -942,7 +1004,10 @@ LExit:
1004
1005
extern "C" HRESULT CacheVerifyContainer(
1006
__in BURN_CONTAINER* pContainer,
945
- __in_z LPCWSTR wzCachedDirectory
1007
+ __in_z LPCWSTR wzCachedDirectory,
1008
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
1009
+ __in LPPROGRESS_ROUTINE pfnProgress,
1010
+ __in LPVOID pContext
1011
)
1012
{
1013
HRESULT hr = S_OK;
@@ -951,7 +1016,7 @@ extern "C" HRESULT CacheVerifyContainer(
1016
hr = PathConcat(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath);
1017
ExitOnFailure(hr, "Failed to concat complete cached path.");
1018
954
- hr = VerifyFileAgainstContainer(pContainer, sczCachedPath, TRUE);
1019
+ hr = VerifyFileAgainstContainer(pContainer, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, pfnCacheMessageHandler, pfnProgress, pContext);
1020
1021
LExit:
1022
ReleaseStr(sczCachedPath);
@@ -961,7 +1026,10 @@ LExit:
1026
1027
extern "C" HRESULT CacheVerifyPayload(
1028
__in BURN_PAYLOAD* pPayload,
964
- __in_z LPCWSTR wzCachedDirectory
1029
+ __in_z LPCWSTR wzCachedDirectory,
1030
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
1031
+ __in LPPROGRESS_ROUTINE pfnProgress,
1032
+ __in LPVOID pContext
1033
)
1034
{
1035
HRESULT hr = S_OK;
@@ -970,7 +1038,7 @@ extern "C" HRESULT CacheVerifyPayload(
1038
hr = PathConcat(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath);
1039
ExitOnFailure(hr, "Failed to concat complete cached path.");
1040
973
- hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE);
1041
+ hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, pfnCacheMessageHandler, pfnProgress, pContext);
1042
1043
LExit:
1044
ReleaseStr(sczCachedPath);
@@ -1342,7 +1410,10 @@ static HRESULT VerifyThenTransferContainer(
1410
__in BURN_CONTAINER* pContainer,
1411
__in_z LPCWSTR wzCachedPath,
1412
__in_z LPCWSTR wzUnverifiedContainerPath,
1345
- __in BOOL fMove
1413
+ __in BOOL fMove,
1414
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
1415
+ __in LPPROGRESS_ROUTINE pfnProgress,
1416
+ __in LPVOID pContext
1417
)
1418
{
1419
HRESULT hr = S_OK;
@@ -1358,22 +1429,13 @@ static HRESULT VerifyThenTransferContainer(
1429
// Container should have a hash we can use to verify with.
1430
if (pContainer->pbHash)
1431
{
1361
- hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzUnverifiedContainerPath, hFile);
1432
+ hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzUnverifiedContainerPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext);
1433
ExitOnFailure(hr, "Failed to verify container hash: %ls", wzCachedPath);
1434
}
1435
1436
LogStringLine(REPORT_STANDARD, "%ls container from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedContainerPath, wzCachedPath);
1437
1367
- if (fMove)
1368
- {
1369
- hr = FileEnsureMoveWithRetry(wzUnverifiedContainerPath, wzCachedPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
1370
- ExitOnFailure(hr, "Failed to move %ls to %ls", wzUnverifiedContainerPath, wzCachedPath);
1371
- }
1372
- else
1373
- {
1374
- hr = FileEnsureCopyWithRetry(wzUnverifiedContainerPath, wzCachedPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
1375
- ExitOnFailure(hr, "Failed to copy %ls to %ls", wzUnverifiedContainerPath, wzCachedPath);
1376
- }
1438
+ hr = CacheTransferFileWithRetry(wzUnverifiedContainerPath, wzCachedPath, fMove, BURN_CACHE_STEP_FINALIZE, pContainer->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext);
1439
1440
LExit:
1441
ReleaseFileHandle(hFile);
@@ -1385,7 +1447,10 @@ static HRESULT VerifyThenTransferPayload(
1447
__in BURN_PAYLOAD* pPayload,
1448
__in_z LPCWSTR wzCachedPath,
1449
__in_z LPCWSTR wzUnverifiedPayloadPath,
1388
- __in BOOL fMove
1450
+ __in BOOL fMove,
1451
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
1452
+ __in LPPROGRESS_ROUTINE pfnProgress,
1453
+ __in LPVOID pContext
1454
)
1455
{
1456
HRESULT hr = S_OK;
@@ -1400,22 +1465,13 @@ static HRESULT VerifyThenTransferPayload(
1465
1466
if (pPayload->pbHash) // the payload should have a hash we can use to verify it.
1467
{
1403
- hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzUnverifiedPayloadPath, hFile);
1468
+ hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzUnverifiedPayloadPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext);
1469
ExitOnFailure(hr, "Failed to verify payload hash: %ls", wzCachedPath);
1470
}
1471
1472
LogStringLine(REPORT_STANDARD, "%ls payload from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedPayloadPath, wzCachedPath);
1473
1409
- if (fMove)
1410
- {
1411
- hr = FileEnsureMoveWithRetry(wzUnverifiedPayloadPath, wzCachedPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
1412
- ExitOnFailure(hr, "Failed to move %ls to %ls", wzUnverifiedPayloadPath, wzCachedPath);
1413
- }
1414
- else
1415
- {
1416
- hr = FileEnsureCopyWithRetry(wzUnverifiedPayloadPath, wzCachedPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
1417
- ExitOnFailure(hr, "Failed to copy %ls to %ls", wzUnverifiedPayloadPath, wzCachedPath);
1418
- }
1474
+ hr = CacheTransferFileWithRetry(wzUnverifiedPayloadPath, wzCachedPath, fMove, BURN_CACHE_STEP_FINALIZE, pPayload->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext);
1475
1476
LExit:
1477
ReleaseFileHandle(hFile);
@@ -1423,33 +1479,50 @@ LExit:
1479
return hr;
1480
}
1481
1426
-static HRESULT TransferWorkingPathToUnverifiedPath(
1427
- __in_z LPCWSTR wzWorkingPath,
1428
- __in_z LPCWSTR wzUnverifiedPayloadPath,
1429
- __in BOOL fMove
1482
+static HRESULT CacheTransferFileWithRetry(
1483
+ __in_z LPCWSTR wzSourcePath,
1484
+ __in_z LPCWSTR wzDestinationPath,
1485
+ __in BOOL fMove,
1486
+ __in BURN_CACHE_STEP cacheStep,
1487
+ __in DWORD64 qwFileSize,
1488
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
1489
+ __in LPPROGRESS_ROUTINE /*pfnProgress*/,
1490
+ __in LPVOID pContext
1491
)
1492
{
1493
HRESULT hr = S_OK;
1494
1495
+ hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep);
1496
+ ExitOnFailure(hr, "Aborted cache file transfer begin.");
1497
+
1498
+ // TODO: send progress during the file transfer.
1499
if (fMove)
1500
{
1436
- hr = FileEnsureMoveWithRetry(wzWorkingPath, wzUnverifiedPayloadPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
1437
- ExitOnFailure(hr, "Failed to move %ls to %ls", wzWorkingPath, wzUnverifiedPayloadPath);
1501
+ hr = FileEnsureMoveWithRetry(wzSourcePath, wzDestinationPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
1502
+ ExitOnFailure(hr, "Failed to move %ls to %ls", wzSourcePath, wzDestinationPath);
1503
}
1504
else
1505
{
1441
- hr = FileEnsureCopyWithRetry(wzWorkingPath, wzUnverifiedPayloadPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
1442
- ExitOnFailure(hr, "Failed to copy %ls to %ls", wzWorkingPath, wzUnverifiedPayloadPath);
1506
+ hr = FileEnsureCopyWithRetry(wzSourcePath, wzDestinationPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT);
1507
+ ExitOnFailure(hr, "Failed to copy %ls to %ls", wzSourcePath, wzDestinationPath);
1508
}
1509
1510
+ hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize);
1511
+
1512
LExit:
1513
+ SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr);
1514
+
1515
return hr;
1516
}
1517
1518
static HRESULT VerifyFileAgainstContainer(
1519
__in BURN_CONTAINER* pContainer,
1520
__in_z LPCWSTR wzVerifyPath,
1452
- __in BOOL fAlreadyCached
1521
+ __in BOOL fAlreadyCached,
1522
+ __in BURN_CACHE_STEP cacheStep,
1523
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
1524
+ __in LPPROGRESS_ROUTINE pfnProgress,
1525
+ __in LPVOID pContext
1526
)
1527
{
1528
HRESULT hr = S_OK;
@@ -1469,7 +1542,7 @@ static HRESULT VerifyFileAgainstContainer(
1542
1543
if (pContainer->pbHash) // the container should have a hash we can use to verify it.
1544
{
1472
- hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzVerifyPath, hFile);
1545
+ hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext);
1546
ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId);
1547
}
1548
@@ -1498,7 +1571,11 @@ LExit:
1571
static HRESULT VerifyFileAgainstPayload(
1572
__in BURN_PAYLOAD* pPayload,
1573
__in_z LPCWSTR wzVerifyPath,
1501
- __in BOOL fAlreadyCached
1574
+ __in BOOL fAlreadyCached,
1575
+ __in BURN_CACHE_STEP cacheStep,
1576
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
1577
+ __in LPPROGRESS_ROUTINE pfnProgress,
1578
+ __in LPVOID pContext
1579
)
1580
{
1581
HRESULT hr = S_OK;
@@ -1518,7 +1595,7 @@ static HRESULT VerifyFileAgainstPayload(
1595
1596
if (pPayload->pbHash) // the payload should have a hash we can use to verify it.
1597
{
1521
- hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzVerifyPath, hFile);
1598
+ hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext);
1599
ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey);
1600
}
1601
@@ -1881,7 +1958,11 @@ static HRESULT VerifyHash(
1958
__in DWORD cbHash,
1959
__in DWORD64 qwFileSize,
1960
__in_z LPCWSTR wzUnverifiedPayloadPath,
1884
- __in HANDLE hFile
1961
+ __in HANDLE hFile,
1962
+ __in BURN_CACHE_STEP cacheStep,
1963
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
1964
+ __in LPPROGRESS_ROUTINE /*pfnProgress*/,
1965
+ __in LPVOID pContext
1966
)
1967
{
1968
UNREFERENCED_PARAMETER(wzUnverifiedPayloadPath);
@@ -1893,6 +1974,9 @@ static HRESULT VerifyHash(
1974
LPWSTR pszExpected = NULL;
1975
LPWSTR pszActual = NULL;
1976
1977
+ hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep);
1978
+ ExitOnFailure(hr, "Aborted cache verify hash begin.");
1979
+
1980
hr = FileSizeByHandle(hFile, &llSize);
1981
ExitOnFailure(hr, "Failed to get file size for path: %ls", wzUnverifiedPayloadPath);
1982
@@ -1922,9 +2006,64 @@ static HRESULT VerifyHash(
2006
}
2007
}
2008
2009
+ hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize);
2010
+
2011
LExit:
2012
+ SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr);
2013
+
2014
ReleaseStr(pszActual);
2015
ReleaseStr(pszExpected);
2016
2017
return hr;
2018
}
2019
+
2020
+static HRESULT SendCacheBeginMessage(
2021
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
2022
+ __in LPVOID pContext,
2023
+ __in BURN_CACHE_STEP cacheStep
2024
+ )
2025
+{
2026
+ HRESULT hr = S_OK;
2027
+ BURN_CACHE_MESSAGE message = { };
2028
+
2029
+ message.type = BURN_CACHE_MESSAGE_BEGIN;
2030
+ message.begin.cacheStep = cacheStep;
2031
+
2032
+ hr = pfnCacheMessageHandler(&message, pContext);
2033
+
2034
+ return hr;
2035
+}
2036
+
2037
+static HRESULT SendCacheSuccessMessage(
2038
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
2039
+ __in LPVOID pContext,
2040
+ __in DWORD64 qwFileSize
2041
+ )
2042
+{
2043
+ HRESULT hr = S_OK;
2044
+ BURN_CACHE_MESSAGE message = { };
2045
+
2046
+ message.type = BURN_CACHE_MESSAGE_SUCCESS;
2047
+ message.success.qwFileSize = qwFileSize;
2048
+
2049
+ hr = pfnCacheMessageHandler(&message, pContext);
2050
+
2051
+ return hr;
2052
+}
2053
+
2054
+static HRESULT SendCacheCompleteMessage(
2055
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
2056
+ __in LPVOID pContext,
2057
+ __in HRESULT hrStatus
2058
+ )
2059
+{
2060
+ HRESULT hr = S_OK;
2061
+ BURN_CACHE_MESSAGE message = { };
2062
+
2063
+ message.type = BURN_CACHE_MESSAGE_COMPLETE;
2064
+ message.complete.hrStatus = hrStatus;
2065
+
2066
+ hr = pfnCacheMessageHandler(&message, pContext);
2067
+
2068
+ return hr;
2069
+}
src/engine/cache.h
+67
-7
@@ -7,7 +7,48 @@
7
extern "C" {
8
#endif
9
10
-// structs
10
+
11
+enum BURN_CACHE_MESSAGE_TYPE
12
+{
13
+ BURN_CACHE_MESSAGE_BEGIN,
14
+ BURN_CACHE_MESSAGE_SUCCESS,
15
+ BURN_CACHE_MESSAGE_COMPLETE,
16
+};
17
+
18
+enum BURN_CACHE_STEP
19
+{
20
+ BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE,
21
+ BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY,
22
+ BURN_CACHE_STEP_STAGE,
23
+ BURN_CACHE_STEP_HASH,
24
+ BURN_CACHE_STEP_FINALIZE,
25
+};
26
+
27
+typedef struct _BURN_CACHE_MESSAGE
28
+{
29
+ BURN_CACHE_MESSAGE_TYPE type;
30
+
31
+ union
32
+ {
33
+ struct
34
+ {
35
+ BURN_CACHE_STEP cacheStep;
36
+ } begin;
37
+ struct
38
+ {
39
+ DWORD64 qwFileSize;
40
+ } success;
41
+ struct
42
+ {
43
+ HRESULT hrStatus;
44
+ } complete;
45
+ };
46
+} BURN_CACHE_MESSAGE;
47
+
48
+typedef HRESULT(CALLBACK* PFN_BURNCACHEMESSAGEHANDLER)(
49
+ __in BURN_CACHE_MESSAGE* pMessage,
50
+ __in LPVOID pvContext
51
+ );
52
53
// functions
54
@@ -95,7 +136,11 @@ HRESULT CacheBundleToWorkingDirectory(
136
HRESULT CacheLayoutBundle(
137
__in_z LPCWSTR wzExecutableName,
138
__in_z LPCWSTR wzLayoutDirectory,
98
- __in_z LPCWSTR wzSourceBundlePath
139
+ __in_z LPCWSTR wzSourceBundlePath,
140
+ __in DWORD64 qwBundleSize,
141
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
142
+ __in LPPROGRESS_ROUTINE pfnProgress,
143
+ __in LPVOID pContext
144
);
145
HRESULT CacheCompleteBundle(
146
__in BOOL fPerMachine,
@@ -110,28 +155,43 @@ HRESULT CacheLayoutContainer(
155
__in BURN_CONTAINER* pContainer,
156
__in_z_opt LPCWSTR wzLayoutDirectory,
157
__in_z LPCWSTR wzUnverifiedContainerPath,
113
- __in BOOL fMove
158
+ __in BOOL fMove,
159
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
160
+ __in LPPROGRESS_ROUTINE pfnProgress,
161
+ __in LPVOID pContext
162
);
163
HRESULT CacheLayoutPayload(
164
__in BURN_PAYLOAD* pPayload,
165
__in_z_opt LPCWSTR wzLayoutDirectory,
166
__in_z LPCWSTR wzUnverifiedPayloadPath,
119
- __in BOOL fMove
167
+ __in BOOL fMove,
168
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
169
+ __in LPPROGRESS_ROUTINE pfnProgress,
170
+ __in LPVOID pContext
171
);
172
HRESULT CacheCompletePayload(
173
__in BOOL fPerMachine,
174
__in BURN_PAYLOAD* pPayload,
175
__in_z LPCWSTR wzCacheId,
176
__in_z LPCWSTR wzUnverifiedPayloadPath,
126
- __in BOOL fMove
177
+ __in BOOL fMove,
178
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
179
+ __in LPPROGRESS_ROUTINE pfnProgress,
180
+ __in LPVOID pContext
181
);
182
HRESULT CacheVerifyContainer(
183
__in BURN_CONTAINER* pContainer,
130
- __in_z LPCWSTR wzCachedDirectory
184
+ __in_z LPCWSTR wzCachedDirectory,
185
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
186
+ __in LPPROGRESS_ROUTINE pfnProgress,
187
+ __in LPVOID pContext
188
);
189
HRESULT CacheVerifyPayload(
190
__in BURN_PAYLOAD* pPayload,
134
- __in_z LPCWSTR wzCachedDirectory
191
+ __in_z LPCWSTR wzCachedDirectory,
192
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
193
+ __in LPPROGRESS_ROUTINE pfnProgress,
194
+ __in LPVOID pContext
195
);
196
HRESULT CacheRemoveWorkingFolder(
197
__in_z_opt LPCWSTR wzBundleId
src/engine/elevation.cpp
+244
-9
@@ -35,11 +35,15 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
35
BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE,
36
BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN,
37
BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE,
38
+ BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN,
39
+ BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE,
40
+ BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS,
41
BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS,
42
BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR,
43
BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE,
44
BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE,
45
BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID,
46
+ BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE,
47
} BURN_ELEVATION_MESSAGE_TYPE;
48
49
@@ -52,6 +56,13 @@ typedef struct _BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT
56
BOOL fSrpCompleteNeeded;
57
} BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT;
58
59
+typedef struct _BURN_ELEVATION_CACHE_MESSAGE_CONTEXT
60
+{
61
+ PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler;
62
+ LPPROGRESS_ROUTINE pfnProgress;
63
+ LPVOID pvContext;
64
+} BURN_ELEVATION_CACHE_MESSAGE_CONTEXT;
65
+
66
typedef struct _BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT
67
{
68
PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler;
@@ -99,6 +110,11 @@ static HRESULT ProcessApplyInitializeMessages(
110
__in_opt LPVOID pvContext,
111
__out DWORD* pdwResult
112
);
113
+static HRESULT ProcessBurnCacheMessages(
114
+ __in BURN_PIPE_MESSAGE* pMsg,
115
+ __in LPVOID pvContext,
116
+ __out DWORD* pdwResult
117
+ );
118
static HRESULT ProcessGenericExecuteMessages(
119
__in BURN_PIPE_MESSAGE* pMsg,
120
__in LPVOID pvContext,
@@ -114,6 +130,12 @@ static HRESULT ProcessLaunchApprovedExeMessages(
130
__in_opt LPVOID pvContext,
131
__out DWORD* pdwResult
132
);
133
+static HRESULT ProcessProgressRoutineMessage(
134
+ __in BURN_PIPE_MESSAGE* pMsg,
135
+ __in LPPROGRESS_ROUTINE pfnProgress,
136
+ __in LPVOID pvContext,
137
+ __out DWORD* pdwResult
138
+ );
139
static HRESULT ProcessElevatedChildMessage(
140
__in BURN_PIPE_MESSAGE* pMsg,
141
__in_opt LPVOID pvContext,
@@ -165,12 +187,14 @@ static HRESULT OnSaveState(
187
__in DWORD cbData
188
);
189
static HRESULT OnCacheCompletePayload(
190
+ __in HANDLE hPipe,
191
__in BURN_PACKAGES* pPackages,
192
__in BURN_PAYLOADS* pPayloads,
193
__in BYTE* pbData,
194
__in DWORD cbData
195
);
196
static HRESULT OnCacheVerifyPayload(
197
+ __in HANDLE hPipe,
198
__in BURN_PACKAGES* pPackages,
199
__in BURN_PAYLOADS* pPayloads,
200
__in BYTE* pbData,
@@ -225,6 +249,21 @@ static HRESULT OnExecutePackageDependencyAction(
249
__in BYTE* pbData,
250
__in DWORD cbData
251
);
252
+static HRESULT CALLBACK BurnCacheMessageHandler(
253
+ __in BURN_CACHE_MESSAGE* pMessage,
254
+ __in LPVOID pvContext
255
+ );
256
+static DWORD CALLBACK ElevatedProgressRoutine(
257
+ __in LARGE_INTEGER TotalFileSize,
258
+ __in LARGE_INTEGER TotalBytesTransferred,
259
+ __in LARGE_INTEGER StreamSize,
260
+ __in LARGE_INTEGER StreamBytesTransferred,
261
+ __in DWORD dwStreamNumber,
262
+ __in DWORD dwCallbackReason,
263
+ __in HANDLE hSourceFile,
264
+ __in HANDLE hDestinationFile,
265
+ __in_opt LPVOID lpData
266
+ );
267
static int GenericExecuteMessageHandler(
268
__in GENERIC_EXECUTE_MESSAGE* pMessage,
269
__in LPVOID pvContext
@@ -582,13 +621,21 @@ extern "C" HRESULT ElevationCacheCompletePayload(
621
__in BURN_PACKAGE* pPackage,
622
__in BURN_PAYLOAD* pPayload,
623
__in_z LPCWSTR wzUnverifiedPath,
585
- __in BOOL fMove
624
+ __in BOOL fMove,
625
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
626
+ __in LPPROGRESS_ROUTINE pfnProgress,
627
+ __in LPVOID pContext
628
)
629
{
630
HRESULT hr = S_OK;
631
BYTE* pbData = NULL;
632
SIZE_T cbData = 0;
633
DWORD dwResult = 0;
634
+ BURN_ELEVATION_CACHE_MESSAGE_CONTEXT context = { };
635
+
636
+ context.pfnCacheMessageHandler = pfnCacheMessageHandler;
637
+ context.pfnProgress = pfnProgress;
638
+ context.pvContext = pContext;
639
640
// serialize message data
641
hr = BuffWriteString(&pbData, &cbData, pPackage->sczId);
@@ -604,7 +651,7 @@ extern "C" HRESULT ElevationCacheCompletePayload(
651
ExitOnFailure(hr, "Failed to write move flag to message buffer.");
652
653
// send message
607
- hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD, pbData, cbData, NULL, NULL, &dwResult);
654
+ hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD, pbData, cbData, ProcessBurnCacheMessages, &context, &dwResult);
655
ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD message to per-machine process.");
656
657
hr = (HRESULT)dwResult;
@@ -618,13 +665,21 @@ LExit:
665
extern "C" HRESULT ElevationCacheVerifyPayload(
666
__in HANDLE hPipe,
667
__in BURN_PACKAGE* pPackage,
621
- __in BURN_PAYLOAD* pPayload
668
+ __in BURN_PAYLOAD* pPayload,
669
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
670
+ __in LPPROGRESS_ROUTINE pfnProgress,
671
+ __in LPVOID pContext
672
)
673
{
674
HRESULT hr = S_OK;
675
BYTE* pbData = NULL;
676
SIZE_T cbData = 0;
677
DWORD dwResult = 0;
678
+ BURN_ELEVATION_CACHE_MESSAGE_CONTEXT context = { };
679
+
680
+ context.pfnCacheMessageHandler = pfnCacheMessageHandler;
681
+ context.pfnProgress = pfnProgress;
682
+ context.pvContext = pContext;
683
684
// serialize message data
685
hr = BuffWriteString(&pbData, &cbData, pPackage->sczId);
@@ -634,7 +689,7 @@ extern "C" HRESULT ElevationCacheVerifyPayload(
689
ExitOnFailure(hr, "Failed to write payload id to message buffer.");
690
691
// send message
637
- hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, pbData, cbData, NULL, NULL, &dwResult);
692
+ hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, pbData, cbData, ProcessBurnCacheMessages, &context, &dwResult);
693
ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD message to per-machine process.");
694
695
hr = (HRESULT)dwResult;
@@ -1377,6 +1432,69 @@ LExit:
1432
return hr;
1433
}
1434
1435
+static HRESULT ProcessBurnCacheMessages(
1436
+ __in BURN_PIPE_MESSAGE* pMsg,
1437
+ __in LPVOID pvContext,
1438
+ __out DWORD* pdwResult
1439
+ )
1440
+{
1441
+ HRESULT hr = S_OK;
1442
+ SIZE_T iData = 0;
1443
+ BURN_ELEVATION_CACHE_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CACHE_MESSAGE_CONTEXT*>(pvContext);
1444
+ BURN_CACHE_MESSAGE message = { };
1445
+ BOOL fProgressRoutine = FALSE;
1446
+
1447
+ // Process the message.
1448
+ switch (pMsg->dwMessage)
1449
+ {
1450
+ case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN:
1451
+ // read message parameters
1452
+ hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&message.begin.cacheStep));
1453
+ ExitOnFailure(hr, "Failed to read begin cache step.");
1454
+
1455
+ message.type = BURN_CACHE_MESSAGE_BEGIN;
1456
+ break;
1457
+
1458
+ case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE:
1459
+ // read message parameters
1460
+ hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&message.complete.hrStatus));
1461
+ ExitOnFailure(hr, "Failed to read complete hresult.");
1462
+
1463
+ message.type = BURN_CACHE_MESSAGE_COMPLETE;
1464
+ break;
1465
+
1466
+ case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS:
1467
+ // read message parameters
1468
+ hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.success.qwFileSize);
1469
+ ExitOnFailure(hr, "Failed to read begin cache step.");
1470
+
1471
+ message.type = BURN_CACHE_MESSAGE_SUCCESS;
1472
+ break;
1473
+
1474
+ case BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE:
1475
+ fProgressRoutine = TRUE;
1476
+ break;
1477
+
1478
+ default:
1479
+ hr = E_INVALIDARG;
1480
+ ExitOnRootFailure(hr, "Invalid burn cache message.");
1481
+ break;
1482
+ }
1483
+
1484
+ if (fProgressRoutine)
1485
+ {
1486
+ hr = ProcessProgressRoutineMessage(pMsg, pContext->pfnProgress, pContext->pvContext, pdwResult);
1487
+ }
1488
+ else
1489
+ {
1490
+ hr = pContext->pfnCacheMessageHandler(&message, pContext->pvContext);
1491
+ *pdwResult = static_cast<DWORD>(hr);
1492
+ }
1493
+
1494
+LExit:
1495
+ return hr;
1496
+}
1497
+
1498
static HRESULT ProcessGenericExecuteMessages(
1499
__in BURN_PIPE_MESSAGE* pMsg,
1500
__in LPVOID pvContext,
@@ -1596,11 +1714,41 @@ LExit:
1714
return hr;
1715
}
1716
1717
+static HRESULT ProcessProgressRoutineMessage(
1718
+ __in BURN_PIPE_MESSAGE* pMsg,
1719
+ __in LPPROGRESS_ROUTINE pfnProgress,
1720
+ __in LPVOID pvContext,
1721
+ __out DWORD* pdwResult
1722
+ )
1723
+{
1724
+ HRESULT hr = S_OK;
1725
+ SIZE_T iData = 0;
1726
+ LARGE_INTEGER liTotalFileSize = { };
1727
+ LARGE_INTEGER liTotalBytesTransferred = { };
1728
+ LARGE_INTEGER liStreamSize = { };
1729
+ LARGE_INTEGER liStreamBytesTransferred = { };
1730
+ DWORD dwStreamNumber = 0;
1731
+ DWORD dwCallbackReason = CALLBACK_CHUNK_FINISHED;
1732
+ HANDLE hSourceFile = INVALID_HANDLE_VALUE;
1733
+ HANDLE hDestinationFile = INVALID_HANDLE_VALUE;
1734
+
1735
+ hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD64*>(&liTotalFileSize.QuadPart));
1736
+ ExitOnFailure(hr, "Failed to read total file size for progress.");
1737
+
1738
+ hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD64*>(&liTotalBytesTransferred.QuadPart));
1739
+ ExitOnFailure(hr, "Failed to read total bytes transferred for progress.");
1740
+
1741
+ *pdwResult = pfnProgress(liTotalFileSize, liTotalBytesTransferred, liStreamSize, liStreamBytesTransferred, dwStreamNumber, dwCallbackReason, hSourceFile, hDestinationFile, pvContext);
1742
+
1743
+LExit:
1744
+ return hr;
1745
+}
1746
+
1747
static HRESULT ProcessElevatedChildMessage(
1748
__in BURN_PIPE_MESSAGE* pMsg,
1749
__in_opt LPVOID pvContext,
1750
__out DWORD* pdwResult
1603
-)
1751
+ )
1752
{
1753
HRESULT hr = S_OK;
1754
BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CHILD_MESSAGE_CONTEXT*>(pvContext);
@@ -1705,11 +1853,11 @@ static HRESULT ProcessElevatedChildCacheMessage(
1853
switch (pMsg->dwMessage)
1854
{
1855
case BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD:
1708
- hrResult = OnCacheCompletePayload(pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
1856
+ hrResult = OnCacheCompletePayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
1857
break;
1858
1859
case BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD:
1712
- hrResult = OnCacheVerifyPayload(pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
1860
+ hrResult = OnCacheVerifyPayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
1861
break;
1862
1863
case BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP:
@@ -2002,6 +2150,7 @@ LExit:
2150
}
2151
2152
static HRESULT OnCacheCompletePayload(
2153
+ __in HANDLE hPipe,
2154
__in BURN_PACKAGES* pPackages,
2155
__in BURN_PAYLOADS* pPayloads,
2156
__in BYTE* pbData,
@@ -2043,7 +2192,7 @@ static HRESULT OnCacheCompletePayload(
2192
2193
if (pPackage && pPayload) // complete payload.
2194
{
2046
- hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove);
2195
+ hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe);
2196
ExitOnFailure(hr, "Failed to cache payload: %ls", pPayload->sczKey);
2197
}
2198
else
@@ -2060,6 +2209,7 @@ LExit:
2209
}
2210
2211
static HRESULT OnCacheVerifyPayload(
2212
+ __in HANDLE hPipe,
2213
__in BURN_PACKAGES* pPackages,
2214
__in BURN_PAYLOADS* pPayloads,
2215
__in BYTE* pbData,
@@ -2097,7 +2247,7 @@ static HRESULT OnCacheVerifyPayload(
2247
hr = CacheGetCompletedPath(TRUE, pPackage->sczCacheId, &sczCacheDirectory);
2248
ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId);
2249
2100
- hr = CacheVerifyPayload(pPayload, sczCacheDirectory);
2250
+ hr = CacheVerifyPayload(pPayload, sczCacheDirectory, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe);
2251
}
2252
else
2253
{
@@ -2573,6 +2723,91 @@ LExit:
2723
return hr;
2724
}
2725
2726
+static HRESULT CALLBACK BurnCacheMessageHandler(
2727
+ __in BURN_CACHE_MESSAGE* pMessage,
2728
+ __in LPVOID pvContext
2729
+ )
2730
+{
2731
+ HRESULT hr = S_OK;
2732
+ DWORD dwResult = 0;
2733
+ HANDLE hPipe = (HANDLE)pvContext;
2734
+ BYTE* pbData = NULL;
2735
+ SIZE_T cbData = 0;
2736
+ DWORD dwMessage = 0;
2737
+
2738
+ switch (pMessage->type)
2739
+ {
2740
+ case BURN_CACHE_MESSAGE_BEGIN:
2741
+ // serialize message data
2742
+ hr = BuffWriteNumber(&pbData, &cbData, pMessage->begin.cacheStep);
2743
+ ExitOnFailure(hr, "Failed to write progress percentage to message buffer.");
2744
+
2745
+ dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN;
2746
+ break;
2747
+
2748
+ case BURN_CACHE_MESSAGE_COMPLETE:
2749
+ // serialize message data
2750
+ hr = BuffWriteNumber(&pbData, &cbData, pMessage->complete.hrStatus);
2751
+ ExitOnFailure(hr, "Failed to write error code to message buffer.");
2752
+
2753
+ dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE;
2754
+ break;
2755
+
2756
+ case BURN_CACHE_MESSAGE_SUCCESS:
2757
+ hr = BuffWriteNumber64(&pbData, &cbData, pMessage->success.qwFileSize);
2758
+ ExitOnFailure(hr, "Failed to count of files in use to message buffer.");
2759
+
2760
+ dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS;
2761
+ break;
2762
+ }
2763
+
2764
+ // send message
2765
+ hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, &dwResult);
2766
+ ExitOnFailure(hr, "Failed to send burn cache message to per-user process.");
2767
+
2768
+ hr = dwResult;
2769
+
2770
+LExit:
2771
+ ReleaseBuffer(pbData);
2772
+
2773
+ return hr;
2774
+}
2775
+
2776
+static DWORD CALLBACK ElevatedProgressRoutine(
2777
+ __in LARGE_INTEGER TotalFileSize,
2778
+ __in LARGE_INTEGER TotalBytesTransferred,
2779
+ __in LARGE_INTEGER /*StreamSize*/,
2780
+ __in LARGE_INTEGER /*StreamBytesTransferred*/,
2781
+ __in DWORD /*dwStreamNumber*/,
2782
+ __in DWORD /*dwCallbackReason*/,
2783
+ __in HANDLE /*hSourceFile*/,
2784
+ __in HANDLE /*hDestinationFile*/,
2785
+ __in_opt LPVOID lpData
2786
+ )
2787
+{
2788
+ HRESULT hr = S_OK;
2789
+ DWORD dwResult = 0;
2790
+ HANDLE hPipe = (HANDLE)lpData;
2791
+ BYTE* pbData = NULL;
2792
+ SIZE_T cbData = 0;
2793
+ DWORD dwMessage = BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE;
2794
+
2795
+ hr = BuffWriteNumber64(&pbData, &cbData, TotalFileSize.QuadPart);
2796
+ ExitOnFailure(hr, "Failed to write total file size progress to message buffer.");
2797
+
2798
+ hr = BuffWriteNumber64(&pbData, &cbData, TotalBytesTransferred.QuadPart);
2799
+ ExitOnFailure(hr, "Failed to write total bytes transferred progress to message buffer.");
2800
+
2801
+ // send message
2802
+ hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, &dwResult);
2803
+ ExitOnFailure(hr, "Failed to send progress routine message to per-user process.");
2804
+
2805
+LExit:
2806
+ ReleaseBuffer(pbData);
2807
+
2808
+ return dwResult;
2809
+}
2810
+
2811
static int GenericExecuteMessageHandler(
2812
__in GENERIC_EXECUTE_MESSAGE* pMessage,
2813
__in LPVOID pvContext
src/engine/elevation.h
+8
-2
@@ -55,12 +55,18 @@ HRESULT ElevationCacheCompletePayload(
55
__in BURN_PACKAGE* pPackage,
56
__in BURN_PAYLOAD* pPayload,
57
__in_z LPCWSTR wzUnverifiedPath,
58
- __in BOOL fMove
58
+ __in BOOL fMove,
59
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
60
+ __in LPPROGRESS_ROUTINE pfnProgress,
61
+ __in LPVOID pContext
62
);
63
HRESULT ElevationCacheVerifyPayload(
64
__in HANDLE hPipe,
65
__in BURN_PACKAGE* pPackage,
63
- __in BURN_PAYLOAD* pPayload
66
+ __in BURN_PAYLOAD* pPayload,
67
+ __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
68
+ __in LPPROGRESS_ROUTINE pfnProgress,
69
+ __in LPVOID pContext
70
);
71
HRESULT ElevationCacheCleanup(
72
__in HANDLE hPipe
src/engine/plan.cpp
+12
-6
@@ -431,8 +431,8 @@ extern "C" HRESULT PlanLayoutBundle(
431
pCacheAction->bundleLayout.qwBundleSize = qwBundleSize;
432
pCacheAction->bundleLayout.pPayloadGroup = pLayoutPayloads;
433
434
- // Acquire + Verify
435
- pPlan->qwCacheSizeTotal += 2 * qwBundleSize;
434
+ // Acquire + Verify + Finalize
435
+ pPlan->qwCacheSizeTotal += 3 * qwBundleSize;
436
437
++pPlan->cOverallProgressTicksTotal;
438
@@ -1006,8 +1006,8 @@ extern "C" HRESULT PlanLayoutContainer(
1006
pCacheAction->type = BURN_CACHE_ACTION_TYPE_CONTAINER;
1007
pCacheAction->container.pContainer = pContainer;
1008
1009
- // Acquire + Verify
1010
- pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize;
1009
+ // Acquire + Verify + Finalize
1010
+ pPlan->qwCacheSizeTotal += 3 * pContainer->qwFileSize;
1011
}
1012
}
1013
else
@@ -2249,8 +2249,14 @@ static HRESULT ProcessPayloadGroup(
2249
2250
if (!pPlan->sczLayoutDirectory || !pPayload->pContainer)
2251
{
2252
- // Acquire + Verify
2253
- pPlan->qwCacheSizeTotal += 2 * pPayload->qwFileSize;
2252
+ // Acquire + Verify + Finalize
2253
+ pPlan->qwCacheSizeTotal += 3 * pPayload->qwFileSize;
2254
+
2255
+ if (!pPlan->sczLayoutDirectory)
2256
+ {
2257
+ // Staging
2258
+ pPlan->qwCacheSizeTotal += pPayload->qwFileSize;
2259
+ }
2260
}
2261
2262
if (!pPlan->sczLayoutDirectory && pPayload->pContainer && 1 == pPayload->cRemainingInstances)
src/engine/userexperience.cpp
+3
-1
@@ -912,7 +912,8 @@ EXTERN_C BAAPI UserExperienceOnCacheVerifyProgress(
912
__in_z_opt LPCWSTR wzPayloadId,
913
__in DWORD64 dw64Progress,
914
__in DWORD64 dw64Total,
915
- __in DWORD dwOverallPercentage
915
+ __in DWORD dwOverallPercentage,
916
+ __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep
917
)
918
{
919
HRESULT hr = S_OK;
@@ -925,6 +926,7 @@ EXTERN_C BAAPI UserExperienceOnCacheVerifyProgress(
926
args.dw64Progress = dw64Progress;
927
args.dw64Total = dw64Total;
928
args.dwOverallPercentage = dwOverallPercentage;
929
+ args.verifyStep = verifyStep;
930
931
results.cbSize = sizeof(results);
932
src/engine/userexperience.h
+2
-1
@@ -233,7 +233,8 @@ BAAPI UserExperienceOnCacheVerifyProgress(
233
__in_z_opt LPCWSTR wzPayloadId,
234
__in DWORD64 dw64Progress,
235
__in DWORD64 dw64Total,
236
- __in DWORD dwOverallPercentage
236
+ __in DWORD dwOverallPercentage,
237
+ __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep
238
);
239
BAAPI UserExperienceOnCommitMsiTransactionBegin(
240
__in BURN_USER_EXPERIENCE* pUserExperience,
src/test/BurnUnitTest/CacheTest.cpp
+45
-1
@@ -2,6 +2,26 @@
2
3
#include "precomp.h"
4
5
+static HRESULT CALLBACK CacheTestEventRoutine(
6
+ __in BURN_CACHE_MESSAGE* pMessage,
7
+ __in LPVOID pvContext
8
+ );
9
+
10
+static DWORD CALLBACK CacheTestProgressRoutine(
11
+ __in LARGE_INTEGER TotalFileSize,
12
+ __in LARGE_INTEGER TotalBytesTransferred,
13
+ __in LARGE_INTEGER StreamSize,
14
+ __in LARGE_INTEGER StreamBytesTransferred,
15
+ __in DWORD dwStreamNumber,
16
+ __in DWORD dwCallbackReason,
17
+ __in HANDLE hSourceFile,
18
+ __in HANDLE hDestinationFile,
19
+ __in_opt LPVOID lpData
20
+ );
21
+
22
+typedef struct _CACHE_TEST_CONTEXT
23
+{
24
+} CACHE_TEST_CONTEXT;
25
26
namespace Microsoft
27
{
@@ -33,6 +53,7 @@ namespace Bootstrapper
53
LPWSTR sczPayloadPath = NULL;
54
BYTE* pb = NULL;
55
DWORD cb = NULL;
56
+ CACHE_TEST_CONTEXT context = { };
57
58
try
59
{
@@ -51,7 +72,7 @@ namespace Bootstrapper
72
payload.pbHash = pb;
73
payload.cbHash = cb;
74
54
- hr = CacheCompletePayload(package.fPerMachine, &payload, package.sczCacheId, sczPayloadPath, FALSE);
75
+ hr = CacheCompletePayload(package.fPerMachine, &payload, package.sczCacheId, sczPayloadPath, FALSE, CacheTestEventRoutine, CacheTestProgressRoutine, &context);
76
Assert::Equal(S_OK, hr);
77
}
78
finally
@@ -73,3 +94,26 @@ namespace Bootstrapper
94
}
95
}
96
}
97
+
98
+static HRESULT CALLBACK CacheTestEventRoutine(
99
+ __in BURN_CACHE_MESSAGE* /*pMessage*/,
100
+ __in LPVOID /*pvContext*/
101
+ )
102
+{
103
+ return S_OK;
104
+}
105
+
106
+static DWORD CALLBACK CacheTestProgressRoutine(
107
+ __in LARGE_INTEGER /*TotalFileSize*/,
108
+ __in LARGE_INTEGER /*TotalBytesTransferred*/,
109
+ __in LARGE_INTEGER /*StreamSize*/,
110
+ __in LARGE_INTEGER /*StreamBytesTransferred*/,
111
+ __in DWORD /*dwStreamNumber*/,
112
+ __in DWORD /*dwCallbackReason*/,
113
+ __in HANDLE /*hSourceFile*/,
114
+ __in HANDLE /*hDestinationFile*/,
115
+ __in_opt LPVOID /*lpData*/
116
+ )
117
+{
118
+ return PROGRESS_QUIET;
119
+}
src/test/BurnUnitTest/PlanTest.cpp
+5
-5
@@ -71,7 +71,7 @@ namespace Bootstrapper
71
Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
72
73
Assert::Equal(107082ull, pPlan->qwEstimatedSize);
74
- Assert::Equal(303687ull, pPlan->qwCacheSizeTotal);
74
+ Assert::Equal(506145ull, pPlan->qwCacheSizeTotal);
75
76
fRollback = FALSE;
77
dwIndex = 0;
@@ -308,7 +308,7 @@ namespace Bootstrapper
308
Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
309
310
Assert::Equal(35694ull, pPlan->qwEstimatedSize);
311
- Assert::Equal(101229ull, pPlan->qwCacheSizeTotal);
311
+ Assert::Equal(168715ull, pPlan->qwCacheSizeTotal);
312
313
fRollback = FALSE;
314
dwIndex = 0;
@@ -388,7 +388,7 @@ namespace Bootstrapper
388
Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
389
390
Assert::Equal(33743ull, pPlan->qwEstimatedSize);
391
- Assert::Equal(101229ull, pPlan->qwCacheSizeTotal);
391
+ Assert::Equal(168715ull, pPlan->qwCacheSizeTotal);
392
393
fRollback = FALSE;
394
dwIndex = 0;
@@ -458,7 +458,7 @@ namespace Bootstrapper
458
Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
459
460
Assert::Equal(35694ull, pPlan->qwEstimatedSize);
461
- Assert::Equal(101229ull, pPlan->qwCacheSizeTotal);
461
+ Assert::Equal(168715ull, pPlan->qwCacheSizeTotal);
462
463
fRollback = FALSE;
464
dwIndex = 0;
@@ -739,7 +739,7 @@ namespace Bootstrapper
739
Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
740
741
Assert::Equal(3055111ull, pPlan->qwEstimatedSize);
742
- Assert::Equal(106496ull, pPlan->qwCacheSizeTotal);
742
+ Assert::Equal(212992ull, pPlan->qwCacheSizeTotal);
743
744
fRollback = FALSE;
745
dwIndex = 0;