3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/np/fsctrl.c
6 * PURPOSE: Named pipe filesystem
7 * PROGRAMMER: David Welch <welch@cwcom.net>
8 * Eric Kohl <ekohl@rz-online.de>
11 /* INCLUDES ******************************************************************/
13 #include <ddk/ntddk.h>
20 /* FUNCTIONS *****************************************************************/
23 NpfsConnectPipe(PNPFS_FCB Fcb)
26 PLIST_ENTRY current_entry;
30 DPRINT("NpfsConnectPipe()\n");
32 if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
33 return STATUS_PIPE_CONNECTED;
35 if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
36 return STATUS_PIPE_CLOSING;
39 * Acceptable states are: FILE_PIPE_DISCONNECTED_STATE and
40 * FILE_PIPE_LISTENING_STATE
43 DPRINT("Waiting for connection...\n");
47 Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
49 /* search for a listening client fcb */
51 current_entry = Pipe->ClientFcbListHead.Flink;
52 while (current_entry != &Pipe->ClientFcbListHead)
54 ClientFcb = CONTAINING_RECORD(current_entry,
58 if ((ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE)
59 || (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE))
64 current_entry = current_entry->Flink;
67 if ((current_entry != &Pipe->ClientFcbListHead)
68 && (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE))
70 /* found a listening client fcb */
71 DPRINT("Listening client fcb found -- connecting\n");
73 /* connect client and server fcb's */
74 Fcb->OtherSide = ClientFcb;
75 ClientFcb->OtherSide = Fcb;
77 /* set connected state */
78 Fcb->PipeState = FILE_PIPE_CONNECTED_STATE;
79 ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
81 /* FIXME: create and initialize data queues */
83 /* signal client's connect event */
84 KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
87 else if ((current_entry != &Pipe->ClientFcbListHead)
88 && (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE))
90 /* found a disconnected client fcb */
91 DPRINT("Disconnected client fcb found - notifying client\n");
93 /* signal client's connect event */
94 KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
98 /* no listening client fcb found */
99 DPRINT("No listening client fcb found -- waiting for client\n");
100 Status = KeWaitForSingleObject(&Fcb->ConnectEvent,
106 DPRINT("Finished waiting! Status: %x\n", Status);
110 DPRINT("Client Fcb: %p\n", Fcb->OtherSide);
112 return STATUS_PIPE_CONNECTED;
117 NpfsDisconnectPipe(PNPFS_FCB Fcb)
121 DPRINT("NpfsDisconnectPipe()\n");
123 if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
124 return(STATUS_SUCCESS);
126 if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
128 Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
129 Fcb->OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
131 /* FIXME: remove data queue(s) */
133 Fcb->OtherSide->OtherSide = NULL;
134 Fcb->OtherSide = NULL;
136 DPRINT("Pipe disconnected\n");
137 return(STATUS_SUCCESS);
140 if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
142 Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
144 /* FIXME: remove data queue(s) */
146 DPRINT("Pipe disconnected\n");
147 return(STATUS_SUCCESS);
150 return(STATUS_UNSUCCESSFUL);
155 NpfsWaitPipe(PIRP Irp,
159 PLIST_ENTRY current_entry;
161 PNPFS_WAIT_PIPE WaitPipe;
164 DPRINT("NpfsWaitPipe\n");
166 WaitPipe = (PNPFS_WAIT_PIPE)Irp->AssociatedIrp.SystemBuffer;
169 /* search for listening server */
170 current_entry = Pipe->ServerFcbListHead.Flink;
171 while (current_entry != &Pipe->ServerFcbListHead)
173 ServerFcb = CONTAINING_RECORD(current_entry,
177 if (ServerFcb->PipeState == FILE_PIPE_LISTENING_STATE)
180 current_entry = current_entry->Flink;
183 if (current_entry != &Pipe->ServerFcbListHead)
185 /* found a listening server fcb */
186 DPRINT("Listening server fcb found -- connecting\n");
188 Status = STATUS_SUCCESS;
192 /* no listening server fcb found -- wait for one */
193 Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
195 Status = KeWaitForSingleObject(&Fcb->ConnectEvent,
209 PIO_STACK_LOCATION IrpSp)
211 * FUNCTION: Return current state of a pipe
213 * Irp = Pointer to I/O request packet
214 * IrpSp = Pointer to current stack location of Irp
216 * Status of operation
219 ULONG OutputBufferLength;
220 PNPFS_GET_STATE Reply;
225 OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
227 /* Validate parameters */
228 if (OutputBufferLength >= sizeof(NPFS_GET_STATE))
230 Fcb = IrpSp->FileObject->FsContext;
231 Reply = (PNPFS_GET_STATE)Irp->AssociatedIrp.SystemBuffer;
234 if (Pipe->PipeWriteMode == FILE_PIPE_MESSAGE_MODE)
236 Reply->WriteModeMessage = TRUE;
240 Reply->WriteModeMessage = FALSE;
243 if (Pipe->PipeReadMode == FILE_PIPE_MESSAGE_MODE)
245 Reply->ReadModeMessage = TRUE;
249 Reply->ReadModeMessage = FALSE;
252 if (Pipe->PipeBlockMode == FILE_PIPE_QUEUE_OPERATION)
254 Reply->NonBlocking = TRUE;
258 Reply->NonBlocking = FALSE;
261 Reply->InBufferSize = Pipe->InboundQuota;
263 Reply->OutBufferSize = Pipe->OutboundQuota;
265 Reply->Timeout = Pipe->TimeOut;
267 Status = STATUS_SUCCESS;
271 Status = STATUS_INVALID_PARAMETER;
274 DPRINT("Status (0x%X).\n", Status);
283 PIO_STACK_LOCATION IrpSp)
285 * FUNCTION: Set state of a pipe
287 * Irp = Pointer to I/O request packet
288 * IrpSp = Pointer to current stack location of Irp
290 * Status of operation
293 ULONG InputBufferLength;
294 PNPFS_SET_STATE Request;
299 InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
301 /* Validate parameters */
302 if (InputBufferLength >= sizeof(NPFS_SET_STATE))
304 Fcb = IrpSp->FileObject->FsContext;
305 Request = (PNPFS_SET_STATE)Irp->AssociatedIrp.SystemBuffer;
308 if (Request->WriteModeMessage)
310 Pipe->PipeWriteMode = FILE_PIPE_MESSAGE_MODE;
314 Pipe->PipeWriteMode = FILE_PIPE_BYTE_STREAM_MODE;
317 if (Request->ReadModeMessage)
319 Pipe->PipeReadMode = FILE_PIPE_MESSAGE_MODE;
323 Pipe->PipeReadMode = FILE_PIPE_BYTE_STREAM_MODE;
326 if (Request->NonBlocking)
328 Pipe->PipeBlockMode = FILE_PIPE_QUEUE_OPERATION;
332 Pipe->PipeBlockMode = FILE_PIPE_COMPLETE_OPERATION;
335 Pipe->InboundQuota = Request->InBufferSize;
337 Pipe->OutboundQuota = Request->OutBufferSize;
339 Pipe->TimeOut = Request->Timeout;
341 Status = STATUS_SUCCESS;
345 Status = STATUS_INVALID_PARAMETER;
348 DPRINT("Status (0x%X).\n", Status);
355 NpfsPeekPipe(PIRP Irp,
356 PIO_STACK_LOCATION IoStack)
358 * FUNCTION: Peek at a pipe (get information about messages)
360 * Irp = Pointer to I/O request packet
361 * IoStack = Pointer to current stack location of Irp
363 * Status of operation
366 ULONG OutputBufferLength;
368 PFILE_PIPE_PEEK_BUFFER Reply;
372 DPRINT("NpfsPeekPipe\n");
374 OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
376 /* Validate parameters */
377 if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
379 DPRINT("Buffer too small\n");
380 return(STATUS_INVALID_PARAMETER);
383 Fcb = IoStack->FileObject->FsContext;
384 Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
387 Status = STATUS_NOT_IMPLEMENTED;
395 NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
398 PEXTENDED_IO_STACK_LOCATION IoStack;
399 PFILE_OBJECT FileObject;
401 PNPFS_DEVICE_EXTENSION DeviceExt;
405 DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
407 DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
408 IoStack = (PEXTENDED_IO_STACK_LOCATION) IoGetCurrentIrpStackLocation(Irp);
409 DPRINT("IoStack: %p\n", IoStack);
410 FileObject = IoStack->FileObject;
411 DPRINT("FileObject: %p\n", FileObject);
412 Fcb = FileObject->FsContext;
413 DPRINT("Fcb: %p\n", Fcb);
415 DPRINT("Pipe: %p\n", Pipe);
416 DPRINT("PipeName: %wZ\n", &Pipe->PipeName);
418 switch (IoStack->Parameters.FileSystemControl.FsControlCode)
420 case FSCTL_PIPE_ASSIGN_EVENT:
421 DPRINT("Assign event\n");
422 Status = STATUS_NOT_IMPLEMENTED;
425 case FSCTL_PIPE_DISCONNECT:
426 DPRINT("Disconnecting pipe %wZ\n", &Pipe->PipeName);
427 Status = NpfsDisconnectPipe(Fcb);
430 case FSCTL_PIPE_LISTEN:
431 DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
432 Status = NpfsConnectPipe(Fcb);
435 case FSCTL_PIPE_PEEK:
436 DPRINT("Peeking pipe %wZ\n", &Pipe->PipeName);
437 Status = NpfsPeekPipe(Irp, IoStack);
440 case FSCTL_PIPE_QUERY_EVENT:
441 DPRINT("Query event\n");
442 Status = STATUS_NOT_IMPLEMENTED;
445 case FSCTL_PIPE_TRANSCEIVE:
446 DPRINT("Transceive\n");
447 Status = STATUS_NOT_IMPLEMENTED;
450 case FSCTL_PIPE_WAIT:
451 DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
452 Status = NpfsWaitPipe(Irp, Fcb);
455 case FSCTL_PIPE_IMPERSONATE:
456 DPRINT("Impersonate\n");
457 Status = STATUS_NOT_IMPLEMENTED;
460 case FSCTL_PIPE_SET_CLIENT_PROCESS:
461 DPRINT("Set client process\n");
462 Status = STATUS_NOT_IMPLEMENTED;
465 case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
466 DPRINT("Query client process\n");
467 Status = STATUS_NOT_IMPLEMENTED;
470 case FSCTL_PIPE_GET_STATE:
471 DPRINT("Get state\n");
472 Status = NpfsGetState(Irp, IoStack);
475 case FSCTL_PIPE_SET_STATE:
476 DPRINT("Set state\n");
477 Status = NpfsSetState(Irp, IoStack);
480 case FSCTL_PIPE_INTERNAL_READ:
481 DPRINT("Internal read\n");
482 Status = STATUS_NOT_IMPLEMENTED;
485 case FSCTL_PIPE_INTERNAL_WRITE:
486 DPRINT("Internal write\n");
487 Status = STATUS_NOT_IMPLEMENTED;
490 case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
491 DPRINT("Internal transceive\n");
492 Status = STATUS_NOT_IMPLEMENTED;
495 case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
496 DPRINT("Internal read overflow\n");
497 Status = STATUS_NOT_IMPLEMENTED;
501 DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode)
502 Status = STATUS_UNSUCCESSFUL;
505 Irp->IoStatus.Status = Status;
506 Irp->IoStatus.Information = 0;
508 IoCompleteRequest(Irp, IO_NO_INCREMENT);