mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 02:15:47 +00:00
[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! svn path=/trunk/; revision=69475
This commit is contained in:
parent
8cd50ca0ee
commit
ead10526aa
4 changed files with 134 additions and 41 deletions
|
@ -5,6 +5,7 @@ list(APPEND SOURCE
|
||||||
fsctrl.c
|
fsctrl.c
|
||||||
msfs.c
|
msfs.c
|
||||||
rw.c
|
rw.c
|
||||||
|
msfssup.c
|
||||||
msfs.h)
|
msfs.h)
|
||||||
|
|
||||||
add_library(msfs SHARED ${SOURCE} msfs.rc)
|
add_library(msfs SHARED ${SOURCE} msfs.rc)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* FILE: drivers/filesystems/msfs/create.c
|
* FILE: drivers/filesystems/msfs/create.c
|
||||||
* PURPOSE: Mailslot filesystem
|
* PURPOSE: Mailslot filesystem
|
||||||
* PROGRAMMER: Eric Kohl
|
* PROGRAMMER: Eric Kohl
|
||||||
|
* Nikita Pechenkin (n.pechenkin@mail.ru)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -183,6 +184,17 @@ MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject,
|
||||||
InitializeListHead(&Fcb->MessageListHead);
|
InitializeListHead(&Fcb->MessageListHead);
|
||||||
KeInitializeSpinLock(&Fcb->MessageListLock);
|
KeInitializeSpinLock(&Fcb->MessageListLock);
|
||||||
|
|
||||||
|
Fcb->WaitCount = 0;
|
||||||
|
KeInitializeSpinLock(&Fcb->QueueLock);
|
||||||
|
InitializeListHead(&Fcb->PendingIrpQueue);
|
||||||
|
IoCsqInitialize(&Fcb->CancelSafeQueue,
|
||||||
|
MsfsInsertIrp,
|
||||||
|
MsfsRemoveIrp,
|
||||||
|
MsfsPeekNextIrp,
|
||||||
|
MsfsAcquireLock,
|
||||||
|
MsfsReleaseLock,
|
||||||
|
MsfsCompleteCanceledIrp);
|
||||||
|
|
||||||
KeLockMutex(&DeviceExtension->FcbListLock);
|
KeLockMutex(&DeviceExtension->FcbListLock);
|
||||||
current_entry = DeviceExtension->FcbListHead.Flink;
|
current_entry = DeviceExtension->FcbListHead.Flink;
|
||||||
while (current_entry != &DeviceExtension->FcbListHead)
|
while (current_entry != &DeviceExtension->FcbListHead)
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
* FILE: drivers/filesystems/msfs/msfs.h
|
* FILE: drivers/filesystems/msfs/msfs.h
|
||||||
* PURPOSE: Mailslot filesystem
|
* PURPOSE: Mailslot filesystem
|
||||||
* PROGRAMMER: Eric Kohl
|
* PROGRAMMER: Eric Kohl
|
||||||
|
* Nikita Pechenkin (n.pechenkin@mail.ru)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DRIVERS_FS_MS_MSFS_H
|
#ifndef __DRIVERS_FS_MS_MSFS_H
|
||||||
#define __DRIVERS_FS_MS_MSFS_H
|
#define __DRIVERS_FS_MS_MSFS_H
|
||||||
|
|
||||||
#include <ntifs.h>
|
#include <ntifs.h>
|
||||||
|
#include <wdm.h>
|
||||||
|
|
||||||
#define DEFAULTAPI NTAPI
|
#define DEFAULTAPI NTAPI
|
||||||
|
|
||||||
|
@ -35,9 +37,22 @@ typedef struct _MSFS_FCB
|
||||||
ULONG MessageCount;
|
ULONG MessageCount;
|
||||||
KSPIN_LOCK MessageListLock;
|
KSPIN_LOCK MessageListLock;
|
||||||
LIST_ENTRY MessageListHead;
|
LIST_ENTRY MessageListHead;
|
||||||
|
IO_CSQ CancelSafeQueue;
|
||||||
|
KSPIN_LOCK QueueLock;
|
||||||
|
LIST_ENTRY PendingIrpQueue;
|
||||||
|
ULONG WaitCount;
|
||||||
} MSFS_FCB, *PMSFS_FCB;
|
} 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
|
typedef struct _MSFS_CCB
|
||||||
{
|
{
|
||||||
LIST_ENTRY CcbListEntry;
|
LIST_ENTRY CcbListEntry;
|
||||||
|
@ -89,4 +104,35 @@ NTSTATUS NTAPI
|
||||||
DriverEntry(PDRIVER_OBJECT DriverObject,
|
DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||||
PUNICODE_STRING RegistryPath);
|
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 */
|
#endif /* __DRIVERS_FS_MS_MSFS_H */
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* FILE: drivers/filesystems/msfs/rw.c
|
* FILE: drivers/filesystems/msfs/rw.c
|
||||||
* PURPOSE: Mailslot filesystem
|
* PURPOSE: Mailslot filesystem
|
||||||
* PROGRAMMER: Eric Kohl
|
* PROGRAMMER: Eric Kohl
|
||||||
|
* Nikita Pechenkin (n.pechenkin@mail.ru)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -28,8 +29,10 @@ MsfsRead(PDEVICE_OBJECT DeviceObject,
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
ULONG LengthRead = 0;
|
ULONG LengthRead = 0;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
NTSTATUS Status;
|
LARGE_INTEGER Timeout;
|
||||||
PLARGE_INTEGER Timeout;
|
PKTIMER Timer;
|
||||||
|
PMSFS_DPC_CTX Context;
|
||||||
|
PKDPC Dpc;
|
||||||
|
|
||||||
DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
|
@ -57,52 +60,74 @@ MsfsRead(PDEVICE_OBJECT DeviceObject,
|
||||||
else
|
else
|
||||||
Buffer = Irp->UserBuffer;
|
Buffer = Irp->UserBuffer;
|
||||||
|
|
||||||
if (Fcb->TimeOut.QuadPart == -1LL)
|
|
||||||
Timeout = NULL;
|
|
||||||
else
|
|
||||||
Timeout = &Fcb->TimeOut;
|
|
||||||
|
|
||||||
Status = KeWaitForSingleObject(&Fcb->MessageEvent,
|
if (Fcb->MessageCount > 0)
|
||||||
UserRequest,
|
|
||||||
UserMode,
|
|
||||||
FALSE,
|
|
||||||
Timeout);
|
|
||||||
if (Status != STATUS_USER_APC)
|
|
||||||
{
|
{
|
||||||
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 */
|
KeClearEvent(&Fcb->MessageEvent);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No message found after waiting */
|
|
||||||
Status = STATUS_IO_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = LengthRead;
|
Irp->IoStatus.Information = LengthRead;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
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 @@ MsfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
|
PIRP CsqIrp;
|
||||||
|
|
||||||
DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
|
@ -176,6 +202,14 @@ MsfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
FALSE);
|
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.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = Length;
|
Irp->IoStatus.Information = Length;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue