Exemple #1
0
        public void Initialize(FileStream isoStream, long offset, bool isRawDump)
        {
            this.VolumeBaseOffset        = offset;
            this.IsRawDump               = isRawDump;
            this.VolumeType              = VolumeDataType.Data;
            this.DirectoryStructureArray = new ArrayList();
            this.FormatDescription       = MicrosoftExFatFileSystem.FORMAT_DESCRIPTION_STRING;

            this.JumpBoot   = ParseFile.ReadUint24LE(isoStream, this.VolumeBaseOffset + 0);
            this.MagicBytes = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 3, 8);
            this.ZeroChunk  = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 11, 53);

            this.PartitionOffset           = ParseFile.ReadUlongLE(isoStream, this.VolumeBaseOffset + 64);
            this.VolumeLength              = ParseFile.ReadUlongLE(isoStream, this.VolumeBaseOffset + 72);
            this.FatOffset                 = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 80);
            this.FatLength                 = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 84);
            this.ClusterHeapOffset         = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 88);
            this.ClusterCount              = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 92);
            this.RootDirectoryFirstCluster = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 96);

            this.VolumeSerialNumber = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 100);
            this.VolumeIdentifier   = this.VolumeSerialNumber.ToString("X2");

            this.FileSystemRevision = ParseFile.ReadUshortLE(isoStream, this.VolumeBaseOffset + 104);
            this.VolumeFlags        = ParseFile.ReadUshortLE(isoStream, this.VolumeBaseOffset + 106);

            this.BytesPerSector    = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 108);
            this.SectorsPerCluster = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 109);

            this.NumberOfFats = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 110);

            // caclulate helper values
            this.SectorSizeInBytes  = (uint)(1 << this.BytesPerSector);
            this.ClusterSizeInBytes = (uint)(1 << (this.SectorsPerCluster + this.BytesPerSector));

            this.VolumeLengthInBytes         = this.VolumeLength * this.SectorSizeInBytes;
            this.FatAbsoluteOffset           = (ulong)this.VolumeBaseOffset + (this.FatOffset * this.SectorSizeInBytes);
            this.FatLengthInBytes            = this.FatLength * this.SectorSizeInBytes;
            this.ClusterHeapAbsoluteOffset   = (ulong)this.VolumeBaseOffset + (this.ClusterHeapOffset * this.SectorSizeInBytes);
            this.RootDirectoryAbsoluteOffset =
                MicrosoftExFatFileSystem.GetOffsetForClusterId(this.ClusterHeapAbsoluteOffset, this.ClusterSizeInBytes, this.RootDirectoryFirstCluster); // this.ClusterHeapAbsoluteOffset + ((this.RootDirectoryFirstCluster - MicrosoftExFatFileSystem.CLUSTER_CORRECTION_OFFSET) * this.ClusterSizeInBytes);

            if (this.FileSystemRevision == MicrosoftExFatFileSystem.EXFAT_VERSION_0100)
            {
                // initialize FAT
                this.InitializeAndValidateFat(isoStream);

                // process root directory entry
                this.GetVolumeLabel(isoStream);

                // load directories
                this.LoadDirectories(isoStream);
            }
            else
            {
                MessageBox.Show(String.Format("Unsupported exFAT version: {0}", this.FileSystemRevision.ToString("X8")));
            }
        }
Exemple #2
0
        private void processDirectory(
            FileStream isoStream,
            long directoryOffset,
            long maxDirectoryLength,
            string parentDirectory,
            long volumeBaseOffset,
            ulong clusterHeapOffset,
            uint clusterSize)
        {
            byte[] primaryEntry;
            byte[] secondaryRecord;
            byte   entryType = 0xFF;


            MicrosoftExFatFileStructure      newFile;
            MicrosoftExFatDirectoryStructure newDirectory;
            ulong objectOffset;

            MicrosoftExFatRootDirFileDirectoryEntry fileEntry; // = new MicrosoftExFatRootDirFileDirectoryEntry(fileDirectoryEntry);

            MicrosoftExFatRootDirStreamExtensionEntry   streamExtensionEntry;
            MicrosoftExFatRootDirFileNameExtensionEntry fileNameExtensionEntry;

            string   fileName = String.Empty;
            DateTime fileDate = new DateTime();  // @todo update to actually parse date

            long currentOffset = directoryOffset;
            long maxOffset     = directoryOffset + maxDirectoryLength;

            // @TODO: need to handle when in non-contiguous clusters
            while ((currentOffset < maxOffset) && (entryType != MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_EMPTY))
            {
                // read primary entry
                primaryEntry = ParseFile.ParseSimpleOffset(isoStream, currentOffset, MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE);

                // process primary entry and subentries if needed
                entryType = primaryEntry[0];

                switch (entryType)
                {
                case MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_TYPE_FILE_DIRECTORY:
                    fileEntry      = new MicrosoftExFatRootDirFileDirectoryEntry(primaryEntry);
                    currentOffset += MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE;

                    // check if in use and process, and skip if not
                    if (fileEntry.IsInUse)
                    {
                        // process Stream Extension Entry
                        secondaryRecord      = ParseFile.ParseSimpleOffset(isoStream, currentOffset, MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE);
                        streamExtensionEntry = new MicrosoftExFatRootDirStreamExtensionEntry(secondaryRecord);
                        objectOffset         = MicrosoftExFatFileSystem.GetOffsetForClusterId(clusterHeapOffset, clusterSize, streamExtensionEntry.FirstCluster);

                        currentOffset += MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE;

                        // process File Name Extention Entry
                        fileName = String.Empty;

                        for (int i = 0; i < (fileEntry.SecondaryCount - 1); i++)
                        {
                            secondaryRecord        = ParseFile.ParseSimpleOffset(isoStream, (currentOffset), MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE);
                            fileNameExtensionEntry = new MicrosoftExFatRootDirFileNameExtensionEntry(secondaryRecord);

                            // build name from chunks
                            fileName += fileNameExtensionEntry.FileNameChunk;

                            // move pointer
                            currentOffset += MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE;
                        }

                        // trim any excess from name
                        fileName = fileName.Substring(0, streamExtensionEntry.NameLength);

                        // create dir or file and add to array list
                        if (fileEntry.IsDirectory)
                        {
                            // get new directory
                            newDirectory = new MicrosoftExFatDirectoryStructure(isoStream, volumeBaseOffset,
                                                                                (long)objectOffset, (long)streamExtensionEntry.DataLength,
                                                                                fileName, parentDirectory, clusterHeapOffset, clusterSize);

                            // add directory to subdirectory array
                            this.SubDirectoryArray.Add(newDirectory);
                        }
                        else     // file
                        {
                            newFile = new MicrosoftExFatFileStructure(parentDirectory, isoStream.Name, fileName, (long)objectOffset,
                                                                      volumeBaseOffset, streamExtensionEntry.FirstCluster, (long)streamExtensionEntry.DataLength, fileDate);

                            this.FileArray.Add(newFile);
                        }
                    }
                    else
                    {
                        currentOffset = (uint)(MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE * fileEntry.SecondaryCount);
                    }

                    break;

                case MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_TYPE_VOLUME_LABEL:
                case MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_TYPE_ALLOCATION_BITMAP:
                case MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_TYPE_UPCASE:
                case MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_TYPE_VOLUME_GUID:
                case MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_TYPE_TEXFAT_PADDING:
                case MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_TYPE_WINDOWS_CE_ACL:
                    currentOffset += MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE;
                    break;

                default:
                    currentOffset += MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE;
                    break;
                } // switch (entryType)
            }
        }