a529a79431e5520757df15cd373fc81067a7ef63
[reactos.git] / reactos / drivers / filesystems / 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 DEFAULTAPI
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_FCB Fcb;
28 PMSFS_CCB Ccb;
29 PMSFS_FCB 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 Ccb = ExAllocatePool(NonPagedPool, sizeof(MSFS_CCB));
42 if (Ccb == 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->FcbListLock);
53 current_entry = DeviceExtension->FcbListHead.Flink;
54 while (current_entry != &DeviceExtension->FcbListHead)
55 {
56 current = CONTAINING_RECORD(current_entry,
57 MSFS_FCB,
58 FcbListEntry);
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->FcbListHead)
69 {
70 ExFreePool(Ccb);
71 KeUnlockMutex(&DeviceExtension->FcbListLock);
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 Fcb = current;
82
83 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
84 InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry);
85 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
86
87 Fcb->ReferenceCount++;
88
89 Ccb->Fcb = Fcb;
90
91 KeUnlockMutex(&DeviceExtension->FcbListLock);
92
93 FileObject->FsContext = Fcb;
94 FileObject->FsContext2 = Ccb;
95 FileObject->Flags |= FO_MAILSLOT;
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 DEFAULTAPI
107 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject,
108 PIRP Irp)
109 {
110 PEXTENDED_IO_STACK_LOCATION IoStack;
111 PFILE_OBJECT FileObject;
112 PMSFS_DEVICE_EXTENSION DeviceExtension;
113 PMSFS_FCB Fcb;
114 PMSFS_CCB Ccb;
115 KIRQL oldIrql;
116 PLIST_ENTRY current_entry;
117 PMSFS_FCB current;
118 PMAILSLOT_CREATE_PARAMETERS Buffer;
119
120 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
121
122 IoStack = (PEXTENDED_IO_STACK_LOCATION)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 Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB));
130 if (Fcb == 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 Fcb->Name.Length = FileObject->FileName.Length;
141 Fcb->Name.MaximumLength = Fcb->Name.Length + sizeof(UNICODE_NULL);
142 Fcb->Name.Buffer = ExAllocatePool(NonPagedPool, Fcb->Name.MaximumLength);
143 if (Fcb->Name.Buffer == NULL)
144 {
145 ExFreePool(Fcb);
146
147 Irp->IoStatus.Status = STATUS_NO_MEMORY;
148 Irp->IoStatus.Information = 0;
149
150 IoCompleteRequest(Irp, IO_NO_INCREMENT);
151
152 return(STATUS_NO_MEMORY);
153 }
154
155 RtlCopyUnicodeString(&Fcb->Name, &FileObject->FileName);
156
157 Ccb = ExAllocatePool(NonPagedPool, sizeof(MSFS_CCB));
158 if (Ccb == NULL)
159 {
160 ExFreePool(Fcb->Name.Buffer);
161 ExFreePool(Fcb);
162
163 Irp->IoStatus.Status = STATUS_NO_MEMORY;
164 Irp->IoStatus.Information = 0;
165
166 IoCompleteRequest(Irp, IO_NO_INCREMENT);
167
168 return(STATUS_NO_MEMORY);
169 }
170
171 Fcb->ReferenceCount = 0;
172 InitializeListHead(&Fcb->CcbListHead);
173 KeInitializeSpinLock(&Fcb->CcbListLock);
174
175 Fcb->MaxMessageSize = Buffer->MaximumMessageSize;
176 Fcb->MessageCount = 0;
177 Fcb->TimeOut = Buffer->ReadTimeout;
178 KeInitializeEvent(&Fcb->MessageEvent,
179 NotificationEvent,
180 FALSE);
181
182 InitializeListHead(&Fcb->MessageListHead);
183 KeInitializeSpinLock(&Fcb->MessageListLock);
184
185 KeLockMutex(&DeviceExtension->FcbListLock);
186 current_entry = DeviceExtension->FcbListHead.Flink;
187 while (current_entry != &DeviceExtension->FcbListHead)
188 {
189 current = CONTAINING_RECORD(current_entry,
190 MSFS_FCB,
191 FcbListEntry);
192
193 if (!RtlCompareUnicodeString(&Fcb->Name, &current->Name, TRUE))
194 {
195 break;
196 }
197
198 current_entry = current_entry->Flink;
199 }
200
201 if (current_entry != &DeviceExtension->FcbListHead)
202 {
203 ExFreePool(Fcb->Name.Buffer);
204 ExFreePool(Fcb);
205
206 Fcb = current;
207 }
208 else
209 {
210 InsertTailList(&DeviceExtension->FcbListHead,
211 &Fcb->FcbListEntry);
212 }
213
214 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
215 InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry);
216 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
217
218 Fcb->ReferenceCount++;
219 Fcb->ServerCcb = Ccb;
220 Ccb->Fcb = Fcb;
221
222 KeUnlockMutex(&DeviceExtension->FcbListLock);
223
224 FileObject->FsContext = Fcb;
225 FileObject->FsContext2 = Ccb;
226 FileObject->Flags |= FO_MAILSLOT;
227
228 Irp->IoStatus.Status = STATUS_SUCCESS;
229 Irp->IoStatus.Information = 0;
230
231 IoCompleteRequest(Irp, IO_NO_INCREMENT);
232
233 return(STATUS_SUCCESS);
234 }
235
236
237 NTSTATUS DEFAULTAPI
238 MsfsClose(PDEVICE_OBJECT DeviceObject,
239 PIRP Irp)
240 {
241 PIO_STACK_LOCATION IoStack;
242 PFILE_OBJECT FileObject;
243 PMSFS_DEVICE_EXTENSION DeviceExtension;
244 PMSFS_FCB Fcb;
245 PMSFS_CCB Ccb;
246 PMSFS_MESSAGE Message;
247 KIRQL oldIrql;
248
249 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
250
251 IoStack = IoGetCurrentIrpStackLocation(Irp);
252 DeviceExtension = DeviceObject->DeviceExtension;
253 FileObject = IoStack->FileObject;
254
255 KeLockMutex(&DeviceExtension->FcbListLock);
256
257 if (DeviceExtension->FcbListHead.Flink == &DeviceExtension->FcbListHead)
258 {
259 KeUnlockMutex(&DeviceExtension->FcbListLock);
260
261 Irp->IoStatus.Status = STATUS_SUCCESS;
262 Irp->IoStatus.Information = 0;
263
264 IoCompleteRequest(Irp, IO_NO_INCREMENT);
265
266 return(STATUS_SUCCESS);
267 }
268
269 Fcb = FileObject->FsContext;
270 Ccb = FileObject->FsContext2;
271
272 DPRINT("Mailslot name: %wZ\n", &Fcb->Name);
273
274 Fcb->ReferenceCount--;
275 if (Fcb->ServerCcb == Ccb)
276 {
277 /* delete all messages from message-list */
278 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
279
280 while (Fcb->MessageListHead.Flink != &Fcb->MessageListHead)
281 {
282 Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink,
283 MSFS_MESSAGE,
284 MessageListEntry);
285 RemoveEntryList(Fcb->MessageListHead.Flink);
286 ExFreePool(Message);
287 }
288 Fcb->MessageCount = 0;
289
290 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
291 Fcb->ServerCcb = NULL;
292 }
293
294 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
295 RemoveEntryList(&Ccb->CcbListEntry);
296 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
297 ExFreePool(Ccb);
298 FileObject->FsContext2 = NULL;
299
300 if (Fcb->ReferenceCount == 0)
301 {
302 DPRINT1("ReferenceCount == 0: Deleting mailslot data\n");
303 RemoveEntryList(&Fcb->FcbListEntry);
304 ExFreePool(Fcb->Name.Buffer);
305 ExFreePool(Fcb);
306 }
307
308 KeUnlockMutex(&DeviceExtension->FcbListLock);
309
310 Irp->IoStatus.Status = STATUS_SUCCESS;
311 Irp->IoStatus.Information = 0;
312
313 IoCompleteRequest(Irp, IO_NO_INCREMENT);
314
315 return(STATUS_SUCCESS);
316 }
317
318 /* EOF */