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)
10 /* INCLUDES *****************************************************************/
17 PKEVENT FsRecLoadSync
;
19 /* FUNCTIONS ****************************************************************/
23 FsRecLoadFileSystem(IN PDEVICE_OBJECT DeviceObject
,
24 IN PWCHAR DriverServiceName
)
26 NTSTATUS Status
= STATUS_IMAGE_ALREADY_LOADED
;
27 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
28 UNICODE_STRING DriverName
;
32 /* Make sure we haven't already been called */
33 if (DeviceExtension
->State
!= Loaded
)
35 /* Acquire the load lock */
36 KeEnterCriticalRegion();
37 KeWaitForSingleObject(FsRecLoadSync
,
43 /* Make sure we're active */
44 if (DeviceExtension
->State
== Pending
)
46 /* Load the FS driver */
47 RtlInitUnicodeString(&DriverName
, DriverServiceName
);
48 Status
= ZwLoadDriver(&DriverName
);
50 /* Loop all the linked recognizer objects */
51 while (DeviceExtension
->State
!= Unloading
)
53 /* Set them to the unload state */
54 DeviceExtension
->State
= Unloading
;
56 /* Go to the next one */
57 DeviceObject
= DeviceExtension
->Alternate
;
58 DeviceExtension
= DeviceObject
->DeviceExtension
;
62 /* Make sure that we haven't already loaded the FS */
63 if (DeviceExtension
->State
!= Loaded
)
65 /* Unregister us, and set us as loaded */
66 IoUnregisterFileSystem(DeviceObject
);
67 DeviceExtension
->State
= Loaded
;
70 /* Release the lock */
71 KeSetEvent(FsRecLoadSync
, IO_NO_INCREMENT
, FALSE
);
72 KeLeaveCriticalRegion();
78 DRIVER_DISPATCH FsRecCreate
;
81 FsRecCreate(IN PDEVICE_OBJECT DeviceObject
,
84 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
88 UNREFERENCED_PARAMETER(DeviceObject
);
90 /* Make sure we have a file name */
91 if (IoStack
->FileObject
->FileName
.Length
)
93 /* Fail the request */
94 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
99 Status
= STATUS_SUCCESS
;
102 /* Complete the IRP */
103 Irp
->IoStatus
.Status
= Status
;
104 Irp
->IoStatus
.Information
= FILE_OPENED
;
105 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
109 DRIVER_DISPATCH FsRecClose
;
112 FsRecClose(IN PDEVICE_OBJECT DeviceObject
,
117 UNREFERENCED_PARAMETER(DeviceObject
);
119 /* Just complete the IRP and return success */
120 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
121 return STATUS_SUCCESS
;
124 DRIVER_DISPATCH FsRecFsControl
;
127 FsRecFsControl(IN PDEVICE_OBJECT DeviceObject
,
130 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
134 /* Check the file system type */
135 switch (DeviceExtension
->FsType
)
139 /* Send FAT command */
140 Status
= FsRecVfatFsControl(DeviceObject
, Irp
);
145 /* Send NTFS command */
146 Status
= FsRecNtfsFsControl(DeviceObject
, Irp
);
151 /* Send CDFS command */
152 Status
= FsRecCdfsFsControl(DeviceObject
, Irp
);
157 /* Send UDFS command */
158 Status
= FsRecUdfsFsControl(DeviceObject
, Irp
);
163 /* Send EXT2 command */
164 Status
= FsRecExt2FsControl(DeviceObject
, Irp
);
169 /* Send BTRFS command */
170 Status
= FsRecBtrfsFsControl(DeviceObject
, Irp
);
173 case FS_TYPE_REISERFS
:
175 /* Send REISERFS command */
176 Status
= FsRecReiserfsFsControl(DeviceObject
, Irp
);
181 /* Send FFS command */
182 Status
= FsRecFfsFsControl(DeviceObject
, Irp
);
187 /* Send FATX command */
188 Status
= FsRecFatxFsControl(DeviceObject
, Irp
);
193 /* Unrecognized FS */
194 Status
= STATUS_INVALID_DEVICE_REQUEST
;
197 /* Complete the IRP */
198 Irp
->IoStatus
.Status
= Status
;
199 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
203 DRIVER_UNLOAD FsRecUnload
;
206 FsRecUnload(IN PDRIVER_OBJECT DriverObject
)
210 /* Loop all driver device objects */
211 while (DriverObject
->DeviceObject
)
213 /* Delete this device */
214 IoDeleteDevice(DriverObject
->DeviceObject
);
218 ExFreePool(FsRecLoadSync
);
223 FsRecRegisterFs(IN PDRIVER_OBJECT DriverObject
,
224 IN PDEVICE_OBJECT ParentObject OPTIONAL
,
225 OUT PDEVICE_OBJECT
*NewDeviceObject OPTIONAL
,
227 IN PCWSTR RecognizerName
,
229 IN DEVICE_TYPE DeviceType
,
230 IN ULONG AdditionalFlags
)
232 OBJECT_ATTRIBUTES ObjectAttributes
;
233 IO_STATUS_BLOCK IoStatus
;
234 PDEVICE_EXTENSION DeviceExtension
;
235 UNICODE_STRING DeviceName
;
236 PDEVICE_OBJECT DeviceObject
;
241 if (NewDeviceObject
) *NewDeviceObject
= NULL
;
243 /* Setup the attributes */
244 RtlInitUnicodeString(&DeviceName
, FsName
);
245 InitializeObjectAttributes(&ObjectAttributes
,
247 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
251 /* Open the device */
252 Status
= ZwCreateFile(&FileHandle
,
258 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
263 if (NT_SUCCESS(Status
))
265 /* We succeeded, close the handle */
268 else if (Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
270 /* We failed with anything else then what we want to fail with */
271 Status
= STATUS_SUCCESS
;
274 /* If we succeeded, there's no point in trying this again */
275 if (NT_SUCCESS(Status
)) return STATUS_IMAGE_ALREADY_LOADED
;
277 /* Create recognizer device object */
278 RtlInitUnicodeString(&DeviceName
, RecognizerName
);
279 Status
= IoCreateDevice(DriverObject
,
280 sizeof(DEVICE_EXTENSION
),
286 if (NT_SUCCESS(Status
))
288 /* Set additional flags in the device object */
289 DeviceObject
->Flags
|= AdditionalFlags
;
291 /* Get the device extension and set it up */
292 DeviceExtension
= DeviceObject
->DeviceExtension
;
293 DeviceExtension
->FsType
= FsType
;
294 DeviceExtension
->State
= Pending
;
296 /* Do we have a parent? */
300 DeviceExtension
->Alternate
=
301 ((PDEVICE_EXTENSION
)ParentObject
->DeviceExtension
)->Alternate
;
302 ((PDEVICE_EXTENSION
)ParentObject
->DeviceExtension
)->Alternate
=
307 /* Otherwise, we're the only one */
308 DeviceExtension
->Alternate
= DeviceObject
;
311 /* Return the DO if needed */
312 if (NewDeviceObject
) *NewDeviceObject
= DeviceObject
;
314 /* Register the file system */
315 IoRegisterFileSystem(DeviceObject
);
324 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
325 IN PUNICODE_STRING RegistryPath
)
328 ULONG DeviceCount
= 0;
329 PDEVICE_OBJECT CdfsObject
;
330 PDEVICE_OBJECT UdfsObject
;
331 PDEVICE_OBJECT FatObject
;
335 UNREFERENCED_PARAMETER(RegistryPath
);
337 /* Page the entire driver */
338 MmPageEntireDriver(DriverEntry
);
340 /* Allocate the lock */
341 FsRecLoadSync
= ExAllocatePoolWithTag(NonPagedPool
,
344 if (!FsRecLoadSync
) return STATUS_INSUFFICIENT_RESOURCES
;
347 KeInitializeEvent(FsRecLoadSync
, SynchronizationEvent
, TRUE
);
349 /* Setup the major functions */
350 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = FsRecCreate
;
351 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = FsRecClose
;
352 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = FsRecClose
;
353 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = FsRecFsControl
;
354 DriverObject
->DriverUnload
= FsRecUnload
;
356 /* Register CDFS for CDs */
357 Status
= FsRecRegisterFs(DriverObject
,
361 L
"\\FileSystem\\CdfsRecognizer",
363 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
364 DO_LOW_PRIORITY_FILESYSTEM
);
365 if (NT_SUCCESS(Status
)) DeviceCount
++;
367 /* Register CDFS for HDDs */
368 Status
= FsRecRegisterFs(DriverObject
,
372 L
"\\FileSystem\\CdfsHddRecognizer",
374 FILE_DEVICE_DISK_FILE_SYSTEM
,
375 DO_LOW_PRIORITY_FILESYSTEM
);
376 if (NT_SUCCESS(Status
)) DeviceCount
++;
378 /* Register UDFS for CDs */
379 Status
= FsRecRegisterFs(DriverObject
,
383 L
"\\FileSystem\\UdfsCdRomRecognizer",
385 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
387 if (NT_SUCCESS(Status
)) DeviceCount
++;
389 /* Register UDFS for HDDs */
390 Status
= FsRecRegisterFs(DriverObject
,
394 L
"\\FileSystem\\UdfsDiskRecognizer",
396 FILE_DEVICE_DISK_FILE_SYSTEM
,
398 if (NT_SUCCESS(Status
)) DeviceCount
++;
401 Status
= FsRecRegisterFs(DriverObject
,
405 L
"\\FileSystem\\FatRecognizer",
407 FILE_DEVICE_DISK_FILE_SYSTEM
,
409 if (NT_SUCCESS(Status
)) DeviceCount
++;
411 /* Register FAT for CDs */
412 Status
= FsRecRegisterFs(DriverObject
,
416 L
"\\FileSystem\\FatCdRomRecognizer",
418 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
420 if (NT_SUCCESS(Status
)) DeviceCount
++;
423 Status
= FsRecRegisterFs(DriverObject
,
427 L
"\\FileSystem\\NtfsRecognizer",
429 FILE_DEVICE_DISK_FILE_SYSTEM
,
431 if (NT_SUCCESS(Status
)) DeviceCount
++;
434 Status
= FsRecRegisterFs(DriverObject
,
438 L
"\\FileSystem\\Ext2Recognizer",
440 FILE_DEVICE_DISK_FILE_SYSTEM
,
442 if (NT_SUCCESS(Status
)) DeviceCount
++;
445 Status
= FsRecRegisterFs(DriverObject
,
449 L
"\\FileSystem\\BtrfsRecognizer",
451 FILE_DEVICE_DISK_FILE_SYSTEM
,
453 if (NT_SUCCESS(Status
)) DeviceCount
++;
455 /* Register REISERFS */
456 Status
= FsRecRegisterFs(DriverObject
,
460 L
"\\FileSystem\\ReiserfsRecognizer",
462 FILE_DEVICE_DISK_FILE_SYSTEM
,
464 if (NT_SUCCESS(Status
)) DeviceCount
++;
467 Status
= FsRecRegisterFs(DriverObject
,
471 L
"\\FileSystem\\FfsRecognizer",
473 FILE_DEVICE_DISK_FILE_SYSTEM
,
475 if (NT_SUCCESS(Status
)) DeviceCount
++;
478 Status
= FsRecRegisterFs(DriverObject
,
482 L
"\\FileSystem\\FatXRecognizer",
484 FILE_DEVICE_DISK_FILE_SYSTEM
,
486 if (NT_SUCCESS(Status
)) DeviceCount
++;
488 /* Return appropriate Status */
489 return (DeviceCount
> 0) ? STATUS_SUCCESS
: STATUS_IMAGE_ALREADY_LOADED
;