示例#1
0
        private string ResolveMedia(MediaSymbol media, string mediaLayoutDirectory, string layoutDirectory)
        {
            string layout = null;

            foreach (var extension in this.BackendExtensions)
            {
                layout = extension.ResolveMedia(media, mediaLayoutDirectory, layoutDirectory);
                if (!String.IsNullOrEmpty(layout))
                {
                    break;
                }
            }

            // If no binder file manager resolved the layout, do the default behavior.
            if (String.IsNullOrEmpty(layout))
            {
                if (String.IsNullOrEmpty(mediaLayoutDirectory))
                {
                    layout = layoutDirectory;
                }
                else if (Path.IsPathRooted(mediaLayoutDirectory))
                {
                    layout = mediaLayoutDirectory;
                }
                else
                {
                    layout = Path.Combine(layoutDirectory, mediaLayoutDirectory);
                }
            }

            return(layout);
        }
示例#2
0
        /// <summary>
        /// Assign files to cabinets based on MediaTemplate authoring.
        /// </summary>
        /// <param name="fileFacades">FileRowCollection</param>
        private void AutoAssignFiles(List <MediaSymbol> mediaTable, Dictionary <MediaSymbol, List <FileFacade> > filesByCabinetMedia, List <FileFacade> uncompressedFiles)
        {
            const int MaxCabIndex = 999;

            ulong currentPreCabSize = 0;
            ulong maxPreCabSizeInBytes;
            var   maxPreCabSizeInMB = 0;
            var   currentCabIndex   = 0;

            MediaSymbol currentMediaRow = null;

            var mediaTemplateTable = this.Section.Symbols.OfType <WixMediaTemplateSymbol>();

            // Remove all previous media symbols since they will be replaced with
            // media template.
            foreach (var mediaSymbol in mediaTable)
            {
                this.Section.Symbols.Remove(mediaSymbol);
            }

            // Auto assign files to cabinets based on maximum uncompressed media size
            var mediaTemplateRow = mediaTemplateTable.Single();

            if (!String.IsNullOrEmpty(mediaTemplateRow.CabinetTemplate))
            {
                this.CabinetNameTemplate = mediaTemplateRow.CabinetTemplate;
            }

            var mumsString = Environment.GetEnvironmentVariable("WIX_MUMS");

            try
            {
                // Override authored mums value if environment variable is authored.
                if (!String.IsNullOrEmpty(mumsString))
                {
                    maxPreCabSizeInMB = Int32.Parse(mumsString);
                }
                else
                {
                    maxPreCabSizeInMB = mediaTemplateRow.MaximumUncompressedMediaSize ?? DefaultMaximumUncompressedMediaSize;
                }

                maxPreCabSizeInBytes = (ulong)maxPreCabSizeInMB * 1024 * 1024;
            }
            catch (FormatException)
            {
                throw new WixException(ErrorMessages.IllegalEnvironmentVariable("WIX_MUMS", mumsString));
            }
            catch (OverflowException)
            {
                throw new WixException(ErrorMessages.MaximumUncompressedMediaSizeTooLarge(null, maxPreCabSizeInMB));
            }

            var mediaSymbolsByDiskId = new Dictionary <int, MediaSymbol>();

            foreach (var facade in this.FileFacades)
            {
                // When building a product, if the current file is not to be compressed or if
                // the package set not to be compressed, don't cab it.
                if (SectionType.Product == this.Section.Type && (facade.Uncompressed || !this.FilesCompressed))
                {
                    uncompressedFiles.Add(facade);
                    continue;
                }

                if (currentCabIndex == MaxCabIndex)
                {
                    // Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore.
                }
                else
                {
                    // Update current cab size.
                    currentPreCabSize += (ulong)facade.FileSize;

                    // Overflow due to current file
                    if (currentPreCabSize > maxPreCabSizeInBytes)
                    {
                        currentMediaRow = this.AddMediaSymbol(mediaTemplateRow, ++currentCabIndex);
                        mediaSymbolsByDiskId.Add(currentMediaRow.DiskId, currentMediaRow);
                        filesByCabinetMedia.Add(currentMediaRow, new List <FileFacade>());

                        // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize
                        currentPreCabSize = (ulong)facade.FileSize;
                    }
                    else // file fits in the current cab.
                    {
                        if (currentMediaRow == null)
                        {
                            // Create new cab and MediaRow
                            currentMediaRow = this.AddMediaSymbol(mediaTemplateRow, ++currentCabIndex);
                            mediaSymbolsByDiskId.Add(currentMediaRow.DiskId, currentMediaRow);
                            filesByCabinetMedia.Add(currentMediaRow, new List <FileFacade>());
                        }
                    }
                }

                // Associate current file with current cab.
                var cabinetFiles = filesByCabinetMedia[currentMediaRow];
                facade.DiskId = currentCabIndex;
                cabinetFiles.Add(facade);
            }

            // If there are uncompressed files and no MediaRow, create a default one.
            if (uncompressedFiles.Count > 0 && !this.Section.Symbols.OfType <MediaSymbol>().Any())
            {
                var defaultMediaRow = this.Section.AddSymbol(new MediaSymbol(null, new Identifier(AccessModifier.Private, 1))
                {
                    DiskId = 1,
                });

                mediaSymbolsByDiskId.Add(1, defaultMediaRow);
            }
        }
示例#3
0
        private static IntermediateSymbol GenerateSymbolFromRow(Wix3.Row row, Dictionary <int, Wix3.WixMediaRow> wixMediaByDiskId, Dictionary <string, Wix3.Row> componentsById, Dictionary <string, Wix3.Row> fontsById, Dictionary <string, Wix3.Row> bindPathsById, Dictionary <string, Wix3.Row> selfRegById, Dictionary <string, Wix3.Row> wixFileById, Dictionary <string, Wix3.Row> wixDirectoryById)
        {
            var name = row.Table.Name;

            switch (name)
            {
            case "_SummaryInformation":
                return(DefaultSymbolFromRow(typeof(SummaryInformationSymbol), row, columnZeroIsId: false));

            case "ActionText":
                return(DefaultSymbolFromRow(typeof(ActionTextSymbol), row, columnZeroIsId: false));

            case "AppId":
                return(DefaultSymbolFromRow(typeof(AppIdSymbol), row, columnZeroIsId: false));

            case "AppSearch":
                return(DefaultSymbolFromRow(typeof(AppSearchSymbol), row, columnZeroIsId: false));

            case "Billboard":
                return(DefaultSymbolFromRow(typeof(BillboardSymbol), row, columnZeroIsId: true));

            case "Binary":
                return(DefaultSymbolFromRow(typeof(BinarySymbol), row, columnZeroIsId: true));

            case "BindPath":
                return(null);

            case "CCPSearch":
                return(DefaultSymbolFromRow(typeof(CCPSearchSymbol), row, columnZeroIsId: true));

            case "Class":
                return(DefaultSymbolFromRow(typeof(ClassSymbol), row, columnZeroIsId: false));

            case "CompLocator":
                return(DefaultSymbolFromRow(typeof(CompLocatorSymbol), row, columnZeroIsId: false));

            case "Component":
            {
                var attributes = FieldAsNullableInt(row, 3);

                var location = ComponentLocation.LocalOnly;
                if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) == WindowsInstallerConstants.MsidbComponentAttributesSourceOnly)
                {
                    location = ComponentLocation.SourceOnly;
                }
                else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesOptional) == WindowsInstallerConstants.MsidbComponentAttributesOptional)
                {
                    location = ComponentLocation.Either;
                }

                var keyPath     = FieldAsString(row, 5);
                var keyPathType = String.IsNullOrEmpty(keyPath) ? ComponentKeyPathType.Directory : ComponentKeyPathType.File;
                if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) == WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath)
                {
                    keyPathType = ComponentKeyPathType.Registry;
                }
                else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) == WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource)
                {
                    keyPathType = ComponentKeyPathType.OdbcDataSource;
                }

                return(new ComponentSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        ComponentId = FieldAsString(row, 1),
                        DirectoryRef = FieldAsString(row, 2),
                        Condition = FieldAsString(row, 4),
                        KeyPath = keyPath,
                        Location = location,
                        DisableRegistryReflection = (attributes & WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection) == WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection,
                        NeverOverwrite = (attributes & WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite) == WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite,
                        Permanent = (attributes & WindowsInstallerConstants.MsidbComponentAttributesPermanent) == WindowsInstallerConstants.MsidbComponentAttributesPermanent,
                        SharedDllRefCount = (attributes & WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount) == WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount,
                        Shared = (attributes & WindowsInstallerConstants.MsidbComponentAttributesShared) == WindowsInstallerConstants.MsidbComponentAttributesShared,
                        Transitive = (attributes & WindowsInstallerConstants.MsidbComponentAttributesTransitive) == WindowsInstallerConstants.MsidbComponentAttributesTransitive,
                        UninstallWhenSuperseded = (attributes & WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence) == WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence,
                        Win64 = (attributes & WindowsInstallerConstants.MsidbComponentAttributes64bit) == WindowsInstallerConstants.MsidbComponentAttributes64bit,
                        KeyPathType = keyPathType,
                    });
            }

            case "Condition":
                return(DefaultSymbolFromRow(typeof(ConditionSymbol), row, columnZeroIsId: false));

            case "CreateFolder":
                return(DefaultSymbolFromRow(typeof(CreateFolderSymbol), row, columnZeroIsId: false));

            case "CustomAction":
            {
                var caType        = FieldAsInt(row, 1);
                var executionType = DetermineCustomActionExecutionType(caType);
                var sourceType    = DetermineCustomActionSourceType(caType);
                var targetType    = DetermineCustomActionTargetType(caType);

                return(new CustomActionSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        ExecutionType = executionType,
                        SourceType = sourceType,
                        Source = FieldAsString(row, 2),
                        TargetType = targetType,
                        Target = FieldAsString(row, 3),
                        Win64 = (caType & WindowsInstallerConstants.MsidbCustomActionType64BitScript) == WindowsInstallerConstants.MsidbCustomActionType64BitScript,
                        TSAware = (caType & WindowsInstallerConstants.MsidbCustomActionTypeTSAware) == WindowsInstallerConstants.MsidbCustomActionTypeTSAware,
                        Impersonate = (caType & WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate) != WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate,
                        IgnoreResult = (caType & WindowsInstallerConstants.MsidbCustomActionTypeContinue) == WindowsInstallerConstants.MsidbCustomActionTypeContinue,
                        Hidden = (caType & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) == WindowsInstallerConstants.MsidbCustomActionTypeHideTarget,
                        Async = (caType & WindowsInstallerConstants.MsidbCustomActionTypeAsync) == WindowsInstallerConstants.MsidbCustomActionTypeAsync,
                    });
            }

            case "Directory":
            {
                var id     = FieldAsString(row, 0);
                var splits = SplitDefaultDir(FieldAsString(row, 2));

                var symbol = new DirectorySymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, id))
                {
                    ParentDirectoryRef = FieldAsString(row, 1),
                    Name            = splits[0],
                    ShortName       = splits[1],
                    SourceName      = splits[2],
                    SourceShortName = splits[3]
                };

                if (wixDirectoryById.TryGetValue(id, out var wixDirectoryRow))
                {
                    symbol.ComponentGuidGenerationSeed = FieldAsString(wixDirectoryRow, 1);
                }

                return(symbol);
            }

            case "DrLocator":
                return(DefaultSymbolFromRow(typeof(DrLocatorSymbol), row, columnZeroIsId: false));

            case "DuplicateFile":
            {
                var splitName = FieldAsString(row, 3)?.Split('|');

                var symbol = new DuplicateFileSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                {
                    ComponentRef         = FieldAsString(row, 1),
                    FileRef              = FieldAsString(row, 2),
                    DestinationName      = splitName == null ? null : splitName.Length > 1 ? splitName[1] : splitName[0],
                    DestinationShortName = splitName == null ? null : splitName.Length > 1 ? splitName[0] : null,
                    DestinationFolder    = FieldAsString(row, 4)
                };

                return(symbol);
            }

            case "Error":
                return(DefaultSymbolFromRow(typeof(ErrorSymbol), row, columnZeroIsId: false));

            case "Extension":
                return(DefaultSymbolFromRow(typeof(ExtensionSymbol), row, columnZeroIsId: false));

            case "Feature":
            {
                var attributes     = FieldAsInt(row, 7);
                var installDefault = FeatureInstallDefault.Local;
                if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) == WindowsInstallerConstants.MsidbFeatureAttributesFollowParent)
                {
                    installDefault = FeatureInstallDefault.FollowParent;
                }
                else if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) == WindowsInstallerConstants.MsidbFeatureAttributesFavorSource)
                {
                    installDefault = FeatureInstallDefault.Source;
                }

                return(new FeatureSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        ParentFeatureRef = FieldAsString(row, 1),
                        Title = FieldAsString(row, 2),
                        Description = FieldAsString(row, 3),
                        Display = FieldAsInt(row, 4), // BUGBUGBUG: FieldAsNullableInt(row, 4),
                        Level = FieldAsInt(row, 5),
                        DirectoryRef = FieldAsString(row, 6),
                        DisallowAbsent = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent) == WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent,
                        DisallowAdvertise = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise,
                        InstallDefault = installDefault,
                        TypicalDefault = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise ? FeatureTypicalDefault.Advertise : FeatureTypicalDefault.Install,
                    });
            }

            case "FeatureComponents":
                return(DefaultSymbolFromRow(typeof(FeatureComponentsSymbol), row, columnZeroIsId: false));

            case "File":
            {
                var attributes = FieldAsNullableInt(row, 6);

                FileSymbolAttributes symbolAttributes = 0;
                symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesReadOnly) == WindowsInstallerConstants.MsidbFileAttributesReadOnly ? FileSymbolAttributes.ReadOnly : 0;
                symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesHidden) == WindowsInstallerConstants.MsidbFileAttributesHidden ? FileSymbolAttributes.Hidden : 0;
                symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesSystem) == WindowsInstallerConstants.MsidbFileAttributesSystem ? FileSymbolAttributes.System : 0;
                symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesVital) == WindowsInstallerConstants.MsidbFileAttributesVital ? FileSymbolAttributes.Vital : 0;
                symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesChecksum) == WindowsInstallerConstants.MsidbFileAttributesChecksum ? FileSymbolAttributes.Checksum : 0;
                symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed ? FileSymbolAttributes.Uncompressed : 0;
                symbolAttributes |= (attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed ? FileSymbolAttributes.Compressed : 0;

                var id        = FieldAsString(row, 0);
                var splitName = FieldAsString(row, 2).Split('|');

                var symbol = new FileSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, id))
                {
                    ComponentRef = FieldAsString(row, 1),
                    Name         = splitName.Length > 1 ? splitName[1] : splitName[0],
                    ShortName    = splitName.Length > 1 ? splitName[0] : null,
                    FileSize     = FieldAsInt(row, 3),
                    Version      = FieldAsString(row, 4),
                    Language     = FieldAsString(row, 5),
                    Attributes   = symbolAttributes
                };

                if (bindPathsById.TryGetValue(id, out var bindPathRow))
                {
                    symbol.BindPath = FieldAsString(bindPathRow, 1) ?? String.Empty;
                }

                if (fontsById.TryGetValue(id, out var fontRow))
                {
                    symbol.FontTitle = FieldAsString(fontRow, 1) ?? String.Empty;
                }

                if (selfRegById.TryGetValue(id, out var selfRegRow))
                {
                    symbol.SelfRegCost = FieldAsNullableInt(selfRegRow, 1) ?? 0;
                }

                if (wixFileById.TryGetValue(id, out var wixFileRow))
                {
                    symbol.DirectoryRef = FieldAsString(wixFileRow, 4);
                    symbol.DiskId       = FieldAsNullableInt(wixFileRow, 5) ?? 0;
                    symbol.Source       = new IntermediateFieldPathValue {
                        Path = FieldAsString(wixFileRow, 6)
                    };
                    symbol.PatchGroup      = FieldAsInt(wixFileRow, 8);
                    symbol.PatchAttributes = (PatchAttributeType)FieldAsInt(wixFileRow, 10);
                }

                return(symbol);
            }

            case "Font":
                return(null);

            case "Icon":
                return(DefaultSymbolFromRow(typeof(IconSymbol), row, columnZeroIsId: true));

            case "IniFile":
            {
                var splitName = FieldAsString(row, 1).Split('|');
                var action    = FieldAsInt(row, 6);

                var symbol = new IniFileSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                {
                    FileName      = splitName.Length > 1 ? splitName[1] : splitName[0],
                    ShortFileName = splitName.Length > 1 ? splitName[0] : null,
                    DirProperty   = FieldAsString(row, 2),
                    Section       = FieldAsString(row, 3),
                    Key           = FieldAsString(row, 4),
                    Value         = FieldAsString(row, 5),
                    Action        = action == 3 ? IniFileActionType.AddTag : action == 1 ? IniFileActionType.CreateLine : IniFileActionType.AddLine,
                    ComponentRef  = FieldAsString(row, 7),
                };

                return(symbol);
            }

            case "IniLocator":
            {
                var splitName = FieldAsString(row, 1).Split('|');

                var symbol = new IniLocatorSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                {
                    FileName      = splitName.Length > 1 ? splitName[1] : splitName[0],
                    ShortFileName = splitName.Length > 1 ? splitName[0] : null,
                    Section       = FieldAsString(row, 2),
                    Key           = FieldAsString(row, 3),
                    Field         = FieldAsInt(row, 4),
                    Type          = FieldAsInt(row, 5),
                };

                return(symbol);
            }

            case "LockPermissions":
                return(DefaultSymbolFromRow(typeof(LockPermissionsSymbol), row, columnZeroIsId: false));

            case "Media":
            {
                var diskId = FieldAsInt(row, 0);
                var symbol = new MediaSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, diskId))
                {
                    DiskId       = diskId,
                    LastSequence = FieldAsNullableInt(row, 1),
                    DiskPrompt   = FieldAsString(row, 2),
                    Cabinet      = FieldAsString(row, 3),
                    VolumeLabel  = FieldAsString(row, 4),
                    Source       = FieldAsString(row, 5)
                };

                if (wixMediaByDiskId.TryGetValue(diskId, out var wixMediaRow))
                {
                    var compressionLevel = FieldAsString(wixMediaRow, 1);

                    symbol.CompressionLevel = String.IsNullOrEmpty(compressionLevel) ? null : (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), compressionLevel, true);
                    symbol.Layout           = wixMediaRow.Layout;
                }

                return(symbol);
            }

            case "MIME":
                return(DefaultSymbolFromRow(typeof(MIMESymbol), row, columnZeroIsId: false));

            case "ModuleIgnoreTable":
                return(DefaultSymbolFromRow(typeof(ModuleIgnoreTableSymbol), row, columnZeroIsId: true));

            case "MoveFile":
                return(DefaultSymbolFromRow(typeof(MoveFileSymbol), row, columnZeroIsId: true));

            case "MsiAssembly":
            {
                var componentId = FieldAsString(row, 0);
                if (componentsById.TryGetValue(componentId, out var componentRow))
                {
                    return(new AssemblySymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(componentRow, 5)))
                        {
                            ComponentRef = componentId,
                            FeatureRef = FieldAsString(row, 1),
                            ManifestFileRef = FieldAsString(row, 2),
                            ApplicationFileRef = FieldAsString(row, 3),
                            Type = FieldAsNullableInt(row, 4) == 1 ? AssemblyType.Win32Assembly : AssemblyType.DotNetAssembly,
                        });
                }

                return(null);
            }

            case "MsiLockPermissionsEx":
                return(DefaultSymbolFromRow(typeof(MsiLockPermissionsExSymbol), row, columnZeroIsId: true));

            case "MsiShortcutProperty":
                return(DefaultSymbolFromRow(typeof(MsiShortcutPropertySymbol), row, columnZeroIsId: true));

            case "ODBCDataSource":
                return(DefaultSymbolFromRow(typeof(ODBCDataSourceSymbol), row, columnZeroIsId: true));

            case "ODBCDriver":
                return(DefaultSymbolFromRow(typeof(ODBCDriverSymbol), row, columnZeroIsId: true));

            case "ODBCTranslator":
                return(DefaultSymbolFromRow(typeof(ODBCTranslatorSymbol), row, columnZeroIsId: true));

            case "ProgId":
                return(DefaultSymbolFromRow(typeof(ProgIdSymbol), row, columnZeroIsId: false));

            case "Property":
                return(DefaultSymbolFromRow(typeof(PropertySymbol), row, columnZeroIsId: true));

            case "PublishComponent":
                return(DefaultSymbolFromRow(typeof(PublishComponentSymbol), row, columnZeroIsId: false));

            case "Registry":
            {
                var value       = FieldAsString(row, 4);
                var valueType   = RegistryValueType.String;
                var valueAction = RegistryValueActionType.Write;

                if (!String.IsNullOrEmpty(value))
                {
                    if (value.StartsWith("#x", StringComparison.Ordinal))
                    {
                        valueType = RegistryValueType.Binary;
                        value     = value.Substring(2);
                    }
                    else if (value.StartsWith("#%", StringComparison.Ordinal))
                    {
                        valueType = RegistryValueType.Expandable;
                        value     = value.Substring(2);
                    }
                    else if (value.StartsWith("#", StringComparison.Ordinal))
                    {
                        valueType = RegistryValueType.Integer;
                        value     = value.Substring(1);
                    }
                    else if (value.StartsWith("[~]", StringComparison.Ordinal) && value.EndsWith("[~]", StringComparison.Ordinal))
                    {
                        value       = value.Substring(3, value.Length - 6);
                        valueType   = RegistryValueType.MultiString;
                        valueAction = RegistryValueActionType.Write;
                    }
                    else if (value.StartsWith("[~]", StringComparison.Ordinal))
                    {
                        value       = value.Substring(3);
                        valueType   = RegistryValueType.MultiString;
                        valueAction = RegistryValueActionType.Append;
                    }
                    else if (value.EndsWith("[~]", StringComparison.Ordinal))
                    {
                        value       = value.Substring(0, value.Length - 3);
                        valueType   = RegistryValueType.MultiString;
                        valueAction = RegistryValueActionType.Prepend;
                    }
                }

                return(new RegistrySymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        Root = (RegistryRootType)FieldAsInt(row, 1),
                        Key = FieldAsString(row, 2),
                        Name = FieldAsString(row, 3),
                        Value = value,
                        ComponentRef = FieldAsString(row, 5),
                        ValueAction = valueAction,
                        ValueType = valueType,
                    });
            }

            case "RegLocator":
            {
                var type = FieldAsInt(row, 4);

                return(new RegLocatorSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        Root = (RegistryRootType)FieldAsInt(row, 1),
                        Key = FieldAsString(row, 2),
                        Name = FieldAsString(row, 3),
                        Type = (RegLocatorType)(type & 0xF),
                        Win64 = (type & WindowsInstallerConstants.MsidbLocatorType64bit) == WindowsInstallerConstants.MsidbLocatorType64bit
                    });
            }

            case "RemoveFile":
            {
                var splitName   = FieldAsString(row, 2).Split('|');
                var installMode = FieldAsInt(row, 4);

                return(new RemoveFileSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        ComponentRef = FieldAsString(row, 1),
                        FileName = splitName.Length > 1 ? splitName[1] : splitName[0],
                        ShortFileName = splitName.Length > 1 ? splitName[0] : null,
                        DirPropertyRef = FieldAsString(row, 3),
                        OnInstall = (installMode & WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall) == WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall ? (bool?)true : null,
                        OnUninstall = (installMode & WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove) == WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove ? (bool?)true : null
                    });
            }

            case "RemoveRegistry":
            {
                return(new RemoveRegistrySymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        Action = RemoveRegistryActionType.RemoveOnInstall,
                        Root = (RegistryRootType)FieldAsInt(row, 1),
                        Key = FieldAsString(row, 2),
                        Name = FieldAsString(row, 3),
                        ComponentRef = FieldAsString(row, 4),
                    });
            }

            case "ReserveCost":
                return(DefaultSymbolFromRow(typeof(ReserveCostSymbol), row, columnZeroIsId: true));

            case "SelfReg":
                return(null);

            case "ServiceControl":
            {
                var events = FieldAsInt(row, 2);
                var wait   = FieldAsNullableInt(row, 4);
                return(new ServiceControlSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        Name = FieldAsString(row, 1),
                        Arguments = FieldAsString(row, 3),
                        Wait = !wait.HasValue || wait.Value == 1,
                        ComponentRef = FieldAsString(row, 5),
                        InstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventDelete) == WindowsInstallerConstants.MsidbServiceControlEventDelete,
                        UninstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete) == WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete,
                        InstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventStart) == WindowsInstallerConstants.MsidbServiceControlEventStart,
                        UninstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStart) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStart,
                        InstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventStop) == WindowsInstallerConstants.MsidbServiceControlEventStop,
                        UninstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStop) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStop,
                    });
            }

            case "ServiceInstall":
                return(DefaultSymbolFromRow(typeof(ServiceInstallSymbol), row, columnZeroIsId: true));

            case "Shortcut":
            {
                var splitName = FieldAsString(row, 2).Split('|');

                return(new ShortcutSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        DirectoryRef = FieldAsString(row, 1),
                        Name = splitName.Length > 1 ? splitName[1] : splitName[0],
                        ShortName = splitName.Length > 1 ? splitName[0] : null,
                        ComponentRef = FieldAsString(row, 3),
                        Target = FieldAsString(row, 4),
                        Arguments = FieldAsString(row, 5),
                        Description = FieldAsString(row, 6),
                        Hotkey = FieldAsNullableInt(row, 7),
                        IconRef = FieldAsString(row, 8),
                        IconIndex = FieldAsNullableInt(row, 9),
                        Show = (ShortcutShowType?)FieldAsNullableInt(row, 10),
                        WorkingDirectory = FieldAsString(row, 11),
                        DisplayResourceDll = FieldAsString(row, 12),
                        DisplayResourceId = FieldAsNullableInt(row, 13),
                        DescriptionResourceDll = FieldAsString(row, 14),
                        DescriptionResourceId = FieldAsNullableInt(row, 15),
                    });
            }

            case "Signature":
                return(DefaultSymbolFromRow(typeof(SignatureSymbol), row, columnZeroIsId: true));

            case "UIText":
                return(DefaultSymbolFromRow(typeof(UITextSymbol), row, columnZeroIsId: true));

            case "Upgrade":
            {
                var attributes = FieldAsInt(row, 4);
                return(new UpgradeSymbol(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
                    {
                        UpgradeCode = FieldAsString(row, 0),
                        VersionMin = FieldAsString(row, 1),
                        VersionMax = FieldAsString(row, 2),
                        Language = FieldAsString(row, 3),
                        Remove = FieldAsString(row, 5),
                        ActionProperty = FieldAsString(row, 6),
                        MigrateFeatures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures) == WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures,
                        OnlyDetect = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect,
                        IgnoreRemoveFailures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure) == WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure,
                        VersionMinInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive,
                        VersionMaxInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive,
                        ExcludeLanguages = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive,
                    });
            }

            case "Verb":
                return(DefaultSymbolFromRow(typeof(VerbSymbol), row, columnZeroIsId: false));

            case "WixAction":
            {
                var sequenceTable = FieldAsString(row, 0);
                return(new WixActionSymbol(SourceLineNumber4(row.SourceLineNumbers))
                    {
                        SequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), sequenceTable == "AdvtExecuteSequence" ? nameof(SequenceTable.AdvertiseExecuteSequence) : sequenceTable),
                        Action = FieldAsString(row, 1),
                        Condition = FieldAsString(row, 2),
                        Sequence = FieldAsNullableInt(row, 3),
                        Before = FieldAsString(row, 4),
                        After = FieldAsString(row, 5),
                        Overridable = FieldAsNullableInt(row, 6) != 0,
                    });
            }

            case "WixBootstrapperApplication":
                return(DefaultSymbolFromRow(typeof(WixBootstrapperApplicationSymbol), row, columnZeroIsId: true));

            case "WixBundleContainer":
                return(DefaultSymbolFromRow(typeof(WixBundleContainerSymbol), row, columnZeroIsId: true));

            case "WixBundleVariable":
                return(DefaultSymbolFromRow(typeof(WixBundleVariableSymbol), row, columnZeroIsId: true));

            case "WixChainItem":
                return(DefaultSymbolFromRow(typeof(WixChainItemSymbol), row, columnZeroIsId: true));

            case "WixCustomTable":
                return(DefaultSymbolFromRow(typeof(WixCustomTableSymbol), row, columnZeroIsId: true));

            case "WixDirectory":
                return(null);

            case "WixFile":
                return(null);

            case "WixInstanceTransforms":
                return(DefaultSymbolFromRow(typeof(WixInstanceTransformsSymbol), row, columnZeroIsId: true));

            case "WixMedia":
                return(null);

            case "WixMerge":
                return(DefaultSymbolFromRow(typeof(WixMergeSymbol), row, columnZeroIsId: true));

            case "WixPatchBaseline":
                return(DefaultSymbolFromRow(typeof(WixPatchBaselineSymbol), row, columnZeroIsId: true));

            case "WixProperty":
            {
                var attributes = FieldAsInt(row, 1);
                return(new WixPropertySymbol(SourceLineNumber4(row.SourceLineNumbers))
                    {
                        PropertyRef = FieldAsString(row, 0),
                        Admin = (attributes & 0x1) == 0x1,
                        Hidden = (attributes & 0x2) == 0x2,
                        Secure = (attributes & 0x4) == 0x4,
                    });
            }

            case "WixSuppressModularization":
                return(DefaultSymbolFromRow(typeof(WixSuppressModularizationSymbol), row, columnZeroIsId: true));

            case "WixUI":
                return(DefaultSymbolFromRow(typeof(WixUISymbol), row, columnZeroIsId: true));

            case "WixVariable":
                return(DefaultSymbolFromRow(typeof(WixVariableSymbol), row, columnZeroIsId: true));

            default:
                return(GenericSymbolFromCustomRow(row, columnZeroIsId: false));
            }
        }
 /// <summary>
 /// See <see cref="IWindowsInstallerBackendBinderExtension.PreBackendBind(IBindContext)"/>
 /// </summary>
 public virtual string ResolveMedia(MediaSymbol mediaRow, string mediaLayoutDirectory, string layoutDirectory) => null;
        public void Execute()
        {
            var mediaRows = this.Section.Symbols.OfType <MediaSymbol>().ToDictionary(t => t.DiskId);

            // Calculate sequence numbers and media disk id layout for all file media information objects.
            if (SectionType.Module == this.Section.Type)
            {
                var lastSequence = 0;

                foreach (var facade in this.FileFacades)
                {
                    facade.Sequence = ++lastSequence;
                }
            }
            else
            {
                var         lastSequence = 0;
                MediaSymbol mediaSymbol  = null;
                var         patchGroups  = new Dictionary <int, List <FileFacade> >();

                // sequence the non-patch-added files
                foreach (var facade in this.FileFacades)
                {
                    if (null == mediaSymbol)
                    {
                        mediaSymbol = mediaRows[facade.DiskId];
                        if (SectionType.Patch == this.Section.Type)
                        {
                            // patch Media cannot start at zero
                            lastSequence = mediaSymbol.LastSequence ?? 1;
                        }
                    }
                    else if (mediaSymbol.DiskId != facade.DiskId)
                    {
                        mediaSymbol.LastSequence = lastSequence;
                        mediaSymbol = mediaRows[facade.DiskId];
                    }

                    if (facade.PatchGroup.HasValue)
                    {
                        if (patchGroups.TryGetValue(facade.PatchGroup.Value, out var patchGroup))
                        {
                            patchGroup = new List <FileFacade>();
                            patchGroups.Add(facade.PatchGroup.Value, patchGroup);
                        }

                        patchGroup.Add(facade);
                    }
                    else if (!facade.FromModule)
                    {
                        facade.Sequence = ++lastSequence;
                    }
                }

                if (null != mediaSymbol)
                {
                    mediaSymbol.LastSequence = lastSequence;
                    mediaSymbol = null;
                }

                // sequence the patch-added files
                foreach (var patchGroup in patchGroups.Values)
                {
                    foreach (var facade in patchGroup)
                    {
                        if (null == mediaSymbol)
                        {
                            mediaSymbol = mediaRows[facade.DiskId];
                        }
                        else if (mediaSymbol.DiskId != facade.DiskId)
                        {
                            mediaSymbol.LastSequence = lastSequence;
                            mediaSymbol = mediaRows[facade.DiskId];
                        }

                        facade.Sequence = ++lastSequence;
                    }
                }

                if (null != mediaSymbol)
                {
                    mediaSymbol.LastSequence = lastSequence;
                }
            }
        }
示例#6
0
        /// <summary>
        /// Creates a work item to create a cabinet.
        /// </summary>
        /// <param name="output">Output for the current database.</param>
        /// <param name="cabinetDir">Directory to create cabinet in.</param>
        /// <param name="mediaSymbol">Media symbol containing information about the cabinet.</param>
        /// <param name="fileFacades">Collection of files in this cabinet.</param>
        /// <returns>created CabinetWorkItem object</returns>
        private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData output, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable <FileFacade> fileFacades)
        {
            CabinetWorkItem cabinetWorkItem  = null;
            var             tempCabinetFileX = Path.Combine(this.IntermediateFolder, mediaSymbol.Cabinet);

            // check for an empty cabinet
            if (!fileFacades.Any())
            {
                // Remove the leading '#' from the embedded cabinet name to make the warning easier to understand
                var cabinetName = mediaSymbol.Cabinet.TrimStart('#');

                // If building a patch, remind them to run -p for torch.
                if (OutputType.Patch == output.Type)
                {
                    this.Messaging.Write(WarningMessages.EmptyCabinet(mediaSymbol.SourceLineNumbers, cabinetName, true));
                }
                else
                {
                    this.Messaging.Write(WarningMessages.EmptyCabinet(mediaSymbol.SourceLineNumbers, cabinetName));
                }
            }

            var cabinetResolver = new CabinetResolver(this.ServiceProvider, this.CabCachePath, this.BackendExtensions);

            var resolvedCabinet = cabinetResolver.ResolveCabinet(tempCabinetFileX, fileFacades);

            // create a cabinet work item if it's not being skipped
            if (CabinetBuildOption.BuildAndCopy == resolvedCabinet.BuildOption || CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption)
            {
                // Default to the threshold for best smartcabbing (makes smallest cabinet).
                cabinetWorkItem = new CabinetWorkItem(fileFacades, resolvedCabinet.Path, maxThreshold: 0, compressionLevel, this.ModularizationSuffix /*, this.FileManager*/);
            }
            else // reuse the cabinet from the cabinet cache.
            {
                this.Messaging.Write(VerboseMessages.ReusingCabCache(mediaSymbol.SourceLineNumbers, mediaSymbol.Cabinet, resolvedCabinet.Path));

                try
                {
                    // Ensure the cached cabinet timestamp is current to prevent perpetual incremental builds. The
                    // problematic scenario goes like this. Imagine two cabinets in the cache. Update a file that
                    // goes into one of the cabinets. One cabinet will get rebuilt, the other will be copied from
                    // the cache. Now the file (an input) has a newer timestamp than the reused cabient (an output)
                    // causing the project to look like it perpetually needs a rebuild until all of the reused
                    // cabinets get newer timestamps.
                    File.SetLastWriteTime(resolvedCabinet.Path, DateTime.Now);
                }
                catch (Exception e)
                {
                    this.Messaging.Write(WarningMessages.CannotUpdateCabCache(mediaSymbol.SourceLineNumbers, resolvedCabinet.Path, e.Message));
                }
            }

            var trackResolvedCabinet = this.BackendHelper.TrackFile(resolvedCabinet.Path, TrackedFileType.Intermediate, mediaSymbol.SourceLineNumbers);

            this.trackedFiles.Add(trackResolvedCabinet);

            if (mediaSymbol.Cabinet.StartsWith("#", StringComparison.Ordinal))
            {
                var streamsTable = output.EnsureTable(this.TableDefinitions["_Streams"]);

                var streamRow = streamsTable.CreateRow(mediaSymbol.SourceLineNumbers);
                streamRow[0] = mediaSymbol.Cabinet.Substring(1);
                streamRow[1] = resolvedCabinet.Path;
            }
            else
            {
                var trackDestination = this.BackendHelper.TrackFile(Path.Combine(cabinetDir, mediaSymbol.Cabinet), TrackedFileType.Final, mediaSymbol.SourceLineNumbers);
                this.trackedFiles.Add(trackDestination);

                var transfer = this.BackendHelper.CreateFileTransfer(resolvedCabinet.Path, trackDestination.Path, resolvedCabinet.BuildOption == CabinetBuildOption.BuildAndMove, mediaSymbol.SourceLineNumbers);
                this.fileTransfers.Add(transfer);
            }

            return(cabinetWorkItem);
        }