xref: /reactos/drivers/filters/fltmgr/Context.c (revision 9d15fb92)
1 /*
2 * PROJECT:         Filesystem Filter Manager
3 * LICENSE:         GPL - See COPYING in the top level directory
4 * FILE:            drivers/filters/fltmgr/Context.c
5 * PURPOSE:         Contains context routines
6 * PROGRAMMERS:     Ged Murphy (gedmurphy@reactos.org)
7 */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "fltmgr.h"
12 #include "fltmgrint.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 
18 /* DATA *********************************************************************/
19 
20 static
21 BOOLEAN
22 IsContextTypeValid(
23     _In_ FLT_CONTEXT_TYPE ContextType
24 );
25 
26 static
27 NTSTATUS
28 SetupContextHeader(
29     _In_ PFLT_FILTER Filter,
30     _In_ PCFLT_CONTEXT_REGISTRATION ContextPtr,
31     _Out_ PALLOCATE_CONTEXT_HEADER ContextHeader
32 );
33 
34 /* EXPORTED FUNCTIONS ******************************************************/
35 
36 
37 
38 
39 /* INTERNAL FUNCTIONS ******************************************************/
40 
41 
42 NTSTATUS
FltpRegisterContexts(_In_ PFLT_FILTER Filter,_In_ const FLT_CONTEXT_REGISTRATION * Context)43 FltpRegisterContexts(_In_ PFLT_FILTER Filter,
44                      _In_ const FLT_CONTEXT_REGISTRATION *Context)
45 {
46     PCFLT_CONTEXT_REGISTRATION ContextPtr;
47     PALLOCATE_CONTEXT_HEADER ContextHeader, Prev;
48     PVOID Buffer;
49     ULONG BufferSize = 0;
50     USHORT i;
51     NTSTATUS Status;
52 
53     /* Loop through all entries in the context registration array */
54     ContextPtr = Context;
55     while (ContextPtr)
56     {
57         /* Bail if we found the terminator */
58         if (ContextPtr->ContextType == FLT_CONTEXT_END)
59             break;
60 
61         /* Make sure we have a valid context  */
62         if (IsContextTypeValid(ContextPtr->ContextType))
63         {
64             /* Each context is backed by a crtl struct. Reserve space for it */
65             BufferSize += sizeof(STREAM_LIST_CTRL);
66         }
67 
68         /* Move to the next entry */
69         ContextPtr++;
70     }
71 
72     /* Bail if we found no valid registration requests */
73     if (BufferSize == 0)
74     {
75         return STATUS_SUCCESS;
76     }
77 
78     /* Allocate the pool that'll hold the context crtl structs */
79     Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, FM_TAG_CONTEXT_REGISTA);
80     if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
81 
82     RtlZeroMemory(Buffer, BufferSize);
83 
84     /* Setup our loop data */
85     ContextHeader = Buffer;
86     Prev = NULL;
87     Status = STATUS_SUCCESS;
88 
89     for (i = 0; i < MAX_CONTEXT_TYPES; i++)
90     {
91         ContextPtr = (PFLT_CONTEXT_REGISTRATION)Context;
92         while (ContextPtr)
93         {
94             /* We don't support variable sized contents yet */
95             FLT_ASSERT(ContextPtr->Size != FLT_VARIABLE_SIZED_CONTEXTS);
96 
97             /* Bail if we found the terminator */
98             if (ContextPtr->ContextType == FLT_CONTEXT_END)
99                 break;
100 
101             /* Size and pooltag are only checked when ContextAllocateCallback is null */
102             if (ContextPtr->ContextAllocateCallback == FALSE && ContextPtr->PoolTag == FALSE)
103             {
104                 Status = STATUS_FLT_INVALID_CONTEXT_REGISTRATION;
105                 goto Quit;
106             }
107 
108             /* Make sure we have a valid context  */
109             if (IsContextTypeValid(ContextPtr->ContextType))
110             {
111                 Status = SetupContextHeader(Filter, ContextPtr, ContextHeader);
112                 if (NT_SUCCESS(Status))
113                 {
114                     if (Prev)
115                     {
116                         Prev->Next = ContextHeader;
117                     }
118 
119                     Filter->SupportedContexts[i] = ContextHeader;
120                 }
121             }
122 
123             Prev = ContextHeader;
124 
125             /* Move to the next entry */
126             ContextPtr++;
127         }
128     }
129 
130 Quit:
131     if (NT_SUCCESS(Status))
132     {
133         Filter->SupportedContextsListHead = Buffer;
134     }
135     else
136     {
137         ExFreePoolWithTag(Buffer, FM_TAG_CONTEXT_REGISTA);
138         //FIXME: Cleanup anything that SetupContextHeader may have allocated
139     }
140 
141     return Status;
142 }
143 
144 
145 /* PRIVATE FUNCTIONS ******************************************************/
146 
147 static
148 BOOLEAN
IsContextTypeValid(_In_ FLT_CONTEXT_TYPE ContextType)149 IsContextTypeValid(_In_ FLT_CONTEXT_TYPE ContextType)
150 {
151     switch (ContextType)
152     {
153     case FLT_VOLUME_CONTEXT:
154     case FLT_INSTANCE_CONTEXT:
155     case FLT_FILE_CONTEXT:
156     case FLT_STREAM_CONTEXT:
157     case FLT_STREAMHANDLE_CONTEXT:
158     case FLT_TRANSACTION_CONTEXT:
159         return TRUE;
160     }
161 
162     return FALSE;
163 }
164 
165 static
166 NTSTATUS
SetupContextHeader(_In_ PFLT_FILTER Filter,_In_ PCFLT_CONTEXT_REGISTRATION ContextPtr,_Out_ PALLOCATE_CONTEXT_HEADER ContextHeader)167 SetupContextHeader(_In_ PFLT_FILTER Filter,
168                    _In_ PCFLT_CONTEXT_REGISTRATION ContextPtr,
169                    _Out_ PALLOCATE_CONTEXT_HEADER ContextHeader)
170 {
171     return 0;
172 }
173