- 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:
Eric Kohl 2004-12-30 16:15:46 +00:00
parent 78c79c31e7
commit 216311551a
3 changed files with 139 additions and 120 deletions

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -76,20 +76,20 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
PNPFS_FCB ClientFcb; PNPFS_FCB ClientFcb;
PNPFS_FCB ServerFcb = NULL; PNPFS_FCB ServerFcb = NULL;
PNPFS_DEVICE_EXTENSION DeviceExt; PNPFS_DEVICE_EXTENSION DeviceExt;
ULONG Disposition; BOOLEAN SpecialAccess;
DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject; FileObject = IoStack->FileObject;
Disposition = ((IoStack->Parameters.Create.Options >> 24) & 0xff);
DPRINT("FileObject %p\n", FileObject); DPRINT("FileObject %p\n", FileObject);
DPRINT("FileName %wZ\n", &FileObject->FileName); DPRINT("FileName %wZ\n", &FileObject->FileName);
Irp->IoStatus.Information = 0; 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"); DPRINT("NpfsCreate() open client end for special use!\n");
} }
@ -122,7 +122,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
*/ */
KeLockMutex(&Pipe->FcbListLock); KeLockMutex(&Pipe->FcbListLock);
if (!(Disposition & FILE_OPEN)) if (!SpecialAccess)
{ {
ServerFcb = NpfsFindListeningServerInstance(Pipe); ServerFcb = NpfsFindListeningServerInstance(Pipe);
if (ServerFcb == NULL) if (ServerFcb == NULL)
@ -160,7 +160,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
ClientFcb->Pipe = Pipe; ClientFcb->Pipe = Pipe;
ClientFcb->PipeEnd = FILE_PIPE_CLIENT_END; ClientFcb->PipeEnd = FILE_PIPE_CLIENT_END;
ClientFcb->OtherSide = NULL; ClientFcb->OtherSide = NULL;
ClientFcb->PipeState = (Disposition & FILE_OPEN) ? 0 : FILE_PIPE_DISCONNECTED_STATE; ClientFcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
/* Initialize data list. */ /* Initialize data list. */
if (Pipe->InboundQuota) if (Pipe->InboundQuota)

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -16,6 +16,8 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#define FIN_WORKAROUND_READCLOSE
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#ifndef NDEBUG #ifndef NDEBUG
@ -46,8 +48,10 @@ VOID HexDump(PUCHAR Buffer, ULONG Length)
} }
#endif #endif
NTSTATUS STDCALL NTSTATUS STDCALL
NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) NpfsRead(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{ {
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
@ -64,7 +68,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
ULONG TempLength; ULONG TempLength;
DPRINT("NpfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DPRINT("NpfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject; FileObject = IoStack->FileObject;
@ -79,7 +83,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Status = STATUS_PIPE_LISTENING; Status = STATUS_PIPE_LISTENING;
else if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE) else if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
Status = STATUS_PIPE_DISCONNECTED; Status = STATUS_PIPE_DISCONNECTED;
else else
Status = STATUS_PIPE_BROKEN; Status = STATUS_PIPE_BROKEN;
Information = 0; Information = 0;
DPRINT("%x\n", Status); DPRINT("%x\n", Status);
@ -93,7 +97,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Information = 0; Information = 0;
goto done; goto done;
} }
if (ReadFcb->Data == NULL) if (ReadFcb->Data == NULL)
{ {
DPRINT("Pipe is NOT readable!\n"); DPRINT("Pipe is NOT readable!\n");
@ -123,118 +127,123 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ {
/* FIXME: check if in blocking mode */ /* FIXME: check if in blocking mode */
if (ReadFcb->ReadDataAvailable == 0) if (ReadFcb->ReadDataAvailable == 0)
{ {
KeResetEvent(&Fcb->Event); KeResetEvent(&Fcb->Event);
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql); KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
if (Information > 0) if (Information > 0)
{ {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
goto done; goto done;
} }
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
{ {
DPRINT("PipeState: %x\n", Fcb->PipeState); DPRINT("PipeState: %x\n", Fcb->PipeState);
Status = STATUS_PIPE_BROKEN; Status = STATUS_PIPE_BROKEN;
goto done; goto done;
} }
/* Wait for ReadEvent to become signaled */
DPRINT("Waiting for readable data (%S)\n", Pipe->PipeName.Buffer); /* Wait for ReadEvent to become signaled */
Status = KeWaitForSingleObject(&Fcb->Event, DPRINT("Waiting for readable data (%S)\n", Pipe->PipeName.Buffer);
Status = KeWaitForSingleObject(&Fcb->Event,
UserRequest, UserRequest,
KernelMode, KernelMode,
FALSE, FALSE,
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 #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.
*/ */
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE) if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
{ {
DPRINT("PipeState: %x\n", Fcb->PipeState); DPRINT("PipeState: %x\n", Fcb->PipeState);
Status = STATUS_PIPE_BROKEN; Status = STATUS_PIPE_BROKEN;
goto done; goto done;
} }
#endif #endif
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 */
while (Length > 0 && ReadFcb->ReadDataAvailable > 0) while (Length > 0 && ReadFcb->ReadDataAvailable > 0)
{ {
CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length); CopyLength = RtlRosMin(ReadFcb->ReadDataAvailable, Length);
if (ReadFcb->ReadPtr + CopyLength <= ReadFcb->Data + ReadFcb->MaxDataLength) if (ReadFcb->ReadPtr + CopyLength <= ReadFcb->Data + ReadFcb->MaxDataLength)
{ {
memcpy(Buffer, ReadFcb->ReadPtr, CopyLength); memcpy(Buffer, ReadFcb->ReadPtr, CopyLength);
ReadFcb->ReadPtr += CopyLength; ReadFcb->ReadPtr += CopyLength;
if (ReadFcb->ReadPtr == ReadFcb->Data + ReadFcb->MaxDataLength) if (ReadFcb->ReadPtr == ReadFcb->Data + ReadFcb->MaxDataLength)
{ {
ReadFcb->ReadPtr = ReadFcb->Data; ReadFcb->ReadPtr = ReadFcb->Data;
} }
} }
else else
{ {
TempLength = ReadFcb->Data + ReadFcb->MaxDataLength - ReadFcb->ReadPtr; TempLength = ReadFcb->Data + ReadFcb->MaxDataLength - ReadFcb->ReadPtr;
memcpy(Buffer, ReadFcb->ReadPtr, TempLength); memcpy(Buffer, ReadFcb->ReadPtr, TempLength);
memcpy(Buffer + TempLength, ReadFcb->Data, CopyLength - TempLength); memcpy(Buffer + TempLength, ReadFcb->Data, CopyLength - TempLength);
ReadFcb->ReadPtr = ReadFcb->Data + CopyLength - TempLength; ReadFcb->ReadPtr = ReadFcb->Data + CopyLength - TempLength;
} }
Buffer += CopyLength; Buffer += CopyLength;
Length -= CopyLength; Length -= CopyLength;
Information += CopyLength; Information += CopyLength;
ReadFcb->ReadDataAvailable -= CopyLength; ReadFcb->ReadDataAvailable -= CopyLength;
ReadFcb->WriteQuotaAvailable += CopyLength; ReadFcb->WriteQuotaAvailable += CopyLength;
} }
if (Length == 0) if (Length == 0)
{ {
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
break; break;
} }
} }
else else
{ {
DPRINT("Message mode\n"); DPRINT("Message mode\n");
/* Message mode */ /* Message mode */
if (ReadFcb->ReadDataAvailable) if (ReadFcb->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(ReadFcb->ReadDataAvailable, Length);
memcpy(Buffer, ReadFcb->Data, CopyLength); memcpy(Buffer, ReadFcb->Data, CopyLength);
#ifndef NDEBUG #ifndef NDEBUG
DPRINT("Length %d Buffer %x\n",CopyLength,Buffer); DPRINT("Length %d Buffer %x\n",CopyLength,Buffer);
HexDump((PUCHAR)Buffer, CopyLength); HexDump((PUCHAR)Buffer, CopyLength);
#endif #endif
Information = CopyLength; Information = CopyLength;
ReadFcb->ReadDataAvailable = 0; ReadFcb->ReadDataAvailable = 0;
ReadFcb->WriteQuotaAvailable = ReadFcb->MaxDataLength; ReadFcb->WriteQuotaAvailable = ReadFcb->MaxDataLength;
} }
if (Information > 0)
{ if (Information > 0)
KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE); {
break; KeSetEvent(&ReadFcb->Event, IO_NO_INCREMENT, FALSE);
} break;
} }
}
#ifdef FIN_WORKAROUND_READCLOSE #ifdef FIN_WORKAROUND_READCLOSE
if (ReadFcb->ReadDataAvailable == 0 && if (ReadFcb->ReadDataAvailable == 0 &&
ReadFcb->PipeState == FILE_PIPE_CLOSING_STATE) ReadFcb->PipeState == FILE_PIPE_CLOSING_STATE)
{ {
DPRINT("Other end of pipe is closed!\n"); DPRINT("Other end of pipe is closed!\n");
break; break;
} }
#endif #endif
} }
KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql); KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
done: done:
@ -243,7 +252,9 @@ done:
IoCompleteRequest(Irp, IO_NO_INCREMENT); 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; Length = 0;
goto done; goto done;
} }
if (Fcb->Data == NULL) if (Fcb->Data == NULL)
{ {
DPRINT("Pipe is NOT writable!\n"); DPRINT("Pipe is NOT writable!\n");
@ -319,45 +330,48 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
while(1) while(1)
{ {
if (Fcb->WriteQuotaAvailable == 0) if (Fcb->WriteQuotaAvailable == 0)
{ {
KeResetEvent(&Fcb->Event); KeResetEvent(&Fcb->Event);
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql); KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE) if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
{ {
Status = STATUS_PIPE_BROKEN; Status = STATUS_PIPE_BROKEN;
goto done; 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, UserRequest,
KernelMode, KernelMode,
FALSE, FALSE,
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 #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.
*/ */
if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE) if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
{ {
DPRINT("PipeState: %x\n", Fcb->PipeState); DPRINT("PipeState: %x\n", Fcb->PipeState);
Status = STATUS_PIPE_BROKEN; Status = STATUS_PIPE_BROKEN;
goto done; goto done;
} }
#endif #endif
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql); KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
} }
if (Pipe->PipeWriteMode == FILE_PIPE_BYTE_STREAM_MODE) if (Pipe->PipeWriteMode == FILE_PIPE_BYTE_STREAM_MODE)
{ {
DPRINT("Byte stream mode\n"); DPRINT("Byte stream mode\n");
while (Length > 0 && Fcb->WriteQuotaAvailable > 0) while (Length > 0 && Fcb->WriteQuotaAvailable > 0)
{ {
CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable); CopyLength = RtlRosMin(Length, Fcb->WriteQuotaAvailable);
if (Fcb->WritePtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength) if (Fcb->WritePtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength)
{ {
memcpy(Fcb->WritePtr, Buffer, CopyLength); memcpy(Fcb->WritePtr, Buffer, CopyLength);
Fcb->WritePtr += CopyLength; Fcb->WritePtr += CopyLength;
if (Fcb->WritePtr == Fcb->Data + Fcb->MaxDataLength) if (Fcb->WritePtr == Fcb->Data + Fcb->MaxDataLength)
{ {
@ -365,16 +379,16 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
} }
} }
else else
{ {
TempLength = Fcb->Data + Fcb->MaxDataLength - Fcb->WritePtr; TempLength = Fcb->Data + Fcb->MaxDataLength - Fcb->WritePtr;
memcpy(Fcb->WritePtr, Buffer, TempLength); memcpy(Fcb->WritePtr, Buffer, TempLength);
memcpy(Fcb->Data, Buffer + TempLength, CopyLength - TempLength); memcpy(Fcb->Data, Buffer + TempLength, CopyLength - TempLength);
Fcb->WritePtr = Fcb->Data + CopyLength - TempLength; Fcb->WritePtr = Fcb->Data + CopyLength - TempLength;
} }
Buffer += CopyLength; Buffer += CopyLength;
Length -= CopyLength; Length -= CopyLength;
Information += CopyLength; Information += CopyLength;
Fcb->ReadDataAvailable += CopyLength; Fcb->ReadDataAvailable += CopyLength;
Fcb->WriteQuotaAvailable -= CopyLength; Fcb->WriteQuotaAvailable -= CopyLength;
@ -387,16 +401,18 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
} }
} }
else 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); memcpy(Fcb->Data, Buffer, CopyLength);
Information = CopyLength; Information = CopyLength;
Fcb->ReadDataAvailable = CopyLength; Fcb->ReadDataAvailable = CopyLength;
Fcb->WriteQuotaAvailable = 0; Fcb->WriteQuotaAvailable = 0;
} }
if (Information > 0) if (Information > 0)
{ {
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
@ -404,15 +420,18 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
} }
} }
} }
KeReleaseSpinLock(&Fcb->DataListLock, OldIrql); KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
done: done:
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information; Irp->IoStatus.Information = Information;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status); DPRINT("NpfsWrite done (Status %lx)\n", Status);
return Status;
} }
/* EOF */ /* EOF */

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -262,8 +262,8 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
FILE_GENERIC_READ, FILE_GENERIC_READ,
&ObjectAttributes, &ObjectAttributes,
&Iosb, &Iosb,
0, FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_ALERT); FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus (Status); SetLastErrorByStatus (Status);