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