aboutsummaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-07-01 09:30:10 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-07-02 12:50:09 -0500
commit9bdf3730cd43e1af8a4ea9be6cf2fba77fcff2d2 (patch)
treeea2a05de5a8a1dfcb2af8e9e3805fe015729f66a /src/api
parent8cbfc326cccf8d9b3b63cb6f752fc770f7dee0fc (diff)
downloadwix-9bdf3730cd43e1af8a4ea9be6cf2fba77fcff2d2.tar.gz
wix-9bdf3730cd43e1af8a4ea9be6cf2fba77fcff2d2.tar.bz2
wix-9bdf3730cd43e1af8a4ea9be6cf2fba77fcff2d2.zip
Add bundle option for command line variables to always be uppercase.
Fixes #3777
Diffstat (limited to 'src/api')
-rw-r--r--src/api/burn/WixToolset.Mba.Core/IOverridableVariables.cs20
-rw-r--r--src/api/burn/WixToolset.Mba.Core/MbaCommand.cs6
-rw-r--r--src/api/burn/WixToolset.Mba.Core/OverridableVariables.cs30
-rw-r--r--src/api/burn/balutil/balinfo.cpp40
-rw-r--r--src/api/burn/balutil/inc/balinfo.h7
-rw-r--r--src/api/burn/test/WixToolsetTest.Mba.Core/WixToolsetTest.Mba.Core.csproj1
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs14
7 files changed, 116 insertions, 2 deletions
diff --git a/src/api/burn/WixToolset.Mba.Core/IOverridableVariables.cs b/src/api/burn/WixToolset.Mba.Core/IOverridableVariables.cs
index 3944913b..1ffe50e4 100644
--- a/src/api/burn/WixToolset.Mba.Core/IOverridableVariables.cs
+++ b/src/api/burn/WixToolset.Mba.Core/IOverridableVariables.cs
@@ -5,11 +5,31 @@ namespace WixToolset.Mba.Core
5 using System.Collections.Generic; 5 using System.Collections.Generic;
6 6
7 /// <summary> 7 /// <summary>
8 /// The case sensitivity of variables from the command line.
9 /// </summary>
10 public enum VariableCommandLineType
11 {
12 /// <summary>
13 /// Similar to Windows Installer, all variable names specified on the command line are automatically converted to upper case.
14 /// </summary>
15 UpperCase,
16 /// <summary>
17 /// All variable names specified on the command line must match the case specified when building the bundle.
18 /// </summary>
19 CaseSensitive,
20 }
21
22 /// <summary>
8 /// Overridable variable information from the BA manifest. 23 /// Overridable variable information from the BA manifest.
9 /// </summary> 24 /// </summary>
10 public interface IOverridableVariables 25 public interface IOverridableVariables
11 { 26 {
12 /// <summary> 27 /// <summary>
28 /// The <see cref="VariableCommandLineType"/> of the bundle.
29 /// </summary>
30 VariableCommandLineType CommandLineType { get; }
31
32 /// <summary>
13 /// Variable Dictionary of variable name to <see cref="IOverridableVariableInfo"/>. 33 /// Variable Dictionary of variable name to <see cref="IOverridableVariableInfo"/>.
14 /// </summary> 34 /// </summary>
15 IDictionary<string, IOverridableVariableInfo> Variables { get; } 35 IDictionary<string, IOverridableVariableInfo> Variables { get; }
diff --git a/src/api/burn/WixToolset.Mba.Core/MbaCommand.cs b/src/api/burn/WixToolset.Mba.Core/MbaCommand.cs
index e7e49607..424cde63 100644
--- a/src/api/burn/WixToolset.Mba.Core/MbaCommand.cs
+++ b/src/api/burn/WixToolset.Mba.Core/MbaCommand.cs
@@ -19,9 +19,11 @@ namespace WixToolset.Mba.Core
19 { 19 {
20 foreach (var kvp in this.Variables) 20 foreach (var kvp in this.Variables)
21 { 21 {
22 if (!overridableVariables.Variables.TryGetValue(kvp.Key, out var overridableVariable)) 22 var key = overridableVariables.CommandLineType == VariableCommandLineType.UpperCase ? kvp.Key.ToUpperInvariant() : kvp.Key;
23
24 if (!overridableVariables.Variables.TryGetValue(key, out var overridableVariable))
23 { 25 {
24 engine.Log(LogLevel.Error, string.Format("Ignoring attempt to set non-overridable variable: '{0}'.", kvp.Key)); 26 engine.Log(LogLevel.Error, string.Format("Ignoring attempt to set non-overridable variable: '{0}'.", key));
25 } 27 }
26 else 28 else
27 { 29 {
diff --git a/src/api/burn/WixToolset.Mba.Core/OverridableVariables.cs b/src/api/burn/WixToolset.Mba.Core/OverridableVariables.cs
index 855ce9a9..148acb34 100644
--- a/src/api/burn/WixToolset.Mba.Core/OverridableVariables.cs
+++ b/src/api/burn/WixToolset.Mba.Core/OverridableVariables.cs
@@ -13,6 +13,9 @@ namespace WixToolset.Mba.Core
13 public class OverridableVariablesInfo : IOverridableVariables 13 public class OverridableVariablesInfo : IOverridableVariables
14 { 14 {
15 /// <inheritdoc /> 15 /// <inheritdoc />
16 public VariableCommandLineType CommandLineType { get; internal set; }
17
18 /// <inheritdoc />
16 public IDictionary<string, IOverridableVariableInfo> Variables { get; internal set; } 19 public IDictionary<string, IOverridableVariableInfo> Variables { get; internal set; }
17 20
18 internal OverridableVariablesInfo() { } 21 internal OverridableVariablesInfo() { }
@@ -26,9 +29,36 @@ namespace WixToolset.Mba.Core
26 { 29 {
27 XmlNamespaceManager namespaceManager = new XmlNamespaceManager(root.NameTable); 30 XmlNamespaceManager namespaceManager = new XmlNamespaceManager(root.NameTable);
28 namespaceManager.AddNamespace("p", BootstrapperApplicationData.XMLNamespace); 31 namespaceManager.AddNamespace("p", BootstrapperApplicationData.XMLNamespace);
32 XPathNavigator commandLineNode = root.SelectSingleNode("/p:BootstrapperApplicationData/p:CommandLine", namespaceManager);
29 XPathNodeIterator nodes = root.Select("/p:BootstrapperApplicationData/p:WixStdbaOverridableVariable", namespaceManager); 33 XPathNodeIterator nodes = root.Select("/p:BootstrapperApplicationData/p:WixStdbaOverridableVariable", namespaceManager);
30 34
31 var overridableVariables = new OverridableVariablesInfo(); 35 var overridableVariables = new OverridableVariablesInfo();
36
37 if (commandLineNode == null)
38 {
39 throw new Exception("Failed to select command line information.");
40 }
41
42 string variablesValue = BootstrapperApplicationData.GetAttribute(commandLineNode, "Variables");
43
44 if (variablesValue == null)
45 {
46 throw new Exception("Failed to get command line variable type.");
47 }
48
49 if (variablesValue.Equals("upperCase", StringComparison.InvariantCulture))
50 {
51 overridableVariables.CommandLineType = VariableCommandLineType.UpperCase;
52 }
53 else if (variablesValue.Equals("caseSensitive", StringComparison.InvariantCulture))
54 {
55 overridableVariables.CommandLineType = VariableCommandLineType.CaseSensitive;
56 }
57 else
58 {
59 throw new Exception(string.Format("Unknown command line variable type: '{0}'", variablesValue));
60 }
61
32 overridableVariables.Variables = new Dictionary<string, IOverridableVariableInfo>(); 62 overridableVariables.Variables = new Dictionary<string, IOverridableVariableInfo>();
33 63
34 foreach (XPathNavigator node in nodes) 64 foreach (XPathNavigator node in nodes)
diff --git a/src/api/burn/balutil/balinfo.cpp b/src/api/burn/balutil/balinfo.cpp
index 5927ef72..f71784a5 100644
--- a/src/api/burn/balutil/balinfo.cpp
+++ b/src/api/burn/balutil/balinfo.cpp
@@ -292,6 +292,7 @@ DAPI_(HRESULT) BalSetOverridableVariablesFromEngine(
292 ) 292 )
293{ 293{
294 HRESULT hr = S_OK; 294 HRESULT hr = S_OK;
295 LPWSTR sczKey = NULL;
295 BAL_INFO_OVERRIDABLE_VARIABLE* pOverridableVariable = NULL; 296 BAL_INFO_OVERRIDABLE_VARIABLE* pOverridableVariable = NULL;
296 297
297 for (DWORD i = 0; i < pCommand->cVariables; ++i) 298 for (DWORD i = 0; i < pCommand->cVariables; ++i)
@@ -299,6 +300,14 @@ DAPI_(HRESULT) BalSetOverridableVariablesFromEngine(
299 LPCWSTR wzVariableName = pCommand->rgVariableNames[i]; 300 LPCWSTR wzVariableName = pCommand->rgVariableNames[i];
300 LPCWSTR wzVariableValue = pCommand->rgVariableValues[i]; 301 LPCWSTR wzVariableValue = pCommand->rgVariableValues[i];
301 302
303 if (BAL_INFO_VARIABLE_COMMAND_LINE_TYPE_UPPER_CASE == pOverridableVariables->commandLineType)
304 {
305 hr = StrAllocStringToUpperInvariant(&sczKey, wzVariableName, 0);
306 ExitOnFailure(hr, "Failed to upper case variable name.");
307
308 wzVariableName = sczKey;
309 }
310
302 hr = DictGetValue(pOverridableVariables->sdVariables, wzVariableName, reinterpret_cast<void**>(&pOverridableVariable)); 311 hr = DictGetValue(pOverridableVariables->sdVariables, wzVariableName, reinterpret_cast<void**>(&pOverridableVariable));
303 if (E_NOTFOUND == hr) 312 if (E_NOTFOUND == hr)
304 { 313 {
@@ -313,6 +322,8 @@ DAPI_(HRESULT) BalSetOverridableVariablesFromEngine(
313 } 322 }
314 323
315LExit: 324LExit:
325 ReleaseStr(sczKey);
326
316 return hr; 327 return hr;
317} 328}
318 329
@@ -527,10 +538,37 @@ static HRESULT ParseOverridableVariablesFromXml(
527 ) 538 )
528{ 539{
529 HRESULT hr = S_OK; 540 HRESULT hr = S_OK;
541 IXMLDOMNode* pCommandLineNode = NULL;
542 LPWSTR scz = NULL;
530 IXMLDOMNode* pNode = NULL; 543 IXMLDOMNode* pNode = NULL;
531 IXMLDOMNodeList* pNodes = NULL; 544 IXMLDOMNodeList* pNodes = NULL;
532 BAL_INFO_OVERRIDABLE_VARIABLE* pOverridableVariable = NULL; 545 BAL_INFO_OVERRIDABLE_VARIABLE* pOverridableVariable = NULL;
533 546
547 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/CommandLine", &pCommandLineNode);
548 if (S_FALSE == hr)
549 {
550 hr = E_NOTFOUND;
551 }
552 ExitOnFailure(hr, "Failed to select command line information.");
553
554 // @Variables
555 hr = XmlGetAttributeEx(pCommandLineNode, L"Variables", &scz);
556 ExitOnFailure(hr, "Failed to get command line variable type.");
557
558 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"upperCase", -1))
559 {
560 pOverridableVariables->commandLineType = BAL_INFO_VARIABLE_COMMAND_LINE_TYPE_UPPER_CASE;
561 }
562 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"caseSensitive", -1))
563 {
564 pOverridableVariables->commandLineType = BAL_INFO_VARIABLE_COMMAND_LINE_TYPE_CASE_SENSITIVE;
565 }
566 else
567 {
568 hr = E_INVALIDARG;
569 ExitOnFailure(hr, "Invalid value for CommandLine/@Variables: %ls", scz);
570 }
571
534 // Get the list of variables users can override on the command line. 572 // Get the list of variables users can override on the command line.
535 hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOverridableVariable", &pNodes); 573 hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOverridableVariable", &pNodes);
536 if (S_FALSE == hr) 574 if (S_FALSE == hr)
@@ -570,6 +608,8 @@ static HRESULT ParseOverridableVariablesFromXml(
570 } 608 }
571 609
572LExit: 610LExit:
611 ReleaseStr(scz);
612 ReleaseObject(pCommandLineNode);
573 ReleaseObject(pNode); 613 ReleaseObject(pNode);
574 ReleaseObject(pNodes); 614 ReleaseObject(pNodes);
575 return hr; 615 return hr;
diff --git a/src/api/burn/balutil/inc/balinfo.h b/src/api/burn/balutil/inc/balinfo.h
index 0fce35ec..07a1cbb7 100644
--- a/src/api/burn/balutil/inc/balinfo.h
+++ b/src/api/burn/balutil/inc/balinfo.h
@@ -18,6 +18,12 @@ typedef enum BAL_INFO_PACKAGE_TYPE
18 BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH, 18 BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH,
19} BAL_INFO_PACKAGE_TYPE; 19} BAL_INFO_PACKAGE_TYPE;
20 20
21typedef enum _BAL_INFO_VARIABLE_COMMAND_LINE_TYPE
22{
23 BAL_INFO_VARIABLE_COMMAND_LINE_TYPE_UPPER_CASE,
24 BAL_INFO_VARIABLE_COMMAND_LINE_TYPE_CASE_SENSITIVE,
25} BAL_INFO_VARIABLE_COMMAND_LINE_TYPE;
26
21 27
22typedef struct _BAL_INFO_PACKAGE 28typedef struct _BAL_INFO_PACKAGE
23{ 29{
@@ -58,6 +64,7 @@ typedef struct _BAL_INFO_OVERRIDABLE_VARIABLES
58 BAL_INFO_OVERRIDABLE_VARIABLE* rgVariables; 64 BAL_INFO_OVERRIDABLE_VARIABLE* rgVariables;
59 DWORD cVariables; 65 DWORD cVariables;
60 STRINGDICT_HANDLE sdVariables; 66 STRINGDICT_HANDLE sdVariables;
67 BAL_INFO_VARIABLE_COMMAND_LINE_TYPE commandLineType;
61} BAL_INFO_OVERRIDABLE_VARIABLES; 68} BAL_INFO_OVERRIDABLE_VARIABLES;
62 69
63 70
diff --git a/src/api/burn/test/WixToolsetTest.Mba.Core/WixToolsetTest.Mba.Core.csproj b/src/api/burn/test/WixToolsetTest.Mba.Core/WixToolsetTest.Mba.Core.csproj
index bdb6a829..8d68546f 100644
--- a/src/api/burn/test/WixToolsetTest.Mba.Core/WixToolsetTest.Mba.Core.csproj
+++ b/src/api/burn/test/WixToolsetTest.Mba.Core/WixToolsetTest.Mba.Core.csproj
@@ -14,6 +14,7 @@
14 </ItemGroup> 14 </ItemGroup>
15 15
16 <ItemGroup> 16 <ItemGroup>
17 <PackageReference Include="Microsoft.NET.Test.Sdk" />
17 <PackageReference Include="xunit" /> 18 <PackageReference Include="xunit" />
18 <PackageReference Include="xunit.runner.visualstudio" PrivateAssets="All" /> 19 <PackageReference Include="xunit.runner.visualstudio" PrivateAssets="All" />
19 </ItemGroup> 20 </ItemGroup>
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs
index 9724cbd7..de5646d3 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs
@@ -33,6 +33,7 @@ namespace WixToolset.Data
33 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.BundleId), IntermediateFieldType.String), 33 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.BundleId), IntermediateFieldType.String),
34 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.ProviderKey), IntermediateFieldType.String), 34 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.ProviderKey), IntermediateFieldType.String),
35 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.InProgressName), IntermediateFieldType.String), 35 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.InProgressName), IntermediateFieldType.String),
36 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.CommandLineVariables), IntermediateFieldType.String),
36 }, 37 },
37 typeof(WixBundleSymbol)); 38 typeof(WixBundleSymbol));
38 } 39 }
@@ -67,6 +68,7 @@ namespace WixToolset.Data.Symbols
67 BundleId, 68 BundleId,
68 ProviderKey, 69 ProviderKey,
69 InProgressName, 70 InProgressName,
71 CommandLineVariables,
70 } 72 }
71 73
72 [Flags] 74 [Flags]
@@ -79,6 +81,12 @@ namespace WixToolset.Data.Symbols
79 PerMachine = 0x8, 81 PerMachine = 0x8,
80 } 82 }
81 83
84 public enum WixBundleCommandLineVariables
85 {
86 UpperCase,
87 CaseSensitive,
88 }
89
82 public class WixBundleSymbol : IntermediateSymbol 90 public class WixBundleSymbol : IntermediateSymbol
83 { 91 {
84 public WixBundleSymbol() : base(SymbolDefinitions.WixBundle, null, null) 92 public WixBundleSymbol() : base(SymbolDefinitions.WixBundle, null, null)
@@ -229,6 +237,12 @@ namespace WixToolset.Data.Symbols
229 set => this.Set((int)WixBundleSymbolFields.InProgressName, value); 237 set => this.Set((int)WixBundleSymbolFields.InProgressName, value);
230 } 238 }
231 239
240 public WixBundleCommandLineVariables CommandLineVariables
241 {
242 get => (WixBundleCommandLineVariables)this.Fields[(int)WixBundleSymbolFields.CommandLineVariables].AsNumber();
243 set => this.Set((int)WixBundleSymbolFields.CommandLineVariables, (int)value);
244 }
245
232 public PackagingType DefaultPackagingType => (this.Compressed.HasValue && !this.Compressed.Value) ? PackagingType.External : PackagingType.Embedded; 246 public PackagingType DefaultPackagingType => (this.Compressed.HasValue && !this.Compressed.Value) ? PackagingType.External : PackagingType.Embedded;
233 247
234 public bool DisableModify => (this.Attributes & WixBundleAttributes.DisableModify) == WixBundleAttributes.DisableModify; 248 public bool DisableModify => (this.Attributes & WixBundleAttributes.DisableModify) == WixBundleAttributes.DisableModify;