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