mirror of
https://github.com/reactos/reactos.git
synced 2025-05-19 17:14:32 +00:00
[FSRTL]
Import code from Pierre Schweitzer's fsrtl branch. - Large MCB and MCB - Change notification svn path=/trunk/; revision=55914
This commit is contained in:
parent
c131df4a4c
commit
9d75a5ebae
6 changed files with 1230 additions and 261 deletions
|
@ -119,6 +119,7 @@ list(APPEND SOURCE
|
||||||
fsrtl/fsfilter.c
|
fsrtl/fsfilter.c
|
||||||
fsrtl/fsrtlpc.c
|
fsrtl/fsrtlpc.c
|
||||||
fsrtl/largemcb.c
|
fsrtl/largemcb.c
|
||||||
|
fsrtl/mcb.c
|
||||||
fsrtl/name.c
|
fsrtl/name.c
|
||||||
fsrtl/notify.c
|
fsrtl/notify.c
|
||||||
fsrtl/oplock.c
|
fsrtl/oplock.c
|
||||||
|
|
|
@ -169,6 +169,8 @@ FsRtlInitSystem(VOID)
|
||||||
IFS_POOL_TAG,
|
IFS_POOL_TAG,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
FsRtlInitializeLargeMcbs();
|
||||||
|
|
||||||
/* Allocate the Resource Buffer */
|
/* Allocate the Resource Buffer */
|
||||||
FsRtlPagingIoResources = FsRtlAllocatePoolWithTag(NonPagedPool,
|
FsRtlPagingIoResources = FsRtlAllocatePoolWithTag(NonPagedPool,
|
||||||
FSRTL_MAX_RESOURCES *
|
FSRTL_MAX_RESOURCES *
|
||||||
|
|
File diff suppressed because it is too large
Load diff
190
reactos/ntoskrnl/fsrtl/mcb.c
Normal file
190
reactos/ntoskrnl/fsrtl/mcb.c
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: ntoskrnl/fsrtl/mcb.c
|
||||||
|
* PURPOSE: Mapped Control Block (MCB) support for File System Drivers
|
||||||
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
FsRtlAddMcbEntry(IN PMCB Mcb,
|
||||||
|
IN VBN Vbn,
|
||||||
|
IN LBN Lbn,
|
||||||
|
IN ULONG SectorCount)
|
||||||
|
{
|
||||||
|
/* Call the newer function */
|
||||||
|
return FsRtlAddLargeMcbEntry(&Mcb->
|
||||||
|
DummyFieldThatSizesThisStructureCorrectly,
|
||||||
|
(LONGLONG)Vbn,
|
||||||
|
(LONGLONG)Lbn,
|
||||||
|
(LONGLONG)SectorCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
FsRtlGetNextMcbEntry(IN PMCB Mcb,
|
||||||
|
IN ULONG RunIndex,
|
||||||
|
OUT PVBN Vbn,
|
||||||
|
OUT PLBN Lbn,
|
||||||
|
OUT PULONG SectorCount)
|
||||||
|
{
|
||||||
|
BOOLEAN Return = FALSE;
|
||||||
|
LONGLONG llVbn;
|
||||||
|
LONGLONG llLbn;
|
||||||
|
LONGLONG llSectorCount;
|
||||||
|
|
||||||
|
/* Call the Large version */
|
||||||
|
Return = FsRtlGetNextLargeMcbEntry(
|
||||||
|
&Mcb->DummyFieldThatSizesThisStructureCorrectly,
|
||||||
|
RunIndex,
|
||||||
|
&llVbn,
|
||||||
|
&llLbn,
|
||||||
|
&llSectorCount);
|
||||||
|
|
||||||
|
/* Return the lower 32 bits */
|
||||||
|
*Vbn = (ULONG)llVbn;
|
||||||
|
*Lbn = (ULONG)llLbn;
|
||||||
|
*SectorCount = (ULONG)llSectorCount;
|
||||||
|
|
||||||
|
/* And return the original value */
|
||||||
|
return Return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FsRtlInitializeMcb(IN PMCB Mcb,
|
||||||
|
IN POOL_TYPE PoolType)
|
||||||
|
{
|
||||||
|
/* Call the newer function */
|
||||||
|
FsRtlInitializeLargeMcb(&Mcb->DummyFieldThatSizesThisStructureCorrectly,
|
||||||
|
PoolType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
FsRtlLookupLastMcbEntry(IN PMCB Mcb,
|
||||||
|
OUT PVBN Vbn,
|
||||||
|
OUT PLBN Lbn)
|
||||||
|
{
|
||||||
|
BOOLEAN Return = FALSE;
|
||||||
|
LONGLONG llVbn = 0;
|
||||||
|
LONGLONG llLbn = 0;
|
||||||
|
|
||||||
|
/* Call the Large version */
|
||||||
|
Return = FsRtlLookupLastLargeMcbEntry(
|
||||||
|
&Mcb->DummyFieldThatSizesThisStructureCorrectly,
|
||||||
|
&llVbn,
|
||||||
|
&llLbn);
|
||||||
|
|
||||||
|
/* Return the lower 32-bits */
|
||||||
|
*Vbn = (ULONG)llVbn;
|
||||||
|
*Lbn = (ULONG)llLbn;
|
||||||
|
|
||||||
|
/* And return the original value */
|
||||||
|
return Return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
FsRtlLookupMcbEntry(IN PMCB Mcb,
|
||||||
|
IN VBN Vbn,
|
||||||
|
OUT PLBN Lbn,
|
||||||
|
OUT PULONG SectorCount OPTIONAL,
|
||||||
|
OUT PULONG Index)
|
||||||
|
{
|
||||||
|
BOOLEAN Return = FALSE;
|
||||||
|
LONGLONG llLbn;
|
||||||
|
LONGLONG llSectorCount;
|
||||||
|
|
||||||
|
/* Call the Large version */
|
||||||
|
Return = FsRtlLookupLargeMcbEntry(&Mcb->
|
||||||
|
DummyFieldThatSizesThisStructureCorrectly,
|
||||||
|
(LONGLONG)Vbn,
|
||||||
|
&llLbn,
|
||||||
|
&llSectorCount,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
Index);
|
||||||
|
|
||||||
|
/* Return the lower 32-bits */
|
||||||
|
*Lbn = (ULONG)llLbn;
|
||||||
|
if (SectorCount) *SectorCount = (ULONG)llSectorCount;
|
||||||
|
|
||||||
|
/* And return the original value */
|
||||||
|
return Return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
FsRtlNumberOfRunsInMcb(IN PMCB Mcb)
|
||||||
|
{
|
||||||
|
/* Call the newer function */
|
||||||
|
return FsRtlNumberOfRunsInLargeMcb(
|
||||||
|
&Mcb->DummyFieldThatSizesThisStructureCorrectly);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FsRtlRemoveMcbEntry(IN PMCB Mcb,
|
||||||
|
IN VBN Vbn,
|
||||||
|
IN ULONG SectorCount)
|
||||||
|
{
|
||||||
|
/* Call the large function */
|
||||||
|
FsRtlRemoveLargeMcbEntry(&Mcb->DummyFieldThatSizesThisStructureCorrectly,
|
||||||
|
(LONGLONG)Vbn,
|
||||||
|
(LONGLONG)SectorCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FsRtlTruncateMcb(IN PMCB Mcb,
|
||||||
|
IN VBN Vbn)
|
||||||
|
{
|
||||||
|
/* Call the newer function */
|
||||||
|
FsRtlTruncateLargeMcb(&Mcb->DummyFieldThatSizesThisStructureCorrectly,
|
||||||
|
(LONGLONG)Vbn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FsRtlUninitializeMcb(IN PMCB Mcb)
|
||||||
|
{
|
||||||
|
/* Call the newer function */
|
||||||
|
FsRtlUninitializeLargeMcb(&Mcb->DummyFieldThatSizesThisStructureCorrectly);
|
||||||
|
}
|
|
@ -12,6 +12,68 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
PNOTIFY_CHANGE
|
||||||
|
FsRtlIsNotifyOnList(IN PLIST_ENTRY NotifyList,
|
||||||
|
IN PVOID FsContext)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY NextEntry;
|
||||||
|
PNOTIFY_CHANGE NotifyChange;
|
||||||
|
|
||||||
|
if (!IsListEmpty(NotifyList))
|
||||||
|
{
|
||||||
|
/* Browse the notifications list to find the matching entry */
|
||||||
|
for (NextEntry = NotifyList->Flink;
|
||||||
|
NextEntry != NotifyList;
|
||||||
|
NextEntry = NextEntry->Flink)
|
||||||
|
{
|
||||||
|
NotifyChange = CONTAINING_RECORD(NextEntry, NOTIFY_CHANGE, NotifyList);
|
||||||
|
/* If the current record matches with the given context, it's the good one */
|
||||||
|
if (NotifyChange->FsContext == FsContext)
|
||||||
|
{
|
||||||
|
return NotifyChange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FORCEINLINE
|
||||||
|
FsRtlNotifyAcquireFastMutex(IN PREAL_NOTIFY_SYNC RealNotifySync)
|
||||||
|
{
|
||||||
|
ULONG_PTR CurrentThread = (ULONG_PTR)KeGetCurrentThread();
|
||||||
|
|
||||||
|
/* Only acquire fast mutex if it's not already acquired by the current thread */
|
||||||
|
if (RealNotifySync->OwningThread != CurrentThread)
|
||||||
|
{
|
||||||
|
ExAcquireFastMutexUnsafe(&(RealNotifySync->FastMutex));
|
||||||
|
RealNotifySync->OwningThread = CurrentThread;
|
||||||
|
}
|
||||||
|
/* Whatever the case, keep trace of the attempt to acquire fast mutex */
|
||||||
|
RealNotifySync->OwnerCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FsRtlNotifyCompleteIrpList(IN PNOTIFY_CHANGE NotifyChange,
|
||||||
|
IN NTSTATUS Status)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FORCEINLINE
|
||||||
|
FsRtlNotifyReleaseFastMutex(IN PREAL_NOTIFY_SYNC RealNotifySync)
|
||||||
|
{
|
||||||
|
RealNotifySync->OwnerCount--;
|
||||||
|
/* Release the fast mutex only if no other instance needs it */
|
||||||
|
if (!RealNotifySync->OwnerCount)
|
||||||
|
{
|
||||||
|
ExReleaseFastMutexUnsafe(&(RealNotifySync->FastMutex));
|
||||||
|
RealNotifySync->OwningThread = (ULONG_PTR)0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
@ -44,8 +106,7 @@
|
||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*
|
*
|
||||||
* @remarks This function only redirects to FsRtlNotifyFullChangeDirectory.
|
* @remarks This function only redirects to FsRtlNotifyFilterChangeDirectory.
|
||||||
* So, it's better to call the entire function.
|
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
VOID
|
VOID
|
||||||
|
@ -58,32 +119,33 @@ FsRtlNotifyChangeDirectory(IN PNOTIFY_SYNC NotifySync,
|
||||||
IN ULONG CompletionFilter,
|
IN ULONG CompletionFilter,
|
||||||
IN PIRP NotifyIrp)
|
IN PIRP NotifyIrp)
|
||||||
{
|
{
|
||||||
FsRtlNotifyFullChangeDirectory(NotifySync,
|
FsRtlNotifyFilterChangeDirectory(NotifySync,
|
||||||
NotifyList,
|
NotifyList,
|
||||||
FsContext,
|
FsContext,
|
||||||
FullDirectoryName,
|
FullDirectoryName,
|
||||||
WatchTree,
|
WatchTree,
|
||||||
TRUE,
|
TRUE,
|
||||||
CompletionFilter,
|
CompletionFilter,
|
||||||
NotifyIrp,
|
NotifyIrp,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* @name FsRtlNotifyCleanup
|
* @name FsRtlNotifyCleanup
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* Called by FSD when all handles to FileObject (identified by FsContext) are closed
|
* Called by FSD when all handles to FileObject (identified by FsContext) are closed
|
||||||
*
|
*
|
||||||
* @param NotifySync
|
* @param NotifySync
|
||||||
* FILLME
|
* Synchronization object pointer
|
||||||
*
|
*
|
||||||
* @param NotifyList
|
* @param NotifyList
|
||||||
* FILLME
|
* Notify list pointer (to head)
|
||||||
*
|
*
|
||||||
* @param FsContext
|
* @param FsContext
|
||||||
* FILLME
|
* Used to identify the notify structure
|
||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*
|
*
|
||||||
|
@ -96,7 +158,67 @@ FsRtlNotifyCleanup(IN PNOTIFY_SYNC NotifySync,
|
||||||
IN PLIST_ENTRY NotifyList,
|
IN PLIST_ENTRY NotifyList,
|
||||||
IN PVOID FsContext)
|
IN PVOID FsContext)
|
||||||
{
|
{
|
||||||
KeBugCheck(FILE_SYSTEM);
|
PNOTIFY_CHANGE NotifyChange;
|
||||||
|
PREAL_NOTIFY_SYNC RealNotifySync;
|
||||||
|
PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
|
||||||
|
|
||||||
|
/* Get real structure hidden behind the opaque pointer */
|
||||||
|
RealNotifySync = (PREAL_NOTIFY_SYNC)NotifySync;
|
||||||
|
|
||||||
|
/* Acquire the fast mutex */
|
||||||
|
FsRtlNotifyAcquireFastMutex(RealNotifySync);
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
/* Find if there's a matching notification with the FsContext */
|
||||||
|
NotifyChange = FsRtlIsNotifyOnList(NotifyList, FsContext);
|
||||||
|
if (NotifyChange)
|
||||||
|
{
|
||||||
|
/* Mark it as to know that cleanup is in process */
|
||||||
|
NotifyChange->Flags |= CLEANUP_IN_PROCESS;
|
||||||
|
|
||||||
|
/* If there are pending IRPs, complete them using the STATUS_NOTIFY_CLEANUP status */
|
||||||
|
if (!IsListEmpty(NotifyChange->NotifyIrps))
|
||||||
|
{
|
||||||
|
FsRtlNotifyCompleteIrpList(NotifyChange, STATUS_NOTIFY_CLEANUP);
|
||||||
|
}
|
||||||
|
/* Remove from the list */
|
||||||
|
RemoveEntryList(NotifyChange->NotifyList);
|
||||||
|
|
||||||
|
/* Downcrease reference number and if 0 is reached, it's time to do complete cleanup */
|
||||||
|
if (!InterlockedDecrement((PLONG)&(NotifyChange->ReferenceCount)))
|
||||||
|
{
|
||||||
|
/* In case there was an allocated buffer, free it */
|
||||||
|
if (NotifyChange->AllocatedBuffer)
|
||||||
|
{
|
||||||
|
PsReturnProcessPagedPoolQuota(NotifyChange->OwningProcess, NotifyChange->ThisBufferLength);
|
||||||
|
ExFreePool(NotifyChange->AllocatedBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In case there the string was set, get the captured subject security context */
|
||||||
|
if (NotifyChange->FullDirectoryName)
|
||||||
|
{
|
||||||
|
SubjectContext = NotifyChange->SubjectContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, free the notification, as it's not needed anymore */
|
||||||
|
ExFreePool(NotifyChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_FINALLY
|
||||||
|
{
|
||||||
|
/* Release fast mutex */
|
||||||
|
FsRtlNotifyReleaseFastMutex(RealNotifySync);
|
||||||
|
|
||||||
|
/* If the subject security context was captured, release and free it */
|
||||||
|
if (SubjectContext)
|
||||||
|
{
|
||||||
|
SeReleaseSubjectContext(SubjectContext);
|
||||||
|
ExFreePool(SubjectContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
@ -219,43 +341,46 @@ FsRtlNotifyFilterReportChange(IN PNOTIFY_SYNC NotifySync,
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* @name FsRtlNotifyFullChangeDirectory
|
* @name FsRtlNotifyFullChangeDirectory
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* FILLME
|
* Lets FSD know if changes occures in the specified directory.
|
||||||
*
|
*
|
||||||
* @param NotifySync
|
* @param NotifySync
|
||||||
* FILLME
|
* Synchronization object pointer
|
||||||
*
|
*
|
||||||
* @param NotifyList
|
* @param NotifyList
|
||||||
* FILLME
|
* Notify list pointer (to head)
|
||||||
*
|
*
|
||||||
* @param FsContext
|
* @param FsContext
|
||||||
* FILLME
|
* Used to identify the notify structure
|
||||||
*
|
*
|
||||||
* @param FullDirectoryName
|
* @param FullDirectoryName
|
||||||
* FILLME
|
* String (A or W) containing the full directory name
|
||||||
*
|
*
|
||||||
* @param WatchTree
|
* @param WatchTree
|
||||||
* FILLME
|
* True to notify changes in subdirectories too
|
||||||
*
|
*
|
||||||
* @param IgnoreBuffer
|
* @param IgnoreBuffer
|
||||||
* FILLME
|
* True to reenumerate directory. It's ignored it NotifyIrp is null
|
||||||
*
|
*
|
||||||
* @param CompletionFilter
|
* @param CompletionFilter
|
||||||
* FILLME
|
* Used to define types of changes to notify
|
||||||
*
|
*
|
||||||
* @param Irp
|
* @param NotifyIrp
|
||||||
* FILLME
|
* IRP pointer to complete notify operation. It can be null
|
||||||
*
|
*
|
||||||
* @param TraverseCallback
|
* @param TraverseCallback
|
||||||
* FILLME
|
* Pointer to a callback function. It's called each time a change is
|
||||||
|
* done in a subdirectory of the main directory. It's ignored it NotifyIrp
|
||||||
|
* is null
|
||||||
*
|
*
|
||||||
* @param SubjectContext
|
* @param SubjectContext
|
||||||
* FILLME
|
* Pointer to pass to SubjectContext member of TraverseCallback.
|
||||||
|
* It's freed after use. It's ignored it NotifyIrp is null
|
||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*
|
*
|
||||||
* @remarks None
|
* @remarks This function only redirects to FsRtlNotifyFilterChangeDirectory.
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
VOID
|
VOID
|
||||||
|
@ -267,49 +392,60 @@ FsRtlNotifyFullChangeDirectory(IN PNOTIFY_SYNC NotifySync,
|
||||||
IN BOOLEAN WatchTree,
|
IN BOOLEAN WatchTree,
|
||||||
IN BOOLEAN IgnoreBuffer,
|
IN BOOLEAN IgnoreBuffer,
|
||||||
IN ULONG CompletionFilter,
|
IN ULONG CompletionFilter,
|
||||||
IN PIRP Irp,
|
IN PIRP NotifyIrp,
|
||||||
IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL,
|
IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL,
|
||||||
IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL)
|
IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL)
|
||||||
{
|
{
|
||||||
KeBugCheck(FILE_SYSTEM);
|
FsRtlNotifyFilterChangeDirectory(NotifySync,
|
||||||
|
NotifyList,
|
||||||
|
FsContext,
|
||||||
|
FullDirectoryName,
|
||||||
|
WatchTree,
|
||||||
|
IgnoreBuffer,
|
||||||
|
CompletionFilter,
|
||||||
|
NotifyIrp,
|
||||||
|
TraverseCallback,
|
||||||
|
SubjectContext,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* @name FsRtlNotifyFullReportChange
|
* @name FsRtlNotifyFullReportChange
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* FILLME
|
* Complets the pending notify IRPs.
|
||||||
*
|
*
|
||||||
* @param NotifySync
|
* @param NotifySync
|
||||||
* FILLME
|
* Synchronization object pointer
|
||||||
*
|
*
|
||||||
* @param NotifyList
|
* @param NotifyList
|
||||||
* FILLME
|
* Notify list pointer (to head)
|
||||||
*
|
*
|
||||||
* @param FullTargetName
|
* @param FullTargetName
|
||||||
* FILLME
|
* String (A or W) containing the full directory name that changed
|
||||||
*
|
*
|
||||||
* @param TargetNameOffset
|
* @param TargetNameOffset
|
||||||
* FILLME
|
* Offset, in FullTargetName, of the final component that is in the changed directory
|
||||||
*
|
*
|
||||||
* @param StreamName
|
* @param StreamName
|
||||||
* FILLME
|
* String (A or W) containing a stream name
|
||||||
*
|
*
|
||||||
* @param NormalizedParentName
|
* @param NormalizedParentName
|
||||||
* FILLME
|
* String (A or W) containing the full directory name that changed with long names
|
||||||
*
|
*
|
||||||
* @param FilterMatch
|
* @param FilterMatch
|
||||||
* FILLME
|
* Flags that will be compared to the completion filter
|
||||||
*
|
*
|
||||||
* @param Action
|
* @param Action
|
||||||
* FILLME
|
* Action code to store in user's buffer
|
||||||
*
|
*
|
||||||
* @param TargetContext
|
* @param TargetContext
|
||||||
* FILLME
|
* Pointer to a callback function. It's called each time a change is
|
||||||
|
* done in a subdirectory of the main directory.
|
||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*
|
*
|
||||||
* @remarks None
|
* @remarks This function only redirects to FsRtlNotifyFilterReportChange.
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
VOID
|
VOID
|
||||||
|
@ -324,54 +460,73 @@ FsRtlNotifyFullReportChange(IN PNOTIFY_SYNC NotifySync,
|
||||||
IN ULONG Action,
|
IN ULONG Action,
|
||||||
IN PVOID TargetContext)
|
IN PVOID TargetContext)
|
||||||
{
|
{
|
||||||
KeBugCheck(FILE_SYSTEM);
|
FsRtlNotifyFilterReportChange(NotifySync,
|
||||||
|
NotifyList,
|
||||||
|
FullTargetName,
|
||||||
|
TargetNameOffset,
|
||||||
|
StreamName,
|
||||||
|
NormalizedParentName,
|
||||||
|
FilterMatch,
|
||||||
|
Action,
|
||||||
|
TargetContext,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* @name FsRtlNotifyInitializeSync
|
* @name FsRtlNotifyInitializeSync
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* FILLME
|
* Allocates the internal structure associated with notifications.
|
||||||
*
|
*
|
||||||
* @param NotifySync
|
* @param NotifySync
|
||||||
* FILLME
|
* Opaque pointer. It will receive the address of the allocated internal structure.
|
||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*
|
*
|
||||||
* @remarks None
|
* @remarks This function raise an exception in case of a failure.
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
FsRtlNotifyInitializeSync(IN PNOTIFY_SYNC *NotifySync)
|
FsRtlNotifyInitializeSync(IN PNOTIFY_SYNC *NotifySync)
|
||||||
{
|
{
|
||||||
KeBugCheck(FILE_SYSTEM);
|
PREAL_NOTIFY_SYNC RealNotifySync;
|
||||||
|
|
||||||
|
*NotifySync = NULL;
|
||||||
|
|
||||||
|
RealNotifySync = ExAllocatePoolWithTag(NonPagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
|
||||||
|
sizeof(REAL_NOTIFY_SYNC), TAG('F', 'S', 'N', 'S'));
|
||||||
|
ExInitializeFastMutex(&(RealNotifySync->FastMutex));
|
||||||
|
RealNotifySync->OwningThread = 0;
|
||||||
|
RealNotifySync->OwnerCount = 0;
|
||||||
|
|
||||||
|
*NotifySync = RealNotifySync;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* @name FsRtlNotifyReportChange
|
* @name FsRtlNotifyReportChange
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* FILLME
|
* Complets the pending notify IRPs.
|
||||||
*
|
*
|
||||||
* @param NotifySync
|
* @param NotifySync
|
||||||
* FILLME
|
* Synchronization object pointer
|
||||||
*
|
*
|
||||||
* @param NotifyList
|
* @param NotifyList
|
||||||
* FILLME
|
* Notify list pointer (to head)
|
||||||
*
|
*
|
||||||
* @param FullTargetName
|
* @param FullTargetName
|
||||||
* FILLME
|
* String (A or W) containing the full directory name that changed
|
||||||
*
|
*
|
||||||
* @param FileNamePartLength
|
* @param FileNamePartLength
|
||||||
* FILLME
|
* Length of the final component that is in the changed directory
|
||||||
*
|
*
|
||||||
* @param FilterMatch
|
* @param FilterMatch
|
||||||
* FILLME
|
* Flags that will be compared to the completion filter
|
||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*
|
*
|
||||||
* @remarks None
|
* @remarks This function only redirects to FsRtlNotifyFilterReportChange.
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
VOID
|
VOID
|
||||||
|
@ -382,11 +537,20 @@ FsRtlNotifyReportChange(IN PNOTIFY_SYNC NotifySync,
|
||||||
IN PUSHORT FileNamePartLength,
|
IN PUSHORT FileNamePartLength,
|
||||||
IN ULONG FilterMatch)
|
IN ULONG FilterMatch)
|
||||||
{
|
{
|
||||||
KeBugCheck(FILE_SYSTEM);
|
FsRtlNotifyFilterReportChange(NotifySync,
|
||||||
|
NotifyList,
|
||||||
|
FullTargetName,
|
||||||
|
FullTargetName->Length - *FileNamePartLength,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
FilterMatch,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* @name FsRtlCurrentBatchOplock
|
* @name FsRtlNotifyUninitializeSync
|
||||||
* @implemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* Uninitialize a NOTIFY_SYNC object
|
* Uninitialize a NOTIFY_SYNC object
|
||||||
|
@ -404,6 +568,10 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
|
FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
|
||||||
{
|
{
|
||||||
KeBugCheck(FILE_SYSTEM);
|
if (*NotifySync)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(*NotifySync, TAG('F', 'S', 'N', 'S'));
|
||||||
|
*NotifySync = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef TAG
|
||||||
|
#define TAG(w,x,y,z) (((w)<<24)|((x)<<16)|((y)<<8)|(z))
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Define this if you want debugging support
|
// Define this if you want debugging support
|
||||||
//
|
//
|
||||||
|
@ -36,7 +40,7 @@
|
||||||
if (x & FsRtlpTraceLevel) DbgPrint(__VA_ARGS__)
|
if (x & FsRtlpTraceLevel) DbgPrint(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define FSTRACE(x, fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
|
#define FSTRACE(x, ...) DPRINT(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -44,12 +48,68 @@
|
||||||
//
|
//
|
||||||
#define FSRTL_MAX_RESOURCES 16
|
#define FSRTL_MAX_RESOURCES 16
|
||||||
|
|
||||||
|
//
|
||||||
|
// Number of maximum pair count per MCB
|
||||||
|
//
|
||||||
|
#define MAXIMUM_PAIR_COUNT 15
|
||||||
|
|
||||||
|
//
|
||||||
|
// Notifications flags
|
||||||
|
//
|
||||||
|
#define CLEANUP_IN_PROCESS 4
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal structure for NOTIFY_SYNC
|
||||||
|
//
|
||||||
|
typedef struct _REAL_NOTIFY_SYNC
|
||||||
|
{
|
||||||
|
FAST_MUTEX FastMutex;
|
||||||
|
ULONG_PTR OwningThread;
|
||||||
|
ULONG OwnerCount;
|
||||||
|
} REAL_NOTIFY_SYNC, * PREAL_NOTIFY_SYNC;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal structure for notifications
|
||||||
|
//
|
||||||
|
typedef struct _NOTIFY_CHANGE
|
||||||
|
{
|
||||||
|
PREAL_NOTIFY_SYNC NotifySync;
|
||||||
|
PVOID FsContext;
|
||||||
|
PVOID StreamID;
|
||||||
|
PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback;
|
||||||
|
PSECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||||
|
PSTRING FullDirectoryName;
|
||||||
|
PLIST_ENTRY NotifyList;
|
||||||
|
PLIST_ENTRY NotifyIrps;
|
||||||
|
PFILTER_REPORT_CHANGE FilterCallback;
|
||||||
|
USHORT Flags;
|
||||||
|
UCHAR CharacterSize;
|
||||||
|
ULONG CompletionFilter;
|
||||||
|
PVOID AllocatedBuffer;
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG BufferLength;
|
||||||
|
ULONG ThisBufferLength;
|
||||||
|
ULONG DataLength;
|
||||||
|
ULONG LastEntry;
|
||||||
|
ULONG ReferenceCount;
|
||||||
|
PEPROCESS OwningProcess;
|
||||||
|
} NOTIFY_CHANGE, *PNOTIFY_CHANGE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal structure for MCB Mapping pointer
|
||||||
|
//
|
||||||
|
typedef struct _INT_MAPPING
|
||||||
|
{
|
||||||
|
VBN Vbn;
|
||||||
|
LBN Lbn;
|
||||||
|
} INT_MAPPING, *PINT_MAPPING;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialization Routines
|
// Initialization Routines
|
||||||
//
|
//
|
||||||
BOOLEAN
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
FsRtlInitSystem(
|
FsRtlInitializeLargeMcbs(
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -62,6 +122,12 @@ FsRtlPTeardownPerFileObjectContexts(
|
||||||
IN PFILE_OBJECT FileObject
|
IN PFILE_OBJECT FileObject
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
FsRtlInitSystem(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Global data inside the File System Runtime Library
|
// Global data inside the File System Runtime Library
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue