Update Indentation (tab->4spaces).
[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: drivers/filesystems/ms/create.c
6 * PURPOSE: Mailslot filesystem
7 * PROGRAMMER: Eric Kohl
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 return STATUS_NO_MEMORY;
49 }
50
51 KeLockMutex(&DeviceExtension->FcbListLock);
52 current_entry = DeviceExtension->FcbListHead.Flink;
53 while (current_entry != &DeviceExtension->FcbListHead)
54 {
55 current = CONTAINING_RECORD(current_entry,
56 MSFS_FCB,
57 FcbListEntry);
58
59 if (!RtlCompareUnicodeString(&FileObject->FileName, &current->Name, TRUE))
60 break;
61
62 current_entry = current_entry->Flink;
63 }
64
65 if (current_entry == &DeviceExtension->FcbListHead)
66 {
67 ExFreePool(Ccb);
68 KeUnlockMutex(&DeviceExtension->FcbListLock);
69
70 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
71 Irp->IoStatus.Information = 0;
72
73 IoCompleteRequest(Irp, IO_NO_INCREMENT);
74
75 return STATUS_UNSUCCESSFUL;
76 }
77
78 Fcb = current;
79
80 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
81 InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry);
82 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
83
84 Fcb->ReferenceCount++;
85
86 Ccb->Fcb = Fcb;
87
88 KeUnlockMutex(&DeviceExtension->FcbListLock);
89
90 FileObject->FsContext = Fcb;
91 FileObject->FsContext2 = Ccb;
92 FileObject->Flags |= FO_MAILSLOT;
93
94 Irp->IoStatus.Status = STATUS_SUCCESS;
95 Irp->IoStatus.Information = 0;
96
97 IoCompleteRequest(Irp, IO_NO_INCREMENT);
98
99 return STATUS_SUCCESS;
100 }
101
102
103 NTSTATUS DEFAULTAPI
104 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject,
105 PIRP Irp)
106 {
107 PEXTENDED_IO_STACK_LOCATION IoStack;
108 PFILE_OBJECT FileObject;
109 PMSFS_DEVICE_EXTENSION DeviceExtension;
110 PMSFS_FCB Fcb;
111 PMSFS_CCB Ccb;
112 KIRQL oldIrql;
113 PLIST_ENTRY current_entry;
114 PMSFS_FCB current;
115 PMAILSLOT_CREATE_PARAMETERS Buffer;
116
117 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
118
119 IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
120 DeviceExtension = DeviceObject->DeviceExtension;
121 FileObject = IoStack->FileObject;
122 Buffer = IoStack->Parameters.CreateMailslot.Parameters;
123
124 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName);
125
126 Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB));
127 if (Fcb == NULL)
128 {
129 Irp->IoStatus.Status = STATUS_NO_MEMORY;
130 Irp->IoStatus.Information = 0;
131
132 IoCompleteRequest(Irp, IO_NO_INCREMENT);
133
134 return STATUS_NO_MEMORY;
135 }
136
137 Fcb->Name.Length = FileObject->FileName.Length;
138 Fcb->Name.MaximumLength = Fcb->Name.Length + sizeof(UNICODE_NULL);
139 Fcb->Name.Buffer = ExAllocatePool(NonPagedPool, Fcb->Name.MaximumLength);
140 if (Fcb->Name.Buffer == NULL)
141 {
142 ExFreePool(Fcb);
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 RtlCopyUnicodeString(&Fcb->Name, &FileObject->FileName);
153
154 Ccb = ExAllocatePool(NonPagedPool, sizeof(MSFS_CCB));
155 if (Ccb == NULL)
156 {
157 ExFreePool(Fcb->Name.Buffer);
158 ExFreePool(Fcb);
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 Fcb->ReferenceCount = 0;
169 InitializeListHead(&Fcb->CcbListHead);
170 KeInitializeSpinLock(&Fcb->CcbListLock);
171
172 Fcb->MaxMessageSize = Buffer->MaximumMessageSize;
173 Fcb->MessageCount = 0;
174 Fcb->TimeOut = Buffer->ReadTimeout;
175 KeInitializeEvent(&Fcb->MessageEvent,
176 NotificationEvent,
177 FALSE);
178
179 InitializeListHead(&Fcb->MessageListHead);
180 KeInitializeSpinLock(&Fcb->MessageListLock);
181
182 KeLockMutex(&DeviceExtension->FcbListLock);
183 current_entry = DeviceExtension->FcbListHead.Flink;
184 while (current_entry != &DeviceExtension->FcbListHead)
185 {
186 current = CONTAINING_RECORD(current_entry,
187 MSFS_FCB,
188 FcbListEntry);
189
190 if (!RtlCompareUnicodeString(&Fcb->Name, &current->Name, TRUE))
191 break;
192
193 current_entry = current_entry->Flink;
194 }
195
196 if (current_entry != &DeviceExtension->FcbListHead)
197 {
198 ExFreePool(Fcb->Name.Buffer);
199 ExFreePool(Fcb);
200
201 Fcb = current;
202 }
203 else
204 {
205 InsertTailList(&DeviceExtension->FcbListHead,
206 &Fcb->FcbListEntry);
207 }
208
209 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
210 InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry);
211 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
212
213 Fcb->ReferenceCount++;
214 Fcb->ServerCcb = Ccb;
215 Ccb->Fcb = Fcb;
216
217 KeUnlockMutex(&DeviceExtension->FcbListLock);
218
219 FileObject->FsContext = Fcb;
220 FileObject->FsContext2 = Ccb;
221 FileObject->Flags |= FO_MAILSLOT;
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 DEFAULTAPI
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_FCB Fcb;
240 PMSFS_CCB Ccb;
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->FcbListLock);
251
252 if (DeviceExtension->FcbListHead.Flink == &DeviceExtension->FcbListHead)
253 {
254 KeUnlockMutex(&DeviceExtension->FcbListLock);
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 Ccb = FileObject->FsContext2;
266
267 DPRINT("Mailslot name: %wZ\n", &Fcb->Name);
268
269 Fcb->ReferenceCount--;
270 if (Fcb->ServerCcb == Ccb)
271 {
272 /* delete all messages from message-list */
273 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
274
275 while (Fcb->MessageListHead.Flink != &Fcb->MessageListHead)
276 {
277 Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink,
278 MSFS_MESSAGE,
279 MessageListEntry);
280 RemoveEntryList(Fcb->MessageListHead.Flink);
281 ExFreePool(Message);
282 }
283
284 Fcb->MessageCount = 0;
285
286 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
287 Fcb->ServerCcb = NULL;
288 }
289
290 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql);
291 RemoveEntryList(&Ccb->CcbListEntry);
292 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql);
293 ExFreePool(Ccb);
294 FileObject->FsContext2 = NULL;
295
296 if (Fcb->ReferenceCount == 0)
297 {
298 DPRINT1("ReferenceCount == 0: Deleting mailslot data\n");
299 RemoveEntryList(&Fcb->FcbListEntry);
300 ExFreePool(Fcb->Name.Buffer);
301 ExFreePool(Fcb);
302 }
303
304 KeUnlockMutex(&DeviceExtension->FcbListLock);
305
306 Irp->IoStatus.Status = STATUS_SUCCESS;
307 Irp->IoStatus.Information = 0;
308
309 IoCompleteRequest(Irp, IO_NO_INCREMENT);
310
311 return STATUS_SUCCESS;
312 }
313
314 /* EOF */