mirror of https://github.com/FDOS/kernel.git
* 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:
parent
dacd24e524
commit
4f1a117069
48
hdr/fat.h
48
hdr/fat.h
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ...);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue