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 ******************************************************************/
18 /* FUNCTIONS *****************************************************************/
21 MsfsCreate(PDEVICE_OBJECT DeviceObject
,
24 PIO_STACK_LOCATION IoStack
;
25 PFILE_OBJECT FileObject
;
26 PMSFS_DEVICE_EXTENSION DeviceExtension
;
27 PMSFS_MAILSLOT Mailslot
;
29 PMSFS_MAILSLOT current
= NULL
;
30 PLIST_ENTRY current_entry
;
33 DPRINT("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
35 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
36 DeviceExtension
= DeviceObject
->DeviceExtension
;
37 FileObject
= IoStack
->FileObject
;
39 DPRINT("Mailslot name: %wZ\n", &FileObject
->FileName
);
41 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_FCB
));
44 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
45 Irp
->IoStatus
.Information
= 0;
47 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
49 return(STATUS_NO_MEMORY
);
52 KeLockMutex(&DeviceExtension
->MailslotListLock
);
53 current_entry
= DeviceExtension
->MailslotListHead
.Flink
;
54 while (current_entry
!= &DeviceExtension
->MailslotListHead
)
56 current
= CONTAINING_RECORD(current_entry
,
60 if (!RtlCompareUnicodeString(&FileObject
->FileName
, ¤t
->Name
, TRUE
))
65 current_entry
= current_entry
->Flink
;
68 if (current_entry
== &DeviceExtension
->MailslotListHead
)
71 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
73 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
74 Irp
->IoStatus
.Information
= 0;
76 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
78 return(STATUS_UNSUCCESSFUL
);
83 KeAcquireSpinLock(&Mailslot
->FcbListLock
, &oldIrql
);
84 InsertTailList(&Mailslot
->FcbListHead
, &Fcb
->FcbListEntry
);
85 KeReleaseSpinLock(&Mailslot
->FcbListLock
, oldIrql
);
87 Mailslot
->ReferenceCount
++;
89 Fcb
->Mailslot
= Mailslot
;
91 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
93 FileObject
->FsContext
= Fcb
;
95 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
96 Irp
->IoStatus
.Information
= 0;
98 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
100 return(STATUS_SUCCESS
);
105 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject
,
108 PEXTENDED_IO_STACK_LOCATION IoStack
;
109 PFILE_OBJECT FileObject
;
110 PMSFS_DEVICE_EXTENSION DeviceExtension
;
111 PMSFS_MAILSLOT Mailslot
;
114 PLIST_ENTRY current_entry
;
115 PMSFS_MAILSLOT current
;
116 PMAILSLOT_CREATE_PARAMETERS Buffer
;
118 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
120 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IoGetCurrentIrpStackLocation(Irp
);
121 DeviceExtension
= DeviceObject
->DeviceExtension
;
122 FileObject
= IoStack
->FileObject
;
123 Buffer
= IoStack
->Parameters
.CreateMailslot
.Parameters
;
125 DPRINT("Mailslot name: %wZ\n", &FileObject
->FileName
);
127 Mailslot
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_MAILSLOT
));
128 if (Mailslot
== NULL
)
130 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
131 Irp
->IoStatus
.Information
= 0;
133 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
135 return(STATUS_NO_MEMORY
);
138 Mailslot
->Name
.Length
= FileObject
->FileName
.Length
;
139 Mailslot
->Name
.MaximumLength
= Mailslot
->Name
.Length
+ sizeof(UNICODE_NULL
);
140 Mailslot
->Name
.Buffer
= ExAllocatePool(NonPagedPool
, Mailslot
->Name
.MaximumLength
);
141 if (Mailslot
->Name
.Buffer
== NULL
)
143 ExFreePool(Mailslot
);
145 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
146 Irp
->IoStatus
.Information
= 0;
148 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
150 return(STATUS_NO_MEMORY
);
153 RtlCopyUnicodeString(&Mailslot
->Name
, &FileObject
->FileName
);
155 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_FCB
));
158 ExFreePool(Mailslot
);
160 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
161 Irp
->IoStatus
.Information
= 0;
163 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
165 return(STATUS_NO_MEMORY
);
168 Mailslot
->ReferenceCount
= 0;
169 InitializeListHead(&Mailslot
->FcbListHead
);
170 KeInitializeSpinLock(&Mailslot
->FcbListLock
);
172 Mailslot
->MaxMessageSize
= Buffer
->MaximumMessageSize
;
173 Mailslot
->MessageCount
= 0;
174 Mailslot
->TimeOut
= Buffer
->ReadTimeout
;
175 KeInitializeEvent(&Mailslot
->MessageEvent
,
179 InitializeListHead(&Mailslot
->MessageListHead
);
180 KeInitializeSpinLock(&Mailslot
->MessageListLock
);
182 KeLockMutex(&DeviceExtension
->MailslotListLock
);
183 current_entry
= DeviceExtension
->MailslotListHead
.Flink
;
184 while (current_entry
!= &DeviceExtension
->MailslotListHead
)
186 current
= CONTAINING_RECORD(current_entry
,
190 if (!RtlCompareUnicodeString(&Mailslot
->Name
, ¤t
->Name
, TRUE
))
195 current_entry
= current_entry
->Flink
;
198 if (current_entry
!= &DeviceExtension
->MailslotListHead
)
200 RtlFreeUnicodeString(&Mailslot
->Name
);
201 ExFreePool(Mailslot
);
207 InsertTailList(&DeviceExtension
->MailslotListHead
,
208 &Mailslot
->MailslotListEntry
);
211 KeAcquireSpinLock(&Mailslot
->FcbListLock
, &oldIrql
);
212 InsertTailList(&Mailslot
->FcbListHead
, &Fcb
->FcbListEntry
);
213 KeReleaseSpinLock(&Mailslot
->FcbListLock
, oldIrql
);
215 Mailslot
->ReferenceCount
++;
216 Mailslot
->ServerFcb
= Fcb
;
217 Fcb
->Mailslot
= Mailslot
;
219 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
221 FileObject
->FsContext
= Fcb
;
223 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
224 Irp
->IoStatus
.Information
= 0;
226 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
228 return(STATUS_SUCCESS
);
233 MsfsClose(PDEVICE_OBJECT DeviceObject
,
236 PIO_STACK_LOCATION IoStack
;
237 PFILE_OBJECT FileObject
;
238 PMSFS_DEVICE_EXTENSION DeviceExtension
;
239 PMSFS_MAILSLOT Mailslot
;
241 PMSFS_MESSAGE Message
;
244 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
246 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
247 DeviceExtension
= DeviceObject
->DeviceExtension
;
248 FileObject
= IoStack
->FileObject
;
250 KeLockMutex(&DeviceExtension
->MailslotListLock
);
252 if (DeviceExtension
->MailslotListHead
.Flink
== &DeviceExtension
->MailslotListHead
)
254 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
256 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
257 Irp
->IoStatus
.Information
= 0;
259 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
261 return(STATUS_SUCCESS
);
264 Fcb
= FileObject
->FsContext
;
265 Mailslot
= Fcb
->Mailslot
;
267 DPRINT("Mailslot name: %wZ\n", &Mailslot
->Name
);
269 Mailslot
->ReferenceCount
--;
270 if (Mailslot
->ServerFcb
== Fcb
)
272 /* delete all messages from message-list */
273 KeAcquireSpinLock(&Mailslot
->MessageListLock
, &oldIrql
);
275 while (Mailslot
->MessageListHead
.Flink
!= &Mailslot
->MessageListHead
)
277 Message
= CONTAINING_RECORD(Mailslot
->MessageListHead
.Flink
,
280 RemoveEntryList(Mailslot
->MessageListHead
.Flink
);
283 Mailslot
->MessageCount
= 0;
285 KeReleaseSpinLock(&Mailslot
->MessageListLock
, oldIrql
);
286 Mailslot
->ServerFcb
= NULL
;
289 KeAcquireSpinLock(&Mailslot
->FcbListLock
, &oldIrql
);
290 RemoveEntryList(&Fcb
->FcbListEntry
);
291 KeReleaseSpinLock(&Mailslot
->FcbListLock
, oldIrql
);
293 FileObject
->FsContext
= NULL
;
295 if (Mailslot
->ReferenceCount
== 0)
297 DPRINT1("ReferenceCount == 0: Deleting mailslot data\n");
298 RtlFreeUnicodeString(&Mailslot
->Name
);
299 RemoveEntryList(&Mailslot
->MailslotListEntry
);
300 ExFreePool(Mailslot
);
303 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
305 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
306 Irp
->IoStatus
.Information
= 0;
308 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
310 return(STATUS_SUCCESS
);