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>
13 #include <ddk/iotypes.h> /* FIXME: Temporary Until NDK implemented */
20 /* FUNCTIONS *****************************************************************/
23 MsfsCreate(PDEVICE_OBJECT DeviceObject
,
26 PIO_STACK_LOCATION IoStack
;
27 PFILE_OBJECT FileObject
;
28 PMSFS_DEVICE_EXTENSION DeviceExtension
;
29 PMSFS_MAILSLOT Mailslot
;
31 PMSFS_MAILSLOT current
;
32 PLIST_ENTRY current_entry
;
35 DPRINT("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
37 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
38 DeviceExtension
= DeviceObject
->DeviceExtension
;
39 FileObject
= IoStack
->FileObject
;
41 DPRINT("Mailslot name: %wZ\n", &FileObject
->FileName
);
43 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_FCB
));
46 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
47 Irp
->IoStatus
.Information
= 0;
49 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
51 return(STATUS_NO_MEMORY
);
54 KeLockMutex(&DeviceExtension
->MailslotListLock
);
55 current_entry
= DeviceExtension
->MailslotListHead
.Flink
;
56 while (current_entry
!= &DeviceExtension
->MailslotListHead
)
58 current
= CONTAINING_RECORD(current_entry
,
62 if (!RtlCompareUnicodeString(&FileObject
->FileName
, ¤t
->Name
, TRUE
))
67 current_entry
= current_entry
->Flink
;
70 if (current_entry
== &DeviceExtension
->MailslotListHead
)
73 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
75 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
76 Irp
->IoStatus
.Information
= 0;
78 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
80 return(STATUS_UNSUCCESSFUL
);
85 KeAcquireSpinLock(&Mailslot
->FcbListLock
, &oldIrql
);
86 InsertTailList(&Mailslot
->FcbListHead
, &Fcb
->FcbListEntry
);
87 KeReleaseSpinLock(&Mailslot
->FcbListLock
, oldIrql
);
89 Mailslot
->ReferenceCount
++;
91 Fcb
->Mailslot
= Mailslot
;
93 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
95 FileObject
->FsContext
= Fcb
;
97 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
98 Irp
->IoStatus
.Information
= 0;
100 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
102 return(STATUS_SUCCESS
);
107 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject
,
110 PIO_STACK_LOCATION IoStack
;
111 PFILE_OBJECT FileObject
;
112 PMSFS_DEVICE_EXTENSION DeviceExtension
;
113 PMSFS_MAILSLOT Mailslot
;
116 PLIST_ENTRY current_entry
;
117 PMSFS_MAILSLOT current
;
118 PMAILSLOT_CREATE_PARAMETERS Buffer
;
120 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
122 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
123 DeviceExtension
= DeviceObject
->DeviceExtension
;
124 FileObject
= IoStack
->FileObject
;
125 Buffer
= IoStack
->Parameters
.CreateMailslot
.Parameters
;
127 DPRINT("Mailslot name: %wZ\n", &FileObject
->FileName
);
129 Mailslot
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_MAILSLOT
));
130 if (Mailslot
== NULL
)
132 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
133 Irp
->IoStatus
.Information
= 0;
135 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
137 return(STATUS_NO_MEMORY
);
140 if (!RtlCreateUnicodeString(&Mailslot
->Name
, FileObject
->FileName
.Buffer
))
142 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
->MaximumMessageSize
;
170 Mailslot
->MessageCount
= 0;
171 Mailslot
->TimeOut
= Buffer
->ReadTimeout
;
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
);