public Result Create(out ReferenceCountedDisposable <IFileSystem> subDirFileSystem,
                             ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, U8Span path, bool preserveUnc)
        {
            UnsafeHelpers.SkipParamInit(out subDirFileSystem);

            // Verify the sub-path exists
            Result rc = baseFileSystem.Target.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);

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

            // Initialize the SubdirectoryFileSystem
            var subDir = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc);

            using var subDirShared = new ReferenceCountedDisposable <SubdirectoryFileSystem>(subDir);

            rc = subDirShared.Target.Initialize(path);
            if (rc.IsFailure())
            {
                return(rc);
            }

            subDirFileSystem = subDirShared.AddReference <IFileSystem>();
            return(Result.Success);
        }
示例#2
0
文件: Utility.cs 项目: garoxas/LibHac
        public static Result CreateSubDirectoryFileSystem(out ReferenceCountedDisposable <IFileSystem> subDirFileSystem,
                                                          ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, U8Span subPath, bool preserveUnc = false)
        {
            UnsafeHelpers.SkipParamInit(out subDirFileSystem);

            // Check if the directory exists
            Result rc = baseFileSystem.Target.OpenDirectory(out IDirectory dir, subPath, OpenDirectoryMode.Directory);

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

            dir.Dispose();

            var fs = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc);

            using (var subDirFs = new ReferenceCountedDisposable <SubdirectoryFileSystem>(fs))
            {
                rc = subDirFs.Target.Initialize(subPath);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                subDirFileSystem = subDirFs.AddReference <IFileSystem>();
                return(Result.Success);
            }
        }
示例#3
0
        public static SwitchFs OpenNandPartition(Keyset keyset, IAttributeFileSystem fileSystem)
        {
            var concatFs     = new ConcatenationFileSystem(fileSystem);
            var saveDirFs    = new SubdirectoryFileSystem(concatFs, "/save");
            var contentDirFs = new SubdirectoryFileSystem(concatFs, "/Contents");

            return(new SwitchFs(keyset, contentDirFs, saveDirFs));
        }
示例#4
0
        protected override IFileSystem CreateFileSystem()
        {
            var baseFs = new InMemoryFileSystem();

            var subFs = new SubdirectoryFileSystem(baseFs);

            subFs.Initialize("/".ToU8String()).ThrowIfFailure();
            return(subFs);
        }
示例#5
0
        public Result Create(out IFileSystem fileSystem, out ISaveDataExtraDataAccessor extraDataAccessor,
                             IFileSystem sourceFileSystem, ulong saveDataId, bool allowDirectorySaveData, bool useDeviceUniqueMac,
                             SaveDataType type, ITimeStampGenerator timeStampGenerator)
        {
            fileSystem        = default;
            extraDataAccessor = default;

            string saveDataPath = $"/{saveDataId:x16}";

            Result rc = sourceFileSystem.GetEntryType(out DirectoryEntryType entryType, saveDataPath);

            if (rc.IsFailure())
            {
                return(rc == ResultFs.PathNotFound ? ResultFs.TargetNotFound : rc);
            }

            switch (entryType)
            {
            case DirectoryEntryType.Directory:
                // Actual FS does this check
                // if (!allowDirectorySaveData) return ResultFs.InvalidSaveDataEntryType.Log();

                var subDirFs = new SubdirectoryFileSystem(sourceFileSystem, saveDataPath);

                rc = DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem saveFs, subDirFs);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                fileSystem = saveFs;

                // Todo: Dummy ISaveDataExtraDataAccessor

                return(Result.Success);

            case DirectoryEntryType.File:
                rc = sourceFileSystem.OpenFile(out IFile saveDataFile, saveDataPath, OpenMode.ReadWrite);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                var saveDataStorage = new DisposingFileStorage(saveDataFile);
                fileSystem = new SaveDataFileSystem(Keyset, saveDataStorage, IntegrityCheckLevel.ErrorOnInvalid, false);

                // Todo: ISaveDataExtraDataAccessor

                return(Result.Success);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#6
0
        public static SwitchFs OpenSdCard(Keyset keyset, IAttributeFileSystem fileSystem)
        {
            var concatFs     = new ConcatenationFileSystem(fileSystem);
            var saveDirFs    = new SubdirectoryFileSystem(concatFs, "/Nintendo/save");
            var contentDirFs = new SubdirectoryFileSystem(concatFs, "/Nintendo/Contents");

            var encSaveFs    = new AesXtsFileSystem(saveDirFs, keyset.SdCardKeys[0], 0x4000);
            var encContentFs = new AesXtsFileSystem(contentDirFs, keyset.SdCardKeys[1], 0x4000);

            return(new SwitchFs(keyset, encContentFs, encSaveFs));
        }
示例#7
0
        private (IFileSystem baseFs, IFileSystem subDirFs) CreateFileSystemInternal()
        {
            var baseFs = new InMemoryFileSystem();

            baseFs.CreateDirectory("/sub".ToU8Span());
            baseFs.CreateDirectory("/sub/path".ToU8Span());

            var subFs = new SubdirectoryFileSystem(baseFs);

            subFs.Initialize("/sub/path".ToU8String()).ThrowIfFailure();

            return(baseFs, subFs);
        }
示例#8
0
        public static SwitchFs OpenNandPartition(KeySet keySet, IAttributeFileSystem fileSystem)
        {
            var concatFs = new ConcatenationFileSystem(fileSystem);
            SubdirectoryFileSystem saveDirFs = null;

            if (concatFs.DirectoryExists("/save"))
            {
                SubdirectoryFileSystem.CreateNew(out saveDirFs, concatFs, "/save".ToU8String()).ThrowIfFailure();
            }

            SubdirectoryFileSystem.CreateNew(out SubdirectoryFileSystem contentDirFs, concatFs, "/Contents".ToU8String()).ThrowIfFailure();

            return(new SwitchFs(keySet, contentDirFs, saveDirFs));
        }
        public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, string path)
        {
            subDirFileSystem = default;

            Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);

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

            subDirFileSystem = new SubdirectoryFileSystem(baseFileSystem, path);

            return(Result.Success);
        }
示例#10
0
文件: Util.cs 项目: CaitSith2/libhac
        public static Result CreateSubFileSystemImpl(out IFileSystem subFileSystem, IFileSystem baseFileSystem, string path)
        {
            subFileSystem = default;

            if (path == null)
            {
                return(ResultFs.NullArgument.Log());
            }

            Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);

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

            subFileSystem = new SubdirectoryFileSystem(baseFileSystem, path);

            return(Result.Success);
        }
示例#11
0
        public static SwitchFs OpenSdCard(KeySet keySet, IAttributeFileSystem fileSystem)
        {
            var concatFs = new ConcatenationFileSystem(fileSystem);

            var contentDirFs = new SubdirectoryFileSystem(concatFs);

            contentDirFs.Initialize("/Nintendo/Contents".ToU8String()).ThrowIfFailure();

            AesXtsFileSystem encSaveFs = null;

            if (fileSystem.DirectoryExists("/Nintendo/save"))
            {
                var saveDirFs = new SubdirectoryFileSystem(concatFs);
                saveDirFs.Initialize("/Nintendo/save".ToU8String()).ThrowIfFailure();

                encSaveFs = new AesXtsFileSystem(saveDirFs, keySet.SdCardEncryptionKeys[0].DataRo.ToArray(), 0x4000);
            }

            var encContentFs = new AesXtsFileSystem(contentDirFs, keySet.SdCardEncryptionKeys[1].DataRo.ToArray(), 0x4000);

            return(new SwitchFs(keySet, encContentFs, encSaveFs));
        }
示例#12
0
        public Result Create(out ReferenceCountedDisposable <IFileSystem> fileSystem,
                             out ReferenceCountedDisposable <ISaveDataExtraDataAccessor> extraDataAccessor,
                             ISaveDataFileSystemCacheManager cacheManager, ref ReferenceCountedDisposable <IFileSystem> baseFileSystem,
                             SaveDataSpaceId spaceId, ulong saveDataId, bool allowDirectorySaveData, bool useDeviceUniqueMac,
                             bool isJournalingSupported, bool isMultiCommitSupported, bool openReadOnly, bool openShared,
                             ISaveDataCommitTimeStampGetter timeStampGetter)
        {
            Span <byte> saveImageName = stackalloc byte[0x12];

            UnsafeHelpers.SkipParamInit(out fileSystem, out extraDataAccessor);

            Assert.SdkRequiresNotNull(cacheManager);

            var sb = new U8StringBuilder(saveImageName);

            sb.Append((byte)'/').AppendFormat(saveDataId, 'x', 16);

            Result rc = baseFileSystem.Target.GetEntryType(out DirectoryEntryType type, new U8Span(saveImageName));

            if (rc.IsFailure())
            {
                return(ResultFs.PathNotFound.Includes(rc) ? ResultFs.TargetNotFound.LogConverted(rc) : rc);
            }

            if (type == DirectoryEntryType.Directory)
            {
                if (!allowDirectorySaveData)
                {
                    return(ResultFs.InvalidSaveDataEntryType.Log());
                }

                SubdirectoryFileSystem subDirFs = null;
                ReferenceCountedDisposable <DirectorySaveDataFileSystem> saveFs = null;
                try
                {
                    subDirFs = new SubdirectoryFileSystem(ref baseFileSystem);

                    rc = subDirFs.Initialize(new U8Span(saveImageName));
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    saveFs = DirectorySaveDataFileSystem.CreateShared(Shared.Move(ref subDirFs), _fsServer.Hos.Fs);

                    rc = saveFs.Target.Initialize(timeStampGetter, _randomGenerator, isJournalingSupported,
                                                  isMultiCommitSupported, !openReadOnly);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    fileSystem        = saveFs.AddReference <IFileSystem>();
                    extraDataAccessor = saveFs.AddReference <ISaveDataExtraDataAccessor>();

                    return(Result.Success);
                }
                finally
                {
                    subDirFs?.Dispose();
                    saveFs?.Dispose();
                }
            }

            ReferenceCountedDisposable <IStorage> fileStorage = null;

            try
            {
                Optional <OpenType> openType =
                    openShared ? new Optional <OpenType>(OpenType.Normal) : new Optional <OpenType>();

                rc = _fsServer.OpenSaveDataStorage(out fileStorage, ref baseFileSystem, spaceId, saveDataId,
                                                   OpenMode.ReadWrite, openType);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                if (!isJournalingSupported)
                {
                    throw new NotImplementedException();
                }

                // Todo: Properly handle shared storage
                fileSystem = new ReferenceCountedDisposable <IFileSystem>(new SaveDataFileSystem(_keySet,
                                                                                                 fileStorage.Target, IntegrityCheckLevel.ErrorOnInvalid, false));

                // Todo: ISaveDataExtraDataAccessor

                return(Result.Success);
            }
            finally
            {
                fileStorage?.Dispose();
            }
        }