source: trunk/eraser/Eraser.DefaultPlugins/ErasureTargets/FolderErasureTarget.cs @ 2039

Revision 2039, 7.1 KB checked in by lowjoel, 5 years ago (diff)

Name the files after the class contained therein.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008-2010 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26
27using System.Text.RegularExpressions;
28using System.Runtime.Serialization;
29using System.Runtime.InteropServices;
30using System.Security.Permissions;
31using System.IO;
32
33using Eraser.Manager;
34using Eraser.Util;
35
36namespace Eraser.DefaultPlugins
37{
38    /// <summary>
39    /// Represents a folder and its files which are to be erased.
40    /// </summary>
41    [Serializable]
42    [Guid("F50B0A44-3AB1-4cab-B81E-1713AC3D28C9")]
43    public class FolderErasureTarget : FileSystemObjectErasureTarget
44    {
45        #region Serialization code
46        protected FolderErasureTarget(SerializationInfo info, StreamingContext context)
47            : base(info, context)
48        {
49            IncludeMask = (string)info.GetValue("IncludeMask", typeof(string));
50            ExcludeMask = (string)info.GetValue("ExcludeMask", typeof(string));
51            DeleteIfEmpty = (bool)info.GetValue("DeleteIfEmpty", typeof(bool));
52        }
53
54        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
55        public override void GetObjectData(SerializationInfo info, StreamingContext context)
56        {
57            base.GetObjectData(info, context);
58            info.AddValue("IncludeMask", IncludeMask);
59            info.AddValue("ExcludeMask", ExcludeMask);
60            info.AddValue("DeleteIfEmpty", DeleteIfEmpty);
61        }
62        #endregion
63
64        /// <summary>
65        /// Constructor.
66        /// </summary>
67        public FolderErasureTarget()
68        {
69            IncludeMask = string.Empty;
70            ExcludeMask = string.Empty;
71            DeleteIfEmpty = true;
72        }
73
74        public override Guid Guid
75        {
76            get { return GetType().GUID; }
77        }
78
79        public override IErasureTargetConfigurer Configurer
80        {
81            get { return new FolderErasureTargetSettings(); }
82        }
83
84        internal override List<string> GetPaths(out long totalSize)
85        {
86            //Get a list to hold all the resulting paths.
87            List<string> result = new List<string>();
88
89            //Open the root of the search, including every file matching the pattern
90            DirectoryInfo dir = new DirectoryInfo(Path);
91
92            //List recursively all the files which match the include pattern.
93            FileInfo[] files = GetFiles(dir);
94
95            //Then exclude each file and finalize the list and total file size
96            totalSize = 0;
97            if (ExcludeMask.Length != 0)
98            {
99                string regex = Regex.Escape(ExcludeMask).Replace("\\*", ".*").
100                    Replace("\\?", ".");
101                Regex excludePattern = new Regex(regex, RegexOptions.IgnoreCase);
102                foreach (FileInfo file in files)
103                    if (file.Exists &&
104                        (file.Attributes & FileAttributes.ReparsePoint) == 0 &&
105                        excludePattern.Matches(file.FullName).Count == 0)
106                    {
107                        totalSize += file.Length;
108                        GetPathADSes(result, out totalSize, file.FullName);
109                        result.Add(file.FullName);
110                    }
111            }
112            else
113                foreach (FileInfo file in files)
114                {
115                    if (!file.Exists || (file.Attributes & FileAttributes.ReparsePoint) != 0)
116                        continue;
117
118                    //Get the size of the file and its ADSes
119                    totalSize += file.Length;
120                    long adsesSize = 0;
121                    GetPathADSes(result, out adsesSize, file.FullName);
122                    totalSize += adsesSize;
123
124                    //Append this file to the list of files to erase.
125                    result.Add(file.FullName);
126                }
127
128            //Return the filtered list.
129            return result;
130        }
131
132        /// <summary>
133        /// Gets all files in the provided directory.
134        /// </summary>
135        /// <param name="info">The directory to look files in.</param>
136        /// <returns>A list of files found in the directory matching the IncludeMask
137        /// property.</returns>
138        private FileInfo[] GetFiles(DirectoryInfo info)
139        {
140            List<FileInfo> result = new List<FileInfo>();
141            if (info.Exists)
142            {
143                try
144                {
145                    foreach (DirectoryInfo dir in info.GetDirectories())
146                        result.AddRange(GetFiles(dir));
147
148                    if (IncludeMask.Length == 0)
149                        result.AddRange(info.GetFiles());
150                    else
151                        result.AddRange(info.GetFiles(IncludeMask, SearchOption.TopDirectoryOnly));
152                }
153                catch (UnauthorizedAccessException e)
154                {
155                    Logger.Log(S._("Could not erase files and subfolders in {0} because {1}",
156                        info.FullName, e.Message), LogLevel.Error);
157                }
158            }
159
160            return result.ToArray();
161        }
162
163        /// <summary>
164        /// A wildcard expression stating the condition for the set of files to include.
165        /// The include mask is applied before the exclude mask is applied. If this value
166        /// is empty, all files and folders within the folder specified is included.
167        /// </summary>
168        public string IncludeMask { get; set; }
169
170        /// <summary>
171        /// A wildcard expression stating the condition for removing files from the set
172        /// of included files. If this value is omitted, all files and folders extracted
173        /// by the inclusion mask is erased.
174        /// </summary>
175        public string ExcludeMask { get; set; }
176
177        /// <summary>
178        /// Determines if Eraser should delete the folder after the erase process.
179        /// </summary>
180        public bool DeleteIfEmpty { get; set; }
181
182        public override void Execute()
183        {
184            base.Execute();
185
186            //If the user requested a folder removal, do it.
187            if (Directory.Exists(Path))
188            {
189                ProgressManager step = new ProgressManager();
190                Progress.Steps.Add(new SteppedProgressManagerStep(step,
191                    0.0f, S._("Removing folders...")));
192
193                //Remove all subfolders which are empty.
194                FileSystem fsManager = ManagerLibrary.Instance.FileSystemRegistrar[
195                    VolumeInfo.FromMountPoint(Path)];
196                Action<DirectoryInfo> eraseEmptySubFolders = null;
197                eraseEmptySubFolders = delegate(DirectoryInfo info)
198                {
199                    foreach (DirectoryInfo subDir in info.GetDirectories())
200                        eraseEmptySubFolders(subDir);
201                    OnProgressChanged(this, new ProgressChangedEventArgs(step,
202                       new TaskProgressChangedEventArgs(info.FullName, 0, 0)));
203
204                    FileSystemInfo[] files = info.GetFileSystemInfos();
205                    if (files.Length == 0)
206                        fsManager.DeleteFolder(info);
207                };
208
209                DirectoryInfo directory = new DirectoryInfo(Path);
210                foreach (DirectoryInfo subDir in directory.GetDirectories())
211                    eraseEmptySubFolders(subDir);
212
213                if (DeleteIfEmpty)
214                {
215                    //See if this is the root of a volume.
216                    bool isVolumeRoot = directory.Parent == null;
217                    foreach (VolumeInfo volume in VolumeInfo.Volumes)
218                        foreach (string mountPoint in volume.MountPoints)
219                            if (directory.FullName == mountPoint)
220                                isVolumeRoot = true;
221
222                    //If the folder is a mount point, then don't delete it. If it isn't,
223                    //search for files under the folder to see if it is empty.
224                    if (!isVolumeRoot && directory.Exists &&
225                        directory.GetFiles("*", SearchOption.AllDirectories).Length == 0)
226                    {
227                        fsManager.DeleteFolder(directory);
228                    }
229                }
230            }
231        }
232    }
233}
Note: See TracBrowser for help on using the repository browser.