test: fat_rec.c Source File

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

# fat_rec.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1992  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     fat_rec.c
    00008
    00009 Abstract:
    00010
    00011     This module contains the mini-file system recognizer for FAT.
    00012
    00013 Author:
    00014
    00015     Darryl E. Havens (darrylh) 8-dec-1992
    00016
    00017 Environment:
    00018
    00019     Kernel mode, local to I/O system
    00020
    00021 Revision History:
    00022
    00023
    00024 --*/
    00025
    00026 #include "fs_rec.h"
    00027 #include "fat_rec.h"
    00028
    00029 //
    00030 //  The local debug trace level
    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 Routine Description:
    00051
    00052     This function performs the mount and driver reload functions for this mini-
    00053     file system recognizer driver.
    00054
    00055 Arguments:
    00056
    00057     DeviceObject - Pointer to this driver's device object.
    00058
    00059     Irp - Pointer to the I/O Request Packet (IRP) representing the function to
    00060         be performed.
    00061
    00062 Return Value:
    00063
    00064     The function value is the final status of the operation.
    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     // Begin by determining what function that is to be performed.
    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         // Attempt to mount a volume:  Determine whether or not the volume in
    00095         // question is a FAT volume and, if so, let the I/O system know that it
    00096         // is by returning a special status code so that this driver can get
    00097         // called back to load the FAT file system.
    00098         //
    00099
    00100         status = STATUS_UNRECOGNIZED_VOLUME;
    00101
    00102         //
    00103         // Attempt to determine whether or not the target volume being mounted
    00104         // is a FAT volume.  Note that if an error occurs, and this is a floppy
    00105         // drive, and the error occurred on the actual read from the device,
    00106         // then the FAT file system will actually be loaded to handle the
    00107         // problem since this driver is a place holder and does not need to
    00108         // know all of the protocols for handling floppy errors.
    00109         //
    00110
    00111         targetDevice = irpSp->Parameters.MountVolume.DeviceObject;
    00112
    00113         //
    00114         //  First retrieve the sector size for this media.
    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              //  Devices that can't get us this much ...
    00143              //
    00144
    00145              isDeviceFailure = TRUE;
    00146          }
    00147
    00148          //
    00149          //  See if we should make the real filesystem take a shot at a wacky floppy.
    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     // Finally, complete the request and return the same status code to the
    00173     // caller.
    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 Routine Description:
    00191
    00192     This routine looks at the buffer passed in which contains the FAT boot
    00193     sector and determines whether or not it represents an actual FAT boot
    00194     sector.
    00195
    00196 Arguments:
    00197
    00198     Buffer - Pointer to buffer containing potential boot block.
    00199
    00200 Return Value:
    00201
    00202     The function returns TRUE if the buffer contains a recognizable FAT boot
    00203     sector, otherwise it returns FALSE.
    00204
    00205 --*/
    00206
    00207 {
    00208     BIOS_PARAMETER_BLOCK bios;
    00209     BOOLEAN result;
    00210
    00211     PAGED_CODE();
    00212
    00213     //
    00214     // Begin by unpacking the Bios Parameter Block that is packed in the boot
    00215     // sector so that it can be examined without incurring alignment faults.
    00216     //
    00217
    00218     UnpackBiosParameterBlock( &Buffer->PackedBpb, &bios );
    00219
    00220     //
    00221     // Assume that the sector represents a FAT boot block and then determine
    00222     // whether or not it really does.
    00223     //
    00224
    00225     result = TRUE;
    00226
    00227     if (bios.Sectors) {
    00228         bios.LargeSectors = 0;
    00229     }
    00230
    00231     // FMR Jul.11.1994 NaokiM - Fujitsu -
    00232     // FMR boot sector has 'IPL1' string at the beginnig.
    00233
    00234     if (Buffer->Jump[0] != 0x49 && /* FMR */
    00235         Buffer->Jump[0] != 0xe9 &&
    00236         Buffer->Jump[0] != 0xeb) {
    00237
    00238         result = FALSE;
    00239
    00240
    00241     // FMR Jul.11.1994 NaokiM - Fujitsu -
    00242     // Sector size of FMR partition is 2048.
    00243
    00244     } else if (bios.BytesPerSector !=  128 &&
    00245                bios.BytesPerSector !=  256 &&
    00246                bios.BytesPerSector !=  512 &&
    00247                bios.BytesPerSector != 1024 &&
    00248                bios.BytesPerSector != 2048 && /* FMR */
    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     // Prior to DOS 3.2 might contains value in both of Sectors and
    00274     // Sectors Large.
    00275     //
    00276     } else if (!bios.Sectors && !bios.LargeSectors) {
    00277
    00278         result = FALSE;
    00279
    00280     // FMR Jul.11.1994 NaokiM - Fujitsu -
    00281     // 1. Media descriptor of FMR partitions is 0xfa.
    00282     // 2. Media descriptor of partitions formated by FMR OS/2 is 0x00.
    00283     // 3. Media descriptor of floppy disks formated by FMR DOS is 0x01.
    00284
    00285     } else if (bios.Media != 0x00 && /* FMR */
    00286                bios.Media != 0x01 && /* FMR */
    00287                bios.Media != 0xf0 &&
    00288                bios.Media != 0xf8 &&
    00289                bios.Media != 0xf9 &&
    00290                bios.Media != 0xfa && /* FMR */
    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 Routine Description:
    00317
    00318     This routine copies a packed Bios Parameter Block to an unpacked Bios
    00319     Parameter Block.
    00320
    00321 Arguments:
    00322
    00323     Bios - Pointer to the packed Bios Parameter Block.
    00324
    00325     UnpackedBios - Pointer to the unpacked Bios Parameter Block.
    00326
    00327 Return Value:
    00328
    00329     None.
    00330
    00331 --*/
    00332
    00333 {
    00334     PAGED_CODE();
    00335
    00336     //
    00337     // Unpack the Bios Parameter Block.
    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 }