using System.IO; using System.Text; namespace BinaryObjectScanner.Wrappers { public class MSDOS : WrapperBase { #region Descriptive Properties /// public override string DescriptionString => "MS-DOS Executable"; #endregion #region Pass-Through Properties #region Header /// #if NET48 public string Magic => _model.Header.Magic; #else public string? Magic => _model.Header?.Magic; #endif /// #if NET48 public ushort LastPageBytes => _model.Header.LastPageBytes; #else public ushort? LastPageBytes => _model.Header?.LastPageBytes; #endif /// #if NET48 public ushort Pages => _model.Header.Pages; #else public ushort? Pages => _model.Header?.Pages; #endif /// #if NET48 public ushort RelocationItems => _model.Header.RelocationItems; #else public ushort? RelocationItems => _model.Header?.RelocationItems; #endif /// #if NET48 public ushort HeaderParagraphSize => _model.Header.HeaderParagraphSize; #else public ushort? HeaderParagraphSize => _model.Header?.HeaderParagraphSize; #endif /// #if NET48 public ushort MinimumExtraParagraphs => _model.Header.MinimumExtraParagraphs; #else public ushort? MinimumExtraParagraphs => _model.Header?.MinimumExtraParagraphs; #endif /// #if NET48 public ushort MaximumExtraParagraphs => _model.Header.MaximumExtraParagraphs; #else public ushort? MaximumExtraParagraphs => _model.Header?.MaximumExtraParagraphs; #endif /// #if NET48 public ushort InitialSSValue => _model.Header.InitialSSValue; #else public ushort? InitialSSValue => _model.Header?.InitialSSValue; #endif /// #if NET48 public ushort InitialSPValue => _model.Header.InitialSPValue; #else public ushort? InitialSPValue => _model.Header?.InitialSPValue; #endif /// #if NET48 public ushort Checksum => _model.Header.Checksum; #else public ushort? Checksum => _model.Header?.Checksum; #endif /// #if NET48 public ushort InitialIPValue => _model.Header.InitialIPValue; #else public ushort? InitialIPValue => _model.Header?.InitialIPValue; #endif /// #if NET48 public ushort InitialCSValue => _model.Header.InitialCSValue; #else public ushort? InitialCSValue => _model.Header?.InitialCSValue; #endif /// #if NET48 public ushort RelocationTableAddr => _model.Header.RelocationTableAddr; #else public ushort? RelocationTableAddr => _model.Header?.RelocationTableAddr; #endif /// #if NET48 public ushort OverlayNumber => _model.Header.OverlayNumber; #else public ushort? OverlayNumber => _model.Header?.OverlayNumber; #endif #endregion #region PE Extensions /// #if NET48 public ushort[] Reserved1 => _model.Header.Reserved1; #else public ushort[]? Reserved1 => _model.Header?.Reserved1; #endif /// #if NET48 public ushort OEMIdentifier => _model.Header.OEMIdentifier; #else public ushort? OEMIdentifier => _model.Header?.OEMIdentifier; #endif /// #if NET48 public ushort OEMInformation => _model.Header.OEMInformation; #else public ushort? OEMInformation => _model.Header?.OEMInformation; #endif /// #if NET48 public ushort[] Reserved2 => _model.Header.Reserved2; #else public ushort[]? Reserved2 => _model.Header?.Reserved2; #endif /// #if NET48 public uint NewExeHeaderAddr => _model.Header.NewExeHeaderAddr; #else public uint? NewExeHeaderAddr => _model.Header?.NewExeHeaderAddr; #endif #endregion #region Relocation Table /// #if NET48 public SabreTools.Models.MSDOS.RelocationEntry[] RelocationTable => _model.RelocationTable; #else public SabreTools.Models.MSDOS.RelocationEntry?[]? RelocationTable => _model.RelocationTable; #endif #endregion #endregion #region Constructors /// #if NET48 public MSDOS(SabreTools.Models.MSDOS.Executable model, byte[] data, int offset) #else public MSDOS(SabreTools.Models.MSDOS.Executable? model, byte[]? data, int offset) #endif : base(model, data, offset) { // All logic is handled by the base class } /// #if NET48 public MSDOS(SabreTools.Models.MSDOS.Executable model, Stream data) #else public MSDOS(SabreTools.Models.MSDOS.Executable? model, Stream? data) #endif : base(model, data) { // All logic is handled by the base class }/// /// Create an MS-DOS executable from a byte array and offset /// /// Byte array representing the executable /// Offset within the array to parse /// An MS-DOS executable wrapper on success, null on failure #if NET48 public static MSDOS Create(byte[] data, int offset) #else public static MSDOS? Create(byte[]? data, int offset) #endif { // If the data is invalid if (data == null) return null; // If the offset is out of bounds if (offset < 0 || offset >= data.Length) return null; // Create a memory stream and use that MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset); return Create(dataStream); } /// /// Create an MS-DOS executable from a Stream /// /// Stream representing the executable /// An MS-DOS executable wrapper on success, null on failure #if NET48 public static MSDOS Create(Stream data) #else public static MSDOS? Create(Stream? data) #endif { // If the data is invalid if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead) return null; var executable = new SabreTools.Serialization.Streams.MSDOS().Deserialize(data); if (executable == null) return null; try { return new MSDOS(executable, data); } catch { return null; } } #endregion #region Printing /// public override StringBuilder PrettyPrint() { StringBuilder builder = new StringBuilder(); Printing.MSDOS.Print(builder, _model); return builder; } #if NET6_0_OR_GREATER /// public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_model, _jsonSerializerOptions); #endif #endregion } }