[CMAKE]
[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
17 /* FUNCTIONS *****************************************************************/
18
19 NTSTATUS DEFAULTAPI
20 MsfsRead(PDEVICE_OBJECT DeviceObject,
21 PIRP Irp)
22 {
23 PIO_STACK_LOCATION IoStack;
24 PFILE_OBJECT FileObject;
25 PMSFS_FCB Fcb;
26 PMSFS_CCB Ccb;
27 PMSFS_MESSAGE Message;
28 KIRQL oldIrql;
29 ULONG Length;
30 ULONG LengthRead = 0;
31 PVOID Buffer;
32 NTSTATUS Status;
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 = MmGetSystemAddressForMdl (Irp->MdlAddress);
57 else
58 Buffer = Irp->UserBuffer;
59
60 Status = KeWaitForSingleObject(&Fcb->MessageEvent,
61 UserRequest,
62 KernelMode,
63 FALSE,
64 &Fcb->TimeOut);
65 if (NT_SUCCESS(Status))
66 {
67 if (Fcb->MessageCount > 0)
68 {
69 /* copy current message into buffer */
70 Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink,
71 MSFS_MESSAGE,
72 MessageListEntry);
73
74 memcpy(Buffer, &Message->Buffer, min(Message->Size,Length));
75 LengthRead = Message->Size;
76
77 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
78 RemoveHeadList(&Fcb->MessageListHead);
79 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
80
81 ExFreePool(Message);
82 Fcb->MessageCount--;
83 if (Fcb->MessageCount == 0)
84 {
85 KeClearEvent(&Fcb->MessageEvent);
86 }
87 }
88 else if (Fcb->TimeOut.QuadPart != 0LL)
89 {
90 /* No message found after waiting */
91 Status = STATUS_IO_TIMEOUT;
92 }
93 }
94
95 Irp->IoStatus.Status = Status;
96 Irp->IoStatus.Information = LengthRead;
97
98 IoCompleteRequest(Irp, IO_NO_INCREMENT);
99
100 return Status;
101 }
102
103
104 NTSTATUS DEFAULTAPI
105 MsfsWrite(PDEVICE_OBJECT DeviceObject,
106 PIRP Irp)
107 {
108 PIO_STACK_LOCATION IoStack;
109 PFILE_OBJECT FileObject;
110 PMSFS_FCB Fcb;
111 PMSFS_CCB Ccb;
112 PMSFS_MESSAGE Message;
113 KIRQL oldIrql;
114 ULONG Length;
115 PVOID Buffer;
116
117 DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
118
119 IoStack = IoGetCurrentIrpStackLocation (Irp);
120 FileObject = IoStack->FileObject;
121 Fcb = (PMSFS_FCB)FileObject->FsContext;
122 Ccb = (PMSFS_CCB)FileObject->FsContext2;
123
124 DPRINT("MailslotName: %wZ\n", &Fcb->Name);
125
126 /* writing is not permitted on server side */
127 if (Fcb->ServerCcb == Ccb)
128 {
129 Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
130 Irp->IoStatus.Information = 0;
131
132 IoCompleteRequest(Irp, IO_NO_INCREMENT);
133
134 return STATUS_ACCESS_DENIED;
135 }
136
137 Length = IoStack->Parameters.Write.Length;
138 if (Irp->MdlAddress)
139 Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
140 else
141 Buffer = Irp->UserBuffer;
142
143 DPRINT("Length: %lu Message: %s\n", Length, (PUCHAR)Buffer);
144
145 /* Allocate new message */
146 Message = ExAllocatePool(NonPagedPool,
147 sizeof(MSFS_MESSAGE) + Length);
148 if (Message == NULL)
149 {
150 Irp->IoStatus.Status = STATUS_NO_MEMORY;
151 Irp->IoStatus.Information = 0;
152
153 IoCompleteRequest(Irp, IO_NO_INCREMENT);
154
155 return STATUS_NO_MEMORY;
156 }
157
158 Message->Size = Length;
159 memcpy(&Message->Buffer, Buffer, Length);
160
161 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
162 InsertTailList(&Fcb->MessageListHead, &Message->MessageListEntry);
163 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
164
165 Fcb->MessageCount++;
166 if (Fcb->MessageCount == 1)
167 {
168 KeSetEvent(&Fcb->MessageEvent,
169 0,
170 FALSE);
171 }
172
173 Irp->IoStatus.Status = STATUS_SUCCESS;
174 Irp->IoStatus.Information = Length;
175
176 IoCompleteRequest(Irp, IO_NO_INCREMENT);
177
178 return STATUS_SUCCESS;
179 }
180
181 /* EOF */