From 5d08e0a4bbf4e4ba28300b8bace1089b64b198d7 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Wed, 30 Mar 2022 10:35:02 -0700 Subject: Implement IWindowsInstallerDecompileExtensions Update Util extension to validate extension model and fix some small issues in MSI decompiling. Fixes 6367 --- .../BaseWindowsInstallerBackendBinderExtension.cs | 8 +- .../BaseWindowsInstallerDecompilerExtension.cs | 77 +++++++++ .../Data/IWindowsInstallerDecompileContext.cs | 12 +- .../Data/IWindowsInstallerDecompileResult.cs | 15 +- .../DecompilerExtension.cs | 61 ------- .../IWindowsInstallerDecompilerExtension.cs | 30 +++- .../Services/IWindowsInstallerDecompilerHelper.cs | 180 +++++++++++++++++++++ 7 files changed, 313 insertions(+), 70 deletions(-) create mode 100644 src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerDecompilerExtension.cs delete mode 100644 src/api/wix/WixToolset.Extensibility/DecompilerExtension.cs create mode 100644 src/api/wix/WixToolset.Extensibility/Services/IWindowsInstallerDecompilerHelper.cs (limited to 'src/api') diff --git a/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerBackendBinderExtension.cs b/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerBackendBinderExtension.cs index e48579d7..a54f05fc 100644 --- a/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerBackendBinderExtension.cs +++ b/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerBackendBinderExtension.cs @@ -4,7 +4,6 @@ namespace WixToolset.Extensibility { using System; using System.Collections.Generic; - using System.Linq; using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Data.WindowsInstaller; @@ -12,7 +11,7 @@ namespace WixToolset.Extensibility using WixToolset.Extensibility.Services; /// - /// Base class for creating a preprocessor extension. + /// Base class for creating a windows installer backend extension. /// public abstract class BaseWindowsInstallerBackendBinderExtension : IWindowsInstallerBackendBinderExtension { @@ -39,7 +38,10 @@ namespace WixToolset.Extensibility /// /// Creates a resolved cabinet result. /// - protected IResolvedCabinet CreateResolvedCabinet() => this.Context.ServiceProvider.GetService(); + protected IResolvedCabinet CreateResolvedCabinet() + { + return this.Context.ServiceProvider.GetService(); + } /// /// See diff --git a/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerDecompilerExtension.cs b/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerDecompilerExtension.cs new file mode 100644 index 00000000..8072cd88 --- /dev/null +++ b/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerDecompilerExtension.cs @@ -0,0 +1,77 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Extensibility +{ + using System.Collections.Generic; + using WixToolset.Data; + using WixToolset.Data.WindowsInstaller; + using WixToolset.Extensibility.Data; + using WixToolset.Extensibility.Services; + + /// + /// Base class for creating a windows installer decompiler extensions. + /// + public abstract class BaseWindowsInstallerDecompilerExtension : IWindowsInstallerDecompilerExtension + { + /// + /// Context for use by the extension. + /// + protected IWindowsInstallerDecompileContext Context { get; private set; } + + /// + /// Messaging for use by the extension. + /// + protected IMessaging Messaging { get; private set; } + + /// + /// Decompiler helper for use by the extension. + /// + protected IWindowsInstallerDecompilerHelper DecompilerHelper { get; private set; } + + /// + /// See + /// + public virtual IReadOnlyCollection TableDefinitions { get; } + + /// + /// See + /// + public virtual void PreDecompile(IWindowsInstallerDecompileContext context) + { + this.Context = context; + + this.Messaging = context.ServiceProvider.GetService(); + + this.DecompilerHelper = context.ServiceProvider.GetService(); + } + + /// + /// See + /// + public virtual void PreDecompileTables(TableIndexedCollection tables) + { + } + + /// + /// See + /// + public virtual bool TryDecompileTable(Table table) + { + return false; + } + + /// + /// See + /// + public virtual void PostDecompileTables(TableIndexedCollection tables) + { + } + + /// + /// See + /// + public virtual void PostDecompile(IWindowsInstallerDecompileResult result) + { + } + } +} diff --git a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs index f744121a..27d30a5a 100644 --- a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs +++ b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs @@ -7,7 +7,7 @@ namespace WixToolset.Extensibility.Data using WixToolset.Data; /// - /// The context used to decompile Windows Installer packages. + /// The context used to decompile a Windows Installer database. /// public interface IWindowsInstallerDecompileContext { @@ -31,6 +31,16 @@ namespace WixToolset.Extensibility.Data /// IReadOnlyCollection Extensions { get; set; } + /// + /// Collection of extension data to use during decompiling. + /// + IReadOnlyCollection ExtensionData { get; set; } + + /// + /// Symbol definition creator used to load extension data. + /// + ISymbolDefinitionCreator SymbolDefinitionCreator { get; set; } + /// /// Gets or sets the folder where content is extracted. /// diff --git a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileResult.cs b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileResult.cs index 3b1dd815..724dd7fc 100644 --- a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileResult.cs +++ b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileResult.cs @@ -6,13 +6,24 @@ namespace WixToolset.Extensibility.Data using System.Xml.Linq; using WixToolset.Data; -#pragma warning disable 1591 // TODO: add documentation + /// + /// The result from decompiling a Windows Installer database. + /// public interface IWindowsInstallerDecompileResult { + /// + /// Decompiled document. + /// XDocument Document { get; set; } - IReadOnlyCollection ExtractedFilePaths { get; set; } + /// + /// Extracted paths. + /// + IList ExtractedFilePaths { get; set; } + /// + /// Decompiled platform. + /// Platform? Platform { get; set; } } } diff --git a/src/api/wix/WixToolset.Extensibility/DecompilerExtension.cs b/src/api/wix/WixToolset.Extensibility/DecompilerExtension.cs deleted file mode 100644 index b492cf3a..00000000 --- a/src/api/wix/WixToolset.Extensibility/DecompilerExtension.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Extensibility -{ - using WixToolset.Data; - -#if BRING_BACK_LATER - /// - /// Base class for creating a decompiler extension. - /// - public abstract class DecompilerExtension : IDecompilerExtension - { - /// - /// Gets or sets the decompiler core for the extension. - /// - /// The decompiler core for the extension. - public IDecompilerCore Core { get; set; } - - /// - /// Gets the table definitions this extension decompiles. - /// - /// Table definitions this extension decompiles. - public virtual TableDefinitionCollection TableDefinitions { get; protected set; } - - /// - /// Gets the library that this decompiler wants removed from the decomipiled output. - /// - /// The table definitions to use while loading the library. - /// The library for this extension or null if there is no library to be removed. - public virtual Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions) - { - return null; - } - - /// - /// Called at the beginning of the decompilation of a database. - /// - /// The collection of all tables. - public virtual void Initialize(TableIndexedCollection tables) - { - } - - /// - /// Decompiles an extension table. - /// - /// The table to decompile. - public virtual void DecompileTable(Table table) - { - this.Core.UnexpectedTable(table); - } - - /// - /// Finalize decompilation. - /// - /// The collection of all tables. - public virtual void Finish(TableIndexedCollection tables) - { - } - } -#endif -} diff --git a/src/api/wix/WixToolset.Extensibility/IWindowsInstallerDecompilerExtension.cs b/src/api/wix/WixToolset.Extensibility/IWindowsInstallerDecompilerExtension.cs index add5f886..f7d54799 100644 --- a/src/api/wix/WixToolset.Extensibility/IWindowsInstallerDecompilerExtension.cs +++ b/src/api/wix/WixToolset.Extensibility/IWindowsInstallerDecompilerExtension.cs @@ -2,21 +2,45 @@ namespace WixToolset.Extensibility { - using WixToolset.Data; + using System.Collections.Generic; using WixToolset.Data.WindowsInstaller; using WixToolset.Extensibility.Data; /// - /// Interface all binder extensions implement. + /// Interface all windows installer decompiler extensions implement. /// public interface IWindowsInstallerDecompilerExtension { + /// + /// Gets the table definitions this extension decompiles. + /// + /// Table definitions this extension decompiles. + IReadOnlyCollection TableDefinitions { get; } + /// /// Called before decompiling occurs. /// + /// Decompile context. void PreDecompile(IWindowsInstallerDecompileContext context); - // TODO: Redesign this interface to be useful. + /// + /// Called before decompiling occurs. + /// + /// The collection of all tables. + void PreDecompileTables(TableIndexedCollection tables); + + /// + /// Try to decompile an extension table. + /// + /// The table to decompile. + /// True if the table was decompiled, false otherwise. + bool TryDecompileTable(Table table); + + /// + /// After decompilation tables. + /// + /// The collection of all tables. + void PostDecompileTables(TableIndexedCollection tables); /// /// Called after all output changes occur and right before the output is bound into its final format. diff --git a/src/api/wix/WixToolset.Extensibility/Services/IWindowsInstallerDecompilerHelper.cs b/src/api/wix/WixToolset.Extensibility/Services/IWindowsInstallerDecompilerHelper.cs new file mode 100644 index 00000000..1f5ac47a --- /dev/null +++ b/src/api/wix/WixToolset.Extensibility/Services/IWindowsInstallerDecompilerHelper.cs @@ -0,0 +1,180 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Extensibility.Services +{ + using System.Xml.Linq; + using WixToolset.Data.WindowsInstaller; + + /// + /// Interface provided to help Windows Installer decompiler extensions. + /// + public interface IWindowsInstallerDecompilerHelper + { + /// + /// Gets or sets the root element of the decompiled output. + /// + XElement RootElement { get; set; } + + /// + /// Creates an element from the standard WiX Toolset namespace and adds it to the root document. + /// + /// Name of the element to create and add. + /// Optional content to add to the new element. + /// Element in the standard namespace. + XElement AddElementToRoot(string name, params object[] content); + + /// + /// Creates an element with the specified name and adds it to the root document. + /// + /// Name of the element to create and add. + /// Optional content to add to the new element. + /// Element in the standard namespace. + XElement AddElementToRoot(XName name, params object[] content); + + /// + /// Adds an existing element to the root document. + /// + /// Element to add. + /// Same element provided. + XElement AddElementToRoot(XElement element); + + /// + /// Creates an element from the standard WiX Toolset namespace. + /// + /// Name of the element to create. + /// Optional content to add to the new element. + /// Element in the standard namespace. + XElement CreateElement(string name, params object[] content); + + /// + /// Get an element index by a row's table and primary keys. + /// + /// Row to get element. + /// Element indexed for the row or null if not found. + XElement GetIndexedElement(Row row); + + /// + /// Get an element index by table and primary key. + /// + /// Table name for indexed element. + /// Primary key for indexed element. + /// Element indexed for the table and primary key or null if not found. + XElement GetIndexedElement(string table, string primaryKey); + + /// + /// Get an element index by table and primary keys. + /// + /// Table name for indexed element. + /// Primary key for first column indexed element. + /// Primary key for second column indexed element. + /// Element indexed for the table and primary keys or null if not found. + XElement GetIndexedElement(string table, string primaryKey1, string primaryKey2); + + /// + /// Get an element index by table and primary keys. + /// + /// Table name for indexed element. + /// Primary key for first column indexed element. + /// Primary key for second column indexed element. + /// Primary key for third column indexed element. + /// Element indexed for the table and primary keys or null if not found. + XElement GetIndexedElement(string table, string primaryKey1, string primaryKey2, string primaryKey3); + + /// + /// Get an element index by table and primary keys. + /// + /// Table name for indexed element. + /// Primary keys for indexed element. + /// Element indexed for the table and primary keys or null if not found. + XElement GetIndexedElement(string table, string[] primaryKeys); + + /// + /// Try to get an element index by a row's table and primary keys. + /// + /// Row to get element. + /// Element indexed for the row. + /// True if the element was index otherwise false. + bool TryGetIndexedElement(Row row, out XElement element); + + /// + /// Try to get an element index by table name and primary key. + /// + /// Table name for indexed element. + /// Primary key for indexed element. + /// Element indexed for the table and primary key. + /// True if the element was index otherwise false. + bool TryGetIndexedElement(string table, string primaryKey, out XElement element); + + /// + /// Try to get an element index by table name and primary keys. + /// + /// Table name for indexed element. + /// First column's primary key for indexed element. + /// Second column's primary key for indexed element. + /// Element indexed for the table and primary key. + /// True if the element was index otherwise false. + bool TryGetIndexedElement(string table, string primaryKey1, string primaryKey2, out XElement element); + + /// + /// Try to get an element index by table name and primary keys. + /// + /// Table name for indexed element. + /// First column's primary key for indexed element. + /// Second column's primary key for indexed element. + /// Third column's primary key for indexed element. + /// Element indexed for the table and primary key. + /// True if the element was index otherwise false. + bool TryGetIndexedElement(string table, string primaryKey1, string primaryKey2, string primaryKey3, out XElement element); + + /// + /// Try to get an element index by table name and primary keys. + /// + /// Table name for indexed element. + /// Primary keys for indexed element. + /// Element indexed for the table and primary key. + /// True if the element was index otherwise false. + bool TryGetIndexedElement(string table, string[] primaryKeys, out XElement element); + + /// + /// Index an element by a row's table and primary keys. + /// + /// Row to index element. + /// Element to index. + void IndexElement(Row row, XElement element); + + /// + /// Index an element by table and primary key. + /// + /// Table name to index element. + /// Primary key to index element. + /// Element to index. + void IndexElement(string table, string primaryKey, XElement element); + + /// + /// Index an element by table and primary keys. + /// + /// Table name to index element. + /// First column's primary key to index element. + /// Second column's primary key to index element. + /// Element to index. + void IndexElement(string table, string primaryKey1, string primaryKey2, XElement element); + + /// + /// Index an element by table and primary keys. + /// + /// Table name to index element. + /// First column's primary key to index element. + /// Second column's primary key to index element. + /// Third column's primary key to index element. + /// Element to index. + void IndexElement(string table, string primaryKey1, string primaryKey2, string primaryKey3, XElement element); + + /// + /// Index an element by table and primary keys. + /// + /// Table name to index element. + /// Column's primary key to index element. + /// Element to index. + void IndexElement(string table, string[] primaryKeys, XElement element); + } +} -- cgit v1.2.3-55-g6feb