mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 20:36:35 +00:00
- Fixed various problems (hangs/crashes) with connecting, disconnecting and closing named pipes.
svn path=/trunk/; revision=9312
This commit is contained in:
parent
65093d7a1e
commit
333e6a58cb
4 changed files with 215 additions and 242 deletions
|
@ -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,
|
|
||||||
¤t->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 */
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue