/// <summary> /// Deletes files and directories scheduled for deletion by the settings provider. /// </summary> /// <param name="settings"><see cref="ISettingsProvider"/> managing the files and directories scheduled for deletion.</param> /// <param name="provider"><see cref="IFileSystem"/> managing where the files and directories are located.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="settings"/> or <paramref name="provider"/> is null.</exception> protected async Task DeleteScheduledFiles(ISettingsProvider settings, IFileSystem provider) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (provider == null) { throw new ArgumentNullException(nameof(settings)); } // Files foreach (var item in settings.GetFilesScheduledForDeletion().ToList()) // Create a new list because the original will be continuously modified { if (CurrentFileSystem.FileExists(item)) { CurrentFileSystem.DeleteFile(item); } CurrentSettingsProvider.UnscheduleFileForDeletion(item); await CurrentSettingsProvider.Save(provider); } // Directories foreach (var item in settings.GetDirectoriesScheduledForDeletion().ToList()) { if (CurrentFileSystem.DirectoryExists(item)) { CurrentFileSystem.DeleteDirectory(item); } CurrentSettingsProvider.UnscheduleDirectoryForDeletion(item); await CurrentSettingsProvider.Save(provider); } }
bool IFileSystem.DirectoryExists(string path) { return(!BlacklistedPaths.Contains(FixPath(path)) && ((CurrentFileSystem != null && CurrentFileSystem.DirectoryExists(GetVirtualPath(path))) || DirectoryExists(GetPathParts(path)) )); }
Stream IFileSystem.OpenFileWriteOnly(string filename) { if (CurrentFileSystem != null) { throw new NotSupportedException("Cannot open a file as a stream without an IO provider."); } var virtualPath = GetVirtualPath(filename); if (!CurrentFileSystem.DirectoryExists(virtualPath)) { CurrentFileSystem.CreateDirectory(virtualPath); } CurrentFileSystem.WriteAllBytes(virtualPath, (this as IFileSystem).ReadAllBytes(filename)); return(CurrentFileSystem.OpenFileWriteOnly(filename)); }
string[] IFileSystem.GetDirectories(string path, bool topDirectoryOnly) { var parts = GetPathParts(path); var output = new List <string>(); void addRomFsDirectories(int partitionId) { var directory = "/" + GetRomFsDirectoryName(partitionId) + "/"; var currentDirectory = GetPartitionOrDefault(partitionId)?.RomFs?.Level3.RootDirectoryMetadataTable; for (int i = 1; i < parts.Length; i += 1) { currentDirectory = currentDirectory?.ChildDirectories.Where(x => string.Compare(x.Name, parts[i], true) == 0).FirstOrDefault(); directory += currentDirectory.Name + "/"; } if (currentDirectory != null) { var dirs = currentDirectory.ChildDirectories .Select(f => directory + f.Name + "/"); output.AddRange(dirs); if (!topDirectoryOnly) { foreach (var d in currentDirectory.ChildDirectories) { output.AddRange((this as IFileSystem).GetDirectories(directory + d.Name + "/", topDirectoryOnly)); } } } } var dirName = parts[0].ToLower(); switch (dirName) { case "" when parts.Length == 1: for (int i = 0; i < Partitions.Length; i++) { if (Partitions[i].ExeFs != null) { output.Add("/" + GetExeFsDirectoryName(i) + "/"); if (!topDirectoryOnly) { output.AddRange((this as IFileSystem).GetDirectories("/" + GetExeFsDirectoryName(i), topDirectoryOnly)); } } if (Partitions[i].RomFs != null) { output.Add("/" + GetRomFsDirectoryName(i) + "/"); if (!topDirectoryOnly) { output.AddRange((this as IFileSystem).GetDirectories("/" + GetRomFsDirectoryName(i), topDirectoryOnly)); } } } break; case "exefs" when parts.Length == 1: // ExeFs doesn't support directories break; case "romfs": case "romfs-partition-0": addRomFsDirectories(0); break; case "manual": case "romfs-partition-1": addRomFsDirectories(1); break; case "downloadplay": case "romfs-partition-2": addRomFsDirectories(2); break; case "n3dsupdate": case "romfs-partition-6": addRomFsDirectories(6); break; case "o3dsupdate": case "romfs-partition-7": addRomFsDirectories(7); break; default: if (dirName.StartsWith("romfs-partition-")) { var partitionNumRaw = dirName.Split("-".ToCharArray(), 3)[2]; if (int.TryParse(partitionNumRaw, out var partitionNum)) { addRomFsDirectories(partitionNum); } } break; } // Apply shadowed files var virtualPath = GetVirtualPath(path); if (CurrentFileSystem != null && CurrentFileSystem.DirectoryExists(virtualPath)) { foreach (var item in CurrentFileSystem.GetDirectories(virtualPath, topDirectoryOnly)) { var overlayPath = "/" + SkyEditor.Core.Utilities.FileSystem.MakeRelativePath(item, VirtualPath); if (!BlacklistedPaths.Contains(overlayPath) && !output.Contains(overlayPath, StringComparer.OrdinalIgnoreCase)) { output.Add(overlayPath); } } } return(output.ToArray()); }
string[] IFileSystem.GetFiles(string path, string searchPattern, bool topDirectoryOnly) { var searchPatternRegex = new Regex(GetFileSearchRegex(searchPattern), RegexOptions.Compiled | RegexOptions.IgnoreCase); var parts = GetPathParts(path); var output = new List <string>(); void addRomFsFiles(int partitionId) { var directory = "/" + GetRomFsDirectoryName(partitionId) + "/"; var currentDirectory = GetPartitionOrDefault(partitionId)?.RomFs?.Level3.RootDirectoryMetadataTable; for (int i = 1; i < parts.Length; i += 1) { currentDirectory = currentDirectory?.ChildDirectories.Where(x => string.Compare(x.Name, parts[i], true) == 0).FirstOrDefault(); directory += currentDirectory.Name + "/"; } if (currentDirectory != null) { IEnumerable <string> files; if (ReferenceEquals(currentDirectory, GetPartitionOrDefault(partitionId).RomFs.Level3.RootDirectoryMetadataTable)) { // The root RomFS directory doesn't contain files; those are located in the level 3 files = GetPartitionOrDefault(partitionId).RomFs.Level3.RootFiles .Where(f => searchPatternRegex.IsMatch(f.Name)) .Select(f => directory + f.Name); } else { files = currentDirectory.ChildFiles .Where(f => searchPatternRegex.IsMatch(f.Name)) .Select(f => directory + f.Name); } output.AddRange(files); if (!topDirectoryOnly) { foreach (var d in currentDirectory.ChildDirectories) { output.AddRange((this as IFileSystem).GetFiles(directory + d.Name + "/", searchPattern, topDirectoryOnly)); } } } } var dirName = parts[0].ToLower(); switch (dirName) { case "" when parts.Length == 1: if (!topDirectoryOnly) { for (int i = 0; i < Partitions.Length; i++) { if (Partitions[i].ExHeader != null) { var exheaderName = GetExHeaderFileName(i); if (!searchPatternRegex.IsMatch(exheaderName)) { output.Add(exheaderName); } } if (Partitions[i].ExeFs != null) { output.AddRange((this as IFileSystem).GetFiles("/" + GetExeFsDirectoryName(i), searchPattern, topDirectoryOnly)); } if (Partitions[i].RomFs != null) { output.AddRange((this as IFileSystem).GetFiles("/" + GetRomFsDirectoryName(i), searchPattern, topDirectoryOnly)); } } } break; case "exefs" when parts.Length == 1: case "exefs-partition-0" when parts.Length == 1: foreach (var file in GetPartitionOrDefault(0)?.ExeFs?.Headers ?.Where(h => searchPatternRegex.IsMatch(h.Filename) && !string.IsNullOrWhiteSpace(h.Filename)) ?.Select(h => h.Filename)) { output.Add("/ExeFS/" + file); } break; case "romfs": case "romfs-partition-0": addRomFsFiles(0); break; case "manual": case "romfs-partition-1": addRomFsFiles(1); break; case "downloadplay": case "romfs-partition-2": addRomFsFiles(2); break; case "n3dsupdate": case "romfs-partition-6": addRomFsFiles(6); break; case "o3dsupdate": case "romfs-partition-7": addRomFsFiles(7); break; default: if (dirName.StartsWith("romfs-partition-")) { var partitionNumRaw = dirName.Split("-".ToCharArray(), 3)[2]; if (int.TryParse(partitionNumRaw, out var partitionNum)) { addRomFsFiles(partitionNum); } } else if (dirName.StartsWith("exefs-partition-")) { var partitionNumRaw = dirName.Split("-".ToCharArray(), 3)[2]; if (int.TryParse(partitionNumRaw, out var partitionNum)) { foreach (var file in GetPartitionOrDefault(partitionNum)?.ExeFs?.Headers ?.Where(h => searchPatternRegex.IsMatch(h.Filename) && !string.IsNullOrWhiteSpace(h.Filename)) ?.Select(h => h.Filename)) { output.Add("/ExeFS/" + file); } } } break; } // Apply shadowed files var virtualPath = GetVirtualPath(path); if (CurrentFileSystem != null && CurrentFileSystem.DirectoryExists(virtualPath)) { foreach (var item in CurrentFileSystem.GetFiles(virtualPath, searchPattern, topDirectoryOnly)) { var overlayPath = "/" + SkyEditor.Core.Utilities.FileSystem.MakeRelativePath(item, VirtualPath); if (!BlacklistedPaths.Contains(overlayPath) && !output.Contains(overlayPath, StringComparer.OrdinalIgnoreCase)) { output.Add(overlayPath); } } } return(output.ToArray()); }