Sync with trunk for console graphics palettes.
[reactos.git] / drivers / filesystems / npfs / fsctrl.c
1 /*
2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/fsctrl.c
5 * PURPOSE: Named Pipe FileSystem I/O Controls
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_FSCTRL)
15
16 /* GLOBALS ********************************************************************/
17
18 IO_STATUS_BLOCK NpUserIoStatusBlock;
19
20 /* FUNCTIONS ******************************************************************/
21
22 NTSTATUS
23 NTAPI
24 NpInternalTransceive(IN PDEVICE_OBJECT DeviceObject,
25 IN PIRP Irp,
26 IN PLIST_ENTRY List)
27 {
28 UNIMPLEMENTED;
29 return STATUS_NOT_IMPLEMENTED;
30 }
31
32 NTSTATUS
33 NTAPI
34 NpInternalRead(IN PDEVICE_OBJECT DeviceObject,
35 IN PIRP Irp,
36 IN BOOLEAN Overflow,
37 IN PLIST_ENTRY List)
38 {
39 UNIMPLEMENTED;
40 return STATUS_NOT_IMPLEMENTED;
41 }
42
43 NTSTATUS
44 NTAPI
45 NpInternalWrite(IN PDEVICE_OBJECT DeviceObject,
46 IN PIRP Irp,
47 IN PLIST_ENTRY List)
48 {
49 UNIMPLEMENTED;
50 return STATUS_NOT_IMPLEMENTED;
51 }
52
53 NTSTATUS
54 NTAPI
55 NpQueryClientProcess(IN PDEVICE_OBJECT DeviceObject,
56 IN PIRP Irp)
57 {
58 UNIMPLEMENTED;
59 return STATUS_NOT_IMPLEMENTED;
60 }
61
62 NTSTATUS
63 NTAPI
64 NpSetClientProcess(IN PDEVICE_OBJECT DeviceObject,
65 IN PIRP Irp)
66 {
67 UNIMPLEMENTED;
68 return STATUS_NOT_IMPLEMENTED;
69 }
70
71 NTSTATUS
72 NTAPI
73 NpAssignEvent(IN PDEVICE_OBJECT DeviceObject,
74 IN PIRP Irp)
75 {
76 UNIMPLEMENTED;
77 return STATUS_NOT_IMPLEMENTED;
78 }
79
80 NTSTATUS
81 NTAPI
82 NpQueryEvent(IN PDEVICE_OBJECT DeviceObject,
83 IN PIRP Irp)
84 {
85 UNIMPLEMENTED;
86 return STATUS_NOT_IMPLEMENTED;
87 }
88
89 NTSTATUS
90 NTAPI
91 NpImpersonate(IN PDEVICE_OBJECT DeviceObject,
92 IN PIRP Irp)
93 {
94 ULONG NamedPipeEnd;
95 PNP_CCB Ccb;
96 NTSTATUS Status;
97 NODE_TYPE_CODE NodeTypeCode;
98 PIO_STACK_LOCATION IoStack;
99 PAGED_CODE();
100
101 IoStack = IoGetCurrentIrpStackLocation(Irp);
102
103 NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
104 if (NodeTypeCode == NPFS_NTC_CCB)
105 {
106 if (NamedPipeEnd == FILE_PIPE_SERVER_END)
107 {
108 Status = NpImpersonateClientContext(Ccb);
109 }
110 else
111 {
112 Status = STATUS_ILLEGAL_FUNCTION;
113 }
114 }
115
116 return Status;
117 }
118
119 NTSTATUS
120 NTAPI
121 NpDisconnect(IN PDEVICE_OBJECT DeviceObject,
122 IN PIRP Irp,
123 IN PLIST_ENTRY List)
124 {
125 ULONG NamedPipeEnd;
126 PNP_CCB Ccb;
127 NTSTATUS Status;
128 NODE_TYPE_CODE NodeTypeCode;
129 PIO_STACK_LOCATION IoStack;
130 PAGED_CODE();
131
132 IoStack = IoGetCurrentIrpStackLocation(Irp);
133
134 NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
135 if (NodeTypeCode == NPFS_NTC_CCB)
136 {
137 if (NamedPipeEnd == FILE_PIPE_SERVER_END)
138 {
139 ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
140
141 Status = NpSetDisconnectedPipeState(Ccb, List);
142
143 NpUninitializeSecurity(Ccb);
144
145 ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
146 }
147 else
148 {
149 Status = STATUS_ILLEGAL_FUNCTION;
150 }
151 }
152 else
153 {
154 Status = STATUS_PIPE_DISCONNECTED;
155 }
156
157 return Status;
158 }
159
160 NTSTATUS
161 NTAPI
162 NpListen(IN PDEVICE_OBJECT DeviceObject,
163 IN PIRP Irp,
164 IN PLIST_ENTRY List)
165 {
166 ULONG NamedPipeEnd;
167 PNP_CCB Ccb;
168 NTSTATUS Status;
169 NODE_TYPE_CODE NodeTypeCode;
170 PIO_STACK_LOCATION IoStack;
171 PAGED_CODE();
172
173 IoStack = IoGetCurrentIrpStackLocation(Irp);
174
175 NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
176 if (NodeTypeCode == NPFS_NTC_CCB)
177 {
178 if (NamedPipeEnd == FILE_PIPE_SERVER_END)
179 {
180 ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
181
182 Status = NpSetListeningPipeState(Ccb, Irp, List);
183
184 NpUninitializeSecurity(Ccb);
185
186 ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
187 }
188 else
189 {
190 Status = STATUS_ILLEGAL_FUNCTION;
191 }
192 }
193 else
194 {
195 Status = STATUS_ILLEGAL_FUNCTION;
196 }
197
198 return Status;
199 }
200
201 NTSTATUS
202 NTAPI
203 NpPeek(IN PDEVICE_OBJECT DeviceObject,
204 IN PIRP Irp,
205 IN PLIST_ENTRY List)
206 {
207 PIO_STACK_LOCATION IoStack;
208 NODE_TYPE_CODE Type;
209 ULONG OutputLength;
210 ULONG NamedPipeEnd;
211 PNP_CCB Ccb;
212 PFILE_PIPE_PEEK_BUFFER PeekBuffer;
213 PNP_DATA_QUEUE DataQueue;
214 ULONG_PTR BytesPeeked;
215 IO_STATUS_BLOCK IoStatus;
216 NTSTATUS Status;
217 PNP_DATA_QUEUE_ENTRY DataEntry;
218 PAGED_CODE();
219
220 IoStack = IoGetCurrentIrpStackLocation(Irp);
221 OutputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
222 Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
223
224 if (!Type)
225 {
226 return STATUS_PIPE_DISCONNECTED;
227 }
228
229 if ((Type != NPFS_NTC_CCB) &&
230 (OutputLength < FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data)))
231 {
232 return STATUS_INVALID_PARAMETER;
233 }
234
235 PeekBuffer = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
236 if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
237 {
238 if (NamedPipeEnd != FILE_PIPE_SERVER_END)
239 {
240 NpBugCheck(NamedPipeEnd, 0, 0);
241 }
242
243 DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
244 }
245 else
246 {
247 DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
248 }
249
250 if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
251 {
252 if (Ccb->NamedPipeState != FILE_PIPE_CLOSING_STATE)
253 {
254 return STATUS_INVALID_PIPE_STATE;
255 }
256
257 if (DataQueue->QueueState != WriteEntries)
258 {
259 return STATUS_PIPE_BROKEN;
260 }
261 }
262
263 PeekBuffer->NamedPipeState = 0;
264 PeekBuffer->ReadDataAvailable = 0;
265 PeekBuffer->NumberOfMessages = 0;
266 PeekBuffer->MessageLength = 0;
267 PeekBuffer->NamedPipeState = Ccb->NamedPipeState;
268 BytesPeeked = FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data);
269
270 if (DataQueue->QueueState == WriteEntries)
271 {
272 DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
273 NP_DATA_QUEUE_ENTRY,
274 QueueEntry);
275 ASSERT((DataEntry->DataEntryType == Buffered) || (DataEntry->DataEntryType == Unbuffered));
276
277 PeekBuffer->ReadDataAvailable = DataQueue->BytesInQueue - DataQueue->ByteOffset;
278 if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE)
279 {
280 PeekBuffer->NumberOfMessages = DataQueue->EntriesInQueue;
281 PeekBuffer->MessageLength = DataEntry->DataSize - DataQueue->ByteOffset;
282 }
283
284 if (OutputLength == FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data))
285 {
286 Status = PeekBuffer->ReadDataAvailable ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
287 }
288 else
289 {
290 IoStatus = NpReadDataQueue(DataQueue,
291 TRUE,
292 FALSE,
293 PeekBuffer->Data,
294 OutputLength - FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data),
295 Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE,
296 Ccb,
297 List);
298 Status = IoStatus.Status;
299 BytesPeeked += IoStatus.Information;
300 }
301 }
302 else
303 {
304 Status = STATUS_SUCCESS;
305 }
306
307 Irp->IoStatus.Information = BytesPeeked;
308 return Status;
309 }
310
311 NTSTATUS
312 NTAPI
313 NpCompleteTransceiveIrp(IN PDEVICE_OBJECT DeviceObject,
314 IN PIRP Irp,
315 IN PVOID Context)
316 {
317 PAGED_CODE();
318
319 if (Irp->AssociatedIrp.SystemBuffer)
320 {
321 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
322 }
323
324 IoFreeIrp(Irp);
325 return STATUS_MORE_PROCESSING_REQUIRED;
326 }
327
328 NTSTATUS
329 NTAPI
330 NpTransceive(IN PDEVICE_OBJECT DeviceObject,
331 IN PIRP Irp,
332 IN PLIST_ENTRY List)
333 {
334 PIO_STACK_LOCATION IoStack;
335 PVOID InBuffer, OutBuffer;
336 ULONG InLength, OutLength, BytesWritten;
337 NODE_TYPE_CODE NodeTypeCode;
338 PNP_CCB Ccb;
339 ULONG NamedPipeEnd;
340 PNP_NONPAGED_CCB NonPagedCcb;
341 PNP_DATA_QUEUE ReadQueue, WriteQueue;
342 PNP_EVENT_BUFFER EventBuffer;
343 NTSTATUS Status;
344 PIRP NewIrp;
345 PAGED_CODE();
346
347 IoStack = IoGetCurrentIrpStackLocation(Irp);
348 InLength = IoStack->Parameters.FileSystemControl.InputBufferLength;
349 InBuffer = IoStack->Parameters.FileSystemControl.Type3InputBuffer;
350 OutLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
351 OutBuffer = Irp->UserBuffer;
352
353 if (Irp->RequestorMode == UserMode)
354 {
355 _SEH2_TRY
356 {
357 ProbeForRead(InBuffer, InLength, sizeof(CHAR));
358 ProbeForWrite(OutBuffer, OutLength, sizeof(CHAR));
359 }
360 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
361 {
362 _SEH2_YIELD(return _SEH2_GetExceptionCode());
363 }
364 _SEH2_END;
365 }
366
367 NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
368 if (NodeTypeCode != NPFS_NTC_CCB)
369 {
370 return STATUS_PIPE_DISCONNECTED;
371 }
372
373 NonPagedCcb = Ccb->NonPagedCcb;
374 ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
375
376 if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
377 {
378 Status = STATUS_INVALID_PIPE_STATE;
379 goto Quickie;
380 }
381
382 if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
383 {
384 if (NamedPipeEnd != FILE_PIPE_SERVER_END)
385 {
386 NpBugCheck(NamedPipeEnd, 0, 0);
387 }
388 ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
389 WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
390 }
391 else
392 {
393 ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
394 WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
395 }
396
397 EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
398
399 if (Ccb->Fcb->NamedPipeConfiguration != FILE_PIPE_FULL_DUPLEX ||
400 Ccb->ReadMode[NamedPipeEnd] != FILE_PIPE_MESSAGE_MODE)
401 {
402 Status = STATUS_INVALID_PIPE_STATE;
403 goto Quickie;
404 }
405
406 if (ReadQueue->QueueState != Empty)
407 {
408 Status = STATUS_PIPE_BUSY;
409 goto Quickie;
410 }
411
412 Status = NpWriteDataQueue(WriteQueue,
413 1,
414 InBuffer,
415 InLength,
416 Ccb->Fcb->NamedPipeType,
417 &BytesWritten,
418 Ccb,
419 NamedPipeEnd,
420 Irp->Tail.Overlay.Thread,
421 List);
422 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
423 {
424 ASSERT(WriteQueue->QueueState != ReadEntries);
425 NewIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
426 if (!NewIrp)
427 {
428 Status = STATUS_INSUFFICIENT_RESOURCES;
429 goto Quickie;
430 }
431
432 IoSetCompletionRoutine(Irp, NpCompleteTransceiveIrp, NULL, TRUE, TRUE, TRUE);
433
434 if (BytesWritten)
435 {
436 NewIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
437 BytesWritten,
438 NPFS_WRITE_BLOCK_TAG);
439 if (!NewIrp->AssociatedIrp.SystemBuffer)
440 {
441 IoFreeIrp(NewIrp);
442 Status = STATUS_INSUFFICIENT_RESOURCES;
443 goto Quickie;
444 }
445
446 _SEH2_TRY
447 {
448 RtlCopyMemory(NewIrp->AssociatedIrp.SystemBuffer,
449 (PVOID)((ULONG_PTR)InBuffer + InLength - BytesWritten),
450 BytesWritten);
451 }
452 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
453 {
454 Status = _SEH2_GetExceptionCode();
455 _SEH2_YIELD(goto Quickie);
456 }
457 _SEH2_END;
458 }
459 else
460 {
461 NewIrp->AssociatedIrp.SystemBuffer = NULL;
462 }
463
464 IoStack = IoGetNextIrpStackLocation(NewIrp);
465 IoSetNextIrpStackLocation(NewIrp);
466
467 NewIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
468 NewIrp->IoStatus.Information = BytesWritten;
469
470 IoStack->Parameters.Read.Length = BytesWritten;
471 IoStack->MajorFunction = IRP_MJ_WRITE;
472
473 if (BytesWritten > 0) NewIrp->Flags = IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO;
474 NewIrp->UserIosb = &NpUserIoStatusBlock;
475
476 Status = NpAddDataQueueEntry(NamedPipeEnd,
477 Ccb,
478 WriteQueue,
479 WriteEntries,
480 Unbuffered,
481 BytesWritten,
482 NewIrp,
483 NULL,
484 0);
485 if (Status != STATUS_PENDING)
486 {
487 NewIrp->IoStatus.Status = Status;
488 InsertTailList(List, &NewIrp->Tail.Overlay.ListEntry);
489 }
490 }
491
492 if (!NT_SUCCESS(Status)) goto Quickie;
493
494 if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
495 ASSERT(ReadQueue->QueueState == Empty);
496 Status = NpAddDataQueueEntry(NamedPipeEnd,
497 Ccb,
498 ReadQueue,
499 ReadEntries,
500 Buffered,
501 OutLength,
502 Irp,
503 NULL,
504 0);
505 if (NT_SUCCESS(Status))
506 {
507 if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
508 }
509
510 Quickie:
511 ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
512 return Status;
513 }
514
515 NTSTATUS
516 NTAPI
517 NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
518 IN PIRP Irp)
519 {
520 PIO_STACK_LOCATION IoStack;
521 ULONG InLength, NameLength;
522 UNICODE_STRING SourceString, Prefix;
523 ULONG NamedPipeEnd;
524 PNP_CCB Ccb;
525 PFILE_PIPE_WAIT_FOR_BUFFER Buffer;
526 NTSTATUS Status;
527 NODE_TYPE_CODE NodeTypeCode;
528 PLIST_ENTRY NextEntry;
529 PNP_FCB Fcb;
530 PWCHAR OriginalBuffer;
531 PAGED_CODE();
532
533 IoStack = IoGetCurrentIrpStackLocation(Irp);
534 InLength = IoStack->Parameters.FileSystemControl.InputBufferLength;
535
536 SourceString.Buffer = NULL;
537
538 if (NpDecodeFileObject(IoStack->FileObject,
539 NULL,
540 &Ccb,
541 &NamedPipeEnd) != NPFS_NTC_ROOT_DCB)
542 {
543 Status = STATUS_ILLEGAL_FUNCTION;
544 goto Quickie;
545 }
546
547 Buffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
548 if (InLength < sizeof(*Buffer))
549 {
550 Status = STATUS_INVALID_PARAMETER;
551 goto Quickie;
552 }
553
554 NameLength = Buffer->NameLength;
555 if ((NameLength > (0xFFFF - sizeof(UNICODE_NULL))) ||
556 ((NameLength + FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name)) > InLength))
557 {
558 Status = STATUS_INVALID_PARAMETER;
559 goto Quickie;
560 }
561
562 SourceString.Length = (USHORT)NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
563 SourceString.Buffer = ExAllocatePoolWithTag(PagedPool,
564 SourceString.Length,
565 NPFS_WRITE_BLOCK_TAG);
566 if (!SourceString.Buffer)
567 {
568 Status = STATUS_INSUFFICIENT_RESOURCES;
569 goto Quickie;
570 }
571
572 SourceString.Buffer[0] = OBJ_NAME_PATH_SEPARATOR;
573 RtlCopyMemory(&SourceString.Buffer[1], Buffer->Name, Buffer->NameLength);
574
575 Status = STATUS_SUCCESS;
576 OriginalBuffer = SourceString.Buffer;
577 //Status = NpTranslateAlias(&SourceString);
578 if (!NT_SUCCESS(Status)) goto Quickie;
579
580 Fcb = NpFindPrefix(&SourceString, TRUE, &Prefix);
581 Fcb = (PNP_FCB)((ULONG_PTR)Fcb & ~1);
582
583 NodeTypeCode = Fcb ? Fcb->NodeType : 0;
584 if (NodeTypeCode != NPFS_NTC_FCB)
585 {
586 Status = STATUS_OBJECT_NAME_NOT_FOUND;
587 goto Quickie;
588 }
589
590 for (NextEntry = Fcb->CcbList.Flink;
591 NextEntry != &Fcb->CcbList;
592 NextEntry = NextEntry->Flink)
593 {
594 Ccb = CONTAINING_RECORD(NextEntry, NP_CCB, CcbEntry);
595 if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) break;
596 }
597
598 if (NextEntry != &Fcb->CcbList)
599 {
600 Status = STATUS_SUCCESS;
601 }
602 else
603 {
604 Status = NpAddWaiter(&NpVcb->WaitQueue,
605 Fcb->Timeout,
606 Irp,
607 OriginalBuffer == SourceString.Buffer ?
608 NULL : &SourceString);
609 }
610
611 Quickie:
612 if (SourceString.Buffer) ExFreePool(SourceString.Buffer);
613 return Status;
614 }
615
616 NTSTATUS
617 NTAPI
618 NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
619 IN PIRP Irp)
620 {
621 ULONG Fsctl;
622 BOOLEAN Overflow = FALSE;
623 LIST_ENTRY DeferredList;
624 NTSTATUS Status;
625 PAGED_CODE();
626
627 InitializeListHead(&DeferredList);
628 Fsctl = IoGetCurrentIrpStackLocation(Irp)->Parameters.FileSystemControl.FsControlCode;
629
630 switch (Fsctl)
631 {
632 case FSCTL_PIPE_PEEK:
633 NpAcquireExclusiveVcb();
634 Status = NpPeek(DeviceObject, Irp, &DeferredList);
635 break;
636
637 case FSCTL_PIPE_INTERNAL_WRITE:
638 NpAcquireSharedVcb();
639 Status = NpInternalWrite(DeviceObject, Irp, &DeferredList);
640 break;
641
642 case FSCTL_PIPE_TRANSCEIVE:
643 NpAcquireSharedVcb();
644 Status = NpTransceive(DeviceObject, Irp, &DeferredList);
645 break;
646
647 case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
648 NpAcquireSharedVcb();
649 Status = NpInternalTransceive(DeviceObject, Irp, &DeferredList);
650 break;
651
652 case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
653 Overflow = TRUE;
654 // on purpose
655
656 case FSCTL_PIPE_INTERNAL_READ:
657 NpAcquireSharedVcb();
658 Status = NpInternalRead(DeviceObject, Irp, Overflow, &DeferredList);
659 break;
660
661 case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
662
663 NpAcquireSharedVcb();
664 Status = NpQueryClientProcess(DeviceObject, Irp);
665 break;
666
667 case FSCTL_PIPE_ASSIGN_EVENT:
668
669 NpAcquireExclusiveVcb();
670 Status = NpAssignEvent(DeviceObject, Irp);
671 break;
672
673 case FSCTL_PIPE_DISCONNECT:
674
675 NpAcquireExclusiveVcb();
676 Status = NpDisconnect(DeviceObject, Irp, &DeferredList);
677 break;
678
679 case FSCTL_PIPE_LISTEN:
680
681 NpAcquireSharedVcb();
682 Status = NpListen(DeviceObject, Irp, &DeferredList);
683 break;
684
685 case FSCTL_PIPE_QUERY_EVENT:
686
687 NpAcquireExclusiveVcb();
688 Status = NpQueryEvent(DeviceObject, Irp);
689 break;
690
691 case FSCTL_PIPE_WAIT:
692
693 NpAcquireExclusiveVcb();
694 Status = NpWaitForNamedPipe(DeviceObject, Irp);
695 break;
696
697 case FSCTL_PIPE_IMPERSONATE:
698
699 NpAcquireExclusiveVcb();
700 Status = NpImpersonate(DeviceObject, Irp);
701 break;
702
703 case FSCTL_PIPE_SET_CLIENT_PROCESS:
704 NpAcquireExclusiveVcb();
705 Status = NpSetClientProcess(DeviceObject, Irp);
706 break;
707
708 default:
709 return STATUS_NOT_SUPPORTED;
710 }
711
712 NpReleaseVcb();
713 NpCompleteDeferredIrps(&DeferredList);
714
715 return Status;
716 }
717
718 NTSTATUS
719 NTAPI
720 NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
721 IN PIRP Irp)
722 {
723 NTSTATUS Status;
724 PAGED_CODE();
725
726 FsRtlEnterFileSystem();
727
728 Status = NpCommonFileSystemControl(DeviceObject, Irp);
729
730 FsRtlExitFileSystem();
731
732 if (Status != STATUS_PENDING)
733 {
734 Irp->IoStatus.Status = Status;
735 IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
736 }
737
738 return Status;
739 }
740
741 /* EOF */