3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/ms/create.c
6 * PURPOSE: Mailslot filesystem
7 * PROGRAMMER: Eric Kohl <ekohl@rz-online.de>
10 /* INCLUDES ******************************************************************/
18 /* FUNCTIONS *****************************************************************/
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
);
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
))
65 current_entry
= current_entry
->Flink
;
68 if (current_entry
== &DeviceExtension
->FcbListHead
)
71 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
73 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
74 Irp
->IoStatus
.Information
= 0;
76 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
78 return(STATUS_UNSUCCESSFUL
);
83 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
84 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
85 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
87 Fcb
->ReferenceCount
++;
91 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
93 FileObject
->FsContext
= Fcb
;
94 FileObject
->FsContext2
= Ccb
;
95 FileObject
->Flags
|= FO_MAILSLOT
;
97 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
98 Irp
->IoStatus
.Information
= 0;
100 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
102 return(STATUS_SUCCESS
);
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
;
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
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_FCB
));
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
= ExAllocatePool(NonPagedPool
, Fcb
->Name
.MaximumLength
);
143 if (Fcb
->Name
.Buffer
== NULL
)
147 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
148 Irp
->IoStatus
.Information
= 0;
150 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
152 return(STATUS_NO_MEMORY
);
155 RtlCopyUnicodeString(&Fcb
->Name
, &FileObject
->FileName
);
157 Ccb
= ExAllocatePool(NonPagedPool
, sizeof(MSFS_CCB
));
160 ExFreePool(Fcb
->Name
.Buffer
);
163 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
164 Irp
->IoStatus
.Information
= 0;
166 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
168 return(STATUS_NO_MEMORY
);
171 Fcb
->ReferenceCount
= 0;
172 InitializeListHead(&Fcb
->CcbListHead
);
173 KeInitializeSpinLock(&Fcb
->CcbListLock
);
175 Fcb
->MaxMessageSize
= Buffer
->MaximumMessageSize
;
176 Fcb
->MessageCount
= 0;
177 Fcb
->TimeOut
= Buffer
->ReadTimeout
;
178 KeInitializeEvent(&Fcb
->MessageEvent
,
182 InitializeListHead(&Fcb
->MessageListHead
);
183 KeInitializeSpinLock(&Fcb
->MessageListLock
);
185 KeLockMutex(&DeviceExtension
->FcbListLock
);
186 current_entry
= DeviceExtension
->FcbListHead
.Flink
;
187 while (current_entry
!= &DeviceExtension
->FcbListHead
)
189 current
= CONTAINING_RECORD(current_entry
,
193 if (!RtlCompareUnicodeString(&Fcb
->Name
, ¤t
->Name
, TRUE
))
198 current_entry
= current_entry
->Flink
;
201 if (current_entry
!= &DeviceExtension
->FcbListHead
)
203 ExFreePool(Fcb
->Name
.Buffer
);
210 InsertTailList(&DeviceExtension
->FcbListHead
,
214 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
215 InsertTailList(&Fcb
->CcbListHead
, &Ccb
->CcbListEntry
);
216 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
218 Fcb
->ReferenceCount
++;
219 Fcb
->ServerCcb
= Ccb
;
222 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
224 FileObject
->FsContext
= Fcb
;
225 FileObject
->FsContext2
= Ccb
;
226 FileObject
->Flags
|= FO_MAILSLOT
;
228 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
229 Irp
->IoStatus
.Information
= 0;
231 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
233 return(STATUS_SUCCESS
);
238 MsfsClose(PDEVICE_OBJECT DeviceObject
,
241 PIO_STACK_LOCATION IoStack
;
242 PFILE_OBJECT FileObject
;
243 PMSFS_DEVICE_EXTENSION DeviceExtension
;
246 PMSFS_MESSAGE Message
;
249 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
251 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
252 DeviceExtension
= DeviceObject
->DeviceExtension
;
253 FileObject
= IoStack
->FileObject
;
255 KeLockMutex(&DeviceExtension
->FcbListLock
);
257 if (DeviceExtension
->FcbListHead
.Flink
== &DeviceExtension
->FcbListHead
)
259 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
261 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
262 Irp
->IoStatus
.Information
= 0;
264 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
266 return(STATUS_SUCCESS
);
269 Fcb
= FileObject
->FsContext
;
270 Ccb
= FileObject
->FsContext2
;
272 DPRINT("Mailslot name: %wZ\n", &Fcb
->Name
);
274 Fcb
->ReferenceCount
--;
275 if (Fcb
->ServerCcb
== Ccb
)
277 /* delete all messages from message-list */
278 KeAcquireSpinLock(&Fcb
->MessageListLock
, &oldIrql
);
280 while (Fcb
->MessageListHead
.Flink
!= &Fcb
->MessageListHead
)
282 Message
= CONTAINING_RECORD(Fcb
->MessageListHead
.Flink
,
285 RemoveEntryList(Fcb
->MessageListHead
.Flink
);
288 Fcb
->MessageCount
= 0;
290 KeReleaseSpinLock(&Fcb
->MessageListLock
, oldIrql
);
291 Fcb
->ServerCcb
= NULL
;
294 KeAcquireSpinLock(&Fcb
->CcbListLock
, &oldIrql
);
295 RemoveEntryList(&Ccb
->CcbListEntry
);
296 KeReleaseSpinLock(&Fcb
->CcbListLock
, oldIrql
);
298 FileObject
->FsContext2
= NULL
;
300 if (Fcb
->ReferenceCount
== 0)
302 DPRINT1("ReferenceCount == 0: Deleting mailslot data\n");
303 RemoveEntryList(&Fcb
->FcbListEntry
);
304 ExFreePool(Fcb
->Name
.Buffer
);
308 KeUnlockMutex(&DeviceExtension
->FcbListLock
);
310 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
311 Irp
->IoStatus
.Information
= 0;
313 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
315 return(STATUS_SUCCESS
);