source: trunk/eraser/Eraser.DefaultPlugins/ErasureTargets/SecureMoveErasureTarget.cs @ 2108

Revision 2108, 5.0 KB checked in by lowjoel, 5 years ago (diff)

Addresses #60: Eraser Secure Cut.

  • 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;
26
27using System.Runtime.InteropServices;
28using System.Runtime.Serialization;
29using System.Security.Permissions;
30using System.IO;
31
32using Eraser.Manager;
33using Eraser.Util;
34using Eraser.Util.ExtensionMethods;
35
36namespace Eraser.DefaultPlugins
37{
38    /// <summary>
39    /// Class representing a path that needs to be moved.
40    /// </summary>
41    [Serializable]
42    [Guid("18FB3523-4012-4718-8B9A-BADAA9084214")]
43    public class SecureMoveErasureTarget : FileSystemObjectErasureTarget
44    {
45        #region Serialization code
46        protected SecureMoveErasureTarget(SerializationInfo info, StreamingContext context)
47            : base(info, context)
48        {
49            Destination = (string)info.GetValue("Destination", typeof(string));
50        }
51
52        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
53        public override void GetObjectData(SerializationInfo info, StreamingContext context)
54        {
55            base.GetObjectData(info, context);
56            info.AddValue("Destination", Destination);
57        }
58        #endregion
59
60        public SecureMoveErasureTarget()
61        {
62        }
63
64        public override Guid Guid
65        {
66            get { return GetType().GUID; }
67        }
68
69        public override string Name
70        {
71            get { return S._("Secure move"); }
72        }
73
74        public override string UIText
75        {
76            get { return S._("Securely move {0}", Path); }
77        }
78
79        /// <summary>
80        /// The destination of the move.
81        /// </summary>
82        public string Destination
83        {
84            get;
85            set;
86        }
87
88        public override IErasureTargetConfigurer Configurer
89        {
90            get { return new SecureMoveErasureTargetConfigurer(); }
91        }
92
93        protected override List<StreamInfo> GetPaths()
94        {
95            List<StreamInfo> result = new List<StreamInfo>();
96            if (!File.Exists(Path))
97                return result;
98
99            FileInfo[] files = null;
100            if ((File.GetAttributes(Path) & FileAttributes.Directory) == 0)
101                files = new FileInfo[] { new FileInfo(Path) };
102            else
103                files = GetFiles(new DirectoryInfo(Path));
104
105            foreach (FileInfo info in files)
106            {
107                //Add the alternate data streams
108                result.AddRange(GetPathADSes(info));
109
110                //And the file itself
111                result.Add(new StreamInfo(info.FullName));
112            }
113
114            return result;
115        }
116
117        public override void Execute()
118        {
119            //If the path doesn't exist, exit.
120            if (!File.Exists(Path))
121                return;
122
123            //Create the progress manager.
124            Progress = new SteppedProgressManager();
125
126            try
127            {
128                //Depending on whether the path is a file or directory, execute the
129                //correct fucntion.
130                if ((File.GetAttributes(Path) & FileAttributes.Directory) != 0)
131                {
132                    DirectoryInfo info = new DirectoryInfo(Path);
133                    CopyDirectory(info);
134                }
135                else
136                {
137                    FileInfo info = new FileInfo(Path);
138                    CopyFile(info);
139                }
140            }
141            finally
142            {
143                Progress = null;
144            }
145        }
146
147        private void CopyDirectory(DirectoryInfo info)
148        {
149            throw new NotImplementedException();
150        }
151
152        private void CopyFile(FileInfo info)
153        {
154            ProgressManager copyProgress = new ProgressManager();
155            Progress.Steps.Add(new SteppedProgressManagerStep(copyProgress, 0.5f,
156                S._("Copying source file to destination")));
157
158            try
159            {
160                info.CopyTo(Destination, delegate(long TotalFileSize, long TotalBytesTransferred)
161                    {
162                        copyProgress.Completed = TotalBytesTransferred;
163                        copyProgress.Total = TotalFileSize;
164                        OnProgressChanged(this, new ProgressChangedEventArgs(Progress, 
165                            new TaskProgressChangedEventArgs(info.FullName, 1, 1)));
166
167                        if (Task.Canceled)
168                            return IO.CopyProgressFunctionResult.Stop;
169                        return IO.CopyProgressFunctionResult.Continue;
170                    });
171            }
172            catch (OperationCanceledException)
173            {
174                //The copy was cancelled: Complete the copy part.
175                copyProgress.MarkComplete();
176
177                //We need to erase the partially copied copy of the file.
178                FileInfo copiedFile = new FileInfo(Destination);
179                List<StreamInfo> streams = new List<StreamInfo>(
180                    copiedFile.GetADSes().Select(x => new StreamInfo(copiedFile.FullName, x));
181                streams.Add(new StreamInfo(copiedFile.FullName));
182                long totalSize = streams.Sum(x => x.Length);
183
184                foreach (StreamInfo stream in streams)
185                {
186                    ProgressManager destroyProgress = new ProgressManager();
187                    Progress.Steps.Add(new SteppedProgressManagerStep(destroyProgress,
188                        0.5f * stream.Length / totalSize,
189                        S._("Erasing incomplete destination file")));
190                    EraseStream(stream, destroyProgress);
191                }
192
193                //Rethrow the exception.
194                throw;
195            }
196        }
197    }
198}
Note: See TracBrowser for help on using the repository browser.