- Timestamp:
- 11/6/2011 11:56:04 PM (20 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eraser6/pluginsRewrite/Eraser.Manager/ErasureMethod.cs
r2085 r2352 23 23 using System.Collections.Generic; 24 24 using System.Text; 25 26 using System.Reflection; 25 27 using System.IO; 26 using System.Reflection; 28 27 29 using Eraser.Util; 30 using Eraser.Plugins; 31 using Eraser.Plugins.ExtensionPoints; 28 32 29 33 namespace Eraser.Manager 30 34 { 31 /// <summary>32 /// An interface class representing the method for erasure. If classes only33 /// inherit this class, then the method can only be used to erase abstract34 /// streams, not unused drive space.35 /// </summary>36 public abstract class ErasureMethod : IRegisterable37 {38 public override string ToString()39 {40 if (Passes == 0)41 return Name;42 return Passes == 1 ? S._("{0} (1 pass)", Name) :43 S._("{0} ({1} passes)", Name, Passes);44 }45 46 /// <summary>47 /// The name of this erase pass, used for display in the UI48 /// </summary>49 public abstract string Name50 {51 get;52 }53 54 /// <summary>55 /// The number of erase passes for this erasure method.56 /// </summary>57 public abstract int Passes58 {59 get;60 }61 62 /// <summary>63 /// The GUID for this erasure method.64 /// </summary>65 public abstract Guid Guid66 {67 get;68 }69 70 /// <summary>71 /// Calculates the total size of the erasure data that needs to be written.72 /// This is mainly for use by the Manager to determine how much data needs73 /// to be written to disk.74 /// </summary>75 /// <param name="paths">The list containing the file paths to erase. This76 /// may be null if the list of paths are unknown.</param>77 /// <param name="targetSize">The precomputed value of the total size of78 /// the files to be erased.</param>79 /// <returns>The total size of the files that need to be erased.</returns>80 /// <remarks>This function MAY be slow. Most erasure methods can81 /// calculate this amount fairly quickly as the number of files and the82 /// total size of the files (the ones that take most computation time)83 /// are already provided. However some exceptional cases may take a84 /// long time if the data set is large.</remarks>85 public abstract long CalculateEraseDataSize(ICollection<StreamInfo> paths, long targetSize);86 87 /// <summary>88 /// The main bit of the class! This function is called whenever data has89 /// to be erased. Erase the stream passed in, using the given PRNG for90 /// randomness where necessary.91 ///92 /// This function should be implemented thread-safe as using the same93 /// instance, this function may be called across different threads.94 /// </summary>95 /// <param name="stream">The stream which needs to be erased.</param>96 /// <param name="erasureLength">The length of the stream to erase. If all97 /// data in the stream should be overwritten, then pass in the maximum98 /// value for long, the function will take the minimum.</param>99 /// <param name="prng">The PRNG source for random data.</param>100 /// <param name="callback">The progress callback function.</param>101 public abstract void Erase(Stream stream, long erasureLength, Prng prng,102 ErasureMethodProgressFunction callback);103 104 /// <summary>105 /// Disk operation write unit. Chosen such that this value mod 3, 4, 512,106 /// and 1024 is 0107 /// </summary>108 public const int DiskOperationUnit = 1536 * 4096;109 110 /// <summary>111 /// Unused space erasure file size. Each of the files used in erasing112 /// unused space will be of this size.113 /// </summary>114 public const int FreeSpaceFileUnit = DiskOperationUnit * 36;115 116 /// <summary>117 /// Shuffles the passes in the input array, effectively randomizing the118 /// order or rewrites.119 /// </summary>120 /// <param name="passes">The input set of passes.</param>121 /// <returns>The shuffled set of passes.</returns>122 protected static ErasureMethodPass[] ShufflePasses(ErasureMethodPass[] passes)123 {124 //Make a copy.125 ErasureMethodPass[] result = new ErasureMethodPass[passes.Length];126 passes.CopyTo(result, 0);127 128 //Randomize.129 Prng rand = ManagerLibrary.Instance.PrngRegistrar[ManagerLibrary.Settings.ActivePrng];130 for (int i = 0; i < result.Length; ++i)131 {132 int val = rand.Next(result.Length - 1);133 ErasureMethodPass tmpPass = result[val];134 result[val] = result[i];135 result[i] = tmpPass;136 }137 138 return result;139 }140 141 /// <summary>142 /// Helper function. This function will write random data to the stream143 /// using the provided PRNG.144 /// </summary>145 /// <param name="strm">The buffer to populate with data to write to disk.</param>146 /// <param name="prng">The PRNG used.</param>147 public static void WriteRandom(byte[] buffer, object value)148 {149 ((Prng)value).NextBytes(buffer);150 }151 152 /// <summary>153 /// Helper function. This function will write the repeating pass constant.154 /// to the provided buffer.155 /// </summary>156 /// <param name="strm">The buffer to populate with data to write to disk.</param>157 /// <param name="value">The byte[] to write.</param>158 public static void WriteConstant(byte[] buffer, object value)159 {160 byte[] constant = (byte[])value;161 for (int i = 0; i < buffer.Length; ++i)162 buffer[i] = constant[i % constant.Length];163 }164 }165 166 /// <summary>167 /// A simple callback for clients to retrieve progress information from168 /// the erase method.169 /// </summary>170 /// <param name="lastWritten">The amount of data written to the stream since171 /// the last call to the delegate.</param>172 /// <param name="totalData">The total amount of data that must be written to173 /// complete the erasure.</param>174 /// <param name="currentPass">The current pass number. The total number175 /// of passes can be found from the Passes property.</param>176 public delegate void ErasureMethodProgressFunction(long lastWritten, long totalData,177 int currentPass);178 179 /// <summary>180 /// A pass object. This object holds both the pass function, as well as the181 /// data used for the pass (random, byte, or triplet)182 /// </summary>183 public class ErasureMethodPass184 {185 public override string ToString()186 {187 return OpaqueValue == null ? S._("Random") : OpaqueValue.ToString();188 }189 190 /// <summary>191 /// Constructor.192 /// </summary>193 /// <param name="function">The delegate to the function.</param>194 /// <param name="opaqueValue">The opaque value passed to the function.</param>195 public ErasureMethodPass(ErasureMethodPassFunction function, object opaqueValue)196 {197 Function = function;198 OpaqueValue = opaqueValue;199 }200 201 /// <summary>202 /// Executes the pass.203 /// </summary>204 /// <param name="buffer">The buffer to populate with the data to write.</param>205 /// <param name="prng">The PRNG used for random passes.</param>206 public void Execute(byte[] buffer, Prng prng)207 {208 Function(buffer, OpaqueValue == null ? prng : OpaqueValue);209 }210 211 /// <summary>212 /// The function to execute for this pass.213 /// </summary>214 public ErasureMethodPassFunction Function { get; set; }215 216 /// <summary>217 /// The value to be passed to the executing function.218 /// </summary>219 public object OpaqueValue { get; set; }220 }221 222 /// <summary>223 /// The prototype of a pass.224 /// </summary>225 /// <param name="strm">The buffer to populate with data to write to disk.</param>226 /// <param name="opaque">An opaque value, depending on the type of callback.</param>227 public delegate void ErasureMethodPassFunction(byte[] buffer, object opaque);228 229 /// <summary>230 /// This class adds functionality to the ErasureMethod class to erase231 /// unused drive space.232 /// </summary>233 public abstract class UnusedSpaceErasureMethod : ErasureMethod234 {235 /// <summary>236 /// This function will allow clients to erase a file in a set of files237 /// used to fill the disk, thus achieving disk unused space erasure.238 ///239 /// By default, this function will simply call the Erase method inherited240 /// from the ErasureMethod class.241 ///242 /// This function should be implemented thread-safe as using the same243 /// instance, this function may be called across different threads.244 /// </summary>245 /// <param name="strm">The stream which needs to be erased.</param>246 /// <param name="prng">The PRNG source for random data.</param>247 /// <param name="callback">The progress callback function.</param>248 public virtual void EraseUnusedSpace(Stream stream, Prng prng, ErasureMethodProgressFunction callback)249 {250 Erase(stream, long.MaxValue, prng, callback);251 }252 }253 254 /// <summary>255 /// Pass-based erasure method. This subclass of erasure methods follow a fixed256 /// pattern (constant or random data) for every pass, although the order of257 /// passes can be randomized. This is to simplify definitions of classes in258 /// plugins.259 ///260 /// Since instances of this class apply data by passes, they can by default261 /// erase unused drive space as well.262 /// </summary>263 public abstract class PassBasedErasureMethod : UnusedSpaceErasureMethod264 {265 public override int Passes266 {267 get { return PassesSet.Length; }268 }269 270 /// <summary>271 /// Whether the passes should be randomized before running them in random272 /// order.273 /// </summary>274 protected abstract bool RandomizePasses275 {276 get;277 }278 279 /// <summary>280 /// The set of Pass objects describing the passes in this erasure method.281 /// </summary>282 protected abstract ErasureMethodPass[] PassesSet283 {284 get;285 }286 287 public override long CalculateEraseDataSize(ICollection<StreamInfo> paths, long targetSize)288 {289 //Simple. Amount of data multiplied by passes.290 return targetSize * Passes;291 }292 293 public override void Erase(Stream stream, long erasureLength, Prng prng,294 ErasureMethodProgressFunction callback)295 {296 //Randomize the order of the passes297 ErasureMethodPass[] randomizedPasses = PassesSet;298 if (RandomizePasses)299 randomizedPasses = ShufflePasses(randomizedPasses);300 301 //Remember the starting position of the stream.302 long strmStart = stream.Position;303 long strmLength = Math.Min(stream.Length - strmStart, erasureLength);304 long totalData = CalculateEraseDataSize(null, strmLength);305 306 //Allocate memory for a buffer holding data for the pass.307 byte[] buffer = new byte[Math.Min(DiskOperationUnit, strmLength)];308 309 //Run every pass!310 for (int pass = 0; pass < Passes; ++pass)311 {312 //Do a progress callback first.313 if (callback != null)314 callback(0, totalData, pass + 1);315 316 //Start from the beginning again317 stream.Seek(strmStart, SeekOrigin.Begin);318 319 //Write the buffer to disk.320 long toWrite = strmLength;321 int dataStopped = buffer.Length;322 while (toWrite > 0)323 {324 //Calculate how much of the buffer to write to disk.325 int amount = (int)Math.Min(toWrite, buffer.Length - dataStopped);326 327 //If we have no data left, get more!328 if (amount == 0)329 {330 randomizedPasses[pass].Execute(buffer, prng);331 dataStopped = 0;332 continue;333 }334 335 //Write the data.336 stream.Write(buffer, dataStopped, amount);337 stream.Flush();338 toWrite -= amount;339 340 //Do a progress callback.341 if (callback != null)342 callback(amount, totalData, pass + 1);343 }344 }345 }346 }347 348 35 /// <summary> 349 36 /// Class managing all the erasure methods. This class pairs GUIDs with constructor … … 383 70 384 71 public override void Erase(Stream strm, long erasureLength, Prng prng, 385 ErasureMethod ProgressFunction callback)72 ErasureMethod.ErasureMethodProgressFunction callback) 386 73 { 387 74 throw new InvalidOperationException("The DefaultMethod class should never " +
Note: See TracChangeset
for help on using the changeset viewer.
