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

📄 fat_open.c

📁 ucFS的加强版,含完整代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        FS__fat_free(buffer);
        return 0;
      }
      s = (FS__fat_dentry_type*)buffer;
      while (1) {
        if (s >= (FS__fat_dentry_type*)(buffer + FS_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 + FS_FAT_SEC_SIZE)) {
        /* Entry found. Return number of 1st block of the directory */
        FS__fat_free(buffer);
        dstart  = (FS_u32)s->data[26];
        dstart += (FS_u32)0x100UL * s->data[27];
        dstart += (FS_u32)0x10000UL * s->data[20];
        dstart += (FS_u32)0x1000000UL * s->data[21];
        return dstart;
      }
    }
    dstart = 0;
    FS__fat_free(buffer);
  }
  return dstart;
}


/*********************************************************************
*
*             FS__fat_dir_realsec
*
  Description:
  FS internal function. Translate a directory relative sector number
  to a real sector number on the media.
  
  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. 
  DirSec      - Sector in the directory.
 
  Return value:
  >0          - Directory found. Value is the sector number on the media.
  ==0         - An error has occured.
*/

FS_u32 FS__fat_dir_realsec(int Idx, FS_u32 Unit, FS_u32 DirStart, FS_u32 DirSec) {
  FS_u32 rootdir;
  FS_u32 rsec;
  FS_u32 dclust;
  FS_u32 fatsize;
  int fattype;
  int lexp;
  unsigned char secperclus;

  fattype = FS__fat_which_type(Idx, Unit);
  lexp = (0 == DirStart);
  lexp = lexp && (fattype != 2);
  
  if (lexp)
  {
    /* Sector in FAT12/FAT16 root directory */
    rootdir = FS__fat_find_dir(Idx, Unit, 0, 0, 0);
    rsec = rootdir + DirSec;
  }
  else
  {
    fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz16;
    
	if (fatsize == 0) 
	{
      fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz32;
    }
    
	secperclus = FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
    dclust = DirSec / secperclus;
    
	if (0 == DirStart) 
	{
      /* FAT32 root directory */
      rsec = FS__FAT_aBPBUnit[Idx][Unit].RootClus;
    } 
    else 
	{
      rsec = FS__fat_diskclust(Idx, Unit, DirStart, dclust);
      
	  if (rsec == 0) 
	  {
        return 0;
      }
    }
    
	rsec -= 2;
    rsec *= secperclus;
    rsec += FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt + FS__FAT_aBPBUnit[Idx][Unit].NumFATs * fatsize;
    rsec += ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[Idx][Unit].RootEntCnt) * FS_FAT_DENTRY_SIZE) / FS_FAT_SEC_SIZE;
    rsec += (DirSec % secperclus);
  }
  return rsec;
}


/*********************************************************************
*
*             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.
*/

FS_u32 FS__fat_dir_size(int Idx, FS_u32 Unit, FS_u32 DirStart) {
  FS_u32 dsize;
  FS_i32 value;

  if (DirStart == 0) {
    /* For FAT12/FAT16 root directory, the size can be found in BPB */
    dsize = ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[Idx][Unit].RootEntCnt)
            * FS_FAT_DENTRY_SIZE) / ((FS_u32)FS__FAT_aBPBUnit[Idx][Unit].BytesPerSec);
    if (dsize == 0) {
      /* Size in BPB is 0, so it is a FAT32 (FAT32 does not have a real root dir) */
      value = FS__fat_FAT_find_eof(Idx, Unit, FS__FAT_aBPBUnit[Idx][Unit].RootClus, &dsize);
      if (value < 0) {
        dsize = 0;
      }
      else {
        dsize *= FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
      }
    }
  }
  else {
    /* Calc size of a sub-dir */
    value = FS__fat_FAT_find_eof(Idx, Unit, DirStart, &dsize);
    if (value < 0) {
      dsize = 0;
    }
    else {
      dsize *= FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
    }
  }
  return dsize;
}


/*********************************************************************
*
*             FS__fat_findpath
*
  Description:
  FS internal function. Return start cluster and size of the directory
  of the file name in pFileName.
  
  Parameters:
  Idx         - Index of device in the device information table 
                referred by FS__pDevInfo.
  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.
*/

