@joebigelow / wix / commits / b1d1e523

Add OnCachePayloadExtract*.

Sean Hall committed Apr 16, 2021 at 13:38 UTC b1d1e523f5cdadce0cbf105179b33c014d5ec9eb
6 files changed +207 -4
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+45
@@ -153,6 +153,9 @@ enum BOOTSTRAPPER_APPLICATION_MESSAGE
153 BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN,
154 BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE,
155 BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS,
156 + BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN,
157 + BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE,
158 + BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS,
159 };
160
161 enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION
@@ -472,6 +475,48 @@ struct BA_ONCACHEPACKAGECOMPLETE_RESULTS
475 BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION action;
476 };
477
478 +struct BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS
479 +{
480 + DWORD cbSize;
481 + LPCWSTR wzContainerId;
482 + LPCWSTR wzPayloadId;
483 +};
484 +
485 +struct BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS
486 +{
487 + DWORD cbSize;
488 + BOOL fCancel;
489 +};
490 +
491 +struct BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS
492 +{
493 + DWORD cbSize;
494 + LPCWSTR wzContainerId;
495 + LPCWSTR wzPayloadId;
496 + HRESULT hrStatus;
497 +};
498 +
499 +struct BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS
500 +{
501 + DWORD cbSize;
502 +};
503 +
504 +struct BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS
505 +{
506 + DWORD cbSize;
507 + LPCWSTR wzContainerId;
508 + LPCWSTR wzPayloadId;
509 + DWORD64 dw64Progress;
510 + DWORD64 dw64Total;
511 + DWORD dwOverallPercentage;
512 +};
513 +
514 +struct BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS
515 +{
516 + DWORD cbSize;
517 + BOOL fCancel;
518 +};
519 +
520 struct BA_ONCACHEVERIFYBEGIN_ARGS
521 {
522 DWORD cbSize;
src/engine/apply.cpp
+54 -4
@@ -16,6 +16,7 @@ enum BURN_CACHE_PROGRESS_TYPE
16 BURN_CACHE_PROGRESS_TYPE_ACQUIRE,
17 BURN_CACHE_PROGRESS_TYPE_VERIFY,
18 BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY,
19 + BURN_CACHE_PROGRESS_TYPE_EXTRACT,
20 };
21
22 // structs
@@ -43,6 +44,7 @@ typedef struct _BURN_CACHE_PROGRESS_CONTEXT
44 BURN_CONTAINER* pContainer;
45 BURN_PACKAGE* pPackage;
46 BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem;
47 + BURN_PAYLOAD* pPayload;
48
49 BOOL fCancel;
50 HRESULT hrError;
@@ -875,6 +877,12 @@ static HRESULT ApplyExtractContainer(
877 pContainer->qwCommittedCacheProgress = 0;
878 }
879
880 + if (pContainer->qwCommittedExtractProgress)
881 + {
882 + pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedExtractProgress;
883 + pContainer->qwCommittedExtractProgress = 0;
884 + }
885 +
886 if (!pContainer->fActuallyAttached)
887 {
888 hr = ApplyAcquireContainerOrPayload(pContext, pContainer, NULL, NULL);
@@ -890,8 +898,18 @@ static HRESULT ApplyExtractContainer(
898 CacheSetLastUsedSource(pContext->pVariables, pContext->sczLastUsedFolderCandidate, pContainer->sczFilePath);
899 }
900
893 - pContext->qwSuccessfulCacheProgress += pContainer->qwExtractSizeTotal;
894 - pContainer->qwCommittedCacheProgress += pContainer->qwExtractSizeTotal;
901 + if (pContainer->qwExtractSizeTotal < pContainer->qwCommittedExtractProgress)
902 + {
903 + AssertSz(FALSE, "Container extracted more than planned.");
904 + pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedExtractProgress;
905 + pContext->qwSuccessfulCacheProgress += pContainer->qwExtractSizeTotal;
906 + }
907 + else
908 + {
909 + pContext->qwSuccessfulCacheProgress += pContainer->qwExtractSizeTotal - pContainer->qwCommittedExtractProgress;
910 + }
911 +
912 + pContainer->qwCommittedExtractProgress = pContainer->qwExtractSizeTotal;
913
914 LExit:
915 ReleaseNullStr(pContext->sczLastUsedFolderCandidate);
@@ -1100,6 +1118,11 @@ static HRESULT ExtractContainer(
1118 BURN_CONTAINER_CONTEXT context = { };
1119 HANDLE hContainerHandle = INVALID_HANDLE_VALUE;
1120 LPWSTR sczExtractPayloadId = NULL;
1121 + BURN_CACHE_PROGRESS_CONTEXT progress = { };
1122 +
1123 + progress.pCacheContext = pContext;
1124 + progress.pContainer = pContainer;
1125 + progress.type = BURN_CACHE_PROGRESS_TYPE_EXTRACT;
1126
1127 // If the container is actually attached, then it was planned to be acquired through hSourceEngineFile.
1128 if (pContainer->fActuallyAttached)
@@ -1119,11 +1142,29 @@ static HRESULT ExtractContainer(
1142 BURN_PAYLOAD* pExtract = pContext->pPayloads->rgPayloads + iExtract;
1143 if (pExtract->sczUnverifiedPath && pExtract->cRemainingInstances && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->sczSourcePath, -1))
1144 {
1145 + progress.pPayload = pExtract;
1146 +
1147 hr = PreparePayloadDestinationPath(pExtract->sczUnverifiedPath);
1148 ExitOnFailure(hr, "Failed to prepare payload destination path: %ls", pExtract->sczUnverifiedPath);
1149
1150 + hr = UserExperienceOnCachePayloadExtractBegin(pContext->pUX, pContainer->sczId, pExtract->sczKey);
1151 + if (FAILED(hr))
1152 + {
1153 + UserExperienceOnCachePayloadExtractComplete(pContext->pUX, pContainer->sczId, pExtract->sczKey, hr);
1154 + ExitOnRootFailure(hr, "BA aborted cache payload extract begin.");
1155 + }
1156 +
1157 // TODO: Send progress when extracting stream to file.
1158 hr = ContainerStreamToFile(&context, pExtract->sczUnverifiedPath);
1159 + // Error handling happens after sending complete message to BA.
1160 +
1161 + // If succeeded, send 100% complete here to make sure progress was sent to the BA.
1162 + if (SUCCEEDED(hr))
1163 + {
1164 + hr = CompleteCacheProgress(&progress, pExtract->qwFileSize);
1165 + }
1166 +
1167 + UserExperienceOnCachePayloadExtractComplete(pContext->pUX, pContainer->sczId, pExtract->sczKey, hr);
1168 ExitOnFailure(hr, "Failed to extract payload: %ls from container: %ls", sczExtractPayloadId, pContainer->sczId);
1169
1170 fExtracted = TRUE;
@@ -1754,7 +1795,12 @@ static HRESULT CompleteCacheProgress(
1795 if (PROGRESS_CONTINUE == dwResult)
1796 {
1797 pContext->pCacheContext->qwSuccessfulCacheProgress += qwFileSize;
1757 - if (pContext->pContainer)
1798 +
1799 + if (pContext->pPayload)
1800 + {
1801 + pContext->pContainer->qwCommittedExtractProgress += qwFileSize;
1802 + }
1803 + else if (pContext->pContainer)
1804 {
1805 pContext->pContainer->qwCommittedCacheProgress += qwFileSize;
1806 }
@@ -1800,7 +1846,7 @@ static DWORD CALLBACK CacheProgressRoutine(
1846 DWORD dwResult = PROGRESS_CONTINUE;
1847 BURN_CACHE_PROGRESS_CONTEXT* pProgress = static_cast<BURN_CACHE_PROGRESS_CONTEXT*>(lpData);
1848 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL;
1803 - LPCWSTR wzPayloadId = pProgress->pPayloadGroupItem ? pProgress->pPayloadGroupItem->pPayload->sczKey : NULL;
1849 + LPCWSTR wzPayloadId = pProgress->pPayloadGroupItem ? pProgress->pPayloadGroupItem->pPayload->sczKey : pProgress->pPayload ? pProgress->pPayload->sczKey : NULL;
1850 DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart;
1851 if (qwCacheProgress > pProgress->pCacheContext->qwTotalCacheSize)
1852 {
@@ -1823,6 +1869,10 @@ static DWORD CALLBACK CacheProgressRoutine(
1869 hr = UserExperienceOnCacheContainerOrPayloadVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1870 ExitOnRootFailure(hr, "BA aborted container or payload verify: %ls", wzPayloadId);
1871 break;
1872 + case BURN_CACHE_PROGRESS_TYPE_EXTRACT:
1873 + hr = UserExperienceOnCachePayloadExtractProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1874 + ExitOnRootFailure(hr, "BA aborted extract container: %ls, payload: %ls", wzPackageOrContainerId, wzPayloadId);
1875 + break;
1876 }
1877
1878 LExit:
src/engine/container.h
+1
@@ -78,6 +78,7 @@ typedef struct _BURN_CONTAINER
78 LPWSTR sczUnverifiedPath;
79 DWORD64 qwExtractSizeTotal;
80 DWORD64 qwCommittedCacheProgress;
81 + DWORD64 qwCommittedExtractProgress;
82 } BURN_CONTAINER;
83
84 typedef struct _BURN_CONTAINERS
src/engine/plan.cpp
+1
@@ -1831,6 +1831,7 @@ static void ResetPlannedContainerState(
1831 pContainer->fPlanned = FALSE;
1832 pContainer->qwExtractSizeTotal = 0;
1833 pContainer->qwCommittedCacheProgress = 0;
1834 + pContainer->qwCommittedExtractProgress = 0;
1835 }
1836
1837 static void ResetPlannedPayloadsState(
src/engine/userexperience.cpp
+87
@@ -758,6 +758,93 @@ LExit:
758 return hr;
759 }
760
761 +EXTERN_C BAAPI UserExperienceOnCachePayloadExtractBegin(
762 + __in BURN_USER_EXPERIENCE* pUserExperience,
763 + __in_z_opt LPCWSTR wzContainerId,
764 + __in_z_opt LPCWSTR wzPayloadId
765 + )
766 +{
767 + HRESULT hr = S_OK;
768 + BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS args = { };
769 + BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS results = { };
770 +
771 + args.cbSize = sizeof(args);
772 + args.wzContainerId = wzContainerId;
773 + args.wzPayloadId = wzPayloadId;
774 +
775 + results.cbSize = sizeof(results);
776 +
777 + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN, &args, &results);
778 + ExitOnFailure(hr, "BA OnCachePayloadExtractBegin failed.");
779 +
780 + if (results.fCancel)
781 + {
782 + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
783 + }
784 +
785 +LExit:
786 + return hr;
787 +}
788 +
789 +EXTERN_C BAAPI UserExperienceOnCachePayloadExtractComplete(
790 + __in BURN_USER_EXPERIENCE* pUserExperience,
791 + __in_z_opt LPCWSTR wzContainerId,
792 + __in_z_opt LPCWSTR wzPayloadId,
793 + __in HRESULT hrStatus
794 + )
795 +{
796 + HRESULT hr = S_OK;
797 + BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS args = { };
798 + BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS results = { };
799 +
800 + args.cbSize = sizeof(args);
801 + args.wzContainerId = wzContainerId;
802 + args.wzPayloadId = wzPayloadId;
803 + args.hrStatus = hrStatus;
804 +
805 + results.cbSize = sizeof(results);
806 +
807 + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE, &args, &results);
808 + ExitOnFailure(hr, "BA OnCachePayloadExtractComplete failed.");
809 +
810 +LExit:
811 + return hr;
812 +}
813 +
814 +EXTERN_C BAAPI UserExperienceOnCachePayloadExtractProgress(
815 + __in BURN_USER_EXPERIENCE* pUserExperience,
816 + __in_z_opt LPCWSTR wzContainerId,
817 + __in_z_opt LPCWSTR wzPayloadId,
818 + __in DWORD64 dw64Progress,
819 + __in DWORD64 dw64Total,
820 + __in DWORD dwOverallPercentage
821 + )
822 +{
823 + HRESULT hr = S_OK;
824 + BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS args = { };
825 + BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS results = { };
826 +
827 + args.cbSize = sizeof(args);
828 + args.wzContainerId = wzContainerId;
829 + args.wzPayloadId = wzPayloadId;
830 + args.dw64Progress = dw64Progress;
831 + args.dw64Total = dw64Total;
832 + args.dwOverallPercentage = dwOverallPercentage;
833 +
834 + results.cbSize = sizeof(results);
835 +
836 + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, &args, &results);
837 + ExitOnFailure(hr, "BA OnCachePayloadExtractProgress failed.");
838 +
839 + if (results.fCancel)
840 + {
841 + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
842 + }
843 +
844 +LExit:
845 + return hr;
846 +}
847 +
848 EXTERN_C BAAPI UserExperienceOnCacheVerifyBegin(
849 __in BURN_USER_EXPERIENCE* pUserExperience,
850 __in_z_opt LPCWSTR wzPackageOrContainerId,
src/engine/userexperience.h
+19
@@ -196,6 +196,25 @@ BAAPI UserExperienceOnCachePackageComplete(
196 __in HRESULT hrStatus,
197 __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction
198 );
199 +BAAPI UserExperienceOnCachePayloadExtractBegin(
200 + __in BURN_USER_EXPERIENCE* pUserExperience,
201 + __in_z_opt LPCWSTR wzContainerId,
202 + __in_z_opt LPCWSTR wzPayloadId
203 + );
204 +BAAPI UserExperienceOnCachePayloadExtractComplete(
205 + __in BURN_USER_EXPERIENCE* pUserExperience,
206 + __in_z_opt LPCWSTR wzContainerId,
207 + __in_z_opt LPCWSTR wzPayloadId,
208 + __in HRESULT hrStatus
209 + );
210 +BAAPI UserExperienceOnCachePayloadExtractProgress(
211 + __in BURN_USER_EXPERIENCE* pUserExperience,
212 + __in_z_opt LPCWSTR wzContainerId,
213 + __in_z_opt LPCWSTR wzPayloadId,
214 + __in DWORD64 dw64Progress,
215 + __in DWORD64 dw64Total,
216 + __in DWORD dwOverallPercentage
217 + );
218 BAAPI UserExperienceOnCacheVerifyBegin(
219 __in BURN_USER_EXPERIENCE* pUserExperience,
220 __in_z_opt LPCWSTR wzPackageOrContainerId,