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 IoMarkIrpPending(Irp
);
61 InsertTailList(&Ccb
->Fcb
->WaiterListHead
, &Entry
->Entry
);
63 IoAcquireCancelSpinLock(&oldIrql
);
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
;
96 DPRINT("NpfsConnectPipe()\n");
98 /* Fail, if the CCB is not a pipe CCB */
99 if (Ccb
->Type
!= CCB_PIPE
)
101 DPRINT("Not a pipe\n");
102 return STATUS_ILLEGAL_FUNCTION
;
105 /* Fail, if the CCB is not a server end CCB */
106 if (Ccb
->PipeEnd
!= FILE_PIPE_SERVER_END
)
108 DPRINT("Not the server end\n");
109 return STATUS_ILLEGAL_FUNCTION
;
112 if (Ccb
->PipeState
== FILE_PIPE_CONNECTED_STATE
)
114 KeResetEvent(&Ccb
->ConnectEvent
);
115 return STATUS_PIPE_CONNECTED
;
118 if (Ccb
->PipeState
== FILE_PIPE_CLOSING_STATE
)
119 return STATUS_PIPE_CLOSING
;
121 DPRINT("Waiting for connection...\n");
124 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
125 FileObject
= IoStack
->FileObject
;
126 Flags
= FileObject
->Flags
;
128 /* search for a listening client fcb */
129 KeLockMutex(&Fcb
->CcbListLock
);
131 current_entry
= Fcb
->ClientCcbListHead
.Flink
;
132 while (current_entry
!= &Fcb
->ClientCcbListHead
)
134 ClientCcb
= CONTAINING_RECORD(current_entry
,
138 if (ClientCcb
->PipeState
== 0)
140 /* found a passive (waiting) client CCB */
141 DPRINT("Passive (waiting) client CCB found -- wake the client\n");
142 KeSetEvent(&ClientCcb
->ConnectEvent
, IO_NO_INCREMENT
, FALSE
);
147 if (ClientCcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
149 /* found a listening client CCB */
150 DPRINT("Listening client CCB found -- connecting\n");
152 /* connect client and server CCBs */
153 Ccb
->OtherSide
= ClientCcb
;
154 ClientCcb
->OtherSide
= Ccb
;
156 /* set connected state */
157 Ccb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
158 ClientCcb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
160 KeUnlockMutex(&Fcb
->CcbListLock
);
162 /* FIXME: create and initialize data queues */
164 /* signal client's connect event */
165 DPRINT("Setting the ConnectEvent for %x\n", ClientCcb
);
166 KeSetEvent(&ClientCcb
->ConnectEvent
, IO_NO_INCREMENT
, FALSE
);
168 return STATUS_PIPE_CONNECTED
;
172 current_entry
= current_entry
->Flink
;
175 /* no listening client fcb found */
176 DPRINT("No listening client fcb found -- waiting for client\n");
178 Ccb
->PipeState
= FILE_PIPE_LISTENING_STATE
;
180 Status
= NpfsAddListeningServerInstance(Irp
, Ccb
);
182 KeUnlockMutex(&Fcb
->CcbListLock
);
184 if (Flags
& FO_SYNCHRONOUS_IO
)
186 KeWaitForSingleObject(&Ccb
->ConnectEvent
,
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");
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
;
406 Status
= KeWaitForSingleObject(&Ccb
->ConnectEvent
,
412 DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status
);
418 NpfsWaitPipe2(PIRP Irp
,
421 PLIST_ENTRY current_entry
;
424 PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe
;
425 LARGE_INTEGER TimeOut
;
427 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
429 UNICODE_STRING PipeName
;
432 DPRINT("NpfsWaitPipe\n");
434 WaitPipe
= (PFILE_PIPE_WAIT_FOR_BUFFER
)Irp
->AssociatedIrp
.SystemBuffer
;
436 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
437 /* Fail, if the CCB does not represent the root directory */
438 if (Ccb
->Type
!= CCB_DIRECTORY
)
439 return STATUS_ILLEGAL_FUNCTION
;
441 /* Calculate the pipe name length and allocate the buffer */
442 PipeName
.Length
= WaitPipe
->NameLength
+ sizeof(WCHAR
);
443 PipeName
.MaximumLength
= PipeName
.Length
+ sizeof(WCHAR
);
444 PipeName
.Buffer
= ExAllocatePoolWithTag(NonPagedPool
,
445 PipeName
.MaximumLength
,
447 if (PipeName
.Buffer
== NULL
)
449 DPRINT1("Could not allocate memory for the pipe name!\n");
450 return STATUS_NO_MEMORY
;
453 /* Copy the pipe name into the buffer, prepend a backslash and append a 0 character */
454 PipeName
.Buffer
[0] = L
'\\';
455 RtlCopyMemory(&PipeName
.Buffer
[1],
457 WaitPipe
->NameLength
);
458 PipeName
.Buffer
[PipeName
.Length
/ sizeof(WCHAR
)] = 0;
460 DPRINT("Waiting for Pipe %wZ\n", &PipeName
);
465 /* Lock the pipe list */
466 KeLockMutex(&Vcb
->PipeListLock
);
468 /* File a pipe with the given name */
469 Fcb
= NpfsFindPipe(Vcb
,
472 /* Unlock the pipe list */
473 KeUnlockMutex(&Vcb
->PipeListLock
);
475 /* Release the pipe name buffer */
476 ExFreePoolWithTag(PipeName
.Buffer
, TAG_NPFS_NAMEBLOCK
);
478 /* Fail if not pipe was found */
481 DPRINT("No pipe found!\n", Fcb
);
482 return STATUS_OBJECT_NAME_NOT_FOUND
;
485 DPRINT("Fcb %p\n", Fcb
);
489 if (Ccb
->PipeState
!= 0)
491 DPRINT("Pipe is not in passive (waiting) state!\n");
492 return STATUS_UNSUCCESSFUL
;
496 /* search for listening server */
497 current_entry
= Fcb
->ServerCcbListHead
.Flink
;
498 while (current_entry
!= &Fcb
->ServerCcbListHead
)
500 ServerCcb
= CONTAINING_RECORD(current_entry
,
504 if (ServerCcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
506 /* found a listening server CCB */
507 DPRINT("Listening server CCB found -- connecting\n");
509 return STATUS_SUCCESS
;
512 current_entry
= current_entry
->Flink
;
515 /* No listening server fcb found */
517 /* If no timeout specified, use the default one */
518 if (WaitPipe
->TimeoutSpecified
)
519 TimeOut
= WaitPipe
->Timeout
;
521 TimeOut
= Fcb
->TimeOut
;
524 Status
= KeWaitForSingleObject(&Ccb
->ConnectEvent
,
530 DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status
);
537 * FUNCTION: Return current state of a pipe
539 * Irp = Pointer to I/O request packet
540 * IrpSp = Pointer to current stack location of Irp
542 * Status of operation
546 * FUNCTION: Peek at a pipe (get information about messages)
548 * Irp = Pointer to I/O request packet
549 * IoStack = Pointer to current stack location of Irp
551 * Status of operation
554 NpfsPeekPipe(PIRP Irp
,
555 PIO_STACK_LOCATION IoStack
)
557 ULONG OutputBufferLength
;
558 ULONG ReturnLength
= 0;
559 PFILE_PIPE_PEEK_BUFFER Reply
;
563 ULONG MessageCount
= 0;
565 ULONG ReadDataAvailable
;
568 DPRINT("NpfsPeekPipe\n");
570 OutputBufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
571 DPRINT("OutputBufferLength: %lu\n", OutputBufferLength
);
573 /* Validate parameters */
574 if (OutputBufferLength
< sizeof(FILE_PIPE_PEEK_BUFFER
))
576 DPRINT1("Buffer too small\n");
577 return STATUS_INVALID_PARAMETER
;
580 Ccb
= IoStack
->FileObject
->FsContext2
;
581 Reply
= (PFILE_PIPE_PEEK_BUFFER
)Irp
->AssociatedIrp
.SystemBuffer
;
585 Reply
->NamedPipeState
= Ccb
->PipeState
;
587 Reply
->ReadDataAvailable
= Ccb
->ReadDataAvailable
;
588 DPRINT("ReadDataAvailable: %lu\n", Ccb
->ReadDataAvailable
);
590 ExAcquireFastMutex(&Ccb
->DataListLock
);
591 BufferPtr
= Ccb
->ReadPtr
;
592 DPRINT("BufferPtr = %x\n", BufferPtr
);
593 if (Ccb
->Fcb
->PipeType
== FILE_PIPE_BYTE_STREAM_TYPE
)
595 DPRINT("Byte Stream Mode\n");
596 Reply
->MessageLength
= Ccb
->ReadDataAvailable
;
597 DPRINT("Reply->MessageLength %lu\n",Reply
->MessageLength
);
600 if (Reply
->Data
[0] && (OutputBufferLength
>= Ccb
->ReadDataAvailable
+ FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[0])))
602 ReturnLength
= Ccb
->ReadDataAvailable
;
603 memcpy(&Reply
->Data
[0], (PVOID
)BufferPtr
, Ccb
->ReadDataAvailable
);
608 DPRINT("Message Mode\n");
609 ReadDataAvailable
=Ccb
->ReadDataAvailable
;
611 if (ReadDataAvailable
> 0)
613 memcpy(&Reply
->MessageLength
, BufferPtr
, sizeof(ULONG
));
615 while ((ReadDataAvailable
> 0) && (BufferPtr
< Ccb
->WritePtr
))
617 memcpy(&MessageLength
, BufferPtr
, sizeof(MessageLength
));
619 ASSERT(MessageLength
> 0);
621 DPRINT("MessageLength = %lu\n",MessageLength
);
622 ReadDataAvailable
-= MessageLength
;
625 /* If its the first message, copy the Message if the size of buffer is large enough */
629 && (OutputBufferLength
>= (MessageLength
+ FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[0]))))
631 memcpy(&Reply
->Data
[0], (PVOID
)((ULONG_PTR
)BufferPtr
+ sizeof(MessageLength
)), MessageLength
);
632 ReturnLength
= MessageLength
;
636 BufferPtr
=(PVOID
)((ULONG_PTR
)BufferPtr
+ MessageLength
+ sizeof(MessageLength
));
637 DPRINT("BufferPtr = %x\n", BufferPtr
);
638 DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable
);
641 if (ReadDataAvailable
!= 0)
643 DPRINT1("Possible memory corruption.\n");
648 ExReleaseFastMutex(&Ccb
->DataListLock
);
650 Reply
->NumberOfMessages
= MessageCount
;
652 Irp
->IoStatus
.Information
= ReturnLength
+ FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[0]);
653 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
655 Status
= STATUS_SUCCESS
;
657 DPRINT("NpfsPeekPipe done\n");
664 NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject
,
667 PIO_STACK_LOCATION IoStack
;
668 PFILE_OBJECT FileObject
;
674 DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
676 Vcb
= (PNPFS_VCB
)DeviceObject
->DeviceExtension
;
677 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
678 DPRINT("IoStack: %p\n", IoStack
);
679 FileObject
= IoStack
->FileObject
;
680 DPRINT("FileObject: %p\n", FileObject
);
681 Ccb
= FileObject
->FsContext2
;
682 DPRINT("CCB: %p\n", Ccb
);
684 DPRINT("Pipe: %p\n", Fcb
);
685 DPRINT("PipeName: %wZ\n", &Fcb
->PipeName
);
687 Irp
->IoStatus
.Information
= 0;
689 switch (IoStack
->Parameters
.FileSystemControl
.FsControlCode
)
691 case FSCTL_PIPE_ASSIGN_EVENT
:
692 DPRINT1("Assign event not implemented\n");
693 Status
= STATUS_NOT_IMPLEMENTED
;
696 case FSCTL_PIPE_DISCONNECT
:
697 DPRINT("Disconnecting pipe %wZ\n", &Fcb
->PipeName
);
698 Status
= NpfsDisconnectPipe(Ccb
);
701 case FSCTL_PIPE_LISTEN
:
702 DPRINT("Connecting pipe %wZ\n", &Fcb
->PipeName
);
703 Status
= NpfsConnectPipe(Irp
, Ccb
);
706 case FSCTL_PIPE_PEEK
:
707 DPRINT("Peeking pipe %wZ\n", &Fcb
->PipeName
);
708 Status
= NpfsPeekPipe(Irp
, (PIO_STACK_LOCATION
)IoStack
);
711 case FSCTL_PIPE_QUERY_EVENT
:
712 DPRINT1("Query event not implemented\n");
713 Status
= STATUS_NOT_IMPLEMENTED
;
716 case FSCTL_PIPE_TRANSCEIVE
:
717 /* If you implement this, please remove the workaround in
718 lib/kernel32/file/npipe.c function TransactNamedPipe() */
719 DPRINT1("Transceive not implemented\n");
720 Status
= STATUS_NOT_IMPLEMENTED
;
723 case FSCTL_PIPE_WAIT
:
724 DPRINT("Waiting for pipe %wZ\n", &Fcb
->PipeName
);
725 Status
= NpfsWaitPipe(Irp
, Ccb
);
728 case FSCTL_PIPE_IMPERSONATE
:
729 DPRINT1("Impersonate not implemented\n");
730 Status
= STATUS_NOT_IMPLEMENTED
;
733 case FSCTL_PIPE_SET_CLIENT_PROCESS
:
734 DPRINT1("Set client process not implemented\n");
735 Status
= STATUS_NOT_IMPLEMENTED
;
738 case FSCTL_PIPE_QUERY_CLIENT_PROCESS
:
739 DPRINT1("Query client process not implemented\n");
740 Status
= STATUS_NOT_IMPLEMENTED
;
743 case FSCTL_PIPE_INTERNAL_READ
:
744 DPRINT1("Internal read not implemented\n");
745 Status
= STATUS_NOT_IMPLEMENTED
;
748 case FSCTL_PIPE_INTERNAL_WRITE
:
749 DPRINT1("Internal write not implemented\n");
750 Status
= STATUS_NOT_IMPLEMENTED
;
753 case FSCTL_PIPE_INTERNAL_TRANSCEIVE
:
754 DPRINT1("Internal transceive not implemented\n");
755 Status
= STATUS_NOT_IMPLEMENTED
;
758 case FSCTL_PIPE_INTERNAL_READ_OVFLOW
:
759 DPRINT1("Internal read overflow not implemented\n");
760 Status
= STATUS_NOT_IMPLEMENTED
;
764 DPRINT1("Unrecognized IoControlCode: %x\n",
765 IoStack
->Parameters
.FileSystemControl
.FsControlCode
);
766 Status
= STATUS_UNSUCCESSFUL
;
769 if (Status
!= STATUS_PENDING
)
771 Irp
->IoStatus
.Status
= Status
;
773 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
781 NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject
,
784 /* FIXME: Implement */
786 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
787 Irp
->IoStatus
.Information
= 0;
789 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
791 return STATUS_SUCCESS
;