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

ntfs_rec.c File Reference

#include "fs_rec.h"
#include "ntfs_rec.h"

Go to the source code of this file.

Defines

#define Dbg   (FSREC_DEBUG_LEVEL_NTFS)

Functions

NTSTATUS NtfsRecFsControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
BOOLEAN IsNtfsVolume (IN PPACKED_BOOT_SECTOR BootSector, IN ULONG BytesPerSector, IN PLARGE_INTEGER NumberOfSectors)


Define Documentation

#define Dbg   (FSREC_DEBUG_LEVEL_NTFS)
 

Definition at line 33 of file ntfs_rec.c.


Function Documentation

BOOLEAN IsNtfsVolume IN PPACKED_BOOT_SECTOR  BootSector,
IN ULONG  BytesPerSector,
IN PLARGE_INTEGER  NumberOfSectors
 

Definition at line 190 of file ntfs_rec.c.

References FALSE, PAGE_SIZE, PAGED_CODE, and TRUE.

Referenced by NtfsRecFsControl().

00198 : 00199 00200 This routine looks at the buffer passed in which contains the NTFS boot 00201 sector and determines whether or not it represents an NTFS volume. 00202 00203 Arguments: 00204 00205 BootSector - Pointer to buffer containing a potential NTFS boot sector. 00206 00207 BytesPerSector - Supplies the number of bytes per sector for the drive. 00208 00209 NumberOfSectors - Supplies the number of sectors on the partition. 00210 00211 Return Value: 00212 00213 The function returns TRUE if the buffer contains a recognizable NTFS boot 00214 sector, otherwise it returns FALSE. 00215 00216 --*/ 00217 00218 { 00219 PAGED_CODE(); 00220 00221 // 00222 // Now perform all the checks, starting with the Name and Checksum. 00223 // The remaining checks should be obvious, including some fields which 00224 // must be 0 and other fields which must be a small power of 2. 00225 // 00226 00227 if (BootSector->Oem[0] == 'N' && 00228 BootSector->Oem[1] == 'T' && 00229 BootSector->Oem[2] == 'F' && 00230 BootSector->Oem[3] == 'S' && 00231 BootSector->Oem[4] == ' ' && 00232 BootSector->Oem[5] == ' ' && 00233 BootSector->Oem[6] == ' ' && 00234 BootSector->Oem[7] == ' ' 00235 00236 && 00237 00238 // 00239 // Check number of bytes per sector. The low order byte of this 00240 // number must be zero (smallest sector size = 0x100) and the 00241 // high order byte shifted must equal the bytes per sector gotten 00242 // from the device and stored in the Vcb. And just to be sure, 00243 // sector size must be less than page size. 00244 // 00245 00246 BootSector->PackedBpb.BytesPerSector[0] == 0 00247 00248 && 00249 00250 ((ULONG) (BootSector->PackedBpb.BytesPerSector[1] << 8) == BytesPerSector) 00251 00252 && 00253 00254 BootSector->PackedBpb.BytesPerSector[1] << 8 <= PAGE_SIZE 00255 00256 && 00257 00258 // 00259 // Sectors per cluster must be a power of 2. 00260 // 00261 00262 (BootSector->PackedBpb.SectorsPerCluster[0] == 0x1 || 00263 BootSector->PackedBpb.SectorsPerCluster[0] == 0x2 || 00264 BootSector->PackedBpb.SectorsPerCluster[0] == 0x4 || 00265 BootSector->PackedBpb.SectorsPerCluster[0] == 0x8 || 00266 BootSector->PackedBpb.SectorsPerCluster[0] == 0x10 || 00267 BootSector->PackedBpb.SectorsPerCluster[0] == 0x20 || 00268 BootSector->PackedBpb.SectorsPerCluster[0] == 0x40 || 00269 BootSector->PackedBpb.SectorsPerCluster[0] == 0x80) 00270 00271 && 00272 00273 // 00274 // These fields must all be zero. For both Fat and HPFS, some of 00275 // these fields must be nonzero. 00276 // 00277 00278 BootSector->PackedBpb.ReservedSectors[0] == 0 && 00279 BootSector->PackedBpb.ReservedSectors[1] == 0 && 00280 BootSector->PackedBpb.Fats[0] == 0 && 00281 BootSector->PackedBpb.RootEntries[0] == 0 && 00282 BootSector->PackedBpb.RootEntries[1] == 0 && 00283 BootSector->PackedBpb.Sectors[0] == 0 && 00284 BootSector->PackedBpb.Sectors[1] == 0 && 00285 BootSector->PackedBpb.SectorsPerFat[0] == 0 && 00286 BootSector->PackedBpb.SectorsPerFat[1] == 0 && 00287 BootSector->PackedBpb.LargeSectors[0] == 0 && 00288 BootSector->PackedBpb.LargeSectors[1] == 0 && 00289 BootSector->PackedBpb.LargeSectors[2] == 0 && 00290 BootSector->PackedBpb.LargeSectors[3] == 0 00291 00292 && 00293 00294 // 00295 // Number of Sectors cannot be greater than the number of sectors 00296 // on the partition. 00297 // 00298 00299 !( BootSector->NumberSectors.QuadPart > NumberOfSectors->QuadPart ) 00300 00301 && 00302 00303 // 00304 // Check that both Lcn values are for sectors within the partition. 00305 // 00306 00307 !( BootSector->MftStartLcn.QuadPart * 00308 BootSector->PackedBpb.SectorsPerCluster[0] > 00309 NumberOfSectors->QuadPart ) 00310 00311 && 00312 00313 !( BootSector->Mft2StartLcn.QuadPart * 00314 BootSector->PackedBpb.SectorsPerCluster[0] > 00315 NumberOfSectors->QuadPart ) 00316 00317 && 00318 00319 // 00320 // Clusters per file record segment and default clusters for Index 00321 // Allocation Buffers must be a power of 2. A negative number indicates 00322 // a shift value to get the actual size of the structure. 00323 // 00324 00325 ((BootSector->ClustersPerFileRecordSegment >= -31 && 00326 BootSector->ClustersPerFileRecordSegment <= -9) || 00327 BootSector->ClustersPerFileRecordSegment == 0x1 || 00328 BootSector->ClustersPerFileRecordSegment == 0x2 || 00329 BootSector->ClustersPerFileRecordSegment == 0x4 || 00330 BootSector->ClustersPerFileRecordSegment == 0x8 || 00331 BootSector->ClustersPerFileRecordSegment == 0x10 || 00332 BootSector->ClustersPerFileRecordSegment == 0x20 || 00333 BootSector->ClustersPerFileRecordSegment == 0x40) 00334 00335 && 00336 00337 ((BootSector->DefaultClustersPerIndexAllocationBuffer >= -31 && 00338 BootSector->DefaultClustersPerIndexAllocationBuffer <= -9) || 00339 BootSector->DefaultClustersPerIndexAllocationBuffer == 0x1 || 00340 BootSector->DefaultClustersPerIndexAllocationBuffer == 0x2 || 00341 BootSector->DefaultClustersPerIndexAllocationBuffer == 0x4 || 00342 BootSector->DefaultClustersPerIndexAllocationBuffer == 0x8 || 00343 BootSector->DefaultClustersPerIndexAllocationBuffer == 0x10 || 00344 BootSector->DefaultClustersPerIndexAllocationBuffer == 0x20 || 00345 BootSector->DefaultClustersPerIndexAllocationBuffer == 0x40)) { 00346 00347 return TRUE; 00348 00349 } else { 00350 00351 // 00352 // This does not appear to be an NTFS volume. 00353 // 00354 00355 return FALSE; 00356 } 00357 }

NTSTATUS NtfsRecFsControl IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp
 

Definition at line 42 of file ntfs_rec.c.

References ExFreePool(), FsRecGetDeviceSectors(), FsRecGetDeviceSectorSize(), FsRecLoadFileSystem(), FsRecReadBlock(), IO_NO_INCREMENT, IoCompleteRequest, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, IRP_MN_LOAD_FILE_SYSTEM, IRP_MN_MOUNT_VOLUME, IsNtfsVolume(), L, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), NULL, PACKED_BOOT_SECTOR, PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by FsRecFsControl().

