mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	tst: passthrough-fuse3
This commit is contained in:
		
							
								
								
									
										7
									
								
								tst/passthrough-fuse3/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tst/passthrough-fuse3/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | build | ||||||
|  | *.ncb | ||||||
|  | *.suo | ||||||
|  | *.vcproj.* | ||||||
|  | *.vcxproj.user | ||||||
|  | *.exe | ||||||
|  | *.install | ||||||
							
								
								
									
										18
									
								
								tst/passthrough-fuse3/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tst/passthrough-fuse3/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | usage: | ||||||
|  | 	@echo "make cygfuse3|winfsp-fuse3" 1>&2 | ||||||
|  | 	@echo "" 1>&2 | ||||||
|  | 	@echo "   cygfuse3        Link with CYGFUSE3" 1>&2 | ||||||
|  | 	@echo "   winfsp-fuse3    Link with WinFsp-FUSE3" 1>&2 | ||||||
|  | 	@exit 2 | ||||||
|  |  | ||||||
|  | cygfuse3: passthrough-cygfuse3 | ||||||
|  |  | ||||||
|  | winfsp-fuse3: passthrough-winfsp-fuse3 | ||||||
|  |  | ||||||
|  | passthrough-cygfuse3: passthrough-fuse3.c | ||||||
|  | 	gcc $^ -o $@ -g -Wall `pkg-config fuse3 --cflags --libs` | ||||||
|  |  | ||||||
|  | passthrough-winfsp-fuse3: export PKG_CONFIG_PATH=$(PWD)/winfsp.install/lib | ||||||
|  | passthrough-winfsp-fuse3: passthrough-fuse3.c | ||||||
|  | 	ln -nsf "`regtool --wow32 get '/HKLM/Software/WinFsp/InstallDir' | cygpath -au -f -`" winfsp.install | ||||||
|  | 	gcc $^ -o $@ -g -Wall `pkg-config fuse3 --cflags --libs` | ||||||
							
								
								
									
										7
									
								
								tst/passthrough-fuse3/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tst/passthrough-fuse3/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | `Passthrough-fuse3` is a simple FUSE3 file system that passes all file system operations to an underlying file system. | ||||||
|  |  | ||||||
|  | It can be built with the following tools: | ||||||
|  |  | ||||||
|  | - Using Visual Studio (`winfsp.sln`). | ||||||
|  | - Using Cygwin GCC and linking directly with the WinFsp DLL (`make winfsp-fuse3`). | ||||||
|  | - Using Cygwin GCC and linking to CYGFUSE3 (`make cygfuse3`). | ||||||
							
								
								
									
										331
									
								
								tst/passthrough-fuse3/passthrough-fuse3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										331
									
								
								tst/passthrough-fuse3/passthrough-fuse3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,331 @@ | |||||||
