This reverts commit 85dbb9559a
.
This commit is contained in:
parent
85dbb9559a
commit
3615a70cae
299 changed files with 12276 additions and 12268 deletions
|
@ -9,297 +9,297 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{
|
||||
internal class ContentManager
|
||||
{
|
||||
private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries;
|
||||
private Dictionary<StorageId, LinkedList<LocationEntry>> LocationEntries;
|
||||
|
||||
private Dictionary<string, long> _sharedFontTitleDictionary;
|
||||
private Dictionary<string, long> SharedFontTitleDictionary;
|
||||
|
||||
private SortedDictionary<(ulong, ContentType), string> _contentDictionary;
|
||||
private SortedDictionary<(ulong, ContentType), string> ContentDictionary;
|
||||
|
||||
private Switch _device;
|
||||
private Switch Device;
|
||||
|
||||
public ContentManager(Switch device)
|
||||
public ContentManager(Switch Device)
|
||||
{
|
||||
_contentDictionary = new SortedDictionary<(ulong, ContentType), string>();
|
||||
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
|
||||
ContentDictionary = new SortedDictionary<(ulong, ContentType), string>();
|
||||
LocationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
|
||||
|
||||
_sharedFontTitleDictionary = new Dictionary<string, long>
|
||||
SharedFontTitleDictionary = new Dictionary<string, long>()
|
||||
{
|
||||
{ "FontStandard", 0x0100000000000811 },
|
||||
{ "FontChineseSimplified", 0x0100000000000814 },
|
||||
{ "FontExtendedChineseSimplified", 0x0100000000000814 },
|
||||
{ "FontKorean", 0x0100000000000812 },
|
||||
{ "FontChineseTraditional", 0x0100000000000813 },
|
||||
{ "FontNintendoExtended", 0x0100000000000810 }
|
||||
{ "FontNintendoExtended" , 0x0100000000000810 },
|
||||
};
|
||||
|
||||
_device = device;
|
||||
this.Device = Device;
|
||||
}
|
||||
|
||||
public void LoadEntries()
|
||||
{
|
||||
_contentDictionary = new SortedDictionary<(ulong, ContentType), string>();
|
||||
ContentDictionary = new SortedDictionary<(ulong, ContentType), string>();
|
||||
|
||||
foreach (StorageId storageId in Enum.GetValues(typeof(StorageId)))
|
||||
foreach (StorageId StorageId in Enum.GetValues(typeof(StorageId)))
|
||||
{
|
||||
string contentDirectory = null;
|
||||
string contentPathString = null;
|
||||
string registeredDirectory = null;
|
||||
string ContentDirectory = null;
|
||||
string ContentPathString = null;
|
||||
string RegisteredDirectory = null;
|
||||
|
||||
try
|
||||
{
|
||||
contentPathString = LocationHelper.GetContentRoot(storageId);
|
||||
contentDirectory = LocationHelper.GetRealPath(_device.FileSystem, contentPathString);
|
||||
registeredDirectory = Path.Combine(contentDirectory, "registered");
|
||||
ContentPathString = LocationHelper.GetContentRoot(StorageId);
|
||||
ContentDirectory = LocationHelper.GetRealPath(Device.FileSystem, ContentPathString);
|
||||
RegisteredDirectory = Path.Combine(ContentDirectory, "registered");
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
catch (NotSupportedException NEx)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(registeredDirectory);
|
||||
Directory.CreateDirectory(RegisteredDirectory);
|
||||
|
||||
LinkedList<LocationEntry> locationList = new LinkedList<LocationEntry>();
|
||||
LinkedList<LocationEntry> LocationList = new LinkedList<LocationEntry>();
|
||||
|
||||
void AddEntry(LocationEntry entry)
|
||||
void AddEntry(LocationEntry Entry)
|
||||
{
|
||||
locationList.AddLast(entry);
|
||||
LocationList.AddLast(Entry);
|
||||
}
|
||||
|
||||
foreach (string directoryPath in Directory.EnumerateDirectories(registeredDirectory))
|
||||
foreach (string DirectoryPath in Directory.EnumerateDirectories(RegisteredDirectory))
|
||||
{
|
||||
if (Directory.GetFiles(directoryPath).Length > 0)
|
||||
if (Directory.GetFiles(DirectoryPath).Length > 0)
|
||||
{
|
||||
string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty);
|
||||
string NcaName = new DirectoryInfo(DirectoryPath).Name.Replace(".nca", string.Empty);
|
||||
|
||||
using (FileStream ncaFile = new FileStream(Directory.GetFiles(directoryPath)[0], FileMode.Open, FileAccess.Read))
|
||||
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, false);
|
||||
|
||||
string switchPath = Path.Combine(contentPathString + ":",
|
||||
ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart('\\'));
|
||||
string SwitchPath = Path.Combine(ContentPathString + ":",
|
||||
NcaFile.Name.Replace(ContentDirectory, string.Empty).TrimStart('\\'));
|
||||
|
||||
// Change path format to switch's
|
||||
switchPath = switchPath.Replace('\\', '/');
|
||||
SwitchPath = SwitchPath.Replace('\\', '/');
|
||||
|
||||
LocationEntry entry = new LocationEntry(switchPath,
|
||||
LocationEntry Entry = new LocationEntry(SwitchPath,
|
||||
0,
|
||||
(long)nca.Header.TitleId,
|
||||
nca.Header.ContentType);
|
||||
(long)Nca.Header.TitleId,
|
||||
Nca.Header.ContentType);
|
||||
|
||||
AddEntry(entry);
|
||||
AddEntry(Entry);
|
||||
|
||||
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
|
||||
ContentDictionary.Add((Nca.Header.TitleId, Nca.Header.ContentType), NcaName);
|
||||
|
||||
ncaFile.Close();
|
||||
nca.Dispose();
|
||||
ncaFile.Dispose();
|
||||
NcaFile.Close();
|
||||
Nca.Dispose();
|
||||
NcaFile.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string filePath in Directory.EnumerateFiles(contentDirectory))
|
||||
foreach (string FilePath in Directory.EnumerateFiles(ContentDirectory))
|
||||
{
|
||||
if (Path.GetExtension(filePath) == ".nca")
|
||||
if (Path.GetExtension(FilePath) == ".nca")
|
||||
{
|
||||
string ncaName = Path.GetFileNameWithoutExtension(filePath);
|
||||
string NcaName = Path.GetFileNameWithoutExtension(FilePath);
|
||||
|
||||
using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
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, false);
|
||||
|
||||
string switchPath = Path.Combine(contentPathString + ":",
|
||||
filePath.Replace(contentDirectory, string.Empty).TrimStart('\\'));
|
||||
string SwitchPath = Path.Combine(ContentPathString + ":",
|
||||
FilePath.Replace(ContentDirectory, string.Empty).TrimStart('\\'));
|
||||
|
||||
// Change path format to switch's
|
||||
switchPath = switchPath.Replace('\\', '/');
|
||||
SwitchPath = SwitchPath.Replace('\\', '/');
|
||||
|
||||
LocationEntry entry = new LocationEntry(switchPath,
|
||||
LocationEntry Entry = new LocationEntry(SwitchPath,
|
||||
0,
|
||||
(long)nca.Header.TitleId,
|
||||
nca.Header.ContentType);
|
||||
(long)Nca.Header.TitleId,
|
||||
Nca.Header.ContentType);
|
||||
|
||||
AddEntry(entry);
|
||||
AddEntry(Entry);
|
||||
|
||||
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
|
||||
ContentDictionary.Add((Nca.Header.TitleId, Nca.Header.ContentType), NcaName);
|
||||
|
||||
ncaFile.Close();
|
||||
nca.Dispose();
|
||||
ncaFile.Dispose();
|
||||
NcaFile.Close();
|
||||
Nca.Dispose();
|
||||
NcaFile.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(_locationEntries.ContainsKey(storageId) && _locationEntries[storageId]?.Count == 0)
|
||||
if(LocationEntries.ContainsKey(StorageId) && LocationEntries[StorageId]?.Count == 0)
|
||||
{
|
||||
_locationEntries.Remove(storageId);
|
||||
LocationEntries.Remove(StorageId);
|
||||
}
|
||||
|
||||
if (!_locationEntries.ContainsKey(storageId))
|
||||
if (!LocationEntries.ContainsKey(StorageId))
|
||||
{
|
||||
_locationEntries.Add(storageId, locationList);
|
||||
LocationEntries.Add(StorageId, LocationList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearEntry(long titleId, ContentType contentType,StorageId storageId)
|
||||
public void ClearEntry(long TitleId, ContentType ContentType,StorageId StorageId)
|
||||
{
|
||||
RemoveLocationEntry(titleId, contentType, storageId);
|
||||
RemoveLocationEntry(TitleId, ContentType, StorageId);
|
||||
}
|
||||
|
||||
public void RefreshEntries(StorageId storageId, int flag)
|
||||
public void RefreshEntries(StorageId StorageId, int Flag)
|
||||
{
|
||||
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
|
||||
LinkedListNode<LocationEntry> locationEntry = locationList.First;
|
||||
LinkedList<LocationEntry> LocationList = LocationEntries[StorageId];
|
||||
LinkedListNode<LocationEntry> LocationEntry = LocationList.First;
|
||||
|
||||
while (locationEntry != null)
|
||||
while (LocationEntry != null)
|
||||
{
|
||||
LinkedListNode<LocationEntry> nextLocationEntry = locationEntry.Next;
|
||||
LinkedListNode<LocationEntry> NextLocationEntry = LocationEntry.Next;
|
||||
|
||||
if (locationEntry.Value.Flag == flag)
|
||||
if (LocationEntry.Value.Flag == Flag)
|
||||
{
|
||||
locationList.Remove(locationEntry.Value);
|
||||
LocationList.Remove(LocationEntry.Value);
|
||||
}
|
||||
|
||||
locationEntry = nextLocationEntry;
|
||||
LocationEntry = NextLocationEntry;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasNca(string ncaId, StorageId storageId)
|
||||
public bool HasNca(string NcaId, StorageId StorageId)
|
||||
{
|
||||
if (_contentDictionary.ContainsValue(ncaId))
|
||||
if (ContentDictionary.ContainsValue(NcaId))
|
||||
{
|
||||
var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId);
|
||||
long titleId = (long)content.Key.Item1;
|
||||
ContentType contentType = content.Key.Item2;
|
||||
StorageId storage = GetInstalledStorage(titleId, contentType, storageId);
|
||||
var Content = ContentDictionary.FirstOrDefault(x => x.Value == NcaId);
|
||||
long TitleId = (long)Content.Key.Item1;
|
||||
ContentType ContentType = Content.Key.Item2;
|
||||
StorageId Storage = GetInstalledStorage(TitleId, ContentType, StorageId);
|
||||
|
||||
return storage == storageId;
|
||||
return Storage == StorageId;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public UInt128 GetInstalledNcaId(long titleId, ContentType contentType)
|
||||
public UInt128 GetInstalledNcaId(long TitleId, ContentType ContentType)
|
||||
{
|
||||
if (_contentDictionary.ContainsKey(((ulong)titleId,contentType)))
|
||||
if (ContentDictionary.ContainsKey(((ulong)TitleId,ContentType)))
|
||||
{
|
||||
return new UInt128(_contentDictionary[((ulong)titleId,contentType)]);
|
||||
return new UInt128(ContentDictionary[((ulong)TitleId,ContentType)]);
|
||||
}
|
||||
|
||||
return new UInt128();
|
||||
}
|
||||
|
||||
public StorageId GetInstalledStorage(long titleId, ContentType contentType, StorageId storageId)
|
||||
public StorageId GetInstalledStorage(long TitleId, ContentType ContentType, StorageId StorageId)
|
||||
{
|
||||
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
|
||||
LocationEntry LocationEntry = GetLocation(TitleId, ContentType, StorageId);
|
||||
|
||||
return locationEntry.ContentPath != null ?
|
||||
LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None;
|
||||
return LocationEntry.ContentPath != null ?
|
||||
LocationHelper.GetStorageId(LocationEntry.ContentPath) : StorageId.None;
|
||||
}
|
||||
|
||||
public string GetInstalledContentPath(long titleId, StorageId storageId, ContentType contentType)
|
||||
public string GetInstalledContentPath(long TitleId, StorageId StorageId, ContentType ContentType)
|
||||
{
|
||||
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
|
||||
LocationEntry LocationEntry = GetLocation(TitleId, ContentType, StorageId);
|
||||
|
||||
if (VerifyContentType(locationEntry, contentType))
|
||||
if (VerifyContentType(LocationEntry, ContentType))
|
||||
{
|
||||
return locationEntry.ContentPath;
|
||||
return LocationEntry.ContentPath;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public void RedirectLocation(LocationEntry newEntry, StorageId storageId)
|
||||
public void RedirectLocation(LocationEntry NewEntry, StorageId StorageId)
|
||||
{
|
||||
LocationEntry locationEntry = GetLocation(newEntry.TitleId, newEntry.ContentType, storageId);
|
||||
LocationEntry LocationEntry = GetLocation(NewEntry.TitleId, NewEntry.ContentType, StorageId);
|
||||
|
||||
if (locationEntry.ContentPath != null)
|
||||
if (LocationEntry.ContentPath != null)
|
||||
{
|
||||
RemoveLocationEntry(newEntry.TitleId, newEntry.ContentType, storageId);
|
||||
RemoveLocationEntry(NewEntry.TitleId, NewEntry.ContentType, StorageId);
|
||||
}
|
||||
|
||||
AddLocationEntry(newEntry, storageId);
|
||||
AddLocationEntry(NewEntry, StorageId);
|
||||
}
|
||||
|
||||
private bool VerifyContentType(LocationEntry locationEntry, ContentType contentType)
|
||||
private bool VerifyContentType(LocationEntry LocationEntry, ContentType ContentType)
|
||||
{
|
||||
if (locationEntry.ContentPath == null)
|
||||
if (LocationEntry.ContentPath == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
StorageId storageId = LocationHelper.GetStorageId(locationEntry.ContentPath);
|
||||
string installedPath = _device.FileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
|
||||
StorageId StorageId = LocationHelper.GetStorageId(LocationEntry.ContentPath);
|
||||
string InstalledPath = Device.FileSystem.SwitchPathToSystemPath(LocationEntry.ContentPath);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(installedPath))
|
||||
if (!string.IsNullOrWhiteSpace(InstalledPath))
|
||||
{
|
||||
if (File.Exists(installedPath))
|
||||
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;
|
||||
FileStream File = new FileStream(InstalledPath, FileMode.Open, FileAccess.Read);
|
||||
Nca Nca = new Nca(Device.System.KeySet, File, false);
|
||||
bool ContentCheck = Nca.Header.ContentType == ContentType;
|
||||
|
||||
nca.Dispose();
|
||||
file.Dispose();
|
||||
Nca.Dispose();
|
||||
File.Dispose();
|
||||
|
||||
return contentCheck;
|
||||
return ContentCheck;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void AddLocationEntry(LocationEntry entry, StorageId storageId)
|
||||
private void AddLocationEntry(LocationEntry Entry, StorageId StorageId)
|
||||
{
|
||||
LinkedList<LocationEntry> locationList = null;
|
||||
LinkedList<LocationEntry> LocationList = null;
|
||||
|
||||
if (_locationEntries.ContainsKey(storageId))
|
||||
if (LocationEntries.ContainsKey(StorageId))
|
||||
{
|
||||
locationList = _locationEntries[storageId];
|
||||
LocationList = LocationEntries[StorageId];
|
||||
}
|
||||
|
||||
if (locationList != null)
|
||||
if (LocationList != null)
|
||||
{
|
||||
if (locationList.Contains(entry))
|
||||
if (LocationList.Contains(Entry))
|
||||
{
|
||||
locationList.Remove(entry);
|
||||
LocationList.Remove(Entry);
|
||||
}
|
||||
|
||||
locationList.AddLast(entry);
|
||||
LocationList.AddLast(Entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveLocationEntry(long titleId, ContentType contentType, StorageId storageId)
|
||||
private void RemoveLocationEntry(long TitleId, ContentType ContentType, StorageId StorageId)
|
||||
{
|
||||
LinkedList<LocationEntry> locationList = null;
|
||||
LinkedList<LocationEntry> LocationList = null;
|
||||
|
||||
if (_locationEntries.ContainsKey(storageId))
|
||||
if (LocationEntries.ContainsKey(StorageId))
|
||||
{
|
||||
locationList = _locationEntries[storageId];
|
||||
LocationList = LocationEntries[StorageId];
|
||||
}
|
||||
|
||||
if (locationList != null)
|
||||
if (LocationList != null)
|
||||
{
|
||||
LocationEntry entry =
|
||||
locationList.ToList().Find(x => x.TitleId == titleId && x.ContentType == contentType);
|
||||
LocationEntry Entry =
|
||||
LocationList.ToList().Find(x => x.TitleId == TitleId && x.ContentType == ContentType);
|
||||
|
||||
if (entry.ContentPath != null)
|
||||
if (Entry.ContentPath != null)
|
||||
{
|
||||
locationList.Remove(entry);
|
||||
LocationList.Remove(Entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetFontTitle(string fontName, out long titleId)
|
||||
public bool TryGetFontTitle(string FontName, out long TitleId)
|
||||
{
|
||||
return _sharedFontTitleDictionary.TryGetValue(fontName, out titleId);
|
||||
return SharedFontTitleDictionary.TryGetValue(FontName, out TitleId);
|
||||
}
|
||||
|
||||
private LocationEntry GetLocation(long titleId, ContentType contentType,StorageId storageId)
|
||||
private LocationEntry GetLocation(long TitleId, ContentType ContentType,StorageId StorageId)
|
||||
{
|
||||
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
|
||||
LinkedList<LocationEntry> LocationList = LocationEntries[StorageId];
|
||||
|
||||
return locationList.ToList().Find(x => x.TitleId == titleId && x.ContentType == contentType);
|
||||
return LocationList.ToList().Find(x => x.TitleId == TitleId && x.ContentType == ContentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,28 @@
|
|||
using LibHac;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using LibHac;
|
||||
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
{
|
||||
public struct LocationEntry
|
||||
{
|
||||
public string ContentPath { get; }
|
||||
public string ContentPath { get; private set; }
|
||||
public int Flag { get; private set; }
|
||||
public long TitleId { get; }
|
||||
public ContentType ContentType { get; }
|
||||
public long TitleId { get; private set; }
|
||||
public ContentType ContentType { get; private set; }
|
||||
|
||||
public LocationEntry(string contentPath, int flag, long titleId, ContentType contentType)
|
||||
public LocationEntry(string ContentPath, int Flag, long TitleId, ContentType ContentType)
|
||||
{
|
||||
ContentPath = contentPath;
|
||||
Flag = flag;
|
||||
TitleId = titleId;
|
||||
ContentType = contentType;
|
||||
this.ContentPath = ContentPath;
|
||||
this.Flag = Flag;
|
||||
this.TitleId = TitleId;
|
||||
this.ContentType = ContentType;
|
||||
}
|
||||
|
||||
public void SetFlag(int flag)
|
||||
public void SetFlag(int Flag)
|
||||
{
|
||||
Flag = flag;
|
||||
this.Flag = Flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,30 +7,30 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{
|
||||
internal static class LocationHelper
|
||||
{
|
||||
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath)
|
||||
public static string GetRealPath(VirtualFileSystem FileSystem, string SwitchContentPath)
|
||||
{
|
||||
string basePath = fileSystem.GetBasePath();
|
||||
string BasePath = FileSystem.GetBasePath();
|
||||
|
||||
switch (switchContentPath)
|
||||
switch (SwitchContentPath)
|
||||
{
|
||||
case ContentPath.SystemContent:
|
||||
return Path.Combine(fileSystem.GetBasePath(), SystemNandPath, "Contents");
|
||||
return Path.Combine(FileSystem.GetBasePath(), SystemNandPath, "Contents");
|
||||
case ContentPath.UserContent:
|
||||
return Path.Combine(fileSystem.GetBasePath(), UserNandPath, "Contents");
|
||||
return Path.Combine(FileSystem.GetBasePath(), UserNandPath, "Contents");
|
||||
case ContentPath.SdCardContent:
|
||||
return Path.Combine(fileSystem.GetSdCardPath(), "Nintendo", "Contents");
|
||||
return Path.Combine(FileSystem.GetSdCardPath(), "Nintendo", "Contents");
|
||||
case ContentPath.System:
|
||||
return Path.Combine(basePath, SystemNandPath);
|
||||
return Path.Combine(BasePath, SystemNandPath);
|
||||
case ContentPath.User:
|
||||
return Path.Combine(basePath, UserNandPath);
|
||||
return Path.Combine(BasePath, UserNandPath);
|
||||
default:
|
||||
throw new NotSupportedException($"Content Path `{switchContentPath}` is not supported.");
|
||||
throw new NotSupportedException($"Content Path `{SwitchContentPath}` is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetContentPath(ContentStorageId contentStorageId)
|
||||
public static string GetContentPath(ContentStorageId ContentStorageId)
|
||||
{
|
||||
switch (contentStorageId)
|
||||
switch (ContentStorageId)
|
||||
{
|
||||
case ContentStorageId.NandSystem:
|
||||
return ContentPath.SystemContent;
|
||||
|
@ -39,13 +39,13 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
case ContentStorageId.SdCard:
|
||||
return ContentPath.SdCardContent;
|
||||
default:
|
||||
throw new NotSupportedException($"Content Storage `{contentStorageId}` is not supported.");
|
||||
throw new NotSupportedException($"Content Storage `{ContentStorageId}` is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetContentRoot(StorageId storageId)
|
||||
public static string GetContentRoot(StorageId StorageId)
|
||||
{
|
||||
switch (storageId)
|
||||
switch (StorageId)
|
||||
{
|
||||
case StorageId.NandSystem:
|
||||
return ContentPath.SystemContent;
|
||||
|
@ -54,15 +54,15 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
case StorageId.SdCard:
|
||||
return ContentPath.SdCardContent;
|
||||
default:
|
||||
throw new NotSupportedException($"Storage Id `{storageId}` is not supported.");
|
||||
throw new NotSupportedException($"Storage Id `{StorageId}` is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public static StorageId GetStorageId(string contentPathString)
|
||||
public static StorageId GetStorageId(string ContentPathString)
|
||||
{
|
||||
string cleanedPath = contentPathString.Split(':')[0];
|
||||
string CleanedPath = ContentPathString.Split(':')[0];
|
||||
|
||||
switch (cleanedPath)
|
||||
switch (CleanedPath)
|
||||
{
|
||||
case ContentPath.SystemContent:
|
||||
case ContentPath.System:
|
||||
|
|
|
@ -10,228 +10,228 @@ namespace Ryujinx.HLE.FileSystem
|
|||
{
|
||||
class FileSystemProvider : IFileSystemProvider
|
||||
{
|
||||
private readonly string _basePath;
|
||||
private readonly string _rootPath;
|
||||
private readonly string BasePath;
|
||||
private readonly string RootPath;
|
||||
|
||||
public FileSystemProvider(string basePath, string rootPath)
|
||||
public FileSystemProvider(string BasePath, string RootPath)
|
||||
{
|
||||
_basePath = basePath;
|
||||
_rootPath = rootPath;
|
||||
this.BasePath = BasePath;
|
||||
this.RootPath = RootPath;
|
||||
|
||||
CheckIfDescendentOfRootPath(basePath);
|
||||
CheckIfDescendentOfRootPath(BasePath);
|
||||
}
|
||||
|
||||
public long CreateDirectory(string name)
|
||||
public long CreateDirectory(string Name)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(name);
|
||||
CheckIfDescendentOfRootPath(Name);
|
||||
|
||||
if (Directory.Exists(name))
|
||||
if (Directory.Exists(Name))
|
||||
{
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(name);
|
||||
Directory.CreateDirectory(Name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long CreateFile(string name, long size)
|
||||
public long CreateFile(string Name, long Size)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(name);
|
||||
CheckIfDescendentOfRootPath(Name);
|
||||
|
||||
if (File.Exists(name))
|
||||
if (File.Exists(Name))
|
||||
{
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
|
||||
}
|
||||
|
||||
using (FileStream newFile = File.Create(name))
|
||||
using (FileStream NewFile = File.Create(Name))
|
||||
{
|
||||
newFile.SetLength(size);
|
||||
NewFile.SetLength(Size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long DeleteDirectory(string name, bool recursive)
|
||||
public long DeleteDirectory(string Name, bool Recursive)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(name);
|
||||
CheckIfDescendentOfRootPath(Name);
|
||||
|
||||
string dirName = name;
|
||||
string DirName = Name;
|
||||
|
||||
if (!Directory.Exists(dirName))
|
||||
if (!Directory.Exists(DirName))
|
||||
{
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
|
||||
}
|
||||
|
||||
Directory.Delete(dirName, recursive);
|
||||
Directory.Delete(DirName, Recursive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long DeleteFile(string name)
|
||||
public long DeleteFile(string Name)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(name);
|
||||
CheckIfDescendentOfRootPath(Name);
|
||||
|
||||
if (!File.Exists(name))
|
||||
if (!File.Exists(Name))
|
||||
{
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Delete(name);
|
||||
File.Delete(Name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetDirectories(string path)
|
||||
public DirectoryEntry[] GetDirectories(string Path)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(path);
|
||||
CheckIfDescendentOfRootPath(Path);
|
||||
|
||||
List<DirectoryEntry> entries = new List<DirectoryEntry>();
|
||||
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
|
||||
|
||||
foreach(string directory in Directory.EnumerateDirectories(path))
|
||||
foreach(string Directory in Directory.EnumerateDirectories(Path))
|
||||
{
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(directory, DirectoryEntryType.Directory);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory, DirectoryEntryType.Directory);
|
||||
|
||||
entries.Add(directoryEntry);
|
||||
Entries.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
return entries.ToArray();
|
||||
return Entries.ToArray();
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetEntries(string path)
|
||||
public DirectoryEntry[] GetEntries(string Path)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(path);
|
||||
CheckIfDescendentOfRootPath(Path);
|
||||
|
||||
if (Directory.Exists(path))
|
||||
if (Directory.Exists(Path))
|
||||
{
|
||||
List<DirectoryEntry> entries = new List<DirectoryEntry>();
|
||||
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
|
||||
|
||||
foreach (string directory in Directory.EnumerateDirectories(path))
|
||||
foreach (string Directory in Directory.EnumerateDirectories(Path))
|
||||
{
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(directory, DirectoryEntryType.Directory);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory, DirectoryEntryType.Directory);
|
||||
|
||||
entries.Add(directoryEntry);
|
||||
Entries.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
foreach (string file in Directory.EnumerateFiles(path))
|
||||
foreach (string File in Directory.EnumerateFiles(Path))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(file);
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(file, DirectoryEntryType.File, fileInfo.Length);
|
||||
FileInfo FileInfo = new FileInfo(File);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(File, DirectoryEntryType.File, FileInfo.Length);
|
||||
|
||||
entries.Add(directoryEntry);
|
||||
Entries.Add(DirectoryEntry);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetFiles(string path)
|
||||
public DirectoryEntry[] GetFiles(string Path)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(path);
|
||||
CheckIfDescendentOfRootPath(Path);
|
||||
|
||||
List<DirectoryEntry> entries = new List<DirectoryEntry>();
|
||||
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
|
||||
|
||||
foreach (string file in Directory.EnumerateFiles(path))
|
||||
foreach (string File in Directory.EnumerateFiles(Path))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(file);
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(file, DirectoryEntryType.File, fileInfo.Length);
|
||||
FileInfo FileInfo = new FileInfo(File);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(File, DirectoryEntryType.File, FileInfo.Length);
|
||||
|
||||
entries.Add(directoryEntry);
|
||||
Entries.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
return entries.ToArray();
|
||||
return Entries.ToArray();
|
||||
}
|
||||
|
||||
public long GetFreeSpace(ServiceCtx context)
|
||||
public long GetFreeSpace(ServiceCtx Context)
|
||||
{
|
||||
return context.Device.FileSystem.GetDrive().AvailableFreeSpace;
|
||||
return Context.Device.FileSystem.GetDrive().AvailableFreeSpace;
|
||||
}
|
||||
|
||||
public string GetFullPath(string name)
|
||||
public string GetFullPath(string Name)
|
||||
{
|
||||
if (name.StartsWith("//"))
|
||||
if (Name.StartsWith("//"))
|
||||
{
|
||||
name = name.Substring(2);
|
||||
Name = Name.Substring(2);
|
||||
}
|
||||
else if (name.StartsWith('/'))
|
||||
else if (Name.StartsWith('/'))
|
||||
{
|
||||
name = name.Substring(1);
|
||||
Name = Name.Substring(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string fullPath = Path.Combine(_basePath, name);
|
||||
string FullPath = Path.Combine(BasePath, Name);
|
||||
|
||||
CheckIfDescendentOfRootPath(fullPath);
|
||||
CheckIfDescendentOfRootPath(FullPath);
|
||||
|
||||
return fullPath;
|
||||
return FullPath;
|
||||
}
|
||||
|
||||
public long GetTotalSpace(ServiceCtx context)
|
||||
public long GetTotalSpace(ServiceCtx Context)
|
||||
{
|
||||
return context.Device.FileSystem.GetDrive().TotalSize;
|
||||
return Context.Device.FileSystem.GetDrive().TotalSize;
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string name)
|
||||
public bool DirectoryExists(string Name)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(name);
|
||||
CheckIfDescendentOfRootPath(Name);
|
||||
|
||||
return Directory.Exists(name);
|
||||
return Directory.Exists(Name);
|
||||
}
|
||||
|
||||
public bool FileExists(string name)
|
||||
public bool FileExists(string Name)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(name);
|
||||
CheckIfDescendentOfRootPath(Name);
|
||||
|
||||
return File.Exists(name);
|
||||
return File.Exists(Name);
|
||||
}
|
||||
|
||||
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface)
|
||||
public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(name);
|
||||
CheckIfDescendentOfRootPath(Name);
|
||||
|
||||
if (Directory.Exists(name))
|
||||
if (Directory.Exists(Name))
|
||||
{
|
||||
directoryInterface = new IDirectory(name, filterFlags, this);
|
||||
DirectoryInterface = new IDirectory(Name, FilterFlags, this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
directoryInterface = null;
|
||||
DirectoryInterface = null;
|
||||
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
|
||||
}
|
||||
|
||||
public long OpenFile(string name, out IFile fileInterface)
|
||||
public long OpenFile(string Name, out IFile FileInterface)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(name);
|
||||
CheckIfDescendentOfRootPath(Name);
|
||||
|
||||
if (File.Exists(name))
|
||||
if (File.Exists(Name))
|
||||
{
|
||||
FileStream stream = new FileStream(name, FileMode.Open);
|
||||
FileStream Stream = new FileStream(Name, FileMode.Open);
|
||||
|
||||
fileInterface = new IFile(stream, name);
|
||||
FileInterface = new IFile(Stream, Name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fileInterface = null;
|
||||
FileInterface = null;
|
||||
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
|
||||
}
|
||||
|
||||
public long RenameDirectory(string oldName, string newName)
|
||||
public long RenameDirectory(string OldName, string NewName)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(oldName);
|
||||
CheckIfDescendentOfRootPath(newName);
|
||||
CheckIfDescendentOfRootPath(OldName);
|
||||
CheckIfDescendentOfRootPath(NewName);
|
||||
|
||||
if (Directory.Exists(oldName))
|
||||
if (Directory.Exists(OldName))
|
||||
{
|
||||
Directory.Move(oldName, newName);
|
||||
Directory.Move(OldName, NewName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -241,14 +241,14 @@ namespace Ryujinx.HLE.FileSystem
|
|||
return 0;
|
||||
}
|
||||
|
||||
public long RenameFile(string oldName, string newName)
|
||||
public long RenameFile(string OldName, string NewName)
|
||||
{
|
||||
CheckIfDescendentOfRootPath(oldName);
|
||||
CheckIfDescendentOfRootPath(newName);
|
||||
CheckIfDescendentOfRootPath(OldName);
|
||||
CheckIfDescendentOfRootPath(NewName);
|
||||
|
||||
if (File.Exists(oldName))
|
||||
if (File.Exists(OldName))
|
||||
{
|
||||
File.Move(oldName, newName);
|
||||
File.Move(OldName, NewName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -258,24 +258,24 @@ namespace Ryujinx.HLE.FileSystem
|
|||
return 0;
|
||||
}
|
||||
|
||||
public void CheckIfDescendentOfRootPath(string path)
|
||||
public void CheckIfDescendentOfRootPath(string Path)
|
||||
{
|
||||
DirectoryInfo pathInfo = new DirectoryInfo(path);
|
||||
DirectoryInfo rootInfo = new DirectoryInfo(_rootPath);
|
||||
DirectoryInfo PathInfo = new DirectoryInfo(Path);
|
||||
DirectoryInfo RootInfo = new DirectoryInfo(RootPath);
|
||||
|
||||
while (pathInfo.Parent != null)
|
||||
while (PathInfo.Parent != null)
|
||||
{
|
||||
if (pathInfo.Parent.FullName == rootInfo.FullName)
|
||||
if (PathInfo.Parent.FullName == RootInfo.FullName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
pathInfo = pathInfo.Parent;
|
||||
PathInfo = PathInfo.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Path {path} is not a child directory of {_rootPath}");
|
||||
throw new InvalidOperationException($"Path {Path} is not a child directory of {RootPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +1,41 @@
|
|||
using Ryujinx.HLE.HOS;
|
||||
using Ryujinx.HLE.HOS.Services.FspSrv;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
interface IFileSystemProvider
|
||||
{
|
||||
long CreateFile(string name, long size);
|
||||
long CreateFile(string Name, long Size);
|
||||
|
||||
long CreateDirectory(string name);
|
||||
long CreateDirectory(string Name);
|
||||
|
||||
long RenameFile(string oldName, string newName);
|
||||
long RenameFile(string OldName, string NewName);
|
||||
|
||||
long RenameDirectory(string oldName, string newName);
|
||||
long RenameDirectory(string OldName, string NewName);
|
||||
|
||||
DirectoryEntry[] GetEntries(string path);
|
||||
DirectoryEntry[] GetEntries(string Path);
|
||||
|
||||
DirectoryEntry[] GetDirectories(string path);
|
||||
DirectoryEntry[] GetDirectories(string Path);
|
||||
|
||||
DirectoryEntry[] GetFiles(string path);
|
||||
DirectoryEntry[] GetFiles(string Path);
|
||||
|
||||
long DeleteFile(string name);
|
||||
long DeleteFile(string Name);
|
||||
|
||||
long DeleteDirectory(string name, bool recursive);
|
||||
long DeleteDirectory(string Name, bool Recursive);
|
||||
|
||||
bool FileExists(string name);
|
||||
bool FileExists(string Name);
|
||||
|
||||
bool DirectoryExists(string name);
|
||||
bool DirectoryExists(string Name);
|
||||
|
||||
long OpenFile(string name, out IFile fileInterface);
|
||||
long OpenFile(string Name, out IFile FileInterface);
|
||||
|
||||
long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface);
|
||||
long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface);
|
||||
|
||||
string GetFullPath(string name);
|
||||
string GetFullPath(string Name);
|
||||
|
||||
long GetFreeSpace(ServiceCtx context);
|
||||
long GetFreeSpace(ServiceCtx Context);
|
||||
|
||||
long GetTotalSpace(ServiceCtx context);
|
||||
long GetTotalSpace(ServiceCtx Context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,98 +12,98 @@ namespace Ryujinx.HLE.FileSystem
|
|||
{
|
||||
class PFsProvider : IFileSystemProvider
|
||||
{
|
||||
private Pfs _pfs;
|
||||
private Pfs Pfs;
|
||||
|
||||
public PFsProvider(Pfs pfs)
|
||||
public PFsProvider(Pfs Pfs)
|
||||
{
|
||||
_pfs = pfs;
|
||||
this.Pfs = Pfs;
|
||||
}
|
||||
|
||||
public long CreateDirectory(string name)
|
||||
public long CreateDirectory(string Name)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long CreateFile(string name, long size)
|
||||
public long CreateFile(string Name, long Size)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long DeleteDirectory(string name, bool recursive)
|
||||
public long DeleteDirectory(string Name, bool Recursive)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long DeleteFile(string name)
|
||||
public long DeleteFile(string Name)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetDirectories(string path)
|
||||
public DirectoryEntry[] GetDirectories(string Path)
|
||||
{
|
||||
return new DirectoryEntry[0];
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetEntries(string path)
|
||||
public DirectoryEntry[] GetEntries(string Path)
|
||||
{
|
||||
List<DirectoryEntry> entries = new List<DirectoryEntry>();
|
||||
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
|
||||
|
||||
foreach (PfsFileEntry file in _pfs.Files)
|
||||
foreach (PfsFileEntry File in Pfs.Files)
|
||||
{
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.Size);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.Size);
|
||||
|
||||
entries.Add(directoryEntry);
|
||||
Entries.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
return entries.ToArray();
|
||||
return Entries.ToArray();
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetFiles(string path)
|
||||
public DirectoryEntry[] GetFiles(string Path)
|
||||
{
|
||||
List<DirectoryEntry> entries = new List<DirectoryEntry>();
|
||||
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
|
||||
|
||||
foreach (PfsFileEntry file in _pfs.Files)
|
||||
foreach (PfsFileEntry File in Pfs.Files)
|
||||
{
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.Size);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.Size);
|
||||
|
||||
entries.Add(directoryEntry);
|
||||
Entries.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
return entries.ToArray();
|
||||
return Entries.ToArray();
|
||||
}
|
||||
|
||||
public long GetFreeSpace(ServiceCtx context)
|
||||
public long GetFreeSpace(ServiceCtx Context)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public string GetFullPath(string name)
|
||||
public string GetFullPath(string Name)
|
||||
{
|
||||
return name;
|
||||
return Name;
|
||||
}
|
||||
|
||||
public long GetTotalSpace(ServiceCtx context)
|
||||
public long GetTotalSpace(ServiceCtx Context)
|
||||
{
|
||||
return _pfs.Files.Sum(x => x.Size);
|
||||
return Pfs.Files.Sum(x => x.Size);
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string name)
|
||||
public bool DirectoryExists(string Name)
|
||||
{
|
||||
return name == "/";
|
||||
return Name == "/" ? true : false;
|
||||
}
|
||||
|
||||
public bool FileExists(string name)
|
||||
public bool FileExists(string Name)
|
||||
{
|
||||
name = name.TrimStart('/');
|
||||
Name = Name.TrimStart('/');
|
||||
|
||||
return _pfs.FileExists(name);
|
||||
return Pfs.FileExists(Name);
|
||||
}
|
||||
|
||||
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface)
|
||||
public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
|
||||
{
|
||||
if (name == "/")
|
||||
if (Name == "/")
|
||||
{
|
||||
directoryInterface = new IDirectory(name, filterFlags, this);
|
||||
DirectoryInterface = new IDirectory(Name, FilterFlags, this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -111,34 +111,34 @@ namespace Ryujinx.HLE.FileSystem
|
|||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long OpenFile(string name, out IFile fileInterface)
|
||||
public long OpenFile(string Name, out IFile FileInterface)
|
||||
{
|
||||
name = name.TrimStart('/');
|
||||
Name = Name.TrimStart('/');
|
||||
|
||||
if (_pfs.FileExists(name))
|
||||
if (Pfs.FileExists(Name))
|
||||
{
|
||||
Stream stream = _pfs.OpenFile(name);
|
||||
fileInterface = new IFile(stream, name);
|
||||
Stream Stream = Pfs.OpenFile(Name);
|
||||
FileInterface = new IFile(Stream, Name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fileInterface = null;
|
||||
FileInterface = null;
|
||||
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
|
||||
}
|
||||
|
||||
public long RenameDirectory(string oldName, string newName)
|
||||
public long RenameDirectory(string OldName, string NewName)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long RenameFile(string oldName, string newName)
|
||||
public long RenameFile(string OldName, string NewName)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void CheckIfOutsideBasePath(string path)
|
||||
public void CheckIfOutsideBasePath(string Path)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
|
|
@ -12,150 +12,150 @@ namespace Ryujinx.HLE.FileSystem
|
|||
{
|
||||
class RomFsProvider : IFileSystemProvider
|
||||
{
|
||||
private Romfs _romFs;
|
||||
private Romfs RomFs;
|
||||
|
||||
public RomFsProvider(Stream storageStream)
|
||||
public RomFsProvider(Stream StorageStream)
|
||||
{
|
||||
_romFs = new Romfs(storageStream);
|
||||
RomFs = new Romfs(StorageStream);
|
||||
}
|
||||
|
||||
public long CreateDirectory(string name)
|
||||
public long CreateDirectory(string Name)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long CreateFile(string name, long size)
|
||||
public long CreateFile(string Name, long Size)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long DeleteDirectory(string name, bool recursive)
|
||||
public long DeleteDirectory(string Name, bool Recursive)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long DeleteFile(string name)
|
||||
public long DeleteFile(string Name)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetDirectories(string path)
|
||||
public DirectoryEntry[] GetDirectories(string Path)
|
||||
{
|
||||
List<DirectoryEntry> directories = new List<DirectoryEntry>();
|
||||
List<DirectoryEntry> Directories = new List<DirectoryEntry>();
|
||||
|
||||
foreach(RomfsDir directory in _romFs.Directories)
|
||||
foreach(RomfsDir Directory in RomFs.Directories)
|
||||
{
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(directory.Name, DirectoryEntryType.Directory);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory.Name, DirectoryEntryType.Directory);
|
||||
|
||||
directories.Add(directoryEntry);
|
||||
Directories.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
return directories.ToArray();
|
||||
return Directories.ToArray();
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetEntries(string path)
|
||||
public DirectoryEntry[] GetEntries(string Path)
|
||||
{
|
||||
List<DirectoryEntry> entries = new List<DirectoryEntry>();
|
||||
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
|
||||
|
||||
foreach (RomfsDir directory in _romFs.Directories)
|
||||
foreach (RomfsDir Directory in RomFs.Directories)
|
||||
{
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(directory.Name, DirectoryEntryType.Directory);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory.Name, DirectoryEntryType.Directory);
|
||||
|
||||
entries.Add(directoryEntry);
|
||||
Entries.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
foreach (RomfsFile file in _romFs.Files)
|
||||
foreach (RomfsFile File in RomFs.Files)
|
||||
{
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.DataLength);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.DataLength);
|
||||
|
||||
entries.Add(directoryEntry);
|
||||
Entries.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
return entries.ToArray();
|
||||
return Entries.ToArray();
|
||||
}
|
||||
|
||||
public DirectoryEntry[] GetFiles(string path)
|
||||
public DirectoryEntry[] GetFiles(string Path)
|
||||
{
|
||||
List<DirectoryEntry> files = new List<DirectoryEntry>();
|
||||
List<DirectoryEntry> Files = new List<DirectoryEntry>();
|
||||
|
||||
foreach (RomfsFile file in _romFs.Files)
|
||||
foreach (RomfsFile File in RomFs.Files)
|
||||
{
|
||||
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.DataLength);
|
||||
DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.DataLength);
|
||||
|
||||
files.Add(directoryEntry);
|
||||
Files.Add(DirectoryEntry);
|
||||
}
|
||||
|
||||
return files.ToArray();
|
||||
return Files.ToArray();
|
||||
}
|
||||
|
||||
public long GetFreeSpace(ServiceCtx context)
|
||||
public long GetFreeSpace(ServiceCtx Context)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public string GetFullPath(string name)
|
||||
public string GetFullPath(string Name)
|
||||
{
|
||||
return name;
|
||||
return Name;
|
||||
}
|
||||
|
||||
public long GetTotalSpace(ServiceCtx context)
|
||||
public long GetTotalSpace(ServiceCtx Context)
|
||||
{
|
||||
return _romFs.Files.Sum(x => x.DataLength);
|
||||
return RomFs.Files.Sum(x => x.DataLength);
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string name)
|
||||
public bool DirectoryExists(string Name)
|
||||
{
|
||||
return _romFs.Directories.Exists(x=>x.Name == name);
|
||||
return RomFs.Directories.Exists(x=>x.Name == Name);
|
||||
}
|
||||
|
||||
public bool FileExists(string name)
|
||||
public bool FileExists(string Name)
|
||||
{
|
||||
return _romFs.FileExists(name);
|
||||
return RomFs.FileExists(Name);
|
||||
}
|
||||
|
||||
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface)
|
||||
public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
|
||||
{
|
||||
RomfsDir directory = _romFs.Directories.Find(x => x.Name == name);
|
||||
RomfsDir Directory = RomFs.Directories.Find(x => x.Name == Name);
|
||||
|
||||
if (directory != null)
|
||||
if (Directory != null)
|
||||
{
|
||||
directoryInterface = new IDirectory(name, filterFlags, this);
|
||||
DirectoryInterface = new IDirectory(Name, FilterFlags, this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
directoryInterface = null;
|
||||
DirectoryInterface = null;
|
||||
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
|
||||
}
|
||||
|
||||
public long OpenFile(string name, out IFile fileInterface)
|
||||
public long OpenFile(string Name, out IFile FileInterface)
|
||||
{
|
||||
if (_romFs.FileExists(name))
|
||||
if (RomFs.FileExists(Name))
|
||||
{
|
||||
Stream stream = _romFs.OpenFile(name);
|
||||
Stream Stream = RomFs.OpenFile(Name);
|
||||
|
||||
fileInterface = new IFile(stream, name);
|
||||
FileInterface = new IFile(Stream, Name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fileInterface = null;
|
||||
FileInterface = null;
|
||||
|
||||
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
|
||||
}
|
||||
|
||||
public long RenameDirectory(string oldName, string newName)
|
||||
public long RenameDirectory(string OldName, string NewName)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public long RenameFile(string oldName, string newName)
|
||||
public long RenameFile(string OldName, string NewName)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void CheckIfOutsideBasePath(string path)
|
||||
public void CheckIfOutsideBasePath(string Path)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
|
|
@ -7,39 +7,39 @@ namespace Ryujinx.HLE.FileSystem
|
|||
{
|
||||
static class SaveHelper
|
||||
{
|
||||
public static string GetSavePath(SaveInfo saveMetaData, ServiceCtx context)
|
||||
public static string GetSavePath(SaveInfo SaveMetaData, ServiceCtx Context)
|
||||
{
|
||||
string baseSavePath = NandPath;
|
||||
long currentTitleId = saveMetaData.TitleId;
|
||||
string BaseSavePath = NandPath;
|
||||
long CurrentTitleId = SaveMetaData.TitleId;
|
||||
|
||||
switch (saveMetaData.SaveSpaceId)
|
||||
switch (SaveMetaData.SaveSpaceId)
|
||||
{
|
||||
case SaveSpaceId.NandUser:
|
||||
baseSavePath = UserNandPath;
|
||||
BaseSavePath = UserNandPath;
|
||||
break;
|
||||
case SaveSpaceId.NandSystem:
|
||||
baseSavePath = SystemNandPath;
|
||||
BaseSavePath = SystemNandPath;
|
||||
break;
|
||||
case SaveSpaceId.SdCard:
|
||||
baseSavePath = Path.Combine(SdCardPath, "Nintendo");
|
||||
BaseSavePath = Path.Combine(SdCardPath, "Nintendo");
|
||||
break;
|
||||
}
|
||||
|
||||
baseSavePath = Path.Combine(baseSavePath, "save");
|
||||
BaseSavePath = Path.Combine(BaseSavePath, "save");
|
||||
|
||||
if (saveMetaData.TitleId == 0 && saveMetaData.SaveDataType == SaveDataType.SaveData)
|
||||
if (SaveMetaData.TitleId == 0 && SaveMetaData.SaveDataType == SaveDataType.SaveData)
|
||||
{
|
||||
currentTitleId = context.Process.TitleId;
|
||||
CurrentTitleId = Context.Process.TitleId;
|
||||
}
|
||||
|
||||
string saveAccount = saveMetaData.UserId.IsZero() ? "savecommon" : saveMetaData.UserId.ToString();
|
||||
string SaveAccount = SaveMetaData.UserId.IsZero() ? "savecommon" : SaveMetaData.UserId.ToString();
|
||||
|
||||
string savePath = Path.Combine(baseSavePath,
|
||||
saveMetaData.SaveId.ToString("x16"),
|
||||
saveAccount,
|
||||
saveMetaData.SaveDataType == SaveDataType.SaveData ? currentTitleId.ToString("x16") : string.Empty);
|
||||
string SavePath = Path.Combine(BaseSavePath,
|
||||
SaveMetaData.SaveId.ToString("x16"),
|
||||
SaveAccount,
|
||||
SaveMetaData.SaveDataType == SaveDataType.SaveData ? CurrentTitleId.ToString("x16") : string.Empty);
|
||||
|
||||
return savePath;
|
||||
return SavePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,25 +4,25 @@ namespace Ryujinx.HLE.FileSystem
|
|||
{
|
||||
struct SaveInfo
|
||||
{
|
||||
public long TitleId { get; }
|
||||
public long SaveId { get; }
|
||||
public UInt128 UserId { get; }
|
||||
public long TitleId { get; private set; }
|
||||
public long SaveId { get; private set; }
|
||||
public UInt128 UserId { get; private set; }
|
||||
|
||||
public SaveDataType SaveDataType { get; }
|
||||
public SaveSpaceId SaveSpaceId { get; }
|
||||
public SaveDataType SaveDataType { get; private set; }
|
||||
public SaveSpaceId SaveSpaceId { get; private set; }
|
||||
|
||||
public SaveInfo(
|
||||
long titleId,
|
||||
long saveId,
|
||||
SaveDataType saveDataType,
|
||||
UInt128 userId,
|
||||
SaveSpaceId saveSpaceId)
|
||||
long TitleId,
|
||||
long SaveId,
|
||||
SaveDataType SaveDataType,
|
||||
UInt128 UserId,
|
||||
SaveSpaceId SaveSpaceId)
|
||||
{
|
||||
TitleId = titleId;
|
||||
UserId = userId;
|
||||
SaveId = saveId;
|
||||
SaveDataType = saveDataType;
|
||||
SaveSpaceId = saveSpaceId;
|
||||
this.TitleId = TitleId;
|
||||
this.UserId = UserId;
|
||||
this.SaveId = SaveId;
|
||||
this.SaveDataType = SaveDataType;
|
||||
this.SaveSpaceId = SaveSpaceId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,40 +18,40 @@ namespace Ryujinx.HLE.FileSystem
|
|||
|
||||
public Stream RomFs { get; private set; }
|
||||
|
||||
public void LoadRomFs(string fileName)
|
||||
public void LoadRomFs(string FileName)
|
||||
{
|
||||
RomFs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
|
||||
RomFs = new FileStream(FileName, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
|
||||
public void SetRomFs(Stream romfsStream)
|
||||
public void SetRomFs(Stream RomfsStream)
|
||||
{
|
||||
RomFs?.Close();
|
||||
RomFs = romfsStream;
|
||||
RomFs = RomfsStream;
|
||||
}
|
||||
|
||||
public string GetFullPath(string basePath, string fileName)
|
||||
public string GetFullPath(string BasePath, string FileName)
|
||||
{
|
||||
if (fileName.StartsWith("//"))
|
||||
if (FileName.StartsWith("//"))
|
||||
{
|
||||
fileName = fileName.Substring(2);
|
||||
FileName = FileName.Substring(2);
|
||||
}
|
||||
else if (fileName.StartsWith('/'))
|
||||
else if (FileName.StartsWith('/'))
|
||||
{
|
||||
fileName = fileName.Substring(1);
|
||||
FileName = FileName.Substring(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string fullPath = Path.GetFullPath(Path.Combine(basePath, fileName));
|
||||
string FullPath = Path.GetFullPath(Path.Combine(BasePath, FileName));
|
||||
|
||||
if (!fullPath.StartsWith(GetBasePath()))
|
||||
if (!FullPath.StartsWith(GetBasePath()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return fullPath;
|
||||
return FullPath;
|
||||
}
|
||||
|
||||
public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath);
|
||||
|
@ -60,84 +60,84 @@ namespace Ryujinx.HLE.FileSystem
|
|||
|
||||
public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath);
|
||||
|
||||
public string GetGameSavePath(SaveInfo save, ServiceCtx context)
|
||||
public string GetGameSavePath(SaveInfo Save, ServiceCtx Context)
|
||||
{
|
||||
return MakeDirAndGetFullPath(SaveHelper.GetSavePath(save, context));
|
||||
return MakeDirAndGetFullPath(SaveHelper.GetSavePath(Save, Context));
|
||||
}
|
||||
|
||||
public string GetFullPartitionPath(string partitionPath)
|
||||
public string GetFullPartitionPath(string PartitionPath)
|
||||
{
|
||||
return MakeDirAndGetFullPath(partitionPath);
|
||||
return MakeDirAndGetFullPath(PartitionPath);
|
||||
}
|
||||
|
||||
public string SwitchPathToSystemPath(string switchPath)
|
||||
public string SwitchPathToSystemPath(string SwitchPath)
|
||||
{
|
||||
string[] parts = switchPath.Split(":");
|
||||
string[] Parts = SwitchPath.Split(":");
|
||||
|
||||
if (parts.Length != 2)
|
||||
if (Parts.Length != 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return GetFullPath(MakeDirAndGetFullPath(parts[0]), parts[1]);
|
||||
return GetFullPath(MakeDirAndGetFullPath(Parts[0]), Parts[1]);
|
||||
}
|
||||
|
||||
public string SystemPathToSwitchPath(string systemPath)
|
||||
public string SystemPathToSwitchPath(string SystemPath)
|
||||
{
|
||||
string baseSystemPath = GetBasePath() + Path.DirectorySeparatorChar;
|
||||
string BaseSystemPath = GetBasePath() + Path.DirectorySeparatorChar;
|
||||
|
||||
if (systemPath.StartsWith(baseSystemPath))
|
||||
if (SystemPath.StartsWith(BaseSystemPath))
|
||||
{
|
||||
string rawPath = systemPath.Replace(baseSystemPath, "");
|
||||
int firstSeparatorOffset = rawPath.IndexOf(Path.DirectorySeparatorChar);
|
||||
string RawPath = SystemPath.Replace(BaseSystemPath, "");
|
||||
int FirstSeparatorOffset = RawPath.IndexOf(Path.DirectorySeparatorChar);
|
||||
|
||||
if (firstSeparatorOffset == -1)
|
||||
if (FirstSeparatorOffset == -1)
|
||||
{
|
||||
return $"{rawPath}:/";
|
||||
return $"{RawPath}:/";
|
||||
}
|
||||
|
||||
string basePath = rawPath.Substring(0, firstSeparatorOffset);
|
||||
string fileName = rawPath.Substring(firstSeparatorOffset + 1);
|
||||
string BasePath = RawPath.Substring(0, FirstSeparatorOffset);
|
||||
string FileName = RawPath.Substring(FirstSeparatorOffset + 1);
|
||||
|
||||
return $"{basePath}:/{fileName}";
|
||||
return $"{BasePath}:/{FileName}";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private string MakeDirAndGetFullPath(string dir)
|
||||
private string MakeDirAndGetFullPath(string Dir)
|
||||
{
|
||||
// Handles Common Switch Content Paths
|
||||
switch (dir)
|
||||
switch (Dir)
|
||||
{
|
||||
case ContentPath.SdCard:
|
||||
case "@Sdcard":
|
||||
dir = SdCardPath;
|
||||
Dir = SdCardPath;
|
||||
break;
|
||||
case ContentPath.User:
|
||||
dir = UserNandPath;
|
||||
Dir = UserNandPath;
|
||||
break;
|
||||
case ContentPath.System:
|
||||
dir = SystemNandPath;
|
||||
Dir = SystemNandPath;
|
||||
break;
|
||||
case ContentPath.SdCardContent:
|
||||
dir = Path.Combine(SdCardPath, "Nintendo", "Contents");
|
||||
Dir = Path.Combine(SdCardPath, "Nintendo", "Contents");
|
||||
break;
|
||||
case ContentPath.UserContent:
|
||||
dir = Path.Combine(UserNandPath, "Contents");
|
||||
Dir = Path.Combine(UserNandPath, "Contents");
|
||||
break;
|
||||
case ContentPath.SystemContent:
|
||||
dir = Path.Combine(SystemNandPath, "Contents");
|
||||
Dir = Path.Combine(SystemNandPath, "Contents");
|
||||
break;
|
||||
}
|
||||
|
||||
string fullPath = Path.Combine(GetBasePath(), dir);
|
||||
string FullPath = Path.Combine(GetBasePath(), Dir);
|
||||
|
||||
if (!Directory.Exists(fullPath))
|
||||
if (!Directory.Exists(FullPath))
|
||||
{
|
||||
Directory.CreateDirectory(fullPath);
|
||||
Directory.CreateDirectory(FullPath);
|
||||
}
|
||||
|
||||
return fullPath;
|
||||
return FullPath;
|
||||
}
|
||||
|
||||
public DriveInfo GetDrive()
|
||||
|
@ -147,9 +147,9 @@ namespace Ryujinx.HLE.FileSystem
|
|||
|
||||
public string GetBasePath()
|
||||
{
|
||||
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
|
||||
return Path.Combine(appDataPath, BasePath);
|
||||
return Path.Combine(AppDataPath, BasePath);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue