public static void EnsureApplicationCacheStorage_SdCardNotAvailable_CreatesCacheStorageOnBis() { FileSystemClient fs = FileSystemServerFactory.CreateClient(false); var applicationId = new Ncm.ApplicationId(11); var nacp = new ApplicationControlProperty { CacheStorageSize = 0x1000, CacheStorageJournalSize = 0x1000 }; Assert.Success(fs.EnsureApplicationCacheStorage(out _, out CacheStorageTargetMedia target, applicationId, ref nacp)); Assert.Equal(CacheStorageTargetMedia.Nand, target); fs.OpenSaveDataIterator(out SaveDataIterator iterator, SaveDataSpaceId.User); var info = new SaveDataInfo[2]; Assert.Success(iterator.ReadSaveDataInfo(out long entriesRead, info)); Assert.Equal(1, entriesRead); Assert.Equal(applicationId, info[0].ProgramId); Assert.Equal(SaveDataType.Cache, info[0].Type); }
public static void EnsureApplicationSaveData_CreatesTemporaryStorage() { FileSystemClient fs = FileSystemServerFactory.CreateClient(true); var applicationId = new Ncm.ApplicationId(11); var userId = new Uid(2, 3); var nacp = new ApplicationControlProperty { TemporaryStorageSize = 0x1000 }; Assert.Success(EnsureApplicationSaveData(fs, out _, applicationId, ref nacp, ref userId)); fs.OpenSaveDataIterator(out SaveDataIterator iterator, SaveDataSpaceId.Temporary); var info = new SaveDataInfo[2]; Assert.Success(iterator.ReadSaveDataInfo(out long entriesRead, info)); Assert.Equal(1, entriesRead); Assert.Equal(applicationId, info[0].ProgramId); Assert.Equal(UserId.Zero, info[0].UserId); Assert.Equal(SaveDataType.Temporary, info[0].Type); }
public NacpItem(ApplicationControlProperty nacp, SectionItem parentItem, DirectoryEntryEx directoryEntry) : base(parentItem, directoryEntry) { Nacp = nacp; ParentItem = parentItem ?? throw new ArgumentNullException(nameof(parentItem)); AddOnContentBaseId = Nacp.AddOnContentBaseId.ToStrId(); }
private bool IsUpdateApplied(string titleId, out string version) { string updatePath = "(unknown)"; try { (Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateData(_virtualFileSystem, titleId, 0, out updatePath); if (patchNca != null && controlNca != null) { ApplicationControlProperty controlData = new ApplicationControlProperty(); controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(out IFile nacpFile, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure(); nacpFile.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure(); version = controlData.DisplayVersion.ToString(); return(true); } } catch (InvalidDataException) { Logger.Warning?.Print(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {updatePath}"); } catch (MissingKeyException exception) { Logger.Warning?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {updatePath}"); } version = ""; return(false); }
private void GetGameInformation(ref ApplicationControlProperty controlData, out string titleName, out string titleId, out string publisher, out string version) { _ = Enum.TryParse(_desiredTitleLanguage.ToString(), out TitleLanguage desiredTitleLanguage); if (controlData.Title.ItemsRo.Length > (int)desiredTitleLanguage) { titleName = controlData.Title[(int)desiredTitleLanguage].NameString.ToString(); publisher = controlData.Title[(int)desiredTitleLanguage].PublisherString.ToString(); } else { titleName = null; publisher = null; } if (string.IsNullOrWhiteSpace(titleName)) { foreach (ref readonly var controlTitle in controlData.Title.ItemsRo) { if (!controlTitle.NameString.IsEmpty()) { titleName = controlTitle.NameString.ToString(); break; } } } if (string.IsNullOrWhiteSpace(publisher)) { foreach (ref readonly var controlTitle in controlData.Title.ItemsRo) { if (!controlTitle.PublisherString.IsEmpty()) { publisher = controlTitle.PublisherString.ToString(); break; } } } if (controlData.PresenceGroupId != 0) { titleId = controlData.PresenceGroupId.ToString("x16"); } else if (controlData.SaveDataOwnerId != 0) { titleId = controlData.SaveDataOwnerId.ToString(); } else if (controlData.AddOnContentBaseId != 0) { titleId = (controlData.AddOnContentBaseId - 0x1000).ToString("x16"); } else { titleId = "0000000000000000"; } version = controlData.DisplayVersionString.ToString(); }
public static void EnsureApplicationSaveData_CreatesAccountSaveData() { FileSystemClient fs = FileSystemServerFactory.CreateClient(true); var applicationId = new Ncm.ApplicationId(11); var userId = new Uid(2, 3); var nacp = new ApplicationControlProperty { UserAccountSaveDataSize = 0x1000, UserAccountSaveDataJournalSize = 0x1000 }; Assert.Success(EnsureApplicationSaveData(fs, out _, applicationId, ref nacp, ref userId)); fs.OpenSaveDataIterator(out SaveDataIterator iterator, SaveDataSpaceId.User); var info = new SaveDataInfo[2]; Assert.Success(iterator.ReadSaveDataInfo(out long entriesRead, info)); Assert.Equal(1, entriesRead); Assert.Equal(applicationId, info[0].ProgramId); Assert.Equal(ConvertAccountUidToFsUserId(userId), info[0].UserId); Assert.Equal(SaveDataType.Account, info[0].Type); }
private void GetNameIdDeveloper(ref ApplicationControlProperty controlData, out string titleName, out string titleId, out string publisher) { _ = Enum.TryParse(_desiredTitleLanguage.ToString(), out TitleLanguage desiredTitleLanguage); if (controlData.Titles.Length > (int)desiredTitleLanguage) { titleName = controlData.Titles[(int)desiredTitleLanguage].Name.ToString(); publisher = controlData.Titles[(int)desiredTitleLanguage].Publisher.ToString(); } else { titleName = null; publisher = null; } if (string.IsNullOrWhiteSpace(titleName)) { foreach (ApplicationControlTitle controlTitle in controlData.Titles) { if (!((U8Span)controlTitle.Name).IsEmpty()) { titleName = controlTitle.Name.ToString(); break; } } } if (string.IsNullOrWhiteSpace(publisher)) { foreach (ApplicationControlTitle controlTitle in controlData.Titles) { if (!((U8Span)controlTitle.Publisher).IsEmpty()) { publisher = controlTitle.Publisher.ToString(); break; } } } if (controlData.PresenceGroupId != 0) { titleId = controlData.PresenceGroupId.ToString("x16"); } else if (controlData.SaveDataOwnerId.Value != 0) { titleId = controlData.SaveDataOwnerId.ToString(); } else if (controlData.AddOnContentBaseId != 0) { titleId = (controlData.AddOnContentBaseId - 0x1000).ToString("x16"); } else { titleId = "0000000000000000"; } }
private void AddUpdate(string path, bool showErrorDialog = true) { if (File.Exists(path)) { using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read)) { PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage()); try { (Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateDataFromPartition(_virtualFileSystem, nsp, _titleId, 0); if (controlNca != null && patchNca != null) { ApplicationControlProperty controlData = new ApplicationControlProperty(); controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(out IFile nacpFile, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure(); nacpFile.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure(); RadioButton radioButton = new RadioButton($"Version {controlData.DisplayVersion.ToString()} - {path}"); radioButton.JoinGroup(_noUpdateRadioButton); _availableUpdatesBox.Add(radioButton); _radioButtonToPathDictionary.Add(radioButton, path); radioButton.Show(); radioButton.Active = true; } else { GtkDialog.CreateErrorDialog("The specified file does not contain an update for the selected title!"); } } catch (InvalidDataException exception) { Logger.Error?.Print(LogClass.Application, $"{exception.Message}. Errored File: {path}"); if (showErrorDialog) { GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add Update Failed!", "The NCA header content type check has failed. This is usually because the header key is incorrect or missing."); } } catch (MissingKeyException exception) { Logger.Error?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {path}"); if (showErrorDialog) { GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add Update Failed!", $"Your key set is missing a key with the name: {exception.Name}"); } } } } }
private bool TryFindSaveData(string titleName, ulong titleId, BlitStruct <ApplicationControlProperty> controlHolder, SaveDataFilter filter, out ulong saveDataId) { saveDataId = default; Result result = _virtualFileSystem.FsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); if (ResultFs.TargetNotFound.Includes(result)) { // Savedata was not found. Ask the user if they want to create it using MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.YesNo, null) { Title = "PangoNX Debugger", Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"), Text = $"There is no savedata for {titleName} [{titleId:x16}]", SecondaryText = "Would you like to create savedata for this game?", WindowPosition = WindowPosition.Center }; if (messageDialog.Run() != (int)ResponseType.Yes) { return(false); } ref ApplicationControlProperty control = ref controlHolder.Value; if (LibHac.Util.IsEmpty(controlHolder.ByteSpan)) { // If the current application doesn't have a loaded control property, create a dummy one // and set the savedata sizes so a user savedata will be created. control = ref new BlitStruct <ApplicationControlProperty>(1).Value; // The set sizes don't actually matter as long as they're non-zero because we use directory savedata. control.UserAccountSaveDataSize = 0x4000; control.UserAccountSaveDataJournalSize = 0x4000; Logger.PrintWarning(LogClass.Application, "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games."); } Uid user = new Uid(1, 0); result = EnsureApplicationSaveData(_virtualFileSystem.FsClient, out _, new TitleId(titleId), ref control, ref user); if (result.IsFailure()) { GtkDialog.CreateErrorDialog($"There was an error creating the specified savedata: {result.ToStringWithName()}"); return(false); } // Try to find the savedata again after creating it result = _virtualFileSystem.FsClient.FindSaveDataWithFilter(out saveDataInfo, SaveDataSpaceId.User, ref filter); }
static string ListApplications(SwitchFs sdfs) { var sb = new StringBuilder(); foreach (Application app in sdfs.Applications.Values.OrderBy(x => x.Name)) { if (app.Main != null) { sb.AppendLine($"{app.Name} v{app.DisplayVersion} ({app.Main.Id.ToString("X16")})"); sb.AppendLine($"Software: {Utilities.GetBytesReadable(app.Main.GetSize())}"); } else { sb.AppendLine($"{app.Name} v{app.DisplayVersion}"); } if (app.Patch != null) { sb.AppendLine($"Update Data: {Utilities.GetBytesReadable(app.Patch.GetSize())}"); } if (app.AddOnContent.Count > 0) { sb.AppendLine($"DLC: {Utilities.GetBytesReadable(app.AddOnContent.Sum(x => x.GetSize()))}"); } ref ApplicationControlProperty nacp = ref app.Nacp.Value; long userTotalSaveDataSize = nacp.UserAccountSaveDataSize + nacp.UserAccountSaveDataJournalSize; long deviceTotalSaveDataSize = nacp.DeviceSaveDataSize + nacp.DeviceSaveDataJournalSize; if (userTotalSaveDataSize > 0) { sb.AppendLine($"User save: {Utilities.GetBytesReadable(userTotalSaveDataSize)}"); } if (deviceTotalSaveDataSize > 0) { sb.AppendLine($"System save: {Utilities.GetBytesReadable(deviceTotalSaveDataSize)}"); } if (nacp.BcatDeliveryCacheStorageSize > 0) { sb.AppendLine($"BCAT save: {Utilities.GetBytesReadable(nacp.BcatDeliveryCacheStorageSize)}"); } sb.AppendLine(); }
public static void GetCacheStorageTargetMedia_ReturnsTargetOfNewCacheStorage(bool isSdCardInserted) { FileSystemClient fs = FileSystemServerFactory.CreateClient(isSdCardInserted); var applicationId = new Ncm.ApplicationId(11); var nacp = new ApplicationControlProperty { CacheStorageSize = 0x1000, CacheStorageJournalSize = 0x1000 }; fs.EnsureApplicationCacheStorage(out _, out CacheStorageTargetMedia targetFromCreation, applicationId, ref nacp); Assert.Success(fs.GetCacheStorageTargetMedia(out CacheStorageTargetMedia target, applicationId)); Assert.Equal(targetFromCreation, target); }
private void AddUpdate(string path) { if (File.Exists(path)) { using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read)) { PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage()); try { (Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateDataFromPartition(_virtualFileSystem, nsp, _titleId, 0); if (controlNca != null && patchNca != null) { ApplicationControlProperty controlData = new ApplicationControlProperty(); using var nacpFile = new UniqueRef <IFile>(); controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref(), "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure(); nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure(); RadioButton radioButton = new RadioButton($"Version {controlData.DisplayVersion.ToString()} - {path}"); radioButton.JoinGroup(_noUpdateRadioButton); _availableUpdatesBox.Add(radioButton); _radioButtonToPathDictionary.Add(radioButton, path); radioButton.Show(); radioButton.Active = true; } else { GtkDialog.CreateErrorDialog("The specified file does not contain an update for the selected title!"); } } catch (Exception exception) { GtkDialog.CreateErrorDialog($"{exception.Message}. Errored File: {path}"); } } } }
// nn::friends::AddPlayHistory(nn::account::Uid, u64, pid, buffer<nn::friends::PlayHistoryRegistrationKey, 0x19>, buffer<nn::friends::InAppScreenName, 0x19>, buffer<nn::friends::InAppScreenName, 0x19>) public ResultCode AddPlayHistory(ServiceCtx context) { UserId userId = context.RequestData.ReadStruct <UserId>(); // Pid placeholder context.RequestData.ReadInt64(); long pid = context.Request.HandleDesc.PId; ulong playHistoryRegistrationKeyPosition = context.Request.PtrBuff[0].Position; ulong PlayHistoryRegistrationKeySize = context.Request.PtrBuff[0].Size; ulong inAppScreenName1Position = context.Request.PtrBuff[1].Position; ulong inAppScreenName1Size = context.Request.PtrBuff[1].Size; ulong inAppScreenName2Position = context.Request.PtrBuff[2].Position; ulong inAppScreenName2Size = context.Request.PtrBuff[2].Size; if (userId.IsNull || inAppScreenName1Size > 0x48 || inAppScreenName2Size > 0x48) { return(ResultCode.InvalidArgument); } // TODO: Call nn::arp::GetApplicationControlProperty here when implemented. ApplicationControlProperty controlProperty = context.Device.Application.ControlData.Value; /* * * NOTE: The service calls nn::friends::detail::service::core::PlayHistoryManager to store informations using the registration key computed in GetPlayHistoryRegistrationKey. * Then calls nn::friends::detail::service::core::FriendListManager to update informations on the friend list. * We currently don't support play history and online services so it's fine to do nothing. * */ Logger.Stub?.PrintStub(LogClass.ServiceFriend); return(ResultCode.Success); }
public void LoadProgram(string filePath) { Npdm metaData = GetDefaultNpdm(); bool isNro = Path.GetExtension(filePath).ToLower() == ".nro"; FileStream input = new FileStream(filePath, FileMode.Open); IExecutable staticObject; if (isNro) { NxRelocatableObject obj = new NxRelocatableObject(input); staticObject = obj; // homebrew NRO can actually have some data after the actual NRO if (input.Length > obj.FileSize) { input.Position = obj.FileSize; BinaryReader reader = new BinaryReader(input); uint asetMagic = reader.ReadUInt32(); if (asetMagic == 0x54455341) { uint asetVersion = reader.ReadUInt32(); if (asetVersion == 0) { ulong iconOffset = reader.ReadUInt64(); ulong iconSize = reader.ReadUInt64(); ulong nacpOffset = reader.ReadUInt64(); ulong nacpSize = reader.ReadUInt64(); ulong romfsOffset = reader.ReadUInt64(); ulong romfsSize = reader.ReadUInt64(); if (romfsSize != 0) { Device.FileSystem.SetRomFs(new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset)); } if (nacpSize != 0) { input.Seek(obj.FileSize + (long)nacpOffset, SeekOrigin.Begin); reader.Read(ControlData.ByteSpan); ref ApplicationControlProperty nacp = ref ControlData.Value; metaData.TitleName = nacp.Titles[(int)State.DesiredTitleLanguage].Name.ToString(); if (string.IsNullOrWhiteSpace(metaData.TitleName)) { metaData.TitleName = nacp.Titles.ToArray().FirstOrDefault(x => x.Name[0] != 0).Name.ToString(); } if (nacp.PresenceGroupId != 0) { metaData.Aci0.TitleId = nacp.PresenceGroupId; } else if (nacp.SaveDataOwnerId.Value != 0) { metaData.Aci0.TitleId = nacp.SaveDataOwnerId.Value; } else if (nacp.AddOnContentBaseId != 0) { metaData.Aci0.TitleId = nacp.AddOnContentBaseId - 0x1000; } else { metaData.Aci0.TitleId = 0000000000000000; } } } else { Logger.PrintWarning(LogClass.Loader, $"Unsupported ASET header version found \"{asetVersion}\""); } } } }
public static Result EnsureApplicationBcatDeliveryCacheStorage(this FileSystemClient fs, out long requiredSize, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp) { return(EnsureApplicationBcatDeliveryCacheStorageImpl(fs, out requiredSize, applicationId, ref nacp)); }
public static Result EnsureApplicationCacheStorage(this FileSystemClient fs, out long requiredSize, out CacheStorageTargetMedia target, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp) { if (nacp.CacheStorageSize <= 0) { requiredSize = default; target = default; return(Result.Success); } return(EnsureApplicationCacheStorageImpl(fs, out requiredSize, out target, applicationId, nacp.SaveDataOwnerId.Value, 0, nacp.CacheStorageSize, nacp.CacheStorageJournalSize, true)); }
public static Result EnsureApplicationCacheStorage(this FileSystemClient fs, out long requiredSize, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp) { return(EnsureApplicationCacheStorageImpl(fs, out requiredSize, out _, applicationId, nacp.SaveDataOwnerId.Value, 0, nacp.CacheStorageSize, nacp.CacheStorageJournalSize, true)); }
private static Result EnsureApplicationBcatDeliveryCacheStorageImpl(FileSystemClient fs, out long requiredSize, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp) { const long bcatDeliveryCacheJournalSize = 0x200000; 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 CreateBcatStorageFunc() => fs.CreateBcatSaveData(applicationId, bcatStorageSize); Result rc = EnsureAndExtendSaveData(fs, CreateBcatStorageFunc, ref requiredSizeBcat, ref filter, 0x4000, bcatStorageSize, bcatDeliveryCacheJournalSize); if (rc.IsFailure()) { return(rc); } requiredSize = requiredSizeBcat; return(requiredSizeBcat > 0 ? ResultFs.InsufficientFreeSpace.Log() : Result.Success); }
public static Result EnsureApplicationSaveData(FileSystemClient fs, out long requiredSize, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp, ref Uid uid) { requiredSize = default; long requiredSizeSum = 0; // Create local variable for use in closures ProgramId 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.Value, 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)); // The 0x4c000 includes the save meta and other stuff Result rc = EnsureAndExtendSaveData(fs, CreateAccountSaveFunc, ref requiredSizeSum, ref filter, 0x4c000, accountSaveDataSize, accountSaveJournalSize); 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.Value, deviceSaveDataSize, deviceSaveJournalSize, 0); var filter = new SaveDataFilter(); filter.SetProgramId(applicationId); filter.SetSaveDataType(SaveDataType.Device); Result rc = EnsureAndExtendSaveData(fs, CreateDeviceSaveFunc, ref requiredSizeSum, ref filter, 0x4000, deviceSaveDataSize, deviceSaveJournalSize); if (rc.IsFailure()) { return(rc); } } Result bcatRc = EnsureApplicationBcatDeliveryCacheStorageImpl(fs, out long requiredSizeBcat, applicationId, ref nacp); if (bcatRc.IsFailure()) { if (!ResultFs.InsufficientFreeSpace.Includes(bcatRc)) { return(bcatRc); } requiredSizeSum += requiredSizeBcat; } if (nacp.TemporaryStorageSize > 0) { if (requiredSizeSum > 0) { // If there was already insufficient space to create the previous saves, check if the temp // save already exists instead of trying to create a new one. var filter = new SaveDataFilter(); filter.SetProgramId(applicationId); filter.SetSaveDataType(SaveDataType.Temporary); Result rc = fs.FindSaveDataWithFilter(out _, SaveDataSpaceId.Temporary, ref filter); if (rc.IsFailure()) { if (!ResultFs.TargetNotFound.Includes(rc)) { return(rc); } Result queryRc = fs.QuerySaveDataTotalSize(out long tempSaveTotalSize, nacp.TemporaryStorageSize, 0); if (queryRc.IsFailure()) { return(queryRc); } requiredSizeSum += Utilities.AlignUp(tempSaveTotalSize, 0x4000) + 0x4000; } } else { Result createRc = fs.CreateTemporaryStorage(applicationId, nacp.SaveDataOwnerId.Value, nacp.TemporaryStorageSize, 0); if (createRc.IsFailure()) { if (ResultFs.InsufficientFreeSpace.Includes(createRc)) { Result queryRc = fs.QuerySaveDataTotalSize(out long tempSaveTotalSize, nacp.TemporaryStorageSize, 0); if (queryRc.IsFailure()) { return(queryRc); } requiredSizeSum += Utilities.AlignUp(tempSaveTotalSize, 0x4000) + 0x4000; } else if (ResultFs.PathAlreadyExists.Includes(createRc)) { requiredSizeSum += 0; } else { return(createRc); } } } } requiredSize = requiredSizeSum; return(requiredSize == 0 ? Result.Success : ResultFs.InsufficientFreeSpace.Log()); }
public Result GetApplicationControlProperty(out ApplicationControlProperty controlProperty, ApplicationId applicationId) { EnsureReaderInitialized(); return(Reader.GetApplicationControlPropertyWithApplicationId(out controlProperty, applicationId)); }
public Result GetApplicationControlProperty(out ApplicationControlProperty controlProperty, ulong processId) { throw new NotImplementedException(); }
public TitleUpdateModel(ApplicationControlProperty control, string path, bool isNoUpdate = false) { Control = control; Path = path; IsNoUpdate = isNoUpdate; }
public static Result CreateApplicationCacheStorage(this FileSystemClient fs, out long requiredSize, out CacheStorageTargetMedia target, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp, ushort index, long dataSize, long journalSize) { UnsafeHelpers.SkipParamInit(out requiredSize, out target); if (index > nacp.CacheStorageMaxIndex) { return(ResultFs.CacheStorageIndexTooLarge.Log()); } if (dataSize + journalSize > nacp.CacheStorageMaxSizeAndMaxJournalSize) { return(ResultFs.CacheStorageSizeTooLarge.Log()); } Result rc = fs.EnsureApplicationCacheStorage(out requiredSize, out target, applicationId, nacp.SaveDataOwnerId.Value, index, dataSize, journalSize, false); fs.Impl.AbortIfNeeded(rc); return(rc); }
public static Result EnsureApplicationSaveData(FileSystemClient fs, out long requiredSize, TitleId applicationId, ref ApplicationControlProperty nacp, ref Uid uid) { requiredSize = default; long requiredSizeSum = 0; if (uid != Uid.Zero && nacp.UserAccountSaveDataSize > 0) { var filter = new SaveDataFilter(); filter.SetTitleId(applicationId); filter.SetSaveDataType(SaveDataType.SaveData); filter.SetUserId(new UserId(uid.Id.High, uid.Id.Low)); Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); if (rc.IsSuccess()) { rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeUser, SaveDataSpaceId.User, saveDataInfo.SaveDataId, nacp.UserAccountSaveDataSize, nacp.UserAccountSaveDataJournalSize); if (rc.IsFailure()) { if (!ResultRangeFs.InsufficientFreeSpace.Contains(rc)) { return(rc); } requiredSizeSum = requiredSizeUser; } } else if (rc != ResultFs.TargetNotFound) { return(rc); } else { UserId userId = ConvertAccountUidToFsUserId(uid); Result createRc = fs.CreateSaveData(applicationId, userId, nacp.SaveDataOwnerId, nacp.UserAccountSaveDataSize, nacp.UserAccountSaveDataJournalSize, 0); if (createRc.IsFailure()) { if (ResultRangeFs.InsufficientFreeSpace.Contains(createRc)) { // todo: Call QuerySaveDataTotalSize and assign the value to requiredSizeSum requiredSizeSum = 0; } else if (createRc == ResultFs.PathAlreadyExists) { requiredSizeSum = 0; } else { return(createRc); } } } } if (nacp.DeviceSaveDataSize > 0) { var filter = new SaveDataFilter(); filter.SetTitleId(applicationId); filter.SetSaveDataType(SaveDataType.DeviceSaveData); Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); if (rc.IsSuccess()) { rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeDevice, SaveDataSpaceId.User, saveDataInfo.SaveDataId, nacp.DeviceSaveDataSize, nacp.DeviceSaveDataJournalSize); if (rc.IsFailure()) { if (!ResultRangeFs.InsufficientFreeSpace.Contains(rc)) { return(rc); } requiredSizeSum += requiredSizeDevice; } } else if (rc != ResultFs.TargetNotFound) { return(rc); } else { Result createRc = fs.CreateDeviceSaveData(applicationId, nacp.SaveDataOwnerId, nacp.DeviceSaveDataSize, nacp.DeviceSaveDataJournalSize, 0); if (createRc.IsFailure()) { if (ResultRangeFs.InsufficientFreeSpace.Contains(createRc)) { // todo: Call QuerySaveDataTotalSize and add the value to requiredSizeSum requiredSizeSum += 0; } else if (createRc == ResultFs.PathAlreadyExists) { requiredSizeSum += 0; } else { return(createRc); } } } } Result bcatRc = EnsureApplicationBcatDeliveryCacheStorageImpl(fs, out long requiredSizeBcat, applicationId, ref nacp); if (bcatRc.IsFailure()) { if (!ResultRangeFs.InsufficientFreeSpace.Contains(bcatRc)) { return(bcatRc); } requiredSizeSum += requiredSizeBcat; } // Don't actually do this yet because the temp save indexer hasn't been implemented // todo: Flip the operator when it is if (nacp.TemporaryStorageSize < 0) { if (requiredSizeSum > 0) { var filter = new SaveDataFilter(); filter.SetTitleId(applicationId); filter.SetSaveDataType(SaveDataType.TemporaryStorage); Result rc = fs.FindSaveDataWithFilter(out _, SaveDataSpaceId.User, ref filter); if (rc.IsFailure()) { if (rc != ResultFs.TargetNotFound) { return(rc); } // todo: Call QuerySaveDataTotalSize and add the value to requiredSizeSum requiredSizeSum += 0; } } else { Result createRc = fs.CreateTemporaryStorage(applicationId, nacp.SaveDataOwnerId, nacp.TemporaryStorageSize, 0); if (createRc.IsFailure()) { if (ResultRangeFs.InsufficientFreeSpace.Contains(createRc)) { // todo: Call QuerySaveDataTotalSize and assign the value to requiredSizeSum requiredSizeSum += 0; } else if (createRc == ResultFs.PathAlreadyExists) { requiredSizeSum += 0; } else { return(createRc); } } } } requiredSize = requiredSizeSum; return(requiredSize == 0 ? Result.Success : ResultFs.InsufficientFreeSpace.Log()); }
public Result GetApplicationControlPropertyWithApplicationId(out ApplicationControlProperty controlProperty, ApplicationId applicationId) { throw new NotImplementedException(); }
private static Result EnsureApplicationBcatDeliveryCacheStorageImpl(FileSystemClient fs, out long requiredSize, TitleId applicationId, ref ApplicationControlProperty nacp) { const long bcatDeliveryCacheJournalSize = 0x200000; requiredSize = default; if (nacp.BcatDeliveryCacheStorageSize <= 0) { requiredSize = 0; return(Result.Success); } var filter = new SaveDataFilter(); filter.SetTitleId(applicationId); filter.SetSaveDataType(SaveDataType.BcatDeliveryCacheStorage); Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); if (rc.IsSuccess()) { rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeBcat, SaveDataSpaceId.User, saveDataInfo.SaveDataId, nacp.DeviceSaveDataSize, bcatDeliveryCacheJournalSize); if (rc.IsFailure()) { if (!ResultRangeFs.InsufficientFreeSpace.Contains(rc)) { return(rc); } requiredSize = requiredSizeBcat; } } else if (rc != ResultFs.TargetNotFound) { return(rc); } else { Result createRc = fs.CreateBcatSaveData(applicationId, nacp.BcatDeliveryCacheStorageSize); if (createRc.IsFailure()) { if (ResultRangeFs.InsufficientFreeSpace.Contains(createRc)) { // todo: Call QuerySaveDataTotalSize and assign the value to requiredSize requiredSize = 0; } else if (createRc == ResultFs.PathAlreadyExists) { requiredSize = 0; } else { return(createRc); } } } return(requiredSize > 0 ? ResultFs.InsufficientFreeSpace.Log() : Result.Success); }
public Result GetApplicationControlProperty(out ApplicationControlProperty controlProperty, ulong processId) { EnsureReaderInitialized(); return(Reader.GetApplicationControlProperty(out controlProperty, processId)); }