ec62287ca5a38eecda96a336f5dace27f4e2052d
[reactos.git] / reactos / drivers / filesystems / msfs / create.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/filesystems/msfs/create.c
5 * PURPOSE: Mailslot filesystem
6 * PROGRAMMER: Eric Kohl
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "msfs.h"
12
13 #include <ndk/iotypes.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* FUNCTIONS *****************************************************************/
19
20 /* Creates the client side */
21 NTSTATUS DEFAULTAPI
22 MsfsCreate(PDEVICE_OBJECT DeviceObject,
23 PIRP Irp)
24 {
25 PIO_STACK_LOCATION IoStack;
26 PFILE_OBJECT FileObject;
27 PMSFS_DEVICE_EXTENSION DeviceExtension;
28 PMSFS_FCB Fcb;
29 PMSFS_CCB Ccb;
30 PMSFS_FCB current = NULL;
31 PLIST_ENTRY current_entry;
32 KIRQL oldIrql;
33
34 DPRINT("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
35
36 IoStack = IoGetCurrentIrpStackLocation(Irp);
37 DeviceExtension = DeviceObject->DeviceExtension;
38 FileObject = IoStack->FileObject;
39
40 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName);
41
42 Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_CCB), 'cFsM');
43 if (Ccb == NULL)
44 {
45 Irp->IoStatus.Status = STATUS_NO_MEMORY;
46 Irp->IoStatus.Information = 0;
47
48 IoCompleteRequest(Irp, IO_NO_INCREMENT);
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 break;
62
63 current_entry = current_entry->Flink;
64 }
65
66 if (current_entry == &DeviceExtension->FcbListHead)
67 {
68 ExFreePoolWithTag(Ccb, 'cFsM');
69 KeUnlockMutex(&DeviceExtension->FcbListLock);
70
71 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
72 Irp->IoStatus.Information = 0;
73
74 IoCompleteRequest(Irp, IO_NO_INCREMENT);
75
76 return STATUS_UNSUCCESSFUL;
77 }
78
79 Fcb = current;
80
81 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
82 InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry);
83 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
84
85 Fcb->ReferenceCount++;
86
87 Ccb->Fcb = Fcb;
88
89 KeUnlockMutex(&DeviceExtension->FcbListLock);
90
91 FileObject->FsContext = Fcb;
92 FileObject->FsContext2 = Ccb;
93 FileObject->Flags |= FO_MAILSLOT;
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 /* Creates the server side */
105 NTSTATUS DEFAULTAPI
106 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject,
107 PIRP Irp)
108 {
109 PEXTENDED_IO_STACK_LOCATION IoStack;
110 PFILE_OBJECT FileObject;
111 PMSFS_DEVICE_EXTENSION DeviceExtension;
112 PMSFS_FCB Fcb;
113 PMSFS_CCB Ccb;
114 KIRQL oldIrql;
115 PLIST_ENTRY current_entry;
116 PMSFS_FCB current = NULL;
117 PMAILSLOT_CREATE_PARAMETERS Buffer;
118
119 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
120
121 IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
122 DeviceExtension = DeviceObject->DeviceExtension;
123 FileObject = IoStack->FileObject;
124 Buffer = IoStack->Parameters.CreateMailslot.Parameters;
125
126 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName);
127
128 Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_FCB), 'fFsM');
129 if (Fcb == NULL)
130 {
131 Irp->IoStatus.Status = STATUS_NO_MEMORY;
132 Irp->IoStatus.Information = 0;
133
134 IoCompleteRequest(Irp, IO_NO_INCREMENT);
135
136 return STATUS_NO_MEMORY;
137 }
138
139 Fcb->Name.Length = FileObject->FileName.Length;
140 Fcb->Name.MaximumLength = Fcb->Name.Length + sizeof(UNICODE_NULL);
141 Fcb->Name.Buffer = ExAllocatePoolWithTag(NonPagedPool,
142 Fcb->Name.MaximumLength,
143 'NFsM');
144 if (Fcb->Name.Buffer == NULL)
145 {
146 ExFreePoolWithTag(Fcb, 'fFsM');
147
148 Irp->IoStatus.Status = STATUS_NO_MEMORY;
149 Irp->IoStatus.Information = 0;
150
151 IoCompleteRequest(Irp, IO_NO_INCREMENT);
152
153 return STATUS_NO_MEMORY;
154 }
155
156 RtlCopyUnicodeString(&Fcb->Name, &FileObject->FileName);
157
158 Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_CCB), 'cFsM');
159 if (Ccb == NULL)
160 {
161 ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM');
162 ExFreePoolWithTag(Fcb, 'fFsM');
163
164 Irp->IoStatus.Status = STATUS_NO_MEMORY;
165 Irp->IoStatus.Information = 0;
166
167 IoCompleteRequest(Irp, IO_NO_INCREMENT);
168
169 return STATUS_NO_MEMORY;
170 }
171
172 Fcb->ReferenceCount = 0;
173 InitializeListHead(&Fcb->CcbListHead);
174 KeInitializeSpinLock(&Fcb->CcbListLock);
175
176 Fcb->MaxMessageSize = Buffer->MaximumMessageSize;
177 Fcb->MessageCount = 0;
178 Fcb->TimeOut = Buffer->ReadTimeout;
179 KeInitializeEvent(&Fcb->MessageEvent,
180 NotificationEvent,
181 FALSE);
182
183 InitializeListHead(&Fcb->MessageListHead);
184 KeInitializeSpinLock(&Fcb->MessageListLock);
185
186 KeLockMutex(&DeviceExtension->FcbListLock);
187 current_entry = DeviceExtension->FcbListHead.Flink;
188 while (current_entry != &DeviceExtension->FcbListHead)
189 {
190 current = CONTAINING_RECORD(current_entry,
191 MSFS_FCB,
192 FcbListEntry);
193
194 if (!RtlCompareUnicodeString(&Fcb->Name, &current->Name, TRUE))
195 break;
196
197 current_entry = current_entry->Flink;
198 }
199
200 if (current_entry != &DeviceExtension->FcbListHead)
201 {
202 ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM');
203 ExFreePoolWithTag(Fcb, 'fFsM');
204 ExFreePoolWithTag(Ccb, 'cFsM');
205
206 KeUnlockMutex(&DeviceExtension->FcbListLock);
207
208 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
209 Irp->IoStatus.Information = 0;
210
211 IoCompleteRequest(Irp, IO_NO_INCREMENT);
212
213 return STATUS_UNSUCCESSFUL;
214 }
215 else
216 {
217 InsertTailList(&DeviceExtension->FcbListHead,
218 &Fcb->FcbListEntry);
219 }
220
221 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
222 InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry);
223 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
224
225 Fcb->ReferenceCount++;
226 Fcb->ServerCcb = Ccb;
227 Ccb->Fcb = Fcb;
228
229 KeUnlockMutex(&DeviceExtension->FcbListLock);
230
231 FileObject->FsContext = Fcb;
232 FileObject->FsContext2 = Ccb;
233 FileObject->Flags |= FO_MAILSLOT;
234
235 Irp->IoStatus.Status = STATUS_SUCCESS;
236 Irp->IoStatus.Information = 0;
237
238 IoCompleteRequest(Irp, IO_NO_INCREMENT);
239
240 return STATUS_SUCCESS;
241 }
242
243
244 NTSTATUS DEFAULTAPI
245 MsfsClose(PDEVICE_OBJECT DeviceObject,
246 PIRP Irp)
247 {
248 PIO_STACK_LOCATION IoStack;
249 PFILE_OBJECT FileObject;
250 PMSFS_DEVICE_EXTENSION DeviceExtension;
251 PMSFS_FCB Fcb;
252 PMSFS_CCB Ccb;
253 PMSFS_MESSAGE Message;
254 KIRQL oldIrql;
255
256 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
257
258 IoStack = IoGetCurrentIrpStackLocation(Irp);
259 DeviceExtension = DeviceObject->DeviceExtension;
260 FileObject = IoStack->FileObject;
261
262 KeLockMutex(&DeviceExtension->FcbListLock);
263
264 if (DeviceExtension->FcbListHead.Flink == &DeviceExtension->FcbListHead)
265 {
266 KeUnlockMutex(&DeviceExtension->FcbListLock);
267
268 Irp->IoStatus.Status = STATUS_SUCCESS;
269 Irp->IoStatus.Information = 0;
270
271 IoCompleteRequest(Irp, IO_NO_INCREMENT);
272
273 return STATUS_SUCCESS;
274 }
275
276 Fcb = FileObject->FsContext;
277 Ccb = FileObject->FsContext2;
278
279 DPRINT("Mailslot name: %wZ\n", &Fcb->Name);
280
281 Fcb->ReferenceCount--;
282 if (Fcb->ServerCcb == Ccb)
283 {
284 /* delete all messages from message-list */
285 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
286
287 while (Fcb->MessageListHead.Flink != &Fcb->MessageListHead)
288 {
289 Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink,
290 MSFS_MESSAGE,
291 MessageListEntry);
292 RemoveEntryList(Fcb->MessageListHead.Flink);
293 ExFreePoolWithTag(Message, 'rFsM');
294 }
295
296 Fcb->MessageCount = 0;
297
298 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
299 Fcb->ServerCcb = NULL;
300 }
301
302 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
303 RemoveEntryList(&Ccb->CcbListEntry);
304 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
305 ExFreePoolWithTag(Ccb, 'cFsM');
306 FileObject->FsContext2 = NULL;
307
308 if (Fcb->ReferenceCount == 0)
309 {
310 DPRINT("ReferenceCount == 0: Deleting mailslot data\n");
311 RemoveEntryList(&Fcb->FcbListEntry);
312 ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM');
313 ExFreePoolWithTag(Fcb, 'fFsM');
314 }
315
316 KeUnlockMutex(&DeviceExtension->FcbListLock);
317
318 Irp->IoStatus.Status = STATUS_SUCCESS;
319 Irp->IoStatus.Information = 0;
320
321 IoCompleteRequest(Irp, IO_NO_INCREMENT);
322
323 return STATUS_SUCCESS;
324 }
325
326 /* EOF */