?? pmp_fs_api_za.c
字號:
/*-------------------------------------------------*
* $RCSfile: pmp_fs_api_ZA.c,v $
* $Date: 2007/01/17 12:28:43 $
* $Author: lanzhu $
* $Log: pmp_fs_api_ZA.c,v $
* Revision 1.1.1.1 2007/01/17 12:28:43 lanzhu
* 齊蘭柱 準備一個新的代碼分支
*
* Revision 1.4 2006/12/29 07:24:45 lanzhu
* 在進行ZA_fread ZA_fwrite 時, 進行CACHE 的清空動作
*
* Revision 1.3 2006/12/18 02:14:27 taiyun
* Modify include filename
*
* Revision 1.2 2006/12/12 00:29:29 lanzhu
* pmp_fs_ZA.c 修改了一個 讀單個字符出錯的BUG, 去除WARNING
*
* Revision 1.1.1.1 2006/12/05 03:01:16 lanzhu
* no message
*
* Revision 1.1.1.1 2006/12/01 09:49:35 lanzhu
* no message
*
* Revision 1.9 2006/10/13 06:10:24 taoli
* 函數中malloc改為棧內申請
*
* Revision 1.8 2006/10/13 01:34:00 taoli
* modify ZA_chdir
*
* Revision 1.7 2006/10/12 09:22:05 taoli
* ZA_access函數檢測不存在的文件返回為存在,錯誤,已修改.
*
* Revision 1.6 2006/09/23 07:18:37 lanzhu
* 修改了get_unicode_ptr 的一個BUG
*
* Revision 1.5 2006/09/20 12:35:00 lanzhu
* 添加了編碼的轉換功能,并逐個進行了測試
*
* Revision 1.4 2006/09/19 08:49:05 taoli
* modify readdir
*
* Revision 1.3 2006/09/19 07:12:27 lanzhu
* 添加了 rewinddir 函數
*
* Revision 1.2 2006/09/11 12:29:13 lanzhu
* 對所發布的ZA FS API 進行測試, 初步測試OK!
*
* Revision 1.1 2006/09/08 01:05:08 lanzhu
* 為移植專案的程序,進行了FS API 的封裝
*
*
*--------------------------------------------------*/
//#define DEBUG_ZA_FS
#define CHANGE_CODE
#include <ctype.h>
#include <string.h>
#include "SPMP_define.h"
#include "os_api.h"
#include "fs_api.h"
#include "za_fs_api.h"
#include "appdriver.h"
#include "SysUtility.h"
// 定義為專案的接口形式
#define _FOR_A3K_PROG
/**************************************************************************
* G E N E R A L C O N S T A N T S *
**************************************************************************/
#define THE_LAST_DIR (0)
#define FS_NAME_BUF (1024)
/**************************************************************************
* M A C R O S *
**************************************************************************/
/**************************************************************************
* D A T A T Y P E S *
**************************************************************************/
/**************************************************************************
* G L O B A L D A T A *
**************************************************************************/
// 進行碼值轉換時使用的內存
static UINT8 *gpFS_strbuf = NULL;
// 進行句柄、指針的轉換
static UINT8 pFHandleBegin;
// FAT 短文件名目錄項中不允許出現的字符, 共10個字符
static const INT8 fnamekeyword[] = "\\/:*?\"<>|";
#define PERSVSUM 34
// WINDOWS FAT 保留的不能作為文件名的字符串
static const INT8 *fnamepersive[PERSVSUM] =
{
"COM1",
"COM2",
"COM3",
"COM4",
"COM5",
"COM6",
"COM7",
"COM8",
"COM9",
"COM10",
"COM11",
"COM12",
"COM13",
"COM14",
"COM15",
"COM16",
"LPT1",
"LPT2",
"LPT3",
"LPT4",
"LPT5",
"LPT6",
"LPT7",
"LPT8",
"LPT9",
"LPT10",
"LPT11",
"LPT12",
"LPT13",
"LPT14",
"LPT15",
"LPT16",
"CON",
"PRN"
};
/**************************************************************************
* E X T E R N A L R E F E R E N C E S *
**************************************************************************/
// lanzhu add @[12/29/2006]
extern void mmuFlushDCache( void );
/**************************************************************************
* F U N C T I O N D E C L A R A T I O N S *
**************************************************************************/
// 根據輸入的字符串,獲得打開模式的內部定義值
static INT16 QFS_get_open_mode( INT8 * in_str);
// 檢查輸入的文件名是否含有非法字符
static INT32 QFS_check_fname(INT8 *name );
// 通過邏輯盤的字符串獲得邏輯盤的內部代號
static UINT16 get_devid_by_name( UINT8 * pDevName, UINT16 *pDevID);
// 從一個多級目錄串中,只取出一級目錄文本串
static INT16 get_dir_from_str(const INT8 *in_str, INT8 *out_str);
// 從ZA 接口層的句柄指針中, 獲得文件句柄代碼值
static INT16 get_file_handle( void * stream, UINT32 *pHandle );
// 獲得 UNICOE 編碼的地址指針
static UINT8 * get_unicode_ptr(const INT8 *plocal);
/************************************************************************/
/*
*/
/************************************************************************/
#ifdef DEBUG_ZA_FS
void test_za_fs( void )
{
INT32 err;
UINT8 *pdir;
FILE_INFO tmp_info;
struct f_info tinfo;
UINT8 buffer[0x100];
UINT8 *pfile;
/*
pfile = ZA_fopen("D:\\阿健康法活動都將返回家","W");
ZA_fclose(pfile);
*/
/*
err = ZA_access("03. 草原之夜.mp3", F_OK);
DEBUG_OUTPUT(("err 0x%x\r\n", err));
*/
// stat OK!
err = ZA_stat("03. 草原之夜.mp3", &tinfo);
DEBUG_OUTPUT(("attr: 0x%x\r\n", tinfo.attribute));
DEBUG_OUTPUT(("size: %d\r\n", tinfo.file_size));
/*
//chdir opendir readdir closedir TEST OK!
DEBUG_OUTPUT(("\r\ntest ZA begin!\r\n"));
ZA_chdir("D:\\AUDIO");
pdir = ZA_opendir("D:\\");
DEBUG_OUTPUT(("%x \r\n", pdir));
while (1)
{
err = ZA_readdir(pdir, buffer, &tmp_info);
if ( !err ){
DEBUG_OUTPUT(("+++++ %s\r\n", buffer));
DEBUG_OUTPUT(("+++++ %x\r\n", tmp_info.attribute));
continue;
}
break;
}
err = ZA_closedir( pdir );
DEBUG_OUTPUT(("%x \r\n", err));
ZA_getcwd(buffer, sizeof(buffer));
DEBUG_OUTPUT(("CWD: %s\r\n", buffer));
*/
/*
ZA_init();
err = fsFormat(1);
DEBUG_OUTPUT(("000 err %x\r\n", err));
err = fsMount(1);
DEBUG_OUTPUT(("0'' err %x\r\n", err));
*/
err = ZA_mkdir("D:\\阿阿阿111222");
sio_printf("mkdir err:%x\r\n", err);
err = ZA_chdir("D:\\阿阿阿111222");
sio_printf("chdir err:%x\r\n", err);
err = ZA_chdir("AAABBB111222");
sio_printf("chdir err:%x\r\n", err);
err = ZA_getcwd(buffer, sizeof(buffer));
sio_printf("%s\r\n", buffer);
while (1);
}
#endif
/************************************************************************/
/* QFS_init
input:
void
output:
void
func:
在使用 QFS layer之前,進行初始化的動作
note:
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
void QFS_init( void )
#else
void ZA_init( void )
#endif
{
/*
UINT8 *pbuf;
// 進行內存的申請
pbuf = MEM_ALLOC( FS_NAME_BUF );
if (NULL == pbuf) {
ERROR_REPORT;
return;
}
// 保存內存指針
gpFS_strbuf = pbuf;
*/
return;
}
/************************************************************************/
/* QFS_stat
input:
fname 文件名字符串的指針, 支持全路徑名
finfo 文件信息結構體的指針
output:
0 成功 從 info 結構體中獲取文件信息
<0 失敗
function:
獲得文件的屬性信息 時間 長度 占用空間的大小 讀寫屬性
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_stat(INT8 * pfile_name, struct f_info * pfileinfo)
#else
INT32 ZA_stat (INT8 * pfile_name, struct f_info * pfileinfo)
#endif
{
UINT16 err;
File_Info_t FileInfoAttr;
INT8 *file_name;
// 判斷輸入參數是否合法
if ((NULL == pfile_name) || (NULL == pfileinfo) ){
ERROR_REPORT;
return QFS_ERR;
}
#ifndef CHANGE_CODE
file_name = pfile_name;
#else
file_name = get_unicode_ptr(pfile_name);
#endif
// 將輸入進行清空的動作
memset( pfileinfo, 0x00, sizeof(struct f_info));
// 獲得文件屬性信息
err = fsFileInfoGet(file_name, &FileInfoAttr);
if ( err ) {
ERROR_REPORT;
return QFS_ERR;
}
// 進行信息的復制
pfileinfo->attribute = FileInfoAttr.attr;
pfileinfo->file_size = FileInfoAttr.fileSize;
pfileinfo->f_tm.tm_year = FileInfoAttr.tCreate.tm_year;
pfileinfo->f_tm.tm_mon = FileInfoAttr.tCreate.tm_mon;
pfileinfo->f_tm.tm_mday = FileInfoAttr.tCreate.tm_mday;
pfileinfo->f_tm.tm_hour = FileInfoAttr.tCreate.tm_hour;
pfileinfo->f_tm.tm_min = FileInfoAttr.tCreate.tm_min;
pfileinfo->f_tm.tm_sec = FileInfoAttr.tCreate.tm_sec;
// 返回成功
return QFS_OK;
}
/************************************************************************/
/*
input:
drvname 邏輯盤字符串指針
output:
0 成功 非0值 失敗
func:
格式化指定的邏輯盤
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_formart(const INT8 * drvname)
#else
INT32 ZA_formart(const INT8 * drvname)
#endif
{
UINT16 dev;
UINT16 err;
// 判斷輸入參數是否合法
if (NULL == drvname) {
ERROR_REPORT;
return NULL;
}
// 通過邏輯設備驅動器的名稱, 獲得內部設備ID
err = get_devid_by_name( (UINT8 *)drvname, &dev );
if ( err ) {
ERROR_REPORT;
return NULL;
}
// 進行邏輯盤的格式化
err = fsFormat( (UINT8) dev );
// 返回結果
return err;
}
/************************************************************************/
/* QFS_open
input:
file_name [in] 文件名字符串指針, // 可以支持全路徑
"C:\\A.BIN"
"C:\\DIR111\\A.BIN"
mode [in] 文件打開模式字符串指針
"R" // 只讀方式,文件必須已經存在
"R+" // 讀寫方式, 文件必須已經存在
"W" // 只寫方式,不存在,則創建,存在則,清空全部內容
"W+" // 讀寫方式,不存在,則創建,存在則,清空全部內容
"A" // 添加模式,不存在,則創建,存在則,打開,指針指向文件尾
"A+" // 添加模式,不存在,則創建,存在則,打開,指針指向文件尾
output:
NULL 失敗
其他值 成功
func:
輸入文件名字符串和文件打開模式, 打開文件
note:
[6/5/2006] 增加對文件名 合法性的檢查
如果輸入的文件名中 含有 windows FAT 所不允許的 字符, 直接返回失敗
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
ZA_FILE * QFS_fopen(const INT8 *pfile_name, const INT8 * mode)
#else
ZA_FILE * ZA_fopen(const INT8 *pfile_name, const INT8 * mode)
#endif
{
// INT32 i;
INT16 open_mode;
INT32 vfs_open_flag;
UINT16 err;
UINT32 FileHandle;
INT8 *file_name;
err = 0x00;
// 判斷輸入參數是否合法, 非法直接返回失敗
if( (pfile_name == NULL) || (mode == NULL) ){
ERROR_REPORT;
return NULL;
}
#ifndef CHANGE_CODE
file_name = pfile_name; // 直接使用文件名字符串
#else
file_name = get_unicode_ptr(pfile_name);
#endif
// 獲得打開模式
open_mode = QFS_get_open_mode((INT8 *) mode ); // 獲得文件的打開模式
if(open_mode <0 ){
ERROR_REPORT;
return NULL;
}
// 暫時不進行打開文件的總數檢查動作
// 556 系統上可以支持全路徑文件名的打開, 不需要進行目錄的逐級切換
/*
// 對輸入的文件名,進行檢查, 如果含有 windows FAT 不允許的字符,直接返回失敗
i = QFS_check_fname( (INT8 *)file_name );
// 字符串非法, 直接返回失敗
if(i) {
ERROR_REPORT;
return NULL; // 返回NULL 指針
}
*/
vfs_open_flag = 0x00;
switch(open_mode)
{
case F_O_RDONLY: // R
case F_O_RD_PLUS: // R+
vfs_open_flag = FS_O_RDONLY; // 以只讀的方式
if( open_mode == F_O_RD_PLUS )
{
DEBUG_OUTPUT((" Mode: read write! \r\n "));
vfs_open_flag = FS_O_RDWR; // 以讀寫的方式
}
// 使用 SPMP 內部文件函數實現
err = fsOpen((UINT8 *)file_name, (UINT32) vfs_open_flag, &FileHandle);
break;
case F_O_WRONLY: // W
case F_O_WR_PLUS: // W+
// 進行文件的刪除動作
err = fsDelete((UINT8 *)file_name );
// 創建文件,以讀寫的方式進行文件的操作
err = fsOpen((UINT8 *)file_name, (UINT32) FS_O_RDWR | FS_O_CREATE, &FileHandle);
break;
case F_O_APPEND: // A
case F_O_APPEND_PLUS: // A+
// 以讀寫的方式打開文件
err = fsOpen((UINT8 *)file_name, (UINT32) FS_O_RDWR, &FileHandle);
// 文件可以打開,說明文件存在,移動文件指針到文件尾
if (err){
err = fsSeek(FileHandle, (UINT32)FS_SEEK_END, 0x00);
}
else{ // 進行文件的創建動作
err = fsOpen((UINT8 *)file_name, (UINT32) FS_O_RDWR | FS_O_CREATE, &FileHandle);
}
break;
default:
ERROR_REPORT;
break;
}
// 判斷是否有錯誤發生
if ( err ) {
ERROR_REPORT;
return NULL;
}
return (&pFHandleBegin + FileHandle);
}
/************************************************************************/
/* QFS_fread
input:
buf [out] 數據讀出后存放的地址值
unit_size [in] 一個數據單位的長度值
unit_count [in] 數據單位的數量
stream [in] 文件句柄的指針
output:
< 0 失敗
>= 0 成功
func:
進行進行文件的讀動作
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_fread (INT8 *buf, UINT32 unit_size, UINT32 unit_count, ZA_FILE * stream )
#else
INT32 ZA_fread (INT8 *buf, UINT32 unit_size, UINT32 unit_count, ZA_FILE * stream )
#endif
{
UINT16 err;
UINT32 BytesWant2Read;
UINT32 BytesRead;
UINT32 FileHandle;
// 判斷輸入參數的合法性
if ( (NULL == buf) || (NULL == stream)
|| !unit_size || !unit_count )
{
ERROR_REPORT;
return (INT32) QFS_ERR;
}
err = get_file_handle(stream, &FileHandle);
if ( err ){
ERROR_REPORT;
return (INT32) QFS_ERR;
}
// 計算需要讀出的數據的總數
BytesWant2Read = unit_size * unit_count;
// lanzhu add@[12/29/2006]
mmuFlushDCache( );
// 使用內部函數進行數據的讀取動作
err = fsRead( (UINT32) FileHandle, buf, BytesWant2Read, &BytesRead );
if ( err ) {
ERROR_REPORT;
return (INT32) QFS_ERR;
}
// 返回數據單位的總數
return (INT32) BytesRead/unit_size;
}
/************************************************************************/
/* QFS_fwrite
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -