| 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.Symbolizer |
| 4 | { |
| 5 | using System; |
| 6 | using System.Collections.Generic; |
| 7 | using System.Linq; |
| 8 | using WixToolset.Data; |
| 9 | using WixToolset.Data.Symbols; |
| 10 | using WixToolset.Data.WindowsInstaller; |
| 11 | using Wix3 = Microsoft.Tools.WindowsInstallerXml; |
| 12 | |
| 13 | #pragma warning disable 1591 // TODO: add documentation |
| 14 | public static class ConvertSymbols |
| 15 | { |
| 16 | public static Intermediate ConvertFile(string path) |
| 17 | { |
| 18 | var output = Wix3.Output.Load(path, suppressVersionCheck: true, suppressSchema: true); |
| 19 | return ConvertOutput(output); |
| 20 | } |
| 21 | |
| 22 | public static Intermediate ConvertOutput(Wix3.Output output) |
| 23 | #pragma warning restore 1591 |
| 24 | { |
| 25 | var section = new IntermediateSection(String.Empty, OutputType3ToSectionType4(output.Type)); |
| 26 | |
| 27 | var wixMediaByDiskId = IndexWixMediaTableByDiskId(output); |
| 28 | var componentsById = IndexById<Wix3.Row>(output, "Component"); |
| 29 | var bindPathsById = IndexById<Wix3.Row>(output, "BindPath"); |
| 30 | var fontsById = IndexById<Wix3.Row>(output, "Font"); |
| 31 | var selfRegById = IndexById<Wix3.Row>(output, "SelfReg"); |
| 32 | var wixDirectoryById = IndexById<Wix3.Row>(output, "WixDirectory"); |
| 33 | var wixFileById = IndexById<Wix3.Row>(output, "WixFile"); |
| 34 | |
| 35 | foreach (Wix3.Table table in output.Tables) |
| 36 | { |
| 37 | foreach (Wix3.Row row in table.Rows) |
| 38 | { |
| 39 | var symbol = GenerateSymbolFromRow(row, wixMediaByDiskId, componentsById, fontsById, bindPathsById, selfRegById, wixFileById, wixDirectoryById); |
| 40 | if (symbol != null) |
| 41 | { |
| 42 | section.AddSymbol(symbol); |
| 43 | } |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | return new Intermediate(String.Empty, new[] { section }, localizationsByCulture: null); |
| 48 | } |
| 49 | |
| 50 | private static Dictionary<int, Wix3.WixMediaRow> IndexWixMediaTableByDiskId(Wix3.Output output) |
| 51 | { |
| 52 | var wixMediaByDiskId = new Dictionary<int, Wix3.WixMediaRow>(); |
| 53 | var wixMediaTable = output.Tables["WixMedia"]; |
| 54 | |
| 55 | if (wixMediaTable != null) |
| 56 | { |
| 57 | foreach (Wix3.WixMediaRow row in wixMediaTable.Rows) |
| 58 | { |
| 59 | wixMediaByDiskId.Add(FieldAsInt(row, 0), row); |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | return wixMediaByDiskId; |
| 64 | } |
| 65 | |
| 66 | private static Dictionary<string, T> IndexById<T>(Wix3.Output output, string tableName) where T : Wix3.Row |
| 67 | { |
| 68 | var byId = new Dictionary<string, T>(); |
| 69 | var table = output.Tables[tableName]; |
| 70 | |
| 71 | if (table != null) |
| 72 | { |
| 73 | foreach (T row in table.Rows) |
| 74 | { |
| 75 | byId.Add(FieldAsString(row, 0), row); |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | return byId; |
| 80 | } |
| 81 | |
| 82 | private static IntermediateSymbol GenerateSymbolFromRow(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) |
| 83 | { |
| 84 | var name = row.Table.Name; |
| 85 | switch (name) |
| 86 | { |
| 87 | case "_SummaryInformation": |
| 88 | return DefaultSymbolFromRow(typeof(SummaryInformationSymbol), row, columnZeroIsId: false); |
| 89 | case "ActionText": |
| 90 | return DefaultSymbolFromRow(typeof(ActionTextSymbol), row, columnZeroIsId: false); |
| 91 | case "AppId": |
| 92 | return DefaultSymbolFromRow(typeof(AppIdSymbol), row, columnZeroIsId: false); |
| 93 | case "AppSearch": |
| 94 | return DefaultSymbolFromRow(typeof(AppSearchSymbol), row, columnZeroIsId: false); |
| 95 | case "Billboard": |
| 96 | return DefaultSymbolFromRow(typeof(BillboardSymbol), row, columnZeroIsId: true); |
| 97 | case "Binary": |
| 98 | return DefaultSymbolFromRow(typeof(BinarySymbol), row, columnZeroIsId: true); |
| 99 | case "BindPath": |
| 100 | return null; |
| 101 | case "CCPSearch": |
| 102 | return DefaultSymbolFromRow(typeof(CCPSearchSymbol), row, columnZeroIsId: true); |
| 103 | case "Class": |
| 104 | return DefaultSymbolFromRow(typeof(ClassSymbol), row, columnZeroIsId: false); |
| 105 | case "CompLocator": |
| 106 | return DefaultSymbolFromRow(typeof(CompLocatorSymbol), row, columnZeroIsId: false); |
| 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 ComponentSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, 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 DefaultSymbolFromRow(typeof(ConditionSymbol), row, columnZeroIsId: false); |
| 153 | case "CreateFolder": |
| 154 | return DefaultSymbolFromRow(typeof(CreateFolderSymbol), 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 CustomActionSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, 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 symbol = new DirectorySymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, 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 | symbol.ComponentGuidGenerationSeed = FieldAsString(wixDirectoryRow, 1); |
| 195 | } |
| 196 | |
| 197 | return symbol; |
| 198 | } |
| 199 | case "DrLocator": |
| 200 | return DefaultSymbolFromRow(typeof(DrLocatorSymbol), row, columnZeroIsId: false); |
| 201 | case "DuplicateFile": |
| 202 | { |
| 203 | var splitName = FieldAsString(row, 3)?.Split('|'); |
| 204 | |
| 205 | var symbol = new DuplicateFileSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 206 | { |
| 207 | ComponentRef = FieldAsString(row, 1), |
| 208 | FileRef = FieldAsString(row, 2), |
| 209 | DestinationName = splitName == null ? null : splitName.Length > 1 ? splitName[1] : splitName[0], |
| 210 | DestinationShortName = splitName == null ? null : splitName.Length > 1 ? splitName[0] : null, |
| 211 | DestinationFolder = FieldAsString(row, 4) |
| 212 | }; |
| 213 | |
| 214 | return symbol; |
| 215 | } |
| 216 | case "Error": |
| 217 | return DefaultSymbolFromRow(typeof(ErrorSymbol), row, columnZeroIsId: false); |
| 218 | case "Extension": |
| 219 | return DefaultSymbolFromRow(typeof(ExtensionSymbol), row, columnZeroIsId: false); |
| 220 | case "Feature": |
| 221 | { |
| 222 | var attributes = FieldAsInt(row, 7); |
| 223 | var installDefault = FeatureInstallDefault.Local; |
| 224 | if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) == WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) |
| 225 | { |
| 226 | installDefault = FeatureInstallDefault.FollowParent; |
| 227 | } |
| 228 | else if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) == WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) |
| 229 | { |
| 230 | installDefault = FeatureInstallDefault.Source; |
| 231 | } |
| 232 | |
| 233 | return new FeatureSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 234 | { |
| 235 | ParentFeatureRef = FieldAsString(row, 1), |
| 236 | Title = FieldAsString(row, 2), |
| 237 | Description = FieldAsString(row, 3), |
| 238 | Display = FieldAsInt(row, 4), // BUGBUGBUG: FieldAsNullableInt(row, 4), |
| 239 | Level = FieldAsInt(row, 5), |
| 240 | DirectoryRef = FieldAsString(row, 6), |
| 241 | DisallowAbsent = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent) == WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent, |
| 242 | DisallowAdvertise = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise, |
| 243 | InstallDefault = installDefault, |
| 244 | TypicalDefault = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise ? FeatureTypicalDefault.Advertise : FeatureTypicalDefault.Install, |
| 245 | }; |
| 246 | } |
| 247 | |
| 248 | case "FeatureComponents": |
| 249 | return DefaultSymbolFromRow(typeof(FeatureComponentsSymbol), row, columnZeroIsId: false); |
| 250 | case "File": |
| 251 | { |
| 252 | var attributes = FieldAsNullableInt(row, 6); |
| 253 | |
| 254 | FileSymbolAttributes symbolAttributes = 0; |
| 255 | symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesReadOnly) == WindowsInstallerConstants.MsidbFileAttributesReadOnly ? FileSymbolAttributes.ReadOnly : 0; |
| 256 | symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesHidden) == WindowsInstallerConstants.MsidbFileAttributesHidden ? FileSymbolAttributes.Hidden : 0; |
| 257 | symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesSystem) == WindowsInstallerConstants.MsidbFileAttributesSystem ? FileSymbolAttributes.System : 0; |
| 258 | symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesVital) == WindowsInstallerConstants.MsidbFileAttributesVital ? FileSymbolAttributes.Vital : 0; |
| 259 | symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesChecksum) == WindowsInstallerConstants.MsidbFileAttributesChecksum ? FileSymbolAttributes.Checksum : 0; |
| 260 | symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed ? FileSymbolAttributes.Uncompressed : 0; |
| 261 | symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed ? FileSymbolAttributes.Compressed : 0; |
| 262 | |
| 263 | var id = FieldAsString(row, 0); |
| 264 | var splitName = FieldAsString(row, 2).Split('|'); |
| 265 | |
| 266 | var symbol = new FileSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, id)) |
| 267 | { |
| 268 | ComponentRef = FieldAsString(row, 1), |
| 269 | Name = splitName.Length > 1 ? splitName[1] : splitName[0], |
| 270 | ShortName = splitName.Length > 1 ? splitName[0] : null, |
| 271 | FileSize = FieldAsInt(row, 3), |
| 272 | Version = FieldAsString(row, 4), |
| 273 | Language = FieldAsString(row, 5), |
| 274 | Attributes = symbolAttributes |
| 275 | }; |
| 276 | |
| 277 | if (bindPathsById.TryGetValue(id, out var bindPathRow)) |
| 278 | { |
| 279 | symbol.BindPath = FieldAsString(bindPathRow, 1) ?? String.Empty; |
| 280 | } |
| 281 | |
| 282 | if (fontsById.TryGetValue(id, out var fontRow)) |
| 283 | { |
| 284 | symbol.FontTitle = FieldAsString(fontRow, 1) ?? String.Empty; |
| 285 | } |
| 286 | |
| 287 | if (selfRegById.TryGetValue(id, out var selfRegRow)) |
| 288 | { |
| 289 | symbol.SelfRegCost = FieldAsNullableInt(selfRegRow, 1) ?? 0; |
| 290 | } |
| 291 | |
| 292 | if (wixFileById.TryGetValue(id, out var wixFileRow)) |
| 293 | { |
| 294 | symbol.DirectoryRef = FieldAsString(wixFileRow, 4); |
| 295 | symbol.DiskId = FieldAsNullableInt(wixFileRow, 5) ?? 0; |
| 296 | symbol.Source = new IntermediateFieldPathValue { Path = FieldAsString(wixFileRow, 6) }; |
| 297 | symbol.PatchGroup = FieldAsInt(wixFileRow, 8); |
| 298 | symbol.PatchAttributes = (PatchAttributeType)FieldAsInt(wixFileRow, 10); |
| 299 | } |
| 300 | |
| 301 | return symbol; |
| 302 | } |
| 303 | case "Font": |
| 304 | return null; |
| 305 | case "Icon": |
| 306 | return DefaultSymbolFromRow(typeof(IconSymbol), row, columnZeroIsId: true); |
| 307 | case "IniFile": |
| 308 | { |
| 309 | var splitName = FieldAsString(row, 1).Split('|'); |
| 310 | var action = FieldAsInt(row, 6); |
| 311 | |
| 312 | var symbol = new IniFileSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 313 | { |
| 314 | FileName = splitName.Length > 1 ? splitName[1] : splitName[0], |
| 315 | ShortFileName = splitName.Length > 1 ? splitName[0] : null, |
| 316 | DirProperty = FieldAsString(row, 2), |
| 317 | Section = FieldAsString(row, 3), |
| 318 | Key = FieldAsString(row, 4), |
| 319 | Value = FieldAsString(row, 5), |
| 320 | Action = action == 3 ? IniFileActionType.AddTag : action == 1 ? IniFileActionType.CreateLine : IniFileActionType.AddLine, |
| 321 | ComponentRef = FieldAsString(row, 7), |
| 322 | }; |
| 323 | |
| 324 | return symbol; |
| 325 | } |
| 326 | case "IniLocator": |
| 327 | { |
| 328 | var splitName = FieldAsString(row, 1).Split('|'); |
| 329 | |
| 330 | var symbol = new IniLocatorSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 331 | { |
| 332 | FileName = splitName.Length > 1 ? splitName[1] : splitName[0], |
| 333 | ShortFileName = splitName.Length > 1 ? splitName[0] : null, |
| 334 | Section = FieldAsString(row, 2), |
| 335 | Key = FieldAsString(row, 3), |
| 336 | Field = FieldAsInt(row, 4), |
| 337 | Type = FieldAsInt(row, 5), |
| 338 | }; |
| 339 | |
| 340 | return symbol; |
| 341 | } |
| 342 | case "LockPermissions": |
| 343 | return DefaultSymbolFromRow(typeof(LockPermissionsSymbol), row, columnZeroIsId: false); |
| 344 | case "Media": |
| 345 | { |
| 346 | var diskId = FieldAsInt(row, 0); |
| 347 | var symbol = new MediaSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, diskId)) |
| 348 | { |
| 349 | DiskId = diskId, |
| 350 | LastSequence = FieldAsNullableInt(row, 1), |
| 351 | DiskPrompt = FieldAsString(row, 2), |
| 352 | Cabinet = FieldAsString(row, 3), |
| 353 | VolumeLabel = FieldAsString(row, 4), |
| 354 | Source = FieldAsString(row, 5) |
| 355 | }; |
| 356 | |
| 357 | if (wixMediaByDiskId.TryGetValue(diskId, out var wixMediaRow)) |
| 358 | { |
| 359 | var compressionLevel = FieldAsString(wixMediaRow, 1); |
| 360 | |
| 361 | symbol.CompressionLevel = String.IsNullOrEmpty(compressionLevel) ? null : (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), compressionLevel, true); |
| 362 | symbol.Layout = wixMediaRow.Layout; |
| 363 | } |
| 364 | |
| 365 | return symbol; |
| 366 | } |
| 367 | case "MIME": |
| 368 | return DefaultSymbolFromRow(typeof(MIMESymbol), row, columnZeroIsId: false); |
| 369 | case "ModuleIgnoreTable": |
| 370 | return DefaultSymbolFromRow(typeof(ModuleIgnoreTableSymbol), row, columnZeroIsId: true); |
| 371 | case "MoveFile": |
| 372 | return DefaultSymbolFromRow(typeof(MoveFileSymbol), row, columnZeroIsId: true); |
| 373 | case "MsiAssembly": |
| 374 | { |
| 375 | var componentId = FieldAsString(row, 0); |
| 376 | if (componentsById.TryGetValue(componentId, out var componentRow)) |
| 377 | { |
| 378 | return new AssemblySymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(componentRow, 5))) |
| 379 | { |
| 380 | ComponentRef = componentId, |
| 381 | FeatureRef = FieldAsString(row, 1), |
| 382 | ManifestFileRef = FieldAsString(row, 2), |
| 383 | ApplicationFileRef = FieldAsString(row, 3), |
| 384 | Type = FieldAsNullableInt(row, 4) == 1 ? AssemblyType.Win32Assembly : AssemblyType.DotNetAssembly, |
| 385 | }; |
| 386 | } |
| 387 | |
| 388 | return null; |
| 389 | } |
| 390 | case "MsiLockPermissionsEx": |
| 391 | return DefaultSymbolFromRow(typeof(MsiLockPermissionsExSymbol), row, columnZeroIsId: true); |
| 392 | case "MsiShortcutProperty": |
| 393 | return DefaultSymbolFromRow(typeof(MsiShortcutPropertySymbol), row, columnZeroIsId: true); |
| 394 | case "ODBCDataSource": |
| 395 | return DefaultSymbolFromRow(typeof(ODBCDataSourceSymbol), row, columnZeroIsId: true); |
| 396 | case "ODBCDriver": |
| 397 | return DefaultSymbolFromRow(typeof(ODBCDriverSymbol), row, columnZeroIsId: true); |
| 398 | case "ODBCTranslator": |
| 399 | return DefaultSymbolFromRow(typeof(ODBCTranslatorSymbol), row, columnZeroIsId: true); |
| 400 | case "ProgId": |
| 401 | return DefaultSymbolFromRow(typeof(ProgIdSymbol), row, columnZeroIsId: false); |
| 402 | case "Property": |
| 403 | return DefaultSymbolFromRow(typeof(PropertySymbol), row, columnZeroIsId: true); |
| 404 | case "PublishComponent": |
| 405 | return DefaultSymbolFromRow(typeof(PublishComponentSymbol), row, columnZeroIsId: false); |
| 406 | case "Registry": |
| 407 | { |
| 408 | var value = FieldAsString(row, 4); |
| 409 | var valueType = RegistryValueType.String; |
| 410 | var valueAction = RegistryValueActionType.Write; |
| 411 | |
| 412 | if (!String.IsNullOrEmpty(value)) |
| 413 | { |
| 414 | if (value.StartsWith("#x", StringComparison.Ordinal)) |
| 415 | { |
| 416 | valueType = RegistryValueType.Binary; |
| 417 | value = value.Substring(2); |
| 418 | } |
| 419 | else if (value.StartsWith("#%", StringComparison.Ordinal)) |
| 420 | { |
| 421 | valueType = RegistryValueType.Expandable; |
| 422 | value = value.Substring(2); |
| 423 | } |
| 424 | else if (value.StartsWith("#", StringComparison.Ordinal)) |
| 425 | { |
| 426 | valueType = RegistryValueType.Integer; |
| 427 | value = value.Substring(1); |
| 428 | } |
| 429 | else if (value.StartsWith("[~]", StringComparison.Ordinal) && value.EndsWith("[~]", StringComparison.Ordinal)) |
| 430 | { |
| 431 | value = value.Substring(3, value.Length - 6); |
| 432 | valueType = RegistryValueType.MultiString; |
| 433 | valueAction = RegistryValueActionType.Write; |
| 434 | } |
| 435 | else if (value.StartsWith("[~]", StringComparison.Ordinal)) |
| 436 | { |
| 437 | value = value.Substring(3); |
| 438 | valueType = RegistryValueType.MultiString; |
| 439 | valueAction = RegistryValueActionType.Append; |
| 440 | } |
| 441 | else if (value.EndsWith("[~]", StringComparison.Ordinal)) |
| 442 | { |
| 443 | value = value.Substring(0, value.Length - 3); |
| 444 | valueType = RegistryValueType.MultiString; |
| 445 | valueAction = RegistryValueActionType.Prepend; |
| 446 | } |
| 447 | } |
| 448 | |
| 449 | return new RegistrySymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 450 | { |
| 451 | Root = (RegistryRootType)FieldAsInt(row, 1), |
| 452 | Key = FieldAsString(row, 2), |
| 453 | Name = FieldAsString(row, 3), |
| 454 | Value = value, |
| 455 | ComponentRef = FieldAsString(row, 5), |
| 456 | ValueAction = valueAction, |
| 457 | ValueType = valueType, |
| 458 | }; |
| 459 | } |
| 460 | case "RegLocator": |
| 461 | { |
| 462 | var type = FieldAsInt(row, 4); |
| 463 | |
| 464 | return new RegLocatorSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 465 | { |
| 466 | Root = (RegistryRootType)FieldAsInt(row, 1), |
| 467 | Key = FieldAsString(row, 2), |
| 468 | Name = FieldAsString(row, 3), |
| 469 | Type = (RegLocatorType)(type & 0xF), |
| 470 | Win64 = (type & WindowsInstallerConstants.MsidbLocatorType64bit) == WindowsInstallerConstants.MsidbLocatorType64bit |
| 471 | }; |
| 472 | } |
| 473 | case "RemoveFile": |
| 474 | { |
| 475 | var splitName = FieldAsString(row, 2).Split('|'); |
| 476 | var installMode = FieldAsInt(row, 4); |
| 477 | |
| 478 | return new RemoveFileSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 479 | { |
| 480 | ComponentRef = FieldAsString(row, 1), |
| 481 | FileName = splitName.Length > 1 ? splitName[1] : splitName[0], |
| 482 | ShortFileName = splitName.Length > 1 ? splitName[0] : null, |
| 483 | DirPropertyRef = FieldAsString(row, 3), |
| 484 | OnInstall = (installMode & WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall) == WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall ? (bool?)true : null, |
| 485 | OnUninstall = (installMode & WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove) == WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove ? (bool?)true : null |
| 486 | }; |
| 487 | } |
| 488 | case "RemoveRegistry": |
| 489 | { |
| 490 | return new RemoveRegistrySymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 491 | { |
| 492 | Action = RemoveRegistryActionType.RemoveOnInstall, |
| 493 | Root = (RegistryRootType)FieldAsInt(row, 1), |
| 494 | Key = FieldAsString(row, 2), |
| 495 | Name = FieldAsString(row, 3), |
| 496 | ComponentRef = FieldAsString(row, 4), |
| 497 | }; |
| 498 | } |
| 499 | |
| 500 | case "ReserveCost": |
| 501 | return DefaultSymbolFromRow(typeof(ReserveCostSymbol), row, columnZeroIsId: true); |
| 502 | case "SelfReg": |
| 503 | return null; |
| 504 | case "ServiceControl": |
| 505 | { |
| 506 | var events = FieldAsInt(row, 2); |
| 507 | var wait = FieldAsNullableInt(row, 4); |
| 508 | return new ServiceControlSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 509 | { |
| 510 | Name = FieldAsString(row, 1), |
| 511 | Arguments = FieldAsString(row, 3), |
| 512 | Wait = !wait.HasValue || wait.Value == 1, |
| 513 | ComponentRef = FieldAsString(row, 5), |
| 514 | InstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventDelete) == WindowsInstallerConstants.MsidbServiceControlEventDelete, |
| 515 | UninstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete) == WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete, |
| 516 | InstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventStart) == WindowsInstallerConstants.MsidbServiceControlEventStart, |
| 517 | UninstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStart) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStart, |
| 518 | InstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventStop) == WindowsInstallerConstants.MsidbServiceControlEventStop, |
| 519 | UninstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStop) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStop, |
| 520 | }; |
| 521 | } |
| 522 | |
| 523 | case "ServiceInstall": |
| 524 | return DefaultSymbolFromRow(typeof(ServiceInstallSymbol), row, columnZeroIsId: true); |
| 525 | case "Shortcut": |
| 526 | { |
| 527 | var splitName = FieldAsString(row, 2).Split('|'); |
| 528 | |
| 529 | return new ShortcutSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 530 | { |
| 531 | DirectoryRef = FieldAsString(row, 1), |
| 532 | Name = splitName.Length > 1 ? splitName[1] : splitName[0], |
| 533 | ShortName = splitName.Length > 1 ? splitName[0] : null, |
| 534 | ComponentRef = FieldAsString(row, 3), |
| 535 | Target = FieldAsString(row, 4), |
| 536 | Arguments = FieldAsString(row, 5), |
| 537 | Description = FieldAsString(row, 6), |
| 538 | Hotkey = FieldAsNullableInt(row, 7), |
| 539 | IconRef = FieldAsString(row, 8), |
| 540 | IconIndex = FieldAsNullableInt(row, 9), |
| 541 | Show = (ShortcutShowType?)FieldAsNullableInt(row, 10), |
| 542 | WorkingDirectory = FieldAsString(row, 11), |
| 543 | DisplayResourceDll = FieldAsString(row, 12), |
| 544 | DisplayResourceId = FieldAsNullableInt(row, 13), |
| 545 | DescriptionResourceDll = FieldAsString(row, 14), |
| 546 | DescriptionResourceId= FieldAsNullableInt(row, 15), |
| 547 | }; |
| 548 | } |
| 549 | case "Signature": |
| 550 | return DefaultSymbolFromRow(typeof(SignatureSymbol), row, columnZeroIsId: true); |
| 551 | case "UIText": |
| 552 | return DefaultSymbolFromRow(typeof(UITextSymbol), row, columnZeroIsId: true); |
| 553 | case "Upgrade": |
| 554 | { |
| 555 | var attributes = FieldAsInt(row, 4); |
| 556 | return new UpgradeSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Global, FieldAsString(row, 0))) |
| 557 | { |
| 558 | UpgradeCode = FieldAsString(row, 0), |
| 559 | VersionMin = FieldAsString(row, 1), |
| 560 | VersionMax = FieldAsString(row, 2), |
| 561 | Language = FieldAsString(row, 3), |
| 562 | Remove = FieldAsString(row, 5), |
| 563 | ActionProperty = FieldAsString(row, 6), |
| 564 | MigrateFeatures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures) == WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures, |
| 565 | OnlyDetect = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect, |
| 566 | IgnoreRemoveFailures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure) == WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure, |
| 567 | VersionMinInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive, |
| 568 | VersionMaxInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive, |
| 569 | ExcludeLanguages = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive, |
| 570 | }; |
| 571 | } |
| 572 | case "Verb": |
| 573 | return DefaultSymbolFromRow(typeof(VerbSymbol), row, columnZeroIsId: false); |
| 574 | case "WixAction": |
| 575 | { |
| 576 | var sequenceTable = FieldAsString(row, 0); |
| 577 | return new WixActionSymbol(SourceLineNumber4(row.SourceLineNumbers)) |
| 578 | { |
| 579 | SequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), sequenceTable == "AdvtExecuteSequence" ? nameof(SequenceTable.AdvertiseExecuteSequence) : sequenceTable), |
| 580 | Action = FieldAsString(row, 1), |
| 581 | Condition = FieldAsString(row, 2), |
| 582 | Sequence = FieldAsNullableInt(row, 3), |
| 583 | Before = FieldAsString(row, 4), |
| 584 | After = FieldAsString(row, 5), |
| 585 | Overridable = FieldAsNullableInt(row, 6) != 0, |
| 586 | }; |
| 587 | } |
| 588 | case "WixBootstrapperApplication": |
| 589 | return DefaultSymbolFromRow(typeof(WixBootstrapperApplicationSymbol), row, columnZeroIsId: true); |
| 590 | case "WixBundleContainer": |
| 591 | return DefaultSymbolFromRow(typeof(WixBundleContainerSymbol), row, columnZeroIsId: true); |
| 592 | case "WixBundleVariable": |
| 593 | return DefaultSymbolFromRow(typeof(WixBundleVariableSymbol), row, columnZeroIsId: true); |
| 594 | case "WixChainItem": |
| 595 | return DefaultSymbolFromRow(typeof(WixChainItemSymbol), row, columnZeroIsId: true); |
| 596 | case "WixComponentGroup": |
| 597 | return DefaultSymbolFromRow(typeof(WixComponentGroupSymbol), row, columnZeroIsId: true); |
| 598 | case "WixCustomTable": |
| 599 | return DefaultSymbolFromRow(typeof(WixCustomTableSymbol), row, columnZeroIsId: true); |
| 600 | case "WixDirectory": |
| 601 | return null; |
| 602 | case "WixFile": |
| 603 | return null; |
| 604 | case "WixInstanceTransforms": |
| 605 | return DefaultSymbolFromRow(typeof(WixInstanceTransformsSymbol), row, columnZeroIsId: true); |
| 606 | case "WixMedia": |
| 607 | return null; |
| 608 | case "WixMerge": |
| 609 | return DefaultSymbolFromRow(typeof(WixMergeSymbol), row, columnZeroIsId: true); |
| 610 | case "WixPatchBaseline": |
| 611 | return DefaultSymbolFromRow(typeof(WixPatchBaselineSymbol), row, columnZeroIsId: true); |
| 612 | case "WixProperty": |
| 613 | { |
| 614 | var attributes = FieldAsInt(row, 1); |
| 615 | return new WixPropertySymbol(SourceLineNumber4(row.SourceLineNumbers)) |
| 616 | { |
| 617 | PropertyRef = FieldAsString(row, 0), |
| 618 | Admin = (attributes & 0x1) == 0x1, |
| 619 | Hidden = (attributes & 0x2) == 0x2, |
| 620 | Secure = (attributes & 0x4) == 0x4, |
| 621 | }; |
| 622 | } |
| 623 | case "WixSuppressModularization": |
| 624 | { |
| 625 | return new WixSuppressModularizationSymbol(SourceLineNumber4(row.SourceLineNumbers)) |
| 626 | { |
| 627 | SuppressIdentifier = FieldAsString(row, 0) |
| 628 | }; |
| 629 | } |
| 630 | case "WixUI": |
| 631 | return DefaultSymbolFromRow(typeof(WixUISymbol), row, columnZeroIsId: true); |
| 632 | case "WixVariable": |
| 633 | return DefaultSymbolFromRow(typeof(WixVariableSymbol), row, columnZeroIsId: true); |
| 634 | default: |
| 635 | return GenericSymbolFromCustomRow(row, columnZeroIsId: false); |
| 636 | } |
| 637 | } |
| 638 | |
| 639 | private static CustomActionTargetType DetermineCustomActionTargetType(int type) |
| 640 | { |
| 641 | var targetType = default(CustomActionTargetType); |
| 642 | |
| 643 | if ((type & WindowsInstallerConstants.MsidbCustomActionTypeVBScript) == WindowsInstallerConstants.MsidbCustomActionTypeVBScript) |
| 644 | { |
| 645 | targetType = CustomActionTargetType.VBScript; |
| 646 | } |
| 647 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeJScript) == WindowsInstallerConstants.MsidbCustomActionTypeJScript) |
| 648 | { |
| 649 | targetType = CustomActionTargetType.JScript; |
| 650 | } |
| 651 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeTextData) == WindowsInstallerConstants.MsidbCustomActionTypeTextData) |
| 652 | { |
| 653 | targetType = CustomActionTargetType.TextData; |
| 654 | } |
| 655 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeExe) == WindowsInstallerConstants.MsidbCustomActionTypeExe) |
| 656 | { |
| 657 | targetType = CustomActionTargetType.Exe; |
| 658 | } |
| 659 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeDll) == WindowsInstallerConstants.MsidbCustomActionTypeDll) |
| 660 | { |
| 661 | targetType = CustomActionTargetType.Dll; |
| 662 | } |
| 663 | |
| 664 | return targetType; |
| 665 | } |
| 666 | |
| 667 | private static CustomActionSourceType DetermineCustomActionSourceType(int type) |
| 668 | { |
| 669 | var sourceType = CustomActionSourceType.Binary; |
| 670 | |
| 671 | if ((type & WindowsInstallerConstants.MsidbCustomActionTypeProperty) == WindowsInstallerConstants.MsidbCustomActionTypeProperty) |
| 672 | { |
| 673 | sourceType = CustomActionSourceType.Property; |
| 674 | } |
| 675 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeDirectory) == WindowsInstallerConstants.MsidbCustomActionTypeDirectory) |
| 676 | { |
| 677 | sourceType = CustomActionSourceType.Directory; |
| 678 | } |
| 679 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeSourceFile) == WindowsInstallerConstants.MsidbCustomActionTypeSourceFile) |
| 680 | { |
| 681 | sourceType = CustomActionSourceType.File; |
| 682 | } |
| 683 | |
| 684 | return sourceType; |
| 685 | } |
| 686 | |
| 687 | private static CustomActionExecutionType DetermineCustomActionExecutionType(int type) |
| 688 | { |
| 689 | var executionType = CustomActionExecutionType.Immediate; |
| 690 | |
| 691 | if ((type & (WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeCommit)) == (WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeCommit)) |
| 692 | { |
| 693 | executionType = CustomActionExecutionType.Commit; |
| 694 | } |
| 695 | else if ((type & (WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeRollback)) == (WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeRollback)) |
| 696 | { |
| 697 | executionType = CustomActionExecutionType.Rollback; |
| 698 | } |
| 699 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeInScript) == WindowsInstallerConstants.MsidbCustomActionTypeInScript) |
| 700 | { |
| 701 | executionType = CustomActionExecutionType.Deferred; |
| 702 | } |
| 703 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeClientRepeat) == WindowsInstallerConstants.MsidbCustomActionTypeClientRepeat) |
| 704 | { |
| 705 | executionType = CustomActionExecutionType.ClientRepeat; |
| 706 | } |
| 707 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeOncePerProcess) == WindowsInstallerConstants.MsidbCustomActionTypeOncePerProcess) |
| 708 | { |
| 709 | executionType = CustomActionExecutionType.OncePerProcess; |
| 710 | } |
| 711 | else if ((type & WindowsInstallerConstants.MsidbCustomActionTypeFirstSequence) == WindowsInstallerConstants.MsidbCustomActionTypeFirstSequence) |
| 712 | { |
| 713 | executionType = CustomActionExecutionType.FirstSequence; |
| 714 | } |
| 715 | |
| 716 | return executionType; |
| 717 | } |
| 718 | |
| 719 | private static IntermediateFieldType ColumnType3ToIntermediateFieldType4(Wix3.ColumnType columnType) |
| 720 | { |
| 721 | switch (columnType) |
| 722 | { |
| 723 | case Wix3.ColumnType.Number: |
| 724 | return IntermediateFieldType.Number; |
| 725 | case Wix3.ColumnType.Object: |
| 726 | return IntermediateFieldType.Path; |
| 727 | case Wix3.ColumnType.Unknown: |
| 728 | case Wix3.ColumnType.String: |
| 729 | case Wix3.ColumnType.Localized: |
| 730 | case Wix3.ColumnType.Preserved: |
| 731 | default: |
| 732 | return IntermediateFieldType.String; |
| 733 | } |
| 734 | } |
| 735 | |
| 736 | private static IntermediateSymbol DefaultSymbolFromRow(Type symbolType, Wix3.Row row, bool columnZeroIsId) |
| 737 | { |
| 738 | var id = columnZeroIsId ? GetIdentifierForRow(row) : null; |
| 739 | |
| 740 | var createSymbol = symbolType.GetConstructor(new[] { typeof(SourceLineNumber), typeof(Identifier) }); |
| 741 | var symbol = (IntermediateSymbol)createSymbol.Invoke(new object[] { SourceLineNumber4(row.SourceLineNumbers), id }); |
| 742 | |
| 743 | SetSymbolFieldsFromRow(row, symbol, columnZeroIsId); |
| 744 | |
| 745 | return symbol; |
| 746 | } |
| 747 | |
| 748 | private static IntermediateSymbol GenericSymbolFromCustomRow(Wix3.Row row, bool columnZeroIsId) |
| 749 | { |
| 750 | var columnDefinitions = row.Table.Definition.Columns.Cast<Wix3.ColumnDefinition>(); |
| 751 | var fieldDefinitions = columnDefinitions.Select(columnDefinition => |
| 752 | new IntermediateFieldDefinition(columnDefinition.Name, ColumnType3ToIntermediateFieldType4(columnDefinition.Type))).ToArray(); |
| 753 | var symbolDefinition = new IntermediateSymbolDefinition(row.Table.Name, fieldDefinitions, null); |
| 754 | |
| 755 | var id = columnZeroIsId ? GetIdentifierForRow(row) : null; |
| 756 | |
| 757 | var createSymbol = typeof(IntermediateSymbol).GetConstructor(new[] { typeof(IntermediateSymbolDefinition), typeof(SourceLineNumber), typeof(Identifier) }); |
| 758 | var symbol = (IntermediateSymbol)createSymbol.Invoke(new object[] { symbolDefinition, SourceLineNumber4(row.SourceLineNumbers), id }); |
| 759 | |
| 760 | SetSymbolFieldsFromRow(row, symbol, columnZeroIsId); |
| 761 | |
| 762 | return symbol; |
| 763 | } |
| 764 | |
| 765 | private static void SetSymbolFieldsFromRow(Wix3.Row row, IntermediateSymbol symbol, bool columnZeroIsId) |
| 766 | { |
| 767 | var offset = 0; |
| 768 | if (columnZeroIsId) |
| 769 | { |
| 770 | offset = 1; |
| 771 | } |
| 772 | |
| 773 | for (var i = offset; i < row.Fields.Length; ++i) |
| 774 | { |
| 775 | var column = row.Fields[i].Column; |
| 776 | switch (column.Type) |
| 777 | { |
| 778 | case Wix3.ColumnType.String: |
| 779 | case Wix3.ColumnType.Localized: |
| 780 | case Wix3.ColumnType.Object: |
| 781 | case Wix3.ColumnType.Preserved: |
| 782 | symbol.Set(i - offset, FieldAsString(row, i)); |
| 783 | break; |
| 784 | case Wix3.ColumnType.Number: |
| 785 | int? nullableValue = FieldAsNullableInt(row, i); |
| 786 | // TODO: Consider whether null values should be coerced to their default value when |
| 787 | // a column is not nullable. For now, just pass through the null. |
| 788 | //int value = FieldAsInt(row, i); |
| 789 | //symbol.Set(i - offset, column.IsNullable ? nullableValue : value); |
| 790 | symbol.Set(i - offset, nullableValue); |
| 791 | break; |
| 792 | case Wix3.ColumnType.Unknown: |
| 793 | break; |
| 794 | } |
| 795 | } |
| 796 | } |
| 797 | |
| 798 | private static Identifier GetIdentifierForRow(Wix3.Row row) |
| 799 | { |
| 800 | var column = row.Fields[0].Column; |
| 801 | switch (column.Type) |
| 802 | { |
| 803 | case Wix3.ColumnType.String: |
| 804 | case Wix3.ColumnType.Localized: |
| 805 | case Wix3.ColumnType.Object: |
| 806 | case Wix3.ColumnType.Preserved: |
| 807 | return new Identifier(AccessModifier.Global, (string)row.Fields[0].Data); |
| 808 | case Wix3.ColumnType.Number: |
| 809 | return new Identifier(AccessModifier.Global, FieldAsInt(row, 0)); |
| 810 | default: |
| 811 | return null; |
| 812 | } |
| 813 | } |
| 814 | |
| 815 | private static SectionType OutputType3ToSectionType4(Wix3.OutputType outputType) |
| 816 | { |
| 817 | switch (outputType) |
| 818 | { |
| 819 | case Wix3.OutputType.Bundle: |
| 820 | return SectionType.Bundle; |
| 821 | case Wix3.OutputType.Module: |
| 822 | return SectionType.Module; |
| 823 | case Wix3.OutputType.Patch: |
| 824 | return SectionType.Patch; |
| 825 | case Wix3.OutputType.PatchCreation: |
| 826 | return SectionType.PatchCreation; |
| 827 | case Wix3.OutputType.Product: |
| 828 | return SectionType.Package; |
| 829 | case Wix3.OutputType.Transform: |
| 830 | case Wix3.OutputType.Unknown: |
| 831 | default: |
| 832 | return SectionType.Unknown; |
| 833 | } |
| 834 | } |
| 835 | |
| 836 | private static SourceLineNumber SourceLineNumber4(Wix3.SourceLineNumberCollection source) |
| 837 | { |
| 838 | return String.IsNullOrEmpty(source?.EncodedSourceLineNumbers) ? null : SourceLineNumber.CreateFromEncoded(source.EncodedSourceLineNumbers); |
| 839 | } |
| 840 | |
| 841 | private static string FieldAsString(Wix3.Row row, int column) |
| 842 | { |
| 843 | return (string)row[column]; |
| 844 | } |
| 845 | |
| 846 | private static int FieldAsInt(Wix3.Row row, int column) |
| 847 | { |
| 848 | return Convert.ToInt32(row[column]); |
| 849 | } |
| 850 | |
| 851 | private static int? FieldAsNullableInt(Wix3.Row row, int column) |
| 852 | { |
| 853 | var field = row.Fields[column]; |
| 854 | if (field.Data == null) |
| 855 | { |
| 856 | return null; |
| 857 | } |
| 858 | else |
| 859 | { |
| 860 | return Convert.ToInt32(field.Data); |
| 861 | } |
| 862 | } |
| 863 | |
| 864 | private static string[] SplitDefaultDir(string defaultDir) |
| 865 | { |
| 866 | var split1 = defaultDir.Split(':'); |
| 867 | var targetSplit = split1.Length > 1 ? split1[1].Split('|') : split1[0].Split('|'); |
| 868 | var sourceSplit = split1.Length > 1 ? split1[0].Split('|') : new[] { String.Empty }; |
| 869 | return new[] |
| 870 | { |
| 871 | targetSplit.Length > 1 ? targetSplit[1] : targetSplit[0], |
| 872 | targetSplit.Length > 1 ? targetSplit[0] : null, |
| 873 | sourceSplit.Length > 1 ? sourceSplit[1] : sourceSplit[0], |
| 874 | sourceSplit.Length > 1 ? sourceSplit[0] : null |
| 875 | }; |
| 876 | } |
| 877 | } |
| 878 | } |