?? fat_open.c
字號:
#endif /* FS_FAT_NOFAT32==0 */
buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
return 0;
}
fattype = FS__fat_which_type(Idx, Unit);
#if (FS_FAT_NOFAT32!=0)
if (fattype == 2) {
FS__fat_free(buffer);
return -1;
}
#endif /* FS_FAT_NOFAT32!=0 */
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz16;
if (fatsize == 0) {
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz32;
}
bytespersec = (FS_i32)FS__FAT_aBPBUnit[Idx][Unit].BytesPerSec;
len = FS__CLIB_strlen(pName);
if (len > 11) {
len = 11;
}
/* Read directory */
for (i = 0; i < DirSize; i++) {
curclst = -1;
dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
if (dsec == 0) {
FS__fat_free(buffer);
return -1;
}
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
/* Scan for pName in the directory sector */
s = (FS__fat_dentry_type*) buffer;
while (1) {
if (s >= (FS__fat_dentry_type*)(buffer + bytespersec)) {
break; /* End of sector reached */
}
x = FS__CLIB_strncmp((char*)s->data, pName, len);
if (x == 0) { /* Name does match */
if (s->data[11] != 0) {
break; /* Entry found */
}
}
s++;
}
if (s < (FS__fat_dentry_type*)(buffer + bytespersec)) {
/* Entry has been found, delete directory entry */
s->data[0] = 0xe5;
s->data[11] = 0;
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
/* Free blocks in FAT */
/*
For normal files, there are no more clusters freed than the entrie's filesize
does indicate. That avoids corruption of the complete media in case there is
no EOF mark found for the file (FAT is corrupt!!!).
If the function should remove a directory, filesize if always 0 and cannot
be used for that purpose. To avoid running into endless loop, todo is set
to 0x0ffffff8L, which is the maximum number of clusters for FAT32.
*/
if (RmFile) {
filesize = s->data[28] + 0x100UL * s->data[29] + 0x10000UL * s->data[30] + 0x1000000UL * s->data[31];
todo = filesize / (FS__FAT_aBPBUnit[Idx][Unit].SecPerClus * bytespersec);
value = filesize % (FS__FAT_aBPBUnit[Idx][Unit].SecPerClus * bytespersec);
if (value != 0) {
todo++;
}
}
else {
todo = (FS_i32)0x0ffffff8L;
}
curclst = s->data[26] + 0x100L * s->data[27] + 0x10000L * s->data[20] + 0x1000000L * s->data[21];
lastsec = -1;
/* Free cluster loop */
while (todo) {
if (fattype == 1) {
fatindex = curclst + (curclst / 2); /* FAT12 */
}
#if (FS_FAT_NOFAT32==0)
else if (fattype == 2) {
fatindex = curclst * 4; /* FAT32 */
}
#endif /* FS_FAT_NOFAT32==0 */
else {
fatindex = curclst * 2; /* FAT16 */
}
fatsec = FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt + (fatindex / bytespersec);
fatoffs = fatindex % bytespersec;
if (fatsec != lastsec) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
if (err < 0) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
/* Try to repair original FAT sector with contents of copy */
FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
}
lastsec = fatsec;
}
if (fattype == 1) {
if (fatoffs == (bytespersec - 1)) {
a = buffer[fatoffs];
if (curclst & 1) {
buffer[fatoffs] &= 0x0f;
}
else {
buffer[fatoffs] = 0x00;
}
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
err2 = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec, (void*)buffer);
lexp = (err < 0);
lexp = lexp || (err2 < 0);
if (lexp) {
FS__fat_free(buffer);
return -1;
}
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsec + 1, (void*)buffer);
if (err < 0) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec + 1, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
/* Try to repair original FAT sector with contents of copy */
FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec + 1, (void*)buffer);
}
lastsec = fatsec + 1;
b = buffer[0];
if (curclst & 1) {
buffer[0] = 0x00;;
}
else {
buffer[0] &= 0xf0;
}
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec + 1, (void*)buffer);
err2 = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec + 1, (void*)buffer);
lexp = (err < 0);
lexp = lexp || (err2 < 0);
if (lexp) {
FS__fat_free(buffer);
return -1;
}
}
else {
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
if (curclst & 1) {
buffer[fatoffs] &= 0x0f;
buffer[fatoffs + 1] = 0x00;
}
else {
buffer[fatoffs] = 0x00;
buffer[fatoffs + 1] &= 0xf0;
}
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
err2 = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec, (void*)buffer);
lexp = (err < 0);
lexp = lexp || (err2 < 0);
if (lexp) {
FS__fat_free(buffer);
return -1;
}
}
if (curclst & 1) {
curclst = ((a & 0xf0) >> 4) + 16 * b;
}
else {
curclst = a + 256 * (b & 0x0f);
}
curclst &= 0x0fff;
if (curclst >= 0x0ff8) {
FS__fat_free(buffer);
return 0;
}
}
#if (FS_FAT_NOFAT32==0)
else if (fattype == 2) { /* FAT32 */
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
c = buffer[fatoffs + 2];
d = buffer[fatoffs + 3] & 0x0f;
buffer[fatoffs] = 0x00;
buffer[fatoffs + 1] = 0x00;
buffer[fatoffs + 2] = 0x00;
buffer[fatoffs + 3] = 0x00;
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
err2 = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec, (void*)buffer);
lexp = (err < 0);
lexp = lexp || (err2 < 0);
if (lexp) {
FS__fat_free(buffer);
return -1;
}
curclst = a + 0x100 * b + 0x10000L * c + 0x1000000L * d;
curclst &= 0x0fffffffL;
if (curclst >= (FS_i32)0x0ffffff8L) {
FS__fat_free(buffer);
return 0;
}
}
#endif /* FS_FAT_NOFAT32==0 */
else {
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
buffer[fatoffs] = 0x00;
buffer[fatoffs + 1] = 0x00;
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
err2 = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec, (void*)buffer);
lexp = (err < 0);
lexp = lexp || (err2 < 0);
if (lexp) {
FS__fat_free(buffer);
return -1;
}
curclst = a + 256 * b;
curclst &= 0xffff;
if (curclst >= (FS_i32)0xfff8) {
FS__fat_free(buffer);
return 0;
}
}
todo--;
} /* Free cluster loop */
} /* Delete entry */
if (curclst > 0) {
FS__fat_free(buffer);
return curclst;
}
} /* for */
FS__fat_free(buffer);
return curclst;
}
/*********************************************************************
*
* FS__fat_make_realname
*
Description:
FS internal function. Convert a given name to the format, which is
used in the FAT directory.
Parameters:
pOrgName - Pointer to name to be translated
pEntryName - Pointer to a buffer for storing the real name used
in a directory.
Return value:
None.
*/
void FS__fat_make_realname(char *pEntryName, const char *pOrgName) {
FS_FARCHARPTR ext;
FS_FARCHARPTR s;
int i;
s = (FS_FARCHARPTR)pOrgName;
ext = (FS_FARCHARPTR) FS__CLIB_strchr(s, '.');
if (!ext) {
ext = &s[FS__CLIB_strlen(s)];
}
i=0;
while (1) {
if (s >= ext) {
break; /* '.' reached */
}
if (i >= 8) {
break; /* If there is no '.', this is the end of the name */
}
if (*s == (char)0xe5) {
pEntryName[i] = 0x05;
}
else {
pEntryName[i] = (char)FS__CLIB_toupper(*s);
}
i++;
s++;
}
while (i < 8) {
/* Fill name with spaces*/
pEntryName[i] = ' ';
i++;
}
if (*s == '.') {
s++;
}
while (i < 11) {
if (*s != 0) {
if (*s == (char)0xe5) {
pEntryName[i] = 0x05;
}
else {
pEntryName[i] = (char)FS__CLIB_toupper(*s);
}
s++;
}
else {
pEntryName[i] = ' ';
}
i++;
}
pEntryName[11]=0;
}
/*********************************************************************
*
* FS__fat_find_dir
*
Description:
FS internal function. Find the directory with name pDirName in directory
DirStart.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number.
pDirName - Directory name; if zero, return the root directory.
DirStart - 1st cluster of the directory.
DirSize - Sector (not cluster) size of the directory.
Return value:
>0 - Directory found. Value is the first cluster of the file.
==0 - An error has occured.
*/
FS_u32 FS__fat_find_dir(int Idx, FS_u32 Unit, char *pDirName, FS_u32 DirStart,
FS_u32 DirSize) {
FS__fat_dentry_type *s;
FS_u32 dstart;
FS_u32 i;
FS_u32 dsec;
FS_u32 fatsize;
int len;
int err;
int c;
char *buffer;
if (pDirName == 0) {
/* Return root directory */
if (FS__FAT_aBPBUnit[Idx][Unit].FATSz16) {
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz16;
dstart = FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt + FS__FAT_aBPBUnit[Idx][Unit].NumFATs * fatsize;
}
else {
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz32;
dstart = FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt + FS__FAT_aBPBUnit[Idx][Unit].NumFATs * fatsize
+ (FS__FAT_aBPBUnit[Idx][Unit].RootClus - 2) * FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
}
}
else {
/* Find directory */
buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
return 0;
}
len = FS__CLIB_strlen(pDirName);
if (len > 11) {
len = 11;
}
/* Read directory */
for (i = 0; i < DirSize; i++) {
dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
if (dsec == 0) {
FS__fat_free(buffer);
return 0;
}
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return 0;
}
s = (FS__fat_dentry_type*)buffer;
while (1) {
if (s >= (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
break; /* End of sector reached */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -