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