public static ushort ToUInt16FromBoth(byte[] data, int offset) { return(EndianUtilities.ToUInt16LittleEndian(data, offset)); }
public void WriteTo(byte[] buffer, int offset) { EndianUtilities.WriteBytesLittleEndian(_value, buffer, offset); }
public int ReadFrom(byte[] buffer, int offset) { Hash = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0); Id = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 4); return(8); }
private static void CreateSparseExtent(Stream extentStream, long size, long descriptorLength, out long descriptorStart) { // Figure out grain size and number of grain tables, and adjust actual extent size to be a multiple // of grain size const int GtesPerGt = 512; long grainSize = 128; int numGrainTables = (int)MathUtilities.Ceil(size, grainSize * GtesPerGt * Sizes.Sector); descriptorLength = MathUtilities.RoundUp(descriptorLength, Sizes.Sector); descriptorStart = 0; if (descriptorLength != 0) { descriptorStart = 1; } long redundantGrainDirStart = Math.Max(descriptorStart, 1) + MathUtilities.Ceil(descriptorLength, Sizes.Sector); long redundantGrainDirLength = numGrainTables * 4; long redundantGrainTablesStart = redundantGrainDirStart + MathUtilities.Ceil(redundantGrainDirLength, Sizes.Sector); long redundantGrainTablesLength = numGrainTables * MathUtilities.RoundUp(GtesPerGt * 4, Sizes.Sector); long grainDirStart = redundantGrainTablesStart + MathUtilities.Ceil(redundantGrainTablesLength, Sizes.Sector); long grainDirLength = numGrainTables * 4; long grainTablesStart = grainDirStart + MathUtilities.Ceil(grainDirLength, Sizes.Sector); long grainTablesLength = numGrainTables * MathUtilities.RoundUp(GtesPerGt * 4, Sizes.Sector); long dataStart = MathUtilities.RoundUp(grainTablesStart + MathUtilities.Ceil(grainTablesLength, Sizes.Sector), grainSize); // Generate the header, and write it HostedSparseExtentHeader header = new HostedSparseExtentHeader(); header.Flags = HostedSparseExtentFlags.ValidLineDetectionTest | HostedSparseExtentFlags.RedundantGrainTable; header.Capacity = MathUtilities.RoundUp(size, grainSize * Sizes.Sector) / Sizes.Sector; header.GrainSize = grainSize; header.DescriptorOffset = descriptorStart; header.DescriptorSize = descriptorLength / Sizes.Sector; header.NumGTEsPerGT = GtesPerGt; header.RgdOffset = redundantGrainDirStart; header.GdOffset = grainDirStart; header.Overhead = dataStart; extentStream.Position = 0; extentStream.Write(header.GetBytes(), 0, Sizes.Sector); // Zero-out the descriptor space if (descriptorLength > 0) { byte[] descriptor = new byte[descriptorLength]; extentStream.Position = descriptorStart * Sizes.Sector; extentStream.Write(descriptor, 0, descriptor.Length); } // Generate the redundant grain dir, and write it byte[] grainDir = new byte[numGrainTables * 4]; for (int i = 0; i < numGrainTables; ++i) { EndianUtilities.WriteBytesLittleEndian( (uint)(redundantGrainTablesStart + i * MathUtilities.Ceil(GtesPerGt * 4, Sizes.Sector)), grainDir, i * 4); } extentStream.Position = redundantGrainDirStart * Sizes.Sector; extentStream.Write(grainDir, 0, grainDir.Length); // Write out the blank grain tables byte[] grainTable = new byte[GtesPerGt * 4]; for (int i = 0; i < numGrainTables; ++i) { extentStream.Position = redundantGrainTablesStart * Sizes.Sector + i * MathUtilities.RoundUp(GtesPerGt * 4, Sizes.Sector); extentStream.Write(grainTable, 0, grainTable.Length); } // Generate the main grain dir, and write it for (int i = 0; i < numGrainTables; ++i) { EndianUtilities.WriteBytesLittleEndian( (uint)(grainTablesStart + i * MathUtilities.Ceil(GtesPerGt * 4, Sizes.Sector)), grainDir, i * 4); } extentStream.Position = grainDirStart * Sizes.Sector; extentStream.Write(grainDir, 0, grainDir.Length); // Write out the blank grain tables for (int i = 0; i < numGrainTables; ++i) { extentStream.Position = grainTablesStart * Sizes.Sector + i * MathUtilities.RoundUp(GtesPerGt * 4, Sizes.Sector); extentStream.Write(grainTable, 0, grainTable.Length); } // Make sure stream is correct length if (extentStream.Length != dataStart * Sizes.Sector) { extentStream.SetLength(dataStart * Sizes.Sector); } }
public BatEntry(byte[] buffer, int offset) { _value = EndianUtilities.ToUInt64LittleEndian(buffer, offset); }
public override int Read(long pos, byte[] buffer, int offset, int count) { if (pos > _inode.FileSize) { return(0); } uint blockSize = _context.SuperBlock.BlockSize; int totalRead = 0; int totalBytesRemaining = (int)Math.Min(count, _inode.FileSize - pos); while (totalBytesRemaining > 0) { uint logicalBlock = (uint)((pos + totalRead) / blockSize); int blockOffset = (int)(pos + totalRead - logicalBlock * (long)blockSize); uint physicalBlock = 0; if (logicalBlock < 12) { physicalBlock = _inode.DirectBlocks[logicalBlock]; } else { logicalBlock -= 12; if (logicalBlock < blockSize / 4) { if (_inode.IndirectBlock != 0) { _context.RawStream.Position = _inode.IndirectBlock * (long)blockSize + logicalBlock * 4; byte[] indirectData = StreamUtilities.ReadExact(_context.RawStream, 4); physicalBlock = EndianUtilities.ToUInt32LittleEndian(indirectData, 0); } } else { logicalBlock -= blockSize / 4; if (logicalBlock < blockSize / 4 * (blockSize / 4)) { if (_inode.DoubleIndirectBlock != 0) { _context.RawStream.Position = _inode.DoubleIndirectBlock * (long)blockSize + logicalBlock / (blockSize / 4) * 4; byte[] indirectData = StreamUtilities.ReadExact(_context.RawStream, 4); uint indirectBlock = EndianUtilities.ToUInt32LittleEndian(indirectData, 0); if (indirectBlock != 0) { _context.RawStream.Position = indirectBlock * (long)blockSize + logicalBlock % (blockSize / 4) * 4; StreamUtilities.ReadExact(_context.RawStream, indirectData, 0, 4); physicalBlock = EndianUtilities.ToUInt32LittleEndian(indirectData, 0); } } } else { throw new NotSupportedException("Triple indirection"); } } } int toRead = (int)Math.Min(totalBytesRemaining, blockSize - blockOffset); int numRead; if (physicalBlock == 0) { Array.Clear(buffer, offset + totalRead, toRead); numRead = toRead; } else { _context.RawStream.Position = physicalBlock * (long)blockSize + blockOffset; numRead = _context.RawStream.Read(buffer, offset + totalRead, toRead); } totalBytesRemaining -= numRead; totalRead += numRead; } return(totalRead); }
public int ReadFrom(byte[] buffer, int offset) { Magic = EndianUtilities.ToUInt32BigEndian(buffer, offset); Blocksize = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x4); DataBlocks = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x8); RealtimeBlocks = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x10); RealtimeExtents = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x18); UniqueId = EndianUtilities.ToGuidBigEndian(buffer, offset + 0x20); Logstart = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x30); RootInode = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x38); RealtimeBitmapInode = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x40); RealtimeSummaryInode = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x48); RealtimeExtentSize = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x50); AgBlocks = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x54); AgCount = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x58); RealtimeBitmapBlocks = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x5C); LogBlocks = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x60); Version = (VersionFlags)EndianUtilities.ToUInt16BigEndian(buffer, offset + 0x64); SectorSize = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0x66); InodeSize = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0x68); InodesPerBlock = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0x6A); FilesystemName = EndianUtilities.BytesToZString(buffer, offset + 0x6C, 12); BlocksizeLog2 = buffer[offset + 0x78]; SectorSizeLog2 = buffer[offset + 0x79]; InodeSizeLog2 = buffer[offset + 0x7A]; InodesPerBlockLog2 = buffer[offset + 0x7B]; AgBlocksLog2 = buffer[offset + 0x7C]; RealtimeExtentsLog2 = buffer[offset + 0x7D]; InProgress = buffer[offset + 0x7E]; InodesMaxPercent = buffer[offset + 0x7F]; AllocatedInodes = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x80); FreeInodes = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x88); FreeDataBlocks = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x90); FreeRealtimeExtents = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0x98); UserQuotaInode = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0xA0); GroupQuotaInode = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0xA8); QuotaFlags = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0xB0); Flags = buffer[offset + 0xB2]; SharedVersionNumber = buffer[offset + 0xB3]; InodeChunkAlignment = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xB4); Unit = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xB8); Width = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xBC); DirBlockLog2 = buffer[offset + 0xC0]; LogSectorSizeLog2 = buffer[offset + 0xC1]; LogSectorSize = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0xC2); LogUnitSize = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xC4); Features2 = (Version2Features)EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xC8); BadFeatures2 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xCC); if (SbVersion >= (ushort)VersionFlags.Version5) { CompatibleFeatures = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xD0); ReadOnlyCompatibleFeatures = (ReadOnlyCompatibleFeatures)EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xD4); IncompatibleFeatures = (IncompatibleFeatures)EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xD8); LogIncompatibleFeatures = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xDC); Crc = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xE0); SparseInodeAlignment = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xE4); ProjectQuotaInode = EndianUtilities.ToUInt64BigEndian(buffer, offset + 0xE8); Lsn = EndianUtilities.ToInt64BigEndian(buffer, offset + 0xF0); MetaUuid = EndianUtilities.ToGuidBigEndian(buffer, offset + 0xF8); if ((IncompatibleFeatures & IncompatibleFeatures.Supported) != IncompatibleFeatures.Supported) { throw new NotSupportedException("XFS Features not supported"); } } var agOffset = AgBlocksLog2 + InodesPerBlockLog2; RelativeInodeMask = 0xffffffff >> (32 - agOffset); AgInodeMask = ~RelativeInodeMask; DirBlockSize = Blocksize << DirBlockLog2; return(Size); }
public int ReadFrom(byte[] buffer, int offset) { Magic = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x40); if (Magic != BtrfsMagic) { return(Size); } Checksum = EndianUtilities.ToByteArray(buffer, offset, 0x20); FsUuid = EndianUtilities.ToGuidLittleEndian(buffer, offset + 0x20); PhysicalAddress = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x30); Flags = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x38); Generation = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x48); Root = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x50); ChunkRoot = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x58); LogRoot = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x60); LogRootTransId = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x68); TotalBytes = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x70); BytesUsed = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x78); RootDirObjectid = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x80); NumDevices = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0x88); SectorSize = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x90); NodeSize = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x94); LeafSize = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x98); StripeSize = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x9c); ChunkRootGeneration = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0xa4); CompatFlags = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0xac); CompatRoFlags = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0xb4); IncompatFlags = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 0xbc); ChecksumType = (ChecksumType)EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0xc4); RootLevel = buffer[offset + 0xc6]; ChunkRootLevel = buffer[offset + 0xc7]; LogRootLevel = buffer[offset + 0xc8]; //c9 62 DEV_ITEM data for this device var labelData = EndianUtilities.ToByteArray(buffer, offset + 0x12b, 0x100); int eos = Array.IndexOf(labelData, (byte)0); if (eos != -1) { Label = Encoding.UTF8.GetString(labelData, 0, eos); } //22b 100 reserved var n = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0xa0); offset += 0x32b; var systemChunks = new List <ChunkItem>(); while (n > 0) { var key = new Key(); offset += key.ReadFrom(buffer, offset); var chunkItem = new ChunkItem(key); offset += chunkItem.ReadFrom(buffer, offset); systemChunks.Add(chunkItem); n = n - (uint)key.Size - (uint)chunkItem.Size; } SystemChunkArray = systemChunks.ToArray(); //32b 800 (n bytes valid) Contains (KEY, CHUNK_ITEM) pairs for all SYSTEM chunks. This is needed to bootstrap the mapping from logical addresses to physical. //b2b 4d5 Currently unused return(Size); }
private static uint ReadDigest(Stream stream) { byte[] data = StreamUtilities.ReadFully(stream, 4); return(EndianUtilities.ToUInt32BigEndian(data, 0)); }
public static bool IsFileOrDirectory(byte[] dirEntryData) { CatalogRecordType type = (CatalogRecordType)EndianUtilities.ToInt16BigEndian(dirEntryData, 0); return(type == CatalogRecordType.FolderRecord || type == CatalogRecordType.FileRecord); }
public void WriteTo(byte[] buffer, int offset) { EndianUtilities.WriteBytesLittleEndian(BlockSize, buffer, offset + 0); EndianUtilities.WriteBytesLittleEndian((uint)Flags, buffer, offset + 4); }
/// <inheritdoc /> public override string ToString() { return($"{Inode}: {EndianUtilities.BytesToString(Name, 0, NameLength)}"); }
internal static void ToBytesFromUInt16(byte[] buffer, int offset, ushort value) { EndianUtilities.WriteBytesLittleEndian(value, buffer, offset); }
internal static void ToBothFromUInt32(byte[] buffer, int offset, uint value) { EndianUtilities.WriteBytesLittleEndian(value, buffer, offset); EndianUtilities.WriteBytesBigEndian(value, buffer, offset + 4); }
/// <inheritdoc/> public void WriteTo(byte[] buffer, int offset) { EndianUtilities.WriteBytesBigEndian(this.StartBlock, buffer, offset + 0); EndianUtilities.WriteBytesBigEndian(this.BlockCount, buffer, offset + 4); }
public void Read(byte[] buffer, int offset) { LogicalBlockAddress = EndianUtilities.ToInt64LittleEndian(buffer, offset + 0); DataSize = EndianUtilities.ToInt32LittleEndian(buffer, offset + 8); }
/// <summary> /// Sends an SCSI command (aka task) to a LUN via the connected target. /// </summary> /// <param name="cmd">The command to send.</param> /// <param name="outBuffer">The data to send with the command.</param> /// <param name="outBufferOffset">The offset of the first byte to send.</param> /// <param name="outBufferCount">The number of bytes to send, if any.</param> /// <param name="inBuffer">The buffer to fill with returned data.</param> /// <param name="inBufferOffset">The first byte to fill with returned data.</param> /// <param name="inBufferMax">The maximum amount of data to receive.</param> /// <returns>The number of bytes received.</returns> public int Send(ScsiCommand cmd, byte[] outBuffer, int outBufferOffset, int outBufferCount, byte[] inBuffer, int inBufferOffset, int inBufferMax) { CommandRequest req = new CommandRequest(this, cmd.TargetLun); int toSend = Math.Min(Math.Min(outBufferCount, Session.ImmediateData ? Session.FirstBurstLength : 0), MaxTargetReceiveDataSegmentLength); byte[] packet = req.GetBytes(cmd, outBuffer, outBufferOffset, toSend, true, inBufferMax != 0, outBufferCount != 0, (uint)(outBufferCount != 0 ? outBufferCount : inBufferMax)); _stream.Write(packet, 0, packet.Length); _stream.Flush(); int numApproved = 0; int numSent = toSend; int pktsSent = 0; while (numSent < outBufferCount) { ProtocolDataUnit pdu = ReadPdu(); ReadyToTransferPacket resp = ParseResponse <ReadyToTransferPacket>(pdu); numApproved = (int)resp.DesiredTransferLength; uint targetTransferTag = resp.TargetTransferTag; while (numApproved > 0) { toSend = Math.Min(Math.Min(outBufferCount - numSent, numApproved), MaxTargetReceiveDataSegmentLength); DataOutPacket pkt = new DataOutPacket(this, cmd.TargetLun); packet = pkt.GetBytes(outBuffer, outBufferOffset + numSent, toSend, toSend == numApproved, pktsSent++, (uint)numSent, targetTransferTag); _stream.Write(packet, 0, packet.Length); _stream.Flush(); numApproved -= toSend; numSent += toSend; } } bool isFinal = false; int numRead = 0; while (!isFinal) { ProtocolDataUnit pdu = ReadPdu(); if (pdu.OpCode == OpCode.ScsiResponse) { Response resp = ParseResponse <Response>(pdu); if (resp.StatusPresent && resp.Status == ScsiStatus.CheckCondition) { ushort senseLength = EndianUtilities.ToUInt16BigEndian(pdu.ContentData, 0); byte[] senseData = new byte[senseLength]; Array.Copy(pdu.ContentData, 2, senseData, 0, senseLength); throw new ScsiCommandException(resp.Status, "Target indicated SCSI failure", senseData); } if (resp.StatusPresent && resp.Status != ScsiStatus.Good) { throw new ScsiCommandException(resp.Status, "Target indicated SCSI failure"); } isFinal = resp.Header.FinalPdu; } else if (pdu.OpCode == OpCode.ScsiDataIn) { DataInPacket resp = ParseResponse <DataInPacket>(pdu); if (resp.StatusPresent && resp.Status != ScsiStatus.Good) { throw new ScsiCommandException(resp.Status, "Target indicated SCSI failure"); } if (resp.ReadData != null) { Array.Copy(resp.ReadData, 0, inBuffer, (int)(inBufferOffset + resp.BufferOffset), resp.ReadData.Length); numRead += resp.ReadData.Length; } isFinal = resp.Header.FinalPdu; } } Session.NextTaskTag(); Session.NextCommandSequenceNumber(); return(numRead); }
internal BlkxResource(Dictionary <string, object> parts) : base("blkx", parts) { Block = EndianUtilities.ToStruct <CompressedBlock>(parts["Data"] as byte[], 0); }
private static string ReadNullTerminatedString(byte[] buffer, int offset, int length) { return(EndianUtilities.BytesToString(buffer, offset, length).TrimEnd('\0')); }
private void Initialize() { Context = new UdfContext { PhysicalPartitions = new Dictionary <ushort, PhysicalPartition>(), PhysicalSectorSize = (int)_sectorSize, LogicalPartitions = new List <LogicalPartition>() }; IBuffer dataBuffer = new StreamBuffer(_data, Ownership.None); AnchorVolumeDescriptorPointer avdp = AnchorVolumeDescriptorPointer.FromStream(_data, 256, _sectorSize); uint sector = avdp.MainDescriptorSequence.Location; bool terminatorFound = false; while (!terminatorFound) { _data.Position = sector * (long)_sectorSize; DescriptorTag dt; if (!DescriptorTag.TryFromStream(_data, out dt)) { break; } switch (dt.TagIdentifier) { case TagIdentifier.PrimaryVolumeDescriptor: _pvd = PrimaryVolumeDescriptor.FromStream(_data, sector, _sectorSize); break; case TagIdentifier.ImplementationUseVolumeDescriptor: // Not used break; case TagIdentifier.PartitionDescriptor: PartitionDescriptor pd = PartitionDescriptor.FromStream(_data, sector, _sectorSize); if (Context.PhysicalPartitions.ContainsKey(pd.PartitionNumber)) { throw new IOException("Duplicate partition number reading UDF Partition Descriptor"); } Context.PhysicalPartitions[pd.PartitionNumber] = new PhysicalPartition(pd, dataBuffer, _sectorSize); break; case TagIdentifier.LogicalVolumeDescriptor: _lvd = LogicalVolumeDescriptor.FromStream(_data, sector, _sectorSize); break; case TagIdentifier.UnallocatedSpaceDescriptor: // Not used for reading break; case TagIdentifier.TerminatingDescriptor: terminatorFound = true; break; default: break; } sector++; } // Convert logical partition descriptors into actual partition objects for (int i = 0; i < _lvd.PartitionMaps.Length; ++i) { Context.LogicalPartitions.Add(LogicalPartition.FromDescriptor(Context, _lvd, i)); } byte[] fsdBuffer = UdfUtilities.ReadExtent(Context, _lvd.FileSetDescriptorLocation); if (DescriptorTag.IsValid(fsdBuffer, 0)) { FileSetDescriptor fsd = EndianUtilities.ToStruct <FileSetDescriptor>(fsdBuffer, 0); RootDirectory = (Directory)File.FromDescriptor(Context, fsd.RootDirectoryIcb); } }
private void CheckBat() { int batSize = MathUtilities.RoundUp(_dynamicHeader.MaxTableEntries * 4, Sizes.Sector); if (_dynamicHeader.TableOffset > _fileStream.Length - batSize) { ReportError("BAT: BAT extends beyond end of file"); return; } _fileStream.Position = _dynamicHeader.TableOffset; byte[] batData = StreamUtilities.ReadExact(_fileStream, batSize); uint[] bat = new uint[batSize / 4]; for (int i = 0; i < bat.Length; ++i) { bat[i] = EndianUtilities.ToUInt32BigEndian(batData, i * 4); } for (int i = _dynamicHeader.MaxTableEntries; i < bat.Length; ++i) { if (bat[i] != uint.MaxValue) { ReportError("BAT: Padding record '" + i + "' should be 0xFFFFFFFF"); } } uint dataStartSector = uint.MaxValue; for (int i = 0; i < _dynamicHeader.MaxTableEntries; ++i) { if (bat[i] < dataStartSector) { dataStartSector = bat[i]; } } if (dataStartSector == uint.MaxValue) { return; } long dataStart = (long)dataStartSector * Sizes.Sector; uint blockBitmapSize = (uint)MathUtilities.RoundUp(_dynamicHeader.BlockSize / Sizes.Sector / 8, Sizes.Sector); uint storedBlockSize = _dynamicHeader.BlockSize + blockBitmapSize; bool[] seenBlocks = new bool[_dynamicHeader.MaxTableEntries]; for (int i = 0; i < _dynamicHeader.MaxTableEntries; ++i) { if (bat[i] != uint.MaxValue) { long absPos = (long)bat[i] * Sizes.Sector; if (absPos + storedBlockSize > _fileStream.Length) { ReportError("BAT: block stored beyond end of stream"); } if ((absPos - dataStart) % storedBlockSize != 0) { ReportError( "BAT: block stored at invalid start sector (not a multiple of size of a stored block)"); } uint streamBlockIdx = (uint)((absPos - dataStart) / storedBlockSize); if (seenBlocks[streamBlockIdx]) { ReportError("BAT: multiple blocks occupying same file space"); } seenBlocks[streamBlockIdx] = true; } } }
public int ReadFrom(byte[] buffer, int offset) { LogicalBlock = EndianUtilities.ToUInt32LittleEndian(buffer, offset); Partition = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 4); return(6); }
public BootVolumeDescriptor(byte[] src, int offset) : base(src, offset) { SystemId = EndianUtilities.BytesToString(src, offset + 0x7, 0x20).TrimEnd('\0'); CatalogSector = EndianUtilities.ToUInt32LittleEndian(src, offset + 0x47); }
private void PreVerifyMft(File file) { int recordLength = _context.BiosParameterBlock.MftRecordSize; int bytesPerSector = _context.BiosParameterBlock.BytesPerSector; // Check out the MFT's clusters foreach (Range <long, long> range in file.GetAttribute(AttributeType.Data, null).GetClusters()) { if (!VerifyClusterRange(range)) { ReportError("Corrupt cluster range in MFT data attribute {0}", range.ToString()); Abort(); } } foreach (Range <long, long> range in file.GetAttribute(AttributeType.Bitmap, null).GetClusters()) { if (!VerifyClusterRange(range)) { ReportError("Corrupt cluster range in MFT bitmap attribute {0}", range.ToString()); Abort(); } } using (Stream mftStream = file.OpenStream(AttributeType.Data, null, FileAccess.Read)) using (Stream bitmapStream = file.OpenStream(AttributeType.Bitmap, null, FileAccess.Read)) { Bitmap bitmap = new Bitmap(bitmapStream, long.MaxValue); long index = 0; while (mftStream.Position < mftStream.Length) { byte[] recordData = StreamUtilities.ReadExact(mftStream, recordLength); string magic = EndianUtilities.BytesToString(recordData, 0, 4); if (magic != "FILE") { if (bitmap.IsPresent(index)) { ReportError("Invalid MFT record magic at index {0} - was ({2},{3},{4},{5}) \"{1}\"", index, magic.Trim('\0'), (int)magic[0], (int)magic[1], (int)magic[2], (int)magic[3]); } } else { if (!VerifyMftRecord(recordData, bitmap.IsPresent(index), bytesPerSector)) { ReportError("Invalid MFT record at index {0}", index); StringBuilder bldr = new StringBuilder(); for (int i = 0; i < recordData.Length; ++i) { bldr.Append(string.Format(CultureInfo.InvariantCulture, " {0:X2}", recordData[i])); } ReportInfo("MFT record binary data for index {0}:{1}", index, bldr.ToString()); } } index++; } } }
public int ReadFrom(byte[] buffer, int offset) { _value = EndianUtilities.ToUInt64LittleEndian(buffer, offset); return(8); }
private bool VerifyMftRecord(byte[] recordData, bool presentInBitmap, int bytesPerSector) { bool ok = true; // // Verify the attributes seem OK... // byte[] tempBuffer = new byte[recordData.Length]; Array.Copy(recordData, tempBuffer, tempBuffer.Length); GenericFixupRecord genericRecord = new GenericFixupRecord(bytesPerSector); genericRecord.FromBytes(tempBuffer, 0); int pos = EndianUtilities.ToUInt16LittleEndian(genericRecord.Content, 0x14); while (EndianUtilities.ToUInt32LittleEndian(genericRecord.Content, pos) != 0xFFFFFFFF) { int attrLen; try { AttributeRecord ar = AttributeRecord.FromBytes(genericRecord.Content, pos, out attrLen); if (attrLen != ar.Size) { ReportError("Attribute size is different to calculated size. AttrId={0}", ar.AttributeId); ok = false; } if (ar.IsNonResident) { NonResidentAttributeRecord nrr = (NonResidentAttributeRecord)ar; if (nrr.DataRuns.Count > 0) { long totalVcn = 0; foreach (DataRun run in nrr.DataRuns) { totalVcn += run.RunLength; } if (totalVcn != nrr.LastVcn - nrr.StartVcn + 1) { ReportError("Declared VCNs doesn't match data runs. AttrId={0}", ar.AttributeId); ok = false; } } } } catch { ReportError("Failure parsing attribute at pos={0}", pos); return(false); } pos += attrLen; } // // Now consider record as a whole // FileRecord record = new FileRecord(bytesPerSector); record.FromBytes(recordData, 0); bool inUse = (record.Flags & FileRecordFlags.InUse) != 0; if (inUse != presentInBitmap) { ReportError("MFT bitmap and record in-use flag don't agree. Mft={0}, Record={1}", presentInBitmap ? "InUse" : "Free", inUse ? "InUse" : "Free"); ok = false; } if (record.Size != record.RealSize) { ReportError("MFT record real size is different to calculated size. Stored in MFT={0}, Calculated={1}", record.RealSize, record.Size); ok = false; } if (EndianUtilities.ToUInt32LittleEndian(recordData, (int)record.RealSize - 8) != uint.MaxValue) { ReportError("MFT record is not correctly terminated with 0xFFFFFFFF"); ok = false; } return(ok); }
public DeviceElementValue(byte[] value) { _parentObject = EndianUtilities.ToGuidLittleEndian(value, 0x00); _record = DeviceRecord.Parse(value, 0x10); }
public int ReadFrom(byte[] buffer, int offset) { OwnerId = EndianUtilities.ToInt32LittleEndian(buffer, offset); return(4); }
public void WriteTo(byte[] buffer, int offset) { EndianUtilities.WriteBytesLittleEndian(Hash, buffer, offset + 0); EndianUtilities.WriteBytesLittleEndian(Id, buffer, offset + 4); }
public int ReadFrom(byte[] buffer, int offset) { InodesCount = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0); BlocksCount = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 4); ReservedBlocksCount = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 8); FreeBlocksCount = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 12); FreeInodesCount = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 16); FirstDataBlock = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 20); LogBlockSize = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 24); LogFragSize = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 28); BlocksPerGroup = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 32); FragsPerGroup = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 36); InodesPerGroup = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 40); MountTime = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 44); WriteTime = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 48); MountCount = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 52); MaxMountCount = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 54); Magic = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 56); State = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 58); Errors = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 60); MinorRevisionLevel = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 62); LastCheckTime = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 64); CheckInterval = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 68); CreatorOS = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 72); RevisionLevel = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 76); DefaultReservedBlockUid = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 80); DefaultReservedBlockGid = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 82); FirstInode = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 84); InodeSize = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 88); BlockGroupNumber = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 90); CompatibleFeatures = (CompatibleFeatures)EndianUtilities.ToUInt32LittleEndian(buffer, offset + 92); IncompatibleFeatures = (IncompatibleFeatures)EndianUtilities.ToUInt32LittleEndian(buffer, offset + 96); ReadOnlyCompatibleFeatures = (ReadOnlyCompatibleFeatures)EndianUtilities.ToUInt32LittleEndian(buffer, offset + 100); UniqueId = EndianUtilities.ToGuidLittleEndian(buffer, offset + 104); VolumeName = EndianUtilities.BytesToZString(buffer, offset + 120, 16); LastMountPoint = EndianUtilities.BytesToZString(buffer, offset + 136, 64); CompressionAlgorithmUsageBitmap = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 200); PreallocateBlockCount = buffer[offset + 204]; DirPreallocateBlockCount = buffer[offset + 205]; ReservedGDTBlocks = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 206); JournalSuperBlockUniqueId = EndianUtilities.ToGuidLittleEndian(buffer, offset + 208); JournalInode = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 224); JournalDevice = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 228); LastOrphan = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 232); HashSeed = new uint[4]; HashSeed[0] = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 236); HashSeed[1] = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 240); HashSeed[2] = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 244); HashSeed[3] = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 248); DefaultHashVersion = buffer[offset + 252]; DescriptorSize = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 254); DefaultMountOptions = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 256); FirstMetablockBlockGroup = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 260); MkfsTime = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 264); JournalBackup = new uint[17]; for (int i = 0; i < 17; ++i) { JournalBackup[i] = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 268 + 4 * i); } BlocksCountHigh = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 336); ReservedBlocksCountHigh = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 340); FreeBlocksCountHigh = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 344); MinimumExtraInodeSize = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 348); WantExtraInodeSize = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 350); Flags = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 352); RaidStride = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 356); MultiMountProtectionInterval = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 358); MultiMountProtectionBlock = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 360); RaidStripeWidth = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 368); LogGroupsPerFlex = buffer[offset + 372]; OverheadBlocksCount = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 584); return(1024); }