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
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MSFS_CCB
), 'cFsM');
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
)
68 ExFreePoolWithTag(Ccb
, 'cFsM');
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
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MSFS_FCB
), 'fFsM');
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
= ExAllocatePoolWithTag(NonPagedPool
,
142 Fcb
->Name
.MaximumLength
,
144 if (Fcb
->Name
.Buffer
== NULL
)
146 ExFreePoolWithTag(Fcb
, 'fFsM');
148 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
149 Irp
->IoStatus
.Information
= 0;
151 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
153 return STATUS_NO_MEMORY
;
156 RtlCopyUnicodeString(&Fcb
->Name
, &FileObject
->FileName
);
158 Ccb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MSFS_CCB
), 'cFsM');
161 ExFreePoolWithTag(Fcb
->Name
.Buffer
, 'NFsM');
162 ExFreePoolWithTag(Fcb
, 'fFsM');
164 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
165 Irp
->IoStatus
.Information
= 0;
167 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
169 return STATUS_NO_MEMORY
;
172 Fcb
->ReferenceCount
= 0;
173 InitializeListHead(&Fcb
->CcbListHead
);
174 KeInitializeSpinLock(&Fcb
->CcbListLock
);
176 Fcb
->MaxMessageSize
= Buffer
->MaximumMessageSize
;
177 Fcb
->MessageCount
= 0;
178 Fcb
->TimeOut
= Buffer
->ReadTimeout
;
179 KeInitializeEvent(&Fcb
->MessageEvent
,
183 InitializeListHead(&Fcb
->MessageListHead
);
184 KeInitializeSpinLock(&Fcb
->MessageListLock
);
186 KeLockMutex(&DeviceExtension
->FcbListLock
);
187 current_entry
= DeviceExtension
->FcbListHead
.Flink
;
188 while (current_entry
!= &DeviceExtension
->FcbListHead
)
190 current
= CONTAINING_RECORD(current_entry
,
194 if (!RtlCompareUnicodeString(&Fcb
->Name
, ¤t
->Name
, TRUE
))
197 current_entry
= current_entry
->Flink
;
200 if (current_entry
!= &DeviceExtension
->FcbListHead
)
202 ExFreePoolWithTag(Fcb
->Name
.Buffer
, 'NFsM');
203 ExFreePoolWithTag(Fcb
, 'fFsM');
204 ExFreePoolWithTag(Ccb
, 'cFsM');
206 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
208 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
209 Irp
->IoStatus
.Information
= 0;
211 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
213 return STATUS_UNSUCCESSFUL
;
217 InsertTailList(&DeviceExtension
->FcbListHead
,
221 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
222 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
223 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
225 Fcb
->ReferenceCount
++;
226 Fcb
->ServerCcb
= Ccb
;
229 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
231 FileObject
->FsContext
= Fcb
;
232 FileObject
->FsContext2
= Ccb
;
233 FileObject
->Flags
|= FO_MAILSLOT
;
235 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
236 Irp
->IoStatus
.Information
= 0;
238 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
240 return STATUS_SUCCESS
;
245 MsfsClose(PDEVICE_OBJECT DeviceObject
,
248 PIO_STACK_LOCATION IoStack
;
249 PFILE_OBJECT FileObject
;
250 PMSFS_DEVICE_EXTENSION DeviceExtension
;
253 PMSFS_MESSAGE Message
;
256 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
258 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
259 DeviceExtension
= DeviceObject
->DeviceExtension
;
260 FileObject
= IoStack
->FileObject
;
262 KeLockMutex(&DeviceExtension
->FcbListLock
);
264 if (DeviceExtension
->FcbListHead
.Flink
== &DeviceExtension
->FcbListHead
)
266 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
268 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
269 Irp
->IoStatus
.Information
= 0;
271 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
273 return STATUS_SUCCESS
;
276 Fcb
= FileObject
->FsContext
;
277 Ccb
= FileObject
->FsContext2
;
279 DPRINT("Mailslot name: %wZ\n", &Fcb
->Name
);
281 Fcb
->ReferenceCount
--;
282 if (Fcb
->ServerCcb
== Ccb
)
284 /* delete all messages from message-list */
285 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
287 while (Fcb
->MessageListHead
.Flink
!= &Fcb
->MessageListHead
)
289 Message
= CONTAINING_RECORD(Fcb
->MessageListHead
.Flink
,
292 RemoveEntryList(Fcb
->MessageListHead
.Flink
);
293 ExFreePoolWithTag(Message
, 'rFsM');
296 Fcb
->MessageCount
= 0;
298 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
299 Fcb
->ServerCcb
= NULL
;
302 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
303 RemoveEntryList(&Ccb
->CcbListEntry
);
304 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
305 ExFreePoolWithTag(Ccb
, 'cFsM');
306 FileObject
->FsContext2
= NULL
;
308 if (Fcb
->ReferenceCount
== 0)
310 DPRINT("ReferenceCount == 0: Deleting mailslot data\n");
311 RemoveEntryList(&Fcb
->FcbListEntry
);
312 ExFreePoolWithTag(Fcb
->Name
.Buffer
, 'NFsM');
313 ExFreePoolWithTag(Fcb
, 'fFsM');
316 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
318 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
319 Irp
->IoStatus
.Information
= 0;
321 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
323 return STATUS_SUCCESS
;