4d8f2b5a31
- 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.
322 lines
9.1 KiB
C
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 */
|