Пример #1
0
void ShowParentViolation(RDWRHandle handle,
                         char* filename,
                         char* message)
{       
    int i;
    
    strcpy(FilePrintBuffer, filename);  
    for (i = strlen(FilePrintBuffer)-1; i >= 0; i--)
    {
        if (FilePrintBuffer[i] == '\\')
        {
           FilePrintBuffer[i] = '\0';
           break;
        }
    }   

    if (i <= 0)
    {
       ShowFileNameViolation(handle, "The root directory", message); 
    }
    else
    {
       ShowFileNameViolation(handle, FilePrintBuffer, message);
    }         
}
Пример #2
0
BOOL PostProcesLFNChecking(RDWRHandle handle, CLUSTER cluster, char* filename, BOOL fixit)
{
    /* After cheking the directory the state machine must be in SFN state. */   
    if ((LFNState != SCANNING_SFN_STATE) ||
        (LFNIndex > 0))/* And the right number of LFN entries must be found. */
    {
       ShowFileNameViolation(handle, filename,  
                             "%s contains a number of invalid long file name entries");       
                           
       if (fixit)
       {
          if (!RemoveInvalidLFNs(handle, cluster, &LFNStart, NULL))
             return FAIL;
       }
       
       return FALSE;
    }   
   
    return TRUE;
}
Пример #3
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;
}
Пример #4
0
BOOL CheckDirectoryForDoubles(RDWRHandle handle,                                   
                              struct DirectoryPosition* pos, 
                              struct DirectoryEntry* entry, 
                              char* filename, 
                              BOOL fixit)
{
    unsigned slot, now, previous = 0xffff;
    
    if ((entry->attribute & FA_LABEL) ||
        IsLFNEntry(entry)             ||
        IsDeletedLabel(*entry))
    {
       return TRUE;
    }

    slot = HashFilename(entry->filename);

    /* Now walk the list starting at the head in the hash table. */
    now = hashtable[slot].ptr;
    while (now != 0xFFFF)
    {
       if ((memcmp(entry->filename,
                   filenamearray[now].filename, 8) == 0) &&
           (memcmp(entry->extension,
                   filenamearray[now].extension, 3) == 0))
       {
           /* Print out the message and the file name */
           ShowFileNameViolation(handle, filename,  
                                  "Found double file %s");            
           
           if (fixit)
           {
              if (!RenameDoubleFile(handle, pos, entry, surroundingdir))
	         return FAIL;
           }

           return FALSE;
       }

       previous = now;
       now = filenamearray[now].next;
    }

    /* Not found, add it to the end of the list */
    if (previous == 0xFFFF) /* First one in the slot. */
    {
       hashtable[slot].ptr = ArrayFreePointer;
    }
    else
    {  /* We already have the end of the list */
       filenamearray[previous].next = ArrayFreePointer;
    }

    memcpy(filenamearray[ArrayFreePointer].filename, entry->filename, 8);
    memcpy(filenamearray[ArrayFreePointer].extension, entry->extension, 3);
    filenamearray[ArrayFreePointer].next = 0xFFFF;

    ArrayFreePointer++;
  
    return TRUE;
} 
Пример #5
0
BOOL CheckEntryForInvalidChars(RDWRHandle handle,                   
                               struct DirectoryPosition* pos, 
                               struct DirectoryEntry* direct, 
                               char* filename,
                               BOOL fixit)
{
    int i;
    BOOL invalidname = FALSE;
    BOOL InRoot;
    struct DirectoryEntry entry;
    
    memcpy(&entry, direct, sizeof(struct DirectoryEntry));
    
    if (((entry.attribute & FA_LABEL) == 0) && /* Not checking volume labels */
        !IsDeletedLabel(entry))   
    {        
        if (IsPreviousDir(entry) || /* .. */
            IsCurrentDir(entry))    /* .  */              
        {
           /* See wether the given directory entry is in the root directory */
           InRoot = IsRootDirPosition(handle, pos);
           if (InRoot == FAIL) return FAIL;   
           
           /* All the '.' and '..' entries must be directories */
           if (((entry.attribute & FA_DIREC) == 0) || (InRoot))
           {
              if (IsCurrentDir(entry))
              {  
                 if (InRoot)
                 {
                    ShowFileNameViolation(handle, "",  
                                          "The root directory contains an '.' entry");   
                 }
                 else
                 {
                    ShowParentViolation(handle, filename,  
                                        "%s contains an '.' entry that is not a directory");
                 }
                 memcpy(entry.filename, "DOT     ", 8); 
              }
              else
              {
                 if (InRoot)
                 {
                    ShowFileNameViolation(handle, "",  
                                          "The root directory contains an '..' entry");                     
                 }   
                 else 
                 {
                    ShowParentViolation(handle, filename,  
                                        "%s contains an '..' entry that is not a directory");
                 }
                  
                 memcpy(entry.filename, "DOTDOT     ", 8);    
              }   
             
              if (fixit)
              {         
                 memcpy(entry.extension, "   ", 3);
                 if (!RenameFile(handle, pos, &entry, DirCluster)) /* Write the changes to disk */
                    return FAIL;          
              }
          
              return FALSE;          
           }

           /* Check wether you realy have '.' and '..' */
           if (IsCurrentDir(entry))
           {                             
              if ((memcmp(entry.filename, ".       ", 8) != 0) ||
                  (memcmp(entry.extension, "   ", 3) != 0))
              {
                 ShowFileNameViolation(handle, filename,  
                                       "%s contains invalid char(s)");  
                 if (fixit)
                 {                          
                    memcpy(entry.filename, ".       ", 8);
                    memcpy(entry.extension, "   ", 3);
                    if (!RenameFile(handle, pos, &entry, DirCluster)) /* Write the changes to disk */
                       return FAIL;                        
                 }
              }
           }           
           
           if (IsPreviousDir(entry))
           {                             
              if ((memcmp(entry.filename, "..      ", 8) != 0) ||
                  (memcmp(entry.extension, "   ", 3) != 0))
              {
                 ShowFileNameViolation(handle, filename,  
                                       "%s contains invalid char(s)");     
                 if (fixit)
                 {
                    memcpy(entry.filename, "..      ", 8);
                    memcpy(entry.extension, "   ", 3);
                    if (!RenameFile(handle, pos, &entry, DirCluster)) /* Write the changes to disk */
                       return FAIL;                    
                 }
              }
           }
        }
        else
        {
          if (entry.filename[0] == ' ')
          {
             invalidname = TRUE;
             entry.filename[0] = 'A';
          }

          /* file name */
          for (i = 0; i < 8; i++)
          {
              if ((strchr(INVALIDSFNCHARS, entry.filename[i]))                ||
                  (((unsigned char)(entry.filename[i]) < 0x20) && (entry.filename[i] != 0x05)) ||
                  (islower(entry.filename[i])))
              {
                 entry.filename[i] = 'A';
                 invalidname = TRUE;
              }
          }

          /* extension */
          for (i = 0; i < 3; i++)
          {
              if ((strchr(INVALIDSFNCHARS, entry.extension[i]))               ||
                  (((unsigned char)(entry.extension[i]) < 0x20) &&
                                                (entry.extension[i] != 0x05)) ||
                 (islower(entry.extension[i])))           
              {
                 entry.extension[i] = 'A';
                 invalidname = TRUE;
              }
          }

          if (invalidname)
          {
             ShowFileNameViolation(handle, filename,  
                                   "%s contains invalid char(s)");
      
             if (fixit)
             {         
                if (!RenameFile(handle, pos, &entry, DirCluster)) /* Write the changes to disk */
                   return FAIL;          
             }
          
             return FALSE;
          }
        }
    }
       
    return TRUE;
}