inc,sys,tst: fsctl: PostDispositionForDirOnly

This commit is contained in:
Bill Zissimopoulos 2022-04-01 20:54:36 +01:00
parent f6fef97a10
commit 98421fe11b
4 changed files with 48 additions and 11 deletions

View File

@ -222,7 +222,8 @@ enum
UINT32 DirectoryMarkerAsNextOffset:1; /* directory marker is next offset instead of last name */\ 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 RejectIrpPriorToTransact0:1; /* reject IRP's prior to FspFsctlTransact with 0 buffers */\
UINT32 SupportsPosixUnlinkRename:1; /* file system supports POSIX-style unlink and rename */\ UINT32 SupportsPosixUnlinkRename:1; /* file system supports POSIX-style unlink and rename */\
UINT32 KmReservedFlags:2;\ UINT32 PostDispositionForDirOnly:1; /* post SetInformation/Disposition for dirs only */\
UINT32 KmReservedFlags:1;\
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\ WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)]; WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\ #define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\

View File

@ -1435,12 +1435,30 @@ static NTSTATUS FspFsvolSetPositionInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static inline FspFsvolSetDispositionInformationFlags(
PFILE_OBJECT FileObject,
FSP_FILE_NODE *FileNode,
FSP_FILE_DESC *FileDesc,
UINT32 DispositionFlags)
{
BOOLEAN Delete = BooleanFlagOn(DispositionFlags, FILE_DISPOSITION_DELETE);
FspFileNodeSetDeletePending(FileNode, Delete);
FileObject->DeletePending = Delete;
if (!Delete)
FileDesc->PosixDelete = FALSE;
else if (FlagOn(DispositionFlags, FILE_DISPOSITION_POSIX_SEMANTICS))
FileDesc->PosixDelete = TRUE;
}
static NTSTATUS FspFsvolSetDispositionInformation( static NTSTATUS FspFsvolSetDispositionInformation(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
PAGED_CODE(); PAGED_CODE();
NTSTATUS Result; NTSTATUS Result;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT FileObject = IrpSp->FileObject;
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass; FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
UINT32 DispositionFlags; UINT32 DispositionFlags;
@ -1465,7 +1483,7 @@ static NTSTATUS FspFsvolSetDispositionInformation(
} }
else else
{ {
if (!FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.SupportsPosixUnlinkRename) if (!FsvolDeviceExtension->VolumeParams.SupportsPosixUnlinkRename)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
if (sizeof(FILE_DISPOSITION_INFORMATION_EX) > Length) if (sizeof(FILE_DISPOSITION_INFORMATION_EX) > Length)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
@ -1589,6 +1607,29 @@ retry:
} }
FileDesc->DispositionStatus = STATUS_SUCCESS; FileDesc->DispositionStatus = STATUS_SUCCESS;
if (!FileNode->IsDirectory && FsvolDeviceExtension->VolumeParams.PostDispositionForDirOnly)
{
if (FILE_DISPOSITION_DELETE ==
(DispositionFlags & (FILE_DISPOSITION_DELETE | FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE)))
{
FSP_FSCTL_FILE_INFO FileInfoBuf;
if (!FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf))
goto slow;
if (0 != (FileInfoBuf.FileAttributes & FILE_ATTRIBUTE_READONLY))
{
Result = STATUS_CANNOT_DELETE;
goto unlock_exit;
}
}
FspFsvolSetDispositionInformationFlags(FileObject, FileNode, FileDesc, DispositionFlags);
Result = STATUS_SUCCESS;
goto unlock_exit;
}
slow:;
Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, 0, Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, 0,
FspFsvolSetInformationRequestFini, &Request); FspFsvolSetInformationRequestFini, &Request);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
@ -1622,19 +1663,12 @@ static NTSTATUS FspFsvolSetDispositionInformationSuccess(
FSP_FILE_DESC *FileDesc = FileObject->FsContext2; FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
UINT32 DispositionFlags = Request->Req.SetInformation.Info.DispositionEx.Flags; UINT32 DispositionFlags = Request->Req.SetInformation.Info.DispositionEx.Flags;
BOOLEAN Delete = BooleanFlagOn(DispositionFlags, FILE_DISPOSITION_DELETE);
FspFileNodeSetDeletePending(FileNode, Delete); FspFsvolSetDispositionInformationFlags(FileObject, FileNode, FileDesc, DispositionFlags);
FileObject->DeletePending = Delete;
if (!Delete)
FileDesc->PosixDelete = FALSE;
else if (FlagOn(DispositionFlags, FILE_DISPOSITION_POSIX_SEMANTICS))
FileDesc->PosixDelete = TRUE;
/* fastfat does this, although it seems unnecessary */ /* fastfat does this, although it seems unnecessary */
#if 1 #if 1
if (FileNode->IsDirectory && Delete) if (FileNode->IsDirectory && FlagOn(DispositionFlags, FILE_DISPOSITION_DELETE))
{ {
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(IrpSp->DeviceObject); FspFsvolDeviceExtension(IrpSp->DeviceObject);

View File

@ -2404,6 +2404,7 @@ NTSTATUS MemfsCreateFunnel(
VolumeParams.RejectIrpPriorToTransact0 = 1; VolumeParams.RejectIrpPriorToTransact0 = 1;
#endif #endif
VolumeParams.SupportsPosixUnlinkRename = SupportsPosixUnlinkRename; VolumeParams.SupportsPosixUnlinkRename = SupportsPosixUnlinkRename;
VolumeParams.PostDispositionForDirOnly = 1;
if (0 != VolumePrefix) if (0 != VolumePrefix)
wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix); wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix);
wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR), wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR),

View File

@ -1279,6 +1279,7 @@ NTSTATUS PtfsCreate(
/*FILE_SUPPORTS_POSIX_UNLINK_RENAME*/); /*FILE_SUPPORTS_POSIX_UNLINK_RENAME*/);
VolumeParams.ReadOnlyVolume = !!(FsAttrInfo.V.FileSystemAttributes & FILE_READ_ONLY_VOLUME); VolumeParams.ReadOnlyVolume = !!(FsAttrInfo.V.FileSystemAttributes & FILE_READ_ONLY_VOLUME);
VolumeParams.PostCleanupWhenModifiedOnly = 1; VolumeParams.PostCleanupWhenModifiedOnly = 1;
VolumeParams.PostDispositionForDirOnly = 1;
VolumeParams.PassQueryDirectoryPattern = 1; VolumeParams.PassQueryDirectoryPattern = 1;
VolumeParams.FlushAndPurgeOnCleanup = !!(FsAttributeMask & PtfsFlushAndPurgeOnCleanup); VolumeParams.FlushAndPurgeOnCleanup = !!(FsAttributeMask & PtfsFlushAndPurgeOnCleanup);
VolumeParams.WslFeatures = !!(FsAttributeMask & PtfsWslFeatures); VolumeParams.WslFeatures = !!(FsAttributeMask & PtfsWslFeatures);