source: branches/eraser6/DefaultPlugins/EraseFirstLast16KB.cs @ 328

Revision 328, 3.7 KB checked in by lowjoel, 6 years ago (diff)

The FirstLast? 16KB erasure method now allows explicit setting of the erasure method to use, since the FL16kb method is merely a filter. This is held across tasks for as long a task is running.

Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using Eraser.Manager;
6using Eraser.Util;
7using System.IO;
8using System.Threading;
9
10namespace Eraser.DefaultPlugins
11{
12    class FirstLast16KB : ErasureMethod
13    {
14        public override string Name
15        {
16            get { return S._("First/last 16KB Erasure"); }
17        }
18
19        public override int Passes
20        {
21            get { return 0; } //Variable number, depending on defaults.
22        }
23
24        public override Guid GUID
25        {
26            get { return new Guid("{0C2E07BF-0207-49a3-ADE8-46F9E1499C01}"); }
27        }
28
29        public override long CalculateEraseDataSize(List<string> paths, long targetSize)
30        {
31            //Amount of data required to be written.
32            long amountToWrite = 0;
33            if (paths == null)
34            {
35                if (targetSize <= dataSize)
36                    amountToWrite = targetSize;
37                else
38                    amountToWrite = dataSize * 2;
39            }
40            else
41                amountToWrite = paths.Count * dataSize * 2;
42
43            //The final amount has to be multiplied by the number of passes.
44            return amountToWrite * Method.Passes;
45        }
46
47        public override void Erase(Stream strm, long erasureLength, PRNG prng,
48            OnProgress callback)
49        {
50            //Make sure that the erasureLength passed in here is the maximum value
51            //for the size of long, since we don't want to write extra or write
52            //less.
53            if (erasureLength != long.MaxValue)
54                throw new ArgumentException(S._("The amount of data erased should not be " +
55                    "limited, since this is a self-limiting erasure method."));
56
57            try
58            {
59                //Acquire a lock on the cached method object and set it if unset.
60                cachedMethodSemaphore.WaitOne();
61                if (cachedMethod == null)
62                    cachedMethod = Method;
63
64                //If the target stream is shorter than 16kb, just forward it to the default
65                //function.
66                if (strm.Length < dataSize)
67                {
68                    cachedMethod.Erase(strm, erasureLength, prng, callback);
69                    return;
70                }
71
72                //Seek to the beginning and write 16kb.
73                strm.Seek(0, SeekOrigin.Begin);
74                cachedMethod.Erase(strm, dataSize, prng, callback);
75
76                //Seek to the end - 16kb, and write.
77                strm.Seek(-dataSize, SeekOrigin.End);
78                cachedMethod.Erase(strm, long.MaxValue, prng, callback);
79            }
80            finally
81            {
82                //Check if no other threads are using the cached erasure method.
83                if (cachedMethodSemaphore.Release() == int.MaxValue - 1)
84                    //If so, we no longer need to cache.
85                    cachedMethod = null;
86            }
87        }
88
89        private ErasureMethod Method
90        {
91            get
92            {
93                //If there are threads locking the cached method variable just
94                //return that
95                if (cachedMethod != null)
96                    return cachedMethod;
97
98                //Try to retrieve the set erasure method
99                ErasureMethod defaultMethod = ErasureMethodManager.GetInstance(
100                    (Guid)DefaultPlugin.Settings["FL16Method"]);
101
102                //If we have no default or we are the default then throw an exception
103                if (defaultMethod == null || defaultMethod.GUID == GUID)
104                    throw new InvalidOperationException(S._("The First/last 16KB erasure method " +
105                        "requires another erasure method to erase the file.\n\nThis can " +
106                        "be set in the Plugin Settings dialog."));
107
108                return defaultMethod;
109            }
110        }
111
112        /// <summary>
113        /// The amount of data to be erased from the header and the end of the file.
114        /// </summary>
115        private const long dataSize = 16 * 1024;
116
117        /// <summary>
118        /// The cached erasure method. This is used when erasing so that the properties
119        /// of this class is not inconsistent in the event that the method of erasure
120        /// changes while executing.
121        /// </summary>
122        ErasureMethod cachedMethod = null;
123
124        /// <summary>
125        /// Tracks the number of erasures locking the cached method variable.
126        /// </summary>
127        Semaphore cachedMethodSemaphore = new Semaphore(int.MaxValue, int.MaxValue);
128    }
129}
Note: See TracBrowser for help on using the repository browser.