// 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.Globalization; using System.Text; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; using WixToolset.Core.Native; /// /// Summary information for the MSI files. /// internal sealed class SummaryInformation : MsiHandle { /// /// Summary information properties for transforms. /// public enum Transform { /// PID_CODEPAGE = code page for the summary information stream CodePage = 1, /// PID_TITLE = typically just "Transform" Title = 2, /// PID_SUBJECT = original subject of target TargetSubject = 3, /// PID_AUTHOR = original manufacturer of target TargetManufacturer = 4, /// PID_KEYWORDS = keywords for the transform, typically including at least "Installer" Keywords = 5, /// PID_COMMENTS = describes what this package does Comments = 6, /// PID_TEMPLATE = target platform;language TargetPlatformAndLanguage = 7, /// PID_LASTAUTHOR = updated platform;language UpdatedPlatformAndLanguage = 8, /// PID_REVNUMBER = {productcode}version;{newproductcode}newversion;upgradecode ProductCodes = 9, /// PID_LASTPRINTED should be null for transforms Reserved11 = 11, ///.PID_CREATE_DTM = the timestamp when the transform was created CreationTime = 12, /// PID_PAGECOUNT = minimum installer version InstallerRequirement = 14, /// PID_CHARCOUNT = validation and error flags ValidationFlags = 16, /// PID_APPNAME = the application that created the transform CreatingApplication = 18, /// PID_SECURITY = whether read-only is enforced; should always be 4 for transforms Security = 19, } /// /// Summary information properties for patches. /// public enum Patch { /// PID_CODEPAGE = code page of the summary information stream CodePage = 1, /// PID_TITLE = a brief description of the package type Title = 2, /// PID_SUBJECT = package name PackageName = 3, /// PID_AUTHOR = manufacturer of the patch package Manufacturer = 4, /// PID_KEYWORDS = alternate sources for the patch package Sources = 5, /// PID_COMMENTS = general purpose of the patch package Comments = 6, /// PID_TEMPLATE = semicolon delimited list of ProductCodes ProductCodes = 7, /// PID_LASTAUTHOR = semicolon delimited list of transform names TransformNames = 8, /// PID_REVNUMBER = GUID patch code PatchCode = 9, /// PID_LASTPRINTED should be null for patches Reserved11 = 11, /// PID_PAGECOUNT should be null for patches Reserved14 = 14, /// PID_WORDCOUNT = minimum installer version InstallerRequirement = 15, /// PID_CHARCOUNT should be null for patches Reserved16 = 16, /// PID_SECURITY = read-only attribute of the patch package Security = 19, } /// /// Summary information values for the InstallerRequirement property. /// public enum InstallerRequirement { /// Any version of the installer will do Version10 = 1, /// At least 1.2 Version12 = 2, /// At least 2.0 Version20 = 3, /// At least 3.0 Version30 = 4, /// At least 3.1 Version31 = 5, } /// /// Instantiate a new SummaryInformation class from an open database. /// /// Database to retrieve summary information from. public SummaryInformation(Database db) { if (null == db) { throw new ArgumentNullException("db"); } uint handle = 0; int error = MsiInterop.MsiGetSummaryInformation(db.Handle, null, 0, ref handle); if (0 != error) { throw new MsiException(error); } this.Handle = handle; } /// /// Instantiate a new SummaryInformation class from a database file. /// /// The database file. public SummaryInformation(string databaseFile) { if (null == databaseFile) { throw new ArgumentNullException("databaseFile"); } uint handle = 0; int error = MsiInterop.MsiGetSummaryInformation(0, databaseFile, 0, ref handle); if (0 != error) { throw new MsiException(error); } this.Handle = handle; } /// /// Variant types in the summary information table. /// private enum VT : uint { /// Variant has not been assigned. EMPTY = 0, /// Null variant type. NULL = 1, /// 16-bit integer variant type. I2 = 2, /// 32-bit integer variant type. I4 = 3, /// String variant type. LPSTR = 30, /// Date time (FILETIME, converted to Variant time) variant type. FILETIME = 64, } /// /// Gets a summary information property. /// /// Index of the summary information property. /// The summary information property. public string GetProperty(int index) { uint dataType; StringBuilder stringValue = new StringBuilder(""); int bufSize = 0; int intValue; FILETIME timeValue; timeValue.dwHighDateTime = 0; timeValue.dwLowDateTime = 0; int error = MsiInterop.MsiSummaryInfoGetProperty(this.Handle, index, out dataType, out intValue, ref timeValue, stringValue, ref bufSize); if (234 == error) { stringValue.EnsureCapacity(++bufSize); error = MsiInterop.MsiSummaryInfoGetProperty(this.Handle, index, out dataType, out intValue, ref timeValue, stringValue, ref bufSize); } if (0 != error) { throw new MsiException(error); } switch ((VT)dataType) { case VT.EMPTY: return String.Empty; case VT.LPSTR: return stringValue.ToString(); case VT.I2: case VT.I4: return Convert.ToString(intValue, CultureInfo.InvariantCulture); case VT.FILETIME: long longFileTime = (((long)timeValue.dwHighDateTime) << 32) | unchecked((uint)timeValue.dwLowDateTime); DateTime dateTime = DateTime.FromFileTime(longFileTime); return dateTime.ToString("yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture); default: throw new InvalidOperationException(); } } } }