Author: pschweitzer Date: Sat Oct 10 08:29:05 2015 New Revision: 69475
URL: http://svn.reactos.org/svn/reactos?rev=69475&view=rev Log: [MSFS] Implement asynchronous reading from mailslot. Patch by Nikita Pechenkin
Adjustements, style fixing by myself.
CORE-10245 #resolve #comment Modified patch committed with r69475. I have tested kernel32:mailslot and your provided test, both are passing 100%. Thanks!
Modified: trunk/reactos/drivers/filesystems/msfs/CMakeLists.txt trunk/reactos/drivers/filesystems/msfs/create.c trunk/reactos/drivers/filesystems/msfs/msfs.h trunk/reactos/drivers/filesystems/msfs/rw.c
Modified: trunk/reactos/drivers/filesystems/msfs/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/msfs/CM... ============================================================================== --- trunk/reactos/drivers/filesystems/msfs/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/msfs/CMakeLists.txt [iso-8859-1] Sat Oct 10 08:29:05 2015 @@ -5,6 +5,7 @@ fsctrl.c msfs.c rw.c + msfssup.c msfs.h)
add_library(msfs SHARED ${SOURCE} msfs.rc)
Modified: trunk/reactos/drivers/filesystems/msfs/create.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/msfs/cr... ============================================================================== --- trunk/reactos/drivers/filesystems/msfs/create.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/msfs/create.c [iso-8859-1] Sat Oct 10 08:29:05 2015 @@ -4,6 +4,7 @@ * FILE: drivers/filesystems/msfs/create.c * PURPOSE: Mailslot filesystem * PROGRAMMER: Eric Kohl + * Nikita Pechenkin (n.pechenkin@mail.ru) */
/* INCLUDES ******************************************************************/ @@ -183,6 +184,17 @@ InitializeListHead(&Fcb->MessageListHead); KeInitializeSpinLock(&Fcb->MessageListLock);
+ Fcb->WaitCount = 0; + 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)
Modified: trunk/reactos/drivers/filesystems/msfs/msfs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/msfs/ms... ============================================================================== --- trunk/reactos/drivers/filesystems/msfs/msfs.h [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/msfs/msfs.h [iso-8859-1] Sat Oct 10 08:29:05 2015 @@ -4,12 +4,14 @@ * FILE: drivers/filesystems/msfs/msfs.h * PURPOSE: Mailslot filesystem * PROGRAMMER: Eric Kohl + * Nikita Pechenkin (n.pechenkin@mail.ru) */
#ifndef __DRIVERS_FS_MS_MSFS_H #define __DRIVERS_FS_MS_MSFS_H
#include <ntifs.h> +#include <wdm.h>
#define DEFAULTAPI NTAPI
@@ -35,7 +37,20 @@ ULONG MessageCount; KSPIN_LOCK MessageListLock; LIST_ENTRY MessageListHead; + IO_CSQ CancelSafeQueue; + KSPIN_LOCK QueueLock; + LIST_ENTRY PendingIrpQueue; + ULONG WaitCount; } MSFS_FCB, *PMSFS_FCB; + + +typedef struct _MSFS_DPC_CTX +{ + KTIMER Timer; + KDPC Dpc; + PIO_CSQ Csq; + IO_CSQ_IRP_CONTEXT CsqContext; +} MSFS_DPC_CTX, *PMSFS_DPC_CTX;
typedef struct _MSFS_CCB @@ -89,4 +104,35 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
+IO_CSQ_INSERT_IRP MsfsInsertIrp; +VOID NTAPI +MsfsInsertIrp(PIO_CSQ Csq, PIRP Irp); + +IO_CSQ_REMOVE_IRP MsfsRemoveIrp; +VOID NTAPI +MsfsRemoveIrp(PIO_CSQ Csq, PIRP Irp); + +IO_CSQ_PEEK_NEXT_IRP MsfsPeekNextIrp; +PIRP NTAPI +MsfsPeekNextIrp(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext); + +IO_CSQ_ACQUIRE_LOCK MsfsAcquireLock; +VOID NTAPI +MsfsAcquireLock(PIO_CSQ Csq, PKIRQL Irql); + +IO_CSQ_RELEASE_LOCK MsfsReleaseLock; +VOID NTAPI +MsfsReleaseLock(PIO_CSQ Csq, KIRQL Irql); + +IO_CSQ_COMPLETE_CANCELED_IRP MsfsCompleteCanceledIrp; +VOID NTAPI +MsfsCompleteCanceledIrp(PIO_CSQ pCsq, PIRP Irp); + +KDEFERRED_ROUTINE MsfsTimeout; +VOID NTAPI +MsfsTimeout(PKDPC Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2); + #endif /* __DRIVERS_FS_MS_MSFS_H */
Modified: trunk/reactos/drivers/filesystems/msfs/rw.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/msfs/rw... ============================================================================== --- trunk/reactos/drivers/filesystems/msfs/rw.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/msfs/rw.c [iso-8859-1] Sat Oct 10 08:29:05 2015 @@ -4,6 +4,7 @@ * FILE: drivers/filesystems/msfs/rw.c * PURPOSE: Mailslot filesystem * PROGRAMMER: Eric Kohl + * Nikita Pechenkin (n.pechenkin@mail.ru) */
/* INCLUDES ******************************************************************/ @@ -28,8 +29,10 @@ ULONG Length; 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,52 +60,74 @@ 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); + + memcpy(Buffer, &Message->Buffer, min(Message->Size,Length)); + LengthRead = Message->Size; + + KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql); + RemoveHeadList(&Fcb->MessageListHead); + KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql); + + ExFreePoolWithTag(Message, 'rFsM'); + Fcb->MessageCount--; + if (Fcb->MessageCount == 0) { - /* 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; - - KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql); - RemoveHeadList(&Fcb->MessageListHead); - KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql); - - ExFreePoolWithTag(Message, 'rFsM'); - Fcb->MessageCount--; - if (Fcb->MessageCount == 0) - { - KeClearEvent(&Fcb->MessageEvent); - } + KeClearEvent(&Fcb->MessageEvent); } - else - { - /* No message found after waiting */ - Status = STATUS_IO_TIMEOUT; - } - } - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = LengthRead; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = LengthRead; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + } + + 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; + } + + IoCsqInsertIrp(&Fcb->CancelSafeQueue, Irp, &Context->CsqContext); + Timer = &Context->Timer; + Dpc = &Context->Dpc; + Context->Csq = &Fcb->CancelSafeQueue; + + /* No timer for INFINITY_WAIT */ + if (Timeout.QuadPart != -1) + { + KeInitializeTimer(Timer); + KeInitializeDpc(Dpc, MsfsTimeout, (PVOID)Context); + KeSetTimer(Timer, Timeout, Dpc); + } + + Fcb->WaitCount++; + Irp->IoStatus.Status = STATUS_PENDING; + Irp->IoStatus.Information = 0; + IoMarkIrpPending(Irp); + + return STATUS_PENDING; }
@@ -118,6 +143,7 @@ KIRQL oldIrql; ULONG Length; PVOID Buffer; + PIRP CsqIrp;
DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
@@ -176,6 +202,14 @@ FALSE); }
+ if (Fcb->WaitCount > 0) + { + CsqIrp = IoCsqRemoveNextIrp(&Fcb->CancelSafeQueue, NULL); + /* FIXME: It is necessary to reset the timers. */ + MsfsRead(DeviceObject, CsqIrp); + Fcb->WaitCount--; + } + Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = Length;