Ejemplo n.º 1
0
        public static FileRecord LoadFromFile(FileStream f, DataDrive drive)
        {
            FileRecord rec = new FileRecord();

            rec.Name = ReadString(f);
            if (rec.Name.Length == 0)
            {
                return(null);
            }
            rec.Length        = ReadLong(f);
            rec.Attributes    = (FileAttributes)ReadUInt32(f);
            rec.CreationTime  = ReadDateTime(f);
            rec.LastWriteTime = ReadDateTime(f);
            rec.StartBlock    = ReadUInt32(f);
            rec.HashCode      = new byte[16];
            rec.drive         = drive;
            if (f.Read(rec.HashCode, 0, 16) != 16)
            {
                return(null);
            }
            if (rec.Name[0] == '\\')
            {
                rec.Name = rec.Name.TrimStart('\\');
            }

            return(rec);
        }
Ejemplo n.º 2
0
 private void Initialize(FileInfo info, string name, DataDrive drive)
 {
     Name          = name;
     Length        = info.Length;
     Attributes    = info.Attributes;
     CreationTime  = info.CreationTime;
     LastWriteTime = info.LastWriteTime;
     StartBlock    = 0;
     this.drive    = drive;
 }
Ejemplo n.º 3
0
        public DataDriveViewModel(DataDrive dataDrive, Config config)
        {
            this.config = config;
              DataDrive = dataDrive;
              DataDrive.PropertyChanged += HandlePropertyChanged;
              DataDrive.ChangesDetected += HandleChangesDetected;
              UpdateStatus();
              UpdateFileCount();
              UpdateAdditionalInfo();

              autoScanTimer = new System.Timers.Timer(1000);
              autoScanTimer.AutoReset = true;
              autoScanTimer.Elapsed += HandleAutoScanTimer;
        }
Ejemplo n.º 4
0
 private void Initialize(FileInfo info, string name, DataDrive drive)
 {
     Name = name;
       Length = info.Length;
       Attributes = info.Attributes;
       CreationTime = info.CreationTime;
       LastWriteTime = info.LastWriteTime;
       StartBlock = 0;
       this.drive = drive;
 }
Ejemplo n.º 5
0
 public FileRecord(FileInfo info, string path, DataDrive drive)
 {
     Initialize(info, Utils.MakeFullPath(path, info.Name), drive);
 }
Ejemplo n.º 6
0
 public FileRecord(string filePath, DataDrive drive)
 {
     FileInfo fi = new FileInfo(filePath);
       Initialize(fi, Utils.StripRoot(drive.Root, filePath), drive);
 }
Ejemplo n.º 7
0
 private void RecoverBlock(DataDrive drive, UInt32 block, ParityBlock parity)
 {
     FileRecord r;
       parity.Load(block);
       foreach (DataDrive d in drives)
     if (d != drive) {
       string error = "";
       try {
     if (d.ReadBlock(block, tempBuf, out r)) {
       parity.Add(tempBuf);
       if (r.Modified)
         error = String.Format("Warning: {0} has been modified.  Some recovered files may be corrupt.", r.FullPath);
     } else if (r != null && !File.Exists(r.FullPath))
       error = String.Format("Warning: {0} could not be found.  Some recovered files may be corrupt.", r.FullPath);
       }
       catch (Exception e) {
     error = e.Message; // ReadBlock should have constructed a nice error message for us
       }
       if (error != "" && errorFiles.Add(error))
     FireErrorMessage(error);
     }
 }
Ejemplo n.º 8
0
        public static FileRecord LoadFromFile(FileStream f, DataDrive drive)
        {
            FileRecord rec = new FileRecord();
              rec.Name = ReadString(f);
              if (rec.Name.Length == 0)
            return null;
              rec.Length = ReadLong(f);
              rec.Attributes = (FileAttributes)ReadUInt32(f);
              rec.CreationTime = ReadDateTime(f);
              rec.LastWriteTime = ReadDateTime(f);
              rec.StartBlock = ReadUInt32(f);
              rec.HashCode = new byte[16];
              rec.drive = drive;
              if (f.Read(rec.HashCode, 0, 16) != 16)
            return null;
              if (rec.Name[0] == '\\')
            rec.Name = rec.Name.TrimStart('\\');

              return rec;
        }
Ejemplo n.º 9
0
 private bool ValidDrive(DataDrive drive)
 {
     foreach (DataDrive d in drives)
     if (d == drive)
       return true;
       return false;
 }
Ejemplo n.º 10
0
 private void PrintBlockMask(DataDrive d)
 {
     BitArray blockMask = d.BlockMask;
       foreach (bool b in blockMask)
     Console.Write("{0}", b ? 'X' : '.');
       Console.WriteLine();
 }
Ejemplo n.º 11
0
 public FileRecord(FileInfo info, string path, DataDrive drive)
 {
     Initialize(info, Utils.MakeFullPath(path, info.Name), drive);
 }
Ejemplo n.º 12
0
        public void Undelete(DataDrive drive, List<string> fileNames)
        {
            List<FileRecord> files = new List<FileRecord>();

              foreach (FileRecord r in drive.Deletes)
            if (fileNames.Contains(r.FullPath))
              files.Add(r);

              if (files.Count == 0) {
            LogFile.Log("No files to undelete.");
            return;
              }

              LogFile.Log("Beginning undelete for {0} file{1}", files.Count, files.Count == 1 ? "" : "s");

              cancel = false;
              recoverTotalBlocks = 0;
              errorFiles.Clear();
              Progress = 0;

              try {
            foreach (FileRecord r in files)
              recoverTotalBlocks += r.LengthInBlocks;
            recoverBlocks = 0;
            int errors = 0;
            int restored = 0;
            foreach (FileRecord r in files) {
              if (RecoverFile(r, drive.Root)) {
            restored++;
            drive.Deletes.Remove(r);
            drive.MaybeRemoveAddByName(r.FullPath);
              }
              else if (!cancel)
            errors++;
              if (cancel)
            break;
              else {
            string statusMsg = String.Format("{0} file{1} restored.", restored, restored == 1 ? "" : "s");
            if (errors > 0)
              statusMsg += " Errors: " + errors;
            Status = statusMsg;
              }
            }
              }
              finally {
            drive.Progress = 0;
            drive.Status = "";
              }
        }
Ejemplo n.º 13
0
 public void ReloadDrives()
 {
     drives.Clear();
       try {
     foreach (Drive d in Config.Drives) {
       if (File.Exists(Path.Combine(Config.ParityDir, d.Metafile)))
     Empty = false;
       DataDrive dataDrive = new DataDrive(d.Path, d.Metafile, Config, env);
       dataDrive.ErrorMessage += HandleDataDriveErrorMessage;
       drives.Add(dataDrive);
     }
       }
       catch (Exception e) {
     drives.Clear();
     throw e;
       }
       // try to record how many drives in the registry
       try {
     Registry.SetValue("HKEY_CURRENT_USER\\Software\\disParity", "dc", Config.Drives.Count,
       RegistryValueKind.DWord);
     Registry.SetValue("HKEY_CURRENT_USER\\Software\\disParity", "mpb", MaxParityBlock(),
       RegistryValueKind.DWord);
       }
       catch { }
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Remove all files from the given drive from the parity set
        /// </summary>
        public void RemoveAllFiles(DataDrive drive)
        {
            totalUpdateBlocks = 0;
              cancel = false;

              // make a copy of the drive's file table to work on
              FileRecord[] files = drive.Files.ToArray();

              // get total blocks for progress reporting
              foreach (FileRecord r in files)
            totalUpdateBlocks += r.LengthInBlocks;

              currentUpdateBlocks = 0;
              Progress = 0;
              drive.Progress = 0;
              foreach (FileRecord r in files) {
            RemoveFromParity(r);
            if (cancel)
              break;
              }
              Progress = 0;
              drive.Progress = 0;
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Recover all files from the given drive to the given location
 /// </summary>
 public void Recover(DataDrive drive, string path, out int successes, out int failures)
 {
     cancel = false;
       if (!ValidDrive(drive))
     throw new Exception("Invalid drive passed to Recover");
       successes = 0;
       failures = 0;
       recoverTotalBlocks = 0;
       errorFiles.Clear();
       Progress = 0;
       foreach (FileRecord f in drive.Files)
     recoverTotalBlocks += f.LengthInBlocks;
       recoverBlocks = 0;
       try {
     foreach (FileRecord f in drive.Files)
       if (RecoverFile(f, path))
     successes++;
       else {
     if (cancel)
       return;
     failures++;
       }
       }
       finally {
     Progress = 0;
     drive.Progress = 0;
     drive.Status = "";
       }
 }
Ejemplo n.º 16
0
        public void HashCheck(DataDrive driveToCheck = null)
        {
            cancel = false;

              int files = 0;
              int failures = 0;
              int inProgres = 0;
              long totalBlocksAllDrives = 0;
              long blocks = 0;

              if (driveToCheck != null)
            totalBlocksAllDrives = driveToCheck.TotalFileBlocks;
              else
            foreach (DataDrive d in drives)
              totalBlocksAllDrives += d.TotalFileBlocks;

              Progress = 0;

              // If a drive encounters a serious problem during its hash check, this will be set
              Exception fatalException = null;

              // Start hashcheck tasks for each drive
              foreach (DataDrive drive in drives) {
            if (driveToCheck != null && drive != driveToCheck)
              continue;

            DataDrive d = drive;
            Interlocked.Increment(ref inProgres);
            Task.Factory.StartNew(() => {
              try {
            UInt32 b = 0;
            UInt32 totalBlocks = d.TotalFileBlocks;
            byte[] buf = new byte[Parity.BLOCK_SIZE];
            LogFile.Log("Starting hashcheck for " + d.Root);
            d.Progress = 0;
            using (MD5 hash = MD5.Create())
              foreach (FileRecord r in d.Files) {
                Interlocked.Increment(ref files);
                // skip zero length files
                if (r.Length == 0)
                  continue;
                // make sure file exists
                if (!File.Exists(r.FullPath)) {
                  FireErrorMessage(r.FullPath + " not found.  Skipping hash check for this file.");
                  b += r.LengthInBlocks;
                  Interlocked.Add(ref blocks, r.LengthInBlocks);
                  continue;
                }
                // warn if file has been modified
                if (r.Modified)
                  FireErrorMessage("Warning: " + r.FullPath + " has been modified.  Hashcheck will probably fail.");
                d.Status = "Reading " + r.FullPath;
                LogFile.Log(d.Status);
                hash.Initialize();
                int read = 0;
                try {
                  using (FileStream s = new FileStream(r.FullPath, FileMode.Open, FileAccess.Read)) {
                    while (!cancel && ((read = s.Read(buf, 0, Parity.BLOCK_SIZE)) > 0)) {
                      hash.TransformBlock(buf, 0, read, buf, 0);
                      d.Progress = (double)b++ / totalBlocks;
                      Interlocked.Increment(ref blocks);
                    }
                  }
                }
                catch (Exception e) {
                  FireErrorMessage("Error reading " + r.FullPath + ": " + e.Message);
                  // progress will be little off after this point, but this is very unlikely anyway so let it be
                  continue;
                }
                if (cancel) {
                  d.Status = "";
                  return;
                }
                hash.TransformFinalBlock(buf, 0, 0);
                if (!Utils.HashCodesMatch(hash.Hash, r.HashCode)) {
                  FireErrorMessage(r.FullPath + " hash check failed");
                  Interlocked.Increment(ref failures);
                }
              }
            d.Status = "";
            if (failures == 0) {
              if (driveToCheck == null)
                d.Status = "Hash check complete.  No errors found.";
              LogFile.Log("Hash check of " + d.Root + " complete.  No errors found.");
            }
            else {
              if (driveToCheck == null)
                d.Status = "Hash check complete.  Errors: " + failures;
              LogFile.Log("Hash check of " + d.Root + " complete.  Errors: " + failures);
            }
              }
              catch (Exception e) {
            d.Status = "Hash check failed: " + e.Message;
            LogFile.Log("Hash check of " + d.Root + " failed: " + e.Message);
            fatalException = e; // this will halt the hash check of all drives below
              }
              finally {
            d.Progress = 0;
            Interlocked.Decrement(ref inProgres);
              }
            });

              }

              // wait for all hashcheck threads to complete
              while (inProgres > 0) {
            if (fatalException != null) {
              // something serious happened to one of the drives?
              cancel = true; // stop all the other tasks
              // CancallableOperation will catch this and log it
              throw fatalException;
            }
            Status = String.Format("Hash check in progress.  Files checked: {0} Failures: {1}", files, failures);
            Progress = (double)blocks / totalBlocksAllDrives;
            Thread.Sleep(100);
              }

              string status;
              if (driveToCheck != null)
            status = "Hash check of " + driveToCheck.Root + " complete.";
              else
            status = "Hash check of all drives complete.";
              if (failures == 0)
            Status = status;
              else
            Status = status + "  Errors: " + failures;
              if (driveToCheck != null)
            LogFile.Log(Status);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Adds a new drive to the parity set to be protected
        /// </summary>
        public DataDrive AddDrive(string path)
        {
            // to do: Check here that this drive is not alredy in the list!
              string metaFile = FindAvailableMetafileName();

              // make sure there isn't already a file there with this name, if there is, rename it
              string fullPath = Path.Combine(Config.ParityDir, metaFile);
              if (File.Exists(fullPath))
            File.Move(fullPath, Path.ChangeExtension(fullPath, ".old"));

              DataDrive newDrive = new DataDrive(path, metaFile, Config, env);
              newDrive.ErrorMessage += HandleDataDriveErrorMessage;
              drives.Add(newDrive);

              // update Config and save
              Config.Drives.Add(new Drive(path, metaFile));
              Config.Save();

              return newDrive;
        }
Ejemplo n.º 18
0
 private DataDriveViewModel AddDrive(DataDrive drive)
 {
     DataDriveViewModel vm = new DataDriveViewModel(drive, config);
       drives.Add(vm);
       drive.PropertyChanged += HandleDateDrivePropertyChanged;
       drive.ScanCompleted += HandleScanCompleted;
       return vm;
 }
Ejemplo n.º 19
0
        private void FlushTempParity(DataDrive drive, ParityChange change)
        {
            bool saveInProgress = true;
              Task.Factory.StartNew(() =>
              {
            try {
              change.Save();
            }
            catch {
            }
            finally {
              saveInProgress = false;
            }
              });

              while (saveInProgress) {
            Thread.Sleep(20);
            drive.Progress = (1.0 - TEMP_FLUSH_PERCENT) + TEMP_FLUSH_PERCENT * change.SaveProgress;
              }
              drive.Progress = 0;
        }
Ejemplo n.º 20
0
        public void RemoveEmptyDrive(DataDrive drive)
        {
            if (drive.FileCount > 0)
            throw new Exception("Attempt to remove non-empty drive");

              // find the config entry for this drive
              Drive driveConfig = Config.Drives.Single(s => s.Path == drive.Root);

              // delete the meta data file, if any
              string metaFilePath = Path.Combine(Config.ParityDir, driveConfig.Metafile);
              if (File.Exists(metaFilePath))
            File.Delete(Path.Combine(Config.ParityDir, driveConfig.Metafile));

              // remove it from the config and save
              Config.Drives.Remove(driveConfig);
              Config.Save();

              // finally remove the drive from the parity set
              drives.Remove(drive);
        }
Ejemplo n.º 21
0
        public FileRecord(string filePath, DataDrive drive)
        {
            FileInfo fi = new FileInfo(filePath);

            Initialize(fi, Utils.StripRoot(drive.Root, filePath), drive);
        }