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,(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的分配表不是1或2,就不支持这个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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |