2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/filesystems/npfs/fsctrl.c
5 * PURPOSE: Named pipe filesystem
6 * PROGRAMMER: David Welch <welch@cwcom.net>
11 /* INCLUDES ******************************************************************/
18 //#define USING_PROPER_NPFS_WAIT_SEMANTICS
20 /* FUNCTIONS *****************************************************************/
22 static DRIVER_CANCEL NpfsListeningCancelRoutine
;
24 NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject
,
27 PNPFS_WAITER_ENTRY Waiter
;
29 UNREFERENCED_PARAMETER(DeviceObject
);
31 Waiter
= (PNPFS_WAITER_ENTRY
)&Irp
->Tail
.Overlay
.DriverContext
;
33 DPRINT("NpfsListeningCancelRoutine() called for <%wZ>\n",
34 &Waiter
->Ccb
->Fcb
->PipeName
);
36 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
39 KeLockMutex(&Waiter
->Ccb
->Fcb
->CcbListLock
);
40 RemoveEntryList(&Waiter
->Entry
);
41 KeUnlockMutex(&Waiter
->Ccb
->Fcb
->CcbListLock
);
43 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
44 Irp
->IoStatus
.Information
= 0;
45 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
50 NpfsAddListeningServerInstance(PIRP Irp
,
53 PNPFS_WAITER_ENTRY Entry
;
56 Entry
= (PNPFS_WAITER_ENTRY
)&Irp
->Tail
.Overlay
.DriverContext
;
60 KeLockMutex(&Ccb
->Fcb
->CcbListLock
);
62 IoAcquireCancelSpinLock(&oldIrql
);
65 Ccb
->PipeState
= FILE_PIPE_LISTENING_STATE
;
66 IoMarkIrpPending(Irp
);
67 InsertTailList(&Ccb
->Fcb
->WaiterListHead
, &Entry
->Entry
);
68 (void)IoSetCancelRoutine(Irp
, NpfsListeningCancelRoutine
);
69 IoReleaseCancelSpinLock(oldIrql
);
70 KeUnlockMutex(&Ccb
->Fcb
->CcbListLock
);
71 return STATUS_PENDING
;
73 IoReleaseCancelSpinLock(oldIrql
);
75 RemoveEntryList(&Entry
->Entry
);
77 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
78 Irp
->IoStatus
.Information
= 0;
79 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
80 KeUnlockMutex(&Ccb
->Fcb
->CcbListLock
);
82 return STATUS_CANCELLED
;
87 NpfsConnectPipe(PIRP Irp
,
90 PIO_STACK_LOCATION IoStack
;
91 PFILE_OBJECT FileObject
;
93 PLIST_ENTRY current_entry
;
97 KPROCESSOR_MODE WaitMode
;
99 DPRINT("NpfsConnectPipe()\n");
101 /* Fail, if the CCB is not a pipe CCB */
102 if (Ccb
->Type
!= CCB_PIPE
)
104 DPRINT("Not a pipe\n");
105 return STATUS_ILLEGAL_FUNCTION
;
108 /* Fail, if the CCB is not a server end CCB */
109 if (Ccb
->PipeEnd
!= FILE_PIPE_SERVER_END
)
111 DPRINT("Not the server end\n");
112 return STATUS_ILLEGAL_FUNCTION
;
115 if (Ccb
->PipeState
== FILE_PIPE_CONNECTED_STATE
)
117 KeResetEvent(&Ccb
->ConnectEvent
);
118 return STATUS_PIPE_CONNECTED
;
121 if (Ccb
->PipeState
== FILE_PIPE_CLOSING_STATE
)
122 return STATUS_PIPE_CLOSING
;
124 DPRINT("Waiting for connection...\n");
127 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
128 FileObject
= IoStack
->FileObject
;
129 Flags
= FileObject
->Flags
;
130 WaitMode
= Irp
->RequestorMode
;
132 /* search for a listening client fcb */
133 KeLockMutex(&Fcb
->CcbListLock
);
135 current_entry
= Fcb
->ClientCcbListHead
.Flink
;
136 while (current_entry
!= &Fcb
->ClientCcbListHead
)
138 ClientCcb
= CONTAINING_RECORD(current_entry
,
142 if (ClientCcb
->PipeState
== 0)
144 /* found a passive (waiting) client CCB */
145 DPRINT("Passive (waiting) client CCB found -- wake the client\n");
146 KeSetEvent(&ClientCcb
->ConnectEvent
, IO_NO_INCREMENT
, FALSE
);
151 if (ClientCcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
153 /* found a listening client CCB */
154 DPRINT("Listening client CCB found -- connecting\n");
156 /* connect client and server CCBs */
157 Ccb
->OtherSide
= ClientCcb
;
158 ClientCcb
->OtherSide
= Ccb
;
160 /* set connected state */
161 Ccb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
162 ClientCcb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
164 KeUnlockMutex(&Fcb
->CcbListLock
);
166 /* FIXME: create and initialize data queues */
168 /* signal client's connect event */
169 DPRINT("Setting the ConnectEvent for %x\n", ClientCcb
);
170 KeSetEvent(&ClientCcb
->ConnectEvent
, IO_NO_INCREMENT
, FALSE
);
172 return STATUS_PIPE_CONNECTED
;
176 current_entry
= current_entry
->Flink
;
179 /* no listening client fcb found */
180 DPRINT("No listening client fcb found -- waiting for client\n");
182 Status
= NpfsAddListeningServerInstance(Irp
, Ccb
);
184 KeUnlockMutex(&Fcb
->CcbListLock
);
186 if ((Status
== STATUS_PENDING
) && (Flags
& FO_SYNCHRONOUS_IO
))
188 KeWaitForSingleObject(&Ccb
->ConnectEvent
,
191 (Flags
& FO_ALERTABLE_IO
) != 0,
195 DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status
);
202 NpfsDisconnectPipe(PNPFS_CCB Ccb
)
209 DPRINT("NpfsDisconnectPipe()\n");
211 /* Fail, if the CCB is not a pipe CCB */
212 if (Ccb
->Type
!= CCB_PIPE
)
214 DPRINT("Not a pipe\n");
215 return STATUS_ILLEGAL_FUNCTION
;
218 /* Fail, if the CCB is not a server end CCB */
219 if (Ccb
->PipeEnd
!= FILE_PIPE_SERVER_END
)
221 DPRINT("Not the server end\n");
222 return STATUS_ILLEGAL_FUNCTION
;
226 KeLockMutex(&Fcb
->CcbListLock
);
228 if (Ccb
->PipeState
== FILE_PIPE_DISCONNECTED_STATE
)
230 DPRINT("Pipe is already disconnected\n");
231 Status
= STATUS_PIPE_DISCONNECTED
;
233 else if ((!Ccb
->OtherSide
) && (Ccb
->PipeState
== FILE_PIPE_CONNECTED_STATE
))
235 ExAcquireFastMutex(&Ccb
->DataListLock
);
236 Ccb
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
237 ExReleaseFastMutex(&Ccb
->DataListLock
);
238 Status
= STATUS_SUCCESS
;
240 else if (Ccb
->PipeState
== FILE_PIPE_CONNECTED_STATE
)
242 Server
= (Ccb
->PipeEnd
== FILE_PIPE_SERVER_END
);
243 OtherSide
= Ccb
->OtherSide
;
244 //Ccb->OtherSide = NULL;
245 Ccb
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
246 /* Lock the server first */
249 ExAcquireFastMutex(&Ccb
->DataListLock
);
250 ExAcquireFastMutex(&OtherSide
->DataListLock
);
254 ExAcquireFastMutex(&OtherSide
->DataListLock
);
255 ExAcquireFastMutex(&Ccb
->DataListLock
);
257 OtherSide
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
258 //OtherSide->OtherSide = NULL;
260 * Signaling the write event. If is possible that an other
261 * thread waits for an empty buffer.
263 KeSetEvent(&OtherSide
->ReadEvent
, IO_NO_INCREMENT
, FALSE
);
264 KeSetEvent(&OtherSide
->WriteEvent
, IO_NO_INCREMENT
, FALSE
);
267 ExReleaseFastMutex(&OtherSide
->DataListLock
);
268 ExReleaseFastMutex(&Ccb
->DataListLock
);
272 ExReleaseFastMutex(&Ccb
->DataListLock
);
273 ExReleaseFastMutex(&OtherSide
->DataListLock
);
275 Status
= STATUS_SUCCESS
;
277 else if (Ccb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
280 PNPFS_WAITER_ENTRY WaitEntry
= NULL
;
281 BOOLEAN Complete
= FALSE
;
284 Entry
= Ccb
->Fcb
->WaiterListHead
.Flink
;
285 while (Entry
!= &Ccb
->Fcb
->WaiterListHead
)
287 WaitEntry
= CONTAINING_RECORD(Entry
, NPFS_WAITER_ENTRY
, Entry
);
288 if (WaitEntry
->Ccb
== Ccb
)
290 RemoveEntryList(Entry
);
291 Irp
= CONTAINING_RECORD(Entry
, IRP
, Tail
.Overlay
.DriverContext
);
292 Complete
= (NULL
!= IoSetCancelRoutine(Irp
, NULL
));
295 Entry
= Entry
->Flink
;
302 Irp
->IoStatus
.Status
= STATUS_PIPE_BROKEN
;
303 Irp
->IoStatus
.Information
= 0;
304 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
307 Ccb
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
308 Status
= STATUS_SUCCESS
;
310 else if (Ccb
->PipeState
== FILE_PIPE_CLOSING_STATE
)
312 Status
= STATUS_PIPE_CLOSING
;
316 Status
= STATUS_UNSUCCESSFUL
;
318 KeUnlockMutex(&Fcb
->CcbListLock
);
323 NpfsWaitPipe(PIRP Irp
,
326 PLIST_ENTRY current_entry
;
329 PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe
;
330 PLARGE_INTEGER TimeOut
;
332 PEXTENDED_IO_STACK_LOCATION IoStack
;
333 PFILE_OBJECT FileObject
;
336 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IoGetCurrentIrpStackLocation(Irp
);
338 FileObject
= IoStack
->FileObject
;
341 DPRINT("Waiting on Pipe %wZ\n", &FileObject
->FileName
);
343 WaitPipe
= (PFILE_PIPE_WAIT_FOR_BUFFER
)Irp
->AssociatedIrp
.SystemBuffer
;
346 ASSERT(Ccb
->Fcb
->Vcb
);
351 /* Lock the pipe list */
352 KeLockMutex(&Vcb
->PipeListLock
);
354 /* File a pipe with the given name */
355 Fcb
= NpfsFindPipe(Vcb
,
356 &FileObject
->FileName
);
358 /* Unlock the pipe list */
359 KeUnlockMutex(&Vcb
->PipeListLock
);
361 /* Fail if not pipe was found */
364 DPRINT("No pipe found!\n");
365 return STATUS_OBJECT_NAME_NOT_FOUND
;
368 /* search for listening server */
369 current_entry
= Fcb
->ServerCcbListHead
.Flink
;
370 while (current_entry
!= &Fcb
->ServerCcbListHead
)
372 ServerCcb
= CONTAINING_RECORD(current_entry
,
376 if (ServerCcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
378 /* found a listening server CCB */
379 DPRINT("Listening server CCB found -- connecting\n");
380 NpfsDereferenceFcb(Fcb
);
381 return STATUS_SUCCESS
;
384 current_entry
= current_entry
->Flink
;
387 /* No listening server fcb found, so wait for one */
389 /* If a timeout specified */
390 if (WaitPipe
->TimeoutSpecified
)
392 /* NMPWAIT_USE_DEFAULT_WAIT = 0 */
393 if (WaitPipe
->Timeout
.QuadPart
== 0)
395 TimeOut
= &Fcb
->TimeOut
;
399 TimeOut
= &WaitPipe
->Timeout
;
407 NpfsDereferenceFcb(Fcb
);
409 Status
= KeWaitForSingleObject(&Ccb
->ConnectEvent
,
412 (Ccb
->FileObject
->Flags
& FO_ALERTABLE_IO
) != 0,
414 if ((Status
== STATUS_USER_APC
) || (Status
== STATUS_KERNEL_APC
) || (Status
== STATUS_ALERTED
))
415 Status
= STATUS_CANCELLED
;
417 DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status
);
423 NpfsWaitPipe2(PIRP Irp
,
426 PLIST_ENTRY current_entry
;
429 PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe
;
430 LARGE_INTEGER TimeOut
;
432 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
434 UNICODE_STRING PipeName
;
437 DPRINT("NpfsWaitPipe\n");
439 WaitPipe
= (PFILE_PIPE_WAIT_FOR_BUFFER
)Irp
->AssociatedIrp
.SystemBuffer
;
441 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
442 /* Fail, if the CCB does not represent the root directory */
443 if (Ccb
->Type
!= CCB_DIRECTORY
)
444 return STATUS_ILLEGAL_FUNCTION
;
446 /* Calculate the pipe name length and allocate the buffer */
447 PipeName
.Length
= WaitPipe
->NameLength
+ sizeof(WCHAR
);
448 PipeName
.MaximumLength
= PipeName
.Length
+ sizeof(WCHAR
);
449 PipeName
.Buffer
= ExAllocatePoolWithTag(NonPagedPool
,
450 PipeName
.MaximumLength
,
452 if (PipeName
.Buffer
== NULL
)
454 DPRINT1("Could not allocate memory for the pipe name!\n");
455 return STATUS_NO_MEMORY
;
458 /* Copy the pipe name into the buffer, prepend a backslash and append a 0 character */
459 PipeName
.Buffer
[0] = L
'\\';
460 RtlCopyMemory(&PipeName
.Buffer
[1],
462 WaitPipe
->NameLength
);
463 PipeName
.Buffer
[PipeName
.Length
/ sizeof(WCHAR
)] = 0;
465 DPRINT("Waiting for Pipe %wZ\n", &PipeName
);
470 /* Lock the pipe list */
471 KeLockMutex(&Vcb
->PipeListLock
);
473 /* File a pipe with the given name */
474 Fcb
= NpfsFindPipe(Vcb
,
477 /* Unlock the pipe list */
478 KeUnlockMutex(&Vcb
->PipeListLock
);
480 /* Release the pipe name buffer */
481 ExFreePoolWithTag(PipeName
.Buffer
, TAG_NPFS_NAMEBLOCK
);
483 /* Fail if not pipe was found */
486 DPRINT("No pipe found!\n");
487 return STATUS_OBJECT_NAME_NOT_FOUND
;
490 DPRINT("Fcb %p\n", Fcb
);
494 if (Ccb
->PipeState
!= 0)
496 DPRINT("Pipe is not in passive (waiting) state!\n");
497 return STATUS_UNSUCCESSFUL
;
501 /* search for listening server */
502 current_entry
= Fcb
->ServerCcbListHead
.Flink
;
503 while (current_entry
!= &Fcb
->ServerCcbListHead
)
505 ServerCcb
= CONTAINING_RECORD(current_entry
,
509 if (ServerCcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
511 /* found a listening server CCB */
512 DPRINT("Listening server CCB found -- connecting\n");
513 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
514 NpfsDereferenceFcb(Fcb
);
516 return STATUS_SUCCESS
;
519 current_entry
= current_entry
->Flink
;
522 /* No listening server fcb found */
524 /* If no timeout specified, use the default one */
525 if (WaitPipe
->TimeoutSpecified
)
526 TimeOut
= WaitPipe
->Timeout
;
528 TimeOut
= Fcb
->TimeOut
;
529 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
530 NpfsDereferenceFcb(Fcb
);
534 Status
= KeWaitForSingleObject(&Ccb
->ConnectEvent
,
537 (Ccb
->FileObject
->Flags
& FO_ALERTABLE_IO
) != 0,
539 if ((Status
== STATUS_USER_APC
) || (Status
== STATUS_KERNEL_APC
) || (Status
== STATUS_ALERTED
))
540 Status
= STATUS_CANCELLED
;
542 DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status
);
549 * FUNCTION: Return current state of a pipe
551 * Irp = Pointer to I/O request packet
552 * IrpSp = Pointer to current stack location of Irp
554 * Status of operation
558 * FUNCTION: Peek at a pipe (get information about messages)
560 * Irp = Pointer to I/O request packet
561 * IoStack = Pointer to current stack location of Irp
563 * Status of operation
566 NpfsPeekPipe(PIRP Irp
,
567 PIO_STACK_LOCATION IoStack
)
569 ULONG OutputBufferLength
;
570 ULONG ReturnLength
= 0;
571 PFILE_PIPE_PEEK_BUFFER Reply
;
575 ULONG MessageCount
= 0;
577 ULONG ReadDataAvailable
;
580 DPRINT("NpfsPeekPipe\n");
582 OutputBufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
583 DPRINT("OutputBufferLength: %lu\n", OutputBufferLength
);
585 /* Validate parameters */
586 if (OutputBufferLength
< (ULONG
)FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[0]))
588 DPRINT1("Buffer too small\n");
589 return STATUS_INVALID_PARAMETER
;
592 Ccb
= IoStack
->FileObject
->FsContext2
;
593 Reply
= Irp
->AssociatedIrp
.SystemBuffer
;
597 Reply
->NamedPipeState
= Ccb
->PipeState
;
599 Reply
->ReadDataAvailable
= Ccb
->ReadDataAvailable
;
600 DPRINT("ReadDataAvailable: %lu\n", Ccb
->ReadDataAvailable
);
602 ExAcquireFastMutex(&Ccb
->DataListLock
);
603 BufferPtr
= Ccb
->ReadPtr
;
604 DPRINT("BufferPtr = %p\n", BufferPtr
);
605 if (Ccb
->Fcb
->PipeType
== FILE_PIPE_BYTE_STREAM_TYPE
)
607 DPRINT("Byte Stream Mode\n");
608 Reply
->MessageLength
= Ccb
->ReadDataAvailable
;
609 DPRINT("Reply->MessageLength %lu\n", Reply
->MessageLength
);
612 if (OutputBufferLength
>= (ULONG
)FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[Ccb
->ReadDataAvailable
]))
614 RtlCopyMemory(Reply
->Data
, BufferPtr
, Ccb
->ReadDataAvailable
);
615 ReturnLength
= Ccb
->ReadDataAvailable
;
620 DPRINT("Message Mode\n");
621 ReadDataAvailable
= Ccb
->ReadDataAvailable
;
623 if (ReadDataAvailable
> 0)
625 RtlCopyMemory(&Reply
->MessageLength
,
627 sizeof(Reply
->MessageLength
));
629 while ((ReadDataAvailable
> 0) && (BufferPtr
< Ccb
->WritePtr
))
631 RtlCopyMemory(&MessageLength
, BufferPtr
, sizeof(MessageLength
));
633 ASSERT(MessageLength
> 0);
635 DPRINT("MessageLength = %lu\n", MessageLength
);
636 ReadDataAvailable
-= MessageLength
;
639 /* If its the first message, copy the Message if the size of buffer is large enough */
640 if (MessageCount
== 1)
642 if (OutputBufferLength
>= (ULONG
)FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[MessageLength
]))
644 RtlCopyMemory(Reply
->Data
,
645 (PVOID
)((ULONG_PTR
)BufferPtr
+ sizeof(MessageLength
)),
647 ReturnLength
= MessageLength
;
651 BufferPtr
= (PVOID
)((ULONG_PTR
)BufferPtr
+ sizeof(MessageLength
) + MessageLength
);
652 DPRINT("BufferPtr = %p\n", BufferPtr
);
653 DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable
);
656 if (ReadDataAvailable
!= 0)
658 DPRINT1("Possible memory corruption.\n");
663 ExReleaseFastMutex(&Ccb
->DataListLock
);
665 Reply
->NumberOfMessages
= MessageCount
;
667 Irp
->IoStatus
.Information
= FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[ReturnLength
]);
668 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
670 Status
= STATUS_SUCCESS
;
672 DPRINT("NpfsPeekPipe done\n");
679 NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject
,
682 PIO_STACK_LOCATION IoStack
;
683 PFILE_OBJECT FileObject
;
689 DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
691 //Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
692 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
693 DPRINT("IoStack: %p\n", IoStack
);
694 FileObject
= IoStack
->FileObject
;
695 DPRINT("FileObject: %p\n", FileObject
);
696 Ccb
= FileObject
->FsContext2
;
697 DPRINT("CCB: %p\n", Ccb
);
699 DPRINT("Pipe: %p\n", Fcb
);
700 DPRINT("PipeName: %wZ\n", &Fcb
->PipeName
);
702 Irp
->IoStatus
.Information
= 0;
704 switch (IoStack
->Parameters
.FileSystemControl
.FsControlCode
)
706 case FSCTL_PIPE_ASSIGN_EVENT
:
707 DPRINT1("Assign event not implemented\n");
708 Status
= STATUS_NOT_IMPLEMENTED
;
711 case FSCTL_PIPE_DISCONNECT
:
712 DPRINT("Disconnecting pipe %wZ\n", &Fcb
->PipeName
);
713 Status
= NpfsDisconnectPipe(Ccb
);
716 case FSCTL_PIPE_LISTEN
:
717 DPRINT("Connecting pipe %wZ\n", &Fcb
->PipeName
);
718 Status
= NpfsConnectPipe(Irp
, Ccb
);
721 case FSCTL_PIPE_PEEK
:
722 DPRINT("Peeking pipe %wZ\n", &Fcb
->PipeName
);
723 Status
= NpfsPeekPipe(Irp
, (PIO_STACK_LOCATION
)IoStack
);
726 case FSCTL_PIPE_QUERY_EVENT
:
727 DPRINT1("Query event not implemented\n");
728 Status
= STATUS_NOT_IMPLEMENTED
;
731 case FSCTL_PIPE_TRANSCEIVE
:
732 /* If you implement this, please remove the workaround in
733 lib/kernel32/file/npipe.c function TransactNamedPipe() */
734 DPRINT1("Transceive not implemented\n");
735 Status
= STATUS_NOT_IMPLEMENTED
;
738 case FSCTL_PIPE_WAIT
:
739 DPRINT("Waiting for pipe %wZ\n", &Fcb
->PipeName
);
740 Status
= NpfsWaitPipe(Irp
, Ccb
);
743 case FSCTL_PIPE_IMPERSONATE
:
744 DPRINT1("Impersonate not implemented\n");
745 Status
= STATUS_NOT_IMPLEMENTED
;
748 case FSCTL_PIPE_SET_CLIENT_PROCESS
:
749 DPRINT1("Set client process not implemented\n");
750 Status
= STATUS_NOT_IMPLEMENTED
;
753 case FSCTL_PIPE_QUERY_CLIENT_PROCESS
:
754 DPRINT1("Query client process not implemented\n");
755 Status
= STATUS_NOT_IMPLEMENTED
;
758 case FSCTL_PIPE_INTERNAL_READ
:
759 DPRINT1("Internal read not implemented\n");
760 Status
= STATUS_NOT_IMPLEMENTED
;
763 case FSCTL_PIPE_INTERNAL_WRITE
:
764 DPRINT1("Internal write not implemented\n");
765 Status
= STATUS_NOT_IMPLEMENTED
;
768 case FSCTL_PIPE_INTERNAL_TRANSCEIVE
:
769 DPRINT1("Internal transceive not implemented\n");
770 Status
= STATUS_NOT_IMPLEMENTED
;
773 case FSCTL_PIPE_INTERNAL_READ_OVFLOW
:
774 DPRINT1("Internal read overflow not implemented\n");
775 Status
= STATUS_NOT_IMPLEMENTED
;
779 DPRINT1("Unrecognized IoControlCode: %x\n",
780 IoStack
->Parameters
.FileSystemControl
.FsControlCode
);
781 Status
= STATUS_UNSUCCESSFUL
;
784 if (Status
!= STATUS_PENDING
)
786 Irp
->IoStatus
.Status
= Status
;
788 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
796 NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject
,
799 /* FIXME: Implement */
800 UNREFERENCED_PARAMETER(DeviceObject
);
802 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
803 Irp
->IoStatus
.Information
= 0;
805 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
807 return STATUS_SUCCESS
;