Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfs_rec.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS File System Recognizer 00004 * FILE: drivers/filesystems/fs_rec/fs_rec.c 00005 * PURPOSE: Main Driver Entrypoint and FS Registration 00006 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) 00007 * Eric Kohl 00008 */ 00009 00010 /* INCLUDES *****************************************************************/ 00011 00012 #include "fs_rec.h" 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 PKEVENT FsRecLoadSync; 00017 00018 /* FUNCTIONS ****************************************************************/ 00019 00020 NTSTATUS 00021 NTAPI 00022 FsRecLoadFileSystem(IN PDEVICE_OBJECT DeviceObject, 00023 IN PWCHAR DriverServiceName) 00024 { 00025 UNICODE_STRING DriverName; 00026 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 00027 NTSTATUS Status = STATUS_IMAGE_ALREADY_LOADED; 00028 PAGED_CODE(); 00029 00030 /* Make sure we haven't already been called */ 00031 if (DeviceExtension->State != Loaded) 00032 { 00033 /* Acquire the load lock */ 00034 KeWaitForSingleObject(FsRecLoadSync, 00035 Executive, 00036 KernelMode, 00037 FALSE, 00038 NULL); 00039 KeEnterCriticalRegion(); 00040 00041 /* Make sure we're active */ 00042 if (DeviceExtension->State == Pending) 00043 { 00044 /* Load the FS driver */ 00045 RtlInitUnicodeString(&DriverName, DriverServiceName); 00046 Status = ZwLoadDriver(&DriverName); 00047 00048 /* Loop all the linked recognizer objects */ 00049 while (DeviceExtension->State != Unloading) 00050 { 00051 /* Set them to the unload state */ 00052 DeviceExtension->State = Unloading; 00053 00054 /* Go to the next one */ 00055 DeviceObject = DeviceExtension->Alternate; 00056 DeviceExtension = DeviceObject->DeviceExtension; 00057 } 00058 } 00059 00060 /* Make sure that we haven't already loaded the FS */ 00061 if (DeviceExtension->State != Loaded) 00062 { 00063 /* Unregiser us, and set us as loaded */ 00064 IoUnregisterFileSystem(DeviceObject); 00065 DeviceExtension->State = Loaded; 00066 } 00067 00068 /* Release the lock */ 00069 KeSetEvent(FsRecLoadSync, 0, FALSE); 00070 KeLeaveCriticalRegion(); 00071 } 00072 00073 /* Return */ 00074 return Status; 00075 } 00076 00077 DRIVER_DISPATCH FsRecCreate; 00078 NTSTATUS 00079 NTAPI 00080 FsRecCreate(IN PDEVICE_OBJECT DeviceObject, 00081 IN PIRP Irp) 00082 { 00083 PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); 00084 NTSTATUS Status; 00085 PAGED_CODE(); 00086 00087 /* Make sure we have a file name */ 00088 if (IoStack->FileObject->FileName.Length) 00089 { 00090 /* Fail the request */ 00091 Status = STATUS_OBJECT_PATH_NOT_FOUND; 00092 } 00093 else 00094 { 00095 /* Let it through */ 00096 Status = STATUS_SUCCESS; 00097 } 00098 00099 /* Complete the IRP */ 00100 Irp->IoStatus.Status = Status; 00101 Irp->IoStatus.Information = FILE_OPENED; 00102 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00103 return Status; 00104 } 00105 00106 DRIVER_DISPATCH FsRecClose; 00107 NTSTATUS 00108 NTAPI 00109 FsRecClose(IN PDEVICE_OBJECT DeviceObject, 00110 IN PIRP Irp) 00111 { 00112 PAGED_CODE(); 00113 00114 /* Just complete the IRP and return success */ 00115 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00116 return STATUS_SUCCESS; 00117 } 00118 00119 DRIVER_DISPATCH FsRecFsControl; 00120 NTSTATUS 00121 NTAPI 00122 FsRecFsControl(IN PDEVICE_OBJECT DeviceObject, 00123 IN PIRP Irp) 00124 { 00125 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 00126 NTSTATUS Status; 00127 PAGED_CODE(); 00128 00129 /* Check the file system type */ 00130 switch (DeviceExtension->FsType) 00131 { 00132 case FS_TYPE_VFAT: 00133 00134 /* Send FAT command */ 00135 Status = FsRecVfatFsControl(DeviceObject, Irp); 00136 break; 00137 00138 case FS_TYPE_NTFS: 00139 00140 /* Send NTFS command */ 00141 Status = FsRecNtfsFsControl(DeviceObject, Irp); 00142 break; 00143 00144 case FS_TYPE_CDFS: 00145 00146 /* Send CDFS command */ 00147 Status = FsRecCdfsFsControl(DeviceObject, Irp); 00148 break; 00149 00150 case FS_TYPE_UDFS: 00151 00152 /* Send UDFS command */ 00153 Status = FsRecUdfsFsControl(DeviceObject, Irp); 00154 break; 00155 00156 case FS_TYPE_EXT2: 00157 00158 /* Send EXT2 command */ 00159 Status = FsRecExt2FsControl(DeviceObject, Irp); 00160 break; 00161 00162 default: 00163 00164 /* Unrecognized FS */ 00165 Status = STATUS_INVALID_DEVICE_REQUEST; 00166 } 00167 00168 /* Complete the IRP */ 00169 Irp->IoStatus.Status = Status; 00170 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00171 return Status; 00172 } 00173 00174 DRIVER_UNLOAD FsRecUnload; 00175 VOID 00176 NTAPI 00177 FsRecUnload(IN PDRIVER_OBJECT DriverObject) 00178 { 00179 PAGED_CODE(); 00180 00181 /* Loop all driver device objects */ 00182 while (DriverObject->DeviceObject) 00183 { 00184 /* Delete this device */ 00185 IoDeleteDevice(DriverObject->DeviceObject); 00186 } 00187 00188 /* Free the lock */ 00189 ExFreePool(FsRecLoadSync); 00190 } 00191 00192 NTSTATUS 00193 NTAPI 00194 FsRecRegisterFs(IN PDRIVER_OBJECT DriverObject, 00195 IN PDEVICE_OBJECT ParentObject OPTIONAL, 00196 OUT PDEVICE_OBJECT *NewDeviceObject OPTIONAL, 00197 IN PCWSTR FsName, 00198 IN PCWSTR RecognizerName, 00199 IN ULONG FsType, 00200 IN DEVICE_TYPE DeviceType) 00201 { 00202 OBJECT_ATTRIBUTES ObjectAttributes; 00203 IO_STATUS_BLOCK IoStatus; 00204 PDEVICE_EXTENSION DeviceExtension; 00205 UNICODE_STRING DeviceName; 00206 PDEVICE_OBJECT DeviceObject; 00207 HANDLE FileHandle; 00208 NTSTATUS Status; 00209 00210 /* Assume failure */ 00211 if (NewDeviceObject) *NewDeviceObject = NULL; 00212 00213 /* Setup the attributes */ 00214 RtlInitUnicodeString(&DeviceName, FsName); 00215 InitializeObjectAttributes(&ObjectAttributes, 00216 &DeviceName, 00217 OBJ_CASE_INSENSITIVE, 00218 0, 00219 NULL); 00220 00221 /* Open the device */ 00222 Status = ZwCreateFile(&FileHandle, 00223 SYNCHRONIZE, 00224 &ObjectAttributes, 00225 &IoStatus, 00226 NULL, 00227 0, 00228 FILE_SHARE_READ | FILE_SHARE_WRITE, 00229 FILE_OPEN, 00230 0, 00231 NULL, 00232 0); 00233 if (NT_SUCCESS(Status)) 00234 { 00235 /* We suceeded, close the handle */ 00236 ZwClose(FileHandle); 00237 } 00238 else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) 00239 { 00240 /* We failed with anything else then what we want to fail with */ 00241 Status = STATUS_SUCCESS; 00242 } 00243 00244 /* If we succeeded, there's no point in trying this again */ 00245 if (NT_SUCCESS(Status)) return STATUS_IMAGE_ALREADY_LOADED; 00246 00247 /* Create recognizer device object */ 00248 RtlInitUnicodeString(&DeviceName, RecognizerName); 00249 Status = IoCreateDevice(DriverObject, 00250 sizeof(DEVICE_EXTENSION), 00251 &DeviceName, 00252 DeviceType, 00253 0, 00254 FALSE, 00255 &DeviceObject); 00256 if (NT_SUCCESS(Status)) 00257 { 00258 /* Get the device extension and set it up */ 00259 DeviceExtension = DeviceObject->DeviceExtension; 00260 DeviceExtension->FsType = FsType; 00261 DeviceExtension->State = Pending; 00262 00263 /* Do we have a parent? */ 00264 if (ParentObject) 00265 { 00266 /* Link it in */ 00267 DeviceExtension->Alternate = 00268 ((PDEVICE_EXTENSION)ParentObject->DeviceExtension)->Alternate; 00269 ((PDEVICE_EXTENSION)ParentObject->DeviceExtension)->Alternate = 00270 DeviceObject; 00271 } 00272 else 00273 { 00274 /* Otherwise, we're the only one */ 00275 DeviceExtension->Alternate = DeviceObject; 00276 } 00277 00278 /* Return the DO if needed */ 00279 if (NewDeviceObject) *NewDeviceObject = DeviceObject; 00280 00281 /* Register the file system */ 00282 IoRegisterFileSystem(DeviceObject); 00283 } 00284 00285 /* Return Status */ 00286 return Status; 00287 } 00288 00289 NTSTATUS 00290 NTAPI 00291 DriverEntry(IN PDRIVER_OBJECT DriverObject, 00292 IN PUNICODE_STRING RegistryPath) 00293 { 00294 ULONG DeviceCount = 0; 00295 NTSTATUS Status; 00296 PDEVICE_OBJECT UdfsObject; 00297 PAGED_CODE(); 00298 00299 /* Page the entire driver */ 00300 MmPageEntireDriver(DriverEntry); 00301 00302 /* Allocate the lock */ 00303 FsRecLoadSync = ExAllocatePoolWithTag(NonPagedPool, 00304 sizeof(KEVENT), 00305 FSREC_TAG); 00306 if (!FsRecLoadSync) return STATUS_INSUFFICIENT_RESOURCES; 00307 00308 /* Initialize it */ 00309 KeInitializeEvent(FsRecLoadSync, SynchronizationEvent, TRUE); 00310 00311 /* Setup the major functions */ 00312 DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate; 00313 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRecClose; 00314 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecClose; 00315 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl; 00316 DriverObject->DriverUnload = FsRecUnload; 00317 00318 /* Register CDFS */ 00319 Status = FsRecRegisterFs(DriverObject, 00320 NULL, 00321 NULL, 00322 L"\\Cdfs", 00323 L"\\FileSystem\\CdfsRecognizer", 00324 FS_TYPE_CDFS, 00325 FILE_DEVICE_CD_ROM_FILE_SYSTEM); 00326 if (NT_SUCCESS(Status)) DeviceCount++; 00327 00328 /* Register UDFS for CDs */ 00329 Status = FsRecRegisterFs(DriverObject, 00330 NULL, 00331 &UdfsObject, 00332 L"\\UdfsCdRom", 00333 L"\\FileSystem\\UdfsCdRomRecognizer", 00334 FS_TYPE_UDFS, 00335 FILE_DEVICE_CD_ROM_FILE_SYSTEM); 00336 if (NT_SUCCESS(Status)) DeviceCount++; 00337 00338 /* Register UDFS for HDDs */ 00339 Status = FsRecRegisterFs(DriverObject, 00340 UdfsObject, 00341 NULL, 00342 L"\\UdfsDisk", 00343 L"\\FileSystem\\UdfsDiskRecognizer", 00344 FS_TYPE_UDFS, 00345 FILE_DEVICE_DISK_FILE_SYSTEM); 00346 if (NT_SUCCESS(Status)) DeviceCount++; 00347 00348 /* Register FAT */ 00349 Status = FsRecRegisterFs(DriverObject, 00350 NULL, 00351 NULL, 00352 L"\\Fat", 00353 L"\\FileSystem\\FatRecognizer", 00354 FS_TYPE_VFAT, 00355 FILE_DEVICE_DISK_FILE_SYSTEM); 00356 if (NT_SUCCESS(Status)) DeviceCount++; 00357 00358 /* Register NTFS */ 00359 Status = FsRecRegisterFs(DriverObject, 00360 NULL, 00361 NULL, 00362 L"\\Ntfs", 00363 L"\\FileSystem\\NtfsRecognizer", 00364 FS_TYPE_NTFS, 00365 FILE_DEVICE_DISK_FILE_SYSTEM); 00366 if (NT_SUCCESS(Status)) DeviceCount++; 00367 00368 /* Register EXT2 */ 00369 /*Status = FsRecRegisterFs(DriverObject, 00370 NULL, 00371 NULL, 00372 L"\\Ext2", 00373 L"\\FileSystem\\Ext2Recognizer", 00374 FS_TYPE_EXT2, 00375 FILE_DEVICE_DISK_FILE_SYSTEM); 00376 if (NT_SUCCESS(Status)) DeviceCount++;*/ 00377 00378 /* Return appropriate Status */ 00379 return (DeviceCount > 0) ? STATUS_SUCCESS : STATUS_IMAGE_ALREADY_LOADED; 00380 } 00381 00382 /* EOF */ Generated on Sun May 27 2012 04:27:47 for ReactOS by
1.7.6.1
|