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

📄 fat_open.c

📁 s3c2410开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
  S8 *ext;
  S8 *s;
  S32 i;

  s = (S8 *)pOrgName;
  ext = (S8 *) FS__CLIB_strchr(s, '.');//ext指向'.'
  if (!ext) {
    ext = &s[FS__CLIB_strlen(s)];//如果没有'.'   ext->'\0'
  }
  i=0;
  while (1) {
    if (s >= ext) {
      break;  /* '.' reached */
    }
    if (i >= 8) {
      break;  /* If there is no '.', this is the end of the name */
    }
    if (*s == (char)0xe5) {
      pEntryName[i] = 0x05;
    }
    else {
      pEntryName[i] = (char)FS__CLIB_toupper(*s);
    }
    i++;
    s++;
  }
  while (i < 8) {
    /* Fill name with spaces*/
    pEntryName[i] = ' ';
    i++;
  }
  if (*s == '.') {
    s++;
  }
  while (i < 11) {
    if (*s != '\0') {
      if (*s == (char)0xe5) {
        pEntryName[i] = 0x05;
      }
      else {
        pEntryName[i] = (char)FS__CLIB_toupper(*s);
      }
      s++;
    }
    else {
      pEntryName[i] = ' ';
    }
    i++;
  }
  pEntryName[11]='\0';
}

/*********************************************************************
*
*             FS__fat_dirsize
*
  Description:
  FS internal function. Return the sector size of the directory 
  starting at DirStart.
  
  Parameters:
  Idx         - Index of device in the device information table 
                referred by FS__pDevInfo.
  Unit        - Unit number.
  DirStart    - 1st cluster of the directory. This is zero to address 
                the root directory. 
 
  Return value:
  >0          - Sector (not cluster) size of the directory.
  ==0         - An error has occured.
*/
//找出一层目录包含的扇区数

U32 FS__fat_dir_size( U32 DirStart) {
  U32 dsize;
  S32 value;

  if (DirStart == 0) {
    /* For FAT12/FAT16 root directory, the size can be found in BPB */
    dsize = FS__pDiskInfo[0].RootSecCnt;
  }
  else {
    /* Calc size of a sub-dir */
    value = FS__fat_FAT_find_eof( DirStart, &dsize);
    if (value < 0) {
      dsize = 0;
    }
    else {
      dsize *= FS__pDiskInfo[0].SecPerClus;
    }
  }
  return dsize;
}


/*********************************************************************
*
*             FS__fat_dir_realsec
*
  Description:
  FS internal function. Translate a directory relative sector number
  to a real sector number on the media.
  
  Parameters:
  DirStart    - 1st cluster of the directory. This is zero to address 
                the root directory. 
  DirSec      - Sector in the directory.
 
  Return value:
  >0          - Directory found. Value is the sector number on the media.
  ==0         - An error has occured.
*/
//返回相对于DirStart簇的扇区的真实扇区号

U32 FS__fat_dir_realsec( U32 DirStart, U32 DirSec) {
  U32 rootdir;
  U32 rsec;
  U32 dclust;
  U32 fatsize;
  S32 fattype;
  S32 lexp;
  U8 secperclus;

  fattype = FS__fat_which_type();
  lexp = (0 == DirStart);
  lexp = lexp && (fattype==FAT16);
  if (lexp) {
    /* Sector in FAT12/FAT16 root directory */
    rootdir =FS__pDiskInfo[0].RootDirTable;
    rsec = rootdir + DirSec;
  }
  else {
    fatsize = FS__pDiskInfo[0].FATSecCnt;
    secperclus = FS__pDiskInfo[0].SecPerClus;
    dclust = DirSec / secperclus;
    rsec = FS__fat_diskclust( DirStart, dclust);
    if (rsec == 0) {
      return 0;
    }
    rsec -= 2;
    rsec *= secperclus;
    rsec+=FS__pDiskInfo[0].DataStartSec;
    rsec += (DirSec % secperclus);
  }
  return rsec;
}


