コード例 #1
0
ファイル: relocchn.c プロジェクト: CivilPol/sdcboot
static BOOL GetNextConsecutiveChain(RDWRHandle handle, CLUSTER source, unsigned long* length)
{
    CLUSTER current = source, label;
    
    if (!GetNthCluster(handle, source, &label))
	RETURN_FTEERROR(FALSE);
    
    *length = 0;
    
    while (FAT_NORMAL(label))
    {
	if (label != current+1)
	{
	   return TRUE;        	    	    
	}	
	
	(*length)++;
	
	if (!GetNthCluster(handle, current, &label))
	    RETURN_FTEERROR(FALSE);
    }
    
    (*length)++;
    return TRUE;    
}
コード例 #2
0
ファイル: RelocClt.c プロジェクト: FDOS/chkdsk
static BOOL CreateFatReferedMap(RDWRHandle handle)
{
    unsigned long LabelsInFat;
    CLUSTER current, label;

    LabelsInFat = GetLabelsInFat(handle);
    if (!LabelsInFat) return FAIL;
        
    FatReferedMap = CreateVFSBitField(handle, LabelsInFat);
    if (!FatReferedMap) return FAIL;

    for (current = 2; current < LabelsInFat; current++)
    {
	if (!GetNthCluster(handle, current, &label))
	    return FALSE;

	if (FAT_NORMAL(label))
	{
	    if (!SetVFSBitfieldBit(FatReferedMap, label))
		return FALSE;	
	}    
    }

    return TRUE;
}
コード例 #3
0
ファイル: relocchn.c プロジェクト: CivilPol/sdcboot
static BOOL CleanFatLabelChain(RDWRHandle handle, CLUSTER source)
{
    CLUSTER label;
    
    do {
	
	if (!GetNthCluster(handle, source, &label))
	    RETURN_FTEERROR(FALSE);	
	
	if (!WriteFatLabel(handle, source, FAT_FREE_LABEL))
	    RETURN_FTEERROR(FALSE);	
	
	source = label;
	
    } while (FAT_NORMAL(label));
    
    return TRUE;
}
コード例 #4
0
ファイル: relocfil.c プロジェクト: CivilPol/sdcboot
static BOOL GetNextConsecutiveChain(RDWRHandle handle, CLUSTER source, unsigned long maxlength, unsigned long* length)
{
    CLUSTER current = source, label;
    unsigned long retLength;
    
    if (!GetNthCluster(handle, source, &label))
	RETURN_FTEERROR(FALSE);
    
    for (retLength=1; 
	 FAT_NORMAL(label) && (label == ++current) && (retLength < maxlength);
         retLength++)    
    {
	if (!GetNthCluster(handle, current, &label))
	    RETURN_FTEERROR(FALSE);
    }
    
    *length = retLength;
    return TRUE;    
}
コード例 #5
0
ファイル: relocchn.c プロジェクト: CivilPol/sdcboot
static BOOL CopyClusterChain(RDWRHandle handle, CLUSTER source, CLUSTER dest)
{
    unsigned long length;
    
    do {
        if (!GetNextConsecutiveChain(handle, source, &length))
	   RETURN_FTEERROR(FALSE);
    
	if (!CopyConsecutiveClusters(handle, source, dest, length))
	    RETURN_FTEERROR(FALSE);
	
	dest += length;
	
	if (!GetNthCluster(handle, source+length-1, &source))
	    RETURN_FTEERROR(FALSE);
	
    } while (FAT_NORMAL(source));
    
    
    return TRUE;
}
コード例 #6
0
ファイル: frag.c プロジェクト: CivilPol/sdcboot
CLUSTER random_cluster(RDWRHandle handle, unsigned long labelsinfat)
{
    unsigned long randomnumber;
    unsigned random1, random2;
    CLUSTER label;

    int fatlabelsize = GetFatLabelSize(handle);
    if (!fatlabelsize) return FALSE;

    random1 = rand() * (labelsinfat % 65536L);
    random2 = rand() * (labelsinfat / 65536L);

    randomnumber = random1 * 65536L + random2;

    randomnumber = (randomnumber % (labelsinfat-2))+2;

    while (TRUE)
    {
        if (fatlabelsize == FAT32)
        {
            if (randomnumber == GetFAT32RootCluster(handle))
            {
                randomnumber++;
                continue;
            }
        }

        if (!GetNthCluster(handle, randomnumber, &label))
            return FALSE;
        
        if (FAT_NORMAL(label) || FAT_LAST(label))
        {
            return randomnumber;
        }

        randomnumber++;
        if (randomnumber == labelsinfat)
       randomnumber = 2;
    }
}
コード例 #7
0
ファイル: recovdsk.c プロジェクト: CivilPol/sdcboot
/*************************************************************************
**                        RecoverFileChains
**************************************************************************
** Goes through the FAT and converts every cluster chain to a valid file.
**************************************************************************/
static BOOL RecoverFileChains(RDWRHandle handle)
{
    unsigned long LabelsInFat, i;
    unsigned long filesize;
    CLUSTER label;
    
    LabelsInFat = GetLabelsInFat(handle);
    if (!LabelsInFat) return FALSE;
	
    for (i = 2; i < LabelsInFat; i++)
    {	
	if (!GetNthCluster(handle, i, &label))
	   return FALSE;
	
	if (FAT_NORMAL(label) || (label == FAT_LAST_LABEL))
	{    
	   switch (IsStartOfChain(handle, i))
	   {
	      case TRUE:    
	           if (!RecoverFileChain(handle, i, &filesize))
		      return FALSE;
		   if (filesize)
		   {    
		      if (!AddToRootDir(handle, i, filesize))
		         return FALSE;
		   }
		   break;
		
	      case FAIL:
	           return FALSE;	       
	   }
       }
    }
    
    return TRUE;
}
コード例 #8
0
ファイル: walktree.c プロジェクト: CivilPol/sdcboot
BOOL WalkDirectoryTree(RDWRHandle handle,
		      int (*func) (RDWRHandle handle,
				   struct DirectoryPosition* position,
				   void** structure),
		      void** structure)
{
    int top = 0;
    struct StackElement* stack;
    CLUSTER cluster = 0, temp;
    unsigned long current = 0;
    struct DirectoryPosition pos;
    struct DirectoryEntry* entry;
    struct StackElement element;
        
    struct PipeStruct pipe, *ppipe = &pipe;

    pipe.func      = func;
    pipe.structure = structure;
    pipe.stop      = FALSE;

    if (!TraverseRootDir(handle, ActionWalker, (void**)&ppipe, TRUE))
       return FALSE;
    if (pipe.stop)
       return TRUE;

    stack = (struct StackElement*)FTEAlloc(DIR_STACK_DEPTH * sizeof(struct StackElement));
    if (!stack)
       return FALSE;

    for (;;)
    {
         /* If there still are sub directories in this directory, 
            push the cluster of that directory. */
         pos.sector = 0;
         pos.offset = 0;
         if (!GetNthSubDirectoryPosition(handle, cluster, current, &pos))
	 {
            FTEFree(stack);
            return FALSE;
         }

	 if ((pos.sector != 0) || (pos.offset != 0))
	 {
	    entry = AllocateDirectoryEntry();
	    if (!entry)
	    {
	       FTEFree(stack);
	       return FALSE;
	    }

	    if (top < DIR_STACK_DEPTH)
	    {
	       element.cluster = cluster;
	       element.index   = current;

	       PushDirectoryEntry(stack, &top, &element);
	    }
	    else
	    {
	       FreeDirectoryEntry(entry);   /* Directory level to deep!? */
	       FTEFree(stack);
	       return FALSE;
	    }

	    if (!GetDirectory(handle, &pos, entry))
	    {
	       FreeDirectoryEntry(entry);
	       FTEFree(stack);
	       return FALSE;
	    }

	    /* Descend in the directory tree and call the function
               for every directory entry in that directory. */
            temp = GetFirstCluster(entry);
            
            /* Don't descend in any directory that is invalid. */
            if (temp && FAT_NORMAL(temp) && IsLabelValid(handle, temp))
            {
	       current = 0;
               cluster = temp;

	       if (!TraverseSubdir(handle, cluster, ActionWalker, (void**) &ppipe, TRUE))
	       {
	          FreeDirectoryEntry(entry);
	          FTEFree(stack);
                  return FALSE;
	       }

	       if (pipe.stop)
	       {
	          FreeDirectoryEntry(entry);
                  FTEFree(stack);
	          return TRUE;
	       }
            }
            else /* cluster not valid, leave this directory */
            {   
	       if (top-1 > 0) /* Be carefull when there are no sub directories
		                 in the volume. */
	       {
	          PopDirectoryEntry(stack, &top, &element);
                  PopDirectoryEntry(stack, &top, &element);

	          current = element.index+1; /* Then find the next sub directory. */
	          cluster = element.cluster;
	       }
	       else
	       {
                  FreeDirectoryEntry(entry);     
	          break;
	       }
            }
            
	    FreeDirectoryEntry(entry);
	 }
	 /* If there are no more sub directories in the current directory,
	    pop the current directory from the stack.                 */
	 else
	 {
	    if (top) /* Be carefull when there are no sub directories
			in the volume. */
	    {
	       PopDirectoryEntry(stack, &top, &element);

	       current = element.index+1; /* Then find the next sub directory. */
	       cluster = element.cluster;
	    }
	    else
	    {
	       break;
	    }
         }
    }

    FTEFree(stack);        
    return TRUE;
}
コード例 #9
0
ファイル: scanfils.c プロジェクト: aquashift/86Duino_DuinOS
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;
}