reactos操作系统实现(137)

 VfatHasFileSystem函数主要用来读取FAT文件系统信息,并且判断这个磁盘卷是否为FAT文件系统,具体实现如下:

#001  static NTSTATUS

#002  VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,

#003                    PBOOLEAN RecognizedFS,

#004                    PFATINFO pFatInfo)

#005  {

#006     NTSTATUS Status;

#007     PARTITION_INFORMATION PartitionInfo;

#008     DISK_GEOMETRY DiskGeometry;

#009     FATINFO FatInfo;

#010     ULONG Size;

#011     ULONG Sectors;

#012     LARGE_INTEGER Offset;

#013     struct _BootSector* Boot;

#014     struct _BootSectorFatX* BootFatX;

#015     BOOLEAN PartitionInfoIsValid = FALSE;

#016 

#017     DPRINT("VfatHasFileSystem/n");

#018 

 

设置返回结果为不认识这个FAT文件系统。

#019     *RecognizedFS = FALSE;

#020 

 

获取磁盘的结构描述信息,通过调用磁盘驱动程序来实现。

#021     Size = sizeof(DISK_GEOMETRY);

#022     Status = VfatBlockDeviceIoControl(DeviceToMount,

#023                                       IOCTL_DISK_GET_DRIVE_GEOMETRY,

#024                                       NULL,

#025                                       0,

#026                                       &DiskGeometry,

#027                                       &Size,

#028                                       FALSE);

#029     if (!NT_SUCCESS(Status))

#030     {

#031        DPRINT("VfatBlockDeviceIoControl faild (%x)/n", Status);

#032        return Status;

#033     }

 

判断磁盘是否为固定媒介。

#034     FatInfo.FixedMedia = DiskGeometry.MediaType == FixedMedia ? TRUE : FALSE;

 

不管是固定的,还是移动的磁盘,反正就是找到了磁盘设备。

#035     if (DiskGeometry.MediaType == FixedMedia || DiskGeometry.MediaType == RemovableMedia)

#036     {

 

通过底层磁盘驱动程序获取磁盘分区信息。

#037        // We have found a hard disk

#038        Size = sizeof(PARTITION_INFORMATION);

#039        Status = VfatBlockDeviceIoControl(DeviceToMount,

#040                                          IOCTL_DISK_GET_PARTITION_INFO,

#041                                          NULL,

#042                                          0,

#043                                          &PartitionInfo,

#044                                          &Size,

#045                                          FALSE);

#046        if (!NT_SUCCESS(Status))

#047        {

#048           DPRINT("VfatBlockDeviceIoControl faild (%x)/n", Status);

#049           return Status;

#050        }

 

设置磁盘分区信息读取到有效数据。

#051        PartitionInfoIsValid = TRUE;

#052        DPRINT("Partition Information:/n");

#053        DPRINT("StartingOffset      %u/n", PartitionInfo.StartingOffset.QuadPart  / 512);

#054        DPRINT("PartitionLength     %u/n", PartitionInfo.PartitionLength.QuadPart / 512);

#055        DPRINT("HiddenSectors       %u/n", PartitionInfo.HiddenSectors);

#056        DPRINT("PartitionNumber     %u/n", PartitionInfo.PartitionNumber);

#057        DPRINT("PartitionType       %u/n", PartitionInfo.PartitionType);

#058        DPRINT("BootIndicator       %u/n", PartitionInfo.BootIndicator);

#059        DPRINT("RecognizedPartition %u/n", PartitionInfo.RecognizedPartition);

#060        DPRINT("RewritePartition    %u/n", PartitionInfo.RewritePartition);

 

根据磁盘格式类型来判断是否FAT驱动程序可以支持的文件系统类型。

#061        if (PartitionInfo.PartitionType)

#062        {

#063           if (PartitionInfo.PartitionType == PARTITION_FAT_12       ||

#064               PartitionInfo.PartitionType == PARTITION_FAT_16       ||

#065               PartitionInfo.PartitionType == PARTITION_HUGE         ||

#066               PartitionInfo.PartitionType == PARTITION_FAT32        ||

#067               PartitionInfo.PartitionType == PARTITION_FAT32_XINT13 ||

#068               PartitionInfo.PartitionType == PARTITION_XINT13)

#069           {

#070              *RecognizedFS = TRUE;

#071           }

#072        }

#073        else if (DiskGeometry.MediaType == RemovableMedia &&

#074                 PartitionInfo.PartitionNumber > 0 &&

#075                 PartitionInfo.StartingOffset.QuadPart == 0 &&

#076                 PartitionInfo.PartitionLength.QuadPart > 0)

#077        {

#078           /* This is possible a removable media formated as super floppy */

#079           *RecognizedFS = TRUE;

#080        }

#081     }

#082     else if (DiskGeometry.MediaType == Unknown)

#083     {

#084        /*

#085         * Floppy disk driver can return Unknown as media type if it

#086         * doesn't know yet what floppy in the drive really is. This is

#087         * perfectly correct to do under Windows.

#088         */

#089        *RecognizedFS = TRUE;

#090        DiskGeometry.BytesPerSector = 512;

#091     }

#092     else

#093     {

#094        *RecognizedFS = TRUE;

#095     }

 

如果文件系统类型是可以支持的,再进一步处理。

#096     if (*RecognizedFS)

#097     {

#098 

#099        Boot = ExAllocatePoolWithTag(NonPagedPool, DiskGeometry.BytesPerSector, TAG_VFAT);

#100        if (Boot == NULL)

#101        {

#102           return STATUS_INSUFFICIENT_RESOURCES;

#103        }

#104 

#105        Offset.QuadPart = 0;

#106 

 

读取FAT的引导扇区数据。

#107        /* Try to recognize FAT12/FAT16/FAT32 partitions */

#108        Status = VfatReadDisk(DeviceToMount, &Offset, DiskGeometry.BytesPerSector, (PUCHAR) Boot, FALSE);

 

如果读取成功,再进一步处理。

#109        if (NT_SUCCESS(Status))

#110        {

 

检验最后两个字节的标志是为0xaa55,如果不是,就是不认识的分区。

#111           if (Boot->Signatur1 != 0xaa55)

#112           {

#113              *RecognizedFS = FALSE;

#114           }

 

如果每个扇区大小是否支持,如果不支持就返回。

#115           if (*RecognizedFS &&

#116           Boot->BytesPerSector != 512 &&

#117           Boot->BytesPerSector != 1024 &&

#118               Boot->BytesPerSector != 2048 &&

#119           Boot->BytesPerSector != 4096)

#120           {

#121              DPRINT1("BytesPerSector %d/n", Boot->BytesPerSector);

#122              *RecognizedFS = FALSE;

#123           }

#124 

 

如果FAT的分配表不是12,就不支持这个FAT文件系统。

#125           if (*RecognizedFS &&

#126               Boot->FATCount != 1 &&

#127               Boot->FATCount != 2)

#128           {

#129              DPRINT1("FATCount %d/n", Boot->FATCount);

#130              *RecognizedFS = FALSE;

#131           }

#132 

 

文件系统分区的类型是否支持。

#133           if (*RecognizedFS &&

#134               Boot->Media != 0xf0 &&

#135               Boot->Media != 0xf8 &&

#136               Boot->Media != 0xf9 &&

#137               Boot->Media != 0xfa &&

#138               Boot->Media != 0xfb &&

#139               Boot->Media != 0xfc &&

#140               Boot->Media != 0xfd &&

#141               Boot->Media != 0xfe &&

#142               Boot->Media != 0xff)

#143           {

#144              DPRINT1("Media             %02x/n", Boot->Media);

#145              *RecognizedFS = FALSE;

#146           }

#147 

 

每簇扇区大小,最多支持的个数。

#148           if (*RecognizedFS &&

#149               Boot->SectorsPerCluster != 1 &&

#150               Boot->SectorsPerCluster != 2 &&

#151               Boot->SectorsPerCluster != 4 &&

#152               Boot->SectorsPerCluster != 8 &&

#153               Boot->SectorsPerCluster != 16 &&

