📄 fat_out.c
字号:
}
todo = N * Size; /* Number of bytes to be written */
if (!todo) {
FS__fat_free(buffer);
return 0;
}
/* Alloc new clusters if required */
bytesperclus = (FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus *
((FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].BytesPerSec);
/* Calculate number of clusters required */
i = (pFile->filepos + todo) / bytesperclus;
if ((pFile->filepos + todo) % bytesperclus) {
i++;
}
/* Calculate clusters already allocated */
j = pFile->size / bytesperclus;
lexp = (pFile->size % bytesperclus);
lexp = lexp || (pFile->size == 0);
if (lexp) {
j++;
}
i -= j;
if (i > 0) {
/* Alloc new clusters */
last = pFile->EOFClust;
if (last < 0) {
/* Position of EOF is unknown, so we scan the whole file to find it */
last = FS__fat_FAT_find_eof(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, 0);
}
if (last < 0) {
/* No EOF found */
FS__fat_free(buffer);
return 0;
}
while (i) {
last = FS__fat_FAT_alloc(pFile->dev_index, pFile->fileid_lo, last); /* Allocate new cluster */
pFile->EOFClust = last;
if (last < 0) {
/* Cluster allocation failed */
pFile->size += (N * Size - todo);
pFile->error = FS_ERR_DISKFULL;
FS__fat_free(buffer);
return ((N * Size - todo) / Size);
}
i--;
}
}
/* Get absolute postion of data area on the media */
dstart = (FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RsvdSecCnt +
FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].NumFATs * fatsize;
dsize = ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RootEntCnt) * FS_FAT_DENTRY_SIZE) / FS_FAT_SEC_SIZE;
datastart = dstart + dsize;
/* Write data to clusters */
prevclust = 0;
while (todo) { /* Write data loop */
/* Translate file ppinter position to cluster position*/
fileclustnum = pFile->filepos / bytesperclus;
/*
Translate the file relative cluster position to an absolute cluster
position on the media. To avoid scanning the whole FAT of the file,
we remember the current cluster position in the FS_FILE data structure.
*/
if (prevclust == 0) {
diskclustnum = pFile->CurClust;
if (diskclustnum == 0) {
/* No known current cluster position, we have to scan from the file's start cluster */
diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, fileclustnum);
}
}
else {
/* Get next cluster of the file starting at the current cluster */
diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1);
}
prevclust = diskclustnum;
pFile->CurClust = diskclustnum;
if (diskclustnum == 0) {
/* Translation to absolute cluster failed */
pFile->error = FS_ERR_WRITEERROR;
FS__fat_free(buffer);
return ((N * Size - todo) / Size);
}
diskclustnum -= 2;
j = (pFile->filepos % bytesperclus) / FS_FAT_SEC_SIZE;
while (1) { /* Cluster loop */
if (!todo) {
break; /* Nothing more to write */
}
if (j >= FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) {
break; /* End of cluster reached */
}
i = pFile->filepos % FS_FAT_SEC_SIZE;
/*
We only have to read the sector from the media, if we do not
modify the whole sector. That is the case if
a) Writing starts not at the first byte of the sector
b) Less data than the sector contains is written
*/
lexp = (i != 0);
lexp = lexp || (todo < FS_FAT_SEC_SIZE);
if (lexp) {
/* We have to read the old sector */
err = FS__lb_read(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo,
datastart +
diskclustnum * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus + j,
(void*)buffer);
if (err < 0) {
pFile->error = FS_ERR_WRITEERROR;
FS__fat_free(buffer);
return ((N * Size - todo) / Size);
}
}
while (1) { /* Sector loop */
if (!todo) {
break; /* Nothing more to write */
}
if (i >= FS_FAT_SEC_SIZE) {
break; /* End of sector reached */
}
buffer[i] = *((FS_FARCHARPTR)(((FS_FARCHARPTR)pData) + N * Size - todo));
i++;
pFile->filepos++;
if (pFile->filepos > pFile->size) {
pFile->size = pFile->filepos;
}
todo--;
} /* Sector loop */
/* Write the modified sector */
err = FS__lb_write(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo,
datastart +
diskclustnum * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus + j,
(void*)buffer);
if (err < 0) {
pFile->error = FS_ERR_WRITEERROR;
FS__fat_free(buffer);
return ((N * Size - todo) / Size);
}
j++;
} /* Cluster loop */
} /* Write data loop */
if (i >= FS_FAT_SEC_SIZE) {
if (j >= FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) {
/* File pointer is already in the next cluster */
pFile->CurClust = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1);
}
}
#if (FS_FAT_FWRITE_UPDATE_DIR)
/* Modify directory entry */
err = _FS_fat_read_dentry(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, pFile->fileid_ex, &s, &dsec, buffer);
if (err == 0) {
pFile->error = FS_ERR_WRITEERROR;
FS__fat_free(buffer);
return ((N * Size - todo) / Size);
}
s.data[28] = (unsigned char)(pFile->size & 0xff); /* FileSize */
s.data[29] = (unsigned char)((pFile->size / 0x100UL) & 0xff);
s.data[30] = (unsigned char)((pFile->size / 0x10000UL) & 0xff);
s.data[31] = (unsigned char)((pFile->size / 0x1000000UL) & 0xff);
val = FS_X_OS_GetTime();
s.data[22] = (unsigned char)(val & 0xff);
s.data[23] = (unsigned char)((val / 0x100) & 0xff);
val = FS_X_OS_GetDate();
s.data[24] = (unsigned char)(val & 0xff);
s.data[25] = (unsigned char)((val / 0x100) & 0xff);
err = _FS_fat_write_dentry(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, &s, dsec, buffer);
if (err == 0) {
pFile->error = FS_ERR_WRITEERROR;
}
#endif /* FS_FAT_FWRITE_UPDATE_DIR */
FS__fat_free(buffer);
return ((N * Size - todo) / Size);
}
/*********************************************************************
*
* FS__fat_fclose
*
Description:
FS internal function. Close a file referred by pFile.
Parameters:
pFile - Pointer to a FS_FILE data structure.
Return value:
None.
*/
void FS__fat_fclose(FS_FILE *pFile) {
#if (FS_FAT_FWRITE_UPDATE_DIR==0)
FS__fat_dentry_type s;
char *buffer;
FS_u32 dsec;
FS_u16 val;
#endif /* FS_FAT_FWRITE_UPDATE_DIR */
int err;
if (!pFile) {
return;
}
/* Check if media is OK */
err = FS__lb_status(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo);
if (err == FS_LBL_MEDIACHANGED) {
pFile->error = FS_ERR_DISKCHANGED;
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_DEC_BUSYCNT, 0, (void*)0); /* Turn off busy signal */
pFile->inuse = 0;
return;
}
else if (err < 0) {
pFile->error = FS_ERR_CLOSE;
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_DEC_BUSYCNT, 0, (void*)0); /* Turn off busy signal */
pFile->inuse = 0;
return;
}
#if (FS_FAT_FWRITE_UPDATE_DIR==0)
/* Modify directory entry */
buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
pFile->inuse = 0;
pFile->error = FS_ERR_CLOSE;
return;
}
err = _FS_fat_read_dentry(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, pFile->fileid_ex, &s, &dsec, buffer);
if (err == 0) {
pFile->inuse = 0;
pFile->error = FS_ERR_CLOSE;
FS__fat_free(buffer);
return;
}
s.data[28] = (unsigned char)(pFile->size & 0xff); /* FileSize */
s.data[29] = (unsigned char)((pFile->size / 0x100UL) & 0xff);
s.data[30] = (unsigned char)((pFile->size / 0x10000UL) & 0xff);
s.data[31] = (unsigned char)((pFile->size / 0x1000000UL) & 0xff);
val = FS_X_OS_GetTime();
s.data[22] = (unsigned char)(val & 0xff);
s.data[23] = (unsigned char)((val / 0x100) & 0xff);
val = FS_X_OS_GetDate();
s.data[24] = (unsigned char)(val & 0xff);
s.data[25] = (unsigned char)((val / 0x100) & 0xff);
err = _FS_fat_write_dentry(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, &s, dsec, buffer);
if (err == 0) {
pFile->error = FS_ERR_CLOSE;
}
FS__fat_free(buffer);
#endif /* FS_FAT_FWRITE_UPDATE_DIR */
err = FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_FLUSH_CACHE, 2, (void*)0);
if (err < 0) {
pFile->error = FS_ERR_WRITEERROR;
}
pFile->inuse = 0;
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_DEC_BUSYCNT, 0, (void*)0); /* Turn off busy signal */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -