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

Revision 850, 26.2 KB checked in by lowjoel, 6 years ago (diff)

-Moved all Shell calls to ShellAPI.cs
-Empty the recycle bin after we are done with the erase
-Only erase the recycle bin that belongs to the current user

Partially fixes #139

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