mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -05:00
dll: fuse: implement BSD flags support
This commit is contained in:
parent
9f2fe92db7
commit
e06fe4153d
110
inc/fuse/fuse.h
110
inc/fuse/fuse.h
@ -39,54 +39,80 @@ typedef int (*fuse_dirfil_t)(fuse_dirh_t h, const char *name,
|
|||||||
|
|
||||||
struct fuse_operations
|
struct fuse_operations
|
||||||
{
|
{
|
||||||
int (*getattr)(const char *path, struct fuse_stat *stbuf);
|
/* S - supported by WinFsp */
|
||||||
int (*getdir)(const char *path, fuse_dirh_t h, fuse_dirfil_t filler);
|
/* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf);
|
||||||
int (*readlink)(const char *path, char *buf, size_t size);
|
/* S */ int (*getdir)(const char *path, fuse_dirh_t h, fuse_dirfil_t filler);
|
||||||
int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev);
|
/* S */ int (*readlink)(const char *path, char *buf, size_t size);
|
||||||
int (*mkdir)(const char *path, fuse_mode_t mode);
|
/* S */ int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev);
|
||||||
int (*unlink)(const char *path);
|
/* S */ int (*mkdir)(const char *path, fuse_mode_t mode);
|
||||||
int (*rmdir)(const char *path);
|
/* S */ int (*unlink)(const char *path);
|
||||||
int (*symlink)(const char *dstpath, const char *srcpath);
|
/* S */ int (*rmdir)(const char *path);
|
||||||
int (*rename)(const char *oldpath, const char *newpath);
|
/* S */ int (*symlink)(const char *dstpath, const char *srcpath);
|
||||||
int (*link)(const char *srcpath, const char *dstpath);
|
/* S */ int (*rename)(const char *oldpath, const char *newpath);
|
||||||
int (*chmod)(const char *path, fuse_mode_t mode);
|
/* _ */ int (*link)(const char *srcpath, const char *dstpath);
|
||||||
int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid);
|
/* S */ int (*chmod)(const char *path, fuse_mode_t mode);
|
||||||
int (*truncate)(const char *path, fuse_off_t size);
|
/* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid);
|
||||||
int (*utime)(const char *path, struct fuse_utimbuf *timbuf);
|
/* S */ int (*truncate)(const char *path, fuse_off_t size);
|
||||||
int (*open)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*utime)(const char *path, struct fuse_utimbuf *timbuf);
|
||||||
int (*read)(const char *path, char *buf, size_t size, fuse_off_t off,
|
/* S */ int (*open)(const char *path, struct fuse_file_info *fi);
|
||||||
|
/* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off,
|
||||||
struct fuse_file_info *fi);
|
struct fuse_file_info *fi);
|
||||||
int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off,
|
/* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off,
|
||||||
struct fuse_file_info *fi);
|
struct fuse_file_info *fi);
|
||||||
int (*statfs)(const char *path, struct fuse_statvfs *stbuf);
|
/* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf);
|
||||||
int (*flush)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*flush)(const char *path, struct fuse_file_info *fi);
|
||||||
int (*release)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*release)(const char *path, struct fuse_file_info *fi);
|
||||||
int (*fsync)(const char *path, int datasync, struct fuse_file_info *fi);
|
/* S */ int (*fsync)(const char *path, int datasync, struct fuse_file_info *fi);
|
||||||
int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
|
/* _ */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
|
||||||
int flags);
|
int flags);
|
||||||
int (*getxattr)(const char *path, const char *name, char *value, size_t size);
|
/* _ */ int (*getxattr)(const char *path, const char *name, char *value, size_t size);
|
||||||
int (*listxattr)(const char *path, char *namebuf, size_t size);
|
/* _ */ int (*listxattr)(const char *path, char *namebuf, size_t size);
|
||||||
int (*removexattr)(const char *path, const char *name);
|
/* _ */ int (*removexattr)(const char *path, const char *name);
|
||||||
int (*opendir)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*opendir)(const char *path, struct fuse_file_info *fi);
|
||||||
int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off,
|
/* S */ int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off,
|
||||||
struct fuse_file_info *fi);
|
struct fuse_file_info *fi);
|
||||||
int (*releasedir)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*releasedir)(const char *path, struct fuse_file_info *fi);
|
||||||
int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
|
/* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
|
||||||
void *(*init)(struct fuse_conn_info *conn);
|
/* S */ void *(*init)(struct fuse_conn_info *conn);
|
||||||
void (*destroy)(void *data);
|
/* S */ void (*destroy)(void *data);
|
||||||
int (*access)(const char *path, int mask);
|
/* _ */ int (*access)(const char *path, int mask);
|
||||||
int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi);
|
/* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi);
|
||||||
int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi);
|
/* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi);
|
||||||
int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);
|
/* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);
|
||||||
int (*lock)(const char *path, struct fuse_file_info *fi, int cmd, struct fuse_flock *lock);
|
/* _ */ int (*lock)(const char *path,
|
||||||
int (*utimens)(const char *path, const struct fuse_timespec tv[2]);
|
struct fuse_file_info *fi, int cmd, struct fuse_flock *lock);
|
||||||
int (*bmap)(const char *path, size_t blocksize, uint64_t *idx);
|
/* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2]);
|
||||||
unsigned int flag_nullpath_ok:1;
|
/* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx);
|
||||||
unsigned int flag_reserved:31;
|
/* _ */ unsigned int flag_nullpath_ok:1;
|
||||||
int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi,
|
/* _ */ unsigned int flag_reserved:31;
|
||||||
|
/* _ */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi,
|
||||||
unsigned int flags, void *data);
|
unsigned int flags, void *data);
|
||||||
int (*poll)(const char *path, struct fuse_file_info *fi,
|
/* _ */ int (*poll)(const char *path, struct fuse_file_info *fi,
|
||||||
struct fuse_pollhandle *ph, unsigned *reventsp);
|
struct fuse_pollhandle *ph, unsigned *reventsp);
|
||||||
|
/* FUSE 2.9 */
|
||||||
|
/* _ */ int (*write_buf)(const char *path,
|
||||||
|
struct fuse_bufvec *buf, fuse_off_t off, struct fuse_file_info *fi);
|
||||||
|
/* _ */ int (*read_buf)(const char *path,
|
||||||
|
struct fuse_bufvec **bufp, size_t size, fuse_off_t off, struct fuse_file_info *fi);
|
||||||
|
/* _ */ int (*flock)(const char *path, struct fuse_file_info *, int op);
|
||||||
|
/* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len,
|
||||||
|
struct fuse_file_info *fi);
|
||||||
|
/* OSXFUSE */
|
||||||
|
/* _ */ int (*reserved00)();
|
||||||
|
/* _ */ int (*reserved01)();
|
||||||
|
/* _ */ int (*reserved02)();
|
||||||
|
/* _ */ int (*statfs_x)(const char *path, struct fuse_statfs *stbuf);
|
||||||
|
/* _ */ int (*setvolname)(const char *volname);
|
||||||
|
/* _ */ int (*exchange)(const char *oldpath, const char *newpath, unsigned long flags);
|
||||||
|
/* _ */ int (*getxtimes)(const char *path,
|
||||||
|
struct fuse_timespec *bkuptime, struct fuse_timespec *crtime);
|
||||||
|
/* _ */ int (*setbkuptime)(const char *path, const struct fuse_timespec *tv);
|
||||||
|
/* _ */ int (*setchgtime)(const char *path, const struct fuse_timespec *tv);
|
||||||
|
/* _ */ int (*setcrtime)(const char *path, const struct fuse_timespec *tv);
|
||||||
|
/* S */ int (*chflags)(const char *path, uint32_t flags);
|
||||||
|
/* _ */ int (*setattr_x)(const char *path, struct fuse_setattr_x *attr);
|
||||||
|
/* _ */ int (*fsetattr_x)(const char *path, struct fuse_setattr_x *attr,
|
||||||
|
struct fuse_file_info *fi);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fuse_context
|
struct fuse_context
|
||||||
|
@ -49,6 +49,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */
|
#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */
|
||||||
#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */
|
#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */
|
||||||
|
#define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */
|
||||||
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
|
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
|
||||||
|
|
||||||
#define FUSE_IOCTL_COMPAT (1 << 0)
|
#define FUSE_IOCTL_COMPAT (1 << 0)
|
||||||
@ -56,6 +57,24 @@ extern "C" {
|
|||||||
#define FUSE_IOCTL_RETRY (1 << 2)
|
#define FUSE_IOCTL_RETRY (1 << 2)
|
||||||
#define FUSE_IOCTL_MAX_IOV 256
|
#define FUSE_IOCTL_MAX_IOV 256
|
||||||
|
|
||||||
|
/* from FreeBSD */
|
||||||
|
#define FSP_FUSE_UF_HIDDEN 0x00008000
|
||||||
|
#define FSP_FUSE_UF_READONLY 0x00001000
|
||||||
|
#define FSP_FUSE_UF_SYSTEM 0x00000080
|
||||||
|
#define FSP_FUSE_UF_ARCHIVE 0x00000800
|
||||||
|
#if !defined(UF_HIDDEN)
|
||||||
|
#define UF_HIDDEN FSP_FUSE_UF_HIDDEN
|
||||||
|
#endif
|
||||||
|
#if !defined(UF_READONLY)
|
||||||
|
#define UF_READONLY FSP_FUSE_UF_READONLY
|
||||||
|
#endif
|
||||||
|
#if !defined(UF_SYSTEM)
|
||||||
|
#define UF_SYSTEM FSP_FUSE_UF_SYSTEM
|
||||||
|
#endif
|
||||||
|
#if !defined(UF_ARCHIVE)
|
||||||
|
#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE
|
||||||
|
#endif
|
||||||
|
|
||||||
struct fuse_file_info
|
struct fuse_file_info
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
@ -85,6 +104,9 @@ struct fuse_conn_info
|
|||||||
struct fuse_session;
|
struct fuse_session;
|
||||||
struct fuse_chan;
|
struct fuse_chan;
|
||||||
struct fuse_pollhandle;
|
struct fuse_pollhandle;
|
||||||
|
struct fuse_bufvec;
|
||||||
|
struct fuse_statfs;
|
||||||
|
struct fuse_setattr_x;
|
||||||
|
|
||||||
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_version)(struct fsp_fuse_env *env);
|
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_version)(struct fsp_fuse_env *env);
|
||||||
FSP_FUSE_API struct fuse_chan *FSP_FUSE_API_NAME(fsp_fuse_mount)(struct fsp_fuse_env *env,
|
FSP_FUSE_API struct fuse_chan *FSP_FUSE_API_NAME(fsp_fuse_mount)(struct fsp_fuse_env *env,
|
||||||
|
@ -65,6 +65,22 @@ extern "C" {
|
|||||||
* to be usable from Cygwin.
|
* to be usable from Cygwin.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FSP_FUSE_STAT_FIELD_DEFN \
|
||||||
|
fuse_dev_t st_dev; \
|
||||||
|
fuse_ino_t st_ino; \
|
||||||
|
fuse_mode_t st_mode; \
|
||||||
|
fuse_nlink_t st_nlink; \
|
||||||
|
fuse_uid_t st_uid; \
|
||||||
|
fuse_gid_t st_gid; \
|
||||||
|
fuse_dev_t st_rdev; \
|
||||||
|
fuse_off_t st_size; \
|
||||||
|
struct fuse_timespec st_atim; \
|
||||||
|
struct fuse_timespec st_mtim; \
|
||||||
|
struct fuse_timespec st_ctim; \
|
||||||
|
fuse_blksize_t st_blksize; \
|
||||||
|
fuse_blkcnt_t st_blocks; \
|
||||||
|
struct fuse_timespec st_birthtim;
|
||||||
|
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
|
|
||||||
typedef uint32_t fuse_uid_t;
|
typedef uint32_t fuse_uid_t;
|
||||||
@ -113,20 +129,7 @@ struct fuse_timespec
|
|||||||
|
|
||||||
struct fuse_stat
|
struct fuse_stat
|
||||||
{
|
{
|
||||||
fuse_dev_t st_dev;
|
FSP_FUSE_STAT_FIELD_DEFN
|
||||||
fuse_ino_t st_ino;
|
|
||||||
fuse_mode_t st_mode;
|
|
||||||
fuse_nlink_t st_nlink;
|
|
||||||
fuse_uid_t st_uid;
|
|
||||||
fuse_gid_t st_gid;
|
|
||||||
fuse_dev_t st_rdev;
|
|
||||||
fuse_off_t st_size;
|
|
||||||
struct fuse_timespec st_atim;
|
|
||||||
struct fuse_timespec st_mtim;
|
|
||||||
struct fuse_timespec st_ctim;
|
|
||||||
fuse_blksize_t st_blksize;
|
|
||||||
fuse_blkcnt_t st_blocks;
|
|
||||||
struct fuse_timespec st_birthtim;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
@ -246,6 +249,13 @@ struct fuse_flock
|
|||||||
#error unsupported environment
|
#error unsupported environment
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct fuse_stat_ex
|
||||||
|
{
|
||||||
|
FSP_FUSE_STAT_FIELD_DEFN
|
||||||
|
uint32_t st_flags;
|
||||||
|
uint64_t st_reserved[3];
|
||||||
|
};
|
||||||
|
|
||||||
struct fsp_fuse_env
|
struct fsp_fuse_env
|
||||||
{
|
{
|
||||||
unsigned environment;
|
unsigned environment;
|
||||||
|
@ -299,6 +299,7 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
FUSE_CAP_DONT_MASK |
|
FUSE_CAP_DONT_MASK |
|
||||||
FSP_FUSE_CAP_READDIR_PLUS |
|
FSP_FUSE_CAP_READDIR_PLUS |
|
||||||
FSP_FUSE_CAP_READ_ONLY |
|
FSP_FUSE_CAP_READ_ONLY |
|
||||||
|
FSP_FUSE_CAP_STAT_EX |
|
||||||
FSP_FUSE_CAP_CASE_INSENSITIVE;
|
FSP_FUSE_CAP_CASE_INSENSITIVE;
|
||||||
if (0 != f->ops.init)
|
if (0 != f->ops.init)
|
||||||
{
|
{
|
||||||
@ -340,7 +341,7 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
}
|
}
|
||||||
if (0 != f->ops.getattr)
|
if (0 != f->ops.getattr)
|
||||||
{
|
{
|
||||||
struct fuse_stat stbuf;
|
struct fuse_stat_ex stbuf;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
memset(&stbuf, 0, sizeof stbuf);
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
|
@ -219,7 +219,7 @@ static NTSTATUS fsp_fuse_intf_NewHiddenName(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
struct { UINT32 V[4]; } Values;
|
struct { UINT32 V[4]; } Values;
|
||||||
UUID Uuid;
|
UUID Uuid;
|
||||||
} UuidBuf;
|
} UuidBuf;
|
||||||
struct fuse_stat stbuf;
|
struct fuse_stat_ex stbuf;
|
||||||
int err, maxtries = 3;
|
int err, maxtries = 3;
|
||||||
|
|
||||||
*PPosixHiddenPath = 0;
|
*PPosixHiddenPath = 0;
|
||||||
@ -291,7 +291,7 @@ static BOOLEAN fsp_fuse_intf_CheckSymlinkDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
char *PosixDotPath = 0;
|
char *PosixDotPath = 0;
|
||||||
size_t Length;
|
size_t Length;
|
||||||
struct fuse_stat stbuf;
|
struct fuse_stat_ex stbuf;
|
||||||
int err;
|
int err;
|
||||||
BOOLEAN Result = FALSE;
|
BOOLEAN Result = FALSE;
|
||||||
|
|
||||||
@ -304,6 +304,7 @@ static BOOLEAN fsp_fuse_intf_CheckSymlinkDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
PosixDotPath[Length + 1] = '.';
|
PosixDotPath[Length + 1] = '.';
|
||||||
PosixDotPath[Length + 2] = '\0';
|
PosixDotPath[Length + 2] = '\0';
|
||||||
|
|
||||||
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
if (0 != f->ops.getattr)
|
if (0 != f->ops.getattr)
|
||||||
err = f->ops.getattr(PosixDotPath, (void *)&stbuf);
|
err = f->ops.getattr(PosixDotPath, (void *)&stbuf);
|
||||||
else
|
else
|
||||||
@ -317,25 +318,57 @@ static BOOLEAN fsp_fuse_intf_CheckSymlinkDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t fsp_fuse_intf_MapFileAttributesToFlags(UINT32 FileAttributes)
|
||||||
|
{
|
||||||
|
uint32_t flags = 0;
|
||||||
|
|
||||||
|
if (FileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||||
|
flags |= FSP_FUSE_UF_READONLY;
|
||||||
|
if (FileAttributes & FILE_ATTRIBUTE_HIDDEN)
|
||||||
|
flags |= FSP_FUSE_UF_HIDDEN;
|
||||||
|
if (FileAttributes & FILE_ATTRIBUTE_SYSTEM)
|
||||||
|
flags |= FSP_FUSE_UF_SYSTEM;
|
||||||
|
if (FileAttributes & FILE_ATTRIBUTE_ARCHIVE)
|
||||||
|
flags |= FSP_FUSE_UF_ARCHIVE;
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline UINT32 fsp_fuse_intf_MapFlagsToFileAttributes(uint32_t flags)
|
||||||
|
{
|
||||||
|
UINT32 FileAttributes = 0;
|
||||||
|
|
||||||
|
if (flags & FSP_FUSE_UF_READONLY)
|
||||||
|
FileAttributes |= FILE_ATTRIBUTE_READONLY;
|
||||||
|
if (flags & FSP_FUSE_UF_HIDDEN)
|
||||||
|
FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||||
|
if (flags & FSP_FUSE_UF_SYSTEM)
|
||||||
|
FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
|
||||||
|
if (flags & FSP_FUSE_UF_ARCHIVE)
|
||||||
|
FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
|
||||||
|
|
||||||
|
return FileAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
#define fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, fi, PUid, PGid, PMode, FileInfo)\
|
#define fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, fi, PUid, PGid, PMode, FileInfo)\
|
||||||
fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, 0, PUid, PGid, PMode, 0, FileInfo)
|
fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, 0, PUid, PGid, PMode, 0, FileInfo)
|
||||||
static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
|
||||||
const char *PosixPath, struct fuse_file_info *fi, const struct fuse_stat *stbufp,
|
const char *PosixPath, struct fuse_file_info *fi, const void *stbufp,
|
||||||
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode, PUINT32 PDev,
|
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode, PUINT32 PDev,
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
UINT64 AllocationUnit;
|
UINT64 AllocationUnit;
|
||||||
struct fuse_stat stbuf;
|
struct fuse_stat_ex stbuf;
|
||||||
|
BOOLEAN StatEx = 0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX);
|
||||||
|
|
||||||
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
if (0 != stbufp)
|
if (0 != stbufp)
|
||||||
memcpy(&stbuf, stbufp, sizeof stbuf);
|
memcpy(&stbuf, stbufp, StatEx ? sizeof(struct fuse_stat_ex) : sizeof(struct fuse_stat));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
memset(&stbuf, 0, sizeof stbuf);
|
|
||||||
|
|
||||||
if (0 != f->ops.fgetattr && 0 != fi && -1 != fi->fh)
|
if (0 != f->ops.fgetattr && 0 != fi && -1 != fi->fh)
|
||||||
err = f->ops.fgetattr(PosixPath, (void *)&stbuf, fi);
|
err = f->ops.fgetattr(PosixPath, (void *)&stbuf, fi);
|
||||||
else if (0 != f->ops.getattr)
|
else if (0 != f->ops.getattr)
|
||||||
@ -390,6 +423,8 @@ static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FileInfo->ReparseTag = 0;
|
FileInfo->ReparseTag = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (StatEx)
|
||||||
|
FileInfo->FileAttributes |= fsp_fuse_intf_MapFlagsToFileAttributes(stbuf.st_flags);
|
||||||
FileInfo->FileSize = stbuf.st_size;
|
FileInfo->FileSize = stbuf.st_size;
|
||||||
FileInfo->AllocationSize =
|
FileInfo->AllocationSize =
|
||||||
(FileInfo->FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
|
(FileInfo->FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
|
||||||
@ -1235,73 +1270,68 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
struct fsp_fuse_file_desc *filedesc = FileNode;
|
struct fsp_fuse_file_desc *filedesc = FileNode;
|
||||||
UINT32 Uid, Gid, Mode;
|
UINT32 Uid, Gid, Mode;
|
||||||
struct fuse_file_info fi;
|
struct fuse_file_info fi;
|
||||||
FSP_FSCTL_FILE_INFO FileInfoBuf;
|
|
||||||
struct fuse_timespec tv[2];
|
struct fuse_timespec tv[2];
|
||||||
struct fuse_utimbuf timbuf;
|
struct fuse_utimbuf timbuf;
|
||||||
int err;
|
int err;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (0 == f->ops.utimens && 0 == f->ops.utime)
|
|
||||||
return STATUS_SUCCESS; /* liar! */
|
|
||||||
|
|
||||||
/* no way to set FileAttributes, CreationTime! */
|
|
||||||
if (0 == LastAccessTime && 0 == LastWriteTime)
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
memset(&fi, 0, sizeof fi);
|
memset(&fi, 0, sizeof fi);
|
||||||
fi.flags = filedesc->OpenFlags;
|
fi.flags = filedesc->OpenFlags;
|
||||||
fi.fh = filedesc->FileHandle;
|
fi.fh = filedesc->FileHandle;
|
||||||
|
|
||||||
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
if (INVALID_FILE_ATTRIBUTES != FileAttributes &&
|
||||||
&Uid, &Gid, &Mode, &FileInfoBuf);
|
0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags)
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
if (0 != LastAccessTime)
|
|
||||||
FileInfoBuf.LastAccessTime = LastAccessTime;
|
|
||||||
if (0 != LastWriteTime)
|
|
||||||
FileInfoBuf.LastWriteTime = LastWriteTime;
|
|
||||||
|
|
||||||
/* UNIX epoch in 100-ns intervals */
|
|
||||||
LastAccessTime = FileInfoBuf.LastAccessTime - 116444736000000000;
|
|
||||||
LastWriteTime = FileInfoBuf.LastWriteTime - 116444736000000000;
|
|
||||||
|
|
||||||
if (0 != f->ops.utimens)
|
|
||||||
{
|
{
|
||||||
|
err = f->ops.chflags(filedesc->PosixPath,
|
||||||
|
fsp_fuse_intf_MapFileAttributesToFlags(FileAttributes));
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((0 != LastAccessTime || 0 != LastWriteTime) &&
|
||||||
|
(0 != f->ops.utimens || 0 != f->ops.utime))
|
||||||
|
{
|
||||||
|
/* UNIX epoch in 100-ns intervals */
|
||||||
|
LastAccessTime -= 116444736000000000;
|
||||||
|
LastWriteTime -= 116444736000000000;
|
||||||
|
|
||||||
|
if (0 != f->ops.utimens)
|
||||||
|
{
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
tv[0].tv_sec = (int64_t)(LastAccessTime / 10000000);
|
tv[0].tv_sec = (int64_t)(LastAccessTime / 10000000);
|
||||||
tv[0].tv_nsec = (int64_t)(LastAccessTime % 10000000) * 100;
|
tv[0].tv_nsec = (int64_t)(LastAccessTime % 10000000) * 100;
|
||||||
tv[1].tv_sec = (int64_t)(LastWriteTime / 10000000);
|
tv[1].tv_sec = (int64_t)(LastWriteTime / 10000000);
|
||||||
tv[1].tv_nsec = (int64_t)(LastWriteTime % 10000000) * 100;
|
tv[1].tv_nsec = (int64_t)(LastWriteTime % 10000000) * 100;
|
||||||
#else
|
#else
|
||||||
tv[0].tv_sec = (int32_t)(LastAccessTime / 10000000);
|
tv[0].tv_sec = (int32_t)(LastAccessTime / 10000000);
|
||||||
tv[0].tv_nsec = (int32_t)(LastAccessTime % 10000000) * 100;
|
tv[0].tv_nsec = (int32_t)(LastAccessTime % 10000000) * 100;
|
||||||
tv[1].tv_sec = (int32_t)(LastWriteTime / 10000000);
|
tv[1].tv_sec = (int32_t)(LastWriteTime / 10000000);
|
||||||
tv[1].tv_nsec = (int32_t)(LastWriteTime % 10000000) * 100;
|
tv[1].tv_nsec = (int32_t)(LastWriteTime % 10000000) * 100;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
err = f->ops.utimens(filedesc->PosixPath, tv);
|
err = f->ops.utimens(filedesc->PosixPath, tv);
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
timbuf.actime = (int64_t)(LastAccessTime / 10000000);
|
timbuf.actime = (int64_t)(LastAccessTime / 10000000);
|
||||||
timbuf.modtime = (int64_t)(LastWriteTime / 10000000);
|
timbuf.modtime = (int64_t)(LastWriteTime / 10000000);
|
||||||
#else
|
#else
|
||||||
timbuf.actime = (int32_t)(LastAccessTime / 10000000);
|
timbuf.actime = (int32_t)(LastAccessTime / 10000000);
|
||||||
timbuf.modtime = (int32_t)(LastWriteTime / 10000000);
|
timbuf.modtime = (int32_t)(LastWriteTime / 10000000);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
err = f->ops.utime(filedesc->PosixPath, &timbuf);
|
err = f->ops.utime(filedesc->PosixPath, &timbuf);
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
memcpy(FileInfo, &FileInfoBuf, sizeof FileInfoBuf);
|
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
||||||
|
&Uid, &Gid, &Mode, FileInfo);
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user