mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Use ShareAccess FILE_SHARE_READ | FILE_SHARE_WRITE to indicate passive mode for client end pipes.
svn path=/trunk/; revision=12406
This commit is contained in:
parent
78c79c31e7
commit
216311551a
3 changed files with 139 additions and 120 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: create.c,v 1.27 2004/12/30 12:34:26 ekohl Exp $
|
||||
/* $Id: create.c,v 1.28 2004/12/30 16:15:10 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -76,20 +76,20 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
|||
PNPFS_FCB ClientFcb;
|
||||
PNPFS_FCB ServerFcb = NULL;
|
||||
PNPFS_DEVICE_EXTENSION DeviceExt;
|
||||
ULONG Disposition;
|
||||
BOOLEAN SpecialAccess;
|
||||
|
||||
DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
||||
|
||||
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = IoStack->FileObject;
|
||||
Disposition = ((IoStack->Parameters.Create.Options >> 24) & 0xff);
|
||||
DPRINT("FileObject %p\n", FileObject);
|
||||
DPRINT("FileName %wZ\n", &FileObject->FileName);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
if (Disposition & FILE_OPEN)
|
||||
SpecialAccess = ((IoStack->Parameters.Create.ShareAccess & 3) == 3);
|
||||
if (SpecialAccess)
|
||||
{
|
||||
DPRINT("NpfsCreate() open client end for special use!\n");
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
|||
*/
|
||||
KeLockMutex(&Pipe->FcbListLock);
|
||||
|
||||
if (!(Disposition & FILE_OPEN))
|
||||
if (!SpecialAccess)
|
||||
{
|
||||
ServerFcb = NpfsFindListeningServerInstance(Pipe);
|
||||
if (ServerFcb == NULL)
|
||||
|
@ -160,7 +160,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
|||
ClientFcb->Pipe = Pipe;
|
||||
ClientFcb->PipeEnd = FILE_PIPE_CLIENT_END;
|
||||
ClientFcb->OtherSide = NULL;
|
||||
ClientFcb->PipeState = (Disposition & FILE_OPEN) ? 0 : FILE_PIPE_DISCONNECTED_STATE;
|
||||
ClientFcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
|
||||
|
||||
/* Initialize data list. */
|
||||
if (Pipe->InboundQuota)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: rw.c,v 1.15 2004/05/10 19:58:10 navaraf Exp $
|
||||
/* $Id: rw.c,v 1.16 2004/12/30 16:15:10 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -16,6 +16,8 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define FIN_WORKAROUND_READCLOSE
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -46,8 +48,10 @@ VOID HexDump(PUCHAR Buffer, ULONG Length)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
NpfsRead(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PFILE_OBJECT FileObject;
|
||||
|
@ -64,7 +68,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
ULONG TempLength;
|
||||
|
||||
DPRINT("NpfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
||||
|
||||
|
||||
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = IoStack->FileObject;
|
||||
|
@ -79,7 +83,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
Status = STATUS_PIPE_LISTENING;
|
||||
else if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
|
||||
Status = STATUS_PIPE_DISCONNECTED;
|
||||
else
|
||||
else
|
||||
Status = STATUS_PIPE_BROKEN;
|
||||
Information = 0;
|
||||
DPRINT("%x\n", Status);
|
||||
|
@ -93,7 +97,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
Information = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (ReadFcb->Data == NULL)
|
||||
{
|
||||
DPRINT("Pipe is NOT readable!\n");
|
||||
|
@ -123,118 +127,123 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
{
|
||||
/* FIXME: check if in blocking mode */
|
||||
if (ReadFcb->ReadDataAvailable == 0)
|
||||
{
|
||||
KeResetEvent(&Fcb->Event);
|
||||
{
|
||||
KeResetEvent(&Fcb->Event);
|
||||
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
|
||||
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
|
||||
if (Information > 0)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
|
||||
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
{
|
||||
DPRINT("PipeState: %x\n", Fcb->PipeState);
|
||||
Status = STATUS_PIPE_BROKEN;
|
||||
goto done;
|
||||
}
|
||||
/* Wait for ReadEvent to become signaled */
|
||||
DPRINT("Waiting for readable data (%S)\n", Pipe->PipeName.Buffer);
|
||||
Status = KeWaitForSingleObject(&Fcb->Event,
|
||||
|
||||
/* Wait for ReadEvent to become signaled */
|
||||
DPRINT("Waiting for readable data (%S)\n", Pipe->PipeName.Buffer);
|
||||
Status = KeWaitForSingleObject(&Fcb->Event,
|
||||
UserRequest,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
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
|
||||
* other side of pipe was closed.
|
||||
*/
|
||||
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
/*
|
||||
* 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(&ReadFcb->DataListLock, &OldIrql);
|
||||
}
|
||||
|
||||
if (Pipe->PipeReadMode == FILE_PIPE_BYTE_STREAM_MODE)
|
||||
{
|
||||
DPRINT("Byte stream mode\n");
|
||||
/* Byte stream mode */
|
||||
while (Length > 0 && ReadFcb->ReadDataAvailable > 0)
|
||||
{
|
||||
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length);
|
||||
if (ReadFcb->ReadPtr + CopyLength <= ReadFcb->Data + ReadFcb->MaxDataLength)
|
||||
{
|
||||
memcpy(Buffer, ReadFcb->ReadPtr, CopyLength);
|
||||
ReadFcb->ReadPtr += CopyLength;
|
||||
if (ReadFcb->ReadPtr == ReadFcb->Data + ReadFcb->MaxDataLength)
|
||||
{
|
||||
ReadFcb->ReadPtr = ReadFcb->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;
|
||||
}
|
||||
if (Pipe->PipeReadMode == FILE_PIPE_BYTE_STREAM_MODE)
|
||||
{
|
||||
DPRINT("Byte stream mode\n");
|
||||
/* Byte stream mode */
|
||||
while (Length > 0 && ReadFcb->ReadDataAvailable > 0)
|
||||
{
|
||||
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length);
|
||||
if (ReadFcb->ReadPtr + CopyLength <= ReadFcb->Data + ReadFcb->MaxDataLength)
|
||||
{
|
||||
memcpy(Buffer, ReadFcb->ReadPtr, CopyLength);
|
||||
ReadFcb->ReadPtr += CopyLength;
|
||||
if (ReadFcb->ReadPtr == ReadFcb->Data + ReadFcb->MaxDataLength)
|
||||
{
|
||||
ReadFcb->ReadPtr = ReadFcb->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;
|
||||
}
|
||||
|
||||
Buffer += CopyLength;
|
||||
Length -= CopyLength;
|
||||
Information += CopyLength;
|
||||
Buffer += CopyLength;
|
||||
Length -= CopyLength;
|
||||
Information += CopyLength;
|
||||
|
||||
ReadFcb->ReadDataAvailable -= CopyLength;
|
||||
ReadFcb->WriteQuotaAvailable += CopyLength;
|
||||
}
|
||||
ReadFcb->ReadDataAvailable -= CopyLength;
|
||||
ReadFcb->WriteQuotaAvailable += CopyLength;
|
||||
}
|
||||
|
||||
if (Length == 0)
|
||||
{
|
||||
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Message mode\n");
|
||||
if (Length == 0)
|
||||
{
|
||||
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Message mode\n");
|
||||
|
||||
/* Message mode */
|
||||
if (ReadFcb->ReadDataAvailable)
|
||||
{
|
||||
/* Truncate the message if the receive buffer is too small */
|
||||
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length);
|
||||
memcpy(Buffer, ReadFcb->Data, CopyLength);
|
||||
/* Message mode */
|
||||
if (ReadFcb->ReadDataAvailable)
|
||||
{
|
||||
/* Truncate the message if the receive buffer is too small */
|
||||
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length);
|
||||
memcpy(Buffer, ReadFcb->Data, CopyLength);
|
||||
|
||||
#ifndef NDEBUG
|
||||
DPRINT("Length %d Buffer %x\n",CopyLength,Buffer);
|
||||
HexDump((PUCHAR)Buffer, CopyLength);
|
||||
DPRINT("Length %d Buffer %x\n",CopyLength,Buffer);
|
||||
HexDump((PUCHAR)Buffer, CopyLength);
|
||||
#endif
|
||||
|
||||
Information = CopyLength;
|
||||
ReadFcb->ReadDataAvailable = 0;
|
||||
ReadFcb->WriteQuotaAvailable = ReadFcb->MaxDataLength;
|
||||
}
|
||||
if (Information > 0)
|
||||
{
|
||||
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Information = CopyLength;
|
||||
ReadFcb->ReadDataAvailable = 0;
|
||||
ReadFcb->WriteQuotaAvailable = ReadFcb->MaxDataLength;
|
||||
}
|
||||
|
||||
if (Information > 0)
|
||||
{
|
||||
KeSetEvent(&ReadFcb->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;
|
||||
}
|
||||
if (ReadFcb->ReadDataAvailable == 0 &&
|
||||
ReadFcb->PipeState == FILE_PIPE_CLOSING_STATE)
|
||||
{
|
||||
DPRINT("Other end of pipe is closed!\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
|
||||
|
||||
done:
|
||||
|
@ -243,7 +252,9 @@ done:
|
|||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
DPRINT("NpfsRead done (Status %lx)\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -298,7 +309,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
Length = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (Fcb->Data == NULL)
|
||||
{
|
||||
DPRINT("Pipe is NOT writable!\n");
|
||||
|
@ -319,45 +330,48 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
while(1)
|
||||
{
|
||||
if (Fcb->WriteQuotaAvailable == 0)
|
||||
{
|
||||
KeResetEvent(&Fcb->Event);
|
||||
{
|
||||
KeResetEvent(&Fcb->Event);
|
||||
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
||||
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
|
||||
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
|
||||
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
{
|
||||
Status = STATUS_PIPE_BROKEN;
|
||||
goto done;
|
||||
}
|
||||
DPRINT("Waiting for buffer space (%S)\n", Pipe->PipeName.Buffer);
|
||||
Status = KeWaitForSingleObject(&Fcb->Event,
|
||||
|
||||
DPRINT("Waiting for buffer space (%S)\n", Pipe->PipeName.Buffer);
|
||||
Status = KeWaitForSingleObject(&Fcb->Event,
|
||||
UserRequest,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
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
|
||||
* other side of pipe was closed.
|
||||
*/
|
||||
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
/*
|
||||
* 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(&Fcb->DataListLock, &OldIrql);
|
||||
}
|
||||
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
|
||||
}
|
||||
|
||||
if (Pipe->PipeWriteMode == FILE_PIPE_BYTE_STREAM_MODE)
|
||||
{
|
||||
DPRINT("Byte stream mode\n");
|
||||
{
|
||||
DPRINT("Byte stream mode\n");
|
||||
while (Length > 0 && Fcb->WriteQuotaAvailable > 0)
|
||||
{
|
||||
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable);
|
||||
if (Fcb->WritePtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength)
|
||||
{
|
||||
memcpy(Fcb->WritePtr, Buffer, CopyLength);
|
||||
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable);
|
||||
if (Fcb->WritePtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength)
|
||||
{
|
||||
memcpy(Fcb->WritePtr, Buffer, CopyLength);
|
||||
Fcb->WritePtr += CopyLength;
|
||||
if (Fcb->WritePtr == Fcb->Data + Fcb->MaxDataLength)
|
||||
{
|
||||
|
@ -365,16 +379,16 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Buffer += CopyLength;
|
||||
Length -= CopyLength;
|
||||
Information += CopyLength;
|
||||
Information += CopyLength;
|
||||
|
||||
Fcb->ReadDataAvailable += CopyLength;
|
||||
Fcb->WriteQuotaAvailable -= CopyLength;
|
||||
|
@ -387,16 +401,18 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Length > 0)
|
||||
{
|
||||
DPRINT("Message mode\n");
|
||||
if (Length > 0)
|
||||
{
|
||||
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable);
|
||||
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable);
|
||||
memcpy(Fcb->Data, Buffer, CopyLength);
|
||||
|
||||
Information = CopyLength;
|
||||
Fcb->ReadDataAvailable = CopyLength;
|
||||
Fcb->WriteQuotaAvailable = 0;
|
||||
}
|
||||
|
||||
if (Information > 0)
|
||||
{
|
||||
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
||||
|
@ -404,15 +420,18 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
|
||||
|
||||
done:
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Information;
|
||||
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
DPRINT("NpfsWrite done (Status %lx)\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: npipe.c,v 1.21 2004/12/23 20:13:19 ekohl Exp $
|
||||
/* $Id: npipe.c,v 1.22 2004/12/30 16:15:46 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -262,8 +262,8 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
|
|||
FILE_GENERIC_READ,
|
||||
&ObjectAttributes,
|
||||
&Iosb,
|
||||
0,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastErrorByStatus (Status);
|
||||
|
|
Loading…
Reference in a new issue