Author: pschweitzer Date: Mon Nov 22 23:30:01 2010 New Revision: 49716
URL: http://svn.reactos.org/svn/reactos?rev=49716&view=rev Log: [NTOSKRNL] - Implemented FsRtlLookupPerStreamContextInternal(), FsRtlInsertPerStreamContext(), FsRtlRemovePerStreamContext(), FsRtlTeardownPerStreamContexts() Based on my previous work on pierre-fsd branch.
Modified: trunk/reactos/ntoskrnl/fsrtl/filtrctx.c
Modified: trunk/reactos/ntoskrnl/fsrtl/filtrctx.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fsrtl/filtrctx.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/fsrtl/filtrctx.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/fsrtl/filtrctx.c [iso-8859-1] Mon Nov 22 23:30:01 2010 @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/filtrctx.c * PURPOSE: File Stream Filter Context support for File System Drivers - * PROGRAMMERS: None. + * PROGRAMMERS: Pierre Schweitzer (pierre.schweitzer@reactos.org) */
/* INCLUDES ******************************************************************/ @@ -36,16 +36,51 @@ }
/* - * @unimplemented + * @implemented */ PFSRTL_PER_STREAM_CONTEXT NTAPI -FsRtlLookupPerStreamContextInternal(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, +FsRtlLookupPerStreamContextInternal(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader, IN PVOID OwnerId OPTIONAL, IN PVOID InstanceId OPTIONAL) { - KeBugCheck(FILE_SYSTEM); - return FALSE; + PLIST_ENTRY NextEntry; + PFSRTL_PER_STREAM_CONTEXT TmpPerStreamContext, PerStreamContext = NULL; + + ASSERT(AdvFcbHeader); + ASSERT(FlagOn(AdvFcbHeader->Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS)); + + ExAcquireFastMutex(AdvFcbHeader->FastMutex); + + /* If list is empty, no need to browse it */ + if (!IsListEmpty(&(AdvFcbHeader->FilterContexts))) + { + for (NextEntry = AdvFcbHeader->FilterContexts.Flink; + NextEntry != &(AdvFcbHeader->FilterContexts); + NextEntry = NextEntry->Flink) + { + /* If we don't have any criteria for search, first entry will be enough */ + if (!OwnerId && !InstanceId) + { + PerStreamContext = (PFSRTL_PER_STREAM_CONTEXT)NextEntry; + break; + } + /* Else, we've to find something that matches with the parameters. */ + else + { + TmpPerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links); + if ((InstanceId && TmpPerStreamContext->InstanceId == InstanceId && TmpPerStreamContext->OwnerId == OwnerId) || + (OwnerId && TmpPerStreamContext->OwnerId == OwnerId)) + { + PerStreamContext = TmpPerStreamContext; + break; + } + } + } + } + ExReleaseFastMutex(AdvFcbHeader->FastMutex); + + return PerStreamContext; }
/* @@ -62,28 +97,77 @@ }
/* - * @unimplemented + * @implemented */ NTSTATUS NTAPI -FsRtlInsertPerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER PerStreamContext, - IN PFSRTL_PER_STREAM_CONTEXT Ptr) -{ - KeBugCheck(FILE_SYSTEM); - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented +FsRtlInsertPerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader, + IN PFSRTL_PER_STREAM_CONTEXT PerStreamContext) +{ + if (!(AdvFcbHeader) || !(AdvFcbHeader->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS)) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + + ExAcquireFastMutex(AdvFcbHeader->FastMutex); + InsertHeadList(&(AdvFcbHeader->FilterContexts), &(PerStreamContext->Links)); + ExReleaseFastMutex(AdvFcbHeader->FastMutex); + return STATUS_SUCCESS; +} + +/* + * @implemented */ PFSRTL_PER_STREAM_CONTEXT NTAPI -FsRtlRemovePerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, +FsRtlRemovePerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader, IN PVOID OwnerId OPTIONAL, IN PVOID InstanceId OPTIONAL) { - KeBugCheck(FILE_SYSTEM); - return NULL; + PLIST_ENTRY NextEntry; + PFSRTL_PER_STREAM_CONTEXT TmpPerStreamContext, PerStreamContext = NULL; + + if (!(AdvFcbHeader) || !(AdvFcbHeader->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS)) + { + return NULL; + } + + ExAcquireFastMutex(AdvFcbHeader->FastMutex); + /* If list is empty, no need to browse it */ + if (!IsListEmpty(&(AdvFcbHeader->FilterContexts))) + { + for (NextEntry = AdvFcbHeader->FilterContexts.Flink; + NextEntry != &(AdvFcbHeader->FilterContexts); + NextEntry = NextEntry->Flink) + { + /* If we don't have any criteria for search, first entry will be enough */ + if (!OwnerId && !InstanceId) + { + PerStreamContext = (PFSRTL_PER_STREAM_CONTEXT)NextEntry; + break; + } + /* Else, we've to find something that matches with the parameters. */ + else + { + TmpPerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links); + if ((InstanceId && TmpPerStreamContext->InstanceId == InstanceId && TmpPerStreamContext->OwnerId == OwnerId) || + (OwnerId && TmpPerStreamContext->OwnerId == OwnerId)) + { + PerStreamContext = TmpPerStreamContext; + break; + } + } + } + /* Finally remove entry from list */ + if (PerStreamContext) + { + RemoveEntryList(&(PerStreamContext->Links)); + } + } + ExReleaseFastMutex(AdvFcbHeader->FastMutex); + + return PerStreamContext; + }
/* @@ -112,12 +196,49 @@ }
/* - * @unimplemented + * @implemented */ VOID NTAPI -FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvancedHeader) -{ - KeBugCheck(FILE_SYSTEM); -} - +FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader) +{ + PLIST_ENTRY NextEntry; + BOOLEAN IsMutexLocked = FALSE; + PFSRTL_PER_STREAM_CONTEXT PerStreamContext; + + _SEH2_TRY + { + /* Acquire mutex to deal with the list */ + ExAcquireFastMutex(AdvFcbHeader->FastMutex); + IsMutexLocked = TRUE; + + /* While there are items... */ + while (!IsListEmpty(&(AdvFcbHeader->FilterContexts))) + { + /* ...remove one */ + NextEntry = RemoveHeadList(&(AdvFcbHeader->FilterContexts)); + PerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links); + + /* Release mutex before calling callback */ + ExReleaseFastMutex(AdvFcbHeader->FastMutex); + IsMutexLocked = FALSE; + + /* Call the callback */ + ASSERT(PerStreamContext->FreeCallback); + (*PerStreamContext->FreeCallback)(PerStreamContext); + + /* Relock the list to continue */ + ExAcquireFastMutex(AdvFcbHeader->FastMutex); + IsMutexLocked = TRUE; + } + } + _SEH2_FINALLY + { + /* If mutex was locked, release */ + if (IsMutexLocked) + { + ExReleaseFastMutex(AdvFcbHeader->FastMutex); + } + } + _SEH2_END; +}