mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: IRP_MN_NOTIFY_CHANGE_DIRECTORY: implementation and related changes
This commit is contained in:
parent
fdb74e60ee
commit
aa81e1ffe5
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user