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);
        }
示例#3
0
        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);
        }