⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatfs.c

📁 xdos源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 + -