Implemented read/write.

svn path=/trunk/; revision=2383
This commit is contained in:
Eric Kohl 2001-11-20 20:35:10 +00:00
parent 229104bb31
commit 5f56974966
8 changed files with 617 additions and 347 deletions

View file

@ -1,4 +1,4 @@
/* $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
@ -53,6 +53,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT("No memory!\n");
return(STATUS_NO_MEMORY);
}
@ -96,10 +97,18 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
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);
@ -108,7 +117,8 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
KeUnlockMutex(&DeviceExt->PipeListLock);
if (Disposition == FILE_OPEN)
#if 0
if (Disposition == OPEN_EXISTING)
{
/* do not connect to listening servers */
FileObject->FsContext = ClientFcb;
@ -117,9 +127,11 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
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;
@ -167,6 +179,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT("Success!\n");
return(STATUS_SUCCESS);
}
@ -238,11 +251,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
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;
@ -294,13 +302,20 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
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;

View file

@ -1,4 +1,4 @@
/* $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
@ -12,7 +12,7 @@
#include <ddk/ntddk.h>
#include "npfs.h"
//#define NDEBUG
#define NDEBUG
#include <debug.h>
@ -21,14 +21,37 @@
/* 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;
@ -64,63 +87,66 @@ NTSTATUS STDCALL
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:
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 = NpfsQueryLocalPipeInformation(DeviceObject,
Fcb,
SystemBuffer,
&BufferLength);
break;
case FilePipeRemoteInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
case FilePipeLocalInformation:
Status = NpfsQueryLocalInformation(DeviceObject,
Fcb,
SystemBuffer,
&BufferLength);
break;
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);
}
@ -128,52 +154,52 @@ NTSTATUS STDCALL
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 */

View file

@ -1,4 +1,4 @@
/* $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
@ -351,123 +351,163 @@ NpfsSetState(
}
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 */

View file

@ -1,4 +1,4 @@
/* $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
@ -30,7 +30,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
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;
@ -70,6 +69,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
return(Status);
}
/* initialize the device object */
DeviceObject->Flags = DO_DIRECT_IO;
/* initialize the device extension */
DeviceExtension = DeviceObject->DeviceExtension;
InitializeListHead(&DeviceExtension->PipeListHead);

View file

@ -4,8 +4,8 @@
typedef struct
{
LIST_ENTRY PipeListHead;
KMUTEX PipeListLock;
LIST_ENTRY PipeListHead;
KMUTEX PipeListLock;
} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
typedef struct
@ -18,40 +18,38 @@ 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;

View file

@ -1,4 +1,4 @@
/* $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
@ -18,30 +18,29 @@
/* 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;
@ -90,93 +89,134 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
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;
ReadFcb = Fcb->OtherSide;
if (ReadFcb == NULL)
{
DPRINT("Pipe is NOT connected!\n");
Status = STATUS_UNSUCCESSFUL;
Length = 0;
goto done;
}
if (Irp->MdlAddress == NULL)
{
DPRINT("Irp->MdlAddress == NULL\n");
Status = STATUS_UNSUCCESSFUL;
Length = 0;
goto done;
}
Status = STATUS_SUCCESS;
Length = IoStack->Parameters.Read.Length;
DPRINT("Irp->MdlAddress %p\n", Irp->MdlAddress);
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
KeAcquireSpinLock(&Pipe->ServerDataListLock, &OldIrql);
DPRINT("Length %d Buffer %x\n",Length,Buffer);
KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
DataListEmpty = IsListEmpty(&ReadFcb->DataListHead);
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
/* 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);
}
KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
if (Pipe->PipeReadMode & FILE_PIPE_BYTE_STREAM_MODE)
{
DPRINT("Byte stream mode\n");
/* Byte stream mode */
Information = 0;
CurrentEntry = Pipe->ServerDataListHead.Flink;
while ((Length > 0) && (CurrentEntry = RemoveHeadList(&Pipe->ServerDataListHead)))
{
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 != &Pipe->ServerDataListHead) && (Current->Offset != Current->Size))
{
DPRINT("Putting pipe data at %p back in queue\n", Current);
DPRINT("Byte stream mode\n");
/* The caller's buffer could not contain the complete message,
so put it back on the queue */
InsertHeadList(&Pipe->ServerDataListHead, &Current->ListEntry);
/* 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);
}
@ -207,26 +247,46 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
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);
{
DPRINT("Attaching pipe data at %p (%d bytes)\n", PipeData, Length);
KeAcquireSpinLock(&Pipe->ServerDataListLock, &OldIrql);
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
InsertTailList(&Fcb->DataListHead, &PipeData->ListEntry);
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
InsertTailList(&Pipe->ServerDataListHead, &PipeData->ListEntry);
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;

View file

@ -159,6 +159,14 @@ typedef struct _NPFS_GET_STATE
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

View file

@ -1,4 +1,4 @@
/* $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
@ -441,7 +441,7 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
}
WINBOOL STDCALL
BOOL STDCALL
CallNamedPipeA(LPCSTR lpNamedPipeName,
LPVOID lpInBuffer,
DWORD nInBufferSize,
@ -450,12 +450,27 @@ CallNamedPipeA(LPCSTR lpNamedPipeName,
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,
@ -464,45 +479,45 @@ CallNamedPipeW(LPCWSTR lpNamedPipeName,
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);
}
@ -515,8 +530,46 @@ GetNamedPipeHandleStateW(HANDLE hNamedPipe,
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);
}
@ -580,7 +633,7 @@ GetNamedPipeInfo(HANDLE hNamedPipe,
}
WINBOOL STDCALL
BOOL STDCALL
PeekNamedPipe(HANDLE hNamedPipe,
LPVOID lpBuffer,
DWORD nBufferSize,
@ -588,12 +641,80 @@ PeekNamedPipe(HANDLE hNamedPipe,
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,