📄 root.c
字号:
PreviousCluster = startCluster;
startCluster = read_Fat(drive, partnum, PreviousCluster);
ClusterOffs--;
}
if (ClusterOffs)
{
if (rw == READ)
return 0;
if (rw == WRITE)
while (ClusterOffs)
{
PreviousCluster = appendFatEntry(drive, partnum, PreviousCluster);
if (!PreviousCluster)
return 0;
ClusterOffs--;
}
}
j = ClusterCnt;
while (j)
{
if (PreviousCluster)
startCluster = read_Fat(drive, partnum, PreviousCluster);
if (startCluster >= LAST_CLUSTER_CODE)
{
if (rw == WRITE)
{
startCluster = appendFatEntry(drive, partnum, PreviousCluster);
if (!startCluster)
break;
}
if (rw == READ)
break;
}
SectorNumber = (startCluster - 2) * b_sect->sectPerCluster +
b_sect->DataStart;
PreviousCluster = startCluster;
r_w_Disk(drive, SectorNumber, b_sect->sectPerCluster,
(unsigned short *)xbuf, rw);
xbuf += b_sect->sectPerCluster * b_sect->bytesPerSector;
j--;
}
return ClusterCnt - j;
}
else
{
// fprintf(stderr, "This File system is not supported\n");
return -1;
}
}
#else
/**********************************************************/
/* returns count of true read/written Cluster */
/**********************************************************/
int r_w_Cluster(unsigned int idx, void *buf,
unsigned int ClusterCnt, unsigned int ClusterOffs, int rw)
{
struct msdos_b_sect *b_sect;
unsigned int FatMode, i;
unsigned int drive, partnum, startCluster, OldClusterOffset;
drive = _handle[idx].drive;
partnum = _handle[idx].partnum;
startCluster = _handle[idx].clusterStart;
OldClusterOffset = ClusterOffs;
b_sect = _hd_ident[drive].bootptr[partnum];
FatMode = b_sect->FatSystem;
if ((FatMode == 12) || (FatMode == 16))
{
unsigned int SectorNumber, j, PreviousCluster;
char *xbuf = (char *)buf;
if ((ClusterCnt == 0) || (!ClusterOk(drive, partnum, startCluster)))
return 0;
PreviousCluster = 0;
#ifdef FAT_OPT
if (ClusterOffs >= _handle[idx].LastClusterOffset)
{
ClusterOffs -= _handle[idx].LastClusterOffset;
startCluster = _handle[idx].LastClusterStart;
PreviousCluster = _handle[idx].LastPreviousCluster;
}
#endif
while ((startCluster < LAST_CLUSTER_CODE) && ClusterOffs)
{
// if (!ClusterOk(drive, partnum, startCluster))
// return 0;
PreviousCluster = startCluster;
startCluster = read_Fat(drive, partnum, PreviousCluster);
ClusterOffs--;
}
if (ClusterOffs)
{
if (rw == READ)
return 0;
if (rw == WRITE)
while (ClusterOffs)
{
PreviousCluster = appendFatEntry(drive, partnum, PreviousCluster);
if (!PreviousCluster)
return 0;
ClusterOffs--;
}
}
j = ClusterCnt;
while (j)
{
if (PreviousCluster)
startCluster = read_Fat(drive, partnum, PreviousCluster);
if (startCluster >= LAST_CLUSTER_CODE)
{
if (rw == WRITE)
{
startCluster = appendFatEntry(drive, partnum, PreviousCluster);
if (!startCluster)
break;
}
if (rw == READ)
break;
}
#ifdef FAT_OPT
_handle[idx].LastClusterOffset = OldClusterOffset;
_handle[idx].LastClusterStart = startCluster;
_handle[idx].LastPreviousCluster = PreviousCluster;
#endif
SectorNumber = (startCluster - 2) * b_sect->sectPerCluster +
b_sect->DataStart;
PreviousCluster = startCluster;
r_w_Disk(drive, SectorNumber, b_sect->sectPerCluster,
(unsigned short *)xbuf, rw);
xbuf += b_sect->sectPerCluster * b_sect->bytesPerSector;
j--;
#ifdef FAT_OPT
OldClusterOffset++;
#endif
}
return ClusterCnt - j;
}
else
{
// fprintf(stderr, "This File system is not supported\n");
return -1;
}
}
#endif
/*
FINDFILE: Searches for the file in the root directory.
in
func: 0 (file exist ?)
1 (delete file)
2 (return direntry structure)
3 (generate dir entry)
FILEXIST 0
DELETEFILE 1
DIRENTRYSTRUCT 2
GENERDIRENTRY 3
Returns:
If file not found: 0
If file found: first cluster of the file
*/
int FINDFILE(int drive, int partnum, const char *filename, struct directory *direntry, int func) {
/*
First, read the whole root directory
into the temporary buffer.
*/
struct msdos_b_sect *b_sect;
char *tempbuf;
char fn[12];
unsigned long _cur_root_dir_start;
int retvalue = 0;
expand_fn8_3(fn, filename);
b_sect = _hd_ident[drive].bootptr[partnum];
tempbuf = alloca(b_sect->bytesPerSector * b_sect->nDir);
_cur_root_dir_start = b_sect->nHidden + b_sect->resSectors + b_sect->nFats * b_sect->sectPerFat;
if ( r_w_Disk(drive, _cur_root_dir_start, b_sect->nDir, (unsigned short *) tempbuf, READ))
return 0;
else
{
int found = 0;
struct directory *tmp, *DeletedEntry;
tmp = (struct directory*) tempbuf;
DeletedEntry = NULL;
while (tmp->name[0] && // modified bug 15/DEC/2000 for soul file
(char *)tmp<(tempbuf+b_sect->bytesPerSector * b_sect->nDir))
{
if (tmp->name[0] == DELMARK)
DeletedEntry = tmp;
else
if (!memicmp(fn, tmp->name, 11))
{
found = 1;
break;
}
tmp++;
}
// should handle the case where all entries are used but
// some deleted entries exist - yet missing
if ((char *)tmp == (tempbuf+b_sect->bytesPerSector * b_sect->nDir))
return 0;
if (found)
{
/* func = DELETEFILE : delete file */
/* func = GENERDIRENTRY: truncate file */
if ((func == DELETEFILE) || (func == GENERDIRENTRY))
{
int sect_offs;
sect_offs = (char *) tmp - (char *) tempbuf;
tempbuf = (char *) tempbuf + (sect_offs & ~(SECTOR_SIZE-1));
sect_offs = sect_offs / SECTOR_SIZE;
if (func == DELETEFILE)
tmp->name[0] = DELMARK;
else
{
if (tmp->attr & FA_RDONLY)
goto done;
else
*tmp = *direntry;
}
retvalue = CvtByteOrder16(tmp->start);
r_w_Disk(drive, _cur_root_dir_start + sect_offs, 1, (unsigned short *) tempbuf, WRITE);
}
else
{
if (func == DIRENTRYSTRUCT /* return direntry structure */)
memcpy((char *)direntry, (char *)tmp->name, 32);
else
return retvalue;
}
retvalue = CvtByteOrder16(tmp->start);
}
else
if (func == GENERDIRENTRY)
{
int sect_offs, fcluster;
if (DeletedEntry)
tmp = DeletedEntry;
sect_offs = (char *) tmp - (char *) tempbuf;
tempbuf = (char *) tempbuf + (sect_offs & ~(SECTOR_SIZE-1));
sect_offs = sect_offs / SECTOR_SIZE;
fcluster = find_free_FatEntry(drive, partnum);
if (fcluster)
{
direntry->start = fcluster;
memcpy(direntry->name, fn, 11);
memcpy((char *)tmp->name, (char *)direntry, sizeof(*direntry));
insert_FatEntry(drive, partnum, 0, fcluster);
r_w_Disk (drive, _cur_root_dir_start + sect_offs, 1,
(unsigned short *) tempbuf, WRITE);
}
retvalue = fcluster;
}
}
done:
return retvalue;
}
/* Help Function */
/* Root Entry Size in bytes */
int _ROOTEntrySize(int drive, int partnum) {
struct msdos_b_sect *b_sect;
b_sect = _hd_ident[drive].bootptr[partnum];
return b_sect->bytesPerSector * b_sect->nDir;
}
int _readROOTEntry(int drive, int partnum, struct directory * dir) {
struct msdos_b_sect *b_sect;
unsigned long _cur_root_dir_start;
b_sect = _hd_ident[drive].bootptr[partnum];
_cur_root_dir_start = b_sect->nHidden + b_sect->resSectors + b_sect->nFats * b_sect->sectPerFat;
r_w_Disk(drive, _cur_root_dir_start, b_sect->nDir, (unsigned short *) dir, READ);
return 0;
}
unsigned long _getserialnum(int drive, int partnum) {
struct msdos_b_sect *b_sect;
b_sect = _hd_ident[drive].bootptr[partnum];
return b_sect->volid;
}
unsigned long _alignClusterSize(unsigned long num, int drive, int partnum) {
struct msdos_b_sect *b_sect;
unsigned long sPc, countcl, rest;
b_sect = _hd_ident[drive].bootptr[partnum];
sPc = b_sect->sectPerCluster * b_sect->bytesPerSector;
countcl = num / sPc;
rest = num % sPc;
if (rest)
return (sPc * (countcl + 1));
else
return num;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -