Skip to content

Commit

Permalink
Add OnCachePayloadExtract*.
Browse files Browse the repository at this point in the history
  • Loading branch information
rseanhall committed Apr 16, 2021
1 parent 526e2a1 commit a2f3914
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ enum BOOTSTRAPPER_APPLICATION_MESSAGE
BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN,
BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE,
BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS,
BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN,
BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE,
BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS,
};

enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION
Expand Down Expand Up @@ -472,6 +475,48 @@ struct BA_ONCACHEPACKAGECOMPLETE_RESULTS
BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION action;
};

struct BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS
{
DWORD cbSize;
LPCWSTR wzContainerId;
LPCWSTR wzPayloadId;
};

struct BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS
{
DWORD cbSize;
BOOL fCancel;
};

struct BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS
{
DWORD cbSize;
LPCWSTR wzContainerId;
LPCWSTR wzPayloadId;
HRESULT hrStatus;
};

struct BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS
{
DWORD cbSize;
};

struct BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS
{
DWORD cbSize;
LPCWSTR wzContainerId;
LPCWSTR wzPayloadId;
DWORD64 dw64Progress;
DWORD64 dw64Total;
DWORD dwOverallPercentage;
};

struct BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS
{
DWORD cbSize;
BOOL fCancel;
};

struct BA_ONCACHEVERIFYBEGIN_ARGS
{
DWORD cbSize;
Expand Down
86 changes: 79 additions & 7 deletions src/engine/apply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum BURN_CACHE_PROGRESS_TYPE
BURN_CACHE_PROGRESS_TYPE_ACQUIRE,
BURN_CACHE_PROGRESS_TYPE_VERIFY,
BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY,
BURN_CACHE_PROGRESS_TYPE_EXTRACT,
};

// structs
Expand Down Expand Up @@ -43,6 +44,7 @@ typedef struct _BURN_CACHE_PROGRESS_CONTEXT
BURN_CONTAINER* pContainer;
BURN_PACKAGE* pPackage;
BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem;
BURN_PAYLOAD* pPayload;

BOOL fCancel;
HRESULT hrError;
Expand Down Expand Up @@ -875,6 +877,12 @@ static HRESULT ApplyExtractContainer(
pContainer->qwCommittedCacheProgress = 0;
}

if (pContainer->qwCommittedExtractProgress)
{
pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedExtractProgress;
pContainer->qwCommittedExtractProgress = 0;
}

if (!pContainer->fActuallyAttached)
{
hr = ApplyAcquireContainerOrPayload(pContext, pContainer, NULL, NULL);
Expand All @@ -890,8 +898,18 @@ static HRESULT ApplyExtractContainer(
CacheSetLastUsedSource(pContext->pVariables, pContext->sczLastUsedFolderCandidate, pContainer->sczFilePath);
}

pContext->qwSuccessfulCacheProgress += pContainer->qwExtractSizeTotal;
pContainer->qwCommittedCacheProgress += pContainer->qwExtractSizeTotal;
if (pContainer->qwExtractSizeTotal < pContainer->qwCommittedExtractProgress)
{
AssertSz(FALSE, "Container extracted more than planned.");
pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedExtractProgress;
pContext->qwSuccessfulCacheProgress += pContainer->qwExtractSizeTotal;
}
else
{
pContext->qwSuccessfulCacheProgress += pContainer->qwExtractSizeTotal - pContainer->qwCommittedExtractProgress;
}

pContainer->qwCommittedExtractProgress = pContainer->qwExtractSizeTotal;

LExit:
ReleaseNullStr(pContext->sczLastUsedFolderCandidate);
Expand Down Expand Up @@ -1100,6 +1118,11 @@ static HRESULT ExtractContainer(
BURN_CONTAINER_CONTEXT context = { };
HANDLE hContainerHandle = INVALID_HANDLE_VALUE;
LPWSTR sczExtractPayloadId = NULL;
BURN_CACHE_PROGRESS_CONTEXT progress = { };

progress.pCacheContext = pContext;
progress.pContainer = pContainer;
progress.type = BURN_CACHE_PROGRESS_TYPE_EXTRACT;

// If the container is actually attached, then it was planned to be acquired through hSourceEngineFile.
if (pContainer->fActuallyAttached)
Expand All @@ -1119,11 +1142,29 @@ static HRESULT ExtractContainer(
BURN_PAYLOAD* pExtract = pContext->pPayloads->rgPayloads + iExtract;
if (pExtract->sczUnverifiedPath && pExtract->cRemainingInstances && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->sczSourcePath, -1))
{
progress.pPayload = pExtract;

hr = PreparePayloadDestinationPath(pExtract->sczUnverifiedPath);
ExitOnFailure(hr, "Failed to prepare payload destination path: %ls", pExtract->sczUnverifiedPath);

hr = UserExperienceOnCachePayloadExtractBegin(pContext->pUX, pContainer->sczId, pExtract->sczKey);
if (FAILED(hr))
{
UserExperienceOnCachePayloadExtractComplete(pContext->pUX, pContainer->sczId, pExtract->sczKey, hr);
ExitOnRootFailure(hr, "BA aborted cache payload extract begin.");
}

// TODO: Send progress when extracting stream to file.
hr = ContainerStreamToFile(&context, pExtract->sczUnverifiedPath);
// Error handling happens after sending complete message to BA.

// If succeeded, send 100% complete here to make sure progress was sent to the BA.
if (SUCCEEDED(hr))
{
hr = CompleteCacheProgress(&progress, pExtract->qwFileSize);
}

UserExperienceOnCachePayloadExtractComplete(pContext->pUX, pContainer->sczId, pExtract->sczKey, hr);
ExitOnFailure(hr, "Failed to extract payload: %ls from container: %ls", sczExtractPayloadId, pContainer->sczId);

fExtracted = TRUE;
Expand Down Expand Up @@ -1220,7 +1261,15 @@ static HRESULT LayoutBundle(
progress.fCancel = FALSE;

hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, NULL, NULL, &sczBundlePath, &sczBundleDownloadUrl, NULL, &cacheOperation);
ExitOnRootFailure(hr, "BA aborted cache acquire begin.");
if (FAILED(hr))
{
UserExperienceOnCacheAcquireComplete(pContext->pUX, NULL, NULL, hr, &fRetryAcquire);
if (fRetryAcquire)
{
continue;
}
ExitOnRootFailure(hr, "BA aborted cache acquire begin.");
}

hr = CopyPayload(&progress, pContext->hSourceEngineFile, sczBundlePath, wzUnverifiedPath);
// Error handling happens after sending complete message to BA.
Expand All @@ -1245,8 +1294,23 @@ static HRESULT LayoutBundle(

do
{
BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL);
ExitOnRootFailure(hr, "BA aborted cache verify begin.");
if (FAILED(hr))
{
UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action);
if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action)
{
hr = S_FALSE; // retry verify.
continue;
}
else if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION == action)
{
fRetry = TRUE; // go back and retry acquire.
break;
}
ExitOnRootFailure(hr, "BA aborted cache verify begin.");
}

if (INVALID_HANDLE_VALUE != pContext->hPipe)
{
Expand All @@ -1262,7 +1326,6 @@ static HRESULT LayoutBundle(
hr = CompleteCacheProgress(&progress, qwBundleSize);
}

BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action);
if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action)
{
Expand Down Expand Up @@ -1754,7 +1817,12 @@ static HRESULT CompleteCacheProgress(
if (PROGRESS_CONTINUE == dwResult)
{
pContext->pCacheContext->qwSuccessfulCacheProgress += qwFileSize;
if (pContext->pContainer)

if (pContext->pPayload)
{
pContext->pContainer->qwCommittedExtractProgress += qwFileSize;
}
else if (pContext->pContainer)
{
pContext->pContainer->qwCommittedCacheProgress += qwFileSize;
}
Expand Down Expand Up @@ -1800,7 +1868,7 @@ static DWORD CALLBACK CacheProgressRoutine(
DWORD dwResult = PROGRESS_CONTINUE;
BURN_CACHE_PROGRESS_CONTEXT* pProgress = static_cast<BURN_CACHE_PROGRESS_CONTEXT*>(lpData);
LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL;
LPCWSTR wzPayloadId = pProgress->pPayloadGroupItem ? pProgress->pPayloadGroupItem->pPayload->sczKey : NULL;
LPCWSTR wzPayloadId = pProgress->pPayloadGroupItem ? pProgress->pPayloadGroupItem->pPayload->sczKey : pProgress->pPayload ? pProgress->pPayload->sczKey : NULL;
DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart;
if (qwCacheProgress > pProgress->pCacheContext->qwTotalCacheSize)
{
Expand All @@ -1823,6 +1891,10 @@ static DWORD CALLBACK CacheProgressRoutine(
hr = UserExperienceOnCacheContainerOrPayloadVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
ExitOnRootFailure(hr, "BA aborted container or payload verify: %ls", wzPayloadId);
break;
case BURN_CACHE_PROGRESS_TYPE_EXTRACT:
hr = UserExperienceOnCachePayloadExtractProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
ExitOnRootFailure(hr, "BA aborted extract container: %ls, payload: %ls", wzPackageOrContainerId, wzPayloadId);
break;
}

LExit:
Expand Down
1 change: 1 addition & 0 deletions src/engine/container.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ typedef struct _BURN_CONTAINER
LPWSTR sczUnverifiedPath;
DWORD64 qwExtractSizeTotal;
DWORD64 qwCommittedCacheProgress;
DWORD64 qwCommittedExtractProgress;
} BURN_CONTAINER;

typedef struct _BURN_CONTAINERS
Expand Down
1 change: 1 addition & 0 deletions src/engine/plan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1831,6 +1831,7 @@ static void ResetPlannedContainerState(
pContainer->fPlanned = FALSE;
pContainer->qwExtractSizeTotal = 0;
pContainer->qwCommittedCacheProgress = 0;
pContainer->qwCommittedExtractProgress = 0;
}

static void ResetPlannedPayloadsState(
Expand Down
87 changes: 87 additions & 0 deletions src/engine/userexperience.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,93 @@ EXTERN_C BAAPI UserExperienceOnCachePackageComplete(
return hr;
}

EXTERN_C BAAPI UserExperienceOnCachePayloadExtractBegin(
__in BURN_USER_EXPERIENCE* pUserExperience,
__in_z_opt LPCWSTR wzContainerId,
__in_z_opt LPCWSTR wzPayloadId
)
{
HRESULT hr = S_OK;
BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS args = { };
BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS results = { };

args.cbSize = sizeof(args);
args.wzContainerId = wzContainerId;
args.wzPayloadId = wzPayloadId;

results.cbSize = sizeof(results);

hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN, &args, &results);
ExitOnFailure(hr, "BA OnCachePayloadExtractBegin failed.");

if (results.fCancel)
{
hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
}

LExit:
return hr;
}

EXTERN_C BAAPI UserExperienceOnCachePayloadExtractComplete(
__in BURN_USER_EXPERIENCE* pUserExperience,
__in_z_opt LPCWSTR wzContainerId,
__in_z_opt LPCWSTR wzPayloadId,
__in HRESULT hrStatus
)
{
HRESULT hr = S_OK;
BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS args = { };
BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS results = { };

args.cbSize = sizeof(args);
args.wzContainerId = wzContainerId;
args.wzPayloadId = wzPayloadId;
args.hrStatus = hrStatus;

results.cbSize = sizeof(results);

hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE, &args, &results);
ExitOnFailure(hr, "BA OnCachePayloadExtractComplete failed.");

LExit:
return hr;
}

EXTERN_C BAAPI UserExperienceOnCachePayloadExtractProgress(
__in BURN_USER_EXPERIENCE* pUserExperience,
__in_z_opt LPCWSTR wzContainerId,
__in_z_opt LPCWSTR wzPayloadId,
__in DWORD64 dw64Progress,
__in DWORD64 dw64Total,
__in DWORD dwOverallPercentage
)
{
HRESULT hr = S_OK;
BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS args = { };
BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS results = { };

args.cbSize = sizeof(args);
args.wzContainerId = wzContainerId;
args.wzPayloadId = wzPayloadId;
args.dw64Progress = dw64Progress;
args.dw64Total = dw64Total;
args.dwOverallPercentage = dwOverallPercentage;

results.cbSize = sizeof(results);

hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, &args, &results);
ExitOnFailure(hr, "BA OnCachePayloadExtractProgress failed.");

if (results.fCancel)
{
hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
}

LExit:
return hr;
}

EXTERN_C BAAPI UserExperienceOnCacheVerifyBegin(
__in BURN_USER_EXPERIENCE* pUserExperience,
__in_z_opt LPCWSTR wzPackageOrContainerId,
Expand Down
19 changes: 19 additions & 0 deletions src/engine/userexperience.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,25 @@ BAAPI UserExperienceOnCachePackageComplete(
__in HRESULT hrStatus,
__inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction
);
BAAPI UserExperienceOnCachePayloadExtractBegin(
__in BURN_USER_EXPERIENCE* pUserExperience,
__in_z_opt LPCWSTR wzContainerId,
__in_z_opt LPCWSTR wzPayloadId
);
BAAPI UserExperienceOnCachePayloadExtractComplete(
__in BURN_USER_EXPERIENCE* pUserExperience,
__in_z_opt LPCWSTR wzContainerId,
__in_z_opt LPCWSTR wzPayloadId,
__in HRESULT hrStatus
);
BAAPI UserExperienceOnCachePayloadExtractProgress(
__in BURN_USER_EXPERIENCE* pUserExperience,
__in_z_opt LPCWSTR wzContainerId,
__in_z_opt LPCWSTR wzPayloadId,
__in DWORD64 dw64Progress,
__in DWORD64 dw64Total,
__in DWORD dwOverallPercentage
);
BAAPI UserExperienceOnCacheVerifyBegin(
__in BURN_USER_EXPERIENCE* pUserExperience,
__in_z_opt LPCWSTR wzPackageOrContainerId,
Expand Down

0 comments on commit a2f3914

Please sign in to comment.