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>
10 /* INCLUDES ******************************************************************/
12 #include <ddk/ntddk.h>
19 /* FUNCTIONS *****************************************************************/
22 MsfsCreate(PDEVICE_OBJECT DeviceObject,
25 PIO_STACK_LOCATION IoStack;
26 PFILE_OBJECT FileObject;
27 PMSFS_DEVICE_EXTENSION DeviceExtension;
28 PMSFS_MAILSLOT Mailslot;
30 PMSFS_MAILSLOT current;
31 PLIST_ENTRY current_entry;
34 DPRINT("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
36 IoStack = IoGetCurrentIrpStackLocation(Irp);
37 DeviceExtension = DeviceObject->DeviceExtension;
38 FileObject = IoStack->FileObject;
40 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName);
42 Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB));
45 Irp->IoStatus.Status = STATUS_NO_MEMORY;
46 Irp->IoStatus.Information = 0;
48 IoCompleteRequest(Irp, IO_NO_INCREMENT);
50 return(STATUS_NO_MEMORY);
53 KeLockMutex(&DeviceExtension->MailslotListLock);
54 current_entry = DeviceExtension->MailslotListHead.Flink;
55 while (current_entry != &DeviceExtension->MailslotListHead)
57 current = CONTAINING_RECORD(current_entry,
61 if (!RtlCompareUnicodeString(&FileObject->FileName, ¤t->Name, TRUE))
66 current_entry = current_entry->Flink;
69 if (current_entry == &DeviceExtension->MailslotListHead)
72 KeUnlockMutex(&DeviceExtension->MailslotListLock);
74 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
75 Irp->IoStatus.Information = 0;
77 IoCompleteRequest(Irp, IO_NO_INCREMENT);
79 return(STATUS_UNSUCCESSFUL);
84 KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql);
85 InsertTailList(&Mailslot->FcbListHead, &Fcb->FcbListEntry);
86 KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql);
88 Mailslot->ReferenceCount++;
90 Fcb->Mailslot = Mailslot;
92 KeUnlockMutex(&DeviceExtension->MailslotListLock);
94 FileObject->FsContext = Fcb;
96 Irp->IoStatus.Status = STATUS_SUCCESS;
97 Irp->IoStatus.Information = 0;
99 IoCompleteRequest(Irp, IO_NO_INCREMENT);
101 return(STATUS_SUCCESS);
106 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject,
109 PIO_STACK_LOCATION IoStack;
110 PFILE_OBJECT FileObject;
111 PMSFS_DEVICE_EXTENSION DeviceExtension;
112 PMSFS_MAILSLOT Mailslot;
115 PLIST_ENTRY current_entry;
116 PMSFS_MAILSLOT current;
117 PIO_MAILSLOT_CREATE_BUFFER Buffer;
119 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
121 IoStack = IoGetCurrentIrpStackLocation(Irp);
122 DeviceExtension = DeviceObject->DeviceExtension;
123 FileObject = IoStack->FileObject;
124 Buffer = (PIO_MAILSLOT_CREATE_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
126 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName);
128 Mailslot = ExAllocatePool(NonPagedPool, sizeof(MSFS_MAILSLOT));
129 if (Mailslot == NULL)
131 Irp->IoStatus.Status = STATUS_NO_MEMORY;
132 Irp->IoStatus.Information = 0;
134 IoCompleteRequest(Irp, IO_NO_INCREMENT);
136 return(STATUS_NO_MEMORY);
139 if (!RtlCreateUnicodeString(&Mailslot->Name, FileObject->FileName.Buffer))
141 ExFreePool(Mailslot);
144 Irp->IoStatus.Status = STATUS_NO_MEMORY;
145 Irp->IoStatus.Information = 0;
147 IoCompleteRequest(Irp, IO_NO_INCREMENT);
149 return(STATUS_NO_MEMORY);
152 Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB));
155 ExFreePool(Mailslot);
157 Irp->IoStatus.Status = STATUS_NO_MEMORY;
158 Irp->IoStatus.Information = 0;
160 IoCompleteRequest(Irp, IO_NO_INCREMENT);
162 return(STATUS_NO_MEMORY);
165 Mailslot->ReferenceCount = 0;
166 InitializeListHead(&Mailslot->FcbListHead);
167 KeInitializeSpinLock(&Mailslot->FcbListLock);
169 Mailslot->MaxMessageSize = Buffer->MaxMessageSize;
170 Mailslot->MessageCount = 0;
171 Mailslot->TimeOut = Buffer->TimeOut;
172 KeInitializeEvent(&Mailslot->MessageEvent,
176 InitializeListHead(&Mailslot->MessageListHead);
177 KeInitializeSpinLock(&Mailslot->MessageListLock);
179 KeLockMutex(&DeviceExtension->MailslotListLock);
180 current_entry = DeviceExtension->MailslotListHead.Flink;
181 while (current_entry != &DeviceExtension->MailslotListHead)
183 current = CONTAINING_RECORD(current_entry,
187 if (!RtlCompareUnicodeString(&Mailslot->Name, ¤t->Name, TRUE))
192 current_entry = current_entry->Flink;
195 if (current_entry != &DeviceExtension->MailslotListHead)
197 RtlFreeUnicodeString(&Mailslot->Name);
198 ExFreePool(Mailslot);
204 InsertTailList(&DeviceExtension->MailslotListHead,
205 &Mailslot->MailslotListEntry);
208 KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql);
209 InsertTailList(&Mailslot->FcbListHead, &Fcb->FcbListEntry);
210 KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql);
212 Mailslot->ReferenceCount++;
213 Mailslot->ServerFcb = Fcb;
214 Fcb->Mailslot = Mailslot;
216 KeUnlockMutex(&DeviceExtension->MailslotListLock);
218 FileObject->FsContext = Fcb;
220 Irp->IoStatus.Status = STATUS_SUCCESS;
221 Irp->IoStatus.Information = 0;
223 IoCompleteRequest(Irp, IO_NO_INCREMENT);
225 return(STATUS_SUCCESS);
230 MsfsClose(PDEVICE_OBJECT DeviceObject,
233 PIO_STACK_LOCATION IoStack;
234 PFILE_OBJECT FileObject;
235 PMSFS_DEVICE_EXTENSION DeviceExtension;
236 PMSFS_MAILSLOT Mailslot;
238 PMSFS_MESSAGE Message;
241 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
243 IoStack = IoGetCurrentIrpStackLocation(Irp);
244 DeviceExtension = DeviceObject->DeviceExtension;
245 FileObject = IoStack->FileObject;
247 KeLockMutex(&DeviceExtension->MailslotListLock);
249 if (DeviceExtension->MailslotListHead.Flink == &DeviceExtension->MailslotListHead)
251 KeUnlockMutex(&DeviceExtension->MailslotListLock);
253 Irp->IoStatus.Status = STATUS_SUCCESS;
254 Irp->IoStatus.Information = 0;
256 IoCompleteRequest(Irp, IO_NO_INCREMENT);
258 return(STATUS_SUCCESS);
261 Fcb = FileObject->FsContext;
262 Mailslot = Fcb->Mailslot;
264 DPRINT("Mailslot name: %wZ\n", &Mailslot->Name);
266 Mailslot->ReferenceCount--;
267 if (Mailslot->ServerFcb == Fcb)
269 /* delete all messages from message-list */
270 KeAcquireSpinLock(&Mailslot->MessageListLock, &oldIrql);
272 while (Mailslot->MessageListHead.Flink != &Mailslot->MessageListHead)
274 Message = CONTAINING_RECORD(Mailslot->MessageListHead.Flink,
277 RemoveEntryList(Mailslot->MessageListHead.Flink);
280 Mailslot->MessageCount = 0;
282 KeReleaseSpinLock(&Mailslot->MessageListLock, oldIrql);
283 Mailslot->ServerFcb = NULL;
286 KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql);
287 RemoveEntryList(&Fcb->FcbListEntry);
288 KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql);
290 FileObject->FsContext = NULL;
292 if (Mailslot->ReferenceCount == 0)
294 DPRINT1("ReferenceCount == 0: Deleting mailslot data\n");
295 RtlFreeUnicodeString(&Mailslot->Name);
296 RemoveEntryList(&Mailslot->MailslotListEntry);
297 ExFreePool(Mailslot);
300 KeUnlockMutex(&DeviceExtension->MailslotListLock);
302 Irp->IoStatus.Status = STATUS_SUCCESS;
303 Irp->IoStatus.Information = 0;
305 IoCompleteRequest(Irp, IO_NO_INCREMENT);
307 return(STATUS_SUCCESS);