Esempio n. 1
0
        public static bool IsMounted(this FileSystemClient fs, U8Span mountName)
        {
            Result      rc;
            bool        isMounted;
            Span <byte> logBuffer = stackalloc byte[0x30];

            if (fs.Impl.IsEnabledAccessLog() && fs.Impl.IsEnabledFileSystemAccessorAccessLog(mountName))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.IsMounted(out isMounted, mountName);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                ReadOnlySpan <byte> boolString = AccessLogImpl.ConvertFromBoolToAccessLogBooleanValue(isMounted);
                sb.Append(LogName).Append(mountName).Append(LogIsMounted).Append(boolString).Append((byte)'"');

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = fs.Impl.IsMounted(out isMounted, mountName);
            }
            fs.Impl.LogErrorMessage(rc);
            Abort.DoAbortUnless(rc.IsSuccess());

            return(isMounted);
        }
Esempio n. 2
0
        public static Result ReadDirectory(this FileSystemClient fs, out long entriesRead,
                                           Span <DirectoryEntry> entryBuffer, DirectoryHandle handle)
        {
            Result rc;

            if (fs.Impl.IsEnabledAccessLog() && fs.Impl.IsEnabledHandleAccessLog(handle))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = Get(handle).Read(out entriesRead, entryBuffer);
                Tick end = fs.Hos.Os.GetSystemTick();

                Span <byte> buffer = stackalloc byte[0x50];
                var         sb     = new U8StringBuilder(buffer, true);

                sb.Append(LogEntryBufferCount).AppendFormat(entryBuffer.Length)
                .Append(LogEntryCount).AppendFormat(entriesRead);
                fs.Impl.OutputAccessLog(rc, start, end, handle, new U8Span(sb.Buffer));
            }
            else
            {
                rc = Get(handle).Read(out entriesRead, entryBuffer);
            }

            fs.Impl.AbortIfNeeded(rc);
            return(rc);
        }
Esempio n. 3
0
        public static Result MountContentStorage(this FileSystemClient fs, U8Span mountName, ContentStorageId storageId)
        {
            Result      rc;
            Span <byte> logBuffer = stackalloc byte[0x40];

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = Mount(fs, mountName, storageId);
                Tick end = fs.Hos.Os.GetSystemTick();

                var idString = new IdString();
                var sb       = new U8StringBuilder(logBuffer, true);

                sb.Append(LogName).Append(mountName).Append(LogQuote)
                .Append(LogContentStorageId).Append(idString.ToString(storageId));

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = Mount(fs, mountName, storageId);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                fs.Impl.EnableFileSystemAccessorAccessLog(mountName);
            }

            return(Result.Success);
Esempio n. 4
0
        public static Result MountApplicationPackage(this FileSystemClient fs, U8Span mountName, U8Span path)
        {
            Result rc;

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = Mount(fs, mountName, path);
                Tick end = fs.Hos.Os.GetSystemTick();

                Span <byte> logBuffer = stackalloc byte[0x300];
                var         sb        = new U8StringBuilder(logBuffer, true);

                sb.Append(LogName).Append(mountName).Append(LogQuote)
                .Append(LogPath).Append(path).Append(LogQuote);

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = Mount(fs, mountName, path);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                fs.Impl.EnableFileSystemAccessorAccessLog(mountName);
            }

            return(Result.Success);
Esempio n. 5
0
        public static Result MountSystemSaveData(this FileSystemClient fs, U8Span mountName,
                                                 SaveDataSpaceId spaceId, ulong saveDataId, UserId userId)
        {
            Result      rc;
            Span <byte> logBuffer = stackalloc byte[0x90];

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = Mount(fs, mountName, spaceId, saveDataId, userId);
                Tick end = fs.Hos.Os.GetSystemTick();

                var idString = new IdString();
                var sb       = new U8StringBuilder(logBuffer, true);
                sb.Append(LogName).Append(mountName)
                .Append(LogSaveDataSpaceId).Append(idString.ToString(spaceId))
                .Append(LogSaveDataId).AppendFormat(saveDataId, 'X')
                .Append(LogUserId).AppendFormat(userId.Id.High, 'X', 16).AppendFormat(userId.Id.Low, 'X', 16);

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = Mount(fs, mountName, spaceId, saveDataId, userId);
            }

            fs.Impl.AbortIfNeeded(rc);
            return(rc);
        public Result ReadSaveDataInfo(out long readCount, Span <SaveDataInfo> buffer)
        {
            Result           rc;
            FileSystemClient fs        = FsClient;
            Span <byte>      logBuffer = stackalloc byte[0x50];

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System) && fs.Impl.IsEnabledHandleAccessLog(null))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = ReadSaveDataInfoImpl(out readCount, buffer);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogSize).AppendFormat(buffer.Length);

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = ReadSaveDataInfoImpl(out readCount, buffer);
            }

            fs.Impl.AbortIfNeeded(rc);
            return(rc);
        }
Esempio n. 7
0
        // todo: Decide how to handle SetBisRootForHost since it allows mounting any directory on the user's computer
        public static Result SetBisRootForHost(this FileSystemClient fs, BisPartitionId partitionId, U8Span rootPath)
        {
            FsPath sfPath;

            unsafe { _ = &sfPath; } // workaround for CS0165

            int pathLen = StringUtils.GetLength(rootPath, PathTools.MaxPathLength + 1);

            if (pathLen > PathTools.MaxPathLength)
            {
                return(ResultFs.TooLongPath.Log());
            }

            if (pathLen > 0)
            {
                byte endingSeparator = PathTool.IsSeparator(rootPath[pathLen - 1])
                    ? StringTraits.NullTerminator
                    : StringTraits.DirectorySeparator;

                var    sb = new U8StringBuilder(sfPath.Str);
                Result rc = sb.Append(rootPath).Append(endingSeparator).ToSfPath();
                if (rc.IsFailure())
                {
                    return(rc);
                }
            }
            else
            {
                sfPath.Str[0] = StringTraits.NullTerminator;
            }

            IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();

            return(fsProxy.SetBisRootForHost(partitionId, ref sfPath));
        }
Esempio n. 8
0
        /// <summary>
        /// Initializes a <see cref="FlatMapKeyValueStore{T}"/>. Reads and writes the store to and from the file imkvdb.arc
        /// in the specified <paramref name="rootPath"/> directory. This directory must exist when calling <see cref="Initialize"/>,
        /// but it is not required for the imkvdb.arc file to exist.
        /// </summary>
        /// <param name="fsClient">The <see cref="FileSystemClient"/> to use for reading and writing the archive.</param>
        /// <param name="rootPath">The directory path used to load and save the archive file. Directory must already exist.</param>
        /// <param name="capacity">The maximum number of entries that can be stored.</param>
        /// <param name="memoryResource"><see cref="MemoryResource"/> for allocating buffers to hold entries and values.</param>
        /// <param name="autoBufferMemoryResource"><see cref="MemoryResource"/> for allocating temporary buffers
        /// when reading and writing the store to a file.</param>
        /// <returns>The <see cref="Result"/> of the operation.</returns>
        public Result Initialize(FileSystemClient fsClient, U8Span rootPath, int capacity,
                                 MemoryResource memoryResource, MemoryResource autoBufferMemoryResource)
        {
            // The root path must be an existing directory
            Result rc = fsClient.GetEntryType(out DirectoryEntryType rootEntryType, rootPath);

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

            if (rootEntryType == DirectoryEntryType.File)
            {
                return(ResultFs.PathNotFound.Log());
            }

            var sb = new U8StringBuilder(_archivePath.Get());

            sb.Append(rootPath).Append(ArchiveFileName);

            rc = _index.Initialize(capacity, memoryResource);
            if (rc.IsFailure())
            {
                return(rc);
            }

            _fsClient       = fsClient;
            _memoryResource = memoryResource;
            _memoryResourceForAutoBuffers = autoBufferMemoryResource;

            return(Result.Success);
        }
Esempio n. 9
0
        public static Result FromSpan(out FsPath fsPath, ReadOnlySpan <byte> path)
        {
            fsPath = new FsPath();

            U8StringBuilder builder = new U8StringBuilder(fsPath.Str).Append(path);

            return(builder.Overflowed ? ResultFs.TooLongPath.Log() : Result.Success);
        }
Esempio n. 10
0
        public static Result FromSpan(out FsPath fsPath, ReadOnlySpan <byte> path)
        {
            fsPath = new FsPath();

            var  sb         = new U8StringBuilder(fsPath.Str);
            bool overflowed = sb.Append(path).Overflowed;

            return(overflowed ? ResultFs.TooLongPath.Log() : Result.Success);
        }
Esempio n. 11
0
        private static void MakeRootPath(Span <byte> buffer, ReadOnlySpan <byte> mountName)
        {
            // returns "%s:/", mountName
            var sb = new U8StringBuilder(buffer);

            sb.Append(mountName);
            sb.Append(MountDelimiter);

            Debug.Assert(!sb.Overflowed);
        }
Esempio n. 12
0
        public static Result OpenDirectory(this FileSystemClient fs, out DirectoryHandle handle, U8Span path,
                                           OpenDirectoryMode mode)
        {
            UnsafeHelpers.SkipParamInit(out handle);

            Result             rc;
            U8Span             subPath;
            FileSystemAccessor fileSystem;
            Span <byte>        logBuffer = stackalloc byte[0x300];

            if (fs.Impl.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.FindFileSystem(out fileSystem, out subPath, path);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogPath).Append(path).Append((byte)'"').Append(LogOpenMode).AppendFormat((int)mode, 'X');
                logBuffer = sb.Buffer;

                fs.Impl.OutputAccessLogUnlessResultSuccess(rc, start, end, null, new U8Span(logBuffer));
            }
            else
            {
                rc = fs.Impl.FindFileSystem(out fileSystem, out subPath, path);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            DirectoryAccessor accessor;

            if (fs.Impl.IsEnabledAccessLog() && fileSystem.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fileSystem.OpenDirectory(out accessor, subPath, mode);
                Tick end = fs.Hos.Os.GetSystemTick();

                fs.Impl.OutputAccessLog(rc, start, end, accessor, new U8Span(logBuffer));
            }
            else
            {
                rc = fileSystem.OpenDirectory(out accessor, subPath, mode);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            handle = new DirectoryHandle(accessor);
            return(Result.Success);
        }
Esempio n. 13
0
        private static void MakeLastPublishedIdSaveFilePath(Span <byte> buffer, ReadOnlySpan <byte> mountName)
        {
            // returns "%s:/%s", mountName, "lastPublishedId"
            var sb = new U8StringBuilder(buffer);

            sb.Append(mountName);
            sb.Append(MountDelimiter);
            sb.Append(LastPublishedIdFileName);

            Debug.Assert(!sb.Overflowed);
        }
Esempio n. 14
0
        public static Result GetEntryType(this FileSystemClient fs, out DirectoryEntryType type, U8Span path)
        {
            UnsafeHelpers.SkipParamInit(out type);

            Result             rc;
            U8Span             subPath;
            FileSystemAccessor fileSystem;
            Span <byte>        logBuffer = stackalloc byte[0x300];

            if (fs.Impl.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.FindFileSystem(out fileSystem, out subPath, path);
                Tick end = fs.Hos.Os.GetSystemTick();

                var idString = new IdString();
                var sb       = new U8StringBuilder(logBuffer, true);
                sb.Append(LogPath).Append(path).Append(LogEntryType)
                .Append(idString.ToString(AccessLogImpl.DereferenceOutValue(in type, rc)));
                logBuffer = sb.Buffer;

                fs.Impl.OutputAccessLogUnlessResultSuccess(rc, start, end, null, new U8Span(logBuffer));
            }
            else
            {
                rc = fs.Impl.FindFileSystem(out fileSystem, out subPath, path);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog() && fileSystem.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fileSystem.GetEntryType(out type, subPath);
                Tick end = fs.Hos.Os.GetSystemTick();

                var idString = new IdString();
                var sb       = new U8StringBuilder(logBuffer, true);
                sb.Append(LogPath).Append(path).Append(LogEntryType)
                .Append(idString.ToString(AccessLogImpl.DereferenceOutValue(in type, rc)));
                logBuffer = sb.Buffer;

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(logBuffer));
            }
            else
            {
                rc = fileSystem.GetEntryType(out type, subPath);
            }
            fs.Impl.AbortIfNeeded(rc);
            return(rc);
        }
