示例#1
0
/****************************************************************************
 *
 * fn_initvolume
 *
 * initiate a volume, this function has to be called 1st to set physical
 * driver function to a given volume
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_initvolume ( F_DRIVERINIT initfunc )
{
#if F_FS_THREAD_AWARE == 1
	{
		extern xSemaphoreHandle fs_lock_semaphore;

		if( fs_lock_semaphore == NULL )
		{
			fs_lock_semaphore = xSemaphoreCreateMutex();
			if( fs_lock_semaphore == NULL )
			{
				return F_ERR_OS;
			}
		}
	}
#endif /* F_FS_THREAD_AWARE */

  gl_volume.state = F_STATE_NONE;

  mdrv = initfunc( 0 );
  if ( mdrv == NULL )
  {
    return F_ERR_INITFUNC;
  }

  gl_volume.state = F_STATE_NEEDMOUNT;

#if F_FILE_CHANGED_EVENT
  f_filechangedevent = 0;
#endif

  return _f_getvolume();
} /* fn_initvolume */
示例#2
0
/****************************************************************************
 *
 * fn_flush
 *
 * flush a previously opened file
 *
 * INPUTS
 *
 * filehandle - which file needs to be closed
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_flush ( F_FILE * f )
{
  unsigned char  ret;

  if ( !f )
  {
    return F_ERR_NOTOPEN;
  }

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  if ( gl_file.mode == F_FILE_CLOSE )
  {
    return F_ERR_NOTOPEN;
  }
  else if ( gl_file.mode != F_FILE_RD )
  {
    if ( gl_file.modified )
    {
      if ( _f_writeglsector( (unsigned long)-1 ) )
      {
        (void)_f_updatefileentry( 1 );
        return F_ERR_WRITE;
      }
    }

    return _f_updatefileentry( 0 );
  }

  return F_NO_ERROR;
} /* fn_flush */
示例#3
0
/****************************************************************************
 *
 * fn_hardformat
 *
 * Making a complete format on media, independently from master boot record,
 * according to media physical
 *
 * INPUTS
 * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA
 *
 * RETURNS
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_hardformat ( unsigned char fattype )
{
  unsigned char  ret;
  int            mdrv_ret;
  F_PHY          phy;

  ret = _f_getvolume();
  if ( ret && ( ret != F_ERR_NOTFORMATTED ) )
  {
    return ret;
  }

  gl_volume.state = F_STATE_NEEDMOUNT;

  psp_memset( &phy, 0, sizeof( F_PHY ) );

  mdrv_ret = mdrv->getphy( mdrv, &phy );
  if ( mdrv_ret )
  {
    return F_ERR_ONDRIVE;
  }

  ret = _f_prepareformat( &phy, fattype ); /*no partition*/
  if ( ret )
  {
    return ret;
  }

  return _f_postformat( &phy, fattype );
} /* fn_hardformat */
示例#4
0
unsigned char fn_seek ( F_FILE * f, long offset, unsigned char whence )
{
  unsigned char  ret;

  if ( !f )
  {
    return F_ERR_NOTOPEN;
  }

  if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )
  {
    return F_ERR_NOTOPEN;
  }

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  if ( whence == F_SEEK_CUR )
  {
    return _f_fseek( (long)( gl_file.abspos + gl_file.relpos + offset ) );
  }
  else if ( whence == F_SEEK_END )
  {
    return _f_fseek( (long)( gl_file.filesize + offset ) );
  }
  else if ( whence == F_SEEK_SET )
  {
    return _f_fseek( offset );
  }

  return F_ERR_NOTUSEABLE;
} /* fn_seek */
示例#5
0
/****************************************************************************
 *
 * fn_getfreespace
 *
 * get total/free/used/bad diskspace
 *
 * INPUTS
 * pspace - pointer where to store the information
 *
 * RETURNS
 * error code
 *
 ***************************************************************************/
unsigned char fn_getfreespace ( F_SPACE * pspace )
{
  unsigned char  ret;
  unsigned long  a;
  unsigned long  clustersize;

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  psp_memset( pspace, 0, sizeof( F_SPACE ) );
  pspace->total = gl_volume.maxcluster;

  gl_volume.fatsector = (unsigned long)-1;
  for ( a = 2 ; a < gl_volume.maxcluster + 2 ; a++ )
  {
    unsigned long  value;

    ret = _f_getclustervalue( a, &value );
    if ( ret )
    {
      return ret;
    }

    if ( !value )
    {
      ++( pspace->free );
    }
    else if ( value == F_CLUSTER_BAD )
    {
      ++( pspace->bad );
    }
    else
    {
      ++( pspace->used );
    }
  }

  clustersize = (unsigned long)( gl_volume.bootrecord.sector_per_cluster * F_SECTOR_SIZE );
  for ( a = 0 ; ( clustersize & 1 ) == 0 ; a++ )
  {
    clustersize >>= 1;
  }

  pspace->total_high = ( pspace->total ) >> ( 32 - a );
  pspace->total <<= a;
  pspace->free_high = ( pspace->free ) >> ( 32 - a );
  pspace->free <<= a;
  pspace->used_high = ( pspace->used ) >> ( 32 - a );
  pspace->used <<= a;
  pspace->bad_high = ( pspace->bad ) >> ( 32 - a );
  pspace->bad <<= a;

  return F_NO_ERROR;
} /* fn_getfreespace */
示例#6
0
/****************************************************************************
 *
 * fn_getserial
 *
 * get serial number
 *
 * INPUTS
 * serial - pointer where to store the serial number
 *
 * RETURNS
 * error code
 *
 ***************************************************************************/
