加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(137)

发布时间:2020-12-15 04:59:32 所属栏目:百科 来源:网络整理
导读:VfatHasFileSystem 函数主要用来读取 FAT 文件系统信息,并且判断这个磁盘卷是否为 FAT 文件系统,具体实现如下: #001 static NTSTATUS #002 VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount, #003 PBOOLEAN RecognizedFS, #004 PFATINFO pFatInfo) #005 {

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,(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,(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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读