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 *****************************************************************/
16 PKEVENT FsRecLoadSync
;
18 /* FUNCTIONS ****************************************************************/
22 FsRecLoadFileSystem(IN PDEVICE_OBJECT DeviceObject
,
23 IN PWCHAR DriverServiceName
)
25 UNICODE_STRING DriverName
;
26 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
27 NTSTATUS Status
= STATUS_IMAGE_ALREADY_LOADED
;
30 /* Make sure we haven't already been called */
31 if (DeviceExtension
->State
!= Loaded
)
33 /* Acquire the load lock */
34 KeWaitForSingleObject(FsRecLoadSync
,
39 KeEnterCriticalRegion();
41 /* Make sure we're active */
42 if (DeviceExtension
->State
== Pending
)
44 /* Load the FS driver */
45 RtlInitUnicodeString(&DriverName
, DriverServiceName
);
46 Status
= ZwLoadDriver(&DriverName
);
48 /* Loop all the linked recognizer objects */
49 while (DeviceExtension
->State
!= Unloading
)
51 /* Set them to the unload state */
52 DeviceExtension
->State
= Unloading
;
54 /* Go to the next one */
55 DeviceObject
= DeviceExtension
->Alternate
;
56 DeviceExtension
= DeviceObject
->DeviceExtension
;
60 /* Make sure that we haven't already loaded the FS */
61 if (DeviceExtension
->State
!= Loaded
)
63 /* Unregiser us, and set us as loaded */
64 IoUnregisterFileSystem(DeviceObject
);
65 DeviceExtension
->State
= Loaded
;
68 /* Release the lock */
69 KeSetEvent(FsRecLoadSync
, 0, FALSE
);
70 KeLeaveCriticalRegion();
77 DRIVER_DISPATCH FsRecCreate
;
80 FsRecCreate(IN PDEVICE_OBJECT DeviceObject
,
83 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
87 /* Make sure we have a file name */
88 if (IoStack
->FileObject
->FileName
.Length
)
90 /* Fail the request */
91 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
96 Status
= STATUS_SUCCESS
;
99 /* Complete the IRP */
100 Irp
->IoStatus
.Status
= Status
;
101 Irp
->IoStatus
.Information
= FILE_OPENED
;
102 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
106 DRIVER_DISPATCH FsRecClose
;
109 FsRecClose(IN PDEVICE_OBJECT DeviceObject
,
114 /* Just complete the IRP and return success */
115 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
116 return STATUS_SUCCESS
;
119 DRIVER_DISPATCH FsRecFsControl
;
122 FsRecFsControl(IN PDEVICE_OBJECT DeviceObject
,
125 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
129 /* Check the file system type */
130 switch (DeviceExtension
->FsType
)
134 /* Send FAT command */
135 Status
= FsRecVfatFsControl(DeviceObject
, Irp
);
140 /* Send NTFS command */
141 Status
= FsRecNtfsFsControl(DeviceObject
, Irp
);
146 /* Send CDFS command */
147 Status
= FsRecCdfsFsControl(DeviceObject
, Irp
);
152 /* Send UDFS command */
153 Status
= FsRecUdfsFsControl(DeviceObject
, Irp
);
158 /* Send EXT2 command */
159 Status
= FsRecExt2FsControl(DeviceObject
, Irp
);
164 /* Unrecognized FS */
165 Status
= STATUS_INVALID_DEVICE_REQUEST
;
168 /* Complete the IRP */
169 Irp
->IoStatus
.Status
= Status
;
170 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
174 DRIVER_UNLOAD FsRecUnload
;
177 FsRecUnload(IN PDRIVER_OBJECT DriverObject
)
181 /* Loop all driver device objects */
182 while (DriverObject
->DeviceObject
)
184 /* Delete this device */
185 IoDeleteDevice(DriverObject
->DeviceObject
);
189 ExFreePool(FsRecLoadSync
);
194 FsRecRegisterFs(IN PDRIVER_OBJECT DriverObject
,
195 IN PDEVICE_OBJECT ParentObject OPTIONAL
,
196 OUT PDEVICE_OBJECT
*NewDeviceObject OPTIONAL
,
198 IN PCWSTR RecognizerName
,
200 IN DEVICE_TYPE DeviceType
)
202 OBJECT_ATTRIBUTES ObjectAttributes
;
203 IO_STATUS_BLOCK IoStatus
;
204 PDEVICE_EXTENSION DeviceExtension
;
205 UNICODE_STRING DeviceName
;
206 PDEVICE_OBJECT DeviceObject
;
211 if (NewDeviceObject
) *NewDeviceObject
= NULL
;
213 /* Setup the attributes */
214 RtlInitUnicodeString(&DeviceName
, FsName
);
215 InitializeObjectAttributes(&ObjectAttributes
,
217 OBJ_CASE_INSENSITIVE
,
221 /* Open the device */
222 Status
= ZwCreateFile(&FileHandle
,
228 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
233 if (NT_SUCCESS(Status
))
235 /* We suceeded, close the handle */
238 else if (Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
240 /* We failed with anything else then what we want to fail with */
241 Status
= STATUS_SUCCESS
;
244 /* If we succeeded, there's no point in trying this again */
245 if (NT_SUCCESS(Status
)) return STATUS_IMAGE_ALREADY_LOADED
;
247 /* Create recognizer device object */
248 RtlInitUnicodeString(&DeviceName
, RecognizerName
);
249 Status
= IoCreateDevice(DriverObject
,
250 sizeof(DEVICE_EXTENSION
),
256 if (NT_SUCCESS(Status
))
258 /* Get the device extension and set it up */
259 DeviceExtension
= DeviceObject
->DeviceExtension
;
260 DeviceExtension
->FsType
= FsType
;
261 DeviceExtension
->State
= Pending
;
263 /* Do we have a parent? */
267 DeviceExtension
->Alternate
=
268 ((PDEVICE_EXTENSION
)ParentObject
->DeviceExtension
)->Alternate
;
269 ((PDEVICE_EXTENSION
)ParentObject
->DeviceExtension
)->Alternate
=
274 /* Otherwise, we're the only one */
275 DeviceExtension
->Alternate
= DeviceObject
;
278 /* Return the DO if needed */
279 if (NewDeviceObject
) *NewDeviceObject
= DeviceObject
;
281 /* Register the file system */
282 IoRegisterFileSystem(DeviceObject
);
291 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
292 IN PUNICODE_STRING RegistryPath
)
294 ULONG DeviceCount
= 0;
296 PDEVICE_OBJECT UdfsObject
;
299 /* Page the entire driver */
300 MmPageEntireDriver(DriverEntry
);
302 /* Allocate the lock */
303 FsRecLoadSync
= ExAllocatePoolWithTag(NonPagedPool
,
306 if (!FsRecLoadSync
) return STATUS_INSUFFICIENT_RESOURCES
;
309 KeInitializeEvent(FsRecLoadSync
, SynchronizationEvent
, TRUE
);
311 /* Setup the major functions */
312 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = FsRecCreate
;
313 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = FsRecClose
;
314 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = FsRecClose
;
315 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = FsRecFsControl
;
316 DriverObject
->DriverUnload
= FsRecUnload
;
319 Status
= FsRecRegisterFs(DriverObject
,
323 L
"\\FileSystem\\CdfsRecognizer",
325 FILE_DEVICE_CD_ROM_FILE_SYSTEM
);
326 if (NT_SUCCESS(Status
)) DeviceCount
++;
328 /* Register UDFS for CDs */
329 Status
= FsRecRegisterFs(DriverObject
,
333 L
"\\FileSystem\\UdfsCdRomRecognizer",
335 FILE_DEVICE_CD_ROM_FILE_SYSTEM
);
336 if (NT_SUCCESS(Status
)) DeviceCount
++;
338 /* Register UDFS for HDDs */
339 Status
= FsRecRegisterFs(DriverObject
,
343 L
"\\FileSystem\\UdfsDiskRecognizer",
345 FILE_DEVICE_DISK_FILE_SYSTEM
);
346 if (NT_SUCCESS(Status
)) DeviceCount
++;
349 Status
= FsRecRegisterFs(DriverObject
,
353 L
"\\FileSystem\\FatRecognizer",
355 FILE_DEVICE_DISK_FILE_SYSTEM
);
356 if (NT_SUCCESS(Status
)) DeviceCount
++;
359 Status
= FsRecRegisterFs(DriverObject
,
363 L
"\\FileSystem\\NtfsRecognizer",
365 FILE_DEVICE_DISK_FILE_SYSTEM
);
366 if (NT_SUCCESS(Status
)) DeviceCount
++;
369 /*Status = FsRecRegisterFs(DriverObject,
373 L"\\FileSystem\\Ext2Recognizer",
375 FILE_DEVICE_DISK_FILE_SYSTEM);
376 if (NT_SUCCESS(Status)) DeviceCount++;*/
378 /* Return appropriate Status */
379 return (DeviceCount
> 0) ? STATUS_SUCCESS
: STATUS_IMAGE_ALREADY_LOADED
;