From 290f5e812e68e47d95aba0cc3789a4bc6d04c7ce Mon Sep 17 00:00:00 2001
From: Alex Barney <thealexbarney@gmail.com>
Date: Fri, 4 Jan 2019 17:41:49 -0700
Subject: [PATCH] Update to LibHac 0.2.0 (#549)

* Update to LibHac 0.2.0

* Changes based on feedback
---
 .../FileSystem/Content/ContentManager.cs      | 26 +++-----
 Ryujinx.HLE/FileSystem/PFsProvider.cs         |  3 +-
 Ryujinx.HLE/FileSystem/RomFsProvider.cs       |  7 +-
 Ryujinx.HLE/HOS/Font/SharedFontManager.cs     | 22 ++++---
 Ryujinx.HLE/HOS/Horizon.cs                    | 61 +++++++++--------
 .../HOS/Services/FspSrv/IFileSystemProxy.cs   | 65 ++++++++++---------
 .../HOS/Services/Set/ISystemSettingsServer.cs | 42 ++++++------
 Ryujinx.HLE/Ryujinx.HLE.csproj                |  2 +-
 Ryujinx/Config.cs                             |  2 +-
 9 files changed, 110 insertions(+), 120 deletions(-)

diff --git a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs
index a20157ce4c..94f06475c5 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 7175766936..fdddc9b089 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 f6a2f82f40..86bf234859 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 31c8178ac1..9eb2c7e5fe 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 5c2ca9b3af..94b2e6c6d0 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 9df7880c08..878f2e4ef4 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 b4464b7794..8eec31cfe3 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 6285825a5c..fd4048635c 100644
--- a/Ryujinx.HLE/Ryujinx.HLE.csproj
+++ b/Ryujinx.HLE/Ryujinx.HLE.csproj
@@ -28,11 +28,11 @@
     <ProjectReference Include="..\Ryujinx.Audio\Ryujinx.Audio.csproj" />
     <ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
     <ProjectReference Include="..\Ryujinx.Graphics\Ryujinx.Graphics.csproj" />
-    <PackageReference Include="LibHac" Version="0.1.3" />
   </ItemGroup>
 
   <ItemGroup>
     <PackageReference Include="Concentus" Version="1.1.7" />
+    <PackageReference Include="LibHac" Version="0.2.0" />
   </ItemGroup>
 
 </Project>
diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs
index e7b346eaf6..d1139da924 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;