#define NDEBUG
#include <debug.h>
+//#define USING_PROPER_NPFS_WAIT_SEMANTICS
+
/* FUNCTIONS *****************************************************************/
-static PNPFS_FCB
-NpfsFindPipe(PNPFS_DEVICE_EXTENSION DeviceExt,
+static
+VOID
+NpfsDeleteFcb(PNPFS_FCB Fcb)
+{
+ PNPFS_VCB Vcb = Fcb->Vcb;
+
+ KeLockMutex(&Vcb->PipeListLock);
+ RemoveEntryList(&Fcb->PipeListEntry);
+ KeUnlockMutex(&Vcb->PipeListLock);
+ RtlFreeUnicodeString(&Fcb->PipeName);
+ ExFreePoolWithTag(Fcb, TAG_NPFS_FCB);
+}
+
+static
+PNPFS_CCB
+NpfsAllocateCcb(CCB_TYPE Type, PNPFS_FCB Fcb)
+{
+ PNPFS_CCB Ccb;
+
+ Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NPFS_CCB), TAG_NPFS_CCB);
+ if (!Ccb)
+ {
+ return NULL;
+ }
+
+ RtlZeroMemory(Ccb, sizeof(NPFS_CCB));
+
+ Ccb->RefCount = 1;
+ Ccb->Type = Type;
+ Ccb->Fcb = Fcb;
+ Ccb->OtherSide = NULL;
+
+ return Ccb;
+}
+
+static
+VOID
+NpfsReferenceCcb(PNPFS_CCB Ccb)
+{
+ ASSERT(Ccb->RefCount > 0);
+ InterlockedIncrement((PLONG)&Ccb->RefCount);
+}
+
+static
+VOID
+NpfsDereferenceCcb(PNPFS_CCB Ccb)
+{
+ /* Decrement reference count */
+ ASSERT(Ccb->RefCount > 0);
+ if (InterlockedDecrement((PLONG)&Ccb->RefCount) == 0)
+ {
+ /* Its zero, delete CCB */
+ ExFreePoolWithTag(Ccb, TAG_NPFS_CCB);
+ }
+}
+
+static
+VOID
+NpfsCcbSetOtherSide(PNPFS_CCB Ccb, PNPFS_CCB OtherSide)
+{
+ /* Dereference old other side */
+ if (Ccb->OtherSide) NpfsDereferenceCcb(Ccb->OtherSide);
+
+ /* Reference the new other side */
+ if (OtherSide) NpfsReferenceCcb(OtherSide);
+
+ /* Set new value */
+ Ccb->OtherSide = OtherSide;
+}
+
+PNPFS_FCB
+NpfsFindPipe(PNPFS_VCB Vcb,
PUNICODE_STRING PipeName)
{
PLIST_ENTRY CurrentEntry;
PNPFS_FCB Fcb;
- CurrentEntry = DeviceExt->PipeListHead.Flink;
- while (CurrentEntry != &DeviceExt->PipeListHead)
+ CurrentEntry = Vcb->PipeListHead.Flink;
+ while (CurrentEntry != &Vcb->PipeListHead)
{
Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, PipeListEntry);
if (RtlCompareUnicodeString(PipeName,
}
+static VOID
+NpfsOpenFileSystem(PNPFS_FCB Fcb,
+ PFILE_OBJECT FileObject,
+ PIO_STATUS_BLOCK IoStatus)
+{
+ PNPFS_CCB Ccb;
+
+ DPRINT("NpfsOpenFileSystem()\n");
+
+ Ccb = NpfsAllocateCcb(CCB_DEVICE, Fcb);
+ if (Ccb == NULL)
+ {
+ IoStatus->Status = STATUS_NO_MEMORY;
+ return;
+ }
+
+ FileObject->FsContext = Fcb;
+ FileObject->FsContext2 = Ccb;
+
+ IoStatus->Information = FILE_OPENED;
+ IoStatus->Status = STATUS_SUCCESS;
+
+ return;
+}
+
+
+static VOID
+NpfsOpenRootDirectory(PNPFS_FCB Fcb,
+ PFILE_OBJECT FileObject,
+ PIO_STATUS_BLOCK IoStatus)
+{
+ PNPFS_CCB Ccb;
+
+ DPRINT("NpfsOpenRootDirectory()\n");
+
+ Ccb = NpfsAllocateCcb(CCB_DIRECTORY, Fcb);
+ if (Ccb == NULL)
+ {
+ IoStatus->Status = STATUS_NO_MEMORY;
+ return;
+ }
+
+ FileObject->FsContext = Fcb;
+ FileObject->FsContext2 = Ccb;
+
+ IoStatus->Information = FILE_OPENED;
+ IoStatus->Status = STATUS_SUCCESS;
+
+ return;
+}
+
+
NTSTATUS NTAPI
NpfsCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PEXTENDED_IO_STACK_LOCATION IoStack;
+ PUNICODE_STRING FileName;
PFILE_OBJECT FileObject;
+ PFILE_OBJECT RelatedFileObject;
PNPFS_FCB Fcb;
PNPFS_CCB ClientCcb;
PNPFS_CCB ServerCcb = NULL;
- PNPFS_DEVICE_EXTENSION DeviceExt;
- BOOLEAN SpecialAccess;
+ PNPFS_VCB Vcb;
ACCESS_MASK DesiredAccess;
+ NTSTATUS Status;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ BOOLEAN SpecialAccess;
+#endif
DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
+ RelatedFileObject = FileObject->RelatedFileObject;
+ FileName = &FileObject->FileName;
DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
+
DPRINT("FileObject %p\n", FileObject);
DPRINT("FileName %wZ\n", &FileObject->FileName);
Irp->IoStatus.Information = 0;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
SpecialAccess = ((DesiredAccess & SPECIFIC_RIGHTS_ALL) == FILE_READ_ATTRIBUTES);
if (SpecialAccess)
{
DPRINT("NpfsCreate() open client end for special use!\n");
}
+#endif
+
+ DPRINT("FileName->Length: %hu RelatedFileObject: %p\n", FileName->Length, RelatedFileObject);
+
+ /* Open the file system */
+ if (FileName->Length == 0 &&
+ (RelatedFileObject == NULL || ((PNPFS_CCB)RelatedFileObject->FsContext2)->Type == CCB_DEVICE))
+ {
+ DPRINT("Open the file system\n");
+
+ NpfsOpenFileSystem(Vcb->DeviceFcb,
+ FileObject,
+ &Irp->IoStatus);
+
+ Status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+ }
+
+ /* Open the root directory */
+ if ((FileName->Length == 2 && FileName->Buffer[0] == L'\\' && RelatedFileObject == NULL) ||
+ (FileName->Length == 0 && ((PNPFS_CCB)RelatedFileObject->FsContext2)->Type == CCB_DIRECTORY))
+ {
+ DPRINT("Open the root directory\n");
+
+ NpfsOpenRootDirectory(Vcb->RootFcb,
+ FileObject,
+ &Irp->IoStatus);
+
+ Status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+ }
+
/*
* Step 1. Find the pipe we're trying to open.
*/
- KeLockMutex(&DeviceExt->PipeListLock);
- Fcb = NpfsFindPipe(DeviceExt,
- &FileObject->FileName);
+ KeLockMutex(&Vcb->PipeListLock);
+ Fcb = NpfsFindPipe(Vcb, &FileObject->FileName);
if (Fcb == NULL)
{
/* Not found, bail out with error. */
DPRINT("No pipe found!\n");
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
/*
* Acquire the lock for CCB lists. From now on no modifications to the
/*
* Step 2. Create the client CCB.
*/
- ClientCcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_CCB));
+ ClientCcb = NpfsAllocateCcb(CCB_PIPE, Fcb);
if (ClientCcb == NULL)
{
DPRINT("No memory!\n");
}
ClientCcb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
- ClientCcb->Fcb = Fcb;
ClientCcb->PipeEnd = FILE_PIPE_CLIENT_END;
- ClientCcb->OtherSide = NULL;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
ClientCcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
+#else
+ ClientCcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+#endif
InitializeListHead(&ClientCcb->ReadRequestListHead);
DPRINT("CCB: %p\n", ClientCcb);
/* Initialize data list. */
if (Fcb->OutboundQuota)
{
- ClientCcb->Data = ExAllocatePool(PagedPool, Fcb->OutboundQuota);
+ ClientCcb->Data = ExAllocatePoolWithTag(PagedPool,
+ Fcb->OutboundQuota,
+ TAG_NPFS_CCB_DATA);
if (ClientCcb->Data == NULL)
{
DPRINT("No memory!\n");
- ExFreePool(ClientCcb);
+ NpfsDereferenceCcb(ClientCcb);
KeUnlockMutex(&Fcb->CcbListLock);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
ClientCcb->MaxDataLength = Fcb->OutboundQuota;
ExInitializeFastMutex(&ClientCcb->DataListLock);
KeInitializeEvent(&ClientCcb->ConnectEvent, SynchronizationEvent, FALSE);
- KeInitializeEvent(&ClientCcb->ReadEvent, SynchronizationEvent, FALSE);
- KeInitializeEvent(&ClientCcb->WriteEvent, SynchronizationEvent, FALSE);
+ KeInitializeEvent(&ClientCcb->ReadEvent, NotificationEvent, FALSE);
+ KeInitializeEvent(&ClientCcb->WriteEvent, NotificationEvent, FALSE);
/*
* Step 3. Search for listening server CCB.
*/
-
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
if (!SpecialAccess)
{
+#endif
/*
* WARNING: Point of no return! Once we get the server CCB it's
* possible that we completed a wait request and so we have to
DPRINT("No listening server CCB found!\n");
if (ClientCcb->Data)
{
- ExFreePool(ClientCcb->Data);
- ClientCcb->Data = NULL;
+ ExFreePoolWithTag(ClientCcb->Data, TAG_NPFS_CCB_DATA);
}
+
+ NpfsDereferenceCcb(ClientCcb);
KeUnlockMutex(&Fcb->CcbListLock);
Irp->IoStatus.Status = STATUS_OBJECT_PATH_NOT_FOUND;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
NpfsSignalAndRemoveListeningServerInstance(Fcb, ServerCcb);
}
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
}
else if (IsListEmpty(&Fcb->ServerCcbListHead))
{
DPRINT("No server fcb found!\n");
+
+ if (ClientCcb->Data)
+ {
+ ExFreePoolWithTag(ClientCcb->Data, TAG_NPFS_CCB_DATA);
+ }
+
+ NpfsDereferenceCcb(ClientCcb);
+
KeUnlockMutex(&Fcb->CcbListLock);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
+#endif
/*
* Step 4. Add the client CCB to a list and connect it if possible.
/* Connect to listening server side */
if (ServerCcb)
{
- ClientCcb->OtherSide = ServerCcb;
- ServerCcb->OtherSide = ClientCcb;
+ NpfsCcbSetOtherSide(ClientCcb, ServerCcb);
+ NpfsCcbSetOtherSide(ServerCcb, ClientCcb);
ClientCcb->PipeState = FILE_PIPE_CONNECTED_STATE;
ServerCcb->PipeState = FILE_PIPE_CONNECTED_STATE;
KeSetEvent(&ServerCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
{
PEXTENDED_IO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PNAMED_PIPE_CREATE_PARAMETERS Buffer;
DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
DPRINT("FileObject %p\n", FileObject);
return STATUS_INVALID_PARAMETER;
}
- Ccb = ExAllocatePool(NonPagedPool, sizeof(NPFS_CCB));
- if (Ccb == NULL)
- {
- Irp->IoStatus.Status = STATUS_NO_MEMORY;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NO_MEMORY;
- }
-
- Ccb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
/*
* First search for existing Pipe with the same name.
*/
- Fcb = NpfsFindPipe(DeviceExt,
- &FileObject->FileName);
+ Fcb = NpfsFindPipe(Vcb, &FileObject->FileName);
if (Fcb != NULL)
{
/*
* Found Pipe with the same name. Check if we are
* allowed to use it.
*/
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
{
DPRINT("Out of instances.\n");
- ExFreePool(Ccb);
Irp->IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSTANCE_NOT_AVAILABLE;
Fcb->PipeType != Buffer->NamedPipeType)
{
DPRINT("Asked for invalid pipe mode.\n");
- ExFreePool(Ccb);
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_ACCESS_DENIED;
else
{
NewPipe = TRUE;
- Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
+ Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NPFS_FCB), TAG_NPFS_FCB);
if (Fcb == NULL)
{
- KeUnlockMutex(&DeviceExt->PipeListLock);
- ExFreePool(Ccb);
+ KeUnlockMutex(&Vcb->PipeListLock);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
}
+ Fcb->Type = FCB_PIPE;
+ Fcb->Vcb = Vcb;
Fcb->PipeName.Length = FileObject->FileName.Length;
Fcb->PipeName.MaximumLength = Fcb->PipeName.Length + sizeof(UNICODE_NULL);
- Fcb->PipeName.Buffer = ExAllocatePool(NonPagedPool, Fcb->PipeName.MaximumLength);
+ Fcb->PipeName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ Fcb->PipeName.MaximumLength,
+ TAG_NPFS_NAMEBLOCK);
if (Fcb->PipeName.Buffer == NULL)
{
- KeUnlockMutex(&DeviceExt->PipeListLock);
- ExFreePool(Fcb);
- ExFreePool(Ccb);
+ KeUnlockMutex(&Vcb->PipeListLock);
+ ExFreePoolWithTag(Fcb, TAG_NPFS_FCB);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
{
if (Buffer->InboundQuota == 0)
{
- Fcb->InboundQuota = DeviceExt->DefaultQuota;
+ Fcb->InboundQuota = Vcb->DefaultQuota;
}
else
{
Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
- if (Fcb->InboundQuota < DeviceExt->MinQuota)
+ if (Fcb->InboundQuota < Vcb->MinQuota)
{
- Fcb->InboundQuota = DeviceExt->MinQuota;
+ Fcb->InboundQuota = Vcb->MinQuota;
}
- else if (Fcb->InboundQuota > DeviceExt->MaxQuota)
+ else if (Fcb->InboundQuota > Vcb->MaxQuota)
{
- Fcb->InboundQuota = DeviceExt->MaxQuota;
+ Fcb->InboundQuota = Vcb->MaxQuota;
}
}
}
{
if (Buffer->OutboundQuota == 0)
{
- Fcb->OutboundQuota = DeviceExt->DefaultQuota;
+ Fcb->OutboundQuota = Vcb->DefaultQuota;
}
else
{
Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
- if (Fcb->OutboundQuota < DeviceExt->MinQuota)
+ if (Fcb->OutboundQuota < Vcb->MinQuota)
{
- Fcb->OutboundQuota = DeviceExt->MinQuota;
+ Fcb->OutboundQuota = Vcb->MinQuota;
}
- else if (Fcb->OutboundQuota > DeviceExt->MaxQuota)
+ else if (Fcb->OutboundQuota > Vcb->MaxQuota)
{
- Fcb->OutboundQuota = DeviceExt->MaxQuota;
+ Fcb->OutboundQuota = Vcb->MaxQuota;
}
}
}
Fcb->OutboundQuota = 0;
}
- InsertTailList(&DeviceExt->PipeListHead, &Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ InsertTailList(&Vcb->PipeListHead, &Fcb->PipeListEntry);
+ KeUnlockMutex(&Vcb->PipeListLock);
+ }
+
+ Ccb = NpfsAllocateCcb(CCB_PIPE, Fcb);
+ if (Ccb == NULL)
+ {
+ if (NewPipe)
+ {
+ NpfsDeleteFcb(Fcb);
+ }
+
+ Irp->IoStatus.Status = STATUS_NO_MEMORY;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NO_MEMORY;
}
+ Ccb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
+
if (Fcb->InboundQuota)
{
- Ccb->Data = ExAllocatePool(PagedPool, Fcb->InboundQuota);
+ Ccb->Data = ExAllocatePoolWithTag(PagedPool,
+ Fcb->InboundQuota,
+ TAG_NPFS_CCB_DATA);
if (Ccb->Data == NULL)
{
- ExFreePool(Ccb);
+ NpfsDereferenceCcb(Ccb);
if (NewPipe)
{
- KeLockMutex(&DeviceExt->PipeListLock);
- RemoveEntryList(&Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
- RtlFreeUnicodeString(&Fcb->PipeName);
- ExFreePool(Fcb);
+ NpfsDeleteFcb(Fcb);
}
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Ccb->Fcb = Fcb;
Ccb->PipeEnd = FILE_PIPE_SERVER_END;
Ccb->PipeState = FILE_PIPE_LISTENING_STATE;
- Ccb->OtherSide = NULL;
DPRINT("CCB: %p\n", Ccb);
KeInitializeEvent(&Ccb->ConnectEvent, SynchronizationEvent, FALSE);
- KeInitializeEvent(&Ccb->ReadEvent, SynchronizationEvent, FALSE);
- KeInitializeEvent(&Ccb->WriteEvent, SynchronizationEvent, FALSE);
+ KeInitializeEvent(&Ccb->ReadEvent, NotificationEvent, FALSE);
+ KeInitializeEvent(&Ccb->WriteEvent, NotificationEvent, FALSE);
KeLockMutex(&Fcb->CcbListLock);
InsertTailList(&Fcb->ServerCcbListHead, &Ccb->CcbListEntry);
NpfsCleanup(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
PNPFS_CCB Ccb, OtherSide;
DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = FileObject->FsContext2;
return STATUS_SUCCESS;
}
+ if (Ccb->Type == CCB_DEVICE)
+ {
+ DPRINT("Cleanup the file system!\n");
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
+ if (Ccb->Type == CCB_DIRECTORY)
+ {
+ DPRINT("Cleanup the root directory!\n");
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
DPRINT("CCB %p\n", Ccb);
Fcb = Ccb->Fcb;
if ((Ccb->PipeState == FILE_PIPE_CONNECTED_STATE) && (Ccb->OtherSide))
{
OtherSide = Ccb->OtherSide;
+ ASSERT(OtherSide->OtherSide == Ccb);
+
/* Lock the server first */
if (Server)
{
ExAcquireFastMutex(&OtherSide->DataListLock);
ExAcquireFastMutex(&Ccb->DataListLock);
}
- //OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
- OtherSide->OtherSide = NULL;
+
+ /* Unlink FCBs */
+ NpfsCcbSetOtherSide(OtherSide, NULL);
+ NpfsCcbSetOtherSide(Ccb, NULL);
+
/*
* Signaling the write event. If is possible that an other
* thread waits for an empty buffer.
ExAcquireFastMutex(&Ccb->DataListLock);
if (Ccb->Data)
{
- ExFreePool(Ccb->Data);
+ ExFreePoolWithTag(Ccb->Data, TAG_NPFS_CCB_DATA);
Ccb->Data = NULL;
Ccb->ReadPtr = NULL;
Ccb->WritePtr = NULL;
NpfsClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
BOOLEAN Server;
DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = FileObject->FsContext2;
return STATUS_SUCCESS;
}
+ if (Ccb->Type == CCB_DEVICE)
+ {
+ DPRINT("Closing the file system!\n");
+
+ NpfsDereferenceCcb(Ccb);
+ FileObject->FsContext = NULL;
+ FileObject->FsContext2 = NULL;
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
+ if (Ccb->Type == CCB_DIRECTORY)
+ {
+ DPRINT("Closing the root directory!\n");
+
+ if (Ccb->u.Directory.SearchPattern.Buffer != NULL)
+ ExFreePoolWithTag(Ccb->u.Directory.SearchPattern.Buffer,
+ TAG_NPFS_NAMEBLOCK);
+
+ NpfsDereferenceCcb(Ccb);
+ FileObject->FsContext = NULL;
+ FileObject->FsContext2 = NULL;
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
DPRINT("CCB %p\n", Ccb);
Fcb = Ccb->Fcb;
}
/* Disconnect the pipes */
- if (Ccb->OtherSide) Ccb->OtherSide->OtherSide = NULL;
- if (Ccb) Ccb->OtherSide = NULL;
+ if (Ccb->OtherSide)
+ {
+ /* FIXME: Timo wants it rewritten */
+ /*ASSERT(Ccb->OtherSide->OtherSide == Ccb);*/
+ NpfsCcbSetOtherSide(Ccb->OtherSide, NULL);
+ NpfsCcbSetOtherSide(Ccb, NULL);
+ }
ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE);
RemoveEntryList(&Ccb->CcbListEntry);
- ExFreePool(Ccb);
+ NpfsDereferenceCcb(Ccb);
KeUnlockMutex(&Fcb->CcbListLock);
if (IsListEmpty(&Fcb->ServerCcbListHead) &&
IsListEmpty(&Fcb->ClientCcbListHead))
{
- RtlFreeUnicodeString(&Fcb->PipeName);
- KeLockMutex(&DeviceExt->PipeListLock);
- RemoveEntryList(&Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
- ExFreePool(Fcb);
+ NpfsDeleteFcb(Fcb);
FileObject->FsContext = NULL;
}