/****************************************************************************** ** 函数名称: RemoveFile ** 功能描述: 删除文件 ** ** 输 入: DirFileName:用户使用的文件名 ** ** 输 出: RETURN_OK:成功 ** 其它参考fat.h中关于返回值的说明 ** 全局变量: 无 ** 调用模块: _GetFDTInfo,FindFDTInfo,FATDelClusChain,DelFDT ** *****************************************************************************/ Uint8 RemoveFile(Int8 *DirFileName) { Uint32 ClusIndex, ClusIndex1; Uint8 Rt; Int8 DirName[12]; FDT temp; DirFileName = FsStrCopy(DirFileName); ClusIndex = _GetFDTInfo(DirName, DirFileName); Rt = PATH_NOT_FIND; if (ClusIndex != BAD_CLUS) { Rt = FindFDTInfo(&temp, ClusIndex, DirName); if (Rt == RETURN_OK) { Rt = NOT_FIND_FILE; if ((temp.Attr & ATTR_DIRECTORY) == 0) /* 是文件才删除 */ { Rt = FILE_LOCK; if (FindOpenFile(ClusIndex, DirName, FILE_FLAGS_READ|FILE_FLAGS_WRITE) == Not_Open_FILE) { /* 文件没有打开才删除 */ ClusIndex1 = temp.FstClusLO + ((Uint32)temp.FstClusHI << 16); FATDelClusChain(ClusIndex1); Rt = DelFDT(ClusIndex, DirName); } } } } return Rt; }
/****************************************************************************** ** 函数名称: _FileOpenR ** 功能描述: 只读方式打开文件,内部使用 ** ** 输 入: DirFileName:用户使用的文件名 ** ** 输 出: 文件句柄,Not_Open_FILE为不能打开 ** ** 全局变量: FileInfo ** 调用模块: _GetFDTInfo,FindFDTInfo ** *****************************************************************************/ HANDLE _FileOpenR(Int8 *DirFileName) { MY_FILE *fp; HANDLE Rt; FDT FileFDT; /* 查找空闲文件登记项 */ for (Rt = 0; FileInfo[Rt].Flags; Rt++) { if(Rt >= MAX_OPEN_FILES) return Not_Open_FILE; } fp = FileInfo + Rt; /* 获取目录开始簇号和文件名 */ fp->DirClus = _GetFDTInfo(fp->Name, DirFileName); if (fp->DirClus < BAD_CLUS) { /* 获取文件信息 */ if (FindFDTInfo(&FileFDT, fp->DirClus, fp->Name) == RETURN_OK) { if ((FileFDT.Attr & ATTR_DIRECTORY) == 0) { fp->Flags = FILE_FLAGS_READ; fp->FileSize = FileFDT.FileSize; fp->FstClus = FileFDT.FstClusLO | (Uint32)FileFDT.FstClusHI << 16; fp->Clus = fp->FstClus; fp->Offset = 0; return Rt; } } } return Not_Open_FILE; }
/********************************************************************************************************* ** 函数名称: RemoveDir ** 功能描述: 删除目录 ** ** 输 入: Path:路径名 ** ** 输 出: RETURN_OK:成功 ** 其它参考fat.h中关于返回值的说明 ** 全局变量: 无 ** 调用模块: strupr,DelFDT ********************************************************************************************************/ acoral_u8 RemoveDir(acoral_char *Path) { acoral_u32 ClusIndex, ClusIndex1; acoral_u8 Drive, Rt; acoral_char DirName[12]; FDT temp; strupr(Path); /* 变为大写 */ ClusIndex = _GetFDTInfo(DirName, Path); if (ClusIndex == BAD_CLUS) { return PATH_NOT_FIND; } Drive = GetDrive(Path); /* 获取FDT其信息 */ Rt = FindFDTInfo(&temp, Drive, ClusIndex, DirName); if (Rt == RETURN_OK) { /* 是否是目录 */ if ((temp.Attr & ATTR_DIRECTORY) != 0) { /* 是 */ ClusIndex1 = temp.FstClusLO + ((acoral_u32)(temp.FstClusHI) << 16); /* 是否是空目录 */ Rt = DirIsEmpty(Drive, ClusIndex1); if (Rt == DIR_EMPTY) { /* 是,删除 */ FATDelClusChain(Drive, ClusIndex1); Rt = DelFDT(Drive, ClusIndex, DirName); } } else { return PATH_NOT_FIND; } } return Rt; }
/****************************************************************************** ** 函数名称: FileClose ** 功能描述: 关闭指定文件 ** ** 输 入: Handle:文件句柄 ** ** 输 出: RETURN_OK:成功 ** 其它参考fat.h中关于返回值的说明 ** 全局变量: 无 ** 调用模块: 无 ** ** 说 明: 增加文件的最后访问时间属性和最后修改时间属性 ** ** 流 程: 判断文件是否有写状态-Y->取出该文件FDT项-->判断文件大小是否变化-Y->更新FDT中首簇号-->保存FDT项 ** 注 意: 关闭文件后,将释放其登记项,并把修改过的扇区回写保存,但其仍占用原来的cache。 ****************************************************************************/ Uint8 FileClose(HANDLE Handle) { Uint8 Rt; FDT FileFDT; MY_FILE *fp; SYS_TIME CurTime; Rt = PARAMETER_ERR; if (Handle < MAX_OPEN_FILES) { if(FS_GetDateTime(&CurTime) != RETURN_OK) // 获取当前时间 { return GET_TIME_ERR; } fp = FileInfo + Handle; // 获取该文件的FDT项 Rt = FindFDTInfo(&FileFDT, fp->DirClus, fp->Name); if (Rt != RETURN_OK) { return Rt; } FileFDT.LstAccDate = CurTime.date; // 更新文件最后访问时间 // 如果文件不是以只写方式打开就不需要保存 if (fp->Flags & FILE_FLAGS_WRITE) { if (FileFDT.FileSize < fp->FileSize) // 查看文件大小是否发生变化 { FileFDT.FileSize = fp->FileSize; // 更新文件最后修改时间 FileFDT.WrtTime = CurTime.time + 1; // 修改时间需要加2秒,因为它不能计算到毫秒戳 FileFDT.WrtDate = CurTime.date; if (FileFDT.FstClusLO == 0) if (FileFDT.FstClusHI == 0) { FileFDT.FstClusLO = fp->FstClus & 0xffff; FileFDT.FstClusHI = fp->FstClus >> 16; } } }
/********************************************************************************************************* ** 函数名称: GetDirClusIndex ** 功能描述: 获取指定目录开始簇号 ** ** 输 入: Path:路径名 ** ** 输 出: 开始簇号,EMPTY_CLUS:为根目录 ** ** 全局变量: 无 ** 调用模块: strupr,GetDiskInfo,FindFDTInfo ********************************************************************************************************/ acoral_u32 GetDirClusIndex(acoral_char *Path) { acoral_char DirName[12]; acoral_u8 Drive; acoral_u32 Rt; FDT temp; Disk_Info *Disk; Rt = BAD_CLUS; if (Path != NULL) { strupr(Path); /* 变为大写 */ Drive = GetDrive(Path); /* 获取路基盘符 */ if (Path[1] == ':') { Path += 2; } Disk = GetDiskInfo(Drive); /* 获取逻辑盘信息 */ if (Disk != NULL) { Rt = 0; if (Disk->FATType == FAT32) /* FAT32 根目录 */ { Rt = Disk->RootDirTable; } if (Path[0] != '\\' || Path[0] != '/') /* 不是目录分隔符号,表明起点是当前路径 */ { Rt = Disk->PathClusIndex; } else { Path++; } if (Path[0] == '.') /* '\.'表明起点是当前路径 */ { Rt = Disk->PathClusIndex; if (Path[1] == 0 || Path[1] == '\\' || Path[1] == '/') { Path++; } } if (Path[0] == '\\' || Path[0] == '/') { Path++; } DirName[11] = 0; while (Path[0] != 0) { /* 获取子目录名 */ StrToFDTName(DirName , Path); /* 子目录名开始簇号 */ if (DirName[0] == 0x20) { Rt = BAD_CLUS; break; } /* 获取FDT信息 */ if (FindFDTInfo(&temp, Drive, Rt, DirName) != RETURN_OK) { Rt = BAD_CLUS; break; } /* FDT是否是目录 */ if ((temp.Attr & ATTR_DIRECTORY) == 0) { Rt = BAD_CLUS; break; } Rt = temp.FstClusLO + ((acoral_u32)(temp.FstClusHI) << 16); /* 字符串到下一个目录 */ while (1) { if (*Path == '\\' || *Path == '/') { Path++; break; } if (*Path == 0) { break; } Path++; } } } if (Disk->FATType == FAT32) if (Rt != BAD_CLUS) if (Rt == Disk->RootDirTable) { Rt = 0; } } return Rt; }
IRAM_FAT uint32 GetDirClusIndexLong(uint8 *Path, uint16 len) { uint16 i; uint32 DirClusIndex; FDT temp; uint16 LName[260]; uint8 SName[13]; uint8 *start; uint8 ret; DirClusIndex = BAD_CLUS; if (Path != NULL) //null pointer { //*********************************************************************** //支持盘符如A: //*********************************************************************** if (Path[1] == ':') { Path += 2; len -= 2; } DirClusIndex = BootSector.BPB_RootClus; //根目录 //*********************************************************************** //A:TEMP、TEMP和.\TEMP都是指当前目录下的TEMP子目录 if (Path[0] != '\\') //* 不是目录分隔符号,表明起点是当前路径 { DirClusIndex = CurDirClus; } else { Path++; len--; } if (Path[0] == '.') // '\.'表明起点是当前路径 { DirClusIndex = CurDirClus; if (Path[1] == '\0' || Path[1] == '\\') //case "." or ".\" { Path++; len--; } } while (len > 0) { if (Path[0] == ' ') //首个字符不允许为空格 { DirClusIndex = BAD_CLUS; break; } start = Path; for (i = 1; i < 256; i++) { Path++; len--; if (*Path == '\\') { Path++; len--; break; } } if( FSIsLongName(start, i)) { FSStr2Wstr(LName, start, i); ret = FindFDTInfoLong(&temp, DirClusIndex, LName); } else { FSRealname(SName, start, 1); ret = FindFDTInfo(&temp, DirClusIndex, SName); } if (ret != RETURN_OK) //获取FDT信息 { DirClusIndex = BAD_CLUS; break; } if ((temp.Attr & ATTR_DIRECTORY) == 0) //FDT是否是目录 { DirClusIndex = BAD_CLUS; break; } DirClusIndex = ((uint32)(temp.FstClusHI) << 16) + temp.FstClusLO; } } return (DirClusIndex); }
/********************************************************************************************************* ** Name : GetDirClusIndex ** Description : get start cluster number of sepecified direction. ** Input : Path:(no include file name) ** Output : start cluster number. ** global : CurDirClus ** call module : FindFDTInfo ** explain : '\' can not be the path end,suppot 1~11 path name. ********************************************************************************************************/ IRAM_FAT uint32 GetDirClusIndex(uint8 *Path) { uint8 i; uint32 DirClusIndex; FDT temp; uint8 PathName[12]; DirClusIndex = BAD_CLUS; if (Path != NULL) //null pointer { //*********************************************************************** //支持盘符如A: //*********************************************************************** StrUprCase(Path); if (Path[1] == ':') { Path += 2; } DirClusIndex = BootSector.BPB_RootClus; //根目录 //*********************************************************************** //A:TEMP、TEMP和.\TEMP都是指当前目录下的TEMP子目录 if (Path[0] != '\\') //* 不是目录分隔符号,表明起点是当前路径 { DirClusIndex = CurDirClus; } else { Path++; } if (Path[0] == '.') // '\.'表明起点是当前路径 { DirClusIndex = CurDirClus; if (Path[1] == '\0' || Path[1] == '\\') //case "." or ".\" { Path++; } } while (Path[0] != '\0') { if (Path[0] == ' ') //首个字符不允许为空格 { DirClusIndex = BAD_CLUS; break; } for (i = 0; i < 11; i++) //目录项填空格 { PathName[i] = ' '; } for (i = 0; i < 12; i++) { if (*Path == '\0') //到路径结束 { break; } PathName[i] = *Path++; } if (FindFDTInfo(&temp, DirClusIndex, PathName) != RETURN_OK) //获取FDT信息 { DirClusIndex = BAD_CLUS; break; } if ((temp.Attr & ATTR_DIRECTORY) == 0) //FDT是否是目录 { DirClusIndex = BAD_CLUS; break; } DirClusIndex = ((uint32)(temp.FstClusHI) << 16) + temp.FstClusLO; } } return (DirClusIndex); }
/****************************************************************************** ** 函数名称: _FileOpenW ** 功能描述: 只写方式打开文件,内部使用 ** ** 输 入: DirFileName:用户使用的文件名 ** ** 输 出: 文件句柄,Not_Open_FILE为不能打开 ** ** 全局变量: FileInfo ** 调用模块: _GetFDTInfo,FindFDTInfo ** *****************************************************************************/ HANDLE _FileOpenW(Int8 *DirFileName) { MY_FILE *fp; FDT temp; HANDLE Rt; Uint8 i; SYS_TIME CurTime,CrtTime; // 保存当前时间日期 /* 查找空闲文件登记项 */ for (Rt = 0; FileInfo[Rt].Flags; Rt++) { if(Rt >= MAX_OPEN_FILES) return Not_Open_FILE; } fp = FileInfo + Rt; // 指向获得的空闲登记项 /* 获取目录开始簇号和文件名 */ fp->DirClus = _GetFDTInfo(fp->Name, DirFileName); // 获取该文件的FDT项的首簇号,及文件名 if (fp->DirClus < BAD_CLUS) { /* 文件已经以读写方式打开,不能再次以读写方式打开 */ if (FindOpenFile(fp->DirClus, fp->Name, FILE_FLAGS_WRITE) == Not_Open_FILE) { if(FS_GetDateTime(&CurTime) != RETURN_OK) // 获取当前系统时间 { return GET_TIME_ERR; } if (FindFDTInfo(&temp, fp->DirClus, fp->Name) == RETURN_OK) { if ((temp.Attr & ATTR_DIRECTORY) != 0) { return Not_Open_FILE; // 如果该文件为目录,则不能删除 } CrtTime.date = temp.CrtDate; // 保存文件建立时间 CrtTime.time = temp.CrtTime; CrtTime.msec = temp.CrtTimeTenth; if (RemoveFile(DirFileName) != RETURN_OK) /* 删除文件 */ { return Not_Open_FILE; } } else { CrtTime = CurTime; // 设置文件建立时间为当前时间 } /* 创建文件 */ for (i = 0; i < 11; i++) // 创建将要生成文件的FDT项 { temp.Name[i] = fp->Name[i]; // 复制名字 } temp.Attr = 0; // 特性为0 temp.FileSize = 0; temp.NTRes = 0; /*-------在此加入创建时间的程序---------*/ temp.CrtTimeTenth = CrtTime.msec; temp.CrtTime = CrtTime.time; temp.CrtDate = CrtTime.date; temp.LstAccDate = CurTime.date; temp.WrtTime = CurTime.time + 1; temp.WrtDate = CurTime.date; /*--------------------------------------*/ temp.FstClusLO = 0; temp.FstClusHI = 0; if (AddFDT(fp->DirClus, &temp) == RETURN_OK) /* 增加文件 */ { /* 设置文件信息 */ fp->Flags = FILE_FLAGS_WRITE; fp->FileSize = 0; fp->FstClus = 0; fp->Clus = 0; fp->Offset = 0; return Rt; } // if(Add..) } // if(Find..) } // if(fp..) return Not_Open_FILE; }