- Fixed various problems (hangs/crashes) with connecting, disconnecting and closing named pipes.

svn path=/trunk/; revision=9312
This commit is contained in:
Filip Navara 2004-05-05 18:30:16 +00:00
parent 65093d7a1e
commit 333e6a58cb
4 changed files with 215 additions and 242 deletions

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.18 2004/04/12 14:46:02 navaraf Exp $ /* $Id: create.c,v 1.19 2004/05/05 18:30:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -19,18 +19,18 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL NTSTATUS STDCALL
NpfsCreate(PDEVICE_OBJECT DeviceObject, NpfsCreate(
PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
{ {
PLIST_ENTRY CurrentEntry;
PNPFS_PIPE Current;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PNPFS_PIPE Pipe; PNPFS_PIPE Pipe;
PNPFS_FCB ClientFcb; PNPFS_FCB ClientFcb;
PNPFS_FCB ServerFcb; PNPFS_FCB ServerFcb;
PNPFS_PIPE current;
PLIST_ENTRY current_entry;
PNPFS_DEVICE_EXTENSION DeviceExt; PNPFS_DEVICE_EXTENSION DeviceExt;
KIRQL oldIrql;
ULONG Disposition; ULONG Disposition;
DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
@ -42,156 +42,154 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
DPRINT("FileObject %p\n", FileObject); DPRINT("FileObject %p\n", FileObject);
DPRINT("FileName %wZ\n", &FileObject->FileName); DPRINT("FileName %wZ\n", &FileObject->FileName);
ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
if (ClientFcb == NULL)
{
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); /*
DPRINT("No memory!\n"); * Step 1. Find the pipe we're trying to open.
*/
return(STATUS_NO_MEMORY);
}
KeLockMutex(&DeviceExt->PipeListLock); KeLockMutex(&DeviceExt->PipeListLock);
current_entry = DeviceExt->PipeListHead.Flink; CurrentEntry = DeviceExt->PipeListHead.Flink;
while (current_entry != &DeviceExt->PipeListHead) while (CurrentEntry != &DeviceExt->PipeListHead)
{ {
current = CONTAINING_RECORD(current_entry, Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE, PipeListEntry);
NPFS_PIPE, if (RtlCompareUnicodeString(
PipeListEntry); &FileObject->FileName,
&Current->PipeName,
if (RtlCompareUnicodeString(&FileObject->FileName,
&current->PipeName,
TRUE) == 0) TRUE) == 0)
{ {
break; break;
} }
CurrentEntry = CurrentEntry->Flink;
current_entry = current_entry->Flink;
} }
if (current_entry == &DeviceExt->PipeListHead) /* Not found, bail out with error. */
if (CurrentEntry == &DeviceExt->PipeListHead)
{ {
ExFreePool(ClientFcb); DPRINT("No pipe found!\n");
KeUnlockMutex(&DeviceExt->PipeListLock);
Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
KeUnlockMutex(&DeviceExt->PipeListLock); KeUnlockMutex(&DeviceExt->PipeListLock);
Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND; /* Save the pipe we found for later use. */
Irp->IoStatus.Information = 0; Pipe = Current;
IoCompleteRequest(Irp, IO_NO_INCREMENT); /*
DPRINT("No pipe found!\n"); * Step 2. Search for listening server FCB.
*/
return(STATUS_OBJECT_NAME_NOT_FOUND); /*
* Acquire the lock for FCB lists. From now on no modifications to the
* FCB lists are allowed, because it can cause various misconsistencies.
*/
KeLockMutex(&Pipe->FcbListLock);
CurrentEntry = Pipe->ServerFcbListHead.Flink;
while (CurrentEntry != &Pipe->ServerFcbListHead)
{
ServerFcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, FcbListEntry);
if (ServerFcb->PipeState == FILE_PIPE_LISTENING_STATE)
{
DPRINT("Server found! Fcb %p\n", ServerFcb);
break;
}
CurrentEntry = CurrentEntry->Flink;
} }
Pipe = current; /* Not found, bail out with error for FILE_OPEN requests. */
if (CurrentEntry == &Pipe->ServerFcbListHead)
{
DPRINT("No server fcb found!\n");
if (Disposition == FILE_OPEN)
{
KeUnlockMutex(&Pipe->FcbListLock);
Irp->IoStatus.Status = STATUS_PIPE_BUSY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_PIPE_BUSY;
}
ServerFcb = NULL;
}
/*
* Step 3. Create the client FCB.
*/
ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
if (ClientFcb == NULL)
{
DPRINT("No memory!\n");
KeUnlockMutex(&Pipe->FcbListLock);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
}
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 = FILE_PIPE_DISCONNECTED_STATE; ClientFcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
/* initialize data list */ /* Initialize data list. */
if (Pipe->InboundQuota) if (Pipe->InboundQuota)
{ {
ClientFcb->Data = ExAllocatePool(NonPagedPool, Pipe->InboundQuota); ClientFcb->Data = ExAllocatePool(NonPagedPool, Pipe->InboundQuota);
if (ClientFcb->Data == NULL) if (ClientFcb->Data == NULL)
{ {
ExFreePool(ClientFcb);
KeUnlockMutex(&DeviceExt->PipeListLock);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT("No memory!\n"); DPRINT("No memory!\n");
ExFreePool(ClientFcb);
return(STATUS_NO_MEMORY); KeUnlockMutex(&Pipe->FcbListLock);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
} }
} }
else else
{ {
ClientFcb->Data = NULL; ClientFcb->Data = NULL;
} }
ClientFcb->ReadPtr = ClientFcb->Data; ClientFcb->ReadPtr = ClientFcb->Data;
ClientFcb->WritePtr = ClientFcb->Data; ClientFcb->WritePtr = ClientFcb->Data;
ClientFcb->ReadDataAvailable = 0; ClientFcb->ReadDataAvailable = 0;
ClientFcb->WriteQuotaAvailable = Pipe->InboundQuota; ClientFcb->WriteQuotaAvailable = Pipe->InboundQuota;
ClientFcb->MaxDataLength = Pipe->InboundQuota; ClientFcb->MaxDataLength = Pipe->InboundQuota;
KeInitializeSpinLock(&ClientFcb->DataListLock); KeInitializeSpinLock(&ClientFcb->DataListLock);
KeInitializeEvent(&ClientFcb->ConnectEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE);
KeInitializeEvent(&ClientFcb->ConnectEvent, /*
SynchronizationEvent, * Step 4. Add the client FCB to a list and connect it if necessary.
FALSE); */
KeInitializeEvent(&ClientFcb->Event, /* Add the client FCB to the pipe FCB list. */
SynchronizationEvent,
FALSE);
KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
InsertTailList(&Pipe->ClientFcbListHead, &ClientFcb->FcbListEntry); InsertTailList(&Pipe->ClientFcbListHead, &ClientFcb->FcbListEntry);
KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
Pipe->ReferenceCount++; if (ServerFcb)
KeUnlockMutex(&DeviceExt->PipeListLock);
/* search for listening server fcb */
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)
{
DPRINT("Server found! Fcb %p\n", ServerFcb);
break;
}
current_entry = current_entry->Flink;
}
if (current_entry == &Pipe->ServerFcbListHead)
{
DPRINT("No server fcb found!\n");
FileObject->FsContext = ClientFcb;
if (Disposition == FILE_OPEN)
{
Irp->IoStatus.Status = STATUS_PIPE_BUSY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_PIPE_BUSY;
}
else
{
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
}
ClientFcb->OtherSide = ServerFcb; ClientFcb->OtherSide = ServerFcb;
ServerFcb->OtherSide = ClientFcb; ServerFcb->OtherSide = ClientFcb;
ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE; ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
ServerFcb->PipeState = FILE_PIPE_CONNECTED_STATE; ServerFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
/* FIXME: create data queue(s) */ /* Wake server thread */
DPRINT("Setting the ConnectEvent for %x\n", ServerFcb);
/* wake server thread */
KeSetEvent(&ServerFcb->ConnectEvent, 0, FALSE); KeSetEvent(&ServerFcb->ConnectEvent, 0, FALSE);
}
KeUnlockMutex(&Pipe->FcbListLock);
FileObject->FsContext = ClientFcb; FileObject->FsContext = ClientFcb;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT("Success!\n"); DPRINT("Success!\n");
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
@ -204,7 +202,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
PNPFS_DEVICE_EXTENSION DeviceExt; PNPFS_DEVICE_EXTENSION DeviceExt;
PNPFS_PIPE Pipe; PNPFS_PIPE Pipe;
PNPFS_FCB Fcb; PNPFS_FCB Fcb;
KIRQL oldIrql;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PNPFS_PIPE current; PNPFS_PIPE current;
PIO_PIPE_CREATE_BUFFER Buffer; PIO_PIPE_CREATE_BUFFER Buffer;
@ -262,6 +259,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
if (Pipe->CurrentInstances >= Pipe->MaximumInstances) if (Pipe->CurrentInstances >= Pipe->MaximumInstances)
{ {
DPRINT("Out of instances.\n");
ExFreePool(Fcb); ExFreePool(Fcb);
Irp->IoStatus.Status = STATUS_PIPE_BUSY; Irp->IoStatus.Status = STATUS_PIPE_BUSY;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -272,6 +270,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
if (Pipe->MaximumInstances != Buffer->MaxInstances || if (Pipe->MaximumInstances != Buffer->MaxInstances ||
Pipe->TimeOut.QuadPart != Buffer->TimeOut.QuadPart) Pipe->TimeOut.QuadPart != Buffer->TimeOut.QuadPart)
{ {
DPRINT("Asked for invalid pipe mode.\n");
ExFreePool(Fcb); ExFreePool(Fcb);
Irp->IoStatus.Status = STATUS_ACCESS_DENIED; Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -301,10 +300,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
return(STATUS_NO_MEMORY); return(STATUS_NO_MEMORY);
} }
Pipe->ReferenceCount = 0;
InitializeListHead(&Pipe->ServerFcbListHead); InitializeListHead(&Pipe->ServerFcbListHead);
InitializeListHead(&Pipe->ClientFcbListHead); InitializeListHead(&Pipe->ClientFcbListHead);
KeInitializeSpinLock(&Pipe->FcbListLock); KeInitializeMutex(&Pipe->FcbListLock, 0);
Pipe->PipeType = Buffer->WriteModeMessage ? FILE_PIPE_MESSAGE_TYPE : FILE_PIPE_BYTE_STREAM_TYPE; Pipe->PipeType = Buffer->WriteModeMessage ? FILE_PIPE_MESSAGE_TYPE : FILE_PIPE_BYTE_STREAM_TYPE;
Pipe->PipeWriteMode = Buffer->WriteModeMessage ? FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE; Pipe->PipeWriteMode = Buffer->WriteModeMessage ? FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE;
@ -396,12 +394,11 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
Fcb->MaxDataLength = Pipe->OutboundQuota; Fcb->MaxDataLength = Pipe->OutboundQuota;
KeInitializeSpinLock(&Fcb->DataListLock); KeInitializeSpinLock(&Fcb->DataListLock);
Pipe->ReferenceCount++;
Pipe->CurrentInstances++; Pipe->CurrentInstances++;
KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql); KeLockMutex(&Pipe->FcbListLock);
InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry); InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry);
KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql); KeUnlockMutex(&Pipe->FcbListLock);
Fcb->Pipe = Pipe; Fcb->Pipe = Pipe;
Fcb->PipeEnd = FILE_PIPE_SERVER_END; Fcb->PipeEnd = FILE_PIPE_SERVER_END;
@ -426,7 +423,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
NTSTATUS STDCALL NTSTATUS STDCALL
NpfsClose(PDEVICE_OBJECT DeviceObject, NpfsClose(
PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
{ {
PNPFS_DEVICE_EXTENSION DeviceExt; PNPFS_DEVICE_EXTENSION DeviceExt;
@ -434,7 +432,7 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PNPFS_FCB Fcb; PNPFS_FCB Fcb;
PNPFS_PIPE Pipe; PNPFS_PIPE Pipe;
KIRQL oldIrql; BOOL Server;
DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
@ -447,10 +445,8 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
{ {
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);
} }
DPRINT("Fcb %x\n", Fcb); DPRINT("Fcb %x\n", Fcb);
@ -458,90 +454,57 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
DPRINT("Closing pipe %wZ\n", &Pipe->PipeName); DPRINT("Closing pipe %wZ\n", &Pipe->PipeName);
KeLockMutex(&DeviceExt->PipeListLock); KeLockMutex(&Pipe->FcbListLock);
if (Fcb->PipeEnd == FILE_PIPE_SERVER_END) Server = (Fcb->PipeEnd == FILE_PIPE_SERVER_END);
if (Server)
{ {
/* FIXME: Clean up existing connections here ?? */ /* FIXME: Clean up existing connections here ?? */
DPRINT("Server\n"); DPRINT("Server\n");
Pipe->CurrentInstances--; Pipe->CurrentInstances--;
} else
{
DPRINT("Client\n");
}
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE) if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
{ {
if (Fcb->OtherSide) if (Fcb->OtherSide)
{ {
Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
/* Signaling the write event. If is possible that an other /*
* Signaling the write event. If is possible that an other
* thread waits of an empty buffer. * thread waits of an empty buffer.
*/ */
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
} }
Fcb->PipeState = 0; Fcb->PipeState = 0;
} }
}
Pipe->ReferenceCount--;
if (Fcb->PipeEnd == FILE_PIPE_CLIENT_END)
{
DPRINT("Client\n");
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
if (Fcb->OtherSide)
{
Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
/* Signaling the read event. If is possible that an other
* thread waits of read data.
*/
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
}
Fcb->PipeState = 0;
}
}
FileObject->FsContext = NULL; FileObject->FsContext = NULL;
#if 0
DPRINT("%x\n", Pipe->ReferenceCount);
if (Pipe->ReferenceCount == 0)
#else
if (Fcb->PipeEnd == FILE_PIPE_SERVER_END &&
Fcb->Pipe->CurrentInstances == 0)
#endif
{
KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
if (Fcb->OtherSide)
{
RemoveEntryList(&Fcb->OtherSide->FcbListEntry);
}
RemoveEntryList(&Fcb->FcbListEntry); RemoveEntryList(&Fcb->FcbListEntry);
KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
if (Fcb->OtherSide)
{
if (Fcb->OtherSide->Data)
{
ExFreePool(Fcb->OtherSide->Data);
}
ExFreePool(Fcb->OtherSide);
}
if (Fcb->Data) if (Fcb->Data)
{
ExFreePool(Fcb->Data); ExFreePool(Fcb->Data);
}
ExFreePool(Fcb); ExFreePool(Fcb);
KeUnlockMutex(&Pipe->FcbListLock);
if (Server && Pipe->CurrentInstances == 0)
{
RtlFreeUnicodeString(&Pipe->PipeName); RtlFreeUnicodeString(&Pipe->PipeName);
KeLockMutex(&DeviceExt->PipeListLock);
RemoveEntryList(&Pipe->PipeListEntry); RemoveEntryList(&Pipe->PipeListEntry);
KeUnlockMutex(&DeviceExt->PipeListLock);
ExFreePool(Pipe); ExFreePool(Pipe);
} }
KeUnlockMutex(&DeviceExt->PipeListLock);
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;
} }
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: fsctrl.c,v 1.14 2004/04/12 13:03:29 navaraf Exp $ /* $Id: fsctrl.c,v 1.15 2004/05/05 18:30:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -25,12 +25,14 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PNPFS_FCB ClientFcb; PNPFS_FCB ClientFcb;
NTSTATUS Status; NTSTATUS Status;
KIRQL oldIrql;
DPRINT("NpfsConnectPipe()\n"); DPRINT("NpfsConnectPipe()\n");
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE) if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
KeResetEvent(&Fcb->ConnectEvent);
return STATUS_PIPE_CONNECTED; return STATUS_PIPE_CONNECTED;
}
if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE) if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
return STATUS_PIPE_CLOSING; return STATUS_PIPE_CLOSING;
@ -41,7 +43,7 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
/* search for a listening client fcb */ /* search for a listening client fcb */
KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql); KeLockMutex(&Pipe->FcbListLock);
current_entry = Pipe->ClientFcbListHead.Flink; current_entry = Pipe->ClientFcbListHead.Flink;
while (current_entry != &Pipe->ClientFcbListHead) while (current_entry != &Pipe->ClientFcbListHead)
{ {
@ -70,20 +72,22 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
Fcb->PipeState = FILE_PIPE_CONNECTED_STATE; Fcb->PipeState = FILE_PIPE_CONNECTED_STATE;
ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE; ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql); KeUnlockMutex(&Pipe->FcbListLock);
/* FIXME: create and initialize data queues */ /* FIXME: create and initialize data queues */
/* signal client's connect event */ /* signal client's connect event */
DPRINT("Setting the ConnectEvent for %x\n", ClientFcb);
KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
Status = STATUS_PIPE_CONNECTED;
} }
else else
{ {
/* no listening client fcb found */ /* no listening client fcb found */
DPRINT("No listening client fcb found -- waiting for client\n"); DPRINT("No listening client fcb found -- waiting for client\n");
KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql); KeUnlockMutex(&Pipe->FcbListLock);
Fcb->PipeState = FILE_PIPE_LISTENING_STATE; Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
@ -93,13 +97,18 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
FALSE, FALSE,
NULL); NULL);
if (NT_SUCCESS(Status))
{
Status = STATUS_PIPE_CONNECTED;
Fcb->PipeState = FILE_PIPE_CONNECTED_STATE;
}
DPRINT("Finished waiting! Status: %x\n", Status); DPRINT("Finished waiting! Status: %x\n", Status);
} }
DPRINT("Client Fcb: %p\n", Fcb->OtherSide); DPRINT("Client Fcb: %p\n", Fcb->OtherSide);
return STATUS_PIPE_CONNECTED; return Status;
} }
@ -114,6 +123,7 @@ NpfsDisconnectPipe(PNPFS_FCB Fcb)
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE) if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
{ {
Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE; Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
/* FIXME: Shouldn't this be FILE_PIPE_CLOSING_STATE? */
Fcb->OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE; Fcb->OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
/* FIXME: remove data queue(s) */ /* FIXME: remove data queue(s) */
@ -128,6 +138,7 @@ NpfsDisconnectPipe(PNPFS_FCB Fcb)
if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE) if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
{ {
Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE; Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
Fcb->OtherSide = NULL;
/* FIXME: remove data queue(s) */ /* FIXME: remove data queue(s) */

View file

@ -1,4 +1,4 @@
/* $Id: npfs.h,v 1.15 2004/04/12 13:03:29 navaraf Exp $ */ /* $Id: npfs.h,v 1.16 2004/05/05 18:30:16 navaraf Exp $ */
#ifndef __SERVICES_FS_NP_NPFS_H #ifndef __SERVICES_FS_NP_NPFS_H
#define __SERVICES_FS_NP_NPFS_H #define __SERVICES_FS_NP_NPFS_H
@ -17,10 +17,9 @@ typedef struct
{ {
UNICODE_STRING PipeName; UNICODE_STRING PipeName;
LIST_ENTRY PipeListEntry; LIST_ENTRY PipeListEntry;
KSPIN_LOCK FcbListLock; KMUTEX FcbListLock;
LIST_ENTRY ServerFcbListHead; LIST_ENTRY ServerFcbListHead;
LIST_ENTRY ClientFcbListHead; LIST_ENTRY ClientFcbListHead;
ULONG ReferenceCount;
ULONG PipeType; ULONG PipeType;
ULONG PipeReadMode; ULONG PipeReadMode;
ULONG PipeWriteMode; ULONG PipeWriteMode;

View file

@ -1,4 +1,4 @@
/* $Id: rw.c,v 1.12 2004/04/12 13:03:29 navaraf Exp $ /* $Id: rw.c,v 1.13 2004/05/05 18:30:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -290,7 +290,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status); DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status);
KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql); KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
} }
if (Pipe->PipeReadMode == 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)