Lines Matching refs:fs

234 #define ABORT(fs, res)		{ fp->err = (BYTE)(res); LEAVE_FF(fs, res); }  argument
242 #define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } argument
244 #define LEAVE_FF(fs, res) return res argument
263 #define SS(fs) ((UINT)FF_MAX_SS) /* Fixed sector size */ argument
265 #define SS(fs) ((fs)->ssize) /* Variable sector size */ argument
286 FATFS *fs; /* Object ID 1, volume (NULL:blank entry) */ member
499 #define INIT_NAMBUF(fs) argument
522 #define INIT_NAMBUF(fs) argument
529 #define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; } argument
533 #define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; } argument
541 …IT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, … argument
545 #define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH… argument
891 FATFS* fs /* Filesystem object */ in lock_fs() argument
894 return ff_req_grant(fs->sobj); in lock_fs()
899 FATFS* fs, /* Filesystem object */ in unlock_fs() argument
903 if (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) { in unlock_fs()
904 ff_rel_grant(fs->sobj); in unlock_fs()
927 if (Files[i].fs) { /* Existing entry */ in chk_lock()
928 if (Files[i].fs == dp->obj.fs && /* Check if the object matches with an open object */ in chk_lock()
948 for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; in enq_lock()
962 if (Files[i].fs == dp->obj.fs in inc_lock()
968 for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; in inc_lock()
970 Files[i].fs = dp->obj.fs; in inc_lock()
997 if (n == 0) Files[i].fs = 0; /* Delete the entry if open count gets zero */ in dec_lock()
1007 FATFS *fs in clear_lock() argument
1013 if (Files[i].fs == fs) Files[i].fs = 0; in clear_lock()
1026 FATFS* fs /* Filesystem object */ in sync_window() argument
1032 if (fs->wflag) { /* Is the disk access window dirty? */ in sync_window()
1033 if (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) { /* Write it back into the volume */ in sync_window()
1034 fs->wflag = 0; /* Clear window dirty flag */ in sync_window()
1035 if (fs->winsect - fs->fatbase < fs->fsize) { /* Is it in the 1st FAT? */ in sync_window()
1036 …if (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2… in sync_window()
1048 FATFS* fs, /* Filesystem object */ in move_window() argument
1055 if (sect != fs->winsect) { /* Window offset changed? */ in move_window()
1057 res = sync_window(fs); /* Flush the window */ in move_window()
1060 if (disk_read(fs->pdrv, fs->win, sect, 1) != RES_OK) { in move_window()
1064 fs->winsect = sect; in move_window()
1079 FATFS* fs /* Filesystem object */ in sync_fs() argument
1085 res = sync_window(fs); in sync_fs()
1087 if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ in sync_fs()
1089 memset(fs->win, 0, sizeof fs->win); in sync_fs()
1090 st_word(fs->win + BS_55AA, 0xAA55); /* Boot signature */ in sync_fs()
1091 st_dword(fs->win + FSI_LeadSig, 0x41615252); /* Leading signature */ in sync_fs()
1092 st_dword(fs->win + FSI_StrucSig, 0x61417272); /* Structure signature */ in sync_fs()
1093 st_dword(fs->win + FSI_Free_Count, fs->free_clst); /* Number of free clusters */ in sync_fs()
1094 st_dword(fs->win + FSI_Nxt_Free, fs->last_clst); /* Last allocated culuster */ in sync_fs()
1095 fs->winsect = fs->volbase + 1; /* Write it into the FSInfo sector (Next to VBR) */ in sync_fs()
1096 disk_write(fs->pdrv, fs->win, fs->winsect, 1); in sync_fs()
1097 fs->fsi_flag = 0; in sync_fs()
1100 if (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR; in sync_fs()
1115 FATFS* fs, /* Filesystem object */ in clst2sect() argument
1120 if (clst >= fs->n_fatent - 2) return 0; /* Is it invalid cluster number? */ in clst2sect()
1121 return fs->database + (LBA_t)fs->csize * clst; /* Start sector number of the cluster */ in clst2sect()
1138 FATFS *fs = obj->fs; in get_fat() local
1141 if (clst < 2 || clst >= fs->n_fatent) { /* Check if in valid range */ in get_fat()
1147 switch (fs->fs_type) { in get_fat()
1150 if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; in get_fat()
1151 wc = fs->win[bc++ % SS(fs)]; /* Get 1st byte of the entry */ in get_fat()
1152 if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; in get_fat()
1153 wc |= fs->win[bc % SS(fs)] << 8; /* Merge 2nd byte of the entry */ in get_fat()
1158 if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break; in get_fat()
1159 val = ld_word(fs->win + clst * 2 % SS(fs)); /* Simple WORD array */ in get_fat()
1163 if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; in get_fat()
1164 …val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF; /* Simple DWORD array but mask out upper… in get_fat()
1170 …DWORD clen = (DWORD)((LBA_t)((obj->objsize - 1) / SS(fs)) / fs->csize); /* Number of clusters - 1 … in get_fat()
1184 if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; in get_fat()
1185 val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF; in get_fat()
1210 FATFS* fs, /* Corresponding filesystem object */ in put_fat() argument
1220 if (clst >= 2 && clst < fs->n_fatent) { /* Check if in valid range */ in put_fat()
1221 switch (fs->fs_type) { in put_fat()
1224 res = move_window(fs, fs->fatbase + (bc / SS(fs))); in put_fat()
1226 p = fs->win + bc++ % SS(fs); in put_fat()
1228 fs->wflag = 1; in put_fat()
1229 res = move_window(fs, fs->fatbase + (bc / SS(fs))); in put_fat()
1231 p = fs->win + bc % SS(fs); in put_fat()
1233 fs->wflag = 1; in put_fat()
1237 res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); in put_fat()
1239 st_word(fs->win + clst * 2 % SS(fs), (WORD)val); /* Simple WORD array */ in put_fat()
1240 fs->wflag = 1; in put_fat()
1247 res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); in put_fat()
1249 if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { in put_fat()
1250 val = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000); in put_fat()
1252 st_dword(fs->win + clst * 4 % SS(fs), val); in put_fat()
1253 fs->wflag = 1; in put_fat()
1275 FATFS* fs, /* Filesystem object */ in find_bitmap() argument
1286 if (clst >= fs->n_fatent - 2) clst = 0; in find_bitmap()
1289 if (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; in find_bitmap()
1290 i = val / 8 % SS(fs); bm = 1 << (val % 8); in find_bitmap()
1293 bv = fs->win[i] & bm; bm <<= 1; /* Get bit value */ in find_bitmap()
1294 if (++val >= fs->n_fatent - 2) { /* Next cluster (with wrap-around) */ in find_bitmap()
1295 val = 0; bm = 0; i = SS(fs); in find_bitmap()
1305 } while (++i < SS(fs)); in find_bitmap()
1315 FATFS* fs, /* Filesystem object */ in change_bitmap() argument
1327 sect = fs->bitbase + clst / 8 / SS(fs); /* Sector address */ in change_bitmap()
1328 i = clst / 8 % SS(fs); /* Byte offset in the sector */ in change_bitmap()
1331 if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; in change_bitmap()
1334 if (bv == (int)((fs->win[i] & bm) != 0)) return FR_INT_ERR; /* Is the bit expected value? */ in change_bitmap()
1335 fs->win[i] ^= bm; /* Flip the bit */ in change_bitmap()
1336 fs->wflag = 1; in change_bitmap()
1340 } while (++i < SS(fs)); /* Next byte */ in change_bitmap()
1360 res = put_fat(obj->fs, cl, cl + 1); in fill_first_frag()
1383 res = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term); in fill_last_frag()
1407 FATFS *fs = obj->fs; in remove_chain() local
1415 if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Check if in valid range */ in remove_chain()
1418 if (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) { in remove_chain()
1419 res = put_fat(fs, pclst, 0xFFFFFFFF); in remove_chain()
1429 if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { in remove_chain()
1430 res = put_fat(fs, clst, 0); /* Mark the cluster 'free' on the FAT */ in remove_chain()
1433 if (fs->free_clst < fs->n_fatent - 2) { /* Update FSINFO */ in remove_chain()
1434 fs->free_clst++; in remove_chain()
1435 fs->fsi_flag |= 1; in remove_chain()
1442 if (fs->fs_type == FS_EXFAT) { in remove_chain()
1443 … res = change_bitmap(fs, scl, ecl - scl + 1, 0); /* Mark the cluster block 'free' on the bitmap */ in remove_chain()
1448 rt[0] = clst2sect(fs, scl); /* Start of data area to be freed */ in remove_chain()
1449 rt[1] = clst2sect(fs, ecl) + fs->csize - 1; /* End of data area to be freed */ in remove_chain()
1450 …disk_ioctl(fs->pdrv, CTRL_TRIM, rt); /* Inform storage device that the data in the block may be e… in remove_chain()
1456 } while (clst < fs->n_fatent); /* Repeat while not the last link */ in remove_chain()
1460 if (fs->fs_type == FS_EXFAT) { in remove_chain()
1501 FATFS *fs = obj->fs; in create_chain() local
1505 scl = fs->last_clst; /* Suggested cluster to start to find */ in create_chain()
1506 if (scl == 0 || scl >= fs->n_fatent) scl = 1; in create_chain()
1512 if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ in create_chain()
1515 if (fs->free_clst == 0) return 0; /* No free cluster */ in create_chain()
1518 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ in create_chain()
1519 ncl = find_bitmap(fs, scl, 1); /* Find a free cluster */ in create_chain()
1521 res = change_bitmap(fs, ncl, 1, 1); /* Mark the cluster 'in use' */ in create_chain()
1547 if (ncl >= fs->n_fatent) ncl = 2; in create_chain()
1551 cs = fs->last_clst; /* Start at suggested cluster if it is valid */ in create_chain()
1552 if (cs >= 2 && cs < fs->n_fatent) scl = cs; in create_chain()
1560 if (ncl >= fs->n_fatent) { /* Check wrap-around */ in create_chain()
1570 res = put_fat(fs, ncl, 0xFFFFFFFF); /* Mark the new cluster 'EOC' */ in create_chain()
1572 res = put_fat(fs, clst, ncl); /* Link it from the previous one if needed */ in create_chain()
1577 fs->last_clst = ncl; in create_chain()
1578 if (fs->free_clst <= fs->n_fatent - 2) fs->free_clst--; in create_chain()
1579 fs->fsi_flag |= 1; in create_chain()
1603 FATFS *fs = fp->obj.fs; in clmt_clust() local
1607 cl = (DWORD)(ofs / SS(fs) / fs->csize); /* Cluster order from top of the file */ in clmt_clust()
1628 FATFS *fs, /* Filesystem object */ in dir_clear() argument
1637 if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ in dir_clear()
1638 sect = clst2sect(fs, clst); /* Top of the cluster */ in dir_clear()
1639 fs->winsect = sect; /* Set window to top of the cluster */ in dir_clear()
1640 memset(fs->win, 0, sizeof fs->win); /* Clear window buffer */ in dir_clear()
1643 …for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; … in dir_clear()
1644 if (szb > SS(fs)) { /* Buffer allocated? */ in dir_clear()
1646 szb /= SS(fs); /* Bytes -> Sectors */ in dir_clear()
1647 …for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* F… in dir_clear()
1652 ibuf = fs->win; szb = 1; /* Use window buffer (many single-sector writes may take a time) */ in dir_clear()
1653 …for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* F… in dir_clear()
1655 return (n == fs->csize) ? FR_OK : FR_DISK_ERR; in dir_clear()
1672 FATFS *fs = dp->obj.fs; in dir_sdi() local
1675 …if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIR… in dir_sdi()
1680 if (clst == 0 && fs->fs_type >= FS_FAT32) { /* Replace cluster# 0 with root cluster# */ in dir_sdi()
1681 clst = (DWORD)fs->dirbase; in dir_sdi()
1686 if (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR; /* Is index out of range? */ in dir_sdi()
1687 dp->sect = fs->dirbase; in dir_sdi()
1690 csz = (DWORD)fs->csize * SS(fs); /* Bytes per cluster */ in dir_sdi()
1694 …if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Reached to end of table or internal er… in dir_sdi()
1697 dp->sect = clst2sect(fs, clst); in dir_sdi()
1701 dp->sect += ofs / SS(fs); /* Sector# of the directory entry */ in dir_sdi()
1702 dp->dir = fs->win + (ofs % SS(fs)); /* Pointer to the entry in the win[] */ in dir_sdi()
1720 FATFS *fs = dp->obj.fs; in dir_next() local
1724 …if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) dp->sect = 0;… in dir_next()
1727 if (ofs % SS(fs) == 0) { /* Sector changed? */ in dir_next()
1731 if (ofs / SZDIRE >= fs->n_rootdir) { /* Report EOT if it reached end of static table */ in dir_next()
1736 if ((ofs / SS(fs) & (fs->csize - 1)) == 0) { /* Cluster changed? */ in dir_next()
1740 if (clst >= fs->n_fatent) { /* It reached end of dynamic table */ in dir_next()
1749 if (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR; /* Clean up the stretched table */ in dir_next()
1757 dp->sect = clst2sect(fs, clst); in dir_next()
1762 dp->dir = fs->win + ofs % SS(fs); /* Pointer to the entry in the win[] */ in dir_next()
1782 FATFS *fs = dp->obj.fs; local
1789 res = move_window(fs, dp->sect);
1792 …if ((fs->fs_type == FS_EXFAT) ? (int)((dp->dir[XDIR_Type] & 0x80) == 0) : (int)(dp->dir[DIR_Name] …
1818 FATFS* fs, /* Pointer to the fs object */ argument
1825 if (fs->fs_type == FS_FAT32) {
1835 FATFS* fs, /* Pointer to the fs object */ argument
1841 if (fs->fs_type == FS_FAT32) {
2105 BYTE *dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */
2109 res = move_window(dp->obj.fs, dp->sect);
2120 res = move_window(dp->obj.fs, dp->sect);
2132 res = move_window(dp->obj.fs, dp->sect);
2151 FATFS* fs, /* Filesystem object */ argument
2155 obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Start cluster */
2156 obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */
2157 obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; /* Allocation status */
2176 dp->obj.fs = obj->fs;
2203 BYTE *dirb = dp->obj.fs->dirbuf; /* Pointer to the direcotry entry block 85+C0+C1s */
2212 res = move_window(dp->obj.fs, dp->sect);
2215 dp->obj.fs->wflag = 1;
2281 FATFS *fs = dp->obj.fs; local
2288 res = move_window(fs, dp->sect);
2295 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
2303 dp->obj.attr = fs->dirbuf[XDIR_Attr] & AM_MASK; /* Get attribute */
2323 … ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;
2358 FATFS *fs = dp->obj.fs; local
2367 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
2370 WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */
2374 …if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object na…
2376 …if (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue; /* Skip comparison if hash mismatched */
2377 …for (nc = fs->dirbuf[XDIR_NumName], di = SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) { /* Compare…
2379 if (ff_wtoupper(ld_word(fs->dirbuf + di)) != ff_wtoupper(fs->lfnbuf[ni])) break;
2381 if (nc == 0 && !fs->lfnbuf[ni]) break; /* Name matched? */
2391 res = move_window(fs, dp->sect);
2408 … ord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;
2439 FATFS *fs = dp->obj.fs; local
2446 for (len = 0; fs->lfnbuf[len]; len++) ; /* Get lfn length */
2449 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
2466 dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */
2467 st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize);
2468 st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize);
2469 fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1; /* Update the allocation status */
2475 create_xdir(fs->dirbuf, fs->lfnbuf); /* Create on-memory directory block to be written later */
2484 gen_numname(dp->fn, sn, fs->lfnbuf, n); /* Generate a numbered name */
2501 res = move_window(fs, dp->sect);
2503 put_lfn(fs->lfnbuf, dp->dir, (BYTE)n_ent, sum);
2504 fs->wflag = 1;
2517 res = move_window(fs, dp->sect);
2524 fs->wflag = 1;
2545 FATFS *fs = dp->obj.fs; local
2552 res = move_window(fs, dp->sect);
2554 if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
2559 fs->wflag = 1;
2567 res = move_window(fs, dp->sect);
2570 fs->wflag = 1;
2595 FATFS *fs = dp->obj.fs; local
2607 if (fs->fs_type == FS_EXFAT) { /* exFAT volume */
2612 while (nc < fs->dirbuf[XDIR_NumName]) {
2615 wc = ld_word(fs->dirbuf + si); si += 2; nc++; /* Get a character */
2629 fno->fattrib = fs->dirbuf[XDIR_Attr] & AM_MASKX; /* Attribute */
2630 fno->fsize = (fno->fattrib & AM_DIR) ? 0 : ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */
2631 fno->ftime = ld_word(fs->dirbuf + XDIR_ModTime + 0); /* Time */
2632 fno->fdate = ld_word(fs->dirbuf + XDIR_ModTime + 2); /* Date */
2640 while (fs->lfnbuf[si] != 0) {
2641 wc = fs->lfnbuf[si++]; /* Get an LFN character (UTF-16) */
2815 p = *path; lfn = dp->obj.fs->lfnbuf; di = 0;
3010 FATFS *fs = dp->obj.fs; local
3015 dp->obj.sclust = fs->cdir; /* Start at the current directory */
3025 if (fs->fs_type == FS_EXFAT && dp->obj.sclust) { /* exFAT: Retrieve the sub-directory's status */
3028 dp->obj.c_scl = fs->cdc_scl;
3029 dp->obj.c_size = fs->cdc_size;
3030 dp->obj.c_ofs = fs->cdc_ofs;
3033 dp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize);
3034 dp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;
3067 if (fs->fs_type == FS_EXFAT) { /* Save containing directory information for next dir */
3071 init_alloc_info(fs, &dp->obj); /* Open next directory */
3075 dp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs)); /* Open next directory */
3239 FATFS* fs, /* Filesystem object */ argument
3247 fs->wflag = 0; fs->winsect = (LBA_t)0 - 1; /* Invaidate window */
3248 if (move_window(fs, sect) != FR_OK) return 4; /* Load the boot sector */
3249 sign = ld_word(fs->win + BS_55AA);
3251 …if (sign == 0xAA55 && !memcmp(fs->win + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11)) return 1; /* I…
3253 b = fs->win[BS_JmpBoot];
3255 if (sign == 0xAA55 && !memcmp(fs->win + BS_FilSysType32, "FAT32 ", 8)) {
3259 w = ld_word(fs->win + BPB_BytsPerSec);
3260 b = fs->win[BPB_SecPerClus];
3263 && ld_word(fs->win + BPB_RsvdSecCnt) != 0 /* Properness of reserved sectors (MNBZ) */
3264 && (UINT)fs->win[BPB_NumFATs] - 1 <= 1 /* Properness of FATs (1 or 2) */
3265 && ld_word(fs->win + BPB_RootEntCnt) != 0 /* Properness of root dir entries (MNBZ) */
3266 …&& (ld_word(fs->win + BPB_TotSec16) >= 128 || ld_dword(fs->win + BPB_TotSec32) >= 0x10000) /* Prop…
3267 && ld_word(fs->win + BPB_FATSz16) != 0) { /* Properness of FAT size (MNBZ) */
3279 FATFS* fs, /* Filesystem object */ argument
3287 fmt = check_fs(fs, 0); /* Load sector 0 and check if it is an FAT VBR as SFD format */
3293 if (fs->win[MBR_Table + PTE_System] == 0xEE) { /* GPT protective MBR? */
3297 if (move_window(fs, 1) != FR_OK) return 4; /* Load GPT header sector (next to MBR) */
3298 if (!test_gpt_header(fs->win)) return 3; /* Check if GPT header is valid */
3299 n_ent = ld_dword(fs->win + GPTH_PtNum); /* Number of entries */
3300 pt_lba = ld_qword(fs->win + GPTH_PtOfs); /* Table location */
3302 if (move_window(fs, pt_lba + i * SZ_GPTE / SS(fs)) != FR_OK) return 4; /* PT sector */
3303 ofs = i * SZ_GPTE % SS(fs); /* Offset in the sector */
3304 if (!memcmp(fs->win + ofs + GPTE_PtGuid, GUID_MS_Basic, 16)) { /* MS basic data partition? */
3306 fmt = check_fs(fs, ld_qword(fs->win + ofs + GPTE_FstLba)); /* Load VBR and check status */
3316 mbr_pt[i] = ld_dword(fs->win + MBR_Table + i * SZ_PTE + PTE_StLba);
3320 fmt = mbr_pt[i] ? check_fs(fs, mbr_pt[i]) : 3; /* Check if the partition is FAT */
3343 FATFS *fs; local
3353 fs = FatFs[vol]; /* Get pointer to the filesystem object */
3354 if (!fs) return FR_NOT_ENABLED; /* Is the filesystem object available? */
3356 if (!lock_fs(fs)) return FR_TIMEOUT; /* Lock the volume */
3358 *rfs = fs; /* Return pointer to the filesystem object */
3361 if (fs->fs_type != 0) { /* If the volume has been mounted */
3362 stat = disk_status(fs->pdrv);
3374 fs->fs_type = 0; /* Clear the filesystem object */
3375 fs->pdrv = LD2PD(vol); /* Volume hosting physical drive */
3376 stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
3384 if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR;
3385 if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR;
3389 fmt = find_volume(fs, LD2PT(vol));
3392 bsect = fs->winsect; /* Volume offset */
3401 for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */
3404 …if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must…
3406 …if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical…
3410 maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA of the volume + 1 */
3413 fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */
3415 fs->n_fats = fs->win[BPB_NumFATsEx]; /* Number of FATs */
3416 if (fs->n_fats != 1) return FR_NO_FILESYSTEM; /* (Supports only 1 FAT) */
3418 fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */
3419 if (fs->csize == 0) return FR_NO_FILESYSTEM; /* (Must be 1..32768 sectors) */
3421 nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */
3423 fs->n_fatent = nclst + 2;
3426 fs->volbase = bsect;
3427 fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx);
3428 fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx);
3429 …if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size mus…
3430 fs->dirbase = ld_dword(fs->win + BPB_RootClusEx);
3436 if (so >= fs->csize) return FR_NO_FILESYSTEM; /* Not found? */
3437 if (move_window(fs, clst2sect(fs, (DWORD)fs->dirbase) + so) != FR_OK) return FR_DISK_ERR;
3440 if (fs->win[i] == ET_BITMAP) break; /* Is it a bitmap entry? */
3441 i = (i + SZDIRE) % SS(fs); /* Next entry */
3443 bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */
3444 if (bcl < 2 || bcl >= fs->n_fatent) return FR_NO_FILESYSTEM; /* (Wrong cluster#) */
3445 fs->bitbase = fs->database + fs->csize * (bcl - 2); /* Bitmap sector */
3447 if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR;
3448 cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4);
3454 fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */
3460 …if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must …
3462 fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */
3463 if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32);
3464 fs->fsize = fasize;
3466 fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */
3467 if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
3468 fasize *= fs->n_fats; /* Number of sectors for FAT area */
3470 fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */
3471 …if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of…
3473 fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
3474 if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
3476 tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
3477 if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);
3479 nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
3483 sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */
3485 nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
3494 fs->n_fatent = nclst + 2; /* Number of FAT entries */
3495 fs->volbase = bsect; /* Volume start sector */
3496 fs->fatbase = bsect + nrsv; /* FAT start sector */
3497 fs->database = bsect + sysect; /* Data start sector */
3499 …if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) …
3500 if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
3501 fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */
3502 szbfat = fs->n_fatent * 4; /* (Needed FAT size) */
3504 if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
3505 fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
3507 fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
3509 …if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not …
3513 fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */
3514 fs->fsi_flag = 0x80;
3517 && ld_word(fs->win + BPB_FSInfo32) == 1
3518 && move_window(fs, bsect + 1) == FR_OK)
3520 fs->fsi_flag = 0;
3521 if (ld_word(fs->win + BS_55AA) == 0xAA55 /* Load FSInfo data if available */
3522 && ld_dword(fs->win + FSI_LeadSig) == 0x41615252
3523 && ld_dword(fs->win + FSI_StrucSig) == 0x61417272)
3526 fs->free_clst = ld_dword(fs->win + FSI_Free_Count);
3529 fs->last_clst = ld_dword(fs->win + FSI_Nxt_Free);
3537 fs->fs_type = (BYTE)fmt;/* FAT sub-type */
3538 fs->id = ++Fsid; /* Volume mount ID */
3540 fs->lfnbuf = LfnBuf; /* Static LFN working buffer */
3542 fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */
3546 fs->cdir = 0; /* Initialize current directory */
3549 clear_lock(fs);
3569 …if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid…
3571 if (lock_fs(obj->fs)) { /* Obtain the filesystem object */
3572 …if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized…
3575 unlock_fs(obj->fs, FR_OK);
3581 …if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized…
3586 *rfs = (res == FR_OK) ? obj->fs : 0; /* Corresponding filesystem object */
3606 FATFS* fs, /* Pointer to the filesystem object to be registered (NULL:unmount)*/ argument
3632 if (fs) {
3633 fs->fs_type = 0; /* Clear new fs object */
3635 if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
3638 FatFs[vol] = fs; /* Register new fs object */
3642 res = mount_volume(&path, &fs, 0); /* Force mounted the volume */
3643 LEAVE_FF(fs, res);
3661 FATFS *fs; local
3674 res = mount_volume(&path, &fs, mode);
3676 dj.obj.fs = fs;
3677 INIT_NAMBUF(fs);
3711 if (fs->fs_type == FS_EXFAT) {
3713 fp->obj.fs = fs;
3714 init_alloc_info(fs, &fp->obj);
3716 memset(fs->dirbuf + 2, 0, 30); /* Clear 85 entry except for NumSec */
3717 memset(fs->dirbuf + 38, 0, 26); /* Clear C0 entry except for NumName and NameHash */
3718 fs->dirbuf[XDIR_Attr] = AM_ARC;
3719 st_dword(fs->dirbuf + XDIR_CrtTime, GET_FATTIME());
3720 fs->dirbuf[XDIR_GenFlags] = 1;
3724 fs->last_clst = fp->obj.sclust - 1; /* Reuse the cluster hole */
3733 cl = ld_clust(fs, dj.dir); /* Get current cluster chain */
3735 st_clust(fs, dj.dir, 0); /* Reset file allocation info */
3737 fs->wflag = 1;
3739 sc = fs->winsect;
3742 res = move_window(fs, sc);
3743 fs->last_clst = cl - 1; /* Reuse the cluster hole */
3762 fp->dir_sect = fs->winsect; /* Pointer to the directory entry */
3783 if (fs->fs_type == FS_EXFAT) {
3787 init_alloc_info(fs, &fp->obj);
3791 fp->obj.sclust = ld_clust(fs, dj.dir); /* Get object allocation info */
3797 fp->obj.fs = fs; /* Validate the file object */
3798 fp->obj.id = fs->id;
3809 bcs = (DWORD)fs->csize * SS(fs); /* Cluster size in byte */
3817 if (res == FR_OK && ofs % SS(fs)) { /* Fill sector buffer if not on the sector boundary */
3818 sc = clst2sect(fs, clst);
3822 fp->sect = sc + (DWORD)(ofs / SS(fs));
3824 if (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR;
3838 if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */
3840 LEAVE_FF(fs, res);
3858 FATFS *fs; local
3867 res = validate(&fp->obj, &fs); /* Check validity of the file object */
3868 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
3869 if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
3874 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
3875 csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */
3889 if (clst < 2) ABORT(fs, FR_INT_ERR);
3890 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
3893 sect = clst2sect(fs, fp->clust); /* Get current sector */
3894 if (sect == 0) ABORT(fs, FR_INT_ERR);
3896 cc = btr / SS(fs); /* When remaining bytes >= sector size, */
3898 if (csect + cc > fs->csize) { /* Clip at cluster boundary */
3899 cc = fs->csize - csect;
3901 if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
3904 if (fs->wflag && fs->winsect - sect < cc) {
3905 memcpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs));
3909 memcpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs));
3913 rcnt = SS(fs) * cc; /* Number of bytes transferred */
3920 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
3924 …if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache …
3929 rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
3932 if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
3933 memcpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
3935 memcpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
3939 LEAVE_FF(fs, FR_OK);
3958 FATFS *fs; local
3966 res = validate(&fp->obj, &fs); /* Check validity of the file object */
3967 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
3968 if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
3971 if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
3976 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
3977 csect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1); /* Sector offset in the cluster */
3995 if (clst == 1) ABORT(fs, FR_INT_ERR);
3996 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4001 …if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sec…
4004 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4008 sect = clst2sect(fs, fp->clust); /* Get current sector */
4009 if (sect == 0) ABORT(fs, FR_INT_ERR);
4011 cc = btw / SS(fs); /* When remaining bytes >= sector size, */
4013 if (csect + cc > fs->csize) { /* Clip at cluster boundary */
4014 cc = fs->csize - csect;
4016 if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
4019 …if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
4020 memcpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs));
4021 fs->wflag = 0;
4025 memcpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs));
4030 wcnt = SS(fs) * cc; /* Number of bytes transferred */
4035 if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR);
4036 fs->winsect = sect;
4041 disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
4042 ABORT(fs, FR_DISK_ERR);
4047 wcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
4050 if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
4051 memcpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */
4052 fs->wflag = 1;
4054 memcpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */
4061 LEAVE_FF(fs, FR_OK);
4076 FATFS *fs; local
4081 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4086 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);
4093 if (fs->fs_type == FS_EXFAT) {
4102 INIT_NAMBUF(fs);
4105fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been ch…
4106 fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1; /* Update file allocation information */
4107 st_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust); /* Update start cluster */
4108 st_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize); /* Update file size */
4109 …st_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize); /* (FatFs does not support Valid File …
4110 st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Update modified time */
4111 fs->dirbuf[XDIR_ModTime10] = 0;
4112 st_dword(fs->dirbuf + XDIR_AccTime, 0);
4115 res = sync_fs(fs);
4124 res = move_window(fs, fp->dir_sect);
4128 st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation information */
4132 fs->wflag = 1;
4133 res = sync_fs(fs); /* Restore it to the directory */
4140 LEAVE_FF(fs, res);
4157 FATFS *fs; local
4164 res = validate(&fp->obj, &fs); /* Lock volume */
4168 if (res == FR_OK) fp->obj.fs = 0; /* Invalidate file object */
4170 fp->obj.fs = 0; /* Invalidate file object */
4173 unlock_fs(fs, FR_OK); /* Unlock volume */
4214 FATFS *fs; local
4219 res = mount_volume(&path, &fs, 0);
4221 dj.obj.fs = fs;
4222 INIT_NAMBUF(fs);
4226 fs->cdir = dj.obj.sclust;
4228 if (fs->fs_type == FS_EXFAT) {
4229 fs->cdc_scl = dj.obj.c_scl;
4230 fs->cdc_size = dj.obj.c_size;
4231 fs->cdc_ofs = dj.obj.c_ofs;
4237 if (fs->fs_type == FS_EXFAT) {
4238 fs->cdir = ld_dword(fs->dirbuf + XDIR_FstClus); /* Sub-directory cluster */
4239 fs->cdc_scl = dj.obj.sclust; /* Save containing directory information */
4240 fs->cdc_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat;
4241 fs->cdc_ofs = dj.blk_ofs;
4245 fs->cdir = ld_clust(fs, dj.dir); /* Sub-directory cluster */
4256 for (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ; /* Set current drive */
4262 LEAVE_FF(fs, res);
4274 FATFS *fs; local
4290 res = mount_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */
4292 dj.obj.fs = fs;
4293 INIT_NAMBUF(fs);
4297 …if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* (Cannot do getcwd on exFAT and returns root path…
4298 dj.obj.sclust = fs->cdir; /* Start to follow upper directory from current directory */
4302 res = move_window(fs, dj.sect);
4304 dj.obj.sclust = ld_clust(fs, dj.dir); /* Goto parent directory */
4310 if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */
4354 LEAVE_FF(fs, res);
4373 FATFS *fs; local
4383 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4386 if (res == FR_OK && fs->fs_type == FS_EXFAT) {
4390 if (res != FR_OK) LEAVE_FF(fs, res);
4405 if (cl <= 1) ABORT(fs, FR_INT_ERR);
4406 if (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4411 } while (cl < fs->n_fatent); /* Repeat until end of chain */
4424 dsc = clst2sect(fs, fp->clust);
4425 if (dsc == 0) ABORT(fs, FR_INT_ERR);
4426 dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1);
4427 if (fp->fptr % SS(fs) && dsc != fp->sect) { /* Refill sector cache if needed */
4431 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4435 …if (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector…
4447 …if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4 GiB - 1 if at FA…
4455 bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */
4466 if (clst == 1) ABORT(fs, FR_INT_ERR);
4467 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4491 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4492 if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR);
4496 if (ofs % SS(fs)) {
4497 nsect = clst2sect(fs, clst); /* Current sector */
4498 if (nsect == 0) ABORT(fs, FR_INT_ERR);
4499 nsect += (DWORD)(ofs / SS(fs));
4507 if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */
4511 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4515 …if (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache…
4521 LEAVE_FF(fs, res);
4537 FATFS *fs; local
4544 res = mount_volume(&path, &fs, 0);
4546 dp->obj.fs = fs;
4547 INIT_NAMBUF(fs);
4553 if (fs->fs_type == FS_EXFAT) {
4557 init_alloc_info(fs, &dp->obj); /* Get object allocation info */
4561 dp->obj.sclust = ld_clust(fs, dp->dir); /* Get object allocation info */
4568 dp->obj.id = fs->id;
4585 if (res != FR_OK) dp->obj.fs = 0; /* Invalidate the directory object if function faild */
4587 LEAVE_FF(fs, res);
4602 FATFS *fs; local
4605 res = validate(&dp->obj, &fs); /* Check validity of the file object */
4609 if (res == FR_OK) dp->obj.fs = 0; /* Invalidate directory object */
4611 dp->obj.fs = 0; /* Invalidate directory object */
4614 unlock_fs(fs, FR_OK); /* Unlock volume */
4633 FATFS *fs; local
4637 res = validate(&dp->obj, &fs); /* Check validity of the directory object */
4642 INIT_NAMBUF(fs);
4653 LEAVE_FF(fs, res);
4726 res = mount_volume(&path, &dj.obj.fs, 0);
4728 INIT_NAMBUF(dj.obj.fs);
4740 LEAVE_FF(dj.obj.fs, res);
4757 FATFS *fs; local
4765 res = mount_volume(&path, &fs, 0);
4767 *fatfs = fs; /* Return ptr to the fs object */
4769 if (fs->free_clst <= fs->n_fatent - 2) {
4770 *nclst = fs->free_clst;
4774 if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */
4775 clst = 2; obj.fs = fs;
4781 } while (++clst < fs->n_fatent);
4784 if (fs->fs_type == FS_EXFAT) { /* exFAT: Scan allocation bitmap */
4788 clst = fs->n_fatent - 2; /* Number of clusters */
4789 sect = fs->bitbase; /* Bitmap sector */
4793 res = move_window(fs, sect++);
4796 for (b = 8, bm = fs->win[i]; b && clst; b--, clst--) {
4800 i = (i + 1) % SS(fs);
4805 clst = fs->n_fatent; /* Number of entries */
4806 sect = fs->fatbase; /* Top of the FAT */
4810 res = move_window(fs, sect++);
4813 if (fs->fs_type == FS_FAT16) {
4814 if (ld_word(fs->win + i) == 0) nfree++;
4817 if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++;
4820 i %= SS(fs);
4826 fs->free_clst = nfree; /* Now free_clst is valid */
4827 fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */
4832 LEAVE_FF(fs, res);
4847 FATFS *fs; local
4851 res = validate(&fp->obj, &fs); /* Check validity of the file object */
4852 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
4853 if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
4864 if (res == FR_OK && ncl < fs->n_fatent) {
4872 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {
4879 if (res != FR_OK) ABORT(fs, res);
4882 LEAVE_FF(fs, res);
4899 FATFS *fs; local
4907 res = mount_volume(&path, &fs, FA_WRITE);
4909 dj.obj.fs = fs;
4910 INIT_NAMBUF(fs);
4928 obj.fs = fs;
4929 if (fs->fs_type == FS_EXFAT) {
4930 init_alloc_info(fs, &obj);
4935 dclst = ld_clust(fs, dj.dir);
4939 if (dclst == fs->cdir) { /* Is it the current directory? */
4944 sdj.obj.fs = fs; /* Open the sub-directory */
4947 if (fs->fs_type == FS_EXFAT) {
4970 if (res == FR_OK) res = sync_fs(fs);
4976 LEAVE_FF(fs, res);
4993 FATFS *fs; local
4998 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
5000 dj.obj.fs = fs;
5001 INIT_NAMBUF(fs);
5008 sobj.fs = fs; /* New object id to create a new chain */
5016 res = dir_clear(fs, dcl); /* Clean up the new table */
5018 if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* Create dot entries (FAT only) */
5019 memset(fs->win + DIR_Name, ' ', 11); /* Create "." entry */
5020 fs->win[DIR_Name] = '.';
5021 fs->win[DIR_Attr] = AM_DIR;
5022 st_dword(fs->win + DIR_ModTime, tm);
5023 st_clust(fs, fs->win, dcl);
5024 memcpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create ".." entry */
5025 fs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust;
5026 st_clust(fs, fs->win + SZDIRE, pcl);
5027 fs->wflag = 1;
5034 if (fs->fs_type == FS_EXFAT) { /* Initialize directory entry block */
5035 st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Created time */
5036 st_dword(fs->dirbuf + XDIR_FstClus, dcl); /* Table start cluster */
5037 …st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)fs->csize * SS(fs)); /* Directory size needs to be val…
5038 st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)fs->csize * SS(fs));
5039 fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag */
5040 fs->dirbuf[XDIR_Attr] = AM_DIR; /* Attribute */
5046 st_clust(fs, dj.dir, dcl); /* Table start cluster */
5048 fs->wflag = 1;
5051 res = sync_fs(fs);
5060 LEAVE_FF(fs, res);
5077 FATFS *fs; local
5084 res = mount_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */
5086 djo.obj.fs = fs;
5087 INIT_NAMBUF(fs);
5097 if (fs->fs_type == FS_EXFAT) { /* At exFAT volume */
5101 memcpy(buf, fs->dirbuf, SZDIRE * 2); /* Save 85+C0 entry of old object */
5110 nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName];
5111 nh = ld_word(fs->dirbuf + XDIR_NameHash);
5112 memcpy(fs->dirbuf, buf, SZDIRE * 2); /* Restore 85+C0 entry */
5113 fs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn;
5114 st_word(fs->dirbuf + XDIR_NameHash, nh);
5115 …if (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute i…
5136 fs->wflag = 1;
5138 sect = clst2sect(fs, ld_clust(fs, dir));
5143 res = move_window(fs, sect);
5144 dir = fs->win + SZDIRE * 1; /* Ptr to .. entry */
5146 st_clust(fs, dir, djn.obj.sclust);
5147 fs->wflag = 1;
5157 res = sync_fs(fs);
5165 LEAVE_FF(fs, res);
5188 FATFS *fs; local
5192 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
5194 dj.obj.fs = fs;
5195 INIT_NAMBUF(fs);
5201 if (fs->fs_type == FS_EXFAT) {
5202fs->dirbuf[XDIR_Attr] = (attr & mask) | (fs->dirbuf[XDIR_Attr] & (BYTE)~mask); /* Apply attribute …
5208 fs->wflag = 1;
5211 res = sync_fs(fs);
5217 LEAVE_FF(fs, res);
5234 FATFS *fs; local
5238 res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */
5240 dj.obj.fs = fs;
5241 INIT_NAMBUF(fs);
5246 if (fs->fs_type == FS_EXFAT) {
5247 st_dword(fs->dirbuf + XDIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime);
5253 fs->wflag = 1;
5256 res = sync_fs(fs);
5262 LEAVE_FF(fs, res);
5282 FATFS *fs; local
5287 res = mount_volume(&path, &fs, 0);
5291 dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */
5297 if (fs->fs_type == FS_EXFAT) {
5343 res = move_window(fs, fs->volbase);
5345 switch (fs->fs_type) {
5357 *vsn = ld_dword(fs->win + di);
5361 LEAVE_FF(fs, res);
5377 FATFS *fs; local
5387 res = mount_volume(&label, &fs, FA_WRITE);
5388 if (res != FR_OK) LEAVE_FF(fs, res);
5391 if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
5404 LEAVE_FF(fs, FR_INVALID_NAME);
5428 LEAVE_FF(fs, FR_INVALID_NAME);
5433 if (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */
5438 dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */
5443 if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {
5453 fs->wflag = 1;
5454 res = sync_fs(fs);
5462 if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {
5470 fs->wflag = 1;
5471 res = sync_fs(fs);
5478 LEAVE_FF(fs, res);
5498 FATFS *fs; local
5502 res = validate(&fp->obj, &fs); /* Check validity of the file object */
5503 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
5504 if (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);
5506 …if (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED); /* Check if in size li…
5508 n = (DWORD)fs->csize * SS(fs); /* Cluster size */
5510 stcl = fs->last_clst; lclst = 0;
5511 if (stcl < 2 || stcl >= fs->n_fatent) stcl = 2;
5514 if (fs->fs_type == FS_EXFAT) {
5515 scl = find_bitmap(fs, stcl, tcl); /* Find a contiguous cluster block */
5520 res = change_bitmap(fs, scl, tcl, 1); /* Mark the cluster block 'in use' */
5532 if (++clst >= fs->n_fatent) clst = 2;
5545 res = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1);
5556 fs->last_clst = lclst; /* Set suggested start cluster to start next */
5562 if (fs->free_clst <= fs->n_fatent - 2) { /* Update FSINFO */
5563 fs->free_clst -= tcl;
5564 fs->fsi_flag |= 1;
5569 LEAVE_FF(fs, res);
5589 FATFS *fs; local
5598 res = validate(&fp->obj, &fs); /* Check validity of the file object */
5599 if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
5600 if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
5606 csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */
5607 if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
5611 if (clst <= 1) ABORT(fs, FR_INT_ERR);
5612 if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
5616 sect = clst2sect(fs, fp->clust); /* Get current data sector */
5617 if (sect == 0) ABORT(fs, FR_INT_ERR);
5620 …if (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window to the file data…
5621 dbuf = fs->win;
5626 if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
5630 if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
5635 rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
5637 rcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt); /* Forward the file data */
5638 if (rcnt == 0) ABORT(fs, FR_INT_ERR);
5641 LEAVE_FF(fs, FR_OK);