From 375c94df2b016a7c1c7290f8d432284eb49f2356 Mon Sep 17 00:00:00 2001 From: Nir Bar Date: Mon, 5 Jun 2023 13:27:56 +0300 Subject: [PATCH] Fixes wixtoolset/issues#5220: Automatically add logging flag for any burn ExePackage, BundlePackage, and related bundles --- src/burn/engine/bundlepackageengine.cpp | 3 ++ src/burn/engine/core.cpp | 64 ++++++++++++++++++++++++- src/burn/engine/core.h | 7 +++ src/burn/engine/exeengine.cpp | 6 +++ src/burn/engine/logging.cpp | 13 +++++ src/burn/engine/pseudobundle.cpp | 14 +++++- 6 files changed, 104 insertions(+), 3 deletions(-) diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp index 61911fb43..d3f59e5df 100644 --- a/src/burn/engine/bundlepackageengine.cpp +++ b/src/burn/engine/bundlepackageengine.cpp @@ -1000,6 +1000,9 @@ static HRESULT ExecuteBundle( ExitOnFailure(hr, "Failed to allocate obfuscated bundle command."); } + // Append logging to command line if it doesn't contain '-log' + CoreAppendLogToCommandLine(&sczBaseCommand, &sczCommandObfuscated, fRollback, pVariables, pPackage); + // Log obfuscated command, which won't include raw hidden variable values or protocol specific arguments to avoid exposing secrets. LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(action), sczExecutablePath, sczCommandObfuscated ? sczCommandObfuscated : sczBaseCommand); diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 8903b5b2f..b60672da4 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp @@ -227,7 +227,7 @@ extern "C" HRESULT CoreInitializeConstants( hr = StrAllocString(&pRegistration->sczBundlePackageAncestors, pRegistration->sczId, 0); ExitOnFailure(hr, "Failed to copy self to bundle package ancestors."); } - + for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i) { BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i; @@ -1301,6 +1301,66 @@ extern "C" HRESULT CoreAppendFileHandleSelfToCommandLine( return hr; } +HRESULT CoreAppendLogToCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __deref_inout_z_opt LPWSTR* psczObfuscatedCommandLine, + __in BOOL fRollback, + __in BURN_VARIABLES* pVariables, + __in BURN_PACKAGE *pPackage + ) +{ + HRESULT hr = S_OK; + INT ccArgs = 0; + LPWSTR* rgszArgs = nullptr; + LPWSTR szLogArg = nullptr; + LPWSTR szLogArgFormatted = nullptr; + LPCWSTR szLogVar = fRollback ? pPackage->sczRollbackLogPathVariable : pPackage->sczLogPathVariable; + + if (!szLogVar || !*szLogVar) + { + ExitFunction1(hr = S_FALSE); + } + + hr = AppParseCommandLine(*psczCommandLine, &ccArgs, &rgszArgs); + ExitOnFailure(hr, "Failed parsing command line"); + + // Log flag already present? + for (INT i = 0; i < ccArgs; ++i) + { + if (rgszArgs[i][0] == L'-' || rgszArgs[i][0] == L'/') + { + // Now looking for 'log' or 'l' + if ((CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &rgszArgs[i][1], -1, L"log", -1)) + || (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &rgszArgs[i][1], -1, L"l", -1))) + { + ExitFunction1(hr = S_FALSE); + } + } + } + + hr = StrAllocFormatted(&szLogArg, L" -log \"[%ls]\"", szLogVar); + ExitOnFailure(hr, "Failed creating log argument"); + + hr = VariableFormatString(pVariables, szLogArg, &szLogArgFormatted, NULL); + ExitOnFailure(hr, "Failed to format argument string."); + + hr = StrAllocConcat(psczCommandLine, szLogArgFormatted, 0); + ExitOnFailure(hr, "Failed concatenating '-log' to command line"); + + hr = StrAllocConcat(psczObfuscatedCommandLine, szLogArgFormatted, 0); + ExitOnFailure(hr, "Failed concatenating '-log' to obfuscated command line"); + +LExit: + if (rgszArgs) + { + AppFreeCommandLineArgs(rgszArgs); + } + ReleaseStr(szLogArg); + ReleaseStr(szLogArgFormatted); + + return hr; +} + extern "C" HRESULT CoreAppendSplashScreenWindowToCommandLine( __in_opt HWND hwndSplashScreen, __deref_inout_z LPWSTR* psczCommandLine @@ -2285,7 +2345,7 @@ static HRESULT DetectPackage( { HRESULT hr = S_OK; BOOL fBegan = FALSE; - + fBegan = TRUE; hr = UserExperienceOnDetectPackageBegin(&pEngineState->userExperience, pPackage->sczId); ExitOnRootFailure(hr, "BA aborted detect package begin."); diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index 186b49ca0..1e6726515 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h @@ -306,6 +306,13 @@ HRESULT CoreAppendFileHandleSelfToCommandLine( __deref_inout_z LPWSTR* psczCommandLine, __deref_inout_z_opt LPWSTR* psczObfuscatedCommandLine ); +HRESULT CoreAppendLogToCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __deref_inout_z_opt LPWSTR* psczObfuscatedCommandLine, + __in BOOL fRollback, + __in BURN_VARIABLES* pVariables, + __in BURN_PACKAGE *pPackage + ); HRESULT CoreAppendSplashScreenWindowToCommandLine( __in_opt HWND hwndSplashScreen, __deref_inout_z LPWSTR* psczCommandLine diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index 6d326a5a7..81cea82cf 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp @@ -616,6 +616,12 @@ extern "C" HRESULT ExeEngineExecutePackage( ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); } + // For bundles, append logging to command line if it doesn't contain '-log' + if (pPackage->Exe.fBundle || BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) + { + CoreAppendLogToCommandLine(&sczBaseCommand, &sczCommandObfuscated, fRollback, pVariables, pPackage); + } + // build user args if (sczUnformattedUserArgs && *sczUnformattedUserArgs) { diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index a16e82b0d..630598ae1 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp @@ -325,6 +325,19 @@ extern "C" HRESULT LoggingSetPackageVariable( ExitFunction(); } + // For burn packages we'll add logging even it it wasn't explictly specified + if (BURN_PACKAGE_TYPE_BUNDLE == pPackage->type || (BURN_PACKAGE_TYPE_EXE == pPackage->type && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)) + { + if (!fRollback && (!pPackage->sczLogPathVariable || !*pPackage->sczLogPathVariable)) + { + StrAllocFormatted(&pPackage->sczLogPathVariable, L"WixBundleLog_%ls", pPackage->sczId); + } + else if (fRollback && (!pPackage->sczRollbackLogPathVariable || !*pPackage->sczRollbackLogPathVariable)) + { + StrAllocFormatted(&pPackage->sczRollbackLogPathVariable, L"WixBundleRollbackLog_%ls", pPackage->sczId); + } + } + if ((!fRollback && pPackage->sczLogPathVariable && *pPackage->sczLogPathVariable) || (fRollback && pPackage->sczRollbackLogPathVariable && *pPackage->sczRollbackLogPathVariable)) { diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index 8b30ebfcd..f0d670683 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp @@ -27,7 +27,7 @@ extern "C" HRESULT PseudoBundleInitializeRelated( ExitOnNull(pPackage->payloads.rgItems, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload group inside of related bundle struct"); pPackage->payloads.cItems = 1; - pPayload = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD), TRUE); + pPayload = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD), TRUE); ExitOnNull(pPayload, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct"); pPackage->payloads.rgItems[0].pPayload = pPayload; pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL; @@ -59,6 +59,10 @@ extern "C" HRESULT PseudoBundleInitializeRelated( hr = StrAllocString(&pPackage->sczCacheId, wzId, 0); ExitOnFailure(hr, "Failed to copy cache id for pseudo bundle."); + // Log variables - best effort + StrAllocFormatted(&pPackage->sczLogPathVariable, L"WixBundleLog_%ls", pPackage->sczId); + StrAllocFormatted(&pPackage->sczRollbackLogPathVariable, L"WixBundleRollbackLog_%ls", pPackage->sczId); + if (pDependencyProvider) { pPackage->rgDependencyProviders = (BURN_DEPENDENCY_PROVIDER*)MemAlloc(sizeof(BURN_DEPENDENCY_PROVIDER), TRUE); @@ -122,6 +126,10 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( hr = StrAllocString(&pPassthroughPackage->sczCacheId, pPackage->sczCacheId, 0); ExitOnFailure(hr, "Failed to copy cache id for passthrough pseudo bundle."); + // Log variables - best effort + StrAllocFormatted(&pPackage->sczLogPathVariable, L"WixBundleLog_%ls", pPackage->sczId); + StrAllocFormatted(&pPackage->sczRollbackLogPathVariable, L"WixBundleRollbackLog_%ls", pPackage->sczId); + hr = CoreCreatePassthroughBundleCommandLine(&sczArguments, pInternalCommand, pCommand); ExitOnFailure(hr, "Failed to create command-line arguments."); @@ -207,6 +215,10 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle( hr = StrAllocString(&pPackage->sczCacheId, wzCacheId, 0); ExitOnFailure(hr, "Failed to copy cache id for update bundle."); + // Log variables - best effort + StrAllocFormatted(&pPackage->sczLogPathVariable, L"WixBundleLog_%ls", pPackage->sczId); + StrAllocFormatted(&pPackage->sczRollbackLogPathVariable, L"WixBundleRollbackLog_%ls", pPackage->sczId); + hr = StrAllocString(&pPackage->Exe.sczInstallArguments, wzInstallArguments, 0); ExitOnFailure(hr, "Failed to copy install arguments for update bundle package");