33 if (Index > (Volume->MaxCluster + 1)) {
34 Volume->FatEntryBuffer = (UINT32)-1;
35 return &Volume->FatEntryBuffer;
41 switch (Volume->FatType) {
43 Pos = FAT_POS_FAT12 (Index);
47 Pos = FAT_POS_FAT16 (Index);
51 Pos = FAT_POS_FAT32 (Index);
57 Volume->FatEntryPos = Volume->FatPos + Pos;
63 &Volume->FatEntryBuffer,
66 if (EFI_ERROR (Status)) {
67 Volume->FatEntryBuffer = (UINT32)-1;
70 return &Volume->FatEntryBuffer;
98 if (Index > (Volume->MaxCluster + 1)) {
102 switch (Volume->FatType) {
105 Accum = En12[0] | (En12[1] << 8);
106 Accum = FAT_ODD_CLUSTER_FAT12 (Index) ? (Accum >> 4) : (Accum & FAT_CLUSTER_MASK_FAT12);
107 Accum = Accum | ((Accum >= FAT_CLUSTER_SPECIAL_FAT12) ? FAT_CLUSTER_SPECIAL_EXT : 0);
113 Accum = Accum | ((Accum >= FAT_CLUSTER_SPECIAL_FAT16) ? FAT_CLUSTER_SPECIAL_EXT : 0);
118 Accum = *En32 & FAT_CLUSTER_MASK_FAT32;
119 Accum = Accum | ((Accum >= FAT_CLUSTER_SPECIAL_FAT32) ? FAT_CLUSTER_SPECIAL_EXT : 0);
154 if (Index < FAT_MIN_CLUSTER) {
155 return EFI_VOLUME_CORRUPTED;
159 if ((Value == FAT_CLUSTER_FREE) && (OriginalVal != FAT_CLUSTER_FREE)) {
160 Volume->FatInfoSector.FreeInfo.ClusterCount += 1;
161 if (Index < Volume->FatInfoSector.FreeInfo.NextCluster) {
162 Volume->FatInfoSector.FreeInfo.NextCluster = (UINT32)Index;
164 }
else if ((Value != FAT_CLUSTER_FREE) && (OriginalVal == FAT_CLUSTER_FREE)) {
165 if (Volume->FatInfoSector.FreeInfo.ClusterCount != 0) {
166 Volume->FatInfoSector.FreeInfo.ClusterCount -= 1;
178 switch (Volume->FatType) {
181 Accum = En12[0] | (En12[1] << 8);
182 Value = Value & FAT_CLUSTER_MASK_FAT12;
184 if (FAT_ODD_CLUSTER_FAT12 (Index)) {
185 Accum = (Value << 4) | (Accum & 0xF);
187 Accum = Value | (Accum & FAT_CLUSTER_UNMASK_FAT12);
190 En12[0] = (UINT8)(Accum & 0xFF);
191 En12[1] = (UINT8)(Accum >> 8);
196 *En16 = (UINT16)Value;
201 *En32 = (*En32 & FAT_CLUSTER_UNMASK_FAT32) | (UINT32)(Value & FAT_CLUSTER_MASK_FAT32);
207 if (!Volume->FatDirty && (Volume->FatType != Fat12)) {
208 Volume->FatDirty =
TRUE;
221 Volume->FatEntrySize,
222 &Volume->FatEntryBuffer,
248 while (!FAT_END_OF_FAT_CHAIN (Cluster)) {
249 if ((Cluster == FAT_CLUSTER_FREE) || (Cluster >= FAT_CLUSTER_SPECIAL)) {
250 DEBUG ((DEBUG_INIT | DEBUG_ERROR,
"FatShrinkEof: cluster chain corrupt\n"));
251 return EFI_VOLUME_CORRUPTED;
254 LastCluster = Cluster;
282 if (Volume->DiskError) {
283 return (
UINTN)FAT_CLUSTER_LAST;
290 if (Volume->FatInfoSector.FreeInfo.NextCluster > (Volume->MaxCluster + 1)) {
291 if (Volume->FreeInfoValid && (0 < (INT32)(Volume->FatInfoSector.FreeInfo.ClusterCount))) {
292 Volume->FreeInfoValid =
FALSE;
296 if (Volume->FatInfoSector.FreeInfo.NextCluster > (Volume->MaxCluster + 1)) {
297 return (
UINTN)FAT_CLUSTER_LAST;
301 Cluster =
FatGetFatEntry (Volume, Volume->FatInfoSector.FreeInfo.NextCluster);
302 if (Cluster == FAT_CLUSTER_FREE) {
309 Volume->FatInfoSector.FreeInfo.NextCluster += 1;
312 Cluster = Volume->FatInfoSector.FreeInfo.NextCluster;
313 Volume->FatInfoSector.FreeInfo.NextCluster += 1;
336 Clusters = Size >> Volume->ClusterAlignment;
337 if ((Size & (Volume->ClusterSize - 1)) > 0) {
365 Volume = OFile->Volume;
366 ASSERT_VOLUME_LOCKED (Volume);
373 Cluster = OFile->FileCluster;
374 LastCluster = FAT_CLUSTER_FREE;
377 for (CurSize = 0; CurSize < NewSize; CurSize++) {
378 if ((Cluster == FAT_CLUSTER_FREE) || (Cluster >= FAT_CLUSTER_SPECIAL)) {
379 DEBUG ((DEBUG_INIT | DEBUG_ERROR,
"FatShrinkEof: cluster chain corrupt\n"));
380 return EFI_VOLUME_CORRUPTED;
383 LastCluster = Cluster;
392 if (Cluster == FAT_CLUSTER_FREE) {
399 OFile->FileCluster = FAT_CLUSTER_FREE;
406 OFile->FileCurrentCluster = OFile->FileCluster;
407 OFile->FileLastCluster = LastCluster;
431 IN UINT64 NewSizeInBytes
446 if (NewSizeInBytes > 0x0FFFFFFFFL) {
447 return EFI_UNSUPPORTED;
450 Volume = OFile->Volume;
451 ASSERT_VOLUME_LOCKED (Volume);
458 if (CurSize < NewSize) {
462 if ((OFile->FileCluster != 0) && (OFile->FileLastCluster == 0)) {
463 Cluster = OFile->FileCluster;
466 while (!FAT_END_OF_FAT_CHAIN (Cluster)) {
467 if ((Cluster < FAT_MIN_CLUSTER) || (Cluster > Volume->MaxCluster + 1)) {
469 (DEBUG_INIT | DEBUG_ERROR,
470 "FatGrowEof: cluster chain corrupt\n")
472 Status = EFI_VOLUME_CORRUPTED;
477 OFile->FileLastCluster = Cluster;
481 if (ClusterCount != CurSize) {
483 (DEBUG_INIT | DEBUG_ERROR,
484 "FatGrowEof: cluster chain size does not match file size\n")
486 Status = EFI_VOLUME_CORRUPTED;
494 LastCluster = OFile->FileLastCluster;
496 while (CurSize < NewSize) {
498 if (FAT_END_OF_FAT_CHAIN (NewCluster)) {
499 if (LastCluster != FAT_CLUSTER_FREE) {
501 OFile->FileLastCluster = LastCluster;
504 Status = EFI_VOLUME_FULL;
508 if ((NewCluster < FAT_MIN_CLUSTER) || (NewCluster > Volume->MaxCluster + 1)) {
509 Status = EFI_VOLUME_CORRUPTED;
513 if (LastCluster != 0) {
516 OFile->FileCluster = NewCluster;
517 OFile->FileCurrentCluster = NewCluster;
520 LastCluster = NewCluster;
535 OFile->FileLastCluster = LastCluster;
539 OFile->FileSize = (
UINTN)NewSizeInBytes;
574 Volume = OFile->Volume;
575 ClusterSize = Volume->ClusterSize;
577 ASSERT_VOLUME_LOCKED (Volume);
583 if (OFile->IsFixedRootDir) {
584 OFile->PosDisk = Volume->RootPos + Position;
585 Run = OFile->FileSize - Position;
599 Cluster = OFile->FileCurrentCluster;
600 StartPos = OFile->Position;
601 if ((Position < StartPos) || (OFile->FileCluster == Cluster)) {
603 Cluster = OFile->FileCluster;
606 while (StartPos + ClusterSize <= Position) {
607 StartPos += ClusterSize;
608 if ((Cluster == FAT_CLUSTER_FREE) || (Cluster >= FAT_CLUSTER_SPECIAL)) {
609 DEBUG ((DEBUG_INIT | DEBUG_ERROR,
"FatOFilePosition:" " cluster chain corrupt\n"));
610 return EFI_VOLUME_CORRUPTED;
616 if ((Cluster < FAT_MIN_CLUSTER) || (Cluster > Volume->MaxCluster + 1)) {
617 return EFI_VOLUME_CORRUPTED;
620 OFile->PosDisk = Volume->FirstClusterPos +
621 LShiftU64 (Cluster - FAT_MIN_CLUSTER, Volume->ClusterAlignment) +
623 OFile->FileCurrentCluster = Cluster;
624 OFile->Position = StartPos;
629 Run = StartPos + ClusterSize - Position;
630 if (!FAT_END_OF_FAT_CHAIN (Cluster)) {
631 while ((
FatGetFatEntry (Volume, Cluster) == Cluster + 1) && Run < PosLimit) {
661 ASSERT_VOLUME_LOCKED (Volume);
671 while (!FAT_END_OF_FAT_CHAIN (Cluster)) {
672 if ((Cluster == FAT_CLUSTER_FREE) || (Cluster >= FAT_CLUSTER_SPECIAL)) {
674 (DEBUG_INIT | DEBUG_ERROR,
675 "FATDirSize: cluster chain corrupt\n")
680 Size += Volume->ClusterSize;
704 UINTN ClusterSizeMask;
707 ClusterSizeMask = Volume->ClusterSize - 1;
708 PhysicalSize = (RealSize + ClusterSizeMask) & (~((UINT64)ClusterSizeMask));
729 if (!Volume->FreeInfoValid) {
730 Volume->FreeInfoValid =
TRUE;
731 Volume->FatInfoSector.FreeInfo.ClusterCount = 0;
732 for (Index = Volume->MaxCluster + 1; Index >= FAT_MIN_CLUSTER; Index--) {
733 if (Volume->DiskError) {
738 Volume->FatInfoSector.FreeInfo.ClusterCount += 1;
739 Volume->FatInfoSector.FreeInfo.NextCluster = (UINT32)Index;
743 Volume->FatInfoSector.Signature = FAT_INFO_SIGNATURE;
744 Volume->FatInfoSector.InfoBeginSignature = FAT_INFO_BEGIN_SIGNATURE;
745 Volume->FatInfoSector.InfoEndSignature = FAT_INFO_END_SIGNATURE;
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
EFI_STATUS FatDiskIo(IN FAT_VOLUME *Volume, IN IO_MODE IoMode, IN UINT64 Offset, IN UINTN BufferSize, IN OUT VOID *Buffer, IN FAT_TASK *Task)
EFI_STATUS FatAccessVolumeDirty(IN FAT_VOLUME *Volume, IN IO_MODE IoMode, IN VOID *DirtyValue)
STATIC UINTN FatAllocateCluster(IN FAT_VOLUME *Volume)
UINTN FatPhysicalDirSize(IN FAT_VOLUME *Volume, IN UINTN Cluster)
EFI_STATUS FatGrowEof(IN FAT_OFILE *OFile, IN UINT64 NewSizeInBytes)
EFI_STATUS FatOFilePosition(IN FAT_OFILE *OFile, IN UINTN Position, IN UINTN PosLimit)
STATIC UINTN FatGetFatEntry(IN FAT_VOLUME *Volume, IN UINTN Index)
VOID FatComputeFreeInfo(IN FAT_VOLUME *Volume)
UINT64 FatPhysicalFileSize(IN FAT_VOLUME *Volume, IN UINTN RealSize)
EFI_STATUS FatShrinkEof(IN FAT_OFILE *OFile)
STATIC VOID * FatLoadFatEntry(IN FAT_VOLUME *Volume, IN UINTN Index)
STATIC EFI_STATUS FatSetFatEntry(IN FAT_VOLUME *Volume, IN UINTN Index, IN UINTN Value)
STATIC EFI_STATUS FatFreeClusters(IN FAT_VOLUME *Volume, IN UINTN Cluster)
STATIC UINTN FatSizeToClusters(IN FAT_VOLUME *Volume, IN UINTN Size)
#define DEBUG(Expression)