public Result CreateSaveDataFileSystemBySystemSaveDataId(ref SaveDataAttribute attribute, ref SaveDataCreationInfo creationInfo) { if (!IsSystemSaveDataId(attribute.SaveDataId)) { return(ResultFs.InvalidArgument.Log()); } SaveDataCreationInfo newCreationInfo = creationInfo; if (creationInfo.OwnerId == TitleId.Zero) { // todo: Assign the current program's ID // throw new NotImplementedException(); } // Missing permission checks if (attribute.Type == SaveDataType.SystemBcat) { newCreationInfo.OwnerId = SystemTitleIds.Bcat; } SaveMetaCreateInfo metaCreateInfo = default; OptionalHashSalt optionalHashSalt = default; return(CreateSaveDataFileSystemImpl(ref attribute, ref newCreationInfo, ref metaCreateInfo, ref optionalHashSalt, false)); }
public static Result CreateBcatSaveData(this FileSystemClient fs, TitleId applicationId, long size) { return(fs.RunOperationWithAccessLog(AccessLogTarget.System, () => { IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); var attribute = new SaveDataAttribute { TitleId = applicationId, Type = SaveDataType.Bcat }; var createInfo = new SaveDataCreationInfo { Size = size, JournalSize = 0x200000, BlockSize = 0x4000, OwnerId = SystemTitleIds.Bcat, Flags = 0, SpaceId = SaveDataSpaceId.User }; var metaInfo = new SaveMetaCreateInfo(); return fsProxy.CreateSaveDataFileSystem(ref attribute, ref createInfo, ref metaInfo); }, () => $", applicationid: 0x{applicationId.Value:X}, save_data_size: {size}")); }
public Result CreateSaveDataFileSystem(ref SaveDataAttribute attribute, ref SaveDataCreationInfo creationInfo, ref SaveMetaCreateInfo metaCreateInfo) { OptionalHashSalt hashSalt = default; return(CreateUserSaveDataFileSystem(ref attribute, ref creationInfo, ref metaCreateInfo, ref hashSalt)); }
public static Result CreateSaveData(this FileSystemClient fs, TitleId applicationId, UserId userId, TitleId ownerId, long size, long journalSize, HashSalt hashSalt, SaveDataFlags flags) { return(fs.RunOperationWithAccessLog(AccessLogTarget.System, () => { IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); var attribute = new SaveDataAttribute { TitleId = applicationId, UserId = userId, Type = SaveDataType.Account }; var createInfo = new SaveDataCreationInfo { Size = size, JournalSize = journalSize, BlockSize = 0x4000, OwnerId = ownerId, Flags = flags, SpaceId = SaveDataSpaceId.User }; var metaInfo = new SaveMetaCreateInfo { Type = SaveDataMetaType.Thumbnail, Size = 0x40060 }; return fsProxy.CreateSaveDataFileSystemWithHashSalt(ref attribute, ref createInfo, ref metaInfo, ref hashSalt); }, () => $", applicationid: 0x{applicationId.Value:X}, userid: 0x{userId}, save_data_owner_id: 0x{ownerId.Value:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:X8}")); }
public static Result CreateSystemSaveData(this FileSystemClient fs, SaveDataSpaceId spaceId, ulong saveDataId, UserId userId, TitleId ownerId, long size, long journalSize, SaveDataFlags flags) { return(fs.RunOperationWithAccessLog(AccessLogTarget.System, () => { IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); var attribute = new SaveDataAttribute { UserId = userId, SaveDataId = saveDataId }; var createInfo = new SaveDataCreationInfo { Size = size, JournalSize = journalSize, BlockSize = 0x4000, OwnerId = ownerId, Flags = flags, SpaceId = spaceId }; return fsProxy.CreateSaveDataFileSystemBySystemSaveDataId(ref attribute, ref createInfo); }, () => $", savedataspaceid: {spaceId}, savedataid: 0x{saveDataId:X}, userid: 0x{userId.Id.High:X16}{userId.Id.Low:X16}, save_data_owner_id: 0x{ownerId.Value:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:x8}")); }
public static Result CreateCacheStorage(this FileSystemClient fs, TitleId applicationId, SaveDataSpaceId spaceId, TitleId ownerId, short index, long size, long journalSize, SaveDataFlags flags) { return(fs.RunOperationWithAccessLog(AccessLogTarget.System, () => { IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); var attribute = new SaveDataAttribute { TitleId = applicationId, Type = SaveDataType.Cache, Index = index }; var creationInfo = new SaveDataCreationInfo { Size = size, JournalSize = journalSize, BlockSize = 0x4000, OwnerId = ownerId, Flags = flags, SpaceId = spaceId }; var metaInfo = new SaveMetaCreateInfo(); return fsProxy.CreateSaveDataFileSystem(ref attribute, ref creationInfo, ref metaInfo); }, () => $", applicationid: 0x{applicationId.Value:X}, savedataspaceid: {spaceId}, save_data_owner_id: 0x{ownerId.Value:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:X8}")); }
public static Result CreateDeviceSaveData(this FileSystemClient fs, Ncm.ApplicationId applicationId, ulong ownerId, long size, long journalSize, SaveDataFlags flags) { return(fs.RunOperationWithAccessLog(AccessLogTarget.System, () => { IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); var attribute = new SaveDataAttribute(applicationId, SaveDataType.Device, UserId.Zero, 0); var createInfo = new SaveDataCreationInfo { Size = size, JournalSize = journalSize, BlockSize = 0x4000, OwnerId = ownerId, Flags = flags, SpaceId = SaveDataSpaceId.User }; var metaInfo = new SaveMetaCreateInfo(); return fsProxy.CreateSaveDataFileSystem(ref attribute, ref createInfo, ref metaInfo); }, () => $", applicationid: 0x{applicationId.Value:X}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:X8}")); }
public ResultCode CreateSaveDataFileSystemBySystemSaveDataId(ServiceCtx context) { SaveDataAttribute attribute = context.RequestData.ReadStruct <SaveDataAttribute>(); SaveDataCreationInfo creationInfo = context.RequestData.ReadStruct <SaveDataCreationInfo>(); Result result = _baseFileSystemProxy.CreateSaveDataFileSystemBySystemSaveDataId(ref attribute, ref creationInfo); return((ResultCode)result.Value); }
public Result CreateSaveDataFileSystem(ulong saveDataId, ref SaveDataAttribute attribute, ref SaveDataCreationInfo creationInfo, U8Span rootPath, OptionalHashSalt hashSalt, bool something) { // Use directory save data for now Result rc = OpenSaveDataDirectory(out IFileSystem fileSystem, creationInfo.SpaceId, string.Empty, false); if (rc.IsFailure()) { return(rc); } return(fileSystem.EnsureDirectoryExists(GetSaveDataIdPath(saveDataId))); }
public ResultCode CreateSaveDataFileSystemWithHashSalt(ServiceCtx context) { SaveDataAttribute attribute = context.RequestData.ReadStruct <SaveDataAttribute>(); SaveDataCreationInfo creationInfo = context.RequestData.ReadStruct <SaveDataCreationInfo>(); SaveMetaCreateInfo metaCreateInfo = context.RequestData.ReadStruct <SaveMetaCreateInfo>(); HashSalt hashSalt = context.RequestData.ReadStruct <HashSalt>(); // TODO: There's currently no program registry for FS to reference. // Workaround that by setting the application ID and owner ID if they're not already set if (attribute.ProgramId == ProgramId.InvalidId) { attribute.ProgramId = new ProgramId(context.Device.Application.TitleId); } Result result = _baseFileSystemProxy.CreateSaveDataFileSystemWithHashSalt(ref attribute, ref creationInfo, ref metaCreateInfo, ref hashSalt); return((ResultCode)result.Value); }
public ResultCode CreateSaveDataFileSystem(ServiceCtx context) { SaveDataAttribute attribute = context.RequestData.ReadStruct <SaveDataAttribute>(); SaveDataCreationInfo creationInfo = context.RequestData.ReadStruct <SaveDataCreationInfo>(); SaveMetaCreateInfo metaCreateInfo = context.RequestData.ReadStruct <SaveMetaCreateInfo>(); // TODO: There's currently no program registry for FS to reference. // Workaround that by setting the application ID and owner ID if they're not already set if (attribute.ProgramId == ProgramId.InvalidId) { attribute.ProgramId = new ProgramId(context.Device.Application.TitleId); } Logger.Info?.Print(LogClass.ServiceFs, $"Creating save with title ID {attribute.ProgramId.Value:x16}"); Result result = _baseFileSystemProxy.CreateSaveDataFileSystem(ref attribute, ref creationInfo, ref metaCreateInfo); return((ResultCode)result.Value); }
private Result CreateUserSaveDataFileSystem(ref SaveDataAttribute attribute, ref SaveDataCreationInfo creationInfo, ref SaveMetaCreateInfo metaCreateInfo, ref OptionalHashSalt hashSalt) { return(CreateSaveDataFileSystemImpl(ref attribute, ref creationInfo, ref metaCreateInfo, ref hashSalt, false)); }
public Result CreateSaveDataFileSystemWithHashSalt(ref SaveDataAttribute attribute, ref SaveDataCreationInfo creationInfo, ref SaveMetaCreateInfo metaCreateInfo, ref HashSalt hashSalt) { var hashSaltCopy = new OptionalHashSalt { IsSet = true, HashSalt = hashSalt }; return(CreateUserSaveDataFileSystem(ref attribute, ref creationInfo, ref metaCreateInfo, ref hashSaltCopy)); }
private Result CreateSaveDataFileSystemImpl(ref SaveDataAttribute attribute, ref SaveDataCreationInfo creationInfo, ref SaveMetaCreateInfo metaCreateInfo, ref OptionalHashSalt hashSalt, bool something) { ulong saveDataId = 0; bool isDeleteNeeded = false; Result rc; SaveDataIndexerReader reader = default; try { if (attribute.SaveDataId == FileSystemServer.SaveIndexerId) { saveDataId = FileSystemServer.SaveIndexerId; rc = FsProxyCore.DoesSaveDataExist(out bool saveExists, creationInfo.SpaceId, saveDataId); if (rc.IsSuccess() && saveExists) { return(ResultFs.PathAlreadyExists.Log()); } isDeleteNeeded = true; } else { rc = FsServer.SaveDataIndexerManager.GetSaveDataIndexer(out reader, creationInfo.SpaceId); if (rc.IsFailure()) { return(rc); } SaveDataAttribute indexerKey = attribute; if (attribute.SaveDataId != 0 && attribute.UserId == UserId.Zero) { saveDataId = attribute.SaveDataId; rc = reader.Indexer.AddSystemSaveData(ref indexerKey); } else { if (attribute.Type != SaveDataType.System && attribute.Type != SaveDataType.SystemBcat) { if (reader.Indexer.IsFull()) { return(ResultKvdb.TooLargeKeyOrDbFull.Log()); } } rc = reader.Indexer.Add(out saveDataId, ref indexerKey); } if (ResultFs.SaveDataPathAlreadyExists.Includes(rc)) { return(ResultFs.PathAlreadyExists.LogConverted(rc)); } isDeleteNeeded = true; rc = reader.Indexer.SetState(saveDataId, SaveDataState.Creating); if (rc.IsFailure()) { return(rc); } SaveDataSpaceId indexerSpaceId = GetSpaceIdForIndexer(creationInfo.SpaceId); rc = reader.Indexer.SetSpaceId(saveDataId, indexerSpaceId); if (rc.IsFailure()) { return(rc); } // todo: calculate size long size = 0; rc = reader.Indexer.SetSize(saveDataId, size); if (rc.IsFailure()) { return(rc); } rc = reader.Indexer.Commit(); if (rc.IsFailure()) { return(rc); } } rc = FsProxyCore.CreateSaveDataFileSystem(saveDataId, ref attribute, ref creationInfo, SaveDataRootPath, hashSalt, false); if (rc.IsFailure()) { if (!ResultFs.PathAlreadyExists.Includes(rc)) { return(rc); } rc = DeleteSaveDataFileSystemImpl2(creationInfo.SpaceId, saveDataId); if (rc.IsFailure()) { return(rc); } rc = FsProxyCore.CreateSaveDataFileSystem(saveDataId, ref attribute, ref creationInfo, SaveDataRootPath, hashSalt, false); if (rc.IsFailure()) { return(rc); } } if (metaCreateInfo.Type != SaveDataMetaType.None) { rc = FsProxyCore.CreateSaveDataMetaFile(saveDataId, creationInfo.SpaceId, metaCreateInfo.Type, metaCreateInfo.Size); if (rc.IsFailure()) { return(rc); } if (metaCreateInfo.Type == SaveDataMetaType.Thumbnail) { rc = FsProxyCore.OpenSaveDataMetaFile(out IFile metaFile, saveDataId, creationInfo.SpaceId, metaCreateInfo.Type); using (metaFile) { if (rc.IsFailure()) { return(rc); } ReadOnlySpan <byte> metaFileData = stackalloc byte[0x20]; rc = metaFile.Write(0, metaFileData, WriteOption.Flush); if (rc.IsFailure()) { return(rc); } } } } if (attribute.SaveDataId == FileSystemServer.SaveIndexerId || something) { isDeleteNeeded = false; return(Result.Success); } rc = reader.Indexer.SetState(saveDataId, SaveDataState.Normal); if (rc.IsFailure()) { return(rc); } rc = reader.Indexer.Commit(); if (rc.IsFailure()) { return(rc); } isDeleteNeeded = false; return(Result.Success); } finally { // Revert changes if an error happened in the middle of creation if (isDeleteNeeded) { DeleteSaveDataFileSystemImpl2(creationInfo.SpaceId, saveDataId).IgnoreResult(); if (reader.IsInitialized && saveDataId != FileSystemServer.SaveIndexerId) { rc = reader.Indexer.GetBySaveDataId(out SaveDataIndexerValue value, saveDataId); if (rc.IsSuccess() && value.SpaceId == creationInfo.SpaceId) { reader.Indexer.Delete(saveDataId).IgnoreResult(); reader.Indexer.Commit().IgnoreResult(); } } } reader.Dispose(); } }