ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

filtrctx.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/fsrtl/filtrctx.c
00005  * PURPOSE:         File Stream Filter Context support for File System Drivers
00006  * PROGRAMMERS:     Pierre Schweitzer (pierre.schweitzer@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* PRIVATE FUNCTIONS *********************************************************/
00016 
00017 typedef struct _FILE_OBJECT_FILTER_CONTEXTS
00018 {
00019     FAST_MUTEX FilterContextsMutex;
00020     LIST_ENTRY FilterContexts;
00021 } FILE_OBJECT_FILTER_CONTEXTS, *PFILE_OBJECT_FILTER_CONTEXTS;
00022 
00023 /*
00024  * @implemented
00025  */
00026 VOID
00027 NTAPI
00028 FsRtlPTeardownPerFileObjectContexts(IN PFILE_OBJECT FileObject)
00029 {
00030     PFILE_OBJECT_FILTER_CONTEXTS FOContext = NULL;
00031 
00032     ASSERT(FileObject);
00033 
00034     if (!(FOContext = IoGetFileObjectFilterContext(FileObject)))
00035     {
00036         return;
00037     }
00038 
00039     ASSERT(IoChangeFileObjectFilterContext(FileObject, FOContext, FALSE) == STATUS_SUCCESS);
00040     ASSERT(IsListEmpty(&(FOContext->FilterContexts)));
00041 
00042     ExFreePoolWithTag(FOContext, 'FOCX');
00043 }
00044 
00045 
00046 /* PUBLIC FUNCTIONS **********************************************************/
00047 
00048 /*++
00049  * @name FsRtlIsPagingFile
00050  * @implemented NT 5.2
00051  *
00052  *     The FsRtlIsPagingFile routine checks if the FileObject is a Paging File.
00053  *
00054  * @param FileObject
00055  *        A pointer to the File Object to be tested.
00056  *
00057  * @return TRUE if the File is a Paging File, FALSE otherwise.
00058  *
00059  * @remarks None.
00060  *
00061  *--*/
00062 LOGICAL
00063 NTAPI
00064 FsRtlIsPagingFile(IN PFILE_OBJECT FileObject)
00065 {
00066     return MmIsFileObjectAPagingFile(FileObject);
00067 }
00068 
00069 /*
00070  * @implemented
00071  */
00072 PFSRTL_PER_FILEOBJECT_CONTEXT
00073 NTAPI
00074 FsRtlLookupPerFileObjectContext(IN PFILE_OBJECT FileObject,
00075                                 IN PVOID OwnerId OPTIONAL,
00076                                 IN PVOID InstanceId OPTIONAL)
00077 {
00078     PLIST_ENTRY NextEntry;
00079     PFILE_OBJECT_FILTER_CONTEXTS FOContext = NULL;
00080     PFSRTL_PER_FILEOBJECT_CONTEXT TmpPerFOContext, PerFOContext = NULL;
00081 
00082     if (!FileObject || !(FOContext = IoGetFileObjectFilterContext(FileObject)))
00083     {
00084         return NULL;
00085     }
00086 
00087     ExAcquireFastMutex(&(FOContext->FilterContextsMutex));
00088 
00089     /* If list is empty, no need to browse it */
00090     if (!IsListEmpty(&(FOContext->FilterContexts)))
00091     {
00092         for (NextEntry = FOContext->FilterContexts.Flink;
00093              NextEntry != &(FOContext->FilterContexts);
00094              NextEntry = NextEntry->Flink)
00095         {
00096             /* If we don't have any criteria for search, first entry will be enough */
00097             if (!OwnerId && !InstanceId)
00098             {
00099                 PerFOContext = (PFSRTL_PER_FILEOBJECT_CONTEXT)NextEntry;
00100                 break;
00101             }
00102             /* Else, we've to find something that matches with the parameters. */
00103             else
00104             {
00105                 TmpPerFOContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_FILEOBJECT_CONTEXT, Links);
00106                 if ((InstanceId && TmpPerFOContext->InstanceId == InstanceId && TmpPerFOContext->OwnerId == OwnerId) ||
00107                     (OwnerId && TmpPerFOContext->OwnerId == OwnerId))
00108                 {
00109                     PerFOContext = TmpPerFOContext;
00110                     break;
00111                 }
00112             }
00113         }
00114     }
00115 
00116     ExReleaseFastMutex(&(FOContext->FilterContextsMutex));
00117 
00118     return PerFOContext;
00119 }
00120 
00121 /*
00122  * @implemented
00123  */
00124 PFSRTL_PER_STREAM_CONTEXT
00125 NTAPI
00126 FsRtlLookupPerStreamContextInternal(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader,
00127                                     IN PVOID OwnerId OPTIONAL,
00128                                     IN PVOID InstanceId OPTIONAL)
00129 {
00130     PLIST_ENTRY NextEntry;
00131     PFSRTL_PER_STREAM_CONTEXT TmpPerStreamContext, PerStreamContext = NULL;
00132 
00133     ASSERT(AdvFcbHeader);
00134     ASSERT(FlagOn(AdvFcbHeader->Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS));
00135 
00136     ExAcquireFastMutex(AdvFcbHeader->FastMutex);
00137 
00138     /* If list is empty, no need to browse it */
00139     if (!IsListEmpty(&(AdvFcbHeader->FilterContexts)))
00140     {
00141         for (NextEntry = AdvFcbHeader->FilterContexts.Flink;
00142              NextEntry != &(AdvFcbHeader->FilterContexts);
00143              NextEntry = NextEntry->Flink)
00144         {
00145             /* If we don't have any criteria for search, first entry will be enough */
00146             if (!OwnerId && !InstanceId)
00147             {
00148                 PerStreamContext = (PFSRTL_PER_STREAM_CONTEXT)NextEntry;
00149                 break;
00150             }
00151             /* Else, we've to find something that matches with the parameters. */
00152             else
00153             {
00154                 TmpPerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links);
00155                 if ((InstanceId && TmpPerStreamContext->InstanceId == InstanceId && TmpPerStreamContext->OwnerId == OwnerId) ||
00156                     (OwnerId && TmpPerStreamContext->OwnerId == OwnerId))
00157                 {
00158                     PerStreamContext = TmpPerStreamContext;
00159                     break;
00160                 }
00161             }
00162         }
00163     }
00164 
00165     ExReleaseFastMutex(AdvFcbHeader->FastMutex);
00166 
00167     return PerStreamContext;
00168 }
00169 
00170 /*
00171  * @implemented
00172  */
00173 NTSTATUS
00174 NTAPI
00175 FsRtlInsertPerFileObjectContext(IN PFILE_OBJECT FileObject,
00176                                 IN PFSRTL_PER_FILEOBJECT_CONTEXT Ptr)
00177 {
00178     PFILE_OBJECT_FILTER_CONTEXTS FOContext = NULL;
00179 
00180     if (!FileObject)
00181     {
00182         return STATUS_INVALID_PARAMETER;
00183     }
00184 
00185     if (!(FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION))
00186     {
00187         return STATUS_INVALID_DEVICE_REQUEST;
00188     }
00189 
00190     /* Get filter contexts */
00191     FOContext = IoGetFileObjectFilterContext(FileObject);
00192     if (!FOContext)
00193     {
00194         /* If there's none, allocate new structure */
00195         FOContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(FILE_OBJECT_FILTER_CONTEXTS), 'FOCX');
00196         if (!FOContext)
00197         {
00198             return STATUS_INSUFFICIENT_RESOURCES;
00199         }
00200 
00201         /* Initialize it */
00202         ExInitializeFastMutex(&(FOContext->FilterContextsMutex));
00203         InitializeListHead(&(FOContext->FilterContexts));
00204 
00205         /* Set it */
00206         if (!IoChangeFileObjectFilterContext(FileObject, FOContext, TRUE))
00207         {
00208             /* If it fails, it means that someone else has set it in the meanwhile */
00209             ExFreePoolWithTag(FOContext, 'FOCX');
00210 
00211             /* So, we can get it */
00212             FOContext = IoGetFileObjectFilterContext(FileObject);
00213             if (!FOContext)
00214             {
00215                 /* If we fall down here, something went very bad. This shouldn't happen */
00216                 ASSERT(FALSE);
00217                 return STATUS_UNSUCCESSFUL;
00218             }
00219         }
00220     }
00221 
00222     /* Finally, insert */
00223     ExAcquireFastMutex(&(FOContext->FilterContextsMutex));
00224     InsertHeadList(&(FOContext->FilterContexts), &(Ptr->Links));
00225     ExReleaseFastMutex(&(FOContext->FilterContextsMutex));
00226 
00227     return STATUS_SUCCESS;
00228 }
00229 
00230 /*
00231  * @implemented
00232  */
00233 NTSTATUS
00234 NTAPI
00235 FsRtlInsertPerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader,
00236                             IN PFSRTL_PER_STREAM_CONTEXT PerStreamContext)
00237 {
00238     if (!(AdvFcbHeader) || !(AdvFcbHeader->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS))
00239     {
00240         return STATUS_INVALID_DEVICE_REQUEST;
00241     }
00242 
00243     ExAcquireFastMutex(AdvFcbHeader->FastMutex);
00244     InsertHeadList(&(AdvFcbHeader->FilterContexts), &(PerStreamContext->Links));
00245     ExReleaseFastMutex(AdvFcbHeader->FastMutex);
00246     return STATUS_SUCCESS;
00247 }
00248 
00249 /*
00250  * @implemented
00251  */
00252 PFSRTL_PER_FILEOBJECT_CONTEXT
00253 NTAPI
00254 FsRtlRemovePerFileObjectContext(IN PFILE_OBJECT FileObject,
00255                                 IN PVOID OwnerId OPTIONAL,
00256                                 IN PVOID InstanceId OPTIONAL)
00257 {
00258     PLIST_ENTRY NextEntry;
00259     PFILE_OBJECT_FILTER_CONTEXTS FOContext = NULL;
00260     PFSRTL_PER_FILEOBJECT_CONTEXT TmpPerFOContext, PerFOContext = NULL;
00261 
00262     if (!FileObject || !(FOContext = IoGetFileObjectFilterContext(FileObject)))
00263     {
00264         return NULL;
00265     }
00266 
00267     ExAcquireFastMutex(&(FOContext->FilterContextsMutex));
00268 
00269     /* If list is empty, no need to browse it */
00270     if (!IsListEmpty(&(FOContext->FilterContexts)))
00271     {
00272         for (NextEntry = FOContext->FilterContexts.Flink;
00273              NextEntry != &(FOContext->FilterContexts);
00274              NextEntry = NextEntry->Flink)
00275         {
00276             /* If we don't have any criteria for search, first entry will be enough */
00277             if (!OwnerId && !InstanceId)
00278             {
00279                 PerFOContext = (PFSRTL_PER_FILEOBJECT_CONTEXT)NextEntry;
00280                 break;
00281             }
00282             /* Else, we've to find something that matches with the parameters. */
00283             else
00284             {
00285                 TmpPerFOContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_FILEOBJECT_CONTEXT, Links);
00286                 if ((InstanceId && TmpPerFOContext->InstanceId == InstanceId && TmpPerFOContext->OwnerId == OwnerId) ||
00287                     (OwnerId && TmpPerFOContext->OwnerId == OwnerId))
00288                 {
00289                     PerFOContext = TmpPerFOContext;
00290                     break;
00291                 }
00292             }
00293         }
00294 
00295         /* Finally remove entry from list */
00296         if (PerFOContext)
00297         {
00298             RemoveEntryList(&(PerFOContext->Links));
00299         }
00300     }
00301 
00302     ExReleaseFastMutex(&(FOContext->FilterContextsMutex));
00303 
00304     return PerFOContext;
00305 }
00306 
00307 /*
00308  * @implemented
00309  */
00310 PFSRTL_PER_STREAM_CONTEXT
00311 NTAPI
00312 FsRtlRemovePerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader,
00313                             IN PVOID OwnerId OPTIONAL,
00314                             IN PVOID InstanceId OPTIONAL)
00315 {
00316     PLIST_ENTRY NextEntry;
00317     PFSRTL_PER_STREAM_CONTEXT TmpPerStreamContext, PerStreamContext = NULL;
00318 
00319     if (!(AdvFcbHeader) || !(AdvFcbHeader->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS))
00320     {
00321         return NULL;
00322     }
00323 
00324     ExAcquireFastMutex(AdvFcbHeader->FastMutex);
00325     /* If list is empty, no need to browse it */
00326     if (!IsListEmpty(&(AdvFcbHeader->FilterContexts)))
00327     {
00328         for (NextEntry = AdvFcbHeader->FilterContexts.Flink;
00329              NextEntry != &(AdvFcbHeader->FilterContexts);
00330              NextEntry = NextEntry->Flink)
00331         {
00332             /* If we don't have any criteria for search, first entry will be enough */
00333             if (!OwnerId && !InstanceId)
00334             {
00335                 PerStreamContext = (PFSRTL_PER_STREAM_CONTEXT)NextEntry;
00336                 break;
00337             }
00338             /* Else, we've to find something that matches with the parameters. */
00339             else
00340             {
00341                 TmpPerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links);
00342                 if ((InstanceId && TmpPerStreamContext->InstanceId == InstanceId && TmpPerStreamContext->OwnerId == OwnerId) ||
00343                     (OwnerId && TmpPerStreamContext->OwnerId == OwnerId))
00344                 {
00345                     PerStreamContext = TmpPerStreamContext;
00346                     break;
00347                 }
00348             }
00349         }
00350 
00351         /* Finally remove entry from list */
00352         if (PerStreamContext)
00353         {
00354             RemoveEntryList(&(PerStreamContext->Links));
00355         }
00356     }
00357     ExReleaseFastMutex(AdvFcbHeader->FastMutex);
00358 
00359     return PerStreamContext;
00360 
00361 }
00362 
00363 /*
00364  * @implemented
00365  */
00366 VOID
00367 NTAPI
00368 FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader)
00369 {
00370     PLIST_ENTRY NextEntry;
00371     BOOLEAN IsMutexLocked = FALSE;
00372     PFSRTL_PER_STREAM_CONTEXT PerStreamContext;
00373 
00374     _SEH2_TRY
00375     {
00376         /* Acquire mutex to deal with the list */
00377         ExAcquireFastMutex(AdvFcbHeader->FastMutex);
00378         IsMutexLocked = TRUE;
00379 
00380         /* While there are items... */
00381         while (!IsListEmpty(&(AdvFcbHeader->FilterContexts)))
00382         {
00383             /* ...remove one */
00384             NextEntry = RemoveHeadList(&(AdvFcbHeader->FilterContexts));
00385             PerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links);
00386 
00387             /* Release mutex before calling callback */
00388             ExReleaseFastMutex(AdvFcbHeader->FastMutex);
00389             IsMutexLocked = FALSE;
00390 
00391             /* Call the callback */
00392             ASSERT(PerStreamContext->FreeCallback);
00393             (*PerStreamContext->FreeCallback)(PerStreamContext);
00394 
00395             /* Relock the list to continue */
00396             ExAcquireFastMutex(AdvFcbHeader->FastMutex);
00397             IsMutexLocked = TRUE;
00398         }
00399     }
00400     _SEH2_FINALLY
00401     {
00402         /* If mutex was locked, release */
00403         if (IsMutexLocked)
00404         {
00405             ExReleaseFastMutex(AdvFcbHeader->FastMutex);
00406         }
00407     }
00408     _SEH2_END;
00409 }

Generated on Sun May 27 2012 04:37:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.