// 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.Core.WindowsInstaller.Bind
{
using System;
using System.Globalization;
using System.Linq;
using WixToolset.Data;
using WixToolset.Data.Symbols;
///
/// Binds the summary information table of a database.
///
internal class BindSummaryInfoCommand
{
public BindSummaryInfoCommand(IntermediateSection section)
{
this.Section = section;
}
private IntermediateSection Section { get; }
///
/// Returns a flag indicating if files are compressed by default.
///
public bool Compressed { get; private set; }
///
/// Returns a flag indicating if uncompressed files use long filenames.
///
public bool LongNames { get; private set; }
public int InstallerVersion { get; private set; }
public Platform Platform { get; private set; }
///
/// Modularization guid, or null if the output is not a module.
///
public string ModularizationSuffix { get; private set; }
public void Execute()
{
this.Compressed = false;
this.LongNames = false;
this.InstallerVersion = 0;
this.ModularizationSuffix = null;
var foundCreateDataTime = false;
var foundLastSaveDataTime = false;
var foundCreatingApplication = false;
var now = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture);
foreach (var summaryInformationSymbol in this.Section.Symbols.OfType())
{
switch (summaryInformationSymbol.PropertyId)
{
case SummaryInformationType.Codepage: // PID_CODEPAGE
// make sure the code page is an int and not a web name or null
var codepage = summaryInformationSymbol.Value;
if (String.IsNullOrEmpty(codepage))
{
codepage = "0";
}
else
{
summaryInformationSymbol.Value = Common.GetValidCodePage(codepage, false, false, summaryInformationSymbol.SourceLineNumbers).ToString(CultureInfo.InvariantCulture);
}
break;
case SummaryInformationType.PlatformAndLanguage:
this.Platform = GetPlatformFromSummaryInformation(summaryInformationSymbol.Value);
break;
case SummaryInformationType.PackageCode: // PID_REVNUMBER
var packageCode = summaryInformationSymbol.Value;
if (SectionType.Module == this.Section.Type)
{
this.ModularizationSuffix = "." + packageCode.Substring(1, 36).Replace('-', '_');
}
else if ("*" == packageCode)
{
// set the revision number (package/patch code) if it should be automatically generated
summaryInformationSymbol.Value = Common.GenerateGuid();
}
break;
case SummaryInformationType.Created:
foundCreateDataTime = true;
break;
case SummaryInformationType.LastSaved:
foundLastSaveDataTime = true;
break;
case SummaryInformationType.WindowsInstallerVersion:
this.InstallerVersion = summaryInformationSymbol[SummaryInformationSymbolFields.Value].AsNumber();
break;
case SummaryInformationType.WordCount:
if (SectionType.Patch == this.Section.Type)
{
this.LongNames = true;
this.Compressed = true;
}
else
{
var attributes = summaryInformationSymbol[SummaryInformationSymbolFields.Value].AsNumber();
this.LongNames = (0 == (attributes & 1));
this.Compressed = (2 == (attributes & 2));
}
break;
case SummaryInformationType.CreatingApplication: // PID_APPNAME
foundCreatingApplication = true;
break;
}
}
// add a summary information row for the create time/date property if its not already set
if (!foundCreateDataTime)
{
this.Section.AddSymbol(new SummaryInformationSymbol(null)
{
PropertyId = SummaryInformationType.Created,
Value = now,
});
}
// add a summary information row for the last save time/date property if its not already set
if (!foundLastSaveDataTime)
{
this.Section.AddSymbol(new SummaryInformationSymbol(null)
{
PropertyId = SummaryInformationType.LastSaved,
Value = now,
});
}
// add a summary information row for the creating application property if its not already set
if (!foundCreatingApplication)
{
this.Section.AddSymbol(new SummaryInformationSymbol(null)
{
PropertyId = SummaryInformationType.CreatingApplication,
Value = String.Format(CultureInfo.InvariantCulture, AppCommon.GetCreatingApplicationString()),
});
}
}
private static Platform GetPlatformFromSummaryInformation(string value)
{
var separatorIndex = value.IndexOf(';');
var platformValue = separatorIndex > 0 ? value.Substring(0, separatorIndex) : value;
switch (platformValue)
{
case "x64":
return Platform.X64;
case "Arm":
return Platform.ARM;
case "Arm64":
return Platform.ARM64;
case "Intel64":
return Platform.IA64;
case "Intel":
default:
return Platform.X86;
}
}
}
}