Exemple #1
0
        /// <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);
            }
        }
Exemple #2
0
 bool IFileSystem.DirectoryExists(string path)
 {
     return(!BlacklistedPaths.Contains(FixPath(path))
            &&
            ((CurrentFileSystem != null && CurrentFileSystem.DirectoryExists(GetVirtualPath(path))) ||
             DirectoryExists(GetPathParts(path))
            ));
 }
Exemple #3
0
        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));
        }
Exemple #4
0
        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());
        }
Exemple #5
0
        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());
        }