/*********************************************************************
*
*             _ReadFile
*
*  Read and measure time
*/
static I32 _ReadFile(FS_FILE * pFile, void * pData, U32 NumBytes) {
  I32 t;
  int i;
  t = (I32)FS_X_OS_GetTime();
  for (i = 0; i < NUM_BLOCKS_MEASURE; i++) {
    FS_Read(pFile, pData, NumBytes);
  }
  return FS_X_OS_GetTime() - t;
}
Beispiel #2
0
static FS_i32 _FS_fat_create_file(int Idx, FS_u32 Unit,  const char *pFileName,
                                    FS_u32 DirStart, FS_u32 DirSize) {
  FS__fat_dentry_type *s;
  FS_u32 i;
  FS_u32 dsec;
  FS_i32 cluster;
  int len;
  int err;
  FS_u16 val;
  char *buffer;

  buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
  if (!buffer) {
    return -1;
  }
  len = FS__CLIB_strlen(pFileName);
  if (len > 11) {
    len = 11;
  }
  /* Read directory */
  for (i = 0; i < DirSize; i++) {
    dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
    if (dsec == 0) {
      FS__fat_free(buffer);
      return -1;
    }
    err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
    if (err < 0) {
      FS__fat_free(buffer);
      return -1;
    }
    s = (FS__fat_dentry_type*)buffer;
    while (1) {
      if (s >= (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
        break;  /* End of sector reached */
      }
      if (s->data[0] == 0x00) {
        break;  /* Empty entry found */
      }
      if (s->data[0] == (unsigned char)0xe5) {
        break;  /* Deleted entry found */
      }
      s++;
    }
    if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
      /* Free entry found. Make entry and return 1st block of the file */
      FS__CLIB_strncpy((char*)s->data, pFileName, len);
      s->data[11] = FS_FAT_ATTR_ARCHIVE;
      /* Alloc block in FAT */
      cluster = FS__fat_FAT_alloc(Idx, Unit, -1);
      if (cluster >= 0) {
        s->data[12]     = 0x00;                           /* Res */
        s->data[13]     = 0x00;                           /* CrtTimeTenth (optional, not supported) */
        s->data[14]     = 0x00;                           /* CrtTime (optional, not supported) */
        s->data[15]     = 0x00;
        s->data[16]     = 0x00;                           /* CrtDate (optional, not supported) */
        s->data[17]     = 0x00;
        s->data[18]     = 0x00;                           /* LstAccDate (optional, not supported) */
        s->data[19]     = 0x00;
        val             = FS_X_OS_GetTime();
        s->data[22]     = (unsigned char)(val & 0xff);   /* WrtTime */
        s->data[23]     = (unsigned char)(val / 256);
        val             = FS_X_OS_GetDate();
        s->data[24]     = (unsigned char)(val & 0xff);   /* WrtDate */
        s->data[25]     = (unsigned char)(val / 256);
        s->data[26]     = (unsigned char)(cluster & 0xff);    /* FstClusLo / FstClusHi */ 
        s->data[27]     = (unsigned char)((cluster / 256) & 0xff);
        s->data[20]     = (unsigned char)((cluster / 0x10000L) & 0xff);
        s->data[21]     = (unsigned char)((cluster / 0x1000000L) & 0xff);
        s->data[28]     = 0x00;                           /* FileSize */
        s->data[29]     = 0x00;
        s->data[30]     = 0x00;
        s->data[31]     = 0x00;
        err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
        if (err < 0) {
          FS__fat_free(buffer);
          return -1;
        }
      }
      FS__fat_free(buffer);
      return cluster;
    }
  }
  FS__fat_free(buffer);
  return -2;      /* Directory is full */
}
Beispiel #3
0
FS_size_t FS__fat_fwrite(const void *pData, FS_size_t Size, FS_size_t N, FS_FILE *pFile) {
  FS_size_t todo;
  FS_u32 dstart;
  FS_u32 dsize;
  FS_u32 bytesperclus;
  FS_u32 datastart;
  FS_u32 fatsize;
  FS_u32 fileclustnum;
  FS_u32 diskclustnum;
  FS_u32 prevclust;
  FS_i32 last;
  FS_i32 i;
  FS_i32 j;
#if (FS_FAT_FWRITE_UPDATE_DIR)
  FS__fat_dentry_type s;
  FS_u32 dsec;
  FS_u16 val;
#endif /* FS_FAT_FWRITE_UPDATE_DIR */
  int err;
  int lexp;
  char *buffer;

  if (!pFile) {
      return 0;
  }
  /* Check if media is OK */
  err = FS__lb_status(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo);
  if (err == FS_LBL_MEDIACHANGED) {
    pFile->error = FS_ERR_DISKCHANGED;
    return 0;
  }
  else if (err < 0) {
    pFile->error = FS_ERR_WRITEERROR;
    return 0;
  }
  buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
  if (!buffer) {
    return 0;
  }
  fatsize = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].FATSz16;
  if (fatsize == 0) {
    /* FAT32 */
    fatsize = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].FATSz32;
  }
  todo = N * Size;  /* Number of bytes to be written */
  if (!todo) {
    FS__fat_free(buffer);
    return 0;
  }
  /* Alloc new clusters if required */
  bytesperclus = (FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus *
                 ((FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].BytesPerSec);
  /* Calculate number of clusters required */
  i = (pFile->filepos + todo) / bytesperclus;
  if ((pFile->filepos + todo) % bytesperclus) {
    i++;
  }
  /* Calculate clusters already allocated */
  j = pFile->size / bytesperclus;
  lexp = (pFile->size % bytesperclus);
  lexp = lexp || (pFile->size == 0);
  if (lexp) {
    j++;
  }
  i -= j;
  if (i > 0) {
    /* Alloc new clusters */
    last = pFile->EOFClust;
    if (last < 0) {
      /* Position of EOF is unknown, so we scan the whole file to find it */
      last = FS__fat_FAT_find_eof(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, 0);
    }
    if (last < 0) {
      /* No EOF found */
      FS__fat_free(buffer);
      return 0;
    }
    while (i) {
      last = FS__fat_FAT_alloc(pFile->dev_index, pFile->fileid_lo, last);  /* Allocate new cluster */
      pFile->EOFClust = last;
      if (last < 0) {
        /* Cluster allocation failed */
        pFile->size += (N * Size - todo);
        pFile->error = FS_ERR_DISKFULL;
        FS__fat_free(buffer);
        return ((N * Size - todo) / Size);
      }
      i--;
    }
  }
  /* Get absolute postion of data area on the media */
  dstart    = (FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RsvdSecCnt + 
              FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].NumFATs * fatsize;
  dsize     = ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RootEntCnt) * FS_FAT_DENTRY_SIZE) / FS_FAT_SEC_SIZE;
  datastart = dstart + dsize;
  /* Write data to clusters */
  prevclust = 0;
  while (todo) {  /* Write data loop */
    /* Translate file ppinter position to cluster position*/
    fileclustnum = pFile->filepos / bytesperclus;
    /* 
       Translate the file relative cluster position to an absolute cluster
       position on the media. To avoid scanning the whole FAT of the file,
       we remember the current cluster position in the FS_FILE data structure.
    */
    if (prevclust == 0) {
      diskclustnum = pFile->CurClust;
      if (diskclustnum == 0) {
        /* No known current cluster position, we have to scan from the file's start cluster */
        diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, fileclustnum);
      }
    } 
    else {
      /* Get next cluster of the file starting at the current cluster */
      diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1);
    }
    prevclust        = diskclustnum;
    pFile->CurClust  = diskclustnum;
    if (diskclustnum == 0) {
      /* Translation to absolute cluster failed */
      pFile->error = FS_ERR_WRITEERROR;
      FS__fat_free(buffer);
      return ((N * Size - todo) / Size);
    }
    diskclustnum -= 2;
    j = (pFile->filepos % bytesperclus) / FS_FAT_SEC_SIZE;
    while (1) {  /* Cluster loop */
      if (!todo) {
        break;  /* Nothing more to write */
      }
      if (j >= FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) {
        break; /* End of cluster reached */
      }
      i = pFile->filepos % FS_FAT_SEC_SIZE;
      /* 
         We only have to read the sector from the media, if we do not
         modify the whole sector. That is the case if

         a) Writing starts not at the first byte of the sector
         b) Less data than the sector contains is written
      */
      lexp = (i != 0);
      lexp = lexp || (todo < FS_FAT_SEC_SIZE);
      if (lexp) {
        /* We have to read the old sector */
        err = FS__lb_read(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo,
                      datastart +
                      diskclustnum * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus + j,
                      (void*)buffer);
        if (err < 0) {
          pFile->error = FS_ERR_WRITEERROR;
          FS__fat_free(buffer);
          return ((N * Size - todo) / Size);
        }
      }
      while (1) {  /* Sector loop */
        if (!todo) {
          break;  /* Nothing more to write */
        }
        if (i >= FS_FAT_SEC_SIZE) {
          break;  /* End of sector reached */
        }
        buffer[i] = *((FS_FARCHARPTR)(((FS_FARCHARPTR)pData) + N * Size - todo));
        i++;
        pFile->filepos++;
        if (pFile->filepos > pFile->size) {
          pFile->size = pFile->filepos;
        }
        todo--;
      }  /* Sector loop */
      /* Write the modified sector */
      err = FS__lb_write(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo,
                    datastart +
                    diskclustnum * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus + j,
                    (void*)buffer);
      if (err < 0) {
        pFile->error = FS_ERR_WRITEERROR;
        FS__fat_free(buffer);
        return ((N * Size - todo) / Size);
      }
      j++;
    }  /* Cluster loop */
  } /* Write data loop */
  if (i >= FS_FAT_SEC_SIZE) {
    if (j >= FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) {
      /* File pointer is already in the next cluster */
      pFile->CurClust = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1);
    }
  }
 
