using System.IO; using SabreTools.Data.Models.WiseInstaller; namespace SabreTools.Wrappers { public partial class WiseOverlayHeader : WrapperBase { #region Descriptive Properties /// public override string DescriptionString => "Wise Installer Overlay Header"; #endregion #region Extension Properties /// /// Returns the offset relative to the start of the header /// where the compressed data lives /// public long CompressedDataOffset { get { // Use the cached data if possible if (field > -1) return field; field = 0; field += 1; // DllNameLen if (Model.DllNameLen > 0) { field += Model.DllNameLen; field += 4; // DllSize } field += 4; // Flags field += 12; // GraphicsData field += 4; // WiseScriptExitEventOffset field += 4; // WiseScriptCancelEventOffset field += 4; // WiseScriptInflatedSize field += 4; // WiseScriptDeflatedSize field += 4; // WiseDllDeflatedSize field += 4; // Ctl3d32DeflatedSize field += 4; // SomeData4DeflatedSize field += 4; // RegToolDeflatedSize field += 4; // ProgressDllDeflatedSize field += 4; // SomeData7DeflatedSize field += 4; // SomeData8DeflatedSize field += 4; // SomeData9DeflatedSize field += 4; // SomeData10DeflatedSize field += 4; // FinalFileDeflatedSize field += 4; // FinalFileInflatedSize field += 4; // EOF if (DibDeflatedSize == 0 && Model.Endianness == 0) return field; field += 4; // DibDeflatedSize field += 4; // DibInflatedSize if (Model.InstallScriptDeflatedSize is not null) field += 4; // InstallScriptDeflatedSize if (Model.CharacterSet is not null) field += 4; // CharacterSet field += 2; // Endianness field += 1; // InitTextLen field += Model.InitTextLen; return field; } } = -1; /// /// Installer data offset /// /// /// This is the offset marking the point after all of the /// header-defined files. It is only set during extraction /// and is not used otherwise. It is automatically set if /// is called. /// public long InstallerDataOffset { get; private set; } /// public uint Ctl3d32DeflatedSize => Model.Ctl3d32DeflatedSize; /// public uint DibDeflatedSize => Model.DibDeflatedSize; /// public uint DibInflatedSize => Model.DibInflatedSize; /// public uint FinalFileDeflatedSize => Model.FinalFileDeflatedSize; /// public uint FinalFileInflatedSize => Model.FinalFileInflatedSize; /// public OverlayHeaderFlags Flags => Model.Flags; /// public uint InstallScriptDeflatedSize => Model.InstallScriptDeflatedSize ?? 0; /// /// Indicates if data is packed in PKZIP containers /// public bool IsPKZIP { get { #if NET20 || NET35 return (Flags & OverlayHeaderFlags.WISE_FLAG_PK_ZIP) != 0; #else return Flags.HasFlag(OverlayHeaderFlags.WISE_FLAG_PK_ZIP); #endif } } /// public uint ProgressDllDeflatedSize => Model.ProgressDllDeflatedSize; /// public uint SomeData4DeflatedSize => Model.SomeData4DeflatedSize; /// public uint SomeData7DeflatedSize => Model.SomeData7DeflatedSize; /// public uint SomeData8DeflatedSize => Model.SomeData8DeflatedSize; /// public uint SomeData9DeflatedSize => Model.SomeData9DeflatedSize; /// public uint SomeData10DeflatedSize => Model.SomeData10DeflatedSize; /// public uint RegToolDeflatedSize => Model.RegToolDeflatedSize; /// public uint WiseDllDeflatedSize => Model.WiseDllDeflatedSize; /// public uint WiseScriptDeflatedSize => Model.WiseScriptDeflatedSize; /// public uint WiseScriptInflatedSize => Model.WiseScriptInflatedSize; #endregion #region Constructors /// public WiseOverlayHeader(OverlayHeader model, byte[] data) : base(model, data) { } /// public WiseOverlayHeader(OverlayHeader model, byte[] data, int offset) : base(model, data, offset) { } /// public WiseOverlayHeader(OverlayHeader model, byte[] data, int offset, int length) : base(model, data, offset, length) { } /// public WiseOverlayHeader(OverlayHeader model, Stream data) : base(model, data) { } /// public WiseOverlayHeader(OverlayHeader model, Stream data, long offset) : base(model, data, offset) { } /// public WiseOverlayHeader(OverlayHeader model, Stream data, long offset, long length) : base(model, data, offset, length) { } #endregion #region Static Constructors /// /// Create a Wise installer overlay header from a byte array and offset /// /// Byte array representing the header /// Offset within the array to parse /// A Wise installer overlay header wrapper on success, null on failure public static WiseOverlayHeader? Create(byte[]? data, int offset) { // If the data is invalid if (data is null || data.Length == 0) return null; // If the offset is out of bounds if (offset < 0 || offset >= data.Length) return null; // Create a memory stream and use that var dataStream = new MemoryStream(data, offset, data.Length - offset); return Create(dataStream); } /// /// Create a Wise installer overlay header from a Stream /// /// Stream representing the header /// A Wise installer overlay header wrapper on success, null on failure public static WiseOverlayHeader? Create(Stream? data) { // If the data is invalid if (data is null || !data.CanRead) return null; try { // Cache the current offset long currentOffset = data.Position; var model = new Serialization.Readers.WiseOverlayHeader().Deserialize(data); if (model is null) return null; return new WiseOverlayHeader(model, data, currentOffset); } catch { return null; } } #endregion } }