[USBOHCI_NEW][USBUHCI_NEW] Avoid unnecessary/incorrect status defines.
[reactos.git] / drivers / filesystems / fs_rec / fs_rec.c
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 */