Пример #1
0
        public virtual int ReadFrom(byte[] buffer, int offset)
        {
            DescriptorTag           = Utilities.ToStruct <DescriptorTag>(buffer, offset);
            InformationControlBlock = Utilities.ToStruct <InformationControlBlock>(buffer, offset + 16);
            Uid                         = Utilities.ToUInt32LittleEndian(buffer, offset + 36);
            Gid                         = Utilities.ToUInt32LittleEndian(buffer, offset + 40);
            Permissions                 = (FilePermissions)Utilities.ToUInt32LittleEndian(buffer, offset + 44);
            FileLinkCount               = Utilities.ToUInt16LittleEndian(buffer, offset + 48);
            RecordFormat                = buffer[offset + 50];
            RecordDisplayAttributes     = buffer[offset + 51];
            RecordLength                = Utilities.ToUInt16LittleEndian(buffer, offset + 52);
            InformationLength           = Utilities.ToUInt64LittleEndian(buffer, offset + 56);
            LogicalBlocksRecorded       = Utilities.ToUInt64LittleEndian(buffer, offset + 64);
            AccessTime                  = UdfUtilities.ParseTimestamp(buffer, offset + 72);
            ModificationTime            = UdfUtilities.ParseTimestamp(buffer, offset + 84);
            AttributeTime               = UdfUtilities.ParseTimestamp(buffer, offset + 96);
            Checkpoint                  = Utilities.ToUInt32LittleEndian(buffer, offset + 108);
            ExtendedAttributeIcb        = Utilities.ToStruct <LongAllocationDescriptor>(buffer, offset + 112);
            ImplementationIdentifier    = Utilities.ToStruct <ImplementationEntityIdentifier>(buffer, offset + 128);
            UniqueId                    = Utilities.ToUInt64LittleEndian(buffer, offset + 160);
            ExtendedAttributesLength    = Utilities.ToInt32LittleEndian(buffer, offset + 168);
            AllocationDescriptorsLength = Utilities.ToInt32LittleEndian(buffer, offset + 172);
            AllocationDescriptors       = Utilities.ToByteArray(buffer, offset + 176 + ExtendedAttributesLength, AllocationDescriptorsLength);

            byte[] eaData = Utilities.ToByteArray(buffer, offset + 176, ExtendedAttributesLength);
            ExtendedAttributes = ReadExtendedAttributes(eaData);

            return((int)(176 + ExtendedAttributesLength + AllocationDescriptorsLength));
        }
Пример #2
0
        public virtual int ReadFrom(byte[] buffer, int offset)
        {
            DescriptorTag = Utilities.ToStruct<DescriptorTag>(buffer, offset);
            InformationControlBlock = Utilities.ToStruct<InformationControlBlock>(buffer, offset + 16);
            Uid = Utilities.ToUInt32LittleEndian(buffer, offset + 36);
            Gid = Utilities.ToUInt32LittleEndian(buffer, offset + 40);
            Permissions = (FilePermissions)Utilities.ToUInt32LittleEndian(buffer, offset + 44);
            FileLinkCount = Utilities.ToUInt16LittleEndian(buffer, offset + 48);
            RecordFormat = buffer[offset + 50];
            RecordDisplayAttributes = buffer[offset + 51];
            RecordLength = Utilities.ToUInt16LittleEndian(buffer, offset + 52);
            InformationLength = Utilities.ToUInt64LittleEndian(buffer, offset + 56);
            LogicalBlocksRecorded = Utilities.ToUInt64LittleEndian(buffer, offset + 64);
            AccessTime = UdfUtilities.ParseTimestamp(buffer, offset + 72);
            ModificationTime = UdfUtilities.ParseTimestamp(buffer, offset + 84);
            AttributeTime = UdfUtilities.ParseTimestamp(buffer, offset + 96);
            Checkpoint = Utilities.ToUInt32LittleEndian(buffer, offset + 108);
            ExtendedAttributeIcb = Utilities.ToStruct<LongAllocationDescriptor>(buffer, offset + 112);
            ImplementationIdentifier = Utilities.ToStruct<ImplementationEntityIdentifier>(buffer, offset + 128);
            UniqueId = Utilities.ToUInt64LittleEndian(buffer, offset + 160);
            ExtendedAttributesLength = Utilities.ToInt32LittleEndian(buffer, offset + 168);
            AllocationDescriptorsLength = Utilities.ToInt32LittleEndian(buffer, offset + 172);
            AllocationDescriptors = Utilities.ToByteArray(buffer, offset + 176 + ExtendedAttributesLength, AllocationDescriptorsLength);

            byte[] eaData = Utilities.ToByteArray(buffer, offset + 176, ExtendedAttributesLength);
            ExtendedAttributes = ReadExtendedAttributes(eaData);

            return (int)(176 + ExtendedAttributesLength + AllocationDescriptorsLength);
        }
Пример #3
0
        public MetadataPartition(UdfContext context, LogicalVolumeDescriptor volumeDescriptor, MetadataPartitionMap partitionMap)
            : base(context, volumeDescriptor)
        {
            _partitionMap = partitionMap;

            PhysicalPartition physical = context.PhysicalPartitions[partitionMap.PartitionNumber];
            long fileEntryPos          = partitionMap.MetadataFileLocation * (long)volumeDescriptor.LogicalBlockSize;

            byte[] entryData = Utilities.ReadFully(physical.Content, fileEntryPos, _context.PhysicalSectorSize);
            if (!DescriptorTag.IsValid(entryData, 0))
            {
                throw new IOException("Invalid descriptor tag looking for Metadata file entry");
            }

            DescriptorTag dt = Utilities.ToStruct <DescriptorTag>(entryData, 0);

            if (dt.TagIdentifier == TagIdentifier.ExtendedFileEntry)
            {
                ExtendedFileEntry efe = Utilities.ToStruct <ExtendedFileEntry>(entryData, 0);
                _metadataFile = new File(context, physical, efe, _volumeDescriptor.LogicalBlockSize);
            }
            else
            {
                throw new NotImplementedException("Only EFE implemented for Metadata file entry");
            }
        }
Пример #4
0
        public int ReadFrom(byte[] buffer, int offset)
        {
            DescriptorTag           = Utilities.ToStruct <DescriptorTag>(buffer, offset);
            FileVersionNumber       = Utilities.ToUInt16LittleEndian(buffer, offset + 16);
            FileCharacteristics     = (FileCharacteristic)buffer[offset + 18];
            NameLength              = buffer[offset + 19];
            FileLocation            = Utilities.ToStruct <LongAllocationDescriptor>(buffer, offset + 20);
            ImplementationUseLength = Utilities.ToUInt16LittleEndian(buffer, offset + 36);
            ImplementationUse       = Utilities.ToByteArray(buffer, offset + 38, ImplementationUseLength);
            Name = UdfUtilities.ReadDCharacters(buffer, offset + 38 + ImplementationUseLength, NameLength);

            return(Utilities.RoundUp(38 + ImplementationUseLength + NameLength, 4));
        }
Пример #5
0
        public static bool TryFromStream(Stream stream, out DescriptorTag result)
        {
            byte[] next = Utilities.ReadFully(stream, 512);
            if (!DescriptorTag.IsValid(next, 0))
            {
                result = null;
                return(false);
            }

            DescriptorTag dt = new DescriptorTag();

            dt.ReadFrom(next, 0);

            result = dt;
            return(true);
        }
        public int ReadFrom(byte[] buffer, int offset)
        {
            if (!DescriptorTag.IsValid(buffer, offset))
            {
                throw new InvalidDataException("Invalid Anchor Volume Descriptor Pointer (invalid tag)");
            }

            Tag = new DescriptorTag();
            Tag.ReadFrom(buffer, offset);

            if (UdfUtilities.ComputeCrc(buffer, offset + Tag.Size, Tag.DescriptorCrcLength) != Tag.DescriptorCrc)
            {
                throw new InvalidDataException("Invalid Anchor Volume Descriptor Pointer (invalid CRC)");
            }

            return Parse(buffer, offset);
        }
Пример #7
0
        public int ReadFrom(byte[] buffer, int offset)
        {
            if (!DescriptorTag.IsValid(buffer, offset))
            {
                throw new InvalidDataException("Invalid Anchor Volume Descriptor Pointer (invalid tag)");
            }

            Tag = new DescriptorTag();
            Tag.ReadFrom(buffer, offset);

            if (UdfUtilities.ComputeCrc(buffer, offset + Tag.Size, Tag.DescriptorCrcLength) != Tag.DescriptorCrc)
            {
                throw new InvalidDataException("Invalid Anchor Volume Descriptor Pointer (invalid CRC)");
            }

            return(Parse(buffer, offset));
        }
Пример #8
0
            private bool ProbeSectorSize(int size)
            {
                if (_data.Length < 257 * (long)size)
                {
                    return(false);
                }

                _data.Position = 256 * (long)size;

                DescriptorTag dt;

                if (!DescriptorTag.TryFromStream(_data, out dt))
                {
                    return(false);
                }

                return(dt.TagIdentifier == TagIdentifier.AnchorVolumeDescriptorPointer &&
                       dt.TagLocation == 256);
            }
Пример #9
0
        protected static List <ExtendedAttributeRecord> ReadExtendedAttributes(byte[] eaData)
        {
            if (eaData != null && eaData.Length != 0)
            {
                DescriptorTag eaTag = new DescriptorTag();
                eaTag.ReadFrom(eaData, 0);

                int implAttrLocation = Utilities.ToInt32LittleEndian(eaData, 16);
                int appAttrLocation  = Utilities.ToInt32LittleEndian(eaData, 20);

                List <ExtendedAttributeRecord> extendedAttrs = new List <ExtendedAttributeRecord>();
                int pos = 24;
                while (pos < eaData.Length)
                {
                    ExtendedAttributeRecord ea;

                    if (pos >= implAttrLocation)
                    {
                        ea = new ImplementationUseExtendedAttributeRecord();
                    }
                    else
                    {
                        ea = new ExtendedAttributeRecord();
                    }

                    int numRead = ea.ReadFrom(eaData, pos);
                    extendedAttrs.Add(ea);

                    pos += numRead;
                }

                return(extendedAttrs);
            }
            else
            {
                return(null);
            }
        }
Пример #10
0
        public int ReadFrom(byte[] buffer, int offset)
        {
            DescriptorTag = Utilities.ToStruct<DescriptorTag>(buffer, offset);
            RecordingTime = UdfUtilities.ParseTimestamp(buffer, offset + 16);
            InterchangeLevel = Utilities.ToUInt16LittleEndian(buffer, offset + 28);
            MaximumInterchangeLevel = Utilities.ToUInt16LittleEndian(buffer, offset + 30);
            CharacterSetList = Utilities.ToUInt32LittleEndian(buffer, offset + 32);
            MaximumCharacterSetList = Utilities.ToUInt32LittleEndian(buffer, offset + 36);
            FileSetNumber = Utilities.ToUInt32LittleEndian(buffer, offset + 40);
            FileSetDescriptorNumber = Utilities.ToUInt32LittleEndian(buffer, offset + 44);
            LogicalVolumeIdentifierCharset = Utilities.ToStruct<CharacterSetSpecification>(buffer, offset + 48);
            LogicalVolumeIdentifier = UdfUtilities.ReadDString(buffer, offset + 112, 128);
            FileSetCharset = Utilities.ToStruct<CharacterSetSpecification>(buffer, offset + 240);
            FileSetIdentifier = UdfUtilities.ReadDString(buffer, offset + 304, 32);
            CopyrightFileIdentifier = UdfUtilities.ReadDString(buffer, offset + 336, 32);
            AbstractFileIdentifier = UdfUtilities.ReadDString(buffer, offset + 368, 32);
            RootDirectoryIcb = Utilities.ToStruct<LongAllocationDescriptor>(buffer, offset + 400);
            DomainIdentifier = Utilities.ToStruct<DomainEntityIdentifier>(buffer, offset + 416);
            NextExtent = Utilities.ToStruct<LongAllocationDescriptor>(buffer, offset + 448);
            SystemStreamDirectoryIcb = Utilities.ToStruct<LongAllocationDescriptor>(buffer, offset + 464);

            return 512;
        }
Пример #11
0
        public int ReadFrom(byte[] buffer, int offset)
        {
            DescriptorTag                  = Utilities.ToStruct <DescriptorTag>(buffer, offset);
            RecordingTime                  = UdfUtilities.ParseTimestamp(buffer, offset + 16);
            InterchangeLevel               = Utilities.ToUInt16LittleEndian(buffer, offset + 28);
            MaximumInterchangeLevel        = Utilities.ToUInt16LittleEndian(buffer, offset + 30);
            CharacterSetList               = Utilities.ToUInt32LittleEndian(buffer, offset + 32);
            MaximumCharacterSetList        = Utilities.ToUInt32LittleEndian(buffer, offset + 36);
            FileSetNumber                  = Utilities.ToUInt32LittleEndian(buffer, offset + 40);
            FileSetDescriptorNumber        = Utilities.ToUInt32LittleEndian(buffer, offset + 44);
            LogicalVolumeIdentifierCharset = Utilities.ToStruct <CharacterSetSpecification>(buffer, offset + 48);
            LogicalVolumeIdentifier        = UdfUtilities.ReadDString(buffer, offset + 112, 128);
            FileSetCharset                 = Utilities.ToStruct <CharacterSetSpecification>(buffer, offset + 240);
            FileSetIdentifier              = UdfUtilities.ReadDString(buffer, offset + 304, 32);
            CopyrightFileIdentifier        = UdfUtilities.ReadDString(buffer, offset + 336, 32);
            AbstractFileIdentifier         = UdfUtilities.ReadDString(buffer, offset + 368, 32);
            RootDirectoryIcb               = Utilities.ToStruct <LongAllocationDescriptor>(buffer, offset + 400);
            DomainIdentifier               = Utilities.ToStruct <DomainEntityIdentifier>(buffer, offset + 416);
            NextExtent = Utilities.ToStruct <LongAllocationDescriptor>(buffer, offset + 448);
            SystemStreamDirectoryIcb = Utilities.ToStruct <LongAllocationDescriptor>(buffer, offset + 464);

            return(512);
        }
Пример #12
0
        public static File FromDescriptor(UdfContext context, LongAllocationDescriptor icb)
        {
            LogicalPartition partition = context.LogicalPartitions[icb.ExtentLocation.Partition];

            byte[]        rootDirData = UdfUtilities.ReadExtent(context, icb);
            DescriptorTag rootDirTag  = Utilities.ToStruct <DescriptorTag>(rootDirData, 0);

            if (rootDirTag.TagIdentifier == TagIdentifier.ExtendedFileEntry)
            {
                ExtendedFileEntry fileEntry = Utilities.ToStruct <ExtendedFileEntry>(rootDirData, 0);
                if (fileEntry.InformationControlBlock.FileType == FileType.Directory)
                {
                    return(new Directory(context, partition, fileEntry));
                }
                else
                {
                    return(new File(context, partition, fileEntry, (uint)partition.LogicalBlockSize));
                }
            }
            else if (rootDirTag.TagIdentifier == TagIdentifier.FileEntry)
            {
                FileEntry fileEntry = Utilities.ToStruct <FileEntry>(rootDirData, 0);
                if (fileEntry.InformationControlBlock.FileType == FileType.Directory)
                {
                    return(new Directory(context, partition, fileEntry));
                }
                else
                {
                    return(new File(context, partition, fileEntry, (uint)partition.LogicalBlockSize));
                }
            }
            else
            {
                throw new NotImplementedException("Only ExtendedFileEntries implemented");
            }
        }
Пример #13
0
        protected static List<ExtendedAttributeRecord> ReadExtendedAttributes(byte[] eaData)
        {
            if (eaData != null && eaData.Length != 0)
            {
                DescriptorTag eaTag = new DescriptorTag();
                eaTag.ReadFrom(eaData, 0);

                int implAttrLocation = Utilities.ToInt32LittleEndian(eaData, 16);
                int appAttrLocation = Utilities.ToInt32LittleEndian(eaData, 20);

                List<ExtendedAttributeRecord> extendedAttrs = new List<ExtendedAttributeRecord>();
                int pos = 24;
                while (pos < eaData.Length)
                {
                    ExtendedAttributeRecord ea;

                    if (pos >= implAttrLocation)
                    {
                        ea = new ImplementationUseExtendedAttributeRecord();
                    }
                    else
                    {
                        ea = new ExtendedAttributeRecord();
                    }

                    int numRead = ea.ReadFrom(eaData, pos);
                    extendedAttrs.Add(ea);

                    pos += numRead;
                }

                return extendedAttrs;
            }
            else
            {
                return null;
            }
        }
Пример #14
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 = Utilities.ToStruct <FileSetDescriptor>(fsdBuffer, 0);
                    RootDirectory = (Directory)File.FromDescriptor(Context, fsd.RootDirectoryIcb);
                }
            }
Пример #15
0
        public int ReadFrom(byte[] buffer, int offset)
        {
            DescriptorTag = Utilities.ToStruct<DescriptorTag>(buffer, offset);
            FileVersionNumber = Utilities.ToUInt16LittleEndian(buffer, offset + 16);
            FileCharacteristics = (FileCharacteristic)buffer[offset + 18];
            NameLength = buffer[offset + 19];
            FileLocation = Utilities.ToStruct<LongAllocationDescriptor>(buffer, offset + 20);
            ImplementationUseLength = Utilities.ToUInt16LittleEndian(buffer, offset + 36);
            ImplementationUse = Utilities.ToByteArray(buffer, offset + 38, ImplementationUseLength);
            Name = UdfUtilities.ReadDCharacters(buffer, offset + 38 + ImplementationUseLength, NameLength);

            return Utilities.RoundUp(38 + ImplementationUseLength + NameLength, 4);
        }
Пример #16
0
        public static bool TryFromStream(Stream stream, out DescriptorTag result)
        {
            byte[] next = Utilities.ReadFully(stream, 512);
            if (!DescriptorTag.IsValid(next, 0))
            {
                result = null;
                return false;
            }

            DescriptorTag dt = new DescriptorTag();
            dt.ReadFrom(next, 0);

            result = dt;
            return true;
        }