minor corrections by M.Taguchi
[reactos.git] / reactos / drivers / fs / ms / create.c
1 /* $Id: create.c,v 1.4 2002/09/08 10:22:10 chorns Exp $
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 "msfs.h"
14
15 #define NDEBUG
16 #include <debug.h>
17
18
19 /* FUNCTIONS *****************************************************************/
20
21 NTSTATUS STDCALL
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_MAILSLOT Mailslot;
29 PMSFS_FCB Fcb;
30 PMSFS_MAILSLOT current;
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 Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB));
43 if (Fcb == NULL)
44 {
45 Irp->IoStatus.Status = STATUS_NO_MEMORY;
46 Irp->IoStatus.Information = 0;
47
48 IoCompleteRequest(Irp, IO_NO_INCREMENT);
49
50 return(STATUS_NO_MEMORY);
51 }
52
53 KeLockMutex(&DeviceExtension->MailslotListLock);
54 current_entry = DeviceExtension->MailslotListHead.Flink;
55 while (current_entry != &DeviceExtension->MailslotListHead)
56 {
57 current = CONTAINING_RECORD(current_entry,
58 MSFS_MAILSLOT,
59 MailslotListEntry);
60
61 if (!RtlCompareUnicodeString(&FileObject->FileName, &current->Name, TRUE))
62 {
63 break;
64 }
65
66 current_entry = current_entry->Flink;
67 }
68
69 if (current_entry == &DeviceExtension->MailslotListHead)
70 {
71 ExFreePool(Fcb);
72 KeUnlockMutex(&DeviceExtension->MailslotListLock);
73
74 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
75 Irp->IoStatus.Information = 0;
76
77 IoCompleteRequest(Irp, IO_NO_INCREMENT);
78
79 return(STATUS_UNSUCCESSFUL);
80 }
81
82 Mailslot = current;
83
84 KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql);
85 InsertTailList(&Mailslot->FcbListHead, &Fcb->FcbListEntry);
86 KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql);
87
88 Mailslot->ReferenceCount++;
89
90 Fcb->Mailslot = Mailslot;
91
92 KeUnlockMutex(&DeviceExtension->MailslotListLock);
93
94 FileObject->FsContext = Fcb;
95
96 Irp->IoStatus.Status = STATUS_SUCCESS;
97 Irp->IoStatus.Information = 0;
98
99 IoCompleteRequest(Irp, IO_NO_INCREMENT);
100
101 return(STATUS_SUCCESS);
102 }
103
104
105 NTSTATUS STDCALL
106 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject,
107 PIRP Irp)
108 {
109 PIO_STACK_LOCATION IoStack;
110 PFILE_OBJECT FileObject;
111 PMSFS_DEVICE_EXTENSION DeviceExtension;
112 PMSFS_MAILSLOT Mailslot;
113 PMSFS_FCB Fcb;
114 KIRQL oldIrql;
115 PLIST_ENTRY current_entry;
116 PMSFS_MAILSLOT current;
117 PIO_MAILSLOT_CREATE_BUFFER Buffer;
118
119 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
120
121 IoStack = IoGetCurrentIrpStackLocation(Irp);
122 DeviceExtension = DeviceObject->DeviceExtension;
123 FileObject = IoStack->FileObject;
124 Buffer = (PIO_MAILSLOT_CREATE_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
125
126 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName);
127
128 Mailslot = ExAllocatePool(NonPagedPool, sizeof(MSFS_MAILSLOT));
129 if (Mailslot == 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 if (!RtlCreateUnicodeString(&Mailslot->Name, FileObject->FileName.Buffer))
140 {
141 ExFreePool(Mailslot);
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 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->MaxMessageSize;
170 Mailslot->MessageCount = 0;
171 Mailslot->TimeOut = Buffer->TimeOut;
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 */