From fa393914f12f6d6bc88a73e4d5b009da765f6dd5 Mon Sep 17 00:00:00 2001
From: Jacob Hoover <jacob.hoover@greenheck.com>
Date: Thu, 10 Nov 2022 10:48:23 -0600
Subject: WIXFEAT-3704 - Allow access to persisted variables from related
 bundles

---
 .../inc/BootstrapperEngine.h                       | 15 +++++++
 .../inc/BundleExtensionEngine.h                    | 16 +++++++
 src/api/burn/balutil/BalBootstrapperEngine.cpp     | 28 ++++++++++++
 src/api/burn/balutil/balutil.cpp                   | 51 ++++++++++++++++++++++
 src/api/burn/balutil/inc/IBootstrapperEngine.h     |  8 ++++
 src/api/burn/balutil/inc/balutil.h                 | 24 ++++++++++
 .../burn/bextutil/BextBundleExtensionEngine.cpp    | 29 ++++++++++++
 src/api/burn/bextutil/inc/IBundleExtensionEngine.h |  7 +++
 8 files changed, 178 insertions(+)

(limited to 'src/api')

diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
index 941e4241..96302bd1 100644
--- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
+++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
@@ -111,6 +111,7 @@ enum BOOTSTRAPPER_ENGINE_MESSAGE
     BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE,
     BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATESOURCE,
     BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS,
+    BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE,
 };
 
 typedef struct _BAENGINE_APPLY_ARGS
@@ -426,6 +427,20 @@ typedef struct _BAENGINE_SETVARIABLEVERSION_RESULTS
     DWORD cbSize;
 } BAENGINE_SETVARIABLEVERSION_RESULTS;
 
+typedef struct _BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS
+{
+    DWORD cbSize;
+    LPCWSTR wzBundleId;
+    LPCWSTR wzVariable;
+} BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS;
+
+typedef struct _BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS
+{
+    DWORD cbSize;
+    LPWSTR wzValue;
+    // Should be initialized to the size of wzValue.
+    SIZE_T cchValue;
+} BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS;
 
 extern "C" typedef HRESULT(WINAPI *PFN_BOOTSTRAPPER_ENGINE_PROC)(
     __in BOOTSTRAPPER_ENGINE_MESSAGE message,
diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BundleExtensionEngine.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BundleExtensionEngine.h
index b397ec16..b585d1a2 100644
--- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BundleExtensionEngine.h
+++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BundleExtensionEngine.h
@@ -28,6 +28,7 @@ enum BUNDLE_EXTENSION_ENGINE_MESSAGE
     BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLESTRING,
     BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLEVERSION,
     BUNDLE_EXTENSION_ENGINE_MESSAGE_COMPAREVERSIONS,
+    BUNDLE_EXTENSION_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE,
 };
 
 typedef struct _BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_ARGS
@@ -172,6 +173,21 @@ typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS
     DWORD cbSize;
 } BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS;
 
+typedef struct _BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS
+{
+    DWORD cbSize;
+    LPCWSTR wzBundleId;
+    LPCWSTR wzVariable;
+} BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS;
+
+typedef struct _BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS
+{
+    DWORD cbSize;
+    LPWSTR wzValue;
+    // Should be initialized to the size of wzValue.
+    SIZE_T cchValue;
+} BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS;
+
 extern "C" typedef HRESULT(WINAPI *PFN_BUNDLE_EXTENSION_ENGINE_PROC)(
     __in BUNDLE_EXTENSION_ENGINE_MESSAGE message,
     __in const LPVOID pvArgs,
diff --git a/src/api/burn/balutil/BalBootstrapperEngine.cpp b/src/api/burn/balutil/BalBootstrapperEngine.cpp
index 898a8a15..be53c6b9 100644
--- a/src/api/burn/balutil/BalBootstrapperEngine.cpp
+++ b/src/api/burn/balutil/BalBootstrapperEngine.cpp
@@ -158,6 +158,34 @@ public: // IBootstrapperEngine
         return hr;
     }
 
