aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.WindowsInstaller/Bind
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2020-07-21 14:31:53 -0700
committerRob Mensching <rob@firegiant.com>2020-07-21 14:41:12 -0700
commitb62a7a0beb7ceb7987de28ec768c7814cadb83b9 (patch)
tree69a9183a3182334f0d48a39ab8e411ee3fc3aecd /src/WixToolset.Core.WindowsInstaller/Bind
parent414c07f7adce9c9fd0132ab0fade0267f743f665 (diff)
downloadwix-b62a7a0beb7ceb7987de28ec768c7814cadb83b9.tar.gz
wix-b62a7a0beb7ceb7987de28ec768c7814cadb83b9.tar.bz2
wix-b62a7a0beb7ceb7987de28ec768c7814cadb83b9.zip
Support implicit standard directory reference and "3264" platform folders
Completes wixtoolset/issues#5798 and wixtoolset/issues#5835
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Bind')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs95
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs9
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs31
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs9
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs36
5 files changed, 154 insertions, 26 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs b/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs
new file mode 100644
index 00000000..4597639b
--- /dev/null
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs
@@ -0,0 +1,95 @@
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
3namespace WixToolset.Core.WindowsInstaller.Bind
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using WixToolset.Data;
9 using WixToolset.Data.Symbols;
10 using WixToolset.Data.WindowsInstaller;
11
12 /// <summary>
13 /// Add referenced standard directory symbols, if not already present.
14 /// </summary>
15 internal class AddRequiredStandardDirectories
16 {
17 internal AddRequiredStandardDirectories(IntermediateSection section, Platform platform)
18 {
19 this.Section = section;
20 this.Platform = platform;
21 }
22
23 private IntermediateSection Section { get; }
24
25 private Platform Platform { get; }
26
27 public void Execute()
28 {
29 var directories = this.Section.Symbols.OfType<DirectorySymbol>().ToList();
30 var directoriesById = directories.ToDictionary(d => d.Id.Id);
31
32 foreach (var directory in directories)
33 {
34 var parentDirectoryId = directory.ParentDirectoryRef;
35
36 if (String.IsNullOrEmpty(parentDirectoryId))
37 {
38 if (directory.Id.Id != "TARGETDIR")
39 {
40 directory.ParentDirectoryRef = "TARGETDIR";
41 }
42 }
43 else
44 {
45 this.EnsureStandardDirectoryAdded(directoriesById, parentDirectoryId, directory.SourceLineNumbers);
46 }
47 }
48
49 if (!directoriesById.ContainsKey("TARGETDIR") && WindowsInstallerStandard.TryGetStandardDirectory("TARGETDIR", out var targetDir))
50 {
51 directoriesById.Add(targetDir.Id.Id, targetDir);
52 this.Section.AddSymbol(targetDir);
53 }
54 }
55
56 private void EnsureStandardDirectoryAdded(Dictionary<string, DirectorySymbol> directoriesById, string directoryId, SourceLineNumber sourceLineNumbers)
57 {
58 if (!directoriesById.ContainsKey(directoryId) && WindowsInstallerStandard.TryGetStandardDirectory(directoryId, out var standardDirectory))
59 {
60 var parentDirectoryId = this.GetStandardDirectoryParent(directoryId);
61
62 var directory = new DirectorySymbol(sourceLineNumbers, standardDirectory.Id)
63 {
64 Name = standardDirectory.Name,
65 ParentDirectoryRef = parentDirectoryId,
66 };
67
68 directoriesById.Add(directory.Id.Id, directory);
69 this.Section.AddSymbol(directory);
70
71 if (!String.IsNullOrEmpty(parentDirectoryId))
72 {
73 this.EnsureStandardDirectoryAdded(directoriesById, parentDirectoryId, sourceLineNumbers);
74 }
75 }
76 }
77
78 private string GetStandardDirectoryParent(string directoryId)
79 {
80 switch (directoryId)
81 {
82 case "TARGETDIR":
83 return null;
84
85 case "CommonFiles6432Folder":
86 case "ProgramFiles6432Folder":
87 case "System6432Folder":
88 return WindowsInstallerStandard.GetPlatformSpecificDirectoryId(directoryId, this.Platform);
89
90 default:
91 return "TARGETDIR";
92 }
93 }
94 }
95}
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
index 950fe1c1..93c617d9 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
@@ -133,6 +133,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
133 bool compressed; 133 bool compressed;
134 bool longNames; 134 bool longNames;
135 int installerVersion; 135 int installerVersion;
136 Platform platform;
136 string modularizationSuffix; 137 string modularizationSuffix;
137 { 138 {
138 var command = new BindSummaryInfoCommand(section); 139 var command = new BindSummaryInfoCommand(section);
@@ -141,6 +142,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
141 compressed = command.Compressed; 142 compressed = command.Compressed;
142 longNames = command.LongNames; 143 longNames = command.LongNames;
143 installerVersion = command.InstallerVersion; 144 installerVersion = command.InstallerVersion;
145 platform = command.Platform;
144 modularizationSuffix = command.ModularizationSuffix; 146 modularizationSuffix = command.ModularizationSuffix;
145 } 147 }
146 148
@@ -194,6 +196,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
194 } 196 }
195 197
196 { 198 {
199 var command = new AddRequiredStandardDirectories(section, platform);
200 command.Execute();
201 }
202
203 {
197 var command = new CreateSpecialPropertiesCommand(section); 204 var command = new CreateSpecialPropertiesCommand(section);
198 command.Execute(); 205 command.Execute();
199 } 206 }
@@ -332,7 +339,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
332 339
333 // Set generated component guids. 340 // Set generated component guids.
334 { 341 {
335 var command = new CalculateComponentGuids(this.Messaging, this.BackendHelper, this.PathResolver, section); 342 var command = new CalculateComponentGuids(this.Messaging, this.BackendHelper, this.PathResolver, section, platform);
336 command.Execute(); 343 command.Execute();
337 } 344 }
338 345
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs
index 82688edf..63691016 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs
@@ -32,6 +32,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
32 32
33 public int InstallerVersion { get; private set; } 33 public int InstallerVersion { get; private set; }
34 34
35 public Platform Platform { get; private set; }
36
35 /// <summary> 37 /// <summary>
36 /// Modularization guid, or null if the output is not a module. 38 /// Modularization guid, or null if the output is not a module.
37 /// </summary> 39 /// </summary>
@@ -66,6 +68,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
66 summaryInformationSymbol.Value = Common.GetValidCodePage(codepage, false, false, summaryInformationSymbol.SourceLineNumbers).ToString(CultureInfo.InvariantCulture); 68 summaryInformationSymbol.Value = Common.GetValidCodePage(codepage, false, false, summaryInformationSymbol.SourceLineNumbers).ToString(CultureInfo.InvariantCulture);
67 } 69 }
68 break; 70 break;
71 case SummaryInformationType.PlatformAndLanguage:
72 this.Platform = GetPlatformFromSummaryInformation(summaryInformationSymbol.Value);
73 break;
74
69 case SummaryInformationType.PackageCode: // PID_REVNUMBER 75 case SummaryInformationType.PackageCode: // PID_REVNUMBER
70 var packageCode = summaryInformationSymbol.Value; 76 var packageCode = summaryInformationSymbol.Value;
71 77
@@ -137,5 +143,30 @@ namespace WixToolset.Core.WindowsInstaller.Bind
137 }); 143 });
138 } 144 }
139 } 145 }
146
147 private static Platform GetPlatformFromSummaryInformation(string value)
148 {
149 var separatorIndex = value.IndexOf(';');
150 var platformValue = separatorIndex > 0 ? value.Substring(0, separatorIndex) : value;
151
152 switch (platformValue)
153 {
154 case "x64":
155 return Platform.X64;
156
157 case "Arm":
158 return Platform.ARM;
159
160 case "Arm64":
161 return Platform.ARM64;
162
163 case "Intel64":
164 return Platform.IA64;
165
166 case "Intel":
167 default:
168 return Platform.X86;
169 }
170 }
140 } 171 }
141} 172}
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs
index a1e3ac83..02336cae 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs
@@ -16,12 +16,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
16 /// </summary> 16 /// </summary>
17 internal class CalculateComponentGuids 17 internal class CalculateComponentGuids
18 { 18 {
19 internal CalculateComponentGuids(IMessaging messaging, IBackendHelper helper, IPathResolver pathResolver, IntermediateSection section) 19 internal CalculateComponentGuids(IMessaging messaging, IBackendHelper helper, IPathResolver pathResolver, IntermediateSection section, Platform platform)
20 { 20 {
21 this.Messaging = messaging; 21 this.Messaging = messaging;
22 this.BackendHelper = helper; 22 this.BackendHelper = helper;
23 this.PathResolver = pathResolver; 23 this.PathResolver = pathResolver;
24 this.Section = section; 24 this.Section = section;
25 this.Platform = platform;
25 } 26 }
26 27
27 private IMessaging Messaging { get; } 28 private IMessaging Messaging { get; }
@@ -32,6 +33,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
32 33
33 private IntermediateSection Section { get; } 34 private IntermediateSection Section { get; }
34 35
36 private Platform Platform { get; }
37
35 public void Execute() 38 public void Execute()
36 { 39 {
37 Dictionary<string, RegistrySymbol> registryKeyRows = null; 40 Dictionary<string, RegistrySymbol> registryKeyRows = null;
@@ -42,7 +45,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
42 // Find components with generatable guids. 45 // Find components with generatable guids.
43 foreach (var componentSymbol in this.Section.Symbols.OfType<ComponentSymbol>()) 46 foreach (var componentSymbol in this.Section.Symbols.OfType<ComponentSymbol>())
44 { 47 {
45 // Skip components that do not specify generate guid. 48 // Skip components that do not specify generate guid.
46 if (componentSymbol.ComponentId != "*") 49 if (componentSymbol.ComponentId != "*")
47 { 50 {
48 continue; 51 continue;
@@ -135,7 +138,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
135 if (fileRow.Id.Id == componentSymbol.KeyPath) 138 if (fileRow.Id.Id == componentSymbol.KeyPath)
136 { 139 {
137 // calculate the key file's canonical target path 140 // calculate the key file's canonical target path
138 string directoryPath = this.PathResolver.GetDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentSymbol.DirectoryRef, true); 141 string directoryPath = this.PathResolver.GetCanonicalDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentSymbol.DirectoryRef, this.Platform);
139 string fileName = Common.GetName(fileRow.Name, false, true).ToLowerInvariant(); 142 string fileName = Common.GetName(fileRow.Name, false, true).ToLowerInvariant();
140 path = Path.Combine(directoryPath, fileName); 143 path = Path.Combine(directoryPath, fileName);
141 144
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
index 7f43da9a..93e25878 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
@@ -34,25 +34,25 @@ namespace WixToolset.Core.WindowsInstaller.Bind
34 { 34 {
35 var requiredActionSymbols = new Dictionary<string, WixActionSymbol>(); 35 var requiredActionSymbols = new Dictionary<string, WixActionSymbol>();
36 36
37 // Get the standard actions required based on symbols in the section.
38 var overridableActionSymbols = this.GetRequiredStandardActions();
39
40 // Index all the action symbols and look for collisions. 37 // Index all the action symbols and look for collisions.
41 foreach (var actionSymbol in this.Section.Symbols.OfType<WixActionSymbol>()) 38 foreach (var actionSymbol in this.Section.Symbols.OfType<WixActionSymbol>())
42 { 39 {
43 if (actionSymbol.Overridable) // overridable action 40 if (actionSymbol.Overridable) // overridable action
44 { 41 {
45 if (overridableActionSymbols.TryGetValue(actionSymbol.Id.Id, out var collidingActionSymbol)) 42 if (requiredActionSymbols.TryGetValue(actionSymbol.Id.Id, out var collidingActionSymbol))
46 { 43 {
47 this.Messaging.Write(ErrorMessages.OverridableActionCollision(actionSymbol.SourceLineNumbers, actionSymbol.SequenceTable.ToString(), actionSymbol.Action)); 44 if (collidingActionSymbol.Overridable)
48 if (null != collidingActionSymbol.SourceLineNumbers)
49 { 45 {
50 this.Messaging.Write(ErrorMessages.OverridableActionCollision2(collidingActionSymbol.SourceLineNumbers)); 46 this.Messaging.Write(ErrorMessages.OverridableActionCollision(actionSymbol.SourceLineNumbers, actionSymbol.SequenceTable.ToString(), actionSymbol.Action));
47 if (null != collidingActionSymbol.SourceLineNumbers)
48 {
49 this.Messaging.Write(ErrorMessages.OverridableActionCollision2(collidingActionSymbol.SourceLineNumbers));
50 }
51 } 51 }
52 } 52 }
53 else 53 else
54 { 54 {
55 overridableActionSymbols.Add(actionSymbol.Id.Id, actionSymbol); 55 requiredActionSymbols.Add(actionSymbol.Id.Id, actionSymbol);
56 } 56 }
57 } 57 }
58 else // unsequenced or sequenced action. 58 else // unsequenced or sequenced action.
@@ -71,7 +71,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
71 } 71 }
72 } 72 }
73 73
74 if (requiredActionSymbols.TryGetValue(actionSymbol.Id.Id, out var collidingActionSymbol)) 74 if (requiredActionSymbols.TryGetValue(actionSymbol.Id.Id, out var collidingActionSymbol) && !collidingActionSymbol.Overridable)
75 { 75 {
76 this.Messaging.Write(ErrorMessages.ActionCollision(actionSymbol.SourceLineNumbers, actionSymbol.SequenceTable.ToString(), actionSymbol.Action)); 76 this.Messaging.Write(ErrorMessages.ActionCollision(actionSymbol.SourceLineNumbers, actionSymbol.SequenceTable.ToString(), actionSymbol.Action));
77 if (null != collidingActionSymbol.SourceLineNumbers) 77 if (null != collidingActionSymbol.SourceLineNumbers)
@@ -81,13 +81,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
81 } 81 }
82 else 82 else
83 { 83 {
84 requiredActionSymbols.Add(actionSymbol.Id.Id, actionSymbol); 84 requiredActionSymbols[actionSymbol.Id.Id] = actionSymbol;
85 } 85 }
86 } 86 }
87 } 87 }
88 88
89 // Get the standard actions required based on symbols in the section.
90 var requiredStandardActions = this.GetRequiredStandardActions();
91
89 // Add the overridable action symbols that are not overridden to the required action symbols. 92 // Add the overridable action symbols that are not overridden to the required action symbols.
90 foreach (var actionSymbol in overridableActionSymbols.Values) 93 foreach (var actionSymbol in requiredStandardActions.Values)
91 { 94 {
92 if (!requiredActionSymbols.ContainsKey(actionSymbol.Id.Id)) 95 if (!requiredActionSymbols.ContainsKey(actionSymbol.Id.Id))
93 { 96 {
@@ -557,17 +560,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
557 return set; 560 return set;
558 } 561 }
559 562
560 private IEnumerable<WixActionSymbol> GetActions(SequenceTable sequence, string[] actionNames)
561 {
562 foreach (var action in WindowsInstallerStandard.StandardActions())
563 {
564 if (action.SequenceTable == sequence && actionNames.Contains(action.Action))
565 {
566 yield return action;
567 }
568 }
569 }
570
571 /// <summary> 563 /// <summary>
572 /// Sequence an action before or after a standard action. 564 /// Sequence an action before or after a standard action.
573 /// </summary> 565 /// </summary>