|  | /** | ||||||
|  |  * @file passthrough-fuse.c | ||||||
|  |  * | ||||||
|  |  * @copyright 2015-2018 Bill Zissimopoulos | ||||||
|  |  */ | ||||||
|  | /* | ||||||
|  |  * This file is part of WinFsp. | ||||||
|  |  * | ||||||
|  |  * You can redistribute it and/or modify it under the terms of the GNU | ||||||
|  |  * 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 <errno.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <limits.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | #include <fuse.h> | ||||||
|  |  | ||||||
|  | #if defined(_WIN64) || defined(_WIN32) | ||||||
|  | #include "winposix.h" | ||||||
|  | #else | ||||||
|  | #include <dirent.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #define FSNAME                          "passthrough" | ||||||
|  | #define PROGNAME                        "passthrough-fuse" | ||||||
|  |  | ||||||
|  | #define concat_path(ptfs, fn, fp)       (sizeof fp > (unsigned)snprintf(fp, sizeof fp, "%s%s", ptfs->rootdir, fn)) | ||||||
|  |  | ||||||
|  | #define fi_dirbit                       (0x8000000000000000ULL) | ||||||
|  | #define fi_fh(fi, MASK)                 ((fi)->fh & (MASK)) | ||||||
|  | #define fi_setfh(fi, FH, MASK)          ((fi)->fh = (intptr_t)(FH) | (MASK)) | ||||||
|  | #define fi_fd(fi)                       (fi_fh(fi, fi_dirbit) ? \ | ||||||
|  |     dirfd((DIR *)(intptr_t)fi_fh(fi, ~fi_dirbit)) : (int)fi_fh(fi, ~fi_dirbit)) | ||||||
|  | #define fi_dirp(fi)                     ((DIR *)(intptr_t)fi_fh(fi, ~fi_dirbit)) | ||||||
|  | #define fi_setfd(fi, fd)                (fi_setfh(fi, fd, 0)) | ||||||
|  | #define fi_setdirp(fi, dirp)            (fi_setfh(fi, dirp, fi_dirbit)) | ||||||
|  |  | ||||||
|  | #define ptfs_impl_fullpath(n)           \ | ||||||
|  |     char full ## n[PATH_MAX];           \ | ||||||
|  |     if (!concat_path(((PTFS *)fuse_get_context()->private_data), n, full ## n))\ | ||||||
|  |         return -ENAMETOOLONG;           \ | ||||||
|  |     n = full ## n | ||||||
|  |  | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |     const char *rootdir; | ||||||
|  | } PTFS; | ||||||
|  |  | ||||||
|  | static int ptfs_getattr(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     if (0 == fi) | ||||||
|  |     { | ||||||
|  |         ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |         return -1 != lstat(path, stbuf) ? 0 : -errno; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         int fd = fi_fd(fi); | ||||||
|  |  | ||||||
|  |         return -1 != fstat(fd, stbuf) ? 0 : -errno; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_mkdir(const char *path, fuse_mode_t mode) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     return -1 != mkdir(path, mode) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_unlink(const char *path) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     return -1 != unlink(path) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_rmdir(const char *path) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     return -1 != rmdir(path) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_rename(const char *oldpath, const char *newpath, unsigned int flags) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(newpath); | ||||||
|  |     ptfs_impl_fullpath(oldpath); | ||||||
|  |  | ||||||
|  |     return -1 != rename(oldpath, newpath) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_chmod(const char *path, fuse_mode_t mode, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     return -1 != chmod(path, mode) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_chown(const char *path, fuse_uid_t uid, fuse_gid_t gid, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     return -1 != lchown(path, uid, gid) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_truncate(const char *path, fuse_off_t size, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     if (0 == fi) | ||||||
|  |     { | ||||||
|  |         ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |         return -1 != truncate(path, size) ? 0 : -errno; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         int fd = fi_fd(fi); | ||||||
|  |  | ||||||
|  |         return -1 != ftruncate(fd, size) ? 0 : -errno; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_open(const char *path, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     int fd; | ||||||
|  |     return -1 != (fd = open(path, fi->flags)) ? (fi_setfd(fi, fd), 0) : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_read(const char *path, char *buf, size_t size, fuse_off_t off, | ||||||
|  |     struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     int fd = fi_fd(fi); | ||||||
|  |  | ||||||
|  |     int nb; | ||||||
|  |     return -1 != (nb = pread(fd, buf, size, off)) ? nb : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_write(const char *path, const char *buf, size_t size, fuse_off_t off, | ||||||
|  |     struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     int fd = fi_fd(fi); | ||||||
|  |  | ||||||
|  |     int nb; | ||||||
|  |     return -1 != (nb = pwrite(fd, buf, size, off)) ? nb : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_statfs(const char *path, struct fuse_statvfs *stbuf) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     return -1 != statvfs(path, stbuf) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_release(const char *path, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     int fd = fi_fd(fi); | ||||||
|  |  | ||||||
|  |     close(fd); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_fsync(const char *path, int datasync, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     int fd = fi_fd(fi); | ||||||
|  |  | ||||||
|  |     return -1 != fsync(fd) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_opendir(const char *path, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     DIR *dirp; | ||||||
|  |     return 0 != (dirp = opendir(path)) ? (fi_setdirp(fi, dirp), 0) : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_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) | ||||||
|  | { | ||||||
|  |     DIR *dirp = fi_dirp(fi); | ||||||
|  |     struct dirent *de; | ||||||
|  |  | ||||||
|  |     rewinddir(dirp); | ||||||
|  |     for (;;) | ||||||
|  |     { | ||||||
|  |         errno = 0; | ||||||
|  |         if (0 == (de = readdir(dirp))) | ||||||
|  |             break; | ||||||
|  | #if defined(_WIN64) || defined(_WIN32) | ||||||
|  |         if (0 != filler(buf, de->d_name, &de->d_stat, 0, FUSE_FILL_DIR_PLUS)) | ||||||
|  | #else | ||||||
|  |         if (0 != filler(buf, de->d_name, 0, 0, 0)) | ||||||
|  | #endif | ||||||
|  |             return -ENOMEM; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_releasedir(const char *path, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     DIR *dirp = fi_dirp(fi); | ||||||
|  |  | ||||||
|  |     return -1 != closedir(dirp) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void *ptfs_init(struct fuse_conn_info *conn, struct fuse_config *conf) | ||||||
|  | { | ||||||
|  |     conn->want |= (conn->capable & FUSE_CAP_READDIRPLUS); | ||||||
|  |  | ||||||
|  | #if defined(FSP_FUSE_CAP_CASE_INSENSITIVE) | ||||||
|  |     conn->want |= (conn->capable & FSP_FUSE_CAP_CASE_INSENSITIVE); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     return fuse_get_context()->private_data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_create(const char *path, fuse_mode_t mode, struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     int fd; | ||||||
|  |     return -1 != (fd = open(path, fi->flags, mode)) ? (fi_setfd(fi, fd), 0) : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ptfs_utimens(const char *path, const struct fuse_timespec tv[2], struct fuse_file_info *fi) | ||||||
|  | { | ||||||
|  |     ptfs_impl_fullpath(path); | ||||||
|  |  | ||||||
|  |     return -1 != utimensat(AT_FDCWD, path, tv, AT_SYMLINK_NOFOLLOW) ? 0 : -errno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static struct fuse_operations ptfs_ops = | ||||||
|  | { | ||||||
|  |     .getattr = ptfs_getattr, | ||||||
|  |     .mkdir = ptfs_mkdir, | ||||||
|  |     .unlink = ptfs_unlink, | ||||||
|  |     .rmdir = ptfs_rmdir, | ||||||
|  |     .rename = ptfs_rename, | ||||||
|  |     .chmod = ptfs_chmod, | ||||||
|  |     .chown = ptfs_chown, | ||||||
|  |     .truncate = ptfs_truncate, | ||||||
|  |     .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, | ||||||
|  |     .utimens = ptfs_utimens, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static void usage(void) | ||||||
|  | { | ||||||
|  |     fprintf(stderr, "usage: " PROGNAME " [FUSE options] rootdir mountpoint\n"); | ||||||
|  |     exit(2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  |     PTFS ptfs = { 0 }; | ||||||
|  |  | ||||||
|  |     if (3 <= argc && '-' != argv[argc - 2][0] && '-' != argv[argc - 1][0]) | ||||||
|  |     { | ||||||
|  |         ptfs.rootdir = realpath(argv[argc - 2], 0); /* memory freed at process end */ | ||||||
|  |         argv[argc - 2] = argv[argc - 1]; | ||||||
|  |         argc--; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if defined(_WIN64) || defined(_WIN32) | ||||||
|  |     /* | ||||||
|  |      * When building for Windows (rather than Cygwin or POSIX OS) | ||||||
|  |      * allow the path to be specified using the --VolumePrefix | ||||||
|  |      * switch using the syntax \\passthrough-fuse\C$\Path. This | ||||||
|  |      * allows us to run the file system under the WinFsp.Launcher | ||||||
|  |      * and start it using commands like: | ||||||
|  |      * | ||||||
|  |      *     net use z: \\passthrough-fuse\C$\Path | ||||||
|  |      */ | ||||||
|  |     if (0 == ptfs.rootdir) | ||||||
|  |         for (int argi = 1; argc > argi; argi++) | ||||||
|  |         { | ||||||
|  |             int strncmp(const char *a, const char *b, size_t length); | ||||||
|  |             char *strchr(const char *s, int c); | ||||||
|  |             char *p = 0; | ||||||
|  |  | ||||||
|  |             if (0 == strncmp("--UNC=", argv[argi], sizeof "--UNC=" - 1)) | ||||||
|  |                 p = argv[argi] + sizeof "--UNC=" - 1; | ||||||
|  |             else if (0 == strncmp("--VolumePrefix=", argv[argi], sizeof "--VolumePrefix=" - 1)) | ||||||
|  |                 p = argv[argi] + sizeof "--VolumePrefix=" - 1; | ||||||
|  |  | ||||||
|  |             if (0 != p && '\\' != p[1]) | ||||||
|  |             { | ||||||
|  |                 p = strchr(p + 1, '\\'); | ||||||
|  |                 if (0 != p && | ||||||
|  |                     ( | ||||||
|  |                     ('A' <= p[1] && p[1] <= 'Z') || | ||||||
|  |                     ('a' <= p[1] && p[1] <= 'z') | ||||||
|  |                     ) && | ||||||
|  |                     '$' == p[2]) | ||||||
|  |                 { | ||||||
|  |                     p[2] = ':'; | ||||||
|  |                     ptfs.rootdir = realpath(p + 1, 0); /* memory freed at process end */ | ||||||
|  |                     p[2] = '$'; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     if (0 == ptfs.rootdir) | ||||||
|  |         usage(); | ||||||
|  |  | ||||||
|  |     return fuse_main(argc, argv, &ptfs_ops, &ptfs); | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								tst/passthrough-fuse3/passthrough-fuse3.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tst/passthrough-fuse3/passthrough-fuse3.sln
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  |  | ||||||
|  | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||||
|  | # Visual Studio 14 | ||||||
|  | VisualStudioVersion = 14.0.25420.1 | ||||||
|  | MinimumVisualStudioVersion = 10.0.40219.1 | ||||||
|  | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "passthrough-fuse3", "passthrough-fuse3.vcxproj", "{5E99498C-D30C-48EF-A04A-7977C0305FAC}" | ||||||
|  | EndProject | ||||||
|  | Global | ||||||
|  | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
|  | 		Debug|x64 = Debug|x64 | ||||||
|  | 		Debug|x86 = Debug|x86 | ||||||
|  | 		Release|x64 = Release|x64 | ||||||
|  | 		Release|x86 = Release|x86 | ||||||
|  | 	EndGlobalSection | ||||||
|  | 	GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||||||
|  | 		{5E99498C-D30C-48EF-A04A-7977C0305FAC}.Debug|x64.ActiveCfg = Debug|x64 | ||||||
|  | 		{5E99498C-D30C-48EF-A04A-7977C0305FAC}.Debug|x64.Build.0 = Debug|x64 | ||||||
|  | 		{5E99498C-D30C-48EF-A04A-7977C0305FAC}.Debug|x86.ActiveCfg = Debug|Win32 | ||||||
|  | 		{5E99498C-D30C-48EF-A04A-7977C0305FAC}.Debug|x86.Build.0 = Debug|Win32 | ||||||
|  | 		{5E99498C-D30C-48EF-A04A-7977C0305FAC}.Release|x64.ActiveCfg = Release|x64 | ||||||
|  | 		{5E99498C-D30C-48EF-A04A-7977C0305FAC}.Release|x64.Build.0 = Release|x64 | ||||||
|  | 		{5E99498C-D30C-48EF-A04A-7977C0305FAC}.Release|x86.ActiveCfg = Release|Win32 | ||||||
|  | 		{5E99498C-D30C-48EF-A04A-7977C0305FAC}.Release|x86.Build.0 = Release|Win32 | ||||||
|  | 	EndGlobalSection | ||||||
|  | 	GlobalSection(SolutionProperties) = preSolution | ||||||
|  | 		HideSolutionNode = FALSE | ||||||
|  | 	EndGlobalSection | ||||||
|  | EndGlobal | ||||||
							
								
								
									
										190
									
								
								tst/passthrough-fuse3/passthrough-fuse3.vcxproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								tst/passthrough-fuse3/passthrough-fuse3.vcxproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|  |   <ItemGroup Label="ProjectConfigurations"> | ||||||
|  |     <ProjectConfiguration Include="Debug|Win32"> | ||||||
|  |       <Configuration>Debug</Configuration> | ||||||
|  |       <Platform>Win32</Platform> | ||||||
|  |     </ProjectConfiguration> | ||||||
|  |     <ProjectConfiguration Include="Release|Win32"> | ||||||
|  |       <Configuration>Release</Configuration> | ||||||
|  |       <Platform>Win32</Platform> | ||||||
|  |     </ProjectConfiguration> | ||||||
|  |     <ProjectConfiguration Include="Debug|x64"> | ||||||
|  |       <Configuration>Debug</Configuration> | ||||||
|  |       <Platform>x64</Platform> | ||||||
|  |     </ProjectConfiguration> | ||||||
|  |     <ProjectConfiguration Include="Release|x64"> | ||||||
|  |       <Configuration>Release</Configuration> | ||||||
|  |       <Platform>x64</Platform> | ||||||
|  |     </ProjectConfiguration> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <PropertyGroup Label="Globals"> | ||||||
|  |     <ProjectGuid>{5E99498C-D30C-48EF-A04A-7977C0305FAC}</ProjectGuid> | ||||||
|  |     <Keyword>Win32Proj</Keyword> | ||||||
|  |     <RootNamespace>passthroughfuse3</RootNamespace> | ||||||
|  |     <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||||
|  |     <ConfigurationType>Application</ConfigurationType> | ||||||
|  |     <UseDebugLibraries>true</UseDebugLibraries> | ||||||
|  |     <PlatformToolset>v140</PlatformToolset> | ||||||
|  |     <CharacterSet>Unicode</CharacterSet> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||||
|  |     <ConfigurationType>Application</ConfigurationType> | ||||||
|  |     <UseDebugLibraries>false</UseDebugLibraries> | ||||||
|  |     <PlatformToolset>v140</PlatformToolset> | ||||||
|  |     <WholeProgramOptimization>true</WholeProgramOptimization> | ||||||
|  |     <CharacterSet>Unicode</CharacterSet> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | ||||||
|  |     <ConfigurationType>Application</ConfigurationType> | ||||||
|  |     <UseDebugLibraries>true</UseDebugLibraries> | ||||||
|  |     <PlatformToolset>v140</PlatformToolset> | ||||||
|  |     <CharacterSet>Unicode</CharacterSet> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | ||||||
|  |     <ConfigurationType>Application</ConfigurationType> | ||||||
|  |     <UseDebugLibraries>false</UseDebugLibraries> | ||||||
|  |     <PlatformToolset>v140</PlatformToolset> | ||||||
|  |     <WholeProgramOptimization>true</WholeProgramOptimization> | ||||||
|  |     <CharacterSet>Unicode</CharacterSet> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||||
|  |   <ImportGroup Label="ExtensionSettings"> | ||||||
|  |   </ImportGroup> | ||||||
|  |   <ImportGroup Label="Shared"> | ||||||
|  |   </ImportGroup> | ||||||
|  |   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||||
|  |     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||||
|  |   </ImportGroup> | ||||||
|  |   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||||
|  |     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||||
|  |   </ImportGroup> | ||||||
|  |   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||||||
|  |     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||||
|  |   </ImportGroup> | ||||||
|  |   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||||||
|  |     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||||
|  |   </ImportGroup> | ||||||
|  |   <PropertyGroup Label="UserMacros" /> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||||
|  |     <LinkIncremental>true</LinkIncremental> | ||||||
|  |     <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> | ||||||
|  |     <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> | ||||||
|  |     <TargetName>$(ProjectName)-$(PlatformTarget)</TargetName> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||||||
|  |     <LinkIncremental>true</LinkIncremental> | ||||||
|  |     <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> | ||||||
|  |     <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> | ||||||
|  |     <TargetName>$(ProjectName)-$(PlatformTarget)</TargetName> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||||
|  |     <LinkIncremental>false</LinkIncremental> | ||||||
|  |     <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> | ||||||
|  |     <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> | ||||||
|  |     <TargetName>$(ProjectName)-$(PlatformTarget)</TargetName> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||||||
|  |     <LinkIncremental>false</LinkIncremental> | ||||||
|  |     <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> | ||||||
|  |     <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> | ||||||
|  |     <TargetName>$(ProjectName)-$(PlatformTarget)</TargetName> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||||
|  |     <ClCompile> | ||||||
|  |       <PrecompiledHeader> | ||||||
|  |       </PrecompiledHeader> | ||||||
|  |       <WarningLevel>Level3</WarningLevel> | ||||||
|  |       <Optimization>Disabled</Optimization> | ||||||
|  |       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||||
|  |       <SDLCheck>true</SDLCheck> | ||||||
|  |       <AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\WinFsp\inc\fuse3;$(MSBuildProgramFiles32)\WinFsp\inc</AdditionalIncludeDirectories> | ||||||
|  |       <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | ||||||
|  |       <DisableSpecificWarnings>4996</DisableSpecificWarnings> | ||||||
|  |     </ClCompile> | ||||||
|  |     <Link> | ||||||
|  |       <SubSystem>Console</SubSystem> | ||||||
|  |       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||||
|  |       <AdditionalDependencies>$(MSBuildProgramFiles32)\WinFsp\lib\winfsp-$(PlatformTarget).lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||||
|  |       <DelayLoadDLLs>winfsp-$(PlatformTarget).dll</DelayLoadDLLs> | ||||||
|  |     </Link> | ||||||
|  |   </ItemDefinitionGroup> | ||||||
|  |   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||||||
|  |     <ClCompile> | ||||||
|  |       <PrecompiledHeader> | ||||||
|  |       </PrecompiledHeader> | ||||||
|  |       <WarningLevel>Level3</WarningLevel> | ||||||
|  |       <Optimization>Disabled</Optimization> | ||||||
|  |       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||||
|  |       <SDLCheck>true</SDLCheck> | ||||||
|  |       <AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\WinFsp\inc\fuse3;$(MSBuildProgramFiles32)\WinFsp\inc</AdditionalIncludeDirectories> | ||||||
|  |       <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | ||||||
|  |       <DisableSpecificWarnings>4996</DisableSpecificWarnings> | ||||||
|  |     </ClCompile> | ||||||
|  |     <Link> | ||||||
|  |       <SubSystem>Console</SubSystem> | ||||||
|  |       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||||
|  |       <AdditionalDependencies>$(MSBuildProgramFiles32)\WinFsp\lib\winfsp-$(PlatformTarget).lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||||
|  |       <DelayLoadDLLs>winfsp-$(PlatformTarget).dll</DelayLoadDLLs> | ||||||
|  |     </Link> | ||||||
|  |   </ItemDefinitionGroup> | ||||||
|  |   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||||
|  |     <ClCompile> | ||||||
|  |       <WarningLevel>Level3</WarningLevel> | ||||||
|  |       <PrecompiledHeader> | ||||||
|  |       </PrecompiledHeader> | ||||||
|  |       <Optimization>MaxSpeed</Optimization> | ||||||
|  |       <FunctionLevelLinking>true</FunctionLevelLinking> | ||||||
|  |       <IntrinsicFunctions>true</IntrinsicFunctions> | ||||||
|  |       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||||
|  |       <SDLCheck>true</SDLCheck> | ||||||
|  |       <AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\WinFsp\inc\fuse3;$(MSBuildProgramFiles32)\WinFsp\inc</AdditionalIncludeDirectories> | ||||||
|  |       <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | ||||||
|  |       <DisableSpecificWarnings>4996</DisableSpecificWarnings> | ||||||
|  |     </ClCompile> | ||||||
|  |     <Link> | ||||||
|  |       <SubSystem>Console</SubSystem> | ||||||
|  |       <EnableCOMDATFolding>true</EnableCOMDATFolding> | ||||||
|  |       <OptimizeReferences>true</OptimizeReferences> | ||||||
|  |       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||||
|  |       <AdditionalDependencies>$(MSBuildProgramFiles32)\WinFsp\lib\winfsp-$(PlatformTarget).lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||||
|  |       <DelayLoadDLLs>winfsp-$(PlatformTarget).dll</DelayLoadDLLs> | ||||||
|  |     </Link> | ||||||
|  |   </ItemDefinitionGroup> | ||||||
|  |   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||||||
|  |     <ClCompile> | ||||||
|  |       <WarningLevel>Level3</WarningLevel> | ||||||
|  |       <PrecompiledHeader> | ||||||
|  |       </PrecompiledHeader> | ||||||
|  |       <Optimization>MaxSpeed</Optimization> | ||||||
|  |       <FunctionLevelLinking>true</FunctionLevelLinking> | ||||||
|  |       <IntrinsicFunctions>true</IntrinsicFunctions> | ||||||
|  |       <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||||
|  |       <SDLCheck>true</SDLCheck> | ||||||
|  |       <AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\WinFsp\inc\fuse3;$(MSBuildProgramFiles32)\WinFsp\inc</AdditionalIncludeDirectories> | ||||||
|  |       <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | ||||||
|  |       <DisableSpecificWarnings>4996</DisableSpecificWarnings> | ||||||
|  |     </ClCompile> | ||||||
|  |     <Link> | ||||||
|  |       <SubSystem>Console</SubSystem> | ||||||
|  |       <EnableCOMDATFolding>true</EnableCOMDATFolding> | ||||||
|  |       <OptimizeReferences>true</OptimizeReferences> | ||||||
|  |       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||||
|  |       <AdditionalDependencies>$(MSBuildProgramFiles32)\WinFsp\lib\winfsp-$(PlatformTarget).lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||||
|  |       <DelayLoadDLLs>winfsp-$(PlatformTarget).dll</DelayLoadDLLs> | ||||||
|  |     </Link> | ||||||
|  |   </ItemDefinitionGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ClCompile Include="passthrough-fuse3.c" /> | ||||||
|  |     <ClCompile Include="winposix.c" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ClInclude Include="winposix.h" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||||
|  |   <ImportGroup Label="ExtensionTargets"> | ||||||
|  |   </ImportGroup> | ||||||
|  | </Project> | ||||||
							
								
								
									
										21
									
								
								tst/passthrough-fuse3/passthrough-fuse3.vcxproj.filters
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tst/passthrough-fuse3/passthrough-fuse3.vcxproj.filters
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Filter Include="Source"> | ||||||
|  |       <UniqueIdentifier>{bfbcc136-ea14-4445-8f9b-1fa7f8aedc71}</UniqueIdentifier> | ||||||
|  |     </Filter> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ClCompile Include="passthrough-fuse3.c"> | ||||||
|  |       <Filter>Source</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="winposix.c"> | ||||||
|  |       <Filter>Source</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ClInclude Include="winposix.h"> | ||||||
|  |       <Filter>Source</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |   </ItemGroup> | ||||||
|  | </Project> | ||||||
							
								
								
									
										634
									
								
								tst/passthrough-fuse3/winposix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										634
									
								
								tst/passthrough-fuse3/winposix.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,634 @@ | |||||||
|  | /** | ||||||
|  |  * @file winposix.c | ||||||
|  |  * | ||||||
|  |  * @copyright 2015-2018 Bill Zissimopoulos | ||||||
|  |  */ | ||||||
|  | /* | ||||||
|  |  * This file is part of WinFsp. | ||||||
|  |  * | ||||||
|  |  * You can redistribute it and/or modify it under the terms of the GNU | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * This is a very simple Windows POSIX layer. It handles all the POSIX | ||||||
|  |  * file API's required to implement passthrough-fuse in POSIX, however | ||||||
|  |  * the API handling is rather unsophisticated. | ||||||
|  |  * | ||||||
|  |  * Ways to improve it: use the FspPosix* API's to properly handle | ||||||
|  |  * file names and security. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <winfsp/winfsp.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <fuse.h> | ||||||
|  | #include "winposix.h" | ||||||
|  |  | ||||||
|  | struct _DIR | ||||||
|  | { | ||||||
|  |     HANDLE h, fh; | ||||||
|  |     struct dirent de; | ||||||
|  |     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) | ||||||
|  | { | ||||||
|  |     errno = maperror(GetLastError()); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline int error(void) | ||||||
|  | { | ||||||
|  |     errno = maperror(GetLastError()); | ||||||
|  |     return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char *realpath(const char *path, char *resolved) | ||||||
|  | { | ||||||
|  |     char *result; | ||||||
|  |  | ||||||
|  |     if (0 == resolved) | ||||||
|  |     { | ||||||
|  |         result = malloc(PATH_MAX); /* sets errno */ | ||||||
|  |         if (0 == result) | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |         result = resolved; | ||||||
|  |  | ||||||
|  |     int err = 0; | ||||||
|  |     DWORD len = GetFullPathNameA(path, PATH_MAX, result, 0); | ||||||
|  |     if (0 == len) | ||||||
|  |         err = GetLastError(); | ||||||
|  |     else if (PATH_MAX < len) | ||||||
|  |         err = ERROR_INVALID_PARAMETER; | ||||||
|  |  | ||||||
|  |     if (0 == err) | ||||||
|  |     { | ||||||
|  |         HANDLE h = CreateFileA(result, | ||||||
|  |             FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||||||
|  |             0, | ||||||
|  |             OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); | ||||||
|  |         if (INVALID_HANDLE_VALUE != h) | ||||||
|  |             CloseHandle(h); | ||||||
|  |         else | ||||||
|  |             err = GetLastError(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (0 != err) | ||||||
|  |     { | ||||||
|  |         if (result != resolved) | ||||||
|  |             free(result); | ||||||
|  |  | ||||||
|  |         errno = maperror(err); | ||||||
|  |         result = 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int statvfs(const char *path, struct fuse_statvfs *stbuf) | ||||||
|  | { | ||||||
|  |     char root[PATH_MAX]; | ||||||
|  |     DWORD | ||||||
|  |         VolumeSerialNumber, | ||||||
|  |         MaxComponentLength, | ||||||
|  |         SectorsPerCluster, | ||||||
|  |         BytesPerSector, | ||||||
|  |         NumberOfFreeClusters, | ||||||
|  |         TotalNumberOfClusters; | ||||||
|  |  | ||||||
|  |     if (!GetVolumePathNameA(path, root, PATH_MAX) || | ||||||
|  |         !GetVolumeInformationA(root, 0, 0, &VolumeSerialNumber, &MaxComponentLength, 0, 0, 0) || | ||||||
|  |         !GetDiskFreeSpaceA(root, &SectorsPerCluster, &BytesPerSector, | ||||||
|  |             &NumberOfFreeClusters, &TotalNumberOfClusters)) | ||||||
|  |     { | ||||||
|  |         return error(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     memset(stbuf, 0, sizeof *stbuf); | ||||||
|  |     stbuf->f_bsize = SectorsPerCluster * BytesPerSector; | ||||||
|  |     stbuf->f_frsize = SectorsPerCluster * BytesPerSector; | ||||||
|  |     stbuf->f_blocks = TotalNumberOfClusters; | ||||||
|  |     stbuf->f_bfree = NumberOfFreeClusters; | ||||||
|  |     stbuf->f_bavail = TotalNumberOfClusters; | ||||||
|  |     stbuf->f_fsid = VolumeSerialNumber; | ||||||
|  |     stbuf->f_namemax = MaxComponentLength; | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int open(const char *path, int oflag, ...) | ||||||
|  | { | ||||||
|  |     static DWORD da[] = { GENERIC_READ, GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE, 0 }; | ||||||
|  |     static DWORD cd[] = { OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXISTING, CREATE_ALWAYS }; | ||||||
|  |     DWORD DesiredAccess = 0 == (oflag & _O_APPEND) ? | ||||||
|  |         da[oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)] : | ||||||
|  |         (da[oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)] & ~FILE_WRITE_DATA) | FILE_APPEND_DATA; | ||||||
|  |     DWORD CreationDisposition = (_O_CREAT | _O_EXCL) == (oflag & (_O_CREAT | _O_EXCL)) ? | ||||||
|  |         CREATE_NEW : | ||||||
|  |         cd[(oflag & (_O_CREAT | _O_TRUNC)) >> 8]; | ||||||
|  |  | ||||||
|  |     HANDLE h = CreateFileA(path, | ||||||
|  |         DesiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||||||
|  |         0/* default security */, | ||||||
|  |         CreationDisposition, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0); | ||||||
|  |  | ||||||
|  |     if (INVALID_HANDLE_VALUE == h) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return (int)(intptr_t)h; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int fstat(int fd, struct fuse_stat *stbuf) | ||||||
|  | { | ||||||
|  |     HANDLE h = (HANDLE)(intptr_t)fd; | ||||||
|  |     BY_HANDLE_FILE_INFORMATION FileInfo; | ||||||
|  |  | ||||||
|  |     if (!GetFileInformationByHandle(h, &FileInfo)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     memset(stbuf, 0, sizeof *stbuf); | ||||||
|  |     stbuf->st_mode = 0777 | | ||||||
|  |         ((FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 0040000/* S_IFDIR */ : 0); | ||||||
|  |     stbuf->st_nlink = 1; | ||||||
|  |     stbuf->st_size = ((UINT64)FileInfo.nFileSizeHigh << 32) | ((UINT64)FileInfo.nFileSizeLow); | ||||||
|  |     FspPosixFileTimeToUnixTime(*(PUINT64)&FileInfo.ftCreationTime, (void *)&stbuf->st_birthtim); | ||||||
|  |     FspPosixFileTimeToUnixTime(*(PUINT64)&FileInfo.ftLastAccessTime, (void *)&stbuf->st_atim); | ||||||
|  |     FspPosixFileTimeToUnixTime(*(PUINT64)&FileInfo.ftLastWriteTime, (void *)&stbuf->st_mtim); | ||||||
|  |     FspPosixFileTimeToUnixTime(*(PUINT64)&FileInfo.ftLastWriteTime, (void *)&stbuf->st_ctim); | ||||||
|  | #if defined(FSP_FUSE_USE_STAT_EX) | ||||||
|  |     stbuf->st_flags = MapFileAttributesToFlags(FileInfo.dwFileAttributes); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ftruncate(int fd, fuse_off_t size) | ||||||
|  | { | ||||||
|  |     HANDLE h = (HANDLE)(intptr_t)fd; | ||||||
|  |     FILE_END_OF_FILE_INFO EndOfFileInfo; | ||||||
|  |  | ||||||
|  |     EndOfFileInfo.EndOfFile.QuadPart = size; | ||||||
|  |  | ||||||
|  |     if (!SetFileInformationByHandle(h, FileEndOfFileInfo, &EndOfFileInfo, sizeof EndOfFileInfo)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int pread(int fd, void *buf, size_t nbyte, fuse_off_t offset) | ||||||
|  | { | ||||||
|  |     HANDLE h = (HANDLE)(intptr_t)fd; | ||||||
|  |     OVERLAPPED Overlapped = { 0 }; | ||||||
|  |     DWORD BytesTransferred; | ||||||
|  |  | ||||||
|  |     Overlapped.Offset = (DWORD)offset; | ||||||
|  |     Overlapped.OffsetHigh = (DWORD)(offset >> 32); | ||||||
|  |  | ||||||
|  |     if (!ReadFile(h, buf, (DWORD)nbyte, &BytesTransferred, &Overlapped)) | ||||||
|  |     { | ||||||
|  |         if (ERROR_HANDLE_EOF == GetLastError()) | ||||||
|  |             return 0; | ||||||
|  |         return error(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return BytesTransferred; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int pwrite(int fd, const void *buf, size_t nbyte, fuse_off_t offset) | ||||||
|  | { | ||||||
|  |     HANDLE h = (HANDLE)(intptr_t)fd; | ||||||
|  |     OVERLAPPED Overlapped = { 0 }; | ||||||
|  |     DWORD BytesTransferred; | ||||||
|  |  | ||||||
|  |     Overlapped.Offset = (DWORD)offset; | ||||||
|  |     Overlapped.OffsetHigh = (DWORD)(offset >> 32); | ||||||
|  |  | ||||||
|  |     if (!WriteFile(h, buf, (DWORD)nbyte, &BytesTransferred, &Overlapped)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return BytesTransferred; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int fsync(int fd) | ||||||
|  | { | ||||||
|  |     HANDLE h = (HANDLE)(intptr_t)fd; | ||||||
|  |  | ||||||
|  |     if (!FlushFileBuffers(h)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int close(int fd) | ||||||
|  | { | ||||||
|  |     HANDLE h = (HANDLE)(intptr_t)fd; | ||||||
|  |  | ||||||
|  |     if (!CloseHandle(h)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int lstat(const char *path, struct fuse_stat *stbuf) | ||||||
|  | { | ||||||
|  |     HANDLE h = CreateFileA(path, | ||||||
|  |         FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||||||
|  |         0, | ||||||
|  |         OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); | ||||||
|  |     if (INVALID_HANDLE_VALUE == h) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     int res = fstat((int)(intptr_t)h, stbuf); | ||||||
|  |  | ||||||
|  |     CloseHandle(h); | ||||||
|  |  | ||||||
|  |     return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int chmod(const char *path, fuse_mode_t mode) | ||||||
|  | { | ||||||
|  |     /* we do not support file security */ | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int lchown(const char *path, fuse_uid_t uid, fuse_gid_t gid) | ||||||
|  | { | ||||||
|  |     /* we do not support file security */ | ||||||
|  |     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, | ||||||
|  |         FILE_WRITE_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||||||
|  |         0, | ||||||
|  |         OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); | ||||||
|  |     if (INVALID_HANDLE_VALUE == h) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     int res = ftruncate((int)(intptr_t)h, size); | ||||||
|  |  | ||||||
|  |     CloseHandle(h); | ||||||
|  |  | ||||||
|  |     return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int utime(const char *path, const struct fuse_utimbuf *timbuf) | ||||||
|  | { | ||||||
|  |     if (0 == timbuf) | ||||||
|  |         return utimensat(AT_FDCWD, path, 0, AT_SYMLINK_NOFOLLOW); | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         struct fuse_timespec times[2]; | ||||||
|  |         times[0].tv_sec = timbuf->actime; | ||||||
|  |         times[0].tv_nsec = 0; | ||||||
|  |         times[1].tv_sec = timbuf->modtime; | ||||||
|  |         times[1].tv_nsec = 0; | ||||||
|  |         return utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int utimensat(int dirfd, const char *path, const struct fuse_timespec times[2], int flag) | ||||||
|  | { | ||||||
|  |     /* ignore dirfd and assume that it is always AT_FDCWD */ | ||||||
|  |     /* ignore flag and assume that it is always AT_SYMLINK_NOFOLLOW */ | ||||||
|  |  | ||||||
|  |     HANDLE h = CreateFileA(path, | ||||||
|  |         FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||||||
|  |         0, | ||||||
|  |         OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); | ||||||
|  |     if (INVALID_HANDLE_VALUE == h) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     UINT64 LastAccessTime, LastWriteTime; | ||||||
|  |     if (0 == times) | ||||||
|  |     { | ||||||
|  |         FILETIME FileTime; | ||||||
|  |         GetSystemTimeAsFileTime(&FileTime); | ||||||
|  |         LastAccessTime = LastWriteTime = *(PUINT64)&FileTime; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         FspPosixUnixTimeToFileTime((void *)×[0], &LastAccessTime); | ||||||
|  |         FspPosixUnixTimeToFileTime((void *)×[1], &LastWriteTime); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     int res = SetFileTime(h, | ||||||
|  |         0, (PFILETIME)&LastAccessTime, (PFILETIME)&LastWriteTime) ? 0 : error(); | ||||||
|  |  | ||||||
|  |     CloseHandle(h); | ||||||
|  |  | ||||||
|  |     return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int setcrtime(const char *path, const struct fuse_timespec *tv) | ||||||
|  | { | ||||||
|  |     HANDLE h = CreateFileA(path, | ||||||
|  |         FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||||||
|  |         0, | ||||||
|  |         OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); | ||||||
|  |     if (INVALID_HANDLE_VALUE == h) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     UINT64 CreationTime; | ||||||
|  |     FspPosixUnixTimeToFileTime((void *)tv, &CreationTime); | ||||||
|  |  | ||||||
|  |     int res = SetFileTime(h, | ||||||
|  |         (PFILETIME)&CreationTime, 0, 0) ? 0 : error(); | ||||||
|  |  | ||||||
|  |     CloseHandle(h); | ||||||
|  |  | ||||||
|  |     return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int unlink(const char *path) | ||||||
|  | { | ||||||
|  |     if (!DeleteFileA(path)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int rename(const char *oldpath, const char *newpath) | ||||||
|  | { | ||||||
|  |     if (!MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int mkdir(const char *path, fuse_mode_t mode) | ||||||
|  | { | ||||||
|  |     if (!CreateDirectoryA(path, 0/* default security */)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int rmdir(const char *path) | ||||||
|  | { | ||||||
|  |     if (!RemoveDirectoryA(path)) | ||||||
|  |         return error(); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | DIR *opendir(const char *path) | ||||||
|  | { | ||||||
|  |     HANDLE h = CreateFileA(path, | ||||||
|  |         FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||||||
|  |         0, | ||||||
|  |         OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); | ||||||
|  |     if (INVALID_HANDLE_VALUE == h) | ||||||
|  |         return error0(); | ||||||
|  |  | ||||||
|  |     size_t pathlen = strlen(path); | ||||||
|  |     if (0 < pathlen && '/' == path[pathlen - 1]) | ||||||
|  |         pathlen--; | ||||||
|  |  | ||||||
|  |     DIR *dirp = malloc(sizeof *dirp + pathlen + 3); /* sets errno */ | ||||||
|  |     if (0 == dirp) | ||||||
|  |     { | ||||||
|  |         CloseHandle(h); | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     memset(dirp, 0, sizeof *dirp); | ||||||
|  |     dirp->h = h; | ||||||
|  |     dirp->fh = INVALID_HANDLE_VALUE; | ||||||
|  |     memcpy(dirp->path, path, pathlen); | ||||||
|  |     dirp->path[pathlen + 0] = '/'; | ||||||
|  |     dirp->path[pathlen + 1] = '*'; | ||||||
|  |     dirp->path[pathlen + 2] = '\0'; | ||||||
|  |  | ||||||
|  |     return dirp; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int dirfd(DIR *dirp) | ||||||
|  | { | ||||||
|  |     return (int)(intptr_t)dirp->h; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void rewinddir(DIR *dirp) | ||||||
|  | { | ||||||
|  |     if (INVALID_HANDLE_VALUE != dirp->fh) | ||||||
|  |     { | ||||||
|  |         FindClose(dirp->fh); | ||||||
|  |         dirp->fh = INVALID_HANDLE_VALUE; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct dirent *readdir(DIR *dirp) | ||||||
|  | { | ||||||
|  |     WIN32_FIND_DATAA FindData; | ||||||
|  |     struct fuse_stat *stbuf = &dirp->de.d_stat; | ||||||
|  |  | ||||||
|  |     if (INVALID_HANDLE_VALUE == dirp->fh) | ||||||
|  |     { | ||||||
|  |         dirp->fh = FindFirstFileA(dirp->path, &FindData); | ||||||
|  |         if (INVALID_HANDLE_VALUE == dirp->fh) | ||||||
|  |             return error0(); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         if (!FindNextFileA(dirp->fh, &FindData)) | ||||||
|  |         { | ||||||
|  |             if (ERROR_NO_MORE_FILES == GetLastError()) | ||||||
|  |                 return 0; | ||||||
|  |             return error0(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     memset(stbuf, 0, sizeof *stbuf); | ||||||
|  |     stbuf->st_mode = 0777 | | ||||||
|  |         ((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 0040000/* S_IFDIR */ : 0); | ||||||
|  |     stbuf->st_nlink = 1; | ||||||
|  |     stbuf->st_size = ((UINT64)FindData.nFileSizeHigh << 32) | ((UINT64)FindData.nFileSizeLow); | ||||||
|  |     FspPosixFileTimeToUnixTime(*(PUINT64)&FindData.ftCreationTime, (void *)&stbuf->st_birthtim); | ||||||
|  |     FspPosixFileTimeToUnixTime(*(PUINT64)&FindData.ftLastAccessTime, (void *)&stbuf->st_atim); | ||||||
|  |     FspPosixFileTimeToUnixTime(*(PUINT64)&FindData.ftLastWriteTime, (void *)&stbuf->st_mtim); | ||||||
|  |     FspPosixFileTimeToUnixTime(*(PUINT64)&FindData.ftLastWriteTime, (void *)&stbuf->st_ctim); | ||||||
|  | #if defined(FSP_FUSE_USE_STAT_EX) | ||||||
|  |     stbuf->st_flags = MapFileAttributesToFlags(FindData.dwFileAttributes); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     strcpy(dirp->de.d_name, FindData.cFileName); | ||||||
|  |  | ||||||
|  |     return &dirp->de; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int closedir(DIR *dirp) | ||||||
|  | { | ||||||
|  |     if (INVALID_HANDLE_VALUE != dirp->fh) | ||||||
|  |         FindClose(dirp->fh); | ||||||
|  |  | ||||||
|  |     CloseHandle(dirp->h); | ||||||
|  |     free(dirp); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int maperror(int winerrno) | ||||||
|  | { | ||||||
|  |     switch (winerrno) | ||||||
|  |     { | ||||||
|  |     case ERROR_INVALID_FUNCTION: | ||||||
|  |         return EINVAL; | ||||||
|  |     case ERROR_FILE_NOT_FOUND: | ||||||
|  |         return ENOENT; | ||||||
|  |     case ERROR_PATH_NOT_FOUND: | ||||||
|  |         return ENOENT; | ||||||
|  |     case ERROR_TOO_MANY_OPEN_FILES: | ||||||
|  |         return EMFILE; | ||||||
|  |     case ERROR_ACCESS_DENIED: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_INVALID_HANDLE: | ||||||
|  |         return EBADF; | ||||||
|  |     case ERROR_ARENA_TRASHED: | ||||||
|  |         return ENOMEM; | ||||||
|  |     case ERROR_NOT_ENOUGH_MEMORY: | ||||||
|  |         return ENOMEM; | ||||||
|  |     case ERROR_INVALID_BLOCK: | ||||||
|  |         return ENOMEM; | ||||||
|  |     case ERROR_BAD_ENVIRONMENT: | ||||||
|  |         return E2BIG; | ||||||
|  |     case ERROR_BAD_FORMAT: | ||||||
|  |         return ENOEXEC; | ||||||
|  |     case ERROR_INVALID_ACCESS: | ||||||
|  |         return EINVAL; | ||||||
|  |     case ERROR_INVALID_DATA: | ||||||
|  |         return EINVAL; | ||||||
|  |     case ERROR_INVALID_DRIVE: | ||||||
|  |         return ENOENT; | ||||||
|  |     case ERROR_CURRENT_DIRECTORY: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_NOT_SAME_DEVICE: | ||||||
|  |         return EXDEV; | ||||||
|  |     case ERROR_NO_MORE_FILES: | ||||||
|  |         return ENOENT; | ||||||
|  |     case ERROR_LOCK_VIOLATION: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_BAD_NETPATH: | ||||||
|  |         return ENOENT; | ||||||
|  |     case ERROR_NETWORK_ACCESS_DENIED: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_BAD_NET_NAME: | ||||||
|  |         return ENOENT; | ||||||
|  |     case ERROR_FILE_EXISTS: | ||||||
|  |         return EEXIST; | ||||||
|  |     case ERROR_CANNOT_MAKE: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_FAIL_I24: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_INVALID_PARAMETER: | ||||||
|  |         return EINVAL; | ||||||
|  |     case ERROR_NO_PROC_SLOTS: | ||||||
|  |         return EAGAIN; | ||||||
|  |     case ERROR_DRIVE_LOCKED: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_BROKEN_PIPE: | ||||||
|  |         return EPIPE; | ||||||
|  |     case ERROR_DISK_FULL: | ||||||
|  |         return ENOSPC; | ||||||
|  |     case ERROR_INVALID_TARGET_HANDLE: | ||||||
|  |         return EBADF; | ||||||
|  |     case ERROR_WAIT_NO_CHILDREN: | ||||||
|  |         return ECHILD; | ||||||
|  |     case ERROR_CHILD_NOT_COMPLETE: | ||||||
|  |         return ECHILD; | ||||||
|  |     case ERROR_DIRECT_ACCESS_HANDLE: | ||||||
|  |         return EBADF; | ||||||
|  |     case ERROR_NEGATIVE_SEEK: | ||||||
|  |         return EINVAL; | ||||||
|  |     case ERROR_SEEK_ON_DEVICE: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_DIR_NOT_EMPTY: | ||||||
|  |         return ENOTEMPTY; | ||||||
|  |     case ERROR_NOT_LOCKED: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_BAD_PATHNAME: | ||||||
|  |         return ENOENT; | ||||||
|  |     case ERROR_MAX_THRDS_REACHED: | ||||||
|  |         return EAGAIN; | ||||||
|  |     case ERROR_LOCK_FAILED: | ||||||
|  |         return EACCES; | ||||||
|  |     case ERROR_ALREADY_EXISTS: | ||||||
|  |         return EEXIST; | ||||||
|  |     case ERROR_FILENAME_EXCED_RANGE: | ||||||
|  |         return ENOENT; | ||||||
|  |     case ERROR_NESTING_NOT_ALLOWED: | ||||||
|  |         return EAGAIN; | ||||||
|  |     case ERROR_NOT_ENOUGH_QUOTA: | ||||||
|  |         return ENOMEM; | ||||||
|  |     default: | ||||||
|  |         if (ERROR_WRITE_PROTECT <= winerrno && winerrno <= ERROR_SHARING_BUFFER_EXCEEDED) | ||||||
|  |             return EACCES; | ||||||
|  |         else if (ERROR_INVALID_STARTING_CODESEG <= winerrno && winerrno <= ERROR_INFLOOP_IN_RELOC_CHAIN) | ||||||
|  |             return ENOEXEC; | ||||||
|  |         else | ||||||
|  |             return EINVAL; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | long WinFspLoad(void) | ||||||
|  | { | ||||||
|  |     return FspLoad(0); | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								tst/passthrough-fuse3/winposix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								tst/passthrough-fuse3/winposix.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | /** | ||||||
|  |  * @file winposix.h | ||||||
|  |  * | ||||||
|  |  * @copyright 2015-2018 Bill Zissimopoulos | ||||||
|  |  */ | ||||||
|  | /* | ||||||
|  |  * This file is part of WinFsp. | ||||||
|  |  * | ||||||
|  |  * You can redistribute it and/or modify it under the terms of the GNU | ||||||
|  |  * 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 WINPOSIX_H_INCLUDED | ||||||
|  | #define WINPOSIX_H_INCLUDED | ||||||
|  |  | ||||||
|  | #define O_RDONLY                        _O_RDONLY | ||||||
|  | #define O_WRONLY                        _O_WRONLY | ||||||
|  | #define O_RDWR                          _O_RDWR | ||||||
|  | #define O_APPEND                        _O_APPEND | ||||||
|  | #define O_CREAT                         _O_CREAT | ||||||
|  | #define O_EXCL                          _O_EXCL | ||||||
|  | #define O_TRUNC                         _O_TRUNC | ||||||
|  |  | ||||||
|  | #define PATH_MAX                        1024 | ||||||
|  | #define AT_FDCWD                        -2 | ||||||
|  | #define AT_SYMLINK_NOFOLLOW             2 | ||||||
|  |  | ||||||
|  | typedef struct _DIR DIR; | ||||||
|  | struct dirent | ||||||
|  | { | ||||||
|  |     struct fuse_stat d_stat; | ||||||
|  |     char d_name[255]; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | char *realpath(const char *path, char *resolved); | ||||||
|  |  | ||||||
|  | int statvfs(const char *path, struct fuse_statvfs *stbuf); | ||||||
|  |  | ||||||
|  | int open(const char *path, int oflag, ...); | ||||||
|  | int fstat(int fd, struct fuse_stat *stbuf); | ||||||
|  | int ftruncate(int fd, fuse_off_t size); | ||||||
|  | int pread(int fd, void *buf, size_t nbyte, fuse_off_t offset); | ||||||
|  | int pwrite(int fd, const void *buf, size_t nbyte, fuse_off_t offset); | ||||||
|  | int fsync(int fd); | ||||||
|  | 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 utimensat(int dirfd, const char *path, const struct fuse_timespec times[2], int flag); | ||||||
|  | int setcrtime(const char *path, const struct fuse_timespec *tv); | ||||||
|  | int unlink(const char *path); | ||||||
|  | int rename(const char *oldpath, const char *newpath); | ||||||
|  |  | ||||||
|  | int mkdir(const char *path, fuse_mode_t mode); | ||||||
|  | int rmdir(const char *path); | ||||||
|  |  | ||||||
|  | DIR *opendir(const char *path); | ||||||
|  | int dirfd(DIR *dirp); | ||||||
|  | void rewinddir(DIR *dirp); | ||||||
|  | struct dirent *readdir(DIR *dirp); | ||||||
|  | int closedir(DIR *dirp); | ||||||
|  |  | ||||||
|  | long WinFspLoad(void); | ||||||
|  | #undef fuse_main | ||||||
|  | #define fuse_main(argc, argv, ops, data)\ | ||||||
|  |     (WinFspLoad(), fuse_main_real(argc, argv, ops, sizeof *(ops), data)) | ||||||
|  |  | ||||||
|  | #endif | ||||||
		Reference in New Issue
	
	Block a user