Пример #1
0
        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));
        }
Пример #2
0
        /// <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));
        }
Пример #3
0
        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);
        }
Пример #4
0
        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");
                }
            }
        }
Пример #5
0
        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));
 }