123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /*
- * (C) Copyright 2002
- * Stäubli Faverges - <www.staubli.com>
- * Pierre AUBERT p.aubert@staubli.com
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
- #include <common.h>
- #include <config.h>
- #include <malloc.h>
- #if (CONFIG_COMMANDS & CFG_CMD_FDOS)
- #include "dos.h"
- #include "fdos.h"
- /*-----------------------------------------------------------------------------
- * fat_decode --
- *-----------------------------------------------------------------------------
- */
- unsigned int fat_decode (Fs_t *fs, unsigned int num)
- {
- unsigned int start = num * 3 / 2;
- unsigned char *address = fs -> fat_buf + start;
-
- if (num < 2 || start + 1 > (fs -> fat_len * SZ_STD_SECTOR))
- return 1;
-
- if (num & 1)
- return ((address [1] & 0xff) << 4) | ((address [0] & 0xf0 ) >> 4);
- else
- return ((address [1] & 0xf) << 8) | (address [0] & 0xff );
- }
- /*-----------------------------------------------------------------------------
- * check_fat --
- *-----------------------------------------------------------------------------
- */
- static int check_fat (Fs_t *fs)
- {
- int i, f;
- /* Cluster verification */
- for (i = 3 ; i < fs -> num_clus; i++){
- f = fat_decode (fs, i);
- if (f < FAT12_LAST && f > fs -> num_clus){
- /* Wrong cluster number detected */
- return (-1);
- }
- }
- return (0);
- }
- /*-----------------------------------------------------------------------------
- * read_one_fat --
- *-----------------------------------------------------------------------------
- */
- static int read_one_fat (BootSector_t *boot, Fs_t *fs, int nfat)
- {
- if (dev_read (fs -> fat_buf,
- (fs -> fat_start + nfat * fs -> fat_len),
- fs -> fat_len) < 0) {
- return (-1);
- }
- if (fs -> fat_buf [0] || fs -> fat_buf [1] || fs -> fat_buf [2]) {
- if ((fs -> fat_buf [0] != boot -> descr &&
- (fs -> fat_buf [0] != 0xf9 || boot -> descr != MEDIA_STD)) ||
- fs -> fat_buf [0] < MEDIA_STD){
- /* Unknown Media */
- return (-1);
- }
- if (fs -> fat_buf [1] != 0xff || fs -> fat_buf [2] != 0xff){
- /* FAT doesn't start with good values */
- return (-1);
- }
- }
- if (fs -> num_clus >= FAT12_MAX_NB) {
- /* Too much clusters */
- return (-1);
- }
- return check_fat (fs);
- }
- /*-----------------------------------------------------------------------------
- * read_fat --
- *-----------------------------------------------------------------------------
- */
- int read_fat (BootSector_t *boot, Fs_t *fs)
- {
- unsigned int buflen;
- int i;
- /* Allocate Fat Buffer */
- buflen = fs -> fat_len * SZ_STD_SECTOR;
- if (fs -> fat_buf) {
- free (fs -> fat_buf);
- }
- if ((fs -> fat_buf = malloc (buflen)) == NULL) {
- return (-1);
- }
- /* Try to read each Fat */
- for (i = 0; i< fs -> nb_fat; i++){
- if (read_one_fat (boot, fs, i) == 0) {
- /* Fat is OK */
- fs -> num_fat = i;
- break;
- }
- }
- if (i == fs -> nb_fat){
- return (-1);
- }
-
- if (fs -> fat_len > (((fs -> num_clus + 2) *
- (FAT_BITS / 4) -1 ) / 2 /
- SZ_STD_SECTOR + 1)) {
- return (-1);
- }
- return (0);
- }
-
- #endif
|