/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
-* FILE: drivers/fs/np/create.c
+* FILE: drivers/filesystems/npfs/create.c
* PURPOSE: Named pipe filesystem
* PROGRAMMER: David Welch <welch@cwcom.net>
*/
/* FUNCTIONS *****************************************************************/
-static
VOID
-NpfsDeleteFcb(PNPFS_FCB Fcb)
+NpfsDereferenceFcb(PNPFS_FCB Fcb)
{
PNPFS_VCB Vcb = Fcb->Vcb;
KeLockMutex(&Vcb->PipeListLock);
- RemoveEntryList(&Fcb->PipeListEntry);
+ if (InterlockedDecrement(&Fcb->RefCount) == 0)
+ {
+ DPRINT("NpfsDereferenceFcb. Deleting %p\n", Fcb);
+ RemoveEntryList(&Fcb->PipeListEntry);
+ RtlFreeUnicodeString(&Fcb->PipeName);
+ ExFreePoolWithTag(Fcb, TAG_NPFS_FCB);
+ }
KeUnlockMutex(&Vcb->PipeListLock);
- RtlFreeUnicodeString(&Fcb->PipeName);
- ExFreePoolWithTag(Fcb, TAG_NPFS_FCB);
}
static
Ccb->RefCount = 1;
Ccb->Type = Type;
+ // FIXME: why does this function not reference Fcb?
Ccb->Fcb = Fcb;
Ccb->OtherSide = NULL;
NpfsReferenceCcb(PNPFS_CCB Ccb)
{
ASSERT(Ccb->RefCount > 0);
- InterlockedIncrement((PLONG)&Ccb->RefCount);
+ InterlockedIncrement(&Ccb->RefCount);
}
static
{
/* Decrement reference count */
ASSERT(Ccb->RefCount > 0);
- if (InterlockedDecrement((PLONG)&Ccb->RefCount) == 0)
+ if (InterlockedDecrement(&Ccb->RefCount) == 0)
{
/* Its zero, delete CCB */
ExFreePoolWithTag(Ccb, TAG_NPFS_CCB);
TRUE) == 0)
{
DPRINT("<%wZ> = <%wZ>\n", PipeName, &Fcb->PipeName);
+ (VOID)InterlockedIncrement(&Fcb->RefCount);
return Fcb;
}
PNPFS_CCB ClientCcb;
PNPFS_CCB ServerCcb = NULL;
PNPFS_VCB Vcb;
- ACCESS_MASK DesiredAccess;
NTSTATUS Status;
#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ ACCESS_MASK DesiredAccess;
BOOLEAN SpecialAccess;
#endif
FileObject = IoStack->FileObject;
RelatedFileObject = FileObject->RelatedFileObject;
FileName = &FileObject->FileName;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
+#endif
DPRINT("FileObject %p\n", FileObject);
DPRINT("FileName %wZ\n", &FileObject->FileName);
{
DPRINT("No memory!\n");
KeUnlockMutex(&Fcb->CcbListLock);
+ NpfsDereferenceFcb(Fcb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
DPRINT("No memory!\n");
NpfsDereferenceCcb(ClientCcb);
KeUnlockMutex(&Fcb->CcbListLock);
+ NpfsDereferenceFcb(Fcb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
NpfsDereferenceCcb(ClientCcb);
KeUnlockMutex(&Fcb->CcbListLock);
- Irp->IoStatus.Status = STATUS_OBJECT_PATH_NOT_FOUND;
+ NpfsDereferenceFcb(Fcb);
+ Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_OBJECT_PATH_NOT_FOUND;
+ return STATUS_OBJECT_NAME_NOT_FOUND;
}
}
else
}
NpfsDereferenceCcb(ClientCcb);
-
KeUnlockMutex(&Fcb->CcbListLock);
+ NpfsDereferenceFcb(Fcb);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
- PNAMED_PIPE_CREATE_PARAMETERS Buffer;
- BOOLEAN NewPipe = FALSE;
+ ULONG Disposition;
+ ULONG ShareAccess;
+ PNAMED_PIPE_CREATE_PARAMETERS Parameters;
DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
DPRINT("FileObject %p\n", FileObject);
DPRINT("Pipe name %wZ\n", &FileObject->FileName);
- Buffer = IoStack->Parameters.CreatePipe.Parameters;
+ Disposition = (IoStack->Parameters.CreatePipe.Options >> 24) & 0xFF;
+ ShareAccess = IoStack->Parameters.CreatePipe.ShareAccess;
+ Parameters = IoStack->Parameters.CreatePipe.Parameters;
Irp->IoStatus.Information = 0;
- if (!(IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) ||
- (IoStack->Parameters.CreatePipe.ShareAccess & ~(FILE_SHARE_READ|FILE_SHARE_WRITE)))
+ if ((Disposition == FILE_OVERWRITE) ||
+ (Disposition == FILE_OVERWRITE_IF) ||
+ !(ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) ||
+ (ShareAccess & ~(FILE_SHARE_READ|FILE_SHARE_WRITE)))
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
{
DPRINT("Out of instances.\n");
+ NpfsDereferenceFcb(Fcb);
Irp->IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSTANCE_NOT_AVAILABLE;
}
- if (Fcb->MaximumInstances != Buffer->MaximumInstances ||
- Fcb->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart ||
- Fcb->PipeType != Buffer->NamedPipeType)
+ if (Disposition == FILE_CREATE ||
+ Fcb->MaximumInstances != Parameters->MaximumInstances ||
+ Fcb->TimeOut.QuadPart != Parameters->DefaultTimeout.QuadPart ||
+ Fcb->PipeType != Parameters->NamedPipeType)
{
DPRINT("Asked for invalid pipe mode.\n");
+ NpfsDereferenceFcb(Fcb);
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_ACCESS_DENIED;
}
else
{
- NewPipe = TRUE;
Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NPFS_FCB), TAG_NPFS_FCB);
if (Fcb == NULL)
{
Fcb->Type = FCB_PIPE;
Fcb->Vcb = Vcb;
+ Fcb->RefCount = 1;
Fcb->PipeName.Length = FileObject->FileName.Length;
Fcb->PipeName.MaximumLength = Fcb->PipeName.Length + sizeof(UNICODE_NULL);
Fcb->PipeName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
InitializeListHead(&Fcb->WaiterListHead);
KeInitializeMutex(&Fcb->CcbListLock, 0);
- Fcb->PipeType = Buffer->NamedPipeType;
- Fcb->ServerReadMode = Buffer->ReadMode;
+ Fcb->PipeType = Parameters->NamedPipeType;
+ Fcb->ServerReadMode = Parameters->ReadMode;
/* MSDN documentation reads that clients always start off in byte mode */
Fcb->ClientReadMode = FILE_PIPE_BYTE_STREAM_MODE;
- Fcb->CompletionMode = Buffer->CompletionMode;
- switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
+ Fcb->CompletionMode = Parameters->CompletionMode;
+ switch (ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
{
case FILE_SHARE_READ:
Fcb->PipeConfiguration = FILE_PIPE_OUTBOUND;
Fcb->PipeConfiguration = FILE_PIPE_FULL_DUPLEX;
break;
}
- Fcb->MaximumInstances = Buffer->MaximumInstances;
+ Fcb->MaximumInstances = Parameters->MaximumInstances;
Fcb->CurrentInstances = 0;
- Fcb->TimeOut = Buffer->DefaultTimeout;
+ Fcb->TimeOut = Parameters->DefaultTimeout;
if (!(Fcb->PipeConfiguration & FILE_PIPE_OUTBOUND) ||
Fcb->PipeConfiguration & FILE_PIPE_FULL_DUPLEX)
{
- if (Buffer->InboundQuota == 0)
+ if (Parameters->InboundQuota == 0)
{
Fcb->InboundQuota = Vcb->DefaultQuota;
}
else
{
- Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
+ Fcb->InboundQuota = PAGE_ROUND_UP(Parameters->InboundQuota);
if (Fcb->InboundQuota < Vcb->MinQuota)
{
Fcb->InboundQuota = Vcb->MinQuota;
if (Fcb->PipeConfiguration & (FILE_PIPE_FULL_DUPLEX|FILE_PIPE_OUTBOUND))
{
- if (Buffer->OutboundQuota == 0)
+ if (Parameters->OutboundQuota == 0)
{
Fcb->OutboundQuota = Vcb->DefaultQuota;
}
else
{
- Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
+ Fcb->OutboundQuota = PAGE_ROUND_UP(Parameters->OutboundQuota);
if (Fcb->OutboundQuota < Vcb->MinQuota)
{
Fcb->OutboundQuota = Vcb->MinQuota;
Ccb = NpfsAllocateCcb(CCB_PIPE, Fcb);
if (Ccb == NULL)
{
- if (NewPipe)
- {
- NpfsDeleteFcb(Fcb);
- }
-
+ NpfsDereferenceFcb(Fcb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
if (Ccb->Data == NULL)
{
NpfsDereferenceCcb(Ccb);
-
- if (NewPipe)
- {
- NpfsDeleteFcb(Fcb);
- }
+ NpfsDereferenceFcb(Fcb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KeUnlockMutex(&Fcb->CcbListLock);
- if (IsListEmpty(&Fcb->ServerCcbListHead) &&
- IsListEmpty(&Fcb->ClientCcbListHead))
- {
- NpfsDeleteFcb(Fcb);
- FileObject->FsContext = NULL;
- }
+ NpfsDereferenceFcb(Fcb);
+ FileObject->FsContext = NULL;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;