mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- 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:
parent
b6701ec6f9
commit
2f494319c3
7 changed files with 170 additions and 254 deletions
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/np/create.c
|
||||
* FILE: drivers/fs/np/create.c
|
||||
* PURPOSE: Named pipe filesystem
|
||||
* PROGRAMMER: David Welch <welch@cwcom.net>
|
||||
*/
|
||||
|
@ -164,9 +164,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
|||
ClientFcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
DPRINT("No memory!\n");
|
||||
|
@ -185,8 +185,8 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
|||
ClientFcb->ReadPtr = ClientFcb->Data;
|
||||
ClientFcb->WritePtr = ClientFcb->Data;
|
||||
ClientFcb->ReadDataAvailable = 0;
|
||||
ClientFcb->WriteQuotaAvailable = Pipe->InboundQuota;
|
||||
ClientFcb->MaxDataLength = Pipe->InboundQuota;
|
||||
ClientFcb->WriteQuotaAvailable = Pipe->OutboundQuota;
|
||||
ClientFcb->MaxDataLength = Pipe->OutboundQuota;
|
||||
KeInitializeSpinLock(&ClientFcb->DataListLock);
|
||||
KeInitializeEvent(&ClientFcb->ConnectEvent, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE);
|
||||
|
@ -381,9 +381,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
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)
|
||||
{
|
||||
ExFreePool(Fcb);
|
||||
|
@ -407,8 +407,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
Fcb->ReadPtr = Fcb->Data;
|
||||
Fcb->WritePtr = Fcb->Data;
|
||||
Fcb->ReadDataAvailable = 0;
|
||||
Fcb->WriteQuotaAvailable = Pipe->OutboundQuota;
|
||||
Fcb->MaxDataLength = Pipe->OutboundQuota;
|
||||
Fcb->WriteQuotaAvailable = Pipe->InboundQuota;
|
||||
Fcb->MaxDataLength = Pipe->InboundQuota;
|
||||
KeInitializeSpinLock(&Fcb->DataListLock);
|
||||
|
||||
Pipe->CurrentInstances++;
|
||||
|
@ -442,9 +442,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NpfsClose(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
NpfsClose(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PNPFS_DEVICE_EXTENSION DeviceExt;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
@ -493,10 +492,8 @@ NpfsClose(
|
|||
{
|
||||
if (Fcb->OtherSide)
|
||||
{
|
||||
#ifndef FIN_WORKAROUND_READCLOSE
|
||||
Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
|
||||
Fcb->OtherSide->OtherSide = NULL;
|
||||
#endif
|
||||
/*
|
||||
* Signaling the write event. If is possible that an other
|
||||
* thread waits for an empty buffer.
|
||||
|
@ -504,39 +501,15 @@ NpfsClose(
|
|||
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
|
||||
#ifndef FIN_WORKAROUND_READCLOSE
|
||||
Fcb->PipeState = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FileObject->FsContext = NULL;
|
||||
|
||||
#ifndef FIN_WORKAROUND_READCLOSE
|
||||
RemoveEntryList(&Fcb->FcbListEntry);
|
||||
if (Fcb->Data)
|
||||
ExFreePool(Fcb->Data);
|
||||
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);
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/np/finfo.c
|
||||
* FILE: drivers/fs/np/finfo.c
|
||||
* PURPOSE: Named pipe filesystem
|
||||
* PROGRAMMER: Eric Kohl <ekohl@rz-online.de>
|
||||
* PROGRAMMER: Eric Kohl
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
@ -36,7 +36,7 @@ NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
|
|||
// Info->CompletionMode =
|
||||
|
||||
*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);
|
||||
return(STATUS_SUCCESS);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -93,24 +93,24 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
|
|||
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:
|
||||
|
@ -134,7 +134,7 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
|
|||
default:
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
if (NT_SUCCESS(Status))
|
||||
Irp->IoStatus.Information =
|
||||
|
@ -142,8 +142,8 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
|
|||
else
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +196,7 @@ NpfsSetInformation(PDEVICE_OBJECT DeviceObject,
|
|||
IoCompleteRequest(Irp,
|
||||
IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/np/fsctrl.c
|
||||
* FILE: drivers/fs/np/fsctrl.c
|
||||
* PURPOSE: Named pipe filesystem
|
||||
* PROGRAMMER: David Welch <welch@cwcom.net>
|
||||
* Eric Kohl <ekohl@rz-online.de>
|
||||
* Eric Kohl
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/np/mount.c
|
||||
* FILE: drivers/fs/np/mount.c
|
||||
* PURPOSE: Named pipe filesystem
|
||||
* PROGRAMMER: David Welch <welch@cwcom.net>
|
||||
*/
|
||||
|
@ -64,7 +64,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Failed to create named pipe device! (Status %x)\n", Status);
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* initialize the device object */
|
||||
|
@ -81,7 +81,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
|
|||
DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
|
||||
DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
/* $Id$ */
|
||||
|
||||
#ifndef __SERVICES_FS_NP_NPFS_H
|
||||
#define __SERVICES_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
|
||||
#ifndef __DRIVERS_FS_NP_NPFS_H
|
||||
#define __DRIVERS_FS_NP_NPFS_H
|
||||
|
||||
typedef struct _NPFS_DEVICE_EXTENSION
|
||||
{
|
||||
|
@ -70,8 +64,6 @@ extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
|
|||
|
||||
#define KeUnlockMutex(x) KeReleaseMutex(x, FALSE);
|
||||
|
||||
#define CP DPRINT("\n");
|
||||
|
||||
|
||||
NTSTATUS STDCALL NpfsCreate(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);
|
||||
|
||||
#endif /* __SERVICES_FS_NP_NPFS_H */
|
||||
#endif /* __DRIVERS_FS_NP_NPFS_H */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/np/rw.c
|
||||
* FILE: drivers/fs/np/rw.c
|
||||
* PURPOSE: Named pipe filesystem
|
||||
* PROGRAMMER: David Welch <welch@cwcom.net>
|
||||
*/
|
||||
|
@ -16,8 +16,6 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define FIN_WORKAROUND_READCLOSE
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -60,7 +58,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
|||
KIRQL OldIrql;
|
||||
ULONG Information;
|
||||
PNPFS_FCB Fcb;
|
||||
PNPFS_FCB ReadFcb;
|
||||
PNPFS_FCB WriterFcb;
|
||||
PNPFS_PIPE Pipe;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
|
@ -74,21 +72,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
|||
FileObject = IoStack->FileObject;
|
||||
Fcb = FileObject->FsContext;
|
||||
Pipe = Fcb->Pipe;
|
||||
ReadFcb = 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;
|
||||
}
|
||||
WriterFcb = Fcb->OtherSide;
|
||||
|
||||
if (Irp->MdlAddress == NULL)
|
||||
{
|
||||
|
@ -98,7 +82,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (ReadFcb->Data == NULL)
|
||||
if (Fcb->Data == NULL)
|
||||
{
|
||||
DPRINT("Pipe is NOT readable!\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
|
@ -106,31 +90,20 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
|||
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;
|
||||
Length = IoStack->Parameters.Read.Length;
|
||||
Information = 0;
|
||||
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
|
||||
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
|
||||
while (1)
|
||||
{
|
||||
/* FIXME: check if in blocking mode */
|
||||
if (ReadFcb->ReadDataAvailable == 0)
|
||||
if (Fcb->ReadDataAvailable == 0)
|
||||
{
|
||||
KeResetEvent(&Fcb->Event);
|
||||
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
|
||||
KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
|
||||
if (Information > 0)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
|
@ -153,56 +126,44 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
|||
NULL);
|
||||
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
|
||||
* 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);
|
||||
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
|
||||
}
|
||||
|
||||
if (Pipe->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
|
||||
{
|
||||
DPRINT("Byte stream mode\n");
|
||||
/* Byte stream mode */
|
||||
while (Length > 0 && ReadFcb->ReadDataAvailable > 0)
|
||||
while (Length > 0 && Fcb->ReadDataAvailable > 0)
|
||||
{
|
||||
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length);
|
||||
if (ReadFcb->ReadPtr + CopyLength <= ReadFcb->Data + ReadFcb->MaxDataLength)
|
||||
CopyLength = RtlRosMin(Fcb->ReadDataAvailable, Length);
|
||||
if (Fcb->ReadPtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength)
|
||||
{
|
||||
memcpy(Buffer, ReadFcb->ReadPtr, CopyLength);
|
||||
ReadFcb->ReadPtr += CopyLength;
|
||||
if (ReadFcb->ReadPtr == ReadFcb->Data + ReadFcb->MaxDataLength)
|
||||
memcpy(Buffer, Fcb->ReadPtr, CopyLength);
|
||||
Fcb->ReadPtr += CopyLength;
|
||||
if (Fcb->ReadPtr == Fcb->Data + Fcb->MaxDataLength)
|
||||
{
|
||||
ReadFcb->ReadPtr = ReadFcb->Data;
|
||||
Fcb->ReadPtr = Fcb->Data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TempLength = ReadFcb->Data + ReadFcb->MaxDataLength - ReadFcb->ReadPtr;
|
||||
memcpy(Buffer, ReadFcb->ReadPtr, TempLength);
|
||||
memcpy(Buffer + TempLength, ReadFcb->Data, CopyLength - TempLength);
|
||||
ReadFcb->ReadPtr = ReadFcb->Data + CopyLength - TempLength;
|
||||
TempLength = Fcb->Data + Fcb->MaxDataLength - Fcb->ReadPtr;
|
||||
memcpy(Buffer, Fcb->ReadPtr, TempLength);
|
||||
memcpy(Buffer + TempLength, Fcb->Data, CopyLength - TempLength);
|
||||
Fcb->ReadPtr = Fcb->Data + CopyLength - TempLength;
|
||||
}
|
||||
|
||||
Buffer += CopyLength;
|
||||
Length -= CopyLength;
|
||||
Information += CopyLength;
|
||||
|
||||
ReadFcb->ReadDataAvailable -= CopyLength;
|
||||
ReadFcb->WriteQuotaAvailable += CopyLength;
|
||||
Fcb->ReadDataAvailable -= CopyLength;
|
||||
Fcb->WriteQuotaAvailable += CopyLength;
|
||||
}
|
||||
|
||||
if (Length == 0)
|
||||
{
|
||||
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -211,11 +172,11 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
|||
DPRINT("Message mode\n");
|
||||
|
||||
/* Message mode */
|
||||
if (ReadFcb->ReadDataAvailable)
|
||||
if (Fcb->ReadDataAvailable)
|
||||
{
|
||||
/* Truncate the message if the receive buffer is too small */
|
||||
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length);
|
||||
memcpy(Buffer, ReadFcb->Data, CopyLength);
|
||||
CopyLength = RtlRosMin(Fcb->ReadDataAvailable, Length);
|
||||
memcpy(Buffer, Fcb->Data, CopyLength);
|
||||
|
||||
#ifndef NDEBUG
|
||||
DPRINT("Length %d Buffer %x\n",CopyLength,Buffer);
|
||||
|
@ -223,28 +184,19 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
|||
#endif
|
||||
|
||||
Information = CopyLength;
|
||||
ReadFcb->ReadDataAvailable = 0;
|
||||
ReadFcb->WriteQuotaAvailable = ReadFcb->MaxDataLength;
|
||||
Fcb->ReadDataAvailable = 0;
|
||||
Fcb->WriteQuotaAvailable = Fcb->MaxDataLength;
|
||||
}
|
||||
|
||||
if (Information > 0)
|
||||
{
|
||||
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
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:
|
||||
Irp->IoStatus.Status = Status;
|
||||
|
@ -265,6 +217,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
PIO_STACK_LOCATION IoStack;
|
||||
PFILE_OBJECT FileObject;
|
||||
PNPFS_FCB Fcb = NULL;
|
||||
PNPFS_FCB ReaderFcb;
|
||||
PNPFS_PIPE Pipe = NULL;
|
||||
PUCHAR Buffer;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
@ -283,6 +236,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
DPRINT("Pipe name %wZ\n", &FileObject->FileName);
|
||||
|
||||
Fcb = FileObject->FsContext;
|
||||
ReaderFcb = Fcb->OtherSide;
|
||||
Pipe = Fcb->Pipe;
|
||||
|
||||
Length = IoStack->Parameters.Write.Length;
|
||||
|
@ -297,7 +251,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (Fcb->OtherSide == NULL)
|
||||
if (ReaderFcb == NULL)
|
||||
{
|
||||
DPRINT("Pipe is NOT connected!\n");
|
||||
if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
|
||||
|
@ -310,7 +264,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (Fcb->Data == NULL)
|
||||
if (ReaderFcb->Data == NULL)
|
||||
{
|
||||
DPRINT("Pipe is NOT writable!\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
|
@ -321,7 +275,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
Status = STATUS_SUCCESS;
|
||||
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||
|
||||
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
|
||||
KeAcquireSpinLock(&ReaderFcb->DataListLock, &OldIrql);
|
||||
#ifndef NDEBUG
|
||||
DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
|
||||
HexDump(Buffer, Length);
|
||||
|
@ -329,11 +283,11 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
while(1)
|
||||
{
|
||||
if (Fcb->WriteQuotaAvailable == 0)
|
||||
if (ReaderFcb->WriteQuotaAvailable == 0)
|
||||
{
|
||||
KeResetEvent(&Fcb->Event);
|
||||
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
|
||||
KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeReleaseSpinLock(&ReaderFcb->DataListLock, OldIrql);
|
||||
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
{
|
||||
Status = STATUS_PIPE_BROKEN;
|
||||
|
@ -348,7 +302,6 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
NULL);
|
||||
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
|
||||
* other side of pipe was closed.
|
||||
|
@ -359,44 +312,43 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
Status = STATUS_PIPE_BROKEN;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
|
||||
KeAcquireSpinLock(&ReaderFcb->DataListLock, &OldIrql);
|
||||
}
|
||||
|
||||
if (Pipe->WriteMode == FILE_PIPE_BYTE_STREAM_MODE)
|
||||
{
|
||||
DPRINT("Byte stream mode\n");
|
||||
while (Length > 0 && Fcb->WriteQuotaAvailable > 0)
|
||||
while (Length > 0 && ReaderFcb->WriteQuotaAvailable > 0)
|
||||
{
|
||||
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable);
|
||||
if (Fcb->WritePtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength)
|
||||
CopyLength = RtlRosMin(Length, ReaderFcb->WriteQuotaAvailable);
|
||||
if (ReaderFcb->WritePtr + CopyLength <= ReaderFcb->Data + ReaderFcb->MaxDataLength)
|
||||
{
|
||||
memcpy(Fcb->WritePtr, Buffer, CopyLength);
|
||||
Fcb->WritePtr += CopyLength;
|
||||
if (Fcb->WritePtr == Fcb->Data + Fcb->MaxDataLength)
|
||||
memcpy(ReaderFcb->WritePtr, Buffer, CopyLength);
|
||||
ReaderFcb->WritePtr += CopyLength;
|
||||
if (ReaderFcb->WritePtr == ReaderFcb->Data + ReaderFcb->MaxDataLength)
|
||||
{
|
||||
Fcb->WritePtr = Fcb->Data;
|
||||
ReaderFcb->WritePtr = ReaderFcb->Data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TempLength = Fcb->Data + Fcb->MaxDataLength - Fcb->WritePtr;
|
||||
memcpy(Fcb->WritePtr, Buffer, TempLength);
|
||||
memcpy(Fcb->Data, Buffer + TempLength, CopyLength - TempLength);
|
||||
Fcb->WritePtr = Fcb->Data + CopyLength - TempLength;
|
||||
TempLength = ReaderFcb->Data + ReaderFcb->MaxDataLength - ReaderFcb->WritePtr;
|
||||
memcpy(ReaderFcb->WritePtr, Buffer, TempLength);
|
||||
memcpy(ReaderFcb->Data, Buffer + TempLength, CopyLength - TempLength);
|
||||
ReaderFcb->WritePtr = ReaderFcb->Data + CopyLength - TempLength;
|
||||
}
|
||||
|
||||
Buffer += CopyLength;
|
||||
Length -= CopyLength;
|
||||
Information += CopyLength;
|
||||
|
||||
Fcb->ReadDataAvailable += CopyLength;
|
||||
Fcb->WriteQuotaAvailable -= CopyLength;
|
||||
ReaderFcb->ReadDataAvailable += CopyLength;
|
||||
ReaderFcb->WriteQuotaAvailable -= CopyLength;
|
||||
}
|
||||
|
||||
if (Length == 0)
|
||||
{
|
||||
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -405,23 +357,23 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
DPRINT("Message mode\n");
|
||||
if (Length > 0)
|
||||
{
|
||||
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable);
|
||||
memcpy(Fcb->Data, Buffer, CopyLength);
|
||||
CopyLength = RtlRosMin(Length, ReaderFcb->WriteQuotaAvailable);
|
||||
memcpy(ReaderFcb->Data, Buffer, CopyLength);
|
||||
|
||||
Information = CopyLength;
|
||||
Fcb->ReadDataAvailable = CopyLength;
|
||||
Fcb->WriteQuotaAvailable = 0;
|
||||
ReaderFcb->ReadDataAvailable = CopyLength;
|
||||
ReaderFcb->WriteQuotaAvailable = 0;
|
||||
}
|
||||
|
||||
if (Information > 0)
|
||||
{
|
||||
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
|
||||
KeReleaseSpinLock(&ReaderFcb->DataListLock, OldIrql);
|
||||
|
||||
done:
|
||||
Irp->IoStatus.Status = Status;
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/npfs/volume.c
|
||||
* FILE: drivers/fs/npfs/volume.c
|
||||
* PURPOSE: Named pipe filesystem
|
||||
* PROGRAMMER: Eric Kohl <ekohl@rz-online.de>
|
||||
* PROGRAMMER: Eric Kohl
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -23,20 +23,20 @@ static NTSTATUS
|
|||
NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
|
||||
PULONG BufferLength)
|
||||
{
|
||||
DPRINT("NpfsQueryFsDeviceInformation()\n");
|
||||
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
|
||||
|
||||
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE;
|
||||
FsDeviceInfo->Characteristics = 0;
|
||||
|
||||
*BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
|
||||
|
||||
DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
DPRINT("NpfsQueryFsDeviceInformation()\n");
|
||||
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
|
||||
|
||||
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
||||
FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE;
|
||||
FsDeviceInfo->Characteristics = 0;
|
||||
|
||||
*BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
|
||||
|
||||
DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,22 +44,22 @@ static NTSTATUS
|
|||
NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
|
||||
PULONG BufferLength)
|
||||
{
|
||||
DPRINT("NpfsQueryFsAttributeInformation() called.\n");
|
||||
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
|
||||
|
||||
if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
|
||||
FsAttributeInfo->MaximumComponentNameLength = 255;
|
||||
FsAttributeInfo->FileSystemNameLength = 8;
|
||||
wcscpy(FsAttributeInfo->FileSystemName,
|
||||
L"NPFS");
|
||||
|
||||
DPRINT("NpfsQueryFsAttributeInformation() finished.\n");
|
||||
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
DPRINT("NpfsQueryFsAttributeInformation() called.\n");
|
||||
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
|
||||
|
||||
if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
||||
FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
|
||||
FsAttributeInfo->MaximumComponentNameLength = 255;
|
||||
FsAttributeInfo->FileSystemNameLength = 8;
|
||||
wcscpy(FsAttributeInfo->FileSystemName,
|
||||
L"NPFS");
|
||||
|
||||
DPRINT("NpfsQueryFsAttributeInformation() finished.\n");
|
||||
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,54 +67,53 @@ NTSTATUS STDCALL
|
|||
NpfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
FS_INFORMATION_CLASS FsInformationClass;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PVOID SystemBuffer;
|
||||
ULONG BufferLength;
|
||||
|
||||
/* PRECONDITION */
|
||||
assert(DeviceObject != NULL);
|
||||
assert(Irp != NULL);
|
||||
|
||||
DPRINT("NpfsQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
|
||||
DeviceObject,
|
||||
Irp);
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
|
||||
BufferLength = Stack->Parameters.QueryVolume.Length;
|
||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
DPRINT("FsInformationClass %d\n", FsInformationClass);
|
||||
DPRINT("SystemBuffer %x\n", SystemBuffer);
|
||||
|
||||
switch (FsInformationClass)
|
||||
{
|
||||
case FileFsDeviceInformation:
|
||||
Status = NpfsQueryFsDeviceInformation(SystemBuffer,
|
||||
&BufferLength);
|
||||
break;
|
||||
|
||||
case FileFsAttributeInformation:
|
||||
Status = NpfsQueryFsAttributeInformation(SystemBuffer,
|
||||
&BufferLength);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
if (NT_SUCCESS(Status))
|
||||
Irp->IoStatus.Information =
|
||||
Stack->Parameters.QueryVolume.Length - BufferLength;
|
||||
else
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,
|
||||
IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
PIO_STACK_LOCATION Stack;
|
||||
FS_INFORMATION_CLASS FsInformationClass;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PVOID SystemBuffer;
|
||||
ULONG BufferLength;
|
||||
|
||||
/* PRECONDITION */
|
||||
ASSERT(DeviceObject != NULL);
|
||||
ASSERT(Irp != NULL);
|
||||
|
||||
DPRINT("NpfsQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
|
||||
DeviceObject,
|
||||
Irp);
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
|
||||
BufferLength = Stack->Parameters.QueryVolume.Length;
|
||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
DPRINT("FsInformationClass %d\n", FsInformationClass);
|
||||
DPRINT("SystemBuffer %x\n", SystemBuffer);
|
||||
|
||||
switch (FsInformationClass)
|
||||
{
|
||||
case FileFsDeviceInformation:
|
||||
Status = NpfsQueryFsDeviceInformation(SystemBuffer,
|
||||
&BufferLength);
|
||||
break;
|
||||
|
||||
case FileFsAttributeInformation:
|
||||
Status = NpfsQueryFsAttributeInformation(SystemBuffer,
|
||||
&BufferLength);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
if (NT_SUCCESS(Status))
|
||||
Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength;
|
||||
else
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,
|
||||
IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue