示例#1
0
BOOL CopyConsecutiveClusters(RDWRHandle handle, CLUSTER source, CLUSTER dest, unsigned long length)
{
    SECTOR ssource, sdest;
    unsigned long sectorspercluster, i, blocks;
    unsigned rest;
    
    ssource = ConvertToDataSector(handle, source);
    if (!ssource) RETURN_FTEERROR(FALSE);
	
    sdest = ConvertToDataSector(handle, dest);
    if (!sdest) RETURN_FTEERROR(FALSE);
	
    sectorspercluster = GetSectorsPerCluster(handle);
    if (!sectorspercluster) RETURN_FTEERROR(FALSE);
    
    blocks = (length * sectorspercluster) / 32768L;
    rest   = (unsigned)((length * sectorspercluster) % 32768L);
    
    for (i=0; i<blocks; i++)
    {
	if (!CopySectors(handle, ssource, sdest, 32768U))
	    RETURN_FTEERROR(FALSE);
	
	ssource += 32768L;
	sdest   += 32768L;
    }
    
    if (rest > 0)
    {
	if (!CopySectors(handle, ssource, sdest, rest))
	    RETURN_FTEERROR(FALSE);
    }
    
    return TRUE;    
}
示例#2
0
BOOL PreReadClusterSequence(RDWRHandle handle, CLUSTER start,
                            unsigned long length)
{
    char* ReadBuf;
    unsigned BufSize;
    unsigned long blocks, i, sectorstoread;
    unsigned rest;
    unsigned char sectorspercluster;
    SECTOR startsector;

    if (!CacheActive()) return TRUE;
    if (length == 0) return TRUE;

    sectorspercluster = GetSectorsPerCluster(handle);
    if (!sectorspercluster) return FALSE;

    sectorstoread = length * sectorspercluster;
    startsector = ConvertToDataSector(handle, start);
    if (!startsector) return FALSE;

    ReadBuf = AllocateReadBuf(sectorstoread * BYTESPERSECTOR, &BufSize);
    BufSize /= BYTESPERSECTOR;

    blocks = (length * sectorspercluster) / BufSize;
    rest   = (unsigned)((length * sectorspercluster) % BufSize);

    for (i = 0; i < blocks; i++)
    {
        if (!OnlyFilledRead(handle, startsector, BufSize, ReadBuf) == -1)
        {
            FreeReadBuf(ReadBuf);
            return FALSE;
        }

        startsector += BufSize;
    }

    if (rest)
    {
        if (!OnlyFilledRead(handle, startsector, rest, ReadBuf) == -1)
        {
            FreeReadBuf(ReadBuf);
            return FALSE;
        }
    }

    FreeReadBuf(ReadBuf);
    return TRUE;
}
示例#3
0
static BOOL ClusterPreReader(RDWRHandle handle, CLUSTER label,
                             SECTOR datasector, void** structure)
{
    SECTOR  firstsector;
    CLUSTER cluster;
    unsigned char sectorspercluster;
    struct Pipe* pipe = *((struct Pipe**) structure);

    if (label);

    sectorspercluster = GetSectorsPerCluster(handle);
    if (!sectorspercluster) return FAIL;

    if (pipe->maxindex == 0) /* cluster > read buf */
    {
        if (!PreReadLargeCluster(handle, datasector, sectorspercluster,
                                 pipe->buf, pipe->bufsize))
            return FAIL;
    }
    else
    {
        cluster = DataSectorToCluster(handle, datasector);

        if ((pipe->index > 0) &&
                ((pipe->prevcluster != cluster-1) ||
                 (pipe->index == pipe->maxindex)))
        {
            firstsector = ConvertToDataSector(handle, pipe->firstcluster);
            if (!firstsector) return FAIL;

            if (ReadSectors(handle, pipe->index*sectorspercluster,
                            firstsector, pipe->buf) == -1)
            {
                return FAIL;
            }

            pipe->index = 0;
            pipe->firstcluster = cluster;
        }
        else
        {
            pipe->index++;
        }
    }

    pipe->prevcluster = cluster;

    return TRUE;
}
示例#4
0
BOOL PreReadClusterChain(RDWRHandle handle, CLUSTER start)
{
    SECTOR  firstsector;
    char* ReadBuf;
    struct Pipe pipe, *ppipe = &pipe;
    unsigned char sectorspercluster;
    unsigned BufSize;

    if (!CacheActive()) return TRUE;

    sectorspercluster = GetSectorsPerCluster(handle);
    if (!sectorspercluster) return FALSE;

    ReadBuf = AllocateReadBuf(MAX_ALLOCATING, &BufSize);
    BufSize /= BYTESPERSECTOR;

    pipe.buf          = ReadBuf;
    pipe.bufsize      = BufSize;
    pipe.index        = 0;
    pipe.maxindex     = BufSize / sectorspercluster;
    pipe.prevcluster  = 0;
    pipe.firstcluster = start;

    if (!FileTraverseFat(handle, start, ClusterPreReader, (void**) &ppipe))
    {
        FreeReadBuf(ReadBuf);
        return FALSE;
    }

    if (pipe.index)
    {
        firstsector = ConvertToDataSector(handle, pipe.firstcluster);
        if (!firstsector)
        {
            FreeReadBuf(ReadBuf);
            return FALSE;
        }

        if (ReadSectors(handle, pipe.index*sectorspercluster,
                        firstsector, pipe.buf) == -1)
        {
            FreeReadBuf(ReadBuf);
            return FALSE;
        }
    }

    FreeReadBuf(ReadBuf);
    return TRUE;
}
示例#5
0
static BOOL CopyClusters(RDWRHandle handle, CLUSTER source, CLUSTER dest, unsigned long length)
{
    SECTOR ssource, sdest;
    unsigned long sectorspercluster, i, blocks, totallength;
    unsigned rest;    
    
    ssource = ConvertToDataSector(handle, source);
    if (!ssource) RETURN_FTEERROR(FALSE);
	
    sdest = ConvertToDataSector(handle, dest);
    if (!sdest) RETURN_FTEERROR(FALSE);
	
    sectorspercluster = GetSectorsPerCluster(handle);
    if (!sectorspercluster) RETURN_FTEERROR(FALSE);
    
    totallength = length * sectorspercluster;
    
    blocks = totallength / COPY_BLOCK_SIZE;
    rest   = (unsigned)(totallength % COPY_BLOCK_SIZE);    
    
    for (i=0; i<blocks; i++)
    {    
	if (!CopySectors(handle, ssource, sdest, COPY_BLOCK_SIZE))
	    RETURN_FTEERROR(FALSE);

        ssource += COPY_BLOCK_SIZE;
        sdest   += COPY_BLOCK_SIZE;
    }
    
    if (rest > 0)
    {
	if (!CopySectors(handle, ssource, sdest, rest))
	    RETURN_FTEERROR(FALSE);	
    }
    
    return TRUE;    
}
示例#6
0
文件: filessum.c 项目: FDOS/chkdsk
static BOOL DirSizeGetter(RDWRHandle handle, struct DirectoryPosition* pos,
                          void** structure)
{
   BOOL InRoot;
   unsigned long **dirsize = (unsigned long**) structure;
   unsigned char sectorspercluster;
   CLUSTER label;

   pos = pos, handle = handle;
    
   /* Check for loops in the directory structure */ 
   InRoot = IsRootDirPosition(handle, pos);
   if (InRoot == -1) return FAIL;

   if (!InRoot && (pos->offset == 0))
   {
      sectorspercluster = GetSectorsPerCluster(handle);
      if (!sectorspercluster) return FAIL;

      if ((pos->sector % sectorspercluster) == 0) 
      {
         label = DataSectorToCluster(handle, pos->sector);
         if (!label) return FAIL;
         
         if (GetBitfieldBit(fatmap, label))
         {
            return FALSE;
         }
         SetBitfieldBit(fatmap, label);
      }
   }
    
   **dirsize += sizeof(struct DirectoryEntry);

   return TRUE;
}
示例#7
0
static BOOL Relocate1Cluster(RDWRHandle handle,
                             CLUSTER source,
                             CLUSTER destination,
                             CLUSTER pSource)
{
   int labelsize;
   CLUSTER fatpos=0, freecluster, label;
   //BOOL IsInFAT = FALSE;
   SECTOR srcsector, destsector;
   unsigned long sectorspercluster;
   CLUSTER clustervalue;
   BOOL DOTSprocessed=FALSE;
   struct FSInfoStruct FSInfo;

   /* See wether the destination is actually free. */
   if (!GetNthCluster(handle, destination, &label))
      RETURN_FTEERROR(FALSE);
   if (!FAT_FREE(label)) 
      RETURN_FTEERROR(FALSE);
   
   /* Do some preliminary calculations. */
   srcsector = ConvertToDataSector(handle, source);
   if (!srcsector)
      RETURN_FTEERROR(FALSE);
   destsector = ConvertToDataSector(handle, destination);
   if (!destsector)
      RETURN_FTEERROR(FALSE);
   sectorspercluster = GetSectorsPerCluster(handle);
   if (!sectorspercluster)
      RETURN_FTEERROR(FALSE);
         
   /* Get the value that is stored at the source position in the FAT */
   if (!ReadFatLabel(handle, source, &clustervalue))
      RETURN_FTEERROR(FALSE);


   /* Copy all sectors in this cluster to the new position */
   if (!CopySectors(handle, srcsector, destsector, sectorspercluster))
   {
      RETURN_FTEERROR(FALSE);
   }
   
   if (!WriteFatLabel(handle, destination, clustervalue))
   {
      RETURN_FTEERROR(FALSE);
   }

   /* Adjust the pointer to the relocated cluster */
   if (!WriteFatLabel(handle, pSource, destination))
   {
      RETURN_FTEERROR(FALSE);
   }

   if (!WriteFatLabel(handle, source, FAT_FREE_LABEL))
   {
      if (DOTSprocessed)
         AdaptCurrentAndPreviousDirs(handle, source, source);
   
      RETURN_FTEERROR(FALSE);
   }

   /* Adjust FSInfo on FAT32 */
   labelsize = GetFatLabelSize(handle);
   if (labelsize == FAT32)
   {
      if (!GetFreeClusterSearchStart(handle, &freecluster))
         RETURN_FTEERROR(FALSE);
         
      if (source < freecluster) /* source cluster became available */
      {
         if (!ReadFSInfo(handle, &FSInfo))
            RETURN_FTEERROR(FALSE);
    
         WriteFreeClusterStart(&FSInfo, source);
    
         if (!WriteFSInfo(handle, &FSInfo))
            RETURN_FTEERROR(FALSE);          
      }
      
      if ((freecluster == destination) && /* We are relocating to the first */
	  (destination < source))         /* free cluster */
      {
         CLUSTER dummy;     
 
         if (!FindFirstFreeSpace(handle, &dummy, &dummy))
            RETURN_FTEERROR(FALSE);
      }
   }
   
   return TRUE;
}
示例#8
0
static BOOL RelocateFirstCluster(RDWRHandle handle, 
                                 struct DirectoryPosition* pos,
                                 struct DirectoryEntry* entry,
                                 CLUSTER destination)
{
   int labelsize;
   CLUSTER fatpos=0, freecluster, label;
   BOOL IsInFAT = FALSE;
   SECTOR srcsector, destsector;
   unsigned long sectorspercluster;
   CLUSTER clustervalue;
   BOOL DOTSprocessed=FALSE;
   struct FSInfoStruct FSInfo;
   CLUSTER source;

   /* Do some preliminary calculations. */
   source = GetFirstCluster(entry);

   srcsector = ConvertToDataSector(handle, source);
   if (!srcsector)
      RETURN_FTEERROR(FALSE);
   destsector = ConvertToDataSector(handle, destination);
   if (!destsector)
      RETURN_FTEERROR(FALSE);
   sectorspercluster = GetSectorsPerCluster(handle);
   if (!sectorspercluster)
      RETURN_FTEERROR(FALSE);

   /* Get the value that is stored at the source position in the FAT */
   if (!ReadFatLabel(handle, source, &clustervalue))
      RETURN_FTEERROR(FALSE);
   
   /* We know the first cluster is refered to in the directory entry given */
    /*
    This is the first cluster of some file. See if it is a directory
    and if it is, adjust the '.' entry of this directory and all
    of the '..' entries of all the (direct) subdirectories to point
    to the new cluster.
    */
    if (entry->attribute & FA_DIREC)
    {
        if (!AdaptCurrentAndPreviousDirs(handle, source, destination))
        {
            RETURN_FTEERROR(FALSE);
        }
        DOTSprocessed = TRUE;
    }

   /* Copy all sectors in this cluster to the new position */
   if (!CopySectors(handle, srcsector, destsector, sectorspercluster))
   {
      RETURN_FTEERROR(FALSE);
   }
   
   /* Write the entry in the FAT */
   if (!WriteFatLabel(handle, destination, clustervalue))
   {
      RETURN_FTEERROR(FALSE);
   }

   SetFirstCluster(destination, entry);
   if (!WriteDirectory(handle, pos, entry))
   {
        RETURN_FTEERROR(FALSE);
   }

//   if (!GetNthCluster(handle, source, &label))
//        return FALSE;

   if (!WriteFatLabel(handle, source, FAT_FREE_LABEL))
   {
      RETURN_FTEERROR(FALSE);
   }

   /* Adjust FSInfo on FAT32 */
   labelsize = GetFatLabelSize(handle);
   if (labelsize == FAT32)
   {
      if (!GetFreeClusterSearchStart(handle, &freecluster))
         RETURN_FTEERROR(FALSE);
         
      if (source < freecluster) /* source cluster became available */
      {
         if (!ReadFSInfo(handle, &FSInfo))
            RETURN_FTEERROR(FALSE);
    
         WriteFreeClusterStart(&FSInfo, source);
    
         if (!WriteFSInfo(handle, &FSInfo))
            RETURN_FTEERROR(FALSE);          
      }
      
      if ((freecluster == destination) && /* We are relocating to the first */
	  (destination < source))         /* free cluster */
      {
         CLUSTER dummy;     
 
         if (!FindFirstFreeSpace(handle, &dummy, &dummy))
            RETURN_FTEERROR(FALSE);
      }
   }
   
   return TRUE;
}
示例#9
0
BOOL ScanFileChain(RDWRHandle handle, CLUSTER firstcluster,
                   struct DirectoryPosition* pos, 
                   struct DirectoryEntry* entry,
                   char* filename,
                   BOOL fixit)
{
    char* bitfield;
    unsigned long labelsinfat;    
    BOOL breakoff = FALSE;
    CLUSTER current = firstcluster, label, breakingcluster, lengthBreakingCluster=0;  
    unsigned long length = 0, calculatedsize, bytespercluster;
    static char tempbuf[255];   
    BOOL retVal = TRUE;

    /* If it is a root directory that we have to scan see wether it is
       a FAT32 volume and if it is get the root cluster */ 
    if (!firstcluster)
    {
       switch (GetFatLabelSize(handle))
       {
          case FAT12:
          case FAT16:
               return TRUE;
               
          case FAT32:
               current = GetFAT32RootCluster(handle);
               break; 
               
          default:
               return FAIL;
       }
    }
    else
    {
       bytespercluster = GetSectorsPerCluster(handle) * BYTESPERSECTOR;
       if (!bytespercluster) return FAIL;   
       
       calculatedsize = (entry->filesize / bytespercluster) +
                                   ((entry->filesize % bytespercluster) > 0);       
    }
      
    labelsinfat = GetLabelsInFat(handle);
    if (!labelsinfat) return FAIL;
  
    bitfield = CreateBitField(labelsinfat);
    if (!bitfield)
    {        
       DestroyBitfield(bitfield);
       return FAIL;  
    }
    
    SetBitfieldBit(bitfield, current);  
    
    /* Initialise the checks on the directory entries */
    if (entry->attribute & FA_DIREC)
    {
       InitClusterEntryChecking(handle, current, filename);
    
       switch (PreProcessClusterEntryChecking(handle, current, filename, fixit))
       {
          case FALSE:
               retVal = FALSE;              
               break;
               
          case FAIL:
               DestroyBitfield(bitfield);
               DestroyClusterEntryChecking(handle, current, filename);
               return FAIL;
       }
    }
    
    while (TRUE)
    {   
        length++;
  

        if (!GetNthCluster(handle, current, &label))
        {
           DestroyBitfield(bitfield);
           if (entry->attribute & FA_DIREC)
              DestroyClusterEntryChecking(handle, current, filename);           
           return FAIL;
        }
         
        /* Check the read cluster: */
        /* the last cluster */
        if (FAT_LAST(label))
        {
           if (entry->attribute & FA_DIREC) /* Here the current cluster is valid */
           {            
              switch (CheckEntriesInCluster(handle, current, filename, fixit))
              {
                  case FALSE:
                       retVal = FALSE;                                
                       break;
                   
                  case FAIL:
                       DestroyBitfield(bitfield);     
                       if (entry->attribute & FA_DIREC)
                          DestroyClusterEntryChecking(handle, current, filename);                 
                       return FAIL;                   
              }
           }                        
           break;                 
        }
        
        /* Check wether it is in range */
        if (FAT_NORMAL(label) && !IsLabelValid(handle, label))
        {
           if (firstcluster)
           {
              ShowFileNameViolation(handle, filename,
                                    "%s contains an invalid cluster");
           }     
           else
           {
              ShowFileNameViolation(handle, filename,
                                     "The root directory contains an invalid cluster");           
           }   
               
           breakoff = TRUE;
           breakingcluster = current;
           retVal = FALSE;                         
        }
        
        /* bad cluster */                                         
        if (FAT_BAD(label))
        {
           if (firstcluster)
           {
              ShowFileNameViolation(handle, filename,
                                    "%s contains a bad cluster");
           }     
           else
           {
              ShowFileNameViolation(handle, filename,
                                    "The root directory contains a bad cluster");           
           }     
           
           breakingcluster = current;
           breakoff = TRUE;
           retVal = FALSE;                         
        }       
                       
        if (FAT_FREE(label))
        {
           if (firstcluster)
           {
              ShowFileNameViolation(handle, filename,
                                     "%s contains a free cluster");
           }     
           else
           {
              ShowFileNameViolation(handle, filename,
                                     "The root directory contains a free cluster");           
           }
             
           breakoff = TRUE;      
           breakingcluster = current;     
           retVal = FALSE;                         
        }
                 
        /* Check wether there is a loop */
        if (!breakoff && GetBitfieldBit(bitfield, label))
        {
           if (firstcluster)
           {
              ShowFileNameViolation(handle, filename,
                                    "%s contains a loop");
           }     
           else
           {
              ShowFileNameViolation(handle, filename,
                                    "The root directory contains a loop");           
           }
                
           breakoff = TRUE;      
           breakingcluster = current;              
           retVal = FALSE;                     
        }
/*
        if ((firstcluster && ((entry->attribute & FA_DIREC) == 0)) &&
            (length > calculatedsize)                              &&
            (lengthBreakingCluster == 0))
        {
           lengthBreakingCluster = current;
        }
*/        
        if (breakoff)
        {
           if (fixit)
           {        
              if (!WriteFatLabel(handle, breakingcluster, FAT_LAST_LABEL))
              {
                 DestroyBitfield(bitfield);     
                 if (entry->attribute & FA_DIREC)
                    DestroyClusterEntryChecking(handle, current, filename);                 
                 return FAIL;
              }
           }
                
           break;
        }
        SetBitfieldBit(bitfield, label);  
      
        if (entry->attribute & FA_DIREC) /* Here the current cluster is valid */
        {            
           switch (CheckEntriesInCluster(handle, current, filename, fixit))
           {
              case FALSE:
                   retVal = FALSE;                                
                   break;
                   
              case FAIL:
                   DestroyBitfield(bitfield);     
                   if (entry->attribute & FA_DIREC)
                      DestroyClusterEntryChecking(handle, current, filename);                 
                   return FAIL;                   
           }
        }
        
        current = label;  
    }
    
    /* Check the length of the file */
    if (firstcluster)
    {
/*            
       if (((entry->attribute & FA_DIREC) == 0) && (length > calculatedsize))
       {
          sprintf(tempbuf, 
                  "%%s has an invalid size, the size should be about %lu, but the entry says it's %lu",
                  length * bytespercluster, entry->filesize);     

          ShowFileNameViolation(handle, filename, tempbuf);
          
          if (fixit &&
              !WriteFatLabel(handle, lengthBreakingCluster, FAT_LAST_LABEL))
          {
             DestroyBitfield(bitfield);     
             if (entry->attribute & FA_DIREC)
                DestroyClusterEntryChecking(handle, current, filename);             
             return FAIL;
          }    
 
          retVal = FALSE;                                   
       }                       
*/     

       if (((entry->attribute & FA_DIREC) == 0) && (length != calculatedsize))
       {            
          sprintf(tempbuf, 
                  "%%s has an invalid size, the size should be about %lu, but the entry says it's %lu",
                  length * bytespercluster, entry->filesize);     


          ShowFileNameViolation(handle, filename, tempbuf); 
       
          if (fixit)
          {
             /* Notice that we are modifying the filesize of the same entry in chkentrs.c,
                the entry shall be written to disk there. */     
             entry->filesize = length * bytespercluster;          
          }
          
          retVal = FALSE;                       
       }
    }
    
    /* Destroy the checks on the directory entries */
    if (entry->attribute & FA_DIREC)
    {
       switch (PostProcessClusterEntryChecking(handle, current, filename, fixit))
       {
          case FALSE:
               retVal = FALSE;                           
               break;
               
          case FAIL:
               retVal = FAIL;
       }
       
       DestroyClusterEntryChecking(handle, current, filename);     
    }
   
    DestroyBitfield(bitfield);
    return retVal;
}
示例#10
0
文件: RelocClt.c 项目: FDOS/chkdsk
/* This function returns FALSE if the destination is not free. */
BOOL RelocateCluster(RDWRHandle handle, CLUSTER source, CLUSTER destination)
{
   int labelsize, value;
   CLUSTER fatpos=0, freecluster, dircluster, label;
   struct DirectoryPosition dirpos;
   struct DirectoryEntry entry;
   BOOL IsInFAT = FALSE;
   SECTOR srcsector, destsector;
   unsigned long sectorspercluster;
   CLUSTER clustervalue;
   BOOL found, DOTSprocessed=FALSE;
   struct FSInfoStruct FSInfo;

   if (!FatReferedMap)
   {
	if (!CreateFatReferedMap(handle))
	    return FALSE;
   }

   /* See wether the destination is actually free. */
   if (!GetNthCluster(handle, destination, &label))
      RETURN_FTEERROR(FALSE);
   if (!FAT_FREE(label)) 
      RETURN_FTEERROR(FALSE);
   
   /* Do some preliminary calculations. */
   srcsector = ConvertToDataSector(handle, source);
   if (!srcsector)
      RETURN_FTEERROR(FALSE);
   destsector = ConvertToDataSector(handle, destination);
   if (!destsector)
      RETURN_FTEERROR(FALSE);
   sectorspercluster = GetSectorsPerCluster(handle);
   if (!sectorspercluster)
      RETURN_FTEERROR(FALSE);
         
   /* Get the value that is stored at the source position in the FAT */
   if (!ReadFatLabel(handle, source, &clustervalue))
      RETURN_FTEERROR(FALSE);
   
   /* See where the cluster is refered */
   if (!GetVFSBitfieldBit(FatReferedMap, source, &value))
      return FALSE;

   if (value)
   {//CLUSTER fatpos1;

	if (!FindClusterInFAT(handle, source, &fatpos))
	    RETURN_FTEERROR(FALSE);
/*
        if (!FindClusterInFAT1(handle, source, &fatpos1))
            RETURN_FTEERROR(FALSE);

        if (fatpos != fatpos1)
            printf("hola");
*/
   }
      
   if (!fatpos)
   {
      if (!FindClusterInDirectories(handle, source, &dirpos, &found))
         RETURN_FTEERROR(FALSE);
      if (!found)
      {
          /* Note: on FAT32 this cluster may be pointing to the root directory.
                   We do not support relocating the root cluster at this time.          
          */
          
          
          RETURN_FTEERROR(FALSE);                /* Non valid cluster! */
      }
      else
      {
         /*
            This is the first cluster of some file. See if it is a directory
            and if it is, adjust the '.' entry of this directory and all
            of the '..' entries of all the (direct) subdirectories to point
            to the new cluster.
         */
         if (!GetDirectory(handle, &dirpos, &entry))
            RETURN_FTEERROR(FALSE);
            
         if (entry.attribute & FA_DIREC)
         {
            dircluster = GetFirstCluster(&entry);
            if (!AdaptCurrentAndPreviousDirs(handle, dircluster, destination))
            {
               RETURN_FTEERROR(FALSE);
            }
            DOTSprocessed = TRUE;
         }
      }
   }
   else
   {
      IsInFAT = TRUE;
   }

   /* Copy all sectors in this cluster to the new position */
   if (!CopySectors(handle, srcsector, destsector, sectorspercluster))
   {
      if (DOTSprocessed)
         AdaptCurrentAndPreviousDirs(handle, dircluster, source);
      RETURN_FTEERROR(FALSE);
   }
   
   /* Write the entry in the FAT */
   if (!WriteFatReference(handle, destination, clustervalue))
   {
      if (DOTSprocessed)
         AdaptCurrentAndPreviousDirs(handle, dircluster, source);
      RETURN_FTEERROR(FALSE);
   }

   if (!WriteFatLabel(handle, destination, clustervalue))
   {
      if (DOTSprocessed)
         AdaptCurrentAndPreviousDirs(handle, dircluster, source);
      RETURN_FTEERROR(FALSE);
   }

   /* Adjust the pointer to the relocated cluster */
   if (IsInFAT)
   {
      if (!WriteFatReference(handle, fatpos, destination))
      {
         RETURN_FTEERROR(FALSE);
      }

      if (!WriteFatLabel(handle, fatpos, destination))
      {
         RETURN_FTEERROR(FALSE);
      }

      if (!ClearVFSBitfieldBit(FatReferedMap, source))
	  return FALSE;
      if (!SetVFSBitfieldBit(FatReferedMap, destination))
	  return FALSE;
      //if (!IndicateFatClusterMoved(fatpos, source, destination))
      //   return FALSE;
   }
   else
   {
      CLUSTER label;

      if (!GetDirectory(handle, &dirpos, &entry))
      {
         if (DOTSprocessed)
            AdaptCurrentAndPreviousDirs(handle, dircluster, source);
      
         RETURN_FTEERROR(FALSE);
      }
      
      SetFirstCluster(destination, &entry);
      if (!WriteDirectory(handle, &dirpos, &entry))
      {
         if (DOTSprocessed)
            AdaptCurrentAndPreviousDirs(handle, dircluster, source);
      
         RETURN_FTEERROR(FALSE);
      }

      if (!IndicateDirEntryMoved(source, destination))
	  return FALSE;

     if (!GetNthCluster(handle, source, &label))
         return FALSE;

     //if (!IndicateFatClusterMoved(label, source, destination))
     //   return FALSE;
   }

   if (!WriteFatReference(handle, source, FAT_FREE_LABEL))
   {
      if (DOTSprocessed)
         AdaptCurrentAndPreviousDirs(handle, dircluster, source);
   
      RETURN_FTEERROR(FALSE);
   }

   if (!WriteFatLabel(handle, source, FAT_FREE_LABEL))
   {
      if (DOTSprocessed)
         AdaptCurrentAndPreviousDirs(handle, dircluster, source);
   
      RETURN_FTEERROR(FALSE);
   }

   if (!IndicateDirClusterMoved(handle, source, destination))
      RETURN_FTEERROR(FALSE);
      
   /* Adjust FSInfo on FAT32 */
   labelsize = GetFatLabelSize(handle);
   if (labelsize == FAT32)
   {
      if (!GetFreeClusterSearchStart(handle, &freecluster))
         RETURN_FTEERROR(FALSE);
         
      if (source < freecluster) /* source cluster became available */
      {
         if (!ReadFSInfo(handle, &FSInfo))
            RETURN_FTEERROR(FALSE);
    
         WriteFreeClusterStart(&FSInfo, source);
    
         if (!WriteFSInfo(handle, &FSInfo))
            RETURN_FTEERROR(FALSE);          
      }
      
      if ((freecluster == destination) && /* We are relocating to the first */
	  (destination < source))         /* free cluster */
      {
         CLUSTER dummy;     
 
         if (!FindFirstFreeSpace(handle, &dummy, &dummy))
            RETURN_FTEERROR(FALSE);
      }
   }
   
   return TRUE;
}
示例#11
0
文件: filessum.c 项目: FDOS/chkdsk
static BOOL FilesSummaryGetter(RDWRHandle handle,
			       struct DirectoryPosition* position,
			       struct DirectoryEntry* entry,
                               void** structure)
{
    CLUSTER firstcluster;
    struct FilesSummary** info = (struct FilesSummary**) structure;
    unsigned long dirsize=0, *pdirsize = &dirsize, bytespercluster, labelsinfat;

    position = position;

    bytespercluster = GetSectorsPerCluster(handle) * BYTESPERSECTOR;
    if (!bytespercluster) return FAIL;

    if (entry->attribute & FA_LABEL)
       return TRUE;

    if (IsLFNEntry(entry))
       return TRUE;
    if (IsDeletedLabel(*entry))
       return TRUE;

    if (entry->attribute & FA_DIREC)
    {
       if (IsCurrentDir(*entry))  return TRUE;
       if (IsPreviousDir(*entry)) return TRUE;

       (*info)->DirectoryCount++;

       labelsinfat = GetLabelsInFat(handle);
       if (!labelsinfat) return FAIL;
       
       fatmap = CreateBitField(labelsinfat);
       if (!fatmap) return FAIL;
      
       firstcluster = GetFirstCluster(entry);
       if (!TraverseSubdir(handle, firstcluster, DirSizeGetter,
                           (void**) &pdirsize, FALSE))
       {
          return FAIL;
       }

       DestroyBitfield(fatmap);
       
       AddUlongLong(&(*info)->SizeOfDirectories[0],dirsize);

       return TRUE;     /* Not taking directories into account when
                           gathering information on files. */
    }

    (*info)->TotalFileCount++;

    AddUlongLong(&(*info)->TotalSizeofFiles[0],entry->filesize);
    AddUlongLong(&(*info)->SizeOfAllFiles[0],
                 CalculateClustersSize(entry->filesize, bytespercluster));

    if (entry->attribute & FA_SYSTEM)
    {
       (*info)->SystemFileCount++;

       AddUlongLong(&(*info)->SizeOfSystemFiles[0],
                    CalculateClustersSize(entry->filesize, bytespercluster));
    }

    if (entry->attribute & FA_HIDDEN)
    {
       (*info)->HiddenFileCount++;

       AddUlongLong(&(*info)->SizeOfHiddenFiles[0],
                    CalculateClustersSize(entry->filesize, bytespercluster));

    }

    return TRUE;
}
示例#12
0
/*
   Beware of circular references:

	fatpos1 = cluster2
	cluster1 = clustervalue2

       A -> B -> C
      
       D -> A -> B

       D -> A -> B -> C => D -> B -> A -> C 


       A: C

       A: A        /
       B: B        A 

       D: B
         



	cluster1 = fatpos2
	clustervalue1 = cluster2

       A -> B -> C

       B -> C -> D

       A -> B -> C -> D => A -> C -> B -> D    


       C: C      B

       A: C       
       B: D

       B: B      /
       
*/ 
  
BOOL SwapClusters (RDWRHandle handle, CLUSTER clust1, CLUSTER clust2) 
{  
	BOOL found, IsInFAT1 = FALSE, IsInFAT2 = FALSE, error = FALSE;
	CLUSTER freeclust, clustervalue1, fatpos1, fatpos2;  
	CLUSTER clustervalue2, dircluster1, dircluster2;  
	unsigned char sectorspercluster;  
	SECTOR startsector;
	struct DirectoryPosition dirpos1, dirpos2;
	struct DirectoryEntry entry;
	unsigned long neededmem;
	void *MemCluster;
	BOOL DOTSProcessed1, DOTSProcessed2;
	SECTOR srcsector, destsector;
  
    /* First check wether we shouldn't be using RelocateCluster instead. */ 
    if (!ReadFatLabel (handle, clust1, &clustervalue1))
		return FALSE;
  
	if (!ReadFatLabel (handle, clust2, &clustervalue2))    
		return FALSE;
  
	if (FAT_FREE (clustervalue1) && (FAT_FREE (clustervalue2)))
    {
		return TRUE;
	}
  
	if (FAT_FREE (clustervalue1))
    {
		return RelocateCluster (handle, clust2, clust1);
	}
	
	if (FAT_FREE (clustervalue2))
	{
		return RelocateCluster (handle, clust1, clust2);
	}
  
    /* See if we have enough memory to load the data for one cluster
       into memory.                                               */ 
    sectorspercluster = GetSectorsPerCluster (handle);
	if (!sectorspercluster)
		return FALSE;

	neededmem = sectorspercluster * BYTESPERSECTOR;
	MemCluster = malloc (neededmem);
	if (MemCluster)
	{
		/* First prepare the first cluster. */ 
		/* See where the cluster is refered */ 
		/* In FAT? */ 
		if (!FindClusterInFAT (handle, clust1, &fatpos1))
		{
			free (MemCluster);
			return FALSE;
		}

		/* No, then look if this is the first cluster of a file. */ 
		if (!fatpos1)
		{
			if (!FindClusterInDirectories (handle, clust1, &dirpos1, &found))
			{
				free (MemCluster);
				return FALSE;
			}
			
			if (!found)
			{
				free (MemCluster);
				return FALSE;	/* Non valid cluster! */
			}
			else
			{
				/*
				   Special case: if this is the first cluster of a directory
				   then adjust all the . and .. pointers to 
				   reflect the new position on the volume.
				*/ 
				if (!GetDirectory (handle, &dirpos1, &entry))
				{
					free (MemCluster);
					return FALSE;
				}
	      
				if (entry.attribute & FA_DIREC)
				{
					dircluster1 = GetFirstCluster (&entry);
		  
					if (!AdaptCurrentAndPreviousDirs(handle, dircluster1, clust2))
					{
						AdaptCurrentAndPreviousDirs (handle, dircluster1,
													 clust1);
						free (MemCluster);
						return FALSE;
					}
					DOTSProcessed1 = TRUE;
				}
	    
			}
	
		}
		else
		{
			IsInFAT1 = TRUE;
		}
      
		/* Then prepare the second cluster. */ 
		/* See where the cluster is refered */ 
		/* In FAT? */ 
		if (!FindClusterInFAT (handle, clust2, &fatpos2))
		{
			if (DOTSProcessed1)
				AdaptCurrentAndPreviousDirs (handle, dircluster1, clust1);

			free (MemCluster);
			return FALSE;
		}
      
		/* No, then look if this is the first cluster of a file. */ 
		if (!fatpos2)
		{
			if (!FindClusterInDirectories (handle, clust2, &dirpos2, &found))
			{
				if (DOTSProcessed1)
					AdaptCurrentAndPreviousDirs (handle, dircluster1, clust1);
	      
				free (MemCluster);
				return FALSE;
			}
	  
			if (!found)
			{
				if (DOTSProcessed1)
					AdaptCurrentAndPreviousDirs (handle, dircluster1, clust1);
	      
				free (MemCluster);
				return FALSE;	/* Non valid cluster! */
	    
			}
			else
			{
				/*
				   Special case: if this is the first cluster of a directory
				   then adjust all the . and .. pointers to 
				   reflect the new position on the volume.
				*/ 
				if (!GetDirectory (handle, &dirpos2, &entry))
				{
					if (DOTSProcessed1)
						AdaptCurrentAndPreviousDirs (handle, dircluster1,
													 clust1);
		  
					free (MemCluster);
					return FALSE;
		
				}
	      
				if (entry.attribute & FA_DIREC)
				{
					dircluster2 = GetFirstCluster (&entry);
		  
					if (!AdaptCurrentAndPreviousDirs(handle, dircluster2, clust1))
					{
						AdaptCurrentAndPreviousDirs (handle, dircluster2, clust2);
		      
						AdaptCurrentAndPreviousDirs (handle, dircluster1, clust1);
		      
						free (MemCluster);
						return FALSE;
					}
					DOTSProcessed2 = TRUE;
				}
			}
		}
		else
		{
			IsInFAT2 = TRUE;
		}
      
		startsector = ConvertToDataSector (handle, clust1);
		if (!startsector)
		{
			if (DOTSProcessed1)
				AdaptCurrentAndPreviousDirs (handle, dircluster1, clust1);
	  
			if (DOTSProcessed2)
				AdaptCurrentAndPreviousDirs (handle, dircluster2, clust2);
	
			free (MemCluster);
			return FALSE;
		}
      
		/* Then copy the data of the second cluster to the new position */ 
		/* Copy all sectors in this cluster to the new position */ 
		srcsector = ConvertToDataSector (handle, clust2);      
		if (!srcsector)
		{
			if (DOTSProcessed1)
				AdaptCurrentAndPreviousDirs (handle, dircluster1, clust1);
	  
			if (DOTSProcessed2)
				AdaptCurrentAndPreviousDirs (handle, dircluster2, clust2);
	  
			free (MemCluster);
			return FALSE;
		}
      
		destsector = ConvertToDataSector (handle, clust1);
		if (!startsector)
		{
			if (DOTSProcessed1)
				AdaptCurrentAndPreviousDirs (handle, dircluster1, clust1);
	  
			if (DOTSProcessed2)
				AdaptCurrentAndPreviousDirs (handle, dircluster2, clust2);
	  
			free (MemCluster);
			return FALSE;
		}
      
		/* AS OF THIS POINT WE WILL NOT BE ABLE TO BACKTRACK,
		   THEREFORE WE KEEP ON GOING EVEN IF THERE WERE ERRORS. */ 
		/* Change the pointers of the first cluster that has to be moved
		   to the second cluster. */ 
		/* Write the entry in the FAT */ 
		if (clust2 == clustervalue1)	/* Beware of circular references */
		{
			if (!WriteFatLabel (handle, clust2, clust1))
				error = TRUE;
		}
		else
		{
			if (!WriteFatLabel (handle, clust2, clustervalue1))
				error = TRUE;
		}
      
		/* Adjust the pointer to the relocated cluster */ 
		if (IsInFAT1)		/* the previous one in the file */
		{
			if (fatpos1 != clust2)	/* Beware of circular references */
			{
				if (!WriteFatLabel (handle, fatpos1, clust2))
					error = TRUE;
			}
		}
		else			/* or the directory entry to the file */
		{
			if (!GetDirectory (handle, &dirpos1, &entry))
				error = TRUE;

			if (GetFirstCluster (&entry) != clust2)
			{
				SetFirstCluster (clust2, &entry);
				if (!WriteDirectory (handle, &dirpos1, &entry))
					error = TRUE;
			}
		}
      
		/* Change the pointers of the second cluster that has to be moved
		   to the first cluster. */ 
		/* Write the entry in the FAT */ 
		if (clust1 == clustervalue2)	/* Beware of circular references */
		{
			if (!WriteFatLabel (handle, clust1, clustervalue1))
				error = TRUE;
		}
		else
		{
			if (!WriteFatLabel (handle, clust1, clustervalue2))
				error = TRUE;
		}
      
		/* Adjust the pointer to the relocated cluster */ 
		if (IsInFAT2)		/* the previous one in the file */
		{
			if (fatpos2 != clust1)	/* Beware of circular references */
			{
				if (!WriteFatLabel (handle, fatpos2, clust1))
				error = TRUE;
			}
		}
		else			/* or the directory entry to the file */
		{
			if (!GetDirectory (handle, &dirpos2, &entry))
				error = TRUE;
	  
			if (GetFirstCluster (&entry) != clust1)	/* Beware of circular references */
			{
				SetFirstCluster (clust1, &entry);
				if (!WriteDirectory (handle, &dirpos2, &entry))
					error = TRUE;
			}