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

Issue4242 #15

Merged
merged 9 commits into from Apr 30, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions History.md
@@ -1,3 +1,17 @@
* HeathS: Don't fail uninstall when planned package was removed by related bundle. Don't repair dependent bundles when upgrading a patch or addon bundle.

* AndySt: Update Registration key was being deleted during a bundle to bundle upgrade. Added version check so that only if the version was the same would the key be deleted.

* AndySt: Skip the repair of the related bundle if it has the same provider key as an embedded bundle that is being installed, so only V2 of the patch bundle is on the machine at the end.

* AndySt: Add /DisableSystemRestore switch and /OriginalSource switch /OriginalSource is used when authoring embedded bundles so it can look to the parent's original location instead of the package cached location that it is run from.

* HeathS: Make sure enough memory is allocated for compatible packages.

* HeathS: Uninstall compatible orphaned MSI packages.

* HeathS: Allow package downgrades for related bundles with proper ref-counting. Make sure packages register their identities in the provider registry.

* STunney/BobArnson: WIXFEAT:4239 - Add option to not extract the .msi when melting .wixpdbs. Don't leave temporary cabinet files behind (unless -notidy is in effect).

* BobArnson: WIXBUG:4331 - guard against null registry keys
Expand Down
2 changes: 1 addition & 1 deletion src/burn/engine/EngineForApplication.cpp
Expand Up @@ -416,7 +416,7 @@ class CEngineForApplication : public IBootstrapperEngine, public IMarshal
ExitOnFailure(hr, "Failed to default local update source");
}

hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, m_pEngineState->command.display, m_pEngineState->command.restart, BOOTSTRAPPER_RELATION_NONE, FALSE, m_pEngineState->registration.sczActiveParent, NULL, m_pEngineState->command.wzCommandLine);
hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, m_pEngineState->command.display, m_pEngineState->command.restart, BOOTSTRAPPER_RELATION_NONE, FALSE, m_pEngineState->registration.sczActiveParent, m_pEngineState->registration.sczAncestors, NULL, m_pEngineState->command.wzCommandLine);
ExitOnFailure(hr, "Failed to recreate command-line for update bundle.");

hr = PseudoBundleInitialize(FILEMAKEVERSION(rmj, rmm, rup, 0), &m_pEngineState->update.package, FALSE, m_pEngineState->registration.sczId, BOOTSTRAPPER_RELATION_UPDATE, BOOTSTRAPPER_PACKAGE_STATE_ABSENT, m_pEngineState->registration.sczExecutableName, sczLocalSource ? sczLocalSource : wzLocalSource, wzDownloadSource, qwSize, TRUE, sczCommandline, NULL, NULL, NULL, rgbHash, cbHash);
Expand Down
28 changes: 28 additions & 0 deletions src/burn/engine/apply.cpp
Expand Up @@ -203,6 +203,10 @@ static HRESULT ExecuteDependencyAction(
__in BURN_EXECUTE_ACTION* pAction,
__in BURN_EXECUTE_CONTEXT* pContext
);
static HRESULT ExecuteCompatiblePackageAction(
__in BURN_ENGINE_STATE* pEngineState,
__in BURN_EXECUTE_ACTION* pAction
);
static HRESULT CleanPackage(
__in HANDLE hElevatedPipe,
__in BURN_PACKAGE* pPackage
Expand Down Expand Up @@ -1675,6 +1679,11 @@ static HRESULT DoExecuteAction(
ExitOnFailure(hr, "Failed to execute dependency action.");
break;

case BURN_EXECUTE_ACTION_TYPE_COMPATIBLE_PACKAGE:
hr = ExecuteCompatiblePackageAction(pEngineState, pExecuteAction);
ExitOnFailure(hr, "Failed to execute compatible package action.");
break;

case BURN_EXECUTE_ACTION_TYPE_REGISTRATION:
*pfKeepRegistration = pExecuteAction->registration.fKeep;
break;
Expand Down Expand Up @@ -2108,6 +2117,25 @@ static HRESULT ExecuteDependencyAction(
return hr;
}

static HRESULT ExecuteCompatiblePackageAction(
__in BURN_ENGINE_STATE* pEngineState,
__in BURN_EXECUTE_ACTION* pAction
)
{
HRESULT hr = S_OK;

if (pAction->compatiblePackage.pReferencePackage->fPerMachine)
{
hr = ElevationLoadCompatiblePackageAction(pEngineState->companionConnection.hPipe, pAction);
ExitOnFailure(hr, "Failed to load compatible package on per-machine package.");
}

// Compatible package already loaded in this process.

LExit:
return hr;
}

static HRESULT CleanPackage(
__in HANDLE hElevatedPipe,
__in BURN_PACKAGE* pPackage
Expand Down
81 changes: 73 additions & 8 deletions src/burn/engine/core.cpp
Expand Up @@ -35,12 +35,15 @@ static HRESULT ParseCommandLine(
__in BURN_PIPE_CONNECTION* pEmbeddedConnection,
__out BURN_MODE* pMode,
__out BURN_AU_PAUSE_ACTION* pAutomaticUpdates,
__out BOOL* pfDisableSystemRestore,
__out_z LPWSTR* psczOriginalSource,
__out BURN_ELEVATION_STATE* pElevationState,
__out BOOL* pfDisableUnelevate,
__out DWORD *pdwLoggingAttributes,
__out_z LPWSTR* psczLogFile,
__out_z LPWSTR* psczActiveParent,
__out_z LPWSTR* psczIgnoreDependencies
__out_z LPWSTR* psczIgnoreDependencies,
__out_z LPWSTR* psczAncestors
);
static HRESULT ParsePipeConnection(
__in LPWSTR* rgArgs,
Expand Down Expand Up @@ -76,9 +79,10 @@ extern "C" HRESULT CoreInitialize(
BYTE* pbBuffer = NULL;
SIZE_T cbBuffer = 0;
BURN_CONTAINER_CONTEXT containerContext = { };
LPWSTR sczOriginalSource = NULL;

// parse command line
hr = ParseCommandLine(wzCommandLine, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &pEngineState->mode, &pEngineState->automaticUpdates, &pEngineState->elevationState, &pEngineState->fDisableUnelevate, &pEngineState->log.dwAttributes, &pEngineState->log.sczPath, &pEngineState->registration.sczActiveParent, &pEngineState->sczIgnoreDependencies);
hr = ParseCommandLine(wzCommandLine, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &pEngineState->mode, &pEngineState->automaticUpdates, &pEngineState->fDisableSystemRestore, &sczOriginalSource, &pEngineState->elevationState, &pEngineState->fDisableUnelevate, &pEngineState->log.dwAttributes, &pEngineState->log.sczPath, &pEngineState->registration.sczActiveParent, &pEngineState->sczIgnoreDependencies, &pEngineState->registration.sczAncestors);
ExitOnFailure(hr, "Failed to parse command line.");

// initialize variables
Expand All @@ -103,6 +107,14 @@ extern "C" HRESULT CoreInitialize(
hr = ManifestLoadXmlFromBuffer(pbBuffer, cbBuffer, pEngineState);
ExitOnFailure(hr, "Failed to load manifest.");

// Set BURN_BUNDLE_ORIGINAL_SOURCE, if it was passed in on the command line.
// Needs to be done after ManifestLoadXmlFromBuffer.
if (sczOriginalSource)
{
hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_ORIGINAL_SOURCE, sczOriginalSource, FALSE);
ExitOnFailure(hr, "Failed to set original source variable.");
}

// If we're not elevated then we'll be loading the bootstrapper application, so extract
// the payloads from the BA container.
if (pEngineState->elevationState == BURN_ELEVATION_STATE_UNELEVATED || pEngineState->elevationState == BURN_ELEVATION_STATE_UNELEVATED_EXPLICITLY)
Expand All @@ -120,6 +132,7 @@ extern "C" HRESULT CoreInitialize(
}

LExit:
ReleaseStr(sczOriginalSource);
ContainerClose(&containerContext);
ReleaseStr(sczStreamName);
ReleaseMem(pbBuffer);
Expand Down Expand Up @@ -396,7 +409,7 @@ extern "C" HRESULT CorePlan(
ExitOnFailure(hr, "Failed to plan the layout of the bundle.");

// Plan the packages' layout.
hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, FALSE, pEngineState->command.display, pEngineState->command.relationType, sczLayoutDirectory, &hSyncpointEvent);
hr = PlanPackages(&pEngineState->registration, &pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, FALSE, pEngineState->command.display, pEngineState->command.relationType, sczLayoutDirectory, &hSyncpointEvent);
ExitOnFailure(hr, "Failed to plan packages.");
}
else if (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED == action)
Expand Down Expand Up @@ -432,12 +445,16 @@ extern "C" HRESULT CorePlan(
// of addons and patches, which should be uninstalled before the main product.
DWORD dwExecuteActionEarlyIndex = pEngineState->plan.cExecuteActions;

hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->registration.fInstalled, pEngineState->command.display, pEngineState->command.relationType, NULL, &hSyncpointEvent);
// Plan the related bundles first to support downgrades with ref-counting.
hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan, pEngineState->mode);
ExitOnFailure(hr, "Failed to plan related bundles.");

hr = PlanPackages(&pEngineState->registration, &pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->registration.fInstalled, pEngineState->command.display, pEngineState->command.relationType, NULL, &hSyncpointEvent);
ExitOnFailure(hr, "Failed to plan packages.");

// Plan the update of related bundles last.
hr = PlanRelatedBundles(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, &hSyncpointEvent, dwExecuteActionEarlyIndex);
ExitOnFailure(hr, "Failed to plan related bundles.");
// Schedule the update of related bundles last.
hr = PlanRelatedBundlesComplete(&pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, &hSyncpointEvent, dwExecuteActionEarlyIndex);
ExitOnFailure(hr, "Failed to schedule related bundles.");
}
}

Expand Down Expand Up @@ -764,6 +781,7 @@ extern "C" HRESULT CoreRecreateCommandLine(
__in BOOTSTRAPPER_RELATION_TYPE relationType,
__in BOOL fPassthrough,
__in_z_opt LPCWSTR wzActiveParent,
__in_z_opt LPCWSTR wzAncestors,
__in_z_opt LPCWSTR wzApppendLogPath,
__in_z_opt LPCWSTR wzAdditionalCommandLineArguments
)
Expand Down Expand Up @@ -825,6 +843,15 @@ extern "C" HRESULT CoreRecreateCommandLine(
ExitOnFailure(hr, "Failed to append active parent command-line to command-line.");
}

if (wzAncestors)
{
hr = StrAllocFormatted(&scz, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, wzAncestors);
Copy link
Member

Choose a reason for hiding this comment

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

Seems we should have a StrAllocFormattedConcat helper...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I understand this comment. Are you saying I should add one? (StrAllocFormatted actually does it when passing the string to itself, but it's not obvious - I've used it elsewhere in older code successfully.)

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, not requesting a change. It just seems a common requirement: format a string and append it to another.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this change good to go then?

ExitOnFailure(hr, "Failed to format ancestors for command-line.");

hr = StrAllocConcat(psczCommandLine, scz, 0);
ExitOnFailure(hr, "Failed to append ancestors to command-line.");
}

if (wzRelationTypeCommandLine)
{
hr = StrAllocFormatted(&scz, L" /%ls", wzRelationTypeCommandLine);
Expand Down Expand Up @@ -876,12 +903,15 @@ static HRESULT ParseCommandLine(
__in BURN_PIPE_CONNECTION* pEmbeddedConnection,
__out BURN_MODE* pMode,
__out BURN_AU_PAUSE_ACTION* pAutomaticUpdates,
__out BOOL* pfDisableSystemRestore,
__out_z LPWSTR* psczOriginalSource,
__out BURN_ELEVATION_STATE* pElevationState,
__out BOOL* pfDisableUnelevate,
__out DWORD *pdwLoggingAttributes,
__out_z LPWSTR* psczLogFile,
__out_z LPWSTR* psczActiveParent,
__out_z LPWSTR* psczIgnoreDependencies
__out_z LPWSTR* psczIgnoreDependencies,
__out_z LPWSTR* psczAncestors
)
{
HRESULT hr = S_OK;
Expand Down Expand Up @@ -1022,6 +1052,21 @@ static HRESULT ParseCommandLine(
*pAutomaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME;
}
}
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"disablesystemrestore", -1))
{
*pfDisableSystemRestore = TRUE;
}
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"originalsource", -1))
{
if (i + 1 >= argc)
{
ExitOnRootFailure(hr = E_INVALIDARG, "Must specify a path for original source.");
}

++i;
hr = StrAllocString(psczOriginalSource, argv[i], 0);
ExitOnFailure(hr, "Failed to copy last used source.");
}
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PARENT, -1))
{
if (i + 1 >= argc)
Expand Down Expand Up @@ -1155,6 +1200,18 @@ static HRESULT ParseCommandLine(
hr = StrAllocString(psczIgnoreDependencies, &wzParam[1], 0);
ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore.");
}
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS), BURN_COMMANDLINE_SWITCH_ANCESTORS, lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS)))
{
// Get a pointer to the next character after the switch.
LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS)];
if (L'=' != wzParam[0] || L'\0' == wzParam[1])
{
ExitOnRootFailure1(hr = E_INVALIDARG, "Missing required parameter for switch: %ls", BURN_COMMANDLINE_SWITCH_ANCESTORS);
}

hr = StrAllocString(psczAncestors, &wzParam[1], 0);
ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
}
else if (lstrlenW(&argv[i][1]) >= lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX) &&
CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX), BURN_COMMANDLINE_SWITCH_PREFIX, lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX)))
{
Expand Down Expand Up @@ -1384,6 +1441,14 @@ static void LogPackages(
LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingBoolToString(pPackage->fAcquire), LoggingBoolToString(pPackage->fUncache), LoggingDependencyActionToString(pPackage->dependencyExecute));
}

for (DWORD i = 0; i < pPackages->cCompatiblePackages; ++i)
{
const DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? pPackages->cCompatiblePackages - 1 - i : i;
const BURN_PACKAGE* pPackage = &pPackages->rgCompatiblePackages[iPackage];

LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingBoolToString(pPackage->fAcquire), LoggingBoolToString(pPackage->fUncache), LoggingDependencyActionToString(pPackage->dependencyExecute));
}

// Display related bundles last if installing, modifying, or repairing.
if (BOOTSTRAPPER_ACTION_UNINSTALL < action && 0 < pRelatedBundles->cRelatedBundles)
{
Expand Down
2 changes: 2 additions & 0 deletions src/burn/engine/core.h
Expand Up @@ -40,6 +40,7 @@ const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_UPDATE = L"burn.related.update";
const LPCWSTR BURN_COMMANDLINE_SWITCH_PASSTHROUGH = L"burn.passthrough";
const LPCWSTR BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE = L"burn.disable.unelevate";
const LPCWSTR BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES = L"burn.ignoredependencies";
const LPCWSTR BURN_COMMANDLINE_SWITCH_ANCESTORS = L"burn.ancestors";
const LPCWSTR BURN_COMMANDLINE_SWITCH_PREFIX = L"burn.";

const LPCWSTR BURN_BUNDLE_LAYOUT_DIRECTORY = L"WixBundleLayoutDirectory";
Expand Down Expand Up @@ -195,6 +196,7 @@ HRESULT CoreRecreateCommandLine(
__in BOOTSTRAPPER_RELATION_TYPE relationType,
__in BOOL fPassthrough,
__in_z_opt LPCWSTR wzActiveParent,
__in_z_opt LPCWSTR wzAncestors,
__in_z_opt LPCWSTR wzApppendLogPath,
__in_z_opt LPCWSTR wzAdditionalCommandLineArguments
);
Expand Down