diff --git a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs index a20157ce..94f06475 100644 --- a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs +++ b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs @@ -1,4 +1,5 @@ using LibHac; +using LibHac.IO; using Ryujinx.HLE.Utilities; using System; using System.Collections.Generic; @@ -73,7 +74,7 @@ namespace Ryujinx.HLE.FileSystem.Content using (FileStream ncaFile = new FileStream(Directory.GetFiles(directoryPath)[0], FileMode.Open, FileAccess.Read)) { - Nca nca = new Nca(_device.System.KeySet, ncaFile, false); + Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage(), false); string switchPath = Path.Combine(contentPathString + ":", ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart('\\')); @@ -89,10 +90,6 @@ namespace Ryujinx.HLE.FileSystem.Content AddEntry(entry); _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); - - ncaFile.Close(); - nca.Dispose(); - ncaFile.Dispose(); } } } @@ -105,7 +102,7 @@ namespace Ryujinx.HLE.FileSystem.Content using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { - Nca nca = new Nca(_device.System.KeySet, ncaFile, false); + Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage(), false); string switchPath = Path.Combine(contentPathString + ":", filePath.Replace(contentDirectory, string.Empty).TrimStart('\\')); @@ -121,10 +118,6 @@ namespace Ryujinx.HLE.FileSystem.Content AddEntry(entry); _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); - - ncaFile.Close(); - nca.Dispose(); - ncaFile.Dispose(); } } } @@ -235,14 +228,13 @@ namespace Ryujinx.HLE.FileSystem.Content { if (File.Exists(installedPath)) { - FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read); - Nca nca = new Nca(_device.System.KeySet, file, false); - bool contentCheck = nca.Header.ContentType == contentType; + using (FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read)) + { + Nca nca = new Nca(_device.System.KeySet, file.AsStorage(), false); + bool contentCheck = nca.Header.ContentType == contentType; - nca.Dispose(); - file.Dispose(); - - return contentCheck; + return contentCheck; + } } } diff --git a/Ryujinx.HLE/FileSystem/PFsProvider.cs b/Ryujinx.HLE/FileSystem/PFsProvider.cs index 71757669..fdddc9b0 100644 --- a/Ryujinx.HLE/FileSystem/PFsProvider.cs +++ b/Ryujinx.HLE/FileSystem/PFsProvider.cs @@ -1,4 +1,5 @@ using LibHac; +using LibHac.IO; using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS.Services.FspSrv; using System; @@ -117,7 +118,7 @@ namespace Ryujinx.HLE.FileSystem if (_pfs.FileExists(name)) { - Stream stream = _pfs.OpenFile(name); + Stream stream = _pfs.OpenFile(name).AsStream(); fileInterface = new IFile(stream, name); return 0; diff --git a/Ryujinx.HLE/FileSystem/RomFsProvider.cs b/Ryujinx.HLE/FileSystem/RomFsProvider.cs index f6a2f82f..86bf2348 100644 --- a/Ryujinx.HLE/FileSystem/RomFsProvider.cs +++ b/Ryujinx.HLE/FileSystem/RomFsProvider.cs @@ -1,4 +1,5 @@ using LibHac; +using LibHac.IO; using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS.Services.FspSrv; using System; @@ -14,9 +15,9 @@ namespace Ryujinx.HLE.FileSystem { private Romfs _romFs; - public RomFsProvider(Stream storageStream) + public RomFsProvider(LibHac.IO.IStorage storage) { - _romFs = new Romfs(storageStream); + _romFs = new Romfs(storage); } public long CreateDirectory(string name) @@ -133,7 +134,7 @@ namespace Ryujinx.HLE.FileSystem { if (_romFs.FileExists(name)) { - Stream stream = _romFs.OpenFile(name); + Stream stream = _romFs.OpenFile(name).AsStream(); fileInterface = new IFile(stream, name); diff --git a/Ryujinx.HLE/HOS/Font/SharedFontManager.cs b/Ryujinx.HLE/HOS/Font/SharedFontManager.cs index 31c8178a..9eb2c7e5 100644 --- a/Ryujinx.HLE/HOS/Font/SharedFontManager.cs +++ b/Ryujinx.HLE/HOS/Font/SharedFontManager.cs @@ -1,4 +1,5 @@ using LibHac; +using LibHac.IO; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem.Content; using Ryujinx.HLE.Resource; @@ -67,14 +68,18 @@ namespace Ryujinx.HLE.HOS.Font fileIndex = 1; } - FileStream ncaFileStream = new FileStream(fontPath, FileMode.Open, FileAccess.Read); - Nca nca = new Nca(_device.System.KeySet, ncaFileStream, false); - NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); - Romfs romfs = new Romfs(nca.OpenSection(romfsSection.SectionNum, false, _device.System.FsIntegrityCheckLevel)); - Stream fontFile = romfs.OpenFile(romfs.Files[fileIndex]); - - byte[] data = DecryptFont(fontFile); + byte[] data; + + using (FileStream ncaFileStream = new FileStream(fontPath, FileMode.Open, FileAccess.Read)) + { + Nca nca = new Nca(_device.System.KeySet, ncaFileStream.AsStorage(), false); + NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); + Romfs romfs = new Romfs(nca.OpenSection(romfsSection.SectionNum, false, _device.System.FsIntegrityCheckLevel, false)); + Stream fontFile = romfs.OpenFile(romfs.Files[fileIndex]).AsStream(); + data = DecryptFont(fontFile); + } + FontInfo info = new FontInfo((int)fontOffset, data.Length); WriteMagicAndSize(_physicalAddress + fontOffset, data.Length); @@ -88,9 +93,6 @@ namespace Ryujinx.HLE.HOS.Font _device.Memory.WriteByte(_physicalAddress + fontOffset, data[fontOffset - start]); } - ncaFileStream.Dispose(); - nca.Dispose(); - return info; } } diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index 5c2ca9b3..94b2e6c6 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -1,4 +1,5 @@ using LibHac; +using LibHac.IO; using Ryujinx.Common.Logging; using Ryujinx.HLE.FileSystem.Content; using Ryujinx.HLE.HOS.Font; @@ -242,7 +243,7 @@ namespace Ryujinx.HLE.HOS { FileStream file = new FileStream(xciFile, FileMode.Open, FileAccess.Read); - Xci xci = new Xci(KeySet, file); + Xci xci = new Xci(KeySet, file.AsStorage()); (Nca mainNca, Nca controlNca) = GetXciGameData(xci); @@ -271,7 +272,7 @@ namespace Ryujinx.HLE.HOS foreach (PfsFileEntry ticketEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".tik"))) { - Ticket ticket = new Ticket(xci.SecurePartition.OpenFile(ticketEntry)); + Ticket ticket = new Ticket(xci.SecurePartition.OpenFile(ticketEntry).AsStream()); if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId)) { @@ -281,9 +282,9 @@ namespace Ryujinx.HLE.HOS foreach (PfsFileEntry fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca"))) { - Stream ncaStream = xci.SecurePartition.OpenFile(fileEntry); + IStorage ncaStorage = xci.SecurePartition.OpenFile(fileEntry); - Nca nca = new Nca(KeySet, ncaStream, true); + Nca nca = new Nca(KeySet, ncaStorage, true); if (nca.Header.ContentType == ContentType.Program) { @@ -326,20 +327,18 @@ namespace Ryujinx.HLE.HOS public void ReadControlData(Nca controlNca) { - Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel)); + Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel, true)); - byte[] controlFile = controlRomfs.GetFile("/control.nacp"); + IStorage controlFile = controlRomfs.OpenFile("/control.nacp"); - BinaryReader reader = new BinaryReader(new MemoryStream(controlFile)); - - ControlData = new Nacp(reader); + ControlData = new Nacp(controlFile.AsStream()); } public void LoadNca(string ncaFile) { FileStream file = new FileStream(ncaFile, FileMode.Open, FileAccess.Read); - Nca nca = new Nca(KeySet, file, true); + Nca nca = new Nca(KeySet, file.AsStorage(false), false); LoadNca(nca, null); } @@ -348,16 +347,16 @@ namespace Ryujinx.HLE.HOS { FileStream file = new FileStream(nspFile, FileMode.Open, FileAccess.Read); - Pfs nsp = new Pfs(file); + Pfs nsp = new Pfs(file.AsStorage(false)); - PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik")); - - // Load title key from the NSP's ticket in case the user doesn't have a title key file - if (ticketFile != null) + foreach (PfsFileEntry ticketEntry in nsp.Files.Where(x => x.Name.EndsWith(".tik"))) { - Ticket ticket = new Ticket(nsp.OpenFile(ticketFile)); + Ticket ticket = new Ticket(nsp.OpenFile(ticketEntry).AsStream()); - KeySet.TitleKeys[ticket.RightsId] = ticket.GetTitleKey(KeySet); + if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId)) + { + KeySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(KeySet)); + } } Nca mainNca = null; @@ -396,26 +395,26 @@ namespace Ryujinx.HLE.HOS return; } - Stream romfsStream = mainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel); - Stream exefsStream = mainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel); + IStorage romfsStorage = mainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel, false); + IStorage exefsStorage = mainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel, true); - if (exefsStream == null) + if (exefsStorage == null) { Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA"); return; } - if (romfsStream == null) + if (romfsStorage == null) { Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA"); } else { - Device.FileSystem.SetRomFs(romfsStream); + Device.FileSystem.SetRomFs(romfsStorage.AsStream(false)); } - Pfs exefs = new Pfs(exefsStream); + Pfs exefs = new Pfs(exefsStorage); Npdm metaData = null; @@ -423,7 +422,7 @@ namespace Ryujinx.HLE.HOS { Logger.PrintInfo(LogClass.Loader, "Loading main.npdm..."); - metaData = new Npdm(exefs.OpenFile("main.npdm")); + metaData = new Npdm(exefs.OpenFile("main.npdm").AsStream()); } else { @@ -445,7 +444,7 @@ namespace Ryujinx.HLE.HOS Logger.PrintInfo(LogClass.Loader, $"Loading {filename}..."); - NxStaticObject staticObject = new NxStaticObject(exefs.OpenFile(file)); + NxStaticObject staticObject = new NxStaticObject(exefs.OpenFile(file).AsStream()); staticObjects.Add(staticObject); } @@ -453,19 +452,17 @@ namespace Ryujinx.HLE.HOS Nacp ReadControlData() { - Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel)); + Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel, true)); - byte[] controlFile = controlRomfs.GetFile("/control.nacp"); + IStorage controlFile = controlRomfs.OpenFile("/control.nacp"); - BinaryReader reader = new BinaryReader(new MemoryStream(controlFile)); + Nacp controlData = new Nacp(controlFile.AsStream()); - Nacp controlData = new Nacp(reader); - - CurrentTitle = controlData.Languages[(int)State.DesiredTitleLanguage].Title; + CurrentTitle = controlData.Descriptions[(int)State.DesiredTitleLanguage].Title; if (string.IsNullOrWhiteSpace(CurrentTitle)) { - CurrentTitle = controlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; + CurrentTitle = controlData.Descriptions.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; } return controlData; diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs index 9df7880c..878f2e4e 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs @@ -1,4 +1,5 @@ using LibHac; +using LibHac.IO; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.Utilities; @@ -65,7 +66,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv if (extension == ".nca") { - return OpenNcaFs(context, fullPath, fileStream); + return OpenNcaFs(context, fullPath, fileStream.AsStorage()); } else if (extension == ".nsp") { @@ -174,10 +175,10 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv if (File.Exists(ncaPath)) { - FileStream ncaStream = new FileStream(ncaPath, FileMode.Open, FileAccess.Read); - Nca nca = new Nca(context.Device.System.KeySet, ncaStream, false); - NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); - Stream romfsStream = nca.OpenSection(romfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel); + LibHac.IO.IStorage ncaStorage = new FileStream(ncaPath, FileMode.Open, FileAccess.Read).AsStorage(); + Nca nca = new Nca(context.Device.System.KeySet, ncaStorage, false); + NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); + Stream romfsStream = nca.OpenSection(romfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel, false).AsStream(); MakeObject(context, new IStorage(romfsStream)); @@ -234,17 +235,11 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv private long OpenNsp(ServiceCtx context, string pfsPath) { - FileStream pfsFile = new FileStream(pfsPath, FileMode.Open, FileAccess.Read); - Pfs nsp = new Pfs(pfsFile); - PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik")); + FileStream pfsFile = new FileStream(pfsPath, FileMode.Open, FileAccess.Read); + Pfs nsp = new Pfs(pfsFile.AsStorage()); - if (ticketFile != null) - { - Ticket ticket = new Ticket(nsp.OpenFile(ticketFile)); + ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet); - context.Device.System.KeySet.TitleKeys[ticket.RightsId] = - ticket.GetTitleKey(context.Device.System.KeySet); - } IFileSystem nspFileSystem = new IFileSystem(pfsPath, new PFsProvider(nsp)); @@ -253,25 +248,25 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return 0; } - private long OpenNcaFs(ServiceCtx context,string ncaPath, Stream ncaStream) + private long OpenNcaFs(ServiceCtx context, string ncaPath, LibHac.IO.IStorage ncaStorage) { - Nca nca = new Nca(context.Device.System.KeySet, ncaStream, false); + Nca nca = new Nca(context.Device.System.KeySet, ncaStorage, false); NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); NcaSection pfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Pfs0); if (romfsSection != null) { - Stream romfsStream = nca.OpenSection(romfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel); - IFileSystem ncaFileSystem = new IFileSystem(ncaPath, new RomFsProvider(romfsStream)); + LibHac.IO.IStorage romfsStorage = nca.OpenSection(romfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel, false); + IFileSystem ncaFileSystem = new IFileSystem(ncaPath, new RomFsProvider(romfsStorage)); MakeObject(context, ncaFileSystem); } - else if(pfsSection !=null) + else if(pfsSection != null) { - Stream pfsStream = nca.OpenSection(pfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel); - Pfs pfs = new Pfs(pfsStream); - IFileSystem ncaFileSystem = new IFileSystem(ncaPath, new PFsProvider(pfs)); + LibHac.IO.IStorage pfsStorage = nca.OpenSection(pfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel, false); + Pfs pfs = new Pfs(pfsStorage); + IFileSystem ncaFileSystem = new IFileSystem(ncaPath, new PFsProvider(pfs)); MakeObject(context, ncaFileSystem); } @@ -299,17 +294,10 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv FileMode.Open, FileAccess.Read); - Pfs nsp = new Pfs(pfsFile); - PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik")); - - if (ticketFile != null) - { - Ticket ticket = new Ticket(nsp.OpenFile(ticketFile)); - - context.Device.System.KeySet.TitleKeys[ticket.RightsId] = - ticket.GetTitleKey(context.Device.System.KeySet); - } + Pfs nsp = new Pfs(pfsFile.AsStorage()); + ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet); + string filename = fullPath.Replace(archivePath.FullName, string.Empty).TrimStart('\\'); if (nsp.FileExists(filename)) @@ -320,5 +308,18 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } + + private void ImportTitleKeysFromNsp(Pfs nsp, Keyset keySet) + { + foreach (PfsFileEntry ticketEntry in nsp.Files.Where(x => x.Name.EndsWith(".tik"))) + { + Ticket ticket = new Ticket(nsp.OpenFile(ticketEntry).AsStream()); + + if (!keySet.TitleKeys.ContainsKey(ticket.RightsId)) + { + keySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(keySet)); + } + } + } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Set/ISystemSettingsServer.cs b/Ryujinx.HLE/HOS/Services/Set/ISystemSettingsServer.cs index b4464b77..8eec31cf 100644 --- a/Ryujinx.HLE/HOS/Services/Set/ISystemSettingsServer.cs +++ b/Ryujinx.HLE/HOS/Services/Set/ISystemSettingsServer.cs @@ -1,12 +1,13 @@ +using LibHac; +using LibHac.IO; using Ryujinx.Common.Logging; +using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.SystemState; using System; using System.Collections.Generic; using System.IO; using System.Text; -using LibHac; -using Ryujinx.HLE.FileSystem; namespace Ryujinx.HLE.HOS.Services.Set { @@ -173,7 +174,6 @@ namespace Ryujinx.HLE.HOS.Services.Set public static byte[] GetFirmwareData(Switch device) { - byte[] data = null; long titleId = 0x0100000000000809; string contentPath = device.System.ContentManager.GetInstalledContentPath(titleId, StorageId.NandSystem, ContentType.Data); @@ -182,32 +182,28 @@ namespace Ryujinx.HLE.HOS.Services.Set return null; } - string firmwareTitlePath = device.FileSystem.SwitchPathToSystemPath(contentPath); - FileStream firmwareStream = File.Open(firmwareTitlePath, FileMode.Open, FileAccess.Read); - Nca firmwareContent = new Nca(device.System.KeySet, firmwareStream, false); - Stream romFsStream = firmwareContent.OpenSection(0, false, device.System.FsIntegrityCheckLevel); + string firmwareTitlePath = device.FileSystem.SwitchPathToSystemPath(contentPath); - if(romFsStream == null) - { - return null; - } + using(FileStream firmwareStream = File.Open(firmwareTitlePath, FileMode.Open, FileAccess.Read)) + { + Nca firmwareContent = new Nca(device.System.KeySet, firmwareStream.AsStorage(), false); + IStorage romFsStorage = firmwareContent.OpenSection(0, false, device.System.FsIntegrityCheckLevel, false); - Romfs firmwareRomFs = new Romfs(romFsStream); - - using(MemoryStream memoryStream = new MemoryStream()) - { - using (Stream firmwareFile = firmwareRomFs.OpenFile("/file")) + if(romFsStorage == null) { - firmwareFile.CopyTo(memoryStream); + return null; } - data = memoryStream.ToArray(); + Romfs firmwareRomFs = new Romfs(romFsStorage); + + IStorage firmwareFile = firmwareRomFs.OpenFile("/file"); + + byte[] data = new byte[firmwareFile.Length]; + + firmwareFile.Read(data, 0); + + return data; } - - firmwareContent.Dispose(); - firmwareStream.Dispose(); - - return data; } } } diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj index 6285825a..fd404863 100644 --- a/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -28,11 +28,11 @@ - + diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs index e7b346ea..d1139da9 100644 --- a/Ryujinx/Config.cs +++ b/Ryujinx/Config.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac.IO; using Ryujinx.Common.Logging; using Ryujinx.HLE; using Ryujinx.HLE.HOS.SystemState;