From 1a879e330298ef9ddca145da2acc98ba60f5e1bf Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sat, 2 Apr 2022 12:48:35 +0100 Subject: [PATCH] inc, src: PostDispositionWhenNecessaryOnly - Rename PostDispositionForDirOnly to PostDispositionWhenNecessaryOnly - Implement PostDispositionWhenNecessaryOnly across the board --- inc/winfsp/fsctl.h | 2 +- src/dll/fsop.c | 3 ++- src/dll/fuse/fuse_loop.c | 2 ++ src/dotnet/FileSystemHost.cs | 5 +++++ src/dotnet/Interop.cs | 1 + src/sys/fileinfo.c | 5 ++--- tst/memfs-dotnet/Program.cs | 1 + tst/memfs/memfs.cpp | 2 +- 8 files changed, 15 insertions(+), 6 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index cec14557..e1c7a0b2 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -222,7 +222,7 @@ enum UINT32 DirectoryMarkerAsNextOffset:1; /* directory marker is next offset instead of last name */\ UINT32 RejectIrpPriorToTransact0:1; /* reject IRP's prior to FspFsctlTransact with 0 buffers */\ UINT32 SupportsPosixUnlinkRename:1; /* file system supports POSIX-style unlink and rename */\ - UINT32 PostDispositionForDirOnly:1; /* post SetInformation/Disposition for dirs only */\ + UINT32 PostDispositionWhenNecessaryOnly:1; /* post Disposition for dirs or READONLY attr check */\ UINT32 KmReservedFlags:1;\ WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\ WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)]; diff --git a/src/dll/fsop.c b/src/dll/fsop.c index 682d7e54..e9e51cbd 100644 --- a/src/dll/fsop.c +++ b/src/dll/fsop.c @@ -1142,7 +1142,8 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, break; case 13/*FileDispositionInformation*/: case 64/*FileDispositionInformationEx*/: - if (0 == (0x10/*IGNORE_READONLY_ATTRIBUTE*/ & Request->Req.SetInformation.Info.DispositionEx.Flags) && + if (1/*DELETE*/ == (0x11/*DELETE|IGNORE_READONLY_ATTRIBUTE*/ & + Request->Req.SetInformation.Info.DispositionEx.Flags) && 0 != FileSystem->Interface->GetFileInfo) { Result = FileSystem->Interface->GetFileInfo(FileSystem, diff --git a/src/dll/fuse/fuse_loop.c b/src/dll/fuse/fuse_loop.c index 0061ff35..be2f8ff4 100644 --- a/src/dll/fuse/fuse_loop.c +++ b/src/dll/fuse/fuse_loop.c @@ -184,6 +184,8 @@ static NTSTATUS fsp_fuse_loop_start(struct fuse *f) f->has_slashdot = 0 == err && 0040000 == (stbuf.st_mode & 0170000); } } + if (0 == (f->conn_want & FSP_FUSE_CAP_DELETE_ACCESS) || 0 == f->ops.access) + f->VolumeParams.PostDispositionWhenNecessaryOnly = 1; if (0 != f->ops.listxattr && 0 != f->ops.getxattr && 0 != f->ops.setxattr && 0 != f->ops.removexattr) f->VolumeParams.ExtendedAttributes = 1; diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs index 196cb5a0..2b59b03e 100644 --- a/src/dotnet/FileSystemHost.cs +++ b/src/dotnet/FileSystemHost.cs @@ -277,6 +277,11 @@ namespace Fsp get { return 0 != (_VolumeParams.Flags & VolumeParams.PostCleanupWhenModifiedOnly); } set { _VolumeParams.Flags |= (value ? VolumeParams.PostCleanupWhenModifiedOnly : 0); } } + public Boolean PostDispositionWhenNecessaryOnly + { + get { return 0 != (_VolumeParams.Flags & VolumeParams.PostDispositionWhenNecessaryOnly); } + set { _VolumeParams.Flags |= (value ? VolumeParams.PostDispositionWhenNecessaryOnly : 0); } + } public Boolean PassQueryDirectoryPattern { get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryPattern); } diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index 7081ef97..bcd58305 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -56,6 +56,7 @@ namespace Fsp.Interop internal const UInt32 WslFeatures = 0x04000000; internal const UInt32 RejectIrpPriorToTransact0 = 0x10000000; internal const UInt32 SupportsPosixUnlinkRename = 0x20000000; + internal const UInt32 PostDispositionWhenNecessaryOnly = 0x40000000; internal const int PrefixSize = 192; internal const int FileSystemNameSize = 16; diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index 88a18fd0..c0e69b57 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -1607,7 +1607,7 @@ retry: } FileDesc->DispositionStatus = STATUS_SUCCESS; - if (!FileNode->IsDirectory && FsvolDeviceExtension->VolumeParams.PostDispositionForDirOnly) + if (!FileNode->IsDirectory && FsvolDeviceExtension->VolumeParams.PostDispositionWhenNecessaryOnly) { if (FILE_DISPOSITION_DELETE == (DispositionFlags & (FILE_DISPOSITION_DELETE | FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE))) @@ -1615,7 +1615,6 @@ retry: FSP_FSCTL_FILE_INFO FileInfoBuf; if (!FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) goto slow; - if (0 != (FileInfoBuf.FileAttributes & FILE_ATTRIBUTE_READONLY)) { Result = STATUS_CANNOT_DELETE; @@ -1627,8 +1626,8 @@ retry: Result = STATUS_SUCCESS; goto unlock_exit; - } slow:; + } Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, 0, FspFsvolSetInformationRequestFini, &Request); diff --git a/tst/memfs-dotnet/Program.cs b/tst/memfs-dotnet/Program.cs index e9207c3e..1768b2ca 100644 --- a/tst/memfs-dotnet/Program.cs +++ b/tst/memfs-dotnet/Program.cs @@ -282,6 +282,7 @@ namespace memfs Host.ReparsePointsAccessCheck = false; Host.NamedStreams = true; Host.PostCleanupWhenModifiedOnly = true; + Host.PostDispositionWhenNecessaryOnly = true; Host.PassQueryDirectoryFileName = true; Host.ExtendedAttributes = true; Host.WslFeatures = true; diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index f1be24bb..40697c70 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -2386,6 +2386,7 @@ NTSTATUS MemfsCreateFunnel( VolumeParams.NamedStreams = 1; #endif VolumeParams.PostCleanupWhenModifiedOnly = 1; + VolumeParams.PostDispositionWhenNecessaryOnly = 1; #if defined(MEMFS_DIRINFO_BY_NAME) VolumeParams.PassQueryDirectoryFileName = 1; #endif @@ -2404,7 +2405,6 @@ NTSTATUS MemfsCreateFunnel( VolumeParams.RejectIrpPriorToTransact0 = 1; #endif VolumeParams.SupportsPosixUnlinkRename = SupportsPosixUnlinkRename; - VolumeParams.PostDispositionForDirOnly = 1; if (0 != VolumePrefix) wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix); wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR),