diff --git a/tst/passthrough-fuse/passthrough-fuse.c b/tst/passthrough-fuse/passthrough-fuse.c
index 5669e938..ef24fc6b 100644
--- a/tst/passthrough-fuse/passthrough-fuse.c
+++ b/tst/passthrough-fuse/passthrough-fuse.c
@@ -212,6 +212,10 @@ static void *ptfs_init(struct fuse_conn_info *conn)
conn->want |= (conn->capable & FSP_FUSE_CAP_READDIR_PLUS);
#endif
+#if defined(FSP_FUSE_USE_STAT_EX) && defined(FSP_FUSE_CAP_STAT_EX)
+ conn->want |= (conn->capable & FSP_FUSE_CAP_STAT_EX);
+#endif
+
#if defined(FSP_FUSE_CAP_CASE_INSENSITIVE)
conn->want |= (conn->capable & FSP_FUSE_CAP_CASE_INSENSITIVE);
#endif
@@ -242,43 +246,42 @@ static int ptfs_fgetattr(const char *path, struct fuse_stat *stbuf, struct fuse_
return -1 != fstat(fd, stbuf) ? 0 : -errno;
}
+#if defined(FSP_FUSE_USE_STAT_EX)
+static int ptfs_chflags(const char *path, uint32_t flags)
+{
+ ptfs_impl_fullpath(path);
+
+ return -1 != lchflags(path, flags) ? 0 : -errno;
+}
+#endif
+
static struct fuse_operations ptfs_ops =
{
- ptfs_getattr,
- 0, //getdir
- 0, //readlink
- 0, //mknod
- ptfs_mkdir,
- ptfs_unlink,
- ptfs_rmdir,
- 0, //symlink
- ptfs_rename,
- 0, //link
- ptfs_chmod,
- ptfs_chown,
- ptfs_truncate,
- ptfs_utime,
- ptfs_open,
- ptfs_read,
- ptfs_write,
- ptfs_statfs,
- 0, //flush
- ptfs_release,
- ptfs_fsync,
- 0, //setxattr
- 0, //getxattr
- 0, //listxattr
- 0, //removexattr
- ptfs_opendir,
- ptfs_readdir,
- ptfs_releasedir,
- 0, //fsyncdir
- ptfs_init,
- 0, //destroy
- 0, //access
- ptfs_create,
- ptfs_ftruncate,
- ptfs_fgetattr,
+ .getattr = ptfs_getattr,
+ .mkdir = ptfs_mkdir,
+ .unlink = ptfs_unlink,
+ .rmdir = ptfs_rmdir,
+ .rename = ptfs_rename,
+ .chmod = ptfs_chmod,
+ .chown = ptfs_chown,
+ .truncate = ptfs_truncate,
+ .utime = ptfs_utime,
+ .open = ptfs_open,
+ .read = ptfs_read,
+ .write = ptfs_write,
+ .statfs = ptfs_statfs,
+ .release = ptfs_release,
+ .fsync = ptfs_fsync,
+ .opendir = ptfs_opendir,
+ .readdir = ptfs_readdir,
+ .releasedir = ptfs_releasedir,
+ .init = ptfs_init,
+ .create = ptfs_create,
+ .ftruncate = ptfs_ftruncate,
+ .fgetattr = ptfs_fgetattr,
+#if defined(FSP_FUSE_USE_STAT_EX)
+ .chflags = ptfs_chflags,
+#endif
};
static void usage(void)
diff --git a/tst/passthrough-fuse/passthrough-fuse.vcxproj b/tst/passthrough-fuse/passthrough-fuse.vcxproj
index 1d0c6a5e..f411ca40 100644
--- a/tst/passthrough-fuse/passthrough-fuse.vcxproj
+++ b/tst/passthrough-fuse/passthrough-fuse.vcxproj
@@ -99,7 +99,7 @@
Level3
Disabled
- WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ FSP_FUSE_USE_STAT_EX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
$(MSBuildProgramFiles32)\WinFsp\inc\fuse;$(MSBuildProgramFiles32)\WinFsp\inc
MultiThreaded
@@ -118,7 +118,7 @@
Level3
Disabled
- _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ FSP_FUSE_USE_STAT_EX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
$(MSBuildProgramFiles32)\WinFsp\inc\fuse;$(MSBuildProgramFiles32)\WinFsp\inc
MultiThreaded
@@ -139,7 +139,7 @@
MaxSpeed
true
true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ FSP_FUSE_USE_STAT_EX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
$(MSBuildProgramFiles32)\WinFsp\inc\fuse;$(MSBuildProgramFiles32)\WinFsp\inc
MultiThreaded
@@ -162,7 +162,7 @@
MaxSpeed
true
true
- NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ FSP_FUSE_USE_STAT_EX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
$(MSBuildProgramFiles32)\WinFsp\inc\fuse;$(MSBuildProgramFiles32)\WinFsp\inc
MultiThreaded
diff --git a/tst/passthrough-fuse/winposix.c b/tst/passthrough-fuse/winposix.c
index c7c7edc2..cada2977 100644
--- a/tst/passthrough-fuse/winposix.c
+++ b/tst/passthrough-fuse/winposix.c
@@ -1,5 +1,5 @@
/**
- * @file passthrough-fuse.c
+ * @file winposix.c
*
* @copyright 2015-2017 Bill Zissimopoulos
*/
@@ -36,6 +36,40 @@ struct _DIR
char path[];
};
+#if defined(FSP_FUSE_USE_STAT_EX)
+static inline uint32_t 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 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;
+}
+#endif
+
static int maperror(int winerrno);
static inline void *error0(void)
@@ -173,6 +207,9 @@ int fstat(int fd, struct fuse_stat *stbuf)
stbuf->st_ctim.tv_nsec = LastWriteTime % 10000000 * 100;
stbuf->st_birthtim.tv_sec = CreationTime / 10000000;
stbuf->st_birthtim.tv_nsec = CreationTime % 10000000 * 100;
+#if defined(FSP_FUSE_USE_STAT_EX)
+ stbuf->st_flags = MapFileAttributesToFlags(FileInfo.dwFileAttributes);
+#endif
return 0;
}
@@ -272,6 +309,21 @@ int lchown(const char *path, fuse_uid_t uid, fuse_gid_t gid)
return 0;
}
+int lchflags(const char *path, uint32_t flags)
+{
+#if defined(FSP_FUSE_USE_STAT_EX)
+ UINT32 FileAttributes = MapFlagsToFileAttributes(flags);
+
+ if (0 == FileAttributes)
+ FileAttributes = FILE_ATTRIBUTE_NORMAL;
+
+ if (!SetFileAttributesA(path, FileAttributes))
+ return error();
+#endif
+
+ return 0;
+}
+
int truncate(const char *path, fuse_off_t size)
{
HANDLE h = CreateFileA(path,
@@ -424,6 +476,9 @@ struct dirent *readdir(DIR *dirp)
stbuf->st_ctim.tv_nsec = LastWriteTime % 10000000 * 100;
stbuf->st_birthtim.tv_sec = CreationTime / 10000000;
stbuf->st_birthtim.tv_nsec = CreationTime % 10000000 * 100;
+#if defined(FSP_FUSE_USE_STAT_EX)
+ stbuf->st_flags = MapFileAttributesToFlags(FindData.dwFileAttributes);
+#endif
strcpy(dirp->de.d_name, FindData.cFileName);
diff --git a/tst/passthrough-fuse/winposix.h b/tst/passthrough-fuse/winposix.h
index 5bc09660..a7f8cff2 100644
--- a/tst/passthrough-fuse/winposix.h
+++ b/tst/passthrough-fuse/winposix.h
@@ -50,6 +50,7 @@ int close(int fd);
int lstat(const char *path, struct fuse_stat *stbuf);
int chmod(const char *path, fuse_mode_t mode);
int lchown(const char *path, fuse_uid_t uid, fuse_gid_t gid);
+int lchflags(const char *path, uint32_t flags);
int truncate(const char *path, fuse_off_t size);
int utime(const char *path, const struct fuse_utimbuf *timbuf);
int unlink(const char *path);