Пример #1
0
        private void secureDelete(String path)
        {
            var emptyDirectory = new DirectoryInfo(path);

            if (!emptyDirectory.Exists)
            {
                throw new Exception("Could not delete the directory \"" + emptyDirectory.FullName + "\" because it does not exist anymore.");
            }

            // Cleanup folder

            // loop trough files and cancel if containsFiles == true
            foreach (var file in emptyDirectory.EnumerateFiles())
            {
                var deleteTrashFile = SystemFunctions.MatchesIgnorePattern(file, ( Int32 )file.Length, this.Data.IgnoreEmptyFiles, this.Data.IgnoreFileList, out var delPattern);

                // If only one file is good, then stop.
                if (deleteTrashFile)
                {
                    try {
                        SystemFunctions.SecureDeleteFile(file, this.Data.DeleteMode);

                        this.Data.AddLogMessage($"-> Successfully deleted file \"{file.FullName}\" because it matched the ignore pattern \"{delPattern}\"");
                    }
                    catch (Exception ex) {
                        this.Data.AddLogMessage($"Failed to delete file \"{file.FullName}\" - Error message: \"{ex.Message}\"");

                        var msg = "Could not delete this empty (trash) file:" + Environment.NewLine + file.FullName + Environment.NewLine + Environment.NewLine +
                                  "Error message: " + ex.Message;

                        if (ex is REDPermissionDeniedException)
                        {
                            throw new REDPermissionDeniedException(msg, ex);
                        }

                        throw new Exception(msg, ex);
                    }
                }
            }


            // End cleanup

            // This function will ensure that the directory is really empty before it gets deleted
            SystemFunctions.SecureDeleteDirectory(emptyDirectory.FullName, this.Data.DeleteMode);
        }
