Пример #1
0
        /// <summary>
        /// Allocates a new DirectoryEntry object for the given settings.
        /// </summary>
        /// <param name="parent">The parent directory entry.</param>
        /// <param name="name">The name of the entry to create.</param>
        /// <param name="node">The vfs node referenced by the directory entry.</param>
        /// <returns>The allocated directory entry.</returns>
        /// <exception cref="System.ArgumentNullException">If any one of the parameters is null.</exception>
        /// <exception cref="System.ArgumentException">If the name is zero-length.</exception>
        /// <remarks>
        /// This method is used to control the DirectoryEntry allocation and maintain a cache of them. Also used to
        /// prevent infinite name allocations.
        /// </remarks>
        public static DirectoryEntry Allocate(DirectoryEntry parent, string name, IVfsNode node)
        {
            //#if VFS_NO_EXCEPTIONS
            if (parent == null)
            {
                throw new System.ArgumentNullException(@"parent");
            }

            if (name == null)
            {
                throw new System.ArgumentNullException(@"name");
            }

            if (node == null)
            {
                throw new System.ArgumentNullException(@"node");
            }

            if (name.Length == 0)
            {
                throw new System.ArgumentException(@"Invalid directory entry name.");                 // , @"name"
            }
            // FIXME: Add precondition check for invalid characters
            // FIXME: Localize exception messages
            //#endif // #if VFS_NO_EXCEPTIONS

            DirectoryEntry directory = new DirectoryEntry();

            directory.Setup(parent, name, node);

            return(directory);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="name"></param>
        /// <param name="node"></param>
        private void Setup(DirectoryEntry parent, string name, IVfsNode node)
        {
            if (!System.Object.ReferenceEquals(this, parent))
            {
                parent.InsertChild(this);
            }

            this.parent = parent;
            this.name   = name;
            inode       = node;
        }
Пример #3
0
        /// <summary>
        /// Allocates a vfs root directory entry.
        /// </summary>
        /// <param name="node">The vfs node, which corresponds to the root directory.</param>
        /// <returns>The created directory entry.</returns>
        /// <exception cref="System.ArgumentNullException">The specified node is invalid.</exception>
        /// <remarks>
        /// This method creates a directory entry, which has some special properties. The first one is, that
        /// its parent is itself. This provides for the ability to cd .. on the root to stay on the root.
        /// <para/>
        /// The next ability is to create specialized root directories to isolate processes from the remainder
        /// of the filesystem. Setting a root directory created using this method effectively limits the process
        /// to access inside of the newly created namespace.
        /// </remarks>
        public static DirectoryEntry AllocateRoot(IVfsNode node)
        {
#if VFS_NO_EXCEPTIONS
            if (node == null)
            {
                throw new ArgumentNullException(@"node");
            }
#endif // #if VFS_NO_EXCEPTIONS
            DirectoryEntry result = new DirectoryEntry();
            result.Setup(result, System.String.Empty, node);
            return(result);
        }
Пример #4
0
		public override void Delete (IVfsNode child, DirectoryEntry dentry)
		{
			FAT fs = this.FileSystem as FAT;

			uint childBlock = (child as VfsDirectory).directoryCluster;

			FAT.DirectoryEntryLocation location = fs.FindEntry (new FAT.FatMatchClusterComparer (childBlock), this.directoryCluster);

			if (!location.Valid)
				throw new System.ArgumentException (); //throw new IOException ("Unable to delete directory because it is not empty");

			fs.Delete (childBlock, directoryCluster, location.DirectoryIndex);
		}
Пример #5
0
        /// <summary>
        /// Called to delete a child from a directory.
        /// </summary>
        /// <param name="child">The IVfsNode interface of the child.</param>
        /// <param name="dentry">The DirectoryEntry of the child.</param>
        /// <remarks>
        /// This function deletes a child IVfsNode from a directory. If child is a directory, it will be empty
        /// before this call is executed. It is recommended to include a debug sanity check though. If the file
        /// system needs to know the name of the child to delete, it can retrieve it from <see cref="DirectoryEntry.Name"/>.
        /// </remarks>
        /// <exception cref="System.NotSupportedException">The object does not support removal this way. There's most likely an object specific API to remove this IVfsNode.</exception>
        public override void Delete(IVfsNode child, DirectoryEntry dentry)
        {
            var fs = FileSystem as FatFileSystem;

            uint targetCluster = (child as VfsDirectory).directoryCluster;

            var location = fs.FindEntry(new Find.ByCluster(targetCluster), directoryCluster);

            if (!location.IsValid)
                throw new System.ArgumentException(); //throw new IOException ("Unable to delete directory because it is not empty");

            fs.Delete(targetCluster, location.DirectorySector, location.DirectorySectorIndex);
        }
Пример #6
0
        /// <summary>
        /// Releases the DirectoryEntry from the parent DirectoryEntry. This is *not* a delete operation.
        /// </summary>
        /// <remarks>
        /// This function is used to remove a DirectoryEntry from the cache. Some (networked) file systems may want to use
        /// this function to remove "known" directories from the lookup cache when they loose server connection.
        /// </remarks>
        public void Release()
        {
            // FIXME: Remove the entry from the parent and release it to the
            // entry cache in the vfs service.
            if (!System.Object.ReferenceEquals(this, Parent))
            {
                parent.RemoveChild(this);
            }

            inode  = null;
            name   = null;
            parent = null;
        }
Пример #7
0
        /// <summary>
        /// Called to delete a child from a directory.
        /// </summary>
        /// <param name="child">The IVfsNode interface of the child.</param>
        /// <param name="dentry">The DirectoryEntry of the child.</param>
        /// <remarks>
        /// This function deletes a child IVfsNode from a directory. If child is a directory, it will be empty
        /// before this call is executed. It is recommended to include a debug sanity check though. If the file
        /// system needs to know the name of the child to delete, it can retrieve it from <see cref="DirectoryEntry.Name"/>.
        /// </remarks>
        /// <exception cref="System.NotSupportedException">The object does not support removal this way. There's most likely an object specific API to remove this IVfsNode.</exception>
        public override void Delete(IVfsNode child, DirectoryEntry dentry)
        {
            FatFileSystem fs = this.FileSystem as FatFileSystem;

            uint targetCluster = (child as VfsDirectory).directoryCluster;

            FatFileLocation location = fs.FindEntry(new Find.ByCluster(targetCluster), this.directoryCluster);

            if (!location.Valid)
            {
                throw new System.ArgumentException();                 //throw new IOException ("Unable to delete directory because it is not empty");
            }
            fs.Delete(targetCluster, location.DirectorySector, location.DirectorySectorIndex);
        }
Пример #8
0
        public override void Delete(IVfsNode child, DirectoryEntry dentry)
        {
            FAT fs = this.FileSystem as FAT;

            uint childBlock = (child as VfsDirectory).directoryCluster;

            FAT.DirectoryEntryLocation location = fs.FindEntry(new FAT.FatMatchClusterComparer(childBlock), this.directoryCluster);

            if (!location.Valid)
            {
                throw new System.ArgumentException();                  //throw new IOException ("Unable to delete directory because it is not empty");
            }
            fs.Delete(childBlock, directoryCluster, location.DirectoryIndex);
        }
Пример #9
0
        /// <summary>
        /// Creates a new node in the (virtual) filesystem.
        /// </summary>
        /// <param name="path">The path to create.</param>
        /// <param name="type">The type of the node to create.</param>
        /// <param name="settings">Settings used to initialize the node.</param>
        /// <param name="access">Requests the specified access modes on the created object.</param>
        /// <param name="share">Requests the specified sharing settings on the object.</param>
        /// <returns>The created filesystem object.</returns>
        /// <remarks>
        /// This function creates new nodes in the virtual filesystem. In contrast to *nix this call
        /// creates all node types, e.g. files, directories, devices and more. Specific types may
        /// require additional settings, which are specified in a settings object passed as the third
        /// parameter.
        /// </remarks>
        public static object Create(string path, VfsNodeType type, object settings, FileAccess access, FileShare share)
        {
            // Retrieve the parent directory
            DirectoryEntry parent = PathResolver.Resolve(rootNode, ref path, PathResolutionFlags.RetrieveParent);

            // Check if the caller has write access in the directory
            AccessCheck.Perform(parent, AccessMode.Write, AccessCheckFlags.None);

            // Yes, we do have write access. Create the new vfs node
            IVfsNode node = parent.Node.Create(path, type, settings);
            // FIXME: Assert(null != node);
            DirectoryEntry entry = DirectoryEntry.Allocate(parent, path, node);

            // FIXME: Fix the permissions for this call. *nix does this using its bitmasks, Win32 through its huge CreateFile API.
            return(node.Open(access, share));
        }
Пример #10
0
 /// <summary>
 /// Called to delete a child from a directory.
 /// </summary>
 /// <param name="child">The IVfsNode interface of the child.</param>
 /// <param name="dentry">The DirectoryEntry of the child.</param>
 /// <remarks>
 /// This function deletes a child IVfsNode from a directory. If child is a directory, it will be empty
 /// before this call is executed. It is recommended to include a debug sanity check though. If the file
 /// system needs to know the name of the child to delete, it can retrieve it from <see cref="DirectoryEntry.Name"/>.
 /// </remarks>
 /// <exception cref="System.NotSupportedException">The object does not support removal this way. There's most likely an object specific API to remove this IVfsNode.</exception>
 public override void Delete(IVfsNode child, DirectoryEntry dentry)
 {
     // FIXME: throw new NotImplementedException();
 }
Пример #11
0
 /// <summary>
 /// Called to delete a child from a directory.
 /// </summary>
 /// <param name="child">The IVfsNode interface of the child.</param>
 /// <param name="dentry">The DirectoryEntry of the child.</param>
 /// <remarks>
 /// This function deletes a child IVfsNode from a directory. If child is a directory, it will be empty
 /// before this call is executed. It is recommended to include a debug sanity check though. If the file
 /// system needs to know the name of the child to delete, it can retrieve it from <see cref="DirectoryEntry.Name"/>.
 /// </remarks>
 /// <exception cref="System.NotSupportedException">The object does not support removal this way. There's most likely an object specific API to remove this IVfsNode.</exception>
 public override void Delete(IVfsNode child, DirectoryEntry dentry)
 {
     // FIXME: throw new NotImplementedException();
 }
Пример #12
0
 /// <summary>
 /// Deletes the specified child.
 /// </summary>
 /// <param name="child">The child.</param>
 /// <param name="entry">The entry.</param>
 public abstract void Delete(IVfsNode child, DirectoryEntry entry);
Пример #13
0
 /// <summary>
 /// Called to delete a child from a directory.
 /// </summary>
 /// <param name="child">The IVfsNode interface of the child.</param>
 /// <param name="dentry">The DirectoryEntry of the child.</param>
 /// <remarks>
 /// This function deletes a child IVfsNode from a directory. If child is a directory, it will be empty
 /// before this call is executed. It is recommended to include a debug sanity check though. If the file
 /// system needs to know the name of the child to delete, it can retrieve it from <see cref="DirectoryEntry.Name"/>.
 /// </remarks>
 /// <exception cref="System.NotSupportedException">The object does not support removal this way. There's most likely an object specific API to remove this IVfsNode.</exception>
 public override void Delete(IVfsNode child, DirectoryEntry dentry)
 {
     throw new System.ArgumentException(); // Delete() method doesn't make sense here
 }
Пример #14
0
 /// <summary>
 /// Allocates a vfs root directory entry.
 /// </summary>
 /// <param name="node">The vfs node, which corresponds to the root directory.</param>
 /// <returns>The created directory entry.</returns>
 /// <exception cref="System.ArgumentNullException">The specified node is invalid.</exception>
 /// <remarks>
 /// This method creates a directory entry, which has some special properties. The first one is, that
 /// its parent is itself. This provides for the ability to cd .. on the root to stay on the root.
 /// <para/>
 /// The next ability is to create specialized root directories to isolate processes from the remainder
 /// of the filesystem. Setting a root directory created using this method effectively limits the process
 /// to access inside of the newly created namespace.
 /// </remarks>
 public static DirectoryEntry AllocateRoot(IVfsNode node)
 {
     #if VFS_NO_EXCEPTIONS
     if (node == null)
         throw new ArgumentNullException(@"node");
     #endif // #if VFS_NO_EXCEPTIONS
     DirectoryEntry result = new DirectoryEntry();
     result.Setup(result, System.String.Empty, node);
     return result;
 }
Пример #15
0
        /// <summary>
        /// Allocates a new DirectoryEntry object for the given settings.
        /// </summary>
        /// <param name="parent">The parent directory entry.</param>
        /// <param name="name">The name of the entry to create.</param>
        /// <param name="node">The vfs node referenced by the directory entry.</param>
        /// <returns>The allocated directory entry.</returns>
        /// <exception cref="System.ArgumentNullException">If any one of the parameters is null.</exception>
        /// <exception cref="System.ArgumentException">If the name is zero-length.</exception>
        /// <remarks>
        /// This method is used to control the DirectoryEntry allocation and maintain a cache of them. Also used to
        /// prevent infinite name allocations.
        /// </remarks>
        public static DirectoryEntry Allocate(DirectoryEntry parent, string name, IVfsNode node)
        {
            //#if VFS_NO_EXCEPTIONS
            if (parent == null)
                throw new System.ArgumentNullException(@"parent");

            if (name == null)
                throw new System.ArgumentNullException(@"name");

            if (node == null)
                throw new System.ArgumentNullException(@"node");

            if (name.Length == 0)
                throw new System.ArgumentException(@"Invalid directory entry name."); // , @"name"
            // FIXME: Add precondition check for invalid characters
            // FIXME: Localize exception messages
            //#endif // #if VFS_NO_EXCEPTIONS

            DirectoryEntry directory = new DirectoryEntry();

            directory.Setup(parent, name, node);

            return directory;
        }
Пример #16
0
 /// <summary>
 /// Deletes the specified child.
 /// </summary>
 /// <param name="child">The child.</param>
 /// <param name="entry">The entry.</param>
 public abstract void Delete(IVfsNode child, DirectoryEntry entry);
Пример #17
0
		public override void Delete(IVfsNode child, DirectoryEntry dentry)
		{
			// FIXME: Delete the symbolic link from the filesystem, after all names have been dropped.
            throw new NotSupportedException();
		}
Пример #18
0
        /// <summary>
        /// Releases the DirectoryEntry from the parent DirectoryEntry. This is *not* a delete operation.
        /// </summary>
        /// <remarks>
        /// This function is used to remove a DirectoryEntry from the cache. Some (networked) file systems may want to use
        /// this function to remove "known" directories from the lookup cache when they loose server connection.
        /// </remarks>
        public void Release()
        {
            // FIXME: Remove the entry from the parent and release it to the
            // entry cache in the vfs service.
            if (!System.Object.ReferenceEquals(this, Parent))
                parent.RemoveChild(this);

            inode = null;
            name = null;
            parent = null;
        }
Пример #19
0
 /// <summary>
 /// Called to delete a child from a directory.
 /// </summary>
 /// <param name="child">The IVfsNode interface of the child.</param>
 /// <param name="dentry">The DirectoryEntry of the child.</param>
 /// <remarks>
 /// This function deletes a child IVfsNode from a directory. If child is a directory, it will be empty
 /// before this call is executed. It is recommended to include a debug sanity check though. If the file
 /// system needs to know the name of the child to delete, it can retrieve it from <see cref="DirectoryEntry.Name"/>.
 /// </remarks>
 /// <exception cref="System.NotSupportedException">The object does not support removal this way. There's most likely an object specific API to remove this IVfsNode.</exception>
 public override void Delete(IVfsNode child, DirectoryEntry dentry)
 {
     throw new System.ArgumentException();             // Delete() method doesn't make sense here
 }
Пример #20
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="name"></param>
        /// <param name="node"></param>
        private void Setup(DirectoryEntry parent, string name, IVfsNode node)
        {
            if (!System.Object.ReferenceEquals(this, parent))
                parent.InsertChild(this);

            this.parent = parent;
            this.name = name;
            inode = node;
        }
Пример #21
0
        /// <summary>
        /// Performs an iterative lookup of the given path starting from the root and obeying to the specified flags.
        /// </summary>
        /// <param name="path">The path to lookup. This can be a relative or absolute path. Path.DirectorySeparatorChar or Path.AltDirectorySeparatorChar are valid delimiters.</param>
        /// <param name="root">The root directory to start lookup from.</param>
        /// <param name="flags">The lookup flags, which control the lookup process.</param>
        /// <returns>The directory entry of the resolved path.</returns>
        /// <exception cref="System.Security.SecurityException">The caller does not have access to the path or a component. For example the caller does not have the right to traverse the path.</exception>
        /// <exception cref="System.IO.PathTooLongException">The path is too long to traverse. This can be the result of circular symbolic links in the path.</exception>
        /// <exception cref="System.IO.FileNotFoundException">The path or a component was not found. This exception can be prevented by specifying PathResolutionFlags.DoNotThrowNotFoundException.</exception>
        /// <exception cref="System.IO.DirectoryNotFoundException">A path component was not found. This exception can be prevented by specifying PathResolutionFlags.DoNotThrowNotFoundException.</exception>
        /// <remarks>
        /// This call may result in other exceptions not specified in the above list. Other exceptions can be thrown by IVfsNode implementations, which are visited during the traversal
        /// process. For example a network file system node may throw an exception, if the server is unreachable.
        /// </remarks>
        private DirectoryEntry Resolve(ref string path, PathResolutionFlags flags)
        {
            // DirectoryNode entry found by stepping through the path
            DirectoryEntry entry = null;

            // Split the given path to its components
            PathSplitter dirs = new PathSplitter(path);

            // Determine the number of path components
            int max = dirs.Length;

            // Current path component
            string item;
            // Loop index
            int index = 0;

            // Perform an access check on the root directory
            AccessCheck.Perform(currentDirectory, AccessMode.Traverse, AccessCheckFlags.None);

            // Do not resolve the last name, if we want the parent directory.
            if (PathResolutionFlags.RetrieveParent == (flags & PathResolutionFlags.RetrieveParent))
            {
                path = dirs[dirs.Length - 1];
                max--;
            }

            // Check if this is an absolute path?
            if (dirs[0].Length == 0)
            {
                // Yes, replace the current directory
                currentDirectory = rootDirectory;
                index++;
            }

            // Iterate over the remaining path components
            while ((currentDirectory != null) && (index < max))
            {
                item  = dirs[index];
                entry = null;
                if (currentDirectory.Node.NodeType == VfsNodeType.SymbolicLink)
                {
                    SymbolicLinkNode link = (SymbolicLinkNode)currentDirectory.Node;
                    if (0 != depth--)
                    {
                        // The symlink stores a relative path, use it for a current relative lookup.
                        string target = link.Target;

                        // Build a new flags set for symlink lookups, as we do not want all of them.
                        PathResolutionFlags symflags = (flags & PathResolutionFlags.SymLinkLookupSafe);
                        entry = Resolve(ref target, symflags);
                    }
                    else
                    {
                        if (PathResolutionFlags.DoNotThrowNotFoundException != (PathResolutionFlags.DoNotThrowNotFoundException & flags))
                        {
                            // FIXME: Provide a MUI resource string for the exception
#if VFS_EXCEPTIONS
                            throw new PathTooLongException();
#endif // #if !VFS_EXCEPTIONS
                        }
                    }
                }
                else
                {
                    // Pass the lookup to the DirectoryEntry (and ultimately to the inode itself.)
                    entry = currentDirectory.Lookup(item);

                    // If lookup in the directory entry failed, ask the real INode to perform the lookup.
                    if (entry == null)
                    {
                        IVfsNode node = currentDirectory.Node.Lookup(item);
                        if (node != null)
                        {
                            entry = DirectoryEntry.Allocate(currentDirectory, item, node);
                        }
                    }
                }

                // Increment the path component index
                index++;

                // Check if we have a new path component?
                if ((entry == null) && (PathResolutionFlags.DoNotThrowNotFoundException != (PathResolutionFlags.DoNotThrowNotFoundException & flags)))
                {
                    // FIXME: Move exception messages to MUI resources
#if VFS_EXCEPTIONS
                    if (index == max)
                    {
                        throw new FileNotFoundException(@"Failed to resolve the path.", path);
                    }
                    else
                    {
                        throw new DirectoryNotFoundException(@"Failed to resolve the path.");
                    }
#endif // #if VFS_EXCEPTIONS
                }

                // Set the current resolution directory
                currentDirectory = entry;

                // Check if the caller has traverse access to the directory
                AccessCheck.Perform(currentDirectory, AccessMode.Traverse, AccessCheckFlags.None);
            }

            return(currentDirectory);
        }
Пример #22
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="child"></param>
 /// <param name="dentry"></param>
 public override void Delete(IVfsNode child, DirectoryEntry dentry)
 {
     // FIXME: Delete the symbolic link from the filesystem, after all names have been dropped.
     throw new System.NotSupportedException();
 }