Something went wrong. Try again.
Reactos
Something went wrong. Try again.
9.4 kB · 334 lines
C
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335/* * 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 <ndk/iotypes.h>
#define NDEBUG#include <debug.h>
/* FUNCTIONS *****************************************************************/
/* Creates the client side */NTSTATUS DEFAULTAPIMsfsCreate(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 DEFAULTAPIMsfsCreateMailslot(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 DEFAULTAPIMsfsClose(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 */