public static bool IsAbortNeeded(this FileSystemClientImpl fs, Result result)
        {
            if (result.IsSuccess())
            {
                return(false);
            }

            switch (fs.Fs.GetCurrentThreadFsContext().HandleResult(result))
            {
            case AbortSpecifier.Default:
                if (fs.Globals.ResultHandlingUtility.IsResultHandledByApplication)
                {
                    return(ResultFs.HandledByAllProcess.Includes(result));
                }
                else
                {
                    return(!(ResultFs.HandledByAllProcess.Includes(result) ||
                             ResultFs.HandledBySystemProcess.Includes(result)));
                }

            case AbortSpecifier.Abort:
                return(true);

            case AbortSpecifier.Return:
                return(false);

            default:
                Abort.UnexpectedDefault();
                return(default);
            }
        }
        public Result SetOpenType(OpenType type)
        {
            Assert.SdkRequires(type == OpenType.Normal || type == OpenType.Internal);

            switch (type)
            {
            case OpenType.Normal:
                if (_isNormalStorageOpened)
                {
                    return(ResultFs.TargetLocked.Log());
                }

                _isNormalStorageOpened = true;
                return(Result.Success);

            case OpenType.Internal:
                if (_isInternalStorageOpened)
                {
                    return(ResultFs.TargetLocked.Log());
                }

                _isInternalStorageOpened      = true;
                _isInternalStorageInvalidated = false;
                return(Result.Success);

            default:
                Abort.UnexpectedDefault();
                return(Result.Success);
            }
        }
        public void ResetIndexer(SaveDataSpaceId spaceId)
        {
            if (spaceId != SaveDataSpaceId.Temporary)
            {
                Abort.UnexpectedDefault();
            }

            // ReSharper disable once RedundantAssignment
            Result rc = _tempIndexer.Indexer.Reset();

            Assert.SdkAssert(rc.IsSuccess());
        }
Beispiel #4
0
        public static U8Span GetCustomStorageDirectoryName(CustomStorageId storageId)
        {
            switch (storageId)
            {
            case CustomStorageId.System:
            case CustomStorageId.SdCard:
                return(new U8Span(CustomStorageDirectoryName));

            default:
                Abort.UnexpectedDefault();
                return(default);
            }
        }
Beispiel #5
0
        private static ReadOnlySpan <byte> GetGameCardMountNameSuffix(GameCardPartition partition)
        {
            switch (partition)
            {
            case GameCardPartition.Update: return(CommonMountNames.GameCardFileSystemMountNameUpdateSuffix);

            case GameCardPartition.Normal: return(CommonMountNames.GameCardFileSystemMountNameNormalSuffix);

            case GameCardPartition.Secure: return(CommonMountNames.GameCardFileSystemMountNameSecureSuffix);

            default:
                Abort.UnexpectedDefault();
                return(default);
            }
        }
        public void InvalidateIndexer(SaveDataSpaceId spaceId)
        {
            // Note: Nintendo doesn't lock when doing this operation
            lock (_sdCardIndexer.Locker)
            {
                if (spaceId != SaveDataSpaceId.SdCache && spaceId != SaveDataSpaceId.SdSystem)
                {
                    Abort.UnexpectedDefault();
                }

                if (_sdCardIndexer.IsInitialized)
                {
                    _sdCardIndexer.Indexer.Dispose();
                    _sdCardIndexer.Indexer = null;
                }
            }
        }
Beispiel #7
0
        private static FileSystemProxyType ConvertToFileSystemProxyType(ContentType type)
        {
            switch (type)
            {
            case ContentType.Meta: return(FileSystemProxyType.Meta);

            case ContentType.Control: return(FileSystemProxyType.Control);

            case ContentType.Manual: return(FileSystemProxyType.Manual);

            case ContentType.Data: return(FileSystemProxyType.Data);

            default:
                Abort.UnexpectedDefault();
                return(default);
            }
        }
