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 --- .../Bind/BindDatabaseCommand.cs | 40 +- .../Bind/CreateCabinetsCommand.cs | 12 +- .../Bind/CreateOutputFromIRCommand.cs | 1254 ------------------- .../CreateWindowsInstallerDataFromIRCommand.cs | 1256 ++++++++++++++++++++ .../WindowsInstallerBackendHelper.cs | 8 +- 5 files changed, 1285 insertions(+), 1285 deletions(-) delete mode 100644 src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs create mode 100644 src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs index b3b9023c..7a64b777 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs @@ -402,31 +402,29 @@ namespace WixToolset.Core.WindowsInstaller.Bind return null; } - // Time to create the output object. Try to put as much above here as possible, updating the IR is better. - WindowsInstallerData output; + // Time to create the WindowsInstallerData object. Try to put as much above here as possible, updating the IR is better. + WindowsInstallerData data; { - var command = new CreateOutputFromIRCommand(this.Messaging, section, tableDefinitions, this.BackendExtensions, this.WindowsInstallerBackendHelper); - command.Execute(); - - output = command.Output; + var command = new CreateWindowsInstallerDataFromIRCommand(this.Messaging, section, tableDefinitions, this.BackendExtensions, this.WindowsInstallerBackendHelper); + data = command.Execute(); } IEnumerable suppressedTableNames = null; - if (output.Type == OutputType.Module) + if (data.Type == OutputType.Module) { // Modularize identifiers. - var modularize = new ModularizeCommand(output, modularizationSuffix, section.Symbols.OfType()); + var modularize = new ModularizeCommand(data, modularizationSuffix, section.Symbols.OfType()); modularize.Execute(); // Ensure all sequence tables in place because, mergemod.dll requires them. - var unsuppress = new AddBackSuppressedSequenceTablesCommand(output, tableDefinitions); + var unsuppress = new AddBackSuppressedSequenceTablesCommand(data, tableDefinitions); suppressedTableNames = unsuppress.Execute(); } - else if (output.Type == OutputType.Patch) + else if (data.Type == OutputType.Patch) { foreach (var storage in this.SubStorages) { - output.SubStorages.Add(storage); + data.SubStorages.Add(storage); } } @@ -448,7 +446,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // create cabinet files and process uncompressed files var layoutDirectory = Path.GetDirectoryName(this.OutputPath); - if (!this.SuppressLayout || OutputType.Module == output.Type) + if (!this.SuppressLayout || OutputType.Module == data.Type) { this.Messaging.Write(VerboseMessages.CreatingCabinetFiles()); @@ -458,7 +456,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind command.CabbingThreadCount = this.CabbingThreadCount; command.CabCachePath = this.CabCachePath; command.DefaultCompressionLevel = this.DefaultCompressionLevel; - command.Output = output; + command.Data = data; command.Messaging = this.Messaging; command.BackendExtensions = this.BackendExtensions; command.LayoutDirectory = layoutDirectory; @@ -481,15 +479,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind } // We can create instance transforms since Component Guids and Outputs are created. - if (output.Type == OutputType.Product) + if (data.Type == OutputType.Product) { - var command = new CreateInstanceTransformsCommand(section, output, tableDefinitions, this.WindowsInstallerBackendHelper); + var command = new CreateInstanceTransformsCommand(section, data, tableDefinitions, this.WindowsInstallerBackendHelper); command.Execute(); } - else if (output.Type == OutputType.Patch) + else if (data.Type == OutputType.Patch) { // Copy output data back into the transforms. - var command = new UpdateTransformsWithFileFacades(this.Messaging, output, this.SubStorages, tableDefinitions, fileFacades); + var command = new UpdateTransformsWithFileFacades(this.Messaging, data, this.SubStorages, tableDefinitions, fileFacades); command.Execute(); } @@ -500,7 +498,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var trackMsi = this.WindowsInstallerBackendHelper.TrackFile(this.OutputPath, TrackedFileType.Final); trackedFiles.Add(trackMsi); - var command = new GenerateDatabaseCommand(this.Messaging, this.WindowsInstallerBackendHelper, this.FileSystemManager, output, trackMsi.Path, tableDefinitions, this.IntermediateFolder, this.Codepage, keepAddedColumns: false, this.SuppressAddingValidationRows, useSubdirectory: false); + var command = new GenerateDatabaseCommand(this.Messaging, this.WindowsInstallerBackendHelper, this.FileSystemManager, data, trackMsi.Path, tableDefinitions, this.IntermediateFolder, this.Codepage, keepAddedColumns: false, this.SuppressAddingValidationRows, useSubdirectory: false); command.Execute(); trackedFiles.AddRange(command.GeneratedTemporaryFiles); @@ -572,12 +570,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind var result = this.ServiceProvider.GetService(); result.FileTransfers = fileTransfers; result.TrackedFiles = trackedFiles; - result.Wixout = this.CreateWixout(trackedFiles, this.Intermediate, output); + result.Wixout = this.CreateWixout(trackedFiles, this.Intermediate, data); return result; } - private WixOutput CreateWixout(List trackedFiles, Intermediate intermediate, WindowsInstallerData output) + private WixOutput CreateWixout(List trackedFiles, Intermediate intermediate, WindowsInstallerData data) { WixOutput wixout; @@ -595,7 +593,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind intermediate.Save(wixout); - output.Save(wixout); + data.Save(wixout); wixout.Reopen(); diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs index f0acd3d4..9f94b2c7 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs @@ -72,7 +72,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind public IEnumerable BackendExtensions { private get; set; } - public WindowsInstallerData Output { private get; set; } + public WindowsInstallerData Data { private get; set; } public string LayoutDirectory { private get; set; } @@ -115,7 +115,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var compressionLevel = mediaSymbol.CompressionLevel ?? this.DefaultCompressionLevel ?? CompressionLevel.Medium; var cabinetDir = this.ResolveMedia(mediaSymbol, mediaSymbol.Layout, this.LayoutDirectory); - var cabinetWorkItem = this.CreateCabinetWorkItem(this.Output, cabinetDir, mediaSymbol, compressionLevel, files); + var cabinetWorkItem = this.CreateCabinetWorkItem(this.Data, cabinetDir, mediaSymbol, compressionLevel, files); if (null != cabinetWorkItem) { cabinetBuilder.Enqueue(cabinetWorkItem); @@ -171,13 +171,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// /// Creates a work item to create a cabinet. /// - /// Output for the current database. + /// Windows Installer data for the current database. /// Directory to create cabinet in. /// Media symbol containing information about the cabinet. /// Desired compression level. /// Collection of files in this cabinet. /// created CabinetWorkItem object - private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData output, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable fileFacades) + private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable fileFacades) { CabinetWorkItem cabinetWorkItem = null; var tempCabinetFileX = Path.Combine(this.IntermediateFolder, mediaSymbol.Cabinet); @@ -189,7 +189,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var cabinetName = mediaSymbol.Cabinet.TrimStart('#'); // If building a patch, remind them to run -p for torch. - if (OutputType.Patch == output.Type) + if (OutputType.Patch == data.Type) { this.Messaging.Write(WarningMessages.EmptyCabinet(mediaSymbol.SourceLineNumbers, cabinetName, true)); } @@ -234,7 +234,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind if (mediaSymbol.Cabinet.StartsWith("#", StringComparison.Ordinal)) { - var streamsTable = output.EnsureTable(this.TableDefinitions["_Streams"]); + var streamsTable = data.EnsureTable(this.TableDefinitions["_Streams"]); var streamRow = streamsTable.CreateRow(mediaSymbol.SourceLineNumbers); streamRow[0] = mediaSymbol.Cabinet.Substring(1); diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs deleted file mode 100644 index 37383caa..00000000 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs +++ /dev/null @@ -1,1254 +0,0 @@ -// 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 CreateOutputFromIRCommand - { - public CreateOutputFromIRCommand(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 Output { get; private set; } - - public void Execute() - { - this.Output = new WindowsInstallerData(this.Section.Symbols.First().SourceLineNumbers) - { - Codepage = this.Section.Codepage, - Type = SectionTypeToOutputType(this.Section.Type) - }; - - this.AddSectionToOutput(); - } - - private void AddSectionToOutput() - { - 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.Output.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.Output.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.Output.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.Output.Type) - { - this.Output.EnsureTable(this.TableDefinitions["AdminExecuteSequence"]); - sequenceTableName = "ModuleAdminExecuteSequence"; - } - else - { - sequenceTableName = "AdminExecuteSequence"; - } - break; - case SequenceTable.AdminUISequence: - if (OutputType.Module == this.Output.Type) - { - this.Output.EnsureTable(this.TableDefinitions["AdminUISequence"]); - sequenceTableName = "ModuleAdminUISequence"; - } - else - { - sequenceTableName = "AdminUISequence"; - } - break; - case SequenceTable.AdvertiseExecuteSequence: - if (OutputType.Module == this.Output.Type) - { - this.Output.EnsureTable(this.TableDefinitions["AdvtExecuteSequence"]); - sequenceTableName = "ModuleAdvtExecuteSequence"; - } - else - { - sequenceTableName = "AdvtExecuteSequence"; - } - break; - case SequenceTable.InstallExecuteSequence: - if (OutputType.Module == this.Output.Type) - { - this.Output.EnsureTable(this.TableDefinitions["InstallExecuteSequence"]); - sequenceTableName = "ModuleInstallExecuteSequence"; - } - else - { - sequenceTableName = "InstallExecuteSequence"; - } - break; - case SequenceTable.InstallUISequence: - if (OutputType.Module == this.Output.Type) - { - this.Output.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.Output.EnsureTable(tableDefinition); - } - - private bool AddSymbolFromExtension(IntermediateSymbol symbol) - { - foreach (var extension in this.BackendExtensions) - { - if (extension.TryProcessSymbol(this.Section, symbol, this.Output, this.TableDefinitions)) - { - return true; - } - } - - return false; - } - - private bool AddSymbolDefaultly(IntermediateSymbol symbol) => - this.BackendHelper.TryAddSymbolToOutputMatchingTableDefinitions(this.Section, symbol, this.Output, 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.Output, 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(); - } - } -} 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(); + } + } +} diff --git a/src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs b/src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs index 248dea9b..09194d4e 100644 --- a/src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs +++ b/src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs @@ -34,9 +34,9 @@ namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices #region IWindowsInstallerBackendHelper interfaces - public Row CreateRow(IntermediateSection section, IntermediateSymbol symbol, WindowsInstallerData output, TableDefinition tableDefinition) + public Row CreateRow(IntermediateSection section, IntermediateSymbol symbol, WindowsInstallerData data, TableDefinition tableDefinition) { - var table = output.EnsureTable(tableDefinition); + var table = data.EnsureTable(tableDefinition); var row = table.CreateRow(symbol.SourceLineNumbers); row.SectionId = section.Id; @@ -44,7 +44,7 @@ namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices return row; } - public bool TryAddSymbolToOutputMatchingTableDefinitions(IntermediateSection section, IntermediateSymbol symbol, WindowsInstallerData output, TableDefinitionCollection tableDefinitions) + public bool TryAddSymbolToMatchingTableDefinitions(IntermediateSection section, IntermediateSymbol symbol, WindowsInstallerData data, TableDefinitionCollection tableDefinitions) { var tableDefinition = tableDefinitions.FirstOrDefault(t => t.SymbolDefinition?.Name == symbol.Definition.Name); if (tableDefinition == null) @@ -52,7 +52,7 @@ namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices return false; } - var row = this.CreateRow(section, symbol, output, tableDefinition); + var row = this.CreateRow(section, symbol, data, tableDefinition); var rowOffset = 0; if (tableDefinition.SymbolIdIsPrimaryKey) -- cgit v1.2.3-55-g6feb