FS_u32 FS__fat_findpath(int Idx, const char *pFullName, FS_FARCHARPTR *pFileName, 
                        FS_u32 *pUnit, FS_u32 *pDirStart) {
  FS_u32 dsize;
  FS_i32 i;
  FS_i32 j;
  FS_FARCHARPTR dname_start;
  FS_FARCHARPTR dname_stop;
  FS_FARCHARPTR chprt;
  
  int x;
  
  /* Find correct unit (unit:name) */
  *pFileName = (FS_FARCHARPTR)FS__CLIB_strchr(pFullName, ':');
  if (*pFileName) {
    /* Scan for unit number */
    *pUnit = FS__CLIB_atoi(pFullName);
    (*pFileName)++;
  }
  else {
    /* Use 1st unit as default */
    *pUnit = 0;
    *pFileName = (FS_FARCHARPTR) pFullName;
  }
  /* Check volume */
  x = !FS__fat_checkunit(Idx, *pUnit);
  
  if (x) 
  {
    return 0;
  }
  
  /* Setup pDirStart/dsize for root directory */
  
  *pDirStart = FS__FAT_aBPBUnit[Idx][*pUnit].RootClus;

  dsize      = FS__fat_dir_size(Idx, *pUnit, 0);
  /* Find correct directory */
  do 
  {
	  dname_start = (FS_FARCHARPTR)FS__CLIB_strchr(*pFileName, '\\');
	  if (dname_start) 
	  {
		  dname_start++;
		  *pFileName = dname_start;
		  dname_stop = (FS_FARCHARPTR)FS__CLIB_strchr(dname_start, '\\');
	  }
	  else 
	  {
		  dname_stop = 0;
	  }
	  
	  if (dname_stop) 
	  {
		  i = dname_stop - dname_start;
		  
		  *pDirStart =  FS__fat_find_dir_ex(Idx, *pUnit, dname_start, i,*pDirStart, dsize);
		  
		  if (*pDirStart)
		  {
			  dsize  =  FS__fat_dir_size(Idx, *pUnit, *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(const char *pFileName, const char *pMode, FS_FILE *pFile) {
  FS_u32 unit;
  FS_u32 dstart;
  FS_u32 dsize;
  FS_i32 i;
  FS_FARCHARPTR fname;
  FS__fat_dentry_type s;
  //char realname[12];
  int lexp_a;
  int lexp_b;
  
  if (!pFile) {
    return 0;  /* Not a valid pointer to an FS_FILE structure*/
  }
  dsize = FS__fat_findpath(pFile->dev_index, pFileName, &fname, &unit, &dstart);
  if (dsize == 0) {
    return 0;  /* Directory not found */
  }
  FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_INC_BUSYCNT, 0, (void*)0);  /* Turn on busy signal */
  
  //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(pFile->dev_index, unit, realname, &s, dstart, dsize);
  i = _FS_fat_find_file_ex(pFile->dev_index, unit, fname, &s, dstart, dsize);
  
  /* 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(pFile->dev_index, unit, fname, dstart, dsize, 1);
    if (i != 0) {
      pFile->error = -1;
    }
    else {
      pFile->error = 0;
    }
    FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_FLUSH_CACHE, 2, (void*)0);
    FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
    return 0;
  }
  else if (lexp_b) {
    FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
    pFile->error = -1;
    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 */
    FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
    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(pFile->dev_index, unit, fname, 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 */
    FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
    return 0;
  }
  else if ((pFile->mode_c) && (i < 0)) {
    /* Create new file */
	//fname = "12345.txt";
    i = _FS_fat_create_file_ex(pFile->dev_index, unit, fname, dstart, dsize);
    if (i < 0) {
      /* Could not create file */
      if (i == -2) {
        /* Directory is full, try to increase */
        i = _FS_fat_IncDir(pFile->dev_index, unit, dstart, &dsize);
        if (i > 0) {
          i = _FS_fat_create_file(pFile->dev_index, unit, fname, dstart, dsize);
        }
      }
      if (i < 0) {
        FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
        return 0;
      }
    }
  }
  pFile->fileid_lo  = unit;
  pFile->fileid_hi  = i;
  pFile->fileid_ex  = dstart;
  pFile->EOFClust   = -1;
  pFile->CurClust   = 0;
  pFile->error      = 0;
  pFile->size       = (FS_u32)s.data[28];   /* FileSize */
  pFile->size      += (FS_u32)0x100UL * s.data[29];
  pFile->size      += (FS_u32)0x10000UL * s.data[30];
  pFile->size      += (FS_u32)0x1000000UL * s.data[31];
  if (pFile->mode_a) {
    pFile->filepos   = pFile->size;
  }
  else {
    pFile->filepos   = 0;
  }
  pFile->inuse     = 1;
  return pFile;
}

⌨️ 快捷键说明

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