source: branches/eraser6/Manager/Task.cs @ 938

Revision 938, 25.9 KB checked in by lowjoel, 6 years ago (diff)

Rename these references as a result of r936

  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008 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.Text;
25using System.IO;
26using System.Text.RegularExpressions;
27using System.Runtime.Serialization;
28using System.ComponentModel;
29using Eraser.Util;
30using System.Security.Permissions;
31
32namespace Eraser.Manager
33{
34    /// <summary>
35    /// Deals with an erase task.
36    /// </summary>
37    [Serializable]
38    public class Task : ISerializable
39    {
40        #region Serialization code
41        protected Task(SerializationInfo info, StreamingContext context)
42        {
43            Name = (string)info.GetValue("Name", typeof(string));
44            Targets = (ErasureTargetsCollection)info.GetValue("Targets", typeof(ErasureTargetsCollection));
45            Targets.Owner = this;
46            Log = (Logger)info.GetValue("Log", typeof(Logger));
47
48            Schedule schedule = (Schedule)info.GetValue("Schedule", typeof(Schedule));
49            if (schedule.GetType() == Schedule.RunNow.GetType())
50                Schedule = Schedule.RunNow;
51            else if (schedule.GetType() == Schedule.RunOnRestart.GetType())
52                Schedule = Schedule.RunOnRestart;
53            else if (schedule is RecurringSchedule)
54                Schedule = schedule;
55            else
56                throw new InvalidDataException(S._("An invalid type was found when loading " +
57                    "the task schedule"));
58        }
59
60        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
61        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
62        {
63            info.AddValue("Name", Name);
64            info.AddValue("Schedule", Schedule);
65            info.AddValue("Targets", Targets);
66
67            lock (Log)
68                info.AddValue("Log", Log);
69        }
70        #endregion
71
72        /// <summary>
73        /// Constructor.
74        /// </summary>
75        public Task()
76        {
77            Name = string.Empty;
78            Targets = new ErasureTargetsCollection(this);
79            Schedule = Schedule.RunNow;
80            Log = new Logger();
81        }
82
83        /// <summary>
84        /// Cancels the task from running, or, if the task is queued for running,
85        /// removes the task from the queue.
86        /// </summary>
87        public void Cancel()
88        {
89            Executor.UnqueueTask(this);
90            Canceled = true;
91        }
92
93        /// <summary>
94        /// The Executor object which is managing this task.
95        /// </summary>
96        public Executor Executor { get; internal set; }
97
98        /// <summary>
99        /// The name for this task. This is just an opaque value for the user to
100        /// recognize the task.
101        /// </summary>
102        public string Name { get; set; }
103
104        /// <summary>
105        /// The name of the task, used for display in UI elements.
106        /// </summary>
107        public string UIText
108        {
109            get
110            {
111                //Simple case, the task name was given by the user.
112                if (Name.Length != 0)
113                    return Name;
114
115                string result = string.Empty;
116                if (Targets.Count < 3)
117                    //Simpler case, small set of data.
118                    foreach (ErasureTarget tgt in Targets)
119                        result += tgt.UIText + ", ";
120                else
121                    //Ok, we've quite a few entries, get the first, the mid and the end.
122                    for (int i = 0; i < Targets.Count; i += Targets.Count / 3)
123                        result += Targets[i].UIText + ", ";
124                return result.Substring(0, result.Length - 2);
125            }
126        }
127
128        /// <summary>
129        /// Gets the status of the task - whether it is being executed.
130        /// </summary>
131        public bool Executing { get; private set; }
132
133        /// <summary>
134        /// Gets whether this task is currently queued to run. This is true only
135        /// if the queue it is in is an explicit request, i.e will run when the
136        /// executor is idle.
137        /// </summary>
138        public bool Queued { get; internal set; }
139
140        /// <summary>
141        /// Gets whether the task has been cancelled from execution.
142        /// </summary>
143        public bool Canceled { get; internal set; }
144
145        /// <summary>
146        /// The set of data to erase when this task is executed.
147        /// </summary>
148        public ErasureTargetsCollection Targets { get; private set; }
149
150        /// <summary>
151        /// The schedule for running the task.
152        /// </summary>
153        public Schedule Schedule { get; set; }
154
155        /// <summary>
156        /// The log entries which this task has accumulated.
157        /// </summary>
158        public Logger Log { get; private set; }
159
160        #region Events
161        /// <summary>
162        /// The prototype for events handling just a task object as the event argument.
163        /// </summary>
164        /// <param name="e">The task object.</param>
165        public delegate void TaskEventFunction(TaskEventArgs e);
166
167        /// <summary>
168        /// The prototype for events handling the progress changed event.
169        /// </summary>
170        /// <param name="e">The new progress value.</param>
171        public delegate void ProgressEventFunction(TaskProgressEventArgs e);
172
173        /// <summary>
174        /// The start of the execution of a task.
175        /// </summary>
176        public event TaskEventFunction TaskStarted;
177
178        /// <summary>
179        /// The event object holding all event handlers.
180        /// </summary>
181        public event ProgressEventFunction ProgressChanged;
182
183        /// <summary>
184        /// The completion of the execution of a task.
185        /// </summary>
186        public event TaskEventFunction TaskFinished;
187
188        /// <summary>
189        /// Broadcasts the task execution start event.
190        /// </summary>
191        /// <param name="e"></param>
192        internal void OnTaskStarted(TaskEventArgs e)
193        {
194            if (TaskStarted != null)
195                TaskStarted(e);
196            Executing = true;
197        }
198
199        /// <summary>
200        /// Broadcasts a ProgressChanged event.
201        /// </summary>
202        /// <param name="e">The new progress value.</param>
203        internal void OnProgressChanged(TaskProgressEventArgs e)
204        {
205            if (ProgressChanged != null)
206                ProgressChanged(e);
207        }
208
209        /// <summary>
210        /// Broadcasts the task execution completion event.
211        /// </summary>
212        /// <param name="e"></param>
213        internal void OnTaskFinished(TaskEventArgs e)
214        {
215            if (TaskFinished != null)
216                TaskFinished(e);
217            Executing = false;
218        }
219        #endregion
220    }
221
222    /// <summary>
223    /// Represents a generic target of erasure
224    /// </summary>
225    [Serializable]
226    public abstract class ErasureTarget : ISerializable
227    {
228        #region Serialization code
229        protected ErasureTarget(SerializationInfo info, StreamingContext context)
230        {
231            Guid methodGuid = (Guid)info.GetValue("Method", typeof(Guid));
232            if (methodGuid == Guid.Empty)
233                method = ErasureMethodManager.Default;
234            else
235                method = ErasureMethodManager.GetInstance(methodGuid);
236        }
237
238        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
239        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
240        {
241            info.AddValue("Method", method.Guid);
242        }
243        #endregion
244
245        /// <summary>
246        /// Constructor.
247        /// </summary>
248        protected ErasureTarget()
249        {
250        }
251
252        /// <summary>
253        /// The method used for erasing the file. If the variable is equal to
254        /// ErasureMethodManager.Default then the default is queried for the
255        /// task type.
256        /// </summary>
257        public abstract ErasureMethod Method
258        {
259            get;
260            set;
261        }
262
263        /// <summary>
264        /// Checks whether a method has been selected for this target. This is
265        /// because the Method property will return non-default erasure methods
266        /// only.
267        /// </summary>
268        public bool MethodDefined
269        {
270            get
271            {
272                return method != ErasureMethodManager.Default;
273            }
274        }
275
276        /// <summary>
277        /// The task which owns this target.
278        /// </summary>
279        public Task Task { get; internal set; }
280
281        /// <summary>
282        /// Retrieves the text to display representing this task.
283        /// </summary>
284        public abstract string UIText
285        {
286            get;
287        }
288
289        /// <summary>
290        /// Retrieves the amount of data that needs to be written in order to
291        /// complete the erasure.
292        /// </summary>
293        public abstract long TotalData
294        {
295            get;
296        }
297
298        /// <summary>
299        /// Erasure method to use for the target.
300        /// </summary>
301        protected ErasureMethod method { get; set; }
302    }
303
304    /// <summary>
305    /// Class representing a tangible object (file/folder) to be erased.
306    /// </summary>
307    [Serializable]
308    public abstract class FileSystemObjectTarget : ErasureTarget
309    {
310        #region Serialization code
311        protected FileSystemObjectTarget(SerializationInfo info, StreamingContext context)
312            : base(info, context)
313        {
314            path = (string)info.GetValue("Path", typeof(string));
315        }
316
317        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
318        public override void GetObjectData(SerializationInfo info, StreamingContext context)
319        {
320            base.GetObjectData(info, context);
321            info.AddValue("Path", path);
322        }
323        #endregion
324
325        /// <summary>
326        /// Constructor.
327        /// </summary>
328        protected FileSystemObjectTarget()
329        {
330        }
331
332        /// <summary>
333        /// Retrieves the list of files/folders to erase as a list.
334        /// </summary>
335        /// <param name="totalSize">Returns the total size in bytes of the
336        /// items.</param>
337        /// <returns>A list containing the paths to all the files to be erased.</returns>
338        internal abstract List<string> GetPaths(out long totalSize);
339
340        /// <summary>
341        /// Adds ADSes of the given file to the list.
342        /// </summary>
343        /// <param name="list">The list to add the ADS paths to.</param>
344        /// <param name="file">The file to look for ADSes</param>
345        protected void GetPathADSes(List<string> list, out long totalSize, string file)
346        {
347            totalSize = 0;
348
349            try
350            {
351                //Get the ADS names
352                List<string> adses = Util.File.GetADSes(new FileInfo(file));
353
354                //Then prepend the path.
355                foreach (string adsName in adses)
356                {
357                    string adsPath = file + ':' + adsName;
358                    list.Add(adsPath);
359                    Util.StreamInfo info = new Util.StreamInfo(adsPath);
360                    totalSize += info.Length;
361                }
362            }
363            catch (UnauthorizedAccessException e)
364            {
365                //The system cannot read the file, assume no ADSes for lack of
366                //more information.
367                Task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Error));
368            }
369        }
370
371        /// <summary>
372        /// The path to the file or folder referred to by this object.
373        /// </summary>
374        public string Path
375        {
376            get { return path; }
377            set { path = value; }
378        }
379
380        public override ErasureMethod Method
381        {
382            get
383            {
384                if (method != ErasureMethodManager.Default)
385                    return method;
386                return ErasureMethodManager.GetInstance(
387                    ManagerLibrary.Settings.DefaultFileErasureMethod);
388            }
389            set
390            {
391                method = value;
392            }
393        }
394
395        public override string UIText
396        {
397            get { return Path; }
398        }
399
400        public override long TotalData
401        {
402            get
403            {
404                long totalSize = 0;
405                List<string> paths = GetPaths(out totalSize);
406                return Method.CalculateEraseDataSize(paths, totalSize);
407            }
408        }
409
410        private string path;
411    }
412
413    /// <summary>
414    /// Class representing a unused space erase.
415    /// </summary>
416    [Serializable]
417    public class UnusedSpaceTarget : ErasureTarget
418    {
419        #region Serialization code
420        protected UnusedSpaceTarget(SerializationInfo info, StreamingContext context)
421            : base(info, context)
422        {
423            Drive = (string)info.GetValue("Drive", typeof(string));
424            EraseClusterTips = (bool)info.GetValue("EraseClusterTips", typeof(bool));
425        }
426
427        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
428        public override void GetObjectData(SerializationInfo info, StreamingContext context)
429        {
430            base.GetObjectData(info, context);
431            info.AddValue("Drive", Drive);
432            info.AddValue("EraseClusterTips", EraseClusterTips);
433        }
434        #endregion
435
436        /// <summary>
437        /// Constructor.
438        /// </summary>
439        public UnusedSpaceTarget()
440        {
441        }
442
443        public override ErasureMethod Method
444        {
445            get
446            {
447                if (method != ErasureMethodManager.Default)
448                    return method;
449                return ErasureMethodManager.GetInstance(
450                    ManagerLibrary.Settings.DefaultUnusedSpaceErasureMethod);
451            }
452            set
453            {
454                method = value;
455            }
456        }
457
458        public override string UIText
459        {
460            get { return S._("Unused disk space ({0})", Drive); }
461        }
462
463        public override long TotalData
464        {
465            get
466            {
467                VolumeInfo info = VolumeInfo.FromMountpoint(Drive);
468                return Method.CalculateEraseDataSize(null, info.AvailableFreeSpace);
469            }
470        }
471
472        /// <summary>
473        /// The drive to erase
474        /// </summary>
475        public string Drive { get; set; }
476
477        /// <summary>
478        /// Whether cluster tips should be erased.
479        /// </summary>
480        public bool EraseClusterTips { get; set; }
481    }
482
483    /// <summary>
484    /// Class representing a file to be erased.
485    /// </summary>
486    [Serializable]
487    public class FileTarget : FileSystemObjectTarget
488    {
489        #region Serialization code
490        protected FileTarget(SerializationInfo info, StreamingContext context)
491            : base(info, context)
492        {
493        }
494        #endregion
495
496        /// <summary>
497        /// Constructor.
498        /// </summary>
499        public FileTarget()
500        {
501        }
502
503        internal override List<string> GetPaths(out long totalSize)
504        {
505            List<string> result = new List<string>();
506            totalSize = 0;
507            GetPathADSes(result, out totalSize, Path);
508
509            totalSize += new FileInfo(Path).Length;
510            result.Add(Path);
511            return result;
512        }
513    }
514
515    /// <summary>
516    /// Represents a folder and its files which are to be erased.
517    /// </summary>
518    [Serializable]
519    public class FolderTarget : FileSystemObjectTarget
520    {
521        #region Serialization code
522        protected FolderTarget(SerializationInfo info, StreamingContext context)
523            : base(info, context)
524        {
525            includeMask = (string)info.GetValue("IncludeMask", typeof(string));
526            excludeMask = (string)info.GetValue("ExcludeMask", typeof(string));
527            deleteIfEmpty = (bool)info.GetValue("DeleteIfEmpty", typeof(bool));
528        }
529
530        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
531        public override void GetObjectData(SerializationInfo info, StreamingContext context)
532        {
533            base.GetObjectData(info, context);
534            info.AddValue("IncludeMask", includeMask);
535            info.AddValue("ExcludeMask", excludeMask);
536            info.AddValue("DeleteIfEmpty", deleteIfEmpty);
537        }
538        #endregion
539
540        /// <summary>
541        /// Constructor.
542        /// </summary>
543        public FolderTarget()
544        {
545        }
546
547        internal override List<string> GetPaths(out long totalSize)
548        {
549            //Get a list to hold all the resulting paths.
550            List<string> result = new List<string>();
551
552            //Open the root of the search, including every file matching the pattern
553            DirectoryInfo dir = new DirectoryInfo(Path);
554
555            //List recursively all the files which match the include pattern.
556            FileInfo[] files = GetFiles(dir);
557
558            //Then exclude each file and finalize the list and total file size
559            totalSize = 0;
560            if (ExcludeMask.Length != 0)
561            {
562                string regex = Regex.Escape(ExcludeMask).Replace("\\*", ".*").
563                    Replace("\\?", ".");
564                Regex excludePattern = new Regex(regex, RegexOptions.IgnoreCase);
565                foreach (FileInfo file in files)
566                    if ((file.Attributes & FileAttributes.ReparsePoint) == 0 &&
567                        excludePattern.Matches(file.FullName).Count == 0)
568                    {
569                        totalSize += file.Length;
570                        GetPathADSes(result, out totalSize, file.FullName);
571                        result.Add(file.FullName);
572                    }
573            }
574            else
575                foreach (FileInfo file in files)
576                {
577                    if ((file.Attributes & FileAttributes.ReparsePoint) != 0)
578                        continue;
579
580                    totalSize += file.Length;
581                    GetPathADSes(result, out totalSize, file.FullName);
582                    result.Add(file.FullName);
583                }
584
585            //Return the filtered list.
586            return result;
587        }
588
589        /// <summary>
590        /// Gets all files in the provided directory.
591        /// </summary>
592        /// <param name="info">The directory to look files in.</param>
593        /// <returns>A list of files found in the directory matching the IncludeMask
594        /// property.</returns>
595        private FileInfo[] GetFiles(DirectoryInfo info)
596        {
597            List<FileInfo> result = new List<FileInfo>();
598            foreach (DirectoryInfo dir in info.GetDirectories())
599                try
600                {
601                    result.AddRange(GetFiles(dir));
602                }
603                catch (Exception e)
604                {
605                    //Ignore, but log.
606                    Task.Log.LastSessionEntries.Add(new LogEntry(S._("Could not erase {0} because {1}",
607                        dir.FullName, e.Message), LogLevel.Error));
608                }
609
610            if (includeMask.Length == 0)
611                result.AddRange(info.GetFiles());
612            else
613                result.AddRange(info.GetFiles(includeMask, SearchOption.TopDirectoryOnly));
614            return result.ToArray();
615        }
616
617        /// <summary>
618        /// A wildcard expression stating the condition for the set of files to include.
619        /// The include mask is applied before the exclude mask is applied. If this value
620        /// is empty, all files and folders within the folder specified is included.
621        /// </summary>
622        public string IncludeMask
623        {
624            get { return includeMask; }
625            set { includeMask = value; }
626        }
627
628        /// <summary>
629        /// A wildcard expression stating the condition for removing files from the set
630        /// of included files. If this value is omitted, all files and folders extracted
631        /// by the inclusion mask is erased.
632        /// </summary>
633        public string ExcludeMask
634        {
635            get { return excludeMask; }
636            set { excludeMask = value; }
637        }
638
639        /// <summary>
640        /// Determines if Eraser should delete the folder after the erase process.
641        /// </summary>
642        public bool DeleteIfEmpty
643        {
644            get { return deleteIfEmpty; }
645            set { deleteIfEmpty = value; }
646        }
647
648        private string includeMask = string.Empty;
649        private string excludeMask = string.Empty;
650        private bool deleteIfEmpty = true;
651    }
652
653    [Serializable]
654    public class RecycleBinTarget : FileSystemObjectTarget
655    {
656        #region Serialization code
657        protected RecycleBinTarget(SerializationInfo info, StreamingContext context)
658            : base(info, context)
659        {
660        }
661        #endregion
662
663        public RecycleBinTarget()
664        {
665        }
666
667        internal override List<string> GetPaths(out long totalSize)
668        {
669            totalSize = 0;
670            List<string> result = new List<string>();
671            string[] rootDirectory = new string[] {
672                    "$RECYCLE.BIN",
673                    "RECYCLER"
674                };
675
676            foreach (DriveInfo drive in DriveInfo.GetDrives())
677            {
678                foreach (string rootDir in rootDirectory)
679                {
680                    DirectoryInfo dir = new DirectoryInfo(
681                        System.IO.Path.Combine(
682                            System.IO.Path.Combine(drive.Name, rootDir),
683                            System.Security.Principal.WindowsIdentity.GetCurrent().
684                                User.ToString()));
685                    if (!dir.Exists)
686                        continue;
687
688                    GetRecyclerFiles(dir, ref result, ref totalSize);
689                }
690            }
691
692            return result;
693        }
694
695        /// <summary>
696        /// Retrieves all files within this folder, without exclusions.
697        /// </summary>
698        /// <param name="info">The DirectoryInfo object representing the folder to traverse.</param>
699        /// <param name="paths">The list of files to store path information in.</param>
700        /// <param name="totalSize">Receives the total size of the files.</param>
701        private void GetRecyclerFiles(DirectoryInfo info, ref List<string> paths,
702            ref long totalSize)
703        {
704            try
705            {
706                foreach (FileSystemInfo fsInfo in info.GetFileSystemInfos())
707                {
708                    if (fsInfo is FileInfo)
709                    {
710                        paths.Add(fsInfo.FullName);
711                        totalSize += ((FileInfo)fsInfo).Length;
712                        GetPathADSes(paths, out totalSize, fsInfo.FullName);
713                    }
714                    else
715                        GetRecyclerFiles((DirectoryInfo)fsInfo, ref paths, ref totalSize);
716                }
717            }
718            catch (UnauthorizedAccessException e)
719            {
720                Task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Error));
721            }
722        }
723
724        /// <summary>
725        /// Retrieves the text to display representing this task.
726        /// </summary>
727        public override string UIText
728        {
729            get
730            {
731                return S._("Recycle Bin");
732            }
733        }
734    }
735
736    /// <summary>
737    /// Maintains a collection of erasure targets.
738    /// </summary>
739    [Serializable]
740    public class ErasureTargetsCollection : IList<ErasureTarget>, ICollection<ErasureTarget>,
741        IEnumerable<ErasureTarget>, ISerializable
742    {
743        #region Constructors
744        internal ErasureTargetsCollection(Task owner)
745        {
746            this.list = new List<ErasureTarget>();
747            this.owner = owner;
748        }
749
750        internal ErasureTargetsCollection(Task owner, int capacity)
751            : this(owner)
752        {
753            list.Capacity = capacity;
754        }
755
756        internal ErasureTargetsCollection(Task owner, IEnumerable<ErasureTarget> targets)
757            : this(owner)
758        {
759            list.AddRange(targets);
760        }
761        #endregion
762
763        #region Serialization Code
764        protected ErasureTargetsCollection(SerializationInfo info, StreamingContext context)
765        {
766            list = (List<ErasureTarget>)info.GetValue("list", typeof(List<ErasureTarget>));
767        }
768
769        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
770        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
771        {
772            info.AddValue("list", list);
773        }
774        #endregion
775
776        #region IEnumerable<ErasureTarget> Members
777        public IEnumerator<ErasureTarget> GetEnumerator()
778        {
779            return list.GetEnumerator();
780        }
781        #endregion
782
783        #region IEnumerable Members
784        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
785        {
786            return GetEnumerator();
787        }
788        #endregion
789
790        #region ICollection<ErasureTarget> Members
791        public void Add(ErasureTarget item)
792        {
793            item.Task = owner;
794            list.Add(item);
795        }
796
797        public void Clear()
798        {
799            foreach (ErasureTarget item in list)
800                Remove(item);
801        }
802
803        public bool Contains(ErasureTarget item)
804        {
805            return list.Contains(item);
806        }
807
808        public void CopyTo(ErasureTarget[] array, int arrayIndex)
809        {
810            list.CopyTo(array, arrayIndex);
811        }
812
813        public int Count
814        {
815            get
816            {
817                return list.Count;
818            }
819        }
820
821        public bool IsReadOnly
822        {
823            get
824            {
825                return false;
826            }
827        }
828
829        public bool Remove(ErasureTarget item)
830        {
831            int index = list.IndexOf(item);
832            if (index < 0)
833                return false;
834
835            RemoveAt(index);
836            return true;
837        }
838        #endregion
839
840        #region IList<ErasureTarget> Members
841        public int IndexOf(ErasureTarget item)
842        {
843            return list.IndexOf(item);
844        }
845
846        public void Insert(int index, ErasureTarget item)
847        {
848            item.Task = owner;
849            list.Insert(index, item);
850        }
851
852        public void RemoveAt(int index)
853        {
854            list.RemoveAt(index);
855        }
856
857        public ErasureTarget this[int index]
858        {
859            get
860            {
861                return list[index];
862            }
863            set
864            {
865                list[index] = value;
866            }
867        }
868        #endregion
869
870        /// <summary>
871        /// The owner of this list of targets.
872        /// </summary>
873        public Task Owner
874        {
875            get
876            {
877                return owner;
878            }
879            internal set
880            {
881                owner = value;
882                foreach (ErasureTarget target in list)
883                    target.Task = owner;
884            }
885        }
886
887        /// <summary>
888        /// The owner of this list of targets. All targets added to this list
889        /// will have the owner set to this object.
890        /// </summary>
891        private Task owner;
892
893        /// <summary>
894        /// The list bring the data store behind this object.
895        /// </summary>
896        private List<ErasureTarget> list;
897    }
898
899    /// <summary>
900    /// A base event class for all event arguments involving a task.
901    /// </summary>
902    public class TaskEventArgs : EventArgs
903    {
904        /// <summary>
905        /// Constructor.
906        /// </summary>
907        /// <param name="task">The task being run.</param>
908        public TaskEventArgs(Task task)
909        {
910            this.task = task;
911        }
912
913        /// <summary>
914        /// The executing task.
915        /// </summary>
916        public Task Task
917        {
918            get { return task; }
919        }
920
921        private Task task;
922    }
923
924    /// <summary>
925    /// A Event argument object containing the progress of the task.
926    /// </summary>
927    public class TaskProgressEventArgs : TaskEventArgs
928    {
929        /// <summary>
930        /// Constructor.
931        /// </summary>
932        /// <param name="task">The task being run.</param>
933        public TaskProgressEventArgs(Task task)
934            : base(task)
935        {
936        }
937
938        /// <summary>
939        /// A number from 0 to 1 detailing the overall progress of the task.
940        /// </summary>
941        public float OverallProgress
942        {
943            get { return overallProgress; }
944        }
945
946        /// <summary>
947        /// The amount of time left for the operation to complete, in seconds.
948        /// </summary>
949        public TimeSpan TimeLeft
950        {
951            get { return timeLeft; }
952            internal set { timeLeft = value; }
953        }
954
955        /// <summary>
956        /// The current erasure target - the current item being erased.
957        /// </summary>
958        public ErasureTarget CurrentTarget
959        {
960            get { return currentTarget; }
961            internal set { currentTarget = value; }
962        }
963
964        /// <summary>
965        /// The current index of the target.
966        /// </summary>
967        public int CurrentTargetIndex
968        {
969            get { return currentTargetIndex; }
970            internal set { currentTargetIndex = value; }
971        }
972
973        /// <summary>
974        /// The total number of passes to complete before this erasure method is
975        /// completed.
976        /// </summary>
977        public int CurrentTargetTotalPasses
978        {
979            get { return currentTargetTotalPasses; }
980            internal set { currentTargetTotalPasses = value; }
981        }
982
983        /// <summary>
984        /// A number from 0 to 1 detailing the overall progress of the item.
985        /// </summary>
986        public float CurrentItemProgress
987        {
988            get { return currentItemProgress; }
989            internal set { currentItemProgress = value; }
990        }
991
992        /// <summary>
993        /// The file name of the item being erased.
994        /// </summary>
995        public string CurrentItemName
996        {
997            get { return currentItemName; }
998            internal set { currentItemName = value; }
999        }
1000
1001        /// <summary>
1002        /// The pass number of a multi-pass erasure method.
1003        /// </summary>
1004        public int CurrentItemPass
1005        {
1006            get { return currentItemPass; }
1007            internal set { currentItemPass = value; }
1008        }
1009
1010        /// <summary>
1011        /// The progress made by the current target.
1012        /// </summary>
1013        internal float CurrentTargetProgress
1014        {
1015            set
1016            {
1017                overallProgress = Math.Min(
1018                    (value + (float)(CurrentTargetIndex - 1)) / Task.Targets.Count,
1019                    1.0f);
1020            }
1021        }
1022
1023        private float overallProgress;
1024        private TimeSpan timeLeft = new TimeSpan(0, 0, -1);
1025
1026        private ErasureTarget currentTarget;
1027        private int currentTargetIndex;
1028        private int currentTargetTotalPasses;
1029
1030        private float currentItemProgress;
1031        private string currentItemName;
1032        private int currentItemPass = 1;
1033    }
1034}
Note: See TracBrowser for help on using the repository browser.