mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-02-04 13:45:40 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
695309bc32 | ||
|
|
97b2f68ec7 | ||
|
|
593044dbf3 | ||
|
|
1fcf44fb8d | ||
|
|
a2a472baf9 | ||
|
|
b5b4a50d94 | ||
|
|
f1b5464052 | ||
|
|
2c0224db22 |
@@ -9,7 +9,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.7.0</Version>
|
||||
<Version>1.7.4</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
|
||||
@@ -78,8 +78,14 @@ namespace SabreTools.Serialization.Deserializers
|
||||
// Iterate and build the partitions
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
// Cache the offset of the partition
|
||||
initialOffset = data.Position;
|
||||
// Find the offset to the partition
|
||||
long partitionOffset = cart.Header.PartitionsTable?[i]?.Offset ?? 0;
|
||||
partitionOffset *= mediaUnitSize;
|
||||
if (partitionOffset == 0)
|
||||
continue;
|
||||
|
||||
// Seek to the start of the partition
|
||||
data.Seek(partitionOffset, SeekOrigin.Begin);
|
||||
|
||||
// Handle the normal header
|
||||
var partition = ParseNCCHHeader(data);
|
||||
@@ -101,7 +107,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
if (partition.ExeFSSizeInMediaUnits > 0)
|
||||
{
|
||||
long offset = partition.ExeFSOffsetInMediaUnits * mediaUnitSize;
|
||||
data.Seek(initialOffset + offset, SeekOrigin.Begin);
|
||||
data.Seek(partitionOffset + offset, SeekOrigin.Begin);
|
||||
|
||||
var exeFsHeader = ParseExeFSHeader(data);
|
||||
if (exeFsHeader == null)
|
||||
@@ -114,7 +120,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
if (partition.RomFSSizeInMediaUnits > 0)
|
||||
{
|
||||
long offset = partition.RomFSOffsetInMediaUnits * mediaUnitSize;
|
||||
data.Seek(initialOffset + offset, SeekOrigin.Begin);
|
||||
data.Seek(partitionOffset + offset, SeekOrigin.Begin);
|
||||
|
||||
var romFsHeader = ParseRomFSHeader(data);
|
||||
if (romFsHeader == null)
|
||||
@@ -124,10 +130,6 @@ namespace SabreTools.Serialization.Deserializers
|
||||
|
||||
cart.RomFSHeaders[i] = romFsHeader;
|
||||
}
|
||||
|
||||
// Skip past other data
|
||||
long partitionSize = partition.ContentSizeInMediaUnits * mediaUnitSize;
|
||||
data.Seek(initialOffset + partitionSize, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -329,7 +331,51 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <returns>Filled NCCH extended header on success, null on error</returns>
|
||||
public static NCCHExtendedHeader? ParseNCCHExtendedHeader(Stream data)
|
||||
{
|
||||
return data.ReadType<NCCHExtendedHeader>();
|
||||
// TODO: Replace with `data.ReadType<NCCHExtendedHeader>();` when enum serialization fixed
|
||||
var header = new NCCHExtendedHeader();
|
||||
|
||||
header.SCI = data.ReadType<SystemControlInfo>();
|
||||
header.ACI = ParseAccessControlInfo(data);
|
||||
header.AccessDescSignature = data.ReadBytes(0x100);
|
||||
header.NCCHHDRPublicKey = data.ReadBytes(0x100);
|
||||
header.ACIForLimitations = ParseAccessControlInfo(data);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into an access control info
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <returns>Filled access control info on success, null on error</returns>
|
||||
public static AccessControlInfo? ParseAccessControlInfo(Stream data)
|
||||
{
|
||||
var aci = new AccessControlInfo();
|
||||
|
||||
aci.ARM11LocalSystemCapabilities = data.ReadType<ARM11LocalSystemCapabilities>();
|
||||
aci.ARM11KernelCapabilities = data.ReadType<ARM11KernelCapabilities>();
|
||||
aci.ARM9AccessControl = ParseARM9AccessControl(data);
|
||||
|
||||
return aci;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into an ARM9 access control
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <returns>Filled ARM9 access control on success, null on error</returns>
|
||||
public static ARM9AccessControl? ParseARM9AccessControl(Stream data)
|
||||
{
|
||||
var a9ac = new ARM9AccessControl();
|
||||
|
||||
a9ac.Descriptors = new ARM9AccessControlDescriptors[15];
|
||||
for (int i = 0; i < a9ac.Descriptors.Length; i++)
|
||||
{
|
||||
a9ac.Descriptors[i] = (ARM9AccessControlDescriptors)data.ReadByteValue();
|
||||
}
|
||||
a9ac.DescriptorVersion = data.ReadByteValue();
|
||||
|
||||
return a9ac;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using SabreTools.Models.N3DS;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
@@ -491,14 +492,20 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine($" Descriptors: {entry.ACI.ARM9AccessControl.Descriptors} (0x{entry.ACI.ARM9AccessControl.Descriptors:X})");
|
||||
string descriptorsStr = "[NULL]";
|
||||
if (entry.ACI.ARM9AccessControl.Descriptors != null)
|
||||
{
|
||||
var descriptors = Array.ConvertAll(entry.ACI.ARM9AccessControl.Descriptors, d => d.ToString());
|
||||
descriptorsStr = string.Join(", ", descriptors);
|
||||
}
|
||||
builder.AppendLine(descriptorsStr, " Descriptors");
|
||||
builder.AppendLine(entry.ACI.ARM9AccessControl.DescriptorVersion, " Descriptor version");
|
||||
}
|
||||
|
||||
builder.AppendLine(entry.AccessDescSignature, " AccessDec signature (RSA-2048-SHA256)");
|
||||
builder.AppendLine(entry.NCCHHDRPublicKey, " NCCH HDR RSA-2048 public key");
|
||||
}
|
||||
|
||||
builder.AppendLine(entry.AccessDescSignature, " AccessDec signature (RSA-2048-SHA256)");
|
||||
builder.AppendLine(entry.NCCHHDRPublicKey, " NCCH HDR RSA-2048 public key");
|
||||
|
||||
builder.AppendLine(" Access control info (for limitations of first ACI):");
|
||||
if (entry.ACIForLimitations == null)
|
||||
{
|
||||
@@ -559,7 +566,13 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine($" Descriptors: {entry.ACIForLimitations.ARM9AccessControl.Descriptors} (0x{entry.ACIForLimitations.ARM9AccessControl.Descriptors:X})");
|
||||
string descriptorsStr = "[NULL]";
|
||||
if (entry.ACIForLimitations.ARM9AccessControl.Descriptors != null)
|
||||
{
|
||||
var descriptors = Array.ConvertAll(entry.ACIForLimitations.ARM9AccessControl.Descriptors, d => d.ToString());
|
||||
descriptorsStr = string.Join(", ", descriptors);
|
||||
}
|
||||
builder.AppendLine(descriptorsStr, " Descriptors");
|
||||
builder.AppendLine(entry.ACIForLimitations.ARM9AccessControl.DescriptorVersion, " Descriptor version");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.7.2</Version>
|
||||
<Version>1.7.4</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
|
||||
@@ -22,76 +22,10 @@ namespace SabreTools.Serialization.Wrappers
|
||||
public NCCHHeader? BackupHeader => Model.CardInfoHeader?.InitialData?.BackupHeader;
|
||||
|
||||
/// <summary>
|
||||
/// Backup Write Wait Time (The time to wait to write save to backup after the card is recognized (0-255
|
||||
/// seconds)). NATIVE_FIRM loads this flag from the gamecard NCSD header starting with 6.0.0-11.
|
||||
/// ExeFS headers
|
||||
/// </summary>
|
||||
public byte BackupWriteWaitTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionFlags == null)
|
||||
return default;
|
||||
|
||||
return Model.Header.PartitionFlags[(int)NCSDFlags.BackupWriteWaitTime];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (Only SDK 2.X)
|
||||
/// </summary>
|
||||
public MediaCardDeviceType MediaCardDevice2X
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionFlags == null)
|
||||
return default;
|
||||
|
||||
return (MediaCardDeviceType)Model.Header.PartitionFlags[(int)NCSDFlags.MediaCardDevice2X];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (SDK 3.X+)
|
||||
/// </summary>
|
||||
public MediaCardDeviceType MediaCardDevice3X
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionFlags == null)
|
||||
return default;
|
||||
|
||||
return (MediaCardDeviceType)Model.Header.PartitionFlags[(int)NCSDFlags.MediaCardDevice3X];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Media Platform Index (1 = CTR)
|
||||
/// </summary>
|
||||
public MediaPlatformIndex MediaPlatformIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionFlags == null)
|
||||
return default;
|
||||
|
||||
return (MediaPlatformIndex)Model.Header.PartitionFlags[(int)NCSDFlags.MediaPlatformIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Media Type Index (0 = Inner Device, 1 = Card1, 2 = Card2, 3 = Extended Device)
|
||||
/// </summary>
|
||||
public MediaTypeIndex MediaTypeIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionFlags == null)
|
||||
return default;
|
||||
|
||||
return (MediaTypeIndex)Model.Header.PartitionFlags[(int)NCSDFlags.MediaTypeIndex];
|
||||
}
|
||||
}
|
||||
|
||||
public ExeFSHeader?[] ExeFSHeaders => Model.ExeFSHeaders ?? [];
|
||||
|
||||
/// <summary>
|
||||
/// Media unit size in bytes
|
||||
/// </summary>
|
||||
@@ -106,7 +40,17 @@ namespace SabreTools.Serialization.Wrappers
|
||||
}
|
||||
}
|
||||
|
||||
#region Partition Entries
|
||||
/// <summary>
|
||||
/// Partitions data table
|
||||
/// </summary>
|
||||
public NCCHHeader?[] Partitions => Model.Partitions ?? [];
|
||||
|
||||
/// <summary>
|
||||
/// Partitions header table
|
||||
/// </summary>
|
||||
public PartitionTableEntry?[] PartitionsTable => Model.Header?.PartitionsTable ?? [];
|
||||
|
||||
#region Named Partition Entries
|
||||
|
||||
/// <summary>
|
||||
/// Partition table entry for Executable Content (CXI)
|
||||
@@ -115,10 +59,10 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionsTable == null)
|
||||
if (PartitionsTable == null || PartitionsTable.Length == 0)
|
||||
return null;
|
||||
|
||||
return Model.Header.PartitionsTable[0];
|
||||
return PartitionsTable[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,10 +73,10 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionsTable == null)
|
||||
if (PartitionsTable == null || PartitionsTable.Length == 0)
|
||||
return null;
|
||||
|
||||
return Model.Header.PartitionsTable[1];
|
||||
return PartitionsTable[1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,10 +87,10 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionsTable == null)
|
||||
if (PartitionsTable == null || PartitionsTable.Length == 0)
|
||||
return null;
|
||||
|
||||
return Model.Header.PartitionsTable[2];
|
||||
return PartitionsTable[2];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +101,10 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionsTable == null)
|
||||
if (PartitionsTable == null || PartitionsTable.Length == 0)
|
||||
return null;
|
||||
|
||||
return Model.Header.PartitionsTable[6];
|
||||
return PartitionsTable[6];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,10 +115,90 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Model.Header?.PartitionsTable == null)
|
||||
if (PartitionsTable == null || PartitionsTable.Length == 0)
|
||||
return null;
|
||||
|
||||
return Model.Header.PartitionsTable[7];
|
||||
return PartitionsTable[7];
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Partitions flags
|
||||
/// </summary>
|
||||
public byte[] PartitionFlags => Model.Header?.PartitionFlags ?? [];
|
||||
|
||||
#region Partition Flags
|
||||
|
||||
/// <summary>
|
||||
/// Backup Write Wait Time (The time to wait to write save to backup after the card is recognized (0-255
|
||||
/// seconds)). NATIVE_FIRM loads this flag from the gamecard NCSD header starting with 6.0.0-11.
|
||||
/// </summary>
|
||||
public byte BackupWriteWaitTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PartitionFlags == null || PartitionFlags.Length == 0)
|
||||
return default;
|
||||
|
||||
return PartitionFlags[(int)NCSDFlags.BackupWriteWaitTime];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (Only SDK 2.X)
|
||||
/// </summary>
|
||||
public MediaCardDeviceType MediaCardDevice2X
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PartitionFlags == null || PartitionFlags.Length == 0)
|
||||
return default;
|
||||
|
||||
return (MediaCardDeviceType)PartitionFlags[(int)NCSDFlags.MediaCardDevice2X];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (SDK 3.X+)
|
||||
/// </summary>
|
||||
public MediaCardDeviceType MediaCardDevice3X
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PartitionFlags == null || PartitionFlags.Length == 0)
|
||||
return default;
|
||||
|
||||
return (MediaCardDeviceType)PartitionFlags[(int)NCSDFlags.MediaCardDevice3X];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Media Platform Index (1 = CTR)
|
||||
/// </summary>
|
||||
public MediaPlatformIndex MediaPlatformIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PartitionFlags == null || PartitionFlags.Length == 0)
|
||||
return default;
|
||||
|
||||
return (MediaPlatformIndex)PartitionFlags[(int)NCSDFlags.MediaPlatformIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Media Type Index (0 = Inner Device, 1 = Card1, 2 = Card2, 3 = Extended Device)
|
||||
/// </summary>
|
||||
public MediaTypeIndex MediaTypeIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PartitionFlags == null || PartitionFlags.Length == 0)
|
||||
return default;
|
||||
|
||||
return (MediaTypeIndex)PartitionFlags[(int)NCSDFlags.MediaTypeIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,31 +275,48 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <summary>
|
||||
/// Get the bit masks for a partition
|
||||
/// </summary>
|
||||
public BitMasks GetBitMasks(int partitionIndex)
|
||||
public BitMasks GetBitMasks(int index)
|
||||
{
|
||||
if (Model.Partitions == null)
|
||||
if (Partitions == null)
|
||||
return 0;
|
||||
if (partitionIndex < 0 || partitionIndex >= Model.Partitions.Length)
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return 0;
|
||||
|
||||
var partition = Model.Partitions[partitionIndex];
|
||||
var partition = Partitions[index];
|
||||
if (partition?.Flags == null)
|
||||
return 0;
|
||||
|
||||
return partition.Flags.BitMasks;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the crypto method for a partition
|
||||
/// </summary>
|
||||
public CryptoMethod GetCryptoMethod(int index)
|
||||
{
|
||||
if (Partitions == null)
|
||||
return 0;
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return 0;
|
||||
|
||||
var partition = Partitions[index];
|
||||
if (partition?.Flags == null)
|
||||
return 0;
|
||||
|
||||
return partition.Flags.CryptoMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a file header represents a CODE block
|
||||
/// </summary>
|
||||
public bool IsCodeBinary(int fsIndex, int headerIndex)
|
||||
{
|
||||
if (Model.ExeFSHeaders == null)
|
||||
if (ExeFSHeaders == null)
|
||||
return false;
|
||||
if (fsIndex < 0 || fsIndex >= Model.ExeFSHeaders.Length)
|
||||
if (fsIndex < 0 || fsIndex >= ExeFSHeaders.Length)
|
||||
return false;
|
||||
|
||||
var fsHeader = Model.ExeFSHeaders[fsIndex];
|
||||
var fsHeader = ExeFSHeaders[fsIndex];
|
||||
if (fsHeader?.FileHeaders == null)
|
||||
return false;
|
||||
|
||||
@@ -286,60 +327,63 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (fileHeader == null)
|
||||
return false;
|
||||
|
||||
return fileHeader.FileName == ".code\0\0\0";
|
||||
return fileHeader.FileName == ".code";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the initial value for the plain counter
|
||||
/// </summary>
|
||||
public byte[] PlainIV(int partitionIndex)
|
||||
public byte[] PlainIV(int index)
|
||||
{
|
||||
if (Model.Partitions == null)
|
||||
if (Partitions == null)
|
||||
return [];
|
||||
if (partitionIndex < 0 || partitionIndex >= Model.Partitions.Length)
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return [];
|
||||
|
||||
var header = Model.Partitions[partitionIndex];
|
||||
if (header == null)
|
||||
var header = Partitions[index];
|
||||
if (header == null || header.MagicID != NCCHMagicNumber)
|
||||
return [];
|
||||
|
||||
byte[] partitionIdBytes = BitConverter.GetBytes(header.PartitionId);
|
||||
Array.Reverse(partitionIdBytes);
|
||||
return [.. partitionIdBytes, .. PlainCounter];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the initial value for the ExeFS counter
|
||||
/// </summary>
|
||||
public byte[] ExeFSIV(int partitionIndex)
|
||||
public byte[] ExeFSIV(int index)
|
||||
{
|
||||
if (Model.Partitions == null)
|
||||
if (Partitions == null)
|
||||
return [];
|
||||
if (partitionIndex < 0 || partitionIndex >= Model.Partitions.Length)
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return [];
|
||||
|
||||
var header = Model.Partitions[partitionIndex];
|
||||
if (header == null)
|
||||
var header = Partitions[index];
|
||||
if (header == null || header.MagicID != NCCHMagicNumber)
|
||||
return [];
|
||||
|
||||
byte[] partitionIdBytes = BitConverter.GetBytes(header.PartitionId);
|
||||
Array.Reverse(partitionIdBytes);
|
||||
return [.. partitionIdBytes, .. ExefsCounter];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the initial value for the RomFS counter
|
||||
/// </summary>
|
||||
public byte[] RomFSIV(int partitionIndex)
|
||||
public byte[] RomFSIV(int index)
|
||||
{
|
||||
if (Model.Partitions == null)
|
||||
if (Partitions == null)
|
||||
return [];
|
||||
if (partitionIndex < 0 || partitionIndex >= Model.Partitions.Length)
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return [];
|
||||
|
||||
var header = Model.Partitions[partitionIndex];
|
||||
if (header == null)
|
||||
var header = Partitions[index];
|
||||
if (header == null || header.MagicID != NCCHMagicNumber)
|
||||
return [];
|
||||
|
||||
byte[] partitionIdBytes = BitConverter.GetBytes(header.PartitionId);
|
||||
Array.Reverse(partitionIdBytes);
|
||||
return [.. partitionIdBytes, .. RomfsCounter];
|
||||
}
|
||||
|
||||
@@ -348,20 +392,11 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// </summary>
|
||||
public bool PossiblyDecrypted(int index)
|
||||
{
|
||||
if (Model.Partitions == null)
|
||||
return false;
|
||||
|
||||
if (index < 0 || index >= Model.Partitions.Length)
|
||||
return false;
|
||||
|
||||
var partition = Model.Partitions[index];
|
||||
if (partition?.Flags == null)
|
||||
return false;
|
||||
|
||||
var bitMasks = GetBitMasks(index);
|
||||
#if NET20 || NET35
|
||||
return (partition.Flags.BitMasks & BitMasks.NoCrypto) != 0;
|
||||
return (bitMasks & BitMasks.NoCrypto) != 0;
|
||||
#else
|
||||
return partition.Flags.BitMasks.HasFlag(BitMasks.NoCrypto);
|
||||
return bitMasks.HasFlag(BitMasks.NoCrypto);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -375,24 +410,20 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <returns>Offset to the ExeFS of the partition, 0 on error</returns>
|
||||
public uint GetExeFSOffset(int index)
|
||||
{
|
||||
// Empty partitions table means no size is available
|
||||
var partitionsTable = Model.Header?.PartitionsTable;
|
||||
if (partitionsTable == null)
|
||||
// No partitions means no size is available
|
||||
if (PartitionsTable == null || Partitions == null)
|
||||
return 0;
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return 0;
|
||||
|
||||
// Invalid partition table entry means no size is available
|
||||
var entry = partitionsTable[index];
|
||||
var entry = PartitionsTable[index];
|
||||
if (entry == null)
|
||||
return 0;
|
||||
|
||||
// Empty partitions array means no size is available
|
||||
var partitions = Model.Partitions;
|
||||
if (partitions == null)
|
||||
return 0;
|
||||
|
||||
// Invalid partition means no size is available
|
||||
var header = partitions[index];
|
||||
if (header == null)
|
||||
var header = Partitions[index];
|
||||
if (header == null || header.MagicID != NCCHMagicNumber)
|
||||
return 0;
|
||||
|
||||
// If the offset is 0, return 0
|
||||
@@ -411,13 +442,14 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <returns>Offset to the partition, 0 on error</returns>
|
||||
public uint GetPartitionOffset(int index)
|
||||
{
|
||||
// Empty partitions table means no size is available
|
||||
var partitionsTable = Model.Header?.PartitionsTable;
|
||||
if (partitionsTable == null)
|
||||
// No partitions means no size is available
|
||||
if (PartitionsTable == null)
|
||||
return 0;
|
||||
if (index < 0 || index >= PartitionsTable.Length)
|
||||
return 0;
|
||||
|
||||
// Invalid partition table entry means no size is available
|
||||
var entry = partitionsTable[index];
|
||||
var entry = PartitionsTable[index];
|
||||
if (entry == null)
|
||||
return 0;
|
||||
|
||||
@@ -436,24 +468,20 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <returns>Offset to the RomFS of the partition, 0 on error</returns>
|
||||
public uint GetRomFSOffset(int index)
|
||||
{
|
||||
// Empty partitions table means no size is available
|
||||
var partitionsTable = Model.Header?.PartitionsTable;
|
||||
if (partitionsTable == null)
|
||||
// No partitions means no size is available
|
||||
if (PartitionsTable == null || Partitions == null)
|
||||
return 0;
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return 0;
|
||||
|
||||
// Invalid partition table entry means no size is available
|
||||
var entry = partitionsTable[index];
|
||||
var entry = PartitionsTable[index];
|
||||
if (entry == null)
|
||||
return 0;
|
||||
|
||||
// Empty partitions array means no size is available
|
||||
var partitions = Model.Partitions;
|
||||
if (partitions == null)
|
||||
return 0;
|
||||
|
||||
// Invalid partition means no size is available
|
||||
var header = partitions[index];
|
||||
if (header == null)
|
||||
var header = Partitions[index];
|
||||
if (header == null || header.MagicID != NCCHMagicNumber)
|
||||
return 0;
|
||||
|
||||
// If the offset is 0, return 0
|
||||
@@ -477,12 +505,13 @@ namespace SabreTools.Serialization.Wrappers
|
||||
public uint GetExeFSSize(int index)
|
||||
{
|
||||
// Empty partitions array means no size is available
|
||||
var partitions = Model.Partitions;
|
||||
if (partitions == null)
|
||||
if (Partitions == null)
|
||||
return 0;
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return 0;
|
||||
|
||||
// Invalid partition header means no size is available
|
||||
var header = partitions[index];
|
||||
var header = Partitions[index];
|
||||
if (header == null)
|
||||
return 0;
|
||||
|
||||
@@ -497,12 +526,13 @@ namespace SabreTools.Serialization.Wrappers
|
||||
public uint GetExtendedHeaderSize(int index)
|
||||
{
|
||||
// Empty partitions array means no size is available
|
||||
var partitions = Model.Partitions;
|
||||
if (partitions == null)
|
||||
if (Partitions == null)
|
||||
return 0;
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return 0;
|
||||
|
||||
// Invalid partition header means no size is available
|
||||
var header = partitions[index];
|
||||
var header = Partitions[index];
|
||||
if (header == null)
|
||||
return 0;
|
||||
|
||||
@@ -517,12 +547,13 @@ namespace SabreTools.Serialization.Wrappers
|
||||
public uint GetRomFSSize(int index)
|
||||
{
|
||||
// Empty partitions array means no size is available
|
||||
var partitions = Model.Partitions;
|
||||
if (partitions == null)
|
||||
if (Partitions == null)
|
||||
return 0;
|
||||
if (index < 0 || index >= Partitions.Length)
|
||||
return 0;
|
||||
|
||||
// Invalid partition header means no size is available
|
||||
var header = partitions[index];
|
||||
var header = Partitions[index];
|
||||
if (header == null)
|
||||
return 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user