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
;
94 FileObject
->Flags
|= FO_MAILSLOT
;
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 PEXTENDED_IO_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 PMAILSLOT_CREATE_PARAMETERS Buffer
;
119 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
121 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IoGetCurrentIrpStackLocation(Irp
);
122 DeviceExtension
= DeviceObject
->DeviceExtension
;
123 FileObject
= IoStack
->FileObject
;
124 Buffer
= IoStack
->Parameters
.CreateMailslot
.Parameters
;
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 Mailslot
->Name
.Length
= FileObject
->FileName
.Length
;
140 Mailslot
->Name
.MaximumLength
= Mailslot
->Name
.Length
+ sizeof(UNICODE_NULL
);
141 Mailslot
->Name
.Buffer
= ExAllocatePool(NonPagedPool
, Mailslot
->Name
.MaximumLength
);
142 if (Mailslot
->Name
.Buffer
== NULL
)
144 ExFreePool(Mailslot
);
146 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
147 Irp
->IoStatus
.Information
= 0;
149 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
151 return(STATUS_NO_MEMORY
);
154 RtlCopyUnicodeString(&Mailslot
->Name
, &FileObject
->FileName
);
156 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_FCB
));
159 ExFreePool(Mailslot
);
161 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
162 Irp
->IoStatus
.Information
= 0;
164 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
166 return(STATUS_NO_MEMORY
);
169 Mailslot
->ReferenceCount
= 0;
170 InitializeListHead(&Mailslot
->FcbListHead
);
171 KeInitializeSpinLock(&Mailslot
->FcbListLock
);
173 Mailslot
->MaxMessageSize
= Buffer
->MaximumMessageSize
;
174 Mailslot
->MessageCount
= 0;
175 Mailslot
->TimeOut
= Buffer
->ReadTimeout
;
176 KeInitializeEvent(&Mailslot
->MessageEvent
,
180 InitializeListHead(&Mailslot
->MessageListHead
);
181 KeInitializeSpinLock(&Mailslot
->MessageListLock
);
183 KeLockMutex(&DeviceExtension
->MailslotListLock
);
184 current_entry
= DeviceExtension
->MailslotListHead
.Flink
;
185 while (current_entry
!= &DeviceExtension
->MailslotListHead
)
187 current
= CONTAINING_RECORD(current_entry
,
191 if (!RtlCompareUnicodeString(&Mailslot
->Name
, ¤t
->Name
, TRUE
))
196 current_entry
= current_entry
->Flink
;
199 if (current_entry
!= &DeviceExtension
->MailslotListHead
)
201 RtlFreeUnicodeString(&Mailslot
->Name
);
202 ExFreePool(Mailslot
);
208 InsertTailList(&DeviceExtension
->MailslotListHead
,
209 &Mailslot
->MailslotListEntry
);
212 KeAcquireSpinLock(&Mailslot
->FcbListLock
, &oldIrql
);
213 InsertTailList(&Mailslot
->FcbListHead
, &Fcb
->FcbListEntry
);
214 KeReleaseSpinLock(&Mailslot
->FcbListLock
, oldIrql
);
216 Mailslot
->ReferenceCount
++;
217 Mailslot
->ServerFcb
= Fcb
;
218 Fcb
->Mailslot
= Mailslot
;
220 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
222 FileObject
->FsContext
= Fcb
;
223 FileObject
->Flags
|= FO_MAILSLOT
;
225 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
226 Irp
->IoStatus
.Information
= 0;
228 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
230 return(STATUS_SUCCESS
);
235 MsfsClose(PDEVICE_OBJECT DeviceObject
,
238 PIO_STACK_LOCATION IoStack
;
239 PFILE_OBJECT FileObject
;
240 PMSFS_DEVICE_EXTENSION DeviceExtension
;
241 PMSFS_MAILSLOT Mailslot
;
243 PMSFS_MESSAGE Message
;
246 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
248 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
249 DeviceExtension
= DeviceObject
->DeviceExtension
;
250 FileObject
= IoStack
->FileObject
;
252 KeLockMutex(&DeviceExtension
->MailslotListLock
);
254 if (DeviceExtension
->MailslotListHead
.Flink
== &DeviceExtension
->MailslotListHead
)
256 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
258 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
259 Irp
->IoStatus
.Information
= 0;
261 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
263 return(STATUS_SUCCESS
);
266 Fcb
= FileObject
->FsContext
;
267 Mailslot
= Fcb
->Mailslot
;
269 DPRINT("Mailslot name: %wZ\n", &Mailslot
->Name
);
271 Mailslot
->ReferenceCount
--;
272 if (Mailslot
->ServerFcb
== Fcb
)
274 /* delete all messages from message-list */
275 KeAcquireSpinLock(&Mailslot
->MessageListLock
, &oldIrql
);
277 while (Mailslot
->MessageListHead
.Flink
!= &Mailslot
->MessageListHead
)
279 Message
= CONTAINING_RECORD(Mailslot
->MessageListHead
.Flink
,
282 RemoveEntryList(Mailslot
->MessageListHead
.Flink
);
285 Mailslot
->MessageCount
= 0;
287 KeReleaseSpinLock(&Mailslot
->MessageListLock
, oldIrql
);
288 Mailslot
->ServerFcb
= NULL
;
291 KeAcquireSpinLock(&Mailslot
->FcbListLock
, &oldIrql
);
292 RemoveEntryList(&Fcb
->FcbListEntry
);
293 KeReleaseSpinLock(&Mailslot
->FcbListLock
, oldIrql
);
295 FileObject
->FsContext
= NULL
;
297 if (Mailslot
->ReferenceCount
== 0)
299 DPRINT1("ReferenceCount == 0: Deleting mailslot data\n");
300 RtlFreeUnicodeString(&Mailslot
->Name
);
301 RemoveEntryList(&Mailslot
->MailslotListEntry
);
302 ExFreePool(Mailslot
);
305 KeUnlockMutex(&DeviceExtension
->MailslotListLock
);
307 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
308 Irp
->IoStatus
.Information
= 0;
310 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
312 return(STATUS_SUCCESS
);