diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj index ca35988c..af53e2c8 100644 --- a/build/VStudio/winfsp_dll.vcxproj +++ b/build/VStudio/winfsp_dll.vcxproj @@ -20,6 +20,9 @@ + + + @@ -27,6 +30,8 @@ + + diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters index acb82f28..b8103d17 100644 --- a/build/VStudio/winfsp_dll.vcxproj.filters +++ b/build/VStudio/winfsp_dll.vcxproj.filters @@ -15,6 +15,12 @@ {c7b83307-0aa0-4593-b2d4-26ff2f1edfc6} + + {0e7ab1b1-bfca-4439-accb-45a909be9cad} + + + {518cce17-85cd-489c-b4be-920a84c1d73c} + @@ -29,6 +35,15 @@ Include\shared + + Include\fuse + + + Include\fuse + + + Include\fuse + @@ -67,6 +82,12 @@ Source + + Source\fuse + + + Source\fuse + diff --git a/inc/fuse/fuse.h b/inc/fuse/fuse.h new file mode 100644 index 00000000..50c74ff6 --- /dev/null +++ b/inc/fuse/fuse.h @@ -0,0 +1,199 @@ +/** + * @file fuse/fuse.h + * WinFsp FUSE compatible API. + * + * This file is derived from libfuse/include/fuse.h: + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi + * + * @copyright 2015-2016 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the + * GNU Affero General Public License version 3 as published by the + * Free Software Foundation. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * software. + */ + +#ifndef FUSE_H_ +#define FUSE_H_ + +#include "fuse_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct fuse; + +enum fuse_readdir_flags +{ + FUSE_READDIR_PLUS = (1 << 0), +}; + +enum fuse_fill_dir_flags +{ + FUSE_FILL_DIR_PLUS = (1 << 1), +}; + +typedef int (*fuse_fill_dir_t)(void *buf, const char *name, + const struct fuse_stat *stbuf, fuse_off_t off, enum fuse_fill_dir_flags flags); + +struct fuse_operations +{ + unsigned int flag_nopath:1; + unsigned int flag_reserved:31; + int (*getattr)(const char *path, struct fuse_stat *stbuf); + int (*readlink)(const char *path, char *buf, size_t size); + int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev); + int (*mkdir)(const char *path, fuse_mode_t mode); + int (*unlink)(const char *path); + int (*rmdir)(const char *path); + int (*symlink)(const char *dstpath, const char *srcpath); + int (*rename)(const char *oldpath, const char *newpath, unsigned int flags); + int (*link)(const char *srcpath, const char *dstpath); + int (*chmod)(const char *path, fuse_mode_t mode); + int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid); + int (*truncate)(const char *path, fuse_off_t size); + int (*open)(const char *path, struct fuse_file_info *fi); + int (*read)(const char *path, char *buf, size_t size, fuse_off_t off, + struct fuse_file_info *fi); + int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off, + struct fuse_file_info *fi); + int (*statfs)(const char *path, struct fuse_statvfs *stbuf); + int (*flush)(const char *path, struct fuse_file_info *fi); + int (*release)(const char *path, struct fuse_file_info *fi); + 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 flags); + int (*getxattr)(const char *path, const char *name, char *value, size_t size); + int (*listxattr)(const char *path, char *namebuf, size_t size); + int (*removexattr)(const char *path, const char *name); + 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, + struct fuse_file_info *fi, enum fuse_readdir_flags flags); + int (*releasedir)(const char *path, struct fuse_file_info *fi); + int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi); + void *(*init)(struct fuse_conn_info *conn); + void (*destroy)(void *data); + int (*access)(const char *path, int mask); + 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); + 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 flock *lock); + int (*utimens)(const char *path, const struct timespec tv[2]); + int (*bmap)(const char *path, size_t blocksize, uint64_t *idx); + int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi, + unsigned int flags, void *data); + int (*poll)(const char *path, struct fuse_file_info *fi, + struct fuse_pollhandle *ph, unsigned *reventsp); + 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); +}; + +struct fuse_context +{ + struct fuse *fuse; + fuse_uid_t uid; + fuse_gid_t gid; + fuse_pid_t pid; + void *private_data; + fuse_mode_t umask; +}; + +#define fuse_main(argc, argv, ops, data)\ + fuse_main_real(argc, argv, ops, sizeof *(ops), data) + +FSP_FUSE_API int fsp_fuse_main_real(int argc, char *argv[], + const struct fuse_operations *ops, size_t opsize, void *data, + int environment); +FSP_FUSE_API struct fuse *fsp_fuse_new(struct fuse_chan *ch, struct fuse_args *args, + const struct fuse_operations *ops, size_t opsize, void *data, + int environment); +FSP_FUSE_API void fsp_fuse_destroy(struct fuse *f); +FSP_FUSE_API int fsp_fuse_loop(struct fuse *f); +FSP_FUSE_API int fsp_fuse_loop_mt(struct fuse *f); +FSP_FUSE_API void fsp_fuse_exit(struct fuse *f); +FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(void); + +static inline int fuse_main_real(int argc, char *argv[], + const struct fuse_operations *ops, size_t opsize, void *data) +{ + return fsp_fuse_main_real(argc, argv, ops, opsize, data, FSP_FUSE_ENVIRONMENT); +} + +static inline struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, + const struct fuse_operations *ops, size_t opsize, void *data) +{ + return fsp_fuse_new(ch, args, ops, opsize, data, FSP_FUSE_ENVIRONMENT); +} + +static inline void fuse_destroy(struct fuse *f) +{ + fsp_fuse_destroy(f); +} + +static inline int fuse_loop(struct fuse *f) +{ + return fuse_loop(f); +} + +static inline int fuse_loop_mt(struct fuse *f) +{ + return fsp_fuse_loop_mt(f); +} + +static inline void fuse_exit(struct fuse *f) +{ + fsp_fuse_exit(f); +} + +static inline struct fuse_context *fuse_get_context(void) +{ + return fsp_fuse_get_context(); +} + +static inline int fuse_getgroups(int size, fuse_gid_t list[]) +{ + return 0; +} + +static inline int fuse_interrupted(void) +{ + return 0; +} + +static inline int fuse_start_cleanup_thread(struct fuse *fuse) +{ + return 0; +} + +static inline void fuse_stop_cleanup_thread(struct fuse *fuse) +{ +} + +static inline int fuse_clean_cache(struct fuse *fuse) +{ + return 60; +} + +static inline struct fuse_session *fuse_get_session(struct fuse *f) +{ + return (void *)f; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/fuse/fuse_common.h b/inc/fuse/fuse_common.h new file mode 100644 index 00000000..90519e1f --- /dev/null +++ b/inc/fuse/fuse_common.h @@ -0,0 +1,213 @@ +/** + * @file fuse/fuse_common.h + * WinFsp FUSE compatible API. + * + * This file is derived from libfuse/include/fuse_common.h: + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi + * + * @copyright 2015-2016 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the + * GNU Affero General Public License version 3 as published by the + * Free Software Foundation. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * software. + */ + +#ifndef FUSE_COMMON_H_ +#define FUSE_COMMON_H_ + +#include +#include "fuse_opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(FSP_FUSE_API) +#if defined(WINFSP_DLL_INTERNAL) +#define FSP_FUSE_API __declspec(dllexport) +#else +#define FSP_FUSE_API __declspec(dllimport) +#endif +#endif + +#define FUSE_MAJOR_VERSION 3 +#define FUSE_MINOR_VERSION 0 +#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) +#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) + +/* + * FUSE uses a number of types (notably: struct stat) that are OS specific. + * Furthermore there are even multiple definitions of the same type even + * within the same OS. This is certainly true on Windows as well, where + * these types are not even native. + * + * For this reason we will define our own fuse_* types which represent the + * types as the WinFsp DLL expects to see them. When the file is included + * by FUSE clients in different environments we will translate between their + * understanding of the types and ours. + */ +#if defined(_MSC_VER) +typedef uint32_t fuse_uid_t; +typedef uint32_t fuse_gid_t; +typedef int32_t fuse_pid_t; + +typedef uint64_t fuse_dev_t; +typedef uint64_t fuse_ino_t; +typedef uint32_t fuse_mode_t; +typedef uint32_t fuse_nlink_t; +typedef int64_t fuse_off_t; + +typedef uint64_t fuse_fsblkcnt_t; +typedef uint64_t fuse_fsfilcnt_t; +typedef int32_t fuse_blksize_t; +typedef int32_t fuse_blkcnt_t; + +struct fuse_timespec +{ + time_t tv_sec; + long tv_nsec; +}; + +struct fuse_stat +{ + 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; +}; + +struct fuse_statvfs +{ + unsigned long f_bsize; + unsigned long f_frsize; + fuse_fsblkcnt_t f_blocks; + fuse_fsblkcnt_t f_bfree; + fuse_fsblkcnt_t f_bavail; + fuse_fsfilcnt_t f_files; + fuse_fsfilcnt_t f_ffree; + fuse_fsfilcnt_t f_favail; + unsigned long f_fsid; + unsigned long f_flag; + unsigned long f_namemax; +}; + +#define FSP_FUSE_ENVIRONMENT 'W' + +#elif defined(__CYGWIN__) + +#error unsupported environment + +#define FSP_FUSE_ENVIRONMENT 'C' + +#else +#error unsupported environment +#endif + +struct fuse_file_info +{ + int flags; + unsigned int writepage:1; + unsigned int direct_io:1; + unsigned int keep_cache:1; + unsigned int flush:1; + unsigned int nonseekable:1; + unsigned int flock_release:1; + unsigned int padding:27; + uint64_t fh; + uint64_t lock_owner; + uint32_t poll_events; +}; + +struct fuse_conn_info +{ + unsigned proto_major; + unsigned proto_minor; + unsigned async_read; + unsigned max_write; + unsigned max_readahead; + unsigned capable; + unsigned want; + unsigned max_background; + unsigned congestion_threshold; + unsigned time_gran; + unsigned reserved[22]; +}; + +struct fuse_session; +struct fuse_chan; +struct fuse_pollhandle; + +FSP_FUSE_API int fsp_fuse_version(void); +FSP_FUSE_API const char *fsp_fuse_pkgversion(void); +FSP_FUSE_API struct fuse_chan *fsp_fuse_mount(const char *mountpoint, struct fuse_args *args); +FSP_FUSE_API void fsp_fuse_unmount(const char *mountpoint, struct fuse_chan *ch); +FSP_FUSE_API int fsp_fuse_parse_cmdline(struct fuse_args *args, char **mountpoint, + int *multithreaded, int *foreground); + +static inline int fuse_version(void) +{ + return fsp_fuse_version(); +} + +static inline const char *fuse_pkgversion(void) +{ + return fsp_fuse_pkgversion(); +} + +static inline struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args) +{ + return fsp_fuse_mount(mountpoint, args); +} + +static inline void fuse_unmount(const char *mountpoint, struct fuse_chan *ch) +{ + fsp_fuse_unmount(mountpoint, ch); +} + +static inline int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint, + int *multithreaded, int *foreground) +{ + return fsp_fuse_parse_cmdline(args, mountpoint, multithreaded, foreground); +} + +static inline void fuse_pollhandle_destroy(struct fuse_pollhandle *ph) +{ +} + +static inline int fuse_daemonize(int foreground) +{ + return 0; +} + +static inline int fuse_set_signal_handlers(struct fuse_session *se) +{ + return 0; +} + +static inline void fuse_remove_signal_handlers(struct fuse_session *se) +{ +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/fuse/fuse_opt.h b/inc/fuse/fuse_opt.h new file mode 100644 index 00000000..f235001b --- /dev/null +++ b/inc/fuse/fuse_opt.h @@ -0,0 +1,114 @@ +/** + * @file fuse/fuse_opt.h + * WinFsp FUSE compatible API. + * + * This file is derived from libfuse/include/fuse_opt.h: + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi + * + * @copyright 2015-2016 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the + * GNU Affero General Public License version 3 as published by the + * Free Software Foundation. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * software. + */ + +#ifndef FUSE_OPT_H_ +#define FUSE_OPT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(FSP_FUSE_API) +#if defined(WINFSP_DLL_INTERNAL) +#define FSP_FUSE_API __declspec(dllexport) +#else +#define FSP_FUSE_API __declspec(dllimport) +#endif +#endif + +#define FUSE_OPT_KEY(templ, key) { templ, -1U, key } +#define FUSE_OPT_END { NULL, 0, 0 } + +#define FUSE_OPT_KEY_OPT -1 +#define FUSE_OPT_KEY_NONOPT -2 +#define FUSE_OPT_KEY_KEEP -3 +#define FUSE_OPT_KEY_DISCARD -4 + +#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 } + +struct fuse_opt +{ + const char *templ; + unsigned long offset; + int value; +}; + +struct fuse_args +{ + int argc; + char **argv; + int allocated; +}; + +typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key, + struct fuse_args *outargs); + +FSP_FUSE_API int fsp_fuse_opt_parse(struct fuse_args *args, void *data, + const struct fuse_opt opts[], fuse_opt_proc_t proc); +FSP_FUSE_API int fsp_fuse_opt_add_opt(char **opts, const char *opt); +FSP_FUSE_API int fsp_fuse_opt_add_opt_escaped(char **opts, const char *opt); +FSP_FUSE_API int fsp_fuse_opt_add_arg(struct fuse_args *args, const char *arg); +FSP_FUSE_API int fsp_fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg); +FSP_FUSE_API void fsp_fuse_opt_free_args(struct fuse_args *args); +FSP_FUSE_API int fsp_fuse_opt_match(const struct fuse_opt opts[], const char *opt); + +static inline int fuse_opt_parse(struct fuse_args *args, void *data, + const struct fuse_opt opts[], fuse_opt_proc_t proc) +{ + return fsp_fuse_opt_parse(args, data, opts, proc); +} + +static inline int fuse_opt_add_opt(char **opts, const char *opt) +{ + return fsp_fuse_opt_add_opt(opts, opt); +} + +static inline int fuse_opt_add_opt_escaped(char **opts, const char *opt) +{ + return fsp_fuse_opt_add_opt_escaped(opts, opt); +} + +static inline int fuse_opt_add_arg(struct fuse_args *args, const char *arg) +{ + return fsp_fuse_opt_add_arg(args, arg); +} + +static inline int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg) +{ + return fsp_fuse_opt_insert_arg(args, pos, arg); +} + +static inline void fuse_opt_free_args(struct fuse_args *args) +{ + fsp_fuse_opt_free_args(args); +} + +static inline int fuse_opt_match(const struct fuse_opt opts[], const char *opt) +{ + return fsp_fuse_opt_match(opts, opt); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c new file mode 100644 index 00000000..45acb045 --- /dev/null +++ b/src/dll/fuse/fuse.c @@ -0,0 +1,84 @@ +/** + * @file dll/fuse/fuse.c + * + * @copyright 2015-2016 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the + * GNU Affero General Public License version 3 as published by the + * Free Software Foundation. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * software. + */ + +#include +#include + +#define STR(x) STR_(x) +#define STR_(x) #x + +FSP_FUSE_API int fsp_fuse_version(void) +{ + return FUSE_VERSION; +} + +FSP_FUSE_API const char *fsp_fuse_pkgversion(void) +{ + return STR(FUSE_VERSION); +} + +FSP_FUSE_API struct fuse_chan *fsp_fuse_mount(const char *mountpoint, struct fuse_args *args) +{ + return 0; +} + +FSP_FUSE_API void fsp_fuse_unmount(const char *mountpoint, struct fuse_chan *ch) +{ +} + +FSP_FUSE_API int fsp_fuse_parse_cmdline(struct fuse_args *args, char **mountpoint, + int *multithreaded, int *foreground) +{ + return 0; +} + +FSP_FUSE_API int fsp_fuse_main_real(int argc, char *argv[], + const struct fuse_operations *ops, size_t opsize, void *data, + int environment) +{ + return 0; +} + +FSP_FUSE_API struct fuse *fsp_fuse_new(struct fuse_chan *ch, struct fuse_args *args, + const struct fuse_operations *ops, size_t opsize, void *data, + int environment) +{ + return 0; +} + +FSP_FUSE_API void fsp_fuse_destroy(struct fuse *f) +{ +} + +FSP_FUSE_API int fsp_fuse_loop(struct fuse *f) +{ + return 0; +} + +FSP_FUSE_API int fsp_fuse_loop_mt(struct fuse *f) +{ + return 0; +} + +FSP_FUSE_API void fsp_fuse_exit(struct fuse *f) +{ +} + +FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(void) +{ + return 0; +} diff --git a/src/dll/fuse/fuse_opt.c b/src/dll/fuse/fuse_opt.c new file mode 100644 index 00000000..4649384d --- /dev/null +++ b/src/dll/fuse/fuse_opt.c @@ -0,0 +1,54 @@ +/** + * @file dll/fuse/fuse_opt.c + * + * @copyright 2015-2016 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the + * GNU Affero General Public License version 3 as published by the + * Free Software Foundation. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * software. + */ + +#include +#include + +FSP_FUSE_API int fsp_fuse_opt_parse(struct fuse_args *args, void *data, + const struct fuse_opt opts[], fuse_opt_proc_t proc) +{ + return 0; +} + +FSP_FUSE_API int fsp_fuse_opt_add_opt(char **opts, const char *opt) +{ + return 0; +} + +FSP_FUSE_API int fsp_fuse_opt_add_opt_escaped(char **opts, const char *opt) +{ + return 0; +} + +FSP_FUSE_API int fsp_fuse_opt_add_arg(struct fuse_args *args, const char *arg) +{ + return 0; +} + +FSP_FUSE_API int fsp_fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg) +{ + return 0; +} + +FSP_FUSE_API void fsp_fuse_opt_free_args(struct fuse_args *args) +{ +} + +FSP_FUSE_API int fsp_fuse_opt_match(const struct fuse_opt opts[], const char *opt) +{ + return 0; +}