From a5879b46f1d6a14dc53eb2eab0e96ce9fe25c87e Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 18 May 2026 19:52:44 -0400 Subject: [PATCH] Slightly more cleanup around IS-CAB and printing --- .../InstallShieldCabinet/Component.cs | 46 ++++++++--- .../InstallShieldCabinet/VolumeHeader.cs | 1 - .../InstallShieldCabinet.cs | 82 +++++++++++++++---- .../InstallShieldCabinet.Printing.cs | 22 +++-- SabreTools.Wrappers/InstallShieldCabinet.cs | 4 +- 5 files changed, 117 insertions(+), 38 deletions(-) diff --git a/SabreTools.Data.Models/InstallShieldCabinet/Component.cs b/SabreTools.Data.Models/InstallShieldCabinet/Component.cs index 098538a4..d9b0948d 100644 --- a/SabreTools.Data.Models/InstallShieldCabinet/Component.cs +++ b/SabreTools.Data.Models/InstallShieldCabinet/Component.cs @@ -6,29 +6,34 @@ namespace SabreTools.Data.Models.InstallShieldCabinet public sealed class Component { /// - /// Offset to the component identifier + /// Offset to the component name /// - public uint IdentifierOffset { get; set; } + public uint NameOffset { get; set; } /// - /// Component identifier + /// Component name /// - public string Identifier { get; set; } = string.Empty; + public string Name { get; set; } = string.Empty; /// - /// Offset to the component descriptor + /// Offset to the component description /// - public uint DescriptorOffset { get; set; } + public uint DescriptionOffset { get; set; } /// - /// Offset to the display name + /// Component description /// - public uint DisplayNameOffset { get; set; } + public string Description { get; set; } = string.Empty; + + /// + /// Offset to the status text + /// + public uint StatusTextOffset { get; set; } /// /// Display name /// - public string DisplayName { get; set; } = string.Empty; + public string StatusText { get; set; } = string.Empty; /// /// Component status @@ -51,30 +56,45 @@ namespace SabreTools.Data.Models.InstallShieldCabinet public ushort ComponentIndex { get; set; } /// - /// Offset to the component name + /// Offset to the display name /// - public uint NameOffset { get; set; } + public uint DisplayNameOffset { get; set; } /// - /// Component name + /// Display name /// - public string Name { get; set; } = string.Empty; + public string DisplayName { get; set; } = string.Empty; /// /// Offset to the CD-ROM folder /// public uint CDRomFolderOffset { get; set; } + /// + /// CD-ROM folder + /// + public string CDRomFolder { get; set; } = string.Empty; + /// /// Offset to the HTTP location /// public uint HTTPLocationOffset { get; set; } + /// + /// HTTP location + /// + public string HTTPLocation { get; set; } = string.Empty; + /// /// Offset to the FTP location /// public uint FTPLocationOffset { get; set; } + /// + /// FTP location + /// + public string FTPLocation { get; set; } = string.Empty; + /// /// Unknown GUIDs /// diff --git a/SabreTools.Data.Models/InstallShieldCabinet/VolumeHeader.cs b/SabreTools.Data.Models/InstallShieldCabinet/VolumeHeader.cs index bb8e1bd6..a23b1823 100644 --- a/SabreTools.Data.Models/InstallShieldCabinet/VolumeHeader.cs +++ b/SabreTools.Data.Models/InstallShieldCabinet/VolumeHeader.cs @@ -1,7 +1,6 @@ namespace SabreTools.Data.Models.InstallShieldCabinet { /// - /// TODO: Should standard and high values be combined? public sealed class VolumeHeader { /// 32-bit in versions 5 and below diff --git a/SabreTools.Serialization.Readers/InstallShieldCabinet.cs b/SabreTools.Serialization.Readers/InstallShieldCabinet.cs index 74898e6c..81c7debb 100644 --- a/SabreTools.Serialization.Readers/InstallShieldCabinet.cs +++ b/SabreTools.Serialization.Readers/InstallShieldCabinet.cs @@ -345,14 +345,14 @@ namespace SabreTools.Serialization.Readers { var obj = new Component(); - obj.IdentifierOffset = data.ReadUInt32LittleEndian(); - obj.DescriptorOffset = data.ReadUInt32LittleEndian(); - obj.DisplayNameOffset = data.ReadUInt32LittleEndian(); + obj.NameOffset = data.ReadUInt32LittleEndian(); + obj.DescriptionOffset = data.ReadUInt32LittleEndian(); + obj.StatusTextOffset = data.ReadUInt32LittleEndian(); obj.Status = (ComponentStatus)data.ReadUInt16LittleEndian(); obj.PasswordOffset = data.ReadUInt32LittleEndian(); obj.MiscOffset = data.ReadUInt32LittleEndian(); obj.ComponentIndex = data.ReadUInt16LittleEndian(); - obj.NameOffset = data.ReadUInt32LittleEndian(); + obj.DisplayNameOffset = data.ReadUInt32LittleEndian(); obj.CDRomFolderOffset = data.ReadUInt32LittleEndian(); obj.HTTPLocationOffset = data.ReadUInt32LittleEndian(); obj.FTPLocationOffset = data.ReadUInt32LittleEndian(); @@ -382,17 +382,43 @@ namespace SabreTools.Serialization.Readers // Cache the current position long currentPosition = data.Position; - // Read the identifier, if possible - if (obj.IdentifierOffset != 0) + // Read the name, if possible + if (obj.NameOffset != 0) { - // Seek to the identifier - data.SeekIfPossible(descriptorOffset + obj.IdentifierOffset, SeekOrigin.Begin); + // Seek to the string + data.SeekIfPossible(descriptorOffset + obj.NameOffset, SeekOrigin.Begin); // Read the string if (majorVersion >= 17) - obj.Identifier = data.ReadNullTerminatedUnicodeString() ?? string.Empty; + obj.Name = data.ReadNullTerminatedUnicodeString() ?? string.Empty; else - obj.Identifier = data.ReadNullTerminatedAnsiString() ?? string.Empty; + obj.Name = data.ReadNullTerminatedAnsiString() ?? string.Empty; + } + + // Read the description, if possible + if (obj.DescriptionOffset != 0) + { + // Seek to the string + data.SeekIfPossible(descriptorOffset + obj.DescriptionOffset, SeekOrigin.Begin); + + // Read the string + if (majorVersion >= 17) + obj.Description = data.ReadNullTerminatedUnicodeString() ?? string.Empty; + else + obj.Description = data.ReadNullTerminatedAnsiString() ?? string.Empty; + } + + // Read the status text, if possible + if (obj.StatusTextOffset != 0) + { + // Seek to the string + data.SeekIfPossible(descriptorOffset + obj.StatusTextOffset, SeekOrigin.Begin); + + // Read the string + if (majorVersion >= 17) + obj.StatusText = data.ReadNullTerminatedUnicodeString() ?? string.Empty; + else + obj.StatusText = data.ReadNullTerminatedAnsiString() ?? string.Empty; } // Read the display name, if possible @@ -408,17 +434,43 @@ namespace SabreTools.Serialization.Readers obj.DisplayName = data.ReadNullTerminatedAnsiString() ?? string.Empty; } - // Read the name, if possible - if (obj.NameOffset != 0) + // Read the CD-ROM folder, if possible + if (obj.CDRomFolderOffset != 0) { // Seek to the string - data.SeekIfPossible(descriptorOffset + obj.NameOffset, SeekOrigin.Begin); + data.SeekIfPossible(descriptorOffset + obj.CDRomFolderOffset, SeekOrigin.Begin); // Read the string if (majorVersion >= 17) - obj.Name = data.ReadNullTerminatedUnicodeString() ?? string.Empty; + obj.CDRomFolder = data.ReadNullTerminatedUnicodeString() ?? string.Empty; else - obj.Name = data.ReadNullTerminatedAnsiString() ?? string.Empty; + obj.CDRomFolder = data.ReadNullTerminatedAnsiString() ?? string.Empty; + } + + // Read the HTTP location, if possible + if (obj.HTTPLocationOffset != 0) + { + // Seek to the string + data.SeekIfPossible(descriptorOffset + obj.HTTPLocationOffset, SeekOrigin.Begin); + + // Read the string + if (majorVersion >= 17) + obj.HTTPLocation = data.ReadNullTerminatedUnicodeString() ?? string.Empty; + else + obj.HTTPLocation = data.ReadNullTerminatedAnsiString() ?? string.Empty; + } + + // Read the FTP location, if possible + if (obj.FTPLocationOffset != 0) + { + // Seek to the string + data.SeekIfPossible(descriptorOffset + obj.FTPLocationOffset, SeekOrigin.Begin); + + // Read the string + if (majorVersion >= 17) + obj.FTPLocation = data.ReadNullTerminatedUnicodeString() ?? string.Empty; + else + obj.FTPLocation = data.ReadNullTerminatedAnsiString() ?? string.Empty; } // Read the CLSID, if possible diff --git a/SabreTools.Wrappers/InstallShieldCabinet.Printing.cs b/SabreTools.Wrappers/InstallShieldCabinet.Printing.cs index dd9ae146..72b15049 100644 --- a/SabreTools.Wrappers/InstallShieldCabinet.Printing.cs +++ b/SabreTools.Wrappers/InstallShieldCabinet.Printing.cs @@ -260,10 +260,14 @@ namespace SabreTools.Wrappers builder.AppendLine(entry.UnknownStringOffset, " Unknown string offset"); builder.AppendLine(entry.OperatingSystemOffset, " Operating system offset"); builder.AppendLine(entry.LanguageOffset, " Language offset"); + builder.AppendLine(entry.Language, " Language"); builder.AppendLine(entry.HTTPLocationOffset, " HTTP location offset"); + builder.AppendLine(entry.HTTPLocation, " HTTP location"); builder.AppendLine(entry.FTPLocationOffset, " FTP location offset"); + builder.AppendLine(entry.FTPLocation, " FTP location"); builder.AppendLine(entry.MiscOffset, " Misc. offset"); builder.AppendLine(entry.TargetDirectoryOffset, " Target directory offset"); + builder.AppendLine(entry.TargetDirectory, " Target directory"); builder.AppendLine($" Overwrite flags: {entry.OverwriteFlags} (0x{entry.OverwriteFlags:X})"); builder.AppendLine(entry.Reserved, " Reserved"); } @@ -287,20 +291,24 @@ namespace SabreTools.Wrappers var entry = entries[i]; builder.AppendLine($" Component {i}:"); - builder.AppendLine(entry.IdentifierOffset, " Identifier offset"); - builder.AppendLine(entry.Identifier, " Identifier"); - builder.AppendLine(entry.DescriptorOffset, " Descriptor offset"); - builder.AppendLine(entry.DisplayNameOffset, " Display name offset"); - builder.AppendLine(entry.DisplayName, " Display name"); + builder.AppendLine(entry.NameOffset, " Name offset"); + builder.AppendLine(entry.Name, " Name"); + builder.AppendLine(entry.DescriptionOffset, " Description offset"); + builder.AppendLine(entry.Description, " Description"); + builder.AppendLine(entry.StatusTextOffset, " Status text offset"); + builder.AppendLine(entry.StatusText, " Status text"); builder.AppendLine($" Status: {entry.Status} (0x{entry.Status:X})"); builder.AppendLine(entry.PasswordOffset, " Password offset"); builder.AppendLine(entry.MiscOffset, " Misc. offset"); builder.AppendLine(entry.ComponentIndex, " Component index"); - builder.AppendLine(entry.NameOffset, " Name offset"); - builder.AppendLine(entry.Name, " Name"); + builder.AppendLine(entry.DisplayNameOffset, " Display name offset"); + builder.AppendLine(entry.DisplayName, " Display name"); builder.AppendLine(entry.CDRomFolderOffset, " CD-ROM folder offset"); + builder.AppendLine(entry.CDRomFolder, " CD-ROM folder"); builder.AppendLine(entry.HTTPLocationOffset, " HTTP location offset"); + builder.AppendLine(entry.HTTPLocation, " HTTP location"); builder.AppendLine(entry.FTPLocationOffset, " FTP location offset"); + builder.AppendLine(entry.FTPLocation, " FTP location"); builder.AppendLine(entry.Guid, " GUIDs"); builder.AppendLine(entry.CLSIDOffset, " CLSID offset"); builder.AppendLine(entry.CLSID, " CLSID"); diff --git a/SabreTools.Wrappers/InstallShieldCabinet.cs b/SabreTools.Wrappers/InstallShieldCabinet.cs index c1d572de..c3abf36b 100644 --- a/SabreTools.Wrappers/InstallShieldCabinet.cs +++ b/SabreTools.Wrappers/InstallShieldCabinet.cs @@ -155,10 +155,10 @@ namespace SabreTools.Wrappers return null; var component = Components[index]; - if (component?.Identifier is null) + if (component?.Name is null) return null; - return component.Identifier.Replace('\\', '/'); + return component.Name.Replace('\\', '/'); } #endregion