00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "fs_rec.h"
00027
#include "ntfs_rec.h"
00028
00029
00030
00031
00032
00033 #define Dbg (FSREC_DEBUG_LEVEL_NTFS)
00034
00035
#ifdef ALLOC_PRAGMA
00036
#pragma alloc_text(PAGE,NtfsRecFsControl)
00037
#pragma alloc_text(PAGE,IsNtfsVolume)
00038
#endif // ALLOC_PRAGMA
00039
00040
00041
NTSTATUS
00042 NtfsRecFsControl(
00043 IN
PDEVICE_OBJECT DeviceObject,
00044 IN
PIRP Irp
00045 )
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
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
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
00096
00097
00098
00099
00100
00101 status = STATUS_UNRECOGNIZED_VOLUME;
00102
00103
00104
00105
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
00179
00180
00181
00182
Irp->
IoStatus.Status = status;
00183
IoCompleteRequest(
Irp,
IO_NO_INCREMENT );
00184
00185
return status;
00186 }
00187
00188
00189 BOOLEAN
00190 IsNtfsVolume(
00191 IN
PPACKED_BOOT_SECTOR BootSector,
00192 IN ULONG BytesPerSector,
00193 IN PLARGE_INTEGER NumberOfSectors
00194 )
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 {
00219
PAGED_CODE();
00220
00221
00222
00223
00224
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
00240
00241
00242
00243
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
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
00275
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
00296
00297
00298
00299 !( BootSector->NumberSectors.QuadPart > NumberOfSectors->QuadPart )
00300
00301 &&
00302
00303
00304
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
00321
00322
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
00353
00354
00355
return FALSE;
00356 }
00357 }
00358