* FAT32 kernels should ignore the upper word of the cluster number for

FAT16 partitions (just like FAT16 kernels do)
* added extra checks to make sure that invalid FAT entries are never
  followed
* made put_console() public to be able to print a message in case of
  FAT corruption
* some small optimizations and header cleanups (some suggested by Arkady)


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@753 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2004-01-26 00:51:49 +00:00
parent dacd24e524
commit 4f1a117069
6 changed files with 86 additions and 55 deletions

View File

@ -57,11 +57,6 @@ static BYTE *fat_hRcsId =
#define DELETED '\x5' /* if first char, delete file */
#define EXT_DELETED '\xe5' /* external deleted flag */
/* FAT cluster to physical conversion macros */
#define clus_add(cl_no) ((ULONG) (((ULONG) cl_no - 2L) \
* (ULONG) cluster_size \
+ (ULONG) data_start))
/* Test for 16 bit or 12 bit FAT */
#define SIZEOF_CLST16 2
#define SIZEOF_CLST32 4
@ -70,8 +65,8 @@ static BYTE *fat_hRcsId =
#define FREE 0x000
#ifdef WITHFAT32
#define LONG_LAST_CLUSTER 0x0FFFFFFFl
#define LONG_BAD 0x0FFFFFF7l
#define LONG_LAST_CLUSTER 0x0FFFFFFFUL
#define LONG_BAD 0x0FFFFFF7UL
#else
#define LONG_LAST_CLUSTER 0xFFFF
#define LONG_BAD 0xFFF7
@ -86,8 +81,8 @@ static BYTE *fat_hRcsId =
for FAT12; similar for 16 and 32 */
#define FAT_MAGIC 4085
#define FAT_MAGIC16 ((unsigned)65525l)
#define FAT_MAGIC32 268435455l
#define FAT_MAGIC16 65525U
#define FAT_MAGIC32 268435455UL
/* int ISFAT32(struct dpb FAR *dpbp);*/
#define ISFAT32(x) _ISFAT32(x)
@ -133,31 +128,26 @@ struct lfn_entry {
/* */
#ifdef WITHFAT32
#define getdstart(dentry) \
(((ULONG)dentry.dir_start_high << 16) | dentry.dir_start)
#define setdstart(dentry, value) \
dentry.dir_start = (UCOUNT)value; \
dentry.dir_start_high = (UCOUNT)(value >> 16)
#define checkdstart(dentry, value) \
(dentry.dir_start == (UCOUNT)value && \
dentry.dir_start_high == (UCOUNT)(value >> 16))
CLUSTER getdstart(struct dpb FAR *dpbp, struct dirent *dentry);
void setdstart(struct dpb FAR *dpbp, struct dirent *dentry, CLUSTER value);
BOOL checkdstart(struct dpb FAR *dpbp, struct dirent *dentry, CLUSTER value);
#else
#define getdstart(dentry) \
dentry.dir_start
#define setdstart(dentry, value) \
dentry.dir_start = (UCOUNT)value
#define checkdstart(dentry, value) \
(dentry.dir_start == (UCOUNT)value)
#define getdstart(dpbp, dentry) \
((dentry)->dir_start)
#define setdstart(dpbp, dentry, value) \
(((dentry)->dir_start) = (UWORD)(value))
#define checkdstart(dpbp, dentry, value) \
(((dentry)->dir_start) == (UWORD)(value))
#endif
#define DIR_NAME 0
#define DIR_EXT FNAME_SIZE
#define DIR_ATTRIB FNAME_SIZE+FEXT_SIZE
#define DIR_RESERVED FNAME_SIZE+FEXT_SIZE+1
#define DIR_TIME FNAME_SIZE+FEXT_SIZE+11
#define DIR_DATE FNAME_SIZE+FEXT_SIZE+13
#define DIR_START FNAME_SIZE+FEXT_SIZE+15
#define DIR_SIZE FNAME_SIZE+FEXT_SIZE+17
#define DIR_ATTRIB (FNAME_SIZE+FEXT_SIZE)
#define DIR_RESERVED (FNAME_SIZE+FEXT_SIZE+1)
#define DIR_TIME (FNAME_SIZE+FEXT_SIZE+11)
#define DIR_DATE (FNAME_SIZE+FEXT_SIZE+13)
#define DIR_START (FNAME_SIZE+FEXT_SIZE+15)
#define DIR_SIZE (FNAME_SIZE+FEXT_SIZE+17)
#define DIRENT_SIZE 32

View File

@ -166,7 +166,7 @@ f_node_ptr dir_open(register const char *dirname)
{
/* make certain we've moved off */
/* root */
dir_init_fnode(fnp, getdstart(fnp->f_dir));
dir_init_fnode(fnp, getdstart(fnp->f_dpb, &fnp->f_dir));
}
}
return fnp;

