diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index adb4e6d0..21416162 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -114,7 +114,7 @@ static NTSTATUS FspFsvolCleanup( Request->Req.Cleanup.SetArchiveBit = FileModified && !FileDesc->DidSetFileAttributes; Request->Req.Cleanup.SetLastAccessTime = !FileDesc->DidSetLastAccessTime; Request->Req.Cleanup.SetLastWriteTime = FileModified && !FileDesc->DidSetLastWriteTime; - Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetBasicInfo) && + Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetMetadata) && !FileDesc->DidSetChangeTime; FspFileNodeAcquireExclusive(FileNode, Pgio); @@ -137,7 +137,7 @@ static NTSTATUS FspFsvolCleanup( return FSP_STATUS_IOQ_POST_BEST_EFFORT; else { - if (FileDesc->DidSetBasicInfo) + if (FileDesc->DidSetMetadata) /* invalidate the parent dir info */ FspFileNodeInvalidateParentDirInfo(FileNode); diff --git a/src/sys/driver.h b/src/sys/driver.h index 605e101f..062c3e6d 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1199,7 +1199,7 @@ typedef struct UINT64 UserContext2; UINT32 CaseSensitive:1, HasTraversePrivilege:1, DeleteOnClose:1, - DidSetBasicInfo:1, + DidSetMetadata:1, DidSetFileAttributes:1, DidSetCreationTime:1, DidSetLastAccessTime:1, DidSetLastWriteTime:1, DidSetChangeTime:1, DirectoryHasSuchFile:1; diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index 21bfd6fb..e1115fa1 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -996,7 +996,7 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject, if (0 != Request->Req.SetInformation.Info.Basic.ChangeTime) FileDesc->DidSetChangeTime = TRUE; - FileDesc->DidSetBasicInfo = TRUE; + FileDesc->DidSetMetadata = TRUE; FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED); } diff --git a/src/sys/flush.c b/src/sys/flush.c index 858f27ca..e8619fc4 100644 --- a/src/sys/flush.c +++ b/src/sys/flush.c @@ -149,7 +149,21 @@ NTSTATUS FspFsvolFlushBuffersComplete( else if (!NT_SUCCESS(FlushResult)) Result = FlushResult; else + { + PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_NODE *FileNode = FileObject->FsContext; + + /* + * A flush request on the volume (or the root directory according to FastFat) + * is a request to flush the whole volume. + */ + if (!FspFileNodeIsValid(FileNode) || FileNode->IsRootDirectory) + ; + else + SetFlag(FileObject->Flags, FO_FILE_MODIFIED); + Result = STATUS_SUCCESS; + } FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject); diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index 86303ea1..6aaf6df3 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -279,7 +279,14 @@ static NTSTATUS FspFsvolFileSystemControlReparsePointComplete( PAGED_CODE(); if (IsWrite) + { + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + FSP_FILE_DESC *FileDesc = IrpSp->FileObject->FsContext2; + + FileDesc->DidSetMetadata = TRUE; + return STATUS_SUCCESS; + } NTSTATUS Result; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); diff --git a/src/sys/security.c b/src/sys/security.c index 813716d5..a0742967 100644 --- a/src/sys/security.c +++ b/src/sys/security.c @@ -254,8 +254,11 @@ NTSTATUS FspFsvolSetSecurityComplete( PFILE_OBJECT FileObject = IrpSp->FileObject; FSP_FILE_NODE *FileNode = FileObject->FsContext; + FSP_FILE_DESC *FileDesc = FileObject->FsContext2; FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); + ASSERT(FileNode == FileDesc->FileNode); + /* if the security descriptor that we got back is valid */ if (0 < Response->Rsp.SetSecurity.SecurityDescriptor.Size && Response->Buffer + Response->Rsp.SetSecurity.SecurityDescriptor.Size <= @@ -273,6 +276,8 @@ NTSTATUS FspFsvolSetSecurityComplete( FspFileNodeSetSecurity(FileNode, 0, 0); } + FileDesc->DidSetMetadata = TRUE; + FspIopRequestContext(Request, RequestFileNode) = 0; FspFileNodeReleaseOwner(FileNode, Full, Request); diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index 3ad8e012..6ad118b6 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -1091,17 +1091,8 @@ static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem, NTSTATUS Flush(FSP_FILE_SYSTEM *FileSystem, PVOID FileNode0) { - MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0; - /* nothing to flush, since we do not cache anything */ - if (0 != FileNode) - { - FileNode->FileInfo.LastAccessTime = - FileNode->FileInfo.LastWriteTime = - FileNode->FileInfo.ChangeTime = MemfsGetSystemTime(); - } - return STATUS_SUCCESS; } @@ -1203,10 +1194,6 @@ static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem, if (!NT_SUCCESS(Result)) return Result; - FileNode->FileInfo.LastAccessTime = - FileNode->FileInfo.LastWriteTime = - FileNode->FileInfo.ChangeTime = MemfsGetSystemTime(); - MemfsFileNodeGetFileInfo(FileNode, FileInfo); return STATUS_SUCCESS; @@ -1359,8 +1346,6 @@ static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem, FileNode->FileSecuritySize = FileSecuritySize; FileNode->FileSecurity = FileSecurity; - FileNode->FileInfo.ChangeTime = MemfsGetSystemTime(); - return STATUS_SUCCESS; } @@ -1565,8 +1550,6 @@ static NTSTATUS SetReparsePoint(FSP_FILE_SYSTEM *FileSystem, FileNode->ReparseData = ReparseData; memcpy(FileNode->ReparseData, Buffer, Size); - FileNode->FileInfo.ChangeTime = MemfsGetSystemTime(); - return STATUS_SUCCESS; } @@ -1600,8 +1583,6 @@ static NTSTATUS DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem, FileNode->ReparseDataSize = 0; FileNode->ReparseData = 0; - FileNode->FileInfo.ChangeTime = MemfsGetSystemTime(); - return STATUS_SUCCESS; } #endif