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

📄 fs_fat32util.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 5 页
字号:
              dir->fd_currcluster = cluster;              dir->fd_currsector  = fat_cluster2sector(fs, cluster);            }        }    }  /* Save the new index into dir->fd_currsector */  dir->fd_index = ndx;  return OK;}/**************************************************************************** * Name: fat_finddirentry * * Desciption: Given a path to something that may or may not be in the file *   system, return the directory entry of the item. * ****************************************************************************/int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,                     const char *path){  size_t cluster;  ubyte *direntry = NULL;  char terminator;  int ret;  /* Initialize to traverse the chain.  Set it to the cluster of   * the root directory   */  cluster = fs->fs_rootbase;  if (fs->fs_type == FSTYPE_FAT32)    {      /* For FAT32, the root directory is variable sized and is a       * cluster chain like any other directory.  fs_rootbase holds       * the first cluster of the root directory.       */      dirinfo->dir.fd_startcluster = cluster;      dirinfo->dir.fd_currcluster  = cluster;      dirinfo->dir.fd_currsector   = fat_cluster2sector(fs, cluster);    }  else    {      /* For FAT12/16, the first sector of the root directory is a sector       * relative to the first sector of the fat volume.       */      dirinfo->dir.fd_startcluster = 0;      dirinfo->dir.fd_currcluster  = 0;      dirinfo->dir.fd_currsector   = cluster;    }  /* fd_index is the index into the current directory table */  dirinfo->dir.fd_index = 0;  /* If no path was provided, then the root directory must be exactly   * what the caller is looking for.   */  if (*path == '\0')    {      dirinfo->fd_entry = NULL;      return OK;    }  /* Otherwise, loop until the path is found */  for (;;)    {      /* Convert the next the path segment name into the kind of       * name that we would see in the directory entry.       */      ret = fat_path2dirname(&path, dirinfo, &terminator);      if (ret < 0)        {          /* ERROR:  The filename contains invalid characters or is           * too long.           */          return ret;        }      /* Now search the current directory entry for an entry with this       * matching name.       */      for (;;)        {          /* Read the next sector into memory */          ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);          if (ret < 0)            {              return ret;            }          /* Get a pointer to the directory entry */          direntry = &fs->fs_buffer[DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index)];          /* Check if we are at the end of the directory */          if (direntry[DIR_NAME] == DIR0_ALLEMPTY)            {              return -ENOENT;            }          /* Check if we have found the directory entry that we are looking for */          if (direntry[DIR_NAME] != DIR0_EMPTY &&              !(DIR_GETATTRIBUTES(direntry) & FATATTR_VOLUMEID) &&              !memcmp(&direntry[DIR_NAME], dirinfo->fd_name, 8+3) )            {              /* Yes.. break out of the loop */              break;            }          /* No... get the next directory index and try again */          if (fat_nextdirentry(fs, &dirinfo->dir) != OK)            {              return -ENOENT;            }        }      /* We get here only if we have found a directory entry that matches       * the path element that we are looking for.       *       * If the terminator character in the path was the end of the string       * then we have successfully found the directory entry that describes       * the path.       */      if (!terminator)        {          /* Return the pointer to the matching directory entry */          dirinfo->fd_entry = direntry;          return OK;        }      /* No.. then we have found one of the intermediate directories on       * the way to the final path target.  In this case, make sure       * the thing that we found is, indeed, a directory.       */      if (!(DIR_GETATTRIBUTES(direntry) & FATATTR_DIRECTORY))        {          /* Ooops.. we found something else */          return -ENOTDIR;        }      /* Get the cluster number of this directory */      cluster =          ((uint32)DIR_GETFSTCLUSTHI(direntry) << 16) |          DIR_GETFSTCLUSTLO(direntry);      /* The restart scanning at the new directory */      dirinfo->dir.fd_currcluster = dirinfo->dir.fd_startcluster = cluster;      dirinfo->dir.fd_currsector  = fat_cluster2sector(fs, cluster);      dirinfo->dir.fd_index       = 2;    }}/**************************************************************************** * Name: fat_allocatedirentry * * Desciption: Find a free directory entry * ****************************************************************************/int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo){  sint32 cluster;  size_t sector;  ubyte *direntry;  ubyte  ch;  int    ret;  int    i;  /* Re-initialize directory object */  cluster = dirinfo->dir.fd_startcluster;  if (cluster)    {     /* Cluster chain can be extended */      dirinfo->dir.fd_currcluster = cluster;      dirinfo->dir.fd_currsector  = fat_cluster2sector(fs, cluster);    }  else    {      /* Fixed size FAT12/16 root directory is at fixxed offset/size */      dirinfo->dir.fd_currsector = fs->fs_rootbase;    }  dirinfo->dir.fd_index = 0;  for (;;)    {      unsigned int dirindex;      /* Read the directory sector into fs_buffer */      ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);      if (ret < 0)        {          return ret;        }      /* Get a pointer to the entry at fd_index */      dirindex = (dirinfo->dir.fd_index & DIRSEC_NDXMASK(fs)) * 32;      direntry = &fs->fs_buffer[dirindex];      /* Check if this directory entry is empty */      ch = direntry[DIR_NAME];      if (ch == DIR0_ALLEMPTY || ch == DIR0_EMPTY)        {          /* It is empty -- we have found a directory entry */          dirinfo->fd_entry = direntry;          return OK;        }      ret = fat_nextdirentry(fs, &dirinfo->dir);      if (ret < 0)        {          return ret;        }    }  /* If we get here, then we have reached the end of the directory table   * in this sector without finding a free directory enty.   *   * It this is a fixed size dirctory entry, then this is an error.   * Otherwise, we can try to extend the directory cluster chain to   * make space for the new directory entry.   */  if (!cluster)    {      /* The size is fixed */      return -ENOSPC;    }  /* Try to extend the cluster chain for this directory */  cluster = fat_extendchain(fs, dirinfo->dir.fd_currcluster);  if (cluster < 0)    {      return cluster;    } /* Flush out any cached date in fs_buffer.. we are going to use  * it to initialize the new directory cluster.  */  ret = fat_fscacheflush(fs);  if (ret < 0)    {      return ret;    }  /* Clear all sectors comprising the new directory cluster */  fs->fs_currentsector = fat_cluster2sector(fs, cluster);  memset(fs->fs_buffer, 0, fs->fs_hwsectorsize);  sector = sector;  for (i = fs->fs_fatsecperclus; i; i--)    {      ret = fat_hwwrite(fs, fs->fs_buffer, sector, 1);      if ( ret < 0)        {          return ret;        }      sector++;    }  dirinfo->fd_entry = fs->fs_buffer;  return OK;}/**************************************************************************** * Name: fat_dirname2path * * Desciption:  Convert a filename in a raw directory entry into a user *    filename.  This is essentially the inverse operation of that performed *    by fat_path2dirname.  See that function for more details. * ****************************************************************************/int fat_dirname2path(char *path, ubyte *direntry){#ifdef CONFIG_FAT_LCNAMES    ubyte ntflags;#endif    int  ch;    int  ndx;    /* Check if we will be doing upper to lower case conversions */#ifdef CONFIG_FAT_LCNAMES    ntflags = DIR_GETNTRES(direntry);#endif    /* Get the 8-byte filename */    for (ndx = 0; ndx < 8; ndx++)      {        /* Get the next filename character from the directory entry */        ch = direntry[ndx];        /* Any space (or ndx==8) terminates the filename */        if (ch == ' ')          {            break;          }        /* In this version, we never write 0xe5 in the directoryfilenames         * (because we do not handle any character sets where 0xe5 is valid         * in a filaname), but we could encounted this in a filesystem         * written by some other system         */        if (ndx == 0 && ch == DIR0_E5)          {            ch = 0xe5;          }        /* Check if we should perform upper to lower case conversion         * of the (whole) filename.         */#ifdef CONFIG_FAT_LCNAMES        if (ntflags & FATNTRES_LCNAME && isupper(ch))          {            ch = tolower(ch);          }#endif        /* Copy the next character into the filename */        *path++ = ch;      }    /* Check if there is an extension */    if (direntry[8] != ' ')      {        /* Yes, output the dot before the extension */        *path++ = '.';        /* Then output the (up to) 3 character extension */        for (ndx = 8; ndx < 11; ndx++)          {            /* Get the next extensions character from the directory entry */            ch = direntry[DIR_NAME + ndx];            /* Any space (or ndx==11) terminates the extension */            if (ch == ' ')              {                break;              }            /* Check if we should perform upper to lower case conversion             * of the (whole) filename.             */#ifdef CONFIG_FAT_LCNAMES            if (ntflags & FATNTRES_LCEXT && isupper(ch))              {                ch = tolower(ch);              }#endif        /* Copy the next character into the filename */            *path++ = ch;          }      }    /* Put a null terminator at the end of the filename */    *path = '\0';    return OK;}/**************************************************************************** * Name: fat_dirtruncate * * Desciption: Truncate an existing file to zero length * * Assumptions:  The caller holds mountpoint semaphore, fs_buffer holds *   the directory entry, dirinfo refers to the current fs_buffer content. * ****************************************************************************/int  fat_dirtruncate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo){  unsigned int startcluster;  uint32       writetime;  size_t       savesector;  int          ret;  /* Get start cluster of the file to truncate */  startcluster =      ((uint32)DIR_GETFSTCLUSTHI(dirinfo->fd_entry) << 16) |      DIR_GETFSTCLUSTLO(dirinfo->fd_entry);  /* Clear the cluster start value in the directory and set the file size   * to zero.  This makes the file look empty but also have to dispose of   * all of the clusters in the chain.   */  DIR_PUTFSTCLUSTHI(dirinfo->fd_entry, 0);  DIR_PUTFSTCLUSTLO(dirinfo->fd_entry, 0);  DIR_PUTFILESIZE(dirinfo->fd_entry, 0);  /* Set the ARCHIVE attribute and update the write time */  DIR_PUTATTRIBUTES(dirinfo->fd_entry, FATATTR_ARCHIVE);   writetime = fat_systime2fattime();  DIR_PUTWRTTIME(dirinfo->fd_entry, writetime & 0xffff);  DIR_PUTWRTDATE(dirinfo->fd_entry, writetime > 16);  /* This sector needs to be written back to disk eventually */  fs->fs_dirty = TRUE;  /* Now remove the entire cluster chain comprising the file */  savesector = fs->fs_currentsector;  ret = fat_removechain(fs, startcluster);  if (ret < 0)  {    return ret;  }  /* Setup FSINFO to resuse this cluster next */  fs->fs_fsinextfree = startcluster - 1;  /* Make sure that the directory is still in the cache */  return fat_fscacheread(fs, savesector);}/**************************************************************************** * Name: fat_dircreate * * Desciption: Create a directory entry for a new file *

⌨️ 快捷键说明

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