?? fat_open.c
字號:
}
c = FS__CLIB_strncmp((char*)s->data, pDirName, len);
if (c == 0) { /* Name does match */
if (s->data[11] & FS_FAT_ATTR_DIRECTORY) {
break; /* Entry found */
}
}
s++;
}
if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
/* Entry found. Return number of 1st block of the directory */
FS__fat_free(buffer);
dstart = (FS_u32)s->data[26];
dstart += (FS_u32)0x100UL * s->data[27];
dstart += (FS_u32)0x10000UL * s->data[20];
dstart += (FS_u32)0x1000000UL * s->data[21];
return dstart;
}
}
dstart = 0;
FS__fat_free(buffer);
}
return dstart;
}
/*********************************************************************
*
* FS__fat_dir_realsec
*
Description:
FS internal function. Translate a directory relative sector number
to a real sector number on the media.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number.
DirStart - 1st cluster of the directory. This is zero to address
the root directory.
DirSec - Sector in the directory.
Return value:
>0 - Directory found. Value is the sector number on the media.
==0 - An error has occured.
*/
FS_u32 FS__fat_dir_realsec(int Idx, FS_u32 Unit, FS_u32 DirStart, FS_u32 DirSec) {
FS_u32 rootdir;
FS_u32 rsec;
FS_u32 dclust;
FS_u32 fatsize;
int fattype;
int lexp;
unsigned char secperclus;
fattype = FS__fat_which_type(Idx, Unit);
lexp = (0 == DirStart);
lexp = lexp && (fattype != 2);
if (lexp) {
/* Sector in FAT12/FAT16 root directory */
rootdir = FS__fat_find_dir(Idx, Unit, 0, 0, 0);
rsec = rootdir + DirSec;
}
else {
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz16;
if (fatsize == 0) {
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz32;
}
secperclus = FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
dclust = DirSec / secperclus;
if (0 == DirStart) {
/* FAT32 root directory */
rsec = FS__FAT_aBPBUnit[Idx][Unit].RootClus;
}
else {
rsec = FS__fat_diskclust(Idx, Unit, DirStart, dclust);
if (rsec == 0) {
return 0;
}
}
rsec -= 2;
rsec *= secperclus;
rsec += FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt + FS__FAT_aBPBUnit[Idx][Unit].NumFATs * fatsize;
rsec += ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[Idx][Unit].RootEntCnt) * FS_FAT_DENTRY_SIZE) / FS_FAT_SEC_SIZE;
rsec += (DirSec % secperclus);
}
return rsec;
}
/*********************************************************************
*
* FS__fat_dirsize
*
Description:
FS internal function. Return the sector size of the directory
starting at DirStart.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number.
DirStart - 1st cluster of the directory. This is zero to address
the root directory.
Return value:
>0 - Sector (not cluster) size of the directory.
==0 - An error has occured.
*/
FS_u32 FS__fat_dir_size(int Idx, FS_u32 Unit, FS_u32 DirStart) {
FS_u32 dsize;
FS_i32 value;
if (DirStart == 0) {
/* For FAT12/FAT16 root directory, the size can be found in BPB */
dsize = ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[Idx][Unit].RootEntCnt)
* FS_FAT_DENTRY_SIZE) / ((FS_u32)FS__FAT_aBPBUnit[Idx][Unit].BytesPerSec);
if (dsize == 0) {
/* Size in BPB is 0, so it is a FAT32 (FAT32 does not have a real root dir) */
value = FS__fat_FAT_find_eof(Idx, Unit, FS__FAT_aBPBUnit[Idx][Unit].RootClus, &dsize);
if (value < 0) {
dsize = 0;
}
else {
dsize *= FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
}
}
}
else {
/* Calc size of a sub-dir */
value = FS__fat_FAT_find_eof(Idx, Unit, DirStart, &dsize);
if (value < 0) {
dsize = 0;
}
else {
dsize *= FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
}
}
return dsize;
}
/*********************************************************************
*
* FS__fat_findpath
*
Description:
FS internal function. Return start cluster and size of the directory
of the file name in pFileName.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
pFullName - Fully qualified file name w/o device name.
pFileName - Pointer to a pointer, which is modified to point to the
file name part of pFullName.
pUnit - Pointer to an FS_u32 for returning the unit number.
pDirStart - Pointer to an FS_u32 for returning the start cluster of
the directory.
Return value:
>0 - Sector (not cluster) size of the directory.
==0 - An error has occured.
*/
FS_u32 FS__fat_findpath(int Idx, const char *pFullName, FS_FARCHARPTR *pFileName,
FS_u32 *pUnit, FS_u32 *pDirStart) {
FS_u32 dsize;
FS_i32 i;
FS_i32 j;
FS_FARCHARPTR dname_start;
FS_FARCHARPTR dname_stop;
FS_FARCHARPTR chprt;
int x;
char dname[12];
char realname[12];
/* Find correct unit (unit:name) */
*pFileName = (FS_FARCHARPTR)FS__CLIB_strchr(pFullName, ':');
if (*pFileName) {
/* Scan for unit number */
*pUnit = FS__CLIB_atoi(pFullName);
(*pFileName)++;
}
else {
/* Use 1st unit as default */
*pUnit = 0;
*pFileName = (FS_FARCHARPTR) pFullName;
}
/* Check volume */
x = !FS__fat_checkunit(Idx, *pUnit);
if (x) {
return 0;
}
/* Setup pDirStart/dsize for root directory */
*pDirStart = 0;
dsize = FS__fat_dir_size(Idx, *pUnit, 0);
/* Find correct directory */
do {
dname_start = (FS_FARCHARPTR)FS__CLIB_strchr(*pFileName, '\\');
if (dname_start) {
dname_start++;
*pFileName = dname_start;
dname_stop = (FS_FARCHARPTR)FS__CLIB_strchr(dname_start, '\\');
}
else {
dname_stop = 0;
}
if (dname_stop) {
i = dname_stop-dname_start;
if (i >= 12) {
j = 0;
for (chprt = dname_start; chprt < dname_stop; chprt++) {
if (*chprt == '.') {
i--;
}
else if (j < 12) {
realname[j] = *chprt;
j++;
}
}
if (i >= 12) {
return 0;
}
}
else {
FS__CLIB_strncpy(realname, dname_start, i);
}
realname[i] = 0;
FS__fat_make_realname(dname, realname);
*pDirStart = FS__fat_find_dir(Idx, *pUnit, dname, *pDirStart, dsize);
if (*pDirStart) {
dsize = FS__fat_dir_size(Idx, *pUnit, *pDirStart);
}
else {
dsize = 0; /* Directory NOT found */
}
}
} while (dname_start);
return dsize;
}
/*********************************************************************
*
* Global functions section 2
*
**********************************************************************
These are real global functions, which are used by the API Layer
of the file system.
*/
/*********************************************************************
*
* FS__fat_fopen
*
Description:
FS internal function. Open an existing file or create a new one.
Parameters:
pFileName - File name.
pMode - Mode for opening the file.
pFile - Pointer to an FS_FILE data structure.
Return value:
==0 - Unable to open the file.
!=0 - Address of the FS_FILE data structure.
*/
FS_FILE *FS__fat_fopen(const char *pFileName, const char *pMode, FS_FILE *pFile) {
FS_u32 unit;
FS_u32 dstart;
FS_u32 dsize;
FS_i32 i;
FS_FARCHARPTR fname;
FS__fat_dentry_type s;
char realname[12];
int lexp_a;
int lexp_b;
if (!pFile) {
return 0; /* Not a valid pointer to an FS_FILE structure*/
}
dsize = FS__fat_findpath(pFile->dev_index, pFileName, &fname, &unit, &dstart);
if (dsize == 0) {
return 0; /* Directory not found */
}
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_INC_BUSYCNT, 0, (void*)0); /* Turn on busy signal */
FS__fat_make_realname(realname, fname); /* Convert name to FAT real name */
/* FileSize = 0 */
s.data[28] = 0x00;
s.data[29] = 0x00;
s.data[30] = 0x00;
s.data[31] = 0x00;
i = _FS_fat_find_file(pFile->dev_index, unit, realname, &s, dstart, dsize);
/* Delete file */
lexp_b = (FS__CLIB_strcmp(pMode, "del") == 0); /* Delete file request */
lexp_a = lexp_b && (i >= 0); /* File does exist */
if (lexp_a) {
i = FS__fat_DeleteFileOrDir(pFile->dev_index, unit, realname, dstart, dsize, 1);
if (i != 0) {
pFile->error = -1;
}
else {
pFile->error = 0;
}
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, FS_CMD_FLUSH_CACHE, 2, (void*)0);
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0); /* Turn off busy signal */
return 0;
}
else if (lexp_b) {
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0); /* Turn off busy signal */
pFile->error = -1;
return 0;
}
/* Check read only */
lexp_a = ((i >= 0) && ((s.data[11] & FS_FAT_ATTR_READ_ONLY) != 0)) &&
((pFile->mode_w) || (pFile->mode_a) || (pFile->mode_c));
if (lexp_a) {
/* Files is RO and we try to create, write or append */
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0); /* Turn off busy signal */
return 0;
}
lexp_a = ( i>= 0) && (!pFile->mode_a) && (((pFile->mode_w) && (!pFile->mode_r)) ||
((pFile->mode_w) && (pFile->mode_c) && (pFile->mode_r)) );
if (lexp_a) {
/* Delete old file */
i = FS__fat_DeleteFileOrDir(pFile->dev_index, unit, realname, dstart, dsize, 1);
/* FileSize = 0 */
s.data[28] = 0x00;
s.data[29] = 0x00;
s.data[30] = 0x00;
s.data[31] = 0x00;
i=-1;
}
if ((!pFile->mode_c) && (i < 0)) {
/* File does not exist and we must not create */
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0); /* Turn off busy signal */
return 0;
}
else if ((pFile->mode_c) && (i < 0)) {
/* Create new file */
i = _FS_fat_create_file(pFile->dev_index, unit, realname, dstart, dsize);
if (i < 0) {
/* Could not create file */
if (i == -2) {
/* Directory is full, try to increase */
i = _FS_fat_IncDir(pFile->dev_index, unit, dstart, &dsize);
if (i > 0) {
i = _FS_fat_create_file(pFile->dev_index, unit, realname, dstart, dsize);
}
}
if (i < 0) {
FS__lb_ioctl(FS__pDevInfo[pFile->dev_index].devdriver, unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0); /* Turn off busy signal */
return 0;
}
}
}
pFile->fileid_lo = unit;
pFile->fileid_hi = i;
pFile->fileid_ex = dstart;
pFile->EOFClust = -1;
pFile->CurClust = 0;
pFile->error = 0;
pFile->size = (FS_u32)s.data[28]; /* FileSize */
pFile->size += (FS_u32)0x100UL * s.data[29];
pFile->size += (FS_u32)0x10000UL * s.data[30];
pFile->size += (FS_u32)0x1000000UL * s.data[31];
if (pFile->mode_a) {
pFile->filepos = pFile->size;
}
else {
pFile->filepos = 0;
}
pFile->inuse = 1;
return pFile;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -