Example #1
0
        private static IErasureMethod ErasureMethodFromNameOrGuid(string param)
        {
            try
            {
                return(Host.Instance.ErasureMethods[new Guid(param)]);
            }
            catch (FormatException)
            {
                //Invalid GUID. Check every registered erasure method for the name
                string         upperParam = param.ToUpperInvariant();
                IErasureMethod result     = null;
                foreach (IErasureMethod method in Host.Instance.ErasureMethods)
                {
                    if (method.Name.ToUpperInvariant() == upperParam)
                    {
                        if (result == null)
                        {
                            result = method;
                        }
                        else
                        {
                            throw new ArgumentException(S._("Ambiguous erasure method name: {0} " +
                                                            "identifies more than one erasure method.", param));
                        }
                    }
                }
            }

            throw new ArgumentException(S._("The provided Erasure Method '{0}' does not exist.",
                                            param));
        }
Example #2
0
        private void OnMethodUnregistered(object sender, EventArgs e)
        {
            IErasureMethod method = (IErasureMethod)sender;

            foreach (IErasureMethod obj in eraseFilesMethod.Items)
            {
                if (obj.Guid == method.Guid)
                {
                    eraseFilesMethod.Items.Remove(obj);
                    break;
                }
            }

            foreach (IErasureMethod obj in eraseDriveMethod.Items)
            {
                if (obj.Guid == method.Guid)
                {
                    eraseDriveMethod.Items.Remove(obj);
                    break;
                }
            }

            if (eraseFilesMethod.SelectedIndex == -1)
            {
                eraseFilesMethod.SelectedIndex = 0;
            }
            if (eraseDriveMethod.SelectedIndex == -1)
            {
                eraseDriveMethod.SelectedIndex = 0;
            }
        }
Example #3
0
        public override void EraseFileSystemObject(StreamInfo info, IErasureMethod method,
                                                   ErasureMethodProgressFunction callback)
        {
            //Create the file stream, and call the erasure method to write to
            //the stream.
            long fileArea = GetFileArea(info);

            using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write,
                                               FileShare.None, FileOptions.WriteThrough))
            {
                //Set the end of the stream after the wrap-round the cluster size
                strm.SetLength(fileArea);

                //If the stream is empty, there's nothing to overwrite. Continue
                //to the next entry
                if (strm.Length != 0)
                {
                    //Then erase the file.
                    method.Erase(strm, long.MaxValue, Host.Instance.Prngs.ActivePrng, callback);
                }

                //Set the length of the file to 0.
                strm.Seek(0, SeekOrigin.Begin);
                strm.SetLength(0);
            }
        }
Example #4
0
        private void OnMethodRegistered(object sender, EventArgs e)
        {
            IErasureMethod method = (IErasureMethod)sender;

            eraseFilesMethod.Items.Add(method);
            if (method is IDriveErasureMethod)
            {
                eraseDriveMethod.Items.Add(method);
            }
        }
Example #5
0
        public override void EraseFileSystemObject(StreamInfo info, IErasureMethod method,
                                                   ErasureMethodProgressFunction callback)
        {
            //Check if the file fits in one cluster - if it does it may be MFT resident
            //TODO: any more deterministic way of finding out?
            VolumeInfo volume = VolumeInfo.FromMountPoint(info.DirectoryName);

            if (info.Length < NtfsApi.GetMftRecordSegmentSize(volume))
            {
                //Yes it does, erase exactly to the file length
                using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write,
                                                   FileShare.None))
                {
                    method.Erase(strm, long.MaxValue, Host.Instance.Prngs.ActivePrng,
                                 null);
                }
            }

            //Create the file stream, and call the erasure method to write to
            //the stream.
            long fileArea = GetFileArea(info);

            //If the stream is empty, there's nothing to overwrite. Continue
            //to the next entry
            if (fileArea == 0)
            {
                return;
            }

            using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write,
                                               FileShare.None, FileOptions.WriteThrough))
            {
                //Set the end of the stream after the wrap-round the cluster size
                strm.SetLength(fileArea);

                //Then erase the file.
                method.Erase(strm, long.MaxValue, Host.Instance.Prngs.ActivePrng, callback);

                //Set the length of the file to 0.
                strm.Seek(0, SeekOrigin.Begin);
                strm.SetLength(0);
            }
        }
Example #6
0
        public override void EraseClusterTips(VolumeInfo info, IErasureMethod method,
                                              ClusterTipsSearchProgress searchCallback, ClusterTipsEraseProgress eraseCallback)
        {
            //List all the files which can be erased.
            List <string> files = new List <string>();

            if (!info.IsMounted)
            {
                throw new InvalidOperationException(S._("Could not erase cluster tips in {0} " +
                                                        "as the volume is not mounted.", info.VolumeId));
            }
            ListFiles(info.MountPoints[0], files, searchCallback);

            //For every file, erase the cluster tips.
            for (int i = 0, j = files.Count; i != j; ++i)
            {
                //Get the file attributes for restoring later
                StreamInfo streamInfo = new StreamInfo(files[i]);
                if (!streamInfo.Exists)
                {
                    continue;
                }

                try
                {
                    EraseFileClusterTips(streamInfo, method);
                }
                catch (UnauthorizedAccessException)
                {
                    Logger.Log(S._("{0} did not have its cluster tips erased because you do not " +
                                   "have the required permissions to erase the file cluster tips.", files[i]),
                               LogLevel.Information);
                }
                catch (IOException e)
                {
                    Logger.Log(S._("{0} did not have its cluster tips erased. The error returned " +
                                   "was: {1}", files[i], e.Message), LogLevel.Warning);
                }

                eraseCallback(i, files.Count, files[i]);
            }
        }