Esempio n. 15
0
        public static Result FromSpan(out FsPath fsPath, ReadOnlySpan <byte> path)
        {
            UnsafeHelpers.SkipParamInit(out fsPath);

            // Ensure null terminator even if the creation fails for safety
            fsPath.Str[MaxLength] = 0;

            var  sb         = new U8StringBuilder(fsPath.Str);
            bool overflowed = sb.Append(path).Overflowed;

            return(overflowed ? ResultFs.TooLongPath.Log() : Result.Success);
        }
        public Result Open(ulong applicationId)
        {
            lock (_locker)
            {
                // Find an existing storage entry for this application ID or get an empty one
                Result rc = FindOrGetUnusedEntry(out int index, applicationId);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                ref Entry entry = ref Entries[index];

                if (entry.RefCount != 0)
                {
                    return(ResultBcat.TargetLocked.Log());
                }

                // Get the mount name
                var mountName = new MountName();

                var sb = new U8StringBuilder(mountName.Name);
                sb.Append(DeliveryCacheMountNamePrefix)
                .AppendFormat(index, 'd', 2);

                // Mount the save if enabled
                if (!DisableStorage)
                {
                    rc = Server.GetFsClient()
                         .MountBcatSaveData(new U8Span(mountName.Name), new Ncm.ApplicationId(applicationId));

                    if (rc.IsFailure())
                    {
                        if (ResultFs.TargetNotFound.Includes(rc))
                        {
                            return(ResultBcat.SaveDataNotFound.LogConverted(rc));
                        }

                        return(rc);
                    }
                }

                // Update the storage entry
                entry.ApplicationId = applicationId;
                entry.RefCount++;

                return(Result.Success);
            }
Esempio n. 17
0
        public static Result CreateFile(this FileSystemClient fs, U8Span path, long size, CreateFileOptions options)
        {
            Result             rc;
            U8Span             subPath;
            FileSystemAccessor fileSystem;
            Span <byte>        logBuffer = stackalloc byte[0x300];

            if (fs.Impl.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.FindFileSystem(out fileSystem, out subPath, path);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogPath).Append(path).Append((byte)'"');
                logBuffer = sb.Buffer;

                fs.Impl.OutputAccessLogUnlessResultSuccess(rc, start, end, null, new U8Span(logBuffer));
            }
            else
            {
                rc = fs.Impl.FindFileSystem(out fileSystem, out subPath, path);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog() && fileSystem.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fileSystem.CreateFile(subPath, size, options);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogPath).Append(path).Append((byte)'"').Append(LogSize).AppendFormat(size);
                logBuffer = sb.Buffer;

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(logBuffer));
            }
            else
            {
                rc = fileSystem.CreateFile(subPath, size, options);
            }
            fs.Impl.AbortIfNeeded(rc);
            return(rc);
        }
Esempio n. 18
0
            public Result GenerateCommonMountName(Span <byte> nameBuffer)
            {
                int requiredNameBufferSize = StringUtils.GetLength(_path.Str, FsPath.MaxLength) + HostRootFileSystemPathLength;

                if (nameBuffer.Length < requiredNameBufferSize)
                {
                    return(ResultFs.TooLongPath.Log());
                }

                // ReSharper disable once RedundantAssignment
                int size = new U8StringBuilder(nameBuffer).Append(HostRootFileSystemPath).Append(_path.Str).Length;

                Debug.Assert(size == requiredNameBufferSize - 1);

                return(Result.Success);
            }
Esempio n. 19
0
            public Result GenerateCommonMountName(Span <byte> nameBuffer)
            {
                U8Span mountName = GetBisMountName(PartitionId);

                // Add 2 for the mount name separator and null terminator
                // ReSharper disable once RedundantAssignment
                int requiredNameBufferSize = StringUtils.GetLength(mountName, PathTools.MountNameLengthMax) + 2;

                Debug.Assert(nameBuffer.Length >= requiredNameBufferSize);

                // ReSharper disable once RedundantAssignment
                int size = new U8StringBuilder(nameBuffer).Append(mountName).Append(StringTraits.DriveSeparator).Length;

                Debug.Assert(size == requiredNameBufferSize - 1);

                return(Result.Success);
            }
Esempio n. 20
0
            public Result GenerateCommonMountName(Span <byte> nameBuffer)
            {
                int requiredNameBufferSize = StringUtils.GetLength(_path.Str, FsPath.MaxLength) + HostRootFileSystemPathLength;

                if (nameBuffer.Length < requiredNameBufferSize)
                {
                    return(ResultFs.TooLongPath.Log());
                }

                var sb = new U8StringBuilder(nameBuffer);

                sb.Append(HostRootFileSystemPath).Append(_path.Str);

                Debug.Assert(sb.Length == requiredNameBufferSize - 1);

                return(Result.Success);
            }
Esempio n. 21
0
            public Result GenerateCommonMountName(Span <byte> nameBuffer)
            {
                // Determine how much space we need.
                int neededSize =
                    StringUtils.GetLength(GetContentStorageMountName(StorageId), PathTool.MountNameLengthMax) + 2;

                Assert.True(nameBuffer.Length >= neededSize);

                // Generate the name.
                var sb = new U8StringBuilder(nameBuffer);

                sb.Append(GetContentStorageMountName(StorageId))
                .Append(StringTraits.DriveSeparator);

                Assert.True(sb.Length == neededSize - 1);

                return(Result.Success);
            }
