Beispiel #1
0
        private DfsDirectoryEntry FindDirectory(DfsDirectoryEntry baseDir, string name, uint flags)
        {
            if (baseDir.FilePointer == 0)
            {
                return(null);
            }

            DfsDirectoryEntry currentDir = new DfsDirectoryEntry(FindSector(baseDir.FilePointer));

            do
            {
                // check flags and path
                if (((currentDir.Flags & DfsDirectoryEntry.FLAG_MASK) == flags) && (currentDir.Path.Equals(name)))
                {
                    return(currentDir);
                }

                // no next enty? -> done
                if (currentDir.NextEntry == 0)
                {
                    break;
                }
                currentDir = new DfsDirectoryEntry(FindSector(currentDir.NextEntry));
            } while (true);

            // not found
            return(null);
        }
Beispiel #2
0
        private void WalkDirectory(DfsDirectoryEntry dir, List <DfsSector> sectors)
        {
            do
            {
                var sector = FindSector(dir.Offset);
                sectors.Remove(sector);
                if (dir.FilePointer != 0)
                {
                    sector = FindSector(dir.FilePointer);
                    var entry = new DfsDirectoryEntry(sector);

                    if ((entry.Flags & DfsDirectoryEntry.FLAG_DIR) != 0)
                    {
                        WalkDirectory(entry, sectors);
                    }
                    else
                    //if ((entry.Flags & DfsDirectoryEntry.FLAG_FILE) != 0)
                    {
                        sectors.Remove(sector);
                        WalkFile(entry, sectors);
                    }
                }

                if (dir.NextEntry == 0)
                {
                    break;
                }
                dir = new DfsDirectoryEntry(FindSector(dir.NextEntry));
            } while (true);
        }
Beispiel #3
0
        public DfsFileStream(DragonFs fs, DfsDirectoryEntry root, FileAccess access)
        {
            _Fs   = fs;
            _Root = root;
            if (root.FilePointer != 0)
            {
                if ((access == FileAccess.Write) || (access == FileAccess.ReadWrite))
                {
                    throw new NotSupportedException("Writing an existing file is not supported");
                }

                // Create MemoryStream from existing data
                _MemStream = new MemoryStream((int)(_Root.Flags & ~DfsDirectoryEntry.FLAG_MASK));

                int  remainingBytes = (int)Length;
                uint offset         = root.FilePointer;
                while (remainingBytes > 0)
                {
                    // Fetch a sector and write to the stream
                    DfsSector sector      = _Fs.FindSector(offset);
                    int       sectorBytes = (int)DfsSector.SECTOR_SIZE;
                    if (sectorBytes >= remainingBytes)
                    {
                        sectorBytes = remainingBytes;
                    }
                    _MemStream.Write(sector.Buffer, 0, sectorBytes);

                    remainingBytes -= sectorBytes;
                    offset         += DfsSector.SECTOR_SIZE;
                }
                _MemStream.Seek(0, SeekOrigin.Begin);
            }
            else
            {
                if (access == FileAccess.Read)
                {
                    throw new NotSupportedException("Cannot read file without content");
                }

                // Create MemoryStream for all file operations
                _MemStream = new MemoryStream();
            }

            switch (access)
            {
            case FileAccess.Read:
                _CanRead = true;
                break;

            case FileAccess.ReadWrite:
                _CanRead  = true;
                _CanWrite = true;
                break;

            case FileAccess.Write:
                _CanWrite = true;
                break;
            }
        }
Beispiel #4
0
 void AppendDirectoryEntry(DfsDirectoryEntry directoryEntry, uint offset)
 {
     while (directoryEntry.NextEntry != 0)
     {
         directoryEntry = new DfsDirectoryEntry(FindSector(directoryEntry.NextEntry));
     }
     directoryEntry.NextEntry = offset;
 }
Beispiel #5
0
        private DfsDirectoryEntry CreateFileEntry(string path)
        {
            DfsDirectoryEntry currentDir;

            if (path[0] == '/')
            {
                currentDir = _RootDirectory;
            }
            else
            {
                currentDir = _CurrentDirectory;
            }

            string[] dirs = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0; i < dirs.Length; i++)
            {
                string            searchDir = dirs[i];
                DfsDirectoryEntry foundDir;
                if (i == dirs.Length - 1)
                {
                    foundDir = FindDirectory(currentDir, searchDir, DfsDirectoryEntry.FLAG_FILE);
                }
                else
                {
                    foundDir = FindDirectory(currentDir, searchDir, DfsDirectoryEntry.FLAG_DIR);
                }
                if (foundDir == null)
                {
                    // Create the new Directory and put it at the end
                    foundDir = NewDirectoryEntry();
                    if (i == dirs.Length - 1)
                    {
                        foundDir.Flags = DfsDirectoryEntry.FLAG_FILE;
                    }
                    else
                    {
                        foundDir.Flags = DfsDirectoryEntry.FLAG_DIR;
                    }
                    foundDir.Path = searchDir;
                    if (currentDir.FilePointer == 0)
                    {
                        currentDir.FilePointer = foundDir.Offset;
                    }
                    else
                    {
                        currentDir = new DfsDirectoryEntry(FindSector(currentDir.FilePointer));
                        AppendDirectoryEntry(currentDir, foundDir.Offset);
                    }
                }
                currentDir = foundDir;
            }
            return(currentDir);
        }
Beispiel #6
0
        private void WalkFile(DfsDirectoryEntry fileEntry, List <DfsSector> sectors)
        {
            int  fileSize = (int)(fileEntry.Flags & ~DfsDirectoryEntry.FLAG_MASK);
            uint offset   = 0;

            do
            {
                var sector = FindSector(fileEntry.FilePointer + offset);
                sectors.Remove(sector);
                offset += DfsSector.SECTOR_SIZE;
            } while (offset < fileSize);
        }
Beispiel #7
0
        public DragonFs()
        {
            DfsDirectoryEntry fsRoot = new DfsDirectoryEntry(NewSector())
            {
                Flags     = ROOT_FLAGS,
                NextEntry = ROOT_NEXTENTRY,
                Path      = ROOT_PATH
            };

            // build a dummy root with a valid file pointer
            // the real first sectors file pointer is always 0
            // but this one can be modified
            _RootDirectory       = new DfsDirectoryEntry(new DfsSector(0));
            _RootDirectory.Flags = DfsDirectoryEntry.FLAG_DIR;
            _CurrentDirectory    = _RootDirectory;
        }
Beispiel #8
0
        public DfsFileStream OpenFile(string path, FileAccess access)
        {
            DfsDirectoryEntry directoryEntry = FindDirectory(path, DfsDirectoryEntry.FLAG_FILE);

            if (directoryEntry == null)
            {
                if (access == FileAccess.Read)
                {
                    throw new FileNotFoundException();
                }
                else
                {
                    directoryEntry = CreateFileEntry(path);
                }
            }
            return(new DfsFileStream(this, directoryEntry, access));
        }
Beispiel #9
0
        public static DragonFs CreateFromStream(Stream source)
        {
            DragonFs  newFs  = new DragonFs();
            DfsSector sector = new DfsSector(0);

            source.Read(sector.Buffer, 0, (int)DfsSector.SECTOR_SIZE);
            DfsDirectoryEntry root = new DfsDirectoryEntry(sector);
            bool checkValid        = true;

            if ((root.Flags != ROOT_FLAGS) || (root.NextEntry != ROOT_NEXTENTRY))
            {
                checkValid = false;
            }
            else
            {
                // Check DFS version string
                if (!root.Path.Equals(DragonFs.ROOT_PATH))
                {
                    checkValid = false;
                }
            }

            if (checkValid == false)
            {
                throw new ArgumentException("source", "The stream does not contain a valid DFS 2.0 image");
            }

            while (source.Position != source.Length)
            {
                sector = newFs.NewSector();
                source.Read(sector.Buffer, 0, (int)DfsSector.SECTOR_SIZE);
            }

            // The virtual root directory entry needs to point to the first sector
            // TODO: Can this be done better?
            newFs._RootDirectory.FilePointer = DfsSector.SECTOR_SIZE;

            return(newFs);
        }
Beispiel #10
0
        public void CreateDirectory(string path)
        {
            DfsDirectoryEntry currentDir;

            if (path[0] == '/')
            {
                currentDir = _RootDirectory;
            }
            else
            {
                currentDir = _CurrentDirectory;
            }

            string[] dirs = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string searchDir in dirs)
            {
                DfsDirectoryEntry foundDir = FindDirectory(currentDir, searchDir, DfsDirectoryEntry.FLAG_DIR);
                if (foundDir == null)
                {
                    // Create the new Directory and put it at the end
                    foundDir       = NewDirectoryEntry();
                    foundDir.Flags = DfsDirectoryEntry.FLAG_DIR;
                    foundDir.Path  = searchDir;
                    if (currentDir.FilePointer == 0)
                    {
                        currentDir.FilePointer = foundDir.Offset;
                    }
                    else
                    {
                        currentDir = new DfsDirectoryEntry(FindSector(currentDir.FilePointer));
                        AppendDirectoryEntry(currentDir, foundDir.Offset);
                    }
                }
                currentDir = foundDir;
            }
        }