1 /* $Id: create.c,v 1.4 2002/09/08 10:22:10 chorns Exp $
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
);