2005-01-01 14:54:25 +00:00
|
|
|
/* $Id$
|
1999-12-04 20:58:45 +00:00
|
|
|
*
|
1999-11-24 11:51:55 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: services/fs/np/create.c
|
|
|
|
* PURPOSE: Named pipe filesystem
|
|
|
|
* PROGRAMMER: David Welch <welch@cwcom.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2002-09-08 10:23:54 +00:00
|
|
|
#include <ddk/ntddk.h>
|
|
|
|
|
2001-05-01 11:09:01 +00:00
|
|
|
#include "npfs.h"
|
|
|
|
|
2001-10-21 18:58:32 +00:00
|
|
|
#define NDEBUG
|
2001-05-01 11:09:01 +00:00
|
|
|
#include <debug.h>
|
1999-11-24 11:51:55 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2004-10-11 12:37:04 +00:00
|
|
|
static PNPFS_PIPE
|
|
|
|
NpfsFindPipe(PNPFS_DEVICE_EXTENSION DeviceExt,
|
|
|
|
PUNICODE_STRING PipeName)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PNPFS_PIPE Pipe;
|
|
|
|
|
|
|
|
CurrentEntry = DeviceExt->PipeListHead.Flink;
|
|
|
|
while (CurrentEntry != &DeviceExt->PipeListHead)
|
|
|
|
{
|
|
|
|
Pipe = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE, PipeListEntry);
|
|
|
|
if (RtlCompareUnicodeString(PipeName,
|
|
|
|
&Pipe->PipeName,
|
|
|
|
TRUE) == 0)
|
|
|
|
{
|
2004-10-14 11:49:55 +00:00
|
|
|
DPRINT("<%wZ> = <%wZ>\n", PipeName, &Pipe->PipeName);
|
2004-10-11 12:37:04 +00:00
|
|
|
return Pipe;
|
|
|
|
}
|
|
|
|
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static PNPFS_FCB
|
|
|
|
NpfsFindListeningServerInstance(PNPFS_PIPE Pipe)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PNPFS_FCB ServerFcb;
|
|
|
|
|
|
|
|
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);
|
|
|
|
return ServerFcb;
|
|
|
|
}
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-01 11:09:01 +00:00
|
|
|
NTSTATUS STDCALL
|
2004-12-23 23:58:44 +00:00
|
|
|
NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
|
|
|
PIRP Irp)
|
1999-11-24 11:51:55 +00:00
|
|
|
{
|
2004-12-23 23:58:44 +00:00
|
|
|
PIO_STACK_LOCATION IoStack;
|
|
|
|
PFILE_OBJECT FileObject;
|
|
|
|
PNPFS_PIPE Pipe;
|
|
|
|
PNPFS_FCB ClientFcb;
|
2004-12-30 12:34:27 +00:00
|
|
|
PNPFS_FCB ServerFcb = NULL;
|
2004-12-23 23:58:44 +00:00
|
|
|
PNPFS_DEVICE_EXTENSION DeviceExt;
|
2004-12-30 16:15:46 +00:00
|
|
|
BOOLEAN SpecialAccess;
|
2004-12-23 23:58:44 +00:00
|
|
|
|
|
|
|
DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
|
|
|
|
|
|
|
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
FileObject = IoStack->FileObject;
|
|
|
|
DPRINT("FileObject %p\n", FileObject);
|
|
|
|
DPRINT("FileName %wZ\n", &FileObject->FileName);
|
|
|
|
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
|
2004-12-30 16:15:46 +00:00
|
|
|
SpecialAccess = ((IoStack->Parameters.Create.ShareAccess & 3) == 3);
|
|
|
|
if (SpecialAccess)
|
2004-12-30 12:34:27 +00:00
|
|
|
{
|
|
|
|
DPRINT("NpfsCreate() open client end for special use!\n");
|
|
|
|
}
|
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
/*
|
|
|
|
* Step 1. Find the pipe we're trying to open.
|
|
|
|
*/
|
|
|
|
KeLockMutex(&DeviceExt->PipeListLock);
|
|
|
|
Pipe = NpfsFindPipe(DeviceExt,
|
|
|
|
&FileObject->FileName);
|
|
|
|
if (Pipe == NULL)
|
|
|
|
{
|
2004-10-11 12:37:04 +00:00
|
|
|
/* Not found, bail out with error. */
|
2004-05-05 18:30:16 +00:00
|
|
|
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;
|
2004-12-23 23:58:44 +00:00
|
|
|
}
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
KeUnlockMutex(&DeviceExt->PipeListLock);
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
/*
|
|
|
|
* Step 2. Search for listening server FCB.
|
|
|
|
*/
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
/*
|
|
|
|
* 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);
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-30 16:15:46 +00:00
|
|
|
if (!SpecialAccess)
|
2004-12-23 23:58:44 +00:00
|
|
|
{
|
2004-12-30 12:34:27 +00:00
|
|
|
ServerFcb = NpfsFindListeningServerInstance(Pipe);
|
|
|
|
if (ServerFcb == NULL)
|
2004-12-23 23:58:44 +00:00
|
|
|
{
|
2004-12-30 12:34:27 +00:00
|
|
|
/* Not found, bail out with error for FILE_OPEN requests. */
|
|
|
|
DPRINT("No listening server fcb found!\n");
|
2004-12-23 23:58:44 +00:00
|
|
|
KeUnlockMutex(&Pipe->FcbListLock);
|
|
|
|
Irp->IoStatus.Status = STATUS_PIPE_BUSY;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_PIPE_BUSY;
|
|
|
|
}
|
|
|
|
}
|
2004-12-30 12:34:27 +00:00
|
|
|
else if (IsListEmpty(&Pipe->ServerFcbListHead))
|
|
|
|
{
|
|
|
|
DPRINT("No server fcb found!\n");
|
|
|
|
KeUnlockMutex(&Pipe->FcbListLock);
|
|
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
/*
|
|
|
|
* Step 3. Create the client FCB.
|
|
|
|
*/
|
|
|
|
ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
|
|
|
|
if (ClientFcb == NULL)
|
|
|
|
{
|
2004-05-05 18:30:16 +00:00
|
|
|
DPRINT("No memory!\n");
|
|
|
|
KeUnlockMutex(&Pipe->FcbListLock);
|
|
|
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_NO_MEMORY;
|
2004-12-23 23:58:44 +00:00
|
|
|
}
|
|
|
|
|
2005-01-01 14:54:25 +00:00
|
|
|
ClientFcb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
|
2004-12-23 23:58:44 +00:00
|
|
|
ClientFcb->Pipe = Pipe;
|
|
|
|
ClientFcb->PipeEnd = FILE_PIPE_CLIENT_END;
|
|
|
|
ClientFcb->OtherSide = NULL;
|
2004-12-30 16:15:46 +00:00
|
|
|
ClientFcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
|
2004-12-23 23:58:44 +00:00
|
|
|
|
|
|
|
/* Initialize data list. */
|
|
|
|
if (Pipe->InboundQuota)
|
|
|
|
{
|
2004-05-05 18:30:16 +00:00
|
|
|
ClientFcb->Data = ExAllocatePool(NonPagedPool, Pipe->InboundQuota);
|
|
|
|
if (ClientFcb->Data == NULL)
|
2004-12-23 23:58:44 +00:00
|
|
|
{
|
|
|
|
DPRINT("No memory!\n");
|
|
|
|
ExFreePool(ClientFcb);
|
|
|
|
KeUnlockMutex(&Pipe->FcbListLock);
|
|
|
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-05-05 18:30:16 +00:00
|
|
|
ClientFcb->Data = NULL;
|
2004-12-23 23:58:44 +00:00
|
|
|
}
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
ClientFcb->ReadPtr = ClientFcb->Data;
|
|
|
|
ClientFcb->WritePtr = ClientFcb->Data;
|
|
|
|
ClientFcb->ReadDataAvailable = 0;
|
|
|
|
ClientFcb->WriteQuotaAvailable = Pipe->InboundQuota;
|
|
|
|
ClientFcb->MaxDataLength = Pipe->InboundQuota;
|
|
|
|
KeInitializeSpinLock(&ClientFcb->DataListLock);
|
|
|
|
KeInitializeEvent(&ClientFcb->ConnectEvent, SynchronizationEvent, FALSE);
|
|
|
|
KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE);
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
/*
|
2005-01-08 14:54:59 +00:00
|
|
|
* Step 4. Add the client FCB to a list and connect it if possible.
|
2004-12-23 23:58:44 +00:00
|
|
|
*/
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
/* Add the client FCB to the pipe FCB list. */
|
|
|
|
InsertTailList(&Pipe->ClientFcbListHead, &ClientFcb->FcbListEntry);
|
2001-10-20 15:30:07 +00:00
|
|
|
|
2005-01-08 14:54:59 +00:00
|
|
|
/* Connect to listening server side */
|
|
|
|
if (ServerFcb)
|
2004-12-23 23:58:44 +00:00
|
|
|
{
|
2004-05-05 18:30:16 +00:00
|
|
|
ClientFcb->OtherSide = ServerFcb;
|
|
|
|
ServerFcb->OtherSide = ClientFcb;
|
|
|
|
ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
|
|
|
|
ServerFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
|
|
|
|
|
|
|
|
/* Wake server thread */
|
|
|
|
DPRINT("Setting the ConnectEvent for %x\n", ServerFcb);
|
|
|
|
KeSetEvent(&ServerFcb->ConnectEvent, 0, FALSE);
|
2004-12-23 23:58:44 +00:00
|
|
|
}
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
KeUnlockMutex(&Pipe->FcbListLock);
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
FileObject->FsContext = ClientFcb;
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2004-05-05 18:30:16 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
DPRINT("Success!\n");
|
2004-10-11 12:37:04 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-03-26 22:00:10 +00:00
|
|
|
}
|
|
|
|
|
2001-05-10 23:38:31 +00:00
|
|
|
|
2001-05-01 11:09:01 +00:00
|
|
|
NTSTATUS STDCALL
|
|
|
|
NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|
|
|
PIRP Irp)
|
2000-03-26 22:00:10 +00:00
|
|
|
{
|
|
|
|
PIO_STACK_LOCATION IoStack;
|
|
|
|
PFILE_OBJECT FileObject;
|
|
|
|
PNPFS_DEVICE_EXTENSION DeviceExt;
|
2000-05-13 13:51:08 +00:00
|
|
|
PNPFS_PIPE Pipe;
|
|
|
|
PNPFS_FCB Fcb;
|
2004-11-01 22:54:24 +00:00
|
|
|
PNAMED_PIPE_CREATE_PARAMETERS Buffer;
|
2004-12-23 23:58:44 +00:00
|
|
|
BOOLEAN NewPipe = FALSE;
|
|
|
|
|
2003-01-19 01:13:04 +00:00
|
|
|
DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2000-03-26 22:00:10 +00:00
|
|
|
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
FileObject = IoStack->FileObject;
|
2001-06-12 12:35:42 +00:00
|
|
|
DPRINT("FileObject %p\n", FileObject);
|
|
|
|
DPRINT("Pipe name %wZ\n", &FileObject->FileName);
|
2004-12-23 23:58:44 +00:00
|
|
|
|
|
|
|
Buffer = IoStack->Parameters.CreatePipe.Parameters;
|
|
|
|
|
2004-04-12 13:03:29 +00:00
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
|
|
|
|
Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
|
|
|
|
if (Fcb == NULL)
|
1999-11-24 11:51:55 +00:00
|
|
|
{
|
2000-03-26 22:00:10 +00:00
|
|
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2004-04-12 13:03:29 +00:00
|
|
|
return STATUS_NO_MEMORY;
|
1999-11-24 11:51:55 +00:00
|
|
|
}
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2005-01-01 14:54:25 +00:00
|
|
|
Fcb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
|
2004-04-12 13:03:29 +00:00
|
|
|
KeLockMutex(&DeviceExt->PipeListLock);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* First search for existing Pipe with the same name.
|
|
|
|
*/
|
2004-12-23 23:58:44 +00:00
|
|
|
Pipe = NpfsFindPipe(DeviceExt,
|
|
|
|
&FileObject->FileName);
|
|
|
|
if (Pipe != NULL)
|
2000-05-13 13:51:08 +00:00
|
|
|
{
|
2004-04-12 13:03:29 +00:00
|
|
|
/*
|
|
|
|
* Found Pipe with the same name. Check if we are
|
|
|
|
* allowed to use it.
|
|
|
|
*/
|
|
|
|
KeUnlockMutex(&DeviceExt->PipeListLock);
|
2001-05-01 11:09:01 +00:00
|
|
|
|
2004-04-12 13:03:29 +00:00
|
|
|
if (Pipe->CurrentInstances >= Pipe->MaximumInstances)
|
|
|
|
{
|
2004-05-05 18:30:16 +00:00
|
|
|
DPRINT("Out of instances.\n");
|
2004-04-12 13:03:29 +00:00
|
|
|
ExFreePool(Fcb);
|
|
|
|
Irp->IoStatus.Status = STATUS_PIPE_BUSY;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_PIPE_BUSY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Check pipe modes also! */
|
2004-11-01 22:54:24 +00:00
|
|
|
if (Pipe->MaximumInstances != Buffer->MaximumInstances ||
|
|
|
|
Pipe->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart)
|
2004-04-12 13:03:29 +00:00
|
|
|
{
|
2004-05-05 18:30:16 +00:00
|
|
|
DPRINT("Asked for invalid pipe mode.\n");
|
2004-04-12 13:03:29 +00:00
|
|
|
ExFreePool(Fcb);
|
|
|
|
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
}
|
2001-05-01 11:09:01 +00:00
|
|
|
}
|
2004-04-12 13:03:29 +00:00
|
|
|
else
|
2003-06-21 19:55:55 +00:00
|
|
|
{
|
2004-12-23 23:58:44 +00:00
|
|
|
NewPipe = TRUE;
|
2004-04-12 13:03:29 +00:00
|
|
|
Pipe = ExAllocatePool(NonPagedPool, sizeof(NPFS_PIPE));
|
|
|
|
if (Pipe == NULL)
|
2003-06-21 19:55:55 +00:00
|
|
|
{
|
2004-04-12 13:03:29 +00:00
|
|
|
KeUnlockMutex(&DeviceExt->PipeListLock);
|
|
|
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_NO_MEMORY;
|
2003-06-21 19:55:55 +00:00
|
|
|
}
|
2004-12-23 23:58:44 +00:00
|
|
|
|
|
|
|
if (RtlCreateUnicodeString(&Pipe->PipeName, FileObject->FileName.Buffer) == FALSE)
|
2004-04-12 13:03:29 +00:00
|
|
|
{
|
|
|
|
KeUnlockMutex(&DeviceExt->PipeListLock);
|
|
|
|
ExFreePool(Pipe);
|
|
|
|
ExFreePool(Fcb);
|
|
|
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2004-12-23 23:58:44 +00:00
|
|
|
return STATUS_NO_MEMORY;
|
2004-04-12 13:03:29 +00:00
|
|
|
}
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2004-04-12 13:03:29 +00:00
|
|
|
InitializeListHead(&Pipe->ServerFcbListHead);
|
|
|
|
InitializeListHead(&Pipe->ClientFcbListHead);
|
2004-05-05 18:30:16 +00:00
|
|
|
KeInitializeMutex(&Pipe->FcbListLock, 0);
|
2004-04-12 13:03:29 +00:00
|
|
|
|
2005-01-03 13:50:04 +00:00
|
|
|
Pipe->PipeType = Buffer->NamedPipeType;
|
|
|
|
Pipe->WriteMode = Buffer->ReadMode;
|
|
|
|
Pipe->ReadMode = Buffer->ReadMode;
|
|
|
|
Pipe->CompletionMode = Buffer->CompletionMode;
|
|
|
|
Pipe->PipeConfiguration = IoStack->Parameters.CreatePipe.Options & 0x3;
|
2004-11-01 22:54:24 +00:00
|
|
|
Pipe->MaximumInstances = Buffer->MaximumInstances;
|
2004-04-12 13:03:29 +00:00
|
|
|
Pipe->CurrentInstances = 0;
|
2004-11-01 22:54:24 +00:00
|
|
|
Pipe->TimeOut = Buffer->DefaultTimeout;
|
2004-04-12 13:03:29 +00:00
|
|
|
if (!(IoStack->Parameters.Create.Options & FILE_PIPE_OUTBOUND) ||
|
|
|
|
IoStack->Parameters.Create.Options & FILE_PIPE_FULL_DUPLEX)
|
2003-06-21 19:55:55 +00:00
|
|
|
{
|
2004-11-01 22:54:24 +00:00
|
|
|
if (Buffer->InboundQuota == 0)
|
2003-06-21 19:55:55 +00:00
|
|
|
{
|
2004-04-12 13:03:29 +00:00
|
|
|
Pipe->InboundQuota = DeviceExt->DefaultQuota;
|
2003-06-21 19:55:55 +00:00
|
|
|
}
|
2004-04-12 13:03:29 +00:00
|
|
|
else
|
2003-06-21 19:55:55 +00:00
|
|
|
{
|
2004-11-01 22:54:24 +00:00
|
|
|
Pipe->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
|
2004-04-12 13:03:29 +00:00
|
|
|
if (Pipe->InboundQuota < DeviceExt->MinQuota)
|
|
|
|
{
|
|
|
|
Pipe->InboundQuota = DeviceExt->MinQuota;
|
|
|
|
}
|
|
|
|
else if (Pipe->InboundQuota > DeviceExt->MaxQuota)
|
|
|
|
{
|
|
|
|
Pipe->InboundQuota = DeviceExt->MaxQuota;
|
|
|
|
}
|
|
|
|
}
|
2003-06-21 19:55:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-04-12 13:03:29 +00:00
|
|
|
Pipe->InboundQuota = 0;
|
|
|
|
}
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2004-04-12 13:03:29 +00:00
|
|
|
if (IoStack->Parameters.Create.Options & (FILE_PIPE_FULL_DUPLEX|FILE_PIPE_OUTBOUND))
|
|
|
|
{
|
2004-11-01 22:54:24 +00:00
|
|
|
if (Buffer->OutboundQuota == 0)
|
2003-06-21 19:55:55 +00:00
|
|
|
{
|
2004-04-12 13:03:29 +00:00
|
|
|
Pipe->OutboundQuota = DeviceExt->DefaultQuota;
|
2003-06-21 19:55:55 +00:00
|
|
|
}
|
2004-04-12 13:03:29 +00:00
|
|
|
else
|
2003-06-21 19:55:55 +00:00
|
|
|
{
|
2004-11-01 22:54:24 +00:00
|
|
|
Pipe->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
|
2004-04-12 13:03:29 +00:00
|
|
|
if (Pipe->OutboundQuota < DeviceExt->MinQuota)
|
|
|
|
{
|
|
|
|
Pipe->OutboundQuota = DeviceExt->MinQuota;
|
|
|
|
}
|
|
|
|
else if (Pipe->OutboundQuota > DeviceExt->MaxQuota)
|
|
|
|
{
|
|
|
|
Pipe->OutboundQuota = DeviceExt->MaxQuota;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Pipe->OutboundQuota = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
InsertTailList(&DeviceExt->PipeListHead, &Pipe->PipeListEntry);
|
|
|
|
KeUnlockMutex(&DeviceExt->PipeListLock);
|
2003-06-21 19:55:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Pipe->OutboundQuota)
|
|
|
|
{
|
|
|
|
Fcb->Data = ExAllocatePool(NonPagedPool, Pipe->OutboundQuota);
|
|
|
|
if (Fcb->Data == NULL)
|
|
|
|
{
|
|
|
|
ExFreePool(Fcb);
|
2004-04-12 13:03:29 +00:00
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
if (NewPipe)
|
2004-04-12 13:03:29 +00:00
|
|
|
{
|
|
|
|
RtlFreeUnicodeString(&Pipe->PipeName);
|
|
|
|
ExFreePool(Pipe);
|
|
|
|
}
|
2003-06-21 19:55:55 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2004-04-12 13:03:29 +00:00
|
|
|
return STATUS_NO_MEMORY;
|
2004-12-23 23:58:44 +00:00
|
|
|
}
|
2003-06-21 19:55:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Fcb->Data = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Fcb->ReadPtr = Fcb->Data;
|
|
|
|
Fcb->WritePtr = Fcb->Data;
|
|
|
|
Fcb->ReadDataAvailable = 0;
|
|
|
|
Fcb->WriteQuotaAvailable = Pipe->OutboundQuota;
|
|
|
|
Fcb->MaxDataLength = Pipe->OutboundQuota;
|
|
|
|
KeInitializeSpinLock(&Fcb->DataListLock);
|
|
|
|
|
2001-07-29 16:41:25 +00:00
|
|
|
Pipe->CurrentInstances++;
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
KeLockMutex(&Pipe->FcbListLock);
|
2001-07-29 16:41:25 +00:00
|
|
|
InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry);
|
2004-05-05 18:30:16 +00:00
|
|
|
KeUnlockMutex(&Pipe->FcbListLock);
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2000-05-13 13:51:08 +00:00
|
|
|
Fcb->Pipe = Pipe;
|
2001-07-29 16:41:25 +00:00
|
|
|
Fcb->PipeEnd = FILE_PIPE_SERVER_END;
|
2004-04-12 13:03:29 +00:00
|
|
|
Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
|
2000-05-13 13:51:08 +00:00
|
|
|
Fcb->OtherSide = NULL;
|
2001-07-29 16:41:25 +00:00
|
|
|
|
2001-05-10 23:38:31 +00:00
|
|
|
KeInitializeEvent(&Fcb->ConnectEvent,
|
|
|
|
SynchronizationEvent,
|
|
|
|
FALSE);
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2003-06-21 19:55:55 +00:00
|
|
|
KeInitializeEvent(&Fcb->Event,
|
2001-11-20 20:35:10 +00:00
|
|
|
SynchronizationEvent,
|
|
|
|
FALSE);
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2000-05-13 13:51:08 +00:00
|
|
|
FileObject->FsContext = Fcb;
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2001-10-21 18:58:32 +00:00
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
1999-11-24 11:51:55 +00:00
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2004-12-23 23:58:44 +00:00
|
|
|
|
2005-01-02 12:02:42 +00:00
|
|
|
DPRINT("Success!\n");
|
|
|
|
|
2004-12-23 23:58:44 +00:00
|
|
|
return STATUS_SUCCESS;
|
1999-11-24 11:51:55 +00:00
|
|
|
}
|
1999-12-04 20:58:45 +00:00
|
|
|
|
|
|
|
|
2001-05-01 11:09:01 +00:00
|
|
|
NTSTATUS STDCALL
|
2004-05-05 18:30:16 +00:00
|
|
|
NpfsClose(
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
PIRP Irp)
|
2001-05-01 11:09:01 +00:00
|
|
|
{
|
2004-05-05 18:30:16 +00:00
|
|
|
PNPFS_DEVICE_EXTENSION DeviceExt;
|
|
|
|
PIO_STACK_LOCATION IoStack;
|
|
|
|
PFILE_OBJECT FileObject;
|
|
|
|
PNPFS_FCB Fcb;
|
|
|
|
PNPFS_PIPE Pipe;
|
|
|
|
BOOL Server;
|
|
|
|
|
|
|
|
DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
|
|
|
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
FileObject = IoStack->FileObject;
|
|
|
|
Fcb = FileObject->FsContext;
|
|
|
|
|
|
|
|
if (Fcb == NULL)
|
|
|
|
{
|
2005-01-02 12:02:42 +00:00
|
|
|
DPRINT("Success!\n");
|
2001-10-20 15:30:07 +00:00
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2004-05-05 18:30:16 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2001-10-20 15:30:07 +00:00
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
DPRINT("Fcb %x\n", Fcb);
|
|
|
|
Pipe = Fcb->Pipe;
|
2001-10-20 15:30:07 +00:00
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
DPRINT("Closing pipe %wZ\n", &Pipe->PipeName);
|
2001-10-20 15:30:07 +00:00
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
KeLockMutex(&Pipe->FcbListLock);
|
2001-10-20 15:30:07 +00:00
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
Server = (Fcb->PipeEnd == FILE_PIPE_SERVER_END);
|
2001-05-01 11:09:01 +00:00
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
if (Server)
|
|
|
|
{
|
2001-10-20 15:30:07 +00:00
|
|
|
/* FIXME: Clean up existing connections here ?? */
|
2002-05-07 22:40:35 +00:00
|
|
|
DPRINT("Server\n");
|
2001-10-20 15:30:07 +00:00
|
|
|
Pipe->CurrentInstances--;
|
2004-10-11 12:37:04 +00:00
|
|
|
}
|
|
|
|
else
|
2004-05-05 18:30:16 +00:00
|
|
|
{
|
2002-05-07 22:40:35 +00:00
|
|
|
DPRINT("Client\n");
|
2004-05-05 18:30:16 +00:00
|
|
|
}
|
2004-10-11 12:37:04 +00:00
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
|
|
|
{
|
2002-05-07 22:40:35 +00:00
|
|
|
if (Fcb->OtherSide)
|
2004-05-05 18:30:16 +00:00
|
|
|
{
|
2004-05-10 19:58:10 +00:00
|
|
|
#ifndef FIN_WORKAROUND_READCLOSE
|
2004-05-05 18:30:16 +00:00
|
|
|
Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
|
2004-05-07 12:13:13 +00:00
|
|
|
Fcb->OtherSide->OtherSide = NULL;
|
2004-05-10 19:58:10 +00:00
|
|
|
#endif
|
2004-05-05 18:30:16 +00:00
|
|
|
/*
|
|
|
|
* Signaling the write event. If is possible that an other
|
2004-12-30 12:34:27 +00:00
|
|
|
* thread waits for an empty buffer.
|
2004-05-05 18:30:16 +00:00
|
|
|
*/
|
|
|
|
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
|
|
|
}
|
2004-10-11 12:37:04 +00:00
|
|
|
|
2004-05-10 19:58:10 +00:00
|
|
|
#ifndef FIN_WORKAROUND_READCLOSE
|
2004-05-05 18:30:16 +00:00
|
|
|
Fcb->PipeState = 0;
|
2004-05-10 19:58:10 +00:00
|
|
|
#endif
|
2004-05-05 18:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FileObject->FsContext = NULL;
|
|
|
|
|
2004-05-10 19:58:10 +00:00
|
|
|
#ifndef FIN_WORKAROUND_READCLOSE
|
2004-05-05 18:30:16 +00:00
|
|
|
RemoveEntryList(&Fcb->FcbListEntry);
|
|
|
|
if (Fcb->Data)
|
|
|
|
ExFreePool(Fcb->Data);
|
|
|
|
ExFreePool(Fcb);
|
2004-05-10 19:58:10 +00:00
|
|
|
#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);
|
|
|
|
}
|
2004-10-11 12:37:04 +00:00
|
|
|
|
2004-05-10 19:58:10 +00:00
|
|
|
RemoveEntryList(&Fcb->FcbListEntry);
|
|
|
|
if (Fcb->Data)
|
|
|
|
ExFreePool(Fcb->Data);
|
2004-10-11 12:37:04 +00:00
|
|
|
|
2004-05-10 19:58:10 +00:00
|
|
|
ExFreePool(Fcb);
|
|
|
|
}
|
|
|
|
#endif
|
2004-05-05 18:30:16 +00:00
|
|
|
|
|
|
|
KeUnlockMutex(&Pipe->FcbListLock);
|
|
|
|
|
2005-01-02 12:02:42 +00:00
|
|
|
if (IsListEmpty(&Pipe->ServerFcbListHead) &&
|
|
|
|
IsListEmpty(&Pipe->ClientFcbListHead))
|
2004-05-05 18:30:16 +00:00
|
|
|
{
|
2001-10-20 15:30:07 +00:00
|
|
|
RtlFreeUnicodeString(&Pipe->PipeName);
|
2004-05-05 18:30:16 +00:00
|
|
|
KeLockMutex(&DeviceExt->PipeListLock);
|
2001-10-20 15:30:07 +00:00
|
|
|
RemoveEntryList(&Pipe->PipeListEntry);
|
2004-05-05 18:30:16 +00:00
|
|
|
KeUnlockMutex(&DeviceExt->PipeListLock);
|
2001-10-20 15:30:07 +00:00
|
|
|
ExFreePool(Pipe);
|
2004-05-05 18:30:16 +00:00
|
|
|
}
|
2001-10-20 15:30:07 +00:00
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2001-10-20 15:30:07 +00:00
|
|
|
|
2005-01-02 12:02:42 +00:00
|
|
|
DPRINT("Success!\n");
|
|
|
|
|
2004-05-05 18:30:16 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-05-01 11:09:01 +00:00
|
|
|
}
|
|
|
|
|
1999-12-04 20:58:45 +00:00
|
|
|
/* EOF */
|