private unsafe void ValidateBlock(byte[] buffer) { long checksum1; int checksum2; fixed(byte *lpData = buffer) { Footer.ComputeChecksum((IntPtr)lpData, out checksum1, out checksum2, buffer.Length - 16); long checksumInData1 = *(long *)(lpData + buffer.Length - 16); int checksumInData2 = *(int *)(lpData + buffer.Length - 8); if (checksum1 != checksumInData1 || checksum2 != checksumInData2) { throw new Exception("Checksum on header file is invalid"); } if (lpData[buffer.Length - 32] != (byte)BlockType.FileAllocationTable) { throw new Exception("IoReadState.BlockTypeMismatch"); } if (*(int *)(lpData + buffer.Length - 28) != 0) { throw new Exception("IoReadState.IndexNumberMissmatch"); } if (*(int *)(lpData + buffer.Length - 24) != 0) { throw new Exception("IoReadState.FileIdNumberDidNotMatch"); } } }
public unsafe void Benchmark() { byte[] data = new byte[4096]; Random r = new Random(1); r.NextBytes(data); //Prime the run Murmur3Orig mm3 = new Murmur3Orig(); for (int x = 0; x < 1000; x++) { mm3.ComputeHash(data); fixed(byte *lp = data) { for (int x = 0; x < 1000; x++) { Murmur3.ComputeHash(lp, data.Length, out ulong value1, out ulong value2); } for (int x = 0; x < 1000; x++) { Footer.ComputeChecksum((IntPtr)lp, out long value3, out int value4, data.Length); } } Stopwatch sw1 = new Stopwatch(); Stopwatch sw2 = new Stopwatch(); Stopwatch sw3 = new Stopwatch(); sw1.Start(); for (int x = 0; x < 10000; x++) mm3.ComputeHash(data); } sw1.Stop(); fixed(byte *lp = data) { sw2.Start(); for (int x = 0; x < 10000; x++) { Murmur3.ComputeHash(lp, data.Length, out ulong value1, out ulong value2); } sw2.Stop(); sw3.Start(); for (int x = 0; x < 10000; x++) { Footer.ComputeChecksum((IntPtr)lp, out long value3, out int value4, data.Length); } sw3.Stop(); } System.Console.WriteLine("orig: " + (4096 * 10000 / sw1.Elapsed.TotalSeconds / 1024 / 1024).ToString("0 MB/S")); System.Console.WriteLine("mine: " + (4096 * 10000 / sw2.Elapsed.TotalSeconds / 1024 / 1024).ToString("0 MB/S")); System.Console.WriteLine("old: " + (4096 * 10000 / sw3.Elapsed.TotalSeconds / 1024 / 1024).ToString("0 MB/S")); }
private unsafe void WriteFooterData(byte[] buffer) { fixed(byte *lpData = buffer) { long checksum1; int checksum2; lpData[buffer.Length - 32] = (byte)BlockType.FileAllocationTable; *(int *)(lpData + buffer.Length - 28) = 0; *(int *)(lpData + buffer.Length - 24) = 0; *(int *)(lpData + buffer.Length - 20) = 0; Footer.ComputeChecksum((IntPtr)lpData, out checksum1, out checksum2, buffer.Length - 16); *(long *)(lpData + buffer.Length - 16) = checksum1; *(int *)(lpData + buffer.Length - 8) = checksum2; *(int *)(lpData + buffer.Length - 4) = 0; } }
private unsafe string TestFile(string fileName) { ShortTime lastReport = ShortTime.Now; int errorBlocks = 0; uint firstBlockWithError = uint.MaxValue; try { using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { int blockSize = FileHeaderBlock.SearchForBlockSize(stream); stream.Position = 0; byte[] data = new byte[blockSize]; stream.ReadAll(data, 0, blockSize); var header = FileHeaderBlock.Open(data); fixed(byte *lp = data) { stream.Position = header.HeaderBlockCount * blockSize; uint startingBlock = header.HeaderBlockCount; if (m_shouldQuickScan) { uint blocksToScan = (uint)Math.Ceiling(m_mbToScan * 1024 * 1024 / blockSize); if (blocksToScan < header.LastAllocatedBlock) { startingBlock = Math.Max(header.HeaderBlockCount, header.LastAllocatedBlock - blocksToScan); } } for (uint x = startingBlock; x <= header.LastAllocatedBlock; x++) { long checksum1; int checksum2; stream.ReadAll(data, 0, blockSize); Footer.ComputeChecksum((IntPtr)lp, out checksum1, out checksum2, blockSize - 16); long checksumInData1 = *(long *)(lp + blockSize - 16); int checksumInData2 = *(int *)(lp + blockSize - 8); if (!(checksum1 == checksumInData1 && checksum2 == checksumInData2)) { firstBlockWithError = Math.Min(firstBlockWithError, x); errorBlocks++; } if (m_quit) { if (errorBlocks == 0) { return("Quit Early - No Errors Found"); } return($"Quit Early - Blocks With Errors {errorBlocks} Starting At {firstBlockWithError}"); } if (lastReport.ElapsedSeconds() > .25) { lastReport = ShortTime.Now; lblProgress.Text = $"Completed {m_filesScanned} of {m_filesToScan} files. Current File: {(stream.Position / (double)stream.Length).ToString("0.0%")}"; Application.DoEvents(); } } } } if (errorBlocks == 0) { return("No Errors Found"); } return($"Blocks With Errors {errorBlocks} Starting At {firstBlockWithError}"); } catch (Exception e) { MessageBox.Show(e.ToString()); return("Error"); } }