Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

fs_rec.c File Reference

#include "fs_rec.h"

Go to the source code of this file.

Defines

#define Dbg   (FSREC_DEBUG_LEVEL_FSREC)
#define RoundUp(x, y)   ( ((x + (y-1)) / y) * y )

Functions

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
NTSTATUS FsRecCleanupClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
NTSTATUS FsRecCreate (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
NTSTATUS FsRecCreateAndRegisterDO (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT HeadRecognizer OPTIONAL, OUT PDEVICE_OBJECT *NewRecognizer OPTIONAL, IN PWCHAR RecFileSystem, IN PWCHAR FileSystemName, IN FILE_SYSTEM_TYPE FileSystemType, IN DEVICE_TYPE DeviceType)
NTSTATUS FsRecFsControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
VOID FsRecUnload (IN PDRIVER_OBJECT DriverObject)
NTSTATUS FsRecLoadFileSystem (IN PDEVICE_OBJECT DeviceObject, IN PWCHAR DriverServiceName)
BOOLEAN FsRecGetDeviceSectors (IN PDEVICE_OBJECT DeviceObject, IN ULONG BytesPerSector, OUT PLARGE_INTEGER NumberOfSectors)
BOOLEAN FsRecGetDeviceSectorSize (IN PDEVICE_OBJECT DeviceObject, OUT PULONG BytesPerSector)
BOOLEAN FsRecReadBlock (IN PDEVICE_OBJECT DeviceObject, IN PLARGE_INTEGER ByteOffset, IN ULONG MinimumBytes, IN ULONG BytesPerSector, OUT PVOID *Buffer, OUT PBOOLEAN IsDeviceFailure OPTIONAL)

Variables

PKEVENT FsRecLoadSync


Define Documentation

#define Dbg   (FSREC_DEBUG_LEVEL_FSREC)
 

Definition at line 33 of file fs_rec.c.

#define RoundUp x,
 )     ( ((x + (y-1)) / y) * y )
 

Referenced by FsRecReadBlock().


Function Documentation

NTSTATUS DriverEntry IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPath
 

Definition at line 67 of file fs_rec.c.

Referenced by CmGetSystemDriverList(), CmpAddDriverToList(), DriverEntry(), IopGetLoadedDriverInfo(), IopInitializeBuiltinDriver(), IopWriteDriverList(), and IopWriteTriageDump().

00074 : 00075 00076 This routine is invoked once when the driver is loaded to allow the driver 00077 to initialize itself. The initialization for the driver consists of simply 00078 creating a device object for each type of file system recognized by this 00079 driver, and then registering each as active file systems. 00080 00081 Arguments: 00082 00083 DriverObject - Pointer to the driver object for this driver. 00084 00085 RegistryPath - Pointer to the registry service node for this driver. 00086 00087 Return Value: 00088 00089 The function value is the final status of the initialization for the driver. 00090 00091 --*/ 00092 00093 { 00094 PDEVICE_OBJECT UdfsMainRecognizerDeviceObject; 00095 NTSTATUS status; 00096 ULONG count = 0; 00097 00098 PAGED_CODE(); 00099 00100 // 00101 // Mark the entire driver as pagable. 00102 // 00103 00104 MmPageEntireDriver ((PVOID)DriverEntry); 00105 00106 // 00107 // Begin by initializing the driver object so that it the driver is 00108 // prepared to provide services. 00109 // 00110 00111 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl; 00112 DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate; 00113 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecCleanupClose; 00114 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRecCleanupClose; 00115 DriverObject->DriverUnload = FsRecUnload; 00116 00117 FsRecLoadSync = ExAllocatePoolWithTag( NonPagedPool, sizeof(KEVENT), FSREC_POOL_TAG ); 00118 00119 if (FsRecLoadSync == NULL) { 00120 00121 return STATUS_INSUFFICIENT_RESOURCES; 00122 } 00123 00124 KeInitializeEvent( FsRecLoadSync, SynchronizationEvent, TRUE ); 00125 00126 // 00127 // Create and initialize each of the file system driver type device 00128 // objects. 00129 // 00130 00131 status = FsRecCreateAndRegisterDO( DriverObject, 00132 NULL, 00133 NULL, 00134 L"\\Cdfs", 00135 L"\\FileSystem\\CdfsRecognizer", 00136 CdfsFileSystem, 00137 FILE_DEVICE_CD_ROM_FILE_SYSTEM ); 00138 if (NT_SUCCESS( status )) { 00139 count++; 00140 } 00141 00142 status = FsRecCreateAndRegisterDO( DriverObject, 00143 NULL, 00144 &UdfsMainRecognizerDeviceObject, 00145 L"\\UdfsCdRom", 00146 L"\\FileSystem\\UdfsCdRomRecognizer", 00147 UdfsFileSystem, 00148 FILE_DEVICE_CD_ROM_FILE_SYSTEM ); 00149 if (NT_SUCCESS( status )) { 00150 count++; 00151 } 00152 00153 status = FsRecCreateAndRegisterDO( DriverObject, 00154 UdfsMainRecognizerDeviceObject, 00155 NULL, 00156 L"\\UdfsDisk", 00157 L"\\FileSystem\\UdfsDiskRecognizer", 00158 UdfsFileSystem, 00159 FILE_DEVICE_DISK_FILE_SYSTEM ); 00160 if (NT_SUCCESS( status )) { 00161 count++; 00162 } 00163 00164 status = FsRecCreateAndRegisterDO( DriverObject, 00165 NULL, 00166 NULL, 00167 L"\\Fat", 00168 L"\\FileSystem\\FatRecognizer", 00169 FatFileSystem, 00170 FILE_DEVICE_DISK_FILE_SYSTEM ); 00171 if (NT_SUCCESS( status )) { 00172 count++; 00173 } 00174 00175 status = FsRecCreateAndRegisterDO( DriverObject, 00176 NULL, 00177 NULL, 00178 L"\\Ntfs", 00179 L"\\FileSystem\\NtfsRecognizer", 00180 NtfsFileSystem, 00181 FILE_DEVICE_DISK_FILE_SYSTEM ); 00182 if (NT_SUCCESS( status )) { 00183 count++; 00184 } 00185 00186 if (count) { 00187 return STATUS_SUCCESS; 00188 } else { 00189 return STATUS_IMAGE_ALREADY_LOADED; 00190 } 00191 }

NTSTATUS FsRecCleanupClose IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp
 

Definition at line 195 of file fs_rec.c.

References IO_NO_INCREMENT, IoCompleteRequest, Irp, and PAGED_CODE.

Referenced by DriverEntry().

00202 : 00203 00204 This routine is invoked when someone attempts to cleanup or close one of 00205 the system recognizer's registered device objects. 00206 00207 Arguments: 00208 00209 DeviceObject - Pointer to the device object being closed. 00210 00211 Irp - Pointer to the cleanup/close IRP. 00212 00213 Return Value: 00214 00215 The final function value is STATUS_SUCCESS. 00216 00217 --*/ 00218 00219 { 00220 PAGED_CODE(); 00221 00222 // 00223 // Simply complete the request successfully (note that IoStatus.Status in 00224 // Irp is already initialized to STATUS_SUCCESS). 00225 // 00226 00227 IoCompleteRequest( Irp, IO_NO_INCREMENT ); 00228 return STATUS_SUCCESS; 00229 }

NTSTATUS FsRecCreate IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp
 

Definition at line 233 of file fs_rec.c.

References _FILE_OBJECT::FileName, _IO_STACK_LOCATION::FileObject, IO_NO_INCREMENT, IoCompleteRequest, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, NTSTATUS(), and PAGED_CODE.

Referenced by DriverEntry().

00240 : 00241 00242 This routine is invoked when someone attempts to open one of the file 00243 system recognizer's registered device objects. 00244 00245 Arguments: 00246 00247 DeviceObject - Pointer to the device object being opened. 00248 00249 Irp - Pointer to the create IRP. 00250 00251 Return Value: 00252 00253 The final function value indicates whether or not the open was successful. 00254 00255 --*/ 00256 00257 { 00258 PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp ); 00259 NTSTATUS status; 00260 00261 PAGED_CODE(); 00262 00263 // 00264 // Simply ensure that the name of the "file" being opened is NULL, and 00265 // complete the request accordingly. 00266 // 00267 00268 if (irpSp->FileObject->FileName.Length) { 00269 status = STATUS_OBJECT_PATH_NOT_FOUND; 00270 } else { 00271 status = STATUS_SUCCESS; 00272 } 00273 00274 Irp->IoStatus.Status = status; 00275 Irp->IoStatus.Information = FILE_OPENED; 00276 IoCompleteRequest( Irp, IO_NO_INCREMENT ); 00277 return status; 00278 }

NTSTATUS FsRecCreateAndRegisterDO IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT HeadRecognizer  OPTIONAL,
OUT PDEVICE_OBJECT *NewRecognizer  OPTIONAL,
IN PWCHAR  RecFileSystem,
IN PWCHAR  FileSystemName,
IN FILE_SYSTEM_TYPE  FileSystemType,
IN DEVICE_TYPE  DeviceType
 

Definition at line 282 of file fs_rec.c.

References Active, _DEVICE_EXTENSION::CoRecognizer, _DEVICE_OBJECT::DeviceExtension, _DEVICE_OBJECT::DeviceObjectExtension, FALSE, FILE_SYSTEM_TYPE, _DEVICE_EXTENSION::FileSystemType, IoCreateDevice(), IoRegisterFileSystem(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlInitUnicodeString(), _DEVICE_EXTENSION::State, and ZwCreateFile().

Referenced by DriverEntry().

00294 : 00295 00296 This routine creates a device object for the specified file system type and 00297 registers it as an active file system. 00298 00299 Arguments: 00300 00301 DriverObject - Pointer to the driver object for this driver. 00302 00303 HeadRecognizer - Optionally supplies a pre-existing recognizer that the 00304 newly created DO should be jointly serialized and unregistered with. 00305 This is useful if a given filesystem exists on multiple device types 00306 and thus requires multiple recognizers. 00307 00308 NewDeviceObject - Receives the created DO on success.. 00309 00310 RecFileSystem - Name of the file system to be recognized. 00311 00312 FileSystemName - Name of file system device object to be registered. 00313 00314 FileSystemType - Type of this file system recognizer device object. 00315 00316 DeviceType - Type of media this file system recognizer device object will inspect. 00317 00318 Return Value: 00319 00320 The final function value indicates whether or not the device object was 00321 successfully created and registered. 00322 00323 --*/ 00324 00325 { 00326 PDEVICE_OBJECT deviceObject; 00327 NTSTATUS status; 00328 UNICODE_STRING nameString; 00329 OBJECT_ATTRIBUTES objectAttributes; 00330 HANDLE fsHandle; 00331 IO_STATUS_BLOCK ioStatus; 00332 PDEVICE_EXTENSION deviceExtension; 00333 00334 PAGED_CODE(); 00335 00336 if (NewRecognizer) { 00337 00338 *NewRecognizer = NULL; 00339 } 00340 00341 // 00342 // Begin by attempting to open the file system driver's device object. If 00343 // it works, then the file system is already loaded, so don't load this 00344 // driver. Otherwise, this mini-driver is the one that should be loaded. 00345 // 00346 00347 RtlInitUnicodeString( &nameString, RecFileSystem ); 00348 InitializeObjectAttributes( &objectAttributes, 00349 &nameString, 00350 OBJ_CASE_INSENSITIVE, 00351 (HANDLE) NULL, 00352 (PSECURITY_DESCRIPTOR) NULL ); 00353 00354 status = ZwCreateFile( &fsHandle, 00355 SYNCHRONIZE, 00356 &objectAttributes, 00357 &ioStatus, 00358 (PLARGE_INTEGER) NULL, 00359 0, 00360 FILE_SHARE_READ | FILE_SHARE_WRITE, 00361 FILE_OPEN, 00362 0, 00363 (PVOID) NULL, 00364 0 ); 00365 00366 if (NT_SUCCESS( status )) { 00367 ZwClose( fsHandle ); 00368 } else if (status != STATUS_OBJECT_NAME_NOT_FOUND) { 00369 status = STATUS_SUCCESS; 00370 } 00371 00372 if (NT_SUCCESS( status )) { 00373 return STATUS_IMAGE_ALREADY_LOADED; 00374 } 00375 00376 // 00377 // Attempt to create a device object for this driver. This device object 00378 // will be used to represent the driver as an active file system in the 00379 // system. 00380 // 00381 00382 RtlInitUnicodeString( &nameString, FileSystemName ); 00383 00384 status = IoCreateDevice( DriverObject, 00385 sizeof( DEVICE_EXTENSION ), 00386 &nameString, 00387 DeviceType, 00388 0, 00389 FALSE, 00390 &deviceObject ); 00391 if (!NT_SUCCESS( status )) { 00392 return status; 00393 } 00394 00395 // 00396 // Initialize the device extension for this device object. 00397 // 00398 00399 deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; 00400 deviceExtension->FileSystemType = FileSystemType; 00401 deviceExtension->State = Active; 00402 00403 // 00404 // Is this a filesystem being jointly recognized by recognizers for 00405 // different device types? 00406 // 00407 00408 if (HeadRecognizer) { 00409 00410 // 00411 // Link into the list. 00412 // 00413 00414 deviceExtension->CoRecognizer = ((PDEVICE_EXTENSION)HeadRecognizer->DeviceExtension)->CoRecognizer; 00415 ((PDEVICE_EXTENSION)HeadRecognizer->DeviceExtension)->CoRecognizer = deviceObject; 00416 00417 } else { 00418 00419 // 00420 // Initialize the list of codependant recognizer objects. 00421 // 00422 00423 deviceExtension->CoRecognizer = deviceObject; 00424 } 00425 00426 #if _PNP_POWER_ 00427 deviceObject->DeviceObjectExtension->PowerControlNeeded = FALSE; 00428 #endif 00429 00430 // 00431 // Finally, register this driver as an active, loaded file system and 00432 // return to the caller. 00433 // 00434 00435 if (NewRecognizer) { 00436 00437 *NewRecognizer = deviceObject; 00438 } 00439 00440 IoRegisterFileSystem( deviceObject ); 00441 return STATUS_SUCCESS; 00442 }

NTSTATUS FsRecFsControl IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp
 

Definition at line 446 of file fs_rec.c.

References Active, CdfsFileSystem, CdfsRecFsControl(), FatFileSystem, FatRecFsControl(), _DEVICE_EXTENSION::FileSystemType, IO_NO_INCREMENT, IoCompleteRequest, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, IRP_MN_MOUNT_VOLUME, _IO_STACK_LOCATION::MinorFunction, NtfsFileSystem, NtfsRecFsControl(), NTSTATUS(), PAGED_CODE, _DEVICE_EXTENSION::State, Transparent, UdfsFileSystem, and UdfsRecFsControl().

Referenced by DriverEntry().

00453 : 00454 00455 This function performs the mount and driver reload functions for this mini- 00456 file system recognizer driver. 00457 00458 Arguments: 00459 00460 DeviceObject - Pointer to this driver's device object. 00461 00462 Irp - Pointer to the I/O Request Packet (IRP) representing the function to 00463 be performed. 00464 00465 Return Value: 00466 00467 The function value is the final status of the operation. 00468 00469 00470 --*/ 00471 00472 { 00473 PDEVICE_EXTENSION deviceExtension; 00474 PIO_STACK_LOCATION irpSp; 00475 NTSTATUS status; 00476 00477 PAGED_CODE(); 00478 00479 // 00480 // Simply vector to the appropriate FS control function given the type 00481 // of file system being interrogated. 00482 // 00483 00484 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00485 irpSp = IoGetCurrentIrpStackLocation( Irp ); 00486 00487 // 00488 // Handle the inactive recognizer states directly. 00489 // 00490 00491 if (deviceExtension->State != Active && irpSp->MinorFunction == IRP_MN_MOUNT_VOLUME) { 00492 00493 if (deviceExtension->State == Transparent) { 00494 00495 status = STATUS_UNRECOGNIZED_VOLUME; 00496 00497 } else { 00498 00499 status = STATUS_FS_DRIVER_REQUIRED; 00500 } 00501 00502 Irp->IoStatus.Status = status; 00503 IoCompleteRequest( Irp, IO_NO_INCREMENT ); 00504 return status; 00505 } 00506 00507 switch ( deviceExtension->FileSystemType ) { 00508 00509 case FatFileSystem: 00510 00511 status = FatRecFsControl( DeviceObject, Irp ); 00512 break; 00513 00514 case NtfsFileSystem: 00515 00516 status = NtfsRecFsControl( DeviceObject, Irp ); 00517 break; 00518 00519 case CdfsFileSystem: 00520 00521 status = CdfsRecFsControl( DeviceObject, Irp ); 00522 break; 00523 00524 case UdfsFileSystem: 00525 00526 status = UdfsRecFsControl( DeviceObject, Irp ); 00527 break; 00528 00529 default: 00530 00531 status = STATUS_INVALID_DEVICE_REQUEST; 00532 } 00533 00534 return status; 00535 }

BOOLEAN FsRecGetDeviceSectors IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  BytesPerSector,
OUT PLARGE_INTEGER  NumberOfSectors
 

Definition at line 703 of file fs_rec.c.

References Executive, FALSE, IoBuildDeviceIoControlRequest(), IoCallDriver, IoGetNextIrpStackLocation, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlExtendedLargeIntegerDivide(), SetFlag, SL_OVERRIDE_VERIFY_VOLUME, TRUE, and VOID().

Referenced by NtfsRecFsControl().

00711 : 00712 00713 This routine returns information about the partition represented by the 00714 device object. 00715 00716 Arguments: 00717 00718 DeviceObject - Pointer to the device object from which to read. 00719 00720 BytesPerSector - The number of bytes per sector for the device being read. 00721 00722 NumberOfSectors - Variable to receive the number of sectors for this 00723 partition. 00724 00725 Return Value: 00726 00727 The function value is TRUE if the information was found, otherwise FALSE. 00728 00729 --*/ 00730 00731 { 00732 PARTITION_INFORMATION partitionInfo; 00733 IO_STATUS_BLOCK ioStatus; 00734 KEVENT event; 00735 PIRP irp; 00736 NTSTATUS status; 00737 ULONG remainder; 00738 00739 PAGED_CODE(); 00740 00741 // 00742 // We only do this for disks right now. This is likely to change when we 00743 // have to recognize CDUDF media. 00744 // 00745 00746 if (DeviceObject->DeviceType != FILE_DEVICE_DISK) { 00747 00748 return FALSE; 00749 } 00750 00751 // 00752 // Get the number of sectors on this partition. 00753 // 00754 00755 KeInitializeEvent( &event, SynchronizationEvent, FALSE ); 00756 00757 irp = IoBuildDeviceIoControlRequest( IOCTL_DISK_GET_PARTITION_INFO, 00758 DeviceObject, 00759 (PVOID) NULL, 00760 0, 00761 &partitionInfo, 00762 sizeof( partitionInfo ), 00763 FALSE, 00764 &event, 00765 &ioStatus ); 00766 if (!irp) { 00767 return FALSE; 00768 } 00769 00770 // 00771 // Override verify logic - we don't care. The fact we're in the picture means 00772 // someone is trying to mount new/changed media in the first place. 00773 // 00774 00775 SetFlag( IoGetNextIrpStackLocation( irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME ); 00776 00777 status = IoCallDriver( DeviceObject, irp ); 00778 if (status == STATUS_PENDING) { 00779 (VOID) KeWaitForSingleObject( &event, 00780 Executive, 00781 KernelMode, 00782 FALSE, 00783 (PLARGE_INTEGER) NULL ); 00784 status = ioStatus.Status; 00785 } 00786 00787 if (!NT_SUCCESS( status )) { 00788 return FALSE; 00789 } 00790 00791 *NumberOfSectors = RtlExtendedLargeIntegerDivide( partitionInfo.PartitionLength, 00792 BytesPerSector, 00793 &remainder ); 00794 00795 return TRUE; 00796 }

BOOLEAN FsRecGetDeviceSectorSize IN PDEVICE_OBJECT  DeviceObject,
OUT PULONG  BytesPerSector
 

Definition at line 800 of file fs_rec.c.

References Executive, FALSE, IoBuildDeviceIoControlRequest(), IoCallDriver, IoGetNextIrpStackLocation, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, SetFlag, SL_OVERRIDE_VERIFY_VOLUME, TRUE, and VOID().

Referenced by FatRecFsControl(), NtfsRecFsControl(), and UdfsRecFsControl().

00807 : 00808 00809 This routine returns the sector size of the underlying device. 00810 00811 Arguments: 00812 00813 DeviceObject - Pointer to the device object from which to read. 00814 00815 BytesPerSector - Variable to receive the number of bytes per sector for the 00816 device being read. 00817 00818 Return Value: 00819 00820 The function value is TRUE if the information was found, otherwise FALSE. 00821 00822 --*/ 00823 00824 { 00825 DISK_GEOMETRY diskGeometry; 00826 IO_STATUS_BLOCK ioStatus; 00827 KEVENT event; 00828 PIRP irp; 00829 NTSTATUS status; 00830 ULONG ControlCode; 00831 00832 PAGED_CODE(); 00833 00834 // 00835 // Figure out what kind of device we have so we can use the right IOCTL. 00836 // 00837 00838 switch (DeviceObject->DeviceType) { 00839 case FILE_DEVICE_CD_ROM: 00840 ControlCode = IOCTL_CDROM_GET_DRIVE_GEOMETRY; 00841 break; 00842 00843 case FILE_DEVICE_DISK: 00844 ControlCode = IOCTL_DISK_GET_DRIVE_GEOMETRY; 00845 break; 00846 00847 default: 00848 return FALSE; 00849 } 00850 00851 KeInitializeEvent( &event, SynchronizationEvent, FALSE ); 00852 irp = IoBuildDeviceIoControlRequest( ControlCode, 00853 DeviceObject, 00854 (PVOID) NULL, 00855 0, 00856 &diskGeometry, 00857 sizeof( diskGeometry ), 00858 FALSE, 00859 &event, 00860 &ioStatus ); 00861 00862 if (!irp) { 00863 return FALSE; 00864 } 00865 00866 // 00867 // Override verify logic - we don't care. The fact we're in the picture means 00868 // someone is trying to mount new/changed media in the first place. 00869 // 00870 00871 SetFlag( IoGetNextIrpStackLocation( irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME ); 00872 00873 status = IoCallDriver( DeviceObject, irp ); 00874 if (status == STATUS_PENDING) { 00875 (VOID) KeWaitForSingleObject( &event, 00876 Executive, 00877 KernelMode, 00878 FALSE, 00879 (PLARGE_INTEGER) NULL ); 00880 status = ioStatus.Status; 00881 } 00882 00883 if (!NT_SUCCESS( status )) { 00884 return FALSE; 00885 } 00886 00887 // 00888 // Ensure that the drive actually knows how many bytes there are per 00889 // sector. Floppy drives do not know if the media is unformatted. 00890 // 00891 00892 if (!diskGeometry.BytesPerSector) { 00893 return FALSE; 00894 } 00895 00896 // 00897 // Store the return values for the caller. 00898 // 00899 00900 *BytesPerSector = diskGeometry.BytesPerSector; 00901 00902 return TRUE; 00903 }

NTSTATUS FsRecLoadFileSystem IN PDEVICE_OBJECT  DeviceObject,
IN PWCHAR  DriverServiceName
 

Definition at line 579 of file fs_rec.c.

References Active, _DEVICE_EXTENSION::CoRecognizer, Executive, FALSE, FastUnload, FsRecLoadSync, IoUnregisterFileSystem(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KernelMode, KeSetEvent(), KeWaitForSingleObject(), NTSTATUS(), NULL, PAGED_CODE, RtlInitUnicodeString(), _DEVICE_EXTENSION::State, Transparent, and ZwLoadDriver().

Referenced by CdfsRecFsControl(), FatRecFsControl(), NtfsRecFsControl(), and UdfsRecFsControl().

00587 : 00588 00589 This routine performs the common work of loading a filesystem on behalf 00590 of one of our recognizers. 00591 00592 Arguments: 00593 00594 DeviceObject - Pointer to the device object for the recognizer. 00595 00596 DriverServiceName - Specifies the name of the node in the registry 00597 associated with the driver to be loaded. 00598 00599 Return Value: 00600 00601 NTSTATUS. The recognizer will be set into a transparent mode on return. 00602 00603 --*/ 00604 00605 { 00606 UNICODE_STRING driverName; 00607 PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00608 NTSTATUS status = STATUS_IMAGE_ALREADY_LOADED; 00609 00610 PAGED_CODE(); 00611 00612 // 00613 // Quickly check if the recognizer has already fired. 00614 // 00615 00616 if (deviceExtension->State != Transparent) { 00617 00618 // 00619 // Serialize all threads trying to load this filesystem. 00620 // 00621 // We need to do this for several reasons. With the new behavior in 00622 // IoRegisterFileSystem, we do not know ahead of time whether the 00623 // filesystem has been loaded ahead or behind this recognizer in the 00624 // scan queue. This means that we cannot make this recognizer transparent 00625 // before the real filesystem has become registered, or else if the 00626 // filesystem loads behind us we may let threads go through that will 00627 // not find it in that window of time. 00628 // 00629 // The reason this is possible is that NtLoadDriver does not guarantee 00630 // that if it returns STATUS_IMAGE_ALREADY_LOADED, that the driver in 00631 // question has actually initialized itself, which *is* guaranteed if 00632 // it returns STATUS_SUCCESS. We have to keep these threads bottled 00633 // up until they can rescan with the promise that what they need is there. 00634 // 00635 // As a bonus, we can now guarantee that the recognizer goes away in 00636 // all cases, not just when the driver successfully loads itself. 00637 // 00638 00639 KeWaitForSingleObject( FsRecLoadSync, 00640 Executive, 00641 KernelMode, 00642 FALSE, 00643 NULL ); 00644 KeEnterCriticalRegion(); 00645 00646 // 00647 // Attempt the filesystem load precisely once for all recognizers 00648 // of a given filesystem. 00649 // 00650 00651 if (deviceExtension->State == Active) { 00652 00653 // 00654 // For bonus points, in the future we may want to log an event 00655 // on failure. 00656 // 00657 00658 RtlInitUnicodeString( &driverName, DriverServiceName ); 00659 status = ZwLoadDriver( &driverName ); 00660 00661 // 00662 // Now walk all codependant recognizers and instruct them to go 00663 // into the fast unload state. Since IO only expects the fsDO 00664 // it is asking to load a filesystem to to unregister itself, if 00665 // we unregistered all of the co-recognizers they would dangle. 00666 // Unfortunately, this means that fsrec may wind up hanging around 00667 // quite a bit longer than strictly neccesary. 00668 // 00669 // Note: we come right back to the original DeviceObject at the 00670 // end of this loop (important). It is also very important that 00671 // we only did this once since after we release the mutex the co- 00672 // recognizers may begin going away in any order. 00673 // 00674 00675 while (deviceExtension->State != FastUnload) { 00676 00677 deviceExtension->State = FastUnload; 00678 00679 DeviceObject = deviceExtension->CoRecognizer; 00680 deviceExtension = DeviceObject->DeviceExtension; 00681 } 00682 } 00683 00684 // 00685 // Unregister this recognizer precisely once. 00686 // 00687 00688 if (deviceExtension->State != Transparent) { 00689 00690 IoUnregisterFileSystem( DeviceObject ); 00691 deviceExtension->State = Transparent; 00692 } 00693 00694 KeSetEvent( FsRecLoadSync, 0, FALSE ); 00695 KeLeaveCriticalRegion(); 00696 } 00697 00698 return status; 00699 }

BOOLEAN FsRecReadBlock IN PDEVICE_OBJECT  DeviceObject,
IN PLARGE_INTEGER  ByteOffset,
IN ULONG  MinimumBytes,
IN ULONG  BytesPerSector,
OUT PVOID *  Buffer,
OUT PBOOLEAN IsDeviceFailure  OPTIONAL
 

Definition at line 907 of file fs_rec.c.

References Buffer, ExAllocatePoolWithTag, Executive, FALSE, FSREC_POOL_TAG, IoBuildSynchronousFsdRequest(), IoCallDriver, IoGetNextIrpStackLocation, IRP_MJ_READ, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, PAGE_SIZE, PAGED_CODE, RoundUp, SetFlag, SL_OVERRIDE_VERIFY_VOLUME, TRUE, and VOID().

Referenced by FatRecFsControl(), IsUdfsVolume(), and NtfsRecFsControl().

00918 : 00919 00920 This routine reads a minimum numbers of bytes into a buffer starting at 00921 the byte offset from the base of the device represented by the device 00922 object. 00923 00924 Arguments: 00925 00926 DeviceObject - Pointer to the device object from which to read. 00927 00928 ByteOffset - Pointer to a 64-bit byte offset from the base of the device 00929 from which to start the read. 00930 00931 MinimumBytes - Supplies the minimum number of bytes to be read. 00932 00933 BytesPerSector - The number of bytes per sector for the device being read. 00934 00935 Buffer - Variable to receive a pointer to the allocated buffer containing 00936 the bytes read. 00937 00938 IsDeviceFailure - Variable to receive an indication whether a failure 00939 was a result of talking to the device. 00940 00941 Return Value: 00942 00943 The function value is TRUE if the bytes were read, otherwise FALSE. 00944 00945 --*/ 00946 00947 { 00948 #define RoundUp( x, y ) ( ((x + (y-1)) / y) * y ) 00949 00950 IO_STATUS_BLOCK ioStatus; 00951 KEVENT event; 00952 PIRP irp; 00953 NTSTATUS status; 00954 00955 PAGED_CODE(); 00956 00957 if (IsDeviceFailure) { 00958 *IsDeviceFailure = FALSE; 00959 } 00960 00961 KeInitializeEvent( &event, SynchronizationEvent, FALSE ); 00962 00963 // 00964 // Set the minimum number of bytes to read to the maximum of the bytes that 00965 // the caller wants to read, and the number of bytes in a sector. 00966 // 00967 00968 if (MinimumBytes < BytesPerSector) { 00969 MinimumBytes = BytesPerSector; 00970 } else { 00971 MinimumBytes = RoundUp( MinimumBytes, BytesPerSector ); 00972 } 00973 00974 // 00975 // Allocate a buffer large enough to contain the bytes required, round the 00976 // request to a page boundary to solve any alignment requirements. 00977 // 00978 00979 if (!*Buffer) { 00980 00981 *Buffer = ExAllocatePoolWithTag( NonPagedPool, 00982 (MinimumBytes + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1), 00983 FSREC_POOL_TAG ); 00984 if (!*Buffer) { 00985 return FALSE; 00986 } 00987 } 00988 00989 // 00990 // Read the actual bytes off of the media. 00991 // 00992 00993 irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, 00994 DeviceObject, 00995 *Buffer, 00996 MinimumBytes, 00997 ByteOffset, 00998 &event, 00999 &ioStatus ); 01000 if (!irp) { 01001 return FALSE; 01002 } 01003 01004 // 01005 // Override verify logic - we don't care. The fact we're in the picture means 01006 // someone is trying to mount new/changed media in the first place. 01007 // 01008 01009 SetFlag( IoGetNextIrpStackLocation( irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME ); 01010 01011 status = IoCallDriver( DeviceObject, irp ); 01012 if (status == STATUS_PENDING) { 01013 (VOID) KeWaitForSingleObject( &event, 01014 Executive, 01015 KernelMode, 01016 FALSE, 01017 (PLARGE_INTEGER) NULL ); 01018 status = ioStatus.Status; 01019 } 01020 01021 if (!NT_SUCCESS( status )) { 01022 01023 if (IsDeviceFailure) { 01024 *IsDeviceFailure = TRUE; 01025 } 01026 return FALSE; 01027 } 01028 01029 return TRUE; 01030 }

VOID FsRecUnload IN PDRIVER_OBJECT  DriverObject  ) 
 

Definition at line 539 of file fs_rec.c.

References ExFreePool(), FsRecLoadSync, IoDeleteDevice(), and PAGED_CODE.

Referenced by DriverEntry().

00545 : 00546 00547 This routine cleans up the driver's data structures so that it can be 00548 unloaded. 00549 00550 Arguments: 00551 00552 DriverObject - Pointer to the driver object for this driver. 00553 00554 Return Value: 00555 00556 None. 00557 00558 --*/ 00559 00560 { 00561 PAGED_CODE(); 00562 00563 // 00564 // Simply delete all of the device objects that this driver has created, the 00565 // load event, and return. 00566 // 00567 00568 while (DriverObject->DeviceObject) { 00569 IoDeleteDevice( DriverObject->DeviceObject ); 00570 } 00571 00572 ExFreePool( FsRecLoadSync ); 00573 00574 return; 00575 }


Variable Documentation

PKEVENT FsRecLoadSync
 

Definition at line 63 of file fs_rec.c.

Referenced by DriverEntry(), FsRecLoadFileSystem(), and FsRecUnload().


Generated on Sat May 15 19:43:45 2004 for test by doxygen 1.3.7