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/C…
==============================================================================
--- 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/c…
==============================================================================
--- 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(a)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/m…
==============================================================================
--- 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(a)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/r…
==============================================================================
--- 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(a)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;