migrate substitution keywords to SVN
[reactos.git] / reactos / drivers / fs / ms / create.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/ms/create.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 <ddk/iotypes.h> /* FIXME: Temporary Until NDK implemented */
14 #include "msfs.h"
15
16 #define NDEBUG
17 #include <debug.h>
18
19
20 /* FUNCTIONS *****************************************************************/
21
22 NTSTATUS STDCALL
23 MsfsCreate(PDEVICE_OBJECT DeviceObject,
24 PIRP Irp)
25 {
26 PIO_STACK_LOCATION IoStack;
27 PFILE_OBJECT FileObject;
28 PMSFS_DEVICE_EXTENSION DeviceExtension;
29 PMSFS_MAILSLOT Mailslot;
30 PMSFS_FCB Fcb;
31 PMSFS_MAILSLOT current;
32 PLIST_ENTRY current_entry;
33 KIRQL oldIrql;
34
35 DPRINT("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
36
37 IoStack = IoGetCurrentIrpStackLocation(Irp);
38 DeviceExtension = DeviceObject->DeviceExtension;
39 FileObject = IoStack->FileObject;
40
41 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName);
42
43 Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB));
44 if (Fcb == NULL)
45 {
46 Irp->IoStatus.Status = STATUS_NO_MEMORY;
47 Irp->IoStatus.Information = 0;
48
49 IoCompleteRequest(Irp, IO_NO_INCREMENT);
50
51 return(STATUS_NO_MEMORY);
52 }
53
54 KeLockMutex(&DeviceExtension->MailslotListLock);
55 current_entry = DeviceExtension->MailslotListHead.Flink;
56 while (current_entry != &DeviceExtension->MailslotListHead)
57 {
58 current = CONTAINING_RECORD(current_entry,
59 MSFS_MAILSLOT,
60 MailslotListEntry);
61
62 if (!RtlCompareUnicodeString(&FileObject->FileName, &current->Name, TRUE))
63 {
64 break;
65 }
66
67 current_entry = current_entry->Flink;
68 }
69
70 if (current_entry == &DeviceExtension->MailslotListHead)
71 {
72 ExFreePool(Fcb);
73 KeUnlockMutex(&DeviceExtension->MailslotListLock);
74
75 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
76 Irp->IoStatus.Information = 0;
77
78 IoCompleteRequest(Irp, IO_NO_INCREMENT);
79
80 return(STATUS_UNSUCCESSFUL);
81 }
82
83 Mailslot = current;
84
85 KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql);
86 InsertTailList(&Mailslot->FcbListHead, &Fcb->FcbListEntry);
87 KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql);
88
89 Mailslot->ReferenceCount++;
90
91 Fcb->Mailslot = Mailslot;
92
93 KeUnlockMutex(&DeviceExtension->MailslotListLock);
94
95 FileObject->FsContext = Fcb;
96
97 Irp->IoStatus.Status = STATUS_SUCCESS;
98 Irp->IoStatus.Information = 0;
99
100 IoCompleteRequest(Irp, IO_NO_INCREMENT);
101
102 return(STATUS_SUCCESS);
103 }
104
105
106 NTSTATUS STDCALL
107 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject,
108 PIRP Irp)
109 {
110 PIO_STACK_LOCATION IoStack;
111 PFILE_OBJECT FileObject;
112 PMSFS_DEVICE_EXTENSION DeviceExtension;
113 PMSFS_MAILSLOT Mailslot;
114 PMSFS_FCB Fcb;
115 KIRQL oldIrql;
116 PLIST_ENTRY current_entry;
117 PMSFS_MAILSLOT current;
118 PMAILSLOT_CREATE_PARAMETERS Buffer;
119
120 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
121
122 IoStack = IoGetCurrentIrpStackLocation(Irp);
123 DeviceExtension = DeviceObject->DeviceExtension;
124 FileObject = IoStack->FileObject;
125 Buffer = IoStack->Parameters.CreateMailslot.Parameters;
126
127 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName);
128
129 Mailslot = ExAllocatePool(NonPagedPool, sizeof(MSFS_MAILSLOT));
130 if (Mailslot == NULL)
131 {
132 Irp->IoStatus.Status = STATUS_NO_MEMORY;
133 Irp->IoStatus.Information = 0;
134
135 IoCompleteRequest(Irp, IO_NO_INCREMENT);
136
137 return(STATUS_NO_MEMORY);
138 }
139
140 if (!RtlCreateUnicodeString(&Mailslot->Name, FileObject->FileName.Buffer))
141 {
142 ExFreePool(Mailslot);
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 Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB));
153 if (Fcb == NULL)
154 {
155 ExFreePool(Mailslot);
156
157 Irp->IoStatus.Status = STATUS_NO_MEMORY;
158 Irp->IoStatus.Information = 0;
159
160 IoCompleteRequest(Irp, IO_NO_INCREMENT);
161
162 return(STATUS_NO_MEMORY);
163 }
164
165 Mailslot->ReferenceCount = 0;
166 InitializeListHead(&Mailslot->FcbListHead);
167 KeInitializeSpinLock(&Mailslot->FcbListLock);
168
169 Mailslot->MaxMessageSize = Buffer->MaximumMessageSize;
170 Mailslot->MessageCount = 0;
171 Mailslot->TimeOut = Buffer->ReadTimeout;
172 KeInitializeEvent(&Mailslot->MessageEvent,
173 NotificationEvent,
174 FALSE);
175
176 InitializeListHead(&Mailslot->MessageListHead);
177 KeInitializeSpinLock(&Mailslot->MessageListLock);
178
179 KeLockMutex(&DeviceExtension->MailslotListLock);
180 current_entry = DeviceExtension->MailslotListHead.Flink;
181 while (current_entry != &DeviceExtension->MailslotListHead)
182 {
183 current = CONTAINING_RECORD(current_entry,
184 MSFS_MAILSLOT,
185 MailslotListEntry);
186
187 if (!RtlCompareUnicodeString(&Mailslot->Name, &current->Name, TRUE))
188 {
189 break;
190 }
191
192 current_entry = current_entry->Flink;
193 }
194
195 if (current_entry != &DeviceExtension->MailslotListHead)
196 {
197 RtlFreeUnicodeString(&Mailslot->Name);
198 ExFreePool(Mailslot);
199
200 Mailslot = current;
201 }
202 else
203 {
204 InsertTailList(&DeviceExtension->MailslotListHead,
205 &Mailslot->MailslotListEntry);
206 }
207
208 KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql);
209 InsertTailList(&Mailslot->FcbListHead, &Fcb->FcbListEntry);
210 KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql);
211
212 Mailslot->ReferenceCount++;
213 Mailslot->ServerFcb = Fcb;
214 Fcb->Mailslot = Mailslot;
215
216 KeUnlockMutex(&DeviceExtension->MailslotListLock);
217
218 FileObject->FsContext = Fcb;
219
220 Irp->IoStatus.Status = STATUS_SUCCESS;
221 Irp->IoStatus.Information = 0;
222
223 IoCompleteRequest(Irp, IO_NO_INCREMENT);
224
225 return(STATUS_SUCCESS);
226 }
227
228
229 NTSTATUS STDCALL
230 MsfsClose(PDEVICE_OBJECT DeviceObject,
231 PIRP Irp)
232 {
233 PIO_STACK_LOCATION IoStack;
234 PFILE_OBJECT FileObject;
235 PMSFS_DEVICE_EXTENSION DeviceExtension;
236 PMSFS_MAILSLOT Mailslot;
237 PMSFS_FCB Fcb;
238 PMSFS_MESSAGE Message;
239 KIRQL oldIrql;
240
241 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
242
243 IoStack = IoGetCurrentIrpStackLocation(Irp);
244 DeviceExtension = DeviceObject->DeviceExtension;
245 FileObject = IoStack->FileObject;
246
247 KeLockMutex(&DeviceExtension->MailslotListLock);
248
249 if (DeviceExtension->MailslotListHead.Flink == &DeviceExtension->MailslotListHead)
250 {
251 KeUnlockMutex(&DeviceExtension->MailslotListLock);
252
253 Irp->IoStatus.Status = STATUS_SUCCESS;
254 Irp->IoStatus.Information = 0;
255
256 IoCompleteRequest(Irp, IO_NO_INCREMENT);
257
258 return(STATUS_SUCCESS);
259 }
260
261 Fcb = FileObject->FsContext;
262 Mailslot = Fcb->Mailslot;
263
264 DPRINT("Mailslot name: %wZ\n", &Mailslot->Name);
265
266 Mailslot->ReferenceCount--;
267 if (Mailslot->ServerFcb == Fcb)
268 {
269 /* delete all messages from message-list */
270 KeAcquireSpinLock(&Mailslot->MessageListLock, &oldIrql);
271
272 while (Mailslot->MessageListHead.Flink != &Mailslot->MessageListHead)
273 {
274 Message = CONTAINING_RECORD(Mailslot->MessageListHead.Flink,
275 MSFS_MESSAGE,
276 MessageListEntry);
277 RemoveEntryList(Mailslot->MessageListHead.Flink);
278 ExFreePool(Message);
279 }
280 Mailslot->MessageCount = 0;
281
282 KeReleaseSpinLock(&Mailslot->MessageListLock, oldIrql);
283 Mailslot->ServerFcb = NULL;
284 }
285
286 KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql);
287 RemoveEntryList(&Fcb->FcbListEntry);
288 KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql);
289 ExFreePool(Fcb);
290 FileObject->FsContext = NULL;
291
292 if (Mailslot->ReferenceCount == 0)
293 {
294 DPRINT1("ReferenceCount == 0: Deleting mailslot data\n");
295 RtlFreeUnicodeString(&Mailslot->Name);
296 RemoveEntryList(&Mailslot->MailslotListEntry);
297 ExFreePool(Mailslot);
298 }
299
300 KeUnlockMutex(&DeviceExtension->MailslotListLock);
301
302 Irp->IoStatus.Status = STATUS_SUCCESS;
303 Irp->IoStatus.Information = 0;
304
305 IoCompleteRequest(Irp, IO_NO_INCREMENT);
306
307 return(STATUS_SUCCESS);
308 }
309
310 /* EOF */