NewExecutable model cleanup

This commit is contained in:
Matt Nadareski
2025-10-30 22:47:17 -04:00
parent d02e0c16c4
commit b4b7ba75cb
10 changed files with 52 additions and 105 deletions

View File

@@ -8,4 +8,4 @@ namespace SabreTools.Data.Models.NewExecutable
public const ushort SignatureUInt16 = 0x454e;
}
}
}

View File

@@ -17,51 +17,51 @@ namespace SabreTools.Data.Models.NewExecutable
/// <summary>
/// MS-DOS executable stub
/// </summary>
public MSDOS.Executable? Stub { get; set; }
public MSDOS.Executable Stub { get; set; }
/// <summary>
/// New Executable header
/// </summary>
public ExecutableHeader? Header { get; set; }
public ExecutableHeader Header { get; set; }
/// <summary>
/// Segment table
/// </summary>
public SegmentTableEntry[]? SegmentTable { get; set; }
public SegmentTableEntry[] SegmentTable { get; set; }
/// <summary>
/// Resource table
/// </summary>
public ResourceTable? ResourceTable { get; set; }
public ResourceTable ResourceTable { get; set; }
/// <summary>
/// Resident-Name table
/// </summary>
public ResidentNameTableEntry[]? ResidentNameTable { get; set; }
public ResidentNameTableEntry[] ResidentNameTable { get; set; }
/// <summary>
/// Module-Reference table
/// </summary>
public ModuleReferenceTableEntry[]? ModuleReferenceTable { get; set; }
public ModuleReferenceTableEntry[] ModuleReferenceTable { get; set; }
/// <summary>
/// Imported-Name table
/// </summary>
public Dictionary<ushort, ImportedNameTableEntry>? ImportedNameTable { get; set; }
public Dictionary<ushort, ImportedNameTableEntry> ImportedNameTable { get; set; }
/// <summary>
/// Entry table
/// </summary>
public EntryTableBundle[]? EntryTable { get; set; }
public EntryTableBundle[] EntryTable { get; set; }
/// <summary>
/// Nonresident-Name table
/// </summary>
public NonResidentNameTableEntry[]? NonResidentNameTable { get; set; }
public NonResidentNameTableEntry[] NonResidentNameTable { get; set; }
/// <summary>
/// Segment relocation data
/// </summary>
public PerSegmentData[]? SegmentRelocationData { get; set; }
public PerSegmentData[] SegmentRelocationData { get; set; }
}
}

View File

@@ -16,7 +16,7 @@ namespace SabreTools.Data.Models.NewExecutable
/// "NE"
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string? Magic;
public string Magic;
/// <summary>
/// Version number of the linker.
@@ -90,7 +90,7 @@ namespace SabreTools.Data.Models.NewExecutable
/// </summary>
/// <remarks>
/// SS:SP initial stack pointer, SS is index into segment table
///
///
/// If SS equals the automatic data segment and SP equals
/// zero, the stack pointer is set to the top of the
/// automatic data segment just below the additional heap

View File

@@ -11,7 +11,7 @@
/// To find the relocation data for a segment, seek to:
/// <see cref="SegmentTableEntry.Offset"/>
/// * (1 << <see cref="ExecutableHeader.SegmentAlignmentShiftCount"/>)
/// + <see cref="SegmentTableEntry.Length"/>
/// + <see cref="SegmentTableEntry.Length"/>
/// </remarks>
/// <see href="https://web.archive.org/web/20240422070115/http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
/// <see href="https://wiki.osdev.org/NE"/>
@@ -25,6 +25,6 @@
/// <summary>
/// A table of relocation records follows.
/// </summary>
public RelocationRecord[]? RelocationRecords { get; set; }
public RelocationRecord[] RelocationRecords { get; set; }
}
}

View File

@@ -14,7 +14,7 @@
/// <summary>
/// Flags byte.
///
///
/// The target value has four types that are defined in the flag
/// byte field.
/// </summary>

View File

@@ -23,12 +23,12 @@ namespace SabreTools.Data.Models.NewExecutable
/// <summary>
/// A table of resource type information blocks follows.
/// </summary>
public ResourceTypeInformationEntry[]? ResourceTypes { get; set; }
public ResourceTypeInformationEntry[] ResourceTypes { get; set; }
/// <summary>
/// Resource type and name strings are stored at the end of the
/// resource table.
/// </summary>
public Dictionary<ushort, ResourceTypeAndNameString?>? TypeAndNameStrings { get; set; }
public Dictionary<ushort, ResourceTypeAndNameString?> TypeAndNameStrings { get; set; }
}
}

View File

@@ -29,6 +29,6 @@
/// <summary>
/// A table of resources for this type follows.
/// </summary>
public ResourceTypeResourceEntry[]? Resources { get; set; }
public ResourceTypeResourceEntry[] Resources { get; set; }
}
}

View File

@@ -549,7 +549,7 @@ namespace SabreTools.Serialization.Readers
stringOffsets.Add(rtie.TypeID);
// Handle types with resources
foreach (var rtre in rtie.Resources ?? [])
foreach (var rtre in rtie.Resources)
{
// Skip invalid entries
if (rtre == null || rtre.IsIntegerType() || rtre.ResourceID == 0)

View File

@@ -20,7 +20,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
// Stub
Print(builder, Model.Stub?.Header);
Print(builder, Model.Stub.Header);
// Header
Print(builder, Model.Header);
@@ -29,23 +29,16 @@ namespace SabreTools.Serialization.Wrappers
Print(builder, Model.SegmentTable);
Print(builder, Model.ResourceTable);
Print(builder, Model.ResidentNameTable);
Print(builder, Model.ModuleReferenceTable, Model.Stub?.Header, Model.Header);
Print(builder, Model.ModuleReferenceTable, Model.Stub.Header, Model.Header);
Print(builder, Model.ImportedNameTable);
Print(builder, Model.EntryTable);
Print(builder, Model.NonResidentNameTable);
}
private static void Print(StringBuilder builder, Data.Models.MSDOS.ExecutableHeader? header)
private static void Print(StringBuilder builder, Data.Models.MSDOS.ExecutableHeader header)
{
builder.AppendLine(" MS-DOS Stub Header Information:");
builder.AppendLine(" -------------------------");
if (header == null)
{
builder.AppendLine(" No MS-DOS stub header");
builder.AppendLine();
return;
}
builder.AppendLine(header.Magic, " Magic number");
builder.AppendLine(header.LastPageBytes, " Last page bytes");
builder.AppendLine(header.Pages, " Pages");
@@ -72,17 +65,10 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, ExecutableHeader? header)
private static void Print(StringBuilder builder, ExecutableHeader header)
{
builder.AppendLine(" Header Information:");
builder.AppendLine(" -------------------------");
if (header == null)
{
builder.AppendLine(" No header");
builder.AppendLine();
return;
}
builder.AppendLine(header.Magic, " Magic number");
builder.AppendLine(header.LinkerVersion, " Linker version");
builder.AppendLine(header.LinkerRevision, " Linker revision");
@@ -117,11 +103,11 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, SegmentTableEntry[]? entries)
private static void Print(StringBuilder builder, SegmentTableEntry[] entries)
{
builder.AppendLine(" Segment Table Information:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Length == 0)
if (entries.Length == 0)
{
builder.AppendLine(" No segment table items");
builder.AppendLine();
@@ -142,19 +128,12 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, ResourceTable? table)
private static void Print(StringBuilder builder, ResourceTable table)
{
builder.AppendLine(" Resource Table Information:");
builder.AppendLine(" -------------------------");
if (table == null)
{
builder.AppendLine(" No resource table");
builder.AppendLine();
return;
}
builder.AppendLine(table.AlignmentShiftCount, " Alignment shift count");
if (table.ResourceTypes == null || table.ResourceTypes.Length == 0)
if (table.ResourceTypes.Length == 0)
{
builder.AppendLine(" No resource table items");
}
@@ -170,7 +149,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine(entry.ResourceCount, " Resource count");
builder.AppendLine(entry.Reserved, " Reserved");
builder.AppendLine(" Resources = ");
if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0)
if (entry.ResourceCount == 0 || entry.Resources.Length == 0)
{
builder.AppendLine(" No resource items");
}
@@ -197,7 +176,7 @@ namespace SabreTools.Serialization.Wrappers
}
}
if (table.TypeAndNameStrings == null || table.TypeAndNameStrings.Count == 0)
if (table.TypeAndNameStrings.Count == 0)
{
builder.AppendLine(" No resource table type/name strings");
}
@@ -220,11 +199,11 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, ResidentNameTableEntry[]? entries)
private static void Print(StringBuilder builder, ResidentNameTableEntry[] entries)
{
builder.AppendLine(" Resident-Name Table Information:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Length == 0)
if (entries.Length == 0)
{
builder.AppendLine(" No resident-name table items");
builder.AppendLine();
@@ -244,11 +223,11 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, ModuleReferenceTableEntry[]? entries, Data.Models.MSDOS.ExecutableHeader? stub, ExecutableHeader? header)
private static void Print(StringBuilder builder, ModuleReferenceTableEntry[] entries, Data.Models.MSDOS.ExecutableHeader stub, ExecutableHeader header)
{
builder.AppendLine(" Module-Reference Table Information:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Length == 0)
if (entries.Length == 0)
{
builder.AppendLine(" No module-reference table items");
builder.AppendLine();
@@ -261,17 +240,17 @@ namespace SabreTools.Serialization.Wrappers
var entry = entries[i];
builder.AppendLine($" Module-Reference Table Entry {i}");
builder.AppendLine($" Offset: {entry.Offset} (adjusted to be {entry.Offset + (stub?.NewExeHeaderAddr ?? 0) + (header?.ImportedNamesTableOffset ?? 0)})");
builder.AppendLine($" Offset: {entry.Offset} (adjusted to be {entry.Offset + stub.NewExeHeaderAddr + header.ImportedNamesTableOffset})");
}
builder.AppendLine();
}
private static void Print(StringBuilder builder, Dictionary<ushort, ImportedNameTableEntry>? entries)
private static void Print(StringBuilder builder, Dictionary<ushort, ImportedNameTableEntry> entries)
{
builder.AppendLine(" Imported-Name Table Information:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Count == 0)
if (entries.Count == 0)
{
builder.AppendLine(" No imported-name table items");
builder.AppendLine();
@@ -288,11 +267,11 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, EntryTableBundle[]? entries)
private static void Print(StringBuilder builder, EntryTableBundle[] entries)
{
builder.AppendLine(" Entry Table Information:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Length == 0)
if (entries.Length == 0)
{
builder.AppendLine(" No entry table items");
builder.AppendLine();
@@ -324,11 +303,11 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, NonResidentNameTableEntry[]? entries)
private static void Print(StringBuilder builder, NonResidentNameTableEntry[] entries)
{
builder.AppendLine(" Nonresident-Name Table Information:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Length == 0)
if (entries.Length == 0)
{
builder.AppendLine(" No nonresident-name table items");
builder.AppendLine();

View File

@@ -18,13 +18,13 @@ namespace SabreTools.Serialization.Wrappers
#region Extension Properties
/// <inheritdoc cref="Executable.Header"/>
public ExecutableHeader? Header => Model.Header;
public ExecutableHeader Header => Model.Header;
/// <inheritdoc cref="Executable.ImportedNameTable"/>
public Dictionary<ushort, ImportedNameTableEntry>? ImportedNameTable => Model.ImportedNameTable;
public Dictionary<ushort, ImportedNameTableEntry> ImportedNameTable => Model.ImportedNameTable;
/// <inheritdoc cref="Executable.NonResidentNameTable"/>
public NonResidentNameTableEntry[]? NonResidentNameTable => Model.NonResidentNameTable;
public NonResidentNameTableEntry[] NonResidentNameTable => Model.NonResidentNameTable;
/// <summary>
/// Address of the overlay, if it exists
@@ -48,13 +48,6 @@ namespace SabreTools.Serialization.Wrappers
return _overlayAddress.Value;
}
// If a required property is missing
if (Header == null || SegmentTable == null || ResourceTable?.ResourceTypes == null)
{
_overlayAddress = -1;
return _overlayAddress.Value;
}
// Search through the segments table to find the furthest
long endOfSectionData = -1;
foreach (var entry in SegmentTable)
@@ -86,7 +79,7 @@ namespace SabreTools.Serialization.Wrappers
foreach (var entry in ResourceTable.ResourceTypes)
{
// Skip invalid entries
if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0)
if (entry.ResourceCount == 0 || entry.Resources.Length == 0)
continue;
foreach (var resource in entry.Resources)
@@ -184,13 +177,6 @@ namespace SabreTools.Serialization.Wrappers
return _overlaySize;
}
// If a required property is missing
if (Header == null || SegmentTable == null || ResourceTable?.ResourceTypes == null)
{
_overlaySize = 0;
return _overlaySize;
}
// Get the overlay address if possible
long endOfSectionData = OverlayAddress;
@@ -252,16 +238,16 @@ namespace SabreTools.Serialization.Wrappers
}
/// <inheritdoc cref="Executable.ResidentNameTable"/>
public ResidentNameTableEntry[]? ResidentNameTable => Model.ResidentNameTable;
public ResidentNameTableEntry[] ResidentNameTable => Model.ResidentNameTable;
/// <inheritdoc cref="Executable.ResourceTable"/>
public ResourceTable? ResourceTable => Model.ResourceTable;
public ResourceTable ResourceTable => Model.ResourceTable;
/// <inheritdoc cref="Executable.SegmentTable"/>
public SegmentTableEntry[]? SegmentTable => Model.SegmentTable;
public SegmentTableEntry[] SegmentTable => Model.SegmentTable;
/// <inheritdoc cref="Executable.Stub"/>
public Data.Models.MSDOS.Executable? Stub => Model.Stub;
public Data.Models.MSDOS.Executable Stub => Model.Stub;
/// <summary>
/// Stub executable data, if it exists
@@ -276,12 +262,6 @@ namespace SabreTools.Serialization.Wrappers
if (_stubExecutableData != null)
return _stubExecutableData;
if (Stub?.Header?.NewExeHeaderAddr == null)
{
_stubExecutableData = [];
return _stubExecutableData;
}
// Populate the raw stub executable data based on the source
int endOfStubHeader = 0x40;
int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
@@ -472,24 +452,20 @@ namespace SabreTools.Serialization.Wrappers
/// <returns>Resource on success, null otherwise</returns>
public ResourceTypeResourceEntry? GetResource(int id)
{
// If the header is invalid
if (Header == null)
return null;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)
return null;
// If the resource table is invalid
if (ResourceTable?.ResourceTypes == null || ResourceTable.ResourceTypes.Length == 0)
if (ResourceTable.ResourceTypes.Length == 0)
return null;
// Loop through the resources to find a matching ID
foreach (var resourceType in ResourceTable.ResourceTypes)
{
// Skip invalid resource types
if (resourceType.ResourceCount == 0 || resourceType.Resources == null || resourceType.Resources.Length == 0)
if (resourceType.ResourceCount == 0 || resourceType.Resources.Length == 0)
continue;
// Loop through the entries to find a matching ID
@@ -559,10 +535,6 @@ namespace SabreTools.Serialization.Wrappers
if (dataLength == -1)
return -1;
// If the resource table is invalid
if (ResourceTable == null)
return -1;
// Get the matching resource
var resource = GetSegment(id);
if (resource == null)
@@ -589,7 +561,7 @@ namespace SabreTools.Serialization.Wrappers
public SegmentTableEntry? GetSegment(int index)
{
// If the segment table is invalid
if (SegmentTable == null || SegmentTable.Length == 0)
if (SegmentTable.Length == 0)
return null;
// If the index is invalid
@@ -646,10 +618,6 @@ namespace SabreTools.Serialization.Wrappers
/// <returns>Segment offset on success, -1 otherwise</returns>
public int GetSegmentOffset(int index)
{
// If the header is invalid
if (Header == null)
return -1;
// Get the available source length, if possible
long dataLength = Length;
if (dataLength == -1)