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 UNREFERENCED_PARAMETER(DeviceObject
);
89 /* Make sure we have a file name */
90 if (IoStack
->FileObject
->FileName
.Length
)
92 /* Fail the request */
93 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
98 Status
= STATUS_SUCCESS
;
101 /* Complete the IRP */
102 Irp
->IoStatus
.Status
= Status
;
103 Irp
->IoStatus
.Information
= FILE_OPENED
;
104 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
108 DRIVER_DISPATCH FsRecClose
;
111 FsRecClose(IN PDEVICE_OBJECT DeviceObject
,
116 UNREFERENCED_PARAMETER(DeviceObject
);
118 /* Just complete the IRP and return success */
119 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
120 return STATUS_SUCCESS
;
123 DRIVER_DISPATCH FsRecFsControl
;
126 FsRecFsControl(IN PDEVICE_OBJECT DeviceObject
,
129 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
133 /* Check the file system type */
134 switch (DeviceExtension
->FsType
)
138 /* Send FAT command */
139 Status
= FsRecVfatFsControl(DeviceObject
, Irp
);
144 /* Send NTFS command */
145 Status
= FsRecNtfsFsControl(DeviceObject
, Irp
);
150 /* Send CDFS command */
151 Status
= FsRecCdfsFsControl(DeviceObject
, Irp
);
156 /* Send UDFS command */
157 Status
= FsRecUdfsFsControl(DeviceObject
, Irp
);
162 /* Send EXT2 command */
163 Status
= FsRecExt2FsControl(DeviceObject
, Irp
);
168 /* Unrecognized FS */
169 Status
= STATUS_INVALID_DEVICE_REQUEST
;
172 /* Complete the IRP */
173 Irp
->IoStatus
.Status
= Status
;
174 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
178 DRIVER_UNLOAD FsRecUnload
;
181 FsRecUnload(IN PDRIVER_OBJECT DriverObject
)
185 /* Loop all driver device objects */
186 while (DriverObject
->DeviceObject
)
188 /* Delete this device */
189 IoDeleteDevice(DriverObject
->DeviceObject
);
193 ExFreePool(FsRecLoadSync
);
198 FsRecRegisterFs(IN PDRIVER_OBJECT DriverObject
,
199 IN PDEVICE_OBJECT ParentObject OPTIONAL
,
200 OUT PDEVICE_OBJECT
*NewDeviceObject OPTIONAL
,
202 IN PCWSTR RecognizerName
,
204 IN DEVICE_TYPE DeviceType
)
206 OBJECT_ATTRIBUTES ObjectAttributes
;
207 IO_STATUS_BLOCK IoStatus
;
208 PDEVICE_EXTENSION DeviceExtension
;
209 UNICODE_STRING DeviceName
;
210 PDEVICE_OBJECT DeviceObject
;
215 if (NewDeviceObject
) *NewDeviceObject
= NULL
;
217 /* Setup the attributes */
218 RtlInitUnicodeString(&DeviceName
, FsName
);
219 InitializeObjectAttributes(&ObjectAttributes
,
221 OBJ_CASE_INSENSITIVE
,
225 /* Open the device */
226 Status
= ZwCreateFile(&FileHandle
,
232 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
237 if (NT_SUCCESS(Status
))
239 /* We suceeded, close the handle */
242 else if (Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
244 /* We failed with anything else then what we want to fail with */
245 Status
= STATUS_SUCCESS
;
248 /* If we succeeded, there's no point in trying this again */
249 if (NT_SUCCESS(Status
)) return STATUS_IMAGE_ALREADY_LOADED
;
251 /* Create recognizer device object */
252 RtlInitUnicodeString(&DeviceName
, RecognizerName
);
253 Status
= IoCreateDevice(DriverObject
,
254 sizeof(DEVICE_EXTENSION
),
260 if (NT_SUCCESS(Status
))
262 /* Get the device extension and set it up */
263 DeviceExtension
= DeviceObject
->DeviceExtension
;
264 DeviceExtension
->FsType
= FsType
;
265 DeviceExtension
->State
= Pending
;
267 /* Do we have a parent? */
271 DeviceExtension
->Alternate
=
272 ((PDEVICE_EXTENSION
)ParentObject
->DeviceExtension
)->Alternate
;
273 ((PDEVICE_EXTENSION
)ParentObject
->DeviceExtension
)->Alternate
=
278 /* Otherwise, we're the only one */
279 DeviceExtension
->Alternate
= DeviceObject
;
282 /* Return the DO if needed */
283 if (NewDeviceObject
) *NewDeviceObject
= DeviceObject
;
285 /* Register the file system */
286 IoRegisterFileSystem(DeviceObject
);
295 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
296 IN PUNICODE_STRING RegistryPath
)
298 ULONG DeviceCount
= 0;
300 PDEVICE_OBJECT UdfsObject
;
303 UNREFERENCED_PARAMETER(RegistryPath
);
305 /* Page the entire driver */
306 MmPageEntireDriver(DriverEntry
);
308 /* Allocate the lock */
309 FsRecLoadSync
= ExAllocatePoolWithTag(NonPagedPool
,
312 if (!FsRecLoadSync
) return STATUS_INSUFFICIENT_RESOURCES
;
315 KeInitializeEvent(FsRecLoadSync
, SynchronizationEvent
, TRUE
);
317 /* Setup the major functions */
318 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = FsRecCreate
;
319 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = FsRecClose
;
320 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = FsRecClose
;
321 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = FsRecFsControl
;
322 DriverObject
->DriverUnload
= FsRecUnload
;
325 Status
= FsRecRegisterFs(DriverObject
,
329 L
"\\FileSystem\\CdfsRecognizer",
331 FILE_DEVICE_CD_ROM_FILE_SYSTEM
);
332 if (NT_SUCCESS(Status
)) DeviceCount
++;
334 /* Register UDFS for CDs */
335 Status
= FsRecRegisterFs(DriverObject
,
339 L
"\\FileSystem\\UdfsCdRomRecognizer",
341 FILE_DEVICE_CD_ROM_FILE_SYSTEM
);
342 if (NT_SUCCESS(Status
)) DeviceCount
++;
344 /* Register UDFS for HDDs */
345 Status
= FsRecRegisterFs(DriverObject
,
349 L
"\\FileSystem\\UdfsDiskRecognizer",
351 FILE_DEVICE_DISK_FILE_SYSTEM
);
352 if (NT_SUCCESS(Status
)) DeviceCount
++;
355 Status
= FsRecRegisterFs(DriverObject
,
359 L
"\\FileSystem\\FatRecognizer",
361 FILE_DEVICE_DISK_FILE_SYSTEM
);
362 if (NT_SUCCESS(Status
)) DeviceCount
++;
365 Status
= FsRecRegisterFs(DriverObject
,
369 L
"\\FileSystem\\NtfsRecognizer",
371 FILE_DEVICE_DISK_FILE_SYSTEM
);
372 if (NT_SUCCESS(Status
)) DeviceCount
++;
375 /*Status = FsRecRegisterFs(DriverObject,
379 L"\\FileSystem\\Ext2Recognizer",
381 FILE_DEVICE_DISK_FILE_SYSTEM);
382 if (NT_SUCCESS(Status)) DeviceCount++;*/
384 /* Return appropriate Status */
385 return (DeviceCount
> 0) ? STATUS_SUCCESS
: STATUS_IMAGE_ALREADY_LOADED
;