source: branches/eraser6/pluginsRewrite/Eraser.DefaultPlugins/ErasureTargets/DriveErasureTarget.cs @ 2468

Revision 2468, 6.3 KB checked in by lowjoel, 3 years ago (diff)

Instead of pushing events to the client, we will update our Progress object and the client should pull progress updates instead. This prepares the code to be used by the remote executor (for service execution).

In the interim, there is no progress feedback for all erasures.

  • 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;
26using System.Runtime.InteropServices;
27using System.Security.Permissions;
28using System.Runtime.Serialization;
29using System.IO;
30
31using Eraser.Util;
32using Eraser.Util.ExtensionMethods;
33using Eraser.Plugins;
34using Eraser.Plugins.ExtensionPoints;
35using Eraser.Plugins.Registrars;
36
37namespace Eraser.DefaultPlugins
38{
39    /// <summary>
40    /// Represents a partition to be erased.
41    /// </summary>
42    [Serializable]
43    [Guid("12CA079F-0B7A-48fa-B221-73AA217C1781")]
44    class DriveErasureTarget : ErasureTargetBase
45    {
46        public DriveErasureTarget()
47        {
48        }
49
50        #region Serialization code
51        protected DriveErasureTarget(SerializationInfo info, StreamingContext context)
52            : base(info, context)
53        {
54            string volumeId = info.GetString("Volume");
55            int physicalDriveIndex = info.GetInt32("PhysicalDrive");
56
57            if (volumeId != null)
58                Volume = new VolumeInfo(volumeId);
59            else if (physicalDriveIndex != -1)
60                PhysicalDrive = new PhysicalDriveInfo(physicalDriveIndex);
61            else
62                throw new InvalidDataException();
63        }
64
65        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
66        public override void GetObjectData(SerializationInfo info, StreamingContext context)
67        {
68            base.GetObjectData(info, context);
69            info.AddValue("Volume", Volume == null ? null : Volume.VolumeId);
70            info.AddValue("PhysicalDrive", PhysicalDrive == null ? -1 : PhysicalDrive.Index);
71        }
72        #endregion
73
74        public override Guid Guid
75        {
76            get { return GetType().GUID; }
77        }
78
79        public override string Name
80        {
81            get { return S._("Drive/Partition"); }
82        }
83
84        public override string ToString()
85        {
86            if (PhysicalDrive != null)
87            {
88                return S._("Hard disk {0}", PhysicalDrive.Index);
89            }
90            else if (Volume != null)
91            {
92                if (Volume.IsReady && Volume.IsMounted)
93                    return S._("Partition: {0}", Volume.MountPoints[0].GetDescription());
94                else if (Volume.IsReady && Volume.PhysicalDrive != null)
95                    return S._("Hard disk {0} Partition {1}", Volume.PhysicalDrive.Index,
96                        Volume.PhysicalDrive.Volumes.IndexOf(Volume) + 1);
97                else
98                    return S._("Partition");
99            }
100            else
101                return null;
102        }
103
104        public override IErasureTargetConfigurer Configurer
105        {
106            get { return new DriveErasureTargetConfigurer(); }
107        }
108
109        public sealed override IErasureMethod EffectiveMethod
110        {
111            get
112            {
113                if (Method != ErasureMethodRegistrar.Default)
114                    return base.EffectiveMethod;
115
116                return Host.Instance.ErasureMethods[
117                    Host.Instance.Settings.DefaultUnusedSpaceErasureMethod];
118            }
119        }
120
121        /// <summary>
122        /// The Volume to erase.
123        /// </summary>
124        public VolumeInfo Volume
125        {
126            get
127            {
128                return volume;
129            }
130            set
131            {
132                if (value != null && physicalDrive != null)
133                    throw new InvalidOperationException("The Drive Erasure target can only " +
134                        "erase a volume or a physical drive, not both.");
135                volume = value;
136            }
137        }
138        private VolumeInfo volume;
139
140        /// <summary>
141        /// The Physical drive to erase.
142        /// </summary>
143        public PhysicalDriveInfo PhysicalDrive
144        {
145            get
146            {
147                return physicalDrive;
148            }
149            set
150            {
151                if (value != null && volume != null)
152                    throw new InvalidOperationException("The Drive Erasure target can only " +
153                        "erase a volume or a physical drive, not both.");
154                physicalDrive = value;
155            }
156        }
157        private PhysicalDriveInfo physicalDrive;
158
159        public override void Execute()
160        {
161            //Check for sufficient privileges to run the erasure.
162            if (!Security.IsAdministrator())
163            {
164                if (Environment.OSVersion.Platform == PlatformID.Win32NT &&
165                    Environment.OSVersion.Version >= new Version(6, 0))
166                {
167                    Logger.Log(S._("The program does not have the required permissions to erase " +
168                        "the unused space on disk. Run the program as an administrator and retry " +
169                        "the operation."), LogLevel.Error);
170                }
171                else
172                {
173                    Logger.Log(S._("The program does not have the required permissions to erase " +
174                        "the unused space on disk."), LogLevel.Error);
175                }
176
177                return;
178            }
179
180            Progress = new ProgressManager();
181            Task.Progress.Steps.Add(new SteppedProgressManagerStep(Progress,
182                1.0f / Task.Targets.Count));
183            FileStream stream = null;
184
185            try
186            {
187                //Overwrite the entire drive
188                IErasureMethod method = EffectiveMethod;
189                if (Volume != null)
190                {
191                    Progress.Total = Volume.TotalSize;
192                    stream = Volume.Open(FileAccess.ReadWrite, FileShare.ReadWrite);
193                }
194                else if (PhysicalDrive != null)
195                {
196                    Progress.Total = PhysicalDrive.Size;
197                    PhysicalDrive.DeleteDriveLayout();
198                    stream = PhysicalDrive.Open(FileAccess.ReadWrite, FileShare.ReadWrite);
199                }
200                else
201                    throw new InvalidOperationException(S._("The Drive erasure target requires a " +
202                        "volume or physical drive selected for erasure."));
203
204                //Calculate the size of the erasure
205                Progress.Total = method.CalculateEraseDataSize(null, Progress.Total);
206
207                //Then run the erase task
208                method.Erase(stream, long.MaxValue, Host.Instance.Prngs.ActivePrng,
209                    delegate(long lastWritten, long totalData, int currentPass)
210                    {
211                        Progress.Completed += lastWritten;
212                        /*OnProgressChanged(this, new ProgressChangedEventArgs(Progress,
213                            new TaskProgressChangedEventArgs(ToString(), currentPass, method.Passes)));*/
214
215                        if (Task.Canceled)
216                            throw new OperationCanceledException(S._("The task was cancelled."));
217                    }
218                );
219            }
220            finally
221            {
222                Progress = null;
223                stream.Close();
224            }
225        }
226
227        /// <summary>
228        /// The Progress manager for this target.
229        /// </summary>
230        private new ProgressManager Progress
231        {
232            get
233            {
234                return (ProgressManager)base.Progress;
235            }
236            set
237            {
238                base.Progress = value;
239            }
240        }
241    }
242}
Note: See TracBrowser for help on using the repository browser.