-/* $Id: create.c,v 1.10 2001/10/21 18:58:31 chorns Exp $
+/* $Id: create.c,v 1.11 2001/11/20 20:34:29 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ DPRINT("No memory!\n");
return(STATUS_NO_MEMORY);
}
ClientFcb->OtherSide = NULL;
ClientFcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+ /* initialize data list */
+ InitializeListHead(&ClientFcb->DataListHead);
+ KeInitializeSpinLock(&ClientFcb->DataListLock);
+
KeInitializeEvent(&ClientFcb->ConnectEvent,
SynchronizationEvent,
FALSE);
+ KeInitializeEvent(&ClientFcb->ReadEvent,
+ SynchronizationEvent,
+ FALSE);
+
KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
InsertTailList(&Pipe->ClientFcbListHead, &ClientFcb->FcbListEntry);
KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
KeUnlockMutex(&DeviceExt->PipeListLock);
- if (Disposition == FILE_OPEN)
+#if 0
+ if (Disposition == OPEN_EXISTING)
{
/* do not connect to listening servers */
FileObject->FsContext = ClientFcb;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ DPRINT("Success!\n");
return(STATUS_SUCCESS);
}
+#endif
/* search for disconnected or listening server fcb */
current_entry = Pipe->ServerFcbListHead.Flink;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ DPRINT("Success!\n");
return(STATUS_SUCCESS);
}
InitializeListHead(&Pipe->ClientFcbListHead);
KeInitializeSpinLock(&Pipe->FcbListLock);
- InitializeListHead(&Pipe->ServerDataListHead);
- KeInitializeSpinLock(&Pipe->ServerDataListLock);
- InitializeListHead(&Pipe->ClientDataListHead);
- KeInitializeSpinLock(&Pipe->ClientDataListLock);
-
Pipe->PipeType = Buffer->WriteModeMessage;
Pipe->PipeWriteMode = Buffer->WriteModeMessage;
Pipe->PipeReadMode = Buffer->ReadModeMessage;
Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
Fcb->ReadDataAvailable = 0;
Fcb->WriteQuotaAvailable = 0;
-// Fcb->InBuffer = NULL;
-// Fcb->OutBuffer = NULL;
+
+ /* initialize data list */
+ InitializeListHead(&Fcb->DataListHead);
+ KeInitializeSpinLock(&Fcb->DataListLock);
KeInitializeEvent(&Fcb->ConnectEvent,
SynchronizationEvent,
FALSE);
+ KeInitializeEvent(&Fcb->ReadEvent,
+ SynchronizationEvent,
+ FALSE);
+
+
KeUnlockMutex(&DeviceExt->PipeListLock);
FileObject->FsContext = Fcb;
-/* $Id: finfo.c,v 1.2 2001/07/29 16:40:20 ekohl Exp $
+/* $Id: finfo.c,v 1.3 2001/11/20 20:34:29 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
#include <ddk/ntddk.h>
#include "npfs.h"
-//#define NDEBUG
+#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
static NTSTATUS
-NpfsQueryLocalInformation(PDEVICE_OBJECT DeviceObject,
- PNPFS_FCB Fcb,
- PFILE_PIPE_LOCAL_INFORMATION Info,
- PULONG BufferLength)
+NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
+ PNPFS_FCB Fcb,
+ PFILE_PIPE_INFORMATION Info,
+ PULONG BufferLength)
{
PNPFS_PIPE Pipe;
- DPRINT("NpfsQueryLocalInformation()\n");
+ DPRINT("NpfsQueryPipeInformation()\n");
+
+ Pipe = Fcb->Pipe;
+
+ RtlZeroMemory(Info,
+ sizeof(FILE_PIPE_INFORMATION));
+
+// Info->PipeMode =
+// Info->CompletionMode =
+
+ *BufferLength -= sizeof(FILE_PIPE_INFORMATION);
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject,
+ PNPFS_FCB Fcb,
+ PFILE_PIPE_LOCAL_INFORMATION Info,
+ PULONG BufferLength)
+{
+ PNPFS_PIPE Pipe;
+
+ DPRINT("NpfsQueryLocalPipeInformation()\n");
Pipe = Fcb->Pipe;
NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PIO_STACK_LOCATION IoStack;
- FILE_INFORMATION_CLASS FileInformationClass;
- PFILE_OBJECT FileObject;
- PNPFS_DEVICE_EXTENSION DeviceExtension;
- PNPFS_FCB Fcb;
- PNPFS_PIPE Pipe;
- PVOID SystemBuffer;
- ULONG BufferLength;
- NTSTATUS Status;
-
- DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
-
- IoStack = IoGetCurrentIrpStackLocation (Irp);
- FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
- DeviceExtension = DeviceObject->DeviceExtension;
- FileObject = IoStack->FileObject;
- Fcb = (PNPFS_FCB)FileObject->FsContext;
- Pipe = Fcb->Pipe;
-
- SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
- BufferLength = IoStack->Parameters.QueryFile.Length;
-
- DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
- DPRINT("FileInformationClass %d\n", FileInformationClass);
- DPRINT("SystemBuffer %x\n", SystemBuffer);
- DPRINT("BufferLength %lu\n", BufferLength);
-
- switch (FileInformationClass)
- {
- case FilePipeInformation:
- Status = STATUS_NOT_IMPLEMENTED;
+ PIO_STACK_LOCATION IoStack;
+ FILE_INFORMATION_CLASS FileInformationClass;
+ PFILE_OBJECT FileObject;
+ PNPFS_DEVICE_EXTENSION DeviceExtension;
+ PNPFS_FCB Fcb;
+ PNPFS_PIPE Pipe;
+ PVOID SystemBuffer;
+ ULONG BufferLength;
+ NTSTATUS Status;
+
+ DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+
+ IoStack = IoGetCurrentIrpStackLocation (Irp);
+ FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
+ DeviceExtension = DeviceObject->DeviceExtension;
+ FileObject = IoStack->FileObject;
+ Fcb = (PNPFS_FCB)FileObject->FsContext;
+ Pipe = Fcb->Pipe;
+
+ SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+ BufferLength = IoStack->Parameters.QueryFile.Length;
+
+ DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
+ DPRINT("FileInformationClass %d\n", FileInformationClass);
+ DPRINT("SystemBuffer %p\n", SystemBuffer);
+ DPRINT("BufferLength %lu\n", BufferLength);
+
+ switch (FileInformationClass)
+ {
+ case FilePipeInformation:
+ Status = NpfsQueryPipeInformation(DeviceObject,
+ Fcb,
+ SystemBuffer,
+ &BufferLength);
break;
- case FilePipeLocalInformation:
- Status = NpfsQueryLocalInformation(DeviceObject,
- Fcb,
- SystemBuffer,
- &BufferLength);
+ case FilePipeLocalInformation:
+ Status = NpfsQueryLocalPipeInformation(DeviceObject,
+ Fcb,
+ SystemBuffer,
+ &BufferLength);
break;
- case FilePipeRemoteInformation:
+ case FilePipeRemoteInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
- default:
+ default:
Status = STATUS_NOT_SUPPORTED;
- }
-
- Irp->IoStatus.Status = Status;
- if (NT_SUCCESS(Status))
- Irp->IoStatus.Information =
- IoStack->Parameters.QueryFile.Length - BufferLength;
- else
- Irp->IoStatus.Information = 0;
- IoCompleteRequest (Irp, IO_NO_INCREMENT);
-
- return(Status);
+ }
+
+ Irp->IoStatus.Status = Status;
+ if (NT_SUCCESS(Status))
+ Irp->IoStatus.Information =
+ IoStack->Parameters.QueryFile.Length - BufferLength;
+ else
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+
+ return(Status);
}
NpfsSetInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PIO_STACK_LOCATION IoStack;
- FILE_INFORMATION_CLASS FileInformationClass;
- PFILE_OBJECT FileObject;
- PNPFS_FCB Fcb;
- PNPFS_PIPE Pipe;
- PVOID SystemBuffer;
- ULONG BufferLength;
- NTSTATUS Status;
-
- DPRINT("NpfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
-
- IoStack = IoGetCurrentIrpStackLocation (Irp);
- FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
- FileObject = IoStack->FileObject;
- Fcb = (PNPFS_FCB)FileObject->FsContext;
- Pipe = Fcb->Pipe;
-
- SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
- BufferLength = IoStack->Parameters.QueryFile.Length;
-
- DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
- DPRINT("FileInformationClass %d\n", FileInformationClass);
- DPRINT("SystemBuffer %x\n", SystemBuffer);
- DPRINT("BufferLength %lu\n", BufferLength);
-
- switch (FileInformationClass)
- {
- case FilePipeInformation:
+ PIO_STACK_LOCATION IoStack;
+ FILE_INFORMATION_CLASS FileInformationClass;
+ PFILE_OBJECT FileObject;
+ PNPFS_FCB Fcb;
+ PNPFS_PIPE Pipe;
+ PVOID SystemBuffer;
+ ULONG BufferLength;
+ NTSTATUS Status;
+
+ DPRINT("NpfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+
+ IoStack = IoGetCurrentIrpStackLocation (Irp);
+ FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
+ FileObject = IoStack->FileObject;
+ Fcb = (PNPFS_FCB)FileObject->FsContext;
+ Pipe = Fcb->Pipe;
+
+ SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+ BufferLength = IoStack->Parameters.QueryFile.Length;
+
+ DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
+ DPRINT("FileInformationClass %d\n", FileInformationClass);
+ DPRINT("SystemBuffer %p\n", SystemBuffer);
+ DPRINT("BufferLength %lu\n", BufferLength);
+
+ switch (FileInformationClass)
+ {
+ case FilePipeInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
- case FilePipeLocalInformation:
+ case FilePipeLocalInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
- case FilePipeRemoteInformation:
+ case FilePipeRemoteInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
- default:
+ default:
Status = STATUS_NOT_SUPPORTED;
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
-
- return(Status);
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp,
+ IO_NO_INCREMENT);
+
+ return(Status);
}
/* EOF */
-/* $Id: fsctrl.c,v 1.7 2001/10/21 18:58:31 chorns Exp $
+/* $Id: fsctrl.c,v 1.8 2001/11/20 20:34:29 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
}
+static NTSTATUS
+NpfsPeekPipe(PIRP Irp,
+ PIO_STACK_LOCATION IoStack)
+/*
+ * FUNCTION: Peek at a pipe (get information about messages)
+ * ARGUMENTS:
+ * Irp = Pointer to I/O request packet
+ * IoStack = Pointer to current stack location of Irp
+ * RETURNS:
+ * Status of operation
+ */
+{
+ ULONG OutputBufferLength;
+ PNPFS_PIPE Pipe;
+ PFILE_PIPE_PEEK_BUFFER Reply;
+ PNPFS_FCB Fcb;
+ NTSTATUS Status;
+
+ DPRINT("NpfsPeekPipe\n");
+
+ OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
+
+ /* Validate parameters */
+ if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
+ {
+ DPRINT("Buffer too small\n");
+ return(STATUS_INVALID_PARAMETER);
+ }
+
+ Fcb = IoStack->FileObject->FsContext;
+ Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+ Pipe = Fcb->Pipe;
+
+ Status = STATUS_NOT_IMPLEMENTED;
+
+ return(Status);
+}
+
+
+
NTSTATUS STDCALL
NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PIO_STACK_LOCATION IoStack;
- PFILE_OBJECT FileObject;
- NTSTATUS Status;
- PNPFS_DEVICE_EXTENSION DeviceExt;
- PNPFS_PIPE Pipe;
- PNPFS_FCB Fcb;
-
- DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
-
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT("IoStack: %p\n", IoStack);
- FileObject = IoStack->FileObject;
- DPRINT("FileObject: %p\n", FileObject);
- Fcb = FileObject->FsContext;
- DPRINT("Fcb: %p\n", Fcb);
- Pipe = Fcb->Pipe;
- DPRINT("Pipe: %p\n", Pipe);
- DPRINT("PipeName: %wZ\n", &Pipe->PipeName);
-
- switch (IoStack->Parameters.FileSystemControl.IoControlCode)
- {
+ PIO_STACK_LOCATION IoStack;
+ PFILE_OBJECT FileObject;
+ NTSTATUS Status;
+ PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_PIPE Pipe;
+ PNPFS_FCB Fcb;
+
+ DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+
+ DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+ DPRINT("IoStack: %p\n", IoStack);
+ FileObject = IoStack->FileObject;
+ DPRINT("FileObject: %p\n", FileObject);
+ Fcb = FileObject->FsContext;
+ DPRINT("Fcb: %p\n", Fcb);
+ Pipe = Fcb->Pipe;
+ DPRINT("Pipe: %p\n", Pipe);
+ DPRINT("PipeName: %wZ\n", &Pipe->PipeName);
+
+ switch (IoStack->Parameters.FileSystemControl.IoControlCode)
+ {
case FSCTL_PIPE_ASSIGN_EVENT:
- DPRINT("Assign event\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Assign event\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_DISCONNECT:
- DPRINT("Disconnecting pipe %wZ\n", &Pipe->PipeName);
- Status = NpfsDisconnectPipe(Fcb);
- break;
+ DPRINT("Disconnecting pipe %wZ\n", &Pipe->PipeName);
+ Status = NpfsDisconnectPipe(Fcb);
+ break;
case FSCTL_PIPE_LISTEN:
- DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
- Status = NpfsConnectPipe(Fcb);
- break;
+ DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
+ Status = NpfsConnectPipe(Fcb);
+ break;
case FSCTL_PIPE_PEEK:
- DPRINT("Peek\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Peeking pipe %wZ\n", &Pipe->PipeName);
+ Status = NpfsPeekPipe(Irp, IoStack);
+ break;
case FSCTL_PIPE_QUERY_EVENT:
- DPRINT("Query event\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Query event\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_TRANSCEIVE:
- DPRINT("Transceive\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Transceive\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_WAIT:
- DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
- Status = NpfsWaitPipe(Irp, Fcb);
- break;
+ DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
+ Status = NpfsWaitPipe(Irp, Fcb);
+ break;
case FSCTL_PIPE_IMPERSONATE:
- DPRINT("Impersonate\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Impersonate\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_SET_CLIENT_PROCESS:
- DPRINT("Set client process\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Set client process\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
- DPRINT("Query client process\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Query client process\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_GET_STATE:
- DPRINT("Get state\n");
- Status = NpfsGetState(Irp, IoStack);
- break;
+ DPRINT("Get state\n");
+ Status = NpfsGetState(Irp, IoStack);
+ break;
case FSCTL_PIPE_SET_STATE:
- DPRINT("Set state\n");
- Status = NpfsSetState(Irp, IoStack);
- break;
+ DPRINT("Set state\n");
+ Status = NpfsSetState(Irp, IoStack);
+ break;
case FSCTL_PIPE_INTERNAL_READ:
- DPRINT("Internal read\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Internal read\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_INTERNAL_WRITE:
- DPRINT("Internal write\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Internal write\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
- DPRINT("Internal transceive\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Internal transceive\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
- DPRINT("Internal read overflow\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ DPRINT("Internal read overflow\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
default:
- DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode)
- Status = STATUS_UNSUCCESSFUL;
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return(Status);
+ DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode)
+ Status = STATUS_UNSUCCESSFUL;
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(Status);
}
/* EOF */
-/* $Id: npfs.c,v 1.2 2001/10/21 18:58:31 chorns Exp $
+/* $Id: npfs.c,v 1.3 2001/11/20 20:34:29 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
DbgPrint("Named Pipe FSD 0.0.2\n");
- DeviceObject->Flags = 0;
DriverObject->MajorFunction[IRP_MJ_CREATE] = NpfsCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
NpfsCreateNamedPipe;
return(Status);
}
+ /* initialize the device object */
+ DeviceObject->Flags = DO_DIRECT_IO;
+
/* initialize the device extension */
DeviceExtension = DeviceObject->DeviceExtension;
InitializeListHead(&DeviceExtension->PipeListHead);
typedef struct
{
- LIST_ENTRY PipeListHead;
- KMUTEX PipeListLock;
+ LIST_ENTRY PipeListHead;
+ KMUTEX PipeListLock;
} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
typedef struct
typedef struct
{
- UNICODE_STRING PipeName;
- LIST_ENTRY PipeListEntry;
- KSPIN_LOCK FcbListLock;
- LIST_ENTRY ServerFcbListHead;
- LIST_ENTRY ClientFcbListHead;
- /* Server posted data */
- LIST_ENTRY ServerDataListHead;
- KSPIN_LOCK ServerDataListLock;
- /* Client posted data */
- LIST_ENTRY ClientDataListHead;
- KSPIN_LOCK ClientDataListLock;
- ULONG ReferenceCount;
- ULONG PipeType;
- ULONG PipeReadMode;
- ULONG PipeWriteMode;
- ULONG PipeBlockMode;
- ULONG PipeConfiguration;
- ULONG MaximumInstances;
- ULONG CurrentInstances;
- ULONG InboundQuota;
- ULONG OutboundQuota;
- LARGE_INTEGER TimeOut;
+ UNICODE_STRING PipeName;
+ LIST_ENTRY PipeListEntry;
+ KSPIN_LOCK FcbListLock;
+ LIST_ENTRY ServerFcbListHead;
+ LIST_ENTRY ClientFcbListHead;
+ ULONG ReferenceCount;
+ ULONG PipeType;
+ ULONG PipeReadMode;
+ ULONG PipeWriteMode;
+ ULONG PipeBlockMode;
+ ULONG PipeConfiguration;
+ ULONG MaximumInstances;
+ ULONG CurrentInstances;
+ ULONG InboundQuota;
+ ULONG OutboundQuota;
+ LARGE_INTEGER TimeOut;
} NPFS_PIPE, *PNPFS_PIPE;
typedef struct _NPFS_FCB
{
- LIST_ENTRY FcbListEntry;
- struct _NPFS_FCB* OtherSide;
- PNPFS_PIPE Pipe;
- KEVENT ConnectEvent;
- ULONG PipeEnd;
- ULONG PipeState;
- ULONG ReadDataAvailable;
- ULONG WriteQuotaAvailable;
+ LIST_ENTRY FcbListEntry;
+ struct _NPFS_FCB* OtherSide;
+ PNPFS_PIPE Pipe;
+ KEVENT ConnectEvent;
+ KEVENT ReadEvent;
+ ULONG PipeEnd;
+ ULONG PipeState;
+ ULONG ReadDataAvailable;
+ ULONG WriteQuotaAvailable;
+
+ LIST_ENTRY DataListHead; /* Data queue */
+ KSPIN_LOCK DataListLock; /* Data queue lock */
} NPFS_FCB, *PNPFS_FCB;
-/* $Id: rw.c,v 1.4 2001/10/21 18:58:32 chorns Exp $
+/* $Id: rw.c,v 1.5 2001/11/20 20:34:29 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* FUNCTIONS *****************************************************************/
-static inline VOID NpfsFreePipeData(
- PNPFS_PIPE_DATA PipeData)
+static inline VOID
+NpfsFreePipeData(PNPFS_PIPE_DATA PipeData)
{
if (PipeData->Data)
- {
- ExFreePool(PipeData->Data);
- }
+ {
+ ExFreePool(PipeData->Data);
+ }
ExFreeToNPagedLookasideList(&NpfsPipeDataLookasideList, PipeData);
}
static inline PNPFS_PIPE_DATA
-NpfsAllocatePipeData(
- PVOID Data,
- ULONG Size)
+NpfsAllocatePipeData(PVOID Data,
+ ULONG Size)
{
PNPFS_PIPE_DATA PipeData;
PipeData = ExAllocateFromNPagedLookasideList(&NpfsPipeDataLookasideList);
if (!PipeData)
- {
- return NULL;
- }
+ {
+ return NULL;
+ }
PipeData->Data = Data;
PipeData->Size = Size;
PNPFS_PIPE_DATA Current;
ULONG Information;
PNPFS_FCB Fcb;
+ PNPFS_FCB ReadFcb;
PNPFS_PIPE Pipe;
- ULONG Length;
- PVOID Buffer;
+ ULONG Length;
+ PVOID Buffer;
ULONG CopyLength;
+ BOOLEAN DataListEmpty;
DPRINT("NpfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
-
+
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
Fcb = FileObject->FsContext;
Pipe = Fcb->Pipe;
- Status = STATUS_SUCCESS;
- Length = IoStack->Parameters.Read.Length;
+ ReadFcb = Fcb->OtherSide;
- DPRINT("Irp->MdlAddress %p\n", Irp->MdlAddress);
-
- Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
- KeAcquireSpinLock(&Pipe->ServerDataListLock, &OldIrql);
+ if (ReadFcb == NULL)
+ {
+ DPRINT("Pipe is NOT connected!\n");
+ Status = STATUS_UNSUCCESSFUL;
+ Length = 0;
+ goto done;
+ }
- if (Pipe->PipeReadMode & FILE_PIPE_BYTE_STREAM_MODE)
- {
- DPRINT("Byte stream mode\n");
+ if (Irp->MdlAddress == NULL)
+ {
+ DPRINT("Irp->MdlAddress == NULL\n");
+ Status = STATUS_UNSUCCESSFUL;
+ Length = 0;
+ goto done;
+ }
- /* Byte stream mode */
- Information = 0;
- CurrentEntry = Pipe->ServerDataListHead.Flink;
- while ((Length > 0) && (CurrentEntry = RemoveHeadList(&Pipe->ServerDataListHead)))
- {
- Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
+ Status = STATUS_SUCCESS;
+ Length = IoStack->Parameters.Read.Length;
- DPRINT("Took pipe data at %p off the queue\n", Current);
+ Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ DPRINT("Length %d Buffer %x\n",Length,Buffer);
- CopyLength = RtlMin(Current->Size, Length);
- RtlCopyMemory(Buffer,
- ((PVOID)((ULONG_PTR)Current->Data + Current->Offset)),
- CopyLength);
- Buffer += CopyLength;
- Length -= CopyLength;
- Information += CopyLength;
+ KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
+ DataListEmpty = IsListEmpty(&ReadFcb->DataListHead);
+ KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
- /* Update the data buffer */
- Current->Offset += CopyLength;
- Current->Size -= CopyLength;
+ /* FIXME: check if in blocking mode */
+ if (DataListEmpty == TRUE)
+ {
+ /* Wait for ReadEvent to become signaled */
+ DPRINT("Waiting for readable data\n");
+ Status = KeWaitForSingleObject(&Fcb->ReadEvent,
+ UserRequest,
+ KernelMode,
+ FALSE,
+ NULL);
+ DPRINT("Finished waiting! Status: %x\n", Status);
+ }
- CurrentEntry = CurrentEntry->Flink;
- }
+ KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
- if ((CurrentEntry != &Pipe->ServerDataListHead) && (Current->Offset != Current->Size))
+ if (Pipe->PipeReadMode & FILE_PIPE_BYTE_STREAM_MODE)
{
- DPRINT("Putting pipe data at %p back in queue\n", Current);
-
- /* The caller's buffer could not contain the complete message,
- so put it back on the queue */
- InsertHeadList(&Pipe->ServerDataListHead, &Current->ListEntry);
+ DPRINT("Byte stream mode\n");
+
+ /* Byte stream mode */
+ Information = 0;
+ CurrentEntry = ReadFcb->DataListHead.Flink;
+ while ((Length > 0) && (CurrentEntry = RemoveHeadList(&ReadFcb->DataListHead)))
+ {
+ Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
+
+ DPRINT("Took pipe data at %p off the queue\n", Current);
+
+ CopyLength = RtlMin(Current->Size, Length);
+ RtlCopyMemory(Buffer,
+ ((PVOID)((ULONG_PTR)Current->Data + Current->Offset)),
+ CopyLength);
+ Buffer += CopyLength;
+ Length -= CopyLength;
+ Information += CopyLength;
+
+ /* Update the data buffer */
+ Current->Offset += CopyLength;
+ Current->Size -= CopyLength;
+
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ if ((CurrentEntry != &ReadFcb->DataListHead) && (Current->Offset != Current->Size))
+ {
+ DPRINT("Putting pipe data at %p back in queue\n", Current);
+
+ /* The caller's buffer could not contain the complete message,
+ so put it back on the queue */
+ InsertHeadList(&ReadFcb->DataListHead, &Current->ListEntry);
+ }
}
- }
else
- {
- DPRINT("Message mode\n");
+ {
+ DPRINT("Message mode\n");
- /* Message mode */
- CurrentEntry = Pipe->ServerDataListHead.Flink;
- if (CurrentEntry = RemoveHeadList(&Pipe->ServerDataListHead))
- {
- Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
+ /* Message mode */
+ CurrentEntry = ReadFcb->DataListHead.Flink;
+ if (CurrentEntry = RemoveHeadList(&ReadFcb->DataListHead))
+ {
+ Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
- DPRINT("Took pipe data at %p off the queue\n", Current);
+ DPRINT("Took pipe data at %p off the queue\n", Current);
- /* Truncate the message if the receive buffer is too small */
- CopyLength = RtlMin(Current->Size, Length);
- RtlCopyMemory(Buffer, Current->Data, CopyLength);
- Information = CopyLength;
+ /* Truncate the message if the receive buffer is too small */
+ CopyLength = RtlMin(Current->Size, Length);
+ RtlCopyMemory(Buffer, Current->Data, CopyLength);
+ Information = CopyLength;
- Current->Offset += CopyLength;
+ Current->Offset += CopyLength;
- CurrentEntry = CurrentEntry->Flink;
+ CurrentEntry = CurrentEntry->Flink;
+ }
}
- }
- KeReleaseSpinLock(&Pipe->ServerDataListLock, OldIrql);
+ KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
+ /* reset ReaderEvent */
+ KeResetEvent(&Fcb->ReadEvent);
+
+done:
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information;
-
+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+
return(Status);
}
Pipe = Fcb->Pipe;
Length = IoStack->Parameters.Write.Length;
- Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
Offset = IoStack->Parameters.Write.ByteOffset.u.LowPart;
+ if (Irp->MdlAddress == NULL)
+ {
+ DbgPrint ("Irp->MdlAddress == NULL\n");
+ Status = STATUS_UNSUCCESSFUL;
+ Length = 0;
+ goto done;
+ }
+
+ if (Fcb->OtherSide == NULL)
+ {
+ DPRINT("Pipe is NOT connected!\n");
+ Status = STATUS_UNSUCCESSFUL;
+ Length = 0;
+ goto done;
+ }
+
+ Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
+ DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
+
PipeData = NpfsInitializePipeData(Buffer, Length);
if (PipeData)
- {
- DPRINT("Attaching pipe data at %p (%d bytes)\n", PipeData, Length);
-
- KeAcquireSpinLock(&Pipe->ServerDataListLock, &OldIrql);
+ {
+ DPRINT("Attaching pipe data at %p (%d bytes)\n", PipeData, Length);
- InsertTailList(&Pipe->ServerDataListHead, &PipeData->ListEntry);
+ KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
+ InsertTailList(&Fcb->DataListHead, &PipeData->ListEntry);
+ KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
- KeReleaseSpinLock(&Pipe->ServerDataListLock, OldIrql);
- }
+ /* signal the readers ReadEvent */
+ KeSetEvent(&Fcb->OtherSide->ConnectEvent, IO_NO_INCREMENT, FALSE);
+ }
else
- {
- Length = 0;
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
+ {
+ Length = 0;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+done:
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
LARGE_INTEGER Timeout;
} NPFS_GET_STATE, *PNPFS_GET_STATE;
+typedef struct _FILE_PIPE_PEEK_BUFFER
+{
+ ULONG NamedPipeState;
+ ULONG ReadDataAvailable;
+ ULONG NumberOfMessages;
+ ULONG MessageLength;
+ CHAR Data[1];
+} FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER;
#define FILE_PIPE_BYTE_STREAM_TYPE 0x00000000
#define FILE_PIPE_MESSAGE_TYPE 0x00000001
-/* $Id: npipe.c,v 1.8 2001/10/21 19:06:42 chorns Exp $
+/* $Id: npipe.c,v 1.9 2001/11/20 20:35:10 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
}
-WINBOOL STDCALL
+BOOL STDCALL
CallNamedPipeA(LPCSTR lpNamedPipeName,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPDWORD lpBytesRead,
DWORD nTimeOut)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ UNICODE_STRING PipeName;
+ BOOL Result;
+
+ RtlCreateUnicodeStringFromAsciiz(&PipeName,
+ (LPSTR)lpNamedPipeName);
+
+ Result = CallNamedPipeW(PipeName.Buffer,
+ lpInBuffer,
+ nInBufferSize,
+ lpOutBuffer,
+ nOutBufferSize,
+ lpBytesRead,
+ nTimeOut);
+
+ RtlFreeUnicodeString(&PipeName);
+
+ return(Result);
}
-WINBOOL STDCALL
+BOOL STDCALL
CallNamedPipeW(LPCWSTR lpNamedPipeName,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPDWORD lpBytesRead,
DWORD nTimeOut)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
-WINBOOL STDCALL
+BOOL STDCALL
DisconnectNamedPipe(HANDLE hNamedPipe)
{
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
- Status = NtFsControlFile(hNamedPipe,
- NULL,
- NULL,
- NULL,
- &Iosb,
- FSCTL_PIPE_DISCONNECT,
- NULL,
- 0,
- NULL,
- 0);
- if (Status == STATUS_PENDING)
- {
- Status = NtWaitForSingleObject(hNamedPipe,
- FALSE,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- SetLastErrorByStatus(Status);
- return(FALSE);
- }
- }
+ Status = NtFsControlFile(hNamedPipe,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ FSCTL_PIPE_DISCONNECT,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (Status == STATUS_PENDING)
+ {
+ Status = NtWaitForSingleObject(hNamedPipe,
+ FALSE,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+ }
- if (!NT_SUCCESS(Status))
- {
- SetLastErrorByStatus(Status);
- return(FALSE);
- }
- return(TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+ return(TRUE);
}
LPWSTR lpUserName,
DWORD nMaxUserNameSize)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ FILE_PIPE_LOCAL_INFORMATION LocalInfo;
+ FILE_PIPE_INFORMATION PipeInfo;
+ IO_STATUS_BLOCK StatusBlock;
+ NTSTATUS Status;
+
+ if (lpState != NULL)
+ {
+ Status = NtQueryInformationFile(hNamedPipe,
+ &StatusBlock,
+ &PipeInfo,
+ sizeof(FILE_PIPE_INFORMATION),
+ FilePipeInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+ *lpState = 0; /* FIXME */
+ }
+
+ if (lpCurInstances != NULL)
+ {
+ Status = NtQueryInformationFile(hNamedPipe,
+ &StatusBlock,
+ &LocalInfo,
+ sizeof(FILE_PIPE_LOCAL_INFORMATION),
+ FilePipeLocalInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+ *lpCurInstances = min(LocalInfo.CurrentInstances, 255);
+ }
+
+
+ /* FIXME: retrieve remaining information */
+
+
+ return(TRUE);
}
}
-WINBOOL STDCALL
+BOOL STDCALL
PeekNamedPipe(HANDLE hNamedPipe,
LPVOID lpBuffer,
DWORD nBufferSize,
LPDWORD lpTotalBytesAvail,
LPDWORD lpBytesLeftThisMessage)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ PFILE_PIPE_PEEK_BUFFER Buffer;
+ IO_STATUS_BLOCK Iosb;
+ ULONG BufferSize;
+ NTSTATUS Status;
+
+ BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER);
+ Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ BufferSize);
+
+ Status = NtFsControlFile(hNamedPipe,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ FSCTL_PIPE_PEEK,
+ NULL,
+ 0,
+ Buffer,
+ BufferSize);
+ if (Status == STATUS_PENDING)
+ {
+ Status = NtWaitForSingleObject(hNamedPipe,
+ FALSE,
+ NULL);
+ if (NT_SUCCESS(Status))
+ Status = Iosb.Status;
+ }
+
+ if (Status == STATUS_BUFFER_OVERFLOW)
+ {
+ Status = STATUS_SUCCESS;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ Buffer);
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+
+ if (lpTotalBytesAvail != NULL)
+ {
+ *lpTotalBytesAvail = Buffer->ReadDataAvailable;
+ }
+
+ if (lpBytesRead != NULL)
+ {
+ *lpBytesRead = Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER);
+ }
+
+ if (lpBytesLeftThisMessage != NULL)
+ {
+ *lpBytesLeftThisMessage = Buffer->MessageLength -
+ (Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER));
+ }
+
+ if (lpBuffer != NULL)
+ {
+ memcpy(lpBuffer, Buffer->Data,
+ min(nBufferSize, Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER)));
+ }
+
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ Buffer);
+
+ return(TRUE);
}
-WINBOOL STDCALL
+BOOL STDCALL
TransactNamedPipe(HANDLE hNamedPipe,
LPVOID lpInBuffer,
DWORD nInBufferSize,