// 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.Msi
{
using System;
using System.Diagnostics;
using System.Text;
using WixToolset.Core.Native;
///
/// Windows Installer message types.
///
[Flags]
internal enum InstallMessage
{
///
/// Premature termination, possibly fatal out of memory.
///
FatalExit = 0x00000000,
///
/// Formatted error message, [1] is message number in Error table.
///
Error = 0x01000000,
///
/// Formatted warning message, [1] is message number in Error table.
///
Warning = 0x02000000,
///
/// User request message, [1] is message number in Error table.
///
User = 0x03000000,
///
/// Informative message for log, not to be displayed.
///
Info = 0x04000000,
///
/// List of files in use that need to be replaced.
///
FilesInUse = 0x05000000,
///
/// Request to determine a valid source location.
///
ResolveSource = 0x06000000,
///
/// Insufficient disk space message.
///
OutOfDiskSpace = 0x07000000,
///
/// Progress: start of action, [1] action name, [2] description, [3] template for ACTIONDATA messages.
///
ActionStart = 0x08000000,
///
/// Action data. Record fields correspond to the template of ACTIONSTART message.
///
ActionData = 0x09000000,
///
/// Progress bar information. See the description of record fields below.
///
Progress = 0x0A000000,
///
/// To enable the Cancel button set [1] to 2 and [2] to 1. To disable the Cancel button set [1] to 2 and [2] to 0.
///
CommonData = 0x0B000000,
///
/// Sent prior to UI initialization, no string data.
///
Initilize = 0x0C000000,
///
/// Sent after UI termination, no string data.
///
Terminate = 0x0D000000,
///
/// Sent prior to display or authored dialog or wizard.
///
ShowDialog = 0x0E000000
}
///
/// Windows Installer log modes.
///
[Flags]
internal enum InstallLogModes
{
///
/// Premature termination of installation.
///
FatalExit = (1 << ((int)InstallMessage.FatalExit >> 24)),
///
/// The error messages are logged.
///
Error = (1 << ((int)InstallMessage.Error >> 24)),
///
/// The warning messages are logged.
///
Warning = (1 << ((int)InstallMessage.Warning >> 24)),
///
/// The user requests are logged.
///
User = (1 << ((int)InstallMessage.User >> 24)),
///
/// The status messages that are not displayed are logged.
///
Info = (1 << ((int)InstallMessage.Info >> 24)),
///
/// Request to determine a valid source location.
///
ResolveSource = (1 << ((int)InstallMessage.ResolveSource >> 24)),
///
/// The was insufficient disk space.
///
OutOfDiskSpace = (1 << ((int)InstallMessage.OutOfDiskSpace >> 24)),
///
/// The start of new installation actions are logged.
///
ActionStart = (1 << ((int)InstallMessage.ActionStart >> 24)),
///
/// The data record with the installation action is logged.
///
ActionData = (1 << ((int)InstallMessage.ActionData >> 24)),
///
/// The parameters for user-interface initialization are logged.
///
CommonData = (1 << ((int)InstallMessage.CommonData >> 24)),
///
/// Logs the property values at termination.
///
PropertyDump = (1 << ((int)InstallMessage.Progress >> 24)),
///
/// Sends large amounts of information to a log file not generally useful to users.
/// May be used for technical support.
///
Verbose = (1 << ((int)InstallMessage.Initilize >> 24)),
///
/// Sends extra debugging information, such as handle creation information, to the log file.
///
ExtraDebug = (1 << ((int)InstallMessage.Terminate >> 24)),
///
/// Progress bar information. This message includes information on units so far and total number of units.
/// See MsiProcessMessage for an explanation of the message format.
/// This message is only sent to an external user interface and is not logged.
///
Progress = (1 << ((int)InstallMessage.Progress >> 24)),
///
/// If this is not a quiet installation, then the basic UI has been initialized.
/// If this is a full UI installation, the full UI is not yet initialized.
/// This message is only sent to an external user interface and is not logged.
///
Initialize = (1 << ((int)InstallMessage.Initilize >> 24)),
///
/// If a full UI is being used, the full UI has ended.
/// If this is not a quiet installation, the basic UI has not yet ended.
/// This message is only sent to an external user interface and is not logged.
///
Terminate = (1 << ((int)InstallMessage.Terminate >> 24)),
///
/// Sent prior to display of the full UI dialog.
/// This message is only sent to an external user interface and is not logged.
///
ShowDialog = (1 << ((int)InstallMessage.ShowDialog >> 24)),
///
/// Files in use information. When this message is received, a FilesInUse Dialog should be displayed.
///
FilesInUse = (1 << ((int)InstallMessage.FilesInUse >> 24))
}
///
/// Windows Installer UI levels.
///
[Flags]
internal enum InstallUILevels
{
///
/// No change in the UI level. However, if phWnd is not Null, the parent window can change.
///
NoChange = 0,
///
/// The installer chooses an appropriate user interface level.
///
Default = 1,
///
/// Completely silent installation.
///
None = 2,
///
/// Simple progress and error handling.
///
Basic = 3,
///
/// Authored user interface with wizard dialog boxes suppressed.
///
Reduced = 4,
///
/// Authored user interface with wizards, progress, and errors.
///
Full = 5,
///
/// If combined with the Basic value, the installer shows simple progress dialog boxes but
/// does not display a Cancel button on the dialog. This prevents users from canceling the install.
/// Available with Windows Installer version 2.0.
///
HideCancel = 0x20,
///
/// If combined with the Basic value, the installer shows simple progress
/// dialog boxes but does not display any modal dialog boxes or error dialog boxes.
///
ProgressOnly = 0x40,
///
/// If combined with any above value, the installer displays a modal dialog
/// box at the end of a successful installation or if there has been an error.
/// No dialog box is displayed if the user cancels.
///
EndDialog = 0x80,
///
/// If this value is combined with the None value, the installer displays only the dialog
/// boxes used for source resolution. No other dialog boxes are shown. This value has no
/// effect if the UI level is not INSTALLUILEVEL_NONE. It is used with an external user
/// interface designed to handle all of the UI except for source resolution. In this case,
/// the installer handles source resolution. This value is only available with Windows Installer 2.0 and later.
///
SourceResOnly = 0x100
}
///
/// Represents the Windows Installer, provides wrappers to
/// create the top-level objects and access their methods.
///
internal sealed class Installer
{
///
/// Protect the constructor.
///
private Installer()
{
}
///
/// Takes the path to a file and returns a 128-bit hash of that file.
///
/// Path to file that is to be hashed.
/// The value in this column must be 0. This parameter is reserved for future use.
/// Int array that receives the returned file hash information.
internal static void GetFileHash(string filePath, int options, out int[] hash)
{
MsiInterop.MSIFILEHASHINFO hashInterop = new MsiInterop.MSIFILEHASHINFO();
hashInterop.FileHashInfoSize = 20;
int error = MsiInterop.MsiGetFileHash(filePath, Convert.ToUInt32(options), hashInterop);
if (0 != error)
{
throw new MsiException(error);
}
Debug.Assert(20 == hashInterop.FileHashInfoSize);
hash = new int[4];
hash[0] = hashInterop.Data0;
hash[1] = hashInterop.Data1;
hash[2] = hashInterop.Data2;
hash[3] = hashInterop.Data3;
}
///
/// Returns the version string and language string in the format that the installer
/// expects to find them in the database. If you just want version information, set
/// lpLangBuf and pcchLangBuf to zero. If you just want language information, set
/// lpVersionBuf and pcchVersionBuf to zero.
///
/// Specifies the path to the file.
/// Returns the file version. Set to 0 for language information only.
/// Returns the file language. Set to 0 for version information only.
internal static void GetFileVersion(string filePath, out string version, out string language)
{
int versionLength = 20;
int languageLength = 20;
StringBuilder versionBuffer = new StringBuilder(versionLength);
StringBuilder languageBuffer = new StringBuilder(languageLength);
int error = MsiInterop.MsiGetFileVersion(filePath, versionBuffer, ref versionLength, languageBuffer, ref languageLength);
if (234 == error)
{
versionBuffer.EnsureCapacity(++versionLength);
languageBuffer.EnsureCapacity(++languageLength);
error = MsiInterop.MsiGetFileVersion(filePath, versionBuffer, ref versionLength, languageBuffer, ref languageLength);
}
else if (1006 == error)
{
// file has no version or language, so no error
error = 0;
}
if (0 != error)
{
throw new MsiException(error);
}
version = versionBuffer.ToString();
language = languageBuffer.ToString();
}
///
/// Enables an external user-interface handler.
///
/// Specifies a callback function.
/// Specifies which messages to handle using the external message handler.
/// Pointer to an application context that is passed to the callback function.
/// The return value is the previously set external handler, or null if there was no previously set handler.
internal static InstallUIHandler SetExternalUI(InstallUIHandler installUIHandler, int messageFilter, IntPtr context)
{
return MsiInterop.MsiSetExternalUI(installUIHandler, messageFilter, context);
}
///
/// Enables the installer's internal user interface.
///
/// Specifies the level of complexity of the user interface.
/// Pointer to a window. This window becomes the owner of any user interface created.
/// The previous user interface level is returned. If an invalid dwUILevel is passed, then INSTALLUILEVEL_NOCHANGE is returned.
internal static int SetInternalUI(int uiLevel, ref IntPtr hwnd)
{
return MsiInterop.MsiSetInternalUI(uiLevel, ref hwnd);
}
}
}