// 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