mirror of
https://github.com/reactos/reactos.git
synced 2024-11-05 22:26:39 +00:00
c424146e2c
svn path=/branches/cmake-bringup/; revision=48236
322 lines
8.5 KiB
C
322 lines
8.5 KiB
C
/*
|
|
* 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 <debug.h>
|
|
|
|
|
|
/* 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);
|
|
|
|
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 */
|