}                                                // 10

        /// <summary>
        /// Populate a CommonHeader from a stream
        /// </summary>
        public static CommonHeader Create(Stream stream)
        {
            if (stream.Length - stream.Position < Constants.COMMON_HEADER_SIZE)
            {
                return(null);
            }

            var commonHeader = new CommonHeader();

            commonHeader.Signature = stream.ReadUInt32();
            if (commonHeader.Signature != Constants.CAB_SIGNATURE)
            {
                return(default);
Exemple #2
0
        /// <summary>
        /// Open the volume at the inputted index
        /// </summary>
        public bool OpenVolume(int volume)
        {
            this.VolumeFile?.Close();
            this.VolumeFile = this.Cabinet.OpenFileForReading(volume, Constants.CABINET_SUFFIX);
            if (this.VolumeFile == null)
            {
                Console.Error.WriteLine($"Failed to open input cabinet file {volume}");
                return(false);
            }

            var commonHeader = CommonHeader.Create(this.VolumeFile);

            if (commonHeader == default)
            {
                return(false);
            }

            this.VolumeHeader = VolumeHeader.Create(this.VolumeFile, this.Cabinet.HeaderList.MajorVersion);
            if (this.VolumeHeader == null)
            {
                return(false);
            }

            // enable support for split archives for IS5
            if (this.Cabinet.HeaderList.MajorVersion == 5)
            {
                if (this.Index < (this.Cabinet.HeaderList.Descriptor.FileCount - 1) &&
                    this.Index == this.VolumeHeader.LastFileIndex &&
                    this.VolumeHeader.LastFileSizeCompressed != this.FileDescriptor.CompressedSize)
                {
                    this.FileDescriptor.Flags |= FileDescriptorFlag.FILE_SPLIT;
                }
                else if (this.Index > 0 &&
                         this.Index == this.VolumeHeader.FirstFileIndex &&
                         this.VolumeHeader.FirstFileSizeCompressed != this.FileDescriptor.CompressedSize)
                {
                    this.FileDescriptor.Flags |= FileDescriptorFlag.FILE_SPLIT;
                }
            }

            ulong dataOffset, volumeBytesLeftCompressed, volumeBytesLeftExpanded;

            if (this.FileDescriptor.Flags.HasFlag(FileDescriptorFlag.FILE_SPLIT))
            {
                if (this.Index == this.VolumeHeader.LastFileIndex && this.VolumeHeader.LastFileOffset != 0x7FFFFFFF)
                {
                    // can be first file too
                    dataOffset = this.VolumeHeader.LastFileOffset;
                    volumeBytesLeftExpanded   = this.VolumeHeader.LastFileSizeExpanded;
                    volumeBytesLeftCompressed = this.VolumeHeader.LastFileSizeCompressed;
                }
                else if (this.Index == this.VolumeHeader.FirstFileIndex)
                {
                    dataOffset = this.VolumeHeader.FirstFileOffset;
                    volumeBytesLeftExpanded   = this.VolumeHeader.FirstFileSizeExpanded;
                    volumeBytesLeftCompressed = this.VolumeHeader.FirstFileSizeCompressed;
                }
                else
                {
                    return(true);
                }
            }
            else
            {
                dataOffset = this.FileDescriptor.DataOffset;
                volumeBytesLeftExpanded   = this.FileDescriptor.ExpandedSize;
                volumeBytesLeftCompressed = this.FileDescriptor.CompressedSize;
            }

            if (this.FileDescriptor.Flags.HasFlag(FileDescriptorFlag.FILE_COMPRESSED))
            {
                this.VolumeBytesLeft = volumeBytesLeftCompressed;
            }
            else
            {
                this.VolumeBytesLeft = volumeBytesLeftExpanded;
            }

            this.VolumeFile.Seek((long)dataOffset, SeekOrigin.Begin);
            this.Volume = volume;

            return(true);
        }
Exemple #3
0
 /// <summary>
 /// Populate the CommonHeader from header data
 /// </summary>
 public bool GetCommmonHeader()
 {
     this.CommonHeader = CommonHeader.Create(this.Data);
     return(this.CommonHeader != default);
 }