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_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);
}

View File

@ -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,7 +757,12 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
}
}
else
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! */

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);
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,

View File

@ -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;
}

View File

@ -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);

View File

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

View File

@ -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 ?