From 109e483a2f817b91c91c83965dc54ef38c713257 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Fri, 1 Apr 2016 13:42:46 -0700 Subject: [PATCH] sys: file change notifications --- src/sys/cleanup.c | 9 +++++++++ src/sys/create.c | 16 +++++++++++++--- src/sys/driver.h | 3 +-- src/sys/file.c | 6 ++++-- src/sys/fileinfo.c | 25 +++++++++++++++++++++++++ src/sys/util.c | 2 +- src/sys/write.c | 5 +++++ 7 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index 9923abd9..6ab177a1 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -115,6 +115,15 @@ NTSTATUS FspFsvolCleanupComplete( { FSP_ENTER_IOC(PAGED_CODE()); + FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); + PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_NODE *FileNode = FileObject->FsContext; + + if (Request->Req.Cleanup.Delete) + FspFileNodeNotifyChange(FileNode, + FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_ACTION_REMOVED); + FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject); } diff --git a/src/sys/create.c b/src/sys/create.c index b790c7fe..7cf4dfc3 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -678,6 +678,10 @@ NTSTATUS FspFsvolCreateComplete( /* file was successfully overwritten/superseded */ FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo); + FspFileNodeNotifyChange(FileNode, + FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE, + FILE_ACTION_MODIFIED); + FspFileNodeReleaseOwner(FileNode, Full, Request); /* SUCCESS! */ @@ -737,9 +741,10 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re { Success = MmFlushImageSection(&FileNode->NonPaged->SectionObjectPointers, MmFlushForWrite); - FspFileNodeRelease(FileNode, Main); if (!Success) { + FspFileNodeRelease(FileNode, Main); + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); BOOLEAN DeleteOnClose = BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE); @@ -752,8 +757,13 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION; } } - else - FspFileNodeRelease(FileNode, Main); + + if (FILE_CREATED == Response->IoStatus.Information) + FspFileNodeNotifyChange(FileNode, + FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_ACTION_ADDED); + + FspFileNodeRelease(FileNode, Main); /* SUCCESS! */ FspIopRequestContext(Request, RequestFileDesc) = 0; diff --git a/src/sys/driver.h b/src/sys/driver.h index 19b91e35..ff925b67 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -927,8 +927,7 @@ BOOLEAN FspFileNodeReferenceDirInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PU VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size); BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size, ULONG DirInfoChangeNumber); -VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, - ULONG Filter, ULONG Action); +VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, diff --git a/src/sys/file.c b/src/sys/file.c index ad88de5a..fd782bdc 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -856,6 +856,8 @@ static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode) VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action) { + /* FileNode must be acquired (exclusive or shared) Main */ + PAGED_CODE(); PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; @@ -869,7 +871,7 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, { case FILE_ACTION_ADDED: case FILE_ACTION_REMOVED: - case FILE_ACTION_MODIFIED: + //case FILE_ACTION_MODIFIED: case FILE_ACTION_RENAMED_OLD_NAME: case FILE_ACTION_RENAMED_NEW_NAME: FspFsvolDeviceLockContextTable(FsvolDeviceObject); @@ -881,7 +883,7 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, if (0 != ParentNode) { FspFileNodeInvalidateDirInfo(ParentNode); - FspFileNodeReference(ParentNode); + FspFileNodeDereference(ParentNode); } break; } diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index 548d1adb..416a7264 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -607,6 +607,8 @@ static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject, FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); FileNode->TruncateOnClose = TRUE; + + FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED); } return STATUS_SUCCESS; @@ -646,8 +648,19 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject, else { FSP_FILE_NODE *FileNode = FileObject->FsContext; + ULONG NotifyFilter = 0; FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); + + if ((UINT32)-1 != Request->Req.SetInformation.Info.Basic.FileAttributes) + NotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES; + if (0 != Request->Req.SetInformation.Info.Basic.CreationTime) + NotifyFilter |= FILE_NOTIFY_CHANGE_CREATION; + if (0 != Request->Req.SetInformation.Info.Basic.LastAccessTime) + NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS; + if (0 != Request->Req.SetInformation.Info.Basic.LastWriteTime) + NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE; + FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED); } return STATUS_SUCCESS; @@ -694,6 +707,8 @@ static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject, FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); FileNode->TruncateOnClose = TRUE; + + FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED); } return STATUS_SUCCESS; @@ -946,6 +961,11 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess( FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); UNICODE_STRING NewFileName; + /* fastfat has some really arcane rules on rename notifications; simplify! */ + FspFileNodeNotifyChange(FileNode, + FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_ACTION_RENAMED_OLD_NAME); + NewFileName.Length = NewFileName.MaximumLength = Request->Req.SetInformation.Info.Rename.NewFileName.Size - sizeof(WCHAR); NewFileName.Buffer = FspAllocMustSucceed(NewFileName.Length); @@ -953,6 +973,11 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess( FspFileNodeRename(FileNode, &NewFileName); + /* fastfat has some really arcane rules on rename notifications; simplify! */ + FspFileNodeNotifyChange(FileNode, + FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_ACTION_RENAMED_NEW_NAME); + FspIopRequestContext(Request, RequestFileNode) = 0; FspIopRequestContext(Request, RequestDeviceObject) = 0; FspFileNodeReleaseOwner(FileNode, Full, Request); diff --git a/src/sys/util.c b/src/sys/util.c index 3d0a44cc..cef5c1de 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -625,7 +625,7 @@ NTSTATUS FspNotifyFullReportChange( try { - FspNotifyFullReportChange( + FsRtlNotifyFullReportChange( NotifySync, NotifyList, FullTargetName, diff --git a/src/sys/write.c b/src/sys/write.c index 89d8fb0a..9f73d6f9 100644 --- a/src/sys/write.c +++ b/src/sys/write.c @@ -406,9 +406,14 @@ NTSTATUS FspFsvolWriteComplete( /* if we are top-level */ if (0 == FspIrpTopFlags(Irp)) { + UINT64 OriginalFileSize = FileNode->Header.FileSize.QuadPart; + /* update file info */ FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Write.FileInfo); + if (OriginalFileSize != Response->Rsp.Write.FileInfo.FileSize) + FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED); + /* update the current file offset if synchronous I/O (and not paging I/O) */ if (SynchronousIo && !PagingIo) FileObject->CurrentByteOffset.QuadPart = WriteToEndOfFile ?