protected override Result RenameDirectoryImpl(string oldPath, string newPath) { oldPath = PathTools.Normalize(oldPath); newPath = PathTools.Normalize(newPath); if (IsConcatenationFile(oldPath)) { return(ResultFs.PathNotFound.Log()); } return(BaseFileSystem.RenameDirectory(oldPath, newPath)); }
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode) { path = PathTools.Normalize(path.ToString()).TrimStart('/').ToU8Span(); if (!FileDict.TryGetValue(path.ToString(), out PartitionFileEntry entry)) { ThrowHelper.ThrowResult(ResultFs.PathNotFound.Value); } file = OpenFile(entry, mode); return(Result.Success); }
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path) { path = PathTools.Normalize(path); if (IsConcatenationFile(path)) { entryType = DirectoryEntryType.File; return(Result.Success); } return(BaseFileSystem.GetEntryType(out entryType, path)); }
protected override Result DeleteFileImpl(string path) { string localPath = ResolveLocalPath(PathTools.Normalize(path)); Result rc = GetFileInfo(out FileInfo file, localPath); if (rc.IsFailure()) { return(rc); } return(DeleteFileInternal(file)); }
protected override Result CreateDirectoryImpl(string path) { path = PathTools.Normalize(path); string parent = PathTools.GetParentDirectory(path); if (IsConcatenationFile(parent)) { // Cannot create a directory inside of a concatenation file return(ResultFs.PathNotFound.Log()); } return(BaseFileSystem.CreateDirectory(path)); }
protected override Result DeleteDirectoryRecursivelyImpl(string path) { string localPath = ResolveLocalPath(PathTools.Normalize(path)); Result rc = GetDirInfo(out DirectoryInfo dir, localPath); if (rc.IsFailure()) { return(rc); } return(DeleteDirectoryInternal(dir, true)); }
protected override Result RenameFileImpl(string oldPath, string newPath) { oldPath = PathTools.Normalize(oldPath); newPath = PathTools.Normalize(newPath); if (IsConcatenationFile(oldPath)) { return(BaseFileSystem.RenameDirectory(oldPath, newPath)); } else { return(BaseFileSystem.RenameFile(oldPath, newPath)); } }
public static Result CopyDirectory(this IFileSystem sourceFs, IFileSystem destFs, string sourcePath, string destPath, IProgressReport logger = null, CreateFileOptions options = CreateFileOptions.None) { Result rc; foreach (DirectoryEntryEx entry in sourceFs.EnumerateEntries(sourcePath, "*", SearchOptions.Default)) { string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePath, entry.Name)); string subDstPath = PathTools.Normalize(PathTools.Combine(destPath, entry.Name)); if (entry.Type == DirectoryEntryType.Directory) { destFs.EnsureDirectoryExists(subDstPath); rc = sourceFs.CopyDirectory(destFs, subSrcPath, subDstPath, logger, options); if (rc.IsFailure()) { return(rc); } } if (entry.Type == DirectoryEntryType.File) { destFs.CreateOrOverwriteFile(subDstPath, entry.Size, options); rc = sourceFs.OpenFile(out IFile srcFile, subSrcPath.ToU8Span(), OpenMode.Read); if (rc.IsFailure()) { return(rc); } using (srcFile) { rc = destFs.OpenFile(out IFile dstFile, subDstPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend); if (rc.IsFailure()) { return(rc); } using (dstFile) { logger?.LogMessage(subSrcPath); srcFile.CopyTo(dstFile, logger); } } } } return(Result.Success); }
protected override Result GetFileSizeImpl(out long fileSize, string path) { fileSize = default; string localPath = ResolveLocalPath(PathTools.Normalize(path)); Result rc = GetFileInfo(out FileInfo info, localPath); if (rc.IsFailure()) { return(rc); } return(GetSizeInternal(out fileSize, info)); }
public PartitionDirectory(PartitionFileSystem fs, string path, OpenDirectoryMode mode) { path = PathTools.Normalize(path); if (path != "/") { throw new DirectoryNotFoundException(); } ParentFileSystem = fs; Mode = mode; CurrentIndex = 0; }
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode) { directory = default; path = PathTools.Normalize(path); Result rc = BaseFileSystem.OpenDirectory(out IDirectory baseDir, path, mode); if (rc.IsFailure()) { return(rc); } directory = new AesXtsDirectory(BaseFileSystem, baseDir, path, mode); return(Result.Success); }
protected override Result QueryEntryImpl(Span <byte> outBuffer, ReadOnlySpan <byte> inBuffer, QueryId queryId, string path) { path = PathTools.Normalize(path); foreach (IFileSystem fs in Sources) { Result getEntryResult = fs.GetEntryType(out DirectoryEntryType type, path); if (getEntryResult.IsSuccess() && type != DirectoryEntryType.NotFound) { return(fs.QueryEntry(outBuffer, inBuffer, queryId, path)); } } return(ResultFs.PathNotFound.Log()); }
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options) { path = PathTools.Normalize(path); CreateFileOptions newOptions = options & ~CreateFileOptions.CreateConcatenationFile; if (!options.HasFlag(CreateFileOptions.CreateConcatenationFile)) { return(BaseFileSystem.CreateFile(path, size, newOptions)); } // A concatenation file directory can't contain normal files string parentDir = PathTools.GetParentDirectory(path); if (IsConcatenationFile(parentDir)) { // Cannot create a file inside of a concatenation file return(ResultFs.PathNotFound.Log()); } Result rc = BaseFileSystem.CreateDirectory(path, NxFileAttributes.Archive); if (rc.IsFailure()) { return(rc); } long remaining = size; for (int i = 0; remaining > 0; i++) { long fileSize = Math.Min(SubFileSize, remaining); string fileName = GetSubFilePath(path, i); Result createSubFileResult = BaseFileSystem.CreateFile(fileName, fileSize, CreateFileOptions.None); if (createSubFileResult.IsFailure()) { BaseFileSystem.DeleteDirectoryRecursively(path); return(createSubFileResult); } remaining -= fileSize; } return(Result.Success); }
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path) { path = PathTools.Normalize(path); foreach (IFileSystem fs in Sources) { Result getEntryResult = fs.GetEntryType(out DirectoryEntryType type, path); if (getEntryResult.IsSuccess() && type != DirectoryEntryType.NotFound) { return(fs.GetFileTimeStampRaw(out timeStamp, path)); } } timeStamp = default; return(ResultFs.PathNotFound.Log()); }
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode) { file = default; path = PathTools.Normalize(path); Result rc = BaseFileSystem.OpenFile(out IFile baseFile, path, mode | OpenMode.Read); if (rc.IsFailure()) { return(rc); } var xtsFile = new AesXtsFile(mode, baseFile, path, KekSource, ValidationKey, BlockSize); file = xtsFile; return(Result.Success); }
public static Result EnsureDirectoryExists(this IFileSystem fs, string path) { path = PathTools.Normalize(path); if (fs.DirectoryExists(path)) { return(Result.Success); } // Find the first subdirectory in the chain that doesn't exist int i; for (i = path.Length - 1; i > 0; i--) { if (path[i] == '/') { string subPath = path.Substring(0, i); if (fs.DirectoryExists(subPath)) { break; } } } // path[i] will be a '/', so skip that character i++; // loop until `path.Length - 1` so CreateDirectory won't be called multiple // times on path if the last character in the path is a '/' for (; i < path.Length - 1; i++) { if (path[i] == '/') { string subPath = path.Substring(0, i); Result rc = fs.CreateDirectory(subPath.ToU8Span()); if (rc.IsFailure()) { return(rc); } } } return(fs.CreateDirectory(path.ToU8Span())); }
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path) { path = PathTools.Normalize(path); foreach (IFileSystem fs in Sources) { Result getEntryResult = fs.GetEntryType(out DirectoryEntryType type, path); if (getEntryResult.IsSuccess() && type != DirectoryEntryType.NotFound) { entryType = type; return(Result.Success); } } entryType = DirectoryEntryType.NotFound; return(ResultFs.PathNotFound.Log()); }
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path) { entryType = DirectoryEntryType.NotFound; path = PathTools.Normalize(path); if (path == "/") { entryType = DirectoryEntryType.Directory; return(Result.Success); } if (FileDict.ContainsKey(path.TrimStart('/'))) { entryType = DirectoryEntryType.File; return(Result.Success); } return(ResultFs.PathNotFound.Log()); }
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode) { directory = default; path = PathTools.Normalize(path); if (IsConcatenationFile(path)) { return(ResultFs.PathNotFound.Log()); } Result rc = BaseFileSystem.OpenDirectory(out IDirectory parentDir, path, OpenDirectoryMode.All); if (rc.IsFailure()) { return(rc); } directory = new ConcatenationDirectory(this, BaseFileSystem, parentDir, mode, path); return(Result.Success); }
protected override Result GetFileAttributesImpl(string path, out NxFileAttributes attributes) { attributes = default; string localPath = ResolveLocalPath(PathTools.Normalize(path)); Result rc = GetFileInfo(out FileInfo info, localPath); if (rc.IsFailure()) { return(rc); } if (info.Attributes == (FileAttributes)(-1)) { attributes = default; return(ResultFs.PathNotFound.Log()); } attributes = info.Attributes.ToNxAttributes(); return(Result.Success); }
protected override Result DeleteFileImpl(string path) { path = PathTools.Normalize(path); if (!IsConcatenationFile(path)) { return(BaseFileSystem.DeleteFile(path)); } int count = GetSubFileCount(path); for (int i = 0; i < count; i++) { Result rc = BaseFileSystem.DeleteFile(GetSubFilePath(path, i)); if (rc.IsFailure()) { return(rc); } } return(BaseFileSystem.DeleteDirectory(path)); }
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode) { file = default; string fullPath = GetFullPath(PathTools.Normalize(path)); lock (Locker) { Result rc = BaseFs.OpenFile(out IFile baseFile, fullPath, mode); if (rc.IsFailure()) { return(rc); } file = new DirectorySaveDataFile(this, baseFile, mode); if (mode.HasFlag(OpenMode.Write)) { OpenWritableFileCount++; } return(Result.Success); } }
protected override Result CreateDirectoryImpl(string path, NxFileAttributes archiveAttribute) { string localPath = ResolveLocalPath(PathTools.Normalize(path)); Result rc = GetDirInfo(out DirectoryInfo dir, localPath); if (rc.IsFailure()) { return(rc); } if (dir.Exists) { return(ResultFs.PathAlreadyExists.Log()); } if (dir.Parent?.Exists != true) { return(ResultFs.PathNotFound.Log()); } return(CreateDirInternal(dir, archiveAttribute)); }
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path) { timeStamp = default; string localPath = ResolveLocalPath(PathTools.Normalize(path)); Result rc = GetFileInfo(out FileInfo file, localPath); if (rc.IsFailure()) { return(rc); } if (!file.Exists) { return(ResultFs.PathNotFound.Log()); } timeStamp.Created = new DateTimeOffset(File.GetCreationTime(localPath)).ToUnixTimeSeconds(); timeStamp.Accessed = new DateTimeOffset(File.GetLastAccessTime(localPath)).ToUnixTimeSeconds(); timeStamp.Modified = new DateTimeOffset(File.GetLastWriteTime(localPath)).ToUnixTimeSeconds(); return(Result.Success); }
protected override Result RenameDirectoryImpl(string oldPath, string newPath) { oldPath = PathTools.Normalize(oldPath); newPath = PathTools.Normalize(newPath); // todo: Return proper result codes // Official code procedure: // Make sure all file headers can be decrypted // Rename directory to the new path // Reencrypt file headers with new path // If no errors, return // Reencrypt any modified file headers with the old path // Rename directory to the old path Result rc = BaseFileSystem.RenameDirectory(oldPath, newPath); if (rc.IsFailure()) { return(rc); } try { RenameDirectoryImpl(oldPath, newPath, false); } catch (Exception) { RenameDirectoryImpl(oldPath, newPath, true); BaseFileSystem.RenameDirectory(oldPath, newPath); throw; } return(Result.Success); }
protected override Result CleanDirectoryRecursivelyImpl(string path) { string localPath = ResolveLocalPath(PathTools.Normalize(path)); foreach (string file in Directory.EnumerateFiles(localPath)) { Result rc = GetFileInfo(out FileInfo fileInfo, file); if (rc.IsFailure()) { return(rc); } rc = DeleteFileInternal(fileInfo); if (rc.IsFailure()) { return(rc); } } foreach (string dir in Directory.EnumerateDirectories(localPath)) { Result rc = GetDirInfo(out DirectoryInfo dirInfo, dir); if (rc.IsFailure()) { return(rc); } rc = DeleteDirectoryInternal(dirInfo, true); if (rc.IsFailure()) { return(rc); } } return(Result.Success); }
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path) { string fullPath = ResolveFullPath(PathTools.Normalize(path)); return(ParentFileSystem.GetEntryType(out entryType, fullPath)); }
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode) { string fullPath = ResolveFullPath(PathTools.Normalize(path)); return(ParentFileSystem.OpenFile(out file, fullPath, mode)); }
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode) { string fullPath = ResolveFullPath(PathTools.Normalize(path)); return(ParentFileSystem.OpenDirectory(out directory, fullPath, mode)); }
protected override Result DeleteFileImpl(string path) { string fullPath = ResolveFullPath(PathTools.Normalize(path)); return(ParentFileSystem.DeleteFile(fullPath)); }