コード例 #1
0
        public Result OpenHostFileSystem(out ReferenceCountedDisposable <IFileSystem> fileSystem, U8Span path,
                                         bool openCaseSensitive)
        {
            UnsafeHelpers.SkipParamInit(out fileSystem);
            Result rc;

            if (!path.IsEmpty())
            {
                rc = Util.VerifyHostPath(path);
                if (rc.IsFailure())
                {
                    return(rc);
                }
            }

            // Todo: Return shared fs from Create
            rc = FsCreators.TargetManagerFileSystemCreator.Create(out IFileSystem hostFs, openCaseSensitive);
            if (rc.IsFailure())
            {
                return(rc);
            }

            ReferenceCountedDisposable <IFileSystem> sharedHostFs = null;
            ReferenceCountedDisposable <IFileSystem> subDirFs     = null;

            try
            {
                sharedHostFs = new ReferenceCountedDisposable <IFileSystem>(hostFs);

                if (path.IsEmpty())
                {
                    ReadOnlySpan <byte> rootHostPath = new[] { (byte)'C', (byte)':', (byte)'/' };
                    rc = sharedHostFs.Target.GetEntryType(out _, new U8Span(rootHostPath));

                    // Nintendo ignores all results other than this one
                    if (ResultFs.TargetNotFound.Includes(rc))
                    {
                        return(rc);
                    }

                    Shared.Move(out fileSystem, ref sharedHostFs);
                    return(Result.Success);
                }

                rc = FsCreators.SubDirectoryFileSystemCreator.Create(out subDirFs, ref sharedHostFs, path,
                                                                     preserveUnc: true);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                fileSystem = subDirFs;
                return(Result.Success);
            }
            finally
            {
                sharedHostFs?.Dispose();
                subDirFs?.Dispose();
            }
        }
コード例 #2
0
        public static bool IsValidMountName(this FileSystemClientImpl fs, U8Span name)
        {
            if (name.IsEmpty())
            {
                return(false);
            }

            // Check for a single-letter mount name
            if ((name.Length <= 1 || name[1] == 0) &&
                ('a' <= name[0] && name[0] <= 'z' || 'A' <= name[0] && name[0] <= 'Z'))
            {
                return(false);
            }

            // Check for mount or directory separators
            int length = 0;

            for (int i = 0; i < name.Length && name[i] != 0; i++)
            {
                if (PathTool.IsDriveSeparator(name[i]) || PathTool.IsSeparator(name[i]))
                {
                    return(false);
                }

                if (++length > PathTools.MountNameLengthMax)
                {
                    return(false);
                }
            }

            // Todo: VerifyUtf8String
            return(true);
        }
コード例 #3
0
ファイル: Util.cs プロジェクト: garoxas/LibHac
        public static Result VerifyHostPath(U8Span path)
        {
            if (path.IsEmpty())
            {
                return(Result.Success);
            }

            if (path[0] != StringTraits.DirectorySeparator)
            {
                return(ResultFs.InvalidPathFormat.Log());
            }

            U8Span path2 = path.Slice(1);

            if (path2.IsEmpty())
            {
                return(Result.Success);
            }

            int skipLength      = WindowsPath.GetWindowsPathSkipLength(path2);
            int remainingLength = PathTools.MaxPathLength - skipLength;

            Result rc = PathUtility.VerifyPath(null, path2.Slice(skipLength), remainingLength, remainingLength);

            if (rc.IsFailure())
            {
                return(rc);
            }

            using var normalizer = new PathNormalizer(path, PathNormalizer.Option.PreserveUnc);
            return(normalizer.Result);
        }
コード例 #4
0
ファイル: FileSystemAccessor.cs プロジェクト: garoxas/LibHac
        public FileSystemAccessor(FileSystemClient fsClient, U8Span name, IMultiCommitTarget multiCommitTarget,
                                  IFileSystem fileSystem, ICommonMountNameGenerator mountNameGenerator,
                                  ISaveDataAttributeGetter saveAttributeGetter)
        {
            FsClient = fsClient;

            _fileSystem      = fileSystem;
            _openFiles       = new LinkedList <FileAccessor>();
            _openDirectories = new LinkedList <DirectoryAccessor>();
            _openListLock.Initialize();
            _mountNameGenerator      = mountNameGenerator;
            _saveDataAttributeGetter = saveAttributeGetter;
            _multiCommitTarget       = multiCommitTarget;

            if (name.IsEmpty())
            {
                Abort.DoAbort(ResultFs.InvalidMountName.Log());
            }

            if (StringUtils.GetLength(name, PathTool.MountNameLengthMax + 1) > PathTool.MountNameLengthMax)
            {
                Abort.DoAbort(ResultFs.InvalidMountName.Log());
            }

            StringUtils.Copy(_mountName.Name.Slice(0, PathTool.MountNameLengthMax), name);
            _mountName.Name[PathTool.MountNameLengthMax] = 0;
        }
コード例 #5
0
        public Result OpenHostFileSystem(out IFileSystem fileSystem, U8Span path, bool openCaseSensitive)
        {
            fileSystem = default;
            Result rc;

            if (!path.IsEmpty())
            {
                rc = Util.VerifyHostPath(path);
                if (rc.IsFailure())
                {
                    return(rc);
                }
            }

            rc = FsCreators.TargetManagerFileSystemCreator.Create(out IFileSystem hostFs, openCaseSensitive);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (path.IsEmpty())
            {
                ReadOnlySpan <byte> rootHostPath = new[] { (byte)'C', (byte)':', (byte)'/' };
                rc = hostFs.GetEntryType(out _, new U8Span(rootHostPath));

                // Nintendo ignores all results other than this one
                if (ResultFs.TargetNotFound.Includes(rc))
                {
                    return(rc);
                }

                fileSystem = hostFs;
                return(Result.Success);
            }

            rc = FsCreators.SubDirectoryFileSystemCreator.Create(out IFileSystem subDirFs, hostFs, path, preserveUnc: true);
            if (rc.IsFailure())
            {
                return(rc);
            }

            fileSystem = subDirFs;
            return(Result.Success);
        }
コード例 #6
0
        // Todo: Make case sensitive
        public Result Create(out ReferenceCountedDisposable <IFileSystem> fileSystem, U8Span rootPath,
                             BisPartitionId partitionId, bool caseSensitive)
        {
            UnsafeHelpers.SkipParamInit(out fileSystem);

            if (!IsValidPartitionId(partitionId))
            {
                return(ResultFs.InvalidArgument.Log());
            }
            if (rootPath.IsNull())
            {
                return(ResultFs.NullptrArgument.Log());
            }

            if (Config.TryGetFileSystem(out IFileSystem fs, partitionId))
            {
                fileSystem = new ReferenceCountedDisposable <IFileSystem>(fs);
                return(Result.Success);
            }

            if (Config.RootFileSystem == null)
            {
                return(ResultFs.PreconditionViolation.Log());
            }

            var partitionPath = GetPartitionPath(partitionId).ToU8String();

            ReferenceCountedDisposable <IFileSystem> partitionFileSystem = null;
            ReferenceCountedDisposable <IFileSystem> sharedRootFs        = null;

            try
            {
                sharedRootFs = new ReferenceCountedDisposable <IFileSystem>(Config.RootFileSystem);

                Result rc = Utility.WrapSubDirectory(out partitionFileSystem, ref sharedRootFs, partitionPath, true);

                if (rc.IsFailure())
                {
                    return(rc);
                }

                if (rootPath.IsEmpty())
                {
                    Shared.Move(out fileSystem, ref partitionFileSystem);
                    return(Result.Success);
                }

                return(Utility.CreateSubDirectoryFileSystem(out fileSystem, ref partitionFileSystem, rootPath));
            }
            finally
            {
                partitionFileSystem?.Dispose();
                sharedRootFs?.Dispose();
            }
        }
コード例 #7
0
ファイル: PathNormalizer.cs プロジェクト: Icyelut/LibHac
 public PathNormalizer(U8Span path, Option option)
 {
     if (option.HasFlag(Option.AcceptEmpty) && path.IsEmpty())
     {
         _path  = path;
         Result = Result.Success;
     }
     else
     {
         bool preserveUnc           = option.HasFlag(Option.PreserveUnc);
         bool preserveTailSeparator = option.HasFlag(Option.PreserveTailSeparator);
         bool hasMountName          = option.HasFlag(Option.HasMountName);
         Result = Normalize(out _path, path, preserveUnc, preserveTailSeparator, hasMountName);
     }
 }