diff --git a/BurnOutSharp.Builder/NewExecutable.cs b/BurnOutSharp.Builder/NewExecutable.cs index b3f5d113..c23966bb 100644 --- a/BurnOutSharp.Builder/NewExecutable.cs +++ b/BurnOutSharp.Builder/NewExecutable.cs @@ -170,7 +170,25 @@ namespace BurnOutSharp.Builder #endregion - // TODO: Complete NE parsing + #region Nonresident-Name Table + + // If the offset for the nonresident-name table doesn't exist + tableAddress = initialOffset + + (int)stub.Header.NewExeHeaderAddr + + (int)executableHeader.NonResidentNamesTableOffset; + if (tableAddress >= data.Length) + return executable; + + // Try to parse the nonresident-name table + var nonResidentNameTable = ParseNonResidentNameTable(data, tableAddress, (ushort)(executableHeader.NonResidentNamesTableOffset + executableHeader.NonResidentNameTableSize)); + if (nonResidentNameTable == null) + return null; + + // Set the nonresident-name table + executable.NonResidentNameTable = nonResidentNameTable; + + #endregion + return executable; } @@ -424,6 +442,30 @@ namespace BurnOutSharp.Builder return entryTable.ToArray(); } + /// + /// Parse a byte array into a nonresident-name table + /// + /// Byte array to parse + /// Offset into the byte array + /// First address not part of the nonresident-name table + /// Filled nonresident-name table on success, null on error + private static NonResidentNameTableEntry[] ParseNonResidentNameTable(byte[] data, int offset, ushort endOffset) + { + // TODO: Use marshalling here instead of building + var residentNameTable = new List(); + + while (offset < endOffset) + { + var entry = new NonResidentNameTableEntry(); + entry.Length = data.ReadByte(ref offset); + entry.NameString = data.ReadBytes(ref offset, entry.Length); + entry.OrdinalNumber = data.ReadUInt16(ref offset); + residentNameTable.Add(entry); + } + + return residentNameTable.ToArray(); + } + #endregion #region Stream Data @@ -593,7 +635,26 @@ namespace BurnOutSharp.Builder #endregion - // TODO: Complete NE parsing + #region Nonresident-Name Table + + // If the offset for the nonresident-name table doesn't exist + tableAddress = initialOffset + + (int)stub.Header.NewExeHeaderAddr + + (int)executableHeader.NonResidentNamesTableOffset; + if (tableAddress >= data.Length) + return executable; + + // Try to parse the nonresident-name table + data.Seek(tableAddress, SeekOrigin.Begin); + var nonResidentNameTable = ParseNonResidentNameTable(data, (ushort)(executableHeader.NonResidentNamesTableOffset + executableHeader.NonResidentNameTableSize)); + if (nonResidentNameTable == null) + return null; + + // Set the nonresident-name table + executable.NonResidentNameTable = nonResidentNameTable; + + #endregion + return executable; } @@ -841,6 +902,29 @@ namespace BurnOutSharp.Builder return entryTable.ToArray(); } + /// + /// Parse a Stream into a nonresident-name table + /// + /// Stream to parse + /// First address not part of the nonresident-name table + /// Filled nonresident-name table on success, null on error + private static NonResidentNameTableEntry[] ParseNonResidentNameTable(Stream data, ushort endOffset) + { + // TODO: Use marshalling here instead of building + var residentNameTable = new List(); + + while (data.Position < endOffset) + { + var entry = new NonResidentNameTableEntry(); + entry.Length = data.ReadByteValue(); + entry.NameString = data.ReadBytes(entry.Length); + entry.OrdinalNumber = data.ReadUInt16(); + residentNameTable.Add(entry); + } + + return residentNameTable.ToArray(); + } + #endregion } } \ No newline at end of file