/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/filesystems/msfs/create.c * PURPOSE: Mailslot filesystem * PROGRAMMER: Eric Kohl * Nikita Pechenkin (n.pechenkin@mail.ru) */ /* INCLUDES ******************************************************************/ #include "msfs.h" #include #define NDEBUG #include /* FUNCTIONS *****************************************************************/ /* Creates the client side */ NTSTATUS DEFAULTAPI MsfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; PMSFS_DEVICE_EXTENSION DeviceExtension; PMSFS_FCB Fcb; PMSFS_CCB Ccb; PMSFS_FCB current = NULL; PLIST_ENTRY current_entry; KIRQL oldIrql; DPRINT("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); IoStack = IoGetCurrentIrpStackLocation(Irp); DeviceExtension = DeviceObject->DeviceExtension; FileObject = IoStack->FileObject; DPRINT("Mailslot name: %wZ\n", &FileObject->FileName); Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_CCB), 'cFsM'); if (Ccb == NULL) { Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; } KeLockMutex(&DeviceExtension->FcbListLock); current_entry = DeviceExtension->FcbListHead.Flink; while (current_entry != &DeviceExtension->FcbListHead) { current = CONTAINING_RECORD(current_entry, MSFS_FCB, FcbListEntry); if (!RtlCompareUnicodeString(&FileObject->FileName, ¤t->Name, TRUE)) break; current_entry = current_entry->Flink; } if (current_entry == &DeviceExtension->FcbListHead) { ExFreePoolWithTag(Ccb, 'cFsM'); KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } Fcb = current; KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry); KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); Fcb->ReferenceCount++; Ccb->Fcb = Fcb; KeUnlockMutex(&DeviceExtension->FcbListLock); FileObject->FsContext = Fcb; FileObject->FsContext2 = Ccb; FileObject->Flags |= FO_MAILSLOT; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } /* Creates the server side */ NTSTATUS DEFAULTAPI MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; PMSFS_DEVICE_EXTENSION DeviceExtension; PMSFS_FCB Fcb; PMSFS_CCB Ccb; KIRQL oldIrql; PLIST_ENTRY current_entry; PMSFS_FCB current = NULL; PMAILSLOT_CREATE_PARAMETERS Buffer; DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp); IoStack = IoGetCurrentIrpStackLocation(Irp); DeviceExtension = DeviceObject->DeviceExtension; FileObject = IoStack->FileObject; Buffer = IoStack->Parameters.CreateMailslot.Parameters; DPRINT("Mailslot name: %wZ\n", &FileObject->FileName); Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_FCB), 'fFsM'); if (Fcb == NULL) { Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; } Fcb->Name.Length = FileObject->FileName.Length; Fcb->Name.MaximumLength = Fcb->Name.Length + sizeof(UNICODE_NULL); Fcb->Name.Buffer = ExAllocatePoolWithTag(NonPagedPool, Fcb->Name.MaximumLength, 'NFsM'); if (Fcb->Name.Buffer == NULL) { ExFreePoolWithTag(Fcb, 'fFsM'); Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; } RtlCopyUnicodeString(&Fcb->Name, &FileObject->FileName); Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_CCB), 'cFsM'); if (Ccb == NULL) { ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM'); ExFreePoolWithTag(Fcb, 'fFsM'); Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; } Fcb->ReferenceCount = 0; InitializeListHead(&Fcb->CcbListHead); KeInitializeSpinLock(&Fcb->CcbListLock); Fcb->MaxMessageSize = Buffer->MaximumMessageSize; Fcb->MessageCount = 0; Fcb->TimeOut = Buffer->ReadTimeout; InitializeListHead(&Fcb->MessageListHead); KeInitializeSpinLock(&Fcb->MessageListLock); KeInitializeSpinLock(&Fcb->QueueLock); InitializeListHead(&Fcb->PendingIrpQueue); IoCsqInitialize(&Fcb->CancelSafeQueue, MsfsInsertIrp, MsfsRemoveIrp, MsfsPeekNextIrp, MsfsAcquireLock, MsfsReleaseLock, MsfsCompleteCanceledIrp); KeLockMutex(&DeviceExtension->FcbListLock); current_entry = DeviceExtension->FcbListHead.Flink; while (current_entry != &DeviceExtension->FcbListHead) { current = CONTAINING_RECORD(current_entry, MSFS_FCB, FcbListEntry); if (!RtlCompareUnicodeString(&Fcb->Name, ¤t->Name, TRUE)) break; current_entry = current_entry->Flink; } if (current_entry != &DeviceExtension->FcbListHead) { ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM'); ExFreePoolWithTag(Fcb, 'fFsM'); ExFreePoolWithTag(Ccb, 'cFsM'); KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } else { InsertTailList(&DeviceExtension->FcbListHead, &Fcb->FcbListEntry); } KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry); KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); Fcb->ReferenceCount++; Fcb->ServerCcb = Ccb; Ccb->Fcb = Fcb; KeUnlockMutex(&DeviceExtension->FcbListLock); FileObject->FsContext = Fcb; FileObject->FsContext2 = Ccb; FileObject->Flags |= FO_MAILSLOT; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DEFAULTAPI MsfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; PMSFS_DEVICE_EXTENSION DeviceExtension; PMSFS_FCB Fcb; PMSFS_CCB Ccb; PMSFS_MESSAGE Message; KIRQL oldIrql; DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); IoStack = IoGetCurrentIrpStackLocation(Irp); DeviceExtension = DeviceObject->DeviceExtension; FileObject = IoStack->FileObject; KeLockMutex(&DeviceExtension->FcbListLock); if (DeviceExtension->FcbListHead.Flink == &DeviceExtension->FcbListHead) { KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } Fcb = FileObject->FsContext; Ccb = FileObject->FsContext2; DPRINT("Mailslot name: %wZ\n", &Fcb->Name); Fcb->ReferenceCount--; if (Fcb->ServerCcb == Ccb) { /* delete all messages from message-list */ KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql); while (Fcb->MessageListHead.Flink != &Fcb->MessageListHead) { Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink, MSFS_MESSAGE, MessageListEntry); RemoveEntryList(Fcb->MessageListHead.Flink); ExFreePoolWithTag(Message, 'rFsM'); } Fcb->MessageCount = 0; KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql); Fcb->ServerCcb = NULL; } KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); RemoveEntryList(&Ccb->CcbListEntry); KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); ExFreePoolWithTag(Ccb, 'cFsM'); FileObject->FsContext2 = NULL; if (Fcb->ReferenceCount == 0) { DPRINT("ReferenceCount == 0: Deleting mailslot data\n"); RemoveEntryList(&Fcb->FcbListEntry); ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM'); ExFreePoolWithTag(Fcb, 'fFsM'); } KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } /* EOF */