diff options
Diffstat (limited to '')
-rw-r--r-- | src/engine/cache.cpp | 263 |
1 files changed, 201 insertions, 62 deletions
diff --git a/src/engine/cache.cpp b/src/engine/cache.cpp index 9aa94d1d..16f2c1e5 100644 --- a/src/engine/cache.cpp +++ b/src/engine/cache.cpp | |||
@@ -44,28 +44,47 @@ static HRESULT VerifyThenTransferContainer( | |||
44 | __in BURN_CONTAINER* pContainer, | 44 | __in BURN_CONTAINER* pContainer, |
45 | __in_z LPCWSTR wzCachedPath, | 45 | __in_z LPCWSTR wzCachedPath, |
46 | __in_z LPCWSTR wzUnverifiedContainerPath, | 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 | ||
48 | ); | 51 | ); |
49 | static HRESULT VerifyThenTransferPayload( | 52 | static HRESULT VerifyThenTransferPayload( |
50 | __in BURN_PAYLOAD* pPayload, | 53 | __in BURN_PAYLOAD* pPayload, |
51 | __in_z LPCWSTR wzCachedPath, | 54 | __in_z LPCWSTR wzCachedPath, |
52 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 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 | ||
54 | ); | 60 | ); |
55 | static HRESULT TransferWorkingPathToUnverifiedPath( | 61 | static HRESULT CacheTransferFileWithRetry( |
56 | __in_z LPCWSTR wzWorkingPath, | 62 | __in_z LPCWSTR wzSourcePath, |
57 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 63 | __in_z LPCWSTR wzDestinationPath, |
58 | __in BOOL fMove | 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 | ||
59 | ); | 70 | ); |
60 | static HRESULT VerifyFileAgainstContainer( | 71 | static HRESULT VerifyFileAgainstContainer( |
61 | __in BURN_CONTAINER* pContainer, | 72 | __in BURN_CONTAINER* pContainer, |
62 | __in_z LPCWSTR wzVerifyPath, | 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 | ||
64 | ); | 79 | ); |
65 | static HRESULT VerifyFileAgainstPayload( | 80 | static HRESULT VerifyFileAgainstPayload( |
66 | __in BURN_PAYLOAD* pPayload, | 81 | __in BURN_PAYLOAD* pPayload, |
67 | __in_z LPCWSTR wzVerifyPath, | 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 | ||
69 | ); | 88 | ); |
70 | static HRESULT ResetPathPermissions( | 89 | static HRESULT ResetPathPermissions( |
71 | __in BOOL fPerMachine, | 90 | __in BOOL fPerMachine, |
@@ -99,7 +118,26 @@ static HRESULT VerifyHash( | |||
99 | __in DWORD cbHash, | 118 | __in DWORD cbHash, |
100 | __in DWORD64 qwFileSize, | 119 | __in DWORD64 qwFileSize, |
101 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 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 | ||
103 | ); | 141 | ); |
104 | 142 | ||
105 | 143 | ||
@@ -754,7 +792,11 @@ LExit: | |||
754 | extern "C" HRESULT CacheLayoutBundle( | 792 | extern "C" HRESULT CacheLayoutBundle( |
755 | __in_z LPCWSTR wzExecutableName, | 793 | __in_z LPCWSTR wzExecutableName, |
756 | __in_z LPCWSTR wzLayoutDirectory, | 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 | ||
758 | ) | 800 | ) |
759 | { | 801 | { |
760 | HRESULT hr = S_OK; | 802 | HRESULT hr = S_OK; |
@@ -765,7 +807,7 @@ extern "C" HRESULT CacheLayoutBundle( | |||
765 | 807 | ||
766 | LogStringLine(REPORT_STANDARD, "Layout bundle from: '%ls' to: '%ls'", wzSourceBundlePath, sczTargetPath); | 808 | LogStringLine(REPORT_STANDARD, "Layout bundle from: '%ls' to: '%ls'", wzSourceBundlePath, sczTargetPath); |
767 | 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); |
769 | ExitOnFailure(hr, "Failed to layout bundle from: '%ls' to '%ls'", wzSourceBundlePath, sczTargetPath); | 811 | ExitOnFailure(hr, "Failed to layout bundle from: '%ls' to '%ls'", wzSourceBundlePath, sczTargetPath); |
770 | 812 | ||
771 | LExit: | 813 | LExit: |
@@ -838,7 +880,10 @@ extern "C" HRESULT CacheLayoutContainer( | |||
838 | __in BURN_CONTAINER* pContainer, | 880 | __in BURN_CONTAINER* pContainer, |
839 | __in_z_opt LPCWSTR wzLayoutDirectory, | 881 | __in_z_opt LPCWSTR wzLayoutDirectory, |
840 | __in_z LPCWSTR wzUnverifiedContainerPath, | 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 | ||
842 | ) | 887 | ) |
843 | { | 888 | { |
844 | HRESULT hr = S_OK; | 889 | HRESULT hr = S_OK; |
@@ -847,7 +892,7 @@ extern "C" HRESULT CacheLayoutContainer( | |||
847 | hr = PathConcat(wzLayoutDirectory, pContainer->sczFilePath, &sczCachedPath); | 892 | hr = PathConcat(wzLayoutDirectory, pContainer->sczFilePath, &sczCachedPath); |
848 | ExitOnFailure(hr, "Failed to concat complete cached path."); | 893 | ExitOnFailure(hr, "Failed to concat complete cached path."); |
849 | 894 | ||
850 | hr = VerifyThenTransferContainer(pContainer, sczCachedPath, wzUnverifiedContainerPath, fMove); | 895 | hr = VerifyThenTransferContainer(pContainer, sczCachedPath, wzUnverifiedContainerPath, fMove, pfnCacheMessageHandler, pfnProgress, pContext); |
851 | ExitOnFailure(hr, "Failed to layout container from cached path: %ls", sczCachedPath); | 896 | ExitOnFailure(hr, "Failed to layout container from cached path: %ls", sczCachedPath); |
852 | 897 | ||
853 | LExit: | 898 | LExit: |
@@ -860,7 +905,10 @@ extern "C" HRESULT CacheLayoutPayload( | |||
860 | __in BURN_PAYLOAD* pPayload, | 905 | __in BURN_PAYLOAD* pPayload, |
861 | __in_z_opt LPCWSTR wzLayoutDirectory, | 906 | __in_z_opt LPCWSTR wzLayoutDirectory, |
862 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 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 | ||
864 | ) | 912 | ) |
865 | { | 913 | { |
866 | HRESULT hr = S_OK; | 914 | HRESULT hr = S_OK; |
@@ -869,7 +917,7 @@ extern "C" HRESULT CacheLayoutPayload( | |||
869 | hr = PathConcat(wzLayoutDirectory, pPayload->sczFilePath, &sczCachedPath); | 917 | hr = PathConcat(wzLayoutDirectory, pPayload->sczFilePath, &sczCachedPath); |
870 | ExitOnFailure(hr, "Failed to concat complete cached path."); | 918 | ExitOnFailure(hr, "Failed to concat complete cached path."); |
871 | 919 | ||
872 | hr = VerifyThenTransferPayload(pPayload, sczCachedPath, wzUnverifiedPayloadPath, fMove); | 920 | hr = VerifyThenTransferPayload(pPayload, sczCachedPath, wzUnverifiedPayloadPath, fMove, pfnCacheMessageHandler, pfnProgress, pContext); |
873 | ExitOnFailure(hr, "Failed to layout payload from cached payload: %ls", sczCachedPath); | 921 | ExitOnFailure(hr, "Failed to layout payload from cached payload: %ls", sczCachedPath); |
874 | 922 | ||
875 | LExit: | 923 | LExit: |
@@ -883,7 +931,10 @@ extern "C" HRESULT CacheCompletePayload( | |||
883 | __in BURN_PAYLOAD* pPayload, | 931 | __in BURN_PAYLOAD* pPayload, |
884 | __in_z LPCWSTR wzCacheId, | 932 | __in_z LPCWSTR wzCacheId, |
885 | __in_z LPCWSTR wzWorkingPayloadPath, | 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 | ||
887 | ) | 938 | ) |
888 | { | 939 | { |
889 | HRESULT hr = S_OK; | 940 | HRESULT hr = S_OK; |
@@ -898,7 +949,7 @@ extern "C" HRESULT CacheCompletePayload( | |||
898 | ExitOnFailure(hr, "Failed to concat complete cached path."); | 949 | ExitOnFailure(hr, "Failed to concat complete cached path."); |
899 | 950 | ||
900 | // If the cached file matches what we expected, we're good. | 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); |
902 | if (SUCCEEDED(hr)) | 953 | if (SUCCEEDED(hr)) |
903 | { | 954 | { |
904 | ExitFunction(); | 955 | ExitFunction(); |
@@ -910,10 +961,21 @@ extern "C" HRESULT CacheCompletePayload( | |||
910 | // If the working path exists, let's get it into the unverified path so we can reset the ACLs and verify the file. | 961 | // If the working path exists, let's get it into the unverified path so we can reset the ACLs and verify the file. |
911 | if (FileExistsEx(wzWorkingPayloadPath, NULL)) | 962 | if (FileExistsEx(wzWorkingPayloadPath, NULL)) |
912 | { | 963 | { |
913 | hr = TransferWorkingPathToUnverifiedPath(wzWorkingPayloadPath, sczUnverifiedPayloadPath, fMove); | 964 | hr = CacheTransferFileWithRetry(wzWorkingPayloadPath, sczUnverifiedPayloadPath, fMove, BURN_CACHE_STEP_STAGE, pPayload->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext); |
914 | ExitOnFailure(hr, "Failed to transfer working path to unverified path for payload: %ls.", pPayload->sczKey); | 965 | ExitOnFailure(hr, "Failed to transfer working path to unverified path for payload: %ls.", pPayload->sczKey); |
915 | } | 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. | ||
917 | { | 979 | { |
918 | hr = E_FILENOTFOUND; | 980 | hr = E_FILENOTFOUND; |
919 | ExitOnFailure(hr, "Failed to find payload: %ls in working path: %ls and unverified path: %ls", pPayload->sczKey, wzWorkingPayloadPath, sczUnverifiedPayloadPath); | 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( | |||
922 | hr = ResetPathPermissions(fPerMachine, sczUnverifiedPayloadPath); | 984 | hr = ResetPathPermissions(fPerMachine, sczUnverifiedPayloadPath); |
923 | ExitOnFailure(hr, "Failed to reset permissions on unverified cached payload: %ls", pPayload->sczKey); | 985 | ExitOnFailure(hr, "Failed to reset permissions on unverified cached payload: %ls", pPayload->sczKey); |
924 | 986 | ||
925 | hr = VerifyFileAgainstPayload(pPayload, sczUnverifiedPayloadPath, FALSE); | 987 | hr = VerifyFileAgainstPayload(pPayload, sczUnverifiedPayloadPath, FALSE, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); |
926 | LogExitOnFailure(hr, MSG_FAILED_VERIFY_PAYLOAD, "Failed to verify payload: %ls at path: %ls", pPayload->sczKey, sczUnverifiedPayloadPath, NULL); | 988 | LogExitOnFailure(hr, MSG_FAILED_VERIFY_PAYLOAD, "Failed to verify payload: %ls at path: %ls", pPayload->sczKey, sczUnverifiedPayloadPath, NULL); |
927 | 989 | ||
928 | LogId(REPORT_STANDARD, MSG_VERIFIED_ACQUIRED_PAYLOAD, pPayload->sczKey, sczUnverifiedPayloadPath, fMove ? "moving" : "copying", sczCachedPath); | 990 | LogId(REPORT_STANDARD, MSG_VERIFIED_ACQUIRED_PAYLOAD, pPayload->sczKey, sczUnverifiedPayloadPath, fMove ? "moving" : "copying", sczCachedPath); |
929 | 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); |
931 | ExitOnFailure(hr, "Failed to move verified file to complete payload path: %ls", sczCachedPath); | 993 | ExitOnFailure(hr, "Failed to move verified file to complete payload path: %ls", sczCachedPath); |
932 | 994 | ||
933 | ::DecryptFileW(sczCachedPath, 0); // Let's try to make sure it's not encrypted. | 995 | ::DecryptFileW(sczCachedPath, 0); // Let's try to make sure it's not encrypted. |
@@ -942,7 +1004,10 @@ LExit: | |||
942 | 1004 | ||
943 | extern "C" HRESULT CacheVerifyContainer( | 1005 | extern "C" HRESULT CacheVerifyContainer( |
944 | __in BURN_CONTAINER* pContainer, | 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 | ||
946 | ) | 1011 | ) |
947 | { | 1012 | { |
948 | HRESULT hr = S_OK; | 1013 | HRESULT hr = S_OK; |
@@ -951,7 +1016,7 @@ extern "C" HRESULT CacheVerifyContainer( | |||
951 | hr = PathConcat(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath); | 1016 | hr = PathConcat(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath); |
952 | ExitOnFailure(hr, "Failed to concat complete cached path."); | 1017 | ExitOnFailure(hr, "Failed to concat complete cached path."); |
953 | 1018 | ||
954 | hr = VerifyFileAgainstContainer(pContainer, sczCachedPath, TRUE); | 1019 | hr = VerifyFileAgainstContainer(pContainer, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, pfnCacheMessageHandler, pfnProgress, pContext); |
955 | 1020 | ||
956 | LExit: | 1021 | LExit: |
957 | ReleaseStr(sczCachedPath); | 1022 | ReleaseStr(sczCachedPath); |
@@ -961,7 +1026,10 @@ LExit: | |||
961 | 1026 | ||
962 | extern "C" HRESULT CacheVerifyPayload( | 1027 | extern "C" HRESULT CacheVerifyPayload( |
963 | __in BURN_PAYLOAD* pPayload, | 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 | ||
965 | ) | 1033 | ) |
966 | { | 1034 | { |
967 | HRESULT hr = S_OK; | 1035 | HRESULT hr = S_OK; |
@@ -970,7 +1038,7 @@ extern "C" HRESULT CacheVerifyPayload( | |||
970 | hr = PathConcat(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath); | 1038 | hr = PathConcat(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath); |
971 | ExitOnFailure(hr, "Failed to concat complete cached path."); | 1039 | ExitOnFailure(hr, "Failed to concat complete cached path."); |
972 | 1040 | ||
973 | hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE); | 1041 | hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, pfnCacheMessageHandler, pfnProgress, pContext); |
974 | 1042 | ||
975 | LExit: | 1043 | LExit: |
976 | ReleaseStr(sczCachedPath); | 1044 | ReleaseStr(sczCachedPath); |
@@ -1342,7 +1410,10 @@ static HRESULT VerifyThenTransferContainer( | |||
1342 | __in BURN_CONTAINER* pContainer, | 1410 | __in BURN_CONTAINER* pContainer, |
1343 | __in_z LPCWSTR wzCachedPath, | 1411 | __in_z LPCWSTR wzCachedPath, |
1344 | __in_z LPCWSTR wzUnverifiedContainerPath, | 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 | ||
1346 | ) | 1417 | ) |
1347 | { | 1418 | { |
1348 | HRESULT hr = S_OK; | 1419 | HRESULT hr = S_OK; |
@@ -1358,22 +1429,13 @@ static HRESULT VerifyThenTransferContainer( | |||
1358 | // Container should have a hash we can use to verify with. | 1429 | // Container should have a hash we can use to verify with. |
1359 | if (pContainer->pbHash) | 1430 | if (pContainer->pbHash) |
1360 | { | 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); |
1362 | ExitOnFailure(hr, "Failed to verify container hash: %ls", wzCachedPath); | 1433 | ExitOnFailure(hr, "Failed to verify container hash: %ls", wzCachedPath); |
1363 | } | 1434 | } |
1364 | 1435 | ||
1365 | LogStringLine(REPORT_STANDARD, "%ls container from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedContainerPath, wzCachedPath); | 1436 | LogStringLine(REPORT_STANDARD, "%ls container from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedContainerPath, wzCachedPath); |
1366 | 1437 | ||
1367 | if (fMove) | 1438 | hr = CacheTransferFileWithRetry(wzUnverifiedContainerPath, wzCachedPath, fMove, BURN_CACHE_STEP_FINALIZE, pContainer->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext); |
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 | } | ||
1377 | 1439 | ||
1378 | LExit: | 1440 | LExit: |
1379 | ReleaseFileHandle(hFile); | 1441 | ReleaseFileHandle(hFile); |
@@ -1385,7 +1447,10 @@ static HRESULT VerifyThenTransferPayload( | |||
1385 | __in BURN_PAYLOAD* pPayload, | 1447 | __in BURN_PAYLOAD* pPayload, |
1386 | __in_z LPCWSTR wzCachedPath, | 1448 | __in_z LPCWSTR wzCachedPath, |
1387 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 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 | ||
1389 | ) | 1454 | ) |
1390 | { | 1455 | { |
1391 | HRESULT hr = S_OK; | 1456 | HRESULT hr = S_OK; |
@@ -1400,22 +1465,13 @@ static HRESULT VerifyThenTransferPayload( | |||
1400 | 1465 | ||
1401 | if (pPayload->pbHash) // the payload should have a hash we can use to verify it. | 1466 | if (pPayload->pbHash) // the payload should have a hash we can use to verify it. |
1402 | { | 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); |
1404 | ExitOnFailure(hr, "Failed to verify payload hash: %ls", wzCachedPath); | 1469 | ExitOnFailure(hr, "Failed to verify payload hash: %ls", wzCachedPath); |
1405 | } | 1470 | } |
1406 | 1471 | ||
1407 | LogStringLine(REPORT_STANDARD, "%ls payload from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedPayloadPath, wzCachedPath); | 1472 | LogStringLine(REPORT_STANDARD, "%ls payload from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedPayloadPath, wzCachedPath); |
1408 | 1473 | ||
1409 | if (fMove) | 1474 | hr = CacheTransferFileWithRetry(wzUnverifiedPayloadPath, wzCachedPath, fMove, BURN_CACHE_STEP_FINALIZE, pPayload->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext); |
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 | } | ||
1419 | 1475 | ||
1420 | LExit: | 1476 | LExit: |
1421 | ReleaseFileHandle(hFile); | 1477 | ReleaseFileHandle(hFile); |
@@ -1423,33 +1479,50 @@ LExit: | |||
1423 | return hr; | 1479 | return hr; |
1424 | } | 1480 | } |
1425 | 1481 | ||
1426 | static HRESULT TransferWorkingPathToUnverifiedPath( | 1482 | static HRESULT CacheTransferFileWithRetry( |
1427 | __in_z LPCWSTR wzWorkingPath, | 1483 | __in_z LPCWSTR wzSourcePath, |
1428 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 1484 | __in_z LPCWSTR wzDestinationPath, |
1429 | __in BOOL fMove | 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 | ||
1430 | ) | 1491 | ) |
1431 | { | 1492 | { |
1432 | HRESULT hr = S_OK; | 1493 | HRESULT hr = S_OK; |
1433 | 1494 | ||
1495 | hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); | ||
1496 | ExitOnFailure(hr, "Aborted cache file transfer begin."); | ||
1497 | |||
1498 | // TODO: send progress during the file transfer. | ||
1434 | if (fMove) | 1499 | if (fMove) |
1435 | { | 1500 | { |
1436 | hr = FileEnsureMoveWithRetry(wzWorkingPath, wzUnverifiedPayloadPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); | 1501 | hr = FileEnsureMoveWithRetry(wzSourcePath, wzDestinationPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); |
1437 | ExitOnFailure(hr, "Failed to move %ls to %ls", wzWorkingPath, wzUnverifiedPayloadPath); | 1502 | ExitOnFailure(hr, "Failed to move %ls to %ls", wzSourcePath, wzDestinationPath); |
1438 | } | 1503 | } |
1439 | else | 1504 | else |
1440 | { | 1505 | { |
1441 | hr = FileEnsureCopyWithRetry(wzWorkingPath, wzUnverifiedPayloadPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); | 1506 | hr = FileEnsureCopyWithRetry(wzSourcePath, wzDestinationPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); |
1442 | ExitOnFailure(hr, "Failed to copy %ls to %ls", wzWorkingPath, wzUnverifiedPayloadPath); | 1507 | ExitOnFailure(hr, "Failed to copy %ls to %ls", wzSourcePath, wzDestinationPath); |
1443 | } | 1508 | } |
1444 | 1509 | ||
1510 | hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize); | ||
1511 | |||
1445 | LExit: | 1512 | LExit: |
1513 | SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); | ||
1514 | |||
1446 | return hr; | 1515 | return hr; |
1447 | } | 1516 | } |
1448 | 1517 | ||
1449 | static HRESULT VerifyFileAgainstContainer( | 1518 | static HRESULT VerifyFileAgainstContainer( |
1450 | __in BURN_CONTAINER* pContainer, | 1519 | __in BURN_CONTAINER* pContainer, |
1451 | __in_z LPCWSTR wzVerifyPath, | 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 | ||
1453 | ) | 1526 | ) |
1454 | { | 1527 | { |
1455 | HRESULT hr = S_OK; | 1528 | HRESULT hr = S_OK; |
@@ -1469,7 +1542,7 @@ static HRESULT VerifyFileAgainstContainer( | |||
1469 | 1542 | ||
1470 | if (pContainer->pbHash) // the container should have a hash we can use to verify it. | 1543 | if (pContainer->pbHash) // the container should have a hash we can use to verify it. |
1471 | { | 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); |
1473 | ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId); | 1546 | ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId); |
1474 | } | 1547 | } |
1475 | 1548 | ||
@@ -1498,7 +1571,11 @@ LExit: | |||
1498 | static HRESULT VerifyFileAgainstPayload( | 1571 | static HRESULT VerifyFileAgainstPayload( |
1499 | __in BURN_PAYLOAD* pPayload, | 1572 | __in BURN_PAYLOAD* pPayload, |
1500 | __in_z LPCWSTR wzVerifyPath, | 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 | ||
1502 | ) | 1579 | ) |
1503 | { | 1580 | { |
1504 | HRESULT hr = S_OK; | 1581 | HRESULT hr = S_OK; |
@@ -1518,7 +1595,7 @@ static HRESULT VerifyFileAgainstPayload( | |||
1518 | 1595 | ||
1519 | if (pPayload->pbHash) // the payload should have a hash we can use to verify it. | 1596 | if (pPayload->pbHash) // the payload should have a hash we can use to verify it. |
1520 | { | 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); |
1522 | ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey); | 1599 | ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey); |
1523 | } | 1600 | } |
1524 | 1601 | ||
@@ -1881,7 +1958,11 @@ static HRESULT VerifyHash( | |||
1881 | __in DWORD cbHash, | 1958 | __in DWORD cbHash, |
1882 | __in DWORD64 qwFileSize, | 1959 | __in DWORD64 qwFileSize, |
1883 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 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 | ||
1885 | ) | 1966 | ) |
1886 | { | 1967 | { |
1887 | UNREFERENCED_PARAMETER(wzUnverifiedPayloadPath); | 1968 | UNREFERENCED_PARAMETER(wzUnverifiedPayloadPath); |
@@ -1893,6 +1974,9 @@ static HRESULT VerifyHash( | |||
1893 | LPWSTR pszExpected = NULL; | 1974 | LPWSTR pszExpected = NULL; |
1894 | LPWSTR pszActual = NULL; | 1975 | LPWSTR pszActual = NULL; |
1895 | 1976 | ||
1977 | hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); | ||
1978 | ExitOnFailure(hr, "Aborted cache verify hash begin."); | ||
1979 | |||
1896 | hr = FileSizeByHandle(hFile, &llSize); | 1980 | hr = FileSizeByHandle(hFile, &llSize); |
1897 | ExitOnFailure(hr, "Failed to get file size for path: %ls", wzUnverifiedPayloadPath); | 1981 | ExitOnFailure(hr, "Failed to get file size for path: %ls", wzUnverifiedPayloadPath); |
1898 | 1982 | ||
@@ -1922,9 +2006,64 @@ static HRESULT VerifyHash( | |||
1922 | } | 2006 | } |
1923 | } | 2007 | } |
1924 | 2008 | ||
2009 | hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize); | ||
2010 | |||
1925 | LExit: | 2011 | LExit: |
2012 | SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); | ||
2013 | |||
1926 | ReleaseStr(pszActual); | 2014 | ReleaseStr(pszActual); |
1927 | ReleaseStr(pszExpected); | 2015 | ReleaseStr(pszExpected); |
1928 | 2016 | ||
1929 | return hr; | 2017 | return hr; |
1930 | } | 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 | } | ||