mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -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);
|
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 */
|
/* create the user-mode file system request; MustSucceed because IRP_MJ_CLEANUP cannot fail */
|
||||||
FspIopCreateRequestMustSucceedEx(Irp, DeletePending ? &FileNode->FileName : 0, 0,
|
FspIopCreateRequestMustSucceedEx(Irp, DeletePending ? &FileNode->FileName : 0, 0,
|
||||||
FspFsvolCleanupRequestFini, &Request);
|
FspFsvolCleanupRequestFini, &Request);
|
||||||
|
@ -337,6 +337,7 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
FileDesc->CaseSensitive =
|
FileDesc->CaseSensitive =
|
||||||
0 != FsvolDeviceExtension->VolumeParams.CaseSensitiveSearch ||
|
0 != FsvolDeviceExtension->VolumeParams.CaseSensitiveSearch ||
|
||||||
BooleanFlagOn(Flags, SL_CASE_SENSITIVE);
|
BooleanFlagOn(Flags, SL_CASE_SENSITIVE);
|
||||||
|
FileDesc->HasTraversePrivilege = HasTraversePrivilege;
|
||||||
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request);
|
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request);
|
||||||
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
|
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
|
||||||
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
|
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
|
||||||
|
@ -50,9 +50,9 @@ VOID FspFsvolDeviceDeleteContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STR
|
|||||||
static RTL_AVL_COMPARE_ROUTINE FspFsvolDeviceCompareContextByName;
|
static RTL_AVL_COMPARE_ROUTINE FspFsvolDeviceCompareContextByName;
|
||||||
static RTL_AVL_ALLOCATE_ROUTINE FspFsvolDeviceAllocateContextByName;
|
static RTL_AVL_ALLOCATE_ROUTINE FspFsvolDeviceAllocateContextByName;
|
||||||
static RTL_AVL_FREE_ROUTINE FspFsvolDeviceFreeContextByName;
|
static RTL_AVL_FREE_ROUTINE FspFsvolDeviceFreeContextByName;
|
||||||
VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
NTSTATUS FspDeviceCopyList(
|
NTSTATUS FspDeviceCopyList(
|
||||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
||||||
VOID FspDeviceDeleteList(
|
VOID FspDeviceDeleteList(
|
||||||
@ -346,6 +346,13 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
|
|||||||
return Result;
|
return Result;
|
||||||
FsvolDeviceExtension->InitDoneDir = 1;
|
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 */
|
/* initialize our context table */
|
||||||
ExInitializeResourceLite(&FsvolDeviceExtension->FileRenameResource);
|
ExInitializeResourceLite(&FsvolDeviceExtension->FileRenameResource);
|
||||||
ExInitializeResourceLite(&FsvolDeviceExtension->ContextTableResource);
|
ExInitializeResourceLite(&FsvolDeviceExtension->ContextTableResource);
|
||||||
@ -395,6 +402,14 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
|
|||||||
if (FsvolDeviceExtension->InitDoneTimer)
|
if (FsvolDeviceExtension->InitDoneTimer)
|
||||||
IoStopTimer(DeviceObject);
|
IoStopTimer(DeviceObject);
|
||||||
|
|
||||||
|
/* uninitialize the FSRTL Notify mechanism */
|
||||||
|
if (FsvolDeviceExtension->InitDoneNotify)
|
||||||
|
{
|
||||||
|
FspNotifyCleanupAll(
|
||||||
|
FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList);
|
||||||
|
FspNotifyUninitializeSync(&FsvolDeviceExtension->NotifySync);
|
||||||
|
}
|
||||||
|
|
||||||
/* delete the directory meta cache */
|
/* delete the directory meta cache */
|
||||||
if (FsvolDeviceExtension->InitDoneDir)
|
if (FsvolDeviceExtension->InitDoneDir)
|
||||||
FspMetaCacheDelete(FsvolDeviceExtension->DirInfoCache);
|
FspMetaCacheDelete(FsvolDeviceExtension->DirInfoCache);
|
||||||
@ -753,7 +768,7 @@ static VOID NTAPI FspFsvolDeviceFreeContextByName(
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||||
{
|
{
|
||||||
// !PAGED_CODE();
|
// !PAGED_CODE();
|
||||||
|
|
||||||
@ -770,7 +785,7 @@ VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *V
|
|||||||
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4701) /* disable idiotic warning! */
|
#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();
|
// !PAGED_CODE();
|
||||||
|
|
||||||
@ -796,7 +811,7 @@ BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_I
|
|||||||
}
|
}
|
||||||
#pragma warning(pop)
|
#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();
|
// !PAGED_CODE();
|
||||||
|
|
||||||
|
@ -571,7 +571,52 @@ static NTSTATUS FspFsvolNotifyChangeDirectory(
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* is this a valid FileObject? */
|
||||||
|
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
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(
|
static NTSTATUS FspFsvolDirectoryControl(
|
||||||
|
@ -411,6 +411,40 @@ NTSTATUS FspCcMdlWriteComplete(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffse
|
|||||||
NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation,
|
NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength,
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength,
|
||||||
PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor);
|
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 */
|
/* utility: synchronous work queue */
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -665,7 +699,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
FSP_DEVICE_EXTENSION Base;
|
FSP_DEVICE_EXTENSION Base;
|
||||||
UINT32 InitDoneFsvrt:1, InitDoneDelRsc:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1,
|
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 FsctlDeviceObject;
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||||
HANDLE MupHandle;
|
HANDLE MupHandle;
|
||||||
@ -691,6 +725,8 @@ typedef struct
|
|||||||
KSPIN_LOCK InfoSpinLock;
|
KSPIN_LOCK InfoSpinLock;
|
||||||
UINT64 InfoExpirationTime;
|
UINT64 InfoExpirationTime;
|
||||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||||
|
PNOTIFY_SYNC NotifySync;
|
||||||
|
LIST_ENTRY NotifyList;
|
||||||
} FSP_FSVOL_DEVICE_EXTENSION;
|
} FSP_FSVOL_DEVICE_EXTENSION;
|
||||||
static inline
|
static inline
|
||||||
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
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);
|
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_ELEMENT *ElementStorage, PBOOLEAN PInserted);
|
||||||
VOID FspFsvolDeviceDeleteContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
VOID FspFsvolDeviceDeleteContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
||||||
PBOOLEAN PDeleted);
|
PBOOLEAN PDeleted);
|
||||||
VOID FspFsvolGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
NTSTATUS FspDeviceCopyList(
|
NTSTATUS FspDeviceCopyList(
|
||||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
||||||
VOID FspDeviceDeleteList(
|
VOID FspDeviceDeleteList(
|
||||||
@ -835,6 +871,7 @@ typedef struct
|
|||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
UINT64 UserContext2;
|
UINT64 UserContext2;
|
||||||
BOOLEAN CaseSensitive;
|
BOOLEAN CaseSensitive;
|
||||||
|
BOOLEAN HasTraversePrivilege;
|
||||||
BOOLEAN DeleteOnClose;
|
BOOLEAN DeleteOnClose;
|
||||||
BOOLEAN DirectoryHasSuchFile;
|
BOOLEAN DirectoryHasSuchFile;
|
||||||
UNICODE_STRING DirectoryPattern;
|
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);
|
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 FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode);
|
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
||||||
|
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,
|
||||||
|
@ -42,7 +42,9 @@ 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 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);
|
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,
|
||||||
@ -76,7 +78,8 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
|
|||||||
// !#pragma alloc_text(PAGE, FspFileNodeReferenceDirInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeReferenceDirInfo)
|
||||||
// !#pragma alloc_text(PAGE, FspFileNodeSetDirInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeSetDirInfo)
|
||||||
// !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo)
|
// !#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, FspFileDescCreate)
|
||||||
#pragma alloc_text(PAGE, FspFileDescDelete)
|
#pragma alloc_text(PAGE, FspFileDescDelete)
|
||||||
#pragma alloc_text(PAGE, FspFileDescResetDirectoryPattern)
|
#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;
|
FspMetaCacheAddItem(FsvolDeviceExtension->DirInfoCache, Buffer, Size) : 0;
|
||||||
FileNode->DirInfoChangeNumber++;
|
FileNode->DirInfoChangeNumber++;
|
||||||
|
|
||||||
/* acquire the DirInfoSpinLock to protect against concurrent FspFileNodeInvalidateParentDirInfo*/
|
/* acquire the DirInfoSpinLock to protect against concurrent FspFileNodeInvalidateDirInfo */
|
||||||
KeAcquireSpinLock(&NonPaged->DirInfoSpinLock, &Irql);
|
KeAcquireSpinLock(&NonPaged->DirInfoSpinLock, &Irql);
|
||||||
NonPaged->DirInfo = DirInfo;
|
NonPaged->DirInfo = DirInfo;
|
||||||
KeReleaseSpinLock(&NonPaged->DirInfoSpinLock, Irql);
|
KeReleaseSpinLock(&NonPaged->DirInfoSpinLock, Irql);
|
||||||
@ -832,29 +835,17 @@ BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG S
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode)
|
static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
// !PAGED_CODE();
|
// !PAGED_CODE();
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
UNICODE_STRING Parent, Suffix;
|
FSP_FILE_NODE_NONPAGED *NonPaged = FileNode->NonPaged;
|
||||||
FSP_FILE_NODE_NONPAGED *NonPaged;
|
|
||||||
KIRQL Irql;
|
KIRQL Irql;
|
||||||
UINT64 DirInfo;
|
UINT64 DirInfo;
|
||||||
|
|
||||||
FspUnicodePathSuffix(&FileNode->FileName, &Parent, &Suffix);
|
/* acquire the DirInfoSpinLock to protect against concurrent FspFileNodeSetDirInfo */
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
|
||||||
FileNode = FspFsvolDeviceLookupContextByName(FsvolDeviceObject, &Parent);
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
|
||||||
|
|
||||||
if (0 == FileNode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
NonPaged = FileNode->NonPaged;
|
|
||||||
|
|
||||||
/* acquire the DirInfoSpinLock to protect against concurrent FspFileNodeSetDirInfo*/
|
|
||||||
KeAcquireSpinLock(&NonPaged->DirInfoSpinLock, &Irql);
|
KeAcquireSpinLock(&NonPaged->DirInfoSpinLock, &Irql);
|
||||||
DirInfo = NonPaged->DirInfo;
|
DirInfo = NonPaged->DirInfo;
|
||||||
KeReleaseSpinLock(&NonPaged->DirInfoSpinLock, Irql);
|
KeReleaseSpinLock(&NonPaged->DirInfoSpinLock, Irql);
|
||||||
@ -862,6 +853,46 @@ VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode)
|
|||||||
FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, DirInfo);
|
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)
|
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -790,6 +790,17 @@ static NTSTATUS FspFsvolSetDispositionInformationSuccess(
|
|||||||
FileNode->DeletePending = Info->DeleteFile;
|
FileNode->DeletePending = Info->DeleteFile;
|
||||||
FileObject->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;
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
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,
|
NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength,
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength,
|
||||||
PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor);
|
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,
|
VOID FspInitializeSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem,
|
||||||
PWORKER_THREAD_ROUTINE Routine, PVOID Context);
|
PWORKER_THREAD_ROUTINE Routine, PVOID Context);
|
||||||
VOID FspExecuteSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem);
|
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, FspCcPrepareMdlWrite)
|
||||||
#pragma alloc_text(PAGE, FspCcMdlWriteComplete)
|
#pragma alloc_text(PAGE, FspCcMdlWriteComplete)
|
||||||
#pragma alloc_text(PAGE, FspQuerySecurityDescriptorInfo)
|
#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, FspInitializeSynchronousWorkItem)
|
||||||
#pragma alloc_text(PAGE, FspExecuteSynchronousWorkItem)
|
#pragma alloc_text(PAGE, FspExecuteSynchronousWorkItem)
|
||||||
#pragma alloc_text(PAGE, FspExecuteSynchronousWorkItemRoutine)
|
#pragma alloc_text(PAGE, FspExecuteSynchronousWorkItemRoutine)
|
||||||
@ -525,6 +550,101 @@ NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation
|
|||||||
return STATUS_BUFFER_TOO_SMALL == Result ? STATUS_BUFFER_OVERFLOW : Result;
|
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,
|
VOID FspInitializeSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem,
|
||||||
PWORKER_THREAD_ROUTINE Routine, PVOID Context)
|
PWORKER_THREAD_ROUTINE Routine, PVOID Context)
|
||||||
{
|
{
|
||||||
|
@ -50,7 +50,7 @@ FSP_DRIVER_DISPATCH FspSetVolumeInformation;
|
|||||||
FSP_FSCTL_VOLUME_INFO VolumeInfoBuf;\
|
FSP_FSCTL_VOLUME_INFO VolumeInfoBuf;\
|
||||||
if (0 == VolumeInfo) \
|
if (0 == VolumeInfo) \
|
||||||
{ \
|
{ \
|
||||||
if (!FspFsvolTryGetVolumeInfo(FsvolDeviceObject, &VolumeInfoBuf))\
|
if (!FspFsvolDeviceTryGetVolumeInfo(FsvolDeviceObject, &VolumeInfoBuf))\
|
||||||
return FSP_STATUS_IOQ_POST; \
|
return FSP_STATUS_IOQ_POST; \
|
||||||
VolumeInfo = &VolumeInfoBuf; \
|
VolumeInfo = &VolumeInfoBuf; \
|
||||||
}
|
}
|
||||||
@ -267,7 +267,7 @@ NTSTATUS FspFsvolQueryVolumeInformationComplete(
|
|||||||
PUINT8 Buffer = Irp->AssociatedIrp.SystemBuffer;
|
PUINT8 Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryFile.Length;
|
PUINT8 BufferEnd = Buffer + IrpSp->Parameters.QueryFile.Length;
|
||||||
|
|
||||||
FspFsvolSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.QueryVolumeInformation.VolumeInfo);
|
FspFsvolDeviceSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.QueryVolumeInformation.VolumeInfo);
|
||||||
|
|
||||||
switch (IrpSp->Parameters.QueryVolume.FsInformationClass)
|
switch (IrpSp->Parameters.QueryVolume.FsInformationClass)
|
||||||
{
|
{
|
||||||
@ -323,7 +323,7 @@ static NTSTATUS FspFsvolSetFsLabelInformation(
|
|||||||
((PWSTR)Request->Buffer)[Info->VolumeLabelLength / sizeof(WCHAR)] = L'\0';
|
((PWSTR)Request->Buffer)[Info->VolumeLabelLength / sizeof(WCHAR)] = L'\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
FspFsvolSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.SetVolumeInformation.VolumeInfo);
|
FspFsvolDeviceSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.SetVolumeInformation.VolumeInfo);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user