Пример #2
0
        private DirectorySearchStatusTypes CheckIfDirectoryEmpty(DirectoryInfo startDir, Int32 depth)
        {
            if (this.PossibleEndlessLoop > this.Data.InfiniteLoopDetectionCount)
            {
                this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(startDir.FullName, DirectorySearchStatusTypes.Error, "Aborted - possible infinite-loop detected"));

                return(DirectorySearchStatusTypes.Error);
            }

            try {
                if (this.Data.MaxDepth != -1 && depth > this.Data.MaxDepth)
                {
                    return(DirectorySearchStatusTypes.NotEmpty);
                }

                // Cancel process if the user hits stop
                if (this.CancellationPending)
                {
                    return(DirectorySearchStatusTypes.NotEmpty);
                }

                this.FolderCount++;

                // update status progress bar after 100 steps:
                if (this.FolderCount % 100 == 0)
                {
                    this.ReportProgress(this.FolderCount, $"Checking directory: {startDir.Name}");
                }

                var containsFiles = false;

                // Get file list
                IEnumerable <FileInfo> fileList;

                // some directories could trigger a exception:
                try {
                    fileList = startDir.EnumerateFiles();
                }
                catch {
                    fileList = null;
                }

                if (fileList == null)
                {
                    // CF = true = folder does not get deleted:
                    containsFiles = true; // secure way
                    this.Data.AddLogMessage("Failed to access files in \"" + startDir.FullName + "\"");
                    this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(startDir.FullName, DirectorySearchStatusTypes.Error, "Failed to access files"));
                }
                else
                {
                    // loop trough files and cancel if containsFiles == true
                    for (var f = 0; f < fileList.Length && !containsFiles; f++)
                    {
                        FileInfo file;
                        Int32    filesize;

                        try {
                            file     = fileList[f];
                            filesize = ( Int32 )file.Length;
                        }
                        catch {
                            // keep folder if there is a strange file that
                            // triggers a exception:

                            return(DirectorySearchStatusTypes.NotEmpty);
                        }

                        // If only one file is good, then stop.
                        if (!SystemFunctions.MatchesIgnorePattern(file, filesize, this.Data.IgnoreEmptyFiles, this.ignoreFileList, out _))
                        {
                            containsFiles = true;
                        }
                    }
                }

                // If the folder does not contain any files -> get subfolders:
                DirectoryInfo[] subFolderList;

                try {
                    subFolderList = startDir.GetDirectories();
                }
                catch {
                    // If we can not read the folder -> don't delete it:
                    this.Data.AddLogMessage("Failed to access subdirectories in \"" + startDir.FullName + "\"");
                    this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(startDir.FullName, DirectorySearchStatusTypes.Error, "Failed to access subdirectories"));

                    return(DirectorySearchStatusTypes.Error);
                }

                // The folder is empty, break here:
                if (!containsFiles && !subFolderList.Any())
                {
                    return(DirectorySearchStatusTypes.Empty);
                }

                var allSubDirectoriesEmpty = true;

                foreach (var curDir in subFolderList)
                {
                    var attribs = curDir.Attributes;

                    // Hidden folder?
                    var ignoreSubDirectory = this.Data.IgnoreHiddenFolders && (attribs & FileAttributes.Hidden) == FileAttributes.Hidden;
                    ignoreSubDirectory = ignoreSubDirectory || this.Data.KeepSystemFolders && (attribs & FileAttributes.System) == FileAttributes.System;

                    if (!ignoreSubDirectory && this.checkIfDirectoryIsOnIgnoreList(curDir))
                    {
                        this.Data.AddLogMessage("Aborted scan of \"" + curDir.FullName + "\" because it is on the ignore list.");
                        this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(curDir.FullName, DirectorySearchStatusTypes.Ignore));
                        ignoreSubDirectory = true;
                    }

                    if (!ignoreSubDirectory && (attribs & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
                    {
                        this.Data.AddLogMessage("Aborted scan of \"" + curDir.FullName + "\" because it is a symbolic link");

                        this.ReportProgress(0,
                                            new FoundEmptyDirInfoEventArgs(curDir.FullName, DirectorySearchStatusTypes.Error, "Aborted because dir is a symbolic link"));

                        ignoreSubDirectory = true;
                    }

                    // TODO: Implement more checks
                    //else if ((attribs & FileAttributes.Device) == FileAttributes.Device) msg = "Device - Aborted - found";
                    //else if ((attribs & FileAttributes.Encrypted) == FileAttributes.Encrypted) msg = "Encrypted -  found";
                    // The file will not be indexed by the operating system's content indexing service.
                    // else if ((attribs & FileAttributes.NotContentIndexed) == FileAttributes.NotContentIndexed) msg = "NotContentIndexed - Device found";
                    //else if ((attribs & FileAttributes.Offline) == FileAttributes.Offline) msg = "Offline -  found";
                    //else if ((attribs & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) msg = "ReadOnly -  found";
                    //else if ((attribs & FileAttributes.Temporary) == FileAttributes.Temporary) msg = "Temporary -  found";

                    // Scan sub folder:
                    var subFolderStatus = DirectorySearchStatusTypes.NotEmpty;

                    if (!ignoreSubDirectory)
                    {
                        // JRS ADDED check for AGE of folder
                        if (curDir.CreationTime.AddHours(this.Data.MinFolderAgeHours) < DateTime.Now)
                        {
                            subFolderStatus = this.CheckIfDirectoryEmpty(curDir, depth + 1);
                        }
                        else
                        {
                            this.Data.AddLogMessage(String.Format(Resources.young_folder_skipped, curDir.FullName, this.Data.MinFolderAgeHours.ToString(),
                                                                  curDir.CreationTime.ToString()));
                        }

                        // Report status to the GUI
                        if (subFolderStatus == DirectorySearchStatusTypes.Empty)
                        {
                            this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(curDir.FullName, subFolderStatus));
                        }
                    }

                    // this folder is not empty:
                    if (subFolderStatus != DirectorySearchStatusTypes.Empty || ignoreSubDirectory)
                    {
                        allSubDirectoriesEmpty = false;
                    }
                }

                // All subdirectories are empty
                return(allSubDirectoriesEmpty && !containsFiles ? DirectorySearchStatusTypes.Empty : DirectorySearchStatusTypes.NotEmpty);
            }
            catch (Exception ex) {
                // Error handling

                if (ex is PathTooLongException)
                {
                    this.PossibleEndlessLoop++;
                }

                this.Data.AddLogMessage("An unknown error occurred while trying to scan this directory: \"" + startDir.FullName + "\" - Error message: " + ex.Message);
                this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(startDir.FullName, DirectorySearchStatusTypes.Error, ex.Message));

                return(DirectorySearchStatusTypes.Error);
            }
        }