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 "fat_rec.h"
00028
00029
00030
00031
00032
00033 #define Dbg (FSREC_DEBUG_LEVEL_FAT)
00034
00035
#ifdef ALLOC_PRAGMA
00036
#pragma alloc_text(PAGE,FatRecFsControl)
00037
#pragma alloc_text(PAGE,IsFatVolume)
00038
#pragma alloc_text(PAGE,UnpackBiosParameterBlock)
00039
#endif // ALLOC_PRAGMA
00040
00041
00042
NTSTATUS
00043 FatRecFsControl(
00044 IN
PDEVICE_OBJECT DeviceObject,
00045 IN
PIRP Irp
00046 )
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 {
00070
NTSTATUS status;
00071
PIO_STACK_LOCATION irpSp;
00072
PDEVICE_EXTENSION deviceExtension;
00073
PDEVICE_OBJECT targetDevice;
00074
PPACKED_BOOT_SECTOR buffer;
00075 LARGE_INTEGER byteOffset;
00076 UNICODE_STRING driverName;
00077 ULONG bytesPerSector;
00078 BOOLEAN isDeviceFailure =
FALSE;
00079
00080
PAGED_CODE();
00081
00082
00083
00084
00085
00086 deviceExtension = (
PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
00087 irpSp =
IoGetCurrentIrpStackLocation(
Irp );
00088
00089
switch ( irpSp->
MinorFunction ) {
00090
00091
case IRP_MN_MOUNT_VOLUME:
00092
00093
00094
00095
00096
00097
00098
00099
00100 status = STATUS_UNRECOGNIZED_VOLUME;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 targetDevice = irpSp->
Parameters.MountVolume.DeviceObject;
00112
00113
00114
00115
00116
00117
if (
FsRecGetDeviceSectorSize( targetDevice,
00118 &bytesPerSector )) {
00119
00120 byteOffset.QuadPart = 0;
00121 buffer =
NULL;
00122
00123
if (
FsRecReadBlock( targetDevice,
00124 &byteOffset,
00125 512,
00126 bytesPerSector,
00127 &buffer,
00128 &isDeviceFailure ) &&
00129
IsFatVolume( buffer )) {
00130
00131 status = STATUS_FS_DRIVER_REQUIRED;
00132
00133 }
00134
00135
if (buffer !=
NULL) {
00136
ExFreePool( buffer );
00137 }
00138
00139 }
else {
00140
00141
00142
00143
00144
00145 isDeviceFailure =
TRUE;
00146 }
00147
00148
00149
00150
00151
00152
if (isDeviceFailure) {
00153
if (targetDevice->
Characteristics & FILE_FLOPPY_DISKETTE) {
00154 status = STATUS_FS_DRIVER_REQUIRED;
00155 }
00156 }
00157
00158
break;
00159
00160
case IRP_MN_LOAD_FILE_SYSTEM:
00161
00162 status =
FsRecLoadFileSystem( DeviceObject,
00163
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Fastfat" );
00164
break;
00165
00166
default:
00167 status = STATUS_INVALID_DEVICE_REQUEST;
00168
00169 }
00170
00171
00172
00173
00174
00175
00176
Irp->
IoStatus.Status = status;
00177
IoCompleteRequest(
Irp,
IO_NO_INCREMENT );
00178
00179
return status;
00180 }
00181
00182
00183 BOOLEAN
00184 IsFatVolume(
00185 IN
PPACKED_BOOT_SECTOR Buffer
00186 )
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 {
00208
BIOS_PARAMETER_BLOCK bios;
00209 BOOLEAN result;
00210
00211
PAGED_CODE();
00212
00213
00214
00215
00216
00217
00218
UnpackBiosParameterBlock( &
Buffer->PackedBpb, &bios );
00219
00220
00221
00222
00223
00224
00225 result =
TRUE;
00226
00227
if (bios.
Sectors) {
00228 bios.
LargeSectors = 0;
00229 }
00230
00231
00232
00233
00234
if (
Buffer->Jump[0] != 0x49 &&
00235
Buffer->Jump[0] != 0xe9 &&
00236
Buffer->Jump[0] != 0xeb) {
00237
00238 result =
FALSE;
00239
00240
00241
00242
00243
00244 }
else if (bios.
BytesPerSector != 128 &&
00245 bios.
BytesPerSector != 256 &&
00246 bios.
BytesPerSector != 512 &&
00247 bios.
BytesPerSector != 1024 &&
00248 bios.
BytesPerSector != 2048 &&
00249 bios.
BytesPerSector != 4096) {
00250
00251 result =
FALSE;
00252
00253 }
else if (bios.
SectorsPerCluster != 1 &&
00254 bios.
SectorsPerCluster != 2 &&
00255 bios.
SectorsPerCluster != 4 &&
00256 bios.
SectorsPerCluster != 8 &&
00257 bios.
SectorsPerCluster != 16 &&
00258 bios.
SectorsPerCluster != 32 &&
00259 bios.
SectorsPerCluster != 64 &&
00260 bios.
SectorsPerCluster != 128) {
00261
00262 result =
FALSE;
00263
00264 }
else if (!bios.
ReservedSectors) {
00265
00266 result =
FALSE;
00267
00268 }
else if (!bios.
Fats) {
00269
00270 result =
FALSE;
00271
00272
00273
00274
00275
00276 }
else if (!bios.
Sectors && !bios.
LargeSectors) {
00277
00278 result =
FALSE;
00279
00280
00281
00282
00283
00284
00285 }
else if (bios.
Media != 0x00 &&
00286 bios.
Media != 0x01 &&
00287 bios.
Media != 0xf0 &&
00288 bios.
Media != 0xf8 &&
00289 bios.
Media != 0xf9 &&
00290 bios.
Media != 0xfa &&
00291 bios.
Media != 0xfb &&
00292 bios.
Media != 0xfc &&
00293 bios.
Media != 0xfd &&
00294 bios.
Media != 0xfe &&
00295 bios.
Media != 0xff) {
00296
00297 result =
FALSE;
00298
00299 }
else if (bios.
SectorsPerFat != 0 && bios.
RootEntries == 0) {
00300
00301 result =
FALSE;
00302 }
00303
00304
return result;
00305 }
00306
00307
00308
VOID
00309 UnpackBiosParameterBlock(
00310 IN
PPACKED_BIOS_PARAMETER_BLOCK Bios,
00311 OUT
PBIOS_PARAMETER_BLOCK UnpackedBios
00312 )
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 {
00334
PAGED_CODE();
00335
00336
00337
00338
00339
00340
CopyUchar2( &UnpackedBios->BytesPerSector, &Bios->BytesPerSector[0] );
00341
CopyUchar2( &UnpackedBios->BytesPerSector, &Bios->BytesPerSector[0] );
00342
CopyUchar1( &UnpackedBios->SectorsPerCluster, &Bios->SectorsPerCluster[0] );
00343
CopyUchar2( &UnpackedBios->ReservedSectors, &Bios->ReservedSectors[0] );
00344
CopyUchar1( &UnpackedBios->Fats, &Bios->Fats[0] );
00345
CopyUchar2( &UnpackedBios->RootEntries, &Bios->RootEntries[0] );
00346
CopyUchar2( &UnpackedBios->Sectors, &Bios->Sectors[0] );
00347
CopyUchar1( &UnpackedBios->Media, &Bios->Media[0] );
00348
CopyUchar2( &UnpackedBios->SectorsPerFat, &Bios->SectorsPerFat[0] );
00349
CopyUchar2( &UnpackedBios->SectorsPerTrack, &Bios->SectorsPerTrack[0] );
00350
CopyUchar2( &UnpackedBios->Heads, &Bios->Heads[0] );
00351
CopyUchar4( &UnpackedBios->HiddenSectors, &Bios->HiddenSectors[0] );
00352
CopyUchar4( &UnpackedBios->LargeSectors, &Bios->LargeSectors[0] );
00353 }