Npdm.cs
1 using Ryujinx.HLE.Exceptions; 2 using System.IO; 3 using System.Text; 4 5 namespace Ryujinx.HLE.Loaders.Npdm 6 { 7 // https://github.com/SciresM/hactool/blob/master/npdm.c 8 // https://github.com/SciresM/hactool/blob/master/npdm.h 9 // http://switchbrew.org/index.php?title=NPDM 10 public class Npdm 11 { 12 private const int MetaMagic = 'M' << 0 | 'E' << 8 | 'T' << 16 | 'A' << 24; 13 14 public byte ProcessFlags { get; private set; } 15 public bool Is64Bit { get; private set; } 16 public byte MainThreadPriority { get; private set; } 17 public byte DefaultCpuId { get; private set; } 18 public int PersonalMmHeapSize { get; private set; } 19 public int Version { get; private set; } 20 public int MainThreadStackSize { get; private set; } 21 public string TitleName { get; set; } 22 public byte[] ProductCode { get; private set; } 23 24 public Aci0 Aci0 { get; private set; } 25 public Acid Acid { get; private set; } 26 27 /// <exception cref="InvalidNpdmException">The stream doesn't contain valid NPDM data.</exception> 28 /// <exception cref="System.NotImplementedException">The FsAccessHeader.ContentOwnerId section is not implemented.</exception> 29 /// <exception cref="System.ArgumentException">The stream does not support reading, is <see langword="null"/>, or is already closed.</exception> 30 /// <exception cref="System.ArgumentException">An error occured while reading bytes from the stream.</exception> 31 /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception> 32 /// <exception cref="System.ObjectDisposedException">The stream is closed.</exception> 33 /// <exception cref="IOException">An I/O error occurred.</exception> 34 public Npdm(Stream stream) 35 { 36 BinaryReader reader = new(stream); 37 38 if (reader.ReadInt32() != MetaMagic) 39 { 40 throw new InvalidNpdmException("NPDM Stream doesn't contain NPDM file!"); 41 } 42 43 reader.ReadInt64(); 44 45 ProcessFlags = reader.ReadByte(); 46 47 Is64Bit = (ProcessFlags & 1) != 0; 48 49 reader.ReadByte(); 50 51 MainThreadPriority = reader.ReadByte(); 52 DefaultCpuId = reader.ReadByte(); 53 54 reader.ReadInt32(); 55 56 PersonalMmHeapSize = reader.ReadInt32(); 57 58 Version = reader.ReadInt32(); 59 60 MainThreadStackSize = reader.ReadInt32(); 61 62 byte[] tempTitleName = reader.ReadBytes(0x10); 63 64 TitleName = Encoding.UTF8.GetString(tempTitleName, 0, tempTitleName.Length).Trim('\0'); 65 66 ProductCode = reader.ReadBytes(0x10); 67 68 stream.Seek(0x30, SeekOrigin.Current); 69 70 int aci0Offset = reader.ReadInt32(); 71 #pragma warning disable IDE0059 // Remove unnecessary value assignment 72 int aci0Size = reader.ReadInt32(); 73 int acidOffset = reader.ReadInt32(); 74 int acidSize = reader.ReadInt32(); 75 #pragma warning restore IDE0059 76 77 Aci0 = new Aci0(stream, aci0Offset); 78 Acid = new Acid(stream, acidOffset); 79 } 80 } 81 }