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 UNICODE_STRING DriverName
;
27 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
28 NTSTATUS Status
= STATUS_IMAGE_ALREADY_LOADED
;
31 /* Make sure we haven't already been called */
32 if (DeviceExtension
->State
!= Loaded
)
34 /* Acquire the load lock */
35 KeWaitForSingleObject(FsRecLoadSync
,
40 KeEnterCriticalRegion();
42 /* Make sure we're active */
43 if (DeviceExtension
->State
== Pending
)
45 /* Load the FS driver */
46 RtlInitUnicodeString(&DriverName
, DriverServiceName
);
47 Status
= ZwLoadDriver(&DriverName
);
49 /* Loop all the linked recognizer objects */
50 while (DeviceExtension
->State
!= Unloading
)
52 /* Set them to the unload state */
53 DeviceExtension
->State
= Unloading
;
55 /* Go to the next one */
56 DeviceObject
= DeviceExtension
->Alternate
;
57 DeviceExtension
= DeviceObject
->DeviceExtension
;
61 /* Make sure that we haven't already loaded the FS */
62 if (DeviceExtension
->State
!= Loaded
)
64 /* Unregiser us, and set us as loaded */
65 IoUnregisterFileSystem(DeviceObject
);
66 DeviceExtension
->State
= Loaded
;
69 /* Release the lock */
70 KeSetEvent(FsRecLoadSync
, 0, FALSE
);
71 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
);
175 /* Unrecognized FS */
176 Status
= STATUS_INVALID_DEVICE_REQUEST
;
179 /* Complete the IRP */
180 Irp
->IoStatus
.Status
= Status
;
181 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
185 DRIVER_UNLOAD FsRecUnload
;
188 FsRecUnload(IN PDRIVER_OBJECT DriverObject
)
192 /* Loop all driver device objects */
193 while (DriverObject
->DeviceObject
)
195 /* Delete this device */
196 IoDeleteDevice(DriverObject
->DeviceObject
);
200 ExFreePool(FsRecLoadSync
);
205 FsRecRegisterFs(IN PDRIVER_OBJECT DriverObject
,
206 IN PDEVICE_OBJECT ParentObject OPTIONAL
,
207 OUT PDEVICE_OBJECT
*NewDeviceObject OPTIONAL
,
209 IN PCWSTR RecognizerName
,
211 IN DEVICE_TYPE DeviceType
)
213 OBJECT_ATTRIBUTES ObjectAttributes
;
214 IO_STATUS_BLOCK IoStatus
;
215 PDEVICE_EXTENSION DeviceExtension
;
216 UNICODE_STRING DeviceName
;
217 PDEVICE_OBJECT DeviceObject
;
222 if (NewDeviceObject
) *NewDeviceObject
= NULL
;
224 /* Setup the attributes */
225 RtlInitUnicodeString(&DeviceName
, FsName
);
226 InitializeObjectAttributes(&ObjectAttributes
,
228 OBJ_CASE_INSENSITIVE
,
232 /* Open the device */
233 Status
= ZwCreateFile(&FileHandle
,
239 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
244 if (NT_SUCCESS(Status
))
246 /* We suceeded, close the handle */
249 else if (Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
251 /* We failed with anything else then what we want to fail with */
252 Status
= STATUS_SUCCESS
;
255 /* If we succeeded, there's no point in trying this again */
256 if (NT_SUCCESS(Status
)) return STATUS_IMAGE_ALREADY_LOADED
;
258 /* Create recognizer device object */
259 RtlInitUnicodeString(&DeviceName
, RecognizerName
);
260 Status
= IoCreateDevice(DriverObject
,
261 sizeof(DEVICE_EXTENSION
),
267 if (NT_SUCCESS(Status
))
269 /* Get the device extension and set it up */
270 DeviceExtension
= DeviceObject
->DeviceExtension
;
271 DeviceExtension
->FsType
= FsType
;
272 DeviceExtension
->State
= Pending
;
274 /* Do we have a parent? */
278 DeviceExtension
->Alternate
=
279 ((PDEVICE_EXTENSION
)ParentObject
->DeviceExtension
)->Alternate
;
280 ((PDEVICE_EXTENSION
)ParentObject
->DeviceExtension
)->Alternate
=
285 /* Otherwise, we're the only one */
286 DeviceExtension
->Alternate
= DeviceObject
;
289 /* Return the DO if needed */
290 if (NewDeviceObject
) *NewDeviceObject
= DeviceObject
;
292 /* Register the file system */
293 IoRegisterFileSystem(DeviceObject
);
302 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
303 IN PUNICODE_STRING RegistryPath
)
305 ULONG DeviceCount
= 0;
307 PDEVICE_OBJECT UdfsObject
;
310 UNREFERENCED_PARAMETER(RegistryPath
);
312 /* Page the entire driver */
313 MmPageEntireDriver(DriverEntry
);
315 /* Allocate the lock */
316 FsRecLoadSync
= ExAllocatePoolWithTag(NonPagedPool
,
319 if (!FsRecLoadSync
) return STATUS_INSUFFICIENT_RESOURCES
;
322 KeInitializeEvent(FsRecLoadSync
, SynchronizationEvent
, TRUE
);
324 /* Setup the major functions */
325 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = FsRecCreate
;
326 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = FsRecClose
;
327 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = FsRecClose
;
328 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = FsRecFsControl
;
329 DriverObject
->DriverUnload
= FsRecUnload
;
332 Status
= FsRecRegisterFs(DriverObject
,
336 L
"\\FileSystem\\CdfsRecognizer",
338 FILE_DEVICE_CD_ROM_FILE_SYSTEM
);
339 if (NT_SUCCESS(Status
)) DeviceCount
++;
341 /* Register UDFS for CDs */
342 Status
= FsRecRegisterFs(DriverObject
,
346 L
"\\FileSystem\\UdfsCdRomRecognizer",
348 FILE_DEVICE_CD_ROM_FILE_SYSTEM
);
349 if (NT_SUCCESS(Status
)) DeviceCount
++;
351 /* Register UDFS for HDDs */
352 Status
= FsRecRegisterFs(DriverObject
,
356 L
"\\FileSystem\\UdfsDiskRecognizer",
358 FILE_DEVICE_DISK_FILE_SYSTEM
);
359 if (NT_SUCCESS(Status
)) DeviceCount
++;
362 Status
= FsRecRegisterFs(DriverObject
,
366 L
"\\FileSystem\\FatRecognizer",
368 FILE_DEVICE_DISK_FILE_SYSTEM
);
369 if (NT_SUCCESS(Status
)) DeviceCount
++;
372 Status
= FsRecRegisterFs(DriverObject
,
376 L
"\\FileSystem\\NtfsRecognizer",
378 FILE_DEVICE_DISK_FILE_SYSTEM
);
379 if (NT_SUCCESS(Status
)) DeviceCount
++;
382 Status
= FsRecRegisterFs(DriverObject
,
386 L
"\\FileSystem\\Ext2Recognizer",
388 FILE_DEVICE_DISK_FILE_SYSTEM
);
389 if (NT_SUCCESS(Status
)) DeviceCount
++;
392 Status
= FsRecRegisterFs(DriverObject
,
396 L
"\\FileSystem\\BtrfsRecognizer",
398 FILE_DEVICE_DISK_FILE_SYSTEM
);
399 if (NT_SUCCESS(Status
)) DeviceCount
++;
401 /* Return appropriate Status */
402 return (DeviceCount
> 0) ? STATUS_SUCCESS
: STATUS_IMAGE_ALREADY_LOADED
;