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

📄 ff.c

📁 S64和VS1003的MP3播放实现的源代码/
💻 C
📖 第 1 页 / 共 4 页
字号:
			}
		} while (--clust);
	}

	*nclust = n;
	return FR_OK;
}




/*-----------------------------------------------------------------------*/
/* Delete a File or a Directory                                          */
/*-----------------------------------------------------------------------*/

FRESULT f_unlink (
	const char *path			/* Pointer to the file or directory path */
)
{
	BYTE *dir, *sdir;
	DWORD dclust, dsect;
	char fn[8+3+1];
	FRESULT res;
	DIR dirobj;
	FATFS *fs;


	if ((res = auto_mount(&path, &fs, 1)) != FR_OK)
		return res;
	dirobj.fs = fs;
	res = trace_path(&dirobj, fn, path, &dir);	/* Trace the file path */

	if (res != FR_OK) return res;				/* Trace failed */
	if (dir == NULL) return FR_NO_FILE;			/* It is a root directory */
	if (*(dir+11) & AM_RDO) return FR_DENIED;	/* It is a R/O item */
	dsect = fs->winsect;
	dclust = ((DWORD)LD_WORD(dir+20) << 16) | LD_WORD(dir+26);

	if (*(dir+11) & AM_DIR) {					/* It is a sub-directory */
		dirobj.clust = dclust;					/* Check if the sub-dir is empty or not */
		dirobj.sect = clust2sect(fs, dclust);
		dirobj.index = 0;
		do {
			if (!move_window(fs, dirobj.sect)) return FR_RW_ERROR;
			sdir = &fs->win[(dirobj.index & 15) * 32];
			if (*sdir == 0) break;
			if (!((*sdir == 0xE5) || *sdir == '.') && !(*(sdir+11) & AM_VOL))
				return FR_DENIED;	/* The directory is not empty */
		} while (next_dir_entry(&dirobj));
	}

	if (!move_window(fs, dsect)) return FR_RW_ERROR;	/* Mark the directory entry 'deleted' */
	*dir = 0xE5; 
	fs->winflag = 1;
	if (!remove_chain(fs, dclust)) return FR_RW_ERROR;	/* Remove the cluster chain */
	if (!move_window(fs, 0)) return FR_RW_ERROR;

	return FR_OK;
}




/*-----------------------------------------------------------------------*/
/* Create a Directory                                                    */
/*-----------------------------------------------------------------------*/

FRESULT f_mkdir (
	const char *path		/* Pointer to the directory path */
)
{
	BYTE *dir, *w, n;
	char fn[8+3+1];
	DWORD sect, dsect, dclust, pclust, tim;
	FRESULT res;
	DIR dirobj;
	FATFS *fs;


	if ((res = auto_mount(&path, &fs, 1)) != FR_OK)
		return res;
	dirobj.fs = fs;
	res = trace_path(&dirobj, fn, path, &dir);	/* Trace the file path */

	if (res == FR_OK) return FR_DENIED;		/* Any file or directory is already existing */
	if (res != FR_NO_FILE) return res;

	dir = reserve_direntry(&dirobj);		/* Reserve a directory entry */
	if (dir == NULL) return FR_DENIED;
	sect = fs->winsect;
	dsect = clust2sect(fs, dclust = create_chain(fs, 0));	/* Get a new cluster for new directory */
	if (!dsect) return FR_DENIED;
	if (!move_window(fs, 0)) return 0;

	w = fs->win;
	memset(w, 0, 512);						/* Initialize the directory table */
	for (n = fs->sects_clust - 1; n; n--) {
		if (disk_write(fs->drive, w, dsect+n, 1) != RES_OK)
			return FR_RW_ERROR;
	}

	fs->winsect = dsect;					/* Create dot directories */
	memset(w, ' ', 8+3);
	*w = '.';
	*(w+11) = AM_DIR;
	tim = get_fattime();
	ST_DWORD(w+22, tim);
	ST_WORD(w+26, dclust);
	ST_WORD(w+20, dclust >> 16);
	memcpy(w+32, w, 32); *(w+33) = '.';
	pclust = dirobj.sclust;
	if (fs->fs_type == FS_FAT32 && pclust == fs->dirbase) pclust = 0;
	ST_WORD(w+32+26, pclust);
	ST_WORD(w+32+20, pclust >> 16);
	fs->winflag = 1;

	if (!move_window(fs, sect)) return FR_RW_ERROR;
	memcpy(dir, fn, 8+3);			/* Initialize the new entry */
	*(dir+11) = AM_DIR;
	*(dir+12) = fn[11];
	memset(dir+13, 0, 32-13);
	ST_DWORD(dir+22, tim);			/* Crated time */
	ST_WORD(dir+26, dclust);		/* Table start cluster */
	ST_WORD(dir+20, dclust >> 16);
	fs->winflag = 1;

	if (!move_window(fs, 0)) return FR_RW_ERROR;

	return FR_OK;
}




/*-----------------------------------------------------------------------*/
/* Change File Attribute                                                 */
/*-----------------------------------------------------------------------*/

FRESULT f_chmod (
	const char *path,	/* Pointer to the file path */
	BYTE value,			/* Attribute bits */
	BYTE mask			/* Attribute mask to change */
)
{
	FRESULT res;
	BYTE *dir;
	DIR dirobj;
	char fn[8+3+1];
	FATFS *fs;


	if ((res = auto_mount(&path, &fs, 1)) != FR_OK)
		return res;
	dirobj.fs = fs;
	res = trace_path(&dirobj, fn, path, &dir);	/* Trace the file path */

	if (res == FR_OK) {			/* Trace completed */
		if (dir == NULL) {
			res = FR_NO_FILE;
		} else {
			mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC;	/* Valid attribute mask */
			*(dir+11) = (value & mask) | (*(dir+11) & ~mask);	/* Apply attribute change */
			fs->winflag = 1;
			if (!move_window(fs, 0)) res = FR_RW_ERROR;
		}
	}
	return res;
}




/*-----------------------------------------------------------------------*/
/* Rename File/Directory                                                 */
/*-----------------------------------------------------------------------*/

FRESULT f_rename (
	const char *path_old,	/* Pointer to the old name */
	const char *path_new	/* Pointer to the new name */
)
{
	FRESULT res;
	DWORD sect_old;
	BYTE *dir_old, *dir_new, direntry[32-11];
	DIR dirobj;
	char fn[8+3+1];
	FATFS *fs;


	if ((res = auto_mount(&path_old, &fs, 1)) != FR_OK)
		return res;
	dirobj.fs = fs;
	res = trace_path(&dirobj, fn, path_old, &dir_old);	/* Check old object */

	if (res != FR_OK) return res;			/* The old object is not found */
	if (!dir_old) return FR_NO_FILE;
	sect_old = fs->winsect;					/* Save the object information */
	memcpy(direntry, dir_old+11, 32-11);

	res = trace_path(&dirobj, fn, path_new, &dir_new);	/* Check new object */
	if (res == FR_OK) return FR_DENIED;		/* The new object name is already existing */
	if (res != FR_NO_FILE) return res;

	dir_new = reserve_direntry(&dirobj);	/* Reserve a directory entry */
	if (dir_new == NULL) return FR_DENIED;
	memcpy(dir_new+11, direntry, 32-11);	/* Create new entry */
	memcpy(dir_new, fn, 8+3);
	*(dir_new+12) = fn[11];
	fs->winflag = 1;

	if (!move_window(fs, sect_old)) return FR_RW_ERROR;	/* Remove old entry */
	*dir_old = 0xE5;
	fs->winflag = 1;
	if (!move_window(fs, 0)) return FR_RW_ERROR;

	return FR_OK;
}



#ifdef _USE_MKFS
/*-----------------------------------------------------------------------*/
/* Create File System on the Drive                                       */
/*-----------------------------------------------------------------------*/

#define ERASE_BLK 32
#define N_ROOTDIR 512
#define N_FATS 2


FRESULT f_mkfs (
	BYTE drv,			/* Logical drive number */
	BYTE partition,		/* Partitioning rule 0:FDISK, 1:SFD */
	BYTE allocsize		/* Allocation unit size */
)
{
	BYTE fmt, m, *tbl;
	DWORD b_part, b_fat, b_dir, b_data;		/* Area offset (LBA) */
	DWORD n_part, n_rsv, n_fat, n_dir;		/* Area size */
	DWORD n_clust, n;
	static const BYTE tbl_alloc[] = {1,2,4,8,16,32,64,0};
	FATFS *fs;
	DSTATUS stat;


	/* Check mounted drive */
	if (drv >= _DRIVES) return FR_INVALID_DRIVE;
	if (!(fs = FatFs[drv])) return FR_NOT_ENABLED;
	memset(fs, 0, sizeof(FATFS));
	drv = ld2pd(drv);

	/* Check validity of the parameters */
	for (n = 0; allocsize != tbl_alloc[n] && tbl_alloc[n]; n++);
	if (!tbl_alloc[n] || partition >= 2) return FR_MKFS_ABORTED;

	/* Get disk size */
	stat = disk_initialize(drv);
	if (stat & STA_NOINIT) return FR_NOT_READY;
	if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
	if (disk_ioctl(drv, GET_SECTORS, &n_part) != RES_OK || n_part < 1000)
		return FR_MKFS_ABORTED;
	b_part = (!partition) ? 63 : 0;
	n_part -= b_part;

	/* Pre-compute number of clusters and FAT type */
	n_clust = n_part / allocsize;
	fmt = FS_FAT12;
	if (n_clust >= 0xFF7) fmt = FS_FAT16;
	if (n_clust >= 0xFFF7) fmt = FS_FAT32;
	switch (fmt) {
	case FS_FAT12:
		n_fat = ((n_clust * 2 + 1) / 3 + 3 + 511) / 512;
		n_rsv = 1 + partition;
		n_dir = N_ROOTDIR * 32 / 512;
		break;
	case FS_FAT16:
		n_fat = ((n_clust * 2) + 4 + 511) / 512;
		n_rsv = 1 + partition;
		n_dir = N_ROOTDIR * 32 / 512;
		break;
	default:
		n_fat = ((n_clust * 4) + 8 + 511) / 512;
		n_rsv = 33 - partition;
		n_dir = 0;
	}
	b_fat = b_part + n_rsv;
	b_dir = b_fat + n_fat * N_FATS;
	b_data = b_dir + n_dir;

#ifdef ERASE_BLK
	/* Round up data start sector to erase block boundary */
	n = (b_data + ERASE_BLK - 1) & ~(ERASE_BLK - 1);
	b_dir += n - b_data;
	n_fat += (n - b_data) / N_FATS;
#endif
	/* Determine number of cluster and final check of validity of the FAT type */
	n_clust = (n_part - n_rsv - n_fat * 2 - n_dir) / allocsize;
	if (   (fmt == FS_FAT16 && n_clust < 0xFF7)
		|| (fmt == FS_FAT32 && n_clust < 0xFFF7))
		return FR_MKFS_ABORTED;

	/* Create partition table if needed */
	if (!partition) {
		DWORD n_disk = b_part + n_part;

		tbl = &fs->win[0x1BE];
		ST_DWORD(tbl+0, 0x00010180);	/* Partition start in CHS */
		if (n_disk < 63UL * 255 * 1024) {	/* Partition end in CHS */
			n_disk = n_disk / 63 / 255;
			*(tbl+7) = (BYTE)n_disk;
			*(tbl+6) = (BYTE)((n_disk >> 2) | 63);
		} else {
			ST_WORD(tbl+6, 0xFFFF);
		}
		*(tbl+5) = 254;
		if (fmt != FS_FAT32)			/* System ID */
			*(tbl+4) = (n_part < 0x10000) ? 0x04 : 0x06;
		else
			*(tbl+4) = 0x0c;
		ST_DWORD(tbl+8, 63);			/* Partition start in LBA */
		ST_DWORD(tbl+12, n_part);		/* Partition size in LBA */
		ST_WORD(tbl+64, 0xAA55);		/* Signature */
		if (disk_write(drv, fs->win, 0, 1) != RES_OK)
			return FR_RW_ERROR;
	}

	/* Create boot record */
	memset(tbl = fs->win, 0, 512);
	ST_DWORD(tbl+0, 0x0090FEEB);		/* Boot code (jmp $) */
	ST_WORD(tbl+11, 512);				/* Sector size */
	*(tbl+13) = (BYTE)allocsize;		/* Cluster size */
	ST_WORD(tbl+14, n_rsv);				/* Reserved sectors */
	*(tbl+16) = N_FATS;					/* Number of FATs */
	ST_WORD(tbl+17, n_dir * 16);		/* Number of rootdir entries */
	if (n_part < 0x10000) {				/* Number of total sectors */
		ST_WORD(tbl+19, n_part);
	} else {
		ST_DWORD(tbl+32, n_part);
	}
	*(tbl+21) = 0xF8;					/* Media descripter */
	ST_WORD(tbl+24, 63);				/* Number of sectors per track */
	ST_WORD(tbl+26, 255);				/* Number of heads */
	ST_DWORD(tbl+28, b_part);			/* Hidden sectors */
	if (fmt != FS_FAT32) {
		ST_WORD(tbl+22, n_fat);			/* Number of secters per FAT */
		*(tbl+36) = 0x80;				/* Drive number */
		*(tbl+38) = 0x29;				/* Extended boot signature */
		memcpy(tbl+43, "NO NAME    ", 11);	/* Volume lavel */
		memcpy(tbl+54, (fmt == FS_FAT12) ?	/* FAT signature */
			"FAT12   " : "FAT16   ", 8);
	} else {
		ST_DWORD(tbl+36, n_fat);		/* Number of secters per FAT */
		ST_DWORD(tbl+44, 2);			/* Root directory cluster */
		ST_WORD(tbl+48, 1);				/* FSInfo record */
		ST_WORD(tbl+50, 6);				/* Backup boot record */
		*(tbl+64) = 0x80;				/* Drive number */
		*(tbl+66) = 0x29;				/* Extended boot signature */
		memcpy(tbl+71, "NO NAME    ", 11);	/* Volume lavel */
		memcpy(tbl+82, "FAT32   ", 8);	/* FAT signature */
	}
	*(WORD*)(tbl+510) = 0xAA55;			/* Signature */
	if (disk_write(drv, tbl, b_part, 1) != RES_OK)
		return FR_RW_ERROR;
	if (fmt == FS_FAT32)
		disk_write(drv, tbl, b_part+6, 1);

	/* Create FSInfo record if needed */
	if (fmt == FS_FAT32) {
		memset(tbl, 0, 510);
		ST_DWORD(tbl, 0x41615252);
		ST_DWORD(tbl+484, 0x61417272);
		ST_DWORD(tbl+488, 0xFFFFFFFF);
		ST_DWORD(tbl+492, 0xFFFFFFFF);
		if (disk_write(drv, tbl, b_part+1, 1) != RES_OK)
			return FR_RW_ERROR;
		disk_write(drv, tbl, b_part+7, 1);
	}

	/* Initialize FAT area */
	for (m = 0; m < N_FATS; m++) {
		memset(tbl, 0, 512);		/* 1st sector of the FAT  */
		if (fmt != FS_FAT32) {
			n = (fmt == FS_FAT12) ? 0xFFFFF8 : 0xFFFFFFF8;
			ST_DWORD(tbl+0, n);
		} else {
			ST_DWORD(tbl+0, 0xFFFFFFF8);
			ST_DWORD(tbl+4, 0xFFFFFFFF);
			ST_DWORD(tbl+8, 0x0FFFFFFF);
		}
		if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
			return FR_RW_ERROR;
		memset(tbl, 0, 512);		/* Following sectors */
		for (n = 1; n < n_fat; n++) {
			if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
				return FR_RW_ERROR;
		}
	}

	/* Initialize Root directory */
	for (m = 0; m < 64; m++) {
		if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
			return FR_RW_ERROR;
	}

	return FR_OK;
}

#endif /* _USE_MKFS */
#endif /* _FS_READONLY == 0 */
#endif /* _FS_MINIMIZE == 0 */
#endif /* _FS_MINIMIZE <= 1 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -