diff --git a/reactos/drivers/fs/np/create.c b/reactos/drivers/fs/np/create.c index 88e3766c73a..79f8aad2ff1 100644 --- a/reactos/drivers/fs/np/create.c +++ b/reactos/drivers/fs/np/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.20 2004/05/07 12:13:13 navaraf Exp $ +/* $Id: create.c,v 1.21 2004/05/10 19:58:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -472,23 +472,47 @@ 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 of an empty buffer. */ 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); diff --git a/reactos/drivers/fs/np/npfs.h b/reactos/drivers/fs/np/npfs.h index ad9efb63dd3..92d59c4b1d9 100644 --- a/reactos/drivers/fs/np/npfs.h +++ b/reactos/drivers/fs/np/npfs.h @@ -1,8 +1,13 @@ -/* $Id: npfs.h,v 1.16 2004/05/05 18:30:16 navaraf Exp $ */ +/* $Id: npfs.h,v 1.17 2004/05/10 19:58:10 navaraf Exp $ */ #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 typedef struct { diff --git a/reactos/drivers/fs/np/rw.c b/reactos/drivers/fs/np/rw.c index a693b5465a3..81dd500a795 100644 --- a/reactos/drivers/fs/np/rw.c +++ b/reactos/drivers/fs/np/rw.c @@ -1,4 +1,4 @@ -/* $Id: rw.c,v 1.14 2004/05/07 12:13:13 navaraf Exp $ +/* $Id: rw.c,v 1.15 2004/05/10 19:58:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -13,11 +13,39 @@ #include #include "npfs.h" -//#define NDEBUG +#define NDEBUG #include /* FUNCTIONS *****************************************************************/ +#ifndef NDEBUG +VOID HexDump(PUCHAR Buffer, ULONG Length) +{ + CHAR Line[65]; + UCHAR ch; + const char Hex[] = "0123456789ABCDEF"; + int i, j; + + DbgPrint("---------------\n"); + + for (i = 0; i < ROUND_UP(Length, 16); i+= 16) + { + memset(Line, ' ', 64); + Line[64] = 0; + + for (j = 0; j < 16 && j + i < Length; j++) + { + ch = Buffer[i + j]; + Line[3*j + 0] = Hex[ch >> 4]; + Line[3*j + 1] = Hex[ch & 0x0f]; + Line[48 + j] = isprint(ch) ? ch : '.'; + } + DbgPrint("%s\n", Line); + } + DbgPrint("---------------\n"); +} +#endif + NTSTATUS STDCALL NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) { @@ -51,9 +79,10 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) Status = STATUS_PIPE_LISTENING; else if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE) Status = STATUS_PIPE_DISCONNECTED; - else - Status = STATUS_UNSUCCESSFUL; + else + Status = STATUS_PIPE_BROKEN; Information = 0; + DPRINT("%x\n", Status); goto done; } @@ -73,6 +102,16 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) 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; @@ -107,6 +146,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) FALSE, 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. @@ -117,6 +157,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) Status = STATUS_PIPE_BROKEN; goto done; } +#endif KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql); } @@ -171,14 +212,7 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) #ifndef NDEBUG DPRINT("Length %d Buffer %x\n",CopyLength,Buffer); - { - DbgPrint("------\n"); - ULONG X; - for (X = 0; X < CopyLength; X++) - DbgPrint("%02x ", ((PUCHAR)Buffer)[X]); - DbgPrint("\n"); - DbgPrint("------\n"); - } + HexDump((PUCHAR)Buffer, CopyLength); #endif Information = CopyLength; @@ -191,6 +225,15 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) 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); @@ -266,19 +309,13 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, Status = STATUS_SUCCESS; Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); -#ifndef NDEBUG - DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset); - { - DbgPrint("------\n"); - ULONG X; - for (X = 0; X < Length; X++) - DbgPrint("%02x ", Buffer[X]); - DbgPrint("\n"); - DbgPrint("------\n"); - } -#endif KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql); +#ifndef NDEBUG + DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset); + HexDump(Buffer, Length); +#endif + while(1) { if (Fcb->WriteQuotaAvailable == 0) @@ -298,6 +335,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, FALSE, 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. @@ -308,6 +346,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, Status = STATUS_PIPE_BROKEN; goto done; } +#endif KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql); } if (Pipe->PipeWriteMode == FILE_PIPE_BYTE_STREAM_MODE)