- Data is now written to the readers data buffer and the reader reads from his own data buffer. This fixes Filip's wrokaround to enable the reader to read data although the writers side was closed.

- Minor cleanup.

svn path=/trunk/; revision=13763
This commit is contained in:
Eric Kohl 2005-02-27 12:43:37 +00:00
parent b6701ec6f9
commit 2f494319c3
7 changed files with 170 additions and 254 deletions

View file

@ -2,7 +2,7 @@
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: services/fs/np/create.c * FILE: drivers/fs/np/create.c
* PURPOSE: Named pipe filesystem * PURPOSE: Named pipe filesystem
* PROGRAMMER: David Welch <welch@cwcom.net> * PROGRAMMER: David Welch <welch@cwcom.net>
*/ */
@ -164,9 +164,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
ClientFcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE; ClientFcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
/* Initialize data list. */ /* Initialize data list. */
if (Pipe->InboundQuota) if (Pipe->OutboundQuota)
{ {
ClientFcb->Data = ExAllocatePool(NonPagedPool, Pipe->InboundQuota); ClientFcb->Data = ExAllocatePool(NonPagedPool, Pipe->OutboundQuota);
if (ClientFcb->Data == NULL) if (ClientFcb->Data == NULL)
{ {
DPRINT("No memory!\n"); DPRINT("No memory!\n");
@ -185,8 +185,8 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
ClientFcb->ReadPtr = ClientFcb->Data; ClientFcb->ReadPtr = ClientFcb->Data;
ClientFcb->WritePtr = ClientFcb->Data; ClientFcb->WritePtr = ClientFcb->Data;
ClientFcb->ReadDataAvailable = 0; ClientFcb->ReadDataAvailable = 0;
ClientFcb->WriteQuotaAvailable = Pipe->InboundQuota; ClientFcb->WriteQuotaAvailable = Pipe->OutboundQuota;
ClientFcb->MaxDataLength = Pipe->InboundQuota; ClientFcb->MaxDataLength = Pipe->OutboundQuota;
KeInitializeSpinLock(&ClientFcb->DataListLock); KeInitializeSpinLock(&ClientFcb->DataListLock);
KeInitializeEvent(&ClientFcb->ConnectEvent, SynchronizationEvent, FALSE); KeInitializeEvent(&ClientFcb->ConnectEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE); KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE);
@ -381,9 +381,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
KeUnlockMutex(&DeviceExt->PipeListLock); KeUnlockMutex(&DeviceExt->PipeListLock);
} }
if (Pipe->OutboundQuota) if (Pipe->InboundQuota)
{ {
Fcb->Data = ExAllocatePool(NonPagedPool, Pipe->OutboundQuota); Fcb->Data = ExAllocatePool(NonPagedPool, Pipe->InboundQuota);
if (Fcb->Data == NULL) if (Fcb->Data == NULL)
{ {
ExFreePool(Fcb); ExFreePool(Fcb);
@ -407,8 +407,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
Fcb->ReadPtr = Fcb->Data; Fcb->ReadPtr = Fcb->Data;
Fcb->WritePtr = Fcb->Data; Fcb->WritePtr = Fcb->Data;
Fcb->ReadDataAvailable = 0; Fcb->ReadDataAvailable = 0;
Fcb->WriteQuotaAvailable = Pipe->OutboundQuota; Fcb->WriteQuotaAvailable = Pipe->InboundQuota;
Fcb->MaxDataLength = Pipe->OutboundQuota; Fcb->MaxDataLength = Pipe->InboundQuota;
KeInitializeSpinLock(&Fcb->DataListLock); KeInitializeSpinLock(&Fcb->DataListLock);
Pipe->CurrentInstances++; Pipe->CurrentInstances++;
@ -442,9 +442,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
NTSTATUS STDCALL NTSTATUS STDCALL
NpfsClose( NpfsClose(PDEVICE_OBJECT DeviceObject,
PDEVICE_OBJECT DeviceObject, PIRP Irp)
PIRP Irp)
{ {
PNPFS_DEVICE_EXTENSION DeviceExt; PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
@ -493,10 +492,8 @@ NpfsClose(
{ {
if (Fcb->OtherSide) if (Fcb->OtherSide)
{ {
#ifndef FIN_WORKAROUND_READCLOSE
Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
Fcb->OtherSide->OtherSide = NULL; Fcb->OtherSide->OtherSide = NULL;
#endif
/* /*
* Signaling the write event. If is possible that an other * Signaling the write event. If is possible that an other
* thread waits for an empty buffer. * thread waits for an empty buffer.
@ -504,39 +501,15 @@ NpfsClose(
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
} }
#ifndef FIN_WORKAROUND_READCLOSE
Fcb->PipeState = 0; Fcb->PipeState = 0;
#endif
} }
FileObject->FsContext = NULL; FileObject->FsContext = NULL;
#ifndef FIN_WORKAROUND_READCLOSE
RemoveEntryList(&Fcb->FcbListEntry); RemoveEntryList(&Fcb->FcbListEntry);
if (Fcb->Data) if (Fcb->Data)
ExFreePool(Fcb->Data); ExFreePool(Fcb->Data);
ExFreePool(Fcb); ExFreePool(Fcb);
#else
Fcb->PipeState = FILE_PIPE_CLOSING_STATE;
if (Fcb->OtherSide == NULL ||
Fcb->OtherSide->PipeState == FILE_PIPE_CLOSING_STATE)
{
if (Server && Fcb->OtherSide != NULL &&
Fcb->OtherSide->PipeState == FILE_PIPE_CLOSING_STATE)
{
RemoveEntryList(&Fcb->OtherSide->FcbListEntry);
if (Fcb->OtherSide->Data)
ExFreePool(Fcb->OtherSide->Data);
ExFreePool(Fcb->OtherSide);
}
RemoveEntryList(&Fcb->FcbListEntry);
if (Fcb->Data)
ExFreePool(Fcb->Data);
ExFreePool(Fcb);
}
#endif
KeUnlockMutex(&Pipe->FcbListLock); KeUnlockMutex(&Pipe->FcbListLock);

View file

@ -2,9 +2,9 @@
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: services/fs/np/finfo.c * FILE: drivers/fs/np/finfo.c
* PURPOSE: Named pipe filesystem * PURPOSE: Named pipe filesystem
* PROGRAMMER: Eric Kohl <ekohl@rz-online.de> * PROGRAMMER: Eric Kohl
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
@ -36,7 +36,7 @@ NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
// Info->CompletionMode = // Info->CompletionMode =
*BufferLength -= sizeof(FILE_PIPE_INFORMATION); *BufferLength -= sizeof(FILE_PIPE_INFORMATION);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
@ -76,7 +76,7 @@ NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject,
} }
*BufferLength -= sizeof(FILE_PIPE_LOCAL_INFORMATION); *BufferLength -= sizeof(FILE_PIPE_LOCAL_INFORMATION);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
@ -93,24 +93,24 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
PVOID SystemBuffer; PVOID SystemBuffer;
ULONG BufferLength; ULONG BufferLength;
NTSTATUS Status; NTSTATUS Status;
DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation (Irp); IoStack = IoGetCurrentIrpStackLocation (Irp);
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass; FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
DeviceExtension = DeviceObject->DeviceExtension; DeviceExtension = DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject; FileObject = IoStack->FileObject;
Fcb = (PNPFS_FCB)FileObject->FsContext; Fcb = (PNPFS_FCB)FileObject->FsContext;
Pipe = Fcb->Pipe; Pipe = Fcb->Pipe;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer; SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = IoStack->Parameters.QueryFile.Length; BufferLength = IoStack->Parameters.QueryFile.Length;
DPRINT("Pipe name: %wZ\n", &Pipe->PipeName); DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
DPRINT("FileInformationClass %d\n", FileInformationClass); DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer); DPRINT("SystemBuffer %p\n", SystemBuffer);
DPRINT("BufferLength %lu\n", BufferLength); DPRINT("BufferLength %lu\n", BufferLength);
switch (FileInformationClass) switch (FileInformationClass)
{ {
case FilePipeInformation: case FilePipeInformation:
@ -134,7 +134,7 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
default: default:
Status = STATUS_NOT_SUPPORTED; Status = STATUS_NOT_SUPPORTED;
} }
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
Irp->IoStatus.Information = Irp->IoStatus.Information =
@ -142,8 +142,8 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
else else
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT); IoCompleteRequest (Irp, IO_NO_INCREMENT);
return(Status); return Status;
} }
@ -196,7 +196,7 @@ NpfsSetInformation(PDEVICE_OBJECT DeviceObject,
IoCompleteRequest(Irp, IoCompleteRequest(Irp,
IO_NO_INCREMENT); IO_NO_INCREMENT);
return(Status); return Status;
} }
/* EOF */ /* EOF */

View file

@ -2,10 +2,10 @@
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: services/fs/np/fsctrl.c * FILE: drivers/fs/np/fsctrl.c
* PURPOSE: Named pipe filesystem * PURPOSE: Named pipe filesystem
* PROGRAMMER: David Welch <welch@cwcom.net> * PROGRAMMER: David Welch <welch@cwcom.net>
* Eric Kohl <ekohl@rz-online.de> * Eric Kohl
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/

View file

@ -2,7 +2,7 @@
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: services/fs/np/mount.c * FILE: drivers/fs/np/mount.c
* PURPOSE: Named pipe filesystem * PURPOSE: Named pipe filesystem
* PROGRAMMER: David Welch <welch@cwcom.net> * PROGRAMMER: David Welch <welch@cwcom.net>
*/ */
@ -64,7 +64,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("Failed to create named pipe device! (Status %x)\n", Status); DPRINT("Failed to create named pipe device! (Status %x)\n", Status);
return(Status); return Status;
} }
/* initialize the device object */ /* initialize the device object */
@ -81,7 +81,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
DeviceExtension->DefaultQuota = 8 * PAGE_SIZE; DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
DeviceExtension->MaxQuota = 64 * PAGE_SIZE; DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
/* EOF */ /* EOF */

View file

@ -1,13 +1,7 @@
/* $Id$ */ /* $Id$ */
#ifndef __SERVICES_FS_NP_NPFS_H #ifndef __DRIVERS_FS_NP_NPFS_H
#define __SERVICES_FS_NP_NPFS_H #define __DRIVERS_FS_NP_NPFS_H
/*
* Hacky support for delayed closing of pipes. We need this to support
* reading from pipe the was closed on one end.
*/
#define FIN_WORKAROUND_READCLOSE
typedef struct _NPFS_DEVICE_EXTENSION typedef struct _NPFS_DEVICE_EXTENSION
{ {
@ -70,8 +64,6 @@ extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
#define KeUnlockMutex(x) KeReleaseMutex(x, FALSE); #define KeUnlockMutex(x) KeReleaseMutex(x, FALSE);
#define CP DPRINT("\n");
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);
@ -89,4 +81,4 @@ NTSTATUS STDCALL NpfsSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS STDCALL NpfsQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS STDCALL NpfsQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp);
#endif /* __SERVICES_FS_NP_NPFS_H */ #endif /* __DRIVERS_FS_NP_NPFS_H */

View file

@ -2,7 +2,7 @@
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: services/fs/np/rw.c * FILE: drivers/fs/np/rw.c
* PURPOSE: Named pipe filesystem * PURPOSE: Named pipe filesystem
* PROGRAMMER: David Welch <welch@cwcom.net> * PROGRAMMER: David Welch <welch@cwcom.net>
*/ */
@ -16,8 +16,6 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#define FIN_WORKAROUND_READCLOSE
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#ifndef NDEBUG #ifndef NDEBUG
@ -60,7 +58,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
KIRQL OldIrql; KIRQL OldIrql;
ULONG Information; ULONG Information;
PNPFS_FCB Fcb; PNPFS_FCB Fcb;
PNPFS_FCB ReadFcb; PNPFS_FCB WriterFcb;
PNPFS_PIPE Pipe; PNPFS_PIPE Pipe;
ULONG Length; ULONG Length;
PVOID Buffer; PVOID Buffer;
@ -74,21 +72,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
FileObject = IoStack->FileObject; FileObject = IoStack->FileObject;
Fcb = FileObject->FsContext; Fcb = FileObject->FsContext;
Pipe = Fcb->Pipe; Pipe = Fcb->Pipe;
ReadFcb = Fcb->OtherSide; WriterFcb = Fcb->OtherSide;
if (ReadFcb == NULL)
{
DPRINT("Pipe is NOT connected!\n");
if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
Status = STATUS_PIPE_LISTENING;
else if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
Status = STATUS_PIPE_DISCONNECTED;
else
Status = STATUS_PIPE_BROKEN;
Information = 0;
DPRINT("%x\n", Status);
goto done;
}
if (Irp->MdlAddress == NULL) if (Irp->MdlAddress == NULL)
{ {
@ -98,7 +82,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
goto done; goto done;
} }
if (ReadFcb->Data == NULL) if (Fcb->Data == NULL)
{ {
DPRINT("Pipe is NOT readable!\n"); DPRINT("Pipe is NOT readable!\n");
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
@ -106,31 +90,20 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
goto done; goto done;
} }
#ifdef FIN_WORKAROUND_READCLOSE
if (ReadFcb->ReadDataAvailable == 0 &&
ReadFcb->PipeState == FILE_PIPE_CLOSING_STATE)
{
DPRINT("Other end of pipe is closed!\n");
Status = STATUS_PIPE_BROKEN;
Information = 0;
goto done;
}
#endif
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
Length = IoStack->Parameters.Read.Length; Length = IoStack->Parameters.Read.Length;
Information = 0; Information = 0;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql); KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
while (1) while (1)
{ {
/* FIXME: check if in blocking mode */ /* FIXME: check if in blocking mode */
if (ReadFcb->ReadDataAvailable == 0) if (Fcb->ReadDataAvailable == 0)
{ {
KeResetEvent(&Fcb->Event); KeResetEvent(&Fcb->Event);
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql); KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
if (Information > 0) if (Information > 0)
{ {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
@ -153,56 +126,44 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
NULL); NULL);
DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status); DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status);
#ifndef FIN_WORKAROUND_READCLOSE KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
/*
* It's possible that the event was signaled because the
* other side of pipe was closed.
*/
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
{
DPRINT("PipeState: %x\n", Fcb->PipeState);
Status = STATUS_PIPE_BROKEN;
goto done;
}
#endif
KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
} }
if (Pipe->ReadMode == FILE_PIPE_BYTE_STREAM_MODE) if (Pipe->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
{ {
DPRINT("Byte stream mode\n"); DPRINT("Byte stream mode\n");
/* Byte stream mode */ /* Byte stream mode */
while (Length > 0 && ReadFcb->ReadDataAvailable > 0) while (Length > 0 && Fcb->ReadDataAvailable > 0)
{ {
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length); CopyLength = RtlRosMin(Fcb->ReadDataAvailable, Length);
if (ReadFcb->ReadPtr + CopyLength <= ReadFcb->Data + ReadFcb->MaxDataLength) if (Fcb->ReadPtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength)
{ {
memcpy(Buffer, ReadFcb->ReadPtr, CopyLength); memcpy(Buffer, Fcb->ReadPtr, CopyLength);
ReadFcb->ReadPtr += CopyLength; Fcb->ReadPtr += CopyLength;
if (ReadFcb->ReadPtr == ReadFcb->Data + ReadFcb->MaxDataLength) if (Fcb->ReadPtr == Fcb->Data + Fcb->MaxDataLength)
{ {
ReadFcb->ReadPtr = ReadFcb->Data; Fcb->ReadPtr = Fcb->Data;
} }
} }
else else
{ {
TempLength = ReadFcb->Data + ReadFcb->MaxDataLength - ReadFcb->ReadPtr; TempLength = Fcb->Data + Fcb->MaxDataLength - Fcb->ReadPtr;
memcpy(Buffer, ReadFcb->ReadPtr, TempLength); memcpy(Buffer, Fcb->ReadPtr, TempLength);
memcpy(Buffer + TempLength, ReadFcb->Data, CopyLength - TempLength); memcpy(Buffer + TempLength, Fcb->Data, CopyLength - TempLength);
ReadFcb->ReadPtr = ReadFcb->Data + CopyLength - TempLength; Fcb->ReadPtr = Fcb->Data + CopyLength - TempLength;
} }
Buffer += CopyLength; Buffer += CopyLength;
Length -= CopyLength; Length -= CopyLength;
Information += CopyLength; Information += CopyLength;
ReadFcb->ReadDataAvailable -= CopyLength; Fcb->ReadDataAvailable -= CopyLength;
ReadFcb->WriteQuotaAvailable += CopyLength; Fcb->WriteQuotaAvailable += CopyLength;
} }
if (Length == 0) if (Length == 0)
{ {
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
break; break;
} }
} }
@ -211,11 +172,11 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
DPRINT("Message mode\n"); DPRINT("Message mode\n");
/* Message mode */ /* Message mode */
if (ReadFcb->ReadDataAvailable) if (Fcb->ReadDataAvailable)
{ {
/* Truncate the message if the receive buffer is too small */ /* Truncate the message if the receive buffer is too small */
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length); CopyLength = RtlRosMin(Fcb->ReadDataAvailable, Length);
memcpy(Buffer, ReadFcb->Data, CopyLength); memcpy(Buffer, Fcb->Data, CopyLength);
#ifndef NDEBUG #ifndef NDEBUG
DPRINT("Length %d Buffer %x\n",CopyLength,Buffer); DPRINT("Length %d Buffer %x\n",CopyLength,Buffer);
@ -223,28 +184,19 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
#endif #endif
Information = CopyLength; Information = CopyLength;
ReadFcb->ReadDataAvailable = 0; Fcb->ReadDataAvailable = 0;
ReadFcb->WriteQuotaAvailable = ReadFcb->MaxDataLength; Fcb->WriteQuotaAvailable = Fcb->MaxDataLength;
} }
if (Information > 0) if (Information > 0)
{ {
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
break; break;
} }
} }
#ifdef FIN_WORKAROUND_READCLOSE
if (ReadFcb->ReadDataAvailable == 0 &&
ReadFcb->PipeState == FILE_PIPE_CLOSING_STATE)
{
DPRINT("Other end of pipe is closed!\n");
break;
}
#endif
} }
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql); KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
done: done:
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
@ -265,6 +217,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PNPFS_FCB Fcb = NULL; PNPFS_FCB Fcb = NULL;
PNPFS_FCB ReaderFcb;
PNPFS_PIPE Pipe = NULL; PNPFS_PIPE Pipe = NULL;
PUCHAR Buffer; PUCHAR Buffer;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
@ -283,6 +236,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
DPRINT("Pipe name %wZ\n", &FileObject->FileName); DPRINT("Pipe name %wZ\n", &FileObject->FileName);
Fcb = FileObject->FsContext; Fcb = FileObject->FsContext;
ReaderFcb = Fcb->OtherSide;
Pipe = Fcb->Pipe; Pipe = Fcb->Pipe;
Length = IoStack->Parameters.Write.Length; Length = IoStack->Parameters.Write.Length;
@ -297,7 +251,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
goto done; goto done;
} }
if (Fcb->OtherSide == NULL) if (ReaderFcb == NULL)
{ {
DPRINT("Pipe is NOT connected!\n"); DPRINT("Pipe is NOT connected!\n");
if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE) if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
@ -310,7 +264,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
goto done; goto done;
} }
if (Fcb->Data == NULL) if (ReaderFcb->Data == NULL)
{ {
DPRINT("Pipe is NOT writable!\n"); DPRINT("Pipe is NOT writable!\n");
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
@ -321,7 +275,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql); KeAcquireSpinLock(&ReaderFcb->DataListLock, &OldIrql);
#ifndef NDEBUG #ifndef NDEBUG
DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset); DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
HexDump(Buffer, Length); HexDump(Buffer, Length);
@ -329,11 +283,11 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
while(1) while(1)
{ {
if (Fcb->WriteQuotaAvailable == 0) if (ReaderFcb->WriteQuotaAvailable == 0)
{ {
KeResetEvent(&Fcb->Event); KeResetEvent(&Fcb->Event);
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql); KeReleaseSpinLock(&ReaderFcb->DataListLock, OldIrql);
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE) if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
{ {
Status = STATUS_PIPE_BROKEN; Status = STATUS_PIPE_BROKEN;
@ -348,7 +302,6 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
NULL); NULL);
DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status); DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status);
#ifndef FIN_WORKAROUND_READCLOSE
/* /*
* It's possible that the event was signaled because the * It's possible that the event was signaled because the
* other side of pipe was closed. * other side of pipe was closed.
@ -359,44 +312,43 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
Status = STATUS_PIPE_BROKEN; Status = STATUS_PIPE_BROKEN;
goto done; goto done;
} }
#endif KeAcquireSpinLock(&ReaderFcb->DataListLock, &OldIrql);
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
} }
if (Pipe->WriteMode == FILE_PIPE_BYTE_STREAM_MODE) if (Pipe->WriteMode == FILE_PIPE_BYTE_STREAM_MODE)
{ {
DPRINT("Byte stream mode\n"); DPRINT("Byte stream mode\n");
while (Length > 0 && Fcb->WriteQuotaAvailable > 0) while (Length > 0 && ReaderFcb->WriteQuotaAvailable > 0)
{ {
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable); CopyLength = RtlRosMin(Length, ReaderFcb->WriteQuotaAvailable);
if (Fcb->WritePtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength) if (ReaderFcb->WritePtr + CopyLength <= ReaderFcb->Data + ReaderFcb->MaxDataLength)
{ {
memcpy(Fcb->WritePtr, Buffer, CopyLength); memcpy(ReaderFcb->WritePtr, Buffer, CopyLength);
Fcb->WritePtr += CopyLength; ReaderFcb->WritePtr += CopyLength;
if (Fcb->WritePtr == Fcb->Data + Fcb->MaxDataLength) if (ReaderFcb->WritePtr == ReaderFcb->Data + ReaderFcb->MaxDataLength)
{ {
Fcb->WritePtr = Fcb->Data; ReaderFcb->WritePtr = ReaderFcb->Data;
} }
} }
else else
{ {
TempLength = Fcb->Data + Fcb->MaxDataLength - Fcb->WritePtr; TempLength = ReaderFcb->Data + ReaderFcb->MaxDataLength - ReaderFcb->WritePtr;
memcpy(Fcb->WritePtr, Buffer, TempLength); memcpy(ReaderFcb->WritePtr, Buffer, TempLength);
memcpy(Fcb->Data, Buffer + TempLength, CopyLength - TempLength); memcpy(ReaderFcb->Data, Buffer + TempLength, CopyLength - TempLength);
Fcb->WritePtr = Fcb->Data + CopyLength - TempLength; ReaderFcb->WritePtr = ReaderFcb->Data + CopyLength - TempLength;
} }
Buffer += CopyLength; Buffer += CopyLength;
Length -= CopyLength; Length -= CopyLength;
Information += CopyLength; Information += CopyLength;
Fcb->ReadDataAvailable += CopyLength; ReaderFcb->ReadDataAvailable += CopyLength;
Fcb->WriteQuotaAvailable -= CopyLength; ReaderFcb->WriteQuotaAvailable -= CopyLength;
} }
if (Length == 0) if (Length == 0)
{ {
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
break; break;
} }
} }
@ -405,23 +357,23 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
DPRINT("Message mode\n"); DPRINT("Message mode\n");
if (Length > 0) if (Length > 0)
{ {
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable); CopyLength = RtlRosMin(Length, ReaderFcb->WriteQuotaAvailable);
memcpy(Fcb->Data, Buffer, CopyLength); memcpy(ReaderFcb->Data, Buffer, CopyLength);
Information = CopyLength; Information = CopyLength;
Fcb->ReadDataAvailable = CopyLength; ReaderFcb->ReadDataAvailable = CopyLength;
Fcb->WriteQuotaAvailable = 0; ReaderFcb->WriteQuotaAvailable = 0;
} }
if (Information > 0) if (Information > 0)
{ {
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
break; break;
} }
} }
} }
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql); KeReleaseSpinLock(&ReaderFcb->DataListLock, OldIrql);
done: done:
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;

View file

@ -2,9 +2,9 @@
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: services/fs/npfs/volume.c * FILE: drivers/fs/npfs/volume.c
* PURPOSE: Named pipe filesystem * PURPOSE: Named pipe filesystem
* PROGRAMMER: Eric Kohl <ekohl@rz-online.de> * PROGRAMMER: Eric Kohl
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -23,20 +23,20 @@ static NTSTATUS
NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo, NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
PULONG BufferLength) PULONG BufferLength)
{ {
DPRINT("NpfsQueryFsDeviceInformation()\n"); DPRINT("NpfsQueryFsDeviceInformation()\n");
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo); DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION)) if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
return(STATUS_BUFFER_OVERFLOW); return STATUS_BUFFER_OVERFLOW;
FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE; FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE;
FsDeviceInfo->Characteristics = 0; FsDeviceInfo->Characteristics = 0;
*BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION); *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
DPRINT("NpfsQueryFsDeviceInformation() finished.\n"); DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
@ -44,22 +44,22 @@ static NTSTATUS
NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
PULONG BufferLength) PULONG BufferLength)
{ {
DPRINT("NpfsQueryFsAttributeInformation() called.\n"); DPRINT("NpfsQueryFsAttributeInformation() called.\n");
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo); DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8) if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)
return(STATUS_BUFFER_OVERFLOW); return STATUS_BUFFER_OVERFLOW;
FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES; FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
FsAttributeInfo->MaximumComponentNameLength = 255; FsAttributeInfo->MaximumComponentNameLength = 255;
FsAttributeInfo->FileSystemNameLength = 8; FsAttributeInfo->FileSystemNameLength = 8;
wcscpy(FsAttributeInfo->FileSystemName, wcscpy(FsAttributeInfo->FileSystemName,
L"NPFS"); L"NPFS");
DPRINT("NpfsQueryFsAttributeInformation() finished.\n"); DPRINT("NpfsQueryFsAttributeInformation() finished.\n");
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
@ -67,54 +67,53 @@ NTSTATUS STDCALL
NpfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, NpfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
{ {
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
FS_INFORMATION_CLASS FsInformationClass; FS_INFORMATION_CLASS FsInformationClass;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PVOID SystemBuffer; PVOID SystemBuffer;
ULONG BufferLength; ULONG BufferLength;
/* PRECONDITION */ /* PRECONDITION */
assert(DeviceObject != NULL); ASSERT(DeviceObject != NULL);
assert(Irp != NULL); ASSERT(Irp != NULL);
DPRINT("NpfsQueryVolumeInformation(DeviceObject %x, Irp %x)\n", DPRINT("NpfsQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
DeviceObject, DeviceObject,
Irp); Irp);
Stack = IoGetCurrentIrpStackLocation (Irp); Stack = IoGetCurrentIrpStackLocation(Irp);
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass; FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
BufferLength = Stack->Parameters.QueryVolume.Length; BufferLength = Stack->Parameters.QueryVolume.Length;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer; SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
DPRINT("FsInformationClass %d\n", FsInformationClass); DPRINT("FsInformationClass %d\n", FsInformationClass);
DPRINT("SystemBuffer %x\n", SystemBuffer); DPRINT("SystemBuffer %x\n", SystemBuffer);
switch (FsInformationClass) switch (FsInformationClass)
{ {
case FileFsDeviceInformation: case FileFsDeviceInformation:
Status = NpfsQueryFsDeviceInformation(SystemBuffer, Status = NpfsQueryFsDeviceInformation(SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileFsAttributeInformation: case FileFsAttributeInformation:
Status = NpfsQueryFsAttributeInformation(SystemBuffer, Status = NpfsQueryFsAttributeInformation(SystemBuffer,
&BufferLength); &BufferLength);
break; break;
default: default:
Status = STATUS_NOT_SUPPORTED; Status = STATUS_NOT_SUPPORTED;
} }
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
Irp->IoStatus.Information = Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength;
Stack->Parameters.QueryVolume.Length - BufferLength; else
else Irp->IoStatus.Information = 0;
Irp->IoStatus.Information = 0; IoCompleteRequest(Irp,
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IO_NO_INCREMENT);
return Status;
return(Status);
} }
/* EOF */ /* EOF */