aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJacob Hoover <jacob.hoover@greenheck.com>2022-11-10 10:48:23 -0600
committerSean Hall <r.sean.hall@gmail.com>2022-11-10 23:49:10 -0600
commitfa393914f12f6d6bc88a73e4d5b009da765f6dd5 (patch)
tree6dbf354d4542b3e085795b0a917eaafc1eead415 /src
parentc843b47d6233153fa961c6d0e61edf7cedf255bb (diff)
downloadwix-fa393914f12f6d6bc88a73e4d5b009da765f6dd5.tar.gz
wix-fa393914f12f6d6bc88a73e4d5b009da765f6dd5.tar.bz2
wix-fa393914f12f6d6bc88a73e4d5b009da765f6dd5.zip
WIXFEAT-3704 - Allow access to persisted variables from related bundles
Diffstat (limited to 'src')
-rw-r--r--src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h15
-rw-r--r--src/api/burn/WixToolset.BootstrapperCore.Native/inc/BundleExtensionEngine.h16
-rw-r--r--src/api/burn/balutil/BalBootstrapperEngine.cpp28
-rw-r--r--src/api/burn/balutil/balutil.cpp51
-rw-r--r--src/api/burn/balutil/inc/IBootstrapperEngine.h8
-rw-r--r--src/api/burn/balutil/inc/balutil.h24
-rw-r--r--src/api/burn/bextutil/BextBundleExtensionEngine.cpp29
-rw-r--r--src/api/burn/bextutil/inc/IBundleExtensionEngine.h7
-rw-r--r--src/burn/engine/EngineForApplication.cpp19
-rw-r--r--src/burn/engine/EngineForExtension.cpp19
-rw-r--r--src/burn/engine/externalengine.cpp20
-rw-r--r--src/burn/engine/externalengine.h8
-rw-r--r--src/burn/test/BurnUnitTest/VariantTest.cpp8
-rw-r--r--src/libs/dutil/WixToolset.DUtil/iniutil.cpp2
-rw-r--r--src/libs/dutil/WixToolset.DUtil/path2utl.cpp11
-rw-r--r--src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.cpp133
-rw-r--r--src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.def6
-rw-r--r--src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.vcxproj66
-rw-r--r--src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.cpp48
-rw-r--r--src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.h43
-rw-r--r--src/test/burn/TestData/Manual/BundleD/BundleD.wixproj22
-rw-r--r--src/test/burn/TestData/Manual/BundleD/BundleD.wxs17
-rw-r--r--src/test/burn/TestData/Manual/BundleD/ManualTests.txt10
23 files changed, 604 insertions, 6 deletions
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
111 BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE, 111 BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE,
112 BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATESOURCE, 112 BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATESOURCE,
113 BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS, 113 BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS,
114 BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE,
114}; 115};
115 116
116typedef struct _BAENGINE_APPLY_ARGS 117typedef struct _BAENGINE_APPLY_ARGS
@@ -426,6 +427,20 @@ typedef struct _BAENGINE_SETVARIABLEVERSION_RESULTS
426 DWORD cbSize; 427 DWORD cbSize;
427} BAENGINE_SETVARIABLEVERSION_RESULTS; 428} BAENGINE_SETVARIABLEVERSION_RESULTS;
428 429
430typedef struct _BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS
431{
432 DWORD cbSize;
433 LPCWSTR wzBundleId;
434 LPCWSTR wzVariable;
435} BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS;
436
437typedef struct _BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS
438{
439 DWORD cbSize;
440 LPWSTR wzValue;
441 // Should be initialized to the size of wzValue.
442 SIZE_T cchValue;
443} BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS;
429 444
430extern "C" typedef HRESULT(WINAPI *PFN_BOOTSTRAPPER_ENGINE_PROC)( 445extern "C" typedef HRESULT(WINAPI *PFN_BOOTSTRAPPER_ENGINE_PROC)(
431 __in BOOTSTRAPPER_ENGINE_MESSAGE message, 446 __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
28 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLESTRING, 28 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLESTRING,
29 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLEVERSION, 29 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLEVERSION,
30 BUNDLE_EXTENSION_ENGINE_MESSAGE_COMPAREVERSIONS, 30 BUNDLE_EXTENSION_ENGINE_MESSAGE_COMPAREVERSIONS,
31 BUNDLE_EXTENSION_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE,
31}; 32};
32 33
33typedef struct _BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_ARGS 34typedef struct _BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_ARGS
@@ -172,6 +173,21 @@ typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS
172 DWORD cbSize; 173 DWORD cbSize;
173} BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS; 174} BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS;
174 175
176typedef struct _BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS
177{
178 DWORD cbSize;
179 LPCWSTR wzBundleId;
180 LPCWSTR wzVariable;
181} BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS;
182
183typedef struct _BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS
184{
185 DWORD cbSize;
186 LPWSTR wzValue;
187 // Should be initialized to the size of wzValue.
188 SIZE_T cchValue;
189} BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS;
190
175extern "C" typedef HRESULT(WINAPI *PFN_BUNDLE_EXTENSION_ENGINE_PROC)( 191extern "C" typedef HRESULT(WINAPI *PFN_BUNDLE_EXTENSION_ENGINE_PROC)(
176 __in BUNDLE_EXTENSION_ENGINE_MESSAGE message, 192 __in BUNDLE_EXTENSION_ENGINE_MESSAGE message,
177 __in const LPVOID pvArgs, 193 __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
158 return hr; 158 return hr;
159 } 159 }
160 160
161 virtual STDMETHODIMP GetRelatedBundleVariable(
162 __in_z LPCWSTR wzBundleId,
163 __in_z LPCWSTR wzVariable,
164 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
165 __inout SIZE_T* pcchValue
166 )
167 {
168 HRESULT hr = S_OK;
169 BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS args = { };
170 BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS results = { };
171
172 ExitOnNull(pcchValue, hr, E_INVALIDARG, "pcchValue is required");
173
174 args.cbSize = sizeof(args);
175 args.wzBundleId = wzBundleId;
176 args.wzVariable = wzVariable;
177
178 results.cbSize = sizeof(results);
179 results.wzValue = wzValue;
180 results.cchValue = *pcchValue;
181
182 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE, &args, &results, m_pvBAEngineProcContext);
183
184 *pcchValue = results.cchValue;
185 LExit:
186 return hr;
187 }
188
161 virtual STDMETHODIMP FormatString( 189 virtual STDMETHODIMP FormatString(
162 __in_z LPCWSTR wzIn, 190 __in_z LPCWSTR wzIn,
163 __out_ecount_opt(*pcchOut) LPWSTR wzOut, 191 __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:
421 return hr; 421 return hr;
422} 422}
423 423
424DAPI_(HRESULT) BalGetRelatedBundleVariable(
425 __in_z LPCWSTR wzBundleId,
426 __in_z LPCWSTR wzVariable,
427 __inout LPWSTR* psczValue
428)
429{
430 HRESULT hr = S_OK;
431
432 if (!vpEngine)
433 {
434 hr = E_POINTER;
435 ExitOnRootFailure(hr, "BalInitialize() must be called first.");
436 }
437
438 hr = BalGetRelatedBundleVariableFromEngine(vpEngine, wzBundleId, wzVariable, psczValue);
439
440LExit:
441 return hr;
442}
443
444DAPI_(HRESULT) BalGetRelatedBundleVariableFromEngine(
445 __in IBootstrapperEngine* pEngine,
446 __in_z LPCWSTR wzBundleId,
447 __in_z LPCWSTR wzVariable,
448 __inout LPWSTR* psczValue
449)
450{
451 HRESULT hr = S_OK;
452 SIZE_T cch = 0;
453
454 if (*psczValue)
455 {
456 hr = StrMaxLength(*psczValue, reinterpret_cast<DWORD_PTR*>(&cch));
457 ExitOnFailure(hr, "Failed to determine length of value.");
458 }
459
460 hr = pEngine->GetRelatedBundleVariable(wzBundleId, wzVariable, *psczValue, &cch);
461 if (E_MOREDATA == hr)
462 {
463 ++cch;
464
465 hr = StrAllocSecure(psczValue, cch);
466 ExitOnFailure(hr, "Failed to allocate value.");
467
468 hr = pEngine->GetRelatedBundleVariable(wzBundleId, wzVariable, *psczValue, &cch);
469 }
470
471LExit:
472 return hr;
473}
474
424DAPI_(HRESULT) BalSetVersionVariable( 475DAPI_(HRESULT) BalSetVersionVariable(
425 __in_z LPCWSTR wzVariable, 476 __in_z LPCWSTR wzVariable,
426 __in_z_opt LPCWSTR wzValue 477 __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
136 __in_z LPCWSTR wzVersion2, 136 __in_z LPCWSTR wzVersion2,
137 __out int* pnResult 137 __out int* pnResult
138 ) = 0; 138 ) = 0;
139
140 STDMETHOD(GetRelatedBundleVariable)(
141 __in_z LPCWSTR wzBundleId,
142 __in_z LPCWSTR wzVariable,
143 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
144 __inout SIZE_T* pcchValue
145 ) = 0;
146
139}; 147};
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
@@ -140,6 +140,30 @@ DAPI_(HRESULT) BalGetNumericVariable(
140 ); 140 );
141 141
142/******************************************************************* 142/*******************************************************************
143BalGetRelatedBundleVariable - gets a string from a shared variable in the engine.
144
145Note: Use StrFree() to release psczValue.
146********************************************************************/
147DAPI_(HRESULT) BalGetRelatedBundleVariable(
148 __in_z LPCWSTR wzBundleId,
149 __in_z LPCWSTR wzVariable,
150 __inout LPWSTR* psczValue
151);
152
153/*******************************************************************
154BalGetRelatedBundleVariableFromEngine - gets a string from a shared variable in the engine.
155
156 Note: Use StrFree() to release psczValue.
157********************************************************************/
158DAPI_(HRESULT) BalGetRelatedBundleVariableFromEngine(
159 __in IBootstrapperEngine* pEngine,
160 __in_z LPCWSTR wzBundleId,
161 __in_z LPCWSTR wzVariable,
162 __inout LPWSTR* psczValue
163);
164
165
166/*******************************************************************
143BalSetNumericVariable - sets a numeric variable in the engine. 167BalSetNumericVariable - sets a numeric variable in the engine.
144 168
145********************************************************************/ 169********************************************************************/
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
306 return hr; 306 return hr;
307 } 307 }
308 308
309 virtual STDMETHODIMP GetRelatedBundleVariable(
310 __in_z LPCWSTR wzBundleId,
311 __in_z LPCWSTR wzVariable,
312 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
313 __inout SIZE_T* pcchValue
314 )
315 {
316 HRESULT hr = S_OK;
317 BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS args = { };
318 BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS results = { };
319
320 ExitOnNull(pcchValue, hr, E_INVALIDARG, "pcchValue is required");
321
322 args.cbSize = sizeof(args);
323 args.wzBundleId = wzBundleId;
324 args.wzVariable = wzVariable;
325
326 results.cbSize = sizeof(results);
327 results.wzValue = wzValue;
328 results.cchValue = *pcchValue;
329
330 hr = m_pfnBundleExtensionEngineProc(BUNDLE_EXTENSION_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE, &args, &results, m_pvBundleExtensionEngineProcContext);
331
332 *pcchValue = results.cchValue;
333
334 LExit:
335 return hr;
336 }
337
309public: 338public:
310 CBextBundleExtensionEngine( 339 CBextBundleExtensionEngine(
311 __in PFN_BUNDLE_EXTENSION_ENGINE_PROC pfnBundleExtensionEngineProc, 340 __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
64 __in_z LPCWSTR wzVersion2, 64 __in_z LPCWSTR wzVersion2,
65 __out int* pnResult 65 __out int* pnResult
66 ) = 0; 66 ) = 0;
67
68 STDMETHOD(GetRelatedBundleVariable)(
69 __in_z LPCWSTR wzBundleId,
70 __in_z LPCWSTR wzVariable,
71 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
72 __inout SIZE_T * pcchValue
73 ) = 0;
67}; 74};
diff --git a/src/burn/engine/EngineForApplication.cpp b/src/burn/engine/EngineForApplication.cpp
index 45bfaf83..eb77cc50 100644
--- a/src/burn/engine/EngineForApplication.cpp
+++ b/src/burn/engine/EngineForApplication.cpp
@@ -427,6 +427,22 @@ LExit:
427 return hr; 427 return hr;
428} 428}
429 429
430static HRESULT BAEngineGetRelatedBundleVariable(
431 __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext,
432 __in const LPVOID pvArgs,
433 __inout LPVOID pvResults
434 )
435{
436 HRESULT hr = S_OK;
437 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS, pArgs);
438 ValidateMessageResults(hr, pvResults, BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS, pResults);
439
440 hr = ExternalEngineGetRelatedBundleVariable(pContext->pEngineState, pArgs->wzBundleId, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
441
442LExit:
443 return hr;
444}
445
430HRESULT WINAPI EngineForApplicationProc( 446HRESULT WINAPI EngineForApplicationProc(
431 __in BOOTSTRAPPER_ENGINE_MESSAGE message, 447 __in BOOTSTRAPPER_ENGINE_MESSAGE message,
432 __in const LPVOID pvArgs, 448 __in const LPVOID pvArgs,
@@ -519,6 +535,9 @@ HRESULT WINAPI EngineForApplicationProc(
519 case BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS: 535 case BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS:
520 hr = BAEngineCompareVersions(pContext, pvArgs, pvResults); 536 hr = BAEngineCompareVersions(pContext, pvArgs, pvResults);
521 break; 537 break;
538 case BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE:
539 hr = BAEngineGetRelatedBundleVariable(pContext, pvArgs, pvResults);
540 break;
522 default: 541 default:
523 hr = E_NOTIMPL; 542 hr = E_NOTIMPL;
524 break; 543 break;
diff --git a/src/burn/engine/EngineForExtension.cpp b/src/burn/engine/EngineForExtension.cpp
index 2e1c98fd..bb134a61 100644
--- a/src/burn/engine/EngineForExtension.cpp
+++ b/src/burn/engine/EngineForExtension.cpp
@@ -203,6 +203,22 @@ LExit:
203 return hr; 203 return hr;
204} 204}
205 205
206static HRESULT BEEngineGetRelatedBundleVariable(
207 __in BURN_EXTENSION_ENGINE_CONTEXT* pContext,
208 __in const LPVOID pvArgs,
209 __inout LPVOID pvResults
210)
211{
212 HRESULT hr = S_OK;
213 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS, pArgs);
214 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS, pResults);
215
216 hr = ExternalEngineGetRelatedBundleVariable(pContext->pEngineState, pArgs->wzBundleId, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
217
218LExit:
219 return hr;
220}
221
206HRESULT WINAPI EngineForExtensionProc( 222HRESULT WINAPI EngineForExtensionProc(
207 __in BUNDLE_EXTENSION_ENGINE_MESSAGE message, 223 __in BUNDLE_EXTENSION_ENGINE_MESSAGE message,
208 __in const LPVOID pvArgs, 224 __in const LPVOID pvArgs,
@@ -253,6 +269,9 @@ HRESULT WINAPI EngineForExtensionProc(
253 case BUNDLE_EXTENSION_ENGINE_MESSAGE_COMPAREVERSIONS: 269 case BUNDLE_EXTENSION_ENGINE_MESSAGE_COMPAREVERSIONS:
254 hr = BEEngineCompareVersions(pContext, pvArgs, pvResults); 270 hr = BEEngineCompareVersions(pContext, pvArgs, pvResults);
255 break; 271 break;
272 case BUNDLE_EXTENSION_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE:
273 hr = BEEngineGetRelatedBundleVariable(pContext, pvArgs, pvResults);
274 break;
256 default: 275 default:
257 hr = E_NOTIMPL; 276 hr = E_NOTIMPL;
258 break; 277 break;
diff --git a/src/burn/engine/externalengine.cpp b/src/burn/engine/externalengine.cpp
index 262bb1a9..c38d8fc3 100644
--- a/src/burn/engine/externalengine.cpp
+++ b/src/burn/engine/externalengine.cpp
@@ -801,6 +801,26 @@ LExit:
801 return hr; 801 return hr;
802} 802}
803 803
804HRESULT ExternalEngineGetRelatedBundleVariable(
805 __in BURN_ENGINE_STATE* /*pEngineState*/,
806 __in_z LPCWSTR wzBundleId,
807 __in_z LPCWSTR wzVariable,
808 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
809 __inout SIZE_T* pcchValue
810 )
811{
812 HRESULT hr = S_OK;
813 if (wzVariable && *wzVariable && pcchValue)
814 {
815 hr = BundleGetBundleVariableFixed(wzBundleId, wzVariable, wzValue, pcchValue);
816 }
817 else
818 {
819 hr = E_INVALIDARG;
820 }
821 return hr;
822}
823
804// TODO: callers need to provide the original size (at the time of first public release) of the struct instead of the current size. 824// TODO: callers need to provide the original size (at the time of first public release) of the struct instead of the current size.
805HRESULT WINAPI ExternalEngineValidateMessageParameter( 825HRESULT WINAPI ExternalEngineValidateMessageParameter(
806 __in_opt const LPVOID pv, 826 __in_opt const LPVOID pv,
diff --git a/src/burn/engine/externalengine.h b/src/burn/engine/externalengine.h
index 9322234a..0c8a8cbb 100644
--- a/src/burn/engine/externalengine.h
+++ b/src/burn/engine/externalengine.h
@@ -129,6 +129,14 @@ HRESULT ExternalEngineCompareVersions(
129 __out int* pnResult 129 __out int* pnResult
130 ); 130 );
131 131
132HRESULT ExternalEngineGetRelatedBundleVariable(
133 __in BURN_ENGINE_STATE* pEngineState,
134 __in_z LPCWSTR wzBundleId,
135 __in_z LPCWSTR wzVariable,
136 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
137 __inout SIZE_T* pcchValue
138);
139
132HRESULT ExternalEngineDetect( 140HRESULT ExternalEngineDetect(
133 __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, 141 __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext,
134 __in_opt const HWND hwndParent 142 __in_opt const HWND hwndParent
diff --git a/src/burn/test/BurnUnitTest/VariantTest.cpp b/src/burn/test/BurnUnitTest/VariantTest.cpp
index 43899a2b..035864cf 100644
--- a/src/burn/test/BurnUnitTest/VariantTest.cpp
+++ b/src/burn/test/BurnUnitTest/VariantTest.cpp
@@ -27,11 +27,9 @@ namespace Bootstrapper
27 { 27 {
28 BURN_VARIANT expectedVariants[10]; 28 BURN_VARIANT expectedVariants[10];
29 BURN_VARIANT actualVariants[10]; 29 BURN_VARIANT actualVariants[10];
30 for (DWORD i = 0; i < 10; i++) 30
31 { 31 memset(expectedVariants, 0, sizeof(expectedVariants));
32 BVariantUninitialize(expectedVariants + i); 32 memset(actualVariants, 0, sizeof(actualVariants));
33 BVariantUninitialize(actualVariants + i);
34 }
35 33
36 try 34 try
37 { 35 {
diff --git a/src/libs/dutil/WixToolset.DUtil/iniutil.cpp b/src/libs/dutil/WixToolset.DUtil/iniutil.cpp
index 70b62995..46f6e380 100644
--- a/src/libs/dutil/WixToolset.DUtil/iniutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/iniutil.cpp
@@ -301,6 +301,8 @@ extern "C" HRESULT DAPI IniParse(
301 wzOpenTagPostfix = wcsstr(pi->rgsczLines[i], pi->sczOpenTagPostfix); 301 wzOpenTagPostfix = wcsstr(pi->rgsczLines[i], pi->sczOpenTagPostfix);
302 } 302 }
303 303
304 wzValueNameStart = NULL;
305
304 if (pi->sczValuePrefix) 306 if (pi->sczValuePrefix)
305 { 307 {
306 wzValuePrefix = wcsstr(pi->rgsczLines[i], pi->sczValuePrefix); 308 wzValuePrefix = wcsstr(pi->rgsczLines[i], pi->sczValuePrefix);
diff --git a/src/libs/dutil/WixToolset.DUtil/path2utl.cpp b/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
index 862a743d..d83a4578 100644
--- a/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
@@ -327,6 +327,7 @@ DAPI_(HRESULT) PathDirectoryContainsPath(
327 LPWSTR sczCanonicalizedPath = NULL; 327 LPWSTR sczCanonicalizedPath = NULL;
328 DWORD dwDefaultFlags = PATH_CANONICALIZE_APPEND_EXTENDED_PATH_PREFIX | PATH_CANONICALIZE_KEEP_UNC_ROOT; 328 DWORD dwDefaultFlags = PATH_CANONICALIZE_APPEND_EXTENDED_PATH_PREFIX | PATH_CANONICALIZE_KEEP_UNC_ROOT;
329 size_t cchDirectory = 0; 329 size_t cchDirectory = 0;
330 size_t cchPath = 0;
330 331
331 if (!wzDirectory || !*wzDirectory) 332 if (!wzDirectory || !*wzDirectory)
332 { 333 {
@@ -355,12 +356,20 @@ DAPI_(HRESULT) PathDirectoryContainsPath(
355 hr = ::StringCchLengthW(sczCanonicalizedDirectory, STRSAFE_MAX_CCH, &cchDirectory); 356 hr = ::StringCchLengthW(sczCanonicalizedDirectory, STRSAFE_MAX_CCH, &cchDirectory);
356 PathExitOnFailure(hr, "Failed to get length of canonicalized directory."); 357 PathExitOnFailure(hr, "Failed to get length of canonicalized directory.");
357 358
359 hr = ::StringCchLengthW(sczCanonicalizedPath, STRSAFE_MAX_CCH, &cchPath);
360 PathExitOnFailure(hr, "Failed to get length of canonicalized path.");
361
362 if (cchPath <= cchDirectory)
363 {
364 ExitFunction1(hr = S_FALSE);
365 }
366
358 if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, sczCanonicalizedDirectory, (DWORD)cchDirectory, sczCanonicalizedPath, (DWORD)cchDirectory)) 367 if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, sczCanonicalizedDirectory, (DWORD)cchDirectory, sczCanonicalizedPath, (DWORD)cchDirectory))
359 { 368 {
360 ExitFunction1(hr = S_FALSE); 369 ExitFunction1(hr = S_FALSE);
361 } 370 }
362 371
363 hr = sczCanonicalizedPath[cchDirectory] ? S_OK : S_FALSE; 372 hr = S_OK;
364 373
365LExit: 374LExit:
366 ReleaseStr(sczCanonicalizedPath); 375 ReleaseStr(sczCanonicalizedPath);
diff --git a/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.cpp b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.cpp
new file mode 100644
index 00000000..5da7b170
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.cpp
@@ -0,0 +1,133 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4#include "BalBaseBAFunctions.h"
5#include "BalBaseBAFunctionsProc.h"
6
7const DWORD VARIABLE_GROW_FACTOR = 80;
8const LPCWSTR STRING_VARIABLE = L"AString";
9const LPCWSTR NUMBER_VARIABLE = L"ANumber";
10
11static void CALLBACK BafRelatedBundleVariableTestingTraceError(
12 __in_z LPCSTR szFile,
13 __in int iLine,
14 __in REPORT_LEVEL rl,
15 __in UINT source,
16 __in HRESULT hrError,
17 __in_z __format_string LPCSTR szFormat,
18 __in va_list args
19 );
20
21class CBafRelatedBundleVariableTesting : public CBalBaseBAFunctions
22{
23public: // IBAFunctions
24
25
26public: //IBootstrapperApplication
27 virtual STDMETHODIMP OnDetectRelatedBundle(
28 __in_z LPCWSTR wzBundleId,
29 __in BOOTSTRAPPER_RELATION_TYPE relationType,
30 __in_z LPCWSTR wzBundleTag,
31 __in BOOL fPerMachine,
32 __in LPCWSTR wzVersion,
33 __in BOOL fMissingFromCache,
34 __inout BOOL* pfCancel
35 )
36 {
37
38 HRESULT hr = S_OK;
39 LPWSTR wzValue = NULL;
40
41 hr = BalGetRelatedBundleVariable(wzBundleId, STRING_VARIABLE, &wzValue);
42
43 ExitOnFailure(hr, "Failed to get related bundle string variable.");
44
45 if (wzValue)
46 {
47 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "AString = %ws", wzValue);
48 }
49
50 hr = BalGetRelatedBundleVariable(wzBundleId, NUMBER_VARIABLE, &wzValue);
51
52 if (wzValue)
53 {
54 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "ANumber = %ws", wzValue);
55 }
56
57 hr = __super::OnDetectRelatedBundle(wzBundleId, relationType, wzBundleTag, fPerMachine, wzVersion, fMissingFromCache, pfCancel);
58 LExit:
59 ReleaseStr(wzValue);
60 return hr;
61 }
62private:
63
64
65public:
66 //
67 // Constructor - initialize member variables.
68 //
69 CBafRelatedBundleVariableTesting(
70 __in HMODULE hModule,
71 __in IBootstrapperEngine* pEngine,
72 __in const BA_FUNCTIONS_CREATE_ARGS* pArgs
73 ) : CBalBaseBAFunctions(hModule, pEngine, pArgs)
74 {
75 }
76
77 //
78 // Destructor - release member variables.
79 //
80 ~CBafRelatedBundleVariableTesting()
81 {
82 }
83
84private:
85};
86
87
88HRESULT WINAPI CreateBAFunctions(
89 __in HMODULE hModule,
90 __in const BA_FUNCTIONS_CREATE_ARGS* pArgs,
91 __inout BA_FUNCTIONS_CREATE_RESULTS* pResults
92 )
93{
94 HRESULT hr = S_OK;
95 CBafRelatedBundleVariableTesting* pBAFunctions = NULL;
96 IBootstrapperEngine* pEngine = NULL;
97
98 DutilInitialize(&BafRelatedBundleVariableTestingTraceError);
99
100 hr = BalInitializeFromCreateArgs(pArgs->pBootstrapperCreateArgs, &pEngine);
101 ExitOnFailure(hr, "Failed to initialize Bal.");
102
103 pBAFunctions = new CBafRelatedBundleVariableTesting(hModule, pEngine, pArgs);
104 ExitOnNull(pBAFunctions, hr, E_OUTOFMEMORY, "Failed to create new CBafRelatedBundleVariableTesting object.");
105
106 pResults->pfnBAFunctionsProc = BalBaseBAFunctionsProc;
107 pResults->pvBAFunctionsProcContext = pBAFunctions;
108 pBAFunctions = NULL;
109
110LExit:
111 ReleaseObject(pBAFunctions);
112 ReleaseObject(pEngine);
113
114 return hr;
115}
116
117static void CALLBACK BafRelatedBundleVariableTestingTraceError(
118 __in_z LPCSTR /*szFile*/,
119 __in int /*iLine*/,
120 __in REPORT_LEVEL /*rl*/,
121 __in UINT source,
122 __in HRESULT hrError,
123 __in_z __format_string LPCSTR szFormat,
124 __in va_list args
125 )
126{
127 // BalLogError currently uses the Exit... macros,
128 // so if expanding the scope need to ensure this doesn't get called recursively.
129 if (DUTIL_SOURCE_THMUTIL == source)
130 {
131 BalLogErrorArgs(hrError, szFormat, args);
132 }
133}
diff --git a/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.def b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.def
new file mode 100644
index 00000000..6e016dad
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.def
@@ -0,0 +1,6 @@
1; Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3
4EXPORTS
5 BAFunctionsCreate
6 BAFunctionsDestroy
diff --git a/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.vcxproj b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.vcxproj
new file mode 100644
index 00000000..94d44ac3
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.vcxproj
@@ -0,0 +1,66 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project DefaultTargets="Build" Toolsxmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <ItemGroup Label="ProjectConfigurations">
6 <ProjectConfiguration Include="Debug|ARM64">
7 <Configuration>Debug</Configuration>
8 <Platform>ARM64</Platform>
9 </ProjectConfiguration>
10 <ProjectConfiguration Include="Release|ARM64">
11 <Configuration>Release</Configuration>
12 <Platform>ARM64</Platform>
13 </ProjectConfiguration>
14 <ProjectConfiguration Include="Debug|Win32">
15 <Configuration>Debug</Configuration>
16 <Platform>Win32</Platform>
17 </ProjectConfiguration>
18 <ProjectConfiguration Include="Release|Win32">
19 <Configuration>Release</Configuration>
20 <Platform>Win32</Platform>
21 </ProjectConfiguration>
22 <ProjectConfiguration Include="Debug|x64">
23 <Configuration>Debug</Configuration>
24 <Platform>x64</Platform>
25 </ProjectConfiguration>
26 <ProjectConfiguration Include="Release|x64">
27 <Configuration>Release</Configuration>
28 <Platform>x64</Platform>
29 </ProjectConfiguration>
30 </ItemGroup>
31
32 <PropertyGroup Label="Globals">
33 <ProjectGuid>{DDD02BDE-B44F-4F37-A359-CE802750CB45}</ProjectGuid>
34 <ConfigurationType>DynamicLibrary</ConfigurationType>
35 <CharacterSet>Unicode</CharacterSet>
36 <TargetName>BafRelatedBundleVariableTesting</TargetName>
37 <ProjectModuleDefinitionFile>BafRelatedBundleVariableTesting.def</ProjectModuleDefinitionFile>
38 <IsWixTestProject>true</IsWixTestProject>
39 </PropertyGroup>
40
41 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
42 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
43
44 <PropertyGroup>
45 <ProjectAdditionalLinkLibraries>comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib</ProjectAdditionalLinkLibraries>
46 </PropertyGroup>
47
48 <ItemGroup>
49 <ClCompile Include="BafRelatedBundleVariableTesting.cpp" />
50 <ClCompile Include="precomp.cpp">
51 <PrecompiledHeader>Create</PrecompiledHeader>
52 </ClCompile>
53 </ItemGroup>
54 <ItemGroup>
55 <ClInclude Include="precomp.h" />
56 </ItemGroup>
57 <ItemGroup>
58 <None Include="BafRelatedBundleVariableTesting.def" />
59 </ItemGroup>
60
61 <ItemGroup>
62 <PackageReference Include="WixToolset.BalUtil" />
63 </ItemGroup>
64
65 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
66</Project>
diff --git a/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.cpp b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.cpp
new file mode 100644
index 00000000..fc9d1177
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.cpp
@@ -0,0 +1,48 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5static HINSTANCE vhInstance = NULL;
6
7extern "C" BOOL WINAPI DllMain(
8 IN HINSTANCE hInstance,
9 IN DWORD dwReason,
10 IN LPVOID /* pvReserved */
11 )
12{
13 switch (dwReason)
14 {
15 case DLL_PROCESS_ATTACH:
16 ::DisableThreadLibraryCalls(hInstance);
17 vhInstance = hInstance;
18 break;
19
20 case DLL_PROCESS_DETACH:
21 vhInstance = NULL;
22 break;
23 }
24
25 return TRUE;
26}
27
28extern "C" HRESULT WINAPI BAFunctionsCreate(
29 __in const BA_FUNCTIONS_CREATE_ARGS* pArgs,
30 __inout BA_FUNCTIONS_CREATE_RESULTS* pResults
31 )
32{
33 HRESULT hr = S_OK;
34
35 hr = CreateBAFunctions(vhInstance, pArgs, pResults);
36 BalExitOnFailure(hr, "Failed to create BAFunctions interface.");
37
38LExit:
39 return hr;
40}
41
42extern "C" void WINAPI BAFunctionsDestroy(
43 __in const BA_FUNCTIONS_DESTROY_ARGS* /*pArgs*/,
44 __inout BA_FUNCTIONS_DESTROY_RESULTS* /*pResults*/
45 )
46{
47 BalUninitialize();
48}
diff --git a/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.h b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.h
new file mode 100644
index 00000000..2e14786a
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.h
@@ -0,0 +1,43 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4
5#include <windows.h>
6
7#pragma warning(push)
8#pragma warning(disable:4458) // declaration of 'xxx' hides class member
9#include <gdiplus.h>
10#pragma warning(pop)
11
12#include <msiquery.h>
13#include <objbase.h>
14#include <shlobj.h>
15#include <shlwapi.h>
16#include <stdlib.h>
17#include <strsafe.h>
18#include <CommCtrl.h>
19#include <sddl.h>
20
21#include "dutil.h"
22#include "dictutil.h"
23#include "fileutil.h"
24#include "locutil.h"
25#include "memutil.h"
26#include "pathutil.h"
27#include "procutil.h"
28#include "strutil.h"
29#include "thmutil.h"
30#include "regutil.h"
31#include "xmlutil.h"
32
33#include "BalBaseBootstrapperApplication.h"
34#include "balutil.h"
35
36#include "BAFunctions.h"
37#include "IBAFunctions.h"
38
39HRESULT WINAPI CreateBAFunctions(
40 __in HMODULE hModule,
41 __in const BA_FUNCTIONS_CREATE_ARGS* pArgs,
42 __inout BA_FUNCTIONS_CREATE_RESULTS* pResults
43 );
diff --git a/src/test/burn/TestData/Manual/BundleD/BundleD.wixproj b/src/test/burn/TestData/Manual/BundleD/BundleD.wixproj
new file mode 100644
index 00000000..1df1f895
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BundleD/BundleD.wixproj
@@ -0,0 +1,22 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BA>customHyperlinkLicense</BA>
6 <UpgradeCode>{98ACBCF6-B54A-46AF-8990-DFB8795B965B}</UpgradeCode>
7 <Version Condition=" '$(Version)' == '' ">1.0.0.0</Version>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
11 </ItemGroup>
12 <ItemGroup>
13 <ProjectReference Include="..\BafRelatedBundleVariableTesting\BafRelatedBundleVariableTesting.vcxproj" Properties="Platform=x86" ReferenceOutputAssembly="false" />
14 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" />
18 </ItemGroup>
19 <Target Name="CopyManualInstructions" AfterTargets="AfterBuild">
20 <Copy SourceFiles="ManualTests.txt" DestinationFiles="$(OutputPath)ManualTests.txt" />
21 </Target>
22</Project>
diff --git a/src/test/burn/TestData/Manual/BundleD/BundleD.wxs b/src/test/burn/TestData/Manual/BundleD/BundleD.wxs
new file mode 100644
index 00000000..a877e214
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BundleD/BundleD.wxs
@@ -0,0 +1,17 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
5 <Fragment>
6 <BootstrapperApplication Id="customHyperlinkLicense">
7 <!-- WixStandardBootstrapperApplication.RtfLicense -->
8 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
9 <Payload SourceFile="$(var.BafRelatedBundleVariableTesting.TargetPath)" bal:BAFunctions="yes" />
10 </BootstrapperApplication>
11 <PackageGroup Id="BundlePackages">
12 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
13 </PackageGroup>
14 <Variable Name="ANumber" bal:Overridable="yes" Value="42" Persisted="yes" />
15 <Variable Name="AString" bal:Overridable="yes" Value="This is a test" Persisted="yes" />
16 </Fragment>
17</Wix>
diff --git a/src/test/burn/TestData/Manual/BundleD/ManualTests.txt b/src/test/burn/TestData/Manual/BundleD/ManualTests.txt
new file mode 100644
index 00000000..309338cc
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BundleD/ManualTests.txt
@@ -0,0 +1,10 @@
1BafRelatedBundleVariableTesting
2# Building, Run initial build w/ no parameters, run a second (re)build w/ a /p:Version=1.1.0.0 (ensure it actually builds, as CLI params aren't accounted in the build optimization)
31. Run BundleD.exe (v1.0).
42. Click Install.
53. Verify that the Bundle installs successfully.
64. Run BundleD.exe (v1.1).
75. Check the log file in %TEMP% There should be lines reporting:
8[0708:04B4]i000: AString = This is a test
9[0708:04B4]i000: ANumber = 42
10