Modified reading of pipes.

Fixed some bugs.

svn path=/trunk/; revision=2936
This commit is contained in:
Hartmut Birr 2002-05-07 22:41:22 +00:00
parent 311a376750
commit 0ef49e3484
2 changed files with 107 additions and 84 deletions

View file

@ -1,3 +1,5 @@
/* $Id: npfs.h,v 1.11 2002/05/07 22:41:22 hbirr Exp $ */
#ifndef __SERVICES_FS_NP_NPFS_H #ifndef __SERVICES_FS_NP_NPFS_H
#define __SERVICES_FS_NP_NPFS_H #define __SERVICES_FS_NP_NPFS_H
@ -66,6 +68,17 @@ extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
#define CP DPRINT("\n"); #define CP DPRINT("\n");
static inline VOID
NpfsFreePipeData(PNPFS_PIPE_DATA PipeData)
{
if (PipeData->Data)
{
ExFreePool(PipeData->Data);
}
ExFreeToNPagedLookasideList(&NpfsPipeDataLookasideList, PipeData);
}
NTSTATUS STDCALL NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS STDCALL NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS STDCALL NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS STDCALL NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);

View file

@ -1,4 +1,4 @@
/* $Id: rw.c,v 1.5 2001/11/20 20:34:29 ekohl Exp $ /* $Id: rw.c,v 1.6 2002/05/07 22:41:22 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -18,18 +18,6 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static inline VOID
NpfsFreePipeData(PNPFS_PIPE_DATA PipeData)
{
if (PipeData->Data)
{
ExFreePool(PipeData->Data);
}
ExFreeToNPagedLookasideList(&NpfsPipeDataLookasideList, PipeData);
}
static inline PNPFS_PIPE_DATA static inline PNPFS_PIPE_DATA
NpfsAllocatePipeData(PVOID Data, NpfsAllocatePipeData(PVOID Data,
ULONG Size) ULONG Size)
@ -94,7 +82,6 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
ULONG Length; ULONG Length;
PVOID Buffer; PVOID Buffer;
ULONG CopyLength; ULONG CopyLength;
BOOLEAN DataListEmpty;
DPRINT("NpfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DPRINT("NpfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
@ -109,7 +96,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ {
DPRINT("Pipe is NOT connected!\n"); DPRINT("Pipe is NOT connected!\n");
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
Length = 0; Information = 0;
goto done; goto done;
} }
@ -117,51 +104,62 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ {
DPRINT("Irp->MdlAddress == NULL\n"); DPRINT("Irp->MdlAddress == NULL\n");
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
Length = 0; Information = 0;
goto done; goto done;
} }
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
Length = IoStack->Parameters.Read.Length; Length = IoStack->Parameters.Read.Length;
Information = 0;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
DPRINT("Length %d Buffer %x\n",Length,Buffer); DPRINT("Length %d Buffer %x\n",Length,Buffer);
KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql); KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
DataListEmpty = IsListEmpty(&ReadFcb->DataListHead); while (1)
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
/* FIXME: check if in blocking mode */
if (DataListEmpty == TRUE)
{ {
/* FIXME: check if in blocking mode */
if (IsListEmpty(&ReadFcb->DataListHead))
{
KeResetEvent(&Fcb->ReadEvent);
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
if (Information > 0)
{
Status = STATUS_SUCCESS;
goto done;
}
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
{
Status = STATUS_PIPE_BROKEN;
goto done;
}
/* Wait for ReadEvent to become signaled */ /* Wait for ReadEvent to become signaled */
DPRINT("Waiting for readable data\n"); DPRINT("Waiting for readable data (%S)\n", Pipe->PipeName.Buffer);
Status = KeWaitForSingleObject(&Fcb->ReadEvent, Status = KeWaitForSingleObject(&Fcb->ReadEvent,
UserRequest, UserRequest,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
DPRINT("Finished waiting! Status: %x\n", Status); DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status);
KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
} }
KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql); if (Pipe->PipeReadMode == FILE_PIPE_BYTE_STREAM_MODE)
if (Pipe->PipeReadMode & FILE_PIPE_BYTE_STREAM_MODE)
{ {
DPRINT("Byte stream mode\n"); DPRINT("Byte stream mode\n");
/* Byte stream mode */ /* Byte stream mode */
Information = 0; CurrentEntry = NULL;
CurrentEntry = ReadFcb->DataListHead.Flink; while (Length > 0 && !IsListEmpty(&ReadFcb->DataListHead))
while ((Length > 0) && (CurrentEntry = RemoveHeadList(&ReadFcb->DataListHead)))
{ {
CurrentEntry = RemoveHeadList(&ReadFcb->DataListHead);
Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry); 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);
CopyLength = RtlMin(Current->Size, Length); CopyLength = RtlMin(Current->Size, Length);
RtlCopyMemory(Buffer, RtlCopyMemory(Buffer,
((PVOID)((ULONG_PTR)Current->Data + Current->Offset)), ((PVOID)((PVOID)Current->Data + Current->Offset)),
CopyLength); CopyLength);
Buffer += CopyLength; Buffer += CopyLength;
Length -= CopyLength; Length -= CopyLength;
@ -170,11 +168,14 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/* Update the data buffer */ /* Update the data buffer */
Current->Offset += CopyLength; Current->Offset += CopyLength;
Current->Size -= CopyLength; Current->Size -= CopyLength;
if (Current->Size == 0)
CurrentEntry = CurrentEntry->Flink; {
NpfsFreePipeData(Current);
CurrentEntry = NULL;
}
} }
if ((CurrentEntry != &ReadFcb->DataListHead) && (Current->Offset != Current->Size)) if (CurrentEntry && Current->Size > 0)
{ {
DPRINT("Putting pipe data at %p back in queue\n", Current); DPRINT("Putting pipe data at %p back in queue\n", Current);
@ -182,15 +183,20 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
so put it back on the queue */ so put it back on the queue */
InsertHeadList(&ReadFcb->DataListHead, &Current->ListEntry); InsertHeadList(&ReadFcb->DataListHead, &Current->ListEntry);
} }
if (Length == 0)
{
break;
}
} }
else else
{ {
DPRINT("Message mode\n"); DPRINT("Message mode\n");
/* Message mode */ /* Message mode */
CurrentEntry = ReadFcb->DataListHead.Flink; if (!IsListEmpty(&ReadFcb->DataListHead))
if (CurrentEntry = RemoveHeadList(&ReadFcb->DataListHead))
{ {
CurrentEntry = RemoveHeadList(&ReadFcb->DataListHead);
Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry); 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);
@ -201,15 +207,17 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Information = CopyLength; Information = CopyLength;
Current->Offset += CopyLength; Current->Offset += CopyLength;
NpfsFreePipeData(Current);
CurrentEntry = CurrentEntry->Flink; }
if (Information > 0)
{
break;
} }
} }
}
/* reset ReaderEvent */
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql); KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
/* reset ReaderEvent */
KeResetEvent(&Fcb->ReadEvent);
done: done:
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
@ -275,10 +283,12 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql); KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
InsertTailList(&Fcb->DataListHead, &PipeData->ListEntry); InsertTailList(&Fcb->DataListHead, &PipeData->ListEntry);
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
/* signal the readers ReadEvent */ /* signal the readers ReadEvent */
KeSetEvent(&Fcb->OtherSide->ConnectEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&Fcb->OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
} }
else else
{ {