Beispiel #8
0
        public static bool IsSharedOpenNeeded(SaveDataType type)
        {
            switch (type)
            {
            case SaveDataType.System:
            case SaveDataType.Bcat:
            case SaveDataType.Temporary:
            case SaveDataType.Cache:
                return(false);

            case SaveDataType.Account:
            case SaveDataType.Device:
                return(true);

            default:
                Abort.UnexpectedDefault();
                return(default);
            }
        }
Beispiel #9
0
        public static bool CanUseIndexerReservedArea(SaveDataType type)
        {
            switch (type)
            {
            case SaveDataType.System:
            case SaveDataType.SystemBcat:
                return(true);

            case SaveDataType.Account:
            case SaveDataType.Bcat:
            case SaveDataType.Device:
            case SaveDataType.Temporary:
            case SaveDataType.Cache:
                return(false);

            default:
                Abort.UnexpectedDefault();
                return(default);
            }
        }
Beispiel #10
0
        /// <summary>
        /// Checks if a given path is normalized. Path must be a basic path, starting with a directory separator
        /// and not containing any sort of prefix such as a mount name.
        /// </summary>
        /// <param name="isNormalized">When this function returns <see cref="Result.Success"/>,
        /// contains <see langword="true"/> if the path is normalized or <see langword="false"/> if it is not.
        /// Contents are undefined if the function does not return <see cref="Result.Success"/>.
        /// </param>
        /// <param name="length">When this function returns <see cref="Result.Success"/> and
        /// <paramref name="isNormalized"/> is <see langword="true"/>, contains the length of the normalized path.
        /// Contents are undefined if the function does not return <see cref="Result.Success"/>
        /// or <paramref name="isNormalized"/> is <see langword="false"/>.
        /// </param>
        /// <param name="path">The path to check.</param>
        /// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
        /// <see cref="ResultFs.InvalidCharacter"/>: The path contains an invalid character.<br/>
        /// <see cref="ResultFs.InvalidPathFormat"/>: The path is not in a valid format.</returns>
        public static Result IsNormalized(out bool isNormalized, out int length, ReadOnlySpan <byte> path)
        {
            UnsafeHelpers.SkipParamInit(out isNormalized, out length);

            var state      = PathState.Initial;
            int pathLength = 0;

            for (int i = 0; i < path.Length; i++)
            {
                byte c = path[i];
                if (c == NullTerminator)
                {
                    break;
                }

                pathLength++;

                if (state != PathState.Initial)
                {
                    Result rc = CheckInvalidCharacter(c);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }
                }

                switch (state)
                {
                case PathState.Initial:
                    if (c != DirectorySeparator)
                    {
                        return(ResultFs.InvalidPathFormat.Log());
                    }

                    state = PathState.FirstSeparator;

                    break;

                case PathState.Normal:

                    if (c == DirectorySeparator)
                    {
                        state = PathState.Separator;
                    }

                    break;

                case PathState.FirstSeparator:
                case PathState.Separator:
                    if (c == DirectorySeparator)
                    {
                        isNormalized = false;
                        return(Result.Success);
                    }

                    state = c == Dot ? PathState.CurrentDir : PathState.Normal;
                    break;

                case PathState.CurrentDir:
                    if (c == DirectorySeparator)
                    {
                        isNormalized = false;
                        return(Result.Success);
                    }

                    state = c == Dot ? PathState.ParentDir : PathState.Normal;
                    break;

                case PathState.ParentDir:
                    if (c == DirectorySeparator)
                    {
                        isNormalized = false;
                        return(Result.Success);
                    }

                    state = PathState.Normal;
                    break;

                // ReSharper disable once UnreachableSwitchCaseDueToIntegerAnalysis
                default:
                    Abort.UnexpectedDefault();
                    break;
                }
            }

            switch (state)
            {
            case PathState.Initial:
                return(ResultFs.InvalidPathFormat.Log());

            case PathState.Normal:
            case PathState.FirstSeparator:
                isNormalized = true;
                break;

            case PathState.Separator:
            case PathState.CurrentDir:
            case PathState.ParentDir:
                isNormalized = false;
                break;

            // ReSharper disable once UnreachableSwitchCaseDueToIntegerAnalysis
            default:
                Abort.UnexpectedDefault();
                break;
            }

            length = pathLength;
            return(Result.Success);
        }