/ src / Ryujinx.HLE / Loaders / Npdm / Npdm.cs
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  }