unsigned char fn_getserial ( unsigned long * serial )
{
  unsigned char  ret;

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  *serial = gl_volume.bootrecord.serial_number;
  return 0;
}
示例#7
0
long fn_filelength ( const char * filename )
{
  F_POS        pos;
  F_DIRENTRY * de;
  F_NAME       fsname;

  if ( _f_setfsname( filename, &fsname ) )
  {
    return 0;                                     /*invalid name*/
  }

  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )
  {
    return 0;                                                    /*invalid name*/
  }

  if ( _f_getvolume() )
  {
    return 0;                     /*can't get the size*/
  }

  if ( !_f_findpath( &fsname, &pos ) )
  {
    return 0;
  }

  if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )
  {
    return 0;
  }

  if ( de->attr & F_ATTR_DIR )
  {
    return 0;                                           /*directory*/
  }

  return (long)_f_getlong( &de->filesize );
} /* fn_filelength */
示例#8
0
long fn_write ( const void * buf, long size, long _size_st, F_FILE * f )
{
  char * buffer = (char *)buf;
  long   retsize;
  long   ret = 0;

  if ( !f )
  {
    return 0;
  }

  if ( ( gl_file.mode & ( F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )
  {
    return 0;
  }

  retsize = size;
  size *= _size_st;
  _size_st = retsize;
  retsize = 0;

  if ( size == 0 )
  {
    return 0;
  }

  if ( _f_getvolume() )
  {
    return 0;                     /*can't write*/
  }

  if ( ( gl_file.mode ) & ( F_FILE_A | F_FILE_AP ) )
  {
    if ( _f_fseek( (long)gl_file.filesize ) )
    {
      gl_file.mode = F_FILE_CLOSE;
      return 0;
    }
  }

  if ( gl_file.startcluster == 0 )
  {
    if ( _f_stepnextsector() )
    {
      gl_file.mode = F_FILE_CLOSE;
      return 0;
    }
  }
  else
  {
    if ( _f_getcurrsector() )
    {
      gl_file.mode = F_FILE_CLOSE;
      return 0;
    }
  }

  for( ; ; )
  {
    unsigned long  wrsize = (unsigned long)size;

    if ( gl_file.relpos == F_SECTOR_SIZE )
    {     /*now full*/
      if ( gl_file.modified )
      {
        if ( _f_writeglsector( gl_file.pos.sector ) )
        {
          gl_file.mode = F_FILE_CLOSE;
          if ( _f_updatefileentry( 0 ) == 0 )
          {
            return retsize;
          }
          else
          {
            return 0;
          }
        }

        gl_file.modified = 0;
      }

      if ( _f_stepnextsector() )
      {
        gl_file.mode = F_FILE_CLOSE;
        if ( _f_updatefileentry( 0 ) == 0 )
        {
          return retsize;
        }
        else
        {
          return 0;
        }
      }

      gl_file.abspos += gl_file.relpos;
      gl_file.relpos = 0;

      if ( wrsize && ( wrsize < F_SECTOR_SIZE ) )
      {
        ret = _f_getcurrsector();

        if ( ret )
        {
          if ( ret != F_ERR_EOF )
          {
            gl_file.mode = F_FILE_CLOSE;       /*no more read allowed*/
            return retsize;
          }
        }
      }
    }

    if ( !size )
    {
      break;
    }

    if ( wrsize >= F_SECTOR_SIZE - gl_file.relpos )
    {
      wrsize = (unsigned long)( F_SECTOR_SIZE - gl_file.relpos );
    }


    psp_memcpy( gl_sector + gl_file.relpos, buffer, wrsize );
    gl_file.modified = 1;    /*sector is modified*/

    buffer += wrsize;
    gl_file.relpos += wrsize;
    size -= wrsize;
    retsize += wrsize;

    if ( gl_file.filesize < gl_file.abspos + gl_file.relpos )
    {
      gl_file.filesize = gl_file.abspos + gl_file.relpos;
    }
  }

  return retsize / _size_st;
} /* fn_write */
示例#9
0
/****************************************************************************
 *
 * fn_read
 *
 * read data from file
 *
 * INPUTS
 *
 * buf - where the store data
 * size - size of items to be read
 * _size_t - number of items need to be read
 * filehandle - file where to read from
 *
 * RETURNS
 *
 * with the number of read bytes
 *
 ***************************************************************************/
long fn_read ( void * buf, long size, long _size_st, F_FILE * f )
{
  char * buffer = (char *)buf;
  long   retsize;

  if ( !f )
  {
    return 0;
  }

  if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )
  {
    return 0;
  }

  retsize = size;
  size *= _size_st;
  _size_st = retsize;
  retsize = 0;

  if ( _f_getvolume() )
  {
    return 0;                     /*cant read any*/
  }

  if ( size + gl_file.relpos + gl_file.abspos >= gl_file.filesize ) /*read len longer than the file*/
  {
    size = (long)( ( gl_file.filesize ) - ( gl_file.relpos ) - ( gl_file.abspos ) ); /*calculate new size*/
  }

  if ( size <= 0 )
  {
    return 0;
  }

  if ( _f_getcurrsector() )
  {
    gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/
    return 0;
  }

  for( ; ; )
  {
    unsigned long  rdsize = (unsigned long)size;

    if ( gl_file.relpos == F_SECTOR_SIZE )
    {
      unsigned char  ret;

      gl_file.abspos += gl_file.relpos;
      gl_file.relpos = 0;

      if ( gl_file.modified )
      {
        ret = _f_writeglsector( (unsigned long)-1 );     /*empty write buffer */
        if ( ret )
        {
          gl_file.mode = F_FILE_CLOSE;         /*no more read allowed*/
          return retsize;
        }
      }

      gl_file.pos.sector++;         /*goto next*/

      ret = _f_getcurrsector();
      if ( ( ret == F_ERR_EOF ) && ( !size ) )
      {
        return retsize;
      }

      if ( ret )
      {
        gl_file.mode = F_FILE_CLOSE;       /*no more read allowed*/
        return retsize;
      }
    }

    if ( !size )
    {
      break;
    }

    if ( rdsize >= F_SECTOR_SIZE - gl_file.relpos )
    {
      rdsize = (unsigned long)( F_SECTOR_SIZE - gl_file.relpos );
    }

    psp_memcpy( buffer, gl_sector + gl_file.relpos, rdsize ); /*always less than 512*/

    buffer += rdsize;
    gl_file.relpos += rdsize;
    size -= rdsize;
    retsize += rdsize;
  }

  return retsize / _size_st;
} /* fn_read */
示例#10
0
/****************************************************************************
 *
 * fn_close
 *
 * close a previously opened file
 *
 * INPUTS
 *
 * filehandle - which file needs to be closed
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_close ( F_FILE * f )
{
  unsigned char  ret;

#if F_FILE_CHANGED_EVENT
  unsigned char  mode;
#endif

  if ( !f )
  {
    return F_ERR_NOTOPEN;
  }

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  if ( gl_file.mode == F_FILE_CLOSE )
  {
    return F_ERR_NOTOPEN;
  }

  else if ( gl_file.mode == F_FILE_RD )
  {
    gl_file.mode = F_FILE_CLOSE;
    return F_NO_ERROR;
  }
  else
  {
 #if F_FILE_CHANGED_EVENT
    mode = f->mode;
 #endif
    gl_file.mode = F_FILE_CLOSE;

    if ( gl_file.modified )
    {
      if ( _f_writeglsector( (unsigned long)-1 ) )
      {
        (void)_f_updatefileentry( 1 );
        return F_ERR_WRITE;
      }
    }

    ret = _f_updatefileentry( 0 );

 #if F_FILE_CHANGED_EVENT
    if ( f_filechangedevent && !ret )
    {
      ST_FILE_CHANGED  fc;
      if ( ( mode == F_FILE_WR )  || ( mode == F_FILE_WRP ) )
      {
        fc.action = FACTION_ADDED;
        fc.flags  = FFLAGS_FILE_NAME;
      }
      else if ( ( mode == F_FILE_A )  || ( mode == F_FILE_RDP ) )
      {
        fc.action = FACTION_MODIFIED;
        fc.flags  = FFLAGS_FILE_NAME | FFLAGS_SIZE;
      }

      strcpy( fc.filename, f->filename );
      if ( f->filename[0] )
      {
        f_filechangedevent( &fc );
      }

      f->filename[0] = '\0';
    }

 #endif /* if F_FILE_CHANGED_EVENT */
    return ret;
  }
} /* fn_close */
示例#11
0
/****************************************************************************
 *
 * fn_open
 *
 * open a file for reading/writing/appending
 *
 * INPUTS
 *
 * filename - which file need to be opened
 * mode - string how to open ("r"-read, "w"-write, "w+"-overwrite, "a"-append
 *
 * RETURNS
 *
 * F_FILE pointer if successfully
 * 0 - if any error
 *
 ***************************************************************************/
F_FILE * fn_open ( const char * filename, const char * mode )
{
  F_DIRENTRY    * de;
  F_NAME          fsname;
  unsigned short  date;
  unsigned short  time;
  unsigned char   m_mode = F_FILE_CLOSE;

  if ( mode[1] == 0 )
  {
    if ( mode[0] == 'r' )
    {
      m_mode = F_FILE_RD;
    }

    if ( mode[0] == 'w' )
    {
      m_mode = F_FILE_WR;
    }

    if ( mode[0] == 'a' )
    {
      m_mode = F_FILE_A;
    }
  }

  if ( ( mode[1] == '+' ) && ( mode[2] == 0 ) )
  {
    if ( mode[0] == 'r' )
    {
      m_mode = F_FILE_RDP;
    }

    if ( mode[0] == 'w' )
    {
      m_mode = F_FILE_WRP;
    }

    if ( mode[0] == 'a' )
    {
      m_mode = F_FILE_AP;
    }

  }

  if ( m_mode == F_FILE_CLOSE )
  {
    return 0;                                       /*invalid mode*/
  }

  if ( _f_setfsname( filename, &fsname ) )
  {
    return 0;                                     /*invalid name*/
  }

  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )
  {
    return 0;                                                    /*invalid name*/
  }

  if ( fsname.filename[0] == '.' )
  {
    return 0;
  }

  if ( _f_getvolume() )
  {
    return 0;                     /*cant open any*/
  }

  if ( gl_file.mode != F_FILE_CLOSE )
  {
    return 0;
  }

  psp_memset( &gl_file, 0, sizeof( F_FILE ) );

  if ( !_f_findpath( &fsname, &gl_file.dirpos ) )
  {
    return 0;
  }

  switch ( m_mode )
  {
    case F_FILE_RDP:   /*r*/
    case F_FILE_RD:   /*r*/
      if ( !_f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) )
      {
        return 0;
      }

      if ( de->attr & F_ATTR_DIR )
      {
        return 0;                                      /*directory*/
      }

      gl_file.startcluster = _f_getdecluster( de );

      if ( gl_file.startcluster )
      {
        _f_clustertopos( gl_file.startcluster, &gl_file.pos );
        gl_file.filesize = _f_getlong( &de->filesize );
        gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE);
        if ( _f_fseek( 0 ) )
        {
          return 0;
        }
      }

#if F_FILE_CHANGED_EVENT
      if ( m_mode == F_FILE_RDP )
      {
        _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );
      }

