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
);
202 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
204 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
205 Irp
->IoStatus
.Information
= 0;
207 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
209 return STATUS_UNSUCCESSFUL
;
213 InsertTailList(&DeviceExtension
->FcbListHead
,
217 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
218 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
219 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
221 Fcb
->ReferenceCount
++;
222 Fcb
->ServerCcb
= Ccb
;
225 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
227 FileObject
->FsContext
= Fcb
;
228 FileObject
->FsContext2
= Ccb
;
229 FileObject
->Flags
|= FO_MAILSLOT
;
231 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
232 Irp
->IoStatus
.Information
= 0;
234 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
236 return STATUS_SUCCESS
;
241 MsfsClose(PDEVICE_OBJECT DeviceObject
,
244 PIO_STACK_LOCATION IoStack
;
245 PFILE_OBJECT FileObject
;
246 PMSFS_DEVICE_EXTENSION DeviceExtension
;
249 PMSFS_MESSAGE Message
;
252 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
254 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
255 DeviceExtension
= DeviceObject
->DeviceExtension
;
256 FileObject
= IoStack
->FileObject
;
258 KeLockMutex(&DeviceExtension
->FcbListLock
);
260 if (DeviceExtension
->FcbListHead
.Flink
== &DeviceExtension
->FcbListHead
)
262 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
264 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
265 Irp
->IoStatus
.Information
= 0;
267 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
269 return STATUS_SUCCESS
;
272 Fcb
= FileObject
->FsContext
;
273 Ccb
= FileObject
->FsContext2
;
275 DPRINT("Mailslot name: %wZ\n", &Fcb
->Name
);
277 Fcb
->ReferenceCount
--;
278 if (Fcb
->ServerCcb
== Ccb
)
280 /* delete all messages from message-list */
281 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
283 while (Fcb
->MessageListHead
.Flink
!= &Fcb
->MessageListHead
)
285 Message
= CONTAINING_RECORD(Fcb
->MessageListHead
.Flink
,
288 RemoveEntryList(Fcb
->MessageListHead
.Flink
);
292 Fcb
->MessageCount
= 0;
294 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
295 Fcb
->ServerCcb
= NULL
;
298 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
299 RemoveEntryList(&Ccb
->CcbListEntry
);
300 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
302 FileObject
->FsContext2
= NULL
;
304 if (Fcb
->ReferenceCount
== 0)
306 DPRINT("ReferenceCount == 0: Deleting mailslot data\n");
307 RemoveEntryList(&Fcb
->FcbListEntry
);
308 ExFreePool(Fcb
->Name
.Buffer
);
312 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
314 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
315 Irp
->IoStatus
.Information
= 0;
317 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
319 return STATUS_SUCCESS
;