/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/filesystems/msfs/create.c * PURPOSE: Mailslot filesystem * PROGRAMMER: Eric Kohl */ /* INCLUDES ******************************************************************/ #include "msfs.h" #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 = ExAllocatePool(NonPagedPool, sizeof(MSFS_CCB)); 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) { ExFreePool(Ccb); 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) { PEXTENDED_IO_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 = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp); DeviceExtension = DeviceObject->DeviceExtension; FileObject = IoStack->FileObject; Buffer = IoStack->Parameters.CreateMailslot.Parameters; DPRINT("Mailslot name: %wZ\n", &FileObject->FileName); Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB)); 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 = ExAllocatePool(NonPagedPool, Fcb->Name.MaximumLength); if (Fcb->Name.Buffer == NULL) { ExFreePool(Fcb); 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 = ExAllocatePool(NonPagedPool, sizeof(MSFS_CCB)); if (Ccb == NULL) { ExFreePool(Fcb->Name.Buffer); ExFreePool(Fcb); 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; KeInitializeEvent(&Fcb->MessageEvent, NotificationEvent, FALSE); InitializeListHead(&Fcb->MessageListHead); KeInitializeSpinLock(&Fcb->MessageListLock); 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) { ExFreePool(Fcb->Name.Buffer); ExFreePool(Fcb); ExFreePool(Ccb); 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); ExFreePool(Message); } Fcb->MessageCount = 0; KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql); Fcb->ServerCcb = NULL; } KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); RemoveEntryList(&Ccb->CcbListEntry); KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); ExFreePool(Ccb); FileObject->FsContext2 = NULL; if (Fcb->ReferenceCount == 0) { DPRINT("ReferenceCount == 0: Deleting mailslot data\n"); RemoveEntryList(&Fcb->FcbListEntry); ExFreePool(Fcb->Name.Buffer); ExFreePool(Fcb); } KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } /* EOF */