mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2025-02-09 13:14:46 +01:00
Combine common code in EnsureApplicationSaveData
This commit is contained in:
parent
cfb79f5780
commit
7bef4c6cd9
@ -13,127 +13,55 @@ namespace LibHac.Fs
|
||||
ref ApplicationControlProperty nacp, ref Uid uid)
|
||||
{
|
||||
requiredSize = default;
|
||||
|
||||
long requiredSizeSum = 0;
|
||||
|
||||
// If the application needs a user save
|
||||
// Create local variable for use in closures
|
||||
TitleId saveDataOwnerId = nacp.SaveDataOwnerId;
|
||||
|
||||
// Ensure the user account save exists
|
||||
if (uid != Uid.Zero && nacp.UserAccountSaveDataSize > 0)
|
||||
{
|
||||
// More local variables for use in closures
|
||||
Uid uidLocal = uid;
|
||||
long accountSaveDataSize = nacp.UserAccountSaveDataSize;
|
||||
long accountSaveJournalSize = nacp.UserAccountSaveDataJournalSize;
|
||||
|
||||
Result CreateAccountSaveFunc()
|
||||
{
|
||||
UserId userId = ConvertAccountUidToFsUserId(uidLocal);
|
||||
return fs.CreateSaveData(applicationId, userId, saveDataOwnerId, accountSaveDataSize,
|
||||
accountSaveJournalSize, SaveDataFlags.None);
|
||||
}
|
||||
|
||||
var filter = new SaveDataFilter();
|
||||
filter.SetProgramId(applicationId);
|
||||
filter.SetSaveDataType(SaveDataType.Account);
|
||||
filter.SetUserId(new UserId(uid.Id.High, uid.Id.Low));
|
||||
|
||||
Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter);
|
||||
// The 0x4c000 includes the save meta and other stuff
|
||||
Result rc = EnsureAndExtendSaveData(fs, CreateAccountSaveFunc, ref requiredSizeSum, ref filter, 0x4c000,
|
||||
accountSaveDataSize, accountSaveJournalSize);
|
||||
|
||||
// If the save already exists
|
||||
if (rc.IsSuccess())
|
||||
{
|
||||
// Make sure the save is large enough
|
||||
rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeUser, SaveDataSpaceId.User,
|
||||
saveDataInfo.SaveDataId, nacp.UserAccountSaveDataSize, nacp.UserAccountSaveDataJournalSize);
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
if (!ResultFs.InsufficientFreeSpace.Includes(rc))
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
requiredSizeSum = requiredSizeUser;
|
||||
}
|
||||
}
|
||||
else if (!ResultFs.TargetNotFound.Includes(rc))
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The save doesn't exist, so try to create it
|
||||
UserId userId = ConvertAccountUidToFsUserId(uid);
|
||||
|
||||
Result createRc = fs.CreateSaveData(applicationId, userId, nacp.SaveDataOwnerId,
|
||||
nacp.UserAccountSaveDataSize, nacp.UserAccountSaveDataJournalSize, 0);
|
||||
|
||||
if (createRc.IsFailure())
|
||||
{
|
||||
// If there's insufficient free space, calculate the space required to create the save
|
||||
if (ResultFs.InsufficientFreeSpace.Includes(createRc))
|
||||
{
|
||||
Result queryRc = fs.QuerySaveDataTotalSize(out long userAccountTotalSize,
|
||||
nacp.UserAccountSaveDataSize, nacp.UserAccountSaveDataJournalSize);
|
||||
|
||||
if (queryRc.IsFailure()) return queryRc;
|
||||
|
||||
// The 0x4c000 includes the save meta and other stuff
|
||||
requiredSizeSum = Util.AlignUp(userAccountTotalSize, 0x4000) + 0x4c000;
|
||||
}
|
||||
else if (ResultFs.PathAlreadyExists.Includes(createRc))
|
||||
{
|
||||
requiredSizeSum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return createRc;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
// Ensure the device save exists
|
||||
if (nacp.DeviceSaveDataSize > 0)
|
||||
{
|
||||
long deviceSaveDataSize = nacp.DeviceSaveDataSize;
|
||||
long deviceSaveJournalSize = nacp.DeviceSaveDataJournalSize;
|
||||
|
||||
Result CreateDeviceSaveFunc() => fs.CreateDeviceSaveData(applicationId, saveDataOwnerId,
|
||||
deviceSaveDataSize, deviceSaveJournalSize, 0);
|
||||
|
||||
var filter = new SaveDataFilter();
|
||||
filter.SetProgramId(applicationId);
|
||||
filter.SetSaveDataType(SaveDataType.Device);
|
||||
|
||||
Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter);
|
||||
Result rc = EnsureAndExtendSaveData(fs, CreateDeviceSaveFunc, ref requiredSizeSum, ref filter, 0x4000,
|
||||
deviceSaveDataSize, deviceSaveJournalSize);
|
||||
|
||||
if (rc.IsSuccess())
|
||||
{
|
||||
rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeDevice, SaveDataSpaceId.User,
|
||||
saveDataInfo.SaveDataId, nacp.DeviceSaveDataSize, nacp.DeviceSaveDataJournalSize);
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
if (!ResultFs.InsufficientFreeSpace.Includes(rc))
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
requiredSizeSum += requiredSizeDevice;
|
||||
}
|
||||
}
|
||||
else if (!ResultFs.TargetNotFound.Includes(rc))
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result createRc = fs.CreateDeviceSaveData(applicationId, nacp.SaveDataOwnerId,
|
||||
nacp.DeviceSaveDataSize, nacp.DeviceSaveDataJournalSize, 0);
|
||||
|
||||
if (createRc.IsFailure())
|
||||
{
|
||||
if (ResultFs.InsufficientFreeSpace.Includes(createRc))
|
||||
{
|
||||
Result queryRc = fs.QuerySaveDataTotalSize(out long deviceSaveTotalSize,
|
||||
nacp.DeviceSaveDataSize, nacp.DeviceSaveDataJournalSize);
|
||||
|
||||
if (queryRc.IsFailure()) return queryRc;
|
||||
|
||||
// Not sure what the additional 0x4000 is
|
||||
requiredSizeSum += Util.AlignUp(deviceSaveTotalSize, 0x4000) + 0x4000;
|
||||
}
|
||||
else if (ResultFs.PathAlreadyExists.Includes(createRc))
|
||||
{
|
||||
requiredSizeSum += 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return createRc;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
Result bcatRc = EnsureApplicationBcatDeliveryCacheStorageImpl(fs,
|
||||
@ -244,71 +172,63 @@ namespace LibHac.Fs
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private static Result EnsureAndExtendSaveData(FileSystemClient fs, Func<Result> createFunc,
|
||||
ref long requiredSize, ref SaveDataFilter filter, long baseSize, long dataSize, long journalSize)
|
||||
{
|
||||
Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo info, SaveDataSpaceId.User, ref filter);
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
if (ResultFs.TargetNotFound.Includes(rc))
|
||||
{
|
||||
rc = CreateSaveData(fs, createFunc, ref requiredSize, baseSize, dataSize, journalSize);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeExtend, SaveDataSpaceId.User, info.SaveDataId,
|
||||
dataSize, journalSize);
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
if (!ResultFs.InsufficientFreeSpace.Includes(rc))
|
||||
return rc;
|
||||
|
||||
requiredSize += requiredSizeExtend;
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private static Result EnsureApplicationBcatDeliveryCacheStorageImpl(FileSystemClient fs, out long requiredSize,
|
||||
TitleId applicationId, ref ApplicationControlProperty nacp)
|
||||
{
|
||||
const long bcatDeliveryCacheJournalSize = 0x200000;
|
||||
|
||||
requiredSize = default;
|
||||
|
||||
if (nacp.BcatDeliveryCacheStorageSize <= 0)
|
||||
long bcatStorageSize = nacp.BcatDeliveryCacheStorageSize;
|
||||
if (bcatStorageSize <= 0)
|
||||
{
|
||||
requiredSize = 0;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
requiredSize = default;
|
||||
long requiredSizeBcat = 0;
|
||||
|
||||
var filter = new SaveDataFilter();
|
||||
filter.SetProgramId(applicationId);
|
||||
filter.SetSaveDataType(SaveDataType.Bcat);
|
||||
|
||||
Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter);
|
||||
Result CreateBcatStorageFunc() => fs.CreateBcatSaveData(applicationId, bcatStorageSize);
|
||||
|
||||
if (rc.IsSuccess())
|
||||
{
|
||||
rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeBcat, SaveDataSpaceId.User,
|
||||
saveDataInfo.SaveDataId, nacp.BcatDeliveryCacheStorageSize, bcatDeliveryCacheJournalSize);
|
||||
Result rc = EnsureAndExtendSaveData(fs, CreateBcatStorageFunc,
|
||||
ref requiredSizeBcat, ref filter, 0x4000, bcatStorageSize, bcatDeliveryCacheJournalSize);
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
if (!ResultFs.InsufficientFreeSpace.Includes(rc))
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
requiredSize = requiredSizeBcat;
|
||||
}
|
||||
}
|
||||
else if (!ResultFs.TargetNotFound.Includes(rc))
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result createRc = fs.CreateBcatSaveData(applicationId, nacp.BcatDeliveryCacheStorageSize);
|
||||
|
||||
if (createRc.IsFailure())
|
||||
{
|
||||
if (ResultFs.InsufficientFreeSpace.Includes(createRc))
|
||||
{
|
||||
Result queryRc = fs.QuerySaveDataTotalSize(out long saveTotalSize,
|
||||
nacp.BcatDeliveryCacheStorageSize, bcatDeliveryCacheJournalSize);
|
||||
|
||||
if (queryRc.IsFailure()) return queryRc;
|
||||
|
||||
requiredSize = Util.AlignUp(saveTotalSize, 0x4000) + 0x4000;
|
||||
}
|
||||
else if (ResultFs.PathAlreadyExists.Includes(createRc))
|
||||
{
|
||||
requiredSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return createRc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return requiredSize > 0 ? ResultFs.InsufficientFreeSpace.Log() : Result.Success;
|
||||
requiredSize = requiredSizeBcat;
|
||||
return requiredSizeBcat > 0 ? ResultFs.InsufficientFreeSpace.Log() : Result.Success;
|
||||
}
|
||||
|
||||
private static Result EnsureApplicationCacheStorageImpl(this FileSystemClient fs, out long requiredSize,
|
||||
@ -407,6 +327,12 @@ namespace LibHac.Fs
|
||||
nacp.SaveDataOwnerId, 0, nacp.CacheStorageSize, nacp.CacheStorageJournalSize, true);
|
||||
}
|
||||
|
||||
public static Result EnsureApplicationBcatDeliveryCacheStorage(this FileSystemClient fs, out long requiredSize,
|
||||
TitleId applicationId, ref ApplicationControlProperty nacp)
|
||||
{
|
||||
return EnsureApplicationBcatDeliveryCacheStorageImpl(fs, out requiredSize, applicationId, ref nacp);
|
||||
}
|
||||
|
||||
public static Result TryCreateCacheStorage(this FileSystemClient fs, out long requiredSize,
|
||||
SaveDataSpaceId spaceId, TitleId applicationId, TitleId saveDataOwnerId, short index, long dataSize,
|
||||
long journalSize, bool allowExisting)
|
||||
@ -464,44 +390,35 @@ namespace LibHac.Fs
|
||||
|
||||
private static Result GetCacheStorageTargetMediaImpl(this FileSystemClient fs, out CacheStorageTargetMedia target, TitleId applicationId)
|
||||
{
|
||||
target = default;
|
||||
target = CacheStorageTargetMedia.None;
|
||||
|
||||
var filter = new SaveDataFilter();
|
||||
filter.SetProgramId(applicationId);
|
||||
filter.SetSaveDataType(SaveDataType.Cache);
|
||||
|
||||
if (fs.IsSdCardAccessible())
|
||||
{
|
||||
var filter = new SaveDataFilter();
|
||||
filter.SetProgramId(applicationId);
|
||||
filter.SetSaveDataType(SaveDataType.Cache);
|
||||
|
||||
Result rc = fs.FindSaveDataWithFilter(out _, SaveDataSpaceId.SdCache, ref filter);
|
||||
if (rc.IsFailure() && !ResultFs.TargetNotFound.Includes(rc)) return rc;
|
||||
|
||||
if (rc.IsSuccess())
|
||||
{
|
||||
target = CacheStorageTargetMedia.SdCard;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (!ResultFs.TargetNotFound.Includes(rc))
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Not on the SD card. Check it it's in NAND
|
||||
if (target == CacheStorageTargetMedia.None)
|
||||
{
|
||||
var filter = new SaveDataFilter();
|
||||
filter.SetProgramId(applicationId);
|
||||
filter.SetSaveDataType(SaveDataType.Cache);
|
||||
|
||||
Result rc = fs.FindSaveDataWithFilter(out _, SaveDataSpaceId.User, ref filter);
|
||||
if (rc.IsFailure() && !ResultFs.TargetNotFound.Includes(rc)) return rc;
|
||||
|
||||
if (rc.IsSuccess())
|
||||
{
|
||||
target = CacheStorageTargetMedia.Nand;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (!ResultFs.TargetNotFound.Includes(rc))
|
||||
return rc;
|
||||
}
|
||||
|
||||
target = CacheStorageTargetMedia.None;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user