Example #7
0
        /// <summary>
        /// Parses the command line for erasure targets and returns them as
        /// a Task object.
        /// </summary>
        /// <param name="arguments">The arguments specified on the command line.</param>
        /// <returns>The task represented on the command line.</returns>
        private static Task TaskFromCommandLine(TaskArguments arguments)
        {
            //Create the task
            Task task = new Task();

            //Get the erasure method the user wants to use
            IErasureMethod method = string.IsNullOrEmpty(arguments.ErasureMethod) ?
                                    ErasureMethodRegistrar.Default :
                                    ErasureMethodFromNameOrGuid(arguments.ErasureMethod);

            //Define the schedule
            if (!string.IsNullOrEmpty(arguments.Schedule))
            {
                switch (arguments.Schedule.ToUpperInvariant())
                {
                case "NOW":
                    task.Schedule = Schedule.RunNow;
                    break;

                case "MANUALLY":
                    task.Schedule = Schedule.RunManually;
                    break;

                case "RESTART":
                    task.Schedule = Schedule.RunOnRestart;
                    break;

                default:
                    throw new ArgumentException(
                              S._("Unknown schedule type: {0}", arguments.Schedule), "/schedule");
                }
            }

            //Parse the rest of the command line parameters as target expressions.
            foreach (string argument in arguments.PositionalArguments)
            {
                IErasureTarget selectedTarget = null;

                //Iterate over every defined erasure target
                foreach (IErasureTarget target in Host.Instance.ErasureTargetFactories)
                {
                    //See if this argument can be handled by the target's configurer
                    IErasureTargetConfigurer configurer = target.Configurer;
                    if (configurer.ProcessArgument(argument))
                    {
                        //Check whether a target has been set (implicitly: check whether two
                        //configurers can process the argument)
                        if (selectedTarget == null)
                        {
                            configurer.SaveTo(target);
                            selectedTarget = target;
                        }
                        else
                        {
                            //Yes, it is an ambiguity. Throw an error.
                            throw new ArgumentException(S._("Ambiguous argument: {0} can be " +
                                                            "handled by more than one erasure target.", argument));
                        }
                    }
                }

                //Check whether a target has been made from parsing the entry.
                if (selectedTarget == null)
                {
                    Console.WriteLine(S._("Unknown argument: {0}, skipped.", argument));
                }
                else
                {
                    selectedTarget.Method = method;
                    task.Targets.Add(selectedTarget);
                }
            }

            //Check the number of tasks in the task.
            if (task.Targets.Count == 0)
            {
                throw new ArgumentException(S._("Tasks must contain at least one erasure target."));
            }

            return(task);
        }
        private void EraseUnusedSpace(VolumeInfo volInfo, DirectoryInfo info, IFileSystem fsInfo,
                                      IErasureMethod method)
        {
            ProgressManager mainProgress = new ProgressManager();

            Progress.Steps.Add(new SteppedProgressManagerStep(mainProgress,
                                                              EraseClusterTips ? 0.8f : 0.9f, S._("Erasing unused space...")));

            //Continue creating files while there is free space.
            while (volInfo.AvailableFreeSpace > 0)
            {
                //Generate a non-existant file name
                string currFile = FileSystemBase.GenerateRandomFileName(info, 18);

                //Create the stream
                FileStream stream = new FileStream(currFile, FileMode.CreateNew,
                                                   FileAccess.Write, FileShare.None, 8, FileOptions.WriteThrough);
                try
                {
                    //Set the length of the file to be the amount of free space left
                    //or the maximum size of one of these dumps.
                    mainProgress.Total = mainProgress.Completed +
                                         method.CalculateEraseDataSize(null, volInfo.AvailableFreeSpace);
                    long streamLength = Math.Min(PassBasedErasureMethod.FreeSpaceFileUnit,
                                                 volInfo.AvailableFreeSpace);

                    //Handle IO exceptions gracefully, because the filesystem
                    //may require more space than demanded by us for file allocation.
                    while (true)
                    {
                        try
                        {
                            stream.SetLength(streamLength);
                            break;
                        }
                        catch (IOException)
                        {
                            if (streamLength > volInfo.ClusterSize)
                            {
                                streamLength -= volInfo.ClusterSize;
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }

                    //Then run the erase task
                    method.Erase(stream, long.MaxValue, Host.Instance.Prngs.ActivePrng,
                                 delegate(long lastWritten, long totalData, int currentPass)
                    {
                        mainProgress.Completed += lastWritten;
                        mainProgress.Tag        = new int[] { currentPass, method.Passes };

                        if (Task.Canceled)
                        {
                            throw new OperationCanceledException(S._("The task was cancelled."));
                        }
                    }
                                 );
                }
                finally
                {
                    stream.Close();
                    fsInfo.ResetFileTimes(new FileInfo(currFile));
                }
            }

            //Mark the main bulk of the progress as complete
            mainProgress.MarkComplete();
        }
        public override void Execute()
        {
            //Check for sufficient privileges to run the unused space erasure.
            if (!Security.IsAdministrator())
            {
                if (Environment.OSVersion.Platform == PlatformID.Win32NT &&
                    Environment.OSVersion.Version >= new Version(6, 0))
                {
                    Logger.Log(S._("The program does not have the required permissions to erase " +
                                   "the unused space on disk. Run the program as an administrator and retry " +
                                   "the operation."), LogLevel.Error);
                }
                else
                {
                    Logger.Log(S._("The program does not have the required permissions to erase " +
                                   "the unused space on disk."), LogLevel.Error);
                }

                return;
            }

            //Check whether System Restore has any available checkpoints.
            if (SystemRestore.GetInstances().Count != 0)
            {
                Logger.Log(S._("This computer has had System Restore or Volume Shadow Copies " +
                               "enabled. This may allow copies of files stored on the disk to be recovered " +
                               "and pose a security concern.", Drive), LogLevel.Warning);
            }

            //If the user is under disk quotas, log a warning message
            if (VolumeInfo.FromMountPoint(Drive).HasQuota)
            {
                Logger.Log(S._("The drive {0} has disk quotas active. This will prevent the " +
                               "complete erasure of unused space and may pose a security concern.",
                               Drive), LogLevel.Warning);
            }

            //Get the erasure method if the user specified he wants the default.
            IErasureMethod method = EffectiveMethod;

            //Make a folder to dump our temporary files in
            DirectoryInfo info      = new DirectoryInfo(Drive);
            VolumeInfo    volInfo   = VolumeInfo.FromMountPoint(Drive);
            IFileSystem   fsManager = Host.Instance.FileSystems[volInfo];

            //Start sampling the speed of the task.
            Progress = new SteppedProgressManager();

            //Erase the cluster tips of every file on the drive.
            if (EraseClusterTips)
            {
                //Define the callback handlers
                ProgressManager tipSearch = new ProgressManager();
                tipSearch.MarkIndeterminate();
                Progress.Steps.Add(new SteppedProgressManagerStep(tipSearch,
                                                                  0.0f, S._("Searching for files' cluster tips...")));
                ClusterTipsSearchProgress searchProgress = delegate(string path)
                {
                    if (Task.Canceled)
                    {
                        throw new OperationCanceledException(S._("The task was cancelled."));
                    }

                    tipSearch.Tag = path;
                };

                ProgressManager tipProgress = new ProgressManager();
                Progress.Steps.Add(new SteppedProgressManagerStep(tipProgress, 0.1f,
                                                                  S._("Erasing cluster tips...")));
                ClusterTipsEraseProgress eraseProgress =
                    delegate(int currentFile, int totalFiles, string currentFilePath)
                {
                    tipSearch.MarkComplete();
                    tipProgress.Total     = totalFiles;
                    tipProgress.Completed = currentFile;
                    tipProgress.Tag       = currentFilePath;

                    if (Task.Canceled)
                    {
                        throw new OperationCanceledException(S._("The task was cancelled."));
                    }
                };

                //Start counting statistics
                fsManager.EraseClusterTips(VolumeInfo.FromMountPoint(Drive),
                                           method, searchProgress, eraseProgress);
                tipProgress.MarkComplete();
            }

            bool lowDiskSpaceNotifications = Shell.LowDiskSpaceNotificationsEnabled;

            info = info.CreateSubdirectory(Path.GetFileName(
                                               FileSystemBase.GenerateRandomFileName(info, 18)));
            try
            {
                //Set the folder's compression flag off since we want to use as much
                //space as possible
                if (info.IsCompressed())
                {
                    info.Uncompress();
                }

                //Disable the low disk space notifications
                Shell.LowDiskSpaceNotificationsEnabled = false;

                //Fill the disk
                EraseUnusedSpace(volInfo, info, fsManager, method);

                //Erase old resident file system table files
                ProgressManager residentProgress = new ProgressManager();
                Progress.Steps.Add(new SteppedProgressManagerStep(residentProgress,
                                                                  0.05f, S._("Old resident file system table files")));
                fsManager.EraseOldFileSystemResidentFiles(volInfo, info, method,
                                                          delegate(int currentFile, int totalFiles)
                {
                    residentProgress.Completed = currentFile;
                    residentProgress.Total     = totalFiles;

                    if (Task.Canceled)
                    {
                        throw new OperationCanceledException(S._("The task was cancelled."));
                    }
                }
                                                          );

                residentProgress.MarkComplete();
            }
            finally
            {
                //Remove the folder holding all our temporary files.
                ProgressManager tempFiles = new ProgressManager();
                Progress.Steps.Add(new SteppedProgressManagerStep(tempFiles,
                                                                  0.0f, S._("Removing temporary files...")));

                fsManager.DeleteFolder(info, true);
                tempFiles.MarkComplete();

                //Reset the low disk space notifications
                Shell.LowDiskSpaceNotificationsEnabled = lowDiskSpaceNotifications;
            }

            //Then clean the old file system entries
            ProgressManager structureProgress = new ProgressManager();

            Progress.Steps.Add(new SteppedProgressManagerStep(structureProgress,
                                                              0.05f, S._("Erasing unused directory structures...")));
            fsManager.EraseDirectoryStructures(volInfo,
                                               delegate(int currentFile, int totalFiles)
            {
                if (Task.Canceled)
                {
                    throw new OperationCanceledException(S._("The task was cancelled."));
                }

                //Compute the progress
                structureProgress.Total     = totalFiles;
                structureProgress.Completed = currentFile;
            }
                                               );

            structureProgress.MarkComplete();
            Progress = null;
        }
 public override bool SupportsMethod(IErasureMethod method)
 {
     return(method == ErasureMethodRegistrar.Default ||
            method is IDriveErasureMethod);
 }
Example #11
0
 public abstract void EraseOldFileSystemResidentFiles(Util.VolumeInfo volume,
                                                      DirectoryInfo tempDirectory, IErasureMethod method,
                                                      FileSystemEntriesEraseProgress callback);
Example #12
0
 public override void EraseOldFileSystemResidentFiles(VolumeInfo volume,
                                                      DirectoryInfo tempDirectory, IErasureMethod method,
                                                      FileSystemEntriesEraseProgress callback)
 {
     //Nothing to be done here. FAT doesn't store files in its FAT.
 }
Example #13
0
        /// <summary>
        /// Erases the cluster tips of the given file.
        /// </summary>
        /// <param name="stream">The stream to erase.</param>
        /// <param name="method">The erasure method to use.</param>
        private void EraseFileClusterTips(StreamInfo streamInfo, IErasureMethod method)
        {
            //Get the file access times
            DateTime lastAccess = streamInfo.LastAccessTime;
            DateTime lastWrite  = streamInfo.LastWriteTime;
            DateTime created    = streamInfo.CreationTime;
            DateTime updated    = streamInfo.LastAccessTime;

            //Get the file attributes
            FileAttributes attributes = streamInfo.Attributes;

            //And get the file lengths to know how much to overwrite
            long fileArea   = GetFileArea(streamInfo);
            long fileLength = streamInfo.Length;

            //If the file length equals the file area there is no cluster tip to overwrite
            if (fileArea == fileLength)
            {
                return;
            }

            //Otherwise, unset any read-only flags, create the stream, lengthen the
            //file, then tell the erasure method to erase the cluster tips.
            try
            {
                streamInfo.Attributes = FileAttributes.Normal;
                FileStream stream = streamInfo.Open(FileMode.Open, FileAccess.Write,
                                                    FileShare.None, FileOptions.WriteThrough);

                try
                {
                    stream.SetLength(fileArea);
                    stream.Seek(fileLength, SeekOrigin.Begin);

                    //Erase the file
                    method.Erase(stream, long.MaxValue, Host.Instance.Prngs.ActivePrng, null);
                }
                finally
                {
                    //Make sure the file length is restored!
                    stream.SetLength(fileLength);

                    //Then destroy the stream
                    stream.Close();
                }
            }
            catch (ArgumentException e)
            {
                //This is an undocumented exception: when the path we are setting
                //cannot be accessed (ERROR_ACCESS_DENIED is returned) an
                //ArgumentException is raised (no idea why!)
                throw new UnauthorizedAccessException(e.Message, e);
            }
            finally
            {
                //Reset the file attributes
                if (streamInfo.Attributes != attributes)
                {
                    streamInfo.Attributes = attributes;
                }

                //Reset the file times
                //Removed MinTimestamp as first param GT31MAR2013
                streamInfo.SetTimes(updated, created, lastWrite, lastAccess);
            }
        }
Example #14
0
        /// <summary>
        /// Attempts to erase a stream, trying to close all open handles if a process has
        /// a lock on the file.
        /// </summary>
        /// <param name="fsManager">The file system provider used to erase the stream.</param>
        /// <param name="method">The erasure method to use to erase the stream.</param>
        /// <param name="info">The stream to erase.</param>
        /// <param name="callback">The erasure progress callback.</param>
        private void TryEraseStream(IFileSystem fsManager, IErasureMethod method, StreamInfo info,
                                    ErasureMethodProgressFunction callback)
        {
            for (int i = 0; ; ++i)
            {
                try
                {
                    //Make sure the file does not have any attributes which may affect
                    //the erasure process
                    if ((info.Attributes & FileAttributes.Compressed) != 0 ||
                        (info.Attributes & FileAttributes.Encrypted) != 0 ||
                        (info.Attributes & FileAttributes.SparseFile) != 0)
                    {
                        //Log the error
                        Logger.Log(S._("The file {0} could not be erased because the file was " +
                                       "either compressed, encrypted or a sparse file.", info.FullName),
                                   LogLevel.Error);
                        return;
                    }

                    //Do not erase reparse points, as they will cause other references to the file
                    //to be to garbage.
                    if ((info.Attributes & FileAttributes.ReparsePoint) == 0)
                    {
                        fsManager.EraseFileSystemObject(info, method, callback);
                    }
                    else
                    {
                        Logger.Log(S._("The file {0} is a hard link or a symbolic link thus the " +
                                       "contents of the file was not erased.", info.FullName), LogLevel.Notice);
                    }
                    return;
                }
                catch (FileNotFoundException)
                {
                    Logger.Log(S._("The file {0} was not erased because it was " +
                                   "deleted before it could be erased.", info.FullName), LogLevel.Information);
                }
                catch (DirectoryNotFoundException)
                {
                    Logger.Log(S._("The file {0} was not erased because the containing " +
                                   "directory was deleted before it could be erased.", info.FullName),
                               LogLevel.Information);
                }
                catch (SharingViolationException)
                {
                    if (!Host.Instance.Settings.ForceUnlockLockedFiles)
                    {
                        throw;
                    }

                    //Try closing all open handles. If it succeeds, we can run the erase again.
                    //To prevent Eraser from deadlocking, we will only attempt this once. Some
                    //programs may be aggressive and keep a handle open in a tight loop.
                    List <OpenHandle> remainingHandles = OpenHandle.Close(info.FullName);
                    if (i == 0 && remainingHandles.Count == 0)
                    {
                        continue;
                    }

                    //Either we could not close all instances, or we already tried twice. Report
                    //the error.
                    string processes = string.Empty;
                    {
                        StringBuilder processStr = new StringBuilder();
                        foreach (OpenHandle handle in remainingHandles)
                        {
                            try
                            {
                                processStr.AppendFormat(
                                    System.Globalization.CultureInfo.InvariantCulture,
                                    "{0}, ", handle.Process.MainModule.FileName);
                            }
                            catch (System.ComponentModel.Win32Exception)
                            {
                                processStr.AppendFormat(
                                    System.Globalization.CultureInfo.InvariantCulture,
                                    "Process ID {0}, ", handle.Process.Id);
                            }
                        }

                        if (processStr.Length > 2)
                        {
                            processes = processStr.ToString().Remove(processStr.Length - 2).Trim();
                        }
                        else
                        {
                            processes = S._("(unknown)");
                        }
                    }

                    throw new SharingViolationException(S._(
                                                            "Could not force closure of file \"{0}\" {1}", info.FileName,
                                                            S._("(locked by {0})", processes)));
                }
            }
        }
Example #15
0
        /// <summary>
        /// Erases the provided stream, and updates progress using the provided
        /// progress manager.
        /// </summary>
        /// <param name="info">The information regarding the stream that needs erasure.</param>
        /// <param name="progress">The progress manager for the erasure of the current
        /// stream.</param>
        protected void EraseStream(StreamInfo info, ProgressManager progress)
        {
            //Check that the file exists - we do not want to bother erasing nonexistant files
            if (!info.Exists)
            {
                Logger.Log(S._("The file {0} was not erased as the file does not exist.",
                               info.FileName), LogLevel.Notice);
                return;
            }

            //Get the filesystem provider to handle the secure file erasures
            IFileSystem fsManager = Host.Instance.FileSystems[
                VolumeInfo.FromMountPoint(info.DirectoryName)];

            bool isReadOnly = false;

            try
            {
                //Update the task progress
                IErasureMethod method = EffectiveMethod;

                //Remove the read-only flag, if it is set.
                if (isReadOnly = info.IsReadOnly)
                {
                    info.IsReadOnly = false;
                }

                //Define the callback function for progress reporting.
                ErasureMethodProgressFunction callback =
                    delegate(long lastWritten, long totalData, int currentPass)
                {
                    if (Task.Canceled)
                    {
                        throw new OperationCanceledException(S._("The task was cancelled."));
                    }

                    progress.Tag        = new int[] { currentPass, method.Passes };
                    progress.Total      = totalData;
                    progress.Completed += lastWritten;
                };

                TryEraseStream(fsManager, method, info, callback);

                //Remove the file.
                FileInfo fileInfo = info.File;
                if (fileInfo != null)
                {
                    fsManager.DeleteFile(fileInfo);
                }
                progress.MarkComplete();
            }
            catch (UnauthorizedAccessException)
            {
                Logger.Log(S._("The file {0} could not be erased because the file's " +
                               "permissions prevent access to the file.", info.FullName), LogLevel.Error);
            }
            catch (SharingViolationException e)
            {
                Logger.Log(S._("The file {0} could not be erased because the file is " +
                               "currently in used by another application.", info.FullName), LogLevel.Error);
            }
            finally
            {
                //Re-set the read-only flag if the file exists (i.e. there was an error)
                if (isReadOnly && info.Exists && !info.IsReadOnly)
                {
                    info.IsReadOnly = isReadOnly;
                }
            }
        }
Example #16
0
 public abstract void EraseFileSystemObject(StreamInfo info, IErasureMethod method,
                                            ErasureMethodProgressFunction callback);
Example #17
0
        public override void EraseOldFileSystemResidentFiles(VolumeInfo volume,
                                                             DirectoryInfo tempDirectory, IErasureMethod method,
                                                             FileSystemEntriesEraseProgress callback)
        {
            //Squeeze files smaller than one MFT record until the volume and the MFT is full.
            long MFTRecordSize = NtfsApi.GetMftRecordSegmentSize(volume);
            long lastFileSize  = MFTRecordSize;

            try
            {
                for ( ; ;)
                {
                    //Open this stream
                    string     fileName = GenerateRandomFileName(tempDirectory, 18);
                    FileStream strm     = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write,
                                                         FileShare.None, 8, FileOptions.WriteThrough);
                    try
                    {
                        //Stretch the file size to use up some of the resident space.
                        strm.SetLength(lastFileSize);

                        //Then run the erase task
                        method.Erase(strm, long.MaxValue, Host.Instance.Prngs.ActivePrng, null);

                        //Call the callback function if one is provided. We'll provide a dummy
                        //value since we really have no idea how much of the MFT we can clean.
                        if (callback != null)
                        {
                            callback((int)(MFTRecordSize - lastFileSize), (int)MFTRecordSize);
                        }
                    }
                    catch (IOException)
                    {
                        if (lastFileSize-- == 0)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        //Close the stream handle
                        strm.Close();

                        //Then reset the time the file was created.
                        ResetFileTimes(new FileInfo(fileName));
                    }
                }
            }
            catch (IOException)
            {
                //OK, enough squeezing: there isn't enough space to even create a new MFT record.
            }
        }
        public override void Execute()
        {
            //Check for sufficient privileges to run the erasure.
            if (!Security.IsAdministrator())
            {
                if (Environment.OSVersion.Platform == PlatformID.Win32NT &&
                    Environment.OSVersion.Version >= new Version(6, 0))
                {
                    Logger.Log(S._("The program does not have the required permissions to erase " +
                                   "the disk. Run the program as an administrator and retry the operation."),
                               LogLevel.Error);
                }
                else
                {
                    Logger.Log(S._("The program does not have the required permissions to erase " +
                                   "the disk."), LogLevel.Error);
                }

                return;
            }

            Progress = new SteppedProgressManager();
            ProgressManager stepProgress = new ProgressManager();

            Progress.Steps.Add(new SteppedProgressManagerStep(stepProgress, 1.0f,
                                                              ToString()));
            FileStream stream = null;

            try
            {
                //Overwrite the entire drive
                IErasureMethod method = EffectiveMethod;
                if (Volume != null)
                {
                    stepProgress.Total = Volume.TotalSize;
                    stream             = Volume.Open(FileAccess.ReadWrite, FileShare.ReadWrite);
                }
                else if (PhysicalDrive != null)
                {
                    stepProgress.Total = PhysicalDrive.Size;
                    PhysicalDrive.DeleteDriveLayout();
                    if (PhysicalDrive.Volumes.Count == 1)
                    {
                        //This could be a removable device where Windows sees an oversized floppy.
                        stream = PhysicalDrive.Volumes[0].Open(FileAccess.ReadWrite, FileShare.ReadWrite);
                    }
                    else if (PhysicalDrive.Volumes.Count > 0)
                    {
                        throw new InvalidOperationException(S._("The partition table on the drive " +
                                                                "could not be erased."));
                    }
                    else
                    {
                        stream = PhysicalDrive.Open(FileAccess.ReadWrite, FileShare.ReadWrite);
                    }
                }
                else
                {
                    throw new InvalidOperationException(S._("The Drive erasure target requires a " +
                                                            "volume or physical drive selected for erasure."));
                }

                //Calculate the size of the erasure
                stepProgress.Total = method.CalculateEraseDataSize(null, stepProgress.Total);

                //Then run the erase task
                method.Erase(stream, long.MaxValue, Host.Instance.Prngs.ActivePrng,
                             delegate(long lastWritten, long totalData, int currentPass)
                {
                    stepProgress.Completed += lastWritten;
                    stepProgress.Tag        = new int[] { currentPass, method.Passes };

                    if (Task.Canceled)
                    {
                        throw new OperationCanceledException(S._("The task was cancelled."));
                    }
                }
                             );
            }
            finally
            {
                Progress = null;
                if (stream != null)
                {
                    stream.Close();
                }
            }
        }
Example #19
0
 public virtual bool SupportsMethod(IErasureMethod method)
 {
     return(true);
 }
Example #20
0
 public abstract void EraseClusterTips(VolumeInfo info, IErasureMethod method,
                                       ClusterTipsSearchProgress searchCallback, ClusterTipsEraseProgress eraseCallback);