[MSFS]
[reactos.git] / reactos / drivers / filesystems / msfs / rw.c
1 /*
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 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "msfs.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 NTSTATUS DEFAULTAPI
19 MsfsRead(PDEVICE_OBJECT DeviceObject,
20 PIRP Irp)
21 {
22 PIO_STACK_LOCATION IoStack;
23 PFILE_OBJECT FileObject;
24 PMSFS_FCB Fcb;
25 PMSFS_CCB Ccb;
26 PMSFS_MESSAGE Message;
27 KIRQL oldIrql;
28 ULONG Length;
29 ULONG LengthRead = 0;
30 PVOID Buffer;
31 NTSTATUS Status;
32 PLARGE_INTEGER Timeout;
33
34 DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
35
36 IoStack = IoGetCurrentIrpStackLocation (Irp);
37 FileObject = IoStack->FileObject;
38 Fcb = (PMSFS_FCB)FileObject->FsContext;
39 Ccb = (PMSFS_CCB)FileObject->FsContext2;
40
41 DPRINT("MailslotName: %wZ\n", &Fcb->Name);
42
43 /* reading is not permitted on client side */
44 if (Fcb->ServerCcb != Ccb)
45 {
46 Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
47 Irp->IoStatus.Information = 0;
48
49 IoCompleteRequest(Irp, IO_NO_INCREMENT);
50
51 return STATUS_ACCESS_DENIED;
52 }
53
54 Length = IoStack->Parameters.Read.Length;
55 if (Irp->MdlAddress)
56 Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
57 else
58 Buffer = Irp->UserBuffer;
59
60 if (Fcb->TimeOut.QuadPart == -1LL)
61 Timeout = NULL;
62 else
63 Timeout = &Fcb->TimeOut;
64
65 Status = KeWaitForSingleObject(&Fcb->MessageEvent,
66 UserRequest,
67 UserMode,
68 FALSE,
69 Timeout);
70 if (Status != STATUS_USER_APC)
71 {
72 if (Fcb->MessageCount > 0)
73 {
74 /* copy current message into buffer */
75 Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink,
76 MSFS_MESSAGE,
77 MessageListEntry);
78
79 memcpy(Buffer, &Message->Buffer, min(Message->Size,Length));
80 LengthRead = Message->Size;
81
82 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
83 RemoveHeadList(&Fcb->MessageListHead);
84 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
85
86 ExFreePoolWithTag(Message, 'rFsM');
87 Fcb->MessageCount--;
88 if (Fcb->MessageCount == 0)
89 {
90 KeClearEvent(&Fcb->MessageEvent);
91 }
92 }
93 else
94 {
95 /* No message found after waiting */
96 Status = STATUS_IO_TIMEOUT;
97 }
98 }
99
100 Irp->IoStatus.Status = Status;
101 Irp->IoStatus.Information = LengthRead;
102
103 IoCompleteRequest(Irp, IO_NO_INCREMENT);
104
105 return Status;
106 }
107
108
109 NTSTATUS DEFAULTAPI
110 MsfsWrite(PDEVICE_OBJECT DeviceObject,
111 PIRP Irp)
112 {
113 PIO_STACK_LOCATION IoStack;
114 PFILE_OBJECT FileObject;
115 PMSFS_FCB Fcb;
116 PMSFS_CCB Ccb;
117 PMSFS_MESSAGE Message;
118 KIRQL oldIrql;
119 ULONG Length;
120 PVOID Buffer;
121
122 DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
123
124 IoStack = IoGetCurrentIrpStackLocation (Irp);
125 FileObject = IoStack->FileObject;
126 Fcb = (PMSFS_FCB)FileObject->FsContext;
127 Ccb = (PMSFS_CCB)FileObject->FsContext2;
128
129 DPRINT("MailslotName: %wZ\n", &Fcb->Name);
130
131 /* writing is not permitted on server side */
132 if (Fcb->ServerCcb == Ccb)
133 {
134 Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
135 Irp->IoStatus.Information = 0;
136
137 IoCompleteRequest(Irp, IO_NO_INCREMENT);
138
139 return STATUS_ACCESS_DENIED;
140 }
141
142 Length = IoStack->Parameters.Write.Length;
143 if (Irp->MdlAddress)
144 Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
145 else
146 Buffer = Irp->UserBuffer;
147
148 DPRINT("Length: %lu Message: %s\n", Length, (PUCHAR)Buffer);
149
150 /* Allocate new message */
151 Message = ExAllocatePoolWithTag(NonPagedPool,
152 sizeof(MSFS_MESSAGE) + Length,
153 'rFsM');
154 if (Message == NULL)
155 {
156 Irp->IoStatus.Status = STATUS_NO_MEMORY;
157 Irp->IoStatus.Information = 0;
158
159 IoCompleteRequest(Irp, IO_NO_INCREMENT);
160
161 return STATUS_NO_MEMORY;
162 }
163
164 Message->Size = Length;
165 memcpy(&Message->Buffer, Buffer, Length);
166
167 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
168 InsertTailList(&Fcb->MessageListHead, &Message->MessageListEntry);
169 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
170
171 Fcb->MessageCount++;
172 if (Fcb->MessageCount == 1)
173 {
174 KeSetEvent(&Fcb->MessageEvent,
175 0,
176 FALSE);
177 }
178
179 Irp->IoStatus.Status = STATUS_SUCCESS;
180 Irp->IoStatus.Information = Length;
181
182 IoCompleteRequest(Irp, IO_NO_INCREMENT);
183
184 return STATUS_SUCCESS;
185 }
186
187 /* EOF */