📄 pmp_fs_api_za.c
字号:
// 申请内存
len = strlen(pCWD);
pbuf = (UINT8 *)MEM_ALLOC( len+4 );
if(NULL == pbuf){
ERROR_REPORT;
return;
}
// reset memory
memset(pbuf, '\0', len+4);
// copy cwd to pbuf
strcpy(pbuf, pCWD);
// 如果是根目录,添加"\\"
if ( pbuf[len-1] == ':' ){
pbuf[len] = '\\';
}
// changd dir to root NAND
fsDirSet("D:\\",0);
err = fsDirSet( pbuf,0 );
// 进行第一次的搜索
err = fsFirstFileFind( );
DEBUG_OUTPUT(("err 0x%x\r\n",err));
// free memory
MEM_FREE( pbuf );
return;
}
/************************************************************************/
/*
input:
stream [in] 文件句柄
len [in] 文件的截取长度
output: 0 成功 非0值 失败
func: 将一个已经打开的文件裁剪为需要的长度
note: 只能将一个长文件,裁剪为短文件,
不能将一个短文件,裁剪为长文件
不能将文件的长度,裁剪为 0 字节
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_ftruncate (ZA_FILE * stream, UINT32 len)
#else
INT32 ZA_ftruncate (ZA_FILE * stream, UINT32 len)
#endif
{
ERROR_REPORT;
return QFS_ERR;
}
/************************************************************************/
/* 进行整个目录内容的删除动作
input:
path 路径名字符串指针
pcontinue 存放删除是否结束的标志
output: 0 成功删除一个文件 或者 一个空目录
非 0 删除文件或者空目录失败
*pcontinue 0 表示整个删除过程,已经结束了
*pcontinue 非0 表示删除过程,还没有结束,需要继续进行删除动作
func:
目录删除是一个较复杂的过程, 将一个复杂的事情,分解为一系列简单的
事情来进行, 每执行一次该函数,删除一个文件或者一个空的目录
输入的path 举例:
ABC
C:\\abc
C:\\ABC\\test
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_rmdirEx(INT8 * path, INT32 *pcontinue)
#else
INT32 ZA_rmdirEx(INT8 * path, INT32 *pcontinue)
#endif
{
ERROR_REPORT;
return QFS_ERR;
}
/************************************************************************/
/*
input:
path [in] 路径名字符串指针
output:
0 成功, 其他值 失败
func:
note:
目前仅支持一级目录
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_mkdir(const INT8 * pPath)
#else
INT32 ZA_mkdir(const INT8 * pPath)
#endif
{
UINT16 err;
INT32 i,ret,offset;
UINT8 *pCurrPath;
UINT8 *pPathBackup;
UINT8 *path;
UINT8 now_path[0x100];
// 判断输入参数是否合法
if (NULL == pPath) {
ERROR_REPORT;
return QFS_ERR;
}
#ifndef CHANGE_CODE
path = pPath; // 直接使用进来的字符串
#else
// 进行编码的转换
path = get_unicode_ptr( pPath );
#endif
// 获得当前路径字符串
err = fsDirGet(&pCurrPath);
if (err) {
ERROR_REPORT;
return QFS_ERR;
}
// 申请内存保存原来的工作路径
i = strlen(pCurrPath) +4;
pPathBackup = (UINT8 *)MEM_ALLOC( i );
if (NULL == pPathBackup) {
ERROR_REPORT;
return QFS_ERR;
}
// 获得当前的工作路径
strcpy(pPathBackup, pCurrPath);
// 如果是根目录,添加"\\"
if ( pPathBackup[ strlen(pPathBackup) -1 ] == ':' )
{
pPathBackup[ strlen(pPathBackup) ] = '\\';
}
// 进行目录的建立动作
ret = QFS_OK; // 初始化为成功
offset = 0x00;
while (path[offset] == '\\') { // 越过前面的'\\', 直接指向实际的字符串
offset ++;
}
for(i=THE_LAST_DIR+1; i!= THE_LAST_DIR; ) {
if( offset && (path[offset] == '\0') ) {
break;
}
i = get_dir_from_str((char *)path+offset, now_path); // 取出一级目录名
DEBUG_OUTPUT(("now path :%s\r\n", now_path));
offset += strlen(now_path); // 指向下一级目录,注意跳过了一个'\\'
while (path[offset] == '\\') { // 越过 '\\'
offset++;
}
// 检查输入的字符串是否合法
ret = QFS_check_fname(now_path);
// 字符串检查失败,再看看是否为"C:\\"
if( ret ) {
if( !strcmp(now_path, "C:\\") || !strcmp(now_path, "D:\\")) {
ret = 0x00;
}
}
// 再给一次机会,进行判断
if(ret) { break; }
// 尝试着进入该级目录
err = fsDirSet( now_path, 0x00);
// 可以进入该级目录,表示该级目录已经存在了, 不需要进行目录的建立
if( !err ){
continue;
}
if( now_path[strlen(now_path)-1] == '\\' ) {
now_path[ strlen(now_path)-1 ] = '\0';
}
// 建立该目录
err = fsDirMake( now_path, strlen(now_path));
// 建立目录成功,进入该目录
if( !err )
{
DEBUG_OUTPUT(("进入该目录\r\n"));
fsDirSet( now_path, strlen(now_path) );
}
else {
ERROR_REPORT;
break;
}
}
// 将工作目录恢复到原来的工作目录
fsDirSet( pPathBackup, 0x00 );
MEM_FREE( pPathBackup );
return ret;
}
/************************************************************************/
/*
-------------- 只在本文件内使用的函数 -----------------------
*/
/************************************************************************/
/************************************************************************/
/* 输入一个字符串, 获得该字符串对应的逻辑盘的内部代码值
input:
pDevName [in] 逻辑盘字符串的指针
pDevID [out] 获得的设备内部代码存放的地址
output:
0 成功, 非0值失败
func:
note:
*/
/************************************************************************/
static UINT16 get_devid_by_name( UINT8 * pDevName, UINT16 *pDevID)
{
UINT16 i,ret;
// 将首字符转换为大写的格式
i = toupper( (int)pDevName[0] );
ret = QFS_OK;
if (i == 'D') {
*pDevID = FS_DRIVE_NAND;
}
else if ( i == 'C') {
*pDevID = FS_DRIVE_SD_MMC;
}
else{
*pDevID = 0xffff;
ret = QFS_ERR;
}
return ret;
}
/************************************************************************/
/*
input:
in_str [in] 模式字符串的指针
output:
(-1)表示输入的参数不正常,正常为:内部定义的类型值
func:
note:
*/
/************************************************************************/
static INT16 QFS_get_open_mode( INT8 * in_str)
{
INT16 i,j, len;
INT8 temp[6];
len = strlen(in_str); // 获得字符串长度
// 判断输入参数是否合法
if( len>(sizeof(temp)-1) || !len){
ERROR_REPORT;
return QFS_ERR;
}
// 将所有的字符转换为小写, 获得字符串的累加和
for(i=0x00, j=0x00; i<len; i++)
{
temp[i] = tolower(in_str[i]);
j += temp[i];
}
// 根据累加和判断结果
if( j == 'r' || j == 'r'+'b') {
return F_O_RDONLY;
}
else if (j == 'w' || j == 'w' + 'b') {
return F_O_WRONLY;
}
else if (j == 'a' || j == 'a' + 'b') {
return F_O_APPEND;
}
else if (j == 'r' + '+' || j == 'r' + 'b' + '+' ) {
return F_O_RD_PLUS;
}
else if (j == 'w' + '+' || j == 'w' + 'b' + '+' ) {
return F_O_WR_PLUS;
}
else if (j == 'a' + '+' || j == 'a' + 'b' + '+' ) {
return F_O_APPEND_PLUS;
}
return QFS_ERR;
}
/************************************************************************/
/*
input:
name [in] 文件名字符串的指针
output:
0 成功 非0 失败
func:
判断输入的文件名字符串是否符合 WINDOWS FAT 规范。
*/
/************************************************************************/
#define INVALID_FNAME (-1)
#define BANJIAO_CHAR (0x80)
static INT32 QFS_check_fname(INT8 *name )
{
INT32 i,j;
// 首字符不能为 '.' 和 ' '
if(name[0] == '.' || name[0] == ' ') {
ERROR_REPORT;
return INVALID_FNAME;
}
// 取得关键字字符串的长度
j = strlen(name);
// 文件名字符串的结尾不能为 '.' 和 ' '
if( (name[j-1] == ' ') || (name[j-1] == '.') ) {
ERROR_REPORT;
return INVALID_FNAME;
}
// 检查是否含有小于 0x20 的字符
for(i=0x00; i<j; i++)
{
if( (UINT8) name[i]< (UINT8)' ')
{
ERROR_REPORT;
return INVALID_FNAME; // 如果存在小于' ' 的字符,直接返回失败
}
}
// 上面的程序没有考虑 繁体汉字 BIG5 编码中 后面一个字节为ASCII 的情形
for(i=0x00; i<strlen(name); i++)
{
// 遇到汉字就跳过一个字节
if((UINT8)name[i] > (UINT8)BANJIAO_CHAR ) {
i++;
continue;
}
// 判断该字符是否为FAT 禁止的字符
for(j=0x00; j<sizeof(fnamekeyword); j++)
{
if(fnamekeyword[j] == name[i]){
ERROR_REPORT;
return INVALID_FNAME;
}
}
}
// 检查文件名是否与 WINDOWS 保留字符串一致
for(i=0x00; i< PERSVSUM; i++)
{
if(!strcmp(name, fnamepersive[i]))
{
ERROR_REPORT;
return INVALID_FNAME; // 如果使用了 WINDOWS FAT 保留的字符串,返回失败
}
}
return 0;
}
/************************************************************************/
/*
// get_dir_from_str
//
//func: 从一个多级目录串中,只取出一级目录文本串
//
//input: PSTR in_str 输入的字符串的指针
// PSTR out_str 得到的目录的存放的指针
//output: THE_LAST_DIR 已经是最后的目录,没有后续目录了
// THE_LAST_DIR+1 还有后续目录,还需要继续进行
//note:
//example:
//
//note:
[6/14/2006] 修改取出目录字符串时,不带有'\\'
[3/17/2005] 对函数进行调整,处理如此的情形 "C:\\123\\\\DEBUG\\9876"
//
// 在目录名之间有多于一个 '\\'出现的情形
//
//
//change: 7/22/2005 需要考虑繁体汉字 BIG5 编码中出现 0x5c 的情形
*/
/************************************************************************/
static INT16 get_dir_from_str(const INT8 *in_str, INT8 *out_str)
{
INT16 i,j, str_len;
out_str[0] = '\0';
// 获得输入字符串的长度
str_len = strlen(in_str);
// 只有"\\" 的情形
if((in_str[0] == '\\') && (in_str[1] == '\0')){
strcpy(out_str, in_str);
return THE_LAST_DIR;
}
// 根目录的情形
if((in_str[0] == '\\') && (in_str[1] != '\0')){
strcpy(out_str, "\\");
return THE_LAST_DIR+1;
}
// "C:\\ABCD\\998HGF" 有":"的情形
if((in_str[1] == ':') && (in_str[2] == '\\')){
memcpy(out_str, in_str, 0x03);
out_str[3] = '\0';
if(in_str[3] == '\0'){
return THE_LAST_DIR;
}
return THE_LAST_DIR+1;
}
// 获得需要复制的长度
// 需要处理如此的情形 "C:\\123\\\\\\DEBUG\\987"
for(i=0x00; i<str_len; i++)
{
// 如果是汉字字符,就跳过下一个字符
if(( UINT8)in_str[i] > (UINT8)BANJIAO_CHAR ) {
i++;
continue;
}
// 如果不是最后一个'\\', 还有继续
if((in_str[i] == '\\') && (in_str[i+1] == '\\')){
continue;
}
// 如果遇到了 '\\' 或者 '\0', 也就是找到结束标志了
if(in_str[i] == '\\' || in_str[i] == '\0') {
#if 0
if(in_str[i+1] != '\\') {
i++;
}
#endif
break;
}
}
// 复制字符串
for(j=0x00; j<i; j++)
{
if(in_str[j] != '\\'){
out_str[j] = in_str[j];
}
else
{
// 考虑 繁体汉字 编码为 0xZZ 0x5C 的情形
if( j && (in_str[j] == '\\') && ((UINT8)in_str[j-1] > BANJIAO_CHAR) ) {
out_str[j] = in_str[j];
continue;
}
else{
out_str[j] = in_str[j];
j++;
i = j;
break;
}
}
}
// 给得到的字符串补零
out_str[i] = '\0';
// 判断需要返回的值
// if(in_str[i+1] != '\0')
if( strlen(in_str) != i ){
return THE_LAST_DIR+1;
}
else{
return THE_LAST_DIR;
}
}
/************************************************************************/
/* 将一个地址指针转换为内部句柄
input:
stream [in] void * ZA 接口层的文件句柄指针
output:
func:
note:
*/
/************************************************************************/
static INT16 get_file_handle( void * stream, UINT32 *pHandle )
{
if ( (UINT32)stream < (UINT32)&pFHandleBegin)
{
ERROR_REPORT;
return QFS_ERR;
}
*pHandle = (UINT32) ( (UINT32)stream - (UINT32)&pFHandleBegin );
return QFS_OK;
}
/************************************************************************/
/* 输入本地编码的地址指针
input:
plocal [in] 本地编码数据存放的地址指针
output:
获得的UNICODE 编码存放的地址指针
func:
note:
*/
/************************************************************************/
static UINT8 * get_unicode_ptr(const INT8 *plocal )
{
UINT8 *pbuf;
pbuf = NULL;
if (NULL == gpFS_strbuf)
{
pbuf = (UINT8 *) MEM_ALLOC(FS_NAME_BUF);
if (NULL == pbuf)
{
ERROR_REPORT;
return NULL;
}
// 保存全局指针
gpFS_strbuf = pbuf;
}
else
{
pbuf = gpFS_strbuf; // 使用全局变量保存的内存地址值
}
SPMP_local2uni((UINT8 *)plocal, pbuf);
return pbuf;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -