⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dir.c

📁 使用IAR430编译源文件
💻 C
字号:
//###########################################################
// File: dir.c
//
// Directory functions
//
// For FAT12, FAT16 and FAT32
// FAT32 not tested yet
// Only for first Partition
// Only for drives with 512 bytes per sector (the most)
//
//#########################################################################
// Last change: 03.15.2006
//#########################################################################
// Compiler: IAR3.10
//#########################################################################
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "dos.h"

#ifdef DOS_WRITE
#ifdef DOS_MKDIR
//###########################################################
// Make a new directory
unsigned char mkdir(char *name)
//###########################################################
{
#ifdef USE_FAT32
 unsigned long newdircluster, upperdircluster;
#else
 unsigned int newdircluster, upperdircluster;
#endif

 unsigned long newdirsector;
 unsigned int i;
 
 if(FileFlag!=0) return F_ERROR; // no open file allowed here

 //Test if directoryname exists in currentdir
 if(FindName(name)==FULL_MATCH) return F_OK;

//from this point i use some variables of FILE entry !
//you have to change a lot of things if you want to use more then ONE file !

 FileAttr=ATTR_DIRECTORY;  //want to make a directory !
 MakeFileName(name, FileName, FileExt);
 if(MakeNewFileEntry())
  {
   //MakeNewFileEntry() allocates first cluster for new directory !
   //entry of new directory is written to currentdir sector
   //first cluster of new directory is returned in FileFirstCluster

   newdircluster=FileFirstCluster; 
   newdirsector=GetFirstSectorOfCluster(newdircluster);
   FileDirSector=newdirsector;

   //clean all sectors of newdir cluster (fill with 0x00)
   for(i=0; i<BYTE_PER_SEC; i++) dirbuf[i]=0; //Fill write buffer

   for(i=0; i<secPerCluster; i++)
    {
     WriteSector(newdirsector,dirbuf);
     newdirsector++;
    }
   //end clean all sectors of newdir cluster (fill with 0x00)

   upperdircluster=FirstDirCluster; //first upperdir cluster needed for later

   //insert "." my new dir entry with newdir firstcluster
   FileDirOffset=0; //first direntry "."
   MakeFileName(".", FileName, FileExt);
   FileFirstCluster=newdircluster;
   UpdateFileEntry();

   //insert ".." upper dir entry with upperdir firstcluster
   FileDirOffset=1;  //2nd direntry ".."
   MakeFileName("..", FileName, FileExt);
   FileFirstCluster=upperdircluster;
   UpdateFileEntry();

#ifdef USE_FATBUFFER
     WriteSector(FATCurrentSector, fatbuf); // write the FAT buffer
     FATStatus=0;
#endif
  }
 else
  {
   FileAttr=ATTR_FILE; //default
   return F_ERROR; //new dir could not be made
  } 
 
 FileAttr=ATTR_FILE; //default
 return F_OK;
}
#endif //DOS_MKDIR
#endif //DOS_WRITE
       
#ifdef DOS_CHDIR
//###########################################################
// Change to a directory
unsigned char chdir(char *name)
//###########################################################
{
 if(FileFlag!=0) return F_ERROR; // no open file allowed here

 if(name[0]=='/')
  {
#ifdef USE_FAT12
   if(FATtype==FAT12) FirstDirCluster=0;
#endif
#ifdef USE_FAT16
   if(FATtype==FAT16) FirstDirCluster=0;
#endif
#ifdef USE_FAT32
   if(FATtype==FAT32) FirstDirCluster=FAT32RootCluster;
#endif
   return F_OK;
  }
 
 if(FindName(name)==FULL_MATCH) return F_OK;
 else return F_ERROR;
}
#endif //DOS_CHDIR

#ifdef DOS_WRITE
//###########################################################
unsigned char MakeNewFileEntry(void)
//###########################################################
{
 unsigned long tmpsector;

#ifdef USE_FAT32
 unsigned long tmpcluster,lastdircluster;
#else
 unsigned int tmpcluster,lastdircluster;
#endif

 unsigned int i;
 unsigned char result;
 
 // search for a free direntry
 if(FirstDirCluster<2) result=SearchRootDir();
 else result=SearchSubDir(FirstDirCluster);

 if(result==0) // no free direntry found. lets try to alloc and add a new dircluster
  {
   //if dir is rootdir (FAT12/16 only) you have a problem ;)
   if(FirstDirCluster<2 && (FATtype==FAT12 || FATtype==FAT16) )
    {
     return F_ERROR;
    }

   //search the last cluster of directory
   lastdircluster=FirstDirCluster;
   do
    {
     tmpcluster=GetNextClusterNumber(lastdircluster);
     if(tmpcluster < endofclusterchain) lastdircluster=tmpcluster;
    }while(tmpcluster < endofclusterchain);
   
   tmpcluster=AllocCluster(lastdircluster); //if currentdir is full alloc new cluster for dir
   if(tmpcluster==DISK_FULL) //no free clusters ?
    {
     return F_ERROR;
    }

   //fill all cluster sectors with zero
   for(i=0; i<BYTE_PER_SEC; i++) dirbuf[i]=0; //Fill write buffer

   tmpsector=GetFirstSectorOfCluster(tmpcluster);
   for(i=0; i<secPerCluster; i++)
    {
     WriteSector(tmpsector,dirbuf);
     tmpsector++;
    }
   
   FileDirOffset=0;              //set offset for new direntry in dirsector
   FileDirSector=GetFirstSectorOfCluster(tmpcluster);
  }     

 tmpcluster=AllocCluster(0); //alloc first cluster for file
 if(tmpcluster==DISK_FULL) //no free clusters ?
  {
   return F_ERROR;
  }

 FileFirstCluster=tmpcluster;
 FileSize=0;
 UpdateFileEntry(); //write new file entry

 return F_OK; //all ok 
}
#endif //DOS_WRITE

#ifdef DOS_WRITE
//###########################################################
unsigned char UpdateFileEntry(void)
//###########################################################
{
 struct DirEntry *di;
 
 ReadSector(FileDirSector,dirbuf);
 di=(struct DirEntry *)&dirbuf[FileDirOffset*32];

 strncpy(di->DIR_Name,FileName,8);
 strncpy(di->DIR_Ext,FileExt,3);

 di->DIR_Attr=FileAttr;
 di->DIR_NTres=0;
 di->DIR_CrtTimeTenth=0;

//because i have no clock give file a fixed time
 di->DIR_CrtTime=(unsigned int)( (19<<11) + (21<<5) );      //creation time
 di->DIR_CrtDate=(unsigned int)( (23<<9) + (5<<5) + 10);  //creation date
 di->DIR_LastAccDate=(unsigned int)( (23<<9) + (5<<5) + 10);  //last access date 10.05.2003
 di->DIR_WrtTime=(unsigned int)( (19<<11) + (21<<5) ); //last write time 19:21
 di->DIR_WrtDate=(unsigned int)( (23<<9) + (5<<5) + 10); //last write date 10.05.2003

#ifdef USE_FAT32
 di->DIR_FstClusHI=(unsigned int)(FileFirstCluster>>16);  //first cluster high word                 
#else
 di->DIR_FstClusHI=0;  //first cluster high word                 
#endif
 di->DIR_FstClusLO=(unsigned int)(FileFirstCluster);  //first cluster low word                 
 di->DIR_FileSize=FileSize;

 WriteSector(FileDirSector,dirbuf);
 return F_OK;
}
#endif //DOS_WRITE

//###########################################################
//search root dir for free dir entry
unsigned char SearchRootDir(void)
//###########################################################
{
// unsigned long i;
 unsigned int i;
 unsigned char result;

 result=0;
  
 for(i=0; i<RootDirSectors; i++)
  {
   result=SearchDirSector(FirstRootSector+i);
   if(result!=0) break; //break sector loop
  }

 return result;
}

//###########################################################
//search sub dir for free dir entry
#ifdef USE_FAT32
 unsigned char SearchSubDir(unsigned long startcluster)
#else
 unsigned char SearchSubDir(unsigned int startcluster)
#endif
//###########################################################
{
 unsigned long tmpsector;

#ifdef USE_FAT32
 unsigned long tmpcluster;
#else
 unsigned int tmpcluster;
#endif

 unsigned char i,result;
 
 tmpcluster=startcluster;
 result=0;
 
 while(tmpcluster < endofclusterchain)
  {
   tmpsector=GetFirstSectorOfCluster(tmpcluster);
   for(i=0; i<secPerCluster; i++)
    {
     result=SearchDirSector(tmpsector+i);
     if(result!=0) break; //break sector loop
    } 

   if(result!=0) break; //break cluster loop
   tmpcluster=GetNextClusterNumber(tmpcluster);
  }

 return result;
}

//###########################################################
//search dir sector for free dir entry
unsigned char SearchDirSector(unsigned long sector)
//###########################################################
{
 unsigned int count;

 ReadSector(sector,dirbuf); //read one directory sector.
 count=0;
 do
  {
   if(dirbuf[count]==0 || dirbuf[count]==0xE5)
    {
     FileDirSector=sector; //keep some values in mind
     FileDirOffset=count/32;
     return 1;
    }

   count+=32;
  }while(count<BYTE_PER_SEC);

 return 0;
}

//###########################################################
// Change to dir or find a filename (if name!=NULL)
//
// Following global variables will be set if dir or filename
// was found:
//
// For directories:
// FirstDirCluster   First cluster of directory
//
// For files:
// FileName          8 chars for filename
// FileExt           3 chars for extension
// FileDirSector     Sector which keeps direntry of the file
// FileDirOffset     Offset to direntry of the file
// FileFirstCluster  First cluster of the dir/file in FAT 
// FileSize
unsigned char ScanOneDirectorySector(unsigned long sector, char *name)
//###########################################################
{
 unsigned char by;
 unsigned int count;
 unsigned long tmp;
 struct DirEntry *di;
 struct DirEntryBuffer *dib;
 char nam[8];
 char ext[3];
 unsigned char match;

 if(name) //find filename or directory name
  {
   MakeFileName(name,nam,ext);
  }//if(name)
 
 by=ReadSector(sector,dirbuf); //read one directory sector.
 count=0;
 do
  {
   match=NO_MATCH;
   di=(struct DirEntry *)(&dirbuf[count]);
   //make a second pointer to dirbuf for easier access to long filename entrys
   dib=(struct DirEntryBuffer *)di;
   
   if(di->DIR_Name[0]==0) return END_DIR; //end of directory
      
   if(di->DIR_Name[0]!=0xE5 && di->DIR_Name[0]>0)
    {
     di->DIR_Attr&=0x3F;            //smash upper two bits

     if(di->DIR_Attr==ATTR_LONG_NAME)
      {
      }
     else
      {
       if(name==NULL) //List only
        {
        }//if(name==NULL)
       else //searching for a filename or a directory name
        {
         if(strncmp(nam,di->DIR_Name,8)==0) match=MATCH_NAME;
         if(strncmp(ext,di->DIR_Ext,3)==0) match+=MATCH_EXT;
        }
                
       if(di->DIR_Attr & ATTR_VOLUME_ID)
        {
        }
       else
        {
         if(di->DIR_Attr & ATTR_DIRECTORY) //this is a directory
          {
           tmp=di->DIR_FstClusHI; //Highword of first cluster number
           tmp<<=16;
           tmp+=di->DIR_FstClusLO; //Lowword of first cluster number

           if(name==NULL) //List only
            {
            } 
           else          //searching for a directoryname
            {
             if(match==FULL_MATCH)
              {
               FirstDirCluster=tmp;
               return FULL_MATCH;
              } 
            }//if(name==NULL) 
          }//if(di->DIR_Attr & ATTR_DIRECTORY)
         else //is not a directory. this is a file
          {
           tmp=di->DIR_FstClusHI; //Highword of first cluster number
           tmp<<=16;
           tmp+=di->DIR_FstClusLO; //Lowword of first cluster number

           if(name==NULL) //List filenames only
            {
            }
           else //searching for a filename
            {
             if(match==FULL_MATCH)
              {
               strncpy(FileName,nam,8);
               strncpy(FileExt,ext,3);
               FileDirSector=sector; //keep some values in mind
               FileDirOffset=count/32;
               FileFirstCluster=tmp;
               FileSize=di->DIR_FileSize;
               FileAttr=ATTR_FILE;
               return FULL_MATCH;
              } 
             } 

          }//if(di->DIR_Attr & ATTR_DIRECTORY)
        }
      }
         
    }//if(di->DIR_Name[0]!=0xE5 && di->DIR_Name[0]>0)
        
   count+=32;
  }while(count<BYTE_PER_SEC);

 return NO_MATCH;
}


//###########################################################
#ifdef USE_FAT32
 unsigned char ScanSubDir(unsigned long startcluster, char *name)
#else
 unsigned char ScanSubDir(unsigned int startcluster, char *name)
#endif
//###########################################################
{
 unsigned long tmpsector;
#ifdef USE_FAT32
 unsigned long tmpcluster;
#else
 unsigned int tmpcluster;
#endif

 unsigned char i,result;
 
 tmpcluster=startcluster;
 result=NO_MATCH;
 
 while(tmpcluster < endofclusterchain)
  {
   tmpsector=GetFirstSectorOfCluster(tmpcluster);
   for(i=0; i<secPerCluster; i++)
    {
     result=ScanOneDirectorySector(tmpsector+i, name);
     if(result!=NO_MATCH) break; //break sector loop
    } 

   if(result!=NO_MATCH) break; //break cluster loop
   tmpcluster=GetNextClusterNumber(tmpcluster);
  }

 return(result);
}

//###########################################################
//FAT12/16 only
unsigned char ScanRootDir(char *name)
//###########################################################
{
// unsigned long i;
 unsigned int i;
 unsigned char result;

 result=NO_MATCH;
  
 for(i=0; i<RootDirSectors; i++)
  {
   result=ScanOneDirectorySector(FirstRootSector+i, name);
   if(result!=NO_MATCH) break; //break sector loop
  }

 return(result);
}

//###########################################################
void MakeFileName(char *inname, char *outname, char *outext)
//###########################################################
{
 unsigned char by,i,j;
 char *po;

 po=outname;
 for(i=0; i<8; i++) *po++=' '; //fill filename buffers with spaces

 po=outext;
 *po++=' ';
 *po++=' ';
 *po  =' ';

 po=outname;

//29.04.2004
 if(inname[0]=='.' && inname[1]==0)
  {
   *po++='.';
   return;
  }

 if(inname[0]=='.' && inname[1]=='.') //change to upper dir
  {
   *po++='.';
   *po  ='.';
  }
 else
  {
   i=0; //get filename and make it uppercase
   do
    {
     by=inname[i];
     if(by!='.' && by!=0) *po++=toupper(by);
     i++;
    }while(i<8 && by!='.' && by!=0);

   //if i < 8 there was a dot or a \0
   //if i == 8 there could be a dot or a \0
   if(i==8 && by!='.' && by!=0) { by=inname[i]; i++; }

   if(by=='.')
    {
     j=0;
     do
      {
       by=inname[i];
       if(by!=0) outext[j]=toupper(by);
       j++;
       i++;
      }while(j<3 && by!=0);
    }
  }

// for(i=0; i<8; i++) putchar(outname[i]);
// for(i=0; i<3; i++) putchar(outext[i]);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -