Index: drivers/filesystems/msfs/CMakeLists.txt =================================================================== --- drivers/filesystems/msfs/CMakeLists.txt (revision 69432) +++ drivers/filesystems/msfs/CMakeLists.txt (working copy) @@ -5,6 +5,8 @@ fsctrl.c msfs.c rw.c + msfssup.c + msfssup.h msfs.h) add_library(msfs SHARED ${SOURCE} msfs.rc) Index: drivers/filesystems/msfs/create.c =================================================================== --- drivers/filesystems/msfs/create.c (revision 69432) +++ drivers/filesystems/msfs/create.c (working copy) @@ -9,6 +9,7 @@ /* INCLUDES ******************************************************************/ #include "msfs.h" +#include "msfssup.h" #include @@ -183,6 +184,17 @@ InitializeListHead(&Fcb->MessageListHead); KeInitializeSpinLock(&Fcb->MessageListLock); + Fcb->WailCount = 0; + KeInitializeSpinLock(&Fcb->QueueLock); + InitializeListHead( &Fcb->PendingIrpQueue ); + IoCsqInitialize( &Fcb->CancelSafeQueue, + (PIO_CSQ_INSERT_IRP)MsfsInsertIrp, + (PIO_CSQ_REMOVE_IRP)MsfsRemoveIrp, + (PIO_CSQ_PEEK_NEXT_IRP)MsfsPeekNextIrp, + (PIO_CSQ_ACQUIRE_LOCK)MsfsAcquireLock, + (PIO_CSQ_RELEASE_LOCK)MsfsReleaseLock, + (PIO_CSQ_COMPLETE_CANCELED_IRP)MsfsCompleteCanceledIrp ); + KeLockMutex(&DeviceExtension->FcbListLock); current_entry = DeviceExtension->FcbListHead.Flink; while (current_entry != &DeviceExtension->FcbListHead) Index: drivers/filesystems/msfs/msfs.h =================================================================== --- drivers/filesystems/msfs/msfs.h (revision 69432) +++ drivers/filesystems/msfs/msfs.h (working copy) @@ -35,8 +35,19 @@ ULONG MessageCount; KSPIN_LOCK MessageListLock; LIST_ENTRY MessageListHead; + IO_CSQ CancelSafeQueue; + KSPIN_LOCK QueueLock; + LIST_ENTRY PendingIrpQueue; + ULONG WailCount; } MSFS_FCB, *PMSFS_FCB; +typedef struct _MSFS_DPC_CTX +{ + KTIMER Timer; + KDPC Dpc; + PIO_CSQ Csq; + IO_CSQ_IRP_CONTEXT Csq_context; +} MSFS_DPC_CTX, *PMSFS_DPC_CTX; typedef struct _MSFS_CCB { Index: drivers/filesystems/msfs/msfssup.c =================================================================== --- drivers/filesystems/msfs/msfssup.c (revision 0) +++ drivers/filesystems/msfs/msfssup.c (working copy) @@ -0,0 +1,118 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/filesystems/msfs/msfssup.c + * PURPOSE: Mailslot filesystem + * PROGRAMMER: nikita pechenkin (n.pechenkin@mail.ru) + */ + +/* INCLUDES ******************************************************************/ +#include "msfs.h" +#include "msfssup.h" + +#include + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +VOID MsfsInsertIrp (PIO_CSQ Csq, PIRP Irp) +{ + PMSFS_FCB fsb; + + fsb = CONTAINING_RECORD(Csq, MSFS_FCB, CancelSafeQueue); + InsertTailList(&fsb->PendingIrpQueue,&Irp->Tail.Overlay.ListEntry); +} + +VOID MsfsRemoveIrp(PIO_CSQ Csq, PIRP Irp) +{ + UNREFERENCED_PARAMETER(Csq); + + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); +} + +PIRP MsfsPeekNextIrp(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext) +{ + PMSFS_FCB fsb; + PIRP nextIrp = NULL; + PLIST_ENTRY nextEntry; + PLIST_ENTRY listHead; + PIO_STACK_LOCATION irpStack; + + fsb = CONTAINING_RECORD(Csq, MSFS_FCB, CancelSafeQueue); + + listHead = &fsb->PendingIrpQueue; + + if (Irp == NULL) { + nextEntry = listHead->Flink; + } else { + nextEntry = Irp->Tail.Overlay.ListEntry.Flink; + } + + while(nextEntry != listHead) { + + nextIrp = CONTAINING_RECORD(nextEntry, IRP, Tail.Overlay.ListEntry); + + irpStack = IoGetCurrentIrpStackLocation(nextIrp); + + if (PeekContext) { + if (irpStack->FileObject == (PFILE_OBJECT) PeekContext) { + break; + } + } else { + break; + } + nextIrp = NULL; + nextEntry = nextEntry->Flink; + } + + return nextIrp; +} + +VOID MsfsAcquireLock(PIO_CSQ Csq, PKIRQL Irql) +{ + PMSFS_FCB fsb; + + fsb = CONTAINING_RECORD(Csq,MSFS_FCB, CancelSafeQueue); + KeAcquireSpinLock(&fsb->QueueLock, Irql); +} + + +VOID MsfsReleaseLock(PIO_CSQ Csq, KIRQL Irql) +{ + PMSFS_FCB fsd; + + fsd = CONTAINING_RECORD(Csq, + MSFS_FCB, CancelSafeQueue); + KeReleaseSpinLock(&fsd->QueueLock, Irql); +} + +VOID MsfsCompleteCanceledIrp(PIO_CSQ pCsq, PIRP Irp) +{ + + UNREFERENCED_PARAMETER(pCsq); + + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + +VOID MsfsTimeout(struct _KDPC *Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + PMSFS_DPC_CTX Context; + PIRP wIrp; + Context = (PMSFS_DPC_CTX)DeferredContext; + wIrp = IoCsqRemoveIrp(Context->Csq,&Context->Csq_context); + if (wIrp) + { + wIrp->IoStatus.Status = STATUS_IO_TIMEOUT; + IoCompleteRequest( wIrp, IO_NO_INCREMENT ); + } + ExFreePool(Context); +} + +/* EOF */ Index: drivers/filesystems/msfs/msfssup.h =================================================================== --- drivers/filesystems/msfs/msfssup.h (revision 0) +++ drivers/filesystems/msfs/msfssup.h (working copy) @@ -0,0 +1,36 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/filesystems/msfs/msfssup.h + * PURPOSE: Mailslot filesystem + * PROGRAMMER: nikita pechenkin (n.pechenkin@mail.ru) + */ + +#ifndef __DRIVERS_FS_MS_MSFSSUP_H +#define __DRIVERS_FS_MS_MSFSSUP_H + +VOID +MsfsInsertIrp (PIO_CSQ Csq, PIRP Irp); + +VOID +MsfsRemoveIrp(PIO_CSQ Csq, PIRP Irp); + +PIRP +MsfsPeekNextIrp(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext); + +VOID +MsfsAcquireLock(PIO_CSQ Csq, PKIRQL Irql); + +VOID +MsfsReleaseLock(PIO_CSQ Csq, KIRQL Irql); + +VOID +MsfsCompleteCanceledIrp(PIO_CSQ pCsq, PIRP Irp); + +VOID +MsfsTimeout(struct _KDPC *Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2); + +#endif /* __DRIVERS_FS_MS_MSFSSUP_H */ Index: drivers/filesystems/msfs/rw.c =================================================================== --- drivers/filesystems/msfs/rw.c (revision 69432) +++ drivers/filesystems/msfs/rw.c (working copy) @@ -9,6 +9,7 @@ /* INCLUDES ******************************************************************/ #include "msfs.h" +#include "msfssup.h" #define NDEBUG #include @@ -29,7 +30,10 @@ ULONG LengthRead = 0; PVOID Buffer; NTSTATUS Status; - PLARGE_INTEGER Timeout; + LARGE_INTEGER Timeout; + PKTIMER Timer; + PMSFS_DPC_CTX Context; + PKDPC Dpc; DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp); @@ -57,51 +61,63 @@ else Buffer = Irp->UserBuffer; - if (Fcb->TimeOut.QuadPart == -1LL) - Timeout = NULL; - else - Timeout = &Fcb->TimeOut; - Status = KeWaitForSingleObject(&Fcb->MessageEvent, - UserRequest, - UserMode, - FALSE, - Timeout); - if (Status != STATUS_USER_APC) + if (Fcb->MessageCount > 0) { - if (Fcb->MessageCount > 0) - { - /* copy current message into buffer */ - Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink, - MSFS_MESSAGE, - MessageListEntry); + /* copy current message into buffer */ + Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink, + MSFS_MESSAGE, + MessageListEntry); - memcpy(Buffer, &Message->Buffer, min(Message->Size,Length)); - LengthRead = Message->Size; + memcpy(Buffer, &Message->Buffer, min(Message->Size,Length)); + LengthRead = Message->Size; - KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql); - RemoveHeadList(&Fcb->MessageListHead); - KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql); + KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql); + RemoveHeadList(&Fcb->MessageListHead); + KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql); - ExFreePoolWithTag(Message, 'rFsM'); - Fcb->MessageCount--; - if (Fcb->MessageCount == 0) - { - KeClearEvent(&Fcb->MessageEvent); - } + ExFreePoolWithTag(Message, 'rFsM'); + Fcb->MessageCount--; + if (Fcb->MessageCount == 0) + { + KeClearEvent(&Fcb->MessageEvent); } + Irp->IoStatus.Status = Status = STATUS_SUCCESS; + Irp->IoStatus.Information = LengthRead; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + else + { + Timeout = Fcb->TimeOut; + if (Timeout.HighPart == 0 && Timeout.LowPart == 0) + { + Irp->IoStatus.Status = Status = STATUS_IO_TIMEOUT; + Irp->IoStatus.Information = LengthRead; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } else { - /* No message found after waiting */ - Status = STATUS_IO_TIMEOUT; - } - } + Context = FsRtlAllocatePool( NonPagedPool, sizeof(MSFS_DPC_CTX)); - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = LengthRead; + IoCsqInsertIrp(&Fcb->CancelSafeQueue, Irp, &Context->Csq_context); + Timer = &Context->Timer; + Dpc = &Context->Dpc; + Context->Csq = &Fcb->CancelSafeQueue; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if ( Timeout.QuadPart != -1 ) //no timer for INFINITY_WAIT + { + KeInitializeTimer( Timer ); + KeInitializeDpc( Dpc, (PKDEFERRED_ROUTINE)MsfsTimeout, (PVOID)Context ); + KeSetTimer( Timer, Timeout, Dpc ); + } + Fcb->WailCount++; + Irp->IoStatus.Status = Status = STATUS_PENDING; + Irp->IoStatus.Information = LengthRead; + IoMarkIrpPending( Irp ); + } + } + return Status; } @@ -118,6 +134,7 @@ KIRQL oldIrql; ULONG Length; PVOID Buffer; + PIRP IrpW; DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp); @@ -176,6 +193,14 @@ FALSE); } + if (Fcb->WailCount > 0) + { + IrpW = IoCsqRemoveNextIrp(&Fcb->CancelSafeQueue, NULL); + /* FIXME: It is necessary to reset the timers. */ + MsfsRead(DeviceObject, IrpW); + Fcb->WailCount--; + } + Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = Length;