예제 #1
0
        /// <summary>
        /// Creates a new EWFInfo helper class from filePath.
        /// </summary>
        /// <param name="filePath">The path of the EWF file.</param>
        public EWFInfo(string filePath)
        {
            FilePath = filePath;

            using (FileStream fs = File.OpenRead(filePath))
            {
                fs.Seek(0, SeekOrigin.Begin);

                byte[] buff = new byte[13];
                fs.Read(buff, 0, 13);
                EWFHeader ewfHeader = new EWFHeader(buff);

                while (fs.Position < fs.Length)
                {
                    buff = new byte[76];
                    fs.Read(buff, 0, 76);
                    SectionDescriptor sd = new SectionDescriptor(buff, fs.Position - 76);

                    switch (sd.SectionType)
                    {
                    case SECTION_TYPE.header:
                    case SECTION_TYPE.header2:
                        // Save the header
                        buff = new byte[sd.NextSectionOffset - fs.Position];
                        fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
                        HeaderSection = new Section.Header2(buff);
                        break;

                    case SECTION_TYPE.volume:
                    case SECTION_TYPE.disk:
                    case SECTION_TYPE.data:
                        // Save the volume
                        buff = new byte[sd.NextSectionOffset - fs.Position];
                        fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
                        VolumeSection = new Section.Volume(buff);
                        break;

                    case SECTION_TYPE.next:
                    case SECTION_TYPE.done:
                        fs.Seek(76, SeekOrigin.Current);
                        break;

                    default:
                        fs.Seek(sd.NextSectionOffset - (int)fs.Position, SeekOrigin.Current);
                        break;
                    }

                    if (HeaderSection != null && VolumeSection != null)
                    {
                        break;
                    }
                }
            }

            if (HeaderSection == null || VolumeSection == null)
            {
                throw new Exception("file missing header or volume section");
            }
        }
예제 #2
0
        /// <summary>
        /// Creates a new EWFInfo helper class from filePath.
        /// </summary>
        /// <param name="filePath">The path of the EWF file.</param>
        public EWFInfo(string filePath)
        {
            FilePath = filePath;

            using (FileStream fs = File.OpenRead(filePath))
            {
                fs.Seek(0, SeekOrigin.Begin);

                byte[] buff = new byte[13];
                fs.Read(buff, 0, 13);
                EWFHeader ewfHeader = new EWFHeader(buff);

                while (fs.Position < fs.Length)
                {
                    buff = new byte[76];
                    fs.Read(buff, 0, 76);
                    SectionDescriptor sd = new SectionDescriptor(buff, fs.Position - 76);

                    switch (sd.SectionType)
                    {
                        case SECTION_TYPE.header:
                        case SECTION_TYPE.header2:
                            // Save the header
                            buff = new byte[sd.NextSectionOffset - fs.Position];
                            fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
                            HeaderSection = new Section.Header2(buff);
                            break;

                        case SECTION_TYPE.volume:
                        case SECTION_TYPE.disk:
                        case SECTION_TYPE.data:
                            // Save the volume
                            buff = new byte[sd.NextSectionOffset - fs.Position];
                            fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
                            VolumeSection = new Section.Volume(buff);
                            break;

                        case SECTION_TYPE.next:
                        case SECTION_TYPE.done:
                            fs.Seek(76, SeekOrigin.Current);
                            break;

                        default:
                            fs.Seek(sd.NextSectionOffset - (int)fs.Position, SeekOrigin.Current);
                            break;
                    }

                    if (HeaderSection != null && VolumeSection != null)
                        break;
                }
            }

            if (HeaderSection == null || VolumeSection == null)
                throw new Exception("file missing header or volume section");
        }
예제 #3
0
        private void ResolveFileChain()
        {
            int  i       = 0;
            bool gotDone = false;

            do
            {
                using (FileStream fs = File.OpenRead(Files[i]))
                {
                    try
                    {
                        byte[] buff = new byte[13];
                        fs.Read(buff, 0, 13);
                        EWFHeader header = new EWFHeader(buff);
                        if (header.SegmentNumber != i + 1)
                        {
                            throw new ArgumentException(string.Format("invalid segment order: got {0}, should be {1}", header.SegmentNumber, i + 1));
                        }

                        buff = new byte[76];
                        fs.Seek(-76, SeekOrigin.End);
                        fs.Read(buff, 0, 76);
                        SectionDescriptor secDescriptor = new SectionDescriptor(buff, fs.Length - 76);
                        if (secDescriptor.SectionType == SECTION_TYPE.next)
                        {
                            Files.Add(Utils.CalcNextFilename(Files[i]));
                            i++;
                        }
                        else if (secDescriptor.SectionType == SECTION_TYPE.done)
                        {
                            gotDone = true;
                        }
                        else
                        {
                            throw new Exception(string.Format("unexpected final section: {0}", secDescriptor.SectionType));
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(string.Format("error whilst processing {0}", Files[i]), ex);
                    }
                }
            } while (!gotDone);
        }
예제 #4
0
        private void PopulateChunkInfo()
        {
            long thisChunk = 0;

            for (int fileCount = 0; fileCount < Files.Count; fileCount++)
            {
                using (FileStream fs = File.OpenRead(Files[fileCount]))
                {
                    bool gotTable, gotHeader, gotHeader2;
                    gotTable = gotHeader = gotHeader2 = false;
                    int endOfSectors = -1;

                    fs.Seek(13, SeekOrigin.Begin); // Skip file header

                    while (fs.Position < fs.Length)
                    {
                        byte[] buff = new byte[76];
                        fs.Read(buff, 0, 76);
                        SectionDescriptor sd;
                        try
                        {
                            sd = new SectionDescriptor(buff, fs.Position - 76);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(Files[fileCount], ex);
                        }

                        switch (sd.SectionType)
                        {
                        case SECTION_TYPE.header:
                            break;

                        case SECTION_TYPE.header2:
                            break;

                        case SECTION_TYPE.ltypes:
                            break;

                        case SECTION_TYPE.ltree:
                            break;

                        case SECTION_TYPE.session:
                            break;

                        case SECTION_TYPE.error2:
                            break;

                        case SECTION_TYPE.incomplete:
                            break;

                        case SECTION_TYPE.disk:
                            break;

                        case SECTION_TYPE.volume:
                            break;

                        case SECTION_TYPE.sectors:
                            break;

                        case SECTION_TYPE.table:
                            break;

                        case SECTION_TYPE.table2:
                            break;

                        case SECTION_TYPE.next:
                            break;

                        case SECTION_TYPE.data:
                            break;

                        case SECTION_TYPE.digest:
                            break;

                        case SECTION_TYPE.hash:
                            break;

                        case SECTION_TYPE.done:
                            break;

                        default:
                            break;
                        }

                        switch (sd.SectionType)
                        {
                        case SECTION_TYPE.header:
                            Sections.Add("header", new Section.Header2(readSection(sd, fs)));
                            break;

                        case SECTION_TYPE.header2:
                            Sections.Add("header2", new Section.Header2(readSection(sd, fs)));
                            break;

                        case SECTION_TYPE.disk:
                        case SECTION_TYPE.data:
                        case SECTION_TYPE.volume:
                            // Calculate bytes per chunk
                            buff = new byte[sd.NextSectionOffset - (int)fs.Position];
                            fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
                            Section.Volume VolumeSection = new Section.Volume(buff);
                            Sections.Add("volume", VolumeSection);
                            _bytesPerChunk = VolumeSection.SectorsPerChunk * VolumeSection.BytesPerSector;

                            switch (VolumeSection.MediaType)
                            {
                            case MEDIA_TYPE.Disc:
                                DiskType = VirtualDiskClass.OpticalDisk;
                                break;

                            case MEDIA_TYPE.Fixed:
                                DiskType = VirtualDiskClass.HardDisk;
                                break;

                            default:
                                DiskType = VirtualDiskClass.None;
                                break;
                            }

                            if (_length < 0)
                            {
                                _length = (long)VolumeSection.BytesPerSector * (long)VolumeSection.SectorCount;
                            }

                            break;

                        case SECTION_TYPE.table:
                        case SECTION_TYPE.table2:
                            // Calculate the chunks
                            if (gotTable) // Don't read both versions of the table...
                            {             // ...so skip the bytes
                                fs.Seek(sd.NextSectionOffset - (int)fs.Position, SeekOrigin.Current);
                            }
                            else
                            {
                                if (_bytesPerChunk < 0)
                                {
                                    throw new Exception(string.Format("table/table2 section before disk/data/volume, in {0}", Files[fileCount]));
                                }

                                bool volumeCompression = ((Section.Volume)GetSection("volume")).Compression != COMPRESSION.None;

                                buff = new byte[sd.NextSectionOffset - fs.Position];
                                fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
                                Section.Table table = new Section.Table(buff);
                                Sections.Add("table", table);
                                for (int i = 0; i < table.Entries.Count; i++)
                                {
                                    Section.Table.TableEntry entry = table.Entries[i];
                                    if (_chunkInfos.Count == 261)
                                    {
                                        Console.WriteLine("!!!");
                                    }
                                    int bytesInChunk = i == table.Entries.Count - 1 ? endOfSectors - entry.Offset : table.Entries[i + 1].Offset - entry.Offset;
                                    _chunkInfos.Add(new ChunkInfo(
                                                        fileCount,
                                                        entry.Offset,
                                                        _bytesPerChunk * thisChunk++,
                                                        _bytesPerChunk,
                                                        volumeCompression | entry.Compressed,
                                                        bytesInChunk));
                                }
                            }
                            gotTable = !gotTable;
                            break;

                        case SECTION_TYPE.next:
                        case SECTION_TYPE.done:
                            fs.Seek(76, SeekOrigin.Current);
                            break;

                        case SECTION_TYPE.sectors:
                            endOfSectors = sd.NextSectionOffset;
                            fs.Seek(sd.NextSectionOffset - (int)fs.Position, SeekOrigin.Current);
                            break;

                        case SECTION_TYPE.digest:
                            if (MD5 == null)
                            {
                                buff = new byte[sd.NextSectionOffset - fs.Position];
                                fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
                                Section.Digest digest = new Section.Digest(buff);
                                MD5 = digest.MD5;
                            }
                            else
                            {
                                fs.Seek(sd.NextSectionOffset - (int)fs.Position, SeekOrigin.Current);
                            }
                            break;

                        case SECTION_TYPE.hash:
                            if (MD5 == null)
                            {
                                buff = new byte[sd.NextSectionOffset - fs.Position];
                                fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
                                Section.Hash hash = new Section.Hash(buff);
                                MD5 = hash.MD5;
                            }
                            else
                            {
                                fs.Seek(sd.NextSectionOffset - (int)fs.Position, SeekOrigin.Current);
                            }
                            break;

                        default:     // Don't care about any other sections
                            fs.Seek(sd.NextSectionOffset - (int)fs.Position, SeekOrigin.Current);
                            break;
                        }
                    }
                }
            }

            if (_chunkInfos.Count > 0)
            {
                _chunkStarts = new long[_chunkInfos.Count];
                int i = 0;
                foreach (ChunkInfo ci in _chunkInfos)
                {
                    _chunkStarts[i++] = ci.Start;
                }
            }
        }
예제 #5
0
 private byte[] readSection(SectionDescriptor sd, FileStream fs)
 {
     byte[] buff = new byte[sd.NextSectionOffset - (int)fs.Position];
     fs.Read(buff, 0, sd.NextSectionOffset - (int)fs.Position);
     return(buff);
 }