mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-29 19:18:39 -05:00 
			
		
		
		
	tst: passthrough-fuse: FSP_FUSE_CAP_*
This commit is contained in:
		| @@ -38,8 +38,6 @@ struct fsp_fuse_core_opt_data | ||||
|         set_attr_timeout, attr_timeout, | ||||
|         rellinks; | ||||
|     int set_FileInfoTimeout; | ||||
|     int CaseInsensitiveSearch, | ||||
|         ReadOnlyVolume; | ||||
|     FSP_FSCTL_VOLUME_PARAMS VolumeParams; | ||||
| }; | ||||
|  | ||||
| @@ -89,8 +87,6 @@ static struct fuse_opt fsp_fuse_core_opts[] = | ||||
|     FSP_FUSE_CORE_OPT("VolumeSerialNumber=%lx", VolumeParams.VolumeSerialNumber, 0), | ||||
|     FSP_FUSE_CORE_OPT("FileInfoTimeout=", set_FileInfoTimeout, 1), | ||||
|     FSP_FUSE_CORE_OPT("FileInfoTimeout=%d", VolumeParams.FileInfoTimeout, 0), | ||||
|     FSP_FUSE_CORE_OPT("CaseInsensitiveSearch", CaseInsensitiveSearch, 1), | ||||
|     FSP_FUSE_CORE_OPT("ReadOnlyVolume", ReadOnlyVolume, 1), | ||||
|     FUSE_OPT_KEY("--UNC=", 'U'), | ||||
|     FUSE_OPT_KEY("--VolumePrefix=", 'U'), | ||||
|     FUSE_OPT_KEY("--FileSystemName=", 'F'), | ||||
| @@ -252,9 +248,17 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) | ||||
|         //FUSE_CAP_ATOMIC_O_TRUNC |     /* due to Windows/WinFsp design, no support */ | ||||
|         //FUSE_CAP_EXPORT_SUPPORT |     /* not needed in Windows/WinFsp */ | ||||
|         FUSE_CAP_BIG_WRITES | | ||||
|         FUSE_CAP_DONT_MASK; | ||||
|         FUSE_CAP_DONT_MASK | | ||||
|         FSP_FUSE_CAP_READDIR_PLUS | | ||||
|         FSP_FUSE_CAP_READ_ONLY | | ||||
|         FSP_FUSE_CAP_CASE_INSENSITIVE; | ||||
|     if (0 != f->ops.init) | ||||
|     { | ||||
|         context->private_data = f->data = f->ops.init(&conn); | ||||
|         f->VolumeParams.ReadOnlyVolume = 0 != (conn.want & FSP_FUSE_CAP_READ_ONLY); | ||||
|         f->VolumeParams.CaseSensitiveSearch = 0 == (conn.want & FSP_FUSE_CAP_CASE_INSENSITIVE); | ||||
|         f->conn_want = conn.want; | ||||
|     } | ||||
|     f->fsinit = TRUE; | ||||
|     if (0 != f->ops.statfs) | ||||
|     { | ||||
| @@ -417,7 +421,6 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key, | ||||
|             "    -o VolumeCreationTime=T    volume creation time (FILETIME hex format)\n" | ||||
|             "    -o VolumeSerialNumber=N    32-bit wide\n" | ||||
|             "    -o FileInfoTimeout=N       FileInfo/Security/VolumeInfo timeout (millisec)\n" | ||||
|             "    -o CaseInsensitiveSearch   file system supports case-insensitive file names\n" | ||||
|             "    --UNC=U --VolumePrefix=U   UNC prefix (\\Server\\Share)\n" | ||||
|             "    --FileSystemName=FSN       Name of user mode file system\n"); | ||||
|         opt_data->help = 1; | ||||
| @@ -501,12 +504,12 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, | ||||
|  | ||||
|     if (!opt_data.set_FileInfoTimeout && opt_data.set_attr_timeout) | ||||
|         opt_data.VolumeParams.FileInfoTimeout = opt_data.set_attr_timeout * 1000; | ||||
|     opt_data.VolumeParams.CaseSensitiveSearch = !opt_data.CaseInsensitiveSearch; | ||||
|     opt_data.VolumeParams.CaseSensitiveSearch = TRUE; | ||||
|     opt_data.VolumeParams.PersistentAcls = TRUE; | ||||
|     opt_data.VolumeParams.ReparsePoints = TRUE; | ||||
|     opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE; | ||||
|     opt_data.VolumeParams.NamedStreams = FALSE; | ||||
|     opt_data.VolumeParams.ReadOnlyVolume = !!opt_data.ReadOnlyVolume; | ||||
|     opt_data.VolumeParams.ReadOnlyVolume = FALSE; | ||||
|     opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE; | ||||
|     opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE; | ||||
|     if (L'\0' == opt_data.VolumeParams.FileSystemName[0]) | ||||
|   | ||||
| @@ -311,28 +311,34 @@ static BOOLEAN fsp_fuse_intf_CheckSymlinkDirectory(FSP_FILE_SYSTEM *FileSystem, | ||||
| } | ||||
|  | ||||
| #define fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, fi, PUid, PGid, PMode, FileInfo)\ | ||||
|     fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, 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, | ||||
|     const char *PosixPath, struct fuse_file_info *fi, | ||||
|     const char *PosixPath, struct fuse_file_info *fi, const struct fuse_stat *stbufp, | ||||
|     PUINT32 PUid, PUINT32 PGid, PUINT32 PMode, PUINT32 PDev, | ||||
|     FSP_FSCTL_FILE_INFO *FileInfo) | ||||
| { | ||||
|     struct fuse *f = FileSystem->UserContext; | ||||
|     UINT64 AllocationUnit; | ||||
|     struct fuse_stat stbuf; | ||||
|     int err; | ||||
|  | ||||
|     memset(&stbuf, 0, sizeof stbuf); | ||||
|  | ||||
|     if (0 != f->ops.fgetattr && 0 != fi && -1 != fi->fh) | ||||
|         err = f->ops.fgetattr(PosixPath, (void *)&stbuf, fi); | ||||
|     else if (0 != f->ops.getattr) | ||||
|         err = f->ops.getattr(PosixPath, (void *)&stbuf); | ||||
|     if (0 != stbufp) | ||||
|         memcpy(&stbuf, stbufp, sizeof stbuf); | ||||
|     else | ||||
|         return STATUS_INVALID_DEVICE_REQUEST; | ||||
|     { | ||||
|         int err; | ||||
|  | ||||
|     if (0 != err) | ||||
|         return fsp_fuse_ntstatus_from_errno(f->env, err); | ||||
|         memset(&stbuf, 0, sizeof stbuf); | ||||
|  | ||||
|         if (0 != f->ops.fgetattr && 0 != fi && -1 != fi->fh) | ||||
|             err = f->ops.fgetattr(PosixPath, (void *)&stbuf, fi); | ||||
|         else if (0 != f->ops.getattr) | ||||
|             err = f->ops.getattr(PosixPath, (void *)&stbuf); | ||||
|         else | ||||
|             return STATUS_INVALID_DEVICE_REQUEST; | ||||
|  | ||||
|         if (0 != err) | ||||
|             return fsp_fuse_ntstatus_from_errno(f->env, err); | ||||
|     } | ||||
|  | ||||
|     if (f->set_umask) | ||||
|         stbuf.st_mode = (stbuf.st_mode & 0170000) | (0777 & ~f->umask); | ||||
| @@ -513,7 +519,7 @@ static NTSTATUS fsp_fuse_intf_GetReparsePointEx(FSP_FILE_SYSTEM *FileSystem, | ||||
|     SIZE_T Size; | ||||
|     NTSTATUS Result; | ||||
|  | ||||
|     Result = fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, | ||||
|     Result = fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, 0, | ||||
|         &Uid, &Gid, &Mode, &Dev, &FileInfo); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|         return Result; | ||||
| @@ -1576,6 +1582,17 @@ static int fsp_fuse_intf_AddDirInfo(void *buf, const char *name, | ||||
|     memset(DirInfo, 0, sizeof *DirInfo); | ||||
|     DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + SizeW * sizeof(WCHAR)); | ||||
|  | ||||
|     if (dh->ReaddirPlus && 0 != stbuf) | ||||
|     { | ||||
|         UINT32 Uid, Gid, Mode; | ||||
|         NTSTATUS Result0; | ||||
|  | ||||
|         Result0 = fsp_fuse_intf_GetFileInfoFunnel(dh->FileSystem, 0, 0, stbuf, | ||||
|             &Uid, &Gid, &Mode, 0, &DirInfo->FileInfo); | ||||
|         if (NT_SUCCESS(Result0)) | ||||
|             DirInfo->Padding[0] = 1; /* HACK: remember that the FileInfo is valid */ | ||||
|     } | ||||
|  | ||||
|     return !FspFileSystemFillDirectoryBuffer(&filedesc->DirBuffer, DirInfo, &dh->Result); | ||||
| } | ||||
|  | ||||
| @@ -1619,44 +1636,53 @@ static NTSTATUS fsp_fuse_intf_FixDirInfo(FSP_FILE_SYSTEM *FileSystem, | ||||
|         DirInfo = (FSP_FSCTL_DIR_INFO *)(Buffer + *Index); | ||||
|         SizeW = (DirInfo->Size - sizeof *DirInfo) / sizeof(WCHAR); | ||||
|  | ||||
|         if (1 == SizeW && L'.' == DirInfo->FileNameBuf[0]) | ||||
|         if (DirInfo->Padding[0]) | ||||
|         { | ||||
|             PosixPathEnd = 1 < PosixName - PosixPath ? PosixName - 1 : PosixName; | ||||
|             SavedPathChar = *PosixPathEnd; | ||||
|             *PosixPathEnd = '\0'; | ||||
|         } | ||||
|         else | ||||
|         if (2 == SizeW && L'.' == DirInfo->FileNameBuf[0] && L'.' == DirInfo->FileNameBuf[1]) | ||||
|         { | ||||
|             PosixPathEnd = 1 < PosixName - PosixPath ? PosixName - 2 : PosixName; | ||||
|             while (PosixPath < PosixPathEnd && '/' != *PosixPathEnd) | ||||
|                 PosixPathEnd--; | ||||
|             if (PosixPath == PosixPathEnd) | ||||
|                 PosixPathEnd++; | ||||
|             SavedPathChar = *PosixPathEnd; | ||||
|             *PosixPathEnd = '\0'; | ||||
|             /* DirInfo has been filled already! */ | ||||
|  | ||||
|             DirInfo->Padding[0] = 0; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             PosixPathEnd = 0; | ||||
|             SizeA = WideCharToMultiByte(CP_UTF8, 0, DirInfo->FileNameBuf, SizeW, PosixName, 255, 0, 0); | ||||
|             if (0 == SizeA) | ||||
|             if (1 == SizeW && L'.' == DirInfo->FileNameBuf[0]) | ||||
|             { | ||||
|                 /* this should never happen because we just converted using MultiByteToWideChar */ | ||||
|                 Result = STATUS_OBJECT_NAME_INVALID; | ||||
|                 goto exit; | ||||
|                 PosixPathEnd = 1 < PosixName - PosixPath ? PosixName - 1 : PosixName; | ||||
|                 SavedPathChar = *PosixPathEnd; | ||||
|                 *PosixPathEnd = '\0'; | ||||
|             } | ||||
|             PosixName[SizeA] = '\0'; | ||||
|             else | ||||
|             if (2 == SizeW && L'.' == DirInfo->FileNameBuf[0] && L'.' == DirInfo->FileNameBuf[1]) | ||||
|             { | ||||
|                 PosixPathEnd = 1 < PosixName - PosixPath ? PosixName - 2 : PosixName; | ||||
|                 while (PosixPath < PosixPathEnd && '/' != *PosixPathEnd) | ||||
|                     PosixPathEnd--; | ||||
|                 if (PosixPath == PosixPathEnd) | ||||
|                     PosixPathEnd++; | ||||
|                 SavedPathChar = *PosixPathEnd; | ||||
|                 *PosixPathEnd = '\0'; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 PosixPathEnd = 0; | ||||
|                 SizeA = WideCharToMultiByte(CP_UTF8, 0, DirInfo->FileNameBuf, SizeW, PosixName, 255, 0, 0); | ||||
|                 if (0 == SizeA) | ||||
|                 { | ||||
|                     /* this should never happen because we just converted using MultiByteToWideChar */ | ||||
|                     Result = STATUS_OBJECT_NAME_INVALID; | ||||
|                     goto exit; | ||||
|                 } | ||||
|                 PosixName[SizeA] = '\0'; | ||||
|             } | ||||
|  | ||||
|             Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, 0, | ||||
|                 &Uid, &Gid, &Mode, &DirInfo->FileInfo); | ||||
|             if (!NT_SUCCESS(Result)) | ||||
|                 goto exit; | ||||
|  | ||||
|             if (0 != PosixPathEnd) | ||||
|                 *PosixPathEnd = SavedPathChar; | ||||
|         } | ||||
|  | ||||
|         Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, 0, | ||||
|             &Uid, &Gid, &Mode, &DirInfo->FileInfo); | ||||
|         if (!NT_SUCCESS(Result)) | ||||
|             goto exit; | ||||
|  | ||||
|         if (0 != PosixPathEnd) | ||||
|             *PosixPathEnd = SavedPathChar; | ||||
|  | ||||
|         FspPosixDecodeWindowsPath(DirInfo->FileNameBuf, SizeW); | ||||
|     } | ||||
|  | ||||
| @@ -1683,6 +1709,8 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem, | ||||
|     { | ||||
|         memset(&dh, 0, sizeof dh); | ||||
|         dh.filedesc = filedesc; | ||||
|         dh.FileSystem = FileSystem; | ||||
|         dh.ReaddirPlus = 0 != (f->conn_want & FSP_FUSE_CAP_READDIR_PLUS); | ||||
|         dh.Result = STATUS_SUCCESS; | ||||
|  | ||||
|         if (0 != f->ops.readdir) | ||||
|   | ||||
| @@ -40,12 +40,13 @@ struct fuse | ||||
|     int rellinks; | ||||
|     struct fuse_operations ops; | ||||
|     void *data; | ||||
|     unsigned conn_want; | ||||
|     BOOLEAN fsinit; | ||||
|     UINT32 DebugLog; | ||||
|     FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy; | ||||
|     FSP_FSCTL_VOLUME_PARAMS VolumeParams; | ||||
|     PWSTR MountPoint; | ||||
|     FSP_FILE_SYSTEM *FileSystem; | ||||
|     BOOLEAN fsinit; | ||||
|     FSP_SERVICE *Service; /* weak */ | ||||
| }; | ||||
|  | ||||
| @@ -66,8 +67,12 @@ struct fsp_fuse_file_desc | ||||
|  | ||||
| struct fuse_dirhandle | ||||
| { | ||||
|     /* ReadDirectory */ | ||||
|     struct fsp_fuse_file_desc *filedesc; | ||||
|     FSP_FILE_SYSTEM *FileSystem; | ||||
|     BOOLEAN ReaddirPlus; | ||||
|     NTSTATUS Result; | ||||
|     /* CanDelete */ | ||||
|     BOOLEAN DotFiles, HasChild; | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user