示例#1
0
        /// <summary>
        /// Reads data from the file.
        /// </summary>
        /// <param name="volumeIndex">The volume index of the file.</param>
        /// <param name="item">The item containing information about the file to read.</param>
        /// <param name="buffer">The buffer to read the data</param>
        /// <returns>Returns true if the data was read successfully.</returns>
        private bool ReadFromFile(int volumeIndex, ref UdfRecord item, ref byte[] buffer)
        {
            if (item.Size >= MaxExtents)
            {
                return(false);
            }

            if (item.IsInline)
            {
                buffer = item.InlineData;
                return(true);
            }

            buffer = new byte[item.Size];
            int position = 0;

            for (int i = 0; i < item.Extents.Count; i++)
            {
                FileExtent e      = item.Extents[i];
                int        length = e.Length;
                byte[]     b      = UdfHelper.Readbytes(position, buffer, buffer.Length);
                if (!this.ReadData(volumeIndex, e.PartitionReference, e.Position, length, b))
                {
                    return(false);
                }

                position += length;
            }

            return(true);
        }
        /// <summary>
        /// Parses the tag information from the buffer.
        /// </summary>
        /// <param name="start">The start index of the tag information.</param>
        /// <param name="buffer">The buffer containing the data.</param>
        /// <param name="size">The number of bytes to read.</param>
        /// <returns>Returns true if the data was parsed sucessfully.</returns>
        public bool Parse(int start, byte[] buffer, int size)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (size < 16 || (start + size) > buffer.Length || buffer[start + 5] != 0)
            {
                return(false);
            }

            int sum = 0;

            for (int i = 0; i < 16; i++)
            {
                if (i != 4)
                {
                    sum = sum + buffer[start + i];
                }
            }

            int m = (sum % 256);

            if (m != buffer[start + 4])
            {
                return(false);
            }

            this.Identifier = UdfHelper.Get16(start, buffer);
            return(true);
        }
示例#3
0
 internal void Parse(byte[] buffer)
 {
     _size = UdfHelper.Get64(56, buffer);
     NumLogBlockRecorded = UdfHelper.Get64(64, buffer);
     ATime.Parse(72, buffer);
     MTime.Parse(84, buffer);
 }
示例#4
0
        /// <summary>
        /// Reads a logical volume descriptor from the buffer.
        /// </summary>
        /// <param name="buffer">The buffer to read the data from.</param>
        /// <returns>Returns true if the descriptor is valid.</returns>
        private bool ReadLogicalDescriptor(byte[] buffer)
        {
            LogicalVolume volume = new LogicalVolume();

            volume.Id.Parse(84, buffer);
            volume.BlockSize = UdfHelper.Get32(212, buffer);
            if (volume.BlockSize < VirtualSectorSize || volume.BlockSize > MaxExtents)
            {
                return(false);
            }

            volume.FileSetLocation.Parse(248, buffer);

            int numPartitionMaps = UdfHelper.Get32(268, buffer);

            if (numPartitionMaps > MaxPartitions)
            {
                return(false);
            }

            int position = 440;

            for (int index = 0; index < numPartitionMaps; index++)
            {
                if (position + 2 > SectorSize)
                {
                    return(false);
                }

                PartitionMap pm = new PartitionMap();
                pm.Type = buffer[position];
                byte length = buffer[position + 1];
                if (position + length > SectorSize)
                {
                    return(false);
                }

                if (pm.Type == 1)
                {
                    if (position + 6 > SectorSize)
                    {
                        return(false);
                    }

                    pm.PartitionNumber = UdfHelper.Get16(position + 4, buffer);
                }
                else
                {
                    return(false);
                }

                position         += length;
                pm.PartitionIndex = volume.PartitionMaps.Count;
                volume.PartitionMaps.Add(pm);
            }

            this.LogicalVolumes.Add(volume);
            return(true);
        }
示例#5
0
        /// <summary>
        /// Reads a partition descriptor from the buffer.
        /// </summary>
        /// <param name="buffer">The buffer to read the partition data from.</param>
        private void ReadPartitionDescriptor(byte[] buffer)
        {
            var partition = new Partition
            {
                Number   = UdfHelper.Get16(22, buffer),
                Position = UdfHelper.Get32(188, buffer),
                Length   = UdfHelper.Get32(192, buffer)
            };

            this.Partitions.Add(partition);
        }
示例#6
0
        public void Parse(int start, byte[] buffer)
        {
            try {
                this.FileType = (IcbFileType)buffer[start + 11];
            } catch (InvalidCastException) {
                this.FileType = IcbFileType.Other;
            }

            int flags = UdfHelper.Get16(start + 18, buffer);

            try {
                this.DescriptorType = (IcbDescriptorType)(flags & 3);
            } catch (InvalidCastException) {
                throw new InvalidOperationException();
            }
        }
 public void Parse(int start, byte[] buffer)
 {
     Data = UdfHelper.Readbytes(start, buffer, 128);
     type = Data[0];
 }
 public void Parse(int start, byte[] buffer, int size)
 {
     type = buffer[start];
     Data = new byte[size];
     Data = UdfHelper.Readbytes(start, buffer, size);
 }
示例#9
0
 public void Parse(int start, byte[] buffer)
 {
     Data = UdfHelper.Readbytes(start, buffer, 12);
 }
示例#10
0
        /// <summary>
        /// Reads the data from the image for a record.
        /// </summary>
        /// <param name="item">The item to read the data into.</param>
        /// <param name="volumeIndex">The index of the volume the file resides on.</param>
        /// <param name="lad">The long allocation descriptor of the file.</param>
        /// <param name="numRecurseAllowed">The number of recursions allowed before the method fails.</param>
        /// <returns>Returns true if the record was read successfully.</returns>
        private bool ReadRecordData(UdfRecord item, int volumeIndex, LongAllocationDescriptor lad, int numRecurseAllowed)
        {
            if (this.itemCount > MaxItems)
            {
                return(false);
            }

            LogicalVolume volume = this.LogicalVolumes[volumeIndex];

            if (lad.Length != volume.BlockSize)
            {
                return(false);
            }

            // Read the record.
            int size = lad.Length;

            byte[] buffer = new byte[size];
            if (!this.ReadData(volumeIndex, lad, buffer))
            {
                return(false);
            }

            // Validate the tag is a file.
            VolumeTag tag = new VolumeTag();

            tag.Parse(0, buffer, size);
            if (tag.Identifier != (short)VolumeDescriptorType.File)
            {
                return(false);
            }

            // Validate the IcbTage indicates file or directory.
            item.IcbTag.Parse(16, buffer);
            if (item.IcbTag.FileType != IcbFileType.Directory && item.IcbTag.FileType != IcbFileType.File)
            {
                return(false);
            }

            item.Parse(buffer);
            int extendedAttrLen     = UdfHelper.Get32(168, buffer);
            int allocDescriptorsLen = UdfHelper.Get32(172, buffer);

            if ((extendedAttrLen & 3) != 0)
            {
                return(false);
            }

            int position = 176;

            if (extendedAttrLen > size - position)
            {
                return(false);
            }

            position += extendedAttrLen;
            IcbDescriptorType desctType = item.IcbTag.DescriptorType;

            if (allocDescriptorsLen > size - position)
            {
                return(false);
            }

            if (desctType == IcbDescriptorType.Inline)
            {
                // If the file data is inline, read it in now since we have it.
                item.IsInline   = true;
                item.InlineData = UdfHelper.Readbytes(position, buffer, allocDescriptorsLen);
            }
            else
            {
                // Otherwise read the information about where the file is located for later.
                item.IsInline   = false;
                item.InlineData = new byte[0];
                if ((desctType != IcbDescriptorType.Short) && (desctType != IcbDescriptorType.Long))
                {
                    return(false);
                }

                for (int index = 0; index < allocDescriptorsLen;)
                {
                    FileExtent extent = new FileExtent();
                    if (desctType == IcbDescriptorType.Short)
                    {
                        if (index + 8 > allocDescriptorsLen)
                        {
                            return(false);
                        }

                        ShortAllocationDescriptor sad = new ShortAllocationDescriptor();
                        sad.Parse(position + index, buffer);
                        extent.Position           = sad.Position;
                        extent.Length             = sad.Length;
                        extent.PartitionReference = lad.Location.PartitionReference;
                        index += 8;
                    }
                    else
                    {
                        if (index + 16 > allocDescriptorsLen)
                        {
                            return(false);
                        }

                        LongAllocationDescriptor ladNew = new LongAllocationDescriptor();
                        ladNew.Parse(position + index, buffer);
                        extent.Position           = ladNew.Location.Position;
                        extent.PartitionReference = ladNew.Location.PartitionReference;
                        extent.Length             = ladNew.Length;
                        index += 16;
                    }

                    item.Extents.Add(extent);
                }
            }

            if (item.IcbTag.IsDirectory)
            {
                if (!item.CheckChunkSizes() || !this.CheckItemExtents(volumeIndex, item))
                {
                    return(false);
                }

                buffer = new byte[0];
                if (!this.ReadFromFile(volumeIndex, ref item, ref buffer))
                {
                    return(false);
                }

                item._size = 0;
                item.Extents.Clear();
                size = buffer.Length;
                int processedTotal = 0;
                int processedCur   = -1;
                while (processedTotal < size || processedCur == 0)
                {
                    UdfFileInformation fileId = new UdfFileInformation();
                    fileId.Parse(processedTotal, buffer, (size - processedTotal), ref processedCur);
                    if (!fileId.IsItLinkParent)
                    {
                        // Recursively read the contentst of the drirectory
                        UdfRecord fileItem = new UdfRecord();
                        fileItem.Id = fileId.Identifier;
                        if (fileItem.Id.Data != null)
                        {
                            this.fileNameLengthTotal += fileItem.Id.Data.Length;
                        }

                        if (this.fileNameLengthTotal > MaxFileNameLength)
                        {
                            return(false);
                        }

                        fileItem._Parent = item;
                        item.Subitems.Add(fileItem);
                        if (item.Subitems.Count > MaxFiles)
                        {
                            return(false);
                        }

                        this.ReadRecord(fileItem, volumeIndex, fileId.Icb, numRecurseAllowed);
                    }

                    processedTotal += processedCur;
                }
            }
            else
            {
                if (item.Extents.Count > MaxExtents - this.numExtents)
                {
                    return(false);
                }

                this.numExtents += item.Extents.Count;
                if (item.InlineData.Length > MaxInlineExtentsSize - this.inlineExtentsSize)
                {
                    return(false);
                }

                this.inlineExtentsSize += item.InlineData.Length;
            }

            this.itemCount++;
            return(true);
        }