@joebigelow / wix-1 / commits / fa393914

WIXFEAT-3704 - Allow access to persisted variables from related bundles

Jacob Hoover committed Nov 10, 2022 at 10:48 UTC fa393914f12f6d6bc88a73e4d5b009da765f6dd5
23 files changed +604 -6
src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
+15
@@ -111,6 +111,7 @@ enum BOOTSTRAPPER_ENGINE_MESSAGE
111 BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE,
112 BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATESOURCE,
113 BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS,
114 + BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE,
115 };
116
117 typedef struct _BAENGINE_APPLY_ARGS
@@ -426,6 +427,20 @@ typedef struct _BAENGINE_SETVARIABLEVERSION_RESULTS
427 DWORD cbSize;
428 } BAENGINE_SETVARIABLEVERSION_RESULTS;
429
430 +typedef struct _BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS
431 +{
432 + DWORD cbSize;
433 + LPCWSTR wzBundleId;
434 + LPCWSTR wzVariable;
435 +} BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS;
436 +
437 +typedef 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;
444
445 extern "C" typedef HRESULT(WINAPI *PFN_BOOTSTRAPPER_ENGINE_PROC)(
446 __in BOOTSTRAPPER_ENGINE_MESSAGE message,
src/api/burn/WixToolset.BootstrapperCore.Native/inc/BundleExtensionEngine.h
+16
@@ -28,6 +28,7 @@ enum BUNDLE_EXTENSION_ENGINE_MESSAGE
28 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLESTRING,
29 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLEVERSION,
30 BUNDLE_EXTENSION_ENGINE_MESSAGE_COMPAREVERSIONS,
31 + BUNDLE_EXTENSION_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE,
32 };
33
34 typedef struct _BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_ARGS
@@ -172,6 +173,21 @@ typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS
173 DWORD cbSize;
174 } BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS;
175
176 +typedef struct _BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS
177 +{
178 + DWORD cbSize;
179 + LPCWSTR wzBundleId;
180 + LPCWSTR wzVariable;
181 +} BUNDLE_EXTENSION_ENGINE_GETRELATEDBUNDLEVARIABLE_ARGS;
182 +
183 +typedef 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 +
191 extern "C" typedef HRESULT(WINAPI *PFN_BUNDLE_EXTENSION_ENGINE_PROC)(
192 __in BUNDLE_EXTENSION_ENGINE_MESSAGE message,
193 __in const LPVOID pvArgs,
src/api/burn/balutil/BalBootstrapperEngine.cpp
+28
@@ -158,6 +158,34 @@ public: // IBootstrapperEngine
158 return hr;
159 }
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 +
189 virtual STDMETHODIMP FormatString(
190 __in_z LPCWSTR wzIn,
191 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
src/api/burn/balutil/balutil.cpp
+51
@@ -421,6 +421,57 @@ LExit:
421 return hr;
422 }
423
424 +DAPI_(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 +
440 +LExit:
441 + return hr;
442 +}
443 +
444 +DAPI_(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 +
471 +LExit:
472 + return hr;
473 +}
474 +
475 DAPI_(HRESULT) BalSetVersionVariable(
476 __in_z LPCWSTR wzVariable,
477 __in_z_opt LPCWSTR wzValue
src/api/burn/balutil/inc/IBootstrapperEngine.h
+8
@@ -136,4 +136,12 @@ DECLARE_INTERFACE_IID_(IBootstrapperEngine, IUnknown, "6480D616-27A0-44D7-905B-8
136 __in_z LPCWSTR wzVersion2,
137 __out int* pnResult
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 +
147 };
src/api/burn/balutil/inc/balutil.h
+24
@@ -139,6 +139,30 @@ DAPI_(HRESULT) BalGetNumericVariable(
139 __out LONGLONG* pllValue
140 );
141
142 +/*******************************************************************
143 +BalGetRelatedBundleVariable - gets a string from a shared variable in the engine.
144 +
145 +Note: Use StrFree() to release psczValue.
146 +********************************************************************/
147 +DAPI_(HRESULT) BalGetRelatedBundleVariable(
148 + __in_z LPCWSTR wzBundleId,
149 + __in_z LPCWSTR wzVariable,
150 + __inout LPWSTR* psczValue
151 +);
152 +
153 +/*******************************************************************
154 +BalGetRelatedBundleVariableFromEngine - gets a string from a shared variable in the engine.
155 +
156 + Note: Use StrFree() to release psczValue.
157 +********************************************************************/
158 +DAPI_(HRESULT) BalGetRelatedBundleVariableFromEngine(
159 + __in IBootstrapperEngine* pEngine,
160 + __in_z LPCWSTR wzBundleId,
161 + __in_z LPCWSTR wzVariable,
162 + __inout LPWSTR* psczValue
163 +);
164 +
165 +
166 /*******************************************************************
167 BalSetNumericVariable - sets a numeric variable in the engine.
168
src/api/burn/bextutil/BextBundleExtensionEngine.cpp
+29
@@ -306,6 +306,35 @@ public: // IBundleExtensionEngine
306 return hr;
307 }
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 +
338 public:
339 CBextBundleExtensionEngine(
340 __in PFN_BUNDLE_EXTENSION_ENGINE_PROC pfnBundleExtensionEngineProc,
src/api/burn/bextutil/inc/IBundleExtensionEngine.h
+7
@@ -64,4 +64,11 @@ DECLARE_INTERFACE_IID_(IBundleExtensionEngine, IUnknown, "9D027A39-F6B6-42CC-973
64 __in_z LPCWSTR wzVersion2,
65 __out int* pnResult
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;
74 };
src/burn/engine/EngineForApplication.cpp
+19
@@ -427,6 +427,22 @@ LExit:
427 return hr;
428 }
429
430 +static 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 +
442 +LExit:
443 + return hr;
444 +}
445 +
446 HRESULT WINAPI EngineForApplicationProc(
447 __in BOOTSTRAPPER_ENGINE_MESSAGE message,
448 __in const LPVOID pvArgs,
@@ -519,6 +535,9 @@ HRESULT WINAPI EngineForApplicationProc(
535 case BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS:
536 hr = BAEngineCompareVersions(pContext, pvArgs, pvResults);
537 break;
538 + case BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE:
539 + hr = BAEngineGetRelatedBundleVariable(pContext, pvArgs, pvResults);
540 + break;
541 default:
542 hr = E_NOTIMPL;
543 break;
src/burn/engine/EngineForExtension.cpp
+19
@@ -203,6 +203,22 @@ LExit:
203 return hr;
204 }
205
206 +static 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 +
218 +LExit:
219 + return hr;
220 +}
221 +
222 HRESULT WINAPI EngineForExtensionProc(
223 __in BUNDLE_EXTENSION_ENGINE_MESSAGE message,
224 __in const LPVOID pvArgs,
@@ -253,6 +269,9 @@ HRESULT WINAPI EngineForExtensionProc(
269 case BUNDLE_EXTENSION_ENGINE_MESSAGE_COMPAREVERSIONS:
270 hr = BEEngineCompareVersions(pContext, pvArgs, pvResults);
271 break;
272 + case BUNDLE_EXTENSION_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE:
273 + hr = BEEngineGetRelatedBundleVariable(pContext, pvArgs, pvResults);
274 + break;
275 default:
276 hr = E_NOTIMPL;
277 break;
src/burn/engine/externalengine.cpp
+20
@@ -801,6 +801,26 @@ LExit:
801 return hr;
802 }
803
804 +HRESULT 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 +
824 // TODO: callers need to provide the original size (at the time of first public release) of the struct instead of the current size.
825 HRESULT WINAPI ExternalEngineValidateMessageParameter(
826 __in_opt const LPVOID pv,
src/burn/engine/externalengine.h
+8
@@ -129,6 +129,14 @@ HRESULT ExternalEngineCompareVersions(
129 __out int* pnResult
130 );
131
132 +HRESULT 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 +
140 HRESULT ExternalEngineDetect(
141 __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext,
142 __in_opt const HWND hwndParent
src/burn/test/BurnUnitTest/VariantTest.cpp
+3 -5
@@ -27,11 +27,9 @@ namespace Bootstrapper
27 {
28 BURN_VARIANT expectedVariants[10];
29 BURN_VARIANT actualVariants[10];
30 - for (DWORD i = 0; i < 10; i++)
31 - {
32 - BVariantUninitialize(expectedVariants + i);
33 - BVariantUninitialize(actualVariants + i);
34 - }
30 +
31 + memset(expectedVariants, 0, sizeof(expectedVariants));
32 + memset(actualVariants, 0, sizeof(actualVariants));
33
34 try
35 {
src/libs/dutil/WixToolset.DUtil/iniutil.cpp
+2
@@ -301,6 +301,8 @@ extern "C" HRESULT DAPI IniParse(
301 wzOpenTagPostfix = wcsstr(pi->rgsczLines[i], pi->sczOpenTagPostfix);
302 }
303
304 + wzValueNameStart = NULL;
305 +
306 if (pi->sczValuePrefix)
307 {
308 wzValuePrefix = wcsstr(pi->rgsczLines[i], pi->sczValuePrefix);
src/libs/dutil/WixToolset.DUtil/path2utl.cpp
+10 -1
@@ -327,6 +327,7 @@ DAPI_(HRESULT) PathDirectoryContainsPath(
327 LPWSTR sczCanonicalizedPath = NULL;
328 DWORD dwDefaultFlags = PATH_CANONICALIZE_APPEND_EXTENDED_PATH_PREFIX | PATH_CANONICALIZE_KEEP_UNC_ROOT;
329 size_t cchDirectory = 0;
330 + size_t cchPath = 0;
331
332 if (!wzDirectory || !*wzDirectory)
333 {
@@ -355,12 +356,20 @@ DAPI_(HRESULT) PathDirectoryContainsPath(
356 hr = ::StringCchLengthW(sczCanonicalizedDirectory, STRSAFE_MAX_CCH, &cchDirectory);
357 PathExitOnFailure(hr, "Failed to get length of canonicalized directory.");
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 +
367 if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, sczCanonicalizedDirectory, (DWORD)cchDirectory, sczCanonicalizedPath, (DWORD)cchDirectory))
368 {
369 ExitFunction1(hr = S_FALSE);
370 }
371
363 - hr = sczCanonicalizedPath[cchDirectory] ? S_OK : S_FALSE;
372 + hr = S_OK;
373
374 LExit:
375 ReleaseStr(sczCanonicalizedPath);
src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.cpp new
+133
@@ -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 +
7 +const DWORD VARIABLE_GROW_FACTOR = 80;
8 +const LPCWSTR STRING_VARIABLE = L"AString";
9 +const LPCWSTR NUMBER_VARIABLE = L"ANumber";
10 +
11 +static 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 +
21 +class CBafRelatedBundleVariableTesting : public CBalBaseBAFunctions
22 +{
23 +public: // IBAFunctions
24 +
25 +
26 +public: //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 + }
62 +private:
63 +
64 +
65 +public:
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 +
84 +private:
85 +};
86 +
87 +
88 +HRESULT 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 +
110 +LExit:
111 + ReleaseObject(pBAFunctions);
112 + ReleaseObject(pEngine);
113 +
114 + return hr;
115 +}
116 +
117 +static 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 +}
src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.def new
+6
@@ -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 +
4 +EXPORTS
5 + BAFunctionsCreate
6 + BAFunctionsDestroy
src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/BafRelatedBundleVariableTesting.vcxproj new
+66
@@ -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>
src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.cpp new
+48
@@ -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 +
5 +static HINSTANCE vhInstance = NULL;
6 +
7 +extern "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 +
28 +extern "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 +
38 +LExit:
39 + return hr;
40 +}
41 +
42 +extern "C" void WINAPI BAFunctionsDestroy(
43 + __in const BA_FUNCTIONS_DESTROY_ARGS* /*pArgs*/,
44 + __inout BA_FUNCTIONS_DESTROY_RESULTS* /*pResults*/
45 + )
46 +{
47 + BalUninitialize();
48 +}
src/test/burn/TestData/Manual/BafRelatedBundleVariableTesting/precomp.h new
+43
@@ -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 +
39 +HRESULT WINAPI CreateBAFunctions(
40 + __in HMODULE hModule,
41 + __in const BA_FUNCTIONS_CREATE_ARGS* pArgs,
42 + __inout BA_FUNCTIONS_CREATE_RESULTS* pResults
43 + );
src/test/burn/TestData/Manual/BundleD/BundleD.wixproj new
+22
@@ -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>
src/test/burn/TestData/Manual/BundleD/BundleD.wxs new
+17
@@ -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>
src/test/burn/TestData/Manual/BundleD/ManualTests.txt new
+10
@@ -0,0 +1,10 @@
1 +BafRelatedBundleVariableTesting
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)
3 +1. Run BundleD.exe (v1.0).
4 +2. Click Install.
5 +3. Verify that the Bundle installs successfully.
6 +4. Run BundleD.exe (v1.1).
7 +5. 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 +