private void WriteFileData(BuilderContext context) { Stream outStream = context.RawStream; bool disposeSource = false; try { if (_source == null) { var locator = new LocalFileLocator(string.Empty); _source = locator.Open(_sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read); disposeSource = true; } if (_source.Position != 0) { _source.Position = 0; } long startPos = outStream.Position; int bufferedBytes = StreamUtilities.ReadMaximum(_source, context.IoBuffer, 0, context.DataBlockSize); if (bufferedBytes < context.DataBlockSize) { // Fragment - less than one complete block of data _inode.StartBlock = 0xFFFFFFFF; _inode.FragmentKey = context.WriteFragment(bufferedBytes, out _inode.FragmentOffset); _inode.FileSize = (uint)bufferedBytes; } else { // At least one full block, no fragments used _inode.FragmentKey = 0xFFFFFFFF; _lengths = new List <uint>(); _inode.StartBlock = (uint)startPos; _inode.FileSize = bufferedBytes; while (bufferedBytes > 0) { _lengths.Add(context.WriteDataBlock(context.IoBuffer, 0, bufferedBytes)); bufferedBytes = StreamUtilities.ReadMaximum(_source, context.IoBuffer, 0, context.DataBlockSize); _inode.FileSize += (uint)bufferedBytes; } } } finally { if (disposeSource) { _source.Dispose(); } } }
/// <summary> /// Detects if a stream contains a valid UDF file system. /// </summary> /// <param name="data">The stream to inspect.</param> /// <returns><c>true</c> if the stream contains a UDF file system, else false.</returns> public static bool Detect(Stream data) { if (data.Length < IsoUtilities.SectorSize) { return(false); } long vdpos = 0x8000; // Skip lead-in byte[] buffer = new byte[IsoUtilities.SectorSize]; bool validDescriptor = true; bool foundUdfMarker = false; BaseVolumeDescriptor bvd; while (validDescriptor) { data.Position = vdpos; int numRead = StreamUtilities.ReadMaximum(data, buffer, 0, IsoUtilities.SectorSize); if (numRead != IsoUtilities.SectorSize) { break; } bvd = new BaseVolumeDescriptor(buffer, 0); switch (bvd.StandardIdentifier) { case "NSR02": case "NSR03": foundUdfMarker = true; break; case "BEA01": case "BOOT2": case "CD001": case "CDW02": case "TEA01": break; default: validDescriptor = false; break; } vdpos += IsoUtilities.SectorSize; } return(foundUdfMarker); }
private Metablock ReadMetaBlock(long pos) { Metablock block = _metablockCache.GetBlock(pos); if (block.Available >= 0) { return(block); } Stream stream = _context.RawStream; stream.Position = pos; byte[] buffer = StreamUtilities.ReadExact(stream, 2); int readLen = EndianUtilities.ToUInt16LittleEndian(buffer, 0); bool isCompressed = (readLen & 0x8000) == 0; readLen &= 0x7FFF; if (readLen == 0) { readLen = 0x8000; } block.NextBlockStart = pos + readLen + 2; if (isCompressed) { if (_ioBuffer == null || readLen > _ioBuffer.Length) { _ioBuffer = new byte[readLen]; } StreamUtilities.ReadExact(stream, _ioBuffer, 0, readLen); using ( ZlibStream zlibStream = new ZlibStream(new MemoryStream(_ioBuffer, 0, readLen, false), CompressionMode.Decompress, true)) { block.Available = StreamUtilities.ReadMaximum(zlibStream, block.Data, 0, MetadataBufferSize); } } else { block.Available = StreamUtilities.ReadMaximum(stream, block.Data, 0, readLen); } return(block); }
public AttributeDefinitions(File file) { _attrDefs = new Dictionary <AttributeType, AttributeDefinitionRecord>(); byte[] buffer = new byte[AttributeDefinitionRecord.Size]; using (Stream s = file.OpenStream(AttributeType.Data, null, FileAccess.Read)) { while (StreamUtilities.ReadMaximum(s, buffer, 0, buffer.Length) == buffer.Length) { AttributeDefinitionRecord record = new AttributeDefinitionRecord(); record.Read(buffer, 0); // NULL terminator record if (record.Type != AttributeType.None) { _attrDefs.Add(record.Type, record); } } } }
/// <summary> /// Detects if a stream contains a valid ISO file system. /// </summary> /// <param name="data">The stream to inspect.</param> /// <returns><c>true</c> if the stream contains an ISO file system, else false.</returns> public static bool Detect(Stream data, int sectorSize) { byte[] buffer = new byte[sectorSize]; if (data.Length < 0x8000 + sectorSize) { return(false); } data.Position = 0x8000; int numRead = StreamUtilities.ReadMaximum(data, buffer, 0, sectorSize); if (numRead != sectorSize) { return(false); } BaseVolumeDescriptor bvd = new BaseVolumeDescriptor(buffer, 0); return(bvd.StandardIdentifier == BaseVolumeDescriptor.Iso9660StandardIdentifier); }
private Block ReadBlock(long pos, int diskLen) { Block block = _blockCache.GetBlock(pos); if (block.Available >= 0) { return(block); } Stream stream = _context.RawStream; stream.Position = pos; int readLen = diskLen & 0x00FFFFFF; bool isCompressed = (diskLen & 0x01000000) == 0; if (isCompressed) { if (_ioBuffer == null || readLen > _ioBuffer.Length) { _ioBuffer = new byte[readLen]; } StreamUtilities.ReadExact(stream, _ioBuffer, 0, readLen); using ( ZlibStream zlibStream = new ZlibStream(new MemoryStream(_ioBuffer, 0, readLen, false), CompressionMode.Decompress, true)) { block.Available = StreamUtilities.ReadMaximum(zlibStream, block.Data, 0, (int)_context.SuperBlock.BlockSize); } } else { StreamUtilities.ReadExact(stream, block.Data, 0, readLen); block.Available = readLen; } return(block); }
private static bool SearchLabel(Stream content, out PhysicalVolumeLabel pvLabel) { pvLabel = null; content.Position = 0; byte[] buffer = new byte[SECTOR_SIZE]; for (uint i = 0; i < 4; i++) { if (StreamUtilities.ReadMaximum(content, buffer, 0, SECTOR_SIZE) != SECTOR_SIZE) { return(false); } var label = EndianUtilities.BytesToString(buffer, 0x0, 0x8); if (label == PhysicalVolumeLabel.LABEL_ID) { pvLabel = new PhysicalVolumeLabel(); pvLabel.ReadFrom(buffer, 0x0); if (pvLabel.Sector != i) { //Invalid PV Sector; return(false); } if (pvLabel.Crc != pvLabel.CalculatedCrc) { //Invalid PV CRC return(false); } if (pvLabel.Label2 != PhysicalVolumeLabel.LVM2_LABEL) { //Invalid LVM2 Label return(false); } return(true); } } return(false); }
public static bool TryRead(Stream logStream, out LogEntry entry) { long position = logStream.Position; byte[] sectorBuffer = new byte[LogSectorSize]; if (StreamUtilities.ReadMaximum(logStream, sectorBuffer, 0, sectorBuffer.Length) != sectorBuffer.Length) { entry = null; return(false); } 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.ReadExact(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 override int Read(byte[] buffer, int offset, int count) { CheckDisposed(); if (_atEof || _position > _length) { _atEof = true; throw new IOException("Attempt to read beyond end of file"); } if (_position == _length) { _atEof = true; return(0); } if (_position % _metadata.LogicalSectorSize != 0 || count % _metadata.LogicalSectorSize != 0) { throw new IOException("Unaligned read"); } int totalToRead = (int)Math.Min(_length - _position, count); int totalRead = 0; while (totalRead < totalToRead) { int chunkIndex; int blockIndex; int sectorIndex; Chunk chunk = GetChunk(_position + totalRead, out chunkIndex, out blockIndex, out sectorIndex); int blockOffset = (int)(sectorIndex * _metadata.LogicalSectorSize); int blockBytesRemaining = (int)(_fileParameters.BlockSize - blockOffset); PayloadBlockStatus blockStatus = chunk.GetBlockStatus(blockIndex); if (blockStatus == PayloadBlockStatus.FullyPresent) { _fileStream.Position = chunk.GetBlockPosition(blockIndex) + blockOffset; int read = StreamUtilities.ReadMaximum(_fileStream, buffer, offset + totalRead, Math.Min(blockBytesRemaining, totalToRead - totalRead)); totalRead += read; } else if (blockStatus == PayloadBlockStatus.PartiallyPresent) { BlockBitmap bitmap = chunk.GetBlockBitmap(blockIndex); bool present; int numSectors = bitmap.ContiguousSectors(sectorIndex, out present); int toRead = (int)Math.Min(numSectors * _metadata.LogicalSectorSize, totalToRead - totalRead); int read; if (present) { _fileStream.Position = chunk.GetBlockPosition(blockIndex) + blockOffset; read = StreamUtilities.ReadMaximum(_fileStream, buffer, offset + totalRead, toRead); } else { _parentStream.Position = _position + totalRead; read = StreamUtilities.ReadMaximum(_parentStream, buffer, offset + totalRead, toRead); } totalRead += read; } else if (blockStatus == PayloadBlockStatus.NotPresent) { _parentStream.Position = _position + totalRead; int read = StreamUtilities.ReadMaximum(_parentStream, buffer, offset + totalRead, Math.Min(blockBytesRemaining, totalToRead - totalRead)); totalRead += read; } else { int zeroed = Math.Min(blockBytesRemaining, totalToRead - totalRead); Array.Clear(buffer, offset + totalRead, zeroed); totalRead += zeroed; } } _position += totalRead; return(totalRead); }