From f81d856c0088da8d3faad2518649685feb815ccf Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 20 Oct 2001 15:30:07 +0000 Subject: [PATCH] Implemented waiting for server pipe (WaitNamedPipe()). svn path=/trunk/; revision=2305 --- reactos/drivers/fs/np/create.c | 143 ++++++++++++++++++++------------- reactos/drivers/fs/np/fsctrl.c | 67 +++++++++++++-- 2 files changed, 148 insertions(+), 62 deletions(-) diff --git a/reactos/drivers/fs/np/create.c b/reactos/drivers/fs/np/create.c index 6431bc35708..d3379a04a99 100644 --- a/reactos/drivers/fs/np/create.c +++ b/reactos/drivers/fs/np/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.8 2001/07/29 16:40:20 ekohl Exp $ +/* $Id: create.c,v 1.9 2001/10/20 15:30:07 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -28,7 +28,6 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, { PIO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; - NTSTATUS Status; PNPFS_PIPE Pipe; PNPFS_FCB ClientFcb; PNPFS_FCB ServerFcb; @@ -36,13 +35,16 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, PLIST_ENTRY current_entry; PNPFS_DEVICE_EXTENSION DeviceExt; KIRQL oldIrql; + ULONG Disposition; 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); ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB)); if (ClientFcb == NULL) @@ -63,7 +65,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, NPFS_PIPE, PipeListEntry); - if (RtlCompareUnicodeString(&Pipe->PipeName, + if (RtlCompareUnicodeString(&FileObject->FileName, ¤t->PipeName, TRUE) == 0) { @@ -82,8 +84,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); + DPRINT("No pipe found!\n"); - return(STATUS_UNSUCCESSFUL); + return(STATUS_OBJECT_NAME_NOT_FOUND); } Pipe = current; @@ -104,7 +107,20 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, Pipe->ReferenceCount++; KeUnlockMutex(&DeviceExt->PipeListLock); - + + if (Disposition == FILE_OPEN) + { + /* do not connect to listening servers */ + FileObject->FsContext = ClientFcb; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_SUCCESS); + } + /* search for disconnected or listening server fcb */ current_entry = Pipe->ServerFcbListHead.Flink; while (current_entry != &Pipe->ServerFcbListHead) @@ -124,12 +140,14 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, if (current_entry == &Pipe->ServerFcbListHead) { DPRINT("No server fcb found!\n"); - + + FileObject->FsContext = ClientFcb; + Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; - + IoCompleteRequest(Irp, IO_NO_INCREMENT); - + return(STATUS_SUCCESS); } @@ -145,12 +163,12 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, FileObject->FsContext = ClientFcb; - Irp->IoStatus.Status = Status; + Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return(Status); + return(STATUS_SUCCESS); } @@ -295,63 +313,76 @@ NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { - PNPFS_DEVICE_EXTENSION DeviceExt; - PIO_STACK_LOCATION IoStack; - PFILE_OBJECT FileObject; - PNPFS_FCB Fcb; - PNPFS_PIPE Pipe; - KIRQL oldIrql; + PNPFS_DEVICE_EXTENSION DeviceExt; + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PNPFS_FCB Fcb; + PNPFS_PIPE Pipe; + KIRQL oldIrql; - DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); - IoStack = IoGetCurrentIrpStackLocation(Irp); - DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - FileObject = IoStack->FileObject; - Fcb = FileObject->FsContext; - Pipe = Fcb->Pipe; + IoStack = IoGetCurrentIrpStackLocation(Irp); + DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + FileObject = IoStack->FileObject; + Fcb = FileObject->FsContext; - DPRINT("Closing pipe %wZ\n", &Pipe->PipeName); + if (Fcb == NULL) + { + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_SUCCESS); + } + + DPRINT("Fcb %x\n", Fcb); + Pipe = Fcb->Pipe; + + DPRINT("Closing pipe %wZ\n", &Pipe->PipeName); + + KeLockMutex(&DeviceExt->PipeListLock); - KeLockMutex(&DeviceExt->PipeListLock); if (Fcb->PipeEnd == FILE_PIPE_SERVER_END) - { - /* FIXME: Clean up existing connections here ?? */ - Pipe->CurrentInstances--; - } - Pipe->ReferenceCount--; + { + /* FIXME: Clean up existing connections here ?? */ + Pipe->CurrentInstances--; + } + Pipe->ReferenceCount--; - if ((Fcb->PipeEnd == FILE_PIPE_CLIENT_END) - && (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)) - { - Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; - Fcb->OtherSide->OtherSide = NULL; - Fcb->OtherSide = NULL; - Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE; - } + if ((Fcb->PipeEnd == FILE_PIPE_CLIENT_END) + && (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)) + { + Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; + Fcb->OtherSide->OtherSide = NULL; + Fcb->OtherSide = NULL; + Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE; + } - KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql); - RemoveEntryList(&Fcb->FcbListEntry); - KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql); - - ExFreePool(Fcb); - FileObject->FsContext = NULL; + KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql); + RemoveEntryList(&Fcb->FcbListEntry); + KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql); - if (Pipe->ReferenceCount == 0) - { - RtlFreeUnicodeString(&Pipe->PipeName); - RemoveEntryList(&Pipe->PipeListEntry); - ExFreePool(Pipe); - } + ExFreePool(Fcb); + FileObject->FsContext = NULL; - KeUnlockMutex(&DeviceExt->PipeListLock); + if (Pipe->ReferenceCount == 0) + { + RtlFreeUnicodeString(&Pipe->PipeName); + RemoveEntryList(&Pipe->PipeListEntry); + ExFreePool(Pipe); + } - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return(STATUS_SUCCESS); + KeUnlockMutex(&DeviceExt->PipeListLock); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/drivers/fs/np/fsctrl.c b/reactos/drivers/fs/np/fsctrl.c index 02b09fd9a45..915737b0f88 100644 --- a/reactos/drivers/fs/np/fsctrl.c +++ b/reactos/drivers/fs/np/fsctrl.c @@ -1,4 +1,4 @@ -/* $Id: fsctrl.c,v 1.5 2001/07/29 16:40:20 ekohl Exp $ +/* $Id: fsctrl.c,v 1.6 2001/10/20 15:30:07 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -55,7 +55,8 @@ NpfsConnectPipe(PNPFS_FCB Fcb) NPFS_FCB, FcbListEntry); - if (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE) + if ((ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE) + || (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)) { break; } @@ -63,7 +64,8 @@ NpfsConnectPipe(PNPFS_FCB Fcb) current_entry = current_entry->Flink; } - if (current_entry != &Pipe->ClientFcbListHead) + if ((current_entry != &Pipe->ClientFcbListHead) + && (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE)) { /* found a listening client fcb */ DPRINT("Listening client fcb found -- connecting\n"); @@ -82,6 +84,15 @@ NpfsConnectPipe(PNPFS_FCB Fcb) KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE); } + else if ((current_entry != &Pipe->ClientFcbListHead) + && (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)) + { + /* found a disconnected client fcb */ + DPRINT("Disconnected client fcb found - notifying client\n"); + + /* signal client's connect event */ + KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE); + } else { /* no listening client fcb found */ @@ -141,10 +152,54 @@ NpfsDisconnectPipe(PNPFS_FCB Fcb) static NTSTATUS -NpfsWaitPipe(PNPFS_FCB Fcb) +NpfsWaitPipe(PIRP Irp, + PNPFS_FCB Fcb) { + PNPFS_PIPE Pipe; + PLIST_ENTRY current_entry; + PNPFS_FCB ServerFcb; + PNPFS_WAIT_PIPE WaitPipe; + NTSTATUS Status; + DPRINT("NpfsWaitPipe\n"); - return STATUS_NOT_IMPLEMENTED; + + WaitPipe = (PNPFS_WAIT_PIPE)Irp->AssociatedIrp.SystemBuffer; + Pipe = Fcb->Pipe; + + /* search for listening server */ + current_entry = Pipe->ServerFcbListHead.Flink; + while (current_entry != &Pipe->ServerFcbListHead) + { + ServerFcb = CONTAINING_RECORD(current_entry, + NPFS_FCB, + FcbListEntry); + + if (ServerFcb->PipeState == FILE_PIPE_LISTENING_STATE) + break; + + current_entry = current_entry->Flink; + } + + if (current_entry != &Pipe->ServerFcbListHead) + { + /* found a listening server fcb */ + DPRINT("Listening server fcb found -- connecting\n"); + + Status = STATUS_SUCCESS; + } + else + { + /* no listening server fcb found -- wait for one */ + Fcb->PipeState = FILE_PIPE_LISTENING_STATE; + + Status = KeWaitForSingleObject(&Fcb->ConnectEvent, + UserRequest, + KernelMode, + FALSE, + &WaitPipe->Timeout); + } + + return(Status); } @@ -186,7 +241,7 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject, case FSCTL_PIPE_WAIT: DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName); - Status = NpfsWaitPipe(Fcb); + Status = NpfsWaitPipe(Irp, Fcb); break; default: