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

📄 mcc_fat32.c

📁 FAT32 file access for PIC
💻 C
📖 第 1 页 / 共 3 页
字号:
}


char FindDirEntry (char *fname, char f)
{
   DIR *pDir;
      int16 i;
      char filename[16];
      int32 nextcluster;
      int32 actsector;

      if (f > (MAXFILES-1)) return FALSE;
   
      gFAT32Vars.gFirstEmptyDirEntry = 0xFFFF;
      gFAT32Vars.gFirstDirEntryCluster = 0x0FFFFFFF;
      
   do
   {
       pDir = (DIR*)(gFiles[f].IOpuffer);
       
         for (i = 0; i < 16; i++)
       {
            if (((pDir->sName[0] == 0xE5) || (pDir->sName[0] == 0)) && (gFAT32Vars.gFirstEmptyDirEntry == 0xFFFF))
           {
              // store first free
                 gFAT32Vars.gFirstEmptyDirEntry = i;
               gFAT32Vars.gFirstDirEntryCluster = gFiles[f].CurrentCluster;
            }

               if (pDir->sName[0] == 0) return FALSE;
                 
         ConvertFilename (pDir,filename);
             if (!strcmp (filename, fname))
           {
               memcpy(&(gFiles[f].DirEntry), pDir, 32);
               gFiles[f].dirIdx = i;
               gFAT32Vars.gDirEntryIdx = i;
               return TRUE;
            }
            
            pDir++;
         }
         
         nextcluster = GetNextCluster (gFiles[f].CurrentCluster);
         
        
            if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
       {
            actsector = nextcluster + gFAT32Vars.gFirstDataSector;
            ReadSector (actsector, gFiles[f].IOpuffer);
            
            gFAT32Vars.gDirEntrySector = actsector;
            gFiles[f].dirSector = actsector;
            gFiles[f].CurrentCluster = nextcluster;
         }
       
         
      } while ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0));
      
      return FALSE;
}

// file I/O routines
char *TryFile(char *fname, char *f)
{
   char i;
      char leng;
      char *filename;

      (*f) = 0xFF;
   
      for (i = 0; i < MAXFILES; i++)
   {
         if (gFiles[i].Free)
        {
           (*f) = i;
            break;
         }
      }
      
      if ((*f) == 0xFF) return 0;
      
      ReadRootDirectory (*f);
      
      filename = fname;
      leng = strlen (fname);
      
      for (i = 0; i < leng; i++)
   {
       if (fname[i] == '/')
       {
           fname[i] = 0;
            
            if (! cwd (filename,(*f)))
           {
                 gFiles[(*f)].Free = TRUE;
               return 0;
            }
         
            filename = fname + i + 1;
            
        }
      }
   
      return filename;
}

char fcreate (char f, char *fname)
{
   DIR *pDir;
      int32 actsector;
      char actcl;
      int16 i;

      if (f > (MAXFILES-1)) return FALSE;
      
      if (gFAT32Vars.gFirstDirEntryCluster == 0x0FFFFFFF)
   {
       // extend the directory file !!!
         gFAT32Vars.gFirstDirEntryCluster = FindFirstFreeCluster ();
         gFAT32Vars.gFirstEmptyDirEntry = 0;
         SetClusterEntry(gFiles[f].CurrentCluster, gFAT32Vars.gFirstDirEntryCluster);
      SetClusterEntry(gFAT32Vars.gFirstDirEntryCluster, 0x0FFFFFFF);
         actsector = gFAT32Vars.gFirstDirEntryCluster + gFAT32Vars.gFirstDataSector;
         
         for (i = 0; i < 512; i++)
         {
            gFiles[f].IOpuffer[i] = 0;
        }
       
         WriteSector(actsector, gFiles[f].IOpuffer);
      }
      
      actsector = gFAT32Vars.gFirstDirEntryCluster + gFAT32Vars.gFirstDataSector;
      ReadSector (actsector, gFiles[f].IOpuffer);
   
   
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gFirstEmptyDirEntry]));
      gFiles[f].dirSector = actsector;
      gFiles[f].dirIdx = gFAT32Vars.gFirstEmptyDirEntry;
      
      GetDOSName (pDir, fname);
      
      pDir->bAttr = 0;
      actcl = FindFirstFreeCluster ();
      pDir->hCluster = actcl & 0xFFFF;
      pDir->hClusterH = actcl >> 16;
      
      SetClusterEntry (actcl, 0x0FFFFFFF);
      pDir->wSize = 0;
      gFiles[f].position = 0;
      pDir->hDate = GetCurrentDOSDate ();
      pDir->hTime = GetCurrentDOSTime ();
      
      WriteSector (actsector, gFiles[f].IOpuffer);
      memcpy (&(gFiles[f].DirEntry), pDir,32);
      
   return TRUE;
}

int32 ComposeCluster (char f)
{
   int32 retval;

   retval = gFiles[f].DirEntry.hClusterH;
   retval <<= 16;
   retval |= gFiles[f].DirEntry.hCluster;

   return retval;
}

char fopen (char *fname, char mode)
{
   char found;
      char f;
      int32 actsector;
      int32 actcluster;
      int32 nextcluster;
      char *filename;

      //if (input(CardInserted)) return 0xFF;
   
            
      filename = TryFile (fname, &f);

      if (filename == 0) return 0xFF;

      found = FALSE;
      found = FindDirEntry (filename,f);

      
      if (!found)
   {
         if (mode == 'r')
         {
            gFiles[f].Free = TRUE;
            return 0xFF;
         }
       else
      {
           if (! fcreate(f, filename)) return 0xFF;
            found = TRUE;
         }
      }
   
   if (found)
   {
         gFiles[f].Free = FALSE;
         gFiles[f].mode = mode;
         
         if  (mode == 'a') // com problemas
       {
           gFiles[f].position = gFiles[f].DirEntry.wSize;
           
            actcluster = ComposeCluster(f);
            
            while ((actcluster != 0x0FFFFFFF) && (nextcluster != 0))
           {
               nextcluster = GetNextCluster(actcluster);
                  
                  if ((nextcluster == 0x0FFFFFFF) || (nextcluster == 0)) break;
                  
                  actcluster = nextcluster;
            }
           
            actsector = actcluster + gFAT32Vars.gFirstDataSector;
            ReadSector (actsector, gFiles[f].IOpuffer);
            
            gFiles[f].CurrentCluster = actcluster;
            gFiles[f].posinsector = gFiles[f].position & 0x01FF;
            
            if ((gFiles[f].posinsector == 0) && (gFiles[f].position != 0))
            {
               gFiles[f].posinsector = 512;
         }   
         }
      
      else
      {
           gFiles[f].position = 0;
           
            actsector = ComposeCluster (f);
            actsector += gFAT32Vars.gFirstDataSector;
         ReadSector(actsector,gFiles[f].IOpuffer);
         
            gFiles[f].CurrentCluster = ComposeCluster (f);
            gFiles[f].posinsector = 0;
         }
      }
   
      return f;
}

void fclose (char f)
{
      if (f > (MAXFILES-1)) return;
      if ((gFiles[f].mode == 'a') || (gFiles[f].mode == 'w')) fflush(f);
      
      gFiles[f].Free = TRUE;
}

void fflush (char f)
{
   int32 actsector;
   DIR *pDir;

      if (f > (MAXFILES-1)) return;
   
      actsector = gFiles[f].CurrentCluster + gFAT32Vars.gFirstDataSector;
      WriteSector (actsector, gFiles[f].IOpuffer);
      ReadSector(gFiles[f].dirSector, gFiles[f].IOpuffer);
   
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFiles[f].dirIdx]));
   
      if (gFiles[f].DirEntry.bAttr & 0x10) pDir->wSize = 0; // if it is a directory
      else pDir->wSize = gFiles[f].position;
   
      pDir->hDate = GetCurrentDOSDate ();
      pDir->hTime = GetCurrentDOSTime ();
      WriteSector(gFiles[f].dirSector,gFiles[f].IOpuffer);
      ReadSector(actsector, gFiles[f].IOpuffer);
}

char cwd (char *fname, char f)
{
   int32 actsector;

     if (f > (MAXFILES-1))
      {
      return FALSE; // just in case of overaddressing
      }
   
   if (IsSelfDir(fname))
      {
         return TRUE; // already in Root dir
      }   
      
      if (!FindDirEntry(fname,f))
      {
         return FALSE; // not found
      }

 
      actsector = ComposeCluster (f);
      actsector += gFAT32Vars.gFirstDataSector; // read current dir
      ReadSector (actsector, gFiles[f].IOpuffer);
      
      gFAT32Vars.gDirEntrySector = actsector;
      gFiles[f].dirSector = actsector;
      gFiles[f].CurrentCluster = ComposeCluster (f);
            
      return TRUE;
}

void fputch (char be, char f)
{
      int32 nextcluster;
      int32 actsector;

      if (f > (MAXFILES-1)) return;
      
      if (gFiles[f].posinsector == 512)
   {
       actsector = gFiles[f].CurrentCluster + gFAT32Vars.gFirstDataSector;
         WriteSector (actsector,gFiles[f].IOpuffer);
         
         nextcluster = FindFirstFreeCluster ();
     
       if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
      {
           SetClusterEntry (gFiles[f].CurrentCluster, nextcluster);
            SetClusterEntry (nextcluster, 0x0FFFFFFF);
            actsector = nextcluster + gFAT32Vars.gFirstDataSector;
            //ReadSector (actsector,gFiles[f].IOpuffer);  //-- nao tem a necessidade de ler o setor toda vez que for gravar um bloco
            gFiles[f].CurrentCluster = nextcluster;
            gFiles[f].posinsector = 0;
         }
      }
      
      gFiles[f].IOpuffer[gFiles[f].posinsector] = be;
      gFiles[f].posinsector++;
      gFiles[f].position++;

   return;      
}

void fputstring (char *be, char f)
{
   int16 leng;
   int16 i;

      if (f > (MAXFILES-1)) return;
   
      leng = strlen (be);
   
      for (i = 0; i < leng; i++)
       fputch (be[i], f);
   
}

int16 fread (char *buffer, int16 leng, char f)
{
   int16 i;
   int16 retv;
   char c;
   char v;

      if (f > (MAXFILES-1)) return 0;
      
      retv = 0;
      
      for (i = 0; i < leng; i++)
   {
       v = fgetch (&c, f);
       
         if (v)
        {
           buffer[i] = c;
            retv++;
         }
         
         else break;
      }
   
      return retv;
}

void fwrite (char *buffer, int16 leng, char f)
{
   int16 i;

      if (f > (MAXFILES-1)) return;
      
      for (i = 0; i < leng; i++)
       fputch (buffer[i],f);

}


char fgetch (char *ki, char f)
{
      int32 nextcluster;
      int32 actsector;

      if (f > (MAXFILES-1)) return FALSE;
      
      if (gFiles[f].position >= gFiles[f].DirEntry.wSize) return FALSE;
      
      *ki = gFiles[f].IOpuffer[gFiles[f].posinsector];
      
      gFiles[f].posinsector++;
      gFiles[f].position++;
   
   if (gFiles[f].posinsector == 512)
   {
       nextcluster = GetNextCluster (gFiles[f].CurrentCluster);
       
         if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
         {
            actsector = nextcluster + gFAT32Vars.gFirstDataSector;
            ReadSector (actsector,gFiles[f].IOpuffer);
            
            gFiles[f].CurrentCluster = nextcluster;
            gFiles[f].posinsector = 0;
         }
      }
   
      return TRUE;
}

char remove (char *fname)
{
      char i;
      char found;
      char f;
      DIR *pDir;
      int32 nextcluster;
      int32 currentcluster;
      char *filename;

      filename = TryFile (fname, &f);
      
      if (filename == 0) return FALSE;
      
      found = FindDirEntry (filename,f);
      
   if (!found)
   {
       gFiles[f].Free = TRUE;
       
       printf ("Arquivo n?o encontrado...\r\n");
         return FALSE;
      }
      
   
   
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gDirEntryIdx]));
      pDir->sName[0] = 0xE5;
      
      for (i = 1; i < 8; i++)
      pDir->sName[i] = ' ';
      
      for (i = 0; i < 3; i++)
         pDir->spam[i] = ' ';
         
      WriteSector (gFAT32Vars.gDirEntrySector, gFiles[f].IOpuffer);
      currentcluster = ComposeCluster (f);
      
      while ((currentcluster != 0x0FFFFFFF) && (nextcluster != 0))
   {
       nextcluster = GetNextCluster (currentcluster);
         ClearClusterEntry (currentcluster);
          currentcluster = nextcluster;
      }
      
      ClearClusterEntry (currentcluster);
      SetClusterEntry (currentcluster, 0);
      currentcluster = gFAT32Vars.gStartSector + DiskInfo.Reserved1 + gFAT32Vars.FATstartidx;
      WriteSector (currentcluster, FATTable);
      currentcluster += DiskInfo.hSectorsPerFat;
      WriteSector (currentcluster, FATTable);
      gFiles[f].Free = TRUE;
   
      return TRUE;
}

char getfsize (char *fname, int32 *fsiz)
{
      char found;
      char f;
      DIR *pDir;
      char *filename;

      filename = TryFile (fname, &f);
      
      if (filename == 0) return FALSE;
      
      found = FindDirEntry (filename, f);
   
   if (!found)
   {
       gFiles[f].Free = TRUE;
       
         return FALSE;
      }
   
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gDirEntryIdx]));
   
      gFiles[f].Free = TRUE;
      *fsiz = pDir->wSize;
   
      return TRUE;
}

⌨️ 快捷键说明

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