+    virtual STDMETHODIMP GetRelatedBundleVariable(
+        __in_z LPCWSTR wzBundleId,
+        __in_z LPCWSTR wzVariable,
+        __out_ecount_opt(*pcchValue) LPWSTR wzValue,
+        __inout SIZE_T* pcchValue
+    )
+    {
+        HRESULT hr = S_OK;
+        BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS args = { };
+        BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS results = { };
+
+        ExitOnNull(pcchValue, hr, E_INVALIDARG, "pcchValue is required");
+
+        args.cbSize = sizeof(args);
+        args.wzBundleId = wzBundleId;
+        args.wzVariable = wzVariable;
+
+        results.cbSize = sizeof(results);
+        results.wzValue = wzValue;
+        results.cchValue = *pcchValue;
+
+        hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE, &args, &results, m_pvBAEngineProcContext);
+
+        *pcchValue = results.cchValue;
+    LExit:
+        return hr;
+    }
+
     virtual STDMETHODIMP FormatString(
         __in_z LPCWSTR wzIn,
         __out_ecount_opt(*pcchOut) LPWSTR wzOut,
diff --git a/src/api/burn/balutil/balutil.cpp b/src/api/burn/balutil/balutil.cpp
index 5671da4e..2d80878c 100644
--- a/src/api/burn/balutil/balutil.cpp
+++ b/src/api/burn/balutil/balutil.cpp
@@ -421,6 +421,57 @@ LExit:
     return hr;
 }
 
+DAPI_(HRESULT) BalGetRelatedBundleVariable(
+    __in_z LPCWSTR wzBundleId,
+    __in_z LPCWSTR wzVariable,
+    __inout LPWSTR* psczValue
+)
+{
+    HRESULT hr = S_OK;
+
+    if (!vpEngine)
+    {
+        hr = E_POINTER;
+        ExitOnRootFailure(hr, "BalInitialize() must be called first.");
+    }
+
+    hr = BalGetRelatedBundleVariableFromEngine(vpEngine, wzBundleId, wzVariable, psczValue);
+
+LExit:
+    return hr;
+}
+
+DAPI_(HRESULT) BalGetRelatedBundleVariableFromEngine(
+    __in IBootstrapperEngine* pEngine,
+    __in_z LPCWSTR wzBundleId,
+    __in_z LPCWSTR wzVariable,
+    __inout LPWSTR* psczValue
+)
+{
+    HRESULT hr = S_OK;
+    SIZE_T cch = 0;
+
+    if (*psczValue)
+    {
+        hr = StrMaxLength(*psczValue, reinterpret_cast<DWORD_PTR*>(&cch));
+        ExitOnFailure(hr, "Failed to determine length of value.");
+    }
+
+    hr = pEngine->GetRelatedBundleVariable(wzBundleId, wzVariable, *psczValue, &cch);
+    if (E_MOREDATA == hr)
+    {
+        ++cch;
+
+        hr = StrAllocSecure(psczValue, cch);
+        ExitOnFailure(hr, "Failed to allocate value.");
+
+        hr = pEngine->GetRelatedBundleVariable(wzBundleId, wzVariable, *psczValue, &cch);
+    }
+
+LExit:
+    return hr;
+}
+
 DAPI_(HRESULT) BalSetVersionVariable(
     __in_z LPCWSTR wzVariable,
     __in_z_opt LPCWSTR wzValue
diff --git a/src/api/burn/balutil/inc/IBootstrapperEngine.h b/src/api/burn/balutil/inc/IBootstrapperEngine.h
index 2a108223..bfa13997 100644
--- a/src/api/burn/balutil/inc/IBootstrapperEngine.h
+++ b/src/api/burn/balutil/inc/IBootstrapperEngine.h
@@ -136,4 +136,12 @@ DECLARE_INTERFACE_IID_(IBootstrapperEngine, IUnknown, "6480D616-27A0-44D7-905B-8
         __in_z LPCWSTR wzVersion2,
         __out int* pnResult
         ) = 0;
+
+    STDMETHOD(GetRelatedBundleVariable)(
+        __in_z LPCWSTR wzBundleId,
+        __in_z LPCWSTR wzVariable,
+        __out_ecount_opt(*pcchValue) LPWSTR wzValue,
+        __inout SIZE_T* pcchValue
+        ) = 0;
+
 };
diff --git a/src/api/burn/balutil/inc/balutil.h b/src/api/burn/balutil/inc/balutil.h
index 3040cfe8..36c165a3 100644
--- a/src/api/burn/balutil/inc/balutil.h
+++ b/src/api/burn/balutil/inc/balutil.h
@@ -139,6 +139,30 @@ DAPI_(HRESULT) BalGetNumericVariable(
     __out LONGLONG* pllValue
     );
 
+/*******************************************************************
+BalGetRelatedBundleVariable - gets a string from a shared variable in the engine.
+
+Note: Use StrFree() to release psczValue.
+********************************************************************/
+DAPI_(HRESULT) BalGetRelatedBundleVariable(
+    __in_z LPCWSTR wzBundleId,
+    __in_z LPCWSTR wzVariable,
+    __inout LPWSTR* psczValue
+);
+
+/*******************************************************************
+BalGetRelatedBundleVariableFromEngine - gets a string from a shared variable in the engine.
+
+ Note: Use StrFree() to release psczValue.
+********************************************************************/
+DAPI_(HRESULT) BalGetRelatedBundleVariableFromEngine(
+    __in IBootstrapperEngine* pEngine,
+    __in_z LPCWSTR wzBundleId,
+    __in_z LPCWSTR wzVariable,
+    __inout LPWSTR* psczValue
+);
+
+
 /*******************************************************************
 BalSetNumericVariable - sets a numeric variable in the engine.
 
diff --git a/src/api/burn/bextutil/BextBundleExtensionEngine.cpp b/src/api/burn/bextutil/BextBundleExtensionEngine.cpp
index 6043e2db..2c854817 100644
--- a/src/api/burn/bextutil/BextBundleExtensionEngine.cpp
+++ b/src/api/burn/bextutil/BextBundleExtensionEngine.cpp
@@ -306,6 +306,35 @@ public: // IBundleExtensionEngine
         return hr;
     }
 
+    virtual STDMETHODIMP GetRelatedBundleVariable(
+        __in_z LPCWSTR wzBundleId,
+        __in_z LPCWSTR wzVariable,
+        __out_ecount_opt(*pcchValue) LPWSTR wzValue,
+        __inout SIZE_T* pcchValue
+    )
+    {
+        HRESULT hr = S_OK;
+        BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS args = { };
+        BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS results = { };
+
+        ExitOnNull(pcchValue, hr, E_INVALIDARG, "pcchValue is required");
+
+        args.cbSize = sizeof(args);
+        args.wzBundleId = wzBundleId;
+        args.wzVariable = wzVariable;
+
+        results.cbSize = sizeof(results);
+        results.wzValue = wzValue;
+        results.cchValue = *pcchValue;
+
+        hr = m_pfnBundleExtensionEngineProc(BUNDLE_EXTENSION_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE, &args, &results, m_pvBundleExtensionEngineProcContext);
+
+        *pcchValue = results.cchValue;
+
+    LExit:
+        return hr;
+    }
+
 public:
     CBextBundleExtensionEngine(
         __in PFN_BUNDLE_EXTENSION_ENGINE_PROC pfnBundleExtensionEngineProc,
diff --git a/src/api/burn/bextutil/inc/IBundleExtensionEngine.h b/src/api/burn/bextutil/inc/IBundleExtensionEngine.h
index 63dadb06..0053a71e 100644
--- a/src/api/burn/bextutil/inc/IBundleExtensionEngine.h
+++ b/src/api/burn/bextutil/inc/IBundleExtensionEngine.h
@@ -64,4 +64,11 @@ DECLARE_INTERFACE_IID_(IBundleExtensionEngine, IUnknown, "9D027A39-F6B6-42CC-973
         __in_z LPCWSTR wzVersion2,
         __out int* pnResult
         ) = 0;
+
+    STDMETHOD(GetRelatedBundleVariable)(
+        __in_z LPCWSTR wzBundleId,
+        __in_z LPCWSTR wzVariable,
+        __out_ecount_opt(*pcchValue) LPWSTR wzValue,
+        __inout SIZE_T * pcchValue
+        ) = 0;
 };
-- 
cgit v1.2.3-55-g6feb