View File

@ -57,6 +57,34 @@ BOOL first_fat(f_node_ptr);
COUNT map_cluster(f_node_ptr, COUNT);
STATIC VOID shrink_file(f_node_ptr fnp);
#ifdef WITHFAT32
CLUSTER getdstart(struct dpb FAR *dpbp, struct dirent *dentry)
{
if (!ISFAT32(dpbp))
return dentry->dir_start;
return (((CLUSTER)dentry->dir_start_high << 16) | dentry->dir_start);
}
void setdstart(struct dpb FAR *dpbp, struct dirent *dentry, CLUSTER value)
{
if (!ISFAT32(dpbp))
{
dentry->dir_start = (UWORD)value;
return;
}
dentry->dir_start = (UWORD)value;
dentry->dir_start_high = (UWORD)(value >> 16);
}
BOOL checkdstart(struct dpb FAR *dpbp, struct dirent *dentry, CLUSTER value)
{
if (!ISFAT32(dpbp))
return dentry->dir_start == (UWORD)value;
return (dentry->dir_start == (UWORD)value &&
dentry->dir_start_high == (UWORD)(value >> 16));
}
#endif
ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp)
{
CLUSTER data =
@ -83,10 +111,12 @@ STATIC void init_direntry(struct dirent *dentry, unsigned attrib,
struct dostime dt;
dentry->dir_size = 0l;
#ifndef WITHFAT32
#ifdef WITHFAT32
dentry->dir_start_high = (UWORD)(cluster >> 16);
#else
dentry->dir_start_high = 0;
#endif
setdstart((*dentry), cluster);
#endif
dentry->dir_start = (UWORD)cluster;
dentry->dir_attrib = attrib;
dentry->dir_case = 0;
DosGetTime(&dt);
@ -236,7 +266,7 @@ long dos_open(char *path, unsigned flags, unsigned attrib)
if (status != S_OPENED)
{
fnp->f_cluster = FREE;
setdstart(fnp->f_dir, FREE);
setdstart(fnp->f_dpb, &fnp->f_dir, FREE);
fnp->f_cluster_offset = 0;
}
@ -247,7 +277,7 @@ long dos_open(char *path, unsigned flags, unsigned attrib)
merge_file_changes(fnp, status == S_OPENED); /* /// Added - Ron Cemer */
/* /// Moved from above. - Ron Cemer */
fnp->f_cluster = getdstart(fnp->f_dir);
fnp->f_cluster = getdstart(fnp->f_dpb, &fnp->f_dir);
fnp->f_cluster_offset = 0;
return xlt_fnp(fnp) | ((long)status << 16);
@ -813,10 +843,10 @@ STATIC VOID wipe_out_clusters(struct dpb FAR * dpbp, CLUSTER st)
STATIC VOID wipe_out(f_node_ptr fnp)
{
/* if already free or not valid file, just exit */
if ((fnp == NULL) || checkdstart(fnp->f_dir, FREE))
if ((fnp == NULL) || checkdstart(fnp->f_dpb, &fnp->f_dir, FREE))
return;
wipe_out_clusters(fnp->f_dpb, getdstart(fnp->f_dir));
wipe_out_clusters(fnp->f_dpb, getdstart(fnp->f_dpb, &fnp->f_dir));
}
STATIC BOOL find_free(f_node_ptr fnp)
@ -1155,7 +1185,7 @@ COUNT dos_mkdir(BYTE * dir)
parent = 0;
}
#endif
setdstart(DirEntBuffer, parent);
setdstart(dpbp, &DirEntBuffer, parent);
/* and put it out */
putdirent(&DirEntBuffer, &bp->b_buffer[DIRENT_SIZE]);
@ -1171,7 +1201,7 @@ COUNT dos_mkdir(BYTE * dir)
{
/* as we are overwriting it completely, don't read first */
bp = getblockOver(clus2phys(getdstart(fnp->f_dir), dpbp) + idx,
bp = getblockOver(clus2phys(getdstart(dpbp, &fnp->f_dir), dpbp) + idx,
dpbp->dpb_unit);
#ifdef DISPLAY_GETBLOCK
printf("DIR (dos_mkdir)\n");
@ -1293,7 +1323,7 @@ STATIC BOOL first_fat(f_node_ptr fnp)
/* BUG!! this caused wrong allocation, if file was created,
then seeked, then written */
fnp->f_cluster = free_fat;
setdstart(fnp->f_dir, free_fat);
setdstart(fnp->f_dpb, &fnp->f_dir, free_fat);
link_fat(fnp->f_dpb, free_fat, LONG_LAST_CLUSTER);
/* Mark the directory so that the entry is updated */
@ -1333,7 +1363,7 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
/* If someone did a seek, but no writes have occured, we will */
/* need to initialize the fnode. */
if ((mode == XFR_WRITE) && checkdstart(fnp->f_dir, FREE))
if ((mode == XFR_WRITE) && checkdstart(fnp->f_dpb, &fnp->f_dir, FREE))
{
/* If there are no more free fat entries, then we are full! */
if (!first_fat(fnp))
@ -1346,7 +1376,7 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
{
/* Set internal index and cluster size. */
fnp->f_cluster = fnp->f_flags.f_ddir ? fnp->f_dirstart :
getdstart(fnp->f_dir);
getdstart(fnp->f_dpb, &fnp->f_dir);
fnp->f_cluster_offset = 0;
}
@ -1841,21 +1871,21 @@ CLUSTER dos_free(struct dpb FAR * dpbp)
/* cluster start at 2 and run to max_cluster+2 */
REG CLUSTER i;
REG CLUSTER cnt = 0;
CLUSTER max_cluster = dpbp->dpb_size + 1;
CLUSTER max_cluster = dpbp->dpb_size;
#ifdef WITHFAT32
if (ISFAT32(dpbp))
{
if (dpbp->dpb_xnfreeclst != XUNKNCLSTFREE)
return dpbp->dpb_xnfreeclst;
max_cluster = dpbp->dpb_xsize + 1;
max_cluster = dpbp->dpb_xsize;
}
else
#endif
if (dpbp->dpb_nfreeclst != UNKNCLSTFREE)
return dpbp->dpb_nfreeclst;
for (i = 2; i < max_cluster; i++)
for (i = 2; i <= max_cluster; i++)
{
if (next_cluster(dpbp, i) == 0)
++cnt;
@ -2192,7 +2222,7 @@ STATIC VOID shrink_file(f_node_ptr fnp)
if (fnp->f_dir.dir_size == 0)
{
setdstart(fnp->f_dir, FREE);
setdstart(dpbp, &fnp->f_dir, FREE);
link_fat(dpbp, st, FREE);
}
else

View File

@ -50,6 +50,23 @@ int ISFAT32(struct dpb FAR * dpbp)
struct buffer FAR *getFATblock(ULONG clussec, struct dpb FAR * dpbp)
{
struct buffer FAR *bp;
CLUSTER max_cluster = dpbp->dpb_size;
#ifdef WITHFAT32
if (ISFAT32(dpbp))
max_cluster = dpbp->dpb_xsize;
#endif
if (clussec <= 1 || clussec > max_cluster)
{
put_string("run CHKDSK: trying to access invalid cluster 0x");
#ifdef WITHFAT32
put_unsigned(clussec >> 16, 16, 4);
#endif
put_unsigned(clussec & 0xffffu, 16, 4);
put_console('\n');
return NULL;
}
if (ISFAT12(dpbp))
{
@ -259,12 +276,6 @@ unsigned link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
{
struct buffer FAR *bp;
#ifdef DEBUG
if (ClusterNum == LONG_LAST_CLUSTER)
printf("fatal error: trying to do next_cluster(dpbp, EOC)!\n");
if (ClusterNum == 0)
printf("fatal error: trying to do next_cluster(dpbp, 0)!\n");
#endif
/* Get the block that this cluster is in */
bp = getFATblock(ClusterNum, dpbp);

View File

@ -57,7 +57,7 @@ static BYTE *prfRcsId =
static int buff_offset = 0;
static char buff[MAX_BUFSIZE];
STATIC VOID put_console(COUNT c)
void put_console(int c)
{
if (buff_offset >= MAX_BUFSIZE)
{
@ -91,7 +91,7 @@ STATIC VOID put_console(COUNT c)
}
}
#else
STATIC VOID put_console(COUNT c)
void put_console(int c)
{
if (c == '\n')
put_console('\r');
@ -129,7 +129,6 @@ typedef char *va_list;
static BYTE *charp = 0;
STATIC VOID handle_char(COUNT);
STATIC VOID put_console(COUNT);
STATIC BYTE * ltob(LONG, BYTE *, COUNT);
STATIC COUNT do_printf(CONST BYTE *, REG va_list);
int CDECL printf(CONST BYTE * fmt, ...);

View File

@ -282,6 +282,7 @@ int CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
VOID hexd(char *title, VOID FAR * p, COUNT numBytes);
void put_unsigned(unsigned n, int base, int width);
void put_string(const char *s);
void put_console(int);
/* strings.c */
size_t /* ASMCFUNC */ ASMPASCAL strlen(const char * s);