コード例 #1
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        private Result GetSaveDataInfo(out SaveDataInfo info, SaveDataSpaceId spaceId, ref SaveDataAttribute attribute)
        {
            info = default;

            SaveDataIndexerReader reader = default;

            try
            {
                Result rc = FsServer.SaveDataIndexerManager.GetSaveDataIndexer(out reader, spaceId);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                rc = reader.Indexer.Get(out SaveDataIndexerValue value, ref attribute);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                SaveDataIndexer.GetSaveDataInfo(out info, ref attribute, ref value);
                return(Result.Success);
            }
            finally
            {
                reader.Dispose();
            }
        }
コード例 #2
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        public Result OpenSaveDataInfoReaderWithFilter(out ISaveDataInfoReader infoReader, SaveDataSpaceId spaceId,
                                                       ref SaveDataFilter filter)
        {
            infoReader = default;

            // Missing permission check

            SaveDataIndexerReader indexReader = default;

            try
            {
                Result rc = FsServer.SaveDataIndexerManager.GetSaveDataIndexer(out indexReader, spaceId);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                rc = indexReader.Indexer.OpenSaveDataInfoReader(out ISaveDataInfoReader baseInfoReader);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                var filterInternal = new SaveDataFilterInternal(ref filter, spaceId);

                infoReader = new SaveDataInfoFilterReader(baseInfoReader, ref filterInternal);

                return(Result.Success);
            }
            finally
            {
                indexReader.Dispose();
            }
        }
コード例 #3
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        private Result DeleteSaveDataFileSystemBySaveDataSpaceIdImpl(SaveDataSpaceId spaceId, ulong saveDataId)
        {
            if (saveDataId != FileSystemServer.SaveIndexerId)
            {
                SaveDataIndexerReader reader = default;

                try
                {
                    Result rc = FsServer.SaveDataIndexerManager.GetSaveDataIndexer(out reader, spaceId);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    rc = reader.Indexer.GetBySaveDataId(out SaveDataIndexerValue value, saveDataId);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    if (value.SpaceId != GetSpaceIdForIndexer(spaceId))
                    {
                        return(ResultFs.TargetNotFound.Log());
                    }
                }
                finally
                {
                    reader.Dispose();
                }
            }

            return(DeleteSaveDataFileSystemImpl(spaceId, saveDataId));
        }
コード例 #4
0
        public Result GetSaveDataIndexer(out SaveDataIndexerReader reader, SaveDataSpaceId spaceId)
        {
            switch (spaceId)
            {
            case SaveDataSpaceId.System:
            case SaveDataSpaceId.User:
                Monitor.Enter(_bisIndexer.Locker);

                if (!_bisIndexer.IsInitialized)
                {
                    _bisIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDb", SaveDataSpaceId.System, SaveDataId);
                }

                reader = new SaveDataIndexerReader(_bisIndexer.Indexer, _bisIndexer.Locker);
                return(Result.Success);

            case SaveDataSpaceId.SdSystem:
            case SaveDataSpaceId.SdCache:
                Monitor.Enter(_sdCardIndexer.Locker);

                // Missing reinitialize if SD handle is old

                if (!_sdCardIndexer.IsInitialized)
                {
                    _sdCardIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbSd", SaveDataSpaceId.SdSystem, SaveDataId);
                }

                reader = new SaveDataIndexerReader(_sdCardIndexer.Indexer, _sdCardIndexer.Locker);
                return(Result.Success);

            case SaveDataSpaceId.TemporaryStorage:
                throw new NotImplementedException();

            case SaveDataSpaceId.ProperSystem:
                Monitor.Enter(_safeIndexer.Locker);

                if (!_safeIndexer.IsInitialized)
                {
                    _safeIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbPr", SaveDataSpaceId.ProperSystem, SaveDataId);
                }

                reader = new SaveDataIndexerReader(_safeIndexer.Indexer, _safeIndexer.Locker);
                return(Result.Success);

            case SaveDataSpaceId.Safe:
                Monitor.Enter(_properSystemIndexer.Locker);

                if (!_properSystemIndexer.IsInitialized)
                {
                    _properSystemIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbSf", SaveDataSpaceId.Safe, SaveDataId);
                }

                reader = new SaveDataIndexerReader(_properSystemIndexer.Indexer, _properSystemIndexer.Locker);
                return(Result.Success);

            default:
                reader = default;
                return(ResultFs.InvalidArgument.Log());
            }
        }
コード例 #5
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        public Result OpenSaveDataInfoReader(out ISaveDataInfoReader infoReader)
        {
            infoReader = default;

            // Missing permission check

            SaveDataIndexerReader indexReader = default;

            try
            {
                Result rc = FsServer.SaveDataIndexerManager.GetSaveDataIndexer(out indexReader, SaveDataSpaceId.System);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                return(indexReader.Indexer.OpenSaveDataInfoReader(out infoReader));
            }
            finally
            {
                indexReader.Dispose();
            }
        }
