1 /* 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) 8 */ 9 10 /* INCLUDES ******************************************************************/ 11 12 #include "msfs.h" 13 14 #include <ndk/iotypes.h> 15 16 #define NDEBUG 17 #include <debug.h> 18 19 /* FUNCTIONS *****************************************************************/ 20 21 /* Creates the client side */ 22 NTSTATUS DEFAULTAPI 23 MsfsCreate(PDEVICE_OBJECT DeviceObject, 24 PIRP Irp) 25 { 26 PIO_STACK_LOCATION IoStack; 27 PFILE_OBJECT FileObject; 28 PMSFS_DEVICE_EXTENSION DeviceExtension; 29 PMSFS_FCB Fcb; 30 PMSFS_CCB Ccb; 31 PMSFS_FCB current = NULL; 32 PLIST_ENTRY current_entry; 33 KIRQL oldIrql; 34 35 DPRINT("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); 36 37 IoStack = IoGetCurrentIrpStackLocation(Irp); 38 DeviceExtension = DeviceObject->DeviceExtension; 39 FileObject = IoStack->FileObject; 40 41 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName); 42 43 Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_CCB), 'cFsM'); 44 if (Ccb == NULL) 45 { 46 Irp->IoStatus.Status = STATUS_NO_MEMORY; 47 Irp->IoStatus.Information = 0; 48 49 IoCompleteRequest(Irp, IO_NO_INCREMENT); 50 return STATUS_NO_MEMORY; 51 } 52 53 KeLockMutex(&DeviceExtension->FcbListLock); 54 current_entry = DeviceExtension->FcbListHead.Flink; 55 while (current_entry != &DeviceExtension->FcbListHead) 56 { 57 current = CONTAINING_RECORD(current_entry, 58 MSFS_FCB, 59 FcbListEntry); 60 61 if (!RtlCompareUnicodeString(&FileObject->FileName, ¤t->Name, TRUE)) 62 break; 63 64 current_entry = current_entry->Flink; 65 } 66 67 if (current_entry == &DeviceExtension->FcbListHead) 68 { 69 ExFreePoolWithTag(Ccb, 'cFsM'); 70 KeUnlockMutex(&DeviceExtension->FcbListLock); 71 72 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 73 Irp->IoStatus.Information = 0; 74 75 IoCompleteRequest(Irp, IO_NO_INCREMENT); 76 77 return STATUS_UNSUCCESSFUL; 78 } 79 80 Fcb = current; 81 82 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); 83 InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry); 84 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); 85 86 Fcb->ReferenceCount++; 87 88 Ccb->Fcb = Fcb; 89 90 KeUnlockMutex(&DeviceExtension->FcbListLock); 91 92 FileObject->FsContext = Fcb; 93 FileObject->FsContext2 = Ccb; 94 FileObject->Flags |= FO_MAILSLOT; 95 96 Irp->IoStatus.Status = STATUS_SUCCESS; 97 Irp->IoStatus.Information = 0; 98 99 IoCompleteRequest(Irp, IO_NO_INCREMENT); 100 101 return STATUS_SUCCESS; 102 } 103 104 105 /* Creates the server side */ 106 NTSTATUS DEFAULTAPI 107 MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject, 108 PIRP Irp) 109 { 110 PIO_STACK_LOCATION IoStack; 111 PFILE_OBJECT FileObject; 112 PMSFS_DEVICE_EXTENSION DeviceExtension; 113 PMSFS_FCB Fcb; 114 PMSFS_CCB Ccb; 115 KIRQL oldIrql; 116 PLIST_ENTRY current_entry; 117 PMSFS_FCB current = NULL; 118 PMAILSLOT_CREATE_PARAMETERS Buffer; 119 120 DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp); 121 122 IoStack = IoGetCurrentIrpStackLocation(Irp); 123 DeviceExtension = DeviceObject->DeviceExtension; 124 FileObject = IoStack->FileObject; 125 Buffer = IoStack->Parameters.CreateMailslot.Parameters; 126 127 DPRINT("Mailslot name: %wZ\n", &FileObject->FileName); 128 129 Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_FCB), 'fFsM'); 130 if (Fcb == NULL) 131 { 132 Irp->IoStatus.Status = STATUS_NO_MEMORY; 133 Irp->IoStatus.Information = 0; 134 135 IoCompleteRequest(Irp, IO_NO_INCREMENT); 136 137 return STATUS_NO_MEMORY; 138 } 139 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, 144 'NFsM'); 145 if (Fcb->Name.Buffer == NULL) 146 { 147 ExFreePoolWithTag(Fcb, 'fFsM'); 148 149 Irp->IoStatus.Status = STATUS_NO_MEMORY; 150 Irp->IoStatus.Information = 0; 151 152 IoCompleteRequest(Irp, IO_NO_INCREMENT); 153 154 return STATUS_NO_MEMORY; 155 } 156 157 RtlCopyUnicodeString(&Fcb->Name, &FileObject->FileName); 158 159 Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(MSFS_CCB), 'cFsM'); 160 if (Ccb == NULL) 161 { 162 ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM'); 163 ExFreePoolWithTag(Fcb, 'fFsM'); 164 165 Irp->IoStatus.Status = STATUS_NO_MEMORY; 166 Irp->IoStatus.Information = 0; 167 168 IoCompleteRequest(Irp, IO_NO_INCREMENT); 169 170 return STATUS_NO_MEMORY; 171 } 172 173 Fcb->ReferenceCount = 0; 174 InitializeListHead(&Fcb->CcbListHead); 175 KeInitializeSpinLock(&Fcb->CcbListLock); 176 177 Fcb->MaxMessageSize = Buffer->MaximumMessageSize; 178 Fcb->MessageCount = 0; 179 Fcb->TimeOut = Buffer->ReadTimeout; 180 181 InitializeListHead(&Fcb->MessageListHead); 182 KeInitializeSpinLock(&Fcb->MessageListLock); 183 184 KeInitializeSpinLock(&Fcb->QueueLock); 185 InitializeListHead(&Fcb->PendingIrpQueue); 186 IoCsqInitialize(&Fcb->CancelSafeQueue, 187 MsfsInsertIrp, 188 MsfsRemoveIrp, 189 MsfsPeekNextIrp, 190 MsfsAcquireLock, 191 MsfsReleaseLock, 192 MsfsCompleteCanceledIrp); 193 194 KeLockMutex(&DeviceExtension->FcbListLock); 195 current_entry = DeviceExtension->FcbListHead.Flink; 196 while (current_entry != &DeviceExtension->FcbListHead) 197 { 198 current = CONTAINING_RECORD(current_entry, 199 MSFS_FCB, 200 FcbListEntry); 201 202 if (!RtlCompareUnicodeString(&Fcb->Name, ¤t->Name, TRUE)) 203 break; 204 205 current_entry = current_entry->Flink; 206 } 207 208 if (current_entry != &DeviceExtension->FcbListHead) 209 { 210 ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM'); 211 ExFreePoolWithTag(Fcb, 'fFsM'); 212 ExFreePoolWithTag(Ccb, 'cFsM'); 213 214 KeUnlockMutex(&DeviceExtension->FcbListLock); 215 216 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 217 Irp->IoStatus.Information = 0; 218 219 IoCompleteRequest(Irp, IO_NO_INCREMENT); 220 221 return STATUS_UNSUCCESSFUL; 222 } 223 else 224 { 225 InsertTailList(&DeviceExtension->FcbListHead, 226 &Fcb->FcbListEntry); 227 } 228 229 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); 230 InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry); 231 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); 232 233 Fcb->ReferenceCount++; 234 Fcb->ServerCcb = Ccb; 235 Ccb->Fcb = Fcb; 236 237 KeUnlockMutex(&DeviceExtension->FcbListLock); 238 239 FileObject->FsContext = Fcb; 240 FileObject->FsContext2 = Ccb; 241 FileObject->Flags |= FO_MAILSLOT; 242 243 Irp->IoStatus.Status = STATUS_SUCCESS; 244 Irp->IoStatus.Information = 0; 245 246 IoCompleteRequest(Irp, IO_NO_INCREMENT); 247 248 return STATUS_SUCCESS; 249 } 250 251 252 NTSTATUS DEFAULTAPI 253 MsfsClose(PDEVICE_OBJECT DeviceObject, 254 PIRP Irp) 255 { 256 PIO_STACK_LOCATION IoStack; 257 PFILE_OBJECT FileObject; 258 PMSFS_DEVICE_EXTENSION DeviceExtension; 259 PMSFS_FCB Fcb; 260 PMSFS_CCB Ccb; 261 PMSFS_MESSAGE Message; 262 KIRQL oldIrql; 263 264 DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); 265 266 IoStack = IoGetCurrentIrpStackLocation(Irp); 267 DeviceExtension = DeviceObject->DeviceExtension; 268 FileObject = IoStack->FileObject; 269 270 KeLockMutex(&DeviceExtension->FcbListLock); 271 272 if (DeviceExtension->FcbListHead.Flink == &DeviceExtension->FcbListHead) 273 { 274 KeUnlockMutex(&DeviceExtension->FcbListLock); 275 276 Irp->IoStatus.Status = STATUS_SUCCESS; 277 Irp->IoStatus.Information = 0; 278 279 IoCompleteRequest(Irp, IO_NO_INCREMENT); 280 281 return STATUS_SUCCESS; 282 } 283 284 Fcb = FileObject->FsContext; 285 Ccb = FileObject->FsContext2; 286 287 DPRINT("Mailslot name: %wZ\n", &Fcb->Name); 288 289 Fcb->ReferenceCount--; 290 if (Fcb->ServerCcb == Ccb) 291 { 292 /* delete all messages from message-list */ 293 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql); 294 295 while (Fcb->MessageListHead.Flink != &Fcb->MessageListHead) 296 { 297 Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink, 298 MSFS_MESSAGE, 299 MessageListEntry); 300 RemoveEntryList(Fcb->MessageListHead.Flink); 301 ExFreePoolWithTag(Message, 'rFsM'); 302 } 303 304 Fcb->MessageCount = 0; 305 306 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql); 307 Fcb->ServerCcb = NULL; 308 } 309 310 KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); 311 RemoveEntryList(&Ccb->CcbListEntry); 312 KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); 313 ExFreePoolWithTag(Ccb, 'cFsM'); 314 FileObject->FsContext2 = NULL; 315 316 if (Fcb->ReferenceCount == 0) 317 { 318 DPRINT("ReferenceCount == 0: Deleting mailslot data\n"); 319 RemoveEntryList(&Fcb->FcbListEntry); 320 ExFreePoolWithTag(Fcb->Name.Buffer, 'NFsM'); 321 ExFreePoolWithTag(Fcb, 'fFsM'); 322 } 323 324 KeUnlockMutex(&DeviceExtension->FcbListLock); 325 326 Irp->IoStatus.Status = STATUS_SUCCESS; 327 Irp->IoStatus.Information = 0; 328 329 IoCompleteRequest(Irp, IO_NO_INCREMENT); 330 331 return STATUS_SUCCESS; 332 } 333 334 /* EOF */ 335