diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index 6c407514..9923abd9 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -73,6 +73,20 @@ static NTSTATUS FspFsvolCleanup( FspFileNodeCleanup(FileNode, FileObject, &DeletePending); + /* if this is a directory inform the FSRTL Notify mechanism */ + if (FileNode->IsDirectory) + { + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = + FspFsvolDeviceExtension(FsvolDeviceObject); + + if (DeletePending) + FspNotifyDeletePending( + FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList, FileNode); + + FspNotifyCleanup( + FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList, FileDesc); + } + /* create the user-mode file system request; MustSucceed because IRP_MJ_CLEANUP cannot fail */ FspIopCreateRequestMustSucceedEx(Irp, DeletePending ? &FileNode->FileName : 0, 0, FspFsvolCleanupRequestFini, &Request); diff --git a/src/sys/create.c b/src/sys/create.c index 32f7f249..b790c7fe 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -337,6 +337,7 @@ static NTSTATUS FspFsvolCreateNoLock( FileDesc->CaseSensitive = 0 != FsvolDeviceExtension->VolumeParams.CaseSensitiveSearch || BooleanFlagOn(Flags, SL_CASE_SENSITIVE); + FileDesc->HasTraversePrivilege = HasTraversePrivilege; FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request); FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject; FspIopRequestContext(Request, RequestFileDesc) = FileDesc; diff --git a/src/sys/device.c b/src/sys/device.c index 52c4967e..4ea50ccd 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -50,9 +50,9 @@ VOID FspFsvolDeviceDeleteContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STR static RTL_AVL_COMPARE_ROUTINE FspFsvolDeviceCompareContextByName; static RTL_AVL_ALLOCATE_ROUTINE FspFsvolDeviceAllocateContextByName; static RTL_AVL_FREE_ROUTINE FspFsvolDeviceFreeContextByName; -VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); -BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); -VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo); +VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); +BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); +VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo); NTSTATUS FspDeviceCopyList( PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); VOID FspDeviceDeleteList( @@ -346,6 +346,13 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) return Result; FsvolDeviceExtension->InitDoneDir = 1; + /* initialize the FSRTL Notify mechanism */ + Result = FspNotifyInitializeSync(&FsvolDeviceExtension->NotifySync); + if (!NT_SUCCESS(Result)) + return Result; + InitializeListHead(&FsvolDeviceExtension->NotifyList); + FsvolDeviceExtension->InitDoneNotify = 1; + /* initialize our context table */ ExInitializeResourceLite(&FsvolDeviceExtension->FileRenameResource); ExInitializeResourceLite(&FsvolDeviceExtension->ContextTableResource); @@ -395,6 +402,14 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject) if (FsvolDeviceExtension->InitDoneTimer) IoStopTimer(DeviceObject); + /* uninitialize the FSRTL Notify mechanism */ + if (FsvolDeviceExtension->InitDoneNotify) + { + FspNotifyCleanupAll( + FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList); + FspNotifyUninitializeSync(&FsvolDeviceExtension->NotifySync); + } + /* delete the directory meta cache */ if (FsvolDeviceExtension->InitDoneDir) FspMetaCacheDelete(FsvolDeviceExtension->DirInfoCache); @@ -753,7 +768,7 @@ static VOID NTAPI FspFsvolDeviceFreeContextByName( PAGED_CODE(); } -VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo) +VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo) { // !PAGED_CODE(); @@ -770,7 +785,7 @@ VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *V #pragma warning(push) #pragma warning(disable:4701) /* disable idiotic warning! */ -BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo) +BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo) { // !PAGED_CODE(); @@ -796,7 +811,7 @@ BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_I } #pragma warning(pop) -VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo) +VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo) { // !PAGED_CODE(); diff --git a/src/sys/dirctl.c b/src/sys/dirctl.c index 15f04203..b64b952a 100644 --- a/src/sys/dirctl.c +++ b/src/sys/dirctl.c @@ -571,7 +571,52 @@ static NTSTATUS FspFsvolNotifyChangeDirectory( { PAGED_CODE(); - return STATUS_INVALID_DEVICE_REQUEST; + /* is this a valid FileObject? */ + if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext)) + return STATUS_INVALID_DEVICE_REQUEST; + + NTSTATUS Result; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_NODE *FileNode = FileObject->FsContext; + FSP_FILE_DESC *FileDesc = FileObject->FsContext2; + ULONG CompletionFilter = IrpSp->Parameters.NotifyDirectory.CompletionFilter; + BOOLEAN WatchTree = BooleanFlagOn(IrpSp->Flags, SL_WATCH_TREE); + BOOLEAN DeletePending; + + ASSERT(FileNode == FileDesc->FileNode); + + /* only directory files can be watched */ + if (!FileNode->IsDirectory) + return STATUS_INVALID_PARAMETER; + + /* only processes with traverse privilege can watch trees! */ + if (WatchTree && !FileDesc->HasTraversePrivilege) + return STATUS_ACCESS_DENIED; + + /* stop now if the directory is pending deletion */ + DeletePending = 0 != FileNode->DeletePending; + MemoryBarrier(); + if (DeletePending) + return STATUS_DELETE_PENDING; + + FspFileNodeAcquireExclusive(FileNode, Main); + + Result = FspNotifyChangeDirectory( + FsvolDeviceExtension->NotifySync, + &FsvolDeviceExtension->NotifyList, + FileDesc, + &FileNode->FileName, + WatchTree, + CompletionFilter, + Irp); + + FspFileNodeRelease(FileNode, Main); + + if (NT_SUCCESS(Result)) + Result = STATUS_PENDING; + + return Result; } static NTSTATUS FspFsvolDirectoryControl( diff --git a/src/sys/driver.h b/src/sys/driver.h index a0df29b5..19b91e35 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -411,6 +411,40 @@ NTSTATUS FspCcMdlWriteComplete(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffse NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength, PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor); +NTSTATUS FspNotifyInitializeSync(PNOTIFY_SYNC *NotifySync); +NTSTATUS FspNotifyFullChangeDirectory( + PNOTIFY_SYNC NotifySync, + PLIST_ENTRY NotifyList, + PVOID FsContext, + PSTRING FullDirectoryName, + BOOLEAN WatchTree, + BOOLEAN IgnoreBuffer, + ULONG CompletionFilter, + PIRP NotifyIrp, + PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback, + PSECURITY_SUBJECT_CONTEXT SubjectContext); +NTSTATUS FspNotifyFullReportChange( + PNOTIFY_SYNC NotifySync, + PLIST_ENTRY NotifyList, + PSTRING FullTargetName, + USHORT TargetNameOffset, + PSTRING StreamName, + PSTRING NormalizedParentName, + ULONG FilterMatch, + ULONG Action, + PVOID TargetContext); +#define FspNotifyUninitializeSync(NS)\ + FsRtlNotifyUninitializeSync(NS) +#define FspNotifyCleanupAll(NS, NL)\ + FsRtlNotifyCleanupAll(NS, NL) +#define FspNotifyChangeDirectory(NS, NL, FC, FN, WT, CF, I)\ + FspNotifyFullChangeDirectory(NS, NL, FC, (PSTRING)FN, WT, FALSE, CF, I, 0, 0) +#define FspNotifyCleanup(NS, NL, FC)\ + FsRtlNotifyCleanup(NS, NL, FC) +#define FspNotifyDeletePending(NS, NL, FC)\ + FspNotifyFullChangeDirectory(NS, NL, FC, 0, 0, FALSE, 0, 0, 0, 0) +#define FspNotifyReportChange(NS, NL, FN, FO, SN, F, A)\ + FspNotifyFullReportChange(NS, NL, (PSTRING)FN, FO, (PSTRING)SN, 0, F, A, 0) /* utility: synchronous work queue */ typedef struct @@ -665,7 +699,7 @@ typedef struct { FSP_DEVICE_EXTENSION Base; UINT32 InitDoneFsvrt:1, InitDoneDelRsc:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, - InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1; + InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1; PDEVICE_OBJECT FsctlDeviceObject; PDEVICE_OBJECT FsvrtDeviceObject; HANDLE MupHandle; @@ -691,6 +725,8 @@ typedef struct KSPIN_LOCK InfoSpinLock; UINT64 InfoExpirationTime; FSP_FSCTL_VOLUME_INFO VolumeInfo; + PNOTIFY_SYNC NotifySync; + LIST_ENTRY NotifyList; } FSP_FSVOL_DEVICE_EXTENSION; static inline FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject) @@ -733,9 +769,9 @@ PVOID FspFsvolDeviceInsertContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_ST FSP_DEVICE_CONTEXT_BY_NAME_TABLE_ELEMENT *ElementStorage, PBOOLEAN PInserted); VOID FspFsvolDeviceDeleteContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName, PBOOLEAN PDeleted); -VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); -BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); -VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo); +VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); +BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); +VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo); NTSTATUS FspDeviceCopyList( PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); VOID FspDeviceDeleteList( @@ -835,6 +871,7 @@ typedef struct FSP_FILE_NODE *FileNode; UINT64 UserContext2; BOOLEAN CaseSensitive; + BOOLEAN HasTraversePrivilege; BOOLEAN DeleteOnClose; BOOLEAN DirectoryHasSuchFile; UNICODE_STRING DirectoryPattern; @@ -890,7 +927,8 @@ 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 FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode); +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 f1f67a0a..ad88de5a 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -42,7 +42,9 @@ 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 FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode); +static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode); +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, @@ -76,7 +78,8 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, // !#pragma alloc_text(PAGE, FspFileNodeReferenceDirInfo) // !#pragma alloc_text(PAGE, FspFileNodeSetDirInfo) // !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo) -// !#pragma alloc_text(PAGE, FspFileNodeInvalidateParentDirInfo) +// !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo) +#pragma alloc_text(PAGE, FspFileNodeNotifyChange) #pragma alloc_text(PAGE, FspFileDescCreate) #pragma alloc_text(PAGE, FspFileDescDelete) #pragma alloc_text(PAGE, FspFileDescResetDirectoryPattern) @@ -814,7 +817,7 @@ VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size) FspMetaCacheAddItem(FsvolDeviceExtension->DirInfoCache, Buffer, Size) : 0; FileNode->DirInfoChangeNumber++; - /* acquire the DirInfoSpinLock to protect against concurrent FspFileNodeInvalidateParentDirInfo*/ + /* acquire the DirInfoSpinLock to protect against concurrent FspFileNodeInvalidateDirInfo */ KeAcquireSpinLock(&NonPaged->DirInfoSpinLock, &Irql); NonPaged->DirInfo = DirInfo; KeReleaseSpinLock(&NonPaged->DirInfoSpinLock, Irql); @@ -832,29 +835,17 @@ BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG S return TRUE; } -VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode) +static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode) { // !PAGED_CODE(); PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); - UNICODE_STRING Parent, Suffix; - FSP_FILE_NODE_NONPAGED *NonPaged; + FSP_FILE_NODE_NONPAGED *NonPaged = FileNode->NonPaged; KIRQL Irql; UINT64 DirInfo; - FspUnicodePathSuffix(&FileNode->FileName, &Parent, &Suffix); - - FspFsvolDeviceLockContextTable(FsvolDeviceObject); - FileNode = FspFsvolDeviceLookupContextByName(FsvolDeviceObject, &Parent); - FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); - - if (0 == FileNode) - return; - - NonPaged = FileNode->NonPaged; - - /* acquire the DirInfoSpinLock to protect against concurrent FspFileNodeSetDirInfo*/ + /* acquire the DirInfoSpinLock to protect against concurrent FspFileNodeSetDirInfo */ KeAcquireSpinLock(&NonPaged->DirInfoSpinLock, &Irql); DirInfo = NonPaged->DirInfo; KeReleaseSpinLock(&NonPaged->DirInfoSpinLock, Irql); @@ -862,6 +853,46 @@ VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode) FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, DirInfo); } +VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, + ULONG Filter, ULONG Action) +{ + PAGED_CODE(); + + PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + UNICODE_STRING Parent, Suffix; + FSP_FILE_NODE *ParentNode; + + FspUnicodePathSuffix(&FileNode->FileName, &Parent, &Suffix); + + switch (Action) + { + case FILE_ACTION_ADDED: + case FILE_ACTION_REMOVED: + case FILE_ACTION_MODIFIED: + case FILE_ACTION_RENAMED_OLD_NAME: + case FILE_ACTION_RENAMED_NEW_NAME: + FspFsvolDeviceLockContextTable(FsvolDeviceObject); + ParentNode = FspFsvolDeviceLookupContextByName(FsvolDeviceObject, &Parent); + if (0 != ParentNode) + FspFileNodeReference(ParentNode); + FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); + + if (0 != ParentNode) + { + FspFileNodeInvalidateDirInfo(ParentNode); + FspFileNodeReference(ParentNode); + } + break; + } + + FspNotifyReportChange( + FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList, + &FileNode->FileName, + (USHORT)((PUINT8)Suffix.Buffer - (PUINT8)FileNode->FileName.Buffer), + 0, Filter, Action); +} + NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc) { PAGED_CODE(); diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index df492c96..548d1adb 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -790,6 +790,17 @@ static NTSTATUS FspFsvolSetDispositionInformationSuccess( FileNode->DeletePending = Info->DeleteFile; FileObject->DeletePending = Info->DeleteFile; + /* fastfat does this, although it seems unnecessary */ +#if 1 + if (FileNode->IsDirectory && Info->DeleteFile) + { + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = + FspFsvolDeviceExtension(IrpSp->DeviceObject); + FspNotifyDeletePending( + FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList, FileNode); + } +#endif + FspIopRequestContext(Request, RequestFileNode) = 0; FspFileNodeReleaseOwner(FileNode, Full, Request); diff --git a/src/sys/util.c b/src/sys/util.c index ece0dd2e..3d0a44cc 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -32,6 +32,28 @@ NTSTATUS FspCcMdlWriteComplete(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffse NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength, PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor); +NTSTATUS FspNotifyInitializeSync(PNOTIFY_SYNC *NotifySync); +NTSTATUS FspNotifyFullChangeDirectory( + PNOTIFY_SYNC NotifySync, + PLIST_ENTRY NotifyList, + PVOID FsContext, + PSTRING FullDirectoryName, + BOOLEAN WatchTree, + BOOLEAN IgnoreBuffer, + ULONG CompletionFilter, + PIRP NotifyIrp, + PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback, + PSECURITY_SUBJECT_CONTEXT SubjectContext); +NTSTATUS FspNotifyFullReportChange( + PNOTIFY_SYNC NotifySync, + PLIST_ENTRY NotifyList, + PSTRING FullTargetName, + USHORT TargetNameOffset, + PSTRING StreamName, + PSTRING NormalizedParentName, + ULONG FilterMatch, + ULONG Action, + PVOID TargetContext); VOID FspInitializeSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem, PWORKER_THREAD_ROUTINE Routine, PVOID Context); VOID FspExecuteSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem); @@ -62,6 +84,9 @@ VOID FspSafeMdlDelete(FSP_SAFE_MDL *SafeMdl); #pragma alloc_text(PAGE, FspCcPrepareMdlWrite) #pragma alloc_text(PAGE, FspCcMdlWriteComplete) #pragma alloc_text(PAGE, FspQuerySecurityDescriptorInfo) +#pragma alloc_text(PAGE, FspNotifyInitializeSync) +#pragma alloc_text(PAGE, FspNotifyFullChangeDirectory) +#pragma alloc_text(PAGE, FspNotifyFullReportChange) #pragma alloc_text(PAGE, FspInitializeSynchronousWorkItem) #pragma alloc_text(PAGE, FspExecuteSynchronousWorkItem) #pragma alloc_text(PAGE, FspExecuteSynchronousWorkItemRoutine) @@ -525,6 +550,101 @@ NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation return STATUS_BUFFER_TOO_SMALL == Result ? STATUS_BUFFER_OVERFLOW : Result; } +NTSTATUS FspNotifyInitializeSync(PNOTIFY_SYNC *NotifySync) +{ + PAGED_CODE(); + + NTSTATUS Result; + + try + { + FsRtlNotifyInitializeSync(NotifySync); + Result = STATUS_SUCCESS; + } + except (EXCEPTION_EXECUTE_HANDLER) + { + Result = GetExceptionCode(); + } + + return Result; +} + +NTSTATUS FspNotifyFullChangeDirectory( + PNOTIFY_SYNC NotifySync, + PLIST_ENTRY NotifyList, + PVOID FsContext, + PSTRING FullDirectoryName, + BOOLEAN WatchTree, + BOOLEAN IgnoreBuffer, + ULONG CompletionFilter, + PIRP NotifyIrp, + PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback, + PSECURITY_SUBJECT_CONTEXT SubjectContext) +{ + PAGED_CODE(); + + NTSTATUS Result; + + try + { + FsRtlNotifyFullChangeDirectory( + NotifySync, + NotifyList, + FsContext, + FullDirectoryName, + WatchTree, + IgnoreBuffer, + CompletionFilter, + NotifyIrp, + TraverseCallback, + SubjectContext); + Result = STATUS_SUCCESS; + } + except (EXCEPTION_EXECUTE_HANDLER) + { + Result = GetExceptionCode(); + } + + return Result; +} + +NTSTATUS FspNotifyFullReportChange( + PNOTIFY_SYNC NotifySync, + PLIST_ENTRY NotifyList, + PSTRING FullTargetName, + USHORT TargetNameOffset, + PSTRING StreamName, + PSTRING NormalizedParentName, + ULONG FilterMatch, + ULONG Action, + PVOID TargetContext) +{ + PAGED_CODE(); + + NTSTATUS Result; + + try + { + FspNotifyFullReportChange( + NotifySync, + NotifyList, + FullTargetName, + TargetNameOffset, + StreamName, + NormalizedParentName, + FilterMatch, + Action, + TargetContext); + Result = STATUS_SUCCESS; + } + except (EXCEPTION_EXECUTE_HANDLER) + { + Result = GetExceptionCode(); + } + + return Result; +} + VOID FspInitializeSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem, PWORKER_THREAD_ROUTINE Routine, PVOID Context) { diff --git a/src/sys/volinfo.c b/src/sys/volinfo.c index b9890560..5b144e67 100644 --- a/src/sys/volinfo.c +++ b/src/sys/volinfo.c @@ -50,7 +50,7 @@ FSP_DRIVER_DISPATCH FspSetVolumeInformation; FSP_FSCTL_VOLUME_INFO VolumeInfoBuf;\ if (0 == VolumeInfo) \ { \ - if (!FspFsvolTryGetVolumeInfo(FsvolDeviceObject, &VolumeInfoBuf))\ + if (!FspFsvolDeviceTryGetVolumeInfo(FsvolDeviceObject, &VolumeInfoBuf))\ return FSP_STATUS_IOQ_POST; \ VolumeInfo = &VolumeInfoBuf; \ } @@ -267,7 +267,7 @@ NTSTATUS FspFsvolQueryVolumeInformationComplete( PUINT8 Buffer = Irp->AssociatedIrp.SystemBuffer; PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryFile.Length; - FspFsvolSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.QueryVolumeInformation.VolumeInfo); + FspFsvolDeviceSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.QueryVolumeInformation.VolumeInfo); switch (IrpSp->Parameters.QueryVolume.FsInformationClass) { @@ -323,7 +323,7 @@ static NTSTATUS FspFsvolSetFsLabelInformation( ((PWSTR)Request->Buffer)[Info->VolumeLabelLength / sizeof(WCHAR)] = L'\0'; } else - FspFsvolSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.SetVolumeInformation.VolumeInfo); + FspFsvolDeviceSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.SetVolumeInformation.VolumeInfo); return STATUS_SUCCESS; }