From 216311551ac0e67d3c9d779737cdb706c7e5f665 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 30 Dec 2004 16:15:46 +0000 Subject: [PATCH] - Use ShareAccess FILE_SHARE_READ | FILE_SHARE_WRITE to indicate passive mode for client end pipes. svn path=/trunk/; revision=12406 --- reactos/drivers/fs/np/create.c | 12 +- reactos/drivers/fs/np/rw.c | 241 ++++++++++++++++-------------- reactos/lib/kernel32/file/npipe.c | 6 +- 3 files changed, 139 insertions(+), 120 deletions(-) diff --git a/reactos/drivers/fs/np/create.c b/reactos/drivers/fs/np/create.c index 019af1a608d..e13fefe6430 100644 --- a/reactos/drivers/fs/np/create.c +++ b/reactos/drivers/fs/np/create.c @@ -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) diff --git a/reactos/drivers/fs/np/rw.c b/reactos/drivers/fs/np/rw.c index 81dd500a795..3d9c4cdd3fa 100644 --- a/reactos/drivers/fs/np/rw.c +++ b/reactos/drivers/fs/np/rw.c @@ -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 +#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 */ diff --git a/reactos/lib/kernel32/file/npipe.c b/reactos/lib/kernel32/file/npipe.c index 71d23b4645f..3031fcbbb15 100644 --- a/reactos/lib/kernel32/file/npipe.c +++ b/reactos/lib/kernel32/file/npipe.c @@ -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);