Esempio n. 22
0
        private static Result CommitImpl(FileSystemClient fs, U8Span mountName,
                                         [CallerMemberName] string functionName = "")
        {
            Result             rc;
            FileSystemAccessor fileSystem;
            Span <byte>        logBuffer = stackalloc byte[0x30];

            if (fs.Impl.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.Find(out fileSystem, mountName);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogName).Append(mountName).Append((byte)'"');
                logBuffer = sb.Buffer;

                fs.Impl.OutputAccessLogUnlessResultSuccess(rc, start, end, null, new U8Span(logBuffer), functionName);
            }
            else
            {
                rc = fs.Impl.Find(out fileSystem, mountName);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog() && fileSystem.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fileSystem.Commit();
                Tick end = fs.Hos.Os.GetSystemTick();

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(logBuffer), functionName);
            }
            else
            {
                rc = fileSystem.Commit();
            }
            fs.Impl.AbortIfNeeded(rc);
            return(rc);
        }
Esempio n. 23
0
        public static Result Commit(this FileSystemClient fs, U8Span mountName, CommitOption option)
        {
            Result             rc;
            FileSystemAccessor fileSystem;
            Span <byte>        logBuffer = stackalloc byte[0x40];

            if (fs.Impl.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.Find(out fileSystem, mountName);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogName).Append(mountName).Append(LogCommitOption).AppendFormat((int)option.Flags, 'X');
                logBuffer = sb.Buffer;

                fs.Impl.OutputAccessLogUnlessResultSuccess(rc, start, end, null, new U8Span(logBuffer));
            }
            else
            {
                rc = fs.Impl.Find(out fileSystem, mountName);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog() && fileSystem.IsEnabledAccessLog())
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = RunCommit(fs, option, fileSystem);
                Tick end = fs.Hos.Os.GetSystemTick();

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(logBuffer));
            }
            else
            {
                rc = RunCommit(fs, option, fileSystem);
            }
            fs.Impl.AbortIfNeeded(rc);
            return(rc);
Esempio n. 24
0
        private Result TryOpenCaseSensitiveContentDirectory(out IFileSystem contentFileSystem,
                                                            IFileSystem baseFileSystem, U8Span path)
        {
            contentFileSystem = default;
            FsPath fullPath;

            unsafe { _ = &fullPath; } // workaround for CS0165

            var sb = new U8StringBuilder(fullPath.Str);

            sb.Append(path)
            .Append(new[] { (byte)'d', (byte)'a', (byte)'t', (byte)'a', (byte)'/' });

            if (sb.Overflowed)
            {
                return(ResultFs.TooLongPath.Log());
            }

            Result rc = FsCreators.TargetManagerFileSystemCreator.GetCaseSensitivePath(out bool success, fullPath.Str);

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

            // Reopen the host filesystem as case sensitive
            if (success)
            {
                baseFileSystem.Dispose();

                rc = OpenHostFileSystem(out baseFileSystem, U8Span.Empty, openCaseSensitive: true);
                if (rc.IsFailure())
                {
                    return(rc);
                }
            }

            return(FsCreators.SubDirectoryFileSystemCreator.Create(out contentFileSystem, baseFileSystem, fullPath));
        }
Esempio n. 25
0
        public static Result MountCacheStorage(this FileSystemClient fs, U8Span mountName,
                                               Ncm.ApplicationId applicationId, int index)
        {
            Result      rc;
            Span <byte> logBuffer = stackalloc byte[0x60];

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = MountSaveDataImpl(fs.Impl, mountName, SaveDataSpaceId.User, applicationId,
                                       Fs.SaveData.InvalidUserId, SaveDataType.Cache, openReadOnly: false, (ushort)index);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogName).Append(mountName).Append(LogQuote)
                .Append(LogApplicationId).AppendFormat(applicationId.Value, 'X')
                .Append(LogIndex).AppendFormat(index);

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = MountSaveDataImpl(fs.Impl, mountName, SaveDataSpaceId.User, applicationId,
                                       Fs.SaveData.InvalidUserId, SaveDataType.Cache, openReadOnly: false, (ushort)index);
            }

            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                fs.Impl.EnableFileSystemAccessorAccessLog(mountName);
            }

            return(rc);
        }
Esempio n. 26
0
        public static Result MountSaveData(this FileSystemClient fs, U8Span mountName, Ncm.ApplicationId applicationId,
                                           UserId userId)
        {
            Result      rc;
            Span <byte> logBuffer = stackalloc byte[0x90];

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.Application))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = MountSaveDataImpl(fs.Impl, mountName, SaveDataSpaceId.User, applicationId, userId,
                                       SaveDataType.Account, openReadOnly: false, index: 0);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogName).Append(mountName).Append(LogQuote)
                .Append(LogApplicationId).AppendFormat(applicationId.Value, 'X')
                .Append(LogUserId).AppendFormat(userId.Id.High, 'X', 16).AppendFormat(userId.Id.Low, 'X', 16);

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = MountSaveDataImpl(fs.Impl, mountName, SaveDataSpaceId.User, applicationId, userId,
                                       SaveDataType.Account, openReadOnly: false, index: 0);
            }

            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.Application))
            {
                fs.Impl.EnableFileSystemAccessorAccessLog(mountName);
            }

            return(rc);
        }
Esempio n. 27
0
        private static Result MountBis(this FileSystemClientImpl fs, U8Span mountName, BisPartitionId partitionId,
                                       U8Span rootPath)
        {
            Result rc;

            if (fs.IsEnabledAccessLog(AccessLogTarget.System))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = Mount(fs, mountName, partitionId);
                Tick end = fs.Hos.Os.GetSystemTick();

                Span <byte> logBuffer = stackalloc byte[0x300];
                var         idString  = new IdString();
                var         sb        = new U8StringBuilder(logBuffer, true);

                sb.Append(LogName).Append(mountName).Append(LogQuote)
                .Append(LogBisPartitionId).Append(idString.ToString(partitionId))
                .Append(LogPath).Append(rootPath).Append(LogQuote);

                fs.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = Mount(fs, mountName, partitionId);
            }

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

            if (fs.IsEnabledAccessLog(AccessLogTarget.System))
            {
                fs.EnableFileSystemAccessorAccessLog(mountName);
            }

            return(Result.Success);
Esempio n. 28
0
        public static void Unmount(this FileSystemClient fs, U8Span mountName)
        {
            Result      rc;
            Span <byte> logBuffer = stackalloc byte[0x30];

            if (fs.Impl.IsEnabledAccessLog() && fs.Impl.IsEnabledFileSystemAccessorAccessLog(mountName))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.Unmount(mountName);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogName).Append(mountName).Append((byte)'"');

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = fs.Impl.Unmount(mountName);
            }
            fs.Impl.LogErrorMessage(rc);
            Abort.DoAbortUnless(rc.IsSuccess());
        }
Esempio n. 29
0
        public static Result MountGameCardPartition(this FileSystemClient fs, U8Span mountName, GameCardHandle handle,
                                                    GameCardPartition partitionId)
        {
            Result      rc;
            Span <byte> logBuffer = stackalloc byte[0x60];

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = Mount(fs, mountName, handle, partitionId);
                Tick end = fs.Hos.Os.GetSystemTick();

                var idString = new IdString();
                var sb       = new U8StringBuilder(logBuffer, true);

                sb.Append(LogName).Append(mountName).Append(LogQuote)
                .Append(LogGameCardHandle).AppendFormat(handle.Value)
                .Append(LogGameCardPartition).Append(idString.ToString(partitionId));

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = Mount(fs, mountName, handle, partitionId);
            }
            fs.Impl.AbortIfNeeded(rc);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
            {
                fs.Impl.EnableFileSystemAccessorAccessLog(mountName);
            }

            return(Result.Success);
Esempio n. 30
0
            public Result GenerateCommonMountName(Span <byte> nameBuffer)
            {
                int handleDigitCount = Unsafe.SizeOf <GameCardHandle>() * 2;

                // Determine how much space we need.
                int neededSize =
                    StringUtils.GetLength(CommonMountNames.GameCardFileSystemMountName, PathTool.MountNameLengthMax) +
                    StringUtils.GetLength(GetGameCardMountNameSuffix(PartitionId), PathTool.MountNameLengthMax) +
                    handleDigitCount + 2;

                Assert.SdkRequiresGreaterEqual(nameBuffer.Length, neededSize);

                // Generate the name.
                var sb = new U8StringBuilder(nameBuffer);

                sb.Append(CommonMountNames.GameCardFileSystemMountName)
                .Append(GetGameCardMountNameSuffix(PartitionId))
                .AppendFormat(Handle.Value, 'x', (byte)handleDigitCount)
                .Append(StringTraits.DriveSeparator);

                Assert.SdkEqual(sb.Length, neededSize - 1);

                return(Result.Success);
            }