📄 ff.lst
字号:
456 DWORD clst /* Cluster# to stretch. 0 means create a new chain. */
457 )
458 {
459 1 DWORD cs, ncl, scl, mcl;
460 1
461 1
462 1 mcl = fs->max_clust;
463 1 if (clst == 0) { /* Create new chain */
464 2 scl = fs->last_clust; /* Get suggested start point */
465 2 if (scl == 0 || scl >= mcl) scl = 1;
466 2 }
467 1 else { /* Stretch existing chain */
468 2 cs = get_fat(fs, clst); /* Check the cluster status */
469 2 if (cs < 2) return 1; /* It is an invalid cluster */
470 2 if (cs < mcl) return cs; /* It is already followed by next cluster */
471 2 scl = clst;
472 2 }
473 1
474 1 ncl = scl; /* Start cluster */
475 1 for (;;) {
476 2 ncl++; /* Next cluster */
477 2 if (ncl >= mcl) { /* Wrap around */
478 3 ncl = 2;
479 3 if (ncl > scl) return 0; /* No free custer */
480 3 }
481 2 cs = get_fat(fs, ncl); /* Get the cluster status */
482 2 if (cs == 0) break; /* Found a free cluster */
483 2 if (cs == 0xFFFFFFFF || cs == 1)/* An error occured */
484 2 return cs;
485 2 if (ncl == scl) return 0; /* No free custer */
486 2 }
487 1
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 9
488 1 if (put_fat(fs, ncl, 0x0FFFFFFF)) /* Mark the new cluster "in use" */
489 1 return 0xFFFFFFFF;
490 1 if (clst != 0) { /* Link it to the previous one if needed */
491 2 if (put_fat(fs, clst, ncl))
492 2 return 0xFFFFFFFF;
493 2 }
494 1
495 1 fs->last_clust = ncl; /* Update FSINFO */
496 1 if (fs->free_clust != 0xFFFFFFFF) {
497 2 fs->free_clust--;
498 2 fs->fsi_flag = 1;
499 2 }
500 1
501 1 return ncl; /* Return new cluster number */
502 1 }
503 #endif /* !_FS_READONLY */
504
505
506
507
508 /*-----------------------------------------------------------------------*/
509 /* Get sector# from cluster# */
510 /*-----------------------------------------------------------------------*/
511
512 static
513 DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
514 FATFS *fs, /* File system object */
515 DWORD clst /* Cluster# to be converted */
516 )
517 {
518 1 clst -= 2;
519 1 if (clst >= (fs->max_clust - 2)) return 0; /* Invalid cluster# */
520 1 return clst * fs->csize + fs->database;
521 1 }
522
523
524
525
526 /*-----------------------------------------------------------------------*/
527 /* Directory handling - Seek directory index */
528 /*-----------------------------------------------------------------------*/
529
530 static
531 FRESULT dir_seek (
532 DIR *dj, /* Pointer to directory object */
533 WORD idx /* Directory index number */
534 )
535 {
536 1 DWORD clst;
537 1 WORD ic;
538 1
539 1
540 1 dj->index = idx;
541 1 clst = dj->sclust;
542 1 if (clst == 1 || clst >= dj->fs->max_clust) /* Check start cluster range */
543 1 return FR_INT_ERR;
544 1 if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */
545 1 clst = dj->fs->dirbase;
546 1
547 1 if (clst == 0) { /* Static table */
548 2 dj->clust = clst;
549 2 if (idx >= dj->fs->n_rootdir) /* Index is out of range */
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 10
550 2 return FR_INT_ERR;
551 2 dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32); /* Sector# */
552 2 }
553 1 else { /* Dynamic table */
554 2 ic = SS(dj->fs) / 32 * dj->fs->csize; /* Entries per cluster */
555 2 while (idx >= ic) { /* Follow cluster chain */
556 3 clst = get_fat(dj->fs, clst); /* Get next cluster */
557 3 if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */
558 3 if (clst < 2 || clst >= dj->fs->max_clust) /* Reached to end of table or int error */
559 3 return FR_INT_ERR;
560 3 idx -= ic;
561 3 }
562 2 dj->clust = clst;
563 2 dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32); /* Sector# */
564 2 }
565 1
566 1 dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32; /* Ptr to the entry in the sector */
567 1
568 1 return FR_OK; /* Seek succeeded */
569 1 }
570
571
572
573
574 /*-----------------------------------------------------------------------*/
575 /* Directory handling - Move directory index next */
576 /*-----------------------------------------------------------------------*/
577
578 static
579 FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not streach */
580 DIR *dj, /* Pointer to directory object */
581 BOOL streach /* FALSE: Do not streach table, TRUE: Streach table if needed */
582 )
583 {
584 1 DWORD clst;
585 1 WORD i;
586 1
587 1
588 1 i = dj->index + 1;
589 1 if (!i || !dj->sect) /* Report EOT when index has reached 65535 */
590 1 return FR_NO_FILE;
591 1
592 1 if (!(i % (SS(dj->fs) / 32))) { /* Sector changed? */
593 2 dj->sect++; /* Next sector */
594 2
595 2 if (dj->clust == 0) { /* Static table */
596 3 if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */
597 3 return FR_NO_FILE;
598 3 }
599 2 else { /* Dynamic table */
600 3 if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */
601 4 clst = get_fat(dj->fs, dj->clust); /* Get next cluster */
602 4 if (clst <= 1) return FR_INT_ERR;
603 4 if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
604 4 if (clst >= dj->fs->max_clust) { /* When it reached end of dynamic table */
605 5 #if !_FS_READONLY
606 5 BYTE c;
607 5 if (!streach) return FR_NO_FILE; /* When do not streach, report EOT */
608 5 clst = create_chain(dj->fs, dj->clust); /* Streach cluster chain */
609 5 if (clst == 0) return FR_DENIED; /* No free cluster */
610 5 if (clst == 1) return FR_INT_ERR;
611 5 if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 11
612 5 /* Clean-up streached table */
613 5 if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */
614 5 mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */
615 5 dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */
616 5 for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */
617 6 dj->fs->wflag = 1;
618 6 if (move_window(dj->fs, 0)) return FR_DISK_ERR;
619 6 dj->fs->winsect++;
620 6 }
621 5 dj->fs->winsect -= c; /* Rewind window address */
622 5 #else
return FR_NO_FILE; /* Report EOT */
#endif
625 5 }
626 4 dj->clust = clst; /* Initialize data for new cluster */
627 4 dj->sect = clust2sect(dj->fs, clst);
628 4 }
629 3 }
630 2 }
631 1
632 1 dj->index = i;
633 1 dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32;
634 1
635 1 return FR_OK;
636 1 }
637
638
639
640
641 /*-----------------------------------------------------------------------*/
642 /* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */
643 /*-----------------------------------------------------------------------*/
644 #if _USE_LFN
static
const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry *
-/
static
BOOL cmp_lfn ( /* TRUE:Matched, FALSE:Not matched */
WCHAR *lfnbuf, /* Pointer to the LFN to be compared */
BYTE *dir /* Pointer to the directory entry containing a part of LFN */
)
{
int i, s;
WCHAR wc;
i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */
s = 0;
do {
wc = ff_wtoupper(LD_WORD(dir+LfnOfs[s])); /* Get an LFN character */
if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it with the reference character */
return FALSE;
} while (++s < 13 && wc); /* Repeat until all chars in the entry or a NUL char is processed */
return TRUE; /* The LFN entry matched */
}
static
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 12
BOOL pick_lfn ( /* TRUE:Succeeded, FALSE:Buffer overflow */
WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */
BYTE *dir /* Pointer to the directory entry */
)
{
int i, s;
WCHAR wc;
i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */
s = 0;
do {
if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -