public Intermediate Execute() { #if TODO_PATCHING Output output; try { using (Database database = new Database(this.Context.InputFilePath, OpenDatabase.ReadOnly)) { var unbindCommand = new UnbindDatabaseCommand(this.Context.Messaging, database, this.Context.InputFilePath, OutputType.Product, this.Context.ExportBasePath, this.Context.IntermediateFolder, this.Context.IsAdminImage, this.Context.SuppressDemodularization, skipSummaryInfo: false); output = unbindCommand.Execute(); // extract the files from the cabinets if (!String.IsNullOrEmpty(this.Context.ExportBasePath) && !this.Context.SuppressExtractCabinets) { var extractCommand = new ExtractCabinetsCommand(output, database, this.Context.InputFilePath, this.Context.ExportBasePath, this.Context.IntermediateFolder); extractCommand.Execute(); } } } catch (Win32Exception e) { if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED { throw new WixException(WixErrors.OpenDatabaseFailed(this.Context.InputFilePath)); } throw; } return(output); #endif throw new NotImplementedException(); }
public IDecompileResult Execute() { var result = this.Context.ServiceProvider.GetService <IDecompileResult>(); try { using (var database = new Database(this.Context.DecompilePath, OpenDatabase.ReadOnly)) { // Delete the directory and its files to prevent cab extraction failure due to an existing file. if (Directory.Exists(this.Context.ExtractFolder)) { Directory.Delete(this.Context.ExtractFolder, true); } var unbindCommand = new UnbindDatabaseCommand(this.Messaging, database, this.Context.DecompilePath, this.Context.DecompileType, this.Context.ExtractFolder, this.Context.IntermediateFolder, this.Context.IsAdminImage, suppressDemodularization: false, skipSummaryInfo: false); var output = unbindCommand.Execute(); var extractedFilePaths = new List <string>(unbindCommand.ExportedFiles); var decompiler = new Decompiler(this.Messaging, this.Extensions, this.Context.BaseSourcePath, this.Context.SuppressCustomTables, this.Context.SuppressDroppingEmptyTables, this.Context.SuppressUI, this.Context.TreatProductAsModule); result.Document = decompiler.Decompile(output); result.Platform = GetPlatformFromOutput(output); // extract the files from the cabinets if (!String.IsNullOrEmpty(this.Context.ExtractFolder) && !this.Context.SuppressExtractCabinets) { var fileDirectory = String.IsNullOrEmpty(this.Context.CabinetExtractFolder) ? Path.Combine(this.Context.ExtractFolder, "File") : this.Context.CabinetExtractFolder; var extractCommand = new ExtractCabinetsCommand(output, database, this.Context.DecompilePath, fileDirectory, this.Context.IntermediateFolder, this.Context.TreatProductAsModule); extractCommand.Execute(); extractedFilePaths.AddRange(extractCommand.ExtractedFiles); result.ExtractedFilePaths = extractedFilePaths; } else { result.ExtractedFilePaths = new string[0]; } } } catch (Win32Exception e) { if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED { throw new WixException(ErrorMessages.OpenDatabaseFailed(this.Context.DecompilePath)); } throw; } return(result); }
public WindowsInstallerData Execute() { var transform = new WindowsInstallerData(new SourceLineNumber(this.TransformFile)); transform.Type = OutputType.Transform; // get the summary information table using (var summaryInformation = new SummaryInformation(this.TransformFile)) { var table = transform.EnsureTable(this.TableDefinitions["_SummaryInformation"]); for (var i = 1; 19 >= i; i++) { var value = summaryInformation.GetProperty(i); if (0 < value.Length) { var row = table.CreateRow(transform.SourceLineNumbers); row[0] = i; row[1] = value; } } } // create a schema msi which hopefully matches the table schemas in the transform var schemaOutput = new WindowsInstallerData(null); var msiDatabaseFile = Path.Combine(this.IntermediateFolder, "schema.msi"); foreach (var tableDefinition in this.TableDefinitions) { // skip unreal tables and the Patch table if (!tableDefinition.Unreal && "Patch" != tableDefinition.Name) { schemaOutput.EnsureTable(tableDefinition); } } var addedRows = new Dictionary <string, Row>(); Table transformViewTable; // Bind the schema msi. this.GenerateDatabase(schemaOutput, msiDatabaseFile); // apply the transform to the database and retrieve the modifications using (var msiDatabase = new Database(msiDatabaseFile, OpenDatabase.Transact)) { // apply the transform with the ViewTransform option to collect all the modifications msiDatabase.ApplyTransform(this.TransformFile, TransformErrorConditions.All | TransformErrorConditions.ViewTransform); // unbind the database var unbindCommand = new UnbindDatabaseCommand(this.Messaging, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true); var transformViewOutput = unbindCommand.Execute(); // index the added and possibly modified rows (added rows may also appears as modified rows) transformViewTable = transformViewOutput.Tables["_TransformView"]; var modifiedRows = new Hashtable(); foreach (var row in transformViewTable.Rows) { var tableName = (string)row[0]; var columnName = (string)row[1]; var primaryKeys = (string)row[2]; if ("INSERT" == columnName) { var index = String.Concat(tableName, ':', primaryKeys); addedRows.Add(index, null); } else if ("CREATE" != columnName && "DELETE" != columnName && "DROP" != columnName && null != primaryKeys) // modified row { var index = String.Concat(tableName, ':', primaryKeys); modifiedRows[index] = row; } } // create placeholder rows for modified rows to make the transform insert the updated values when its applied foreach (Row row in modifiedRows.Values) { var tableName = (string)row[0]; var columnName = (string)row[1]; var primaryKeys = (string)row[2]; var index = String.Concat(tableName, ':', primaryKeys); // ignore information for added rows if (!addedRows.ContainsKey(index)) { var table = schemaOutput.Tables[tableName]; this.CreateRow(table, primaryKeys, true); } } } // Re-bind the schema output with the placeholder rows. this.GenerateDatabase(schemaOutput, msiDatabaseFile); // apply the transform to the database and retrieve the modifications using (var msiDatabase = new Database(msiDatabaseFile, OpenDatabase.Transact)) { try { // apply the transform msiDatabase.ApplyTransform(this.TransformFile, TransformErrorConditions.All); // commit the database to guard against weird errors with streams msiDatabase.Commit(); } catch (Win32Exception ex) { if (0x65B == ex.NativeErrorCode) { // this commonly happens when the transform was built // against a database schema different from the internal // table definitions throw new WixException(ErrorMessages.TransformSchemaMismatch()); } } // unbind the database var unbindCommand = new UnbindDatabaseCommand(this.Messaging, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true); var output = unbindCommand.Execute(); // index all the rows to easily find modified rows var rows = new Dictionary <string, Row>(); foreach (var table in output.Tables) { foreach (var row in table.Rows) { rows.Add(String.Concat(table.Name, ':', row.GetPrimaryKey('\t', " ")), row); } } // process the _TransformView rows into transform rows foreach (var row in transformViewTable.Rows) { var tableName = (string)row[0]; var columnName = (string)row[1]; var primaryKeys = (string)row[2]; var table = transform.EnsureTable(this.TableDefinitions[tableName]); if ("CREATE" == columnName) // added table { table.Operation = TableOperation.Add; } else if ("DELETE" == columnName) // deleted row { var deletedRow = this.CreateRow(table, primaryKeys, false); deletedRow.Operation = RowOperation.Delete; } else if ("DROP" == columnName) // dropped table { table.Operation = TableOperation.Drop; } else if ("INSERT" == columnName) // added row { var index = String.Concat(tableName, ':', primaryKeys); var addedRow = rows[index]; addedRow.Operation = RowOperation.Add; table.Rows.Add(addedRow); } else if (null != primaryKeys) // modified row { var index = String.Concat(tableName, ':', primaryKeys); // the _TransformView table includes information for added rows // that looks like modified rows so it sometimes needs to be ignored if (!addedRows.ContainsKey(index)) { var modifiedRow = rows[index]; // mark the field as modified var indexOfModifiedValue = -1; for (var i = 0; i < modifiedRow.TableDefinition.Columns.Length; ++i) { if (columnName.Equals(modifiedRow.TableDefinition.Columns[i].Name, StringComparison.Ordinal)) { indexOfModifiedValue = i; break; } } modifiedRow.Fields[indexOfModifiedValue].Modified = true; // move the modified row into the transform the first time its encountered if (RowOperation.None == modifiedRow.Operation) { modifiedRow.Operation = RowOperation.Modify; table.Rows.Add(modifiedRow); } } } else // added column { var column = table.Definition.Columns.Single(c => c.Name.Equals(columnName, StringComparison.Ordinal)); column.Added = true; } } } return(transform); }