source: trunk/eraser/Eraser.DefaultPlugins/ErasureTargets/DriveErasureTargetConfigurer.cs @ 2509

Revision 2509, 8.2 KB checked in by lowjoel, 2 years ago (diff)

Redesign the Eraser Plugin framework.

  • Split the plugin-dependent interfaces and related support classes out to Eraser.Plugins assembly
    • The extension interfaces are in the Eraser.Plugins.ExtensionPoints? namespace.
      • New IClientTool interface for plugins to create Eraser-hosted tools (e.g. #147)
    • The Registrars are in the Eraser.Plugins.Registrars namespace
    • Base types are now interfaces, no longer abstract base classes
    • Version the Eraser.plugins assembly differently from the rest of the project so that other plugins can target different versions of Eraser with the same assembly. Change the Eraser.Plugins assembly version only if there is an API change.
  • Plugin loading behaviour:
    • Core plugins will be loaded before the rest of the plugins, but they will be loaded only by assembly name and not by path
    • Non-core plugin loading is handled by the Manager Library and not the Plugin code
    • The PluginInstance? class is now the PluginInfo? class
    • There is no longer a need to indicate the default file and unused space erasure methods, PRNGs etc; they are now hardcoded to prevent plugins from changing defaults.
  • The separate command line for the Eraser shell extension has been removed.
    • The Erase on Restart menu item has been removed (since it is a scheduling option and should be set in the Task Properties Dialog)
  • Task Progress information is now pulled from the Eraser core instead of pushed via events.
  • New persistent store class to generalise the use of the old Settings class
  • IDragAndDropConfigurerFactory for transforming drag-and-drop operations to erasure targets. This removes the Eraser.exe assembly's dependency on Eraser.DefaultPlugins?.

Closes #363.

  • 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.ComponentModel;
25using System.Drawing;
26using System.Data;
27using System.Linq;
28using System.Text;
29using System.Windows.Forms;
30using System.IO;
31using System.Text.RegularExpressions;
32using System.Globalization;
33
34using Eraser.Util;
35using Eraser.Util.ExtensionMethods;
36using Eraser.Plugins;
37using Eraser.Plugins.ExtensionPoints;
38
39namespace Eraser.DefaultPlugins
40{
41    public partial class DriveErasureTargetConfigurer : UserControl, IErasureTargetConfigurer
42    {
43        /// <summary>
44        /// Represents an item in the list of drives.
45        /// </summary>
46        private class PartitionItem
47        {
48            public override string ToString()
49            {
50                if (!string.IsNullOrEmpty(Cache))
51                    return Cache;
52
53                if (PhysicalDrive != null)
54                {
55                    try
56                    {
57                        Cache = S._("Hard disk {0} ({1})", PhysicalDrive.Index,
58                            new FileSize(PhysicalDrive.Size));
59                    }
60                    catch (UnauthorizedAccessException)
61                    {
62                        Cache = S._("Hard disk {0}", PhysicalDrive.Index);
63                    }
64                }
65                else if (Volume != null)
66                {
67                    try
68                    {
69                        if (Volume.IsMounted)
70                            Cache = Volume.MountPoints[0].GetDescription();
71                        else if (Volume.PhysicalDrive != null)
72                            Cache = S._("Partition {0} ({1})",
73                                Volume.PhysicalDrive.Volumes.IndexOf(Volume) + 1,
74                                new FileSize(Volume.TotalSize));
75                        else
76                            Cache = S._("Partition ({0})", new FileSize(Volume.TotalSize));
77                    }
78                    catch (UnauthorizedAccessException)
79                    {
80                        if (Volume.PhysicalDrive != null)
81                            Cache = S._("Partition {0}",
82                                Volume.PhysicalDrive.Volumes.IndexOf(Volume) + 1);
83                        else
84                            Cache = S._("Partition");
85                    }
86                }
87                else
88                    throw new InvalidOperationException();
89
90                return Cache;
91            }
92
93            /// <summary>
94            /// Stores the display text for rapid access.
95            /// </summary>
96            private string Cache;
97
98            /// <summary>
99            /// The Physical drive this partition refers to.
100            /// </summary>
101            public PhysicalDriveInfo PhysicalDrive;
102
103            /// <summary>
104            /// The volume this partition refers to.
105            /// </summary>
106            public VolumeInfo Volume;
107
108            /// <summary>
109            /// The icon of the drive.
110            /// </summary>
111            public Icon Icon;
112        }
113
114        public DriveErasureTargetConfigurer()
115        {
116            InitializeComponent();
117            Theming.ApplyTheme(this);
118
119            //Populate the drives list
120            List<VolumeInfo> volumes = new List<VolumeInfo>();
121            foreach (PhysicalDriveInfo drive in PhysicalDriveInfo.Drives)
122            {
123                PartitionItem item = new PartitionItem();
124                item.PhysicalDrive = drive;
125                partitionCmb.Items.Add(item);
126
127                foreach (VolumeInfo volume in drive.Volumes)
128                {
129                    item = new PartitionItem();
130                    item.Volume = volume;
131
132                    if (volume.IsMounted)
133                    {
134                        DirectoryInfo root = volume.MountPoints[0];
135                        item.Icon = root.GetIcon();
136                    }
137                   
138                    partitionCmb.Items.Add(item);
139                    volumes.Add(volume);
140                }
141            }
142
143            //And then add volumes which aren't accounted for (notably, Dynamic volumes)
144            foreach (VolumeInfo volume in VolumeInfo.Volumes)
145            {
146                if (volumes.IndexOf(volume) == -1 && volume.VolumeType == DriveType.Fixed)
147                {
148                    PartitionItem item = new PartitionItem();
149                    item.Volume = volume;
150
151                    if (volume.IsMounted)
152                    {
153                        DirectoryInfo root = volume.MountPoints[0];
154                        item.Icon = root.GetIcon();
155                    }
156
157                    partitionCmb.Items.Insert(0, item);
158                    volumes.Add(volume);
159                }
160            }
161
162            if (partitionCmb.Items.Count != 0)
163                partitionCmb.SelectedIndex = 0;
164        }
165
166        #region ICliConfigurer<ErasureTarget> Members
167
168        public string Help()
169        {
170            return S._(@"drive               Erases partitions, volumes or drives
171  arguments:
172    drive=\Device\Harddisk<index>
173    drive=\\.\PhysicalDrive<index>
174    drive=\\?\Volume<guid>");
175        }
176
177        public bool ProcessArgument(string argument)
178        {
179            //The hard disk index
180            Regex hardDiskRegex = new Regex("^(drive=)?\\\\Device\\\\Harddisk(?<disk>[\\d]+)",
181                RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
182
183            //PhysicalDrive index
184            Regex physicalDriveIndex = new Regex("^(drive=)?\\\\\\\\\\.\\\\PhysicalDrive(?<disk>[\\d]+)",
185                RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
186
187            //The volume GUID
188            Regex volumeRegex = new Regex("^(drive=)?\\\\\\\\\\?\\\\Volume\\{(?<guid>([0-9a-f-]+))\\}",
189                RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
190
191            //Try to get the hard disk index.
192            Match match = hardDiskRegex.Match(argument);
193            if (!match.Groups["disk"].Success)
194                match = physicalDriveIndex.Match(argument);
195            if (match.Groups["disk"].Success)
196            {
197                //Get the index of the disk.
198                int index = Convert.ToInt32(match.Groups["disk"].Value);
199
200                //Create a physical drive info object for the target disk
201                PhysicalDriveInfo target = new PhysicalDriveInfo(index);
202
203                //Select it in the GUI.
204                foreach (PartitionItem item in partitionCmb.Items)
205                    if (item.PhysicalDrive != null && item.PhysicalDrive.Equals(target))
206                        partitionCmb.SelectedItem = item;
207
208                return true;
209            }
210
211            //Try to get the volume GUID
212            match = volumeRegex.Match(argument);
213            if (match.Groups["guid"].Success)
214            {
215                //Find the volume GUID
216                Guid guid = new Guid(match.Groups["guid"].Value);
217
218                //Create a volume info object for the target volume
219                VolumeInfo target = new VolumeInfo(string.Format(CultureInfo.InvariantCulture,
220                    "\\\\?\\Volume{{{0}}}\\", guid));
221
222                //Select it in the GUI.
223                foreach (PartitionItem item in partitionCmb.Items)
224                    if (item.Volume != null && item.Volume.Equals(target))
225                        partitionCmb.SelectedItem = item;
226               
227                return true;
228            }
229
230            return false;
231        }
232
233        #endregion
234
235        #region IConfigurer<ErasureTarget> Members
236
237        public void LoadFrom(IErasureTarget target)
238        {
239            DriveErasureTarget partition = target as DriveErasureTarget;
240            if (partition == null)
241                throw new ArgumentException("The provided erasure target type is not " +
242                    "supported by this configurer.");
243
244            foreach (PartitionItem item in partitionCmb.Items)
245                if ((item.PhysicalDrive != null &&
246                        item.PhysicalDrive.Equals(partition.PhysicalDrive)) ||
247                    (item.Volume != null && item.Volume.Equals(partition.Volume)))
248                {
249                    partitionCmb.SelectedItem = item;
250                    break;
251                }
252        }
253
254        public bool SaveTo(IErasureTarget target)
255        {
256            DriveErasureTarget partition = target as DriveErasureTarget;
257            if (partition == null)
258                throw new ArgumentException("The provided erasure target type is not " +
259                    "supported by this configurer.");
260
261            PartitionItem item = (PartitionItem)partitionCmb.SelectedItem;
262
263            //Make sure we don't set both Volume and PhysicalDrive
264            partition.PhysicalDrive = null;
265
266            //Then set the proper values.
267            partition.Volume = item.Volume;
268            partition.PhysicalDrive = item.PhysicalDrive;
269            return true;
270        }
271
272        #endregion
273
274        private void OnDrawItem(object sender, DrawItemEventArgs e)
275        {
276            if (e.Index == -1)
277                return;
278
279            Graphics g = e.Graphics;
280            PartitionItem item = (PartitionItem)partitionCmb.Items[e.Index];
281            Color textColour = e.ForeColor;
282            PointF textPos = e.Bounds.Location;
283            if (item.Icon != null)
284                textPos.X += item.Icon.Width + 4;
285            textPos.Y += 1;
286
287            //Set the text colour and background colour if the control is disabled
288            if ((e.State & DrawItemState.Disabled) == 0)
289                e.DrawBackground();
290            else
291            {
292                g.FillRectangle(new SolidBrush(SystemColors.ButtonFace), e.Bounds);
293                textColour = SystemColors.GrayText;
294            }
295
296            if (item.Icon != null)
297                g.DrawIcon(item.Icon, e.Bounds.X + 2, e.Bounds.Y);
298            g.DrawString(item.ToString(), e.Font, new SolidBrush(textColour), textPos);
299            if ((e.State & DrawItemState.Focus) != 0)
300                e.DrawFocusRectangle();
301        }
302    }
303}
Note: See TracBrowser for help on using the repository browser.