1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS File System Recognizer 4 * FILE: drivers/filesystems/fs_rec/fs_rec.c 5 * PURPOSE: Main Driver Entrypoint and FS Registration 6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) 7 * Eric Kohl 8 */ 9 10 /* INCLUDES *****************************************************************/ 11 12 #include "fs_rec.h" 13 14 #define NDEBUG 15 #include <debug.h> 16 17 PKEVENT FsRecLoadSync; 18 19 /* FUNCTIONS ****************************************************************/ 20 21 NTSTATUS 22 NTAPI 23 FsRecLoadFileSystem(IN PDEVICE_OBJECT DeviceObject, 24 IN PWCHAR DriverServiceName) 25 { 26 UNICODE_STRING DriverName; 27 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 28 NTSTATUS Status = STATUS_IMAGE_ALREADY_LOADED; 29 PAGED_CODE(); 30 31 /* Make sure we haven't already been called */ 32 if (DeviceExtension->State != Loaded) 33 { 34 /* Acquire the load lock */ 35 KeWaitForSingleObject(FsRecLoadSync, 36 Executive, 37 KernelMode, 38 FALSE, 39 NULL); 40 KeEnterCriticalRegion(); 41 42 /* Make sure we're active */ 43 if (DeviceExtension->State == Pending) 44 { 45 /* Load the FS driver */ 46 RtlInitUnicodeString(&DriverName, DriverServiceName); 47 Status = ZwLoadDriver(&DriverName); 48 49 /* Loop all the linked recognizer objects */ 50 while (DeviceExtension->State != Unloading) 51 { 52 /* Set them to the unload state */ 53 DeviceExtension->State = Unloading; 54 55 /* Go to the next one */ 56 DeviceObject = DeviceExtension->Alternate; 57 DeviceExtension = DeviceObject->DeviceExtension; 58 } 59 } 60 61 /* Make sure that we haven't already loaded the FS */ 62 if (DeviceExtension->State != Loaded) 63 { 64 /* Unregister us, and set us as loaded */ 65 IoUnregisterFileSystem(DeviceObject); 66 DeviceExtension->State = Loaded; 67 } 68 69 /* Release the lock */ 70 KeSetEvent(FsRecLoadSync, 0, FALSE); 71 KeLeaveCriticalRegion(); 72 } 73 74 /* Return */ 75 return Status; 76 } 77 78 DRIVER_DISPATCH FsRecCreate; 79 NTSTATUS 80 NTAPI 81 FsRecCreate(IN PDEVICE_OBJECT DeviceObject, 82 IN PIRP Irp) 83 { 84 PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); 85 NTSTATUS Status; 86 PAGED_CODE(); 87 88 UNREFERENCED_PARAMETER(DeviceObject); 89 90 /* Make sure we have a file name */ 91 if (IoStack->FileObject->FileName.Length) 92 { 93 /* Fail the request */ 94 Status = STATUS_OBJECT_PATH_NOT_FOUND; 95 } 96 else 97 { 98 /* Let it through */ 99 Status = STATUS_SUCCESS; 100 } 101 102 /* Complete the IRP */ 103 Irp->IoStatus.Status = Status; 104 Irp->IoStatus.Information = FILE_OPENED; 105 IoCompleteRequest(Irp, IO_NO_INCREMENT); 106 return Status; 107 } 108 109 DRIVER_DISPATCH FsRecClose; 110 NTSTATUS 111 NTAPI 112 FsRecClose(IN PDEVICE_OBJECT DeviceObject, 113 IN PIRP Irp) 114 { 115 PAGED_CODE(); 116 117 UNREFERENCED_PARAMETER(DeviceObject); 118 119 /* Just complete the IRP and return success */ 120 IoCompleteRequest(Irp, IO_NO_INCREMENT); 121 return STATUS_SUCCESS; 122 } 123 124 DRIVER_DISPATCH FsRecFsControl; 125 NTSTATUS 126 NTAPI 127 FsRecFsControl(IN PDEVICE_OBJECT DeviceObject, 128 IN PIRP Irp) 129 { 130 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 131 NTSTATUS Status; 132 PAGED_CODE(); 133 134 /* Check the file system type */ 135 switch (DeviceExtension->FsType) 136 { 137 case FS_TYPE_VFAT: 138 139 /* Send FAT command */ 140 Status = FsRecVfatFsControl(DeviceObject, Irp); 141 break; 142 143 case FS_TYPE_NTFS: 144 145 /* Send NTFS command */ 146 Status = FsRecNtfsFsControl(DeviceObject, Irp); 147 break; 148 149 case FS_TYPE_CDFS: 150 151 /* Send CDFS command */ 152 Status = FsRecCdfsFsControl(DeviceObject, Irp); 153 break; 154 155 case FS_TYPE_UDFS: 156 157 /* Send UDFS command */ 158 Status = FsRecUdfsFsControl(DeviceObject, Irp); 159 break; 160 161 case FS_TYPE_EXT2: 162 163 /* Send EXT2 command */ 164 Status = FsRecExt2FsControl(DeviceObject, Irp); 165 break; 166 167 case FS_TYPE_BTRFS: 168 169 /* Send BTRFS command */ 170 Status = FsRecBtrfsFsControl(DeviceObject, Irp); 171 break; 172 173 case FS_TYPE_REISERFS: 174 175 /* Send REISERFS command */ 176 Status = FsRecReiserfsFsControl(DeviceObject, Irp); 177 break; 178 179 case FS_TYPE_FFS: 180 181 /* Send FFS command */ 182 Status = FsRecFfsFsControl(DeviceObject, Irp); 183 break; 184 185 default: 186 187 /* Unrecognized FS */ 188 Status = STATUS_INVALID_DEVICE_REQUEST; 189 } 190 191 /* Complete the IRP */ 192 Irp->IoStatus.Status = Status; 193 IoCompleteRequest(Irp, IO_NO_INCREMENT); 194 return Status; 195 } 196 197 DRIVER_UNLOAD FsRecUnload; 198 VOID 199 NTAPI 200 FsRecUnload(IN PDRIVER_OBJECT DriverObject) 201 { 202 PAGED_CODE(); 203 204 /* Loop all driver device objects */ 205 while (DriverObject->DeviceObject) 206 { 207 /* Delete this device */ 208 IoDeleteDevice(DriverObject->DeviceObject); 209 } 210 211 /* Free the lock */ 212 ExFreePool(FsRecLoadSync); 213 } 214 215 NTSTATUS 216 NTAPI 217 FsRecRegisterFs(IN PDRIVER_OBJECT DriverObject, 218 IN PDEVICE_OBJECT ParentObject OPTIONAL, 219 OUT PDEVICE_OBJECT *NewDeviceObject OPTIONAL, 220 IN PCWSTR FsName, 221 IN PCWSTR RecognizerName, 222 IN ULONG FsType, 223 IN DEVICE_TYPE DeviceType, 224 IN ULONG AdditionalFlags) 225 { 226 OBJECT_ATTRIBUTES ObjectAttributes; 227 IO_STATUS_BLOCK IoStatus; 228 PDEVICE_EXTENSION DeviceExtension; 229 UNICODE_STRING DeviceName; 230 PDEVICE_OBJECT DeviceObject; 231 HANDLE FileHandle; 232 NTSTATUS Status; 233 234 /* Assume failure */ 235 if (NewDeviceObject) *NewDeviceObject = NULL; 236 237 /* Setup the attributes */ 238 RtlInitUnicodeString(&DeviceName, FsName); 239 InitializeObjectAttributes(&ObjectAttributes, 240 &DeviceName, 241 OBJ_CASE_INSENSITIVE, 242 0, 243 NULL); 244 245 /* Open the device */ 246 Status = ZwCreateFile(&FileHandle, 247 SYNCHRONIZE, 248 &ObjectAttributes, 249 &IoStatus, 250 NULL, 251 0, 252 FILE_SHARE_READ | FILE_SHARE_WRITE, 253 FILE_OPEN, 254 0, 255 NULL, 256 0); 257 if (NT_SUCCESS(Status)) 258 { 259 /* We succeeded, close the handle */ 260 ZwClose(FileHandle); 261 } 262 else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) 263 { 264 /* We failed with anything else then what we want to fail with */ 265 Status = STATUS_SUCCESS; 266 } 267 268 /* If we succeeded, there's no point in trying this again */ 269 if (NT_SUCCESS(Status)) return STATUS_IMAGE_ALREADY_LOADED; 270 271 /* Create recognizer device object */ 272 RtlInitUnicodeString(&DeviceName, RecognizerName); 273 Status = IoCreateDevice(DriverObject, 274 sizeof(DEVICE_EXTENSION), 275 &DeviceName, 276 DeviceType, 277 0, 278 FALSE, 279 &DeviceObject); 280 if (NT_SUCCESS(Status)) 281 { 282 /* Set additional flags in the device object */ 283 DeviceObject->Flags |= AdditionalFlags; 284 285 /* Get the device extension and set it up */ 286 DeviceExtension = DeviceObject->DeviceExtension; 287 DeviceExtension->FsType = FsType; 288 DeviceExtension->State = Pending; 289 290 /* Do we have a parent? */ 291 if (ParentObject) 292 { 293 /* Link it in */ 294 DeviceExtension->Alternate = 295 ((PDEVICE_EXTENSION)ParentObject->DeviceExtension)->Alternate; 296 ((PDEVICE_EXTENSION)ParentObject->DeviceExtension)->Alternate = 297 DeviceObject; 298 } 299 else 300 { 301 /* Otherwise, we're the only one */ 302 DeviceExtension->Alternate = DeviceObject; 303 } 304 305 /* Return the DO if needed */ 306 if (NewDeviceObject) *NewDeviceObject = DeviceObject; 307 308 /* Register the file system */ 309 IoRegisterFileSystem(DeviceObject); 310 } 311 312 /* Return Status */ 313 return Status; 314 } 315 316 NTSTATUS 317 NTAPI 318 DriverEntry(IN PDRIVER_OBJECT DriverObject, 319 IN PUNICODE_STRING RegistryPath) 320 { 321 ULONG DeviceCount = 0; 322 NTSTATUS Status; 323 PDEVICE_OBJECT CdfsObject; 324 PDEVICE_OBJECT UdfsObject; 325 PAGED_CODE(); 326 327 UNREFERENCED_PARAMETER(RegistryPath); 328 329 /* Page the entire driver */ 330 MmPageEntireDriver(DriverEntry); 331 332 /* Allocate the lock */ 333 FsRecLoadSync = ExAllocatePoolWithTag(NonPagedPool, 334 sizeof(KEVENT), 335 FSREC_TAG); 336 if (!FsRecLoadSync) return STATUS_INSUFFICIENT_RESOURCES; 337 338 /* Initialize it */ 339 KeInitializeEvent(FsRecLoadSync, SynchronizationEvent, TRUE); 340 341 /* Setup the major functions */ 342 DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate; 343 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRecClose; 344 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecClose; 345 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl; 346 DriverObject->DriverUnload = FsRecUnload; 347 348 /* Register CDFS for CDs */ 349 Status = FsRecRegisterFs(DriverObject, 350 NULL, 351 &CdfsObject, 352 L"\\Cdfs", 353 L"\\FileSystem\\CdfsRecognizer", 354 FS_TYPE_CDFS, 355 FILE_DEVICE_CD_ROM_FILE_SYSTEM, 356 DO_LOW_PRIORITY_FILESYSTEM); 357 if (NT_SUCCESS(Status)) DeviceCount++; 358 359 /* Register CDFS for HDDs */ 360 Status = FsRecRegisterFs(DriverObject, 361 CdfsObject, 362 NULL, 363 L"\\CdfsHdd", 364 L"\\FileSystem\\CdfsHddRecognizer", 365 FS_TYPE_CDFS, 366 FILE_DEVICE_DISK_FILE_SYSTEM, 367 DO_LOW_PRIORITY_FILESYSTEM); 368 if (NT_SUCCESS(Status)) DeviceCount++; 369 370 /* Register UDFS for CDs */ 371 Status = FsRecRegisterFs(DriverObject, 372 NULL, 373 &UdfsObject, 374 L"\\UdfsCdRom", 375 L"\\FileSystem\\UdfsCdRomRecognizer", 376 FS_TYPE_UDFS, 377 FILE_DEVICE_CD_ROM_FILE_SYSTEM, 378 0); 379 if (NT_SUCCESS(Status)) DeviceCount++; 380 381 /* Register UDFS for HDDs */ 382 Status = FsRecRegisterFs(DriverObject, 383 UdfsObject, 384 NULL, 385 L"\\UdfsDisk", 386 L"\\FileSystem\\UdfsDiskRecognizer", 387 FS_TYPE_UDFS, 388 FILE_DEVICE_DISK_FILE_SYSTEM, 389 0); 390 if (NT_SUCCESS(Status)) DeviceCount++; 391 392 /* Register FAT */ 393 Status = FsRecRegisterFs(DriverObject, 394 NULL, 395 NULL, 396 L"\\Fat", 397 L"\\FileSystem\\FatRecognizer", 398 FS_TYPE_VFAT, 399 FILE_DEVICE_DISK_FILE_SYSTEM, 400 0); 401 if (NT_SUCCESS(Status)) DeviceCount++; 402 403 /* Register NTFS */ 404 Status = FsRecRegisterFs(DriverObject, 405 NULL, 406 NULL, 407 L"\\Ntfs", 408 L"\\FileSystem\\NtfsRecognizer", 409 FS_TYPE_NTFS, 410 FILE_DEVICE_DISK_FILE_SYSTEM, 411 0); 412 if (NT_SUCCESS(Status)) DeviceCount++; 413 414 /* Register EXT2 */ 415 Status = FsRecRegisterFs(DriverObject, 416 NULL, 417 NULL, 418 L"\\Ext2fs", 419 L"\\FileSystem\\Ext2Recognizer", 420 FS_TYPE_EXT2, 421 FILE_DEVICE_DISK_FILE_SYSTEM, 422 0); 423 if (NT_SUCCESS(Status)) DeviceCount++; 424 425 /* Register BTRFS */ 426 Status = FsRecRegisterFs(DriverObject, 427 NULL, 428 NULL, 429 L"\\Btrfs", 430 L"\\FileSystem\\BtrfsRecognizer", 431 FS_TYPE_BTRFS, 432 FILE_DEVICE_DISK_FILE_SYSTEM, 433 0); 434 if (NT_SUCCESS(Status)) DeviceCount++; 435 436 /* Register REISERFS */ 437 Status = FsRecRegisterFs(DriverObject, 438 NULL, 439 NULL, 440 L"\\Reiserfs", 441 L"\\FileSystem\\ReiserfsRecognizer", 442 FS_TYPE_REISERFS, 443 FILE_DEVICE_DISK_FILE_SYSTEM, 444 0); 445 if (NT_SUCCESS(Status)) DeviceCount++; 446 447 /* Register FFS */ 448 Status = FsRecRegisterFs(DriverObject, 449 NULL, 450 NULL, 451 L"\\ffs", 452 L"\\FileSystem\\FfsRecognizer", 453 FS_TYPE_FFS, 454 FILE_DEVICE_DISK_FILE_SYSTEM, 455 0); 456 if (NT_SUCCESS(Status)) DeviceCount++; 457 458 /* Return appropriate Status */ 459 return (DeviceCount > 0) ? STATUS_SUCCESS : STATUS_IMAGE_ALREADY_LOADED; 460 } 461 462 /* EOF */ 463