00049 : 00050 00051 This function performs the mount and driver reload functions for this mini- 00052 file system recognizer driver. 00053 00054 Arguments: 00055 00056 DeviceObject - Pointer to this driver's device object. 00057 00058 Irp - Pointer to the I/O Request Packet (IRP) representing the function to 00059 be performed. 00060 00061 Return Value: 00062 00063 The function value is the final status of the operation. 00064 00065 00066 --*/ 00067 00068 { 00069 NTSTATUS status; 00070 PIO_STACK_LOCATION irpSp; 00071 PDEVICE_EXTENSION deviceExtension; 00072 PDEVICE_OBJECT targetDevice; 00073 PPACKED_BOOT_SECTOR buffer; 00074 LARGE_INTEGER byteOffset; 00075 LARGE_INTEGER secondByteOffset; 00076 LARGE_INTEGER lastByteOffset; 00077 UNICODE_STRING driverName; 00078 ULONG bytesPerSector; 00079 LARGE_INTEGER numberOfSectors; 00080 00081 PAGED_CODE(); 00082 00083 // 00084 // Begin by determining what function that is to be performed. 00085 // 00086 00087 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00088 irpSp = IoGetCurrentIrpStackLocation( Irp ); 00089 00090 switch ( irpSp->MinorFunction ) { 00091 00092 case IRP_MN_MOUNT_VOLUME: 00093 00094 // 00095 // Attempt to mount a volume: Determine whether or not the volume in 00096 // question is an NTFS volume and, if so, let the I/O system know that it 00097 // is by returning a special status code so that this driver can get 00098 // called back to load the NTFS file system. 00099 // 00100 00101 status = STATUS_UNRECOGNIZED_VOLUME; 00102 00103 // 00104 // Attempt to determine whether or not the target volume being mounted 00105 // is an NTFS volume. 00106 // 00107 00108 targetDevice = irpSp->Parameters.MountVolume.DeviceObject; 00109 00110 if (FsRecGetDeviceSectorSize( targetDevice, 00111 &bytesPerSector ) && 00112 FsRecGetDeviceSectors( targetDevice, 00113 bytesPerSector, 00114 &numberOfSectors )) { 00115 00116 byteOffset.QuadPart = 0; 00117 buffer = NULL; 00118 secondByteOffset.QuadPart = numberOfSectors.QuadPart >> 1; 00119 secondByteOffset.QuadPart *= (LONG) bytesPerSector; 00120 lastByteOffset.QuadPart = (numberOfSectors.QuadPart - 1) * (LONG) bytesPerSector; 00121 00122 if (FsRecReadBlock( targetDevice, 00123 &byteOffset, 00124 sizeof( PACKED_BOOT_SECTOR ), 00125 bytesPerSector, 00126 (PVOID *)&buffer, 00127 NULL ) && 00128 IsNtfsVolume( buffer, bytesPerSector, &numberOfSectors )) { 00129 00130 status = STATUS_FS_DRIVER_REQUIRED; 00131 00132 } else { 00133 00134 if (FsRecReadBlock( targetDevice, 00135 &secondByteOffset, 00136 sizeof( PACKED_BOOT_SECTOR ), 00137 bytesPerSector, 00138 (PVOID *)&buffer, 00139 NULL ) && 00140 IsNtfsVolume( buffer, bytesPerSector, &numberOfSectors )) { 00141 00142 status = STATUS_FS_DRIVER_REQUIRED; 00143 00144 } else { 00145 00146 if (FsRecReadBlock( targetDevice, 00147 &lastByteOffset, 00148 sizeof( PACKED_BOOT_SECTOR ), 00149 bytesPerSector, 00150 (PVOID *)&buffer, 00151 NULL ) && 00152 IsNtfsVolume( buffer, bytesPerSector, &numberOfSectors )) { 00153 00154 status = STATUS_FS_DRIVER_REQUIRED; 00155 } 00156 } 00157 } 00158 00159 if (buffer != NULL) { 00160 ExFreePool( buffer ); 00161 } 00162 } 00163 00164 break; 00165 00166 case IRP_MN_LOAD_FILE_SYSTEM: 00167 00168 status = FsRecLoadFileSystem( DeviceObject, 00169 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Ntfs" ); 00170 break; 00171 00172 default: 00173 status = STATUS_INVALID_DEVICE_REQUEST; 00174 00175 } 00176 00177 // 00178 // Finally, complete the request and return the same status code to the 00179 // caller. 00180 // 00181 00182 Irp->IoStatus.Status = status; 00183 IoCompleteRequest( Irp, IO_NO_INCREMENT ); 00184 00185 return status; 00186 }


Generated on Sat May 15 19:44:52 2004 for test by doxygen 1.3.7