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 if (Fcb
->MessageCount
> 0)
67 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
68 Entry
= RemoveHeadList(&Fcb
->MessageListHead
);
69 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
71 /* copy current message into buffer */
72 Message
= CONTAINING_RECORD(Entry
, MSFS_MESSAGE
, MessageListEntry
);
73 memcpy(Buffer
, &Message
->Buffer
, min(Message
->Size
,Length
));
74 LengthRead
= Message
->Size
;
76 ExFreePoolWithTag(Message
, 'rFsM');
78 if (Fcb
->MessageCount
== 0)
80 KeClearEvent(&Fcb
->MessageEvent
);
83 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
84 Irp
->IoStatus
.Information
= LengthRead
;
85 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
87 return STATUS_SUCCESS
;
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 IoCsqInsertIrp(&Fcb
->CancelSafeQueue
, Irp
, &Context
->CsqContext
);
111 Timer
= &Context
->Timer
;
113 Context
->Csq
= &Fcb
->CancelSafeQueue
;
115 /* No timer for INFINITY_WAIT */
116 if (Timeout
.QuadPart
!= -1)
118 KeInitializeTimer(Timer
);
119 KeInitializeDpc(Dpc
, MsfsTimeout
, (PVOID
)Context
);
120 KeSetTimer(Timer
, Timeout
, Dpc
);
124 IoMarkIrpPending(Irp
);
126 return STATUS_PENDING
;
131 MsfsWrite(PDEVICE_OBJECT DeviceObject
,
134 PIO_STACK_LOCATION IoStack
;
135 PFILE_OBJECT FileObject
;
138 PMSFS_MESSAGE Message
;
144 DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
146 IoStack
= IoGetCurrentIrpStackLocation (Irp
);
147 FileObject
= IoStack
->FileObject
;
148 Fcb
= (PMSFS_FCB
)FileObject
->FsContext
;
149 Ccb
= (PMSFS_CCB
)FileObject
->FsContext2
;
151 DPRINT("MailslotName: %wZ\n", &Fcb
->Name
);
153 /* writing is not permitted on server side */
154 if (Fcb
->ServerCcb
== Ccb
)
156 Irp
->IoStatus
.Status
= STATUS_ACCESS_DENIED
;
157 Irp
->IoStatus
.Information
= 0;
159 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
161 return STATUS_ACCESS_DENIED
;
164 Length
= IoStack
->Parameters
.Write
.Length
;
166 Buffer
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
168 Buffer
= Irp
->UserBuffer
;
170 DPRINT("Length: %lu Message: %s\n", Length
, (PUCHAR
)Buffer
);
172 /* Allocate new message */
173 Message
= ExAllocatePoolWithTag(NonPagedPool
,
174 sizeof(MSFS_MESSAGE
) + Length
,
178 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
179 Irp
->IoStatus
.Information
= 0;
181 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
183 return STATUS_NO_MEMORY
;
186 Message
->Size
= Length
;
187 memcpy(&Message
->Buffer
, Buffer
, Length
);
189 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
190 InsertTailList(&Fcb
->MessageListHead
, &Message
->MessageListEntry
);
191 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
194 if (Fcb
->MessageCount
== 1)
196 KeSetEvent(&Fcb
->MessageEvent
,
201 if (Fcb
->WaitCount
> 0)
203 CsqIrp
= IoCsqRemoveNextIrp(&Fcb
->CancelSafeQueue
, NULL
);
204 /* FIXME: It is necessary to reset the timers. */
205 MsfsRead(DeviceObject
, CsqIrp
);
209 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
210 Irp
->IoStatus
.Information
= Length
;
212 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
214 return STATUS_SUCCESS
;