Skip to content

Commit

Permalink
Handle MergeModule.CABinet for extraction.
Browse files Browse the repository at this point in the history
  • Loading branch information
barnson committed Jun 21, 2023
1 parent 9a550ac commit ddae99c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 16 deletions.
Expand Up @@ -29,7 +29,7 @@ public ExtractCabinetsCommand(IFileSystem fileSystem, WindowsInstallerData outpu

public Dictionary<string, MediaRow> ExtractedFileIdsWithMediaRow { get; private set; }

private IFileSystem FileSystem { get; }
private IFileSystem FileSystem { get; }

private WindowsInstallerData Output { get; }

Expand All @@ -55,13 +55,23 @@ public void Execute()
// index all of the cabinet files
if (OutputType.Module == this.Output.Type || this.TreatOutputAsModule)
{
embeddedCabinetNamesByDiskId.Add(0, "MergeModule.CABinet");
var mediaRow = new MediaRow(null, WindowsInstallerTableDefinitions.Media)
{
DiskId = 1,
LastSequence = 1,
Cabinet = "MergeModule.CABinet",
};

embeddedCabinetRowsByDiskId.Add(1, mediaRow);
embeddedCabinetNamesByDiskId.Add(1, "MergeModule.CABinet");
}
else if (this.Output.Tables.TryGetTable("Media", out var mediaTable))

if (this.Output.Tables.TryGetTable("Media", out var mediaTable))
{
foreach (var mediaRow in mediaTable.Rows.Cast<MediaRow>().Where(r => !String.IsNullOrEmpty(r.Cabinet)))
{
if (OutputType.Package == this.Output.Type ||
OutputType.Module == this.Output.Type ||
(OutputType.Transform == this.Output.Type && RowOperation.Add == mediaRow.Operation))
{
if (mediaRow.Cabinet.StartsWith("#", StringComparison.Ordinal))
Expand Down
34 changes: 22 additions & 12 deletions src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs
Expand Up @@ -2,31 +2,41 @@

namespace WixToolsetTest.CoreIntegration
{
using System;
using System.IO;
using WixInternal.TestSupport;
using WixInternal.Core.TestPackage;
using WixInternal.TestSupport;
using Xunit;

public class DecompileFixture
{
private static void DecompileAndCompare(string msiName, string expectedWxsName, params string[] sourceFolder)
private static void DecompileAndCompare(string msiName, bool extract, string expectedWxsName, params string[] sourceFolder)
{
var folder = TestData.Get(sourceFolder);

using (var fs = new DisposableFileSystem())
{
var intermediateFolder = fs.GetFolder();
var extractPath = Path.Combine(intermediateFolder, "$extracted");
var outputPath = Path.Combine(intermediateFolder, @"Actual.wxs");

var result = WixRunner.Execute(new[]
{
"msi", "decompile",
Path.Combine(folder, msiName),
"-intermediateFolder", intermediateFolder,
"-o", outputPath
"-o", outputPath,
extract ? "-x" : String.Empty,
extract ? extractPath : String.Empty,
}, out var messages);

Assert.Equal(0, result);
Assert.Empty(messages);

if (extract)
{
Assert.NotEmpty(Directory.EnumerateFiles(extractPath, "*", SearchOption.AllDirectories));
}

WixAssert.CompareXml(Path.Combine(folder, expectedWxsName), outputPath);
}
Expand All @@ -35,19 +45,19 @@ private static void DecompileAndCompare(string msiName, string expectedWxsName,
[Fact]
public void CanDecompileSingleFileCompressed()
{
DecompileAndCompare("example.msi", "Expected.wxs", "TestData", "DecompileSingleFileCompressed");
DecompileAndCompare("example.msi", extract: true, "Expected.wxs", "TestData", "DecompileSingleFileCompressed");
}

[Fact]
public void CanDecompile64BitSingleFileCompressed()
{
DecompileAndCompare("example.msi", "Expected.wxs", "TestData", "DecompileSingleFileCompressed64");
DecompileAndCompare("example.msi", extract: true, "Expected.wxs", "TestData", "DecompileSingleFileCompressed64");
}

[Fact]
public void CanDecompileNestedDirSearchUnderRegSearch()
{
DecompileAndCompare("NestedDirSearchUnderRegSearch.msi", "DecompiledNestedDirSearchUnderRegSearch.wxs", "TestData", "AppSearch");
DecompileAndCompare("NestedDirSearchUnderRegSearch.msi", extract: false, "DecompiledNestedDirSearchUnderRegSearch.wxs", "TestData", "AppSearch");
}

[Fact]
Expand All @@ -56,37 +66,37 @@ public void CanDecompileOldClassTableDefinition()
// The input MSI was not created using standard methods, it is an example of a real world database that needs to be decompiled.
// The Class/@Feature_ column has length of 32, the File/@Attributes has length of 2,
// and numerous foreign key relationships are missing.
DecompileAndCompare("OldClassTableDef.msi", "DecompiledOldClassTableDef.wxs", "TestData", "Class");
DecompileAndCompare("OldClassTableDef.msi", extract: false, "DecompiledOldClassTableDef.wxs", "TestData", "Class");
}

[Fact]
public void CanDecompileSequenceTables()
{
DecompileAndCompare("SequenceTables.msi", "DecompiledSequenceTables.wxs", "TestData", "SequenceTables");
DecompileAndCompare("SequenceTables.msi", extract: false, "DecompiledSequenceTables.wxs", "TestData", "SequenceTables");
}

[Fact]
public void CanDecompileShortcuts()
{
DecompileAndCompare("shortcuts.msi", "DecompiledShortcuts.wxs", "TestData", "Shortcut");
DecompileAndCompare("shortcuts.msi", extract: false, "DecompiledShortcuts.wxs", "TestData", "Shortcut");
}

[Fact]
public void CanDecompileNullComponent()
{
DecompileAndCompare("example.msi", "Expected.wxs", "TestData", "DecompileNullComponent");
DecompileAndCompare("example.msi", extract: true, "Expected.wxs", "TestData", "DecompileNullComponent");
}

[Fact]
public void CanDecompileMergeModuleWithTargetDirComponent()
{
DecompileAndCompare("MergeModule1.msm", "Expected.wxs", "TestData", "DecompileTargetDirMergeModule");
DecompileAndCompare("MergeModule1.msm", extract: true, "Expected.wxs", "TestData", "DecompileTargetDirMergeModule");
}

[Fact]
public void CanDecompileUI()
{
DecompileAndCompare("ui.msi", "ExpectedUI.wxs", "TestData", "Decompile");
DecompileAndCompare("ui.msi", extract: false, "ExpectedUI.wxs", "TestData", "Decompile");
}
}
}
Expand Up @@ -575,7 +575,7 @@ private static void CreateAdminImage(string msiPath, string targetDir)
var args = $"/a \"{Path.ChangeExtension(msiPath, "msi")}\" TARGETDIR=\"{targetDir}\" /qn";

var proc = Process.Start("msiexec.exe", args);
proc.WaitForExit(5000);
proc.WaitForExit(10000);

Assert.Equal(0, proc.ExitCode);
}
Expand Down

0 comments on commit ddae99c

Please sign in to comment.