From 85e611c40c3c8bf3ff3b06b52d53d046bc8ff392 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 2 Mar 2021 01:49:28 -0800 Subject: Remove references to "Output" and use "Data" instead --- .../CreateWindowsInstallerDataFromIRCommand.cs | 1256 ++++++++++++++++++++ 1 file changed, 1256 insertions(+) create mode 100644 src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs (limited to 'src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs') diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs new file mode 100644 index 00000000..dc60a9ac --- /dev/null +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs @@ -0,0 +1,1256 @@ +// 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. + +namespace WixToolset.Core.WindowsInstaller.Bind +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Security.Cryptography; + using System.Text; + using WixToolset.Data; + using WixToolset.Data.Symbols; + using WixToolset.Data.WindowsInstaller; + using WixToolset.Data.WindowsInstaller.Rows; + using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; + + internal class CreateWindowsInstallerDataFromIRCommand + { + public CreateWindowsInstallerDataFromIRCommand(IMessaging messaging, IntermediateSection section, TableDefinitionCollection tableDefinitions, IEnumerable backendExtensions, IWindowsInstallerBackendHelper backendHelper) + { + this.Messaging = messaging; + this.Section = section; + this.TableDefinitions = tableDefinitions; + this.BackendExtensions = backendExtensions; + this.BackendHelper = backendHelper; + } + + private IEnumerable BackendExtensions { get; } + + private IWindowsInstallerBackendHelper BackendHelper { get; } + + private IMessaging Messaging { get; } + + private TableDefinitionCollection TableDefinitions { get; } + + private IntermediateSection Section { get; } + + public WindowsInstallerData Data { get; private set; } + + public WindowsInstallerData Execute() + { + this.Data = new WindowsInstallerData(this.Section.Symbols.First().SourceLineNumbers) + { + Codepage = this.Section.Codepage, + Type = SectionTypeToOutputType(this.Section.Type) + }; + + this.AddSectionToData(); + + return this.Data; + } + + private void AddSectionToData() + { + var cellsByTableAndRowId = new Dictionary>(); + + foreach (var symbol in this.Section.Symbols) + { + var unknownSymbol = false; + switch (symbol.Definition.Type) + { + case SymbolDefinitionType.AppSearch: + this.AddSymbolDefaultly(symbol); + this.Data.EnsureTable(this.TableDefinitions["Signature"]); + break; + + case SymbolDefinitionType.Assembly: + this.AddAssemblySymbol((AssemblySymbol)symbol); + break; + + case SymbolDefinitionType.BBControl: + this.AddBBControlSymbol((BBControlSymbol)symbol); + break; + + case SymbolDefinitionType.Class: + this.AddClassSymbol((ClassSymbol)symbol); + break; + + case SymbolDefinitionType.Control: + this.AddControlSymbol((ControlSymbol)symbol); + break; + + case SymbolDefinitionType.ControlEvent: + this.AddControlEventSymbol((ControlEventSymbol)symbol); + break; + + case SymbolDefinitionType.Component: + this.AddComponentSymbol((ComponentSymbol)symbol); + break; + + case SymbolDefinitionType.CustomAction: + this.AddCustomActionSymbol((CustomActionSymbol)symbol); + break; + + case SymbolDefinitionType.Dialog: + this.AddDialogSymbol((DialogSymbol)symbol); + break; + + case SymbolDefinitionType.Directory: + this.AddDirectorySymbol((DirectorySymbol)symbol); + break; + + case SymbolDefinitionType.DuplicateFile: + this.AddDuplicateFileSymbol((DuplicateFileSymbol)symbol); + break; + + case SymbolDefinitionType.Environment: + this.AddEnvironmentSymbol((EnvironmentSymbol)symbol); + break; + + case SymbolDefinitionType.Error: + this.AddErrorSymbol((ErrorSymbol)symbol); + break; + + case SymbolDefinitionType.Feature: + this.AddFeatureSymbol((FeatureSymbol)symbol); + break; + + case SymbolDefinitionType.File: + this.AddFileSymbol((FileSymbol)symbol); + break; + + case SymbolDefinitionType.IniFile: + this.AddIniFileSymbol((IniFileSymbol)symbol); + break; + + case SymbolDefinitionType.IniLocator: + this.AddIniLocatorSymbol((IniLocatorSymbol)symbol); + break; + + case SymbolDefinitionType.Media: + this.AddMediaSymbol((MediaSymbol)symbol); + break; + + case SymbolDefinitionType.ModuleConfiguration: + this.AddModuleConfigurationSymbol((ModuleConfigurationSymbol)symbol); + break; + + case SymbolDefinitionType.MsiEmbeddedUI: + this.AddMsiEmbeddedUISymbol((MsiEmbeddedUISymbol)symbol); + break; + + case SymbolDefinitionType.MsiServiceConfig: + this.AddMsiServiceConfigSymbol((MsiServiceConfigSymbol)symbol); + break; + + case SymbolDefinitionType.MsiServiceConfigFailureActions: + this.AddMsiServiceConfigFailureActionsSymbol((MsiServiceConfigFailureActionsSymbol)symbol); + break; + + case SymbolDefinitionType.MoveFile: + this.AddMoveFileSymbol((MoveFileSymbol)symbol); + break; + + case SymbolDefinitionType.ProgId: + this.AddSymbolDefaultly(symbol); + this.Data.EnsureTable(this.TableDefinitions["Extension"]); + break; + + case SymbolDefinitionType.Property: + this.AddPropertySymbol((PropertySymbol)symbol); + break; + + case SymbolDefinitionType.RemoveFile: + this.AddRemoveFileSymbol((RemoveFileSymbol)symbol); + break; + + case SymbolDefinitionType.Registry: + this.AddRegistrySymbol((RegistrySymbol)symbol); + break; + + case SymbolDefinitionType.RegLocator: + this.AddRegLocatorSymbol((RegLocatorSymbol)symbol); + break; + + case SymbolDefinitionType.RemoveRegistry: + this.AddRemoveRegistrySymbol((RemoveRegistrySymbol)symbol); + break; + + case SymbolDefinitionType.ServiceControl: + this.AddServiceControlSymbol((ServiceControlSymbol)symbol); + break; + + case SymbolDefinitionType.ServiceInstall: + this.AddServiceInstallSymbol((ServiceInstallSymbol)symbol); + break; + + case SymbolDefinitionType.Shortcut: + this.AddShortcutSymbol((ShortcutSymbol)symbol); + break; + + case SymbolDefinitionType.TextStyle: + this.AddTextStyleSymbol((TextStyleSymbol)symbol); + break; + + case SymbolDefinitionType.Upgrade: + this.AddUpgradeSymbol((UpgradeSymbol)symbol); + break; + + case SymbolDefinitionType.WixAction: + this.AddWixActionSymbol((WixActionSymbol)symbol); + break; + + case SymbolDefinitionType.WixCustomTableCell: + this.IndexCustomTableCellSymbol((WixCustomTableCellSymbol)symbol, cellsByTableAndRowId); + break; + + case SymbolDefinitionType.WixEnsureTable: + this.AddWixEnsureTableSymbol((WixEnsureTableSymbol)symbol); + break; + + // Symbols used internally and are not added to the output. + case SymbolDefinitionType.WixBuildInfo: + case SymbolDefinitionType.WixBindUpdatedFiles: + case SymbolDefinitionType.WixComponentGroup: + case SymbolDefinitionType.WixComplexReference: + case SymbolDefinitionType.WixDeltaPatchFile: + case SymbolDefinitionType.WixDeltaPatchSymbolPaths: + case SymbolDefinitionType.WixFragment: + case SymbolDefinitionType.WixFeatureGroup: + case SymbolDefinitionType.WixInstanceComponent: + case SymbolDefinitionType.WixInstanceTransforms: + case SymbolDefinitionType.WixFeatureModules: + case SymbolDefinitionType.WixGroup: + case SymbolDefinitionType.WixMediaTemplate: + case SymbolDefinitionType.WixMerge: + case SymbolDefinitionType.WixOrdering: + case SymbolDefinitionType.WixPatchBaseline: + case SymbolDefinitionType.WixPatchFamilyGroup: + case SymbolDefinitionType.WixPatchId: + case SymbolDefinitionType.WixPatchRef: + case SymbolDefinitionType.WixPatchTarget: + case SymbolDefinitionType.WixProperty: + case SymbolDefinitionType.WixProductTag: + case SymbolDefinitionType.WixSimpleReference: + case SymbolDefinitionType.WixSuppressAction: + case SymbolDefinitionType.WixSuppressModularization: + case SymbolDefinitionType.WixUI: + case SymbolDefinitionType.WixVariable: + break; + + // Already processed by LoadTableDefinitions. + case SymbolDefinitionType.WixCustomTable: + case SymbolDefinitionType.WixCustomTableColumn: + break; + + case SymbolDefinitionType.MustBeFromAnExtension: + unknownSymbol = !this.AddSymbolFromExtension(symbol); + break; + + default: + unknownSymbol = !this.AddSymbolDefaultly(symbol); + break; + } + + if (unknownSymbol) + { + this.Messaging.Write(WarningMessages.SymbolNotTranslatedToOutput(symbol)); + } + } + + this.AddIndexedCellSymbols(cellsByTableAndRowId); + } + + private void AddAssemblySymbol(AssemblySymbol symbol) + { + var attributes = symbol.Type == AssemblyType.Win32Assembly ? 1 : (int?)null; + + var row = this.CreateRow(symbol, "MsiAssembly"); + row[0] = symbol.ComponentRef; + row[1] = symbol.FeatureRef; + row[2] = symbol.ManifestFileRef; + row[3] = symbol.ApplicationFileRef; + row[4] = attributes; + } + + private void AddBBControlSymbol(BBControlSymbol symbol) + { + var attributes = symbol.Attributes; + attributes |= symbol.Enabled ? WindowsInstallerConstants.MsidbControlAttributesEnabled : 0; + attributes |= symbol.Indirect ? WindowsInstallerConstants.MsidbControlAttributesIndirect : 0; + attributes |= symbol.Integer ? WindowsInstallerConstants.MsidbControlAttributesInteger : 0; + attributes |= symbol.LeftScroll ? WindowsInstallerConstants.MsidbControlAttributesLeftScroll : 0; + attributes |= symbol.RightAligned ? WindowsInstallerConstants.MsidbControlAttributesRightAligned : 0; + attributes |= symbol.RightToLeft ? WindowsInstallerConstants.MsidbControlAttributesRTLRO : 0; + attributes |= symbol.Sunken ? WindowsInstallerConstants.MsidbControlAttributesSunken : 0; + attributes |= symbol.Visible ? WindowsInstallerConstants.MsidbControlAttributesVisible : 0; + + var row = this.CreateRow(symbol, "BBControl"); + row[0] = symbol.BillboardRef; + row[1] = symbol.BBControl; + row[2] = symbol.Type; + row[3] = symbol.X; + row[4] = symbol.Y; + row[5] = symbol.Width; + row[6] = symbol.Height; + row[7] = attributes; + row[8] = symbol.Text; + } + + private void AddClassSymbol(ClassSymbol symbol) + { + var row = this.CreateRow(symbol, "Class"); + row[0] = symbol.CLSID; + row[1] = symbol.Context; + row[2] = symbol.ComponentRef; + row[3] = symbol.DefaultProgIdRef; + row[4] = symbol.Description; + row[5] = symbol.AppIdRef; + row[6] = symbol.FileTypeMask; + row[7] = symbol.IconRef; + row[8] = symbol.IconIndex; + row[9] = symbol.DefInprocHandler; + row[10] = symbol.Argument; + row[11] = symbol.FeatureRef; + row[12] = symbol.RelativePath ? (int?)1 : null; + } + + private void AddControlSymbol(ControlSymbol symbol) + { + var text = symbol.Text; + var attributes = symbol.Attributes; + attributes |= symbol.Enabled ? WindowsInstallerConstants.MsidbControlAttributesEnabled : 0; + attributes |= symbol.Indirect ? WindowsInstallerConstants.MsidbControlAttributesIndirect : 0; + attributes |= symbol.Integer ? WindowsInstallerConstants.MsidbControlAttributesInteger : 0; + attributes |= symbol.LeftScroll ? WindowsInstallerConstants.MsidbControlAttributesLeftScroll : 0; + attributes |= symbol.RightAligned ? WindowsInstallerConstants.MsidbControlAttributesRightAligned : 0; + attributes |= symbol.RightToLeft ? WindowsInstallerConstants.MsidbControlAttributesRTLRO : 0; + attributes |= symbol.Sunken ? WindowsInstallerConstants.MsidbControlAttributesSunken : 0; + attributes |= symbol.Visible ? WindowsInstallerConstants.MsidbControlAttributesVisible : 0; + + // If we're tracking disk space, and this is a non-FormatSize Text control, + // and the text attribute starts with '[' and ends with ']', add a space. + // It is not necessary for the whole string to be a property, just those + // two characters matter. + if (symbol.TrackDiskSpace && + "Text" == symbol.Type && + WindowsInstallerConstants.MsidbControlAttributesFormatSize != (attributes & WindowsInstallerConstants.MsidbControlAttributesFormatSize) && + null != text && text.StartsWith("[", StringComparison.Ordinal) && text.EndsWith("]", StringComparison.Ordinal)) + { + text = String.Concat(text, " "); + } + + var row = this.CreateRow(symbol, "Control"); + row[0] = symbol.DialogRef; + row[1] = symbol.Control; + row[2] = symbol.Type; + row[3] = symbol.X; + row[4] = symbol.Y; + row[5] = symbol.Width; + row[6] = symbol.Height; + row[7] = attributes; + row[8] = symbol.Property; + row[9] = text; + row[10] = symbol.NextControlRef; + row[11] = symbol.Help; + } + + private void AddControlEventSymbol(ControlEventSymbol symbol) + { + var row = this.CreateRow(symbol, "ControlEvent"); + row[0] = symbol.DialogRef; + row[1] = symbol.ControlRef; + row[2] = symbol.Event; + row[3] = symbol.Argument; + row[4] = String.IsNullOrEmpty(symbol.Condition) ? "1" : symbol.Condition; + row[5] = symbol.Ordering; + } + + private void AddComponentSymbol(ComponentSymbol symbol) + { + var attributes = ComponentLocation.Either == symbol.Location ? WindowsInstallerConstants.MsidbComponentAttributesOptional : 0; + attributes |= ComponentLocation.SourceOnly == symbol.Location ? WindowsInstallerConstants.MsidbComponentAttributesSourceOnly : 0; + attributes |= ComponentKeyPathType.Registry == symbol.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath : 0; + attributes |= ComponentKeyPathType.OdbcDataSource == symbol.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource : 0; + attributes |= symbol.DisableRegistryReflection ? WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection : 0; + attributes |= symbol.NeverOverwrite ? WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite : 0; + attributes |= symbol.Permanent ? WindowsInstallerConstants.MsidbComponentAttributesPermanent : 0; + attributes |= symbol.SharedDllRefCount ? WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount : 0; + attributes |= symbol.Shared ? WindowsInstallerConstants.MsidbComponentAttributesShared : 0; + attributes |= symbol.Transitive ? WindowsInstallerConstants.MsidbComponentAttributesTransitive : 0; + attributes |= symbol.UninstallWhenSuperseded ? WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence : 0; + attributes |= symbol.Win64 ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0; + + var row = this.CreateRow(symbol, "Component"); + row[0] = symbol.Id.Id; + row[1] = symbol.ComponentId; + row[2] = symbol.DirectoryRef; + row[3] = attributes; + row[4] = symbol.Condition; + row[5] = symbol.KeyPath; + } + + private void AddCustomActionSymbol(CustomActionSymbol symbol) + { + var type = symbol.Win64 ? WindowsInstallerConstants.MsidbCustomActionType64BitScript : 0; + type |= symbol.IgnoreResult ? WindowsInstallerConstants.MsidbCustomActionTypeContinue : 0; + type |= symbol.Hidden ? WindowsInstallerConstants.MsidbCustomActionTypeHideTarget : 0; + type |= symbol.Async ? WindowsInstallerConstants.MsidbCustomActionTypeAsync : 0; + type |= CustomActionExecutionType.FirstSequence == symbol.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeFirstSequence : 0; + type |= CustomActionExecutionType.OncePerProcess == symbol.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeOncePerProcess : 0; + type |= CustomActionExecutionType.ClientRepeat == symbol.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeClientRepeat : 0; + type |= CustomActionExecutionType.Deferred == symbol.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript : 0; + type |= CustomActionExecutionType.Rollback == symbol.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeRollback : 0; + type |= CustomActionExecutionType.Commit == symbol.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeCommit : 0; + type |= CustomActionSourceType.File == symbol.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeSourceFile : 0; + type |= CustomActionSourceType.Directory == symbol.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeDirectory : 0; + type |= CustomActionSourceType.Property == symbol.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeProperty : 0; + type |= CustomActionTargetType.Dll == symbol.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeDll : 0; + type |= CustomActionTargetType.Exe == symbol.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeExe : 0; + type |= CustomActionTargetType.TextData == symbol.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeTextData : 0; + type |= CustomActionTargetType.JScript == symbol.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeJScript : 0; + type |= CustomActionTargetType.VBScript == symbol.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeVBScript : 0; + + if (WindowsInstallerConstants.MsidbCustomActionTypeInScript == (type & WindowsInstallerConstants.MsidbCustomActionTypeInScript)) + { + type |= symbol.Impersonate ? 0 : WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate; + type |= symbol.TSAware ? WindowsInstallerConstants.MsidbCustomActionTypeTSAware : 0; + } + + var row = this.CreateRow(symbol, "CustomAction"); + row[0] = symbol.Id.Id; + row[1] = type; + row[2] = symbol.Source; + row[3] = symbol.Target; + row[4] = symbol.PatchUninstall ? (int?)WindowsInstallerConstants.MsidbCustomActionTypePatchUninstall : null; + } + + private void AddDialogSymbol(DialogSymbol symbol) + { + var attributes = symbol.Visible ? WindowsInstallerConstants.MsidbDialogAttributesVisible : 0; + attributes |= symbol.Modal ? WindowsInstallerConstants.MsidbDialogAttributesModal : 0; + attributes |= symbol.Minimize ? WindowsInstallerConstants.MsidbDialogAttributesMinimize : 0; + attributes |= symbol.CustomPalette ? WindowsInstallerConstants.MsidbDialogAttributesUseCustomPalette : 0; + attributes |= symbol.ErrorDialog ? WindowsInstallerConstants.MsidbDialogAttributesError : 0; + attributes |= symbol.LeftScroll ? WindowsInstallerConstants.MsidbDialogAttributesLeftScroll : 0; + attributes |= symbol.KeepModeless ? WindowsInstallerConstants.MsidbDialogAttributesKeepModeless : 0; + attributes |= symbol.RightAligned ? WindowsInstallerConstants.MsidbDialogAttributesRightAligned : 0; + attributes |= symbol.RightToLeft ? WindowsInstallerConstants.MsidbDialogAttributesRTLRO : 0; + attributes |= symbol.SystemModal ? WindowsInstallerConstants.MsidbDialogAttributesSysModal : 0; + attributes |= symbol.TrackDiskSpace ? WindowsInstallerConstants.MsidbDialogAttributesTrackDiskSpace : 0; + + var row = this.CreateRow(symbol, "Dialog"); + row[0] = symbol.Id.Id; + row[1] = symbol.HCentering; + row[2] = symbol.VCentering; + row[3] = symbol.Width; + row[4] = symbol.Height; + row[5] = attributes; + row[6] = symbol.Title; + row[7] = symbol.FirstControlRef; + row[8] = symbol.DefaultControlRef; + row[9] = symbol.CancelControlRef; + + this.Data.EnsureTable(this.TableDefinitions["ListBox"]); + } + + private void AddDirectorySymbol(DirectorySymbol symbol) + { + if (String.IsNullOrEmpty(symbol.ShortName) && symbol.Name != null && !symbol.Name.Equals(".") && !symbol.Name.Equals("SourceDir") && !Common.IsValidShortFilename(symbol.Name, false)) + { + symbol.ShortName = CreateShortName(symbol.Name, false, false, "Directory", symbol.ParentDirectoryRef); + } + + if (String.IsNullOrEmpty(symbol.SourceShortName) && !String.IsNullOrEmpty(symbol.SourceName) && !Common.IsValidShortFilename(symbol.SourceName, false)) + { + symbol.SourceShortName = CreateShortName(symbol.SourceName, false, false, "Directory", symbol.ParentDirectoryRef); + } + + var sourceName = GetMsiFilenameValue(symbol.SourceShortName, symbol.SourceName); + var targetName = GetMsiFilenameValue(symbol.ShortName, symbol.Name); + + if (String.IsNullOrEmpty(targetName)) + { + targetName = "."; + } + + var defaultDir = String.IsNullOrEmpty(sourceName) ? targetName : targetName + ":" + sourceName; + + var row = this.CreateRow(symbol, "Directory"); + row[0] = symbol.Id.Id; + row[1] = symbol.ParentDirectoryRef; + row[2] = defaultDir; + } + + private void AddDuplicateFileSymbol(DuplicateFileSymbol symbol) + { + var name = symbol.DestinationName; + if (null == symbol.DestinationShortName && null != name && !Common.IsValidShortFilename(name, false)) + { + symbol.DestinationShortName = CreateShortName(name, true, false, "CopyFile", symbol.ComponentRef, symbol.FileRef); + } + + var row = this.CreateRow(symbol, "DuplicateFile"); + row[0] = symbol.Id.Id; + row[1] = symbol.ComponentRef; + row[2] = symbol.FileRef; + row[3] = GetMsiFilenameValue(symbol.DestinationShortName, symbol.DestinationName); + row[4] = symbol.DestinationFolder; + } + + private void AddEnvironmentSymbol(EnvironmentSymbol symbol) + { + var action = String.Empty; + var system = symbol.System ? "*" : String.Empty; + var uninstall = symbol.Permanent ? String.Empty : "-"; + var value = symbol.Value; + + switch (symbol.Action) + { + case EnvironmentActionType.Create: + action = "+"; + break; + case EnvironmentActionType.Set: + action = "="; + break; + case EnvironmentActionType.Remove: + action = "!"; + break; + } + + switch (symbol.Part) + { + case EnvironmentPartType.First: + value = String.Concat(value, symbol.Separator, "[~]"); + break; + case EnvironmentPartType.Last: + value = String.Concat("[~]", symbol.Separator, value); + break; + } + + var row = this.CreateRow(symbol, "Environment"); + row[0] = symbol.Id.Id; + row[1] = String.Concat(action, uninstall, system, symbol.Name); + row[2] = value; + row[3] = symbol.ComponentRef; + } + + private void AddErrorSymbol(ErrorSymbol symbol) + { + var row = this.CreateRow(symbol, "Error"); + row[0] = Convert.ToInt32(symbol.Id.Id); + row[1] = symbol.Message; + } + + private void AddFeatureSymbol(FeatureSymbol symbol) + { + var attributes = symbol.DisallowAbsent ? WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent : 0; + attributes |= symbol.DisallowAdvertise ? WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise : 0; + attributes |= FeatureInstallDefault.FollowParent == symbol.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFollowParent : 0; + attributes |= FeatureInstallDefault.Source == symbol.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorSource : 0; + attributes |= FeatureTypicalDefault.Advertise == symbol.TypicalDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise : 0; + + var row = this.CreateRow(symbol, "Feature"); + row[0] = symbol.Id.Id; + row[1] = symbol.ParentFeatureRef; + row[2] = symbol.Title; + row[3] = symbol.Description; + row[4] = symbol.Display; + row[5] = symbol.Level; + row[6] = symbol.DirectoryRef; + row[7] = attributes; + } + + private void AddFileSymbol(FileSymbol symbol) + { + var name = symbol.Name; + if (null == symbol.ShortName && null != name && !Common.IsValidShortFilename(name, false)) + { + symbol.ShortName = CreateShortName(name, true, false, "File", symbol.DirectoryRef); + } + + var row = (FileRow)this.CreateRow(symbol, "File"); + row.File = symbol.Id.Id; + row.Component = symbol.ComponentRef; + row.FileName = GetMsiFilenameValue(symbol.ShortName, name); + row.FileSize = symbol.FileSize; + row.Version = symbol.Version; + row.Language = symbol.Language; + row.DiskId = symbol.DiskId ?? 1; // TODO: is 1 the correct thing to default here + row.Sequence = symbol.Sequence; + row.Source = symbol.Source.Path; + + var attributes = (symbol.Attributes & FileSymbolAttributes.Checksum) == FileSymbolAttributes.Checksum ? WindowsInstallerConstants.MsidbFileAttributesChecksum : 0; + attributes |= (symbol.Attributes & FileSymbolAttributes.Compressed) == FileSymbolAttributes.Compressed ? WindowsInstallerConstants.MsidbFileAttributesCompressed : 0; + attributes |= (symbol.Attributes & FileSymbolAttributes.Uncompressed) == FileSymbolAttributes.Uncompressed ? WindowsInstallerConstants.MsidbFileAttributesNoncompressed : 0; + attributes |= (symbol.Attributes & FileSymbolAttributes.Hidden) == FileSymbolAttributes.Hidden ? WindowsInstallerConstants.MsidbFileAttributesHidden : 0; + attributes |= (symbol.Attributes & FileSymbolAttributes.ReadOnly) == FileSymbolAttributes.ReadOnly ? WindowsInstallerConstants.MsidbFileAttributesReadOnly : 0; + attributes |= (symbol.Attributes & FileSymbolAttributes.System) == FileSymbolAttributes.System ? WindowsInstallerConstants.MsidbFileAttributesSystem : 0; + attributes |= (symbol.Attributes & FileSymbolAttributes.Vital) == FileSymbolAttributes.Vital ? WindowsInstallerConstants.MsidbFileAttributesVital : 0; + row.Attributes = attributes; + + if (symbol.FontTitle != null) + { + var fontRow = this.CreateRow(symbol, "Font"); + fontRow[0] = symbol.Id.Id; + fontRow[1] = symbol.FontTitle; + } + + if (symbol.SelfRegCost.HasValue) + { + var selfRegRow = this.CreateRow(symbol, "SelfReg"); + selfRegRow[0] = symbol.Id.Id; + selfRegRow[1] = symbol.SelfRegCost.Value; + } + } + + private void AddIniFileSymbol(IniFileSymbol symbol) + { + var tableName = (IniFileActionType.AddLine == symbol.Action || IniFileActionType.AddTag == symbol.Action || IniFileActionType.CreateLine == symbol.Action) ? "IniFile" : "RemoveIniFile"; + + var name = symbol.FileName; + if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false)) + { + symbol.ShortFileName = CreateShortName(name, true, false, "IniFile", symbol.ComponentRef); + } + + var row = this.CreateRow(symbol, tableName); + row[0] = symbol.Id.Id; + row[1] = GetMsiFilenameValue(symbol.ShortFileName, name); + row[2] = symbol.DirProperty; + row[3] = symbol.Section; + row[4] = symbol.Key; + row[5] = symbol.Value; + row[6] = symbol.Action; + row[7] = symbol.ComponentRef; + } + + private void AddIniLocatorSymbol(IniLocatorSymbol symbol) + { + var name = symbol.FileName; + if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false)) + { + symbol.ShortFileName = CreateShortName(name, true, false, "IniFileSearch"); + } + + var row = this.CreateRow(symbol, "IniLocator"); + row[0] = symbol.Id.Id; + row[1] = GetMsiFilenameValue(symbol.ShortFileName, name); + row[2] = symbol.Section; + row[3] = symbol.Key; + row[4] = symbol.Field; + row[5] = symbol.Type; + } + + private void AddMediaSymbol(MediaSymbol symbol) + { + if (this.Section.Type != SectionType.Module) + { + var row = (MediaRow)this.CreateRow(symbol, "Media"); + row.DiskId = symbol.DiskId; + row.LastSequence = symbol.LastSequence ?? 0; + row.DiskPrompt = symbol.DiskPrompt; + row.Cabinet = symbol.Cabinet; + row.VolumeLabel = symbol.VolumeLabel; + row.Source = symbol.Source; + } + } + + private void AddModuleConfigurationSymbol(ModuleConfigurationSymbol symbol) + { + var row = this.CreateRow(symbol, "ModuleConfiguration"); + row[0] = symbol.Id.Id; + row[1] = symbol.Format; + row[2] = symbol.Type; + row[3] = symbol.ContextData; + row[4] = symbol.DefaultValue; + row[5] = (symbol.KeyNoOrphan ? WindowsInstallerConstants.MsidbMsmConfigurableOptionKeyNoOrphan : 0) | + (symbol.NonNullable ? WindowsInstallerConstants.MsidbMsmConfigurableOptionNonNullable : 0); + row[6] = symbol.DisplayName; + row[7] = symbol.Description; + row[8] = symbol.HelpLocation; + row[9] = symbol.HelpKeyword; + } + + private void AddMsiEmbeddedUISymbol(MsiEmbeddedUISymbol symbol) + { + var attributes = symbol.EntryPoint ? WindowsInstallerConstants.MsidbEmbeddedUI : 0; + attributes |= symbol.SupportsBasicUI ? WindowsInstallerConstants.MsidbEmbeddedHandlesBasic : 0; + + var row = this.CreateRow(symbol, "MsiEmbeddedUI"); + row[0] = symbol.Id.Id; + row[1] = symbol.FileName; + row[2] = attributes; + row[3] = symbol.MessageFilter; + row[4] = symbol.Source; + } + + private void AddMsiServiceConfigSymbol(MsiServiceConfigSymbol symbol) + { + var events = symbol.OnInstall ? WindowsInstallerConstants.MsidbServiceConfigEventInstall : 0; + events |= symbol.OnReinstall ? WindowsInstallerConstants.MsidbServiceConfigEventReinstall : 0; + events |= symbol.OnUninstall ? WindowsInstallerConstants.MsidbServiceConfigEventUninstall : 0; + + var row = this.CreateRow(symbol, "MsiServiceConfigFailureActions"); + row[0] = symbol.Id.Id; + row[1] = symbol.Name; + row[2] = events; + row[3] = symbol.ConfigType; + row[4] = symbol.Argument; + row[5] = symbol.ComponentRef; + } + + private void AddMsiServiceConfigFailureActionsSymbol(MsiServiceConfigFailureActionsSymbol symbol) + { + var events = symbol.OnInstall ? WindowsInstallerConstants.MsidbServiceConfigEventInstall : 0; + events |= symbol.OnReinstall ? WindowsInstallerConstants.MsidbServiceConfigEventReinstall : 0; + events |= symbol.OnUninstall ? WindowsInstallerConstants.MsidbServiceConfigEventUninstall : 0; + + var row = this.CreateRow(symbol, "MsiServiceConfig"); + row[0] = symbol.Id.Id; + row[1] = symbol.Name; + row[2] = events; + row[3] = symbol.ResetPeriod.HasValue ? symbol.ResetPeriod : null; + row[4] = symbol.RebootMessage ?? "[~]"; + row[5] = symbol.Command ?? "[~]"; + row[6] = symbol.Actions; + row[7] = symbol.DelayActions; + row[8] = symbol.ComponentRef; + } + + private void AddMoveFileSymbol(MoveFileSymbol symbol) + { + var name = symbol.DestinationName; + if (null == symbol.DestinationShortName && null != name && !Common.IsValidShortFilename(name, false)) + { + symbol.DestinationShortName = CreateShortName(name, true, false, "MoveFile", symbol.ComponentRef); + } + + var row = this.CreateRow(symbol, "MoveFile"); + row[0] = symbol.Id.Id; + row[1] = symbol.ComponentRef; + row[2] = symbol.SourceName; + row[3] = GetMsiFilenameValue(symbol.DestinationShortName, symbol.DestinationName); + row[4] = symbol.SourceFolder; + row[5] = symbol.DestFolder; + row[6] = symbol.Delete ? WindowsInstallerConstants.MsidbMoveFileOptionsMove : 0; + } + + private void AddPropertySymbol(PropertySymbol symbol) + { + if (String.IsNullOrEmpty(symbol.Value)) + { + return; + } + + var row = (PropertyRow)this.CreateRow(symbol, "Property"); + row.Property = symbol.Id.Id; + row.Value = symbol.Value; + } + + private void AddRemoveFileSymbol(RemoveFileSymbol symbol) + { + var name = symbol.FileName; + if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false)) + { + symbol.ShortFileName = CreateShortName(name, true, false, "RemoveFile", symbol.ComponentRef); + } + + var installMode = symbol.OnInstall == true ? WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall : 0; + installMode |= symbol.OnUninstall == true ? WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove : 0; + + var row = this.CreateRow(symbol, "RemoveFile"); + row[0] = symbol.Id.Id; + row[1] = symbol.ComponentRef; + row[2] = GetMsiFilenameValue(symbol.ShortFileName, symbol.FileName); + row[3] = symbol.DirPropertyRef; + row[4] = installMode; + } + + private void AddRegistrySymbol(RegistrySymbol symbol) + { + var value = symbol.Value; + + switch (symbol.ValueType) + { + case RegistryValueType.Binary: + value = String.Concat("#x", value); + break; + case RegistryValueType.Expandable: + value = String.Concat("#%", value); + break; + case RegistryValueType.Integer: + value = String.Concat("#", value); + break; + case RegistryValueType.MultiString: + switch (symbol.ValueAction) + { + case RegistryValueActionType.Append: + value = String.Concat("[~]", value); + break; + case RegistryValueActionType.Prepend: + value = String.Concat(value, "[~]"); + break; + case RegistryValueActionType.Write: + default: + if (null != value && -1 == value.IndexOf("[~]", StringComparison.Ordinal)) + { + value = String.Format(CultureInfo.InvariantCulture, "[~]{0}[~]", value); + } + break; + } + break; + case RegistryValueType.String: + // escape the leading '#' character for string registry keys + if (null != value && value.StartsWith("#", StringComparison.Ordinal)) + { + value = String.Concat("#", value); + } + break; + } + + var row = this.CreateRow(symbol, "Registry"); + row[0] = symbol.Id.Id; + row[1] = symbol.Root; + row[2] = symbol.Key; + row[3] = symbol.Name; + row[4] = value; + row[5] = symbol.ComponentRef; + } + + private void AddRegLocatorSymbol(RegLocatorSymbol symbol) + { + var type = (int)symbol.Type; + type |= symbol.Win64 ? WindowsInstallerConstants.MsidbLocatorType64bit : 0; + + var row = this.CreateRow(symbol, "RegLocator"); + row[0] = symbol.Id.Id; + row[1] = symbol.Root; + row[2] = symbol.Key; + row[3] = symbol.Name; + row[4] = type; + } + + private void AddRemoveRegistrySymbol(RemoveRegistrySymbol symbol) + { + if (symbol.Action == RemoveRegistryActionType.RemoveOnInstall) + { + var row = this.CreateRow(symbol, "RemoveRegistry"); + row[0] = symbol.Id.Id; + row[1] = symbol.Root; + row[2] = symbol.Key; + row[3] = symbol.Name; + row[4] = symbol.ComponentRef; + } + else // Registry table is used to remove registry keys on uninstall. + { + var row = this.CreateRow(symbol, "Registry"); + row[0] = symbol.Id.Id; + row[1] = symbol.Root; + row[2] = symbol.Key; + row[3] = symbol.Name; + row[5] = symbol.ComponentRef; + } + } + + private void AddServiceControlSymbol(ServiceControlSymbol symbol) + { + var events = symbol.InstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventDelete : 0; + events |= symbol.UninstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete : 0; + events |= symbol.InstallStart ? WindowsInstallerConstants.MsidbServiceControlEventStart : 0; + events |= symbol.UninstallStart ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStart : 0; + events |= symbol.InstallStop ? WindowsInstallerConstants.MsidbServiceControlEventStop : 0; + events |= symbol.UninstallStop ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStop : 0; + + var row = this.CreateRow(symbol, "ServiceControl"); + row[0] = symbol.Id.Id; + row[1] = symbol.Name; + row[2] = events; + row[3] = symbol.Arguments; + if (symbol.Wait.HasValue) + { + row[4] = symbol.Wait.Value ? 1 : 0; + } + row[5] = symbol.ComponentRef; + } + + private void AddServiceInstallSymbol(ServiceInstallSymbol symbol) + { + var errorControl = (int)symbol.ErrorControl; + errorControl |= symbol.Vital ? WindowsInstallerConstants.MsidbServiceInstallErrorControlVital : 0; + + var serviceType = (int)symbol.ServiceType; + serviceType |= symbol.Interactive ? WindowsInstallerConstants.MsidbServiceInstallInteractive : 0; + + var row = this.CreateRow(symbol, "ServiceInstall"); + row[0] = symbol.Id.Id; + row[1] = symbol.Name; + row[2] = symbol.DisplayName; + row[3] = serviceType; + row[4] = (int)symbol.StartType; + row[5] = errorControl; + row[6] = symbol.LoadOrderGroup; + row[7] = symbol.Dependencies; + row[8] = symbol.StartName; + row[9] = symbol.Password; + row[10] = symbol.Arguments; + row[11] = symbol.ComponentRef; + row[12] = symbol.Description; + } + + private void AddShortcutSymbol(ShortcutSymbol symbol) + { + var name = symbol.Name; + if (null == symbol.ShortName && null != name && !Common.IsValidShortFilename(name, false)) + { + symbol.ShortName = CreateShortName(name, true, false, "Shortcut", symbol.ComponentRef, symbol.DirectoryRef); + } + + var row = this.CreateRow(symbol, "Shortcut"); + row[0] = symbol.Id.Id; + row[1] = symbol.DirectoryRef; + row[2] = GetMsiFilenameValue(symbol.ShortName, name); + row[3] = symbol.ComponentRef; + row[4] = symbol.Target; + row[5] = symbol.Arguments; + row[6] = symbol.Description; + row[7] = symbol.Hotkey; + row[8] = symbol.IconRef; + row[9] = symbol.IconIndex; + row[10] = (int?)symbol.Show; + row[11] = symbol.WorkingDirectory; + row[12] = symbol.DisplayResourceDll; + row[13] = symbol.DisplayResourceId; + row[14] = symbol.DescriptionResourceDll; + row[15] = symbol.DescriptionResourceId; + } + + private void AddTextStyleSymbol(TextStyleSymbol symbol) + { + var styleBits = symbol.Bold ? WindowsInstallerConstants.MsidbTextStyleStyleBitsBold : 0; + styleBits |= symbol.Italic ? WindowsInstallerConstants.MsidbTextStyleStyleBitsItalic : 0; + styleBits |= symbol.Strike ? WindowsInstallerConstants.MsidbTextStyleStyleBitsStrike : 0; + styleBits |= symbol.Underline ? WindowsInstallerConstants.MsidbTextStyleStyleBitsUnderline : 0; + + long? color = null; + + if (symbol.Red.HasValue || symbol.Green.HasValue || symbol.Blue.HasValue) + { + color = symbol.Red ?? 0; + color += (long)(symbol.Green ?? 0) * 256; + color += (long)(symbol.Blue ?? 0) * 65536; + } + + var row = this.CreateRow(symbol, "TextStyle"); + row[0] = symbol.Id.Id; + row[1] = symbol.FaceName; + row[2] = symbol.Size; + row[3] = color; + row[4] = styleBits == 0 ? null : (int?)styleBits; + } + + private void AddUpgradeSymbol(UpgradeSymbol symbol) + { + var row = (UpgradeRow)this.CreateRow(symbol, "Upgrade"); + row.UpgradeCode = symbol.UpgradeCode; + row.VersionMin = symbol.VersionMin; + row.VersionMax = symbol.VersionMax; + row.Language = symbol.Language; + row.Remove = symbol.Remove; + row.ActionProperty = symbol.ActionProperty; + + var attributes = symbol.MigrateFeatures ? WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures : 0; + attributes |= symbol.OnlyDetect ? WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect : 0; + attributes |= symbol.IgnoreRemoveFailures ? WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure : 0; + attributes |= symbol.VersionMinInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive : 0; + attributes |= symbol.VersionMaxInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive : 0; + attributes |= symbol.ExcludeLanguages ? WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive : 0; + row.Attributes = attributes; + } + + private void AddWixActionSymbol(WixActionSymbol symbol) + { + // Get the table definition for the action (and ensure the proper table exists for a module). + string sequenceTableName = null; + switch (symbol.SequenceTable) + { + case SequenceTable.AdminExecuteSequence: + if (OutputType.Module == this.Data.Type) + { + this.Data.EnsureTable(this.TableDefinitions["AdminExecuteSequence"]); + sequenceTableName = "ModuleAdminExecuteSequence"; + } + else + { + sequenceTableName = "AdminExecuteSequence"; + } + break; + case SequenceTable.AdminUISequence: + if (OutputType.Module == this.Data.Type) + { + this.Data.EnsureTable(this.TableDefinitions["AdminUISequence"]); + sequenceTableName = "ModuleAdminUISequence"; + } + else + { + sequenceTableName = "AdminUISequence"; + } + break; + case SequenceTable.AdvertiseExecuteSequence: + if (OutputType.Module == this.Data.Type) + { + this.Data.EnsureTable(this.TableDefinitions["AdvtExecuteSequence"]); + sequenceTableName = "ModuleAdvtExecuteSequence"; + } + else + { + sequenceTableName = "AdvtExecuteSequence"; + } + break; + case SequenceTable.InstallExecuteSequence: + if (OutputType.Module == this.Data.Type) + { + this.Data.EnsureTable(this.TableDefinitions["InstallExecuteSequence"]); + sequenceTableName = "ModuleInstallExecuteSequence"; + } + else + { + sequenceTableName = "InstallExecuteSequence"; + } + break; + case SequenceTable.InstallUISequence: + if (OutputType.Module == this.Data.Type) + { + this.Data.EnsureTable(this.TableDefinitions["InstallUISequence"]); + sequenceTableName = "ModuleInstallUISequence"; + } + else + { + sequenceTableName = "InstallUISequence"; + } + break; + } + + // create the action sequence row in the output + var row = this.CreateRow(symbol, sequenceTableName); + + if (SectionType.Module == this.Section.Type) + { + row[0] = symbol.Action; + if (0 != symbol.Sequence) + { + row[1] = symbol.Sequence; + } + else + { + var after = (null == symbol.Before); + row[2] = after ? symbol.After : symbol.Before; + row[3] = after ? 1 : 0; + } + row[4] = symbol.Condition; + } + else + { + row[0] = symbol.Action; + row[1] = symbol.Condition; + row[2] = symbol.Sequence; + } + } + + private void IndexCustomTableCellSymbol(WixCustomTableCellSymbol wixCustomTableCellSymbol, Dictionary> cellsByTableAndRowId) + { + var tableAndRowId = wixCustomTableCellSymbol.TableRef + "/" + wixCustomTableCellSymbol.RowId; + if (!cellsByTableAndRowId.TryGetValue(tableAndRowId, out var cells)) + { + cells = new List(); + cellsByTableAndRowId.Add(tableAndRowId, cells); + } + + cells.Add(wixCustomTableCellSymbol); + } + + private void AddIndexedCellSymbols(Dictionary> cellsByTableAndRowId) + { + foreach (var rowOfCells in cellsByTableAndRowId.Values) + { + var firstCellSymbol = rowOfCells[0]; + var customTableDefinition = this.TableDefinitions[firstCellSymbol.TableRef]; + + if (customTableDefinition.Unreal) + { + continue; + } + + var customRow = this.CreateRow(firstCellSymbol, customTableDefinition); + var customRowFieldsByColumnName = customRow.Fields.ToDictionary(f => f.Column.Name); + +#if TODO // SectionId seems like a good thing to preserve. + customRow.SectionId = symbol.SectionId; +#endif + foreach (var cell in rowOfCells) + { + var data = cell.Data; + + if (customRowFieldsByColumnName.TryGetValue(cell.ColumnRef, out var rowField)) + { + if (!String.IsNullOrEmpty(data)) + { + if (rowField.Column.Type == ColumnType.Number) + { + try + { + rowField.Data = Convert.ToInt32(data, CultureInfo.InvariantCulture); + } + catch (FormatException) + { + this.Messaging.Write(ErrorMessages.IllegalIntegerValue(cell.SourceLineNumbers, rowField.Column.Name, customTableDefinition.Name, data)); + } + catch (OverflowException) + { + this.Messaging.Write(ErrorMessages.IllegalIntegerValue(cell.SourceLineNumbers, rowField.Column.Name, customTableDefinition.Name, data)); + } + } + else if (rowField.Column.Category == ColumnCategory.Identifier) + { + if (Common.IsIdentifier(data) || Common.IsValidBinderVariable(data) || ColumnCategory.Formatted == rowField.Column.Category) + { + rowField.Data = data; + } + else + { + this.Messaging.Write(ErrorMessages.IllegalIdentifier(cell.SourceLineNumbers, "Data", data)); + } + } + else + { + rowField.Data = data; + } + } + } + else + { + this.Messaging.Write(ErrorMessages.UnexpectedCustomTableColumn(cell.SourceLineNumbers, cell.ColumnRef)); + } + } + + for (var i = 0; i < customTableDefinition.Columns.Length; ++i) + { + if (!customTableDefinition.Columns[i].Nullable && (null == customRow.Fields[i].Data || 0 == customRow.Fields[i].Data.ToString().Length)) + { + this.Messaging.Write(ErrorMessages.NoDataForColumn(firstCellSymbol.SourceLineNumbers, customTableDefinition.Columns[i].Name, customTableDefinition.Name)); + } + } + } + } + + private void AddWixEnsureTableSymbol(WixEnsureTableSymbol symbol) + { + var tableDefinition = this.TableDefinitions[symbol.Table]; + this.Data.EnsureTable(tableDefinition); + } + + private bool AddSymbolFromExtension(IntermediateSymbol symbol) + { + foreach (var extension in this.BackendExtensions) + { + if (extension.TryProcessSymbol(this.Section, symbol, this.Data, this.TableDefinitions)) + { + return true; + } + } + + return false; + } + + private bool AddSymbolDefaultly(IntermediateSymbol symbol) => + this.BackendHelper.TryAddSymbolToMatchingTableDefinitions(this.Section, symbol, this.Data, this.TableDefinitions); + + private static OutputType SectionTypeToOutputType(SectionType type) + { + switch (type) + { + case SectionType.Bundle: + return OutputType.Bundle; + case SectionType.Module: + return OutputType.Module; + case SectionType.Product: + return OutputType.Product; + case SectionType.PatchCreation: + return OutputType.PatchCreation; + case SectionType.Patch: + return OutputType.Patch; + + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + } + + private Row CreateRow(IntermediateSymbol symbol, string tableDefinitionName) => + this.CreateRow(symbol, this.TableDefinitions[tableDefinitionName]); + + private Row CreateRow(IntermediateSymbol symbol, TableDefinition tableDefinition) => + this.BackendHelper.CreateRow(this.Section, symbol, this.Data, tableDefinition); + + private static string GetMsiFilenameValue(string shortName, string longName) + { + if (String.IsNullOrEmpty(shortName) || String.Equals(shortName, longName, StringComparison.OrdinalIgnoreCase)) + { + return longName; + } + else + { + return shortName + "|" + longName; + } + } + + private static string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args) + { + longName = longName.ToLowerInvariant(); + + // collect all the data + var strings = new List(1 + args.Length); + strings.Add(longName); + strings.AddRange(args); + + // prepare for hashing + var stringData = String.Join("|", strings); + var data = Encoding.UTF8.GetBytes(stringData); + + // hash the data + byte[] hash; + using (var sha1 = new SHA1CryptoServiceProvider()) + { + hash = sha1.ComputeHash(data); + } + + // generate the short file/directory name without an extension + var shortName = new StringBuilder(Convert.ToBase64String(hash)); + shortName.Length = 8; + shortName.Replace('+', '-').Replace('/', '_'); + + if (keepExtension) + { + var extension = Path.GetExtension(longName); + + if (4 < extension.Length) + { + extension = extension.Substring(0, 4); + } + + shortName.Append(extension); + + // check the generated short name to ensure its still legal (the extension may not be legal) + if (!Common.IsValidShortFilename(shortName.ToString(), allowWildcards)) + { + // remove the extension (by truncating the generated file name back to the generated characters) + shortName.Length -= extension.Length; + } + } + + return shortName.ToString().ToLowerInvariant(); + } + } +} -- cgit v1.2.3-55-g6feb