source: branches/eraser6/XmlTaskLists/Eraser.DefaultPlugins/ErasureTargets/DriveErasureTarget.cs @ 2584

Revision 2584, 6.1 KB checked in by lowjoel, 3 years ago (diff)

Switch the Default Plugin's erasure targets to follow the new IXmlSerializable interface.

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