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