/// <summary> /// Performs a path lookup obeying to the passed flags. /// </summary> /// <param name="rootDirectory">The root directory.</param> /// <param name="path">The path to resolve.</param> /// <param name="flags">Controls aspects of the path 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 file or folder path 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 my 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> public static DirectoryEntry Resolve(DirectoryEntry rootDirectory, ref string path, PathResolutionFlags flags) { // FIXME: Get the root from the thread execution block DirectoryEntry current = rootDirectory; PathResolver resolver = new PathResolver(rootDirectory, current); return(resolver.Resolve(ref path, flags)); }
/// <summary> /// Performs a standard path lookup. /// </summary> /// <param name="rootDirectory">The root directory.</param> /// <param name="path">The path to resolve.</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 file or folder path not found.</exception> /// <exception cref="System.IO.DirectoryNotFoundException">A path component was not found.</exception> /// <remarks> /// This call my 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> public static DirectoryEntry Resolve(DirectoryEntry rootDirectory, ref string path) { // FIXME: Remove the root argument. The filesystem root should be unique for a process as part of a security model similar to jails, e.g. give apps from // untrusted sources their private filesystem regions. // FIXME: Get the root from the thread execution block DirectoryEntry current = rootDirectory; PathResolver resolver = new PathResolver(rootDirectory, current); return(resolver.Resolve(ref path, PathResolutionFlags.None)); }
/// <summary> /// Checks if the caller has access to the inode /// </summary> /// <param name="path">The resource to check permissions for.</param> /// <returns>True if the requested access mode combination is available to the immediate caller. If any one requested access mode is not available, the result is false.</returns> public static bool Access(string path, AccessMode mode) { DirectoryEntry entry = PathResolver.Resolve(rootNode, ref path, PathResolutionFlags.DoNotThrowNotFoundException); if (null != entry) { return(AccessCheck.Perform(entry, mode, AccessCheckFlags.NoThrow)); } return(false); }
/// <summary> /// Deletes the named node from the filesystem. /// </summary> /// <param name="path">The path, which identifies a node.</param> public static void Delete(string path) { DirectoryEntry entry = PathResolver.Resolve(rootNode, ref path, PathResolutionFlags.DoNotThrowNotFoundException); if (null != entry) { AccessCheck.Perform(entry, AccessMode.Delete, AccessCheckFlags.None); //entry.Node.Delete(); entry.Parent.Node.Delete(entry.Node, entry); entry.Release(); } }
public static object Open(string path, FileAccess access, FileShare share) { DirectoryEntry entry = PathResolver.Resolve(rootNode, ref path); /* HINT: * * 1. Do we really need to pass the FileShare flags down to the inode? * 2. Shouldn't we have some sort of lock deamon governing shared access? * * Ansers: * 1. Yes. * 2. Yes and no. A lock deamon would only work for local filesystems. For imported * ones we need to notify the server of the sharing lock anyway, so that the IVfsNode * (acting as a client to the server) is the best place to do it without giving the * lock deamon knowledge of all file sharing protocols (afp, smb, ftp, name it.) * 3. The inode may reject the file sharing requests. We do want to represent devices * and sync objects in the VFS, which means *they* need to decide if the flags are * applicable. * */ // FIXME: Perform access checks on the DirectoryEntry/IVfsNode. AccessMode modeFlags = AccessMode.Exists; switch (access) { case FileAccess.Read: modeFlags = AccessMode.Read; break; case FileAccess.Write: modeFlags = AccessMode.Write; break; case FileAccess.ReadWrite: modeFlags = AccessMode.Read | AccessMode.Write; break; } AccessCheck.Perform(entry, modeFlags, AccessCheckFlags.None); if (entry == null) { SharpOS.Kernel.ADC.TextMode.WriteLine("VirtualFileSystem.Open.4a"); } if (entry.Node == null) { SharpOS.Kernel.ADC.TextMode.WriteLine("VirtualFileSystem.Open.4b"); } return(entry.Node.Open(access, share)); }
/// <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)); }
/// <summary> /// Mounts a new file system. /// </summary> /// <param name="source">The source of the filesystem. This is usually a device name, but can also be another directory.</param> /// <param name="target">The path including the name of the mount point, where to mount the new filesystem.</param> public static void Mount(string source, string target) { // Retrieve the parent directory of the mount DirectoryEntry parent = PathResolver.Resolve(rootNode, ref target, PathResolutionFlags.RetrieveParent); if (parent == null) { throw new System.ArgumentException(); } IFileSystem root = FileSystemFactory.CreateFileSystem(source); if (root == null) { throw new System.ArgumentException(); } PathSplitter path = new PathSplitter(target); DirectoryEntry.Allocate(parent, path.Last, root.Root); }
/// <summary> /// Performs a standard path lookup. /// </summary> /// <param name="rootDirectory">The root directory.</param> /// <param name="path">The path to resolve.</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 file or folder path not found.</exception> /// <exception cref="System.IO.DirectoryNotFoundException">A path component was not found.</exception> /// <remarks> /// This call my 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> public static DirectoryEntry Resolve (DirectoryEntry rootDirectory, ref string path) { // FIXME: Remove the root argument. The filesystem root should be unique for a process as part of a security model similar to jails, e.g. give apps from // untrusted sources their private filesystem regions. // FIXME: Get the root from the thread execution block DirectoryEntry current = rootDirectory; PathResolver resolver = new PathResolver (rootDirectory, current); return resolver.Resolve (ref path, PathResolutionFlags.None); }
/// <summary> /// Performs a path lookup obeying to the passed flags. /// </summary> /// <param name="rootDirectory">The root directory.</param> /// <param name="path">The path to resolve.</param> /// <param name="flags">Controls aspects of the path 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 file or folder path 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 my 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> public static DirectoryEntry Resolve (DirectoryEntry rootDirectory, ref string path, PathResolutionFlags flags) { // FIXME: Get the root from the thread execution block DirectoryEntry current = rootDirectory; PathResolver resolver = new PathResolver (rootDirectory, current); return resolver.Resolve (ref path, flags); }
/// <summary> /// Changes the current directory in the thread execution block. /// </summary> /// <param name="path">The path to change to. This path may be relative or absolute.</param> /// < public static void ChangeDirectory(string path) { DirectoryEntry entry = PathResolver.Resolve(rootNode, ref path); // FIXME: Set the current directory in the thread execution block }