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
7 * Nikita Pechenkin (n.pechenkin@mail.ru)
10 /* INCLUDES ******************************************************************/
14 #include <ndk/iotypes.h>
19 /* FUNCTIONS *****************************************************************/
21 /* Creates the client side */
23 MsfsCreate(PDEVICE_OBJECT DeviceObject
,
26 PIO_STACK_LOCATION IoStack
;
27 PFILE_OBJECT FileObject
;
28 PMSFS_DEVICE_EXTENSION DeviceExtension
;
31 PMSFS_FCB current
= NULL
;
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 Ccb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MSFS_CCB
), 'cFsM');
46 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
47 Irp
->IoStatus
.Information
= 0;
49 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
50 return STATUS_NO_MEMORY
;
53 KeLockMutex(&DeviceExtension
->FcbListLock
);
54 current_entry
= DeviceExtension
->FcbListHead
.Flink
;
55 while (current_entry
!= &DeviceExtension
->FcbListHead
)
57 current
= CONTAINING_RECORD(current_entry
,
61 if (!RtlCompareUnicodeString(&FileObject
->FileName
, ¤t
->Name
, TRUE
))
64 current_entry
= current_entry
->Flink
;
67 if (current_entry
== &DeviceExtension
->FcbListHead
)
69 ExFreePoolWithTag(Ccb
, 'cFsM');
70 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
72 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
73 Irp
->IoStatus
.Information
= 0;
75 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
77 return STATUS_UNSUCCESSFUL
;
82 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
83 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
84 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
86 Fcb
->ReferenceCount
++;
90 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
92 FileObject
->FsContext
= Fcb
;
93 FileObject
->FsContext2
= Ccb
;
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
;
105 /* Creates the server side */
107 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject
,
110 PEXTENDED_IO_STACK_LOCATION IoStack
;
111 PFILE_OBJECT FileObject
;
112 PMSFS_DEVICE_EXTENSION DeviceExtension
;
116 PLIST_ENTRY current_entry
;
117 PMSFS_FCB current
= NULL
;
118 PMAILSLOT_CREATE_PARAMETERS Buffer
;
120 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
122 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)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 Fcb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MSFS_FCB
), 'fFsM');
132 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
133 Irp
->IoStatus
.Information
= 0;
135 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
137 return STATUS_NO_MEMORY
;
140 Fcb
->Name
.Length
= FileObject
->FileName
.Length
;
141 Fcb
->Name
.MaximumLength
= Fcb
->Name
.Length
+ sizeof(UNICODE_NULL
);
142 Fcb
->Name
.Buffer
= ExAllocatePoolWithTag(NonPagedPool
,
143 Fcb
->Name
.MaximumLength
,
145 if (Fcb
->Name
.Buffer
== NULL
)
147 ExFreePoolWithTag(Fcb
, 'fFsM');
149 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
150 Irp
->IoStatus
.Information
= 0;
152 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
154 return STATUS_NO_MEMORY
;
157 RtlCopyUnicodeString(&Fcb
->Name
, &FileObject
->FileName
);
159 Ccb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MSFS_CCB
), 'cFsM');
162 ExFreePoolWithTag(Fcb
->Name
.Buffer
, 'NFsM');
163 ExFreePoolWithTag(Fcb
, 'fFsM');
165 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
166 Irp
->IoStatus
.Information
= 0;
168 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
170 return STATUS_NO_MEMORY
;
173 Fcb
->ReferenceCount
= 0;
174 InitializeListHead(&Fcb
->CcbListHead
);
175 KeInitializeSpinLock(&Fcb
->CcbListLock
);
177 Fcb
->MaxMessageSize
= Buffer
->MaximumMessageSize
;
178 Fcb
->MessageCount
= 0;
179 Fcb
->TimeOut
= Buffer
->ReadTimeout
;
181 InitializeListHead(&Fcb
->MessageListHead
);
182 KeInitializeSpinLock(&Fcb
->MessageListLock
);
184 KeInitializeSpinLock(&Fcb
->QueueLock
);
185 InitializeListHead(&Fcb
->PendingIrpQueue
);
186 IoCsqInitialize(&Fcb
->CancelSafeQueue
,
192 MsfsCompleteCanceledIrp
);
194 KeLockMutex(&DeviceExtension
->FcbListLock
);
195 current_entry
= DeviceExtension
->FcbListHead
.Flink
;
196 while (current_entry
!= &DeviceExtension
->FcbListHead
)
198 current
= CONTAINING_RECORD(current_entry
,
202 if (!RtlCompareUnicodeString(&Fcb
->Name
, ¤t
->Name
, TRUE
))
205 current_entry
= current_entry
->Flink
;
208 if (current_entry
!= &DeviceExtension
->FcbListHead
)
210 ExFreePoolWithTag(Fcb
->Name
.Buffer
, 'NFsM');
211 ExFreePoolWithTag(Fcb
, 'fFsM');
212 ExFreePoolWithTag(Ccb
, 'cFsM');
214 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
216 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
217 Irp
->IoStatus
.Information
= 0;
219 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
221 return STATUS_UNSUCCESSFUL
;
225 InsertTailList(&DeviceExtension
->FcbListHead
,
229 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
230 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
231 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
233 Fcb
->ReferenceCount
++;
234 Fcb
->ServerCcb
= Ccb
;
237 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
239 FileObject
->FsContext
= Fcb
;
240 FileObject
->FsContext2
= Ccb
;
241 FileObject
->Flags
|= FO_MAILSLOT
;
243 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
244 Irp
->IoStatus
.Information
= 0;
246 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
248 return STATUS_SUCCESS
;
253 MsfsClose(PDEVICE_OBJECT DeviceObject
,
256 PIO_STACK_LOCATION IoStack
;
257 PFILE_OBJECT FileObject
;
258 PMSFS_DEVICE_EXTENSION DeviceExtension
;
261 PMSFS_MESSAGE Message
;
264 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
266 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
267 DeviceExtension
= DeviceObject
->DeviceExtension
;
268 FileObject
= IoStack
->FileObject
;
270 KeLockMutex(&DeviceExtension
->FcbListLock
);
272 if (DeviceExtension
->FcbListHead
.Flink
== &DeviceExtension
->FcbListHead
)
274 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
276 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
277 Irp
->IoStatus
.Information
= 0;
279 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
281 return STATUS_SUCCESS
;
284 Fcb
= FileObject
->FsContext
;
285 Ccb
= FileObject
->FsContext2
;
287 DPRINT("Mailslot name: %wZ\n", &Fcb
->Name
);
289 Fcb
->ReferenceCount
--;
290 if (Fcb
->ServerCcb
== Ccb
)
292 /* delete all messages from message-list */
293 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
295 while (Fcb
->MessageListHead
.Flink
!= &Fcb
->MessageListHead
)
297 Message
= CONTAINING_RECORD(Fcb
->MessageListHead
.Flink
,
300 RemoveEntryList(Fcb
->MessageListHead
.Flink
);
301 ExFreePoolWithTag(Message
, 'rFsM');
304 Fcb
->MessageCount
= 0;
306 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
307 Fcb
->ServerCcb
= NULL
;
310 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
311 RemoveEntryList(&Ccb
->CcbListEntry
);
312 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
313 ExFreePoolWithTag(Ccb
, 'cFsM');
314 FileObject
->FsContext2
= NULL
;
316 if (Fcb
->ReferenceCount
== 0)
318 DPRINT("ReferenceCount == 0: Deleting mailslot data\n");
319 RemoveEntryList(&Fcb
->FcbListEntry
);
320 ExFreePoolWithTag(Fcb
->Name
.Buffer
, 'NFsM');
321 ExFreePoolWithTag(Fcb
, 'fFsM');
324 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
326 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
327 Irp
->IoStatus
.Information
= 0;
329 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
331 return STATUS_SUCCESS
;