sys: file change notifications

This commit is contained in:
Bill Zissimopoulos 2016-04-01 13:42:46 -07:00
parent aa81e1ffe5
commit 109e483a2f
7 changed files with 58 additions and 8 deletions

View File

@ -115,6 +115,15 @@ NTSTATUS FspFsvolCleanupComplete(
{ {
FSP_ENTER_IOC(PAGED_CODE()); 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); FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject);
} }

View File

@ -678,6 +678,10 @@ NTSTATUS FspFsvolCreateComplete(
/* file was successfully overwritten/superseded */ /* file was successfully overwritten/superseded */
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo); 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); FspFileNodeReleaseOwner(FileNode, Full, Request);
/* SUCCESS! */ /* SUCCESS! */
@ -737,9 +741,10 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
{ {
Success = MmFlushImageSection(&FileNode->NonPaged->SectionObjectPointers, Success = MmFlushImageSection(&FileNode->NonPaged->SectionObjectPointers,
MmFlushForWrite); MmFlushForWrite);
FspFileNodeRelease(FileNode, Main);
if (!Success) if (!Success)
{ {
FspFileNodeRelease(FileNode, Main);
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
BOOLEAN DeleteOnClose = BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE); 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; 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! */ /* SUCCESS! */
FspIopRequestContext(Request, RequestFileDesc) = 0; FspIopRequestContext(Request, RequestFileDesc) = 0;

View File

@ -927,8 +927,7 @@ BOOLEAN FspFileNodeReferenceDirInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PU
VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size); VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size, BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
ULONG DirInfoChangeNumber); ULONG DirInfoChangeNumber);
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action);
ULONG Filter, ULONG Action);
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,

View File

@ -856,6 +856,8 @@ static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode)
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
ULONG Filter, ULONG Action) ULONG Filter, ULONG Action)
{ {
/* FileNode must be acquired (exclusive or shared) Main */
PAGED_CODE(); PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
@ -869,7 +871,7 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
{ {
case FILE_ACTION_ADDED: case FILE_ACTION_ADDED:
case FILE_ACTION_REMOVED: case FILE_ACTION_REMOVED:
case FILE_ACTION_MODIFIED: //case FILE_ACTION_MODIFIED:
case FILE_ACTION_RENAMED_OLD_NAME: case FILE_ACTION_RENAMED_OLD_NAME:
case FILE_ACTION_RENAMED_NEW_NAME: case FILE_ACTION_RENAMED_NEW_NAME:
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
@ -881,7 +883,7 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
if (0 != ParentNode) if (0 != ParentNode)
{ {
FspFileNodeInvalidateDirInfo(ParentNode); FspFileNodeInvalidateDirInfo(ParentNode);
FspFileNodeReference(ParentNode); FspFileNodeDereference(ParentNode);
} }
break; break;
} }

View File

@ -607,6 +607,8 @@ static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject,
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
FileNode->TruncateOnClose = TRUE; FileNode->TruncateOnClose = TRUE;
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -646,8 +648,19 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
else else
{ {
FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_NODE *FileNode = FileObject->FsContext;
ULONG NotifyFilter = 0;
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); 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; return STATUS_SUCCESS;
@ -694,6 +707,8 @@ static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject,
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
FileNode->TruncateOnClose = TRUE; FileNode->TruncateOnClose = TRUE;
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -946,6 +961,11 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess(
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
UNICODE_STRING NewFileName; 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 = NewFileName.Length = NewFileName.MaximumLength =
Request->Req.SetInformation.Info.Rename.NewFileName.Size - sizeof(WCHAR); Request->Req.SetInformation.Info.Rename.NewFileName.Size - sizeof(WCHAR);
NewFileName.Buffer = FspAllocMustSucceed(NewFileName.Length); NewFileName.Buffer = FspAllocMustSucceed(NewFileName.Length);
@ -953,6 +973,11 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess(
FspFileNodeRename(FileNode, &NewFileName); 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, RequestFileNode) = 0;
FspIopRequestContext(Request, RequestDeviceObject) = 0; FspIopRequestContext(Request, RequestDeviceObject) = 0;
FspFileNodeReleaseOwner(FileNode, Full, Request); FspFileNodeReleaseOwner(FileNode, Full, Request);

View File

@ -625,7 +625,7 @@ NTSTATUS FspNotifyFullReportChange(
try try
{ {
FspNotifyFullReportChange( FsRtlNotifyFullReportChange(
NotifySync, NotifySync,
NotifyList, NotifyList,
FullTargetName, FullTargetName,

View File

@ -406,9 +406,14 @@ NTSTATUS FspFsvolWriteComplete(
/* if we are top-level */ /* if we are top-level */
if (0 == FspIrpTopFlags(Irp)) if (0 == FspIrpTopFlags(Irp))
{ {
UINT64 OriginalFileSize = FileNode->Header.FileSize.QuadPart;
/* update file info */ /* update file info */
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Write.FileInfo); 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) */ /* update the current file offset if synchronous I/O (and not paging I/O) */
if (SynchronousIo && !PagingIo) if (SynchronousIo && !PagingIo)
FileObject->CurrentByteOffset.QuadPart = WriteToEndOfFile ? FileObject->CurrentByteOffset.QuadPart = WriteToEndOfFile ?