Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use wiutil to start/end msi transactions #29

Closed
wants to merge 4 commits into from

Conversation

nirbar
Copy link
Contributor

@nirbar nirbar commented Jan 12, 2021

Add logging for transactions
Let BA vote whether or not to use the transaction
Warn if transactions aren't suported on the target machine
See wixtoolset/issues#5386

@rseanhall
Copy link
Contributor

There's way too much going on here for one pull request. Let's start with the first one - using wiutil to start/end msi transactions. Please get rid of everything else. It's up to you whether to keep this one open and force push, or close this and open a new one. You must keep calling the methods in msiengine, make the changes there.

Copy link
Contributor

@rseanhall rseanhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having to keep track of the handles made things really messy. I really hope we can avoid that.

burn.sln Outdated
@@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 15.0.26124.0
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "engine", "src\engine\engine.vcxproj", "{8119537D-E1D9-6591-D51A-49768A2F9C37}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stub", "src\stub\stub.vcxproj", "{C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}"
ProjectSection(ProjectDependencies) = postProject
{8119537D-E1D9-6591-D51A-49768A2F9C37} = {8119537D-E1D9-6591-D51A-49768A2F9C37}
EndProjectSection
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reverted.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the root issue (incomplete ProjectReference) in #37.

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reverted.

Comment on lines 817 to 837
// If inside a MSI transaction, roll it back.
if (pCheckpoint->pActiveRollbackBoundary && pCheckpoint->pActiveRollbackBoundary->fActiveTransaction)
{
hrRollback = ExecuteMsiRollbackTransaction(pEngineState, pCheckpoint->pActiveRollbackBoundary, &context);
IgnoreRollbackError(hrRollback, "Failed rolling back transaction");
}
else
{
hrRollback = DoRollbackActions(pEngineState, &context, pCheckpoint->dwId, pfKeepRegistration, pRestart);
IgnoreRollbackError(hrRollback, "Failed rollback actions");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong. DoRollbackActions needs to be executed even if there was an active MSI transaction. I have already modified the plan so that it doesn't have rollback actions for the MSI/MSP packages.

@@ -830,6 +835,7 @@ extern "C" HRESULT ApplyExecute(
}

// Move forward to next rollback boundary.
hr = S_OK;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to take this change in this pull request, it seems to belong to a completely different bug.

SymbolicName=MSG_UX_DECLINED_MSI_TRANSACTION
Language=English
UX voted against MSI transaction on rollback boundary '%1!ls!'
.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These messages should be removed.

@@ -157,10 +157,12 @@ static HRESULT InitializeVariableNumeric(
__in DWORD_PTR dwpData,
__inout BURN_VARIANT* pValue
);
#if !defined(_WIN64)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in this file should be reverted.

@@ -641,6 +641,9 @@ namespace Bootstrapper
::InitializeCriticalSection(&pEngineState->csActive);
::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive);

hr = WiuInitialize();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should no longer be necessary when the call to WiuIsMsiTransactionSupported is removed.

src/engine/msiengine.cpp Outdated Show resolved Hide resolved
uResult = ::MsiBeginTransaction(wzName, 0, &hTransactionHandle, &hChangeOfOwnerEvent);

if (ERROR_ROLLBACK_DISABLED == uResult)
if (E_ROLLBACK_DISABLED == hr)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I don't see us defining a new HRESULT value from a Win32 error anywhere else in Burn. Since it's used only once, I would rather do HRESULT_FROM_WIN32(ERROR_ROLLBACK_DISABLED) inline.

src/engine/elevation.h Show resolved Hide resolved
@rseanhall
Copy link
Contributor

I've been thinking about this, and you might as well include the real logging logic in this pull request as well.

There needs to be dwLoggingAttributes and sczLogPath in the rollback boundary struct which needs to be calculated during plan, like msiengine. The handles could also be stored there. The MsiEngine*Transaction methods would need the struct as a parameter instead of the id.

LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, &pAction->msiPackage.sczLogPath); // ignore errors.
pAction->msiPackage.dwLoggingAttributes = pLog->dwAttributes;

You would have to pass dwLoggingAttributes and sczLogPath along with the id to the elevated engine when creating the transaction, where it would use the id to look up the rollback boundary struct like it does when looking up an MSI package. You would store the log parameters there. The other transaction methods would need to keep requiring the id so they can look up the rollback boundary.

burn/src/engine/elevation.cpp

Lines 2322 to 2323 in 5bab3f6

hr = PackageFindById(pPackages, sczPackage, &executeAction.msiPackage.pPackage);
ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);

dwLoggingAttributes is used for adding INSTALLLOGMODE_EXTRADEBUG.

burn/src/engine/msiengine.cpp

Lines 1249 to 1255 in 5bab3f6

// Default to "verbose" logging and set extra debug mode only if explicitly required.
DWORD dwLogMode = WIU_LOG_DEFAULT | INSTALLLOGMODE_VERBOSE;
if (pExecuteAction->msiPackage.dwLoggingAttributes & BURN_LOGGING_ATTRIBUTE_EXTRADEBUG)
{
dwLogMode |= INSTALLLOGMODE_EXTRADEBUG;
}

Copy link
Contributor

@rseanhall rseanhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you been able to make any progress? I would like to start getting these MSI transaction changes in.

burn.sln Outdated
@@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 15.0.26124.0
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "engine", "src\engine\engine.vcxproj", "{8119537D-E1D9-6591-D51A-49768A2F9C37}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stub", "src\stub\stub.vcxproj", "{C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}"
ProjectSection(ProjectDependencies) = postProject
{8119537D-E1D9-6591-D51A-49768A2F9C37} = {8119537D-E1D9-6591-D51A-49768A2F9C37}
EndProjectSection
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the root issue (incomplete ProjectReference) in #37.

)
{
HRESULT hr = S_OK;
BOOL fBeginCalled = FALSE;
BOOL fCommitCalled = FALSE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was shorthand for "fOnCommitMsiTransactionBeginCalled". There are many places where we're using fBeginCalled to track whether the BA *Begin method was called. If you find this confusing, then I would prefer fCommitBeginCalled.

@@ -1825,6 +1825,13 @@ extern "C" HRESULT PlanRollbackBoundaryBegin(
AssertSz(!pPlan->pActiveRollbackBoundary, "PlanRollbackBoundaryBegin called without completing previous RollbackBoundary");
pPlan->pActiveRollbackBoundary = pRollbackBoundary;

// Best effort to support MSI transactions
if (pRollbackBoundary->fTransaction && !WiuIsMsiTransactionSupported())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was done in #37.

@nirbar
Copy link
Contributor Author

nirbar commented Feb 8, 2021

I have some clients nearing product release dates, so it's quite busy currently.
I'll get back to it in a few weeks

@rseanhall
Copy link
Contributor

@nirbar Ping.

Add logging for transactions
Let BA vote whether or not to use the transaction
Warn if transactions aren't suported on the target machine
@rseanhall
Copy link
Contributor

Thanks. I took the changes for using wiutil and closing the handles immediately and submitted it here: #47. I look forward to the next pull request with the logging enhancements or the BA involvement.

@rseanhall rseanhall closed this Mar 17, 2021
This was referenced Apr 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants