Lines Matching refs:fs

167 #define ABORT(fs, res)		{ fp->err = (BYTE)(res); LEAVE_FF(fs, res); }
176 #define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; }
178 #define LEAVE_FF(fs, res) { (void)fs; return res; }
181 #define LEAVE_FF(fs, res) return res
197 FATFS* fs; /* Object ID 1, volume (NULL:blank entry) */
742 FATFS* fs /* Filesystem object */
745 return (fs && ff_req_grant(&fs->sobj)) ? 1 : 0;
750 FATFS* fs, /* Filesystem object */
754 if (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) {
755 ff_rel_grant(&fs->sobj);
778 if (Files[i].fs) { /* Existing entry */
779 if (Files[i].fs == dp->obj.fs && /* Check if the object matches with an open object */
799 for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; /* Find a free entry */
813 if (Files[i].fs == dp->obj.fs
819 for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; /* Find a free entry */
821 Files[i].fs = dp->obj.fs;
849 Files[i].fs = 0; /* Free the entry <<<If this memory write operation is not in atomic, FF_FS_REENTRANT == 1 and FF_VOLUMES > 1, there is a potential error in this process >>> */
860 FATFS* fs
866 if (Files[i].fs == fs) Files[i].fs = 0;
871 FRESULT empty_lock(FATFS* fs) /* check lock entries is empty or not. */
876 if (Files[i].fs == fs) return FR_LOCKED;
897 FATFS* fs /* Filesystem object */
903 /* Forced the fs point to its parents */
904 if (ISCHILD(fs)) fs = PARENTFS(fs);
907 if (fs->wflag) { /* Is the disk access window dirty? */
908 if (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) { /* Write it back into the volume */
909 fs->wflag = 0; /* Clear window dirty flag */
910 if (fs->winsect - fs->fatbase < fs->fsize) { /* Is it in the 1st FAT? */
911 if (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2nd FAT if needed */
923 FATFS* fs, /* File system object */
924 LBA_t sect /* Sector LBA to make appearance in the fs->win[] */
930 /* Forced the fs point to its parents */
931 if (ISCHILD(fs)) fs = PARENTFS(fs);
934 if (sect != fs->winsect) { /* Window offset changed? */
936 res = sync_window(fs); /* Flush the window */
939 if (disk_read(fs->pdrv, fs->win, sect, 1) != RES_OK) {
943 fs->winsect = sect;
951 FATFS* fs, /* File system object */
952 LBA_t sect /* Sector number to make appearance in the fs->win[] */
958 /* Forced the fs point to its parents */
959 if (ISCHILD(fs)) fs = PARENTFS(fs);
962 if (sect != fs->winsect) { /* Window offset changed? */
964 res = sync_window(fs); /* Flush the window */
967 if (disk_read_readdir(fs->pdrv, fs->win, sect, 1) != RES_OK) {
971 fs->winsect = sect;
984 FATFS* fs /* Filesystem object */
990 res = sync_window(fs);
993 /* Forced the fs point to its parents */
994 if (ISCHILD(fs)) fs = PARENTFS(fs);
996 if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */
998 mem_set(fs->win, 0, SS(fs));
999 st_word(fs->win + BS_55AA, 0xAA55); /* Boot signature */
1000 st_dword(fs->win + FSI_LeadSig, 0x41615252); /* Leading signature */
1001 st_dword(fs->win + FSI_StrucSig, 0x61417272); /* Structure signature */
1002 st_dword(fs->win + FSI_Free_Count, fs->free_clst); /* Number of free clusters */
1003 st_dword(fs->win + FSI_Nxt_Free, fs->last_clst); /* Last allocated culuster */
1004 fs->winsect = fs->volbase + 1; /* Write it into the FSInfo sector (Next to VBR) */
1005 disk_write(fs->pdrv, fs->win, fs->winsect, 1);
1006 fs->fsi_flag = 0;
1009 if (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR;
1024 FATFS* fs, /* Filesystem object */
1029 if (clst >= fs->n_fatent - 2) return 0; /* Is it invalid cluster number? */
1030 return fs->database + (LBA_t)fs->csize * clst; /* Start sector number of the cluster */
1047 FATFS *fs = obj->fs;
1049 /* Forced the fs point to its parents */
1050 if (ISCHILD(fs)) fs = PARENTFS(fs);
1053 if (clst < 2 || clst >= fs->n_fatent) { /* Check if in valid range */
1059 switch (fs->fs_type) {
1062 if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;
1063 wc = fs->win[bc++ % SS(fs)]; /* Get 1st byte of the entry */
1064 if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;
1065 wc |= fs->win[bc % SS(fs)] << 8; /* Merge 2nd byte of the entry */
1070 if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break;
1071 val = ld_word(fs->win + clst * 2 % SS(fs)); /* Simple WORD array */
1075 if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break;
1076 val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF; /* Simple DWORD array but mask out upper 4 bits */
1096 FATFS* fs, /* Corresponding filesystem object */
1106 /* Forced the fs point to its parents */
1107 if (ISCHILD(fs)) fs = PARENTFS(fs);
1110 if (clst >= 2 && clst < fs->n_fatent) { /* Check if in valid range */
1111 switch (fs->fs_type) {
1114 res = move_window(fs, fs->fatbase + (bc / SS(fs)));
1116 p = fs->win + bc++ % SS(fs);
1118 fs->wflag = 1;
1119 res = move_window(fs, fs->fatbase + (bc / SS(fs)));
1121 p = fs->win + bc % SS(fs);
1123 fs->wflag = 1;
1127 res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
1129 st_word(fs->win + clst * 2 % SS(fs), (WORD)val); /* Simple WORD array */
1130 fs->wflag = 1;
1134 res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
1136 val = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000);
1137 st_dword(fs->win + clst * 4 % SS(fs), val);
1138 fs->wflag = 1;
1161 FATFS *fs = obj->fs;
1167 if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Check if in valid range */
1171 res = put_fat(fs, pclst, 0xFFFFFFFF);
1181 res = put_fat(fs, clst, 0); /* Mark the cluster 'free' on the FAT */
1185 if (fs->free_clst < fs->n_fatent - 2) { /* Update FSINFO */
1186 fs->free_clst++;
1187 fs->fsi_flag |= 1;
1191 if (fs->free_clst < fs->ct_clst && ISCHILD(fs) && ISVIRPART(fs))
1192 fs->free_clst++;
1194 if (PARENTFS(fs)->free_clst < PARENTFS(fs)->n_fatent - 2) {
1195 PARENTFS(fs)->free_clst++;
1196 PARENTFS(fs)->fsi_flag |= 1;
1203 rt[0] = clst2sect(fs, scl); /* Start of data area to be freed */
1204 rt[1] = clst2sect(fs, ecl) + fs->csize - 1; /* End of data area to be freed */
1205 disk_ioctl(fs->pdrv, CTRL_TRIM, rt); /* Inform storage device that the data in the block may be erased */
1210 } while (clst < fs->n_fatent); /* Repeat while not the last link */
1229 FATFS *fs = obj->fs;
1232 if (ISVIRPART(fs) && (fs->st_clst == 0xFFFFFFFF || fs->ct_clst == 0xFFFFFFFF)) {
1238 scl = fs->last_clst; /* Suggested cluster to start to find */
1240 if (ISVIRPART(fs)) {
1241 if (scl == 0 || scl >= fs->n_fatent)
1242 scl = fs->st_clst - 1 ;
1243 if (scl == 0 || scl < fs->st_clst || scl >= fs->st_clst + fs->ct_clst)
1244 scl = fs->st_clst - 1;
1248 if (scl == 0 || scl >= fs->n_fatent) scl = 1;
1255 if (ISVIRPART(fs)) {
1257 if (cs < fs->st_clst + fs->ct_clst && cs >= fs->st_clst)
1260 if ((cs >= fs->st_clst + fs->ct_clst && cs < fs->n_fatent) || cs < fs->st_clst)
1265 if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */
1269 if (fs->free_clst == 0) return 0; /* No free cluster */
1276 if (ISVIRPART(fs)) {
1278 if (ncl >= fs->st_clst + fs->ct_clst || ncl < fs->st_clst)
1279 ncl = fs->st_clst;
1283 if (ncl >= fs->n_fatent) ncl = 2;
1289 if (ISVIRPART(fs)) {
1290 cs = PARENTFS(fs)->last_clst; /* Start at suggested cluster if it is valid */
1291 if (cs >= fs->st_clst && cs < fs->st_clst + fs->ct_clst) scl = cs;
1295 cs = fs->last_clst; /* Start at suggested cluster if it is valid */
1296 if (cs >= 2 && cs < fs->n_fatent) scl = cs;
1307 if (ISVIRPART(fs)) {
1309 if (ncl >= fs->st_clst + fs->ct_clst || ncl < fs->st_clst) {
1310 ncl = fs->st_clst;
1316 if (ncl >= fs->n_fatent) { /* Check wrap-around */
1327 res = put_fat(fs, ncl, 0xFFFFFFFF); /* Mark the new cluster 'EOC' */
1329 res = put_fat(fs, clst, ncl); /* Link it from the previous one if needed */
1335 if (ISVIRPART(fs)) {
1336 fs->last_clst = ncl;
1337 PARENTFS(fs)->last_clst = ncl;
1338 if (fs->free_clst <= fs->ct_clst && ISCHILD(fs))
1339 fs->free_clst--;
1340 if (PARENTFS(fs)->free_clst <= PARENTFS(fs)->n_fatent - 2)
1341 (PARENTFS(fs))->free_clst--;
1342 PARENTFS(fs)->fsi_flag |= 1;
1346 fs->last_clst = ncl;
1347 if (fs->free_clst <= fs->n_fatent - 2) fs->free_clst--;
1348 fs->fsi_flag |= 1;
1374 FATFS *fs = fp->obj.fs;
1378 cl = (DWORD)(ofs / SS(fs) / fs->csize); /* Cluster order from top of the file */
1399 FATFS *fs, /* Filesystem object */
1408 /* Forced the fs point to its parents */
1409 if (ISCHILD(fs)) fs = PARENTFS(fs);
1412 if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */
1413 sect = clst2sect(fs, clst); /* Top of the cluster */
1414 fs->winsect = sect; /* Set window to top of the cluster */
1415 mem_set(fs->win, 0, SS(fs)); /* Clear window buffer */
1418 for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ;
1419 if (szb > SS(fs)) { /* Buffer allocated? */
1421 szb /= SS(fs); /* Bytes -> Sectors */
1422 for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */
1427 ibuf = fs->win; szb = 1; /* Use window buffer (many single-sector writes may take a time) */
1428 for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */
1430 return (n == fs->csize) ? FR_OK : FR_DISK_ERR;
1447 FATFS *fs = dp->obj.fs;
1455 if (clst == 0 && fs->fs_type >= FS_FAT32) { /* Replace cluster# 0 with root cluster# */
1456 clst = (DWORD)fs->dirbase;
1460 if (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR; /* Is index out of range? */
1461 dp->sect = fs->dirbase;
1464 csz = (DWORD)fs->csize * SS(fs); /* Bytes per cluster */
1468 if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Reached to end of table or internal error */
1471 dp->sect = clst2sect(fs, clst);
1475 dp->sect += ofs / SS(fs); /* Sector# of the directory entry */
1477 dp->dir = fs->win + (ofs % SS(fs)); /* Pointer to the entry in the win[] */
1479 dp->dir = PARENTFS(fs)->win + (ofs % SS(PARENTFS(fs)));
1497 FATFS *fs = dp->obj.fs;
1504 if (ofs % SS(fs) == 0) { /* Sector changed? */
1508 if (ofs / SZDIRE >= fs->n_rootdir) { /* Report EOT if it reached end of static table */
1513 if ((ofs / SS(fs) & (fs->csize - 1)) == 0) { /* Cluster changed? */
1517 if (clst >= fs->n_fatent) { /* It reached end of dynamic table */
1526 if (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR; /* Clean up the stretched table */
1533 dp->sect = clst2sect(fs, clst);
1539 dp->dir = fs->win + ofs % SS(fs); /* Pointer to the entry in the win[] */
1541 dp->dir = PARENTFS(fs)->win + (ofs % SS(PARENTFS(fs)));
1561 FATFS *fs = dp->obj.fs;
1568 res = move_window(fs, dp->sect);
1593 FATFS* fs, /* Pointer to the fs object */
1600 if (fs->fs_type == FS_FAT32) {
1610 FATFS* fs, /* Pointer to the fs object */
1616 if (fs->fs_type == FS_FAT32) {
1829 FATFS *fs = dp->obj.fs;
1836 res = move_window(fs, dp->sect);
1856 ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;
1886 FATFS *fs = dp->obj.fs;
1893 res = move_window_readdir(fs, dp->sect);
1913 ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;
1945 FATFS *fs = dp->obj.fs;
1959 res = move_window(fs, dp->sect);
1976 ord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;
2006 for (nlen = 0; dp->obj.fs->lfnbuf[nlen]; nlen++) ; /* Get lfn length */
2026 FATFS *fs = dp->obj.fs;
2033 for (len = 0; fs->lfnbuf[len]; len++) ; /* Get lfn length */
2040 gen_numname(dp->fn, sn, fs->lfnbuf, n); /* Generate a numbered name */
2057 res = move_window(fs, dp->sect);
2059 put_lfn(fs->lfnbuf, dp->dir, (BYTE)n_ent, sum);
2061 fs->wflag = 1;
2063 PARENTFS(fs)->wflag = 1;
2077 res = move_window(fs, dp->sect);
2085 fs->wflag = 1;
2087 PARENTFS(fs)->wflag = 1;
2109 FATFS *fs = dp->obj.fs;
2115 res = move_window(fs, dp->sect);
2120 fs->wflag = 1;
2122 PARENTFS(fs)->wflag = 1;
2131 res = move_window(fs, dp->sect);
2135 fs->wflag = 1;
2137 PARENTFS(fs)->wflag = 1;
2163 FATFS *fs = dp->obj.fs;
2177 while (fs->lfnbuf[si] != 0) {
2178 wc = fs->lfnbuf[si++]; /* Get an LFN character (UTF-16) */
2248 fno->sclst = ld_clust(fs, dp->dir); /* Start cluster */
2363 p = *path; lfn = dp->obj.fs->lfnbuf; di = 0;
2559 FATFS *fs = dp->obj.fs;
2564 dp->obj.sclust = fs->cdir; /* Start at the current directory */
2600 dp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs)); /* Open next directory */
2602 dp->obj.sclust = ld_clust(PARENTFS(fs), PARENTFS(fs)->win + dp->dptr % SS(PARENTFS(fs)));
2699 FATFS* fs, /* Filesystem object */
2707 fs->wflag = 0; fs->winsect = (LBA_t)0 - 1; /* Invaidate window */
2708 if (move_window(fs, sect) != FR_OK) return 4; /* Load the boot sector */
2709 sign = ld_word(fs->win + BS_55AA);
2711 b = fs->win[BS_JmpBoot];
2713 if (sign == 0xAA55 && !mem_cmp(fs->win + BS_FilSysType32, "FAT32 ", 8)) {
2717 w = ld_word(fs->win + BPB_BytsPerSec);
2719 b = fs->win[BPB_SecPerClus];
2721 && (fs->win[BPB_NumFATs] == 1 || fs->win[BPB_NumFATs] == 2) /* Properness of number of FATs */
2722 && ld_word(fs->win + BPB_RootEntCnt) != 0 /* Properness of root entry count */
2723 && ld_word(fs->win + BPB_FATSz16) != 0) { /* Properness of FAT size */
2736 FATFS* fs, /* Filesystem object */
2748 fmt = check_fs(fs, 0); /* Load sector 0 and check if it is an FAT VBR as SFD */
2752 if (fs->win[MBR_Table + 4] != 0xEE) { /* The partition type is MBR, not GPT */
2757 mbr_pt = fs->win + MBR_Table + i * SZ_PTE;
2760 mbr_pt = fs->win + MBR_Table + extended_pos * SZ_PTE;
2763 mem_set(fs->win, 0, SS(fs));
2765 if (disk_raw_read(LD2DI(vol), fs->win, bsect + offset, 1) != RES_OK) return FR_DISK_ERR;
2767 if (disk_read(LD2PD(vol), fs->win, bsect + offset, 1) != RES_OK) return FR_DISK_ERR;
2769 mbr_pt = fs->win + MBR_Table;
2780 mbr_pt = fs->win + (MBR_Table + i * SZ_PTE);
2784 mbr_pt = fs->win + MBR_Table;
2791 fmt = bsect ? check_fs(fs, bsect) : 2; /* Check the partition */
2810 FATFS *fs;
2824 fs = FatFs[vol]; /* Get pointer to the filesystem object */
2825 if (!fs) return FR_NOT_ENABLED; /* Is the filesystem object available? */
2827 if (!lock_fs(fs)) return FR_TIMEOUT; /* Lock the volume, and system if needed */
2829 *rfs = fs; /* Return pointer to the filesystem object */
2832 if (fs->fs_type != 0) { /* If the volume has been mounted */
2833 stat = disk_status(fs->pdrv);
2845 fs->fs_type = 0; /* Invalidate the filesystem object */
2846 fs->pdrv = LD2PD(vol); /* Volume hosting physical drive */
2847 stat = disk_initialize(fs->pdrv); /* Initialize the volume hosting physical drive */
2855 if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR;
2856 if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR;
2859 if (fs->win == NULL) {
2860 fs->win = (BYTE*) ff_memalloc(SS(fs));
2861 if (fs->win == NULL)
2865 fmt = find_volume(fs, vol);
2868 bsect = fs->winsect; /* Volume offset in the hosting physical drive */
2873 if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must be equal to the physical sector size) */
2875 fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */
2876 if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32);
2877 fs->fsize = fasize;
2879 fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */
2880 if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
2881 fasize *= fs->n_fats; /* Number of sectors for FAT area */
2883 fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */
2884 if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */
2886 fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
2887 if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
2889 tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
2890 if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);
2892 nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
2896 sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */
2898 nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
2907 fs->n_fatent = nclst + 2; /* Number of FAT entries */
2908 fs->volbase = bsect; /* Volume start sector */
2909 fs->fatbase = bsect + nrsv; /* FAT start sector */
2910 fs->database = bsect + sysect; /* Data start sector */
2912 if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */
2913 if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
2914 fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */
2915 szbfat = fs->n_fatent * 4; /* (Needed FAT size) */
2917 if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
2918 fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
2920 fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
2922 if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */
2926 fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */
2927 fs->fsi_flag = 0x80;
2930 && ld_word(fs->win + BPB_FSInfo32) == 1
2931 && move_window(fs, bsect + 1) == FR_OK)
2933 fs->fsi_flag = 0;
2934 if (ld_word(fs->win + BS_55AA) == 0xAA55 /* Load FSInfo data if available */
2935 && ld_dword(fs->win + FSI_LeadSig) == 0x41615252
2936 && ld_dword(fs->win + FSI_StrucSig) == 0x61417272)
2939 fs->free_clst = ld_dword(fs->win + FSI_Free_Count);
2942 fs->last_clst = ld_dword(fs->win + FSI_Nxt_Free);
2950 fs->fs_type = (BYTE)fmt;/* FAT sub-type (the filesystem object gets valid) */
2951 fs->id = ++Fsid; /* Volume mount ID */
2953 fs->lfnbuf = LfnBuf; /* Static LFN working buffer */
2956 fs->cdir = 0; /* Initialize current directory */
2959 clear_share(fs);
2979 if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid */
2982 if (lock_fs(obj->fs)) { /* Take a grant to access the volume */
2983 if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the hosting phsical drive is kept initialized */
2986 unlock_fs(obj->fs, FR_OK); /* Invalidated volume, abort to access */
2995 if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the hosting phsical drive is kept initialized */
3000 *rfs = (res == FR_OK) ? obj->fs : 0; /* Return corresponding filesystem object if it is valid */
3010 FATFS *fs
3013 switch(fs->fs_type) {
3032 DWORD last_clust = get_end_of_cluster(fp->obj.fs);
3059 FATFS* fs, /* Pointer to the filesystem object to be registered (NULL:unmount)*/
3085 if (fs) { /* Register new filesystem object */
3086 fs->fs_type = 0; /* Clear new fs object */
3088 fs->vir_flag = FS_PARENT;
3089 fs->parent_fs = fs;
3090 fs->vir_amount = 0xFFFFFFFF;
3091 fs->vir_avail = FS_VIRDISABLE;
3094 if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
3097 FatFs[vol] = fs; /* Register new fs object */
3101 res = mount_volume(&path, &fs, 0); /* Force mounted the volume */
3102 LEAVE_FF(fs, res);
3106 FRESULT init_fatobj(FATFS *fs, BYTE fmt, QWORD start_sector)
3115 if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) { /* (BPB_BytsPerSec must be equal to the physical sector size) */
3119 fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */
3120 if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32);
3121 fs->fsize = fasize;
3123 fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */
3124 if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
3125 fasize *= fs->n_fats; /* Number of sectors for FAT area */
3127 fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */
3128 if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */
3130 fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
3131 if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
3133 tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
3134 if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);
3136 nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
3140 sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */
3142 nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
3151 fs->n_fatent = nclst + FAT_RESERVED_NUM; /* Number of FAT entries */
3152 fs->volbase = start_sector; /* Volume start sector */
3153 fs->fatbase = start_sector + nrsv; /* FAT start sector */
3154 fs->database = start_sector + sysect; /* Data start sector */
3156 if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */
3157 if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
3158 fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */
3159 szbfat = fs->n_fatent * FAT32_ENTRY_SIZE; /* (Needed FAT size) */
3161 if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
3162 fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
3163 szbfat = (fmt == FS_FAT16) ? (fs->n_fatent * FAT16_ENTRY_SIZE) :
3164 (fs->n_fatent * 3 / 2 + (fs->n_fatent & 1)); /* (Needed FAT size) */
3166 if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) {
3173 fs->last_clst = fs->free_clst = DISK_ERROR; /* Initialize cluster allocation information */
3174 fs->fsi_flag = 0x80;
3177 && ld_word(fs->win + BPB_FSInfo32) == 1
3178 && move_window(fs, start_sector + 1) == FR_OK) {
3179 fs->fsi_flag = 0;
3180 if (ld_word(fs->win + BS_55AA) == 0xAA55 /* Load FSInfo data if available */
3181 && ld_dword(fs->win + FSI_LeadSig) == 0x41615252
3182 && ld_dword(fs->win + FSI_StrucSig) == 0x61417272) {
3184 fs->free_clst = ld_dword(fs->win + FSI_Free_Count);
3187 fs->last_clst = ld_dword(fs->win + FSI_Nxt_Free);
3194 fs->fs_type = fmt; /* FAT sub-type */
3195 fs->id = 0; /* Volume mount ID */
3197 fs->lfnbuf = LfnBuf; /* Static LFN working buffer */
3200 fs->cdir = 0; /* Initialize current directory */
3207 FRESULT find_fat_partition(FATFS *fs, los_part *part, BYTE *format, QWORD *start_sector)
3218 fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */
3221 if (fs->win[MBR_Table + PTE_System] != GPT_PROTECTIVE_MBR) { /* The partition type is GPT, not MBR */
3226 pt = fs->win + MBR_Table + i * SZ_PTE;
3231 pt = fs->win + MBR_Table + extended_pos * SZ_PTE;
3234 mem_set(fs->win, 0, SS(fs));
3235 if (disk_raw_read(part->disk_id, fs->win, bsect + offset, 1) != RES_OK) {
3238 pt = fs->win + MBR_Table;
3246 pt = fs->win + MBR_Table;
3252 fmt = bsect ? check_fs(fs, bsect) : VBR_BS_NOT_FAT; /* Check the partition */
3280 FATFS *fs;
3299 res = mount_volume(&path, &fs, mode);
3301 fs_bak = fs;
3304 dj.obj.fs = fs;
3307 if (ISCHILD(fs)) LEAVE_FF(fs_bak,FR_INVAILD_FATFS);
3309 if (ISCHILD(fs)) LEAVE_FF(fs,FR_INVAILD_FATFS);
3311 if (ISVIRPART(fs)) {
3312 /* Check the virtual partition top directory, and match the virtual fs */
3317 if (res == FR_INT_ERR) LEAVE_FF(fs,res);
3320 fs = dj.obj.fs;
3323 INIT_NAMBUF(fs);
3368 cl = ld_clust(fs, dj.dir); /* Get cluster chain */
3369 st_clust(fs, dj.dir, 0); /* Reset file allocation info */
3372 PARENTFS(fs)->wflag = 1;
3374 fs->wflag = 1;
3378 sc = fs->winsect;
3381 res = move_window(fs, sc);
3382 fs->last_clst = cl - 1; /* Reuse the cluster hole */
3386 dw = PARENTFS(fs)->winsect;
3389 res = move_window(fs, dw);
3390 if (ISVIRPART(fs) && ISCHILD(fs))
3391 fs->last_clst = cl - 1; /* Reuse the cluster hole */
3392 PARENTFS(fs)->last_clst = cl -1;
3412 fp->dir_sect = PARENTFS(fs)->winsect; /* Pointer to the directory entry */
3414 fp->dir_sect = fs->winsect; /* Pointer to the directory entry */
3436 fp->obj.sclust = ld_clust(fs, dj.dir); /* Get object allocation info */
3441 fp->obj.fs = fs; /* Validate the file object */
3442 fp->obj.id = fs->id;
3449 fp->buf = (BYTE*) ff_memalloc(SS(fs)); /* Init sector buffer */
3458 LEAVE_FF(fs, res);
3464 bcs = (DWORD)fs->csize * SS(fs); /* Cluster size in byte */
3472 if (res == FR_OK && ofs % SS(fs)) { /* Fill sector buffer if not on the sector boundary */
3473 sc = clst2sect(fs, clst);
3477 fp->sect = sc + (DWORD)(ofs / SS(fs));
3479 if (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR;
3490 if (res == FR_OK && (mode & ~FA_READ) && ISVIRPART(fs) &&
3491 (ISCHILD(fs) || (ISPARENT(fs) && fs->st_clst != 0xFFFFFFFF && fs->ct_clst != 0xFFFFFFFF))) {
3493 cl = get_end_of_cluster(fs);
3504 if (clst < 2 || clst >= fs->n_fatent) {
3508 if (clst < fs->st_clst || clst >= fs->st_clst + fs->ct_clst) {
3524 if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */
3528 LEAVE_FF(fs, res);
3547 FATFS *fs;
3558 res = validate(&fp->obj, &fs); /* Check validity of the file object */
3559 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
3560 if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_NO_EPERM); /* Check access mode */
3565 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
3566 csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */
3580 if (clst < 2) ABORT(fs, FR_INT_ERR);
3581 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
3584 sect = clst2sect(fs, fp->clust); /* Get current sector */
3585 if (sect == 0) ABORT(fs, FR_INT_ERR);
3587 cc = btr / SS(fs); /* When remaining bytes >= sector size, */
3589 if (csect + cc > fs->csize) { /* Clip at cluster boundary */
3590 cc = fs->csize - csect;
3592 if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
3595 if (fs->wflag && fs->winsect - sect < cc) {
3597 copy_ret = LOS_CopyFromKernel(rbuff + ((fs->winsect - sect) * SS(fs)), SS(fs), fs->win, SS(fs));
3598 if (copy_ret != EOK) ABORT(fs, FR_INVALID_PARAMETER);
3600 mem_cpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs));
3606 copy_ret = LOS_CopyFromKernel(rbuff + ((fp->sect - sect) * SS(fs)), SS(fs), fp->buf, SS(fs));
3607 if (copy_ret != EOK) ABORT(fs, FR_INVALID_PARAMETER);
3609 mem_cpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs));
3614 rcnt = SS(fs) * cc; /* Number of bytes transferred */
3621 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
3625 if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
3630 rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
3633 if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
3635 copy_ret = LOS_CopyFromKernel(rbuff, rcnt, fs->win + fp->fptr % SS(fs), rcnt);
3636 if (copy_ret != EOK) ABORT(fs, FR_INVALID_PARAMETER);
3640 copy_ret = LOS_CopyFromKernel(rbuff, rcnt, fp->buf + fp->fptr % SS(fs), rcnt);
3641 if (copy_ret != EOK) ABORT(fs, FR_INVALID_PARAMETER);
3643 mem_cpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
3648 LEAVE_FF(fs, FR_OK);
3667 FATFS *fs;
3677 res = validate(&fp->obj, &fs); /* Check validity of the file object */
3678 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
3679 if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_NO_EPERM); /* Check access mode */
3687 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
3688 csect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1); /* Sector offset in the cluster */
3709 if (clst == 1) ABORT(fs, FR_INT_ERR);
3710 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
3715 if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */
3718 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
3722 sect = clst2sect(fs, fp->clust); /* Get current sector */
3723 if (sect == 0) ABORT(fs, FR_INT_ERR);
3725 cc = btw / SS(fs); /* When remaining bytes >= sector size, */
3727 if (csect + cc > fs->csize) { /* Clip at cluster boundary */
3728 cc = fs->csize - csect;
3730 if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
3733 if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
3734 copy_ret = LOS_CopyToKernel(fs->win, SS(fs), wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs));
3735 if (copy_ret != EOK) ABORT(fs, FR_INVALID_PARAMETER);
3736 fs->wflag = 0;
3741 copy_ret = LOS_CopyToKernel(fp->buf, SS(fs), wbuff + ((fp->sect - sect) * SS(fs)), SS(fs));
3742 if (copy_ret != EOK) ABORT(fs, FR_INVALID_PARAMETER);
3744 mem_cpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs));
3750 wcnt = SS(fs) * cc; /* Number of bytes transferred */
3755 if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR);
3756 fs->winsect = sect;
3761 disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
3762 ABORT(fs, FR_DISK_ERR);
3767 wcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */
3770 if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
3772 copy_ret = LOS_CopyToKernel(fs->win + fp->fptr % SS(fs), wcnt, wbuff, wcnt);
3773 if (copy_ret != EOK) ABORT(fs, FR_INVALID_PARAMETER);
3774 fs->wflag = 1;
3777 copy_ret = LOS_CopyToKernel(fp->buf + fp->fptr % SS(fs), wcnt, wbuff, wcnt);
3778 if (copy_ret != EOK) ABORT(fs, FR_INVALID_PARAMETER);
3780 mem_cpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */
3789 LEAVE_FF(fs, res);
3804 FATFS *fs;
3809 res = validate(&fp->obj, &fs); /* Check validity of the file object */
3814 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);
3821 res = move_window(fs, fp->dir_sect);
3826 st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation information */
3835 fs->wflag = 1;
3837 PARENTFS(fs)->wflag = 1;
3840 res = sync_fs(fs); /* Restore it to the directory */
3846 LEAVE_FF(fs, res);
3863 FATFS *fs;
3870 res = validate(&fp->obj, &fs); /* Lock volume */
3874 if (res == FR_OK) fp->obj.fs = 0; /* Invalidate file object */
3876 fp->obj.fs = 0; /* Invalidate file object */
3879 unlock_fs(fs, FR_OK); /* Unlock volume */
3920 FATFS *fs;
3925 res = mount_volume(&path, &fs, 0);
3927 dj.obj.fs = fs;
3928 INIT_NAMBUF(fs);
3932 fs->cdir = dj.obj.sclust;
3935 fs->cdir = ld_clust(fs, dj.dir); /* Sub-directory cluster */
3945 for (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ; /* Set current drive */
3951 LEAVE_FF(fs, res);
3963 FATFS *fs;
3979 res = mount_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */
3981 dj.obj.fs = fs;
3982 INIT_NAMBUF(fs);
3987 dj.obj.sclust = fs->cdir; /* Start to follow upper directory from current directory */
3991 res = move_window(fs, dj.sect);
3993 dj.obj.sclust = ld_clust(fs, dj.dir); /* Goto parent directory */
3999 if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */
4044 LEAVE_FF(fs, res);
4063 FATFS *fs;
4073 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4075 if (res != FR_OK) LEAVE_FF(fs, res);
4090 if (cl <= 1) ABORT(fs, FR_INT_ERR);
4091 if (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4096 } while (cl < fs->n_fatent); /* Repeat until end of chain */
4109 dsc = clst2sect(fs, fp->clust);
4110 if (dsc == 0) ABORT(fs, FR_INT_ERR);
4111 dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1);
4112 if (fp->fptr % SS(fs) && dsc != fp->sect) { /* Refill sector cache if needed */
4116 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4120 if (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */
4137 bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */
4149 if (clst == 1) ABORT(fs, FR_INT_ERR);
4150 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4172 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4173 if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR);
4177 if (ofs % SS(fs)) {
4178 nsect = clst2sect(fs, clst); /* Current sector */
4179 if (nsect == 0) ABORT(fs, FR_INT_ERR);
4180 nsect += (DWORD)(ofs / SS(fs));
4188 if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */
4192 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4196 if (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
4202 LEAVE_FF(fs, res);
4218 FATFS *fs;
4225 res = mount_volume(&path, &fs, 0);
4227 dp->obj.fs = fs;
4228 INIT_NAMBUF(fs);
4233 dp->obj.sclust = ld_clust(fs, dp->dir); /* Get object allocation info */
4239 dp->obj.id = fs->id;
4256 if (res != FR_OK) dp->obj.fs = 0; /* Invalidate the directory object if function failed */
4258 LEAVE_FF(fs, res);
4273 FATFS *fs;
4276 res = validate(&dp->obj, &fs); /* Check validity of the file object */
4280 if (res == FR_OK) dp->obj.fs = 0; /* Invalidate directory object */
4282 dp->obj.fs = 0; /* Invalidate directory object */
4285 unlock_fs(fs, FR_OK); /* Unlock volume */
4304 FATFS *fs;
4308 res = validate(&dp->obj, &fs); /* Check validity of the directory object */
4313 INIT_NAMBUF(fs);
4324 LEAVE_FF(fs, res);
4397 res = mount_volume(&path, &dj.obj.fs, 0);
4399 INIT_NAMBUF(dj.obj.fs);
4411 LEAVE_FF(dj.obj.fs, res);
4417 FATFS *fs /* Pointer to corresponding filesystem object */
4427 if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */
4428 clst = 2; obj.fs = fs;
4438 } while (++clst < fs->n_fatent);
4441 clst = fs->n_fatent; /* Number of entries */
4442 sect = fs->fatbase; /* Top of the FAT */
4446 res = move_window(fs, sect++);
4449 if (fs->fs_type == FS_FAT16) {
4450 if (ld_word(fs->win + i) == 0) nfree++;
4453 if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++;
4456 i %= SS(fs);
4460 fs->free_clst = nfree; /* Now free_clst is valid */
4461 fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */
4477 FATFS *fs;
4480 res = mount_volume(&path, &fs, 0);
4482 *fatfs = fs; /* Return ptr to the fs object */
4484 if (fs->free_clst <= fs->n_fatent - 2) {
4485 *nclst = fs->free_clst;
4488 res = fat_count_free_entries(nclst, fs);
4492 LEAVE_FF(fs, res);
4509 FATFS *fs;
4511 ret = validate(&fp->obj,&fs);
4512 if (ret != FR_OK) LEAVE_FF(fs,ret);
4516 LEAVE_FF(fs,FR_DENIED);
4519 LEAVE_FF(fs,FR_OK);
4528 FATFS *fs;
4531 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4532 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
4533 if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_NO_EPERM); /* Check access mode */
4540 n = (DWORD)fs->csize * SS(fs); /* Cluster size */
4543 last_clust = get_end_of_cluster(fs);
4556 if (res == FR_OK && val < fs->n_fatent) {
4563 fs->last_clst = fclust;
4565 if (ISVIRPART(fs) && ISCHILD(fs))
4566 fs->last_clst = fclust;
4567 PARENTFS(fs)->last_clst = fclust;
4578 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {
4585 if (res != FR_OK) ABORT(fs, res);
4588 LEAVE_FF(fs, res);
4603 FATFS *fs;
4620 res = mount_volume(&path, &fs, FA_WRITE);
4621 dj.obj.fs = fs;
4623 fs_bak = fs;
4628 if (ISCHILD(fs)) LEAVE_FF(fs_bak,FR_INVAILD_FATFS);
4630 if (ISCHILD(fs)) LEAVE_FF(fs,FR_INVAILD_FATFS);
4632 if (ISVIRPART(fs)) {
4633 /* Check the virtual partition top directory, and match the virtual fs */
4638 if (res == FR_INT_ERR) LEAVE_FF(fs,res);
4641 fs = dj.obj.fs;
4644 INIT_NAMBUF(fs);
4650 if (res == FR_OK && ISVIRPART(fs)) {
4652 st_bak = PARENTFS(dj.obj.fs)->winsect;
4653 last_clust = get_end_of_cluster(fs);
4659 if (rtclst == 0xFFFFFFFF) LEAVE_FF(fs,FR_DISK_ERR);
4663 if (rtclst < 2 || rtclst >= fs->n_fatent) LEAVE_FF(fs_bak,FR_INT_ERR);
4666 if (rtclst < 2 || rtclst >= fs->n_fatent) LEAVE_FF(fs,FR_INT_ERR);
4667 if (rtclst == 0 || rtclst == 1) LEAVE_FF(fs,FR_INT_ERR);
4679 if (ISCHILD(fs)) {
4684 LEAVE_FF(fs,FR_DENIED);
4688 res = move_window(dj.obj.fs,st_bak);
4704 dclst = ld_clust(fs, dj.dir);
4707 if (dclst == fs->cdir) { /* Is it the current directory? */
4712 sdj.obj.fs = fs; /* Open the sub-directory */
4728 if (res == FR_OK) res = sync_fs(fs);
4736 LEAVE_FF(fs, res);
4752 FATFS *fs;
4765 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
4766 dj.obj.fs = fs;
4768 fs_bak = fs;
4774 if (ISCHILD(fs)) LEAVE_FF(fs_bak,FR_INVAILD_FATFS);
4776 if (ISCHILD(fs)) LEAVE_FF(fs,FR_INVAILD_FATFS);
4778 if (ISVIRPART(fs)) {
4779 /* Check the virtual partition top directory, and match the virtual fs */
4784 if (res == FR_INT_ERR) LEAVE_FF(fs,res);
4787 fs = dj.obj.fs;
4790 INIT_NAMBUF(fs);
4797 sobj.fs = fs; /* New object id to create a new chain */
4803 if (res == FR_OK) res = sync_window(fs); /* Flush FAT */
4806 dsc = clst2sect(fs, dcl);
4808 dir = fs->win;
4810 dir = PARENTFS(fs)->win;
4812 mem_set(dir, 0, SS(fs));
4821 st_clust(fs, dir, dcl);
4824 if (fs->fs_type == FS_FAT32 && pcl == fs->dirbase) pcl = 0;
4825 st_clust(fs, dir + SZDIRE, pcl);
4827 for (n = fs->csize; n; n--) { /* Write dot entries and clear following sectors */
4829 fs->winsect = dsc++;
4830 fs->wflag = 1;
4831 res = sync_window(fs);
4833 mem_set(dir, 0, SS(fs));
4835 PARENTFS(fs)->winsect = dsc++;
4836 PARENTFS(fs)->wflag = 1;
4837 res = sync_window(fs);
4839 mem_set(dir, 0, SS(fs));
4855 st_clust(fs, dir, dcl); /* Table start cluster */
4858 fs->wflag = 1;
4860 PARENTFS(fs)->wflag = 1;
4863 res = sync_fs(fs);
4874 LEAVE_FF(fs, res);
4888 FATFS *fs;
4903 res = mount_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */
4905 fs_bak = fs;
4908 djo.obj.fs = fs;
4910 if (ISCHILD(fs)) LEAVE_FF(fs,FR_INVAILD_FATFS);
4911 if (ISVIRPART(fs)) {
4912 /* Check the virtual partition top directory, and match the virtual fs */
4917 if (res == FR_INT_ERR) LEAVE_FF(fs,res);
4920 fs = djo.obj.fs;
4923 INIT_NAMBUF(fs);
4932 if (res == FR_OK && ISVIRPART(fs)) {
4934 st_bak = PARENTFS(djo.obj.fs)->winsect;
4935 last_clust = get_end_of_cluster(fs);
4941 if (rtclst < 2 || rtclst >= fs->n_fatent) LEAVE_FF(fs_bak,FR_INT_ERR);
4944 if (rtclst == 0xFFFFFFFF) LEAVE_FF(fs,FR_DISK_ERR);
4946 if (rtclst < 2 || rtclst >= fs->n_fatent) LEAVE_FF(fs,FR_INT_ERR);
4947 if (rtclst == 0 || rtclst == 1) LEAVE_FF(fs,FR_INT_ERR);
4958 if (ISCHILD(fs)) {
4963 LEAVE_FF(fs,FR_DENIED);
4967 res = move_window(djo.obj.fs,st_bak);
4986 fs->wflag = 1;
4988 PARENTFS(fs)->wflag = 1;
4991 sect = clst2sect(fs, ld_clust(fs, dir));
4997 res = move_window(fs, sect);
4998 dir = fs->win + SZDIRE * 1; /* Ptr to .. entry */
5000 st_clust(fs, dir, djn.obj.sclust);
5001 fs->wflag = 1;
5003 res = move_window(fs, sect);
5004 dir = PARENTFS(fs)->win + SZDIRE * 1; /* Ptr to .. entry */
5006 st_clust(fs, dir, djn.obj.sclust);
5007 PARENTFS(fs)->wflag = 1;
5017 res = sync_fs(fs);
5027 LEAVE_FF(fs, res);
5050 FATFS *fs;
5058 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
5062 if (ISCHILD(fs)) LEAVE_FF(fs_bak,FR_INVAILD_FATFS);
5064 if (ISCHILD(fs)) LEAVE_FF(fs,FR_INVAILD_FATFS);
5066 if (ISVIRPART(fs)) {
5067 /* Check the virtual partition top directory, and match the virtual fs */
5072 if (res == FR_INT_ERR) LEAVE_FF(fs,res);
5075 fs = dj.obj.fs;
5078 INIT_NAMBUF(fs);
5085 fs->wflag = 1;
5087 PARENTFS(fs)->wflag = 1;
5090 res = sync_fs(fs);
5098 LEAVE_FF(fs, res);
5115 FATFS *fs;
5120 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
5122 dj.obj.fs = fs;
5123 INIT_NAMBUF(fs);
5128 fs->wflag = 1;
5130 res = sync_fs(fs);
5136 LEAVE_FF(fs, res);
5155 FATFS *fs;
5161 res = mount_volume(&path, &fs, 0);
5165 dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */
5198 res = move_window(fs, fs->volbase);
5200 switch (fs->fs_type) {
5208 *vsn = ld_dword(fs->win + di);
5212 LEAVE_FF(fs, res);
5222 FRESULT set_volumn_label(FATFS *fs, const TCHAR *label)
5251 LEAVE_FF(fs, FR_INVALID_NAME);
5256 if (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */
5260 dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */
5270 fs->wflag = 1;
5271 res = sync_fs(fs);
5281 fs->wflag = 1;
5282 res = sync_fs(fs);
5297 FATFS *fs;
5300 res = mount_volume(&label, &fs, FA_WRITE);
5301 if (res != FR_OK) LEAVE_FF(fs, res);
5303 res = set_volumn_label(fs, label);
5305 LEAVE_FF(fs, res);
5326 FATFS *fs;
5331 res = validate(&fp->obj, &fs); /* Check validity of the file object */
5332 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
5334 if (fsz == 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);
5336 n = (DWORD)fs->csize * SS(fs); /* Cluster size */
5341 if (offset + fsz <= n * count) LEAVE_FF(fs, FR_OK);
5345 stcl = fs->last_clst; lclst = 0;
5348 if (ISVIRPART(fs)) {
5349 if (stcl < fs->st_clst || stcl >= fs->st_clst + fs->ct_clst) stcl = fs->st_clst;
5357 res = put_fat(fs, clstbak, clst);
5365 res = put_fat(fs, clst, 0xFFFFFFFF);
5374 if (++clst >= fs->st_clst + fs->ct_clst) clst = fs->st_clst;
5379 if (stcl < 2 || stcl >= fs->n_fatent) stcl = 2;
5387 res = put_fat(fs, clstbak, clst);
5394 res = put_fat(fs, clst, 0xFFFFFFFF);
5403 if (++clst >= fs->n_fatent) clst = 2;
5409 fs->last_clst = lclst; /* Set suggested start cluster to start next */
5414 res = put_fat(fs, fclust, scl);
5415 if (res != FR_OK) LEAVE_FF(fs, res);
5418 if (fs->free_clst <= fs->n_fatent - 2) { /* Update FSINFO */
5419 fs->free_clst -= tcl;
5420 fs->fsi_flag |= 1;
5424 if (ISVIRPART(fs) && ISCHILD(fs))
5425 fs->last_clst = lclst; /* Set suggested start cluster to start next */
5426 PARENTFS(fs)->last_clst = lclst;
5431 res = put_fat(fs, fclust, scl);
5432 if (res != FR_OK) LEAVE_FF(fs, res);
5435 if (ISVIRPART(fs)) {
5436 if (fs->free_clst <= fs->ct_clst && ISCHILD(fs))
5437 fs->free_clst -= tcl;
5438 if (PARENTFS(fs)->free_clst <= PARENTFS(fs)->n_fatent - 2) {
5439 PARENTFS(fs)->free_clst -= tcl;
5440 PARENTFS(fs)->fsi_flag |= 1;
5443 if (fs->free_clst <= fs->n_fatent - 2) { /* Update FSINFO */
5444 fs->free_clst -= tcl;
5445 fs->fsi_flag |= 1;
5452 lclst = get_end_of_cluster(fs); /* Get the end of cluster chain */
5457 res = put_fat(fs, clst, 0);
5462 res = put_fat(fs, fclust, 0xFFFFFFFF);
5465 LEAVE_FF(fs, res);
5485 FATFS *fs;
5494 res = validate(&fp->obj, &fs); /* Check validity of the file object */
5495 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
5496 if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_NO_EPERM); /* Check access mode */
5502 csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */
5503 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
5507 if (clst <= 1) ABORT(fs, FR_INT_ERR);
5508 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
5512 sect = clst2sect(fs, fp->clust); /* Get current data sector */
5513 if (sect == 0) ABORT(fs, FR_INT_ERR);
5516 if (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window to the file data */
5517 dbuf = fs->win;
5522 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
5526 if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
5531 rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
5533 rcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt); /* Forward the file data */
5534 if (rcnt == 0) ABORT(fs, FR_INT_ERR);
5537 LEAVE_FF(fs, FR_OK);
5648 if (FatFs[vol]) FatFs[vol]->fs_type = 0; /* Clear the fs object if mounted */
6906 FATFS *fs;
6909 res = validate(&(dir_info->f_dir.obj), &fs); /* Lock volume */
6911 clust_size = (DWORD)fs->csize * SS(fs); /* Cluster size */
6926 LEAVE_FF(fs, res);
6930 LEAVE_FF(fs, res);
6932 if (val == get_end_of_cluster(fs)) {
6934 LEAVE_FF(fs, res);
6936 if (val < fs->n_fatent) {
6946 LEAVE_FF(fs, res);