aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs')
-rw-r--r--src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs928
1 files changed, 565 insertions, 363 deletions
diff --git a/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs b/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs
index c07dd42e..007b9c62 100644
--- a/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs
+++ b/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs
@@ -3,6 +3,7 @@
3namespace WixToolset.Converters.Tupleizer 3namespace WixToolset.Converters.Tupleizer
4{ 4{
5 using System; 5 using System;
6 using System.Collections.Generic;
6 using System.Linq; 7 using System.Linq;
7 using WixToolset.Data; 8 using WixToolset.Data;
8 using WixToolset.Data.Tuples; 9 using WixToolset.Data.Tuples;
@@ -21,11 +22,17 @@ namespace WixToolset.Converters.Tupleizer
21 { 22 {
22 var section = new IntermediateSection(String.Empty, OutputType3ToSectionType4(output.Type), output.Codepage); 23 var section = new IntermediateSection(String.Empty, OutputType3ToSectionType4(output.Type), output.Codepage);
23 24
25 var wixMediaByDiskId = IndexWixMediaTableByDiskId(output);
26 var bindPathsById = IndexById<Wix3.Row>(output, "BindPath");
27 var fontsById = IndexById<Wix3.Row>(output, "Font");
28 var selfRegById = IndexById<Wix3.Row>(output, "SelfReg");
29 var wixDirectoryById = IndexById<Wix3.Row>(output, "WixDirectory");
30
24 foreach (Wix3.Table table in output.Tables) 31 foreach (Wix3.Table table in output.Tables)
25 { 32 {
26 foreach (Wix3.Row row in table.Rows) 33 foreach (Wix3.Row row in table.Rows)
27 { 34 {
28 var tuple = GenerateTupleFromRow(row); 35 var tuple = GenerateTupleFromRow(row, wixMediaByDiskId, fontsById, bindPathsById, selfRegById, wixDirectoryById);
29 if (tuple != null) 36 if (tuple != null)
30 { 37 {
31 section.Tuples.Add(tuple); 38 section.Tuples.Add(tuple);
@@ -36,353 +43,534 @@ namespace WixToolset.Converters.Tupleizer
36 return new Intermediate(String.Empty, new[] { section }, localizationsByCulture: null, embedFilePaths: null); 43 return new Intermediate(String.Empty, new[] { section }, localizationsByCulture: null, embedFilePaths: null);
37 } 44 }
38 45
39 private static IntermediateTuple GenerateTupleFromRow(Wix3.Row row) 46 private static Dictionary<int, Wix3.WixMediaRow> IndexWixMediaTableByDiskId(Wix3.Output output)
47 {
48 var wixMediaByDiskId = new Dictionary<int, Wix3.WixMediaRow>();
49 var wixMediaTable = output.Tables["WixMedia"];
50
51 if (wixMediaTable != null)
52 {
53 foreach (Wix3.WixMediaRow row in wixMediaTable.Rows)
54 {
55 wixMediaByDiskId.Add(FieldAsInt(row, 0), row);
56 }
57 }
58
59 return wixMediaByDiskId;
60 }
61
62 private static Dictionary<string, T> IndexById<T>(Wix3.Output output, string tableName) where T : Wix3.Row
63 {
64 var byId = new Dictionary<string, T>();
65 var table = output.Tables[tableName];
66
67 if (table != null)
68 {
69 foreach (T row in table.Rows)
70 {
71 byId.Add(FieldAsString(row, 0), row);
72 }
73 }
74
75 return byId;
76 }
77
78 private static IntermediateTuple GenerateTupleFromRow(Wix3.Row row, Dictionary<int, Wix3.WixMediaRow> wixMediaByDiskId, Dictionary<string, Wix3.Row> fontsById, Dictionary<string, Wix3.Row> bindPathsById, Dictionary<string, Wix3.Row> selfRegById, Dictionary<string, Wix3.Row> wixDirectoryById)
40 { 79 {
41 var name = row.Table.Name; 80 var name = row.Table.Name;
42 switch (name) 81 switch (name)
43 { 82 {
44 case "_SummaryInformation": 83 case "_SummaryInformation":
45 return DefaultTupleFromRow(typeof(_SummaryInformationTuple), row, columnZeroIsId: false); 84 return DefaultTupleFromRow(typeof(SummaryInformationTuple), row, columnZeroIsId: false);
46 case "ActionText": 85 case "ActionText":
47 return DefaultTupleFromRow(typeof(ActionTextTuple), row, columnZeroIsId: false); 86 return DefaultTupleFromRow(typeof(ActionTextTuple), row, columnZeroIsId: false);
48 case "AdvtExecuteSequence": 87 case "AdvtExecuteSequence":
49 return DefaultTupleFromRow(typeof(AdvtExecuteSequenceTuple), row, columnZeroIsId: false); 88 return DefaultTupleFromRow(typeof(AdvtExecuteSequenceTuple), row, columnZeroIsId: false);
50 case "AppId": 89 case "AppId":
51 return DefaultTupleFromRow(typeof(AppIdTuple), row, columnZeroIsId: false); 90 return DefaultTupleFromRow(typeof(AppIdTuple), row, columnZeroIsId: false);
52 case "AppSearch": 91 case "AppSearch":
53 return DefaultTupleFromRow(typeof(AppSearchTuple), row, columnZeroIsId: false); 92 return DefaultTupleFromRow(typeof(AppSearchTuple), row, columnZeroIsId: false);
54 case "Binary": 93 case "Billboard":
55 return DefaultTupleFromRow(typeof(BinaryTuple), row, columnZeroIsId: false); 94 return DefaultTupleFromRow(typeof(BillboardTuple), row, columnZeroIsId: true);
56 case "Class": 95 case "Binary":
57 return DefaultTupleFromRow(typeof(ClassTuple), row, columnZeroIsId: false); 96 return DefaultTupleFromRow(typeof(BinaryTuple), row, columnZeroIsId: true);
58 case "CompLocator": 97 case "BindPath":
59 return DefaultTupleFromRow(typeof(CompLocatorTuple), row, columnZeroIsId: true); 98 return null;
60 case "Component": 99 case "CCPSearch":
61 { 100 return DefaultTupleFromRow(typeof(CCPSearchTuple), row, columnZeroIsId: true);
62 var attributes = FieldAsNullableInt(row, 3); 101 case "Class":
63 102 return DefaultTupleFromRow(typeof(ClassTuple), row, columnZeroIsId: false);
64 var location = ComponentLocation.LocalOnly; 103 case "CompLocator":
65 if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) == WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) 104 return DefaultTupleFromRow(typeof(CompLocatorTuple), row, columnZeroIsId: true);
66 { 105 case "Component":
67 location = ComponentLocation.SourceOnly; 106 {
68 } 107 var attributes = FieldAsNullableInt(row, 3);
69 else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesOptional) == WindowsInstallerConstants.MsidbComponentAttributesOptional)
70 {
71 location = ComponentLocation.Either;
72 }
73 108
74 var keyPathType = ComponentKeyPathType.File; 109 var location = ComponentLocation.LocalOnly;
75 if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) == WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) 110 if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) == WindowsInstallerConstants.MsidbComponentAttributesSourceOnly)
76 { 111 {
77 keyPathType = ComponentKeyPathType.Registry; 112 location = ComponentLocation.SourceOnly;
78 } 113 }
79 else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) == WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) 114 else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesOptional) == WindowsInstallerConstants.MsidbComponentAttributesOptional)
80 { 115 {
81 keyPathType = ComponentKeyPathType.OdbcDataSource; 116 location = ComponentLocation.Either;
82 } 117 }
83 118
84 return new ComponentTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) 119 var keyPathType = ComponentKeyPathType.File;
85 { 120 if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) == WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath)
86 ComponentId = FieldAsString(row, 1), 121 {
87 Directory_ = FieldAsString(row, 2), 122 keyPathType = ComponentKeyPathType.Registry;
88 Condition = FieldAsString(row, 4), 123 }
89 KeyPath = FieldAsString(row, 5), 124 else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) == WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource)
90 Location = location, 125 {
91 DisableRegistryReflection = (attributes & WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection) == WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection, 126 keyPathType = ComponentKeyPathType.OdbcDataSource;
92 NeverOverwrite = (attributes & WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite) == WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite,
93 Permanent = (attributes & WindowsInstallerConstants.MsidbComponentAttributesPermanent) == WindowsInstallerConstants.MsidbComponentAttributesPermanent,
94 SharedDllRefCount = (attributes & WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount) == WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount,
95 Shared = (attributes & WindowsInstallerConstants.MsidbComponentAttributesShared) == WindowsInstallerConstants.MsidbComponentAttributesShared,
96 Transitive = (attributes & WindowsInstallerConstants.MsidbComponentAttributesTransitive) == WindowsInstallerConstants.MsidbComponentAttributesTransitive,
97 UninstallWhenSuperseded = (attributes & WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence) == WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence,
98 Win64 = (attributes & WindowsInstallerConstants.MsidbComponentAttributes64bit) == WindowsInstallerConstants.MsidbComponentAttributes64bit,
99 KeyPathType = keyPathType,
100 };
101 } 127 }
102 128
103 case "Condition": 129 return new ComponentTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
104 return DefaultTupleFromRow(typeof(ConditionTuple), row, columnZeroIsId: false);
105 case "CreateFolder":
106 return DefaultTupleFromRow(typeof(CreateFolderTuple), row, columnZeroIsId: false);
107 case "CustomAction":
108 { 130 {
109 var caType = FieldAsInt(row, 1); 131 ComponentId = FieldAsString(row, 1),
110 var executionType = DetermineCustomActionExecutionType(caType); 132 DirectoryRef = FieldAsString(row, 2),
111 var sourceType = DetermineCustomActionSourceType(caType); 133 Condition = FieldAsString(row, 4),
112 var targetType = DetermineCustomActionTargetType(caType); 134 KeyPath = FieldAsString(row, 5),
135 Location = location,
136 DisableRegistryReflection = (attributes & WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection) == WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection,
137 NeverOverwrite = (attributes & WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite) == WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite,
138 Permanent = (attributes & WindowsInstallerConstants.MsidbComponentAttributesPermanent) == WindowsInstallerConstants.MsidbComponentAttributesPermanent,
139 SharedDllRefCount = (attributes & WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount) == WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount,
140 Shared = (attributes & WindowsInstallerConstants.MsidbComponentAttributesShared) == WindowsInstallerConstants.MsidbComponentAttributesShared,
141 Transitive = (attributes & WindowsInstallerConstants.MsidbComponentAttributesTransitive) == WindowsInstallerConstants.MsidbComponentAttributesTransitive,
142 UninstallWhenSuperseded = (attributes & WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence) == WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence,
143 Win64 = (attributes & WindowsInstallerConstants.MsidbComponentAttributes64bit) == WindowsInstallerConstants.MsidbComponentAttributes64bit,
144 KeyPathType = keyPathType,
145 };
146 }
113 147
114 return new CustomActionTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) 148 case "Condition":
115 { 149 return DefaultTupleFromRow(typeof(ConditionTuple), row, columnZeroIsId: false);
116 ExecutionType = executionType, 150 case "CreateFolder":
117 SourceType = sourceType, 151 return DefaultTupleFromRow(typeof(CreateFolderTuple), row, columnZeroIsId: false);
118 Source = FieldAsString(row, 2), 152 case "CustomAction":
119 TargetType = targetType, 153 {
120 Target = FieldAsString(row, 3), 154 var caType = FieldAsInt(row, 1);
121 Win64 = (caType & WindowsInstallerConstants.MsidbCustomActionType64BitScript) == WindowsInstallerConstants.MsidbCustomActionType64BitScript, 155 var executionType = DetermineCustomActionExecutionType(caType);
122 TSAware = (caType & WindowsInstallerConstants.MsidbCustomActionTypeTSAware) == WindowsInstallerConstants.MsidbCustomActionTypeTSAware, 156 var sourceType = DetermineCustomActionSourceType(caType);
123 Impersonate = (caType & WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate) != WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate, 157 var targetType = DetermineCustomActionTargetType(caType);
124 IgnoreResult = (caType & WindowsInstallerConstants.MsidbCustomActionTypeContinue) == WindowsInstallerConstants.MsidbCustomActionTypeContinue,
125 Hidden = (caType & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) == WindowsInstallerConstants.MsidbCustomActionTypeHideTarget,
126 Async = (caType & WindowsInstallerConstants.MsidbCustomActionTypeAsync) == WindowsInstallerConstants.MsidbCustomActionTypeAsync,
127 };
128 }
129 158
130 case "Directory": 159 return new CustomActionTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
131 return DefaultTupleFromRow(typeof(DirectoryTuple), row, columnZeroIsId: false); 160 {
132 case "DrLocator": 161 ExecutionType = executionType,
133 return DefaultTupleFromRow(typeof(DrLocatorTuple), row, columnZeroIsId: false); 162 SourceType = sourceType,
134 case "Error": 163 Source = FieldAsString(row, 2),
135 return DefaultTupleFromRow(typeof(ErrorTuple), row, columnZeroIsId: false); 164 TargetType = targetType,
136 case "Extension": 165 Target = FieldAsString(row, 3),
137 return DefaultTupleFromRow(typeof(ExtensionTuple), row, columnZeroIsId: false); 166 Win64 = (caType & WindowsInstallerConstants.MsidbCustomActionType64BitScript) == WindowsInstallerConstants.MsidbCustomActionType64BitScript,
138 case "Feature": 167 TSAware = (caType & WindowsInstallerConstants.MsidbCustomActionTypeTSAware) == WindowsInstallerConstants.MsidbCustomActionTypeTSAware,
139 { 168 Impersonate = (caType & WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate) != WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate,
140 int attributes = FieldAsInt(row, 7); 169 IgnoreResult = (caType & WindowsInstallerConstants.MsidbCustomActionTypeContinue) == WindowsInstallerConstants.MsidbCustomActionTypeContinue,
141 var installDefault = FeatureInstallDefault.Local; 170 Hidden = (caType & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) == WindowsInstallerConstants.MsidbCustomActionTypeHideTarget,
142 if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) == WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) 171 Async = (caType & WindowsInstallerConstants.MsidbCustomActionTypeAsync) == WindowsInstallerConstants.MsidbCustomActionTypeAsync,
143 { 172 };
144 installDefault = FeatureInstallDefault.FollowParent; 173 }
145 }
146 else
147 if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) == WindowsInstallerConstants.MsidbFeatureAttributesFavorSource)
148 {
149 installDefault = FeatureInstallDefault.Source;
150 }
151 174
152 return new FeatureTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) 175 case "Directory":
153 { 176 {
154 Feature_Parent = FieldAsString(row, 1), 177 var id = FieldAsString(row, 0);
155 Title = FieldAsString(row, 2), 178 var splits = SplitDefaultDir(FieldAsString(row, 2));
156 Description = FieldAsString(row, 3), 179
157 Display = FieldAsInt(row, 4), // BUGBUGBUG: FieldAsNullableInt(row, 4), 180 var tuple = new DirectoryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, id))
158 Level = FieldAsInt(row, 5), 181 {
159 Directory_ = FieldAsString(row, 6), 182 ParentDirectoryRef = FieldAsString(row, 1),
160 DisallowAbsent = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent) == WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent, 183 Name = splits[0],
161 DisallowAdvertise = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise, 184 ShortName = splits[1],
162 InstallDefault = installDefault, 185 SourceName = splits[2],
163 TypicalDefault = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise ? FeatureTypicalDefault.Advertise : FeatureTypicalDefault.Install, 186 SourceShortName = splits[3]
164 }; 187 };
188
189 if (wixDirectoryById.TryGetValue(id, out var wixDirectoryRow))
190 {
191 tuple.ComponentGuidGenerationSeed = FieldAsString(wixDirectoryRow, 1);
165 } 192 }
166 193
167 case "FeatureComponents": 194 return tuple;
168 return DefaultTupleFromRow(typeof(FeatureComponentsTuple), row, columnZeroIsId: false); 195 }
169 case "File": 196 case "DrLocator":
170 { 197 return DefaultTupleFromRow(typeof(DrLocatorTuple), row, columnZeroIsId: false);
171 var attributes = FieldAsNullableInt(row, 6); 198 case "DuplicateFile":
172 var readOnly = (attributes & WindowsInstallerConstants.MsidbFileAttributesReadOnly) == WindowsInstallerConstants.MsidbFileAttributesReadOnly; 199 return DefaultTupleFromRow(typeof(DuplicateFileTuple), row, columnZeroIsId: true);
173 var hidden = (attributes & WindowsInstallerConstants.MsidbFileAttributesHidden) == WindowsInstallerConstants.MsidbFileAttributesHidden; 200 case "Error":
174 var system = (attributes & WindowsInstallerConstants.MsidbFileAttributesSystem) == WindowsInstallerConstants.MsidbFileAttributesSystem; 201 return DefaultTupleFromRow(typeof(ErrorTuple), row, columnZeroIsId: false);
175 var vital = (attributes & WindowsInstallerConstants.MsidbFileAttributesVital) == WindowsInstallerConstants.MsidbFileAttributesVital; 202 case "Extension":
176 var checksum = (attributes & WindowsInstallerConstants.MsidbFileAttributesChecksum) == WindowsInstallerConstants.MsidbFileAttributesChecksum; 203 return DefaultTupleFromRow(typeof(ExtensionTuple), row, columnZeroIsId: false);
177 bool? compressed = null; 204 case "Feature":
178 if ((attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed) 205 {
179 { 206 var attributes = FieldAsInt(row, 7);
180 compressed = false; 207 var installDefault = FeatureInstallDefault.Local;
181 } 208 if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) == WindowsInstallerConstants.MsidbFeatureAttributesFollowParent)
182 else if ((attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed) 209 {
183 { 210 installDefault = FeatureInstallDefault.FollowParent;
184 compressed = true; 211 }
185 } 212 else if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) == WindowsInstallerConstants.MsidbFeatureAttributesFavorSource)
213 {
214 installDefault = FeatureInstallDefault.Source;
215 }
186 216
187 return new FileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) 217 return new FeatureTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
188 { 218 {
189 Component_ = FieldAsString(row, 1), 219 ParentFeatureRef = FieldAsString(row, 1),
190 LongFileName = FieldAsString(row, 2), 220 Title = FieldAsString(row, 2),
191 FileSize = FieldAsInt(row, 3), 221 Description = FieldAsString(row, 3),
192 Version = FieldAsString(row, 4), 222 Display = FieldAsInt(row, 4), // BUGBUGBUG: FieldAsNullableInt(row, 4),
193 Language = FieldAsString(row, 5), 223 Level = FieldAsInt(row, 5),
194 ReadOnly = readOnly, 224 DirectoryRef = FieldAsString(row, 6),
195 Hidden = hidden, 225 DisallowAbsent = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent) == WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent,
196 System = system, 226 DisallowAdvertise = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise,
197 Vital = vital, 227 InstallDefault = installDefault,
198 Checksum = checksum, 228 TypicalDefault = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise ? FeatureTypicalDefault.Advertise : FeatureTypicalDefault.Install,
199 Compressed = compressed, 229 };
200 }; 230 }
231
232 case "FeatureComponents":
233 return DefaultTupleFromRow(typeof(FeatureComponentsTuple), row, columnZeroIsId: false);
234 case "File":
235 {
236 var attributes = FieldAsNullableInt(row, 6);
237 var readOnly = (attributes & WindowsInstallerConstants.MsidbFileAttributesReadOnly) == WindowsInstallerConstants.MsidbFileAttributesReadOnly;
238 var hidden = (attributes & WindowsInstallerConstants.MsidbFileAttributesHidden) == WindowsInstallerConstants.MsidbFileAttributesHidden;
239 var system = (attributes & WindowsInstallerConstants.MsidbFileAttributesSystem) == WindowsInstallerConstants.MsidbFileAttributesSystem;
240 var vital = (attributes & WindowsInstallerConstants.MsidbFileAttributesVital) == WindowsInstallerConstants.MsidbFileAttributesVital;
241 var checksum = (attributes & WindowsInstallerConstants.MsidbFileAttributesChecksum) == WindowsInstallerConstants.MsidbFileAttributesChecksum;
242 bool? compressed = null;
243 if ((attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed)
244 {
245 compressed = false;
246 }
247 else if ((attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed)
248 {
249 compressed = true;
201 } 250 }
202 251
203 case "Font": 252 var id = FieldAsString(row, 0);
204 return DefaultTupleFromRow(typeof(FontTuple), row, columnZeroIsId: false);
205 case "Icon":
206 return DefaultTupleFromRow(typeof(IconTuple), row, columnZeroIsId: false);
207 case "InstallExecuteSequence":
208 return DefaultTupleFromRow(typeof(InstallExecuteSequenceTuple), row, columnZeroIsId: false);
209 case "LockPermissions":
210 return DefaultTupleFromRow(typeof(LockPermissionsTuple), row, columnZeroIsId: false);
211 case "Media":
212 return DefaultTupleFromRow(typeof(MediaTuple), row, columnZeroIsId: false);
213 case "MIME":
214 return DefaultTupleFromRow(typeof(MIMETuple), row, columnZeroIsId: false);
215 case "MoveFile":
216 return DefaultTupleFromRow(typeof(MoveFileTuple), row, columnZeroIsId: false);
217 case "MsiAssembly":
218 return DefaultTupleFromRow(typeof(MsiAssemblyTuple), row, columnZeroIsId: false);
219 case "MsiShortcutProperty":
220 return DefaultTupleFromRow(typeof(MsiShortcutPropertyTuple), row, columnZeroIsId: false);
221 case "ProgId":
222 return DefaultTupleFromRow(typeof(ProgIdTuple), row, columnZeroIsId: false);
223 case "Property":
224 return DefaultTupleFromRow(typeof(PropertyTuple), row, columnZeroIsId: false);
225 case "PublishComponent":
226 return DefaultTupleFromRow(typeof(PublishComponentTuple), row, columnZeroIsId: false);
227 case "Registry":
228 {
229 var value = FieldAsString(row, 4);
230 var valueType = RegistryValueType.String;
231 var valueAction = RegistryValueActionType.Write;
232
233 if (!String.IsNullOrEmpty(value))
234 {
235 if (value.StartsWith("#x", StringComparison.Ordinal))
236 {
237 valueType = RegistryValueType.Binary;
238 value = value.Substring(2);
239 }
240 else if (value.StartsWith("#%", StringComparison.Ordinal))
241 {
242 valueType = RegistryValueType.Expandable;
243 value = value.Substring(2);
244 }
245 else if (value.StartsWith("#", StringComparison.Ordinal))
246 {
247 valueType = RegistryValueType.Integer;
248 value = value.Substring(1);
249 }
250 else if (value.StartsWith("[~]", StringComparison.Ordinal) && value.EndsWith("[~]", StringComparison.Ordinal))
251 {
252 value = value.Substring(3, value.Length - 6);
253 valueType = RegistryValueType.MultiString;
254 valueAction = RegistryValueActionType.Write;
255 }
256 else if (value.StartsWith("[~]", StringComparison.Ordinal))
257 {
258 value = value.Substring(3);
259 valueType = RegistryValueType.MultiString;
260 valueAction = RegistryValueActionType.Append;
261 }
262 else if (value.EndsWith("[~]", StringComparison.Ordinal))
263 {
264 value = value.Substring(0, value.Length - 3);
265 valueType = RegistryValueType.MultiString;
266 valueAction = RegistryValueActionType.Prepend;
267 }
268 }
269 253
270 return new RegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) 254 var tuple = new FileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, id))
271 { 255 {
272 Root = (RegistryRootType)FieldAsInt(row, 1), 256 ComponentRef = FieldAsString(row, 1),
273 Key = FieldAsString(row, 2), 257 Name = FieldAsString(row, 2),
274 Name = FieldAsString(row, 3), 258 FileSize = FieldAsInt(row, 3),
275 Value = value, 259 Version = FieldAsString(row, 4),
276 Component_ = FieldAsString(row, 5), 260 Language = FieldAsString(row, 5),
277 ValueAction = valueAction, 261 ReadOnly = readOnly,
278 ValueType = valueType, 262 Hidden = hidden,
279 }; 263 System = system,
264 Vital = vital,
265 Checksum = checksum,
266 Compressed = compressed,
267 };
268
269 if (bindPathsById.TryGetValue(id, out var bindPathRow))
270 {
271 tuple.BindPath = FieldAsString(bindPathRow, 1) ?? String.Empty;
280 } 272 }
281 273
282 case "RegLocator": 274 if (fontsById.TryGetValue(id, out var fontRow))
283 return DefaultTupleFromRow(typeof(RegLocatorTuple), row, columnZeroIsId: false);
284 case "RemoveFile":
285 return DefaultTupleFromRow(typeof(RemoveFileTuple), row, columnZeroIsId: false);
286 case "RemoveRegistry":
287 { 275 {
288 return new RemoveRegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) 276 tuple.FontTitle = FieldAsString(fontRow, 1) ?? String.Empty;
289 {
290 Action = RemoveRegistryActionType.RemoveOnInstall,
291 Root = (RegistryRootType)FieldAsInt(row, 1),
292 Key = FieldAsString(row, 2),
293 Name = FieldAsString(row, 3),
294 Component_ = FieldAsString(row, 4),
295 };
296 } 277 }
297 278
298 case "ReserveCost": 279 if (selfRegById.TryGetValue(id, out var selfRegRow))
299 return DefaultTupleFromRow(typeof(ReserveCostTuple), row, columnZeroIsId: false);
300 case "ServiceControl":
301 { 280 {
302 var events = FieldAsInt(row, 2); 281 tuple.SelfRegCost = FieldAsNullableInt(selfRegRow, 1) ?? 0;
303 var wait = FieldAsNullableInt(row, 4);
304 return new ServiceControlTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
305 {
306 Name = FieldAsString(row, 1),
307 Arguments = FieldAsString(row, 3),
308 Wait = !wait.HasValue || wait.Value == 1,
309 Component_ = FieldAsString(row, 5),
310 InstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventDelete) == WindowsInstallerConstants.MsidbServiceControlEventDelete,
311 UninstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete) == WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete,
312 InstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventStart) == WindowsInstallerConstants.MsidbServiceControlEventStart,
313 UninstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStart) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStart,
314 InstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventStop) == WindowsInstallerConstants.MsidbServiceControlEventStop,
315 UninstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStop) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStop,
316 };
317 } 282 }
318 283
319 case "ServiceInstall": 284 return tuple;
320 return DefaultTupleFromRow(typeof(ServiceInstallTuple), row, columnZeroIsId: true); 285 }
321 case "Shortcut": 286 case "Font":
322 return DefaultTupleFromRow(typeof(ShortcutTuple), row, columnZeroIsId: true); 287 return null;
323 case "Signature": 288 case "Icon":
324 return DefaultTupleFromRow(typeof(SignatureTuple), row, columnZeroIsId: false); 289 return DefaultTupleFromRow(typeof(IconTuple), row, columnZeroIsId: true);
325 case "Upgrade": 290 case "InstallExecuteSequence":
291 return DefaultTupleFromRow(typeof(InstallExecuteSequenceTuple), row, columnZeroIsId: false);
292 case "LockPermissions":
293 return DefaultTupleFromRow(typeof(LockPermissionsTuple), row, columnZeroIsId: false);
294 case "Media":
295 {
296 var diskId = FieldAsInt(row, 0);
297 var tuple = new MediaTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, diskId))
326 { 298 {
327 var attributes = FieldAsInt(row, 4); 299 DiskId = diskId,
328 return new UpgradeTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) 300 LastSequence = FieldAsNullableInt(row, 1),
329 { 301 DiskPrompt = FieldAsString(row, 2),
330 UpgradeCode = FieldAsString(row, 0), 302 Cabinet = FieldAsString(row, 3),
331 VersionMin = FieldAsString(row, 1), 303 VolumeLabel = FieldAsString(row, 4),
332 VersionMax = FieldAsString(row, 2), 304 Source = FieldAsString(row, 5)
333 Language = FieldAsString(row, 3), 305 };
334 Remove = FieldAsString(row, 5), 306
335 ActionProperty = FieldAsString(row, 6), 307 if (wixMediaByDiskId.TryGetValue(diskId, out var wixMediaRow))
336 MigrateFeatures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures) == WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures, 308 {
337 OnlyDetect = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect, 309 var compressionLevel = FieldAsString(wixMediaRow, 1);
338 IgnoreRemoveFailures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure) == WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure, 310
339 VersionMinInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive, 311 tuple.CompressionLevel = String.IsNullOrEmpty(compressionLevel) ? null : (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), compressionLevel, true);
340 VersionMaxInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive, 312 tuple.Layout = wixMediaRow.Layout;
341 ExcludeLanguages = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive,
342 };
343 } 313 }
344 314
345 case "Verb": 315 return tuple;
346 return DefaultTupleFromRow(typeof(VerbTuple), row, columnZeroIsId: false); 316 }
347 //case "WixAction": 317 case "MIME":
348 // return new WixActionTuple(SourceLineNumber4(row.SourceLineNumbers)) 318 return DefaultTupleFromRow(typeof(MIMETuple), row, columnZeroIsId: false);
349 // { 319 case "ModuleIgnoreTable":
350 // SequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), FieldAsString(row, 0)), 320 return DefaultTupleFromRow(typeof(ModuleIgnoreTableTuple), row, columnZeroIsId: true);
351 // Action = FieldAsString(row, 1), 321 case "MoveFile":
352 // Condition = FieldAsString(row, 2), 322 return DefaultTupleFromRow(typeof(MoveFileTuple), row, columnZeroIsId: true);
353 // Sequence = FieldAsInt(row, 3), 323 case "MsiAssembly":
354 // Before = FieldAsString(row, 4), 324 return DefaultTupleFromRow(typeof(MsiAssemblyTuple), row, columnZeroIsId: false);
355 // After = FieldAsString(row, 5), 325 case "MsiLockPermissionsEx":
356 // Overridable = FieldAsNullableInt(row, 6) != 0, 326 return DefaultTupleFromRow(typeof(MsiLockPermissionsExTuple), row, columnZeroIsId: true);
357 // }; 327 case "MsiShortcutProperty":
358 case "WixFile": 328 return DefaultTupleFromRow(typeof(MsiShortcutPropertyTuple), row, columnZeroIsId: true);
359 var assemblyAttributes3 = FieldAsNullableInt(row, 1); 329 case "ODBCDataSource":
360 return new WixFileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) 330 return DefaultTupleFromRow(typeof(ODBCDataSourceTuple), row, columnZeroIsId: true);
331 case "ODBCDriver":
332 return DefaultTupleFromRow(typeof(ODBCDriverTuple), row, columnZeroIsId: true);
333 case "ODBCTranslator":
334 return DefaultTupleFromRow(typeof(ODBCTranslatorTuple), row, columnZeroIsId: true);
335 case "ProgId":
336 return DefaultTupleFromRow(typeof(ProgIdTuple), row, columnZeroIsId: false);
337 case "Property":
338 return DefaultTupleFromRow(typeof(PropertyTuple), row, columnZeroIsId: true);
339 case "PublishComponent":
340 return DefaultTupleFromRow(typeof(PublishComponentTuple), row, columnZeroIsId: false);
341 case "Registry":
342 {
343 var value = FieldAsString(row, 4);
344 var valueType = RegistryValueType.String;
345 var valueAction = RegistryValueActionType.Write;
346
347 if (!String.IsNullOrEmpty(value))
348 {
349 if (value.StartsWith("#x", StringComparison.Ordinal))
361 { 350 {
362 AssemblyType = assemblyAttributes3 == 0 ? FileAssemblyType.DotNetAssembly : assemblyAttributes3 == 1 ? FileAssemblyType.Win32Assembly : FileAssemblyType.NotAnAssembly, 351 valueType = RegistryValueType.Binary;
363 File_AssemblyManifest = FieldAsString(row, 2), 352 value = value.Substring(2);
364 File_AssemblyApplication = FieldAsString(row, 3), 353 }
365 Directory_ = FieldAsString(row, 4), 354 else if (value.StartsWith("#%", StringComparison.Ordinal))
366 DiskId = FieldAsInt(row, 5), // TODO: BUGBUGBUG: AB#2626: DiskId is nullable in WiX v3. 355 {
367 Source = new IntermediateFieldPathValue() { Path = FieldAsString(row, 6) }, 356 valueType = RegistryValueType.Expandable;
368 ProcessorArchitecture = FieldAsString(row, 7), 357 value = value.Substring(2);
369 PatchGroup = FieldAsInt(row, 8), 358 }
370 Attributes = FieldAsInt(row, 9), 359 else if (value.StartsWith("#", StringComparison.Ordinal))
371 }; 360 {
372 case "WixProperty": 361 valueType = RegistryValueType.Integer;
373 { 362 value = value.Substring(1);
374 var attributes = FieldAsInt(row, 1); 363 }
375 return new WixPropertyTuple(SourceLineNumber4(row.SourceLineNumbers)) 364 else if (value.StartsWith("[~]", StringComparison.Ordinal) && value.EndsWith("[~]", StringComparison.Ordinal))
365 {
366 value = value.Substring(3, value.Length - 6);
367 valueType = RegistryValueType.MultiString;
368 valueAction = RegistryValueActionType.Write;
369 }
370 else if (value.StartsWith("[~]", StringComparison.Ordinal))
371 {
372 value = value.Substring(3);
373 valueType = RegistryValueType.MultiString;
374 valueAction = RegistryValueActionType.Append;
375 }
376 else if (value.EndsWith("[~]", StringComparison.Ordinal))
376 { 377 {
377 Property_ = FieldAsString(row, 0), 378 value = value.Substring(0, value.Length - 3);
378 Admin = (attributes & 0x1) == 0x1, 379 valueType = RegistryValueType.MultiString;
379 Hidden = (attributes & 0x2) == 0x2, 380 valueAction = RegistryValueActionType.Prepend;
380 Secure = (attributes & 0x4) == 0x4, 381 }
381 };
382 } 382 }
383 383
384 default: 384 return new RegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
385 return GenericTupleFromCustomRow(row, columnZeroIsId: false); 385 {
386 Root = (RegistryRootType)FieldAsInt(row, 1),
387 Key = FieldAsString(row, 2),
388 Name = FieldAsString(row, 3),
389 Value = value,
390 ComponentRef = FieldAsString(row, 5),
391 ValueAction = valueAction,
392 ValueType = valueType,
393 };
394 }
395 case "RegLocator":
396 {
397 var type = FieldAsInt(row, 4);
398
399 return new RegLocatorTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
400 {
401 Root = (RegistryRootType)FieldAsInt(row, 1),
402 Key = FieldAsString(row, 2),
403 Name = FieldAsString(row, 3),
404 Type = (RegLocatorType)(type & 0xF),
405 Win64 = (type & WindowsInstallerConstants.MsidbLocatorType64bit) == WindowsInstallerConstants.MsidbLocatorType64bit
406 };
407 }
408 case "RemoveFile":
409 {
410 var installMode = FieldAsInt(row, 4);
411 return new RemoveFileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
412 {
413 ComponentRef = FieldAsString(row, 1),
414 FileName = FieldAsString(row, 2),
415 DirProperty = FieldAsString(row, 3),
416 OnInstall = (installMode & WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall) == WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall ? (bool?)true : null,
417 OnUninstall = (installMode & WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove) == WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove ? (bool?)true : null
418 };
419 }
420 case "RemoveRegistry":
421 {
422 return new RemoveRegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
423 {
424 Action = RemoveRegistryActionType.RemoveOnInstall,
425 Root = (RegistryRootType)FieldAsInt(row, 1),
426 Key = FieldAsString(row, 2),
427 Name = FieldAsString(row, 3),
428 ComponentRef = FieldAsString(row, 4),
429 };
430 }
431
432 case "ReserveCost":
433 return DefaultTupleFromRow(typeof(ReserveCostTuple), row, columnZeroIsId: true);
434 case "SelfReg":
435 return null;
436 case "ServiceControl":
437 {
438 var events = FieldAsInt(row, 2);
439 var wait = FieldAsNullableInt(row, 4);
440 return new ServiceControlTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
441 {
442 Name = FieldAsString(row, 1),
443 Arguments = FieldAsString(row, 3),
444 Wait = !wait.HasValue || wait.Value == 1,
445 ComponentRef = FieldAsString(row, 5),
446 InstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventDelete) == WindowsInstallerConstants.MsidbServiceControlEventDelete,
447 UninstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete) == WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete,
448 InstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventStart) == WindowsInstallerConstants.MsidbServiceControlEventStart,
449 UninstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStart) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStart,
450 InstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventStop) == WindowsInstallerConstants.MsidbServiceControlEventStop,
451 UninstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStop) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStop,
452 };
453 }
454
455 case "ServiceInstall":
456 return DefaultTupleFromRow(typeof(ServiceInstallTuple), row, columnZeroIsId: true);
457 case "Shortcut":
458 {
459 var splitName = FieldAsString(row, 2).Split('|');
460
461 return new ShortcutTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
462 {
463 DirectoryRef = FieldAsString(row, 1),
464 Name = splitName.Length > 1 ? splitName[1] : splitName[0],
465 ShortName = splitName.Length > 1 ? splitName[0] : null,
466 ComponentRef = FieldAsString(row, 3),
467 Target = FieldAsString(row, 4),
468 Arguments = FieldAsString(row, 5),
469 Description = FieldAsString(row, 6),
470 Hotkey = FieldAsNullableInt(row, 7),
471 IconRef = FieldAsString(row, 8),
472 IconIndex = FieldAsNullableInt(row, 9),
473 Show = (ShortcutShowType?)FieldAsNullableInt(row, 10),
474 WorkingDirectory = FieldAsString(row, 11),
475 DisplayResourceDll = FieldAsString(row, 12),
476 DisplayResourceId = FieldAsNullableInt(row, 13),
477 DescriptionResourceDll = FieldAsString(row, 14),
478 DescriptionResourceId= FieldAsNullableInt(row, 15),
479 };
480 }
481 case "Signature":
482 return DefaultTupleFromRow(typeof(SignatureTuple), row, columnZeroIsId: false);
483 case "UIText":
484 return DefaultTupleFromRow(typeof(UITextTuple), row, columnZeroIsId: true);
485 case "Upgrade":
486 {
487 var attributes = FieldAsInt(row, 4);
488 return new UpgradeTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
489 {
490 UpgradeCode = FieldAsString(row, 0),
491 VersionMin = FieldAsString(row, 1),
492 VersionMax = FieldAsString(row, 2),
493 Language = FieldAsString(row, 3),
494 Remove = FieldAsString(row, 5),
495 ActionProperty = FieldAsString(row, 6),
496 MigrateFeatures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures) == WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures,
497 OnlyDetect = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect,
498 IgnoreRemoveFailures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure) == WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure,
499 VersionMinInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive,
500 VersionMaxInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive,
501 ExcludeLanguages = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive,
502 };
503 }
504 case "Verb":
505 return DefaultTupleFromRow(typeof(VerbTuple), row, columnZeroIsId: false);
506 case "WixAction":
507 var sequenceTable = FieldAsString(row, 0);
508 return new WixActionTuple(SourceLineNumber4(row.SourceLineNumbers))
509 {
510 SequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), sequenceTable == "AdvtExecuteSequence" ? nameof(SequenceTable.AdvertiseExecuteSequence) : sequenceTable),
511 Action = FieldAsString(row, 1),
512 Condition = FieldAsString(row, 2),
513 Sequence = FieldAsNullableInt(row, 3),
514 Before = FieldAsString(row, 4),
515 After = FieldAsString(row, 5),
516 Overridable = FieldAsNullableInt(row, 6) != 0,
517 };
518 case "WixBootstrapperApplication":
519 return DefaultTupleFromRow(typeof(WixBootstrapperApplicationTuple), row, columnZeroIsId: true);
520 case "WixBundleContainer":
521 return DefaultTupleFromRow(typeof(WixBundleContainerTuple), row, columnZeroIsId: true);
522 case "WixBundleVariable":
523 return DefaultTupleFromRow(typeof(WixBundleVariableTuple), row, columnZeroIsId: true);
524 case "WixChainItem":
525 return DefaultTupleFromRow(typeof(WixChainItemTuple), row, columnZeroIsId: true);
526 case "WixCustomTable":
527 return DefaultTupleFromRow(typeof(WixCustomTableTuple), row, columnZeroIsId: true);
528 case "WixDeltaPatchFile":
529 return DefaultTupleFromRow(typeof(WixDeltaPatchFileTuple), row, columnZeroIsId: true);
530 case "WixDirectory":
531 return null;
532 case "WixFile":
533 var assemblyAttributes3 = FieldAsNullableInt(row, 1);
534 return new WixFileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
535 {
536 AssemblyType = assemblyAttributes3 == 0 ? FileAssemblyType.DotNetAssembly : assemblyAttributes3 == 1 ? FileAssemblyType.Win32Assembly : FileAssemblyType.NotAnAssembly,
537 AssemblyManifestFileRef = FieldAsString(row, 2),
538 AssemblyApplicationFileRef = FieldAsString(row, 3),
539 DirectoryRef = FieldAsString(row, 4),
540 DiskId = FieldAsNullableInt(row, 5) ?? 0,
541 Source = new IntermediateFieldPathValue() { Path = FieldAsString(row, 6) },
542 ProcessorArchitecture = FieldAsString(row, 7),
543 PatchGroup = FieldAsInt(row, 8),
544 Attributes = FieldAsInt(row, 9),
545 PatchAttributes = (PatchAttributeType)FieldAsInt(row, 10),
546 };
547 case "WixInstanceTransforms":
548 return DefaultTupleFromRow(typeof(WixInstanceTransformsTuple), row, columnZeroIsId: true);
549 case "WixMedia":
550 return null;
551 case "WixMerge":
552 return DefaultTupleFromRow(typeof(WixMergeTuple), row, columnZeroIsId: true);
553 case "WixPatchBaseline":
554 return DefaultTupleFromRow(typeof(WixPatchBaselineTuple), row, columnZeroIsId: true);
555 case "WixProperty":
556 {
557 var attributes = FieldAsInt(row, 1);
558 return new WixPropertyTuple(SourceLineNumber4(row.SourceLineNumbers))
559 {
560 PropertyRef = FieldAsString(row, 0),
561 Admin = (attributes & 0x1) == 0x1,
562 Hidden = (attributes & 0x2) == 0x2,
563 Secure = (attributes & 0x4) == 0x4,
564 };
565 }
566 case "WixSuppressModularization":
567 return DefaultTupleFromRow(typeof(WixSuppressModularizationTuple), row, columnZeroIsId: true);
568 case "WixUI":
569 return DefaultTupleFromRow(typeof(WixUITuple), row, columnZeroIsId: true);
570 case "WixVariable":
571 return DefaultTupleFromRow(typeof(WixVariableTuple), row, columnZeroIsId: true);
572 default:
573 return GenericTupleFromCustomRow(row, columnZeroIsId: false);
386 } 574 }
387 } 575 }
388 576
@@ -470,16 +658,16 @@ namespace WixToolset.Converters.Tupleizer
470 { 658 {
471 switch (columnType) 659 switch (columnType)
472 { 660 {
473 case Wix3.ColumnType.Number: 661 case Wix3.ColumnType.Number:
474 return IntermediateFieldType.Number; 662 return IntermediateFieldType.Number;
475 case Wix3.ColumnType.Object: 663 case Wix3.ColumnType.Object:
476 return IntermediateFieldType.Path; 664 return IntermediateFieldType.Path;
477 case Wix3.ColumnType.Unknown: 665 case Wix3.ColumnType.Unknown:
478 case Wix3.ColumnType.String: 666 case Wix3.ColumnType.String:
479 case Wix3.ColumnType.Localized: 667 case Wix3.ColumnType.Localized:
480 case Wix3.ColumnType.Preserved: 668 case Wix3.ColumnType.Preserved:
481 default: 669 default:
482 return IntermediateFieldType.String; 670 return IntermediateFieldType.String;
483 } 671 }
484 } 672 }
485 673
@@ -520,22 +708,22 @@ namespace WixToolset.Converters.Tupleizer
520 var column = row.Fields[i].Column; 708 var column = row.Fields[i].Column;
521 switch (column.Type) 709 switch (column.Type)
522 { 710 {
523 case Wix3.ColumnType.String: 711 case Wix3.ColumnType.String:
524 case Wix3.ColumnType.Localized: 712 case Wix3.ColumnType.Localized:
525 case Wix3.ColumnType.Object: 713 case Wix3.ColumnType.Object:
526 case Wix3.ColumnType.Preserved: 714 case Wix3.ColumnType.Preserved:
527 tuple.Set(i - offset, FieldAsString(row, i)); 715 tuple.Set(i - offset, FieldAsString(row, i));
528 break; 716 break;
529 case Wix3.ColumnType.Number: 717 case Wix3.ColumnType.Number:
530 int? nullableValue = FieldAsNullableInt(row, i); 718 int? nullableValue = FieldAsNullableInt(row, i);
531 // TODO: Consider whether null values should be coerced to their default value when 719 // TODO: Consider whether null values should be coerced to their default value when
532 // a column is not nullable. For now, just pass through the null. 720 // a column is not nullable. For now, just pass through the null.
533 //int value = FieldAsInt(row, i); 721 //int value = FieldAsInt(row, i);
534 //tuple.Set(i - offset, column.IsNullable ? nullableValue : value); 722 //tuple.Set(i - offset, column.IsNullable ? nullableValue : value);
535 tuple.Set(i - offset, nullableValue); 723 tuple.Set(i - offset, nullableValue);
724 break;
725 case Wix3.ColumnType.Unknown:
536 break; 726 break;
537 case Wix3.ColumnType.Unknown:
538 break;
539 } 727 }
540 } 728 }
541 } 729 }
@@ -545,15 +733,15 @@ namespace WixToolset.Converters.Tupleizer
545 var column = row.Fields[0].Column; 733 var column = row.Fields[0].Column;
546 switch (column.Type) 734 switch (column.Type)
547 { 735 {
548 case Wix3.ColumnType.String: 736 case Wix3.ColumnType.String:
549 case Wix3.ColumnType.Localized: 737 case Wix3.ColumnType.Localized:
550 case Wix3.ColumnType.Object: 738 case Wix3.ColumnType.Object:
551 case Wix3.ColumnType.Preserved: 739 case Wix3.ColumnType.Preserved:
552 return new Identifier(AccessModifier.Public, (string)row.Fields[0].Data); 740 return new Identifier(AccessModifier.Public, (string)row.Fields[0].Data);
553 case Wix3.ColumnType.Number: 741 case Wix3.ColumnType.Number:
554 return new Identifier(AccessModifier.Public, FieldAsInt(row, 0)); 742 return new Identifier(AccessModifier.Public, FieldAsInt(row, 0));
555 default: 743 default:
556 return null; 744 return null;
557 } 745 }
558 } 746 }
559 747
@@ -561,20 +749,20 @@ namespace WixToolset.Converters.Tupleizer
561 { 749 {
562 switch (outputType) 750 switch (outputType)
563 { 751 {
564 case Wix3.OutputType.Bundle: 752 case Wix3.OutputType.Bundle:
565 return SectionType.Bundle; 753 return SectionType.Bundle;
566 case Wix3.OutputType.Module: 754 case Wix3.OutputType.Module:
567 return SectionType.Module; 755 return SectionType.Module;
568 case Wix3.OutputType.Patch: 756 case Wix3.OutputType.Patch:
569 return SectionType.Patch; 757 return SectionType.Patch;
570 case Wix3.OutputType.PatchCreation: 758 case Wix3.OutputType.PatchCreation:
571 return SectionType.PatchCreation; 759 return SectionType.PatchCreation;
572 case Wix3.OutputType.Product: 760 case Wix3.OutputType.Product:
573 return SectionType.Product; 761 return SectionType.Product;
574 case Wix3.OutputType.Transform: 762 case Wix3.OutputType.Transform:
575 case Wix3.OutputType.Unknown: 763 case Wix3.OutputType.Unknown:
576 default: 764 default:
577 return SectionType.Unknown; 765 return SectionType.Unknown;
578 } 766 }
579 } 767 }
580 768
@@ -605,5 +793,19 @@ namespace WixToolset.Converters.Tupleizer
605 return Convert.ToInt32(field.Data); 793 return Convert.ToInt32(field.Data);
606 } 794 }
607 } 795 }
796
797 private static string[] SplitDefaultDir(string defaultDir)
798 {
799 var split1 = defaultDir.Split(':');
800 var targetSplit = split1.Length > 1 ? split1[1].Split('|') : split1[0].Split('|');
801 var sourceSplit = split1.Length > 1 ? split1[0].Split('|') : new[] { String.Empty };
802 return new[]
803 {
804 targetSplit.Length > 1 ? targetSplit[1] : targetSplit[0],
805 targetSplit.Length > 1 ? targetSplit[0] : null,
806 sourceSplit.Length > 1 ? sourceSplit[1] : sourceSplit[0],
807 sourceSplit.Length > 1 ? sourceSplit[0] : null
808 };
809 }
608 } 810 }
609} 811}