Changeset 311


Ignore:
Timestamp:
Sep 22, 2017, 5:48:49 PM (3 years ago)
Author:
Valery V. Sedletski
Message:

CHKDSK fixes/enhancements

  • Support for fixing crosslinked clusters.
  • Support for fixing incorrect "." and ".." entries (wrong cluster number).
Location:
trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ifsinf/fat32/fat32.ipf

    r308 r311  
    15081508default cache size is 1024KB&per. Maximum cache size is 2048KB&per. *   
    15091509
     1510.br
     1511
     1512:p.:hp2.Note&colon.  :ehp2.Cache memory is allocated as FIXED memory, so if you have less
     1513than 16MB a setting of 512KB or less for this option is suggested&per.
     1514
    15101515:p.:hp2./AUTOCHECK&colon.<drive letter list> :ehp2.Specifies the drive letters to check on boot&per. If /AUTOCHECK&colon.*
    15111516is specified, CHKDSK will check all FAT32 disks for dirty flag present, and if it is, CHKDSK is run on that drive&per.
     
    15431548Erdmann, and SVDISK&per.SYS by Albert J. Shan, HD4DISK&per.ADD by _dixie_ (included with QSINIT boot loader)&per. The latter
    15441549is successfully tested both with FAT32 PAE ramdisks and with EXFAT ramdisks in lower memory&per.
    1545 
    1546 .br
    1547 
    1548 :p.:hp2.Note&colon.  :ehp2.Cache memory is allocated as FIXED memory, so if you have less
    1549 than 16MB a setting of 512KB or less for this option is suggested&per.
    15501550
    15511551:p.:hp2./MONITOR :ehp2.Set F32MON ON by default&per. If omitted F32MON is OFF&per. See :link reftype=hd refid=49.
  • trunk/src/ufat32/chkdsk.c

    r306 r311  
    4545PRIVATE ULONG CheckDir(PCDINFO pCD, ULONG ulDirCluster, PSZ pszPath, ULONG ulParentDirCluster);
    4646PRIVATE ULONG GetClusterCount(PCDINFO pCD, ULONG ulCluster, PSHOPENINFO pSHInfo, PSZ pszFile);
    47 PRIVATE BOOL   MarkCluster(PCDINFO pCD, ULONG ulCluster, PSZ pszFile);
     47PRIVATE BOOL   MarkCluster(PCDINFO pCD, ULONG ulFirstCluster, ULONG ulCluster, PSHOPENINFO pSHInfo, PSZ pszFile);
    4848PRIVATE PSZ    MakeName(PDIRENTRY pDir, PSZ pszName, USHORT usMax);
    4949PRIVATE ULONG fGetVolLabel(PCDINFO pCD, PSZ pszVolLabel);
    5050PRIVATE BOOL   fGetLongName(PDIRENTRY pDir, PSZ pszName, USHORT wMax);
    5151BOOL   ClusterInUse(PCDINFO pCD, ULONG ulCluster);
    52 PRIVATE BOOL RecoverChain(PCDINFO pCD, ULONG ulCluster);
     52PRIVATE BOOL RecoverChain(PCDINFO pCD, ULONG ulCluster, PSHOPENINFO pSHInfo);
    5353PRIVATE BOOL LostToFile(PCDINFO pCD, ULONG ulCluster, ULONG ulSize);
    5454PRIVATE BOOL ClusterInChain(PCDINFO pCD, ULONG ulStart, ULONG ulCluster);
     
    578578      for (i = 0; i < ulBitmapClusters; i++)
    579579          {
    580           MarkCluster(pCD, ulBitmapFirstCluster + i, "Allocation Bitmap");
     580          MarkCluster(pCD, ulBitmapFirstCluster, ulBitmapFirstCluster + i, NULL, "Allocation Bitmap");
    581581          }
    582582      pCD->ulBmpStartSector = pCD->ulStartOfData +
     
    592592      for (i = 0; i < ulUpCaseClusters; i++)
    593593          {
    594           MarkCluster(pCD, ulUpCaseFirstCluster + i, "UpCase Table");
     594          MarkCluster(pCD, ulUpCaseFirstCluster, ulUpCaseFirstCluster + i, NULL, "UpCase Table");
    595595          }
    596596      }
     
    690690   rc = CheckFreeSpace(pCD);
    691691   pCD->FSInfo.ulFreeClusters = pCD->ulFreeClusters;
     692
     693#ifdef EXFAT
     694   if (pCD->bFatType == FAT_TYPE_EXFAT)
     695      {
     696      // write back the bitmap
     697      ULONG ulCluster = ulBitmapFirstCluster;
     698      char *pBuf = pCD->pFatBits;
     699      while (ulCluster != pCD->ulFatEof)
     700         {
     701         ReadCluster(pCD, ulCluster, pBuf);
     702         ulCluster = GetNextCluster(pCD, NULL, ulCluster, FALSE);
     703         if (!ulCluster)
     704            {
     705            ulCluster = pCD->ulFatEof;
     706            }
     707         pBuf += pCD->ulClusterSize;
     708         }
     709      }
     710#endif
    692711
    693712   if (pCD->fFix)
     
    781800
    782801   mem_free((void *)pCD->pFatBits, usBlocks * 4096);
    783    //free((void *)pCD->pFatBits);
    784802#ifdef EXFAT
    785803   if (pCD->bFatType == FAT_TYPE_EXFAT)
     
    961979         {
    962980         pCD->ulBadClusters++;
    963          MarkCluster(pCD, ulCluster+2, "Bad sectors");
     981         MarkCluster(pCD, ulCluster+2, ulCluster+2, NULL, "Bad sectors");
    964982         }
    965983      else if (!ulNext)
     
    970988#endif
    971989            {
    972             MarkCluster(pCD, ulCluster+2, "Free space");
     990            MarkCluster(pCD, ulCluster+2, ulCluster+2, NULL, "Free space");
    973991            pCD->ulFreeClusters++;
    974992            }
     
    9921010                  fMsg = TRUE;
    9931011                  }
    994                RecoverChain(pCD, ulCluster+2);
     1012               RecoverChain(pCD, ulCluster+2, NULL);
    9951013               }
    9961014            }
     
    13231341                  {
    13241342                  // mark it as deleted
    1325                   pPrevDir = pDir - 1;
     1343                  pPrevDir = pDir;
    13261344                  while (pPrevDir->bAttr == FILE_LONGNAME &&
    13271345                         pPrevDir->bFileName[0] &&
     
    13321350                     }
    13331351                  fModified = TRUE;
     1352
     1353                  show_message("This has been corrected\n", 2439, 0, 0);
    13341354                  }
    13351355               else
     
    15481568                           strcpy(Mark.szFileName, pszBaseName + 1);
    15491569                           }
     1570
    15501571                        strcat(Mark.szFileName, ".EA");
    15511572                        rc = MarkVolume(pCD, TRUE);
     
    17501771                  {
    17511772                  if (ulCluster != ulDirCluster)
     1773                     {
    17521774                     show_message(". entry in %s is incorrect!\n", 2430, 0, 1, pszPath);
     1775                     if (pCD->fFix)
     1776                        {
     1777                        pDir->wCluster = ulDirCluster & 0xffff;
     1778
     1779                        if (pCD->bFatType == FAT_TYPE_FAT32)
     1780                           pDir->wClusterHigh = ulDirCluster >> 16;
     1781
     1782                        if (ulDirCluster == 1)
     1783                           {
     1784                           // reading root directory on FAT12/FAT16
     1785                           ulSector = pCD->BootSect.bpb.ReservedSectors +
     1786                           pCD->BootSect.bpb.SectorsPerFat * pCD->BootSect.bpb.NumberOfFATs +
     1787                           ((((char *)pDir - pbCluster) / pCD->ulClusterSize) * pCD->ulClusterSize) / pCD->BootSect.bpb.BytesPerSector;
     1788                           WriteSector(pCD, ulSector, pCD->SectorsPerCluster, pbCluster + (((char *)pDir - pbCluster) / pCD->ulClusterSize) * pCD->ulClusterSize);
     1789                           }
     1790                        else
     1791                           WriteCluster(pCD, ulDirCluster, pbCluster + (((char *)pDir - pbCluster) / pCD->ulClusterSize) * pCD->ulClusterSize);
     1792
     1793                        show_message("This has been corrected\n", 2439, 0, 0);
     1794                        }
     1795                     }
    17531796                  }
    17541797               else if (!memicmp(pDir->bFileName, "..         ", 11))
    17551798                  {
    17561799                  if (ulCluster != ulParentDirCluster)
     1800                     {
    17571801                     show_message(".. entry in %s is incorrect! (%lX %lX)\n", 2431, 0, 3,
    1758                         pszPath, ulCluster, ulParentDirCluster);
     1802                                  pszPath, ulCluster, ulParentDirCluster);
     1803                     if (pCD->fFix)
     1804                        {
     1805                        pDir->wCluster = ulParentDirCluster & 0xffff;
     1806
     1807                        if (pCD->bFatType == FAT_TYPE_FAT32)
     1808                           pDir->wClusterHigh = ulParentDirCluster >> 16;
     1809
     1810                        if (ulDirCluster == 1)
     1811                           {
     1812                           // reading root directory on FAT12/FAT16
     1813                           ulSector = pCD->BootSect.bpb.ReservedSectors +
     1814                           pCD->BootSect.bpb.SectorsPerFat * pCD->BootSect.bpb.NumberOfFATs +
     1815                           ((((char *)pDir - pbCluster) / pCD->ulClusterSize) * pCD->ulClusterSize) / pCD->BootSect.bpb.BytesPerSector;
     1816                           WriteSector(pCD, ulSector, pCD->SectorsPerCluster, pbCluster + (((char *)pDir - pbCluster) / pCD->ulClusterSize) * pCD->ulClusterSize);
     1817                           }
     1818                        else
     1819                           WriteCluster(pCD, ulDirCluster, pbCluster + (((char *)pDir - pbCluster) / pCD->ulClusterSize) * pCD->ulClusterSize);
     1820
     1821                        show_message("This has been corrected\n", 2439, 0, 0);
     1822                        }
     1823                     }
    17591824                  }
    17601825               else
     
    22812346                        if (lastchar(fs.szFileName) != '\\')
    22822347                           strcat(fs.szFileName, "\\");
    2283                         strcat(fs.szFileName, MakeName((PDIRENTRY)pDir, szShortName, sizeof(szShortName))); ////
     2348                        strcat(fs.szFileName, MakeName((PDIRENTRY)pDir, szShortName, sizeof(szShortName)));
    22842349                        fs.ullFileSize = ulClustersUsed * pCD->ulClusterSize;
    22852350                        rc = SetFileSize(pCD, (PFILESIZEDATA)&fs);
     
    25122577{
    25132578ULONG ulCount;
     2579ULONG ulFirstCluster = ulCluster;
    25142580ULONG ulNextCluster;
    25152581BOOL  fCont = TRUE;
     
    25412607      {
    25422608      ulNextCluster = GetNextCluster(pCD, pSHInfo, ulCluster, FALSE);
    2543       if (!MarkCluster(pCD, ulCluster, pszFile))
     2609      if (!MarkCluster(pCD, ulFirstCluster, ulCluster, pSHInfo, pszFile))
    25442610         return ulCount;
    25452611      ulCount++;
     
    25862652}
    25872653
    2588 BOOL MarkCluster(PCDINFO pCD, ULONG ulCluster, PSZ pszFile)
     2654BOOL   MarkCluster(PCDINFO pCD, ULONG ulFirstCluster, ULONG ulCluster, PSHOPENINFO pSHInfo, PSZ pszFile)
    25892655{
    25902656ULONG ulOffset;
     
    25972663         TYPE_STRING, pszFile,
    25982664         TYPE_LONG, ulCluster);
    2599       pCD->ulErrorCount++;
     2665
     2666      if (pCD->fFix)
     2667         {
     2668         ULONG ulCluster2 = ulFirstCluster;
     2669
     2670         // unmark all file clusters
     2671         while (ulCluster2 != pCD->ulFatEof)
     2672            {
     2673            // clear bit in the bitmap
     2674            ulOffset = (ulCluster2 - 2) / 8;
     2675            usShift = (USHORT)((ulCluster2 - 2) % 8);
     2676            bMask = (BYTE)(1 << usShift);
     2677            pCD->pFatBits[ulOffset] &= ~bMask;
     2678
     2679            ulCluster2 = GetNextCluster(pCD, pSHInfo, ulCluster2, FALSE);
     2680            if (!ulCluster2)
     2681               ulCluster2 = pCD->ulFatEof;
     2682            }
     2683
     2684         // @todo We're saving the second file to FOUNDXXX. How to determine the very 1st one?
     2685         RecoverChain(pCD, ulFirstCluster, pSHInfo);
     2686         // delete the file itself
     2687         DelFile(pCD, pszFile);
     2688         show_message("This has been corrected\n", 2439, 0, 0);
     2689         }
     2690      else
     2691         pCD->ulErrorCount++;
     2692
    26002693      return FALSE;
    26012694      }
     
    26062699   bMask = (BYTE)(1 << usShift);
    26072700   pCD->pFatBits[ulOffset] |= bMask;
     2701
    26082702   return TRUE;
    26092703}
     
    28722966}
    28732967
    2874 BOOL RecoverChain(PCDINFO pCD, ULONG ulCluster)
     2968BOOL RecoverChain(PCDINFO pCD, ULONG ulCluster, PSHOPENINFO pSHInfo)
    28752969{
    28762970ULONG  ulSize;
     
    28932987         while (ulNext != pCD->rgulLost[usIndex])
    28942988            {
    2895             MarkCluster(pCD, ulNext, "Lost cluster");
     2989            MarkCluster(pCD, ulCluster, ulNext, pSHInfo, "Lost cluster");
    28962990            pCD->rgulSize[usIndex]++;
    28972991            pCD->ulLostClusters++;
    2898             ulNext = GetNextCluster(pCD, NULL, ulNext, FALSE);
     2992            ulNext = GetNextCluster(pCD, pSHInfo, ulNext, FALSE);
    28992993            }
    29002994         pCD->rgulLost[usIndex] = ulCluster;
     
    29032997      }
    29042998
    2905    ulSize = GetClusterCount(pCD, ulCluster, NULL, "Lost data");
     2999   ulSize = GetClusterCount(pCD, ulCluster, pSHInfo, "Lost data");
    29063000   if (pCD->usLostChains < MAX_LOST_CHAINS)
    29073001      {
Note: See TracChangeset for help on using the changeset viewer.