From ddae99c27fcec6c90696f6df66608aae155d6a93 Mon Sep 17 00:00:00 2001
From: Bob Arnson <bob@firegiant.com>
Date: Tue, 20 Jun 2023 20:09:19 -0400
Subject: Handle MergeModule.CABinet for extraction.

Fixes https://github.com/wixtoolset/issues/issues/7568,
---
 .../Unbind/ExtractCabinetsCommand.cs               | 16 ++++++++--
 .../DecompileFixture.cs                            | 34 ++++++++++++++--------
 .../WixToolsetTest.CoreIntegration/PatchFixture.cs |  2 +-
 3 files changed, 36 insertions(+), 16 deletions(-)

(limited to 'src')

diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs
index 5ac7efe6..ba6877c8 100644
--- a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs
+++ b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs
@@ -29,7 +29,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
 
         public Dictionary<string, MediaRow> ExtractedFileIdsWithMediaRow { get; private set; }
 
-        private  IFileSystem FileSystem { get; }
+        private IFileSystem FileSystem { get; }
 
         private WindowsInstallerData Output { get; }
 
@@ -55,13 +55,23 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
             // 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))
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs
index a4915a3a..6a9de6df 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs
@@ -2,20 +2,22 @@
 
 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[]
@@ -23,10 +25,18 @@ namespace WixToolsetTest.CoreIntegration
                     "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);
             }
@@ -35,19 +45,19 @@ namespace WixToolsetTest.CoreIntegration
         [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]
@@ -56,37 +66,37 @@ namespace WixToolsetTest.CoreIntegration
             // 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");
         }
     }
 }
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/PatchFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/PatchFixture.cs
index d07793a1..82dfc7e5 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/PatchFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/PatchFixture.cs
@@ -575,7 +575,7 @@ namespace WixToolsetTest.CoreIntegration
             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);
         }
-- 
cgit v1.2.3-55-g6feb