コード例 #1
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        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));
        }
コード例 #2
0
        public static Result CreateSaveData(this FileSystemClient fs, TitleId applicationId, UserId userId, TitleId ownerId,
                                            long size, long journalSize, HashSalt hashSalt, uint flags)
        {
            return(fs.RunOperationWithAccessLog(LocalAccessLogMode.System,
                                                () =>
            {
                IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();

                var attribute = new SaveDataAttribute
                {
                    TitleId = applicationId,
                    UserId = userId,
                    Type = SaveDataType.SaveData
                };

                var createInfo = new SaveDataCreateInfo
                {
                    Size = size,
                    JournalSize = journalSize,
                    BlockSize = 0x4000,
                    OwnerId = ownerId,
                    Flags = flags,
                    SpaceId = SaveDataSpaceId.User
                };

                var metaInfo = new SaveMetaCreateInfo
                {
                    Type = SaveMetaType.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{flags:x8}"));
        }
コード例 #3
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        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));
        }
コード例 #4
0
        public static Result CreateBcatSaveData(this FileSystemClient fs, TitleId applicationId, long size)
        {
            return(fs.RunOperationWithAccessLog(LocalAccessLogMode.System,
                                                () =>
            {
                IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();

                var attribute = new SaveDataAttribute
                {
                    TitleId = applicationId,
                    Type = SaveDataType.BcatDeliveryCacheStorage
                };

                var createInfo = new SaveDataCreateInfo
                {
                    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}"));
        }
コード例 #5
0
        public static Result CreateTemporaryStorage(this FileSystemClient fs, TitleId applicationId, TitleId ownerId, long size, uint flags)
        {
            return(fs.RunOperationWithAccessLog(LocalAccessLogMode.System,
                                                () =>
            {
                IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();

                var attribute = new SaveDataAttribute
                {
                    TitleId = applicationId,
                    Type = SaveDataType.TemporaryStorage
                };

                var createInfo = new SaveDataCreateInfo
                {
                    Size = size,
                    BlockSize = 0x4000,
                    OwnerId = ownerId,
                    Flags = flags,
                    SpaceId = SaveDataSpaceId.TemporaryStorage
                };

                var metaInfo = new SaveMetaCreateInfo();

                return fsProxy.CreateSaveDataFileSystem(ref attribute, ref createInfo, ref metaInfo);
            },
                                                () => $", applicationid: 0x{applicationId.Value:X}, save_data_owner_id: 0x{ownerId.Value:X}, save_data_size: {size}, save_data_flags: 0x{flags:x8}"));
        }
コード例 #6
0
        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}"));
        }
コード例 #7
0
        public static Result CreateBcatSaveData(this FileSystemClient fs, Ncm.ApplicationId applicationId, long size)
        {
            return(fs.RunOperationWithAccessLog(AccessLogTarget.System,
                                                () =>
            {
                IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();

                var attribute = new SaveDataAttribute(applicationId, SaveDataType.Bcat, UserId.Zero, 0);

                var createInfo = new SaveDataCreationInfo
                {
                    Size = size,
                    JournalSize = 0x200000,
                    BlockSize = 0x4000,
                    OwnerId = SystemProgramId.Bcat.Value,
                    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}"));
        }
コード例 #8
0
        public static Result CreateSaveData(this FileSystemClient fs, Ncm.ApplicationId applicationId, UserId userId,
                                            ulong ownerId, long size, long journalSize, SaveDataFlags flags)
        {
            return(fs.RunOperationWithAccessLog(AccessLogTarget.System,
                                                () =>
            {
                IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();

                var attribute = new SaveDataAttribute(applicationId, SaveDataType.Account, userId, 0);

                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.CreateSaveDataFileSystem(ref attribute, ref createInfo, ref metaInfo);
            },
                                                () =>
                                                $", applicationid: 0x{applicationId.Value:X}, userid: 0x{userId}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:X8}"));
        }
コード例 #9
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        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));
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        public static Result CreateTemporaryStorage(this FileSystemClient fs, Ncm.ApplicationId applicationId, ulong ownerId, long size, SaveDataFlags flags)
        {
            return(fs.RunOperationWithAccessLog(AccessLogTarget.System,
                                                () =>
            {
                IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();

                var attribute = new SaveDataAttribute(applicationId, SaveDataType.Temporary, UserId.Zero, 0);

                var createInfo = new SaveDataCreationInfo
                {
                    Size = size,
                    BlockSize = 0x4000,
                    OwnerId = ownerId,
                    Flags = flags,
                    SpaceId = SaveDataSpaceId.Temporary
                };

                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_flags: 0x{(int)flags:X8}"));
        }
コード例 #13
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
 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));
 }
コード例 #14
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        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();
            }
        }