mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: IRP_MN_NOTIFY_CHANGE_DIRECTORY: implementation and related changes
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
|   | ||||
| @@ -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( | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
							
								
								
									
										120
									
								
								src/sys/util.c
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								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) | ||||
| { | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user