コード例 #6
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        private Result OpenSaveDataFileSystemImpl(out IFileSystem fileSystem, out ulong saveDataId,
                                                  SaveDataSpaceId spaceId, ref SaveDataAttribute attribute, bool openReadOnly, bool cacheExtraData)
        {
            fileSystem = default;
            saveDataId = default;

            bool hasFixedId = attribute.SaveDataId != 0 && attribute.UserId == UserId.Zero;

            if (hasFixedId)
            {
                saveDataId = attribute.SaveDataId;
            }
            else
            {
                SaveDataAttribute indexerKey = attribute;

                Result rc = FsServer.SaveDataIndexerManager.GetSaveDataIndexer(out SaveDataIndexerReader tmpReader, spaceId);
                using SaveDataIndexerReader reader = tmpReader;
                if (rc.IsFailure())
                {
                    return(rc);
                }

                rc = reader.Indexer.Get(out SaveDataIndexerValue indexerValue, ref indexerKey);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                SaveDataSpaceId indexerSpaceId = GetSpaceIdForIndexer(spaceId);

                if (indexerValue.SpaceId != indexerSpaceId)
                {
                    return(ResultFs.TargetNotFound.Log());
                }

                if (indexerValue.State == SaveDataState.Extending)
                {
                    return(ResultFs.SaveDataIsExtending.Log());
                }

                saveDataId = indexerValue.SaveDataId;
            }

            Result saveFsResult = FsProxyCore.OpenSaveDataFileSystem(out fileSystem, spaceId, saveDataId,
                                                                     SaveDataRootPath.ToString(), openReadOnly, attribute.Type, cacheExtraData);

            if (saveFsResult.IsSuccess())
            {
                return(Result.Success);
            }

            if (!ResultFs.PathNotFound.Includes(saveFsResult) && !ResultFs.TargetNotFound.Includes(saveFsResult))
            {
                return(saveFsResult);
            }

            if (saveDataId != FileSystemServer.SaveIndexerId)
            {
                if (hasFixedId)
                {
                    // todo: remove save indexer entry
                }
            }

            if (ResultFs.PathNotFound.Includes(saveFsResult))
            {
                return(ResultFs.TargetNotFound.LogConverted(saveFsResult));
            }

            return(saveFsResult);
        }
コード例 #7
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();
            }
        }
コード例 #8
0
ファイル: FileSystemProxy.cs プロジェクト: leo60228/LibHac
        private Result DeleteSaveDataFileSystemImpl(SaveDataSpaceId spaceId, ulong saveDataId)
        {
            SaveDataIndexerReader reader = default;

            try
            {
                Result rc = FsServer.SaveDataIndexerManager.GetSaveDataIndexer(out reader, spaceId);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                if (saveDataId == FileSystemServer.SaveIndexerId)
                {
                    // missing: This save can only be deleted by the FS process itself
                }
                else
                {
                    if (spaceId != SaveDataSpaceId.ProperSystem && spaceId != SaveDataSpaceId.SafeMode)
                    {
                        rc = reader.Indexer.GetBySaveDataId(out SaveDataIndexerValue value, saveDataId);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }

                        spaceId = value.SpaceId;
                    }

                    rc = reader.Indexer.GetKey(out SaveDataAttribute key, saveDataId);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    if (key.Type == SaveDataType.System || key.Type == SaveDataType.SystemBcat)
                    {
                        // Check if permissions allow deleting system save data
                    }
                    else
                    {
                        // Check if permissions allow deleting save data
                    }

                    rc = reader.Indexer.SetState(saveDataId, SaveDataState.Creating);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    rc = reader.Indexer.Commit();
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }
                }

                rc = DeleteSaveDataFileSystemImpl2(spaceId, saveDataId);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                if (saveDataId != FileSystemServer.SaveIndexerId)
                {
                    rc = reader.Indexer.Delete(saveDataId);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    rc = reader.Indexer.Commit();
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }
                }

                return(Result.Success);
            }
            finally
            {
                reader.Dispose();
            }
        }
コード例 #9
0
        public Result GetSaveDataIndexer(out SaveDataIndexerReader reader, SaveDataSpaceId spaceId)
        {
            switch (spaceId)
            {
            case SaveDataSpaceId.System:
            case SaveDataSpaceId.User:
                Monitor.Enter(_bisIndexer.Locker);

                if (!_bisIndexer.IsInitialized)
                {
                    _bisIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDb".ToU8Span(), SaveDataSpaceId.System, SaveDataId);
                }

                reader = new SaveDataIndexerReader(_bisIndexer.Indexer, _bisIndexer.Locker);
                return(Result.Success);

            case SaveDataSpaceId.SdSystem:
            case SaveDataSpaceId.SdCache:
                Monitor.Enter(_sdCardIndexer.Locker);

                // todo: Missing reinitialize if SD handle is old

                if (!_sdCardIndexer.IsInitialized)
                {
                    _sdCardIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbSd".ToU8Span(), SaveDataSpaceId.SdSystem, SaveDataId);
                }

                reader = new SaveDataIndexerReader(_sdCardIndexer.Indexer, _sdCardIndexer.Locker);
                return(Result.Success);

            case SaveDataSpaceId.Temporary:
                Monitor.Enter(_tempIndexer.Locker);

                if (!_tempIndexer.IsInitialized)
                {
                    _tempIndexer.Indexer = new SaveDataIndexerLite();
                }

                reader = new SaveDataIndexerReader(_tempIndexer.Indexer, _tempIndexer.Locker);
                return(Result.Success);

            case SaveDataSpaceId.ProperSystem:
                Monitor.Enter(_safeIndexer.Locker);

                if (!_safeIndexer.IsInitialized)
                {
                    _safeIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbPr".ToU8Span(), SaveDataSpaceId.ProperSystem, SaveDataId);
                }

                reader = new SaveDataIndexerReader(_safeIndexer.Indexer, _safeIndexer.Locker);
                return(Result.Success);

            case SaveDataSpaceId.SafeMode:
                Monitor.Enter(_properSystemIndexer.Locker);

                if (!_properSystemIndexer.IsInitialized)
                {
                    _properSystemIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbSf".ToU8Span(), SaveDataSpaceId.SafeMode, SaveDataId);
                }

                reader = new SaveDataIndexerReader(_properSystemIndexer.Indexer, _properSystemIndexer.Locker);
                return(Result.Success);

            default:
                reader = default;
                return(ResultFs.InvalidArgument.Log());
            }
        }