Implemented waiting for server pipe (WaitNamedPipe()).

svn path=/trunk/; revision=2305
This commit is contained in:
Eric Kohl 2001-10-20 15:30:07 +00:00
parent fc27cfa0c9
commit f81d856c00
2 changed files with 148 additions and 62 deletions

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -28,7 +28,6 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
{ {
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
NTSTATUS Status;
PNPFS_PIPE Pipe; PNPFS_PIPE Pipe;
PNPFS_FCB ClientFcb; PNPFS_FCB ClientFcb;
PNPFS_FCB ServerFcb; PNPFS_FCB ServerFcb;
@ -36,13 +35,16 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PNPFS_DEVICE_EXTENSION DeviceExt; PNPFS_DEVICE_EXTENSION DeviceExt;
KIRQL oldIrql; KIRQL oldIrql;
ULONG Disposition;
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);
ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB)); ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
if (ClientFcb == NULL) if (ClientFcb == NULL)
@ -63,7 +65,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
NPFS_PIPE, NPFS_PIPE,
PipeListEntry); PipeListEntry);
if (RtlCompareUnicodeString(&Pipe->PipeName, if (RtlCompareUnicodeString(&FileObject->FileName,
&current->PipeName, &current->PipeName,
TRUE) == 0) TRUE) == 0)
{ {
@ -82,8 +84,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT("No pipe found!\n");
return(STATUS_UNSUCCESSFUL); return(STATUS_OBJECT_NAME_NOT_FOUND);
} }
Pipe = current; Pipe = current;
@ -104,7 +107,20 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
Pipe->ReferenceCount++; Pipe->ReferenceCount++;
KeUnlockMutex(&DeviceExt->PipeListLock); 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 */ /* search for disconnected or listening server fcb */
current_entry = Pipe->ServerFcbListHead.Flink; current_entry = Pipe->ServerFcbListHead.Flink;
while (current_entry != &Pipe->ServerFcbListHead) while (current_entry != &Pipe->ServerFcbListHead)
@ -124,12 +140,14 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
if (current_entry == &Pipe->ServerFcbListHead) if (current_entry == &Pipe->ServerFcbListHead)
{ {
DPRINT("No server fcb found!\n"); DPRINT("No server fcb found!\n");
FileObject->FsContext = ClientFcb;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -145,12 +163,12 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
FileObject->FsContext = ClientFcb; FileObject->FsContext = ClientFcb;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status); return(STATUS_SUCCESS);
} }
@ -295,63 +313,76 @@ NTSTATUS STDCALL
NpfsClose(PDEVICE_OBJECT DeviceObject, NpfsClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
{ {
PNPFS_DEVICE_EXTENSION DeviceExt; PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PNPFS_FCB Fcb; PNPFS_FCB Fcb;
PNPFS_PIPE Pipe; PNPFS_PIPE Pipe;
KIRQL oldIrql; KIRQL oldIrql;
DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject; FileObject = IoStack->FileObject;
Fcb = FileObject->FsContext; Fcb = FileObject->FsContext;
Pipe = Fcb->Pipe;
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) if (Fcb->PipeEnd == FILE_PIPE_SERVER_END)
{ {
/* FIXME: Clean up existing connections here ?? */ /* FIXME: Clean up existing connections here ?? */
Pipe->CurrentInstances--; Pipe->CurrentInstances--;
} }
Pipe->ReferenceCount--; Pipe->ReferenceCount--;
if ((Fcb->PipeEnd == FILE_PIPE_CLIENT_END) if ((Fcb->PipeEnd == FILE_PIPE_CLIENT_END)
&& (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)) && (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE))
{ {
Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
Fcb->OtherSide->OtherSide = NULL; Fcb->OtherSide->OtherSide = NULL;
Fcb->OtherSide = NULL; Fcb->OtherSide = NULL;
Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE; Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
} }
KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql); KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
RemoveEntryList(&Fcb->FcbListEntry); RemoveEntryList(&Fcb->FcbListEntry);
KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql); KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
ExFreePool(Fcb);
FileObject->FsContext = NULL;
if (Pipe->ReferenceCount == 0) ExFreePool(Fcb);
{ FileObject->FsContext = NULL;
RtlFreeUnicodeString(&Pipe->PipeName);
RemoveEntryList(&Pipe->PipeListEntry);
ExFreePool(Pipe);
}
KeUnlockMutex(&DeviceExt->PipeListLock); if (Pipe->ReferenceCount == 0)
{
RtlFreeUnicodeString(&Pipe->PipeName);
RemoveEntryList(&Pipe->PipeListEntry);
ExFreePool(Pipe);
}
Irp->IoStatus.Status = STATUS_SUCCESS; KeUnlockMutex(&DeviceExt->PipeListLock);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); Irp->IoStatus.Information = 0;
return(STATUS_SUCCESS); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
} }
/* EOF */ /* EOF */

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -55,7 +55,8 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
NPFS_FCB, NPFS_FCB,
FcbListEntry); FcbListEntry);
if (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE) if ((ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE)
|| (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE))
{ {
break; break;
} }
@ -63,7 +64,8 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
current_entry = current_entry->Flink; 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 */ /* found a listening client fcb */
DPRINT("Listening client fcb found -- connecting\n"); DPRINT("Listening client fcb found -- connecting\n");
@ -82,6 +84,15 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE); 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 else
{ {
/* no listening client fcb found */ /* no listening client fcb found */
@ -141,10 +152,54 @@ NpfsDisconnectPipe(PNPFS_FCB Fcb)
static NTSTATUS 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"); 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: case FSCTL_PIPE_WAIT:
DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName); DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
Status = NpfsWaitPipe(Fcb); Status = NpfsWaitPipe(Irp, Fcb);
break; break;
default: default: