예제 #1
0
파일: invchar.c 프로젝트: FDOS/chkdsk
static BOOL RenameFile(RDWRHandle handle,
                       struct DirectoryPosition* pos,
                       struct DirectoryEntry* entry,
                       CLUSTER firstcluster)
{
    BOOL retval;
    int counter=0;
   
    for (;;)
    {
        retval = LoFileNameExists(handle, firstcluster,
                                  entry->filename, entry->extension);

        if (retval == FALSE) break;
        if (retval == FAIL)  return FALSE;

        counter++;
        sprintf(entry->extension, "%03d", counter);
        
        if (IsCurrentDir(*entry))
        {
           memcpy(entry->filename, "DOT     ", 8);
        }        
        if (IsPreviousDir(*entry))
        {
           memcpy(entry->filename, "DOTDOT  ", 8);
        }
    }

    return WriteDirectory(handle, pos, entry);
}
예제 #2
0
파일: nthentry.c 프로젝트: CivilPol/sdcboot
STATIC BOOL SubdirGetter(RDWRHandle handle,
		         struct DirectoryPosition* pos,
			 void** buffer)
{
   struct DirectoryEntry entry;
   struct Pipe** pipe = (struct Pipe**) buffer;
   
   handle = handle;
   
   if (!GetDirectory(handle, pos, &entry))
      return FAIL;
   
   if (IsLFNEntry(&entry)          ||
       (IsDeletedLabel(entry))     ||
       (IsCurrentDir(entry))       ||
       (IsPreviousDir(entry)))  
   {
      return TRUE;
   }   
     
   if (entry.attribute & FA_DIREC)
   {           
      if ((*pipe)->n == (*pipe)->counter)
      {             
         memcpy((*pipe)->pos, pos, sizeof(struct DirectoryPosition));
         return FALSE;   
      }
   
      (*pipe)->counter++;
   }
   
   return TRUE;
}
예제 #3
0
파일: memsort.c 프로젝트: CivilPol/sdcboot
void MemorySortEntries(struct DirectoryEntry* entries,
                       int amofentries)
{
     int i=0, realentries = 0;

     struct DirectoryEntry* temp = entries;

     SetResourceConfiguration(&MemConfig);

     if (amofentries == 0) return; 
     
     if (IsCurrentDir(entries[0]))
     {
        if (amofentries == 1) return; 
        entries++;
        i++;     
     }
     
     if (IsPreviousDir(entries[0]))
     {
        entries++;
        i++; 
     }

     for (; i < amofentries; i++)
	 if (IsLFNEntry(&temp[i]) == 0)
            realentries++;

     if (realentries)
	SelectionSortEntries(entries, realentries);
}
예제 #4
0
파일: dsksort.c 프로젝트: CivilPol/sdcboot
BOOL DiskSortEntries(RDWRHandle handle, CLUSTER cluster)
{
   int  i=0;
   long totalcount, lfncount, realcount;
   struct DiskEntryGetterStruct parameters;
   struct DirectoryPosition pos;
   struct DirectoryEntry entry;

   parameters.handle = handle;
   parameters.cluster = cluster;
   
   SetResourceConfiguration(&DiskConfig);  

   totalcount = low_dircount(handle, cluster, 0xffff);
   if (totalcount == -1)
      RETURN_FTEERR(FALSE);
      
   lfncount   = low_dircount(handle, cluster, LFN_ATTRIBUTES);
   if (lfncount == -1)
      RETURN_FTEERR(FALSE);
      
   realcount = totalcount - lfncount;
   
   for (i = 0; i < 2; i++)
   {
       if (!GetNthDirectoryPosition(handle, cluster, i, &pos))
       {
          RETURN_FTEERR(FALSE);
       }
   
       if (!GetDirectory(handle, &pos, &entry))
       {
          RETURN_FTEERR(FALSE);
       }
   
       switch (i)
       {
          case 0:
               if (IsCurrentDir(entry))
               {
                  realcount--;
               }
               break;
          case 1:
               if (IsPreviousDir(entry))
               {
                  realcount--;
               }
       }
   } 
            
   if (realcount && realcount <= INT_MAX)
      SelectionSortEntries(&parameters, (int)realcount);

   return TRUE;
}
예제 #5
0
파일: NTHENTRY.C 프로젝트: FDOS/defrag
BOOL GetNthSubDirectoryPosition(RDWRHandle handle, CLUSTER cluster, 
                                unsigned long n, 
                                struct DirectoryPosition* result)        
{
   int counter = 0;
   struct DirectoryPosition pos;
   struct DirectoryEntry* entry;
   
   entry = AllocateDirectoryEntry();
   if (!entry) return FALSE;

   n++;                                       /* n is 0 based */
   while (n)
   {
       pos.sector = 0;
       pos.offset = 0;
       
       if (!GetNthDirectoryPosition(handle, cluster, counter++, &pos))
       {
          FreeDirectoryEntry(entry);
          return FALSE;
       }

       if ((pos.sector == 0) && (pos.offset == 0)) /* Not found*/
       {
	  FreeDirectoryEntry(entry);
	  return TRUE;
       }
          
       if (!GetDirectory(handle, &pos, entry))
       {
          FreeDirectoryEntry(entry);
	  return TRUE;
       }

       if (!IsLFNEntry((entry))        &&
	   (entry->attribute & FA_DIREC) &&
	   (!IsDeletedLabel(*entry))     &&
	   (!IsCurrentDir(*entry))       &&
	   (!IsPreviousDir(*entry)))  
       {
          n--;
       }
   }
 
   memcpy(result, &pos, sizeof(struct DirectoryPosition));
   FreeDirectoryEntry(entry);
   return TRUE;
}
예제 #6
0
파일: dsksort.c 프로젝트: CivilPol/sdcboot
static int entrygetter (RDWRHandle handle,
         struct DirectoryPosition* pos,
         void** buffer)
{
     struct Pipe** pipe = (struct Pipe**) buffer;
     struct DirectoryEntry entry;
     
     if (!GetDirectory(handle, pos, &entry))
     {        
        RETURN_FTEERR(FAIL);
     }
     
     if (IsCurrentDir(entry) || IsPreviousDir(entry))
     {
	return TRUE; 
     }
     
     if ((*pipe)->entrynr == (*pipe)->ecounter)
     {
        if ((*pipe)->slotorentry == ENTRY)
        {
           memcpy((*pipe)->entry, &entry, sizeof(struct DirectoryEntry));
           RETURN_FTEERR(FALSE);
        }
        else
        {
           if ((*pipe)->slot == (*pipe)->scounter)
           {
              memcpy((*pipe)->entry, &entry, sizeof(struct DirectoryEntry));
              RETURN_FTEERR(FALSE);
           }
           (*pipe)->scounter++;
           return TRUE;
        }  
     }
     
     if ((entry.attribute & FA_LABEL) == 0)
        (*pipe)->ecounter++;     
     
     return TRUE;   
}
예제 #7
0
파일: invchar.c 프로젝트: FDOS/chkdsk
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;
}
예제 #8
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;
}
예제 #9
0
bool Path::ParsePathString (UCS2String& volume, vector<UCS2String>& dirnames, UCS2String& filename, const UCS2String& path)
{
    UCS2String stash;

    // Unless noted otherwise, all components are considered empty.
    volume.clear();
    dirnames.clear();
    filename.clear();

    // Empty strings are considered valid path names, too.
    if (path.empty() == true)
        return true;

    UCS2String::const_iterator i = path.begin();

    // Check for a volume identifier:
    // - If the second character is a colon, we presume the first two characters to identify the drive. In that case
    //   we'll also check whether the following character is a path separator, indicating an absolute path on that
    //   drive, in which case we'll also include a trailing separator to the drive letter.
    // - If the path starts with two identical path separator characters, we presume the string to be a UNC path, in
    //   which case we set the volume identifier to the network share, including two leading and a trailing separator
    //   characters.
    // - Otherwise, if the first character is a path separator, this indicates an absolute path on the current drive,
    //   in which case we set the volume identifier to a single path separator character.
    // - In any other case, we presume the string to be a relative path, and set the volume identifier to an empty
    //   string.

    if ((*i == POV_PATH_SEPARATOR) || (*i == POV_PATH_SEPARATOR_2))
    {
        // String starts with a path separator; may be an absolute path on the current drive or a UNC path.

        // Stash the separator (use the canonical one, not the one actually used).
        stash += POV_PATH_SEPARATOR;
        ++i;

        if ((i != path.end()) && (*i == stash[0]))
        {
            // The second character is also an (identical) separator character, indicating a UNC path.

            // Stash another path separators (use the canonical one, not the one actually used).
            stash += POV_PATH_SEPARATOR;
            ++i;

            // Stash everything that follows, up to the next path separator.
            for (; (i != path.end()) && (*i != POV_PATH_SEPARATOR) && (*i != POV_PATH_SEPARATOR_2); ++i)
                stash += *i;

            // Currently, we don't support bare UNC share names without trailing separator character,
            // even though allegedly they are technically valid.
            if (i == path.end())
                return false;

            // Stash another path separator (use the canonical one, not the one actually used)
            // to indicate an absolute path.
            stash += POV_PATH_SEPARATOR;
            ++i;
        }
        // If it's not a UNC path, at this point our stash contains a single path separator,
        // which is exactly what we intend to emit as the volume identifier in that case.

        // Emit whatever string we have stashed as the volume identifier.
        volume = stash;
        stash.clear();
    }
    else if (isalpha (*i))
    {
        // String starts with an ASCII letter; may be a relative path or a drive letter.

        // Stash the character, then go on to test what's next.
        stash += *i;
        ++i;

        if ((i != path.end()) && (*i == ':'))
        {
            // Yup, that's a drive letter. Add the colon to the stashed letter.
            stash += ':';
            ++i;

            // Currently, we don't support relative paths if a volume is specified.
            if ((i == path.end()) || ((*i != POV_PATH_SEPARATOR) && (*i != POV_PATH_SEPARATOR_2)))
                return false;

            // Stash another path separator (use the canonical one, not the one actually used)
            // to indicate an absolute path.
            stash += POV_PATH_SEPARATOR;
            ++i;

            // Emit the stashed string as the volume identifier.
            volume = stash;
            stash.clear();
        }
        // If it's not a drive letter, at this point we have only stashed the first letter, but
        // our index still points to the second one so the following algorithm will take care of it.
    }

    // Walk through the path string, stashing any non-separator characters. Whenever we hit a separator
    // character, emit the stashed characters (if any) as a directory name and clear the stash.
    // Also, as we go along, resolve the special directory names `.` and `..` if possible.

    // NB since we do not emit "empty" directory names, any sequence of consecutive separator
    // characters is effectively treated as a single separator character.

    for(; i != path.end(); ++i)
    {
        if ((*i == POV_PATH_SEPARATOR) || (*i == POV_PATH_SEPARATOR_2))
        {
            if (!stash.empty() && !IsCurrentDir(stash))
            {
                if (!dirnames.empty() && IsParentDir(stash))
                    dirnames.pop_back();
                else
                    dirnames.push_back (stash);
                stash.clear();
            }
        }
        else
            stash += *i;
    }

    // Whatever is left in the stash is presumably the actual file name.

    // NB as a consequence of the algorithm chosen, any path name ending in a path separator
    // character will be emitted as a list of directories only, with the file name left empty.

    filename = stash;

    return true;
}