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
+