private static void SetSymbolFieldsFromRow(Wix3.Row row, IntermediateSymbol symbol, bool columnZeroIsId) { var offset = 0; if (columnZeroIsId) { offset = 1; } for (var i = offset; i < row.Fields.Length; ++i) { var column = row.Fields[i].Column; switch (column.Type) { case Wix3.ColumnType.String: case Wix3.ColumnType.Localized: case Wix3.ColumnType.Object: case Wix3.ColumnType.Preserved: symbol.Set(i - offset, FieldAsString(row, i)); break; case Wix3.ColumnType.Number: int?nullableValue = FieldAsNullableInt(row, i); // TODO: Consider whether null values should be coerced to their default value when // a column is not nullable. For now, just pass through the null. //int value = FieldAsInt(row, i); //symbol.Set(i - offset, column.IsNullable ? nullableValue : value); symbol.Set(i - offset, nullableValue); break; case Wix3.ColumnType.Unknown: break; } } }
public RollbackBoundaryInfo(Row row) { this.Id = row[0].ToString(); this.Vital = (null == row[10] || 1 == (int)row[10]) ? YesNoType.Yes : YesNoType.No; this.SourceLineNumbers = row.SourceLineNumbers; }
private static IntermediateSymbol DefaultSymbolFromRow(Type symbolType, Wix3.Row row, bool columnZeroIsId) { var symbol = Activator.CreateInstance(symbolType) as IntermediateSymbol; SetSymbolFieldsFromRow(row, symbol, columnZeroIsId); symbol.SourceLineNumbers = SourceLineNumber4(row.SourceLineNumbers); return(symbol); }
/// <summary> /// Creates a new output row. /// </summary> /// <param name="row">Table row to wrap.</param> /// <param name="sectionId">If not null, the sectionId attribute will be set on this row in the output.</param> public OutputRow(Row row, string sectionId) { if (null == row) { throw new ArgumentNullException("row"); } this.row = row; this.row.SectionId = sectionId; }
private static IntermediateSymbol DefaultSymbolFromRow(Type symbolType, Wix3.Row row, bool columnZeroIsId) { var id = columnZeroIsId ? GetIdentifierForRow(row) : null; var createSymbol = symbolType.GetConstructor(new[] { typeof(SourceLineNumber), typeof(Identifier) }); var symbol = (IntermediateSymbol)createSymbol.Invoke(new object[] { SourceLineNumber4(row.SourceLineNumbers), id }); SetSymbolFieldsFromRow(row, symbol, columnZeroIsId); return(symbol); }
public ChainInfo(Row row) { BundleChainAttributes attributes = (null == row[0]) ? BundleChainAttributes.None : (BundleChainAttributes)row[0]; this.DisableRollback = (BundleChainAttributes.DisableRollback == (attributes & BundleChainAttributes.DisableRollback)); this.DisableSystemRestore = (BundleChainAttributes.DisableSystemRestore == (attributes & BundleChainAttributes.DisableSystemRestore)); this.ParallelCache = (BundleChainAttributes.ParallelCache == (attributes & BundleChainAttributes.ParallelCache)); this.Packages = new List<ChainPackageInfo>(); this.RollbackBoundaries = new List<RollbackBoundaryInfo>(); this.SourceLineNumbers = row.SourceLineNumbers; }
private static IntermediateSymbol GenericSymbolFromCustomRow(Wix3.Row row, bool columnZeroIsId) { var columnDefinitions = row.Table.Definition.Columns.Cast <Wix3.ColumnDefinition>(); var fieldDefinitions = columnDefinitions.Select(columnDefinition => new IntermediateFieldDefinition(columnDefinition.Name, ColumnType3ToIntermediateFieldType4(columnDefinition.Type))).ToArray(); var symbolDefinition = new IntermediateSymbolDefinition(row.Table.Name, fieldDefinitions, null); var symbol = new IntermediateSymbol(symbolDefinition, SourceLineNumber4(row.SourceLineNumbers)); SetSymbolFieldsFromRow(row, symbol, columnZeroIsId); return(symbol); }
private static int?FieldAsNullableInt(Wix3.Row row, int column) { var field = row.Fields[column]; if (field.Data == null) { return(null); } else { return(Convert.ToInt32(field.Data)); } }
private static IntermediateSymbol GenericSymbolFromCustomRow(Wix3.Row row, bool columnZeroIsId) { var columnDefinitions = row.Table.Definition.Columns.Cast <Wix3.ColumnDefinition>(); var fieldDefinitions = columnDefinitions.Select(columnDefinition => new IntermediateFieldDefinition(columnDefinition.Name, ColumnType3ToIntermediateFieldType4(columnDefinition.Type))).ToArray(); var symbolDefinition = new IntermediateSymbolDefinition(row.Table.Name, fieldDefinitions, null); var id = columnZeroIsId ? GetIdentifierForRow(row) : null; var createSymbol = typeof(IntermediateSymbol).GetConstructor(new[] { typeof(IntermediateSymbolDefinition), typeof(SourceLineNumber), typeof(Identifier) }); var symbol = (IntermediateSymbol)createSymbol.Invoke(new object[] { symbolDefinition, SourceLineNumber4(row.SourceLineNumbers), id }); SetSymbolFieldsFromRow(row, symbol, columnZeroIsId); return(symbol); }
private static Identifier GetIdentifierForRow(Wix3.Row row) { var column = row.Fields[0].Column; switch (column.Type) { case Wix3.ColumnType.String: case Wix3.ColumnType.Localized: case Wix3.ColumnType.Object: case Wix3.ColumnType.Preserved: return(new Identifier(AccessModifier.Public, (string)row.Fields[0].Data)); case Wix3.ColumnType.Number: return(new Identifier(AccessModifier.Public, FieldAsInt(row, 0))); default: return(null); } }
private Row CompareRows(Table targetTable, Row targetRow, Row updatedRow, out RowOperation operation, out bool keepRow) { Row comparedRow = null; keepRow = false; operation = RowOperation.None; if (null == targetRow ^ null == updatedRow) { if (null == targetRow) { operation = updatedRow.Operation = RowOperation.Add; comparedRow = updatedRow; } else if (null == updatedRow) { operation = targetRow.Operation = RowOperation.Delete; targetRow.SectionId = targetRow.SectionId + sectionDelimiter; comparedRow = targetRow; keepRow = true; } } else // possibly modified { updatedRow.Operation = RowOperation.None; if (!this.suppressKeepingSpecialRows && "_SummaryInformation" == targetTable.Name) { // ignore rows that shouldn't be in a transform if (Enum.IsDefined(typeof(SummaryInformation.Transform), (int)updatedRow[0])) { updatedRow.SectionId = targetRow.SectionId + sectionDelimiter + updatedRow.SectionId; comparedRow = updatedRow; keepRow = true; operation = RowOperation.Modify; } } else { if (this.preserveUnchangedRows) { keepRow = true; } for (int i = 0; i < updatedRow.Fields.Length; i++) { ColumnDefinition columnDefinition = updatedRow.Fields[i].Column; if (!columnDefinition.IsPrimaryKey) { bool modified = false; if (i >= targetRow.Fields.Length) { columnDefinition.Added = true; modified = true; } else if (ColumnType.Number == columnDefinition.Type && !columnDefinition.IsLocalizable) { if (null == targetRow[i] ^ null == updatedRow[i]) { modified = true; } else if (null != targetRow[i] && null != updatedRow[i]) { modified = ((int)targetRow[i] != (int)updatedRow[i]); } } else if (ColumnType.Preserved == columnDefinition.Type) { updatedRow.Fields[i].PreviousData = (string)targetRow.Fields[i].Data; // keep rows containing preserved fields so the historical data is available to the binder keepRow = !this.suppressKeepingSpecialRows; } else if (ColumnType.Object == columnDefinition.Type) { ObjectField targetObjectField = (ObjectField)targetRow.Fields[i]; ObjectField updatedObjectField = (ObjectField)updatedRow.Fields[i]; updatedObjectField.PreviousCabinetFileId = targetObjectField.CabinetFileId; updatedObjectField.PreviousBaseUri = targetObjectField.BaseUri; // always keep a copy of the previous data even if they are identical // This makes diff.wixmst clean and easier to control patch logic updatedObjectField.PreviousData = (string)targetObjectField.Data; // always remember the unresolved data for target build updatedObjectField.UnresolvedPreviousData = (string)targetObjectField.UnresolvedData; // keep rows containing object fields so the files can be compared in the binder keepRow = !this.suppressKeepingSpecialRows; } else { modified = ((string)targetRow[i] != (string)updatedRow[i]); } if (modified) { if (null != updatedRow.Fields[i].PreviousData) { updatedRow.Fields[i].PreviousData = targetRow.Fields[i].Data.ToString(); } updatedRow.Fields[i].Modified = true; operation = updatedRow.Operation = RowOperation.Modify; keepRow = true; } } } if (keepRow) { comparedRow = updatedRow; comparedRow.SectionId = targetRow.SectionId + sectionDelimiter + updatedRow.SectionId; } } } return comparedRow; }
public WixProductSearchInfo(Row row) : this((string)row[0], (string)row[1], (int)row[2]) { }
public ContainerInfo(Row row, BinderFileManager fileManager) : this((string)row[0], (string)row[1], (string)row[2], (string)row[3], fileManager) { this.SourceLineNumbers = row.SourceLineNumbers; }
/// <summary> /// Creates a shallow copy of a row from another row. /// </summary> /// <param name="source">The row the data is copied from.</param> protected Row(Row source) { this.table = source.table; this.tableDefinition = source.tableDefinition; this.rowNumber = source.rowNumber; this.operation = source.operation; this.sectionId = source.sectionId; this.sourceLineNumbers = source.sourceLineNumbers; this.fields = source.fields; this.symbol = source.symbol; }
/// <summary> /// Adds a row to the collection. /// </summary> /// <param name="row">Row to add to collection.</param> public void Add(Row row) { this.collection.Add(row); }
private RowCollection CompareTables(Output targetOutput, Table targetTable, Table updatedTable, out TableOperation operation) { RowCollection rows = new RowCollection(); operation = TableOperation.None; // dropped tables if (null == updatedTable ^ null == targetTable) { if (null == targetTable) { operation = TableOperation.Add; rows.AddRange(updatedTable.Rows); } else if (null == updatedTable) { operation = TableOperation.Drop; } } else // possibly modified tables { SortedList updatedPrimaryKeys = new SortedList(); SortedList targetPrimaryKeys = new SortedList(); // compare the table definitions if (0 != targetTable.Definition.CompareTo(updatedTable.Definition)) { // continue to the next table; may be more mismatches this.OnMessage(WixErrors.DatabaseSchemaMismatch(targetOutput.SourceLineNumbers, targetTable.Name)); } else { this.IndexPrimaryKeys(targetTable, targetPrimaryKeys, updatedTable, updatedPrimaryKeys); // diff the target and updated rows foreach (DictionaryEntry targetPrimaryKeyEntry in targetPrimaryKeys) { string targetPrimaryKey = (string)targetPrimaryKeyEntry.Key; bool keepRow = false; RowOperation rowOperation = RowOperation.None; Row compared = this.CompareRows(targetTable, targetPrimaryKeyEntry.Value as Row, updatedPrimaryKeys[targetPrimaryKey] as Row, out rowOperation, out keepRow); if (keepRow) { rows.Add(compared); } } // find the inserted rows foreach (DictionaryEntry updatedPrimaryKeyEntry in updatedPrimaryKeys) { string updatedPrimaryKey = (string)updatedPrimaryKeyEntry.Key; if (!targetPrimaryKeys.Contains(updatedPrimaryKey)) { Row updatedRow = (Row)updatedPrimaryKeyEntry.Value; updatedRow.Operation = RowOperation.Add; updatedRow.SectionId = sectionDelimiter + updatedRow.SectionId; rows.Add(updatedRow); } } } } return(rows); }
private void UpdateTransformSummaryInformationTable(Table summaryInfoTable, TransformFlags validationFlags) { // calculate the minimum version of MSI required to process the transform int targetMin; int updatedMin; int minimumVersion = 100; if (Int32.TryParse(this.transformSummaryInfo.TargetMinimumVersion, out targetMin) && Int32.TryParse(this.transformSummaryInfo.UpdatedMinimumVersion, out updatedMin)) { minimumVersion = Math.Max(targetMin, updatedMin); } Hashtable summaryRows = new Hashtable(summaryInfoTable.Rows.Count); foreach (Row row in summaryInfoTable.Rows) { summaryRows[row[0]] = row; if ((int)SummaryInformation.Transform.CodePage == (int)row[0]) { row.Fields[1].Data = this.transformSummaryInfo.UpdatedSummaryInfoCodepage; row.Fields[1].PreviousData = this.transformSummaryInfo.TargetSummaryInfoCodepage; } else if ((int)SummaryInformation.Transform.TargetPlatformAndLanguage == (int)row[0]) { row[1] = this.transformSummaryInfo.TargetPlatformAndLanguage; } else if ((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage == (int)row[0]) { row[1] = this.transformSummaryInfo.UpdatedPlatformAndLanguage; } else if ((int)SummaryInformation.Transform.ProductCodes == (int)row[0]) { row[1] = String.Concat(this.transformSummaryInfo.TargetProductCode, this.transformSummaryInfo.TargetProductVersion, ';', this.transformSummaryInfo.UpdatedProductCode, this.transformSummaryInfo.UpdatedProductVersion, ';', this.transformSummaryInfo.TargetUpgradeCode); } else if ((int)SummaryInformation.Transform.InstallerRequirement == (int)row[0]) { row[1] = minimumVersion.ToString(CultureInfo.InvariantCulture); } else if ((int)SummaryInformation.Transform.Security == (int)row[0]) { row[1] = "4"; } } if (!summaryRows.Contains((int)SummaryInformation.Transform.TargetPlatformAndLanguage)) { Row summaryRow = summaryInfoTable.CreateRow(null); summaryRow[0] = (int)SummaryInformation.Transform.TargetPlatformAndLanguage; summaryRow[1] = this.transformSummaryInfo.TargetPlatformAndLanguage; } if (!summaryRows.Contains((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage)) { Row summaryRow = summaryInfoTable.CreateRow(null); summaryRow[0] = (int)SummaryInformation.Transform.UpdatedPlatformAndLanguage; summaryRow[1] = this.transformSummaryInfo.UpdatedPlatformAndLanguage; } if (!summaryRows.Contains((int)SummaryInformation.Transform.ValidationFlags)) { Row summaryRow = summaryInfoTable.CreateRow(null); summaryRow[0] = (int)SummaryInformation.Transform.ValidationFlags; summaryRow[1] = ((int)validationFlags).ToString(CultureInfo.InvariantCulture); } if (!summaryRows.Contains((int)SummaryInformation.Transform.InstallerRequirement)) { Row summaryRow = summaryInfoTable.CreateRow(null); summaryRow[0] = (int)SummaryInformation.Transform.InstallerRequirement; summaryRow[1] = minimumVersion.ToString(CultureInfo.InvariantCulture); } if (!summaryRows.Contains((int)SummaryInformation.Transform.Security)) { Row summaryRow = summaryInfoTable.CreateRow(null); summaryRow[0] = (int)SummaryInformation.Transform.Security; summaryRow[1] = "4"; } }
/// <summary> /// Gets the validation rows for the table. /// </summary> /// <param name="validationTable">Defintion for the validation table.</param> /// <returns>Collection of output rows for the validation table.</returns> internal OutputRowCollection GetValidationRows(TableDefinition validationTable) { OutputRowCollection outputRows = new OutputRowCollection(); foreach (ColumnDefinition columnDef in this.columns) { if (columnDef.IsUnreal) { continue; } Row row = new Row(validationTable); row[0] = this.name; row[1] = columnDef.Name; if (columnDef.IsNullable) { row[2] = "Y"; } else { row[2] = "N"; } if (columnDef.IsMinValueSet) { row[3] = columnDef.MinValue; } if (columnDef.IsMaxValueSet) { row[4] = columnDef.MaxValue; } row[5] = columnDef.KeyTable; if (columnDef.IsKeyColumnSet) { row[6] = columnDef.KeyColumn; } if (ColumnCategory.Unknown != columnDef.Category) { row[7] = columnDef.Category.ToString(); } row[8] = columnDef.Possibilities; row[9] = columnDef.Description; outputRows.Add(new OutputRow(row)); } return outputRows; }
public void AddWixSearchRowInfo(Row row) { Debug.Assert((string)row[0] == Id); Variable = (string)row[1]; Condition = (string)row[2]; }
public WixRegistrySearchInfo(Row row) : this((string)row[0], (int)row[1], (string)row[2], (string)row[3], (int)row[4]) { }
/// <summary> /// Set an MsiAssemblyName row. If it was directly authored, override the value, otherwise /// create a new row. /// </summary> /// <param name="assemblyNameOutputTable">MsiAssemblyName output table.</param> /// <param name="fileRow">FileRow containing the assembly read for the MsiAssemblyName row.</param> /// <param name="name">MsiAssemblyName name.</param> /// <param name="value">MsiAssemblyName value.</param> private void SetMsiAssemblyName(OutputTable assemblyNameOutputTable, FileRow fileRow, string name, string value) { // check for null value (this can occur when grabbing the file version from an assembly without one) if (null == value || 0 == value.Length) { this.OnMessage(WixErrors.NullMsiAssemblyNameValue(fileRow.SourceLineNumbers, fileRow.Component, name)); } // override directly authored value foreach (OutputRow outputRow in assemblyNameOutputTable.OutputRows) { if ((string)outputRow.Row[0] == fileRow.Component && (string)outputRow.Row[1] == name) { outputRow.Row[2] = value; return; } } Row assemblyNameRow = new Row(assemblyNameOutputTable.TableDefinition); assemblyNameRow[0] = fileRow.Component; assemblyNameRow[1] = name; assemblyNameRow[2] = value; assemblyNameOutputTable.OutputRows.Add(new OutputRow(assemblyNameRow)); }
public MsiPropertyInfo(Row row) : this((string)row[0], (string)row[1], (string)row[2]) { }
public WixFileSearchInfo(Row row) : this((string)row[0], (string)row[1], (int)row[9]) { }
public WixComponentSearchInfo(Row row) : this((string)row[0], (string)row[1], (string)row[2], (int)row[3]) { }
/// <summary> /// Adds a row to the collection. /// </summary> /// <param name="row">Row to add to collection.</param> public void Add(Row row) { this.collection.Add(row); }
/// <summary> /// Creates a new output row. /// </summary> /// <param name="row">Table row to wrap.</param> public OutputRow(Row row) : this(row, row.SectionId) { }
public ExitCodeInfo(Row row) : this((string)row[0], (int)row[1], (string)row[2]) { }
public CommandLineInfo(Row row) : this((string)row[0], (string)row[1], (string)row[2], (string)row[3], (string)row[4]) { }
/// <summary> /// Creates a new instance of the <see cref="ProviderDependency"/> class from a <see cref="Row"/>. /// </summary> /// <param name="row">The <see cref="Row"/> from which data is imported.</param> internal ProvidesDependency(Row row) : this((string)row[2], (string)row[3], (string)row[4], (int?)row[5]) { }
/// <summary> /// Creates a new row in the table. /// </summary> /// <param name="sourceLineNumbers">Original source lines for this row.</param> /// <param name="add">Specifies whether to only create the row or add it to the table automatically.</param> /// <returns>Row created in table.</returns> public Row CreateRow(SourceLineNumberCollection sourceLineNumbers, bool add) { Row row; switch (this.Name) { case "BBControl": row = new BBControlRow(sourceLineNumbers, this); break; case "ChainMsiPackage": row = new ChainMsiPackageRow(sourceLineNumbers, this); break; case "Component": row = new ComponentRow(sourceLineNumbers, this); break; case "Control": row = new ControlRow(sourceLineNumbers, this); break; case "File": row = new FileRow(sourceLineNumbers, this); break; case "Media": row = new MediaRow(sourceLineNumbers, this); break; case "PayloadInfo": row = new PayloadInfoRow(sourceLineNumbers, this); break; case "Upgrade": row = new UpgradeRow(sourceLineNumbers, this); break; case "Variable": row = new VariableRow(sourceLineNumbers, this); break; case "WixAction": row = new WixActionRow(sourceLineNumbers, this); break; case "WixApprovedExeForElevation": row = new WixApprovedExeForElevationRow(sourceLineNumbers, this); break; case "WixBundle": row = new WixBundleRow(sourceLineNumbers, this); break; case "WixBundlePatchTargetCode": row = new WixBundlePatchTargetCodeRow(sourceLineNumbers, this); break; case "WixBundleUpdate": row = new WixBundleUpdateRow(sourceLineNumbers, this); break; case "WixCatalog": row = new WixCatalogRow(sourceLineNumbers, this); break; case "WixCommandLine": row = new WixCommandLineRow(sourceLineNumbers, this); break; case "WixComplexReference": row = new WixComplexReferenceRow(sourceLineNumbers, this); break; case "WixFile": row = new WixFileRow(sourceLineNumbers, this); break; case "WixMedia": row = new WixMediaRow(sourceLineNumbers, this); break; case "WixMediaTemplate": row = new WixMediaTemplateRow(sourceLineNumbers, this); break; case "WixMerge": row = new WixMergeRow(sourceLineNumbers, this); break; case "WixProperty": row = new WixPropertyRow(sourceLineNumbers, this); break; case "WixSimpleReference": row = new WixSimpleReferenceRow(sourceLineNumbers, this); break; case "WixUpdateRegistration": row = new WixUpdateRegistrationRow(sourceLineNumbers, this); break; case "WixVariable": row = new WixVariableRow(sourceLineNumbers, this); break; default: row = new Row(sourceLineNumbers, this); break; } if (add) { this.rows.Add(row); } return row; }
/// <summary> /// Updates database with signatures from external cabinets. /// </summary> /// <param name="databaseFile">Path to MSI database.</param> /// <param name="outputFile">Ouput for updated MSI database.</param> /// <param name="tidy">Clean up files.</param> /// <returns>True if database is updated.</returns> public bool InscribeDatabase(string databaseFile, string outputFile, bool tidy) { // Keeps track of whether we've encountered at least one signed cab or not - we'll throw a warning if no signed cabs were encountered bool foundUnsignedExternals = false; bool shouldCommit = false; FileAttributes attributes = File.GetAttributes(databaseFile); if (FileAttributes.ReadOnly == (attributes & FileAttributes.ReadOnly)) { this.OnMessage(WixErrors.ReadOnlyOutputFile(databaseFile)); return(shouldCommit); } using (Database database = new Database(databaseFile, OpenDatabase.Transact)) { // Just use the English codepage, because the tables we're importing only have binary streams / MSI identifiers / other non-localizable content int codepage = 1252; // list of certificates for this database (hash/identifier) Dictionary <string, string> certificates = new Dictionary <string, string>(); // Reset the in-memory tables for this new database Table digitalSignatureTable = new Table(null, this.tableDefinitions["MsiDigitalSignature"]); Table digitalCertificateTable = new Table(null, this.tableDefinitions["MsiDigitalCertificate"]); // If any digital signature records exist that are not of the media type, preserve them if (database.TableExists("MsiDigitalSignature")) { using (View digitalSignatureView = database.OpenExecuteView("SELECT `Table`, `SignObject`, `DigitalCertificate_`, `Hash` FROM `MsiDigitalSignature` WHERE `Table` <> 'Media'")) { while (true) { using (Record digitalSignatureRecord = digitalSignatureView.Fetch()) { if (null == digitalSignatureRecord) { break; } Row digitalSignatureRow = null; digitalSignatureRow = digitalSignatureTable.CreateRow(null); string table = digitalSignatureRecord.GetString(0); string signObject = digitalSignatureRecord.GetString(1); digitalSignatureRow[0] = table; digitalSignatureRow[1] = signObject; digitalSignatureRow[2] = digitalSignatureRecord.GetString(2); if (false == digitalSignatureRecord.IsNull(3)) { // Export to a file, because the MSI API's require us to provide a file path on disk string hashPath = Path.Combine(this.TempFilesLocation, "MsiDigitalSignature"); string hashFileName = string.Concat(table, ".", signObject, ".bin"); Directory.CreateDirectory(hashPath); hashPath = Path.Combine(hashPath, hashFileName); using (FileStream fs = File.Create(hashPath)) { int bytesRead; byte[] buffer = new byte[1024 * 4]; while (0 != (bytesRead = digitalSignatureRecord.GetStream(3, buffer, buffer.Length))) { fs.Write(buffer, 0, bytesRead); } } digitalSignatureRow[3] = hashFileName; } } } } } // If any digital certificates exist, extract and preserve them if (database.TableExists("MsiDigitalCertificate")) { using (View digitalCertificateView = database.OpenExecuteView("SELECT * FROM `MsiDigitalCertificate`")) { while (true) { using (Record digitalCertificateRecord = digitalCertificateView.Fetch()) { if (null == digitalCertificateRecord) { break; } string certificateId = digitalCertificateRecord.GetString(1); // get the identifier of the certificate // Export to a file, because the MSI API's require us to provide a file path on disk string certPath = Path.Combine(this.TempFilesLocation, "MsiDigitalCertificate"); Directory.CreateDirectory(certPath); certPath = Path.Combine(certPath, string.Concat(certificateId, ".cer")); using (FileStream fs = File.Create(certPath)) { int bytesRead; byte[] buffer = new byte[1024 * 4]; while (0 != (bytesRead = digitalCertificateRecord.GetStream(2, buffer, buffer.Length))) { fs.Write(buffer, 0, bytesRead); } } // Add it to our "add to MsiDigitalCertificate" table dictionary Row digitalCertificateRow = digitalCertificateTable.CreateRow(null); digitalCertificateRow[0] = certificateId; // Now set the file path on disk where this binary stream will be picked up at import time digitalCertificateRow[1] = string.Concat(certificateId, ".cer"); // Load the cert to get it's thumbprint X509Certificate cert = X509Certificate.CreateFromCertFile(certPath); X509Certificate2 cert2 = new X509Certificate2(cert); certificates.Add(cert2.Thumbprint, certificateId); } } } } using (View mediaView = database.OpenExecuteView("SELECT * FROM `Media`")) { while (true) { using (Record mediaRecord = mediaView.Fetch()) { if (null == mediaRecord) { break; } X509Certificate2 cert2 = null; Row digitalSignatureRow = null; string cabName = mediaRecord.GetString(4); // get the name of the cab // If there is no cabinet or it's an internal cab, skip it. if (String.IsNullOrEmpty(cabName) || cabName.StartsWith("#", StringComparison.Ordinal)) { continue; } string cabId = mediaRecord.GetString(1); // get the ID of the cab string cabPath = Path.Combine(Path.GetDirectoryName(databaseFile), cabName); // If the cabs aren't there, throw an error but continue to catch the other errors if (!File.Exists(cabPath)) { this.OnMessage(WixErrors.WixFileNotFound(cabPath)); continue; } try { // Get the certificate from the cab X509Certificate signedFileCert = X509Certificate.CreateFromSignedFile(cabPath); cert2 = new X509Certificate2(signedFileCert); } catch (System.Security.Cryptography.CryptographicException e) { uint HResult = unchecked ((uint)Marshal.GetHRForException(e)); // If the file has no cert, continue, but flag that we found at least one so we can later give a warning if (0x80092009 == HResult) // CRYPT_E_NO_MATCH { foundUnsignedExternals = true; continue; } // todo: exactly which HRESULT corresponds to this issue? // If it's one of these exact platforms, warn the user that it may be due to their OS. if ((5 == Environment.OSVersion.Version.Major && 2 == Environment.OSVersion.Version.Minor) || // W2K3 (5 == Environment.OSVersion.Version.Major && 1 == Environment.OSVersion.Version.Minor)) // XP { this.OnMessage(WixErrors.UnableToGetAuthenticodeCertOfFileDownlevelOS(cabPath, String.Format(CultureInfo.InvariantCulture, "HRESULT: 0x{0:x8}", HResult))); } else // otherwise, generic error { this.OnMessage(WixErrors.UnableToGetAuthenticodeCertOfFile(cabPath, String.Format(CultureInfo.InvariantCulture, "HRESULT: 0x{0:x8}", HResult))); } } // If we haven't added this cert to the MsiDigitalCertificate table, set it up to be added if (!certificates.ContainsKey(cert2.Thumbprint)) { // generate a stable identifier string certificateGeneratedId = Common.GenerateIdentifier("cer", true, cert2.Thumbprint); // Add it to our "add to MsiDigitalCertificate" table dictionary Row digitalCertificateRow = digitalCertificateTable.CreateRow(null); digitalCertificateRow[0] = certificateGeneratedId; // Export to a file, because the MSI API's require us to provide a file path on disk string certPath = Path.Combine(this.TempFilesLocation, "MsiDigitalCertificate"); Directory.CreateDirectory(certPath); certPath = Path.Combine(certPath, string.Concat(cert2.Thumbprint, ".cer")); File.Delete(certPath); using (BinaryWriter writer = new BinaryWriter(File.Open(certPath, FileMode.Create))) { writer.Write(cert2.RawData); writer.Close(); } // Now set the file path on disk where this binary stream will be picked up at import time digitalCertificateRow[1] = string.Concat(cert2.Thumbprint, ".cer"); certificates.Add(cert2.Thumbprint, certificateGeneratedId); } digitalSignatureRow = digitalSignatureTable.CreateRow(null); digitalSignatureRow[0] = "Media"; digitalSignatureRow[1] = cabId; digitalSignatureRow[2] = certificates[cert2.Thumbprint]; } } } if (digitalCertificateTable.Rows.Count > 0) { database.ImportTable(codepage, (IMessageHandler)this, digitalCertificateTable, this.TempFilesLocation, true); shouldCommit = true; } if (digitalSignatureTable.Rows.Count > 0) { database.ImportTable(codepage, (IMessageHandler)this, digitalSignatureTable, this.TempFilesLocation, true); shouldCommit = true; } // TODO: if we created the table(s), then we should add the _Validation records for them. certificates = null; // If we did find external cabs but none of them were signed, give a warning if (foundUnsignedExternals) { this.OnMessage(WixWarnings.ExternalCabsAreNotSigned(databaseFile)); } if (shouldCommit) { database.Commit(); } } return(shouldCommit); }
/// <summary> /// Tests if the passed in row is identical. /// </summary> /// <param name="row">Row to compare against.</param> /// <returns>True if two rows are identical.</returns> public bool IsIdentical(Row row) { bool identical = (this.TableDefinition.Name == row.TableDefinition.Name && this.fields.Length == row.fields.Length); for (int i = 0; identical && i < this.fields.Length; ++i) { if (!(this.fields[i].IsIdentical(row.fields[i]))) { identical = false; } } return identical; }
private static int FieldAsInt(Wix3.Row row, int column) { return(Convert.ToInt32(row[column])); }
public ChainPackageInfo(Row chainPackageRow, Table wixGroupTable, Dictionary<string, PayloadInfoRow> allPayloads, Dictionary<string, ContainerInfo> containers, BinderFileManager fileManager, BinderCore core, Output bundle) : base(chainPackageRow.SourceLineNumbers, bundle.Tables["ChainPackageInfo"]) { string id = (string)chainPackageRow[0]; string packageType = (string)chainPackageRow[1]; string payloadId = (string)chainPackageRow[2]; string installCondition = (string)chainPackageRow[3]; string installCommand = (string)chainPackageRow[4]; string repairCommand = (string)chainPackageRow[5]; string uninstallCommand = (string)chainPackageRow[6]; object cacheData = chainPackageRow[7]; string cacheId = (string)chainPackageRow[8]; object attributesData = chainPackageRow[9]; object vitalData = chainPackageRow[10]; object perMachineData = chainPackageRow[11]; string detectCondition = (string)chainPackageRow[12]; string msuKB = (string)chainPackageRow[13]; object repairableData = chainPackageRow[14]; string logPathVariable = (string)chainPackageRow[15]; string rollbackPathVariable = (string)chainPackageRow[16]; string protocol = (string)chainPackageRow[17]; long installSize = (int)chainPackageRow[18]; object suppressLooseFilePayloadGenerationData = chainPackageRow[19]; object enableFeatureSelectionData = chainPackageRow[20]; object forcePerMachineData = chainPackageRow[21]; object displayInternalUIData = chainPackageRow[22]; BundlePackageAttributes attributes = (null == attributesData) ? 0 : (BundlePackageAttributes)attributesData; YesNoAlwaysType cache = YesNoAlwaysType.NotSet; if (null != cacheData) { switch ((int)cacheData) { case 0: cache = YesNoAlwaysType.No; break; case 1: cache = YesNoAlwaysType.Yes; break; case 2: cache = YesNoAlwaysType.Always; break; } } YesNoType vital = (null == vitalData || 1 == (int)vitalData) ? YesNoType.Yes : YesNoType.No; YesNoDefaultType perMachine = YesNoDefaultType.NotSet; if (null != perMachineData) { switch ((int)perMachineData) { case 0: perMachine = YesNoDefaultType.No; break; case 1: perMachine = YesNoDefaultType.Yes; break; case 2: perMachine = YesNoDefaultType.Default; break; } } YesNoType repairable = YesNoType.NotSet; if (null != repairableData) { repairable = (1 == (int)repairableData) ? YesNoType.Yes : YesNoType.No; } YesNoType suppressLooseFilePayloadGeneration = YesNoType.NotSet; if (null != suppressLooseFilePayloadGenerationData) { suppressLooseFilePayloadGeneration = (1 == (int)suppressLooseFilePayloadGenerationData) ? YesNoType.Yes : YesNoType.No; } YesNoType enableFeatureSelection = YesNoType.NotSet; if (null != enableFeatureSelectionData) { enableFeatureSelection = (1 == (int)enableFeatureSelectionData) ? YesNoType.Yes : YesNoType.No; } YesNoType forcePerMachine = YesNoType.NotSet; if (null != forcePerMachineData) { forcePerMachine = (1 == (int)forcePerMachineData) ? YesNoType.Yes : YesNoType.No; } YesNoType displayInternalUI = YesNoType.NotSet; if (null != displayInternalUIData) { displayInternalUI = (1 == (int)displayInternalUIData) ? YesNoType.Yes : YesNoType.No; } this.core = core; this.Id = id; this.ChainPackageType = (Compiler.ChainPackageType)Enum.Parse(typeof(Compiler.ChainPackageType), packageType, true); PayloadInfoRow packagePayload; if (!allPayloads.TryGetValue(payloadId, out packagePayload)) { this.core.OnMessage(WixErrors.IdentifierNotFound("Payload", payloadId)); return; } this.PackagePayload = packagePayload; this.InstallCondition = installCondition; this.InstallCommand = installCommand; this.RepairCommand = repairCommand; this.UninstallCommand = uninstallCommand; this.PerMachine = perMachine; this.ProductCode = null; this.Cache = YesNoAlwaysType.NotSet == cache ? YesNoAlwaysType.Yes : cache; // The default is yes. this.CacheId = cacheId; this.Permanent = (BundlePackageAttributes.Permanent == (attributes & BundlePackageAttributes.Permanent)); this.Visible = (BundlePackageAttributes.Visible == (attributes & BundlePackageAttributes.Visible)); this.Slipstream = (BundlePackageAttributes.Slipstream == (attributes & BundlePackageAttributes.Slipstream)); this.Vital = (YesNoType.Yes == vital); // true only when specifically requested. this.DetectCondition = detectCondition; this.MsuKB = msuKB; this.Protocol = protocol; this.Repairable = (YesNoType.Yes == repairable); // true only when specifically requested. this.LogPathVariable = logPathVariable; this.RollbackLogPathVariable = rollbackPathVariable; this.DisplayInternalUI = (YesNoType.Yes == displayInternalUI); this.Payloads = new List<PayloadInfoRow>(); this.RelatedPackages = new List<RelatedPackage>(); this.MsiFeatures = new List<MsiFeature>(); this.MsiProperties = new List<MsiPropertyInfo>(); this.SlipstreamMsps = new List<string>(); this.ExitCodes = new List<ExitCodeInfo>(); this.Provides = new ProvidesDependencyCollection(); this.TargetCodes = new RowDictionary<WixBundlePatchTargetCodeRow>(); // Default the display name and description to the package payload. this.DisplayName = this.PackagePayload.ProductName; this.Description = this.PackagePayload.Description; // Start the package size with the package's payload size. this.Size = this.PackagePayload.FileSize; // get all contained payloads... foreach (Row row in wixGroupTable.Rows) { string rowParentName = (string)row[0]; string rowParentType = (string)row[1]; string rowChildName = (string)row[2]; string rowChildType = (string)row[3]; if ("Package" == rowParentType && this.Id == rowParentName && "Payload" == rowChildType && this.PackagePayload.Id != rowChildName) { PayloadInfoRow payload = allPayloads[rowChildName]; this.Payloads.Add(payload); this.Size += payload.FileSize; // add each payload to the total size of the package. } } // Default the install size to the calculated package size. this.InstallSize = this.Size; switch (this.ChainPackageType) { case Compiler.ChainPackageType.Msi: this.ResolveMsiPackage(fileManager, allPayloads, containers, suppressLooseFilePayloadGeneration, enableFeatureSelection, forcePerMachine, bundle); break; case Compiler.ChainPackageType.Msp: this.ResolveMspPackage(bundle); break; case Compiler.ChainPackageType.Msu: this.ResolveMsuPackage(); break; case Compiler.ChainPackageType.Exe: this.ResolveExePackage(); break; } if (CompilerCore.IntegerNotSet != installSize) { this.InstallSize = installSize; } }
/// <summary> /// Determines if the given row can be ignored when comparing results. /// </summary> /// <param name="row">The row to check.</param> /// <returns>True if the row can be ignored; otherwise, false.</returns> private static bool Ignore(Row row) { if ("_SummaryInformation" == row.Table.Name) { // check timestamp and version-dependent fields switch ((int)row[0]) { case 9: case 12: case 13: case 18: return true; } } else if ("Property" == row.Table.Name) { switch ((string)row[0]) { case "ProductCode": return true; } } else if ("MsiPatchMetadata" == row.Table.Name) { switch (row.GetPrimaryKey('/')) { case "/CreationTimeUTC": return true; } } return false; }
/// <summary> /// Add a row to the <paramref name="index"/> using the primary key. /// </summary> /// <param name="index">The indexed rows.</param> /// <param name="row">The row to index.</param> private void AddIndexedRow(IDictionary index, Row row) { string primaryKey = row.GetPrimaryKey('/'); if (null != primaryKey) { // Overriding WixActionRows have a primary key defined and take precedence in the index. if (row is WixActionRow) { WixActionRow currentRow = (WixActionRow)row; if (index.Contains(primaryKey)) { // If the current row is not overridable, see if the indexed row is. if (!currentRow.Overridable) { WixActionRow indexedRow = index[primaryKey] as WixActionRow; if (null != indexedRow && indexedRow.Overridable) { // The indexed key is overridable and should be replaced // (not removed and re-added which results in two Array.Copy // operations for SortedList, or may be re-hashing in other // implementations of IDictionary). index[primaryKey] = currentRow; } } // If we got this far, the row does not need to be indexed. return; } } // Nothing else should be added more than once. if (!index.Contains(primaryKey)) { index.Add(primaryKey, row); } else if (this.showPedanticMessages) { this.OnMessage(WixWarnings.DuplicatePrimaryKey(row.SourceLineNumbers, primaryKey, row.Table.Name)); } } else // use the string representation of the row as its primary key (it may not be unique) { // this is provided for compatibility with unreal tables with no primary key // all real tables must specify at least one column as the primary key primaryKey = row.ToString(); index[primaryKey] = row; } }
private Row CompareRows(Table targetTable, Row targetRow, Row updatedRow, out RowOperation operation, out bool keepRow) { Row comparedRow = null; keepRow = false; operation = RowOperation.None; if (null == targetRow ^ null == updatedRow) { if (null == targetRow) { operation = updatedRow.Operation = RowOperation.Add; comparedRow = updatedRow; } else if (null == updatedRow) { operation = targetRow.Operation = RowOperation.Delete; targetRow.SectionId = targetRow.SectionId + sectionDelimiter; comparedRow = targetRow; keepRow = true; } } else // possibly modified { updatedRow.Operation = RowOperation.None; if (!this.suppressKeepingSpecialRows && "_SummaryInformation" == targetTable.Name) { // ignore rows that shouldn't be in a transform if (Enum.IsDefined(typeof(SummaryInformation.Transform), (int)updatedRow[0])) { updatedRow.SectionId = targetRow.SectionId + sectionDelimiter + updatedRow.SectionId; comparedRow = updatedRow; keepRow = true; operation = RowOperation.Modify; } } else { if (this.preserveUnchangedRows) { keepRow = true; } for (int i = 0; i < updatedRow.Fields.Length; i++) { ColumnDefinition columnDefinition = updatedRow.Fields[i].Column; if (!columnDefinition.IsPrimaryKey) { bool modified = false; if (i >= targetRow.Fields.Length) { columnDefinition.Added = true; modified = true; } else if (ColumnType.Number == columnDefinition.Type && !columnDefinition.IsLocalizable) { if (null == targetRow[i] ^ null == updatedRow[i]) { modified = true; } else if (null != targetRow[i] && null != updatedRow[i]) { modified = ((int)targetRow[i] != (int)updatedRow[i]); } } else if (ColumnType.Preserved == columnDefinition.Type) { updatedRow.Fields[i].PreviousData = (string)targetRow.Fields[i].Data; // keep rows containing preserved fields so the historical data is available to the binder keepRow = !this.suppressKeepingSpecialRows; } else if (ColumnType.Object == columnDefinition.Type) { ObjectField targetObjectField = (ObjectField)targetRow.Fields[i]; ObjectField updatedObjectField = (ObjectField)updatedRow.Fields[i]; updatedObjectField.PreviousCabinetFileId = targetObjectField.CabinetFileId; updatedObjectField.PreviousBaseUri = targetObjectField.BaseUri; // always keep a copy of the previous data even if they are identical // This makes diff.wixmst clean and easier to control patch logic updatedObjectField.PreviousData = (string)targetObjectField.Data; // always remember the unresolved data for target build updatedObjectField.UnresolvedPreviousData = (string)targetObjectField.UnresolvedData; // keep rows containing object fields so the files can be compared in the binder keepRow = !this.suppressKeepingSpecialRows; } else { modified = ((string)targetRow[i] != (string)updatedRow[i]); } if (modified) { if (null != updatedRow.Fields[i].PreviousData) { updatedRow.Fields[i].PreviousData = targetRow.Fields[i].Data.ToString(); } updatedRow.Fields[i].Modified = true; operation = updatedRow.Operation = RowOperation.Modify; keepRow = true; } } } if (keepRow) { comparedRow = updatedRow; comparedRow.SectionId = targetRow.SectionId + sectionDelimiter + updatedRow.SectionId; } } } return(comparedRow); }
public VariableInfo(Row row) : this((string)row[0], (string)row[1], (string)row[2], (int)row[3] == 1 ? true : false, (int)row[4] == 1 ? true : false) { }
/// <summary> /// Update several msi tables with data contained in files references in the File table. /// </summary> /// <remarks> /// For versioned files, update the file version and language in the File table. For /// unversioned files, add a row to the MsiFileHash table for the file. For assembly /// files, add a row to the MsiAssembly table and add AssemblyName information by adding /// MsiAssemblyName rows. /// </remarks> /// <param name="output">Internal representation of the msi database to operate upon.</param> private void UpdateFileInformation(Output output) { OutputTable mergeTable = output.OutputTables["Merge"]; if (null != mergeTable) { foreach (OutputRow outputRow in mergeTable.OutputRows) { MergeRow mergeRow = (MergeRow)outputRow.Row; string moduleFile = null; try { moduleFile = this.extension.FileResolutionHandler(mergeRow.SourceFile, FileResolutionType.Module); } catch (WixFileNotFoundException wfnfe) { this.OnMessage(WixErrors.BinderExtensionMissingFile(null, ErrorLevel.Normal, wfnfe.Message)); continue; } output.Modules.Add(mergeRow); try { // read the module's File table to get its FileMediaInformation entries using (Database db = new Database(moduleFile, OpenDatabase.ReadOnly)) { mergeRow.HasFiles = false; if (db.TableExists("File") && db.TableExists("Component")) { Hashtable uniqueModuleFileIdentifiers = System.Collections.Specialized.CollectionsUtil.CreateCaseInsensitiveHashtable(); using (View view = db.OpenExecuteView("SELECT `File`, `Directory_` FROM `File`, `Component` WHERE `Component_`=`Component`")) { Record record; while (view.Fetch(out record)) { FileMediaInformation fileMediaInformation = new FileMediaInformation(record[1], record[2], mergeRow.DiskId, String.Concat(this.tempFiles.BasePath, Path.DirectorySeparatorChar, "MergeId.", mergeRow.Id.GetHashCode().ToString("X4", CultureInfo.InvariantCulture.NumberFormat), Path.DirectorySeparatorChar, record[1]), mergeRow.Number, mergeRow.FileCompression, moduleFile, -1); FileMediaInformation otherFileMediaInformation = output.FileMediaInformationCollection[fileMediaInformation.FileId]; string collidingModuleFileIdentifier = (string)uniqueModuleFileIdentifiers[fileMediaInformation.FileId]; if (null == otherFileMediaInformation && null == collidingModuleFileIdentifier) { output.FileMediaInformationCollection.Add(fileMediaInformation); // keep track of file identifiers in this merge module uniqueModuleFileIdentifiers.Add(fileMediaInformation.FileId, fileMediaInformation.FileId); } else // collision(s) detected { // case-sensitive collision with another merge module or a user-authored file identifier if (null != otherFileMediaInformation) { this.OnMessage(WixErrors.DuplicateModuleFileIdentifier(mergeRow.SourceLineNumbers, mergeRow.Id, fileMediaInformation.FileId)); } // case-insensitive collision with another file identifier in the same merge module if (null != collidingModuleFileIdentifier) { this.OnMessage(WixErrors.DuplicateModuleCaseInsensitiveFileIdentifier(mergeRow.SourceLineNumbers, mergeRow.Id, fileMediaInformation.FileId, collidingModuleFileIdentifier)); } } mergeRow.HasFiles = true; } } } } } catch (FileNotFoundException fnfe) { throw new WixFileNotFoundException(null, moduleFile, fnfe); } catch (IOException ioe) { throw new WixMergeModuleOpenException(mergeRow.SourceLineNumbers, mergeRow.Id, moduleFile, ioe); } } } // calculate sequence numbers and media disk id layout for all file media information objects if (OutputType.Module == output.Type) { int lastSequence = 0; foreach (FileMediaInformation fmi in output.FileMediaInformationCollection) { fmi.Modularize(output.ModularizationGuid); fmi.Sequence = ++lastSequence; } } else { int lastSequence = 0; MediaRow mediaRow = null; output.FileMediaInformationCollection.Sort(); SortedList patchGroups = new SortedList(); // sequence the non-patch-added files foreach (FileMediaInformation fmi in output.FileMediaInformationCollection) { if (null == mediaRow) { mediaRow = output.MediaRows[fmi.Media]; } else if (mediaRow.DiskId != fmi.Media) { mediaRow.LastSequence = lastSequence; mediaRow = output.MediaRows[fmi.Media]; } if (0 < fmi.PatchGroup) { ArrayList patchGroup = (ArrayList)patchGroups[fmi.PatchGroup]; if (null == patchGroup) { patchGroup = new ArrayList(); patchGroups.Add(fmi.PatchGroup, patchGroup); } patchGroup.Add(fmi); } else { fmi.Sequence = ++lastSequence; } } if (null != mediaRow) { mediaRow.LastSequence = lastSequence; mediaRow = null; } // sequence the patch-added files foreach (ArrayList patchGroup in patchGroups.Values) { foreach (FileMediaInformation fmi in patchGroup) { if (null == mediaRow) { mediaRow = output.MediaRows[fmi.Media]; } else if (mediaRow.DiskId != fmi.Media) { mediaRow.LastSequence = lastSequence; mediaRow = output.MediaRows[fmi.Media]; } fmi.Sequence = ++lastSequence; } } if (null != mediaRow) { mediaRow.LastSequence = lastSequence; } } // copy the special media rows back to the real media table if (0 < output.MediaRows.Count) { OutputTable mediaTable = Common.EnsureOutputTable(output, this.tableDefinitions["Media"]); foreach (MediaRow mediaRow in output.MediaRows) { mediaTable.OutputRows.Add(new OutputRow(mediaRow)); } } OutputTable fileTable = output.OutputTables["File"]; if (null == fileTable) // no work to do { return; } foreach (OutputRow outputRow in fileTable.OutputRows) { FileRow fileRow = outputRow.Row as FileRow; if (null == fileRow) { throw new ApplicationException("Expected FileRow"); } // copy the sequence number from the file media information to the file table fileRow.Sequence = output.FileMediaInformationCollection[fileRow.File].Sequence; string src = fileRow.Source; FileInfo fileInfo = null; if (!this.suppressFileHashAndInfo || (!this.suppressAssemblies && FileAssemblyType.NotAnAssembly != fileRow.AssemblyType)) { try { src = this.extension.FileResolutionHandler(fileRow.Source, FileResolutionType.File); } catch (WixFileNotFoundException wfnfe) { this.OnMessage(WixErrors.BinderExtensionMissingFile(fileRow.SourceLineNumbers, ErrorLevel.Normal, wfnfe.Message)); continue; } try { fileInfo = new FileInfo(src); } catch (ArgumentException) { this.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, ErrorLevel.Normal, src)); continue; } catch (PathTooLongException) { this.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, ErrorLevel.Normal, src)); continue; } catch (NotSupportedException) { this.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, ErrorLevel.Normal, src)); continue; } } if (!this.suppressFileHashAndInfo) { if (fileInfo.Exists) { string version; string language; fileRow.FileSize = fileInfo.Length; try { MsiBase.FileVersion(fileInfo.FullName, out version, out language); } catch (FileNotFoundException e) { throw new WixFileNotFoundException(null, fileInfo.FullName, e); // TODO: find a way to get the sourceFile (instead of null) } if (0 == version.Length && 0 == language.Length) // unversioned files have their hashes added to the MsiFileHash table { int[] hash; try { MsiBase.GetFileHash(fileInfo.FullName, 0, out hash); } catch (FileNotFoundException e) { throw new WixFileNotFoundException(null, fileInfo.FullName, e); // TODO: find a way to get the sourceFile (instead of null) } OutputTable outputHashTable = Common.EnsureOutputTable(output, this.tableDefinitions["MsiFileHash"]); Row hashRow = new Row(outputHashTable.TableDefinition); hashRow[0] = fileRow.File; hashRow[1] = 0; hashRow[2] = hash[0]; hashRow[3] = hash[1]; hashRow[4] = hash[2]; hashRow[5] = hash[3]; outputHashTable.OutputRows.Add(new OutputRow(hashRow)); } else // update the file row with the version and language information { fileRow.Version = version; fileRow.Language = language; } } else { this.OnMessage(WixErrors.CannotFindFile(fileRow.SourceLineNumbers, ErrorLevel.Normal, fileRow.File, fileRow.FileName, src)); } } // if we're not suppressing automagically grabbing assembly information and this is a // CLR assembly, load the assembly and get the assembly name information if (!this.suppressAssemblies) { if (FileAssemblyType.DotNetAssembly == fileRow.AssemblyType) { StringDictionary assemblyNameValues = new StringDictionary(); // under CLR 2.0, use a more robust method of gathering AssemblyName information if (2 <= Environment.Version.Major) { CLRInterop.IReferenceIdentity referenceIdentity = null; Guid referenceIdentityGuid = CLRInterop.ReferenceIdentityGuid; if (0 == CLRInterop.GetAssemblyIdentityFromFile(fileInfo.FullName, ref referenceIdentityGuid, out referenceIdentity)) { if (null != referenceIdentity) { string culture = referenceIdentity.GetAttribute(null, "Culture"); if (null != culture) { assemblyNameValues.Add("Culture", culture); } string name = referenceIdentity.GetAttribute(null, "Name"); if (null != name) { assemblyNameValues.Add("Name", name); } string processorArchitecture = referenceIdentity.GetAttribute(null, "ProcessorArchitecture"); if (null != processorArchitecture) { assemblyNameValues.Add("ProcessorArchitecture", processorArchitecture); } string publicKeyToken = referenceIdentity.GetAttribute(null, "PublicKeyToken"); if (null != publicKeyToken) { assemblyNameValues.Add("PublicKeyToken", publicKeyToken.ToUpper(CultureInfo.InvariantCulture)); } string version = referenceIdentity.GetAttribute(null, "Version"); if (null != version) { assemblyNameValues.Add("Version", version); } } } } else { AssemblyName assemblyName = null; try { assemblyName = AssemblyName.GetAssemblyName(fileInfo.FullName); if (null != assemblyName.CultureInfo) { assemblyNameValues.Add("Culture", assemblyName.CultureInfo.ToString()); } if (null != assemblyName.Name) { assemblyNameValues.Add("Name", assemblyName.Name); } byte[] publicKey = assemblyName.GetPublicKeyToken(); if (null != publicKey && 0 < publicKey.Length) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < publicKey.GetLength(0); ++i) { sb.AppendFormat("{0:X2}", publicKey[i]); } assemblyNameValues.Add("PublicKeyToken", sb.ToString()); } if (null != assemblyName.Version) { assemblyNameValues.Add("Version", assemblyName.Version.ToString()); } } catch (FileNotFoundException fnfe) { throw new WixFileNotFoundException(fileRow.SourceLineNumbers, fileInfo.FullName, fnfe); } catch (Exception e) { if (e is NullReferenceException || e is SEHException) { throw; } else { throw new WixInvalidAssemblyException(fileRow.SourceLineNumbers, fileInfo, e); } } } OutputTable assemblyNameOutputTable = Common.EnsureOutputTable(output, this.tableDefinitions["MsiAssemblyName"]); if (assemblyNameValues.ContainsKey("name")) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "name", assemblyNameValues["name"]); } string fileVersion = null; if (this.setMsiAssemblyNameFileVersion) { string language; MsiBase.FileVersion(fileInfo.FullName, out fileVersion, out language); this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "fileVersion", fileVersion); } if (assemblyNameValues.ContainsKey("version")) { string assemblyVersion = assemblyNameValues["version"]; // there is a bug in fusion that requires the assembly's "version" attribute // to be equal to or longer than the "fileVersion" in length when its present; // the workaround is to prepend zeroes to the last version number in the assembly version if (this.setMsiAssemblyNameFileVersion && null != fileVersion && fileVersion.Length > assemblyVersion.Length) { string padding = new string('0', fileVersion.Length - assemblyVersion.Length); string[] assemblyVersionNumbers = assemblyVersion.Split('.'); if (assemblyVersionNumbers.Length > 0) { assemblyVersionNumbers[assemblyVersionNumbers.Length - 1] = String.Concat(padding, assemblyVersionNumbers[assemblyVersionNumbers.Length - 1]); assemblyVersion = String.Join(".", assemblyVersionNumbers); } } this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "version", assemblyVersion); } if (assemblyNameValues.ContainsKey("culture")) { string culture = assemblyNameValues["culture"]; this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "culture", (String.Empty == culture ? "neutral" : culture)); } if (assemblyNameValues.ContainsKey("publicKeyToken")) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "publicKeyToken", assemblyNameValues["publicKeyToken"]); } if (null != fileRow.ProcessorArchitecture && 0 < fileRow.ProcessorArchitecture.Length) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "processorArchitecture", fileRow.ProcessorArchitecture); } if (assemblyNameValues.ContainsKey("processorArchitecture")) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "processorArchitecture", assemblyNameValues["processorArchitecture"]); } } else if (FileAssemblyType.Win32Assembly == fileRow.AssemblyType) { FileRow fileManifestRow = fileRow; // would rather look this up through a data structure rather than // do an order n search through the list of files for every // instance of a win32 assembly. From what I can find, there // are no indexed data structures available at this point // in the code we're left with this expensive search. foreach (OutputRow manifestOutputRow in fileTable.OutputRows) { fileManifestRow = manifestOutputRow.Row as FileRow; if (fileManifestRow.File == fileRow.AssemblyManifest) { break; } } string type = null; string name = null; string version = null; string processorArchitecture = null; string publicKeyToken = null; // loading the dom is expensive we want more performant APIs than the DOM // Navigator is cheaper than dom. Perhaps there is a cheaper API still. string manifestSourcePath = null; try { manifestSourcePath = this.extension.FileResolutionHandler(fileManifestRow.Source, FileResolutionType.File); } catch (WixFileNotFoundException wfnfe) { this.OnMessage(WixErrors.BinderExtensionMissingFile(fileRow.SourceLineNumbers, ErrorLevel.Normal, wfnfe.Message)); continue; } try { XPathDocument doc = new XPathDocument(manifestSourcePath); XPathNavigator nav = doc.CreateNavigator(); nav.MoveToRoot(); // this assumes a particular schema for a win32 manifest and does not // provide error checking if the file does not conform to schema. // The fallback case here is that nothing is added to the MsiAssemblyName // table for a out of tollerence Win32 manifest. Perhaps warnings needed. if (nav.MoveToFirstChild()) { while (nav.NodeType != XPathNodeType.Element || nav.Name != "assembly") { nav.MoveToNext(); } if (nav.MoveToFirstChild()) { while (nav.NodeType != XPathNodeType.Element || nav.Name != "assemblyIdentity") { nav.MoveToNext(); } if (nav.MoveToAttribute("type", String.Empty)) { type = nav.Value; nav.MoveToParent(); } if (nav.MoveToAttribute("name", String.Empty)) { name = nav.Value; nav.MoveToParent(); } if (nav.MoveToAttribute("version", String.Empty)) { version = nav.Value; nav.MoveToParent(); } if (nav.MoveToAttribute("processorArchitecture", String.Empty)) { processorArchitecture = nav.Value; nav.MoveToParent(); } if (nav.MoveToAttribute("publicKeyToken", String.Empty)) { publicKeyToken = nav.Value; nav.MoveToParent(); } } } } catch (XmlException xe) { this.OnMessage(WixErrors.InvalidXml(SourceLineNumberCollection.FromFileName(manifestSourcePath), "manifest", xe.Message)); } OutputTable assemblyNameOutputTable = Common.EnsureOutputTable(output, this.tableDefinitions["MsiAssemblyName"]); if (null != name && 0 < name.Length) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "name", name); } if (null != version && 0 < version.Length) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "version", version); } if (null != type && 0 < type.Length) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "type", type); } if (null != processorArchitecture && 0 < processorArchitecture.Length) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "processorArchitecture", processorArchitecture); } if (null != publicKeyToken && 0 < publicKeyToken.Length) { this.SetMsiAssemblyName(assemblyNameOutputTable, fileRow, "publicKeyToken", publicKeyToken); } } } } }
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> /// Creates a symbol for a row. /// </summary> /// <param name="row">Row for the symbol</param> public Symbol(Row row) { this.row = row; }
private static string FieldAsString(Wix3.Row row, int column) { return((string)row[column]); }
private static IEnumerable <string> RowToStrings(Wix3.Row row, Dictionary <int, Wix3.WixMediaRow> wixMediaByDiskId) { string fields = null; // Massage output to match WiX v3 rows and v4 symbols. // switch (row.Table.Name) { case "Directory": var dirs = SplitDefaultDir((string)row[2]); fields = String.Join(",", row[0], row[1], dirs[0], dirs[1], dirs[2], dirs[3]); break; case "File": { var fieldValues = row.Fields.Take(7).Select(SafeConvertField).ToArray(); if (fieldValues[3] == null) { // "Somebody" sometimes writes out a null field even when the column definition says // it's non-nullable. Not naming names or anything. (SWID tags.) fieldValues[3] = "0"; } fields = String.Join(",", fieldValues); break; } case "Media": var compression = wixMediaByDiskId.TryGetValue((int)row[0], out var wixMedia) ? (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), SafeConvertField(wixMedia.Fields[1]), true) : null; fields = String.Join(",", row.Fields.Select(SafeConvertField)); fields = String.Join(",", fields, (int?)compression, SafeConvertField(wixMedia?.Fields[2])); break; case "RegLocator": var type = (int)row[4]; fields = String.Join(",", row[0], row[1], row[2], row[3], type & 0xF, (type & 0x10) == 0x10); break; case "RemoveFile": var attributes = (int)row[4]; var onInstall = (attributes & 1) == 1 ? (bool?)true : null; var onUninstall = (attributes & 2) == 2 ? (bool?)true : null; fields = String.Join(",", row.Fields.Take(4).Select(SafeConvertField)); fields = String.Join(",", fields, onInstall, onUninstall); break; case "Shortcut": var split = ((string)row[2]).Split('|'); var afterName = String.Join(",", row.Fields.Skip(3).Select(SafeConvertField)); fields = String.Join(",", row[0], row[1], split.Length > 1 ? split[1] : split[0], split.Length > 1 ? split[0] : String.Empty, afterName); break; case "WixAction": var table = (int)SequenceStringToSequenceTable(row[0]); fields = String.Join(",", table, row[1], row[2], row[3], row[4], row[5], row[6]); break; case "WixFile": { var fieldValues = row.Fields.Select(SafeConvertField).ToArray(); if (fieldValues[8] == null) { // "Somebody" sometimes writes out a null field even when the column definition says // it's non-nullable. Not naming names or anything. (SWID tags.) fieldValues[8] = "0"; } if (fieldValues[10] == null) { // WixFile rows that come from merge modules will not have the attributes column set // so initilaize with 0. fieldValues[10] = "0"; } fields = String.Join(",", fieldValues); break; } case "WixMedia": break; default: fields = String.Join(",", row.Fields.Select(SafeConvertField)); break; } if (fields != null) { yield return($"{row.Table.Name}:{fields}"); } }
public void FillFromPayloadRow(Output output, Row payloadRow) { SourceLineNumberCollection sourceLineNumbers = payloadRow.SourceLineNumbers; this[0] = payloadRow[0]; this[1] = payloadRow[1]; this[2] = (string)payloadRow[2] ?? String.Empty; this[3] = payloadRow[3]; this[4] = payloadRow[4]; this[5] = payloadRow[5] ?? String.Empty; this[6] = payloadRow[6]; // payload files sourced from a cabinet (think WixExtension with embedded binary wixlib) are considered "non-content files". ObjectField field = (ObjectField)payloadRow.Fields[2]; this.ContentFile = String.IsNullOrEmpty(field.CabinetFileId); this.Resolve(); return; }
public CatalogInfo(Row row, string payloadId) { this.Initialize((string)row[0], (string)row[1], payloadId); }
/// <summary> /// Links an array of intermediates into an output. /// </summary> /// <param name="intermediates">Array of intermediates to link together.</param> /// <returns>Output object from the linking.</returns> public Output Link(Intermediate[] intermediates) { Output output = null; try { SymbolCollection allSymbols; Section entrySection; bool containsModuleSubstitution = false; bool containsModuleConfiguration = false; StringCollection referencedSymbols = new StringCollection(); ArrayList unresolvedReferences = new ArrayList(); ConnectToFeatureCollection componentGroupsToFeatures = new ConnectToFeatureCollection(); ConnectToModuleCollection componentGroupsToModules = new ConnectToModuleCollection(); ComplexReferenceCollection componentsToComponentGroupsComplexReferences = new ComplexReferenceCollection(); ConnectToFeatureCollection componentsToFeatures = new ConnectToFeatureCollection(); ConnectToFeatureCollection featuresToFeatures = new ConnectToFeatureCollection(); this.activeOutput = null; this.foundError = false; SortedList adminProperties = new SortedList(); SortedList secureProperties = new SortedList(); SortedList hiddenProperties = new SortedList(); ActionTable requiredActions = new ActionTable(); RowCollection suppressActionRows = new RowCollection(); TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection(); RowCollection customRows = new RowCollection(); foreach (SchemaExtension extension in this.extensions.Values) { extension.Messages = this.extensionMessages; } // first find the entry section and create the symbols hash for all // the sections in all the intermediates Common.FindEntrySectionAndLoadSymbols(intermediates, this.allowIdenticalRows, this, out entrySection, out allSymbols); // should have found an entry section by now if (null == entrySection) { this.OnMessage(WixErrors.MissingEntrySection()); return null; } // add the standard action symbols to the entry section's symbol table this.LoadStandardActionSymbols(allSymbols, entrySection, this.standardActions); // now that we know where we're starting from, create the output object output = new Output(entrySection); // Note: this entry section will get added to the output section collection later if (null != this.localizer && -1 != this.localizer.Codepage) { output.Codepage = this.localizer.Codepage; } this.activeOutput = output; // resolve the symbol references to find the set of sections we // care about then resolve complex references in those sections Common.ResolveReferences(output.Type, output.Sections, output.EntrySection, allSymbols, referencedSymbols, unresolvedReferences, this); this.ProcessComplexReferences(output, output.Sections, referencedSymbols, componentsToComponentGroupsComplexReferences, componentGroupsToFeatures, componentGroupsToModules, componentsToFeatures, featuresToFeatures); for (int i = 0; i < unresolvedReferences.Count; ++i) { Common.ReferenceSection referenceSection = (Common.ReferenceSection)unresolvedReferences[i]; if (this.allowUnresolvedReferences) { this.OnMessage(WixWarnings.UnresolvedReferenceWarning(SourceLineNumberCollection.FromFileName(referenceSection.section.Intermediate.SourcePath), referenceSection.section.Type.ToString(), referenceSection.section.Id, referenceSection.reference.SymbolicName)); } else { this.OnMessage(WixErrors.UnresolvedReference(SourceLineNumberCollection.FromFileName(referenceSection.section.Intermediate.SourcePath), referenceSection.section.Type.ToString(), referenceSection.section.Id, referenceSection.reference.SymbolicName)); } } if (this.foundError) { return null; } this.ResolveComponentGroups(output, referencedSymbols, componentsToComponentGroupsComplexReferences, componentGroupsToFeatures, componentGroupsToModules, componentsToFeatures); this.FindOrphanedSymbols(referencedSymbols); // resolve the feature backlink for each section then update the feature to feature connects this.ResolveFeatureBacklinks(output, componentsToFeatures, allSymbols, referencedSymbols, unresolvedReferences); this.ResolveFeatureToFeatureConnects(featuresToFeatures, allSymbols, referencedSymbols, unresolvedReferences); // create a Hashtable of all the suppressed sequence types Hashtable suppressedSequenceTypes = new Hashtable(); // create a Hashtable of all the suppressed standard actions Hashtable suppressedStandardActions = new Hashtable(); if (this.suppressAdminSequence) { suppressedSequenceTypes[SequenceType.adminExecute] = null; suppressedSequenceTypes[SequenceType.adminUI] = null; } if (this.suppressAdvertiseSequence) { suppressedSequenceTypes[SequenceType.advertiseExecute] = null; } if (this.suppressUISequence) { suppressedSequenceTypes[SequenceType.adminUI] = null; suppressedSequenceTypes[SequenceType.installUI] = null; } // start generating OutputTables and OutputRows for all the sections in the output RowCollection ensureTableRows = new RowCollection(); foreach (Section section in this.activeOutput.Sections) { // add this sections list of identifiers to ignore modularization this.activeOutput.IgnoreModularizations.Add(section.IgnoreModularizations); foreach (Table table in section.Tables) { bool copyRows = !table.Definition.IsUnreal; // by default, copy rows if the table is not unreal // handle special tables switch (table.Name) { case "Actions": foreach (Row row in table.Rows) { SequenceType sequenceType; string seqType = (string)row[0]; string id = (string)row[1]; int sequence = null == row[3] ? 0 : Convert.ToInt32(row[3]); bool suppress = 1 == Convert.ToInt32(row[6]); switch (seqType) { case "AdminUISequence": sequenceType = SequenceType.adminUI; break; case "AdminExecuteSequence": sequenceType = SequenceType.adminExecute; break; case "AdvertiseExecuteSequence": sequenceType = SequenceType.advertiseExecute; break; case "InstallExecuteSequence": sequenceType = SequenceType.installExecute; break; case "InstallUISequence": sequenceType = SequenceType.installUI; break; default: throw new WixInvalidSequenceTypeException(null, seqType); } if (suppressedSequenceTypes.Contains(sequenceType)) { this.OnMessage(WixWarnings.SuppressAction(id, Action.SequenceTypeToString(sequenceType))); continue; } // create a SuppressAction row to allow suppressing the action from a merge module if (suppress) { Row suppressActionRow = new Row(row.SourceLineNumbers, this.tableDefinitions["SuppressAction"]); if ("AdvertiseExecuteSequence" == (string)row[0]) { suppressActionRow[0] = "AdvtExecuteSequence"; } else { suppressActionRow[0] = row[0]; } suppressActionRow[1] = row[1]; suppressActionRows.Add(suppressActionRow); } Action action = this.standardActions[sequenceType, id]; string beforeAction = (string)row[4]; string afterAction = (string)row[5]; // if this is not a standard action or there is a before or after action specified if (null == action || null != beforeAction || null != afterAction) { action = new Action(sequenceType, id, (string)row[2], sequence, beforeAction, afterAction); requiredActions.Add(action, true); // add the action and overwrite even if it already exists since this is a customization // if the parent action is a standard action add it to the required list string parentActionName = null != beforeAction ? beforeAction : afterAction; Action parentAction = this.standardActions[sequenceType, parentActionName]; if (null != parentAction) { requiredActions.Add(parentAction); } } else if (!suppress) // must have a standard action that is being overriden (when not suppressed) { action.Condition = (string)row[2]; if (0 != sequence) // if the user specified a sequence number, override the default { action.SequenceNumber = sequence; } requiredActions.Add(action, true); // ensure this action is in the required list } // action was suppressed by user if (suppress && null != action) { suppressedStandardActions[String.Concat(action.SequenceType.ToString(), id)] = action; } } break; case "AppSearch": Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Signature"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "AppSearch"]); requiredActions.Add(this.standardActions[SequenceType.installUI, "AppSearch"]); break; case "Binary": case "Icon": case "MsiDigitalCertificate": foreach (Row row in table.Rows) { ImportStreamType importStreamType = ImportStreamType.Unknown; switch (table.Name) { case "Binary": importStreamType = ImportStreamType.Binary; break; case "Icon": importStreamType = ImportStreamType.Icon; break; case "MsiDigitalCertificate": importStreamType = ImportStreamType.DigitalCertificate; break; } ImportStream importStream = new ImportStream(importStreamType, row[0].ToString(), row[1].ToString()); if (this.activeOutput.ImportStreams.Contains(importStream.Name)) { this.OnMessage(WixErrors.DuplicateSymbol(row.SourceLineNumbers, String.Format("{0} element with Id='{1}' is defined multiple times.", table.Name, row.Symbol.Name))); } this.activeOutput.ImportStreams.Add(importStream); } Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions[table.Name]); copyRows = false; break; case "BindImage": requiredActions.Add(this.standardActions[SequenceType.installExecute, "BindImage"]); break; case "CCPSearch": requiredActions.Add(this.standardActions[SequenceType.installExecute, "AppSearch"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "CCPSearch"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RMCCPSearch"]); requiredActions.Add(this.standardActions[SequenceType.installUI, "AppSearch"]); requiredActions.Add(this.standardActions[SequenceType.installUI, "CCPSearch"]); requiredActions.Add(this.standardActions[SequenceType.installUI, "RMCCPSearch"]); break; case "Class": requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "RegisterClassInfo"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterClassInfo"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterClassInfo"]); break; case "Complus": requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterComPlus"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterComPlus"]); break; case "CreateFolder": requiredActions.Add(this.standardActions[SequenceType.installExecute, "CreateFolders"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveFolders"]); break; case "CustomAction": if (OutputType.Module == this.activeOutput.Type) { Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminExecuteSequence"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminUISequence"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdvtExecuteSequence"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallExecuteSequence"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallUISequence"]); } break; case "CustomTables": foreach (Row row in table.Rows) { TableDefinition customTable = new TableDefinition((string)row[0], false); if (null == row[4]) { this.OnMessage(WixErrors.ExpectedAttribute(row.SourceLineNumbers, "CustomTable/Column", "PrimaryKey")); } string[] columnNames = row[2].ToString().Split(tabCharacter); string[] columnTypes = row[3].ToString().Split(tabCharacter); string[] primaryKeys = row[4].ToString().Split(tabCharacter); string[] minValues = row[5] == null ? null : row[5].ToString().Split(tabCharacter); string[] maxValues = row[6] == null ? null : row[6].ToString().Split(tabCharacter); string[] keyTables = row[7] == null ? null : row[7].ToString().Split(tabCharacter); string[] keyColumns = row[8] == null ? null : row[8].ToString().Split(tabCharacter); string[] categories = row[9] == null ? null : row[9].ToString().Split(tabCharacter); string[] sets = row[10] == null ? null : row[10].ToString().Split(tabCharacter); string[] descriptions = row[11] == null ? null : row[11].ToString().Split(tabCharacter); string[] modularizations = row[12] == null ? null : row[12].ToString().Split(tabCharacter); int currentPrimaryKey = 0; for (int i = 0; i < columnNames.Length; ++i) { string name = columnNames[i]; ColumnType type = ColumnType.Unknown; switch (columnTypes[i].Substring(0, 1).ToLower(CultureInfo.InvariantCulture)) { case "s": type = ColumnType.String; break; case "l": type = ColumnType.Localized; break; case "i": type = ColumnType.Number; break; case "g": type = ColumnType.Object; break; default: throw new ApplicationException(String.Format("Unknown custom table column type: {0}", columnTypes[i])); } bool nullable = columnTypes[i].Substring(0, 1) == columnTypes[i].Substring(0, 1).ToUpper(CultureInfo.InvariantCulture); int length = Convert.ToInt32(columnTypes[i].Substring(1)); bool primaryKey = false; if (currentPrimaryKey < primaryKeys.Length && primaryKeys[currentPrimaryKey] == columnNames[i]) { primaryKey = true; currentPrimaryKey++; } bool minValSet = null != minValues && null != minValues[i] && 0 < minValues[i].Length; int minValue = 0; if (minValSet) { minValue = Convert.ToInt32(minValues[i]); } bool maxValSet = null != maxValues && null != maxValues[i] && 0 < maxValues[i].Length; int maxValue = 0; if (maxValSet) { maxValue = Convert.ToInt32(maxValues[i]); } bool keyColumnSet = null != keyColumns && null != keyColumns[i] && 0 < keyColumns[i].Length; int keyColumn = 0; if (keyColumnSet) { keyColumn = Convert.ToInt32(keyColumns[i]); } ColumnCategory category = ColumnCategory.Unknown; if (null != categories && null != categories[i] && 0 < categories[i].Length) { switch (categories[i]) { case "Text": category = ColumnCategory.Text; break; case "UpperCase": category = ColumnCategory.UpperCase; break; case "LowerCase": category = ColumnCategory.LowerCase; break; case "Integer": category = ColumnCategory.Integer; break; case "DoubleInteger": category = ColumnCategory.DoubleInteger; break; case "TimeDate": category = ColumnCategory.TimeDate; break; case "Identifier": category = ColumnCategory.Identifier; break; case "Property": category = ColumnCategory.Property; break; case "Filename": category = ColumnCategory.Filename; break; case "WildCardFilename": category = ColumnCategory.WildCardFilename; break; case "Path": category = ColumnCategory.Path; break; case "Paths": category = ColumnCategory.Paths; break; case "AnyPath": category = ColumnCategory.AnyPath; break; case "DefaultDir": category = ColumnCategory.DefaultDir; break; case "RegPath": category = ColumnCategory.RegPath; break; case "Formatted": category = ColumnCategory.Formatted; break; case "Template": category = ColumnCategory.Template; break; case "Condition": category = ColumnCategory.Condition; break; case "Guid": category = ColumnCategory.Guid; break; case "Version": category = ColumnCategory.Version; break; case "Language": category = ColumnCategory.Language; break; case "Binary": category = ColumnCategory.Binary; break; case "CustomSource": category = ColumnCategory.CustomSource; break; case "Cabinet": category = ColumnCategory.Cabinet; break; case "Shortcut": category = ColumnCategory.Shortcut; break; default: break; } } string keyTable = keyTables != null ? keyTables[i] : null; string setValue = sets != null ? sets[i] : null; string description = descriptions != null ? descriptions[i] : null; string modString = modularizations != null ? modularizations[i] : null; ColumnModularizeType modularization = ColumnModularizeType.None; if (modString != null) { switch (modString) { case "None": modularization = ColumnModularizeType.None; break; case "Column": modularization = ColumnModularizeType.Column; break; case "Property": modularization = ColumnModularizeType.Property; break; case "Condition": modularization = ColumnModularizeType.Condition; break; case "CompanionFile": modularization = ColumnModularizeType.CompanionFile; break; case "SemicolonDelimited": modularization = ColumnModularizeType.SemicolonDelimited; break; } } ColumnDefinition columnDefinition = new ColumnDefinition(name, type, length, primaryKey, false, nullable, modularization, false, ColumnType.Localized == type, minValSet, minValue, maxValSet, maxValue, keyTable, keyColumnSet, keyColumn, category, setValue, description, true, true); customTable.Columns.Add(columnDefinition); } customTableDefinitions.Add(customTable); } copyRows = false; // we've created table definitions from these rows, no need to process them any longer break; case "RowData": foreach (Row row in table.Rows) { customRows.Add(row); } copyRows = false; break; case "Dialog": Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ListBox"]); break; case "Directory": foreach (Row row in table.Rows) { if (OutputType.Module == this.activeOutput.Type && Common.IsStandardDirectory(row[0].ToString())) { // if the directory table contains references to standard windows folders // mergemod.dll will add customactions to set the MSM directory to // the same directory as the standard windows folder and will add references to // custom action to all the standard sequence tables. A problem will occur // if the MSI does not have these tables as mergemod.dll does not add these // tables to the MSI if absent. This code adds the tables in case mergemod.dll // needs them. Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["CustomAction"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminExecuteSequence"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminUISequence"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdvtExecuteSequence"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallExecuteSequence"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallUISequence"]); break; // no need to look here any more, we already found all that we needed to } } break; case "DuplicateFile": requiredActions.Add(this.standardActions[SequenceType.installExecute, "DuplicateFiles"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveDuplicateFiles"]); break; case "EnsureTables": foreach (Row row in table.Rows) { ensureTableRows.Add(row); } break; case "Environment": requiredActions.Add(this.standardActions[SequenceType.installExecute, "WriteEnvironmentStrings"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveEnvironmentStrings"]); break; case "Extension": requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "RegisterExtensionInfo"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterExtensionInfo"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterExtensionInfo"]); break; case "File": foreach (FileRow row in table.Rows) { // DiskId is not valid when creating a module, so set it to // 0 for all files to ensure proper sorting in the binder if (OutputType.Module == this.activeOutput.Type) { row.DiskId = 0; } // if we have an assembly, insert the MsiAssembly row and assembly actions if (FileAssemblyType.NotAnAssembly != row.AssemblyType) { string feature; if (OutputType.Module == output.Type) { feature = Guid.Empty.ToString("B"); } else { ConnectToFeature connect = componentsToFeatures[row.Component]; if (null == connect) { throw new WixMissingFeatureException(row.SourceLineNumbers, new FeatureBacklink(row.Component, FeatureBacklinkType.Assembly, row.File)); } feature = connect.PrimaryFeature; } OutputTable assemblyOutputTable = Common.EnsureOutputTable(output, this.tableDefinitions["MsiAssembly"]); Row assemblyRow = new Row(assemblyOutputTable.TableDefinition); assemblyRow[0] = row.Component; assemblyRow[1] = feature; assemblyRow[2] = row.AssemblyManifest; assemblyRow[3] = row.AssemblyApplication; assemblyRow[4] = Convert.ToInt32(row.AssemblyType); assemblyOutputTable.OutputRows.Add(new OutputRow(assemblyRow, this.sectionIdOnTuples ? section.Id : null)); requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "MsiPublishAssemblies"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "MsiPublishAssemblies"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "MsiUnpublishAssemblies"]); } if (null == row.Source) // source to the file must be provided { this.OnMessage(WixErrors.FileSourceRequired(row.SourceLineNumbers, row.File)); } this.activeOutput.FileMediaInformationCollection.Add(new FileMediaInformation(row)); } requiredActions.Add(this.standardActions[SequenceType.installExecute, "InstallFiles"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveFiles"]); break; case "Font": requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterFonts"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterFonts"]); break; case "IniFile": case "RemoveIniFile": requiredActions.Add(this.standardActions[SequenceType.installExecute, "WriteIniValues"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveIniValues"]); break; case "IsolatedComponent": requiredActions.Add(this.standardActions[SequenceType.installExecute, "IsolateComponents"]); break; case "LaunchCondition": requiredActions.Add(this.standardActions[SequenceType.installExecute, "LaunchConditions"]); requiredActions.Add(this.standardActions[SequenceType.installUI, "LaunchConditions"]); break; case "Media": foreach (MediaRow row in table.Rows) { this.activeOutput.MediaRows.Add(row); } copyRows = false; break; case "Merge": // just copy the rows to the output copyRows = true; break; case "MIME": requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "RegisterMIMEInfo"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterMIMEInfo"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterMIMEInfo"]); break; case "ModuleSignature": if (OutputType.Module == this.activeOutput.Type) { foreach (Row row in table.Rows) { if (null != this.activeOutput.ModularizationGuid) { throw new ArgumentOutOfRangeException("Unexpected number of rows found in table", "ModuleSignature"); } this.activeOutput.ModularizationGuid = row[3].ToString(); } } break; case "ModuleSubstitution": containsModuleSubstitution = true; break; case "ModuleConfiguration": containsModuleConfiguration = true; break; case "MoveFile": requiredActions.Add(this.standardActions[SequenceType.installExecute, "MoveFiles"]); break; case "MsiAssembly": requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "MsiPublishAssemblies"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "MsiPublishAssemblies"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "MsiUnpublishAssemblies"]); break; case "ODBCDataSource": case "ODBCTranslator": case "ODBCDriver": requiredActions.Add(this.standardActions[SequenceType.installExecute, "SetODBCFolders"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "InstallODBC"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveODBC"]); break; case "ProgId": requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "RegisterProgIdInfo"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterProgIdInfo"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterProgIdInfo"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Extension"]); // Extension table is required with a ProgId table break; case "Property": foreach (PropertyRow row in table.Rows) { // if there is no value in the property, then it must be virtual if (null == row.Value || 0 == row.Value.Length) { row.IsUnreal = true; } if (row.Admin) { adminProperties[row.Id] = null; } if (row.Secure) { secureProperties[row.Id] = null; } if (row.Hidden) { hiddenProperties[row.Id] = null; } } break; case "PublishComponent": requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "PublishComponents"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "PublishComponents"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnpublishComponents"]); break; case "Registry": requiredActions.Add(this.standardActions[SequenceType.installExecute, "WriteRegistryValues"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveRegistryValues"]); break; case "RemoveFile": requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveFiles"]); break; case "SelfReg": requiredActions.Add(this.standardActions[SequenceType.installExecute, "SelfRegModules"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "SelfUnregModules"]); break; case "ServiceControl": requiredActions.Add(this.standardActions[SequenceType.installExecute, "StartServices"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "StopServices"]); break; case "ServiceInstall": requiredActions.Add(this.standardActions[SequenceType.installExecute, "InstallServices"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "DeleteServices"]); break; case "Shortcut": requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "CreateShortcuts"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "CreateShortcuts"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveShortcuts"]); break; case "TypeLib": requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterTypeLibraries"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterTypeLibraries"]); break; case "Upgrade": { requiredActions.Add(this.standardActions[SequenceType.installExecute, "FindRelatedProducts"]); requiredActions.Add(this.standardActions[SequenceType.installExecute, "MigrateFeatureStates"]); requiredActions.Add(this.standardActions[SequenceType.installUI, "FindRelatedProducts"]); requiredActions.Add(this.standardActions[SequenceType.installUI, "MigrateFeatureStates"]); foreach (UpgradeRow row in table.Rows) { // this should never happen because candle will make sure that all UpgradeVersion(s) have an ActionProperty...but still don't let it slide if (null == row.ActionProperty) { this.OnMessage(WixErrors.ExpectedAttribute(row.SourceLineNumbers, "UpgradeVersion", "ActionProperty")); } secureProperties[row.ActionProperty] = null; } break; } case "_SummaryInformation": // if we are processing a product, reach into the summary // information and pull out the bits that say if the layout // image is supposed to have long file names and is compressed if (OutputType.Product == output.Type) { foreach (Row row in table.Rows) { // we're looking for the "Word Count" property which happens to // be number 15 (and I thought the answer to the universe was 42, heh). if ("15" == row[0].ToString()) { output.LongFileNames = (0 == (Convert.ToInt32(row[1]) & 1)); output.Compressed = (2 == (Convert.ToInt32(row[1]) & 2)); break; // we're done looking for what we came looking for } } } break; } if (copyRows) { OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions[table.Name]); this.CopyTableRowsToOutputTable(table, outputTable, section.Id); } } } if (0 < ensureTableRows.Count) { foreach (Row row in ensureTableRows) { string tableId = (string)row[0]; TableDefinition tableDef = null; try { tableDef = this.tableDefinitions[tableId]; } catch (WixMissingTableDefinitionException) { tableDef = customTableDefinitions[tableId]; } Common.EnsureOutputTable(this.activeOutput, tableDef); } } // copy all the suppress action rows to the output to suppress actions from merge modules if (0 < suppressActionRows.Count) { OutputTable suppressActionOutputTable = new OutputTable(this.tableDefinitions["SuppressAction"]); this.activeOutput.OutputTables.Add(suppressActionOutputTable); foreach (Row suppressActionRow in suppressActionRows) { suppressActionOutputTable.OutputRows.Add(new OutputRow(suppressActionRow)); } } foreach (Action suppressedAction in suppressedStandardActions.Values) { if (requiredActions.Contains(suppressedAction)) { // We thought they really ought to have a standard action // that they wanted to suppress, so warn them and remove it this.OnMessage(WixWarnings.SuppressAction(suppressedAction.Id, Action.SequenceTypeToString(suppressedAction.SequenceType))); requiredActions.Remove(suppressedAction); } } // check for missing table and add them or display an error as appropriate switch (this.activeOutput.Type) { case OutputType.Module: Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Component"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Directory"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["FeatureComponents"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["File"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ModuleComponents"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ModuleSignature"]); break; case OutputType.PatchCreation: OutputTable imageFamiliesTable = this.activeOutput.OutputTables["ImageFamilies"]; OutputTable targetImagesTable = this.activeOutput.OutputTables["TargetImages"]; OutputTable upgradedImagesTable = this.activeOutput.OutputTables["UpgradedImages"]; if (null == imageFamiliesTable || 1 > imageFamiliesTable.OutputRows.Count) { this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("ImageFamilies")); } if (null == targetImagesTable || 1 > targetImagesTable.OutputRows.Count) { this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("TargetImages")); } if (null == upgradedImagesTable || 1 > upgradedImagesTable.OutputRows.Count) { this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("UpgradedImages")); } Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Properties"]); break; case OutputType.Product: // AdminExecuteSequence Table this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "CostInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "CostInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "FileCost"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "CostFinalize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallValidate"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallFiles"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallAdminPackage"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallFinalize"]); // AdminUISequence Table this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminUI, "CostInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminUI, "FileCost"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminUI, "CostFinalize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminUI, "ExecuteAction"]); // AdvtExecuteSequence Table this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "CostInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "CostFinalize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "InstallValidate"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "InstallInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "PublishFeatures"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "PublishProduct"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "InstallFinalize"]); // InstallExecuteSequence Table this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "ValidateProductID"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "CostInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "FileCost"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "CostFinalize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "InstallValidate"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "InstallInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "ProcessComponents"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "UnpublishFeatures"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "CostInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "RegisterUser"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "RegisterProduct"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "PublishFeatures"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "PublishProduct"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "InstallFinalize"]); // InstallUISequence Table this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "ValidateProductID"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "CostInitialize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "FileCost"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "CostFinalize"]); this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "ExecuteAction"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["File"]); Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Media"]); break; } // check for illegal tables foreach (OutputTable table in this.activeOutput.OutputTables) { switch (this.activeOutput.Type) { case OutputType.Module: if ("BBControl" == table.Name || "Billboard" == table.Name || "CCPSearch" == table.Name || "Feature" == table.Name || "LaunchCondition" == table.Name || "Media" == table.Name || "Merge" == table.Name || "Patch" == table.Name || "Upgrade" == table.Name) { foreach (OutputRow outputRow in table.OutputRows) { this.OnMessage(WixErrors.UnexpectedTableInMergeModule(outputRow.Row.SourceLineNumbers, table.Name)); } } else if ("Error" == table.Name) { foreach (OutputRow outputRow in table.OutputRows) { this.OnMessage(WixWarnings.DangerousTableInMergeModule(outputRow.Row.SourceLineNumbers, table.Name)); } } break; case OutputType.PatchCreation: if ("_SummaryInformation" != table.Name && "ExternalFiles" != table.Name && "FamilyFileRanges" != table.Name && "ImageFamilies" != table.Name && "PatchMetadata" != table.Name && "PatchSequence" != table.Name && "Properties" != table.Name && "TargetFiles_OptionalData" != table.Name && "TargetImages" != table.Name && "UpgradedFiles_OptionalData" != table.Name && "UpgradedFilesToIgnore" != table.Name && "UpgradedImages" != table.Name) { foreach (OutputRow outputRow in table.OutputRows) { this.OnMessage(WixErrors.UnexpectedTableInPatchCreationPackage(outputRow.Row.SourceLineNumbers, table.Name)); } } break; case OutputType.Product: if ("ModuleAdminExecuteSequence" == table.Name || "ModuleAdminUISequence" == table.Name || "ModuleAdvtExecuteSequence" == table.Name || "ModuleAdvtUISequence" == table.Name || "ModuleComponents" == table.Name || "ModuleConfiguration" == table.Name || "ModuleDependency" == table.Name || "ModuleExclusion" == table.Name || "ModuleIgnoreTable" == table.Name || "ModuleInstallExecuteSequence" == table.Name || "ModuleInstallUISequence" == table.Name || "ModuleSignature" == table.Name || "ModuleSubstitution" == table.Name) { foreach (OutputRow outputRow in table.OutputRows) { this.OnMessage(WixWarnings.UnexpectedTableInProduct(outputRow.Row.SourceLineNumbers, table.Name)); } } break; } } // add the custom row data foreach (Row row in customRows) { TableDefinition customTable = (TableDefinition)customTableDefinitions[row[0].ToString()]; string[] data = row[2].ToString().Split(tabCharacter); Row customRow = new Row(customTable); for (int i = 0; i < data.Length; ++i) { string[] item = data[i].Split(colonCharacter, 2); customRow.SetData(item[0], item[1]); } bool dataErrors = false; for (int i = 0; i < customTable.Columns.Count; ++i) { if (!customTable.Columns[i].IsNullable && customRow.IsColumnEmpty(i)) { this.OnMessage(WixErrors.NoDataForColumn(row.SourceLineNumbers, customTable.Columns[i].Name, customTable.Name)); dataErrors = true; } } if (!dataErrors) { OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, customTable); outputTable.OutputRows.Add(new OutputRow(customRow)); } } // update the special properties if (0 < adminProperties.Count) { Row newRow = new Row(this.tableDefinitions["Property"]); newRow[0] = "AdminProperties"; newRow[1] = GetPropertyListString(adminProperties); OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Property"]); outputTable.OutputRows.Add(new OutputRow(newRow)); } if (0 < secureProperties.Count) { Row newRow = new Row(this.tableDefinitions["Property"]); newRow[0] = "SecureCustomProperties"; newRow[1] = GetPropertyListString(secureProperties); OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Property"]); outputTable.OutputRows.Add(new OutputRow(newRow)); } if (0 < hiddenProperties.Count) { Row newRow = new Row(this.tableDefinitions["Property"]); newRow[0] = "MsiHiddenProperties"; newRow[1] = GetPropertyListString(hiddenProperties); OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Property"]); outputTable.OutputRows.Add(new OutputRow(newRow)); } if (containsModuleSubstitution) { Row newRow = new Row(this.tableDefinitions["ModuleIgnoreTable"]); newRow[0] = "ModuleSubstitution"; OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ModuleIgnoreTable"]); outputTable.OutputRows.Add(new OutputRow(newRow)); } if (containsModuleConfiguration) { Row newRow = new Row(this.tableDefinitions["ModuleIgnoreTable"]); newRow[0] = "ModuleConfiguration"; OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ModuleIgnoreTable"]); outputTable.OutputRows.Add(new OutputRow(newRow)); } // process the actions foreach (Action action in requiredActions) { // skip actions in suppressed sequences if (suppressedSequenceTypes.Contains(action.SequenceType)) { continue; } if (OutputType.Product == this.activeOutput.Type) { this.ResolveActionSequence(action, requiredActions); } TableDefinition sequenceTableDef = null; bool module = OutputType.Module == this.activeOutput.Type; switch (action.SequenceType) { case SequenceType.adminExecute: if (module) { Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminExecuteSequence"]); sequenceTableDef = this.tableDefinitions["ModuleAdminExecuteSequence"]; } else { sequenceTableDef = this.tableDefinitions["AdminExecuteSequence"]; } break; case SequenceType.adminUI: if (module) { Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminUISequence"]); sequenceTableDef = this.tableDefinitions["ModuleAdminUISequence"]; } else { sequenceTableDef = this.tableDefinitions["AdminUISequence"]; } break; case SequenceType.advertiseExecute: if (module) { Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdvtExecuteSequence"]); sequenceTableDef = this.tableDefinitions["ModuleAdvtExecuteSequence"]; } else { sequenceTableDef = this.tableDefinitions["AdvtExecuteSequence"]; } break; case SequenceType.installExecute: if (module) { Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallExecuteSequence"]); sequenceTableDef = this.tableDefinitions["ModuleInstallExecuteSequence"]; } else { sequenceTableDef = this.tableDefinitions["InstallExecuteSequence"]; } break; case SequenceType.installUI: if (module) { Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallUISequence"]); sequenceTableDef = this.tableDefinitions["ModuleInstallUISequence"]; } else { sequenceTableDef = this.tableDefinitions["InstallUISequence"]; } break; } Row row = new Row(sequenceTableDef); if (module) { row[0] = action.Id; if (0 != action.SequenceNumber) { row[1] = action.SequenceNumber; } else { bool after = null == action.Before; row[2] = after ? action.After : action.Before; row[3] = after ? 1 : 0; } row[4] = action.Condition; } else // add the row to the sequence table { row[0] = action.Id; row[1] = action.Condition; row[2] = action.SequenceNumber; } OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, sequenceTableDef); outputTable.OutputRows.Add(new OutputRow(row)); } // set the suppressed action sequences if (this.suppressAdminSequence) { this.activeOutput.SuppressAdminSequence = true; } if (this.suppressAdvertiseSequence) { this.activeOutput.SuppressAdvertiseSequence = true; } if (this.suppressUISequence) { this.activeOutput.SuppressUISequence = true; } } finally { this.activeOutput = null; } return (this.foundError ? null : output); }
/// <summary> /// Creates a new instance of the <see cref="ProviderDependency"/> class from a <see cref="Row"/>. /// </summary> /// <param name="row">The <see cref="Row"/> from which data is imported.</param> internal ProvidesDependency(Row row) : this((string)row[2], (string)row[3], (string)row[4], (int?)row[5]) { }