2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/np/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 Waiter
= (PNPFS_WAITER_ENTRY
)&Irp
->Tail
.Overlay
.DriverContext
;
31 DPRINT("NpfsListeningCancelRoutine() called for <%wZ>\n",
32 &Waiter
->Ccb
->Fcb
->PipeName
);
34 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
37 KeLockMutex(&Waiter
->Ccb
->Fcb
->CcbListLock
);
38 RemoveEntryList(&Waiter
->Entry
);
39 KeUnlockMutex(&Waiter
->Ccb
->Fcb
->CcbListLock
);
41 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
42 Irp
->IoStatus
.Information
= 0;
43 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
48 NpfsAddListeningServerInstance(PIRP Irp
,
51 PNPFS_WAITER_ENTRY Entry
;
54 Entry
= (PNPFS_WAITER_ENTRY
)&Irp
->Tail
.Overlay
.DriverContext
;
58 KeLockMutex(&Ccb
->Fcb
->CcbListLock
);
60 IoAcquireCancelSpinLock(&oldIrql
);
63 Ccb
->PipeState
= FILE_PIPE_LISTENING_STATE
;
64 IoMarkIrpPending(Irp
);
65 InsertTailList(&Ccb
->Fcb
->WaiterListHead
, &Entry
->Entry
);
66 (void)IoSetCancelRoutine(Irp
, NpfsListeningCancelRoutine
);
67 IoReleaseCancelSpinLock(oldIrql
);
68 KeUnlockMutex(&Ccb
->Fcb
->CcbListLock
);
69 return STATUS_PENDING
;
71 IoReleaseCancelSpinLock(oldIrql
);
73 RemoveEntryList(&Entry
->Entry
);
75 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
76 Irp
->IoStatus
.Information
= 0;
77 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
78 KeUnlockMutex(&Ccb
->Fcb
->CcbListLock
);
80 return STATUS_CANCELLED
;
85 NpfsConnectPipe(PIRP Irp
,
88 PIO_STACK_LOCATION IoStack
;
89 PFILE_OBJECT FileObject
;
91 PLIST_ENTRY current_entry
;
95 KPROCESSOR_MODE WaitMode
;
97 DPRINT("NpfsConnectPipe()\n");
99 /* Fail, if the CCB is not a pipe CCB */
100 if (Ccb
->Type
!= CCB_PIPE
)
102 DPRINT("Not a pipe\n");
103 return STATUS_ILLEGAL_FUNCTION
;
106 /* Fail, if the CCB is not a server end CCB */
107 if (Ccb
->PipeEnd
!= FILE_PIPE_SERVER_END
)
109 DPRINT("Not the server end\n");
110 return STATUS_ILLEGAL_FUNCTION
;
113 if (Ccb
->PipeState
== FILE_PIPE_CONNECTED_STATE
)
115 KeResetEvent(&Ccb
->ConnectEvent
);
116 return STATUS_PIPE_CONNECTED
;
119 if (Ccb
->PipeState
== FILE_PIPE_CLOSING_STATE
)
120 return STATUS_PIPE_CLOSING
;
122 DPRINT("Waiting for connection...\n");
125 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
126 FileObject
= IoStack
->FileObject
;
127 Flags
= FileObject
->Flags
;
128 WaitMode
= Irp
->RequestorMode
;
130 /* search for a listening client fcb */
131 KeLockMutex(&Fcb
->CcbListLock
);
133 current_entry
= Fcb
->ClientCcbListHead
.Flink
;
134 while (current_entry
!= &Fcb
->ClientCcbListHead
)
136 ClientCcb
= CONTAINING_RECORD(current_entry
,
140 if (ClientCcb
->PipeState
== 0)
142 /* found a passive (waiting) client CCB */
143 DPRINT("Passive (waiting) client CCB found -- wake the client\n");
144 KeSetEvent(&ClientCcb
->ConnectEvent
, IO_NO_INCREMENT
, FALSE
);
149 if (ClientCcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
151 /* found a listening client CCB */
152 DPRINT("Listening client CCB found -- connecting\n");
154 /* connect client and server CCBs */
155 Ccb
->OtherSide
= ClientCcb
;
156 ClientCcb
->OtherSide
= Ccb
;
158 /* set connected state */
159 Ccb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
160 ClientCcb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
162 KeUnlockMutex(&Fcb
->CcbListLock
);
164 /* FIXME: create and initialize data queues */
166 /* signal client's connect event */
167 DPRINT("Setting the ConnectEvent for %x\n", ClientCcb
);
168 KeSetEvent(&ClientCcb
->ConnectEvent
, IO_NO_INCREMENT
, FALSE
);
170 return STATUS_PIPE_CONNECTED
;
174 current_entry
= current_entry
->Flink
;
177 /* no listening client fcb found */
178 DPRINT("No listening client fcb found -- waiting for client\n");
180 Status
= NpfsAddListeningServerInstance(Irp
, Ccb
);
182 KeUnlockMutex(&Fcb
->CcbListLock
);
184 if ((Status
== STATUS_PENDING
) && (Flags
& FO_SYNCHRONOUS_IO
))
186 KeWaitForSingleObject(&Ccb
->ConnectEvent
,
189 (Flags
& FO_ALERTABLE_IO
) != 0,
193 DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status
);
200 NpfsDisconnectPipe(PNPFS_CCB Ccb
)
207 DPRINT("NpfsDisconnectPipe()\n");
209 /* Fail, if the CCB is not a pipe CCB */
210 if (Ccb
->Type
!= CCB_PIPE
)
212 DPRINT("Not a pipe\n");
213 return STATUS_ILLEGAL_FUNCTION
;
216 /* Fail, if the CCB is not a server end CCB */
217 if (Ccb
->PipeEnd
!= FILE_PIPE_SERVER_END
)
219 DPRINT("Not the server end\n");
220 return STATUS_ILLEGAL_FUNCTION
;
224 KeLockMutex(&Fcb
->CcbListLock
);
226 if (Ccb
->PipeState
== FILE_PIPE_DISCONNECTED_STATE
)
228 DPRINT("Pipe is already disconnected\n");
229 Status
= STATUS_PIPE_DISCONNECTED
;
231 else if ((!Ccb
->OtherSide
) && (Ccb
->PipeState
== FILE_PIPE_CONNECTED_STATE
))
233 ExAcquireFastMutex(&Ccb
->DataListLock
);
234 Ccb
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
235 ExReleaseFastMutex(&Ccb
->DataListLock
);
236 Status
= STATUS_SUCCESS
;
238 else if (Ccb
->PipeState
== FILE_PIPE_CONNECTED_STATE
)
240 Server
= (Ccb
->PipeEnd
== FILE_PIPE_SERVER_END
);
241 OtherSide
= Ccb
->OtherSide
;
242 //Ccb->OtherSide = NULL;
243 Ccb
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
244 /* Lock the server first */
247 ExAcquireFastMutex(&Ccb
->DataListLock
);
248 ExAcquireFastMutex(&OtherSide
->DataListLock
);
252 ExAcquireFastMutex(&OtherSide
->DataListLock
);
253 ExAcquireFastMutex(&Ccb
->DataListLock
);
255 OtherSide
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
256 //OtherSide->OtherSide = NULL;
258 * Signaling the write event. If is possible that an other
259 * thread waits for an empty buffer.
261 KeSetEvent(&OtherSide
->ReadEvent
, IO_NO_INCREMENT
, FALSE
);
262 KeSetEvent(&OtherSide
->WriteEvent
, IO_NO_INCREMENT
, FALSE
);
265 ExReleaseFastMutex(&OtherSide
->DataListLock
);
266 ExReleaseFastMutex(&Ccb
->DataListLock
);
270 ExReleaseFastMutex(&Ccb
->DataListLock
);
271 ExReleaseFastMutex(&OtherSide
->DataListLock
);
273 Status
= STATUS_SUCCESS
;
275 else if (Ccb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
278 PNPFS_WAITER_ENTRY WaitEntry
= NULL
;
279 BOOLEAN Complete
= FALSE
;
282 Entry
= Ccb
->Fcb
->WaiterListHead
.Flink
;
283 while (Entry
!= &Ccb
->Fcb
->WaiterListHead
)
285 WaitEntry
= CONTAINING_RECORD(Entry
, NPFS_WAITER_ENTRY
, Entry
);
286 if (WaitEntry
->Ccb
== Ccb
)
288 RemoveEntryList(Entry
);
289 Irp
= CONTAINING_RECORD(Entry
, IRP
, Tail
.Overlay
.DriverContext
);
290 Complete
= (NULL
!= IoSetCancelRoutine(Irp
, NULL
));
293 Entry
= Entry
->Flink
;
300 Irp
->IoStatus
.Status
= STATUS_PIPE_BROKEN
;
301 Irp
->IoStatus
.Information
= 0;
302 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
305 Ccb
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
306 Status
= STATUS_SUCCESS
;
308 else if (Ccb
->PipeState
== FILE_PIPE_CLOSING_STATE
)
310 Status
= STATUS_PIPE_CLOSING
;
314 Status
= STATUS_UNSUCCESSFUL
;
316 KeUnlockMutex(&Fcb
->CcbListLock
);
321 NpfsWaitPipe(PIRP Irp
,
324 PLIST_ENTRY current_entry
;
327 PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe
;
328 PLARGE_INTEGER TimeOut
;
330 PEXTENDED_IO_STACK_LOCATION IoStack
;
331 PFILE_OBJECT FileObject
;
334 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IoGetCurrentIrpStackLocation(Irp
);
336 FileObject
= IoStack
->FileObject
;
339 DPRINT("Waiting on Pipe %wZ\n", &FileObject
->FileName
);
341 WaitPipe
= (PFILE_PIPE_WAIT_FOR_BUFFER
)Irp
->AssociatedIrp
.SystemBuffer
;
344 ASSERT(Ccb
->Fcb
->Vcb
);
349 /* Lock the pipe list */
350 KeLockMutex(&Vcb
->PipeListLock
);
352 /* File a pipe with the given name */
353 Fcb
= NpfsFindPipe(Vcb
,
354 &FileObject
->FileName
);
356 /* Unlock the pipe list */
357 KeUnlockMutex(&Vcb
->PipeListLock
);
359 /* Fail if not pipe was found */
362 DPRINT("No pipe found!\n", Fcb
);
363 return STATUS_OBJECT_NAME_NOT_FOUND
;
366 /* search for listening server */
367 current_entry
= Fcb
->ServerCcbListHead
.Flink
;
368 while (current_entry
!= &Fcb
->ServerCcbListHead
)
370 ServerCcb
= CONTAINING_RECORD(current_entry
,
374 if (ServerCcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
376 /* found a listening server CCB */
377 DPRINT("Listening server CCB found -- connecting\n");
378 NpfsDereferenceFcb(Fcb
);
379 return STATUS_SUCCESS
;
382 current_entry
= current_entry
->Flink
;
385 /* No listening server fcb found, so wait for one */
387 /* If a timeout specified */
388 if (WaitPipe
->TimeoutSpecified
)
390 /* NMPWAIT_USE_DEFAULT_WAIT = 0 */
391 if (WaitPipe
->Timeout
.QuadPart
== 0)
393 TimeOut
= &Fcb
->TimeOut
;
397 TimeOut
= &WaitPipe
->Timeout
;
405 NpfsDereferenceFcb(Fcb
);
407 Status
= KeWaitForSingleObject(&Ccb
->ConnectEvent
,
410 (Ccb
->FileObject
->Flags
& FO_ALERTABLE_IO
) != 0,
412 if ((Status
== STATUS_USER_APC
) || (Status
== STATUS_KERNEL_APC
) || (Status
== STATUS_ALERTED
))
413 Status
= STATUS_CANCELLED
;
415 DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status
);
421 NpfsWaitPipe2(PIRP Irp
,
424 PLIST_ENTRY current_entry
;
427 PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe
;
428 LARGE_INTEGER TimeOut
;
430 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
432 UNICODE_STRING PipeName
;
435 DPRINT("NpfsWaitPipe\n");
437 WaitPipe
= (PFILE_PIPE_WAIT_FOR_BUFFER
)Irp
->AssociatedIrp
.SystemBuffer
;
439 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
440 /* Fail, if the CCB does not represent the root directory */
441 if (Ccb
->Type
!= CCB_DIRECTORY
)
442 return STATUS_ILLEGAL_FUNCTION
;
444 /* Calculate the pipe name length and allocate the buffer */
445 PipeName
.Length
= WaitPipe
->NameLength
+ sizeof(WCHAR
);
446 PipeName
.MaximumLength
= PipeName
.Length
+ sizeof(WCHAR
);
447 PipeName
.Buffer
= ExAllocatePoolWithTag(NonPagedPool
,
448 PipeName
.MaximumLength
,
450 if (PipeName
.Buffer
== NULL
)
452 DPRINT1("Could not allocate memory for the pipe name!\n");
453 return STATUS_NO_MEMORY
;
456 /* Copy the pipe name into the buffer, prepend a backslash and append a 0 character */
457 PipeName
.Buffer
[0] = L
'\\';
458 RtlCopyMemory(&PipeName
.Buffer
[1],
460 WaitPipe
->NameLength
);
461 PipeName
.Buffer
[PipeName
.Length
/ sizeof(WCHAR
)] = 0;
463 DPRINT("Waiting for Pipe %wZ\n", &PipeName
);
468 /* Lock the pipe list */
469 KeLockMutex(&Vcb
->PipeListLock
);
471 /* File a pipe with the given name */
472 Fcb
= NpfsFindPipe(Vcb
,
475 /* Unlock the pipe list */
476 KeUnlockMutex(&Vcb
->PipeListLock
);
478 /* Release the pipe name buffer */
479 ExFreePoolWithTag(PipeName
.Buffer
, TAG_NPFS_NAMEBLOCK
);
481 /* Fail if not pipe was found */
484 DPRINT("No pipe found!\n", Fcb
);
485 return STATUS_OBJECT_NAME_NOT_FOUND
;
488 DPRINT("Fcb %p\n", Fcb
);
492 if (Ccb
->PipeState
!= 0)
494 DPRINT("Pipe is not in passive (waiting) state!\n");
495 return STATUS_UNSUCCESSFUL
;
499 /* search for listening server */
500 current_entry
= Fcb
->ServerCcbListHead
.Flink
;
501 while (current_entry
!= &Fcb
->ServerCcbListHead
)
503 ServerCcb
= CONTAINING_RECORD(current_entry
,
507 if (ServerCcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
509 /* found a listening server CCB */
510 DPRINT("Listening server CCB found -- connecting\n");
511 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
512 NpfsDereferenceFcb(Fcb
);
514 return STATUS_SUCCESS
;
517 current_entry
= current_entry
->Flink
;
520 /* No listening server fcb found */
522 /* If no timeout specified, use the default one */
523 if (WaitPipe
->TimeoutSpecified
)
524 TimeOut
= WaitPipe
->Timeout
;
526 TimeOut
= Fcb
->TimeOut
;
527 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
528 NpfsDereferenceFcb(Fcb
);
532 Status
= KeWaitForSingleObject(&Ccb
->ConnectEvent
,
535 (Ccb
->FileObject
->Flags
& FO_ALERTABLE_IO
) != 0,
537 if ((Status
== STATUS_USER_APC
) || (Status
== STATUS_KERNEL_APC
) || (Status
== STATUS_ALERTED
))
538 Status
= STATUS_CANCELLED
;
540 DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status
);
547 * FUNCTION: Return current state of a pipe
549 * Irp = Pointer to I/O request packet
550 * IrpSp = Pointer to current stack location of Irp
552 * Status of operation
556 * FUNCTION: Peek at a pipe (get information about messages)
558 * Irp = Pointer to I/O request packet
559 * IoStack = Pointer to current stack location of Irp
561 * Status of operation
564 NpfsPeekPipe(PIRP Irp
,
565 PIO_STACK_LOCATION IoStack
)
567 ULONG OutputBufferLength
;
568 ULONG ReturnLength
= 0;
569 PFILE_PIPE_PEEK_BUFFER Reply
;
573 ULONG MessageCount
= 0;
575 ULONG ReadDataAvailable
;
578 DPRINT("NpfsPeekPipe\n");
580 OutputBufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
581 DPRINT("OutputBufferLength: %lu\n", OutputBufferLength
);
583 /* Validate parameters */
584 if (OutputBufferLength
< FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[0]))
586 DPRINT1("Buffer too small\n");
587 return STATUS_INVALID_PARAMETER
;
590 Ccb
= IoStack
->FileObject
->FsContext2
;
591 Reply
= Irp
->AssociatedIrp
.SystemBuffer
;
595 Reply
->NamedPipeState
= Ccb
->PipeState
;
597 Reply
->ReadDataAvailable
= Ccb
->ReadDataAvailable
;
598 DPRINT("ReadDataAvailable: %lu\n", Ccb
->ReadDataAvailable
);
600 ExAcquireFastMutex(&Ccb
->DataListLock
);
601 BufferPtr
= Ccb
->ReadPtr
;
602 DPRINT("BufferPtr = %x\n", BufferPtr
);
603 if (Ccb
->Fcb
->PipeType
== FILE_PIPE_BYTE_STREAM_TYPE
)
605 DPRINT("Byte Stream Mode\n");
606 Reply
->MessageLength
= Ccb
->ReadDataAvailable
;
607 DPRINT("Reply->MessageLength %lu\n", Reply
->MessageLength
);
610 if (OutputBufferLength
>= FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[Ccb
->ReadDataAvailable
]))
612 RtlCopyMemory(Reply
->Data
, BufferPtr
, Ccb
->ReadDataAvailable
);
613 ReturnLength
= Ccb
->ReadDataAvailable
;
618 DPRINT("Message Mode\n");
619 ReadDataAvailable
= Ccb
->ReadDataAvailable
;
621 if (ReadDataAvailable
> 0)
623 RtlCopyMemory(&Reply
->MessageLength
,
625 sizeof(Reply
->MessageLength
));
627 while ((ReadDataAvailable
> 0) && (BufferPtr
< Ccb
->WritePtr
))
629 RtlCopyMemory(&MessageLength
, BufferPtr
, sizeof(MessageLength
));
631 ASSERT(MessageLength
> 0);
633 DPRINT("MessageLength = %lu\n", MessageLength
);
634 ReadDataAvailable
-= MessageLength
;
637 /* If its the first message, copy the Message if the size of buffer is large enough */
638 if (MessageCount
== 1)
640 if (OutputBufferLength
>= FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[MessageLength
]))
642 RtlCopyMemory(Reply
->Data
,
643 (PVOID
)((ULONG_PTR
)BufferPtr
+ sizeof(MessageLength
)),
645 ReturnLength
= MessageLength
;
649 BufferPtr
= (PVOID
)((ULONG_PTR
)BufferPtr
+ sizeof(MessageLength
) + MessageLength
);
650 DPRINT("BufferPtr = %x\n", BufferPtr
);
651 DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable
);
654 if (ReadDataAvailable
!= 0)
656 DPRINT1("Possible memory corruption.\n");
661 ExReleaseFastMutex(&Ccb
->DataListLock
);
663 Reply
->NumberOfMessages
= MessageCount
;
665 Irp
->IoStatus
.Information
= FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[ReturnLength
]);
666 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
668 Status
= STATUS_SUCCESS
;
670 DPRINT("NpfsPeekPipe done\n");
677 NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject
,
680 PIO_STACK_LOCATION IoStack
;
681 PFILE_OBJECT FileObject
;
687 DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
689 //Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
690 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
691 DPRINT("IoStack: %p\n", IoStack
);
692 FileObject
= IoStack
->FileObject
;
693 DPRINT("FileObject: %p\n", FileObject
);
694 Ccb
= FileObject
->FsContext2
;
695 DPRINT("CCB: %p\n", Ccb
);
697 DPRINT("Pipe: %p\n", Fcb
);
698 DPRINT("PipeName: %wZ\n", &Fcb
->PipeName
);
700 Irp
->IoStatus
.Information
= 0;
702 switch (IoStack
->Parameters
.FileSystemControl
.FsControlCode
)
704 case FSCTL_PIPE_ASSIGN_EVENT
:
705 DPRINT1("Assign event not implemented\n");
706 Status
= STATUS_NOT_IMPLEMENTED
;
709 case FSCTL_PIPE_DISCONNECT
:
710 DPRINT("Disconnecting pipe %wZ\n", &Fcb
->PipeName
);
711 Status
= NpfsDisconnectPipe(Ccb
);
714 case FSCTL_PIPE_LISTEN
:
715 DPRINT("Connecting pipe %wZ\n", &Fcb
->PipeName
);
716 Status
= NpfsConnectPipe(Irp
, Ccb
);
719 case FSCTL_PIPE_PEEK
:
720 DPRINT("Peeking pipe %wZ\n", &Fcb
->PipeName
);
721 Status
= NpfsPeekPipe(Irp
, (PIO_STACK_LOCATION
)IoStack
);
724 case FSCTL_PIPE_QUERY_EVENT
:
725 DPRINT1("Query event not implemented\n");
726 Status
= STATUS_NOT_IMPLEMENTED
;
729 case FSCTL_PIPE_TRANSCEIVE
:
730 /* If you implement this, please remove the workaround in
731 lib/kernel32/file/npipe.c function TransactNamedPipe() */
732 DPRINT1("Transceive not implemented\n");
733 Status
= STATUS_NOT_IMPLEMENTED
;
736 case FSCTL_PIPE_WAIT
:
737 DPRINT("Waiting for pipe %wZ\n", &Fcb
->PipeName
);
738 Status
= NpfsWaitPipe(Irp
, Ccb
);
741 case FSCTL_PIPE_IMPERSONATE
:
742 DPRINT1("Impersonate not implemented\n");
743 Status
= STATUS_NOT_IMPLEMENTED
;
746 case FSCTL_PIPE_SET_CLIENT_PROCESS
:
747 DPRINT1("Set client process not implemented\n");
748 Status
= STATUS_NOT_IMPLEMENTED
;
751 case FSCTL_PIPE_QUERY_CLIENT_PROCESS
:
752 DPRINT1("Query client process not implemented\n");
753 Status
= STATUS_NOT_IMPLEMENTED
;
756 case FSCTL_PIPE_INTERNAL_READ
:
757 DPRINT1("Internal read not implemented\n");
758 Status
= STATUS_NOT_IMPLEMENTED
;
761 case FSCTL_PIPE_INTERNAL_WRITE
:
762 DPRINT1("Internal write not implemented\n");
763 Status
= STATUS_NOT_IMPLEMENTED
;
766 case FSCTL_PIPE_INTERNAL_TRANSCEIVE
:
767 DPRINT1("Internal transceive not implemented\n");
768 Status
= STATUS_NOT_IMPLEMENTED
;
771 case FSCTL_PIPE_INTERNAL_READ_OVFLOW
:
772 DPRINT1("Internal read overflow not implemented\n");
773 Status
= STATUS_NOT_IMPLEMENTED
;
777 DPRINT1("Unrecognized IoControlCode: %x\n",
778 IoStack
->Parameters
.FileSystemControl
.FsControlCode
);
779 Status
= STATUS_UNSUCCESSFUL
;
782 if (Status
!= STATUS_PENDING
)
784 Irp
->IoStatus
.Status
= Status
;
786 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
794 NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject
,
797 /* FIXME: Implement */
799 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
800 Irp
->IoStatus
.Information
= 0;
802 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
804 return STATUS_SUCCESS
;