From 84a1b0f8ffe40a26916b1dfb3e1b59b6b0c31ad4 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Thu, 30 Dec 2021 15:12:26 -0600 Subject: Add BURN_PROTOCOL_VERSION in registration to avoid version checks. Also, old versions of Burn should ignore ancestors if they doesn't support them. --- src/burn/engine/inc/engine.h | 2 ++ src/burn/engine/pipe.cpp | 1 + src/burn/engine/pseudobundle.cpp | 13 +++++-------- src/burn/engine/pseudobundle.h | 2 +- src/burn/engine/registration.cpp | 3 +++ src/burn/engine/registration.h | 1 + src/burn/engine/relatedbundle.cpp | 25 +++++++++++++++++++------ src/burn/test/BurnUnitTest/PlanTest.cpp | 2 +- 8 files changed, 33 insertions(+), 16 deletions(-) (limited to 'src/burn') diff --git a/src/burn/engine/inc/engine.h b/src/burn/engine/inc/engine.h index b80b4213..9b29dd84 100644 --- a/src/burn/engine/inc/engine.h +++ b/src/burn/engine/inc/engine.h @@ -9,6 +9,8 @@ #define BURN_SECTION_MAGIC 0x00f14300 #define BURN_SECTION_VERSION 0x00000002 +// This needs to be incremented whenever a breaking change is made to the Burn protocol. +#define BURN_PROTOCOL_VERSION 1 #if defined(__cplusplus) extern "C" { diff --git a/src/burn/engine/pipe.cpp b/src/burn/engine/pipe.cpp index 48be8785..80275b52 100644 --- a/src/burn/engine/pipe.cpp +++ b/src/burn/engine/pipe.cpp @@ -710,6 +710,7 @@ static HRESULT ChildPipeConnected( } // All is well, tell the parent process. + // TODO: consider sending BURN_PROTOCOL_VERSION as a way to verify compatibility. hr = FileWriteHandle(hPipe, reinterpret_cast(&dwAck), sizeof(dwAck)); ExitOnFailure(hr, "Failed to inform parent process that child is running."); diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index 91c6c14f..14dd2b77 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp @@ -4,8 +4,8 @@ extern "C" HRESULT PseudoBundleInitialize( - __in DWORD64 qwEngineVersion, __in BURN_PACKAGE* pPackage, + __in BOOL fSupportsBurnProtocol, __in BOOL fPerMachine, __in_z LPCWSTR wzId, __in BOOTSTRAPPER_RELATION_TYPE relationType, @@ -84,6 +84,9 @@ extern "C" HRESULT PseudoBundleInitialize( pPackage->qwSize = qwSize; pPackage->fVital = fVital; + pPackage->Exe.protocol = fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE; + pPackage->Exe.fSupportsAncestors = TRUE; + hr = StrAllocString(&pPackage->sczId, wzId, 0); ExitOnFailure(hr, "Failed to copy key for pseudo bundle."); @@ -131,12 +134,6 @@ extern "C" HRESULT PseudoBundleInitialize( pPackage->fUninstallable = TRUE; } - // Only support progress from engines that are compatible (aka: version greater than or equal to last protocol breaking change *and* versions that are older or the same as this engine). - pPackage->Exe.protocol = (FILEMAKEVERSION(3, 6, 2221, 0) <= qwEngineVersion && qwEngineVersion <= FILEMAKEVERSION(rmj, rmm, rup, rpr)) ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE; - - // All versions of Burn past v3.9 RTM support suppressing ancestors. - pPackage->Exe.fSupportsAncestors = FILEMAKEVERSION(3, 9, 1006, 0) <= qwEngineVersion; - if (pDependencyProvider) { pPackage->rgDependencyProviders = (BURN_DEPENDENCY_PROVIDER*)MemAlloc(sizeof(BURN_DEPENDENCY_PROVIDER), TRUE); @@ -310,7 +307,7 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle( hr = StrAllocString(&pPackage->Exe.sczInstallArguments, wzInstallArguments, 0); ExitOnFailure(hr, "Failed to copy install arguments for update bundle package"); - // Assume the update bundle has the same engine version as this one. + // Trust the BA to only use UPDATE_REPLACE_EMBEDDED when appropriate. pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN; pPackage->Exe.fSupportsAncestors = TRUE; diff --git a/src/burn/engine/pseudobundle.h b/src/burn/engine/pseudobundle.h index 0fd4cbdb..22132c5e 100644 --- a/src/burn/engine/pseudobundle.h +++ b/src/burn/engine/pseudobundle.h @@ -7,8 +7,8 @@ extern "C" { #endif HRESULT PseudoBundleInitialize( - __in DWORD64 qwEngineVersion, __in BURN_PACKAGE* pPackage, + __in BOOL fSupportsBurnProtocol, __in BOOL fPerMachine, __in_z LPCWSTR wzId, __in BOOTSTRAPPER_RELATION_TYPE relationType, diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index e06767e1..9cc4b199 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp @@ -671,6 +671,9 @@ extern "C" HRESULT RegistrationSessionBegin( hr = RegWriteStringFormatted(hkRegistration, BURN_REGISTRATION_REGISTRY_ENGINE_VERSION, L"%hs", szVerMajorMinorBuild); ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_ENGINE_VERSION); + hr = RegWriteNumber(hkRegistration, BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION, BURN_PROTOCOL_VERSION); + ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION); + // DisplayIcon: [path to exe] and ",0" to refer to the first icon in the executable. hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_DISPLAY_ICON, L"%s,0", pRegistration->sczCacheExecutablePath); ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_ICON); diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h index f9411636..e33d5270 100644 --- a/src/burn/engine/registration.h +++ b/src/burn/engine/registration.h @@ -23,6 +23,7 @@ const LPCWSTR BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = L"BundleUpgradeCo const LPCWSTR BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME = L"DisplayName"; const LPCWSTR BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION = L"BundleVersion"; const LPCWSTR BURN_REGISTRATION_REGISTRY_ENGINE_VERSION = L"EngineVersion"; +const LPCWSTR BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION = L"EngineProtocolVersion"; const LPCWSTR BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey"; const LPCWSTR BURN_REGISTRATION_REGISTRY_BUNDLE_TAG = L"BundleTag"; diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index d3c856a6..4a694ef6 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp @@ -21,7 +21,7 @@ static HRESULT LoadRelatedBundleFromKey( __in HKEY hkBundleId, __in BOOL fPerMachine, __in BOOTSTRAPPER_RELATION_TYPE relationType, - __inout BURN_RELATED_BUNDLE *pRelatedBundle + __in BURN_RELATED_BUNDLE *pRelatedBundle ); @@ -398,21 +398,34 @@ static HRESULT LoadRelatedBundleFromKey( __in HKEY hkBundleId, __in BOOL fPerMachine, __in BOOTSTRAPPER_RELATION_TYPE relationType, - __inout BURN_RELATED_BUNDLE* pRelatedBundle + __in BURN_RELATED_BUNDLE* pRelatedBundle ) { HRESULT hr = S_OK; DWORD64 qwEngineVersion = 0; + DWORD dwEngineProtocolVersion = 0; + BOOL fSupportsBurnProtocol = FALSE; LPWSTR sczBundleVersion = NULL; LPWSTR sczCachePath = NULL; BOOL fCached = FALSE; DWORD64 qwFileSize = 0; BURN_DEPENDENCY_PROVIDER dependencyProvider = { }; - hr = RegReadVersion(hkBundleId, BURN_REGISTRATION_REGISTRY_ENGINE_VERSION, &qwEngineVersion); - if (FAILED(hr)) + // Only support progress from engines that are compatible. + hr = RegReadNumber(hkBundleId, BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION, &dwEngineProtocolVersion); + if (SUCCEEDED(hr)) + { + fSupportsBurnProtocol = BURN_PROTOCOL_VERSION == dwEngineProtocolVersion; + } + else { - qwEngineVersion = 0; + // Rely on version checking (aka: version greater than or equal to last protocol breaking change *and* versions that are older or the same as this engine) + hr = RegReadVersion(hkBundleId, BURN_REGISTRATION_REGISTRY_ENGINE_VERSION, &qwEngineVersion); + if (SUCCEEDED(hr)) + { + fSupportsBurnProtocol = (FILEMAKEVERSION(3, 6, 2221, 0) <= qwEngineVersion && qwEngineVersion <= FILEMAKEVERSION(rmj, rmm, rup, rpr)); + } + hr = S_OK; } @@ -467,7 +480,7 @@ static HRESULT LoadRelatedBundleFromKey( pRelatedBundle->relationType = relationType; - hr = PseudoBundleInitialize(qwEngineVersion, &pRelatedBundle->package, fPerMachine, wzRelatedBundleId, pRelatedBundle->relationType, + hr = PseudoBundleInitialize(&pRelatedBundle->package, fSupportsBurnProtocol, fPerMachine, wzRelatedBundleId, pRelatedBundle->relationType, BOOTSTRAPPER_PACKAGE_STATE_PRESENT, fCached, sczCachePath, sczCachePath, NULL, qwFileSize, FALSE, L"-quiet", L"-repair -quiet", L"-uninstall -quiet", (dependencyProvider.sczKey && *dependencyProvider.sczKey) ? &dependencyProvider : NULL, diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 627da49a..35ddb22f 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp @@ -1154,7 +1154,7 @@ namespace Bootstrapper pRelatedBundle->fPlannable = TRUE; pRelatedBundle->relationType = BOOTSTRAPPER_RELATION_UPGRADE; - hr = PseudoBundleInitialize(0, &pRelatedBundle->package, TRUE, wzId, pRelatedBundle->relationType, BOOTSTRAPPER_PACKAGE_STATE_PRESENT, TRUE, wzFilePath, wzFilePath, NULL, 0, FALSE, L"-quiet", L"-repair -quiet", L"-uninstall -quiet", &dependencyProvider, NULL, 0); + hr = PseudoBundleInitialize(&pRelatedBundle->package, TRUE, TRUE, wzId, pRelatedBundle->relationType, BOOTSTRAPPER_PACKAGE_STATE_PRESENT, TRUE, wzFilePath, wzFilePath, NULL, 0, FALSE, L"-quiet", L"-repair -quiet", L"-uninstall -quiet", &dependencyProvider, NULL, 0); NativeAssert::Succeeded(hr, "Failed to initialize related bundle to represent bundle: %ls", wzId); ++pRelatedBundles->cRelatedBundles; -- cgit v1.2.3-55-g6feb