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