xrdp/sesman/chansrv/chansrv_xfs.h
matt335672 4d8f2b5a31 Significant remote file system improvements
- Reimplemented inode store in separate module chansrv_xfs.[hc]
- Allowed atimes and mtimes to be written to Windows side
- Mapped file user write bit to (inverted) Windows FILE_ATTRIBUTE_READONLY bit
- Mapped file user execute bit to Windows FILE_ATTRIBUTE_SYSTEM bit
- Implemented improved security for remotely mounted drives
- Implemented USB device removal, allowing hot-plug/remove of memory sticks
- Fixed pagefile.sys breaking Ubuntu file browser
- Fixed write offset bug
- Allowed renaming of open files
- Improved reported error codes
- Fixed various memory leaks
- Addressed valgrind errors related to struct fuse_file_info pointers.
2019-12-05 11:41:32 +00:00

322 lines
9.1 KiB
C

/**
* xrdp: A Remote Desktop Protocol server.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is the interface to the FUSE file system used by
* chansrv
*/
#ifndef _CHANSRV_XFS
#define _CHANSRV_XFS
/* Skip this include if there's no FUSE */
#ifdef XRDP_FUSE
#include <stddef.h>
#include <fuse_lowlevel.h>
#include <time.h>
#include "arch.h"
#define XFS_MAXFILENAMELEN 255
/*
* Incomplete types for the public interface
*/
struct xfs_fs;
struct xfs_dir_handle;
typedef struct xfs_inode
{
fuse_ino_t inum; /* File serial number. */
mode_t mode; /* File mode. */
uid_t uid; /* User ID of the file's owner. */
gid_t gid; /* Group ID of the file's group. */
off_t size; /* Size of file, in bytes. */
time_t atime; /* Time of last access. */
time_t mtime; /* Time of last modification. */
time_t ctime; /* Time of last status change. */
char name[XFS_MAXFILENAMELEN + 1]; /* Short name */
tui32 generation; /* Changes if inode is reused */
tui32 device_id; /* for file system redirection
* Non-redirected devices are guaranteed
* to have a device_id or zero */
int lindex; /* used in clipboard operations */
} XFS_INODE;
/*
* Create a new filesystem instance
*
* @param umask Umask to apply to initial data structures
* @param uid Owner UID for initial root directory
* @param gid Owner GID for initial root directory
* @return Pointer to instance, or NULL if no memory
*/
struct xfs_fs *
xfs_create_xfs_fs(mode_t umask, uid_t uid, gid_t gid);
/*
* Delete a filesystem instance
*
* @param xfs Filesystem instance
*/
void
xfs_delete_xfs_fs(struct xfs_fs *xfs);
/*
* Add an entry to the filesystem
*
* The returned element has default values inherited from the parent
*
* The specified mode is sanitised in that:-
* - Bits other than the lowest nine permissions bits, the directory
* bit (S_IFDIR) and the regular bit (S_IFREG) are cleared.
* - S_IFREG is cleared if S_IFDIR is set
* - S_IFREG is set if neither S_IFDIR or S_IFREG is set
*
* NULL is returned for one of the following conditions:-
* - the parent does not exist
* - the parent is not a directory
* - the name length exceeds XFS_MAXFILENAMELEN
* - the entry already exists
* - memory is exhausted.
*
* @param xfs filesystem instance
* @param parent_inode parent inode
* @param name Name of entry
* @param mode Initial mode for file.
* @return inode, or NULL
*/
XFS_INODE *
xfs_add_entry(struct xfs_fs *xfs, fuse_ino_t parent_inum,
const char *name, mode_t mode);
/*
* Delete the contents of a directory
*
* If normal files are opened when they are deleted, the inode is not
* released until the open count goes to zero.
*
* @param xfs filesystem instance
* @param inode Reference to entry to delete
*
*/
void
xfs_remove_directory_contents(struct xfs_fs *xfs, fuse_ino_t inum);
/*
* Delete an entry from the filesystem
*
* If normal files are opened when they are deleted, the inode is not
* released until the open count goes to zero.
*
* For directories, the contents are removed first.
*
* @param xfs filesystem instance
* @param inode Reference to entry to delete
*
*/
void
xfs_remove_entry(struct xfs_fs *xfs, fuse_ino_t inum);
/*
* Get an XFS_INODE for an inum
*
* @param xfs filesystem instance
* @param inum Inumber
* @return Pointer to XFS_INODE
*/
XFS_INODE *
xfs_get(struct xfs_fs *xfs, fuse_ino_t inum);
/*
* Get the full path for an inum
*
* The path is dynamically allocated, and must be freed after use
*
* @param xfs filesystem instance
* @param inum Inumber to get path for
* @return Full path (free after use)
*/
char *
xfs_get_full_path(struct xfs_fs *xfs, fuse_ino_t inum);
/*
* Lookup a file in a directory
*
* @param xfs filesystem instance
* @param inum Inumber of the directory
* @param name Name of the file to lookup
* @return Pointer to XFS_INODE if found
*/
XFS_INODE *
xfs_lookup_in_dir(struct xfs_fs *xfs, fuse_ino_t inum, const char *name);
/*
* Inquires as to whether a directory is empty.
*
* The caller must check that the inum is actually a directory, or
* the result is undefined.
*
* @param xfs filesystem instance
* @param inum Inumber of the directory
* @return True if the directory is empty
*/
int
xfs_is_dir_empty(struct xfs_fs *xfs, fuse_ino_t inum);
/*
* Inquires as to whether an entry is under a directory.
*
* This can be used to check for invalid renames, where we try to
* rename a directory into one of its sub-directories.
*
* Returned value means one of the following:-
* 0 Entry is not related to the directory
* 1 Entry is an immediate member of the directory
* 2.. Entry is a few levels below the directory
*
* @param xfs filesystem instance
* @param dir Inumber of the directory
* @param entry Inumber of the entry
* @return Nesting count of entry in the directory, or 0 for
* no nesting
*/
unsigned int
xfs_is_under(struct xfs_fs *xfs, fuse_ino_t dir, fuse_ino_t entry);
/*
* Opens a directory for reading
*
* @param xfs filesystem instance
* @param dir Inumber of the directory
* @return handle to be passed to xfs_readdir() and xfs_closedir()
*/
struct xfs_dir_handle *
xfs_opendir(struct xfs_fs *xfs, fuse_ino_t dir);
/*
* Gets the next entry from a directory
*
* This function is safe to call while the filesystem is being modified.
* Whether files added or removed from the directory in question are
* returned or not is unspecified by this interface.
*
* @param xfs filesystem instance
* @param handle Handle from xfs_opendir
* @param off Offset (by reference). Pass in zero to get the first
* entry. After the call, the offset is updated so that
* the next call gets the next entry.
*
* @return pointer to details of file entry, or NULL if no more
* entries are available.
*/
XFS_INODE *
xfs_readdir(struct xfs_fs *xfs, struct xfs_dir_handle *handle, off_t *off);
/*
* Closes a directory opened for reading
*
* @param xfs filesystem instance
* @param handle Earlier result of readdir() call
*/
void
xfs_closedir(struct xfs_fs *xfs, struct xfs_dir_handle *handle);
/*
* Increment the file open count
*
* The file open count is used to be sure when an entry can be deleted from
* the data structures. It allows us to remove an entry while still retaining
* enough state to manage the file
*
* This call is only necessary for regular files - not directories
*
* @param xfs filesystem instance
* @param inum File to increment the count of
*/
void
xfs_increment_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum);
/*
* Decrement the file open count
*
* This call will ensure that deleted inodes are cleared up at the appropriate
* time.
*
* This call is only necessary for regular files - not directories
*
* @param xfs filesystem instance
* @param inum File to decrement the count of
*/
void
xfs_decrement_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum);
/*
* Return the file open count for a regular file
*/
unsigned int
xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum);
/*
* Deletes all entries with the matching device id
*
* Files are deleted even if they are open
*
* The specified device_id must be non-zero so that the root
* filesystem is not deleted!
*
* @param device_id Device ID
*/
void
xfs_delete_entries_with_device_id(struct xfs_fs *xfs, tui32 device_id);
/*
* Check an entry move will be successful
*
* A move will fail if:-
* - Any of the parameters are invalid
* - if the entry is a directory, and the new parent is below the
* entry in the existing hierarchy.
*
* @param xfs filesystem instance
* @param inum Inumber of entry
* @param new_parent New parent
* @param name New name
*
* @result != 0 if all looks OK
*/
int
xfs_check_move_entry(struct xfs_fs *xfs, fuse_ino_t inum,
fuse_ino_t new_parent_inum, const char *name);
/*
* Move (rename) an entry
*
* @param xfs filesystem instance
* @param inum Inumber of entry
* @param new_parent New parent
* @param name New name
*
* @result 0, or a suitable errno value.
*/
int
xfs_move_entry(struct xfs_fs *xfs, fuse_ino_t inum,
fuse_ino_t new_parent_inum, const char *name);
#endif /* XRDP_FUSE */
#endif /* _CHANSRV_XFS */