[FLTMGR] Latest from my branch (#135)
[reactos.git] / drivers / filters / fltmgr / Context.c
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
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
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
167 SetupContextHeader(_In_ PFLT_FILTER Filter,
168 _In_ PCFLT_CONTEXT_REGISTRATION ContextPtr,
169 _Out_ PALLOCATE_CONTEXT_HEADER ContextHeader)
170 {
171 return 0;
172 }