internal static uint CalcCrc(byte[] buffer, int offset, int count) { byte[] temp = new byte[count]; Array.Copy(buffer, offset, temp, 0, count); // Reset CRC field Utilities.WriteBytesLittleEndian((uint)0, temp, 16); return(Crc32LittleEndian.Compute(Crc32Algorithm.Common, temp, 0, count)); }
/// <summary> /// Makes a best guess at the geometry of a disk. /// </summary> /// <param name="disk">String containing the disk image to detect the geometry from.</param> /// <returns>The detected geometry.</returns> public static Geometry DetectGeometry(Stream disk) { if (disk.Length >= Sizes.Sector) { disk.Position = 0; byte[] bootSector = StreamUtilities.ReadExact(disk, Sizes.Sector); if (bootSector[510] == 0x55 && bootSector[511] == 0xAA) { long lastSector = 0; disk.Position = Sizes.Sector; var sector = StreamUtilities.ReadExact(disk, Sizes.Sector); var header = new GptHeader(Sizes.Sector); if (!header.ReadFrom(sector, 0)) { throw new InvalidDataException("Failed to read primary GPT header"); } disk.Position = header.PartitionEntriesLba * Sizes.Sector; var entryBuffer = StreamUtilities.ReadExact(disk, (int)(header.PartitionEntrySize * header.PartitionEntryCount)); if (header.EntriesCrc != Crc32LittleEndian.Compute(Crc32Algorithm.Common, entryBuffer, 0, entryBuffer.Length)) { throw new InvalidDataException("Invalid GPT header"); } for (int i = 0; i < header.PartitionEntryCount; ++i) { GptEntry entry = new GptEntry(); entry.ReadFrom(entryBuffer, i * header.PartitionEntrySize); if (entry.PartitionType != Guid.Empty) { lastSector = entry.LastUsedLogicalBlock + 1; } } if (lastSector > 0) { return(Geometry.FromCapacity(lastSector * Sizes.Sector, Sizes.Sector)); } } } return(Geometry.FromCapacity(disk.Length)); }
public void WriteTo(byte[] buffer, int offset) { EntryCount = (uint)Regions.Count; Checksum = 0; Utilities.WriteBytesLittleEndian(Signature, _data, 0); Utilities.WriteBytesLittleEndian(Checksum, _data, 4); Utilities.WriteBytesLittleEndian(EntryCount, _data, 8); int dataOffset = 16; foreach (KeyValuePair <Guid, RegionEntry> region in Regions) { region.Value.WriteTo(_data, dataOffset); dataOffset += 32; } Checksum = Crc32LittleEndian.Compute(Crc32Algorithm.Castagnoli, _data, 0, FixedSize); Utilities.WriteBytesLittleEndian(Checksum, _data, 4); Array.Copy(_data, 0, buffer, offset, FixedSize); }
internal void VerifyChecksum(byte[] checksum, byte[] data, int offset, int count) { if (!Options.VerifyChecksums) { return; } if (SuperBlock.ChecksumType != ChecksumType.Crc32C) { throw new NotImplementedException($"Unsupported ChecksumType {SuperBlock.ChecksumType}"); } var crc = new Crc32LittleEndian(Crc32Algorithm.Castagnoli); crc.Process(data, offset, count); var calculated = new byte[4]; EndianUtilities.WriteBytesLittleEndian(crc.Value, calculated, 0); for (int i = 0; i < calculated.Length; i++) { if (calculated[i] != checksum[i]) { throw new IOException("Invalid checksum"); } } }
public static bool TryRead(Stream logStream, out LogEntry entry) { long position = logStream.Position; byte[] sectorBuffer = new byte[LogSectorSize]; StreamUtilities.ReadFully(logStream, sectorBuffer, 0, sectorBuffer.Length); uint sig = EndianUtilities.ToUInt32LittleEndian(sectorBuffer, 0); if (sig != LogEntryHeader.LogEntrySignature) { entry = null; return(false); } LogEntryHeader header = new LogEntryHeader(); header.ReadFrom(sectorBuffer, 0); if (!header.IsValid || header.EntryLength > logStream.Length) { entry = null; return(false); } byte[] logEntryBuffer = new byte[header.EntryLength]; Array.Copy(sectorBuffer, logEntryBuffer, LogSectorSize); StreamUtilities.ReadFully(logStream, logEntryBuffer, LogSectorSize, logEntryBuffer.Length - LogSectorSize); EndianUtilities.WriteBytesLittleEndian(0, logEntryBuffer, 4); if (header.Checksum != Crc32LittleEndian.Compute(Crc32Algorithm.Castagnoli, logEntryBuffer, 0, (int)header.EntryLength)) { entry = null; return(false); } int dataPos = MathUtilities.RoundUp((int)header.DescriptorCount * 32 + 64, LogSectorSize); List <Descriptor> descriptors = new List <Descriptor>(); for (int i = 0; i < header.DescriptorCount; ++i) { int offset = i * 32 + 64; Descriptor descriptor; uint descriptorSig = EndianUtilities.ToUInt32LittleEndian(logEntryBuffer, offset); switch (descriptorSig) { case Descriptor.ZeroDescriptorSignature: descriptor = new ZeroDescriptor(); break; case Descriptor.DataDescriptorSignature: descriptor = new DataDescriptor(logEntryBuffer, dataPos); dataPos += LogSectorSize; break; default: entry = null; return(false); } descriptor.ReadFrom(logEntryBuffer, offset); if (!descriptor.IsValid(header.SequenceNumber)) { entry = null; return(false); } descriptors.Add(descriptor); } entry = new LogEntry(position, header, descriptors); return(true); }
public void CalcChecksum() { Checksum = 0; RefreshData(); Checksum = Crc32LittleEndian.Compute(Crc32Algorithm.Castagnoli, _data, 0, 4096); }
private uint CalcEntriesCrc() { return(Crc32LittleEndian.Compute(Crc32Algorithm.Common, _entryBuffer, 0, _entryBuffer.Length)); }
private static uint CalcEntriesCrc(byte[] buffer) { return(Crc32LittleEndian.Compute(Crc32Algorithm.Common, buffer, 0, buffer.Length)); }