xref: /reactos/drivers/filesystems/npfs/strucsup.c (revision c2c66aff)
1 /*
2  * PROJECT:     ReactOS Named Pipe FileSystem
3  * LICENSE:     BSD - See COPYING.ARM in the top level directory
4  * FILE:        drivers/filesystems/npfs/strucsup.c
5  * PURPOSE:
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "npfs.h"
12 
13 // File ID number for NPFS bugchecking support
14 #define NPFS_BUGCHECK_FILE_ID   (NPFS_BUGCHECK_STRUCSUP)
15 
16 /* GLOBALS ********************************************************************/
17 
18 WCHAR NpRootDCBName[] = L"\\";
19 PNP_VCB NpVcb;
20 
21 /* FUNCTIONS ******************************************************************/
22 
23 RTL_GENERIC_COMPARE_RESULTS
24 NTAPI
NpEventTableCompareRoutine(IN PRTL_GENERIC_TABLE Table,IN PVOID FirstStruct,IN PVOID SecondStruct)25 NpEventTableCompareRoutine(IN PRTL_GENERIC_TABLE Table,
26                            IN PVOID FirstStruct,
27                            IN PVOID SecondStruct)
28 {
29     UNIMPLEMENTED;
30     return GenericEqual;
31 }
32 
33 PVOID
34 NTAPI
NpEventTableAllocate(IN PRTL_GENERIC_TABLE Table,IN CLONG ByteSize)35 NpEventTableAllocate(IN PRTL_GENERIC_TABLE Table,
36                      IN CLONG ByteSize)
37 {
38     UNIMPLEMENTED;
39     return NULL;
40 }
41 
42 VOID
43 NTAPI
NpEventTableDeallocate(IN PRTL_GENERIC_TABLE Table,IN PVOID Buffer)44 NpEventTableDeallocate(IN PRTL_GENERIC_TABLE Table,
45                        IN PVOID Buffer)
46 {
47     UNIMPLEMENTED;
48 }
49 
50 BOOLEAN
51 NTAPI
NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,IN PVOID Buffer)52 NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
53                         IN PVOID Buffer)
54 {
55     if (!Buffer) return FALSE;
56 
57     ObDereferenceObject(((PNP_EVENT_BUFFER)Buffer)->Event);
58     return RtlDeleteElementGenericTable(Table, Buffer);
59 }
60 
61 VOID
62 NTAPI
NpDeleteFcb(IN PNP_FCB Fcb,IN PLIST_ENTRY ListEntry)63 NpDeleteFcb(IN PNP_FCB Fcb,
64             IN PLIST_ENTRY ListEntry)
65 {
66     PNP_DCB Dcb;
67     PAGED_CODE();
68 
69     Dcb = Fcb->ParentDcb;
70     if (Fcb->CurrentInstances) NpBugCheck(0, 0, 0);
71 
72     NpCancelWaiter(&NpVcb->WaitQueue,
73                    &Fcb->FullName,
74                    STATUS_OBJECT_NAME_NOT_FOUND,
75                    ListEntry);
76 
77     RemoveEntryList(&Fcb->DcbEntry);
78 
79     if (Fcb->SecurityDescriptor)
80     {
81         ObDereferenceSecurityDescriptor(Fcb->SecurityDescriptor, 1);
82     }
83 
84     RtlRemoveUnicodePrefix(&NpVcb->PrefixTable, &Fcb->PrefixTableEntry);
85     ExFreePool(Fcb->FullName.Buffer);
86     ExFreePool(Fcb);
87     NpCheckForNotify(Dcb, TRUE, ListEntry);
88 }
89 
90 VOID
91 NTAPI
NpDeleteCcb(IN PNP_CCB Ccb,IN PLIST_ENTRY ListEntry)92 NpDeleteCcb(IN PNP_CCB Ccb,
93             IN PLIST_ENTRY ListEntry)
94 {
95     PNP_ROOT_DCB_FCB RootDcbCcb;
96     PAGED_CODE();
97 
98     RootDcbCcb = (PNP_ROOT_DCB_FCB)Ccb;
99     if (Ccb->NodeType == NPFS_NTC_CCB)
100     {
101         RemoveEntryList(&Ccb->CcbEntry);
102         --Ccb->Fcb->CurrentInstances;
103 
104         NpDeleteEventTableEntry(&NpVcb->EventTable,
105                                 Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END]);
106         NpDeleteEventTableEntry(&NpVcb->EventTable,
107                                 Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_SERVER_END]);
108         NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND]);
109         NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_OUTBOUND]);
110         NpCheckForNotify(Ccb->Fcb->ParentDcb, FALSE, ListEntry);
111         ExDeleteResourceLite(&Ccb->NonPagedCcb->Lock);
112         NpUninitializeSecurity(Ccb);
113         if (Ccb->ClientSession)
114         {
115             ExFreePool(Ccb->ClientSession);
116             Ccb->ClientSession = NULL;
117         }
118         ExFreePool(Ccb->NonPagedCcb);
119     }
120     else if (RootDcbCcb->NodeType == NPFS_NTC_ROOT_DCB_CCB && RootDcbCcb->Unknown)
121     {
122         ExFreePool(RootDcbCcb->Unknown);
123     }
124 
125     ExFreePool(Ccb);
126 }
127 
128 VOID
129 NTAPI
NpInitializeVcb(VOID)130 NpInitializeVcb(VOID)
131 {
132     PAGED_CODE();
133 
134     RtlZeroMemory(NpVcb, sizeof(*NpVcb));
135 
136     NpVcb->NodeType = NPFS_NTC_VCB;
137     RtlInitializeUnicodePrefix(&NpVcb->PrefixTable);
138     ExInitializeResourceLite(&NpVcb->Lock);
139     RtlInitializeGenericTable(&NpVcb->EventTable,
140                               NpEventTableCompareRoutine,
141                               NpEventTableAllocate,
142                               NpEventTableDeallocate,
143                               0);
144     NpInitializeWaitQueue(&NpVcb->WaitQueue);
145 }
146 
147 NTSTATUS
148 NTAPI
NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB * NewRootCcb)149 NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB *NewRootCcb)
150 {
151     PNP_ROOT_DCB_FCB RootCcb;
152     PAGED_CODE();
153 
154     RootCcb = ExAllocatePoolWithTag(PagedPool, sizeof(*RootCcb), NPFS_ROOT_DCB_CCB_TAG);
155     if (!RootCcb) return STATUS_INSUFFICIENT_RESOURCES;
156 
157     RtlZeroMemory(RootCcb, sizeof(*RootCcb));
158     RootCcb->NodeType = NPFS_NTC_ROOT_DCB_CCB;
159     *NewRootCcb = RootCcb;
160     return STATUS_SUCCESS;
161 }
162 
163 NTSTATUS
164 NTAPI
NpCreateRootDcb(VOID)165 NpCreateRootDcb(VOID)
166 {
167     PNP_DCB Dcb;
168     PAGED_CODE();
169 
170     if (NpVcb->RootDcb)
171     {
172         NpBugCheck(0, 0, 0);
173     }
174 
175     NpVcb->RootDcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Dcb), NPFS_DCB_TAG);
176     if (!NpVcb->RootDcb)
177     {
178         return STATUS_INSUFFICIENT_RESOURCES;
179     }
180 
181     Dcb = NpVcb->RootDcb;
182     RtlZeroMemory(Dcb, sizeof(*Dcb));
183     Dcb->NodeType = NPFS_NTC_ROOT_DCB;
184 
185     InitializeListHead(&Dcb->DcbEntry);
186     InitializeListHead(&Dcb->NotifyList);
187     InitializeListHead(&Dcb->NotifyList2);
188     InitializeListHead(&Dcb->FcbList);
189 
190     Dcb->FullName.Buffer = NpRootDCBName;
191     Dcb->FullName.Length = sizeof(NpRootDCBName) - sizeof(UNICODE_NULL);
192     Dcb->FullName.MaximumLength = sizeof(NpRootDCBName);
193 
194     Dcb->ShortName.Length = Dcb->FullName.Length;
195     Dcb->ShortName.MaximumLength = Dcb->FullName.MaximumLength;
196     Dcb->ShortName.Buffer = Dcb->FullName.Buffer;
197 
198     if (!RtlInsertUnicodePrefix(&NpVcb->PrefixTable,
199                                 &Dcb->FullName,
200                                 &Dcb->PrefixTableEntry))
201     {
202         NpBugCheck(0, 0, 0);
203     }
204 
205     return STATUS_SUCCESS;
206 }
207 
208 NTSTATUS
209 NTAPI
NpCreateFcb(IN PNP_DCB Dcb,IN PUNICODE_STRING PipeName,IN ULONG MaximumInstances,IN LARGE_INTEGER Timeout,IN USHORT NamedPipeConfiguration,IN USHORT NamedPipeType,OUT PNP_FCB * NewFcb)210 NpCreateFcb(IN PNP_DCB Dcb,
211             IN PUNICODE_STRING PipeName,
212             IN ULONG MaximumInstances,
213             IN LARGE_INTEGER Timeout,
214             IN USHORT NamedPipeConfiguration,
215             IN USHORT NamedPipeType,
216             OUT PNP_FCB *NewFcb)
217 {
218     PNP_FCB Fcb;
219     BOOLEAN RootPipe;
220     PWCHAR NameBuffer;
221     USHORT Length, MaximumLength;
222     PAGED_CODE();
223 
224     Length = PipeName->Length;
225     MaximumLength = Length + sizeof(UNICODE_NULL);
226 
227     if ((Length < sizeof(WCHAR)) || (MaximumLength < Length))
228     {
229         return STATUS_INVALID_PARAMETER;
230     }
231 
232     RootPipe = FALSE;
233     if (PipeName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR)
234     {
235         Length += sizeof(OBJ_NAME_PATH_SEPARATOR);
236         MaximumLength += sizeof(OBJ_NAME_PATH_SEPARATOR);
237         RootPipe = TRUE;
238         if (MaximumLength < sizeof(WCHAR))
239         {
240             return STATUS_INVALID_PARAMETER;
241         }
242     }
243 
244     Fcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Fcb), NPFS_FCB_TAG);
245     if (!Fcb) return STATUS_INSUFFICIENT_RESOURCES;
246 
247     RtlZeroMemory(Fcb, sizeof(*Fcb));
248     Fcb->MaximumInstances = MaximumInstances;
249     Fcb->Timeout = Timeout;
250     Fcb->NodeType = NPFS_NTC_FCB;
251     Fcb->ParentDcb = Dcb;
252     InitializeListHead(&Fcb->CcbList);
253 
254     NameBuffer = ExAllocatePoolWithTag(PagedPool,
255                                        MaximumLength,
256                                        NPFS_NAME_BLOCK_TAG);
257     if (!NameBuffer)
258     {
259         ExFreePool(Fcb);
260         return STATUS_INSUFFICIENT_RESOURCES;
261     }
262 
263     InsertTailList(&Dcb->FcbList, &Fcb->DcbEntry);
264 
265     if (RootPipe)
266     {
267         NameBuffer[0] = OBJ_NAME_PATH_SEPARATOR;
268         RtlCopyMemory(NameBuffer + 1,
269                       PipeName->Buffer,
270                       PipeName->Length);
271     }
272     else
273     {
274         RtlCopyMemory(NameBuffer,
275                       PipeName->Buffer,
276                       PipeName->Length);
277     }
278 
279     NameBuffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
280 
281     Fcb->FullName.Length = Length;
282     Fcb->FullName.MaximumLength = MaximumLength;
283     Fcb->FullName.Buffer = NameBuffer;
284 
285     Fcb->ShortName.MaximumLength = Length;
286     Fcb->ShortName.Length = Length - sizeof(OBJ_NAME_PATH_SEPARATOR);
287     Fcb->ShortName.Buffer = NameBuffer + 1;
288 
289     if (!RtlInsertUnicodePrefix(&NpVcb->PrefixTable,
290                                 &Fcb->FullName,
291                                 &Fcb->PrefixTableEntry))
292     {
293         NpBugCheck(0, 0, 0);
294     }
295 
296     Fcb->NamedPipeConfiguration = NamedPipeConfiguration;
297     Fcb->NamedPipeType = NamedPipeType;
298     *NewFcb = Fcb;
299     return STATUS_SUCCESS;
300 }
301 
302 NTSTATUS
303 NTAPI
NpCreateCcb(IN PNP_FCB Fcb,IN PFILE_OBJECT FileObject,IN UCHAR State,IN UCHAR ReadMode,IN UCHAR CompletionMode,IN ULONG InQuota,IN ULONG OutQuota,OUT PNP_CCB * NewCcb)304 NpCreateCcb(IN PNP_FCB Fcb,
305             IN PFILE_OBJECT FileObject,
306             IN UCHAR State,
307             IN UCHAR ReadMode,
308             IN UCHAR CompletionMode,
309             IN ULONG InQuota,
310             IN ULONG OutQuota,
311             OUT PNP_CCB *NewCcb)
312 {
313     PNP_CCB Ccb;
314     PNP_NONPAGED_CCB CcbNonPaged;
315     NTSTATUS Status;
316     PAGED_CODE();
317 
318     Ccb = ExAllocatePoolWithTag(PagedPool, sizeof(*Ccb), NPFS_CCB_TAG);
319     if (!Ccb) return STATUS_INSUFFICIENT_RESOURCES;
320 
321     CcbNonPaged = ExAllocatePoolWithTag(NonPagedPool, sizeof(*CcbNonPaged), NPFS_CCB_TAG);
322     if (!CcbNonPaged)
323     {
324         ExFreePool(Ccb);
325         return STATUS_INSUFFICIENT_RESOURCES;
326     }
327 
328     RtlZeroMemory(CcbNonPaged, sizeof(*CcbNonPaged));
329     CcbNonPaged->NodeType = NPFS_NTC_NONPAGED_CCB;
330 
331     RtlZeroMemory(Ccb, sizeof(*Ccb));
332     Ccb->NodeType = NPFS_NTC_CCB;
333     Ccb->NonPagedCcb = CcbNonPaged;
334     Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
335     Ccb->Fcb = Fcb;
336     Ccb->NamedPipeState = State;
337     Ccb->ReadMode[FILE_PIPE_SERVER_END] = ReadMode;
338     Ccb->CompletionMode[FILE_PIPE_SERVER_END] = CompletionMode;
339 
340     Status = NpInitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND], InQuota);
341     if (!NT_SUCCESS(Status))
342     {
343         ExFreePool(CcbNonPaged);
344         ExFreePool(Ccb);
345         return STATUS_INSUFFICIENT_RESOURCES;
346     }
347 
348     Status = NpInitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_OUTBOUND], OutQuota);
349     if (!NT_SUCCESS(Status))
350     {
351         NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND]);
352         ExFreePool(CcbNonPaged);
353         ExFreePool(Ccb);
354         return STATUS_INSUFFICIENT_RESOURCES;
355     }
356 
357     InsertTailList(&Fcb->CcbList, &Ccb->CcbEntry);
358 
359     Fcb->CurrentInstances++;
360     Fcb->ServerOpenCount++;
361     InitializeListHead(&Ccb->IrpList);
362     ExInitializeResourceLite(&Ccb->NonPagedCcb->Lock);
363     *NewCcb = Ccb;
364     return STATUS_SUCCESS;
365 }
366 
367 /* EOF */
368