#if (FS_FAT_FWRITE_UPDATE_DIR)
  /* Modify directory entry */
  err = _FS_fat_read_dentry(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, pFile->fileid_ex, &s, &dsec, buffer);
  if (err == 0) {
    pFile->error = FS_ERR_WRITEERROR;
    FS__fat_free(buffer);
    return ((N * Size - todo) / Size);
  }
  s.data[28] = (unsigned char)(pFile->size & 0xff);   /* FileSize */
  s.data[29] = (unsigned char)((pFile->size / 0x100UL) & 0xff);   
  s.data[30] = (unsigned char)((pFile->size / 0x10000UL) & 0xff);
  s.data[31] = (unsigned char)((pFile->size / 0x1000000UL) & 0xff);
  val = FS_X_OS_GetTime();
  s.data[22] = (unsigned char)(val & 0xff);
  s.data[23] = (unsigned char)((val / 0x100) & 0xff);
  val = FS_X_OS_GetDate();
  s.data[24] = (unsigned char)(val & 0xff);
  s.data[25] = (unsigned char)((val / 0x100) & 0xff);
  err = _FS_fat_write_dentry(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, &s, dsec, buffer);
  if (err == 0) {
    pFile->error = FS_ERR_WRITEERROR;
  }
#endif /* FS_FAT_FWRITE_UPDATE_DIR */
  FS__fat_free(buffer);
  return ((N * Size - todo) / Size);
}
Beispiel #4
0
void FS__fat_fclose(FS_FILE *pFile) {
#if (FS_FAT_FWRITE_UPDATE_DIR==0)
  FS__fat_dentry_type s;
  char *buffer;
  FS_u32 dsec;
  FS_u16 val;
#endif /* FS_FAT_FWRITE_UPDATE_DIR */
  int err;

  if (!pFile) {
      return;
  }
  /* Check if media is OK */
  err = FS__lb_status(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo);
  if (err == FS_LBL_MEDIACHANGED) {
    pFile->error = FS_ERR_DISKCHANGED;
    FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
    pFile->inuse = 0;
    return;
  }
  else if (err < 0) {
    pFile->error = FS_ERR_CLOSE;
    FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
    pFile->inuse = 0;
    return;
  }
#if (FS_FAT_FWRITE_UPDATE_DIR==0)
  /* Modify directory entry */
  buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
  if (!buffer) {
    pFile->inuse = 0;
    pFile->error = FS_ERR_CLOSE;
    return;
  }
  err = _FS_fat_read_dentry(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, pFile->fileid_ex, &s, &dsec, buffer);
  if (err == 0) {
    pFile->inuse = 0;
    pFile->error = FS_ERR_CLOSE;
    FS__fat_free(buffer);
    return;
  }
  s.data[28] = (unsigned char)(pFile->size & 0xff);   /* FileSize */
  s.data[29] = (unsigned char)((pFile->size / 0x100UL) & 0xff);   
  s.data[30] = (unsigned char)((pFile->size / 0x10000UL) & 0xff);
  s.data[31] = (unsigned char)((pFile->size / 0x1000000UL) & 0xff);
  val = FS_X_OS_GetTime();
  s.data[22] = (unsigned char)(val & 0xff);
  s.data[23] = (unsigned char)((val / 0x100) & 0xff);
  val = FS_X_OS_GetDate();
  s.data[24] = (unsigned char)(val & 0xff);
  s.data[25] = (unsigned char)((val / 0x100) & 0xff);
  err = _FS_fat_write_dentry(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, &s, dsec, buffer);
  if (err == 0) {
    pFile->error = FS_ERR_CLOSE;
  }
  FS__fat_free(buffer);
#endif /* FS_FAT_FWRITE_UPDATE_DIR */
  err = FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_FLUSH_CACHE, 2, (void*)0);
  if (err < 0) {
    pFile->error = FS_ERR_WRITEERROR;
  }
  pFile->inuse = 0;
  FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
}
Beispiel #5
0
static int _FS_fat_create_directory(int Idx, FS_u32 Unit, const char *pDirName,
                                    FS_u32 DirStart, FS_u32 DirSize) {
  char *buffer;
  FS__fat_dentry_type *s;
  FS_u32 dirindex;
  FS_u32 dsec;
  FS_i32 cluster;
  FS_u16 val_time;
  FS_u16 val_date;
  int err;
  int len;
  int j;

  buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
  if (!buffer) {
    return -1;
  }
  len = FS__CLIB_strlen(pDirName);
  if (len > 11) {
    len = 11;
  }
  /* Read directory */
  for (dirindex = 0; dirindex < DirSize; dirindex++) {
    dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, dirindex);
    if (dsec == 0) {
      /* Translation of relativ directory sector to an absolute sector failed */
      FS__fat_free(buffer);
      return -1;
    }
    err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer); /* Read directory sector */
    if (err < 0) {
      /* Read error */
      FS__fat_free(buffer);
      return -1;
    }
    /* Scan the directory sector for a free or deleted entry */
    s = (FS__fat_dentry_type*)buffer;
    while (1) {
      if (s >= (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
        break;  /* End of sector reached */
      }
      if (s->data[0] == 0x00) {
        break;  /* Found a free entry */
      }
      if (s->data[0] == (unsigned char)0xe5) {
        break;  /* Found a deleted entry */
      }
      s++;
    }
    if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
      /* Free entry found. Make entry and return 1st block of the file. */
      FS__CLIB_strncpy((char*)s->data, pDirName, len);
       s->data[11] = FS_FAT_ATTR_DIRECTORY;
      cluster = FS__fat_FAT_alloc(Idx, Unit, -1);              /* Alloc block in FAT */
      if (cluster >= 0) {
        s->data[12]     = 0x00;                                /* Res */
        s->data[13]     = 0x00;                                /* CrtTimeTenth (optional, not supported) */
        s->data[14]     = 0x00;                                /* CrtTime (optional, not supported) */
        s->data[15]     = 0x00;
        s->data[16]     = 0x00;                                /* CrtDate (optional, not supported) */
        s->data[17]     = 0x00;
        s->data[18]     = 0x00;                                /* LstAccDate (optional, not supported) */
        s->data[19]     = 0x00;
        val_time        = FS_X_OS_GetTime();
        s->data[22]     = (unsigned char)(val_time & 0xff);   /* WrtTime */
        s->data[23]     = (unsigned char)(val_time / 256);
        val_date        = FS_X_OS_GetDate();
        s->data[24]     = (unsigned char)(val_date & 0xff);   /* WrtDate */
        s->data[25]     = (unsigned char)(val_date / 256);
        s->data[26]     = (unsigned char)(cluster & 0xff);    /* FstClusLo / FstClusHi */ 
        s->data[27]     = (unsigned char)((cluster / 256) & 0xff);
        s->data[20]     = (unsigned char)((cluster / 0x10000L) & 0xff);
        s->data[21]     = (unsigned char)((cluster / 0x1000000L) & 0xff);
        s->data[28]     = 0x00;                                /* FileSize */
        s->data[29]     = 0x00;
        s->data[30]     = 0x00;
        s->data[31]     = 0x00;
        err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer); /* Write the modified directory sector */
        if (err < 0) {
          FS__fat_free(buffer);
          return -1;
        }
        /* Clear new directory and make '.' and '..' entries */
        /* Make "." entry */
        FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE);
        s = (FS__fat_dentry_type*)buffer;
        FS__CLIB_strncpy((char*)s->data, ".          ", 11);
        s->data[11]     = FS_FAT_ATTR_DIRECTORY;
        s->data[22]     = (unsigned char)(val_time & 0xff);   /* WrtTime */
        s->data[23]     = (unsigned char)(val_time / 256);
        s->data[24]     = (unsigned char)(val_date & 0xff);   /* WrtDate */
        s->data[25]     = (unsigned char)(val_date / 256);
        s->data[26]     = (unsigned char)(cluster & 0xff);    /* FstClusLo / FstClusHi */ 
        s->data[27]     = (unsigned char)((cluster / 256) & 0xff);
        s->data[20]     = (unsigned char)((cluster / 0x10000L) & 0xff);
        s->data[21]     = (unsigned char)((cluster / 0x1000000L) & 0xff);
        /* Make entry ".." */
        s++;
        FS__CLIB_strncpy((char*)s->data, "..         ", 11);
        s->data[11]     = FS_FAT_ATTR_DIRECTORY;
        s->data[22]     = (unsigned char)(val_time & 0xff);   /* WrtTime */
        s->data[23]     = (unsigned char)(val_time / 256);
        s->data[24]     = (unsigned char)(val_date & 0xff);   /* WrtDate */
        s->data[25]     = (unsigned char)(val_date / 256);
        s->data[26]     = (unsigned char)(DirStart & 0xff);    /* FstClusLo / FstClusHi */ 
        s->data[27]     = (unsigned char)((DirStart / 256) & 0xff);
        s->data[20]     = (unsigned char)((DirStart / 0x10000L) & 0xff);
        s->data[21]     = (unsigned char)((DirStart / 0x1000000L) & 0xff);
        dsec = FS__fat_dir_realsec(Idx, Unit, cluster, 0); /* Find 1st absolute sector of the new directory */
        if (dsec == 0) {
          FS__fat_free(buffer);
          return -1;
        }
        /* Write "." & ".." entries into the new directory */
        err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
        if (err < 0) {
          FS__fat_free(buffer);
          return -1;
        }
        /* Clear rest of the directory cluster */
        FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE);
        for (j = 1; j < FS__FAT_aBPBUnit[Idx][Unit].SecPerClus; j++) {
          dsec = FS__fat_dir_realsec(Idx, Unit, cluster, j);
          err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
          if (err < 0) {
            FS__fat_free(buffer);
            return -1;
          }
        }
        FS__fat_free(buffer);
        return 1;

      }
      FS__fat_free(buffer);
      return -1;
    }
  }
  FS__fat_free(buffer);
  return -2;  /* Directory is full */
}