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

View File

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

View File

@ -57,7 +57,7 @@ static BYTE *prfRcsId =
static int buff_offset = 0; static int buff_offset = 0;
static char buff[MAX_BUFSIZE]; static char buff[MAX_BUFSIZE];
STATIC VOID put_console(COUNT c) void put_console(int c)
{ {
if (buff_offset >= MAX_BUFSIZE) if (buff_offset >= MAX_BUFSIZE)
{ {
@ -91,7 +91,7 @@ STATIC VOID put_console(COUNT c)
} }
} }
#else #else
STATIC VOID put_console(COUNT c) void put_console(int c)
{ {
if (c == '\n') if (c == '\n')
put_console('\r'); put_console('\r');
@ -129,7 +129,6 @@ typedef char *va_list;
static BYTE *charp = 0; static BYTE *charp = 0;
STATIC VOID handle_char(COUNT); STATIC VOID handle_char(COUNT);
STATIC VOID put_console(COUNT);
STATIC BYTE * ltob(LONG, BYTE *, COUNT); STATIC BYTE * ltob(LONG, BYTE *, COUNT);
STATIC COUNT do_printf(CONST BYTE *, REG va_list); STATIC COUNT do_printf(CONST BYTE *, REG va_list);
int CDECL printf(CONST BYTE * fmt, ...); 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 hexd(char *title, VOID FAR * p, COUNT numBytes);
void put_unsigned(unsigned n, int base, int width); void put_unsigned(unsigned n, int base, int width);
void put_string(const char *s); void put_string(const char *s);
void put_console(int);
/* strings.c */ /* strings.c */
size_t /* ASMCFUNC */ ASMPASCAL strlen(const char * s); size_t /* ASMCFUNC */ ASMPASCAL strlen(const char * s);