Пример #1
0
        private void LoadDirectories(FileStream isoStream)
        {
            MicrosoftExFatDirectoryStructure rootDirectory;

            byte[] primaryEntry = new byte[MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE];

            byte  entryType     = 0xFF;
            long  currentOffset = (long)this.RootDirectoryAbsoluteOffset;
            ulong maxDirectoryLength;

            bool rootDirectoryProcessed = false;

            // @TODO: Updated to use max data size and to jump clusters if needed.
            do
            {
                // 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:
                    // calculate max size for root directory entries
                    maxDirectoryLength = this.GetMaxDataSizeForFirstCluster(this.RootDirectoryFirstCluster);

                    // build root directory
                    rootDirectory = new MicrosoftExFatDirectoryStructure(isoStream, this.VolumeBaseOffset, (long)this.RootDirectoryAbsoluteOffset, (long)maxDirectoryLength,
                                                                         String.Empty, String.Empty, this.ClusterHeapAbsoluteOffset, this.ClusterSizeInBytes);

                    // add root directory
                    this.DirectoryStructureArray.Add(rootDirectory);

                    // skip the root directory entries, primaryEntry[1] is the FileDirectoryEntry.SecondaryCount value
                    currentOffset += MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE +
                                     (uint)(MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_SIZE * primaryEntry[1]);

                    // set flag to indicate directory was processed
                    rootDirectoryProcessed = true;
                    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)
            }while ((!rootDirectoryProcessed) && (entryType != MicrosoftExFatFileSystem.ROOT_DIR_ENTRY_EMPTY)); // @todo: add max size?
        }
Пример #2
0
        public int CompareTo(object obj)
        {
            if (obj is MicrosoftExFatDirectoryStructure)
            {
                MicrosoftExFatDirectoryStructure o = (MicrosoftExFatDirectoryStructure)obj;

                return(this.DirectoryName.CompareTo(o.DirectoryName));
            }

            throw new ArgumentException("object is not an MicrosoftExFatDirectoryStructure");
        }
Пример #3
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)
            }
        }