Esempio n. 1
0
        private void tree_OnDeleteRequest(object sender, DeleteRequestFromTreeEventArgs e)
        {
            try
            {
                var deletePath = e.Directory;

                // To simplify the code here there is only the RecycleBinWithQuestion or simulate possible here
                // (all others will be ignored)
                SystemFunctions.ManuallyDeleteDirectory(deletePath, (DeleteModes)Properties.Settings.Default.delete_mode);

                // Remove root node
                this.tree.RemoveNode(deletePath);

                this.Data.AddLogMessage("Manually deleted: \"" + deletePath + "\" including all subdirectories");

                // Disable the delete button because the user has to re-scan after he manually deleted a directory
                this.btnDelete.Enabled = false;
            }
            catch (System.OperationCanceledException)
            {
                // The user canceled the deletion
            }
            catch (Exception ex)
            {
                this.Data.AddLogMessage("Could not manually delete \"" + e.Directory + "\" because of the following error: " + ex.Message);

                MessageBox.Show(this, "The directory was not deleted, because of the following error:" + Environment.NewLine + ex.Message);
            }
        }
        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

            String[] ignoreFileList = this.Data.GetIgnoreFileList();

            FileInfo[] Files = emptyDirectory.GetFiles();

            if (Files != null && Files.Length != 0)
            {
                // loop trough files and cancel if containsFiles == true
                for (int f = 0; f < Files.Length; f++)
                {
                    var file = Files[f];

                    string delPattern      = "";
                    bool   deleteTrashFile = SystemFunctions.MatchesIgnorePattern(file, (int)file.Length, this.Data.IgnoreEmptyFiles, ignoreFileList, out delPattern);

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

                            this.Data.AddLogMessage(String.Format("-> Successfully deleted file \"{0}\" because it matched the ignore pattern \"{1}\"", file.FullName, delPattern));
                        }
                        catch (Exception ex)
                        {
                            this.Data.AddLogMessage(String.Format("Failed to delete file \"{0}\" - Error message: \"{1}\"", file.FullName, 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);
                            }
                            else
                            {
                                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);
        }
Esempio n. 3
0
 void Default_SettingChanging(object sender, System.Configuration.SettingChangingEventArgs e)
 {
     if (e.SettingName == "keep_system_folders" && !(bool)e.NewValue)
     {
         if (MessageBox.Show(this, SystemFunctions.ConvertLineBreaks(RED2.Properties.Resources.warning_really_delete), RED2.Properties.Resources.warning, MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) == DialogResult.Cancel)
         {
             e.Cancel = true;
         }
     }
 }
Esempio n. 4
0
 private void btnExplorerRemove_Click(object sender, EventArgs e)
 {
     SystemFunctions.AddOrRemoveRegKey(false);
     this.btnExplorerRemove.Enabled    = false;
     this.btnExplorerIntegrate.Enabled = true;
 }
Esempio n. 5
0
 private void btnShowConfig_Click(object sender, EventArgs e)
 {
     SystemFunctions.OpenDirectoryWithExplorer(Application.StartupPath);
 }
Esempio n. 6
0
 /// <summary>
 /// Let the user select a folder
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void btnChooseFolder_Click(object sender, EventArgs e)
 {
     Properties.Settings.Default.last_used_directory = SystemFunctions.ChooseDirectoryDialog(Properties.Settings.Default.last_used_directory);
 }
Esempio n. 7
0
        private void init()
        {
            this.tree = new TreeManager(this.tvFolders);
            this.tree.OnProtectionStatusChanged += new EventHandler <ProtectionStatusChangedEventArgs>(tree_OnProtectionStatusChanged);
            this.tree.OnDeleteRequest           += new EventHandler <DeleteRequestFromTreeEventArgs>(tree_OnDeleteRequest);

            this.lbAppTitle.Text += string.Format("{0}", Assembly.GetExecutingAssembly().GetName().Version.ToString());

            #region Bind config settings to controls

            // Read folder from the config file
            this.tbFolder.DataBindings.Add("Text", Properties.Settings.Default, "last_used_directory");

            this.cbIgnoreHiddenFolders.DataBindings.Add("Checked", Properties.Settings.Default, "dont_scan_hidden_folders");
            this.cbIgnore0kbFiles.DataBindings.Add("Checked", Properties.Settings.Default, "ignore_0kb_files");
            this.cbKeepSystemFolders.DataBindings.Add("Checked", Properties.Settings.Default, "keep_system_folders");
            this.cbClipboardDetection.DataBindings.Add("Checked", Properties.Settings.Default, "clipboard_detection");
            this.cbHideScanErrors.DataBindings.Add("Checked", Properties.Settings.Default, "hide_scan_errors");

            this.tbIgnoreFiles.DataBindings.Add("Text", Properties.Settings.Default, "ignore_files");
            this.tbIgnoreFolders.DataBindings.Add("Text", Properties.Settings.Default, "ignore_directories");

            this.nuMaxDepth.DataBindings.Add("Value", Properties.Settings.Default, "max_depth");
            this.nuInfiniteLoopDetectionCount.DataBindings.Add("Value", Properties.Settings.Default, "infinite_loop_detection_count");
            this.nuPause.DataBindings.Add("Value", Properties.Settings.Default, "pause_between");
            this.cbIgnoreErrors.DataBindings.Add("Checked", Properties.Settings.Default, "ignore_deletion_errors");

            // Special field
            this.lblRedStats.Text = String.Format(RED2.Properties.Resources.red_deleted, Properties.Settings.Default.delete_stats);

            // Delete mode
            foreach (var d in DeleteModeItem.GetList())
            {
                this.cbDeleteMode.Items.Add(new DeleteModeItem(d));
            }

            this.cbDeleteMode.DataBindings.Add("SelectedIndex", Properties.Settings.Default, "delete_mode");

            #region Check if the user started RED as admin

            var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());

            if (principal.IsInRole(WindowsBuiltInRole.Administrator))
            {
                var isIntegrated = SystemFunctions.IsRegKeyIntegratedIntoWindowsExplorer();

                this.btnExplorerIntegrate.Enabled = !isIntegrated;
                this.btnExplorerRemove.Enabled    = isIntegrated;

                this.Text += " (Admin mode)";
            }
            else
            {
                this.lblReqAdmin.ForeColor        = Color.Red;
                this.btnExplorerIntegrate.Enabled = false;
                this.btnExplorerRemove.Enabled    = false;
            }

            #endregion

            var credits = Path.Combine(Application.StartupPath, "credits.txt");

            if (File.Exists(credits))
            {
                this.tbCredits.AppendText(File.ReadAllText(credits));
            }
            else
            {
                this.tbCredits.AppendText("Error: Could not find the credits text file:" + Environment.NewLine + credits);
            }

            this.nuFolderAge.DataBindings.Add("Value", Properties.Settings.Default, "min_folder_age_hours");

            #endregion

            this.lbStatus.Text   = "";
            this.cmStrip.Enabled = false;

            this.pbProgressStatus.Maximum = 100;
            this.pbProgressStatus.Minimum = 0;
            this.pbProgressStatus.Step    = 5;

            this.btnShowLog.Enabled = false;

            drawDirectoryIcons();

            #region Read and apply command line arguments

            string[] args = Environment.GetCommandLineArgs();

            if (args.Length > 1)
            {
                args[0] = "";
                var path = String.Join("", args).Replace("\"", "").Trim();

                // add ending backslash
                if (!path.EndsWith("\\"))
                {
                    path += "\\";
                }

                Properties.Settings.Default.last_used_directory = path;
            }

            #endregion
        }
Esempio n. 8
0
 private void openFolderToolStripMenuItem_Click(object sender, EventArgs e)
 {
     SystemFunctions.OpenDirectoryWithExplorer(this.tree.GetSelectedFolderPath());
 }
Esempio n. 9
0
 /// <summary>
 /// User clicks twice on a folder
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void tvFolders_DoubleClick(object sender, EventArgs e)
 {
     SystemFunctions.OpenDirectoryWithExplorer(this.tree.GetSelectedFolderPath());
 }
Esempio n. 10
0
        private DirectorySearchStatusTypes checkIfDirectoryEmpty(DirectoryInfo startDir, int 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
            {
                // Thread.Sleep(500); -> ?

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

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

                this.folderCount++;

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

                bool containsFiles = false;

                // Get file list
                FileInfo[] fileList = null;

                // some directories could trigger a exception:
                try
                {
                    fileList = startDir.GetFiles();
                }
                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 if (fileList.Length == 0)
                {
                    containsFiles = false;
                }
                else
                {
                    string delPattern = "";

                    // loop trough files and cancel if containsFiles == true
                    for (int f = 0; (f < fileList.Length && !containsFiles); f++)
                    {
                        FileInfo file     = null;
                        int      filesize = 0;

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

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

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

                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.Length == 0)
                {
                    return(DirectorySearchStatusTypes.Empty);
                }

                bool allSubDirectoriesEmpty = true;

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

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

                    if (!ignoreSubDirectory && 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(RED2.Properties.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 System.IO.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);
            }
        }