#endif

      break;

    case F_FILE_AP:
    case F_FILE_A: /*a*/
      psp_memcpy( &( gl_file.pos ), &( gl_file.dirpos ), sizeof( F_POS ) );
      if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) )
      {
        if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) )
        {
          return 0;
        }

        gl_file.startcluster = _f_getdecluster( de );
        gl_file.filesize = _f_getlong( &de->filesize );

        if ( gl_file.startcluster )
        {
          _f_clustertopos( gl_file.startcluster, &gl_file.pos );
          gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE);   /*forcing seek to read 1st sector! abspos=0;*/
          if ( _f_fseek( (long)gl_file.filesize ) )
          {
            gl_file.mode = F_FILE_CLOSE;
            return 0;
          }
        }
      }
      else
      {
        psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) );
        _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos );

        if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) )
        {
          return 0;                                                  /*couldnt be added*/
        }

        de->attr |= F_ATTR_ARC;         /*set as archiv*/
        if ( _f_writeglsector( (unsigned long)-1 ) )
        {
          return 0;
        }
      }

 #if F_FILE_CHANGED_EVENT
      _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );
 #endif
      break;


    case F_FILE_WR:  /*w*/
    case F_FILE_WRP: /*w+*/
      _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos );
      if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.pos, &de, 0 ) )
      {
        unsigned long  cluster = _f_getdecluster( de );    /*exist*/

        if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) )
        {
          return 0;
        }

        psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) );

        _f_setlong( de->filesize, 0 );  /*reset size;*/
        de->attr |= F_ATTR_ARC;         /*set as archiv*/
        _f_setword( de->clusterlo, 0 ); /*no points anywhere*/
        _f_setword( de->clusterhi, 0 );

        if ( gl_volume.mediatype == F_FAT32_MEDIA )
        {
          f_igettimedate( &time, &date );
          _f_setword( &de->crtdate, date );        /*if there is realtime clock then creation date could be set from*/
          _f_setword( &de->crttime, time );        /*if there is realtime clock then creation time could be set from*/
          _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/
        }

        if ( _f_writeglsector( (unsigned long)-1 ) )
        {
          return 0;
        }

        if ( _f_removechain( cluster ) )
        {
          return 0;                                /*remove */
        }
      }
      else
      {
        if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) )
        {
          return 0;                                                  /*couldnt be added*/
        }

        psp_memset( &gl_file, 0, 21 );
        de->attr |= F_ATTR_ARC;         /*set as archiv*/
        if ( _f_writeglsector( (unsigned long)-1 ) )
        {
          return 0;
        }
      }

 #if F_FILE_CHANGED_EVENT
      _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );
 #endif

      break;

    default:
      return 0;        /*invalid mode*/
  } /* switch */

  gl_file.mode = m_mode; /* lock it */
  return (F_FILE *)1;
} /* fn_open */
示例#12
0
/****************************************************************************
 *
 * fn_delete
 *
 * delete a file
 *
 * INPUTS
 *
 * filename - file which wanted to be deleted (with or without path)
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_delete ( const char * filename )
{
  F_POS          pos;
  F_DIRENTRY   * de;
  F_NAME         fsname;
  unsigned char  ret;

  if ( _f_setfsname( filename, &fsname ) )
  {
    return F_ERR_INVALIDNAME;                                     /*invalid name*/
  }

  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )
  {
    return F_ERR_INVALIDNAME;                                                    /*invalid name*/
  }

  if ( fsname.filename[0] == '.' )
  {
    return F_ERR_NOTFOUND;
  }

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  if ( !( _f_findpath( &fsname, &pos ) ) )
  {
    return F_ERR_INVALIDDIR;
  }

  if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )
  {
    return F_ERR_NOTFOUND;
  }

  if ( de->attr & F_ATTR_DIR )
  {
    return F_ERR_INVALIDDIR;                                /*directory*/
  }

  if ( de->attr & F_ATTR_READONLY )
  {
    return F_ERR_ACCESSDENIED;                                      /*readonly*/
  }

  if ( ( gl_file.mode != F_FILE_CLOSE ) && ( gl_file.dirpos.sector == pos.sector ) && ( gl_file.dirpos.pos == pos.pos ) )
  {
    return F_ERR_LOCKED;
  }

  de->name[0] = (unsigned char)0xe5; /*removes it*/
  ret = _f_writeglsector( (unsigned long)-1 );
  if ( ret )
  {
    return ret;
  }

  ret = _f_removechain( _f_getdecluster( de ) );

 #if F_FILE_CHANGED_EVENT
  if ( f_filechangedevent && !ret )
  {
    ST_FILE_CHANGED  fc;
    fc.action = FACTION_REMOVED;
    fc.flags = FFLAGS_FILE_NAME;

    if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )
    {
      f_filechangedevent( &fc );
    }
  }

 #endif

  return ret;
} /* fn_delete */