2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/filesystems/msfs/create.c
5 * PURPOSE: Mailslot filesystem
6 * PROGRAMMER: Eric Kohl
9 /* INCLUDES ******************************************************************/
13 #include <ndk/iotypes.h>
18 /* FUNCTIONS *****************************************************************/
20 /* Creates the client side */
22 MsfsCreate(PDEVICE_OBJECT DeviceObject
,
25 PIO_STACK_LOCATION IoStack
;
26 PFILE_OBJECT FileObject
;
27 PMSFS_DEVICE_EXTENSION DeviceExtension
;
30 PMSFS_FCB current
= NULL
;
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 Ccb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_CCB
));
45 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
46 Irp
->IoStatus
.Information
= 0;
48 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
49 return STATUS_NO_MEMORY
;
52 KeLockMutex(&DeviceExtension
->FcbListLock
);
53 current_entry
= DeviceExtension
->FcbListHead
.Flink
;
54 while (current_entry
!= &DeviceExtension
->FcbListHead
)
56 current
= CONTAINING_RECORD(current_entry
,
60 if (!RtlCompareUnicodeString(&FileObject
->FileName
, ¤t
->Name
, TRUE
))
63 current_entry
= current_entry
->Flink
;
66 if (current_entry
== &DeviceExtension
->FcbListHead
)
69 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
71 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
72 Irp
->IoStatus
.Information
= 0;
74 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
76 return STATUS_UNSUCCESSFUL
;
81 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
82 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
83 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
85 Fcb
->ReferenceCount
++;
89 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
91 FileObject
->FsContext
= Fcb
;
92 FileObject
->FsContext2
= Ccb
;
93 FileObject
->Flags
|= FO_MAILSLOT
;
95 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
96 Irp
->IoStatus
.Information
= 0;
98 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
100 return STATUS_SUCCESS
;
104 /* Creates the server side */
106 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject
,
109 PEXTENDED_IO_STACK_LOCATION IoStack
;
110 PFILE_OBJECT FileObject
;
111 PMSFS_DEVICE_EXTENSION DeviceExtension
;
115 PLIST_ENTRY current_entry
;
116 PMSFS_FCB current
= NULL
;
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 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_FCB
));
131 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
132 Irp
->IoStatus
.Information
= 0;
134 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
136 return STATUS_NO_MEMORY
;
139 Fcb
->Name
.Length
= FileObject
->FileName
.Length
;
140 Fcb
->Name
.MaximumLength
= Fcb
->Name
.Length
+ sizeof(UNICODE_NULL
);
141 Fcb
->Name
.Buffer
= ExAllocatePool(NonPagedPool
, Fcb
->Name
.MaximumLength
);
142 if (Fcb
->Name
.Buffer
== NULL
)
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(&Fcb
->Name
, &FileObject
->FileName
);
156 Ccb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_CCB
));
159 ExFreePool(Fcb
->Name
.Buffer
);
162 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
163 Irp
->IoStatus
.Information
= 0;
165 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
167 return STATUS_NO_MEMORY
;
170 Fcb
->ReferenceCount
= 0;
171 InitializeListHead(&Fcb
->CcbListHead
);
172 KeInitializeSpinLock(&Fcb
->CcbListLock
);
174 Fcb
->MaxMessageSize
= Buffer
->MaximumMessageSize
;
175 Fcb
->MessageCount
= 0;
176 Fcb
->TimeOut
= Buffer
->ReadTimeout
;
177 KeInitializeEvent(&Fcb
->MessageEvent
,
181 InitializeListHead(&Fcb
->MessageListHead
);
182 KeInitializeSpinLock(&Fcb
->MessageListLock
);
184 KeLockMutex(&DeviceExtension
->FcbListLock
);
185 current_entry
= DeviceExtension
->FcbListHead
.Flink
;
186 while (current_entry
!= &DeviceExtension
->FcbListHead
)
188 current
= CONTAINING_RECORD(current_entry
,
192 if (!RtlCompareUnicodeString(&Fcb
->Name
, ¤t
->Name
, TRUE
))
195 current_entry
= current_entry
->Flink
;
198 if (current_entry
!= &DeviceExtension
->FcbListHead
)
200 ExFreePool(Fcb
->Name
.Buffer
);
204 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
206 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
207 Irp
->IoStatus
.Information
= 0;
209 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
211 return STATUS_UNSUCCESSFUL
;
215 InsertTailList(&DeviceExtension
->FcbListHead
,
219 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
220 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
221 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
223 Fcb
->ReferenceCount
++;
224 Fcb
->ServerCcb
= Ccb
;
227 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
229 FileObject
->FsContext
= Fcb
;
230 FileObject
->FsContext2
= Ccb
;
231 FileObject
->Flags
|= FO_MAILSLOT
;
233 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
234 Irp
->IoStatus
.Information
= 0;
236 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
238 return STATUS_SUCCESS
;
243 MsfsClose(PDEVICE_OBJECT DeviceObject
,
246 PIO_STACK_LOCATION IoStack
;
247 PFILE_OBJECT FileObject
;
248 PMSFS_DEVICE_EXTENSION DeviceExtension
;
251 PMSFS_MESSAGE Message
;
254 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
256 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
257 DeviceExtension
= DeviceObject
->DeviceExtension
;
258 FileObject
= IoStack
->FileObject
;
260 KeLockMutex(&DeviceExtension
->FcbListLock
);
262 if (DeviceExtension
->FcbListHead
.Flink
== &DeviceExtension
->FcbListHead
)
264 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
266 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
267 Irp
->IoStatus
.Information
= 0;
269 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
271 return STATUS_SUCCESS
;
274 Fcb
= FileObject
->FsContext
;
275 Ccb
= FileObject
->FsContext2
;
277 DPRINT("Mailslot name: %wZ\n", &Fcb
->Name
);
279 Fcb
->ReferenceCount
--;
280 if (Fcb
->ServerCcb
== Ccb
)
282 /* delete all messages from message-list */
283 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
285 while (Fcb
->MessageListHead
.Flink
!= &Fcb
->MessageListHead
)
287 Message
= CONTAINING_RECORD(Fcb
->MessageListHead
.Flink
,
290 RemoveEntryList(Fcb
->MessageListHead
.Flink
);
294 Fcb
->MessageCount
= 0;
296 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
297 Fcb
->ServerCcb
= NULL
;
300 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
301 RemoveEntryList(&Ccb
->CcbListEntry
);
302 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
304 FileObject
->FsContext2
= NULL
;
306 if (Fcb
->ReferenceCount
== 0)
308 DPRINT("ReferenceCount == 0: Deleting mailslot data\n");
309 RemoveEntryList(&Fcb
->FcbListEntry
);
310 ExFreePool(Fcb
->Name
.Buffer
);
314 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
316 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
317 Irp
->IoStatus
.Information
= 0;
319 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
321 return STATUS_SUCCESS
;