/// <summary> /// Create a new snapshot from scratch /// </summary> private void Create() { DateTime start = DateTime.Now; // TO DO: check free space on parity drive here? UInt32 totalBlocks = 1; // make it one so no chance of divide-by-zero below foreach (DataDrive d in drives) { d.BeginFileEnum(); UInt32 scanBlocks = d.TotalScanBlocks; if (scanBlocks > totalBlocks) totalBlocks = scanBlocks; } try { ParityBlock parityBlock = new ParityBlock(parity); byte[] dataBuf = new byte[Parity.BLOCK_SIZE]; UInt32 block = 0; bool done = false; while (!done) { done = true; foreach (DataDrive d in drives) if (d.GetNextBlock(done ? parityBlock.Data : dataBuf)) if (done) done = false; else parityBlock.Add(dataBuf); if (!done) parityBlock.Write(block); Progress = (double)block / totalBlocks; block++; if (cancel) { // we can't salvage an initial update that was cancelled so we'll have to start again from scratch next time. LogFile.Log("Initial update cancelled. Resetting parity to empty."); Erase(); return; } } } catch (Exception e) { LogFile.Log("Fatal error on initial update: " + e.Message); LogFile.Log(e.StackTrace); // can't recover from errors either, must also start over from scratch Erase(); throw new UpdateFailedException(e.Message); } finally { foreach (DataDrive d in drives) d.EndFileEnum(); parity.Close(); if (!cancel) Empty = false; } }