[USBOHCI_NEW][USBUHCI_NEW] Avoid unnecessary/incorrect status defines.
[reactos.git] / 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 * Nikita Pechenkin (n.pechenkin@mail.ru)
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include "msfs.h"
13
14 #define NDEBUG
15 #include <debug.h>
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 LARGE_INTEGER Timeout;
33 PKTIMER Timer;
34 PMSFS_DPC_CTX Context;
35 PKDPC Dpc;
36 PLIST_ENTRY Entry;
37
38 DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
39
40 IoStack = IoGetCurrentIrpStackLocation (Irp);
41 FileObject = IoStack->FileObject;
42 Fcb = (PMSFS_FCB)FileObject->FsContext;
43 Ccb = (PMSFS_CCB)FileObject->FsContext2;
44
45 DPRINT("MailslotName: %wZ\n", &Fcb->Name);
46
47 /* reading is not permitted on client side */
48 if (Fcb->ServerCcb != Ccb)
49 {
50 Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
51 Irp->IoStatus.Information = 0;
52
53 IoCompleteRequest(Irp, IO_NO_INCREMENT);
54
55 return STATUS_ACCESS_DENIED;
56 }
57
58 Length = IoStack->Parameters.Read.Length;
59 if (Irp->MdlAddress)
60 Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
61 else
62 Buffer = Irp->UserBuffer;
63
64
65 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
66 if (Fcb->MessageCount > 0)
67 {
68 Entry = RemoveHeadList(&Fcb->MessageListHead);
69 Fcb->MessageCount--;
70 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
71
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;
76
77 ExFreePoolWithTag(Message, 'rFsM');
78
79 Irp->IoStatus.Status = STATUS_SUCCESS;
80 Irp->IoStatus.Information = LengthRead;
81 IoCompleteRequest(Irp, IO_NO_INCREMENT);
82
83 return STATUS_SUCCESS;
84 }
85 else
86 {
87 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
88 }
89
90 Timeout = Fcb->TimeOut;
91 if (Timeout.HighPart == 0 && Timeout.LowPart == 0)
92 {
93 Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
94 Irp->IoStatus.Information = 0;
95 IoCompleteRequest(Irp, IO_NO_INCREMENT);
96
97 return STATUS_IO_TIMEOUT;
98 }
99
100 Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_DPC_CTX), 'NFsM');
101 if (Context == NULL)
102 {
103 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
104 Irp->IoStatus.Information = 0;
105 IoCompleteRequest(Irp, IO_NO_INCREMENT);
106
107 return STATUS_INSUFFICIENT_RESOURCES;
108 }
109
110 KeInitializeEvent(&Context->Event, SynchronizationEvent, FALSE);
111 IoCsqInsertIrp(&Fcb->CancelSafeQueue, Irp, &Context->CsqContext);
112 Timer = &Context->Timer;
113 Dpc = &Context->Dpc;
114 Context->Csq = &Fcb->CancelSafeQueue;
115 Irp->Tail.Overlay.DriverContext[0] = Context;
116
117 /* No timer for INFINITY_WAIT */
118 if (Timeout.QuadPart != -1)
119 {
120 KeInitializeTimer(Timer);
121 KeInitializeDpc(Dpc, MsfsTimeout, (PVOID)Context);
122 KeSetTimer(Timer, Timeout, Dpc);
123 }
124
125 IoMarkIrpPending(Irp);
126
127 return STATUS_PENDING;
128 }
129
130
131 NTSTATUS DEFAULTAPI
132 MsfsWrite(PDEVICE_OBJECT DeviceObject,
133 PIRP Irp)
134 {
135 PIO_STACK_LOCATION IoStack;
136 PFILE_OBJECT FileObject;
137 PMSFS_FCB Fcb;
138 PMSFS_CCB Ccb;
139 PMSFS_MESSAGE Message;
140 KIRQL oldIrql;
141 ULONG Length;
142 PVOID Buffer;
143 PIRP CsqIrp;
144 PMSFS_DPC_CTX Context;
145
146 DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
147
148 IoStack = IoGetCurrentIrpStackLocation (Irp);
149 FileObject = IoStack->FileObject;
150 Fcb = (PMSFS_FCB)FileObject->FsContext;
151 Ccb = (PMSFS_CCB)FileObject->FsContext2;
152
153 DPRINT("MailslotName: %wZ\n", &Fcb->Name);
154
155 /* writing is not permitted on server side */
156 if (Fcb->ServerCcb == Ccb)
157 {
158 Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
159 Irp->IoStatus.Information = 0;
160
161 IoCompleteRequest(Irp, IO_NO_INCREMENT);
162
163 return STATUS_ACCESS_DENIED;
164 }
165
166 Length = IoStack->Parameters.Write.Length;
167 if (Irp->MdlAddress)
168 Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
169 else
170 Buffer = Irp->UserBuffer;
171
172 DPRINT("Length: %lu Message: %s\n", Length, (PUCHAR)Buffer);
173
174 /* Allocate new message */
175 Message = ExAllocatePoolWithTag(NonPagedPool,
176 sizeof(MSFS_MESSAGE) + Length,
177 'rFsM');
178 if (Message == NULL)
179 {
180 Irp->IoStatus.Status = STATUS_NO_MEMORY;
181 Irp->IoStatus.Information = 0;
182
183 IoCompleteRequest(Irp, IO_NO_INCREMENT);
184
185 return STATUS_NO_MEMORY;
186 }
187
188 Message->Size = Length;
189 memcpy(&Message->Buffer, Buffer, Length);
190
191 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
192 InsertTailList(&Fcb->MessageListHead, &Message->MessageListEntry);
193 Fcb->MessageCount++;
194 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
195
196 CsqIrp = IoCsqRemoveNextIrp(&Fcb->CancelSafeQueue, NULL);
197 if (CsqIrp != NULL)
198 {
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))
203 {
204 KeWaitForSingleObject(&Context->Event, Executive, KernelMode, FALSE, NULL);
205 }
206
207 /* Free context & attempt read */
208 ExFreePoolWithTag(Context, 'NFsM');
209 MsfsRead(DeviceObject, CsqIrp);
210 }
211
212 Irp->IoStatus.Status = STATUS_SUCCESS;
213 Irp->IoStatus.Information = Length;
214
215 IoCompleteRequest(Irp, IO_NO_INCREMENT);
216
217 return STATUS_SUCCESS;
218 }
219
220 /* EOF */