2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/filesystems/msfs/rw.c
5 * PURPOSE: Mailslot filesystem
6 * PROGRAMMER: Eric Kohl
7 * Nikita Pechenkin (n.pechenkin@mail.ru)
10 /* INCLUDES ******************************************************************/
17 /* FUNCTIONS *****************************************************************/
20 MsfsRead(PDEVICE_OBJECT DeviceObject
,
23 PIO_STACK_LOCATION IoStack
;
24 PFILE_OBJECT FileObject
;
27 PMSFS_MESSAGE Message
;
32 LARGE_INTEGER Timeout
;
34 PMSFS_DPC_CTX Context
;
38 DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
40 IoStack
= IoGetCurrentIrpStackLocation (Irp
);
41 FileObject
= IoStack
->FileObject
;
42 Fcb
= (PMSFS_FCB
)FileObject
->FsContext
;
43 Ccb
= (PMSFS_CCB
)FileObject
->FsContext2
;
45 DPRINT("MailslotName: %wZ\n", &Fcb
->Name
);
47 /* reading is not permitted on client side */
48 if (Fcb
->ServerCcb
!= Ccb
)
50 Irp
->IoStatus
.Status
= STATUS_ACCESS_DENIED
;
51 Irp
->IoStatus
.Information
= 0;
53 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
55 return STATUS_ACCESS_DENIED
;
58 Length
= IoStack
->Parameters
.Read
.Length
;
60 Buffer
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
62 Buffer
= Irp
->UserBuffer
;
65 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
66 if (Fcb
->MessageCount
> 0)
68 Entry
= RemoveHeadList(&Fcb
->MessageListHead
);
70 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
72 /* copy current message into buffer */
73 Message
= CONTAINING_RECORD(Entry
, MSFS_MESSAGE
, MessageListEntry
);
74 memcpy(Buffer
, &Message
->Buffer
, min(Message
->Size
,Length
));
75 LengthRead
= Message
->Size
;
77 ExFreePoolWithTag(Message
, 'rFsM');
79 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
80 Irp
->IoStatus
.Information
= LengthRead
;
81 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
83 return STATUS_SUCCESS
;
87 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
90 Timeout
= Fcb
->TimeOut
;
91 if (Timeout
.HighPart
== 0 && Timeout
.LowPart
== 0)
93 Irp
->IoStatus
.Status
= STATUS_IO_TIMEOUT
;
94 Irp
->IoStatus
.Information
= 0;
95 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
97 return STATUS_IO_TIMEOUT
;
100 Context
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MSFS_DPC_CTX
), 'NFsM');
103 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
104 Irp
->IoStatus
.Information
= 0;
105 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
107 return STATUS_INSUFFICIENT_RESOURCES
;
110 KeInitializeEvent(&Context
->Event
, SynchronizationEvent
, FALSE
);
111 IoCsqInsertIrp(&Fcb
->CancelSafeQueue
, Irp
, &Context
->CsqContext
);
112 Timer
= &Context
->Timer
;
114 Context
->Csq
= &Fcb
->CancelSafeQueue
;
115 Irp
->Tail
.Overlay
.DriverContext
[0] = Context
;
117 /* No timer for INFINITY_WAIT */
118 if (Timeout
.QuadPart
!= -1)
120 KeInitializeTimer(Timer
);
121 KeInitializeDpc(Dpc
, MsfsTimeout
, (PVOID
)Context
);
122 KeSetTimer(Timer
, Timeout
, Dpc
);
125 IoMarkIrpPending(Irp
);
127 return STATUS_PENDING
;
132 MsfsWrite(PDEVICE_OBJECT DeviceObject
,
135 PIO_STACK_LOCATION IoStack
;
136 PFILE_OBJECT FileObject
;
139 PMSFS_MESSAGE Message
;
144 PMSFS_DPC_CTX Context
;
146 DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
148 IoStack
= IoGetCurrentIrpStackLocation (Irp
);
149 FileObject
= IoStack
->FileObject
;
150 Fcb
= (PMSFS_FCB
)FileObject
->FsContext
;
151 Ccb
= (PMSFS_CCB
)FileObject
->FsContext2
;
153 DPRINT("MailslotName: %wZ\n", &Fcb
->Name
);
155 /* writing is not permitted on server side */
156 if (Fcb
->ServerCcb
== Ccb
)
158 Irp
->IoStatus
.Status
= STATUS_ACCESS_DENIED
;
159 Irp
->IoStatus
.Information
= 0;
161 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
163 return STATUS_ACCESS_DENIED
;
166 Length
= IoStack
->Parameters
.Write
.Length
;
168 Buffer
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
170 Buffer
= Irp
->UserBuffer
;
172 DPRINT("Length: %lu Message: %s\n", Length
, (PUCHAR
)Buffer
);
174 /* Allocate new message */
175 Message
= ExAllocatePoolWithTag(NonPagedPool
,
176 sizeof(MSFS_MESSAGE
) + Length
,
180 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
181 Irp
->IoStatus
.Information
= 0;
183 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
185 return STATUS_NO_MEMORY
;
188 Message
->Size
= Length
;
189 memcpy(&Message
->Buffer
, Buffer
, Length
);
191 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
192 InsertTailList(&Fcb
->MessageListHead
, &Message
->MessageListEntry
);
194 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
196 CsqIrp
= IoCsqRemoveNextIrp(&Fcb
->CancelSafeQueue
, NULL
);
199 /* Get the context */
200 Context
= CsqIrp
->Tail
.Overlay
.DriverContext
[0];
201 /* DPC was queued, wait for it to fail (IRP is ours) */
202 if (Fcb
->TimeOut
.QuadPart
!= -1 && !KeCancelTimer(&Context
->Timer
))
204 KeWaitForSingleObject(&Context
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
207 /* Free context & attempt read */
208 ExFreePoolWithTag(Context
, 'NFsM');
209 MsfsRead(DeviceObject
, CsqIrp
);
212 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
213 Irp
->IoStatus
.Information
= Length
;
215 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
217 return STATUS_SUCCESS
;