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 ******************************************************************/
17 /* FUNCTIONS *****************************************************************/
19 /* Creates the client side */
21 MsfsCreate(PDEVICE_OBJECT DeviceObject
,
24 PIO_STACK_LOCATION IoStack
;
25 PFILE_OBJECT FileObject
;
26 PMSFS_DEVICE_EXTENSION DeviceExtension
;
29 PMSFS_FCB 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 Ccb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_CCB
));
44 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
45 Irp
->IoStatus
.Information
= 0;
47 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
48 return STATUS_NO_MEMORY
;
51 KeLockMutex(&DeviceExtension
->FcbListLock
);
52 current_entry
= DeviceExtension
->FcbListHead
.Flink
;
53 while (current_entry
!= &DeviceExtension
->FcbListHead
)
55 current
= CONTAINING_RECORD(current_entry
,
59 if (!RtlCompareUnicodeString(&FileObject
->FileName
, ¤t
->Name
, TRUE
))
62 current_entry
= current_entry
->Flink
;
65 if (current_entry
== &DeviceExtension
->FcbListHead
)
68 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
70 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
71 Irp
->IoStatus
.Information
= 0;
73 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
75 return STATUS_UNSUCCESSFUL
;
80 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
81 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
82 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
84 Fcb
->ReferenceCount
++;
88 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
90 FileObject
->FsContext
= Fcb
;
91 FileObject
->FsContext2
= Ccb
;
92 FileObject
->Flags
|= FO_MAILSLOT
;
94 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
95 Irp
->IoStatus
.Information
= 0;
97 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
99 return STATUS_SUCCESS
;
103 /* Creates the server side */
105 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject
,
108 PEXTENDED_IO_STACK_LOCATION IoStack
;
109 PFILE_OBJECT FileObject
;
110 PMSFS_DEVICE_EXTENSION DeviceExtension
;
114 PLIST_ENTRY current_entry
;
115 PMSFS_FCB current
= NULL
;
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 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_FCB
));
130 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
131 Irp
->IoStatus
.Information
= 0;
133 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
135 return STATUS_NO_MEMORY
;
138 Fcb
->Name
.Length
= FileObject
->FileName
.Length
;
139 Fcb
->Name
.MaximumLength
= Fcb
->Name
.Length
+ sizeof(UNICODE_NULL
);
140 Fcb
->Name
.Buffer
= ExAllocatePool(NonPagedPool
, Fcb
->Name
.MaximumLength
);
141 if (Fcb
->Name
.Buffer
== NULL
)
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(&Fcb
->Name
, &FileObject
->FileName
);
155 Ccb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_CCB
));
158 ExFreePool(Fcb
->Name
.Buffer
);
161 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
162 Irp
->IoStatus
.Information
= 0;
164 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
166 return STATUS_NO_MEMORY
;
169 Fcb
->ReferenceCount
= 0;
170 InitializeListHead(&Fcb
->CcbListHead
);
171 KeInitializeSpinLock(&Fcb
->CcbListLock
);
173 Fcb
->MaxMessageSize
= Buffer
->MaximumMessageSize
;
174 Fcb
->MessageCount
= 0;
175 Fcb
->TimeOut
= Buffer
->ReadTimeout
;
176 KeInitializeEvent(&Fcb
->MessageEvent
,
180 InitializeListHead(&Fcb
->MessageListHead
);
181 KeInitializeSpinLock(&Fcb
->MessageListLock
);
183 KeLockMutex(&DeviceExtension
->FcbListLock
);
184 current_entry
= DeviceExtension
->FcbListHead
.Flink
;
185 while (current_entry
!= &DeviceExtension
->FcbListHead
)
187 current
= CONTAINING_RECORD(current_entry
,
191 if (!RtlCompareUnicodeString(&Fcb
->Name
, ¤t
->Name
, TRUE
))
194 current_entry
= current_entry
->Flink
;
197 if (current_entry
!= &DeviceExtension
->FcbListHead
)
199 ExFreePool(Fcb
->Name
.Buffer
);
203 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
205 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
206 Irp
->IoStatus
.Information
= 0;
208 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
210 return STATUS_UNSUCCESSFUL
;
214 InsertTailList(&DeviceExtension
->FcbListHead
,
218 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
219 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
220 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
222 Fcb
->ReferenceCount
++;
223 Fcb
->ServerCcb
= Ccb
;
226 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
228 FileObject
->FsContext
= Fcb
;
229 FileObject
->FsContext2
= Ccb
;
230 FileObject
->Flags
|= FO_MAILSLOT
;
232 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
233 Irp
->IoStatus
.Information
= 0;
235 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
237 return STATUS_SUCCESS
;
242 MsfsClose(PDEVICE_OBJECT DeviceObject
,
245 PIO_STACK_LOCATION IoStack
;
246 PFILE_OBJECT FileObject
;
247 PMSFS_DEVICE_EXTENSION DeviceExtension
;
250 PMSFS_MESSAGE Message
;
253 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
255 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
256 DeviceExtension
= DeviceObject
->DeviceExtension
;
257 FileObject
= IoStack
->FileObject
;
259 KeLockMutex(&DeviceExtension
->FcbListLock
);
261 if (DeviceExtension
->FcbListHead
.Flink
== &DeviceExtension
->FcbListHead
)
263 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
265 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
266 Irp
->IoStatus
.Information
= 0;
268 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
270 return STATUS_SUCCESS
;
273 Fcb
= FileObject
->FsContext
;
274 Ccb
= FileObject
->FsContext2
;
276 DPRINT("Mailslot name: %wZ\n", &Fcb
->Name
);
278 Fcb
->ReferenceCount
--;
279 if (Fcb
->ServerCcb
== Ccb
)
281 /* delete all messages from message-list */
282 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
284 while (Fcb
->MessageListHead
.Flink
!= &Fcb
->MessageListHead
)
286 Message
= CONTAINING_RECORD(Fcb
->MessageListHead
.Flink
,
289 RemoveEntryList(Fcb
->MessageListHead
.Flink
);
293 Fcb
->MessageCount
= 0;
295 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
296 Fcb
->ServerCcb
= NULL
;
299 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
300 RemoveEntryList(&Ccb
->CcbListEntry
);
301 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
303 FileObject
->FsContext2
= NULL
;
305 if (Fcb
->ReferenceCount
== 0)
307 DPRINT("ReferenceCount == 0: Deleting mailslot data\n");
308 RemoveEntryList(&Fcb
->FcbListEntry
);
309 ExFreePool(Fcb
->Name
.Buffer
);
313 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
315 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
316 Irp
->IoStatus
.Information
= 0;
318 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
320 return STATUS_SUCCESS
;