Add formatted Title ID output

This commit is contained in:
Matt Nadareski
2026-03-13 21:01:38 -04:00
parent 81cd284a80
commit 82ed800a32
5 changed files with 57 additions and 2 deletions

View File

@@ -0,0 +1,32 @@
using SabreTools.IO.Extensions;
namespace SabreTools.Data.Extensions
{
public static class XboxExecutable
{
/// <summary>
/// Convert a 4-byte value to a formatted XBE title ID
/// </summary>
public static string? ToFormattedXBETitleID(this byte[]? data)
{
// Ignore invalid data
if (data is null || data.Length < 4)
return null;
// Create the prefix
string prefix1 = (0x41 <= data[3] && data[3] <= 0x5A) || (0x30 <= data[3] && data[3] <= 0x39)
? $"{(char)data[3]}"
: $"{data[3]:X2}";
string prefix2 = (0x41 <= data[2] && data[2] <= 0x5A) || (0x30 <= data[2] && data[2] <= 0x39)
? $"{(char)data[2]}"
: $"{data[2]:X2}";
// Create the serial
int offset = 0;
ushort serial = data.ReadUInt16LittleEndian(ref offset);
// Assemble and return
return $"{prefix1}{prefix2}-{serial:D3}";
}
}
}

View File

@@ -21,7 +21,8 @@ namespace SabreTools.Data.Models.XboxExecutable
/// Title ID for this application. This field doesn't appear to matter with
/// unsigned code, so it can be set to zero.
/// </summary>
public uint TitleID { get; set; }
/// <remarks>4 bytes</remarks>
public byte[] TitleID { get; set; } = new byte[4];
/// <summary>
/// Title name for this application (i.e. L"The Simpsons Road Rage").

View File

@@ -153,7 +153,7 @@ namespace SabreTools.Serialization.Readers
obj.SizeOfCertificate = data.ReadUInt32LittleEndian();
obj.TimeDate = data.ReadUInt32LittleEndian();
obj.TitleID = data.ReadUInt32LittleEndian();
obj.TitleID = data.ReadBytes(4);
obj.TitleName = data.ReadBytes(0x50);
obj.AlternativeTitleIDs = new uint[16];

View File

@@ -41,6 +41,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine(certificate.SizeOfCertificate, " Size of certificate");
builder.AppendLine(certificate.TimeDate, " Time/Date stamp");
builder.AppendLine(certificate.TitleID, " Title ID");
builder.AppendLine(certificate.TitleID.ToFormattedXBETitleID(), " Title ID (Formatted)");
builder.AppendLine(certificate.TitleName, " Title name");
builder.AppendLine(Encoding.Unicode.GetString(certificate.TitleName).TrimEnd('\0'), " Title name (Unicode)");
builder.AppendLine(certificate.AlternativeTitleIDs, " Alternative title IDs");

View File

@@ -1,4 +1,6 @@
using System.IO;
using System.Text;
using SabreTools.Data.Extensions;
using SabreTools.Data.Models.XboxExecutable;
namespace SabreTools.Serialization.Wrappers
@@ -51,6 +53,25 @@ namespace SabreTools.Serialization.Wrappers
/// <inheritdoc cref="Executable.ThreadLocalStorage"/>
public ThreadLocalStorage? ThreadLocalStorage => Model.ThreadLocalStorage;
/// <inheritdoc cref="Certificate.TitleID"/>
public byte[]? TitleIDBytes => Certificate?.TitleID;
/// <inheritdoc cref="Certificate.TitleID"/>
public string? TitleIDString => TitleIDBytes.ToFormattedXBETitleID();
/// <inheritdoc cref="Certificate.TitleName"/>
public string? TitleName
{
get
{
// Ignore invalid certificates
if (Certificate is null)
return null;
return Encoding.Unicode.GetString(Certificate.TitleName);
}
}
/// <inheritdoc cref="Executable.XAPILibraryVersion"/>
public LibraryVersion? XAPILibraryVersion => Model.XAPILibraryVersion;