Lines Matching refs:fs

235 #define ABORT(fs, res)		{ fp->err = (BYTE)(res); LEAVE_FF(fs, res); }  argument
243 #define LEAVE_FF(fs, res) { unlock_volume(fs, res); return res; } argument
245 #define LEAVE_FF(fs, res) return res argument
264 #define SS(fs) ((UINT)FF_MAX_SS) /* Fixed sector size */ argument
266 #define SS(fs) ((fs)->ssize) /* Variable sector size */ argument
287 FATFS* fs; /* Object ID 1, volume (NULL:blank entry) */ member
504 #define INIT_NAMBUF(fs) argument
527 #define INIT_NAMBUF(fs) argument
534 #define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; } argument
538 #define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; } argument
546 …IT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, … argument
550 #define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH… argument
898 FATFS* fs, /* Filesystem object to lock */ in lock_volume() argument
906 rv = ff_mutex_take(fs->ldrv); /* Lock the volume */ in lock_volume()
910 SysLockVolume = fs->ldrv; in lock_volume()
913 ff_mutex_give(fs->ldrv); /* Failed system lock */ in lock_volume()
917 …rv = syslock ? ff_mutex_take(fs->ldrv) : ff_mutex_take(fs->ldrv); /* Lock the volume (this is to p… in lock_volume()
924 FATFS* fs, /* Filesystem object */ in unlock_volume() argument
928 if (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) { in unlock_volume()
930 …if (SysLock == 2 && SysLockVolume == fs->ldrv) { /* Unlock system if it has been locked by this ta… in unlock_volume()
935 ff_mutex_give(fs->ldrv); /* Unlock the volume */ in unlock_volume()
958 if (Files[i].fs) { /* Existing entry */ in chk_share()
959 if (Files[i].fs == dp->obj.fs && /* Check if the object matches with an open object */ in chk_share()
979 for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; /* Find a free entry */ in enq_share()
993 if (Files[i].fs == dp->obj.fs in inc_share()
999 for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; /* Find a free entry */ in inc_share()
1001 Files[i].fs = dp->obj.fs; in inc_share()
1029 …Files[i].fs = 0; /* Free the entry <<<If this memory write operation is not in atomic, FF_FS_REENT… in dec_share()
1040 FATFS* fs in clear_share() argument
1046 if (Files[i].fs == fs) Files[i].fs = 0; in clear_share()
1059 FATFS* fs /* Filesystem object */ in sync_window() argument
1065 if (fs->wflag) { /* Is the disk access window dirty? */ in sync_window()
1066 if (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) { /* Write it back into the volume */ in sync_window()
1067 fs->wflag = 0; /* Clear window dirty flag */ in sync_window()
1068 if (fs->winsect - fs->fatbase < fs->fsize) { /* Is it in the 1st FAT? */ in sync_window()
1069 …if (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2… in sync_window()
1081 FATFS* fs, /* Filesystem object */ in move_window() argument
1088 if (sect != fs->winsect) { /* Window offset changed? */ in move_window()
1090 res = sync_window(fs); /* Flush the window */ in move_window()
1093 if (disk_read(fs->pdrv, fs->win, sect, 1) != RES_OK) { in move_window()
1097 fs->winsect = sect; in move_window()
1112 FATFS* fs /* Filesystem object */ in sync_fs() argument
1118 res = sync_window(fs); in sync_fs()
1120 if (fs->fsi_flag == 1) { /* Allocation changed? */ in sync_fs()
1121 fs->fsi_flag = 0; in sync_fs()
1122 if (fs->fs_type == FS_FAT32) { /* FAT32: Update FSInfo sector */ in sync_fs()
1124 memset(fs->win, 0, sizeof fs->win); in sync_fs()
1125 st_dword(fs->win + FSI_LeadSig, 0x41615252); /* Leading signature */ in sync_fs()
1126 st_dword(fs->win + FSI_StrucSig, 0x61417272); /* Structure signature */ in sync_fs()
1127 st_dword(fs->win + FSI_Free_Count, fs->free_clst); /* Number of free clusters */ in sync_fs()
1128 st_dword(fs->win + FSI_Nxt_Free, fs->last_clst); /* Last allocated culuster */ in sync_fs()
1129 st_dword(fs->win + FSI_TrailSig, 0xAA550000); /* Trailing signature */ in sync_fs()
1130 …disk_write(fs->pdrv, fs->win, fs->winsect = fs->volbase + 1, 1); /* Write it into the FSInfo secto… in sync_fs()
1133 else if (fs->fs_type == FS_EXFAT) { /* exFAT: Update PercInUse field in BPB */ in sync_fs()
1134 if (disk_read(fs->pdrv, fs->win, fs->winsect = fs->volbase, 1) == RES_OK) { /* Load VBR */ in sync_fs()
1135 …BYTE perc_inuse = (fs->free_clst <= fs->n_fatent - 2) ? (BYTE)((QWORD)(fs->n_fatent - 2 - fs->free… in sync_fs()
1137 if (fs->win[BPB_PercInUseEx] != perc_inuse) { /* Write it back into VBR if needed */ in sync_fs()
1138 fs->win[BPB_PercInUseEx] = perc_inuse; in sync_fs()
1139 disk_write(fs->pdrv, fs->win, fs->winsect, 1); in sync_fs()
1146 if (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR; in sync_fs()
1161 FATFS* fs, /* Filesystem object */ in clst2sect() argument
1166 if (clst >= fs->n_fatent - 2) return 0; /* Is it invalid cluster number? */ in clst2sect()
1167 return fs->database + (LBA_t)fs->csize * clst; /* Start sector number of the cluster */ in clst2sect()
1184 FATFS *fs = obj->fs; in get_fat() local
1187 if (clst < 2 || clst >= fs->n_fatent) { /* Check if in valid range */ in get_fat()
1193 switch (fs->fs_type) { in get_fat()
1196 if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; in get_fat()
1197 wc = fs->win[bc++ % SS(fs)]; /* Get 1st byte of the entry */ in get_fat()
1198 if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; in get_fat()
1199 wc |= fs->win[bc % SS(fs)] << 8; /* Merge 2nd byte of the entry */ in get_fat()
1204 if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break; in get_fat()
1205 val = ld_word(fs->win + clst * 2 % SS(fs)); /* Simple WORD array */ in get_fat()
1209 if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; in get_fat()
1210 …val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF; /* Simple DWORD array but mask out upper… in get_fat()
1216 …DWORD clen = (DWORD)((LBA_t)((obj->objsize - 1) / SS(fs)) / fs->csize); /* Number of clusters - 1 … in get_fat()
1230 if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; in get_fat()
1231 val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF; in get_fat()
1256 FATFS* fs, /* Corresponding filesystem object */ in put_fat() argument
1266 if (clst >= 2 && clst < fs->n_fatent) { /* Check if in valid range */ in put_fat()
1267 switch (fs->fs_type) { in put_fat()
1270 res = move_window(fs, fs->fatbase + (bc / SS(fs))); in put_fat()
1272 p = fs->win + bc++ % SS(fs); in put_fat()
1274 fs->wflag = 1; in put_fat()
1275 res = move_window(fs, fs->fatbase + (bc / SS(fs))); in put_fat()
1277 p = fs->win + bc % SS(fs); in put_fat()
1279 fs->wflag = 1; in put_fat()
1283 res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); in put_fat()
1285 st_word(fs->win + clst * 2 % SS(fs), (WORD)val); /* Simple WORD array */ in put_fat()
1286 fs->wflag = 1; in put_fat()
1293 res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); in put_fat()
1295 if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { in put_fat()
1296 val = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000); in put_fat()
1298 st_dword(fs->win + clst * 4 % SS(fs), val); in put_fat()
1299 fs->wflag = 1; in put_fat()
1321 FATFS* fs, /* Filesystem object */ in find_bitmap() argument
1332 if (clst >= fs->n_fatent - 2) clst = 0; in find_bitmap()
1335 if (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; in find_bitmap()
1336 i = val / 8 % SS(fs); bm = 1 << (val % 8); in find_bitmap()
1339 bv = fs->win[i] & bm; bm <<= 1; /* Get bit value */ in find_bitmap()
1340 if (++val >= fs->n_fatent - 2) { /* Next cluster (with wrap-around) */ in find_bitmap()
1341 val = 0; bm = 0; i = SS(fs); in find_bitmap()
1351 } while (++i < SS(fs)); in find_bitmap()
1361 FATFS* fs, /* Filesystem object */ in change_bitmap() argument
1373 sect = fs->bitbase + clst / 8 / SS(fs); /* Sector address */ in change_bitmap()
1374 i = clst / 8 % SS(fs); /* Byte offset in the sector */ in change_bitmap()
1377 if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; in change_bitmap()
1380 if (bv == (int)((fs->win[i] & bm) != 0)) return FR_INT_ERR; /* Is the bit expected value? */ in change_bitmap()
1381 fs->win[i] ^= bm; /* Flip the bit */ in change_bitmap()
1382 fs->wflag = 1; in change_bitmap()
1386 } while (++i < SS(fs)); /* Next byte */ in change_bitmap()
1406 res = put_fat(obj->fs, cl, cl + 1); in fill_first_frag()
1429 res = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term); in fill_last_frag()
1453 FATFS *fs = obj->fs; in remove_chain() local
1461 if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Check if in valid range */ in remove_chain()
1464 if (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) { in remove_chain()
1465 res = put_fat(fs, pclst, 0xFFFFFFFF); in remove_chain()
1475 if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { in remove_chain()
1476 res = put_fat(fs, clst, 0); /* Mark the cluster 'free' on the FAT */ in remove_chain()
1479 if (fs->free_clst < fs->n_fatent - 2) { /* Update allocation information if it is valid */ in remove_chain()
1480 fs->free_clst++; in remove_chain()
1481 fs->fsi_flag |= 1; in remove_chain()
1488 if (fs->fs_type == FS_EXFAT) { in remove_chain()
1489 … res = change_bitmap(fs, scl, ecl - scl + 1, 0); /* Mark the cluster block 'free' on the bitmap */ in remove_chain()
1494 rt[0] = clst2sect(fs, scl); /* Start of data area to be freed */ in remove_chain()
1495 rt[1] = clst2sect(fs, ecl) + fs->csize - 1; /* End of data area to be freed */ in remove_chain()
1496 …disk_ioctl(fs->pdrv, CTRL_TRIM, rt); /* Inform storage device that the data in the block may be e… in remove_chain()
1502 } while (clst < fs->n_fatent); /* Repeat until the last link */ in remove_chain()
1506 if (fs->fs_type == FS_EXFAT) { in remove_chain()
1547 FATFS *fs = obj->fs; in create_chain() local
1551 scl = fs->last_clst; /* Suggested cluster to start to find */ in create_chain()
1552 if (scl == 0 || scl >= fs->n_fatent) scl = 1; in create_chain()
1558 if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ in create_chain()
1561 if (fs->free_clst == 0) return 0; /* No free cluster */ in create_chain()
1564 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ in create_chain()
1565 ncl = find_bitmap(fs, scl, 1); /* Find a free cluster */ in create_chain()
1567 res = change_bitmap(fs, ncl, 1, 1); /* Mark the cluster 'in use' */ in create_chain()
1593 if (ncl >= fs->n_fatent) ncl = 2; in create_chain()
1597 cs = fs->last_clst; /* Start at suggested cluster if it is valid */ in create_chain()
1598 if (cs >= 2 && cs < fs->n_fatent) scl = cs; in create_chain()
1606 if (ncl >= fs->n_fatent) { /* Check wrap-around */ in create_chain()
1616 res = put_fat(fs, ncl, 0xFFFFFFFF); /* Mark the new cluster 'EOC' */ in create_chain()
1618 res = put_fat(fs, clst, ncl); /* Link it from the previous one if needed */ in create_chain()
1623 fs->last_clst = ncl; in create_chain()
1624 if (fs->free_clst > 0 && fs->free_clst <= fs->n_fatent - 2) { in create_chain()
1625 fs->free_clst--; in create_chain()
1626 fs->fsi_flag |= 1; in create_chain()
1652 FATFS *fs = fp->obj.fs; in clmt_clust() local
1656 cl = (DWORD)(ofs / SS(fs) / fs->csize); /* Cluster order from top of the file */ in clmt_clust()
1677 FATFS *fs, /* Filesystem object */ in dir_clear() argument
1686 if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ in dir_clear()
1687 sect = clst2sect(fs, clst); /* Top of the cluster */ in dir_clear()
1688 fs->winsect = sect; /* Set window to top of the cluster */ in dir_clear()
1689 memset(fs->win, 0, sizeof fs->win); /* Clear window buffer */ in dir_clear()
1692 …for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; … in dir_clear()
1693 if (szb > SS(fs)) { /* Buffer allocated? */ in dir_clear()
1695 szb /= SS(fs); /* Bytes -> Sectors */ in dir_clear()
1696 …for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* F… in dir_clear()
1701 ibuf = fs->win; szb = 1; /* Use window buffer (many single-sector writes may take a time) */ in dir_clear()
1702 …for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* F… in dir_clear()
1704 return (n == fs->csize) ? FR_OK : FR_DISK_ERR; in dir_clear()
1721 FATFS *fs = dp->obj.fs; in dir_sdi() local
1724 …if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIR… in dir_sdi()
1729 if (clst == 0 && fs->fs_type >= FS_FAT32) { /* Replace cluster# 0 with root cluster# */ in dir_sdi()
1730 clst = (DWORD)fs->dirbase; in dir_sdi()
1735 if (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR; /* Is index out of range? */ in dir_sdi()
1736 dp->sect = fs->dirbase; in dir_sdi()
1739 csz = (DWORD)fs->csize * SS(fs); /* Bytes per cluster */ in dir_sdi()
1743 …if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Reached to end of table or internal er… in dir_sdi()
1746 dp->sect = clst2sect(fs, clst); in dir_sdi()
1750 dp->sect += ofs / SS(fs); /* Sector# of the directory entry */ in dir_sdi()
1751 dp->dir = fs->win + (ofs % SS(fs)); /* Pointer to the entry in the win[] */ in dir_sdi()
1769 FATFS *fs = dp->obj.fs; in dir_next() local
1773 …if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) dp->sect = 0;… in dir_next()
1776 if (ofs % SS(fs) == 0) { /* Sector changed? */ in dir_next()
1780 if (ofs / SZDIRE >= fs->n_rootdir) { /* Report EOT if it reached end of static table */ in dir_next()
1785 if ((ofs / SS(fs) & (fs->csize - 1)) == 0) { /* Cluster changed? */ in dir_next()
1789 if (clst >= fs->n_fatent) { /* It reached end of dynamic table */ in dir_next()
1798 if (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR; /* Clean up the stretched table */ in dir_next()
1806 dp->sect = clst2sect(fs, clst); in dir_next()
1811 dp->dir = fs->win + ofs % SS(fs); /* Pointer to the entry in the win[] */ in dir_next()
1831 FATFS *fs = dp->obj.fs; local
1838 res = move_window(fs, dp->sect);
1841 …if ((fs->fs_type == FS_EXFAT) ? (int)((dp->dir[XDIR_Type] & 0x80) == 0) : (int)(dp->dir[DIR_Name] …
1867 FATFS* fs, /* Pointer to the fs object */ argument
1874 if (fs->fs_type == FS_FAT32) {
1884 FATFS* fs, /* Pointer to the fs object */ argument
1890 if (fs->fs_type == FS_FAT32) {
2154 BYTE *dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory directory entry block 85+C0+C1s */
2158 res = move_window(dp->obj.fs, dp->sect);
2169 res = move_window(dp->obj.fs, dp->sect);
2181 res = move_window(dp->obj.fs, dp->sect);
2201 FATFS* fs, /* Filesystem object */ argument
2205 obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Start cluster */
2206 obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */
2207 obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; /* Allocation status */
2226 dp->obj.fs = obj->fs;
2253 BYTE *dirb = dp->obj.fs->dirbuf; /* Pointer to the entry set 85+C0+C1s */
2263 res = move_window(dp->obj.fs, dp->sect);
2266 dp->obj.fs->wflag = 1;
2333 FATFS *fs = dp->obj.fs; local
2340 res = move_window(fs, dp->sect);
2347 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
2355 dp->obj.attr = fs->dirbuf[XDIR_Attr] & AM_MASK; /* Get attribute */
2375 … ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;
2410 FATFS *fs = dp->obj.fs; local
2419 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
2422 WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */
2426 …if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object na…
2428 …if (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue; /* Skip comparison if hash mismatched */
2429 …for (nc = fs->dirbuf[XDIR_NumName], di = SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) { /* Compare…
2431 if (ff_wtoupper(ld_word(fs->dirbuf + di)) != ff_wtoupper(fs->lfnbuf[ni])) break;
2433 if (nc == 0 && !fs->lfnbuf[ni]) break; /* Name matched? */
2443 res = move_window(fs, dp->sect);
2461 … ord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;
2492 FATFS *fs = dp->obj.fs; local
2499 for (len = 0; fs->lfnbuf[len]; len++) ; /* Get lfn length */
2502 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
2519 dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */
2520 st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize);
2521 st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize);
2522 fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1; /* Update the allocation status */
2528 create_xdir(fs->dirbuf, fs->lfnbuf); /* Create on-memory directory block to be written later */
2537 gen_numname(dp->fn, sn, fs->lfnbuf, n); /* Generate a numbered name */
2554 res = move_window(fs, dp->sect);
2556 put_lfn(fs->lfnbuf, dp->dir, (BYTE)n_ent, sum);
2557 fs->wflag = 1;
2570 res = move_window(fs, dp->sect);
2577 fs->wflag = 1;
2598 FATFS *fs = dp->obj.fs; local
2605 res = move_window(fs, dp->sect);
2607 if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
2612 fs->wflag = 1;
2620 res = move_window(fs, dp->sect);
2623 fs->wflag = 1;
2648 FATFS *fs = dp->obj.fs; local
2660 if (fs->fs_type == FS_EXFAT) { /* exFAT volume */
2665 while (nc < fs->dirbuf[XDIR_NumName]) {
2670 wc = ld_word(fs->dirbuf + si); si += 2; nc++; /* Get a character */
2686 fno->fattrib = fs->dirbuf[XDIR_Attr] & AM_MASKX; /* Attribute */
2687 fno->fsize = (fno->fattrib & AM_DIR) ? 0 : ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */
2688 fno->ftime = ld_word(fs->dirbuf + XDIR_ModTime + 0); /* Time */
2689 fno->fdate = ld_word(fs->dirbuf + XDIR_ModTime + 2); /* Date */
2697 while (fs->lfnbuf[si] != 0) {
2698 wc = fs->lfnbuf[si++]; /* Get an LFN character (UTF-16) */
2884 p = *path; lfn = dp->obj.fs->lfnbuf; di = 0;
3080 FATFS *fs = dp->obj.fs; local
3085 dp->obj.sclust = fs->cdir; /* Start at the current directory */
3095 if (fs->fs_type == FS_EXFAT && dp->obj.sclust) { /* exFAT: Retrieve the sub-directory's status */
3098 dp->obj.c_scl = fs->cdc_scl;
3099 dp->obj.c_size = fs->cdc_size;
3100 dp->obj.c_ofs = fs->cdc_ofs;
3103 dp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize);
3104 dp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;
3137 if (fs->fs_type == FS_EXFAT) { /* Save containing directory information for next dir */
3141 init_alloc_info(fs, &dp->obj); /* Open next directory */
3145 dp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs)); /* Open next directory */
3308 FATFS* fs, /* Filesystem object */ argument
3316 fs->wflag = 0; fs->winsect = (LBA_t)0 - 1; /* Invaidate window */
3317 if (move_window(fs, sect) != FR_OK) return 4; /* Load the boot sector */
3318 sign = ld_word(fs->win + BS_55AA);
3320 …if (sign == 0xAA55 && !memcmp(fs->win + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11)) return 1; /* I…
3322 b = fs->win[BS_JmpBoot];
3324 if (sign == 0xAA55 && !memcmp(fs->win + BS_FilSysType32, "FAT32 ", 8)) {
3328 w = ld_word(fs->win + BPB_BytsPerSec);
3329 b = fs->win[BPB_SecPerClus];
3332 && ld_word(fs->win + BPB_RsvdSecCnt) != 0 /* Properness of number of reserved sectors (MNBZ) */
3333 && (UINT)fs->win[BPB_NumFATs] - 1 <= 1 /* Properness of number of FATs (1 or 2) */
3334 && ld_word(fs->win + BPB_RootEntCnt) != 0 /* Properness of root dir size (MNBZ) */
3335 …&& (ld_word(fs->win + BPB_TotSec16) >= 128 || ld_dword(fs->win + BPB_TotSec32) >= 0x10000) /* Prop…
3336 && ld_word(fs->win + BPB_FATSz16) != 0) { /* Properness of FAT size (MNBZ) */
3348 FATFS* fs, /* Filesystem object */ argument
3356 fmt = check_fs(fs, 0); /* Load sector 0 and check if it is an FAT VBR as SFD format */
3362 if (fs->win[MBR_Table + PTE_System] == 0xEE) { /* GPT protective MBR? */
3366 if (move_window(fs, 1) != FR_OK) return 4; /* Load GPT header sector (next to MBR) */
3367 if (!test_gpt_header(fs->win)) return 3; /* Check if GPT header is valid */
3368 n_ent = ld_dword(fs->win + GPTH_PtNum); /* Number of entries */
3369 pt_lba = ld_qword(fs->win + GPTH_PtOfs); /* Table location */
3371 if (move_window(fs, pt_lba + i * SZ_GPTE / SS(fs)) != FR_OK) return 4; /* PT sector */
3372 ofs = i * SZ_GPTE % SS(fs); /* Offset in the sector */
3373 if (!memcmp(fs->win + ofs + GPTE_PtGuid, GUID_MS_Basic, 16)) { /* MS basic data partition? */
3375 fmt = check_fs(fs, ld_qword(fs->win + ofs + GPTE_FstLba)); /* Load VBR and check status */
3385 mbr_pt[i] = ld_dword(fs->win + MBR_Table + i * SZ_PTE + PTE_StLba);
3389 fmt = mbr_pt[i] ? check_fs(fs, mbr_pt[i]) : 3; /* Check if the partition is FAT */
3408 FATFS *fs; local
3422 fs = FatFs[vol]; /* Get pointer to the filesystem object */
3423 if (!fs) return FR_NOT_ENABLED; /* Is the filesystem object available? */
3425 if (!lock_volume(fs, 1)) return FR_TIMEOUT; /* Lock the volume, and system if needed */
3427 *rfs = fs; /* Return pointer to the filesystem object */
3430 if (fs->fs_type != 0) { /* If the volume has been mounted */
3431 stat = disk_status(fs->pdrv);
3443 fs->fs_type = 0; /* Invalidate the filesystem object */
3444 stat = disk_initialize(fs->pdrv); /* Initialize the volume hosting physical drive */
3452 if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR;
3453 if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR;
3457 fmt = find_volume(fs, LD2PT(vol));
3460 bsect = fs->winsect; /* Volume offset in the hosting physical drive */
3469 for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */
3472 …if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must…
3474 …if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical…
3478 maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA of the volume + 1 */
3481 fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */
3483 fs->n_fats = fs->win[BPB_NumFATsEx]; /* Number of FATs */
3484 if (fs->n_fats != 1) return FR_NO_FILESYSTEM; /* (Supports only 1 FAT) */
3486 fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */
3487 if (fs->csize == 0) return FR_NO_FILESYSTEM; /* (Must be 1..32768 sectors) */
3489 nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */
3491 fs->n_fatent = nclst + 2;
3494 fs->volbase = bsect;
3495 fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx);
3496 fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx);
3497 …if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size mus…
3498 fs->dirbase = ld_dword(fs->win + BPB_RootClusEx);
3504 if (so >= fs->csize) return FR_NO_FILESYSTEM; /* Not found? */
3505 if (move_window(fs, clst2sect(fs, (DWORD)fs->dirbase) + so) != FR_OK) return FR_DISK_ERR;
3508 if (fs->win[i] == ET_BITMAP) break; /* Is it a bitmap entry? */
3509 i = (i + SZDIRE) % SS(fs); /* Next entry */
3511 bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */
3512 if (bcl < 2 || bcl >= fs->n_fatent) return FR_NO_FILESYSTEM; /* (Wrong cluster#) */
3513 fs->bitbase = fs->database + fs->csize * (bcl - 2); /* Bitmap sector */
3515 if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR;
3516 cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4);
3522 fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Invalidate cluster allocation information */
3523 fs->fsi_flag = 0; /* Enable to sync PercInUse value in VBR */
3529 …if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must …
3531 fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */
3532 if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32);
3533 fs->fsize = fasize;
3535 fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */
3536 if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
3537 fasize *= fs->n_fats; /* Number of sectors for FAT area */
3539 fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */
3540 …if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of…
3542 fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
3543 if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
3545 tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
3546 if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);
3548 nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
3552 sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */
3554 nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
3563 fs->n_fatent = nclst + 2; /* Number of FAT entries */
3564 fs->volbase = bsect; /* Volume start sector */
3565 fs->fatbase = bsect + nrsv; /* FAT start sector */
3566 fs->database = bsect + sysect; /* Data start sector */
3568 …if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) …
3569 if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
3570 fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */
3571 szbfat = fs->n_fatent * 4; /* (Needed FAT size) */
3573 if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
3574 fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
3576 fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
3578 …if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not …
3582 fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Invalidate cluster allocation information */
3583 fs->fsi_flag = 0x80; /* Disable FSInfo by default */
3585 …&& ld_word(fs->win + BPB_FSInfo32) == 1 /* FAT32: Enable FSInfo feature only if FSInfo sector is n…
3586 && move_window(fs, bsect + 1) == FR_OK)
3588 fs->fsi_flag = 0;
3589 if ( ld_dword(fs->win + FSI_LeadSig) == 0x41615252 /* Load FSInfo data if available */
3590 && ld_dword(fs->win + FSI_StrucSig) == 0x61417272
3591 && ld_dword(fs->win + FSI_TrailSig) == 0xAA550000)
3594 fs->free_clst = ld_dword(fs->win + FSI_Free_Count);
3597 fs->last_clst = ld_dword(fs->win + FSI_Nxt_Free);
3604 fs->fs_type = (BYTE)fmt;/* FAT sub-type (the filesystem object gets valid) */
3605 fs->id = ++Fsid; /* Volume mount ID */
3607 fs->lfnbuf = LfnBuf; /* Static LFN working buffer */
3609 fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */
3613 fs->cdir = 0; /* Initialize current directory */
3616 clear_share(fs);
3636 …if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid…
3638 if (lock_volume(obj->fs, 0)) { /* Take a grant to access the volume */
3639 …if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the hosting physical drive is kept in…
3642 unlock_volume(obj->fs, FR_OK); /* Invalidated volume, abort to access */
3648 …if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the hosting physical drive is kept in…
3653 *rfs = (res == FR_OK) ? obj->fs : 0; /* Return corresponding filesystem object if it is valid */
3673 FATFS* fs, /* Pointer to the filesystem object to be registered (NULL:unmount)*/ argument
3700 if (fs) { /* Register new filesystem object */
3701 fs->pdrv = LD2PD(vol); /* Volume hosting physical drive */
3703 fs->ldrv = (BYTE)vol; /* Owner volume ID */
3715 fs->fs_type = 0; /* Invalidate the new filesystem object */
3716 FatFs[vol] = fs; /* Register new fs object */
3721 res = mount_volume(&path, &fs, 0); /* Force mounted the volume */
3722 LEAVE_FF(fs, res);
3740 FATFS *fs; local
3753 res = mount_volume(&path, &fs, mode);
3755 dj.obj.fs = fs;
3756 INIT_NAMBUF(fs);
3790 if (fs->fs_type == FS_EXFAT) {
3792 fp->obj.fs = fs;
3793 init_alloc_info(fs, &fp->obj);
3795 memset(fs->dirbuf + 2, 0, 30); /* Clear 85 entry except for NumSec */
3796 memset(fs->dirbuf + 38, 0, 26); /* Clear C0 entry except for NumName and NameHash */
3797 fs->dirbuf[XDIR_Attr] = AM_ARC;
3798 st_dword(fs->dirbuf + XDIR_CrtTime, GET_FATTIME());
3799 fs->dirbuf[XDIR_GenFlags] = 1;
3803 fs->last_clst = fp->obj.sclust - 1; /* Reuse the cluster hole */
3812 cl = ld_clust(fs, dj.dir); /* Get current cluster chain */
3814 st_clust(fs, dj.dir, 0); /* Reset file allocation info */
3816 fs->wflag = 1;
3818 sc = fs->winsect;
3821 res = move_window(fs, sc);
3822 fs->last_clst = cl - 1; /* Reuse the cluster hole */
3841 fp->dir_sect = fs->winsect; /* Pointer to the directory entry */
3862 if (fs->fs_type == FS_EXFAT) {
3866 init_alloc_info(fs, &fp->obj);
3870 fp->obj.sclust = ld_clust(fs, dj.dir); /* Get object allocation info */
3876 fp->obj.fs = fs; /* Validate the file object */
3877 fp->obj.id = fs->id;
3888 bcs = (DWORD)fs->csize * SS(fs); /* Cluster size in byte */
3896 if (res == FR_OK && ofs % SS(fs)) { /* Fill sector buffer if not on the sector boundary */
3897 sc = clst2sect(fs, clst);
3901 fp->sect = sc + (DWORD)(ofs / SS(fs));
3903 if (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR;
3917 if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */
3919 LEAVE_FF(fs, res);
3937 FATFS *fs; local
3946 res = validate(&fp->obj, &fs); /* Check validity of the file object */
3947 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
3948 if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
3953 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
3954 csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */
3968 if (clst < 2) ABORT(fs, FR_INT_ERR);
3969 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
3972 sect = clst2sect(fs, fp->clust); /* Get current sector */
3973 if (sect == 0) ABORT(fs, FR_INT_ERR);
3975 cc = btr / SS(fs); /* When remaining bytes >= sector size, */
3977 if (csect + cc > fs->csize) { /* Clip at cluster boundary */
3978 cc = fs->csize - csect;
3980 if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
3983 if (fs->wflag && fs->winsect - sect < cc) {
3984 memcpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs));
3988 memcpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs));
3992 rcnt = SS(fs) * cc; /* Number of bytes transferred */
3999 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4003 …if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache …
4008 rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
4011 if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
4012 memcpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
4014 memcpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
4018 LEAVE_FF(fs, FR_OK);
4037 FATFS *fs; local
4045 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4046 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
4047 if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
4050 if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
4055 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
4056 csect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1); /* Sector offset in the cluster */
4074 if (clst == 1) ABORT(fs, FR_INT_ERR);
4075 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4080 …if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sec…
4083 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4087 sect = clst2sect(fs, fp->clust); /* Get current sector */
4088 if (sect == 0) ABORT(fs, FR_INT_ERR);
4090 cc = btw / SS(fs); /* When remaining bytes >= sector size, */
4092 if (csect + cc > fs->csize) { /* Clip at cluster boundary */
4093 cc = fs->csize - csect;
4095 if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
4098 …if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
4099 memcpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs));
4100 fs->wflag = 0;
4104 memcpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs));
4109 wcnt = SS(fs) * cc; /* Number of bytes transferred */
4114 if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR);
4115 fs->winsect = sect;
4120 disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
4121 ABORT(fs, FR_DISK_ERR);
4126 wcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
4129 if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
4130 memcpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */
4131 fs->wflag = 1;
4133 memcpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */
4140 LEAVE_FF(fs, FR_OK);
4155 FATFS *fs; local
4160 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4165 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);
4172 if (fs->fs_type == FS_EXFAT) {
4181 INIT_NAMBUF(fs);
4184fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been ch…
4185 fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1; /* Update file allocation information */
4186 st_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust); /* Update start cluster */
4187 st_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize); /* Update file size */
4188 …st_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize); /* (FatFs does not support Valid File …
4189 st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Update modified time */
4190 fs->dirbuf[XDIR_ModTime10] = 0;
4191 st_dword(fs->dirbuf + XDIR_AccTime, 0);
4194 res = sync_fs(fs);
4203 res = move_window(fs, fp->dir_sect);
4207 st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation information */
4211 fs->wflag = 1;
4212 res = sync_fs(fs); /* Restore it to the directory */
4219 LEAVE_FF(fs, res);
4236 FATFS *fs; local
4243 res = validate(&fp->obj, &fs); /* Lock volume */
4247 if (res == FR_OK) fp->obj.fs = 0; /* Invalidate file object */
4249 fp->obj.fs = 0; /* Invalidate file object */
4252 unlock_volume(fs, FR_OK); /* Unlock volume */
4293 FATFS *fs; local
4298 res = mount_volume(&path, &fs, 0);
4300 dj.obj.fs = fs;
4301 INIT_NAMBUF(fs);
4305 fs->cdir = dj.obj.sclust;
4307 if (fs->fs_type == FS_EXFAT) {
4308 fs->cdc_scl = dj.obj.c_scl;
4309 fs->cdc_size = dj.obj.c_size;
4310 fs->cdc_ofs = dj.obj.c_ofs;
4316 if (fs->fs_type == FS_EXFAT) {
4317 fs->cdir = ld_dword(fs->dirbuf + XDIR_FstClus); /* Sub-directory cluster */
4318 fs->cdc_scl = dj.obj.sclust; /* Save containing directory information */
4319 fs->cdc_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat;
4320 fs->cdc_ofs = dj.blk_ofs;
4324 fs->cdir = ld_clust(fs, dj.dir); /* Sub-directory cluster */
4335 for (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ; /* Set current drive */
4341 LEAVE_FF(fs, res);
4353 FATFS *fs; local
4369 res = mount_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */
4371 dj.obj.fs = fs;
4372 INIT_NAMBUF(fs);
4376 …if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* (Cannot do getcwd on exFAT and returns root path…
4377 dj.obj.sclust = fs->cdir; /* Start to follow upper directory from current directory */
4381 res = move_window(fs, dj.sect);
4383 dj.obj.sclust = ld_clust(fs, dj.dir); /* Goto parent directory */
4389 if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */
4435 LEAVE_FF(fs, res);
4454 FATFS *fs; local
4464 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4467 if (res == FR_OK && fs->fs_type == FS_EXFAT) {
4471 if (res != FR_OK) LEAVE_FF(fs, res);
4486 if (cl <= 1) ABORT(fs, FR_INT_ERR);
4487 if (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4492 } while (cl < fs->n_fatent); /* Repeat until end of chain */
4505 dsc = clst2sect(fs, fp->clust);
4506 if (dsc == 0) ABORT(fs, FR_INT_ERR);
4507 dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1);
4508 if (fp->fptr % SS(fs) && dsc != fp->sect) { /* Refill sector cache if needed */
4512 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4516 …if (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector…
4528 …if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4 GiB - 1 if at FA…
4536 bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */
4547 if (clst == 1) ABORT(fs, FR_INT_ERR);
4548 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4572 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4573 if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR);
4577 if (ofs % SS(fs)) {
4578 nsect = clst2sect(fs, clst); /* Current sector */
4579 if (nsect == 0) ABORT(fs, FR_INT_ERR);
4580 nsect += (DWORD)(ofs / SS(fs));
4588 if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */
4592 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4596 …if (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache…
4602 LEAVE_FF(fs, res);
4618 FATFS *fs; local
4625 res = mount_volume(&path, &fs, 0);
4627 dp->obj.fs = fs;
4628 INIT_NAMBUF(fs);
4634 if (fs->fs_type == FS_EXFAT) {
4638 init_alloc_info(fs, &dp->obj); /* Get object allocation info */
4642 dp->obj.sclust = ld_clust(fs, dp->dir); /* Get object allocation info */
4649 dp->obj.id = fs->id;
4666 if (res != FR_OK) dp->obj.fs = 0; /* Invalidate the directory object if function failed */
4668 LEAVE_FF(fs, res);
4683 FATFS *fs; local
4686 res = validate(&dp->obj, &fs); /* Check validity of the file object */
4690 if (res == FR_OK) dp->obj.fs = 0; /* Invalidate directory object */
4692 dp->obj.fs = 0; /* Invalidate directory object */
4695 unlock_volume(fs, FR_OK); /* Unlock volume */
4714 FATFS *fs; local
4718 res = validate(&dp->obj, &fs); /* Check validity of the directory object */
4723 INIT_NAMBUF(fs);
4734 LEAVE_FF(fs, res);
4807 res = mount_volume(&path, &dj.obj.fs, 0);
4809 INIT_NAMBUF(dj.obj.fs);
4821 LEAVE_FF(dj.obj.fs, res);
4838 FATFS *fs; local
4846 res = mount_volume(&path, &fs, 0);
4848 *fatfs = fs; /* Return ptr to the fs object */
4850 if (fs->free_clst <= fs->n_fatent - 2) {
4851 *nclst = fs->free_clst;
4855 if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */
4856 clst = 2; obj.fs = fs;
4866 } while (++clst < fs->n_fatent);
4869 if (fs->fs_type == FS_EXFAT) { /* exFAT: Scan allocation bitmap */
4873 clst = fs->n_fatent - 2; /* Number of clusters */
4874 sect = fs->bitbase; /* Bitmap sector */
4878 res = move_window(fs, sect++);
4881 for (b = 8, bm = ~fs->win[i]; b && clst; b--, clst--) { /* Count clear bits in a byte */
4885 i = (i + 1) % SS(fs); /* Next byte */
4890 clst = fs->n_fatent; /* Number of entries */
4891 sect = fs->fatbase; /* Top of the FAT */
4895 res = move_window(fs, sect++);
4898 if (fs->fs_type == FS_FAT16) {
4899 if (ld_word(fs->win + i) == 0) nfree++; /* FAT16: Is this cluster free? */
4902 if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++; /* FAT32: Is this cluster free? */
4905 i %= SS(fs);
4911 fs->free_clst = nfree; /* Now free cluster count is valid */
4912 fs->fsi_flag |= 1; /* FAT32/exfAT : Allocation information is to be updated */
4917 LEAVE_FF(fs, res);
4932 FATFS *fs; local
4936 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4937 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
4938 if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
4949 if (res == FR_OK && ncl < fs->n_fatent) {
4957 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {
4964 if (res != FR_OK) ABORT(fs, res);
4967 LEAVE_FF(fs, res);
4982 FATFS *fs; local
4992 res = mount_volume(&path, &fs, FA_WRITE);
4994 dj.obj.fs = fs;
4995 INIT_NAMBUF(fs);
5013 obj.fs = fs;
5014 if (fs->fs_type == FS_EXFAT) {
5015 init_alloc_info(fs, &obj);
5020 dclst = ld_clust(fs, dj.dir);
5024 if (dclst == fs->cdir) { /* Is it the current directory? */
5029 sdj.obj.fs = fs; /* Open the sub-directory */
5032 if (fs->fs_type == FS_EXFAT) {
5055 if (res == FR_OK) res = sync_fs(fs);
5061 LEAVE_FF(fs, res);
5076 FATFS *fs; local
5083 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
5085 dj.obj.fs = fs;
5086 INIT_NAMBUF(fs);
5093 sobj.fs = fs; /* New object id to create a new chain */
5101 res = dir_clear(fs, dcl); /* Clean up the new table */
5103 if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* Create dot entries (FAT only) */
5104 memset(fs->win + DIR_Name, ' ', 11); /* Create "." entry */
5105 fs->win[DIR_Name] = '.';
5106 fs->win[DIR_Attr] = AM_DIR;
5107 st_dword(fs->win + DIR_ModTime, tm);
5108 st_clust(fs, fs->win, dcl);
5109 memcpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create ".." entry */
5110 fs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust;
5111 st_clust(fs, fs->win + SZDIRE, pcl);
5112 fs->wflag = 1;
5119 if (fs->fs_type == FS_EXFAT) { /* Initialize directory entry block */
5120 st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Created time */
5121 st_dword(fs->dirbuf + XDIR_FstClus, dcl); /* Table start cluster */
5122 …st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)fs->csize * SS(fs)); /* Directory size needs to be val…
5123 st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)fs->csize * SS(fs));
5124 fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag */
5125 fs->dirbuf[XDIR_Attr] = AM_DIR; /* Attribute */
5131 st_clust(fs, dj.dir, dcl); /* Table start cluster */
5133 fs->wflag = 1;
5136 res = sync_fs(fs);
5145 LEAVE_FF(fs, res);
5161 FATFS *fs; local
5169 res = mount_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */
5171 djo.obj.fs = fs;
5172 INIT_NAMBUF(fs);
5182 if (fs->fs_type == FS_EXFAT) { /* At exFAT volume */
5186 memcpy(buf, fs->dirbuf, SZDIRE * 2); /* Save 85+C0 entry of old object */
5195 nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName];
5196 nh = ld_word(fs->dirbuf + XDIR_NameHash);
5197 memcpy(fs->dirbuf, buf, SZDIRE * 2); /* Restore 85+C0 entry */
5198 fs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn;
5199 st_word(fs->dirbuf + XDIR_NameHash, nh);
5200 …if (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute i…
5221 fs->wflag = 1;
5223 sect = clst2sect(fs, ld_clust(fs, dir));
5228 res = move_window(fs, sect);
5229 dir = fs->win + SZDIRE * 1; /* Pointer to .. entry */
5231 st_clust(fs, dir, djn.obj.sclust);
5232 fs->wflag = 1;
5242 res = sync_fs(fs);
5250 LEAVE_FF(fs, res);
5272 FATFS *fs; local
5277 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
5279 dj.obj.fs = fs;
5280 INIT_NAMBUF(fs);
5286 if (fs->fs_type == FS_EXFAT) {
5287fs->dirbuf[XDIR_Attr] = (attr & mask) | (fs->dirbuf[XDIR_Attr] & (BYTE)~mask); /* Apply attribute …
5293 fs->wflag = 1;
5296 res = sync_fs(fs);
5302 LEAVE_FF(fs, res);
5318 FATFS *fs; local
5323 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
5325 dj.obj.fs = fs;
5326 INIT_NAMBUF(fs);
5331 if (fs->fs_type == FS_EXFAT) {
5332 st_dword(fs->dirbuf + XDIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime);
5338 fs->wflag = 1;
5341 res = sync_fs(fs);
5347 LEAVE_FF(fs, res);
5366 FATFS *fs; local
5372 res = mount_volume(&path, &fs, 0);
5376 dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */
5382 if (fs->fs_type == FS_EXFAT) {
5432 res = move_window(fs, fs->volbase); /* Load VBR */
5434 switch (fs->fs_type) {
5444 di = fs->win[BS_BootSig] == 0x29 ? BS_VolID : 0;
5446 *vsn = di ? ld_dword(fs->win + di) : 0; /* Get VSN in the VBR */
5450 LEAVE_FF(fs, res);
5465 FATFS *fs; local
5476 res = mount_volume(&label, &fs, FA_WRITE);
5477 if (res != FR_OK) LEAVE_FF(fs, res);
5483 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
5496 LEAVE_FF(fs, FR_INVALID_NAME);
5520 LEAVE_FF(fs, FR_INVALID_NAME);
5525 if (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */
5530 dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */
5535 if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {
5545 fs->wflag = 1;
5546 res = sync_fs(fs);
5554 if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {
5562 fs->wflag = 1;
5563 res = sync_fs(fs);
5570 LEAVE_FF(fs, res);
5590 FATFS *fs; local
5594 res = validate(&fp->obj, &fs); /* Check validity of the file object */
5595 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
5596 if (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);
5598 …if (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED); /* Check if in size li…
5600 n = (DWORD)fs->csize * SS(fs); /* Cluster size */
5602 stcl = fs->last_clst; lclst = 0;
5603 if (stcl < 2 || stcl >= fs->n_fatent) stcl = 2;
5606 if (fs->fs_type == FS_EXFAT) {
5607 scl = find_bitmap(fs, stcl, tcl); /* Find a contiguous cluster block */
5612 res = change_bitmap(fs, scl, tcl, 1); /* Mark the cluster block 'in use' */
5624 if (++clst >= fs->n_fatent) clst = 2;
5643 res = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1);
5654 fs->last_clst = lclst; /* Set suggested start cluster to start next */
5660 if (fs->free_clst <= fs->n_fatent - 2) { /* Update FSINFO */
5661 fs->free_clst -= tcl;
5662 fs->fsi_flag |= 1;
5667 LEAVE_FF(fs, res);
5687 FATFS *fs; local
5696 res = validate(&fp->obj, &fs); /* Check validity of the file object */
5697 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
5698 if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
5704 csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */
5705 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
5709 if (clst <= 1) ABORT(fs, FR_INT_ERR);
5710 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
5714 sect = clst2sect(fs, fp->clust); /* Get current data sector */
5715 if (sect == 0) ABORT(fs, FR_INT_ERR);
5718 …if (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window to the file data…
5719 dbuf = fs->win;
5724 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
5728 if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
5733 rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
5735 rcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt); /* Forward the file data */
5736 if (rcnt == 0) ABORT(fs, FR_INT_ERR);
5739 LEAVE_FF(fs, FR_OK);