Clean the SD card save directory when opening the emulator (#2564)
Cleans "sdcard:/Nintendo/save" and deletes "sdcard:/save" when opening the emulator. Works around invalid encryption when keys or the SD card encryption seed are changed.
This commit is contained in:
parent
97aedc030d
commit
e0af248e6f
2 changed files with 27 additions and 34 deletions
|
@ -9,8 +9,6 @@ namespace Ryujinx.HLE.FileSystem
|
||||||
{
|
{
|
||||||
public class EncryptedFileSystemCreator : IEncryptedFileSystemCreator
|
public class EncryptedFileSystemCreator : IEncryptedFileSystemCreator
|
||||||
{
|
{
|
||||||
public EncryptedFileSystemCreator() { }
|
|
||||||
|
|
||||||
public Result Create(out ReferenceCountedDisposable<IFileSystem> encryptedFileSystem, ReferenceCountedDisposable<IFileSystem> baseFileSystem,
|
public Result Create(out ReferenceCountedDisposable<IFileSystem> encryptedFileSystem, ReferenceCountedDisposable<IFileSystem> baseFileSystem,
|
||||||
EncryptedFsKeyId keyId, in EncryptionSeed encryptionSeed)
|
EncryptedFsKeyId keyId, in EncryptionSeed encryptionSeed)
|
||||||
{
|
{
|
||||||
|
@ -23,40 +21,9 @@ namespace Ryujinx.HLE.FileSystem
|
||||||
|
|
||||||
// Force all-zero keys for now since people can open the emulator with different keys or sd seeds sometimes
|
// Force all-zero keys for now since people can open the emulator with different keys or sd seeds sometimes
|
||||||
var fs = new AesXtsFileSystem(baseFileSystem, new byte[0x32], 0x4000);
|
var fs = new AesXtsFileSystem(baseFileSystem, new byte[0x32], 0x4000);
|
||||||
var aesFileSystem = new ReferenceCountedDisposable<IFileSystem>(fs);
|
encryptedFileSystem = new ReferenceCountedDisposable<IFileSystem>(fs);
|
||||||
|
|
||||||
// This wrapper will handle deleting files that were created with different keys
|
|
||||||
var wrappedFs = new ChangedEncryptionHandlingFileSystem(aesFileSystem);
|
|
||||||
encryptedFileSystem = new ReferenceCountedDisposable<IFileSystem>(wrappedFs);
|
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChangedEncryptionHandlingFileSystem : ForwardingFileSystem
|
|
||||||
{
|
|
||||||
public ChangedEncryptionHandlingFileSystem(ReferenceCountedDisposable<IFileSystem> baseFileSystem) : base(baseFileSystem) { }
|
|
||||||
|
|
||||||
protected override Result DoOpenFile(out IFile file, U8Span path, OpenMode mode)
|
|
||||||
{
|
|
||||||
UnsafeHelpers.SkipParamInit(out file);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return base.DoOpenFile(out file, path, mode);
|
|
||||||
}
|
|
||||||
catch (HorizonResultException ex)
|
|
||||||
{
|
|
||||||
if (ResultFs.AesXtsFileHeaderInvalidKeys.Includes(ex.ResultValue))
|
|
||||||
{
|
|
||||||
Result rc = DeleteFile(path);
|
|
||||||
if (rc.IsFailure()) return rc;
|
|
||||||
|
|
||||||
return base.DoOpenFile(out file, path, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
using LibHac;
|
using LibHac;
|
||||||
using LibHac.Bcat;
|
using LibHac.Bcat;
|
||||||
|
using LibHac.Common;
|
||||||
|
using LibHac.Fs.Fsa;
|
||||||
|
using LibHac.Fs.Shim;
|
||||||
using LibHac.FsSrv.Impl;
|
using LibHac.FsSrv.Impl;
|
||||||
using LibHac.Loader;
|
using LibHac.Loader;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
|
@ -57,6 +60,8 @@ namespace Ryujinx.HLE.HOS
|
||||||
virtualFileSystem.InitializeFsServer(Server, out var fsClient);
|
virtualFileSystem.InitializeFsServer(Server, out var fsClient);
|
||||||
|
|
||||||
FsClient = fsClient;
|
FsClient = fsClient;
|
||||||
|
|
||||||
|
CleanSdCardDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeSystemClients()
|
public void InitializeSystemClients()
|
||||||
|
@ -80,6 +85,27 @@ namespace Ryujinx.HLE.HOS
|
||||||
npdm.FsAccessControlData, npdm.FsAccessControlDescriptor);
|
npdm.FsAccessControlData, npdm.FsAccessControlDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function was added to avoid errors that come from a user's keys or SD encryption seed changing.
|
||||||
|
// Catching these errors and recreating the file ended up not working because of the different ways
|
||||||
|
// applications respond to a file suddenly containing all zeros or having a length of zero.
|
||||||
|
// Clearing the SD card save directory was determined to be the best option for the moment since
|
||||||
|
// the saves on the SD card are meant as caches that can be deleted at any time.
|
||||||
|
private void CleanSdCardDirectory()
|
||||||
|
{
|
||||||
|
Result rc = RyujinxClient.Fs.MountSdCard("sdcard".ToU8Span());
|
||||||
|
if (rc.IsFailure()) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RyujinxClient.Fs.CleanDirectoryRecursively("sdcard:/Nintendo/save".ToU8Span()).IgnoreResult();
|
||||||
|
RyujinxClient.Fs.DeleteDirectoryRecursively("sdcard:/save".ToU8Span()).IgnoreResult();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
RyujinxClient.Fs.Unmount("sdcard".ToU8Span());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static AccessControlBits.Bits AccountFsPermissions => AccessControlBits.Bits.SystemSaveData |
|
private static AccessControlBits.Bits AccountFsPermissions => AccessControlBits.Bits.SystemSaveData |
|
||||||
AccessControlBits.Bits.GameCard |
|
AccessControlBits.Bits.GameCard |
|
||||||
AccessControlBits.Bits.SaveDataMeta |
|
AccessControlBits.Bits.SaveDataMeta |
|
||||||
|
|
Loading…
Reference in a new issue