Exemple #1
0
 public static ushort ToUInt16FromBoth(byte[] data, int offset)
 {
     return(EndianUtilities.ToUInt16LittleEndian(data, offset));
 }
Exemple #2
0
 public void WriteTo(byte[] buffer, int offset)
 {
     EndianUtilities.WriteBytesLittleEndian(_value, buffer, offset);
 }
Exemple #3
0
 public int ReadFrom(byte[] buffer, int offset)
 {
     Hash = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0);
     Id   = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 4);
     return(8);
 }
Exemple #4
0
        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);
            }
        }
Exemple #5
0
 public BatEntry(byte[] buffer, int offset)
 {
     _value = EndianUtilities.ToUInt64LittleEndian(buffer, offset);
 }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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));
 }
Exemple #10
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);
 }
Exemple #12
0
 /// <inheritdoc />
 public override string ToString()
 {
     return($"{Inode}: {EndianUtilities.BytesToString(Name, 0, NameLength)}");
 }
Exemple #13
0
 internal static void ToBytesFromUInt16(byte[] buffer, int offset, ushort value)
 {
     EndianUtilities.WriteBytesLittleEndian(value, buffer, offset);
 }
Exemple #14
0
 internal static void ToBothFromUInt32(byte[] buffer, int offset, uint value)
 {
     EndianUtilities.WriteBytesLittleEndian(value, buffer, offset);
     EndianUtilities.WriteBytesBigEndian(value, buffer, offset + 4);
 }
Exemple #15
0
 /// <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);
 }
Exemple #17
0
        /// <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);
        }
Exemple #18
0
 internal BlkxResource(Dictionary <string, object> parts)
     : base("blkx", parts)
 {
     Block = EndianUtilities.ToStruct <CompressedBlock>(parts["Data"] as byte[], 0);
 }
Exemple #19
0
 private static string ReadNullTerminatedString(byte[] buffer, int offset, int length)
 {
     return(EndianUtilities.BytesToString(buffer, offset, length).TrimEnd('\0'));
 }
Exemple #20
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;
                }
            }
        }
Exemple #22
0
 public int ReadFrom(byte[] buffer, int offset)
 {
     LogicalBlock = EndianUtilities.ToUInt32LittleEndian(buffer, offset);
     Partition    = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 4);
     return(6);
 }
Exemple #23
0
 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++;
                    }
                }
        }
Exemple #25
0
 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);
        }
Exemple #27
0
 public DeviceElementValue(byte[] value)
 {
     _parentObject = EndianUtilities.ToGuidLittleEndian(value, 0x00);
     _record       = DeviceRecord.Parse(value, 0x10);
 }
Exemple #28
0
 public int ReadFrom(byte[] buffer, int offset)
 {
     OwnerId = EndianUtilities.ToInt32LittleEndian(buffer, offset);
     return(4);
 }
Exemple #29
0
 public void WriteTo(byte[] buffer, int offset)
 {
     EndianUtilities.WriteBytesLittleEndian(Hash, buffer, offset + 0);
     EndianUtilities.WriteBytesLittleEndian(Id, buffer, offset + 4);
 }
Exemple #30
0
        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);
        }