/*********************************************************************
*
*             FS__fat_find_dir
*
  Description:
  FS internal function. Find the directory with name pDirName in directory
  DirStart.
  
  Parameters:
  Idx         - Index of device in the device information table 
                referred by FS__pDevInfo.
  Unit        - Unit number.
  pDirName    - Directory name; if zero, return the root directory.
  DirStart    - 1st cluster of the directory.
  DirSize     - Sector (not cluster) size of the directory.
 
  Return value:
  >0          - Directory found. Value is the first cluster of the file.
  ==0         - An error has occured.
*/
//在一层目录树中寻找目录返回一个目录的开始簇号
U32 FS__fat_find_dir( S8 *pDirName, U32 DirStart,U32 DirSize) {
  FS__fat_dentry_type *s;
  U32 dstart;
  U32 i;
  U32 dsec;
  S32 len;
  S32 err;
  S32 c;
  S8 *buffer;

  if (pDirName == 0) {
    /* Return root directory */
      dstart=FS__pDiskInfo[0].RootDirTable;
  }
  else {
    /* Find directory */
    buffer = (S8 *)FS__fat_malloc(FAT_SEC_SIZE);
    if (BUFFER_ERR==(S32)buffer) {
      return 0;
    }
    len = FS__CLIB_strlen(pDirName);
    if (len > 11) {
      len = 11;
    }
    /* Read directory */
    for (i = 0; i < DirSize; i++) {
      dsec = FS__fat_dir_realsec(DirStart, i);
      if (dsec == 0) {
        FS__fat_free(buffer);
        return 0;
      }
      err = FS__lb_read(FS__pDevInfo[0].harddisk_driver, 0, dsec, (void*)buffer);
      if (err!=SD_NO_ERR) {
        FS__fat_free(buffer);
        return 0;
      }
      s = (FS__fat_dentry_type*)buffer;
      while (1) {
        if (s >= (FS__fat_dentry_type*)(buffer + FAT_SEC_SIZE)) {
          break;  /* End of sector reached */
        }
        c = FS__CLIB_strncmp((char*)s->data, pDirName, len);
        if (c == 0) { /* Name does match */
          if (s->data[11] & FS_FAT_ATTR_DIRECTORY) {
            break;  /* Entry found */
          }
        }
        s++;
      }
      if (s < (FS__fat_dentry_type*)(buffer + FAT_SEC_SIZE)) {
        /* Entry found. Return number of 1st block of the directory */
        FS__fat_free(buffer);
        dstart  = (U32)s->data[26];
        dstart += (U32)0x100UL * s->data[27];
        dstart += (U32)0x10000UL * s->data[20];
        dstart += (U32)0x1000000UL * s->data[21];
        return dstart;
      }
    }
    dstart = 0;
    FS__fat_free(buffer);
  }
  return dstart;
}



/*********************************************************************
*
*             FS__fat_findpath
*
  Description:
  FS internal function. Return start cluster and size of the directory
  of the file name in pFileName.
  
  Parameters:
  pFullName   - Fully qualified file name w/o device name.
  pFileName   - Pointer to a pointer, which is modified to point to the
                file name part of pFullName.
  pUnit       - Pointer to an FS_u32 for returning the unit number.
  pDirStart   - Pointer to an FS_u32 for returning the start cluster of
                the directory.

  Return value:
  >0          - Sector (not cluster) size of the directory.
  ==0         - An error has occured.
*/

//根据路径寻找一个目录文件,返回目录文件的开始簇号,目录文件的路径必须是   \\***\\****\\*****\\

U32 FS__fat_findpath( const S8 *pFullName, S8 **pFileName,U32 *pDirStart) {
  U32 dsize;
  S32 i;
  S32 j;
  S8 *dname_start;
  S8 *dname_stop;
  S8 *chprt;
  S32 x;
  S8 dname[12];
  S8 realname[12];
    /* Use 1st unit as default */
    *pFileName = (S8 *) pFullName;
  /* Check volume */
  x = FS__fat_checkunit();
  if (x!=FS_NO_ERR) {
    return 0;
  }
  /* Setup pDirStart/dsize for root directory */
  *pDirStart = 0;
  dsize      = FS__fat_dir_size(0);
  /* Find correct directory */
  do {
    dname_start = (S8 *)FS__CLIB_strchr(*pFileName, '\\');
    if (dname_start) {
      dname_start++;
      *pFileName = dname_start;
      dname_stop = (S8 *)FS__CLIB_strchr(dname_start, '\\');
    }
    else {
      dname_stop = 0;
    }
    if (dname_stop) {
      i = dname_stop-dname_start;
      if (i >= 12) {
        j = 0;
        for (chprt = dname_start; chprt < dname_stop; chprt++) {
          if (*chprt == '.') {
            i--;
          }
          else if (j < 12) {
            realname[j] = *chprt;
            j++;
          }
        }
        if (i >= 12) {
          return 0;
        }
      }
      else {
        FS__CLIB_strncpy(realname, dname_start, i);
      }
      realname[i] = '\0';
      FS__fat_make_realname(dname, realname);
      *pDirStart =  FS__fat_find_dir(dname, *pDirStart, dsize);
      if (*pDirStart) {
        dsize  =  FS__fat_dir_size(*pDirStart);
      }
      else {
        dsize = 0;    /* Directory NOT found */
      }
    }
  } while (dname_start);
  return dsize;
}



/*********************************************************************
*
*             Global functions section 2
*
**********************************************************************

  These are real global functions, which are used by the API Layer
  of the file system.
  
*/

/*********************************************************************
*
*             FS__fat_fopen
*
  Description:
  FS internal function. Open an existing file or create a new one.

  Parameters:
  pFileName   - File name. 
  pMode       - Mode for opening the file.
  pFile       - Pointer to an FS_FILE data structure.
  
  Return value:
  ==0         - Unable to open the file.
  !=0         - Address of the FS_FILE data structure.
*/

FS_FILE *FS__fat_fopen(S8 *pFileName,const S8 *pMode, FS_FILE *pFile) {
  U32 dstart;
  U32 dsize;
  S32 i;
  S8 * fname;
  FS__fat_dentry_type s;
  S8 realname[12];
  S32 lexp_a;
  S32 lexp_b;
  S32 lexp_c;
  
  if (!pFile) {
    return 0;  /* Not a valid pointer to an FS_FILE structure*/
  }
  dsize = FS__fat_findpath( pFileName, &fname, &dstart);
  if (dsize == 0) {
    return 0;  /* Directory not found */
  }
  FS__fat_make_realname(realname, fname);  /* Convert name to FAT real name */
  /* FileSize = 0 */
  s.data[28] = 0x00;      
  s.data[29] = 0x00;
  s.data[30] = 0x00;
  s.data[31] = 0x00;
  i = _FS_fat_find_file( realname, &s, dstart, dsize);
  if(i==0){
    FS__fat_DeleteFileOrDir(realname,dstart,dsize,1);
    i=_FS_fat_create_file(realname,dstart,dsize);
  }
  lexp_c=(i>0);
  /* Delete file */
  lexp_b = (FS__CLIB_strcmp(pMode, "del") == 0);    /* Delete file request */
  lexp_a = lexp_b && (i >= 0);                      /* File does exist */
  if (lexp_a) {
    i = FS__fat_DeleteFileOrDir( realname, dstart, dsize, 1);
    if (i < 0) {
      return (FS_FILE *)FS_ERR;
    }
    return 0;
  }
  else if (lexp_b) {
    return 0;
  }
  /* Check read only */
  lexp_a = ((i >= 0) && ((s.data[11] & FS_FAT_ATTR_READ_ONLY) != 0)) &&((pFile->mode_w) || (pFile->mode_a) || (pFile->mode_c));
  if (lexp_a) {
    /* Files is RO and we try to create, write or append */
    return 0;
  }
  lexp_a = (( i>= 0) && (!pFile->mode_a) && (((pFile->mode_w) && (!pFile->mode_r)) || ((pFile->mode_w) && (pFile->mode_c) && (pFile->mode_r)) ));
  if (lexp_a) {
    /* Delete old file */
    i = FS__fat_DeleteFileOrDir( realname, dstart, dsize, 1);
    /* FileSize = 0 */
    s.data[28] = 0x00;      
    s.data[29] = 0x00;
    s.data[30] = 0x00;
    s.data[31] = 0x00;
    i=-1;
  }
  if ((!pFile->mode_c) && (i < 0)) {
    /* File does not exist and we must not create */
    return 0;
  }
  else if ((pFile->mode_c) && (i < 0)) {
    /* Create new file */
    i = _FS_fat_create_file(realname, dstart, dsize);
    if (i < 0) {
      /* Could not create file */
      if (i == DIR_FULL) {
        /* Directory is full, try to increase */
        i = _FS_fat_IncDir( dstart, &dsize);
        if (i ==FS_NO_ERR) {
          i = _FS_fat_create_file(realname, dstart, dsize);
        }
      }
      if (i != FS_NO_ERR) {
        return 0;
      }
    }
  }
  pFile->CurClust   = 0;
  pFile->FstClus    = i;
  pFile->DirClus    =dstart;
  pFile->EOFClust   = -1;
  pFile->CacheId    =-1;
  pFile->dirty      =0;
  pFile->FileSize       = (U32)s.data[28];   /* FileSize */
  pFile->FileSize      += (U32)0x100UL * s.data[29];
  pFile->FileSize      += (U32)0x10000UL * s.data[30];
  pFile->FileSize      += (U32)0x1000000UL * s.data[31];
  if (pFile->mode_a) {
    pFile->Offset   = pFile->FileSize;
  }
  else {
    pFile->Offset   = 0;
  }
  pFile->inuse      = 1;
  return pFile;
}


⌨️ 快捷键说明

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