#154               Boot->SectorsPerCluster != 32 &&

#155               Boot->SectorsPerCluster != 64 &&

#156               Boot->SectorsPerCluster != 128)

#157           {

#158              DPRINT1("SectorsPerCluster %02x/n", Boot->SectorsPerCluster);

#159              *RecognizedFS = FALSE;

#160           }

#161 

 

每簇支持最大的字节。

#162           if (*RecognizedFS &&

#163               Boot->BytesPerSector * Boot->SectorsPerCluster > 32 * 1024)

#164           {

#165              DPRINT1("ClusterSize %dx/n", Boot->BytesPerSector * Boot->SectorsPerCluster);

#166              *RecognizedFS = FALSE;

#167           }

#168 

 

如果可以支持的FAT文件系统,就保存相应的参数。

#169           if (*RecognizedFS)

#170           {

 

FAT卷标识号。

#171              FatInfo.VolumeID = Boot->VolumeID;

 

FAT的分配表的开始位置。

#172              FatInfo.FATStart = Boot->ReservedSectors;

 

FAT的分配表的个数。

#173              FatInfo.FATCount = Boot->FATCount;

#174              FatInfo.FATSectors = Boot->FATSectors ? Boot->FATSectors : ((struct _BootSector32*) Boot)->FATSectors32;

 

每扇区的多少字节。

#175              FatInfo.BytesPerSector = Boot->BytesPerSector;

 

每簇包括多少扇区。

#176              FatInfo.SectorsPerCluster = Boot->SectorsPerCluster;

 

每簇包括多少字节。

#177              FatInfo.BytesPerCluster = FatInfo.BytesPerSector * FatInfo.SectorsPerCluster;

 

根目录扇区数。

#178              FatInfo.rootDirectorySectors = ((Boot->RootEntries * 32) + Boot->BytesPerSector - 1) / Boot->BytesPerSector;

 

根目录开始位置。

#179              FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;

 

FAT文件系统数据开始位置。

#180              FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;

#181              FatInfo.Sectors = Sectors = Boot->Sectors ? Boot->Sectors : Boot->SectorsHuge;

 

计算分区里有多少簇。

#182              Sectors -= Boot->ReservedSectors + FatInfo.FATCount * FatInfo.FATSectors + FatInfo.rootDirectorySectors;

#183              FatInfo.NumberOfClusters = Sectors / Boot->SectorsPerCluster;

 

根据簇数大小来区分采用FAT12,还是FAT32等等。

#184              if (FatInfo.NumberOfClusters < 4085)

#185              {

#186                 DPRINT("FAT12/n");

#187                 FatInfo.FatType = FAT12;

#188                 FatInfo.RootCluster = (FatInfo.rootStart - 1) / FatInfo.SectorsPerCluster;

#189              }

#190              else if (FatInfo.NumberOfClusters >= 65525)

#191              {

#192                 DPRINT("FAT32/n");

#193                 FatInfo.FatType = FAT32;

#194                 FatInfo.RootCluster = ((struct _BootSector32*) Boot)->RootCluster;

#195                 FatInfo.rootStart = FatInfo.dataStart + ((FatInfo.RootCluster - 2) * FatInfo.SectorsPerCluster);

#196                 FatInfo.VolumeID = ((struct _BootSector32*) Boot)->VolumeID;

#197              }

#198              else

#199              {

#200                 DPRINT("FAT16/n");

#201                 FatInfo.FatType = FAT16;

#202                 FatInfo.RootCluster = FatInfo.rootStart / FatInfo.SectorsPerCluster;

#203              }

#204              if (PartitionInfoIsValid &&

#205                  FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector)

#206              {

#207                 *RecognizedFS = FALSE;

#208              }

#209 

#210              if (pFatInfo && *RecognizedFS)

#211              {

#212                 *pFatInfo = FatInfo;

#213              }

#214           }

#215        }

#216 

#217        ExFreePool(Boot);

#218     }

#219 

 

如果不认识的FAT文件系统,就进行下面的处理。

#220     if (!*RecognizedFS && PartitionInfoIsValid)

#221     {

#222        BootFatX = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _BootSectorFatX), TAG_VFAT);

#223        if (BootFatX == NULL)

#224        {

#225           *RecognizedFS=FALSE;

#226           return STATUS_INSUFFICIENT_RESOURCES;

#227        }

#228 

#229        Offset.QuadPart = 0;

#230 

 

扩展的FAT文件系统识别。

#231        /* Try to recognize FATX16/FATX32 partitions (Xbox) */

#232        Status = VfatReadDisk(DeviceToMount, &Offset, sizeof(struct _BootSectorFatX), (PUCHAR) BootFatX, FALSE);

#233        if (NT_SUCCESS(Status))

#234        {

#235           *RecognizedFS = TRUE;

#236           if (BootFatX->SysType[0] != 'F' ||

#237               BootFatX->SysType[1] != 'A' ||

#238               BootFatX->SysType[2] != 'T' ||

#239               BootFatX->SysType[3] != 'X')

#240           {

#241              DPRINT1("SysType %c%c%c%c/n", BootFatX->SysType[0], BootFatX->SysType[1], BootFatX->SysType[2], BootFatX->SysType[3]);

#242              *RecognizedFS=FALSE;

#243           }

#244 

#245           if (*RecognizedFS &&

#246              BootFatX->SectorsPerCluster != 1 &&

#247              BootFatX->SectorsPerCluster != 2 &&

#248              BootFatX->SectorsPerCluster != 4 &&

#249              BootFatX->SectorsPerCluster != 8 &&

#250              BootFatX->SectorsPerCluster != 16 &&

#251              BootFatX->SectorsPerCluster != 32 &&

#252              BootFatX->SectorsPerCluster != 64 &&

#253              BootFatX->SectorsPerCluster != 128)

#254           {

#255              DPRINT1("SectorsPerCluster %lu/n", BootFatX->SectorsPerCluster);

#256              *RecognizedFS=FALSE;

#257           }

#258 

#259           if (*RecognizedFS)

#260           {

#261              FatInfo.BytesPerSector = DiskGeometry.BytesPerSector;

#262              FatInfo.SectorsPerCluster = BootFatX->SectorsPerCluster;

#263              FatInfo.rootDirectorySectors = BootFatX->SectorsPerCluster;

#264              FatInfo.BytesPerCluster = BootFatX->SectorsPerCluster * DiskGeometry.BytesPerSector;

#265              FatInfo.Sectors = (ULONG)(PartitionInfo.PartitionLength.QuadPart / DiskGeometry.BytesPerSector);

#266              if (FatInfo.Sectors / FatInfo.SectorsPerCluster < 65525)

#267              {

#268                 DPRINT("FATX16/n");

#269                 FatInfo.FatType = FATX16;

#270              }

#271              else

#272              {

#273                 DPRINT("FATX32/n");

#274                 FatInfo.FatType = FATX32;

#275              }

#276              FatInfo.VolumeID = BootFatX->VolumeID;

#277              FatInfo.FATStart = sizeof(struct _BootSectorFatX) / DiskGeometry.BytesPerSector;

#278              FatInfo.FATCount = BootFatX->FATCount;

#279              FatInfo.FATSectors =

#280                    ROUND_UP(FatInfo.Sectors / FatInfo.SectorsPerCluster * (FatInfo.FatType == FATX16 ? 2 : 4), 4096) /

#281                    FatInfo.BytesPerSector;

#282              FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;

#283              FatInfo.RootCluster = (FatInfo.rootStart - 1) / FatInfo.SectorsPerCluster;

#284              FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;

#285              FatInfo.NumberOfClusters = (FatInfo.Sectors - FatInfo.dataStart) / FatInfo.SectorsPerCluster;

#286 

#287              if (pFatInfo && *RecognizedFS)

#288              {

#289                 *pFatInfo = FatInfo;

#290              }

#291           }

#292        }

#293        ExFreePool(BootFatX);

#294     }

#295 

#296     DPRINT("VfatHasFileSystem done/n");

#297     return Status;

#298  }

#299  

你可能感兴趣的:(reactos操作系统实现(137))