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
;
37 DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
39 IoStack
= IoGetCurrentIrpStackLocation (Irp
);
40 FileObject
= IoStack
->FileObject
;
41 Fcb
= (PMSFS_FCB
)FileObject
->FsContext
;
42 Ccb
= (PMSFS_CCB
)FileObject
->FsContext2
;
44 DPRINT("MailslotName: %wZ\n", &Fcb
->Name
);
46 /* reading is not permitted on client side */
47 if (Fcb
->ServerCcb
!= Ccb
)
49 Irp
->IoStatus
.Status
= STATUS_ACCESS_DENIED
;
50 Irp
->IoStatus
.Information
= 0;
52 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
54 return STATUS_ACCESS_DENIED
;
57 Length
= IoStack
->Parameters
.Read
.Length
;
59 Buffer
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
61 Buffer
= Irp
->UserBuffer
;
64 if (Fcb
->MessageCount
> 0)
66 /* copy current message into buffer */
67 Message
= CONTAINING_RECORD(Fcb
->MessageListHead
.Flink
,
71 memcpy(Buffer
, &Message
->Buffer
, min(Message
->Size
,Length
));
72 LengthRead
= Message
->Size
;
74 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
75 RemoveHeadList(&Fcb
->MessageListHead
);
76 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
78 ExFreePoolWithTag(Message
, 'rFsM');
80 if (Fcb
->MessageCount
== 0)
82 KeClearEvent(&Fcb
->MessageEvent
);
85 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
86 Irp
->IoStatus
.Information
= LengthRead
;
87 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
89 return STATUS_SUCCESS
;
92 Timeout
= Fcb
->TimeOut
;
93 if (Timeout
.HighPart
== 0 && Timeout
.LowPart
== 0)
95 Irp
->IoStatus
.Status
= STATUS_IO_TIMEOUT
;
96 Irp
->IoStatus
.Information
= 0;
97 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
99 return STATUS_IO_TIMEOUT
;
102 Context
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MSFS_DPC_CTX
), 'NFsM');
105 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
106 Irp
->IoStatus
.Information
= 0;
107 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
109 return STATUS_INSUFFICIENT_RESOURCES
;
112 IoCsqInsertIrp(&Fcb
->CancelSafeQueue
, Irp
, &Context
->CsqContext
);
113 Timer
= &Context
->Timer
;
115 Context
->Csq
= &Fcb
->CancelSafeQueue
;
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
);
126 Irp
->IoStatus
.Status
= STATUS_PENDING
;
127 Irp
->IoStatus
.Information
= 0;
128 IoMarkIrpPending(Irp
);
130 return STATUS_PENDING
;
135 MsfsWrite(PDEVICE_OBJECT DeviceObject
,
138 PIO_STACK_LOCATION IoStack
;
139 PFILE_OBJECT FileObject
;
142 PMSFS_MESSAGE Message
;
148 DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
150 IoStack
= IoGetCurrentIrpStackLocation (Irp
);
151 FileObject
= IoStack
->FileObject
;
152 Fcb
= (PMSFS_FCB
)FileObject
->FsContext
;
153 Ccb
= (PMSFS_CCB
)FileObject
->FsContext2
;
155 DPRINT("MailslotName: %wZ\n", &Fcb
->Name
);
157 /* writing is not permitted on server side */
158 if (Fcb
->ServerCcb
== Ccb
)
160 Irp
->IoStatus
.Status
= STATUS_ACCESS_DENIED
;
161 Irp
->IoStatus
.Information
= 0;
163 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
165 return STATUS_ACCESS_DENIED
;
168 Length
= IoStack
->Parameters
.Write
.Length
;
170 Buffer
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
172 Buffer
= Irp
->UserBuffer
;
174 DPRINT("Length: %lu Message: %s\n", Length
, (PUCHAR
)Buffer
);
176 /* Allocate new message */
177 Message
= ExAllocatePoolWithTag(NonPagedPool
,
178 sizeof(MSFS_MESSAGE
) + Length
,
182 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
183 Irp
->IoStatus
.Information
= 0;
185 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
187 return STATUS_NO_MEMORY
;
190 Message
->Size
= Length
;
191 memcpy(&Message
->Buffer
, Buffer
, Length
);
193 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
194 InsertTailList(&Fcb
->MessageListHead
, &Message
->MessageListEntry
);
195 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
198 if (Fcb
->MessageCount
== 1)
200 KeSetEvent(&Fcb
->MessageEvent
,
205 if (Fcb
->WaitCount
> 0)
207 CsqIrp
= IoCsqRemoveNextIrp(&Fcb
->CancelSafeQueue
, NULL
);
208 /* FIXME: It is necessary to reset the timers. */
209 MsfsRead(DeviceObject
, CsqIrp
);
213 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
214 Irp
->IoStatus
.Information
= Length
;
216 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
218 return STATUS_SUCCESS
;