diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-07-01 09:30:10 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-07-02 12:50:09 -0500 |
commit | 9bdf3730cd43e1af8a4ea9be6cf2fba77fcff2d2 (patch) | |
tree | ea2a05de5a8a1dfcb2af8e9e3805fe015729f66a /src/api | |
parent | 8cbfc326cccf8d9b3b63cb6f752fc770f7dee0fc (diff) | |
download | wix-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')
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 | ||
315 | LExit: | 324 | LExit: |
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 | ||
572 | LExit: | 610 | LExit: |
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 | ||
21 | typedef 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 | ||
22 | typedef struct _BAL_INFO_PACKAGE | 28 | typedef 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; |