mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
220 lines
6 KiB
C
220 lines
6 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* FILE: drivers/filesystems/msfs/rw.c
|
|
* PURPOSE: Mailslot filesystem
|
|
* PROGRAMMER: Eric Kohl
|
|
* Nikita Pechenkin (n.pechenkin@mail.ru)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include "msfs.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
NTSTATUS DEFAULTAPI
|
|
MsfsRead(PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
PIO_STACK_LOCATION IoStack;
|
|
PFILE_OBJECT FileObject;
|
|
PMSFS_FCB Fcb;
|
|
PMSFS_CCB Ccb;
|
|
PMSFS_MESSAGE Message;
|
|
KIRQL oldIrql;
|
|
ULONG Length;
|
|
ULONG LengthRead = 0;
|
|
PVOID Buffer;
|
|
LARGE_INTEGER Timeout;
|
|
PKTIMER Timer;
|
|
PMSFS_DPC_CTX Context;
|
|
PKDPC Dpc;
|
|
PLIST_ENTRY Entry;
|
|
|
|
DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation (Irp);
|
|
FileObject = IoStack->FileObject;
|
|
Fcb = (PMSFS_FCB)FileObject->FsContext;
|
|
Ccb = (PMSFS_CCB)FileObject->FsContext2;
|
|
|
|
DPRINT("MailslotName: %wZ\n", &Fcb->Name);
|
|
|
|
/* reading is not permitted on client side */
|
|
if (Fcb->ServerCcb != Ccb)
|
|
{
|
|
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
}
|
|
|
|
Length = IoStack->Parameters.Read.Length;
|
|
if (Irp->MdlAddress)
|
|
Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
|
else
|
|
Buffer = Irp->UserBuffer;
|
|
|
|
|
|
KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
|
|
if (Fcb->MessageCount > 0)
|
|
{
|
|
Entry = RemoveHeadList(&Fcb->MessageListHead);
|
|
Fcb->MessageCount--;
|
|
KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
|
|
|
|
/* copy current message into buffer */
|
|
Message = CONTAINING_RECORD(Entry, MSFS_MESSAGE, MessageListEntry);
|
|
memcpy(Buffer, &Message->Buffer, min(Message->Size,Length));
|
|
LengthRead = Message->Size;
|
|
|
|
ExFreePoolWithTag(Message, 'rFsM');
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = LengthRead;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
|
|
}
|
|
|
|
Timeout = Fcb->TimeOut;
|
|
if (Timeout.HighPart == 0 && Timeout.LowPart == 0)
|
|
{
|
|
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_IO_TIMEOUT;
|
|
}
|
|
|
|
Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_DPC_CTX), 'NFsM');
|
|
if (Context == NULL)
|
|
{
|
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
KeInitializeEvent(&Context->Event, SynchronizationEvent, FALSE);
|
|
IoCsqInsertIrp(&Fcb->CancelSafeQueue, Irp, &Context->CsqContext);
|
|
Timer = &Context->Timer;
|
|
Dpc = &Context->Dpc;
|
|
Context->Csq = &Fcb->CancelSafeQueue;
|
|
Irp->Tail.Overlay.DriverContext[0] = Context;
|
|
|
|
/* No timer for INFINITY_WAIT */
|
|
if (Timeout.QuadPart != -1)
|
|
{
|
|
KeInitializeTimer(Timer);
|
|
KeInitializeDpc(Dpc, MsfsTimeout, (PVOID)Context);
|
|
KeSetTimer(Timer, Timeout, Dpc);
|
|
}
|
|
|
|
IoMarkIrpPending(Irp);
|
|
|
|
return STATUS_PENDING;
|
|
}
|
|
|
|
|
|
NTSTATUS DEFAULTAPI
|
|
MsfsWrite(PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
PIO_STACK_LOCATION IoStack;
|
|
PFILE_OBJECT FileObject;
|
|
PMSFS_FCB Fcb;
|
|
PMSFS_CCB Ccb;
|
|
PMSFS_MESSAGE Message;
|
|
KIRQL oldIrql;
|
|
ULONG Length;
|
|
PVOID Buffer;
|
|
PIRP CsqIrp;
|
|
PMSFS_DPC_CTX Context;
|
|
|
|
DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation (Irp);
|
|
FileObject = IoStack->FileObject;
|
|
Fcb = (PMSFS_FCB)FileObject->FsContext;
|
|
Ccb = (PMSFS_CCB)FileObject->FsContext2;
|
|
|
|
DPRINT("MailslotName: %wZ\n", &Fcb->Name);
|
|
|
|
/* writing is not permitted on server side */
|
|
if (Fcb->ServerCcb == Ccb)
|
|
{
|
|
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
}
|
|
|
|
Length = IoStack->Parameters.Write.Length;
|
|
if (Irp->MdlAddress)
|
|
Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
|
else
|
|
Buffer = Irp->UserBuffer;
|
|
|
|
DPRINT("Length: %lu Message: %s\n", Length, (PUCHAR)Buffer);
|
|
|
|
/* Allocate new message */
|
|
Message = ExAllocatePoolWithTag(NonPagedPool,
|
|
sizeof(MSFS_MESSAGE) + Length,
|
|
'rFsM');
|
|
if (Message == NULL)
|
|
{
|
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
Message->Size = Length;
|
|
memcpy(&Message->Buffer, Buffer, Length);
|
|
|
|
KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
|
|
InsertTailList(&Fcb->MessageListHead, &Message->MessageListEntry);
|
|
Fcb->MessageCount++;
|
|
KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
|
|
|
|
CsqIrp = IoCsqRemoveNextIrp(&Fcb->CancelSafeQueue, NULL);
|
|
if (CsqIrp != NULL)
|
|
{
|
|
/* Get the context */
|
|
Context = CsqIrp->Tail.Overlay.DriverContext[0];
|
|
/* DPC was queued, wait for it to fail (IRP is ours) */
|
|
if (Fcb->TimeOut.QuadPart != -1 && !KeCancelTimer(&Context->Timer))
|
|
{
|
|
KeWaitForSingleObject(&Context->Event, Executive, KernelMode, FALSE, NULL);
|
|
}
|
|
|
|
/* Free context & attempt read */
|
|
ExFreePoolWithTag(Context, 'NFsM');
|
|
MsfsRead(DeviceObject, CsqIrp);
|
|
}
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = Length;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/* EOF */
|