From dbde9e7104b907bbbaea17e21247d8cafc8b3a4c Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sat, 14 Oct 2017 16:12:07 -0700 Subject: Massive refactoring to introduce the concept of IBackend --- .../MergeMod/NativeMethods.cs | 508 +++++++++++++++++++++ 1 file changed, 508 insertions(+) create mode 100644 src/WixToolset.Core.WindowsInstaller/MergeMod/NativeMethods.cs (limited to 'src/WixToolset.Core.WindowsInstaller/MergeMod/NativeMethods.cs') diff --git a/src/WixToolset.Core.WindowsInstaller/MergeMod/NativeMethods.cs b/src/WixToolset.Core.WindowsInstaller/MergeMod/NativeMethods.cs new file mode 100644 index 00000000..daf259b4 --- /dev/null +++ b/src/WixToolset.Core.WindowsInstaller/MergeMod/NativeMethods.cs @@ -0,0 +1,508 @@ +// 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. +#if false +namespace WixToolset.MergeMod +{ + using System; + using System.Collections; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Errors returned by merge operations. + /// + [Guid("0ADDA825-2C26-11D2-AD65-00A0C9AF11A6")] + internal enum MsmErrorType + { + /// + /// A request was made to open a module with a language not supported by the module. + /// No more general language is supported by the module. + /// Adds msmErrorLanguageUnsupported to the Type property and the requested language + /// to the Language Property (Error Object). All Error object properties are empty. + /// The OpenModule function returns ERROR_INSTALL_LANGUAGE_UNSUPPORTED (as HRESULT). + /// + msmErrorLanguageUnsupported = 1, + + /// + /// A request was made to open a module with a supported language but the module has + /// an invalid language transform. Adds msmErrorLanguageFailed to the Type property + /// and the applied transform's language to the Language Property of the Error object. + /// This may not be the requested language if a more general language was used. + /// All other properties of the Error object are empty. The OpenModule function + /// returns ERROR_INSTALL_LANGUAGE_UNSUPPORTED (as HRESULT). + /// + msmErrorLanguageFailed = 2, + + /// + /// The module cannot be merged because it excludes, or is excluded by, another module + /// in the database. Adds msmErrorExclusion to the Type property of the Error object. + /// The ModuleKeys property or DatabaseKeys property contains the primary keys of the + /// excluded module's row in the ModuleExclusion table. If an existing module excludes + /// the module being merged, the excluded module's ModuleSignature information is added + /// to ModuleKeys. If the module being merged excludes an existing module, DatabaseKeys + /// contains the excluded module's ModuleSignature information. All other properties + /// are empty (or -1). + /// + msmErrorExclusion = 3, + + /// + /// Merge conflict during merge. The value of the Type property is set to + /// msmErrorTableMerge. The DatabaseTable property and DatabaseKeys property contain + /// the table name and primary keys of the conflicting row in the database. The + /// ModuleTable property and ModuleKeys property contain the table name and primary keys + /// of the conflicting row in the module. The ModuleTable and ModuleKeys entries may be + /// null if the row does not exist in the database. For example, if the conflict is in a + /// generated FeatureComponents table entry. On Windows Installer version 2.0, when + /// merging a configurable merge module, configuration may cause these properties to + /// refer to rows that do not exist in the module. + /// + msmErrorTableMerge = 4, + + /// + /// There was a problem resequencing a sequence table to contain the necessary merged + /// actions. The Type property is set to msmErrorResequenceMerge. The DatabaseTable + /// and DatabaseKeys properties contain the sequence table name and primary keys + /// (action name) of the conflicting row. The ModuleTable and ModuleKeys properties + /// contain the sequence table name and primary key (action name) of the conflicting row. + /// On Windows Installer version 2.0, when merging a configurable merge module, + /// configuration may cause these properties to refer to rows that do not exist in the module. + /// + msmErrorResequenceMerge = 5, + + /// + /// Not used. + /// + msmErrorFileCreate = 6, + + /// + /// There was a problem creating a directory to extract a file to disk. The Path property + /// contains the directory that could not be created. All other properties are empty or -1. + /// Not available with Windows Installer version 1.0. + /// + msmErrorDirCreate = 7, + + /// + /// A feature name is required to complete the merge, but no feature name was provided. + /// The Type property is set to msmErrorFeatureRequired. The DatabaseTable and DatabaseKeys + /// contain the table name and primary keys of the conflicting row. The ModuleTable and + /// ModuleKeys properties contain the table name and primary keys of the row cannot be merged. + /// On Windows Installer version 2.0, when merging a configurable merge module, configuration + /// may cause these properties to refer to rows that do not exist in the module. + /// If the failure is in a generated FeatureComponents table, the DatabaseTable and + /// DatabaseKeys properties are empty and the ModuleTable and ModuleKeys properties refer to + /// the row in the Component table causing the failure. + /// + msmErrorFeatureRequired = 8, + + /// + /// Available with Window Installer version 2.0. Substitution of a Null value into a + /// non-nullable column. This enters msmErrorBadNullSubstitution in the Type property and + /// enters "ModuleSubstitution" and the keys from the ModuleSubstitution table for this row + /// into the ModuleTable property and ModuleKeys property. All other properties of the Error + /// object are set to an empty string or -1. This error causes the immediate failure of the + /// merge and the MergeEx function to return E_FAIL. + /// + msmErrorBadNullSubstitution = 9, + + /// + /// Available with Window Installer version 2.0. Substitution of Text Format Type or Integer + /// Format Type into a Binary Type data column. This type of error returns + /// msmErrorBadSubstitutionType in the Type property and enters "ModuleSubstitution" and the + /// keys from the ModuleSubstitution table for this row into the ModuleTable property. + /// All other properties of the Error object are set to an empty string or -1. This error + /// causes the immediate failure of the merge and the MergeEx function to return E_FAIL. + /// + msmErrorBadSubstitutionType = 10, + + /// + /// Available with Window Installer Version 2.0. A row in the ModuleSubstitution table + /// references a configuration item not defined in the ModuleConfiguration table. + /// This type of error returns msmErrorMissingConfigItem in the Type property and enters + /// "ModuleSubstitution" and the keys from the ModuleSubstitution table for this row into + /// the ModuleTable property. All other properties of the Error object are set to an empty + /// string or -1. This error causes the immediate failure of the merge and the MergeEx + /// function to return E_FAIL. + /// + msmErrorMissingConfigItem = 11, + + /// + /// Available with Window Installer version 2.0. The authoring tool has returned a Null + /// value for an item marked with the msmConfigItemNonNullable attribute. An error of this + /// type returns msmErrorBadNullResponse in the Type property and enters "ModuleSubstitution" + /// and the keys from the ModuleSubstitution table for for the item into the ModuleTable property. + /// All other properties of the Error object are set to an empty string or -1. This error + /// causes the immediate failure of the merge and the MergeEx function to return E_FAIL. + /// + msmErrorBadNullResponse = 12, + + /// + /// Available with Window Installer version 2.0. The authoring tool returned a failure code + /// (not S_OK or S_FALSE) when asked for data. An error of this type will return + /// msmErrorDataRequestFailed in the Type property and enters "ModuleSubstitution" + /// and the keys from the ModuleSubstitution table for the item into the ModuleTable property. + /// All other properties of the Error object are set to an empty string or -1. This error + /// causes the immediate failure of the merge and the MergeEx function to return E_FAIL. + /// + msmErrorDataRequestFailed = 13, + + /// + /// Available with Windows Installer 2.0 and later versions. Indicates that an attempt was + /// made to merge a 64-bit module into a package that was not a 64-bit package. An error of + /// this type returns msmErrorPlatformMismatch in the Type property. All other properties of + /// the error object are set to an empty string or -1. This error causes the immediate failure + /// of the merge and causes the Merge function or MergeEx function to return E_FAIL. + /// + msmErrorPlatformMismatch = 14, + } + + /// + /// IMsmMerge2 interface. + /// + [ComImport, Guid("351A72AB-21CB-47ab-B7AA-C4D7B02EA305")] + internal interface IMsmMerge2 + { + /// + /// The OpenDatabase method of the Merge object opens a Windows Installer installation + /// database, located at a specified path, that is to be merged with a module. + /// + /// Path to the database being opened. + void OpenDatabase(string path); + + /// + /// The OpenModule method of the Merge object opens a Windows Installer merge module + /// in read-only mode. A module must be opened before it can be merged with an installation database. + /// + /// Fully qualified file name pointing to a merge module. + /// A valid language identifier (LANGID). + void OpenModule(string fileName, short language); + + /// + /// The CloseDatabase method of the Merge object closes the currently open Windows Installer database. + /// + /// true if changes should be saved, false otherwise. + void CloseDatabase(bool commit); + + /// + /// The CloseModule method of the Merge object closes the currently open Windows Installer merge module. + /// + void CloseModule(); + + /// + /// The OpenLog method of the Merge object opens a log file that receives progress and error messages. + /// If the log file already exists, the installer appends new messages. If the log file does not exist, + /// the installer creates a log file. + /// + /// Fully qualified filename pointing to a file to open or create. + void OpenLog(string fileName); + + /// + /// The CloseLog method of the Merge object closes the current log file. + /// + void CloseLog(); + + /// + /// The Log method of the Merge object writes a text string to the currently open log file. + /// + /// The text string to display. + void Log(string message); + + /// + /// Gets the errors from the last merge operation. + /// + /// The errors from the last merge operation. + IMsmErrors Errors + { + get; + } + + /// + /// Gets a collection of Dependency objects that enumerates a set of unsatisfied dependencies for the current database. + /// + /// A collection of Dependency objects that enumerates a set of unsatisfied dependencies for the current database. + object Dependencies + { + get; + } + + /// + /// The Merge method of the Merge object executes a merge of the current database and current + /// module. The merge attaches the components in the module to the feature identified by Feature. + /// The root of the module's directory tree is redirected to the location given by RedirectDir. + /// + /// The name of a feature in the database. + /// The key of an entry in the Directory table of the database. + /// This parameter may be NULL or an empty string. + void Merge(string feature, string redirectDir); + + /// + /// The Connect method of the Merge object connects a module to an additional feature. + /// The module must have already been merged into the database or will be merged into the database. + /// The feature must exist before calling this function. + /// + /// The name of a feature already existing in the database. + void Connect(string feature); + + /// + /// The ExtractCAB method of the Merge object extracts the embedded .cab file from a module and + /// saves it as the specified file. The installer creates this file if it does not already exist + /// and overwritten if it does exist. + /// + /// The fully qualified destination file. + void ExtractCAB(string fileName); + + /// + /// The ExtractFiles method of the Merge object extracts the embedded .cab file from a module + /// and then writes those files to the destination directory. + /// + /// The fully qualified destination directory. + void ExtractFiles(string path); + + /// + /// The MergeEx method of the Merge object is equivalent to the Merge function, except that it + /// takes an extra argument. The Merge method executes a merge of the current database and + /// current module. The merge attaches the components in the module to the feature identified + /// by Feature. The root of the module's directory tree is redirected to the location given by RedirectDir. + /// + /// The name of a feature in the database. + /// The key of an entry in the Directory table of the database. This parameter may + /// be NULL or an empty string. + /// The pConfiguration argument is an interface implemented by the client. The argument may + /// be NULL. The presence of this argument indicates that the client is capable of supporting the configuration + /// functionality, but does not obligate the client to provide configuration data for any specific configurable item. + void MergeEx(string feature, string redirectDir, IMsmConfigureModule configuration); + + /// + /// The ExtractFilesEx method of the Merge object extracts the embedded .cab file from a module and + /// then writes those files to the destination directory. + /// + /// The fully qualified destination directory. + /// Set to specify using long file names for path segments and final file names. + /// This is a list of fully-qualified paths for the files that were successfully extracted. + /// The list is empty if no files can be extracted. This argument may be null. No list is provided if pFilePaths is null. + void ExtractFilesEx(string path, bool longFileNames, ref IntPtr filePaths); + + /// + /// Gets a collection ConfigurableItem objects, each of which represents a single row from the ModuleConfiguration table. + /// + /// A collection ConfigurableItem objects, each of which represents a single row from the ModuleConfiguration table. + /// Semantically, each interface in the enumerator represents an item that can be configured by the module consumer. + /// The collection is a read-only collection and implements the standard read-only collection interfaces of Item(), Count() and _NewEnum(). + /// The IEnumMsmConfigItems enumerator implements Next(), Skip(), Reset(), and Clone() with the standard semantics. + object ConfigurableItems + { + get; + } + + /// + /// The CreateSourceImage method of the Merge object allows the client to extract the files from a module to + /// a source image on disk after a merge, taking into account changes to the module that might have been made + /// during module configuration. The list of files to be extracted is taken from the file table of the module + /// during the merge process. The list of files consists of every file successfully copied from the file table + /// of the module to the target database. File table entries that were not copied due to primary key conflicts + /// with existing rows in the database are not a part of this list. At image creation time, the directory for + /// each of these files comes from the open (post-merge) database. The path specified in the Path parameter is + /// the root of the source image for the install. fLongFileNames determines whether or not long file names are + /// used for both path segments and final file names. The function fails if no database is open, no module is + /// open, or no merge has been performed. + /// + /// The path of the root of the source image for the install. + /// Determines whether or not long file names are used for both path segments and final file names. + /// This is a list of fully-qualified paths for the files that were successfully extracted. + /// The list is empty if no files can be extracted. This argument may be null. No list is provided if pFilePaths is null. + void CreateSourceImage(string path, bool longFileNames, ref IntPtr filePaths); + + /// + /// The get_ModuleFiles function implements the ModuleFiles property of the GetFiles object. This function + /// returns the primary keys in the File table of the currently open module. The primary keys are returned + /// as a collection of strings. The module must be opened by a call to the OpenModule function before calling get_ModuleFiles. + /// + IMsmStrings ModuleFiles + { + get; + } + } + + /// + /// Collection of merge errors. + /// + [ComImport, Guid("0ADDA82A-2C26-11D2-AD65-00A0C9AF11A6")] + internal interface IMsmErrors + { + /// + /// Gets the IMsmError at the specified index. + /// + /// The one-based index of the IMsmError to get. + IMsmError this[int index] + { + get; + } + + /// + /// Gets the count of IMsmErrors in this collection. + /// + /// The count of IMsmErrors in this collection. + int Count + { + get; + } + } + + /// + /// A merge error. + /// + [ComImport, Guid("0ADDA828-2C26-11D2-AD65-00A0C9AF11A6")] + internal interface IMsmError + { + /// + /// Gets the type of merge error. + /// + /// The type of merge error. + MsmErrorType Type + { + get; + } + + /// + /// Gets the path information from the merge error. + /// + /// The path information from the merge error. + string Path + { + get; + } + + /// + /// Gets the language information from the merge error. + /// + /// The language information from the merge error. + short Language + { + get; + } + + /// + /// Gets the database table from the merge error. + /// + /// The database table from the merge error. + string DatabaseTable + { + get; + } + + /// + /// Gets the collection of database keys from the merge error. + /// + /// The collection of database keys from the merge error. + IMsmStrings DatabaseKeys + { + get; + } + + /// + /// Gets the module table from the merge error. + /// + /// The module table from the merge error. + string ModuleTable + { + get; + } + + /// + /// Gets the collection of module keys from the merge error. + /// + /// The collection of module keys from the merge error. + IMsmStrings ModuleKeys + { + get; + } + } + + /// + /// A collection of strings. + /// + [ComImport, Guid("0ADDA827-2C26-11D2-AD65-00A0C9AF11A6")] + internal interface IMsmStrings + { + /// + /// Gets the string at the specified index. + /// + /// The one-based index of the string to get. + string this[int index] + { + get; + } + + /// + /// Gets the count of strings in this collection. + /// + /// The count of strings in this collection. + int Count + { + get; + } + } + + /// + /// Callback for configurable merge modules. + /// + [ComImport, Guid("AC013209-18A7-4851-8A21-2353443D70A0"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] + internal interface IMsmConfigureModule + { + /// + /// Callback to retrieve text data for configurable merge modules. + /// + /// Name of the data to be retrieved. + /// The data corresponding to the name. + /// The error code (HRESULT). + [PreserveSig] + int ProvideTextData([In, MarshalAs(UnmanagedType.BStr)] string name, [MarshalAs(UnmanagedType.BStr)] out string configData); + + /// + /// Callback to retrieve integer data for configurable merge modules. + /// + /// Name of the data to be retrieved. + /// The data corresponding to the name. + /// The error code (HRESULT). + [PreserveSig] + int ProvideIntegerData([In, MarshalAs(UnmanagedType.BStr)] string name, out int configData); + } + + /// + /// Merge merge modules into an MSI file. + /// + [ComImport, Guid("F94985D5-29F9-4743-9805-99BC3F35B678")] + internal class MsmMerge2 + { + } + + /// + /// Defines the standard COM IClassFactory interface. + /// + [ComImport, Guid("00000001-0000-0000-C000-000000000046")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface IClassFactory + { + [return:MarshalAs(UnmanagedType.IUnknown)] + object CreateInstance(IntPtr unkOuter, [MarshalAs(UnmanagedType.LPStruct)] Guid iid); + } + + /// + /// Contains native methods for merge operations. + /// + internal class NativeMethods + { + [DllImport("mergemod.dll", EntryPoint="DllGetClassObject", PreserveSig=false)] + [return: MarshalAs(UnmanagedType.IUnknown)] + private static extern object MergeModGetClassObject([MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [MarshalAs(UnmanagedType.LPStruct)] Guid iid); + + /// + /// Load the merge object directly from a local mergemod.dll without going through COM registration. + /// + /// Merge interface. + internal static IMsmMerge2 GetMsmMerge() + { + IClassFactory classFactory = (IClassFactory) MergeModGetClassObject(typeof(MsmMerge2).GUID, typeof(IClassFactory).GUID); + return (IMsmMerge2) classFactory.CreateInstance(IntPtr.Zero, typeof(IMsmMerge2).GUID); + } + } +} +#endif \ No newline at end of file -- cgit v1.2.3-55-g6feb