📄 fatfs.c
字号:
if(fnp -> f_dir.dir_attrib & ~D_DIR)
{
dir_close(fnp);
return DE_ACCESS;
}
/* Check that the directory is empty. Only the */
/* "." and ".." are permissable. */
fnp -> f_flags.f_dmod = FALSE;
fnp1 = dir_open((BYTE FAR *)path);
dir_read(fnp1);
if(fnp1 -> f_dir.dir_name[0] != '.')
{
dir_close(fnp);
return DE_ACCESS;
}
dir_read(fnp1);
if(fnp1 -> f_dir.dir_name[0] != '.')
{
dir_close(fnp);
return DE_ACCESS;
}
/* Now search through the directory and make certain */
/* that there are no entries. */
found = FALSE;
while(dir_read(fnp1) == DIRENT_SIZE)
{
if(fnp1 -> f_dir.dir_name[0] == '\0')
break;
if(fnp1 -> f_dir.dir_name[0] == DELETED)
continue;
else
{
found = TRUE;
break;
}
}
dir_close(fnp1);
/* If anything was found, exit with an error. */
if(found)
{
dir_close(fnp);
return DE_ACCESS;
}
/* Ok, so we can delete. Start out by */
/* clobbering all FAT entries for this file */
/* (or, in English, truncate the FAT). */
wipe_out(fnp);
fnp -> f_dir.dir_size = 0l;
*(fnp -> f_dir.dir_name) = DELETED;
/* The directory has been modified, so set the */
/* bit before closing it, allowing it to be */
/* updated */
fnp -> f_flags.f_dmod = TRUE;
dir_close(fnp);
/* SUCCESSful completion, return it */
return SUCCESS;
}
else
{
/* No such file, return the error */
dir_close(fnp);
return DE_FILENOTFND;
}
}
COUNT dos_rename(path1, path2)
BYTE FAR *path1, FAR *path2;
{
REG struct f_node FAR *fnp1;
REG struct f_node FAR *fnp2;
BOOL is_free;
/* first split the passed target into compnents (i.e. - path to */
/* new file name and name of new file name */
if((fnp2 = split_path(path2, szSecDirName, szSecFileName, szSecFileExt)) == NULL)
{
dir_close(fnp2);
return DE_PATHNOTFND;
}
/* Check that we don't have a duplicate name, so if we find */
/* one, it's an error. */
if(find_fname(fnp2, szSecFileName, szSecFileExt))
{
dir_close(fnp2);
return DE_ACCESS;
}
/* next split the passed source into compnents (i.e. - path to */
/* old file name and name of old file name */
if((fnp1 = split_path(path1, szPriDirName, szPriFileName, szPriFileExt)) == NULL)
{
dir_close(fnp1);
dir_close(fnp2);
return DE_PATHNOTFND;
}
/* Reset the directory by a close followed by an open */
fnp2 -> f_flags.f_dmod = FALSE;
dir_close(fnp2);
fnp2 = dir_open((BYTE FAR *)szSecDirName);
/* Now find a free slot to put the file into. */
/* If it's the root and we don't have room, return an error. */
if(!(is_free = find_free(fnp2)) && (fnp2 -> f_flags.f_droot))
{
fnp2 -> f_flags.f_dmod = FALSE;
dir_close(fnp1);
dir_close(fnp2);
return DE_TOOMANY;
}
/* Otherwise just expand the directory */
else if(!is_free && !(fnp2 -> f_flags.f_droot))
{
COUNT ret;
if(extend_dir(fnp2) != SUCCESS)
return ret;
}
if(!find_fname(fnp1, szPriFileName, szPriFileExt))
{
/* No such file, return the error */
dir_close(fnp1);
dir_close(fnp2);
return DE_FILENOTFND;
}
/* put the fnode's name into the directory. */
fbcopy((BYTE FAR *)szSecFileName,
(BYTE FAR *)fnp2 -> f_dir.dir_name, FNAME_SIZE);
fbcopy((BYTE FAR *)szSecFileExt,
(BYTE FAR *)fnp2 -> f_dir.dir_ext, FEXT_SIZE);
/* Set the fnode to the desired mode */
fnp2 -> f_dir.dir_size = fnp1 -> f_dir.dir_size;
fnp2 -> f_dir.dir_start = fnp1 -> f_dir.dir_start;
fnp2 -> f_dir.dir_attrib = fnp1 -> f_dir.dir_attrib;
fnp2 -> f_dir.dir_time = fnp1 -> f_dir.dir_time;
fnp2 -> f_dir.dir_date = fnp1 -> f_dir.dir_date;
/* The directory has been modified, so set the bit before */
/* closing it, allowing it to be updated. */
fnp1 -> f_flags.f_dmod = fnp2 -> f_flags.f_dmod = TRUE;
fnp1 -> f_flags.f_dnew = fnp2 -> f_flags.f_dnew = FALSE;
fnp1 -> f_flags.f_ddir = fnp2 -> f_flags.f_ddir = TRUE;
fnp2 -> f_highwater = fnp2 -> f_offset = fnp1 -> f_dir.dir_size;
/* Ok, so we can delete this one. Save the file info. */
fnp1 -> f_dir.dir_size = 0l;
*(fnp1 -> f_dir.dir_name) = DELETED;
dir_close(fnp1);
dir_close(fnp2);
/* SUCCESSful completion, return it */
return SUCCESS;
}
/* */
/* wipe out all FAT entries for create, delete, etc. */
/* */
static VOID
wipe_out (struct f_node FAR *fnp)
{
REG UWORD st, next;
struct dpb *dpbp = fnp -> f_dpb;
/* if already free or not valid file, just exit */
if((fnp == NULL) || (fnp -> f_dir.dir_start == FREE))
return;
/* if there are no FAT entries, just exit */
if(fnp -> f_dir.dir_start == FREE)
return;
/* Loop from start until either a FREE entry is */
/* encountered (due to a fractured file system) of the */
/* last cluster is encountered. */
for(st = fnp -> f_dir.dir_start ;
st != LONG_LAST_CLUSTER && st != LAST_CLUSTER;)
{
/* get the next cluster pointed to */
next = next_cluster(dpbp, st);
/* just exit if a damaged file system exists */
if(next == FREE)
return;
/* zap the FAT pointed to */
link_fat(dpbp, st, FREE);
/* and the start of free space pointer */
if((dpbp -> dpb_cluster == UNKNCLUSTER)
|| (dpbp -> dpb_cluster > st))
dpbp -> dpb_cluster = st;
/* and just follow the linked list */
st = next;
}
}
static BOOL
find_free (struct f_node FAR *fnp)
{
while(dir_read(fnp) == DIRENT_SIZE)
{
if(fnp -> f_dir.dir_name[0] == '\0'
|| fnp -> f_dir.dir_name[0] == DELETED)
{
return TRUE;
}
}
return !fnp -> f_flags.f_dfull;
}
/* */
/* dos_getdate for the file date */
/* */
date dos_getdate()
{
#ifndef NOTIME
# ifndef IPL
BYTE WeekDay, Month, MonthDay;
COUNT Year;
date Date;
/* First - get the system date set by either the user */
/* on start-up or the CMOS clock */
DosGetDate((BYTE FAR *)&WeekDay,
(BYTE FAR *)&Month,
(BYTE FAR *)&MonthDay,
(COUNT FAR *)& Year);
Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR);
return Date;
# else
return 0;
# endif
#else
return 0;
#endif
}
/* */
/* dos_gettime for the file time */
/* */
time dos_gettime()
{
#ifndef NOTIME
# ifndef IPL
BYTE Hour, Minute, Second, Hundredth;
time Time;
BYTE h;
/* First - get the system time set by either the user */
/* on start-up or the CMOS clock */
DosGetTime((BYTE FAR *)&Hour,
(BYTE FAR *)&Minute,
(BYTE FAR *)&Second,
(BYTE FAR *)&Hundredth);
h = Second * 10 + ((Hundredth + 5) / 10);
Time = TM_ENCODE(Hour, Minute, h);
return Time;
# else
return 0;
# endif
#else
return 0;
#endif
}
#ifndef IPL
/* */
/* dos_getftime for the file time */
/* */
BOOL dos_getftime(fd, dp, tp)
COUNT fd;
date FAR *dp;
time FAR *tp;
{
struct f_node FAR *fnp;
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
fnp = xlt_fd(fd);
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if(fnp == (struct f_node FAR *)0 || fnp -> f_count <= 0)
return FALSE;
/* Get the date and time from the fnode and return */
*dp = fnp -> f_dir.dir_date;
*tp = fnp -> f_dir.dir_time;
return TRUE;
}
/* */
/* dos_setftime for the file time */
/* */
BOOL dos_setftime(fd, dp, tp)
COUNT fd;
date FAR *dp;
time FAR *tp;
{
struct f_node FAR *fnp;
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
fnp = xlt_fd(fd);
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if(fnp == (struct f_node FAR *)0 || fnp -> f_count <= 0)
return FALSE;
/* Set the date and time from the fnode and return */
fnp -> f_dir.dir_date = *dp;
fnp -> f_dir.dir_time = *tp;
return TRUE;
}
/* */
/* dos_getfsize for the file time */
/* */
LONG
dos_getcufsize (COUNT fd)
{
struct f_node FAR *fnp;
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
fnp = xlt_fd(fd);
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if(fnp == (struct f_node FAR *)0 || fnp -> f_count <= 0)
return -1l;
/* Return the file size */
return fnp -> f_highwater;
}
/* */
/* dos_getfsize for the file time */
/* */
LONG
dos_getfsize (COUNT fd)
{
struct f_node FAR *fnp;
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
fnp = xlt_fd(fd);
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if(fnp == (struct f_node FAR *)0 || fnp -> f_count <= 0)
return -1l;
/* Return the file size */
return fnp -> f_dir.dir_size;
}
/* */
/* dos_setfsize for the file time */
/* */
BOOL
dos_setfsize (COUNT fd, LONG size)
{
struct f_node FAR *fnp;
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
fnp = xlt_fd(fd);
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if(fnp == (struct f_node FAR *)0 || fnp -> f_count <= 0)
return FALSE;
/* Change the file size */
fnp -> f_dir.dir_size = size;
fnp -> f_highwater = size;
return TRUE;
}
#endif
/* */
/* Find free cluster in disk FAT table */
/* */
static UWORD
find_fat_free (struct f_node FAR *fnp)
{
REG UWORD idx;
/* Start from optimized lookup point for start of FAT */
if(fnp -> f_dpb -> dpb_cluster != UNKNCLUSTER)
idx = fnp -> f_dpb -> dpb_cluster;
else
idx = 2;
/* Search the FAT table looking for the first free */
/* entry. */
for( ; idx < fnp -> f_dpb -> dpb_size; idx++)
{
if(next_cluster(fnp -> f_dpb, idx) == FREE)
break;
}
/* No empty clusters, disk is FULL! */
if(idx >= fnp -> f_dpb -> dpb_size)
{
fnp -> f_dpb -> dpb_cluster = UNKNCLUSTER;
dir_close(fnp);
return LONG_LAST_CLUSTER;
}
/* return the free entry */
fnp -> f_dpb -> dpb_cluster = idx;
return idx;
}
/* */
/* crate a directory - returns success or a negative error */
/* number */
/* */
COUNT
dos_mkdir (BYTE FAR *dir)
{
REG struct f_node FAR *fnp;
REG COUNT idx;
struct buffer FAR *bp;
BYTE FAR *p;
UWORD free_fat;
UWORD parent;
/* first split the passed dir into comopnents (i.e. - */
/* path to new directory and name of new directory */
if((fnp = split_path(dir, szDirName, szFileName, szFileExt)) == NULL)
{
dir_close(fnp);
return DE_PATHNOTFND;
}
/* Check that we don't have a duplicate name, so if we */
/* find one, it's an error. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -