📄 fscreate.c
字号:
/* ============================================================================ Project Name : jayaCard Module Name : proto/bios/fs/fscreate.c Version : $Id: fscreate.c,v 1.27 2004/04/24 21:13:43 dgil Exp $ Description: Create EF or DF The Original Code is jayaCard code. The Initial Developer of the Original Code is Gilles Dumortier. Portions created by the Initial Developer are Copyright (C) 2002-2004 the Initial Developer. All Rights Reserved. Contributor(s): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see http://www.gnu.org/licenses/gpl.html History Rev Description 040203 dgil wrote it from scratch ============================================================================*/#include "precomp.h"#ifdef JAYA_FILESYSTEM/* ============================================================================ Import from fstools.c ========================================================================= */void __fs_save_EF_header(void);void __fs_save_DF_header(void);void __fs_save_file_header(void);void __fs_load_EF_header(jword link);jword __fs_header_bodysize(void);jbool __fs_isreserved_fid(jword id);/* ============================================================================ __fs_found_header_entry() found an erased header to recycle OR add a new header in the free area, updating header_file_addr. Use a first-fit algorithm. Think about using a best-fist to avoid memory fragmentation ... Some error code in lasterr if any problem. ========================================================================= */void __fs_found_free_header_entry(void){ LOCAL(jword,addr); /* address of the newly header file in EEPROM */ LOCAL(jword,wsize); /* size */ header_file_addr = HAL_EEPROM_READ_WORD(FREE_HEADER_FILE_ADDR); /* begin the seek at the base of headers */ addr = BASE_HEADER_FILE_ADDR; while (addr<header_file_addr) { __fs_load_EF_header(addr); if (lasterr!=SUCCESS) return; if (current_EF.fid == FID_BOGUS) { /* yep - we found a bogus header ! */ LOG1("FSTOOLS","__fs_found_free_header_entry(): looking at 0x%.4X correct a bogus header",addr); HAL_ERASE_XRAM((jbyte xdata*)¤t_EF,sizeof(current_EF)); current_EF.fid = FID_RFU; } if (current_EF.fid == FID_RFU) { /* yep - we found a free header ! */ LOG2("FSTOOLS","__fs_found_free_header_entry(): looking at 0x%.4X size=%d",addr,current_EF.u4.sizefile); #ifdef JAYACFG_FILESYSTEM_ALIAS if ((header_file.fdesc&FDESC_ALIAS)==FDESC_ALIAS) { if ( ((current_EF.fdesc&FDESC_TYPE_MASK)==FDESC_TYPE_DF) || ((current_EF.fdesc&FDESC_ALIAS)==FDESC_ALIAS) ) { /* found an alias file / seek an alias header or DF header => go on ! */ header_file_addr = addr; return; } /* otherwise seek another header ... */ } else #endif if ((header_file.fdesc&FDESC_TYPE_MASK)==FDESC_TYPE_DF) { if ((current_EF.fdesc&FDESC_TYPE_MASK)==FDESC_TYPE_DF) { /* found a DF header / seek a DF header => go on ! */ header_file_addr = addr; return; } /* otherwise seek another header ... */ } else { /* can we also recycle the body ? */ if (current_EF.u4.sizefile>__fs_header_bodysize()) { /* bigger body -> split the body and recycle one of the bodies, creating another header */ LOG2("FSTOOLS","__fs_found_free_header_entry(): bigger body size %d at 0x%.4X - split it and use it",current_EF.u4.sizefile,addr); wsize = current_EF.u4.sizefile - __fs_header_bodysize(); current_EF.u4.sizefile = wsize; header_file.u3.body_ef = current_EF.u3.body_ef + wsize; /* save current_EF with shorter body */ current_EF_addr = addr; __fs_save_EF_header(); if (lasterr!=SUCCESS) return; /* CHECKME __r hmmm */ /* continue with header_file */ } else { if (current_EF.u4.sizefile == __fs_header_bodysize()) { /* same bodies -> direct re-use of the header and bodies */ LOG2("FSTOOLS","__fs_found_free_header_entry(): same body size %d at 0x%.4X - lucky use it",current_EF.u4.sizefile,addr); header_file.u3.body_ef = current_EF.u3.body_ef; header_file_addr = addr; return; } else { /* smaller body -> try another entry */ LOG2("FSTOOLS","__fs_found_free_header_entry(): smaller body size %d at 0x%.4X - continue to search",current_EF.u4.sizefile,addr); header_file.u3.body_ef = 0; } } } } /* no luck - try next header */ addr += SIZE_HEADER_FILE; } /* no free header found - create a new one ! if we have enough room ... */ if ((header_file_addr+SIZE_HEADER_FILE)>=HAL_EEPROM_READ_WORD(FREE_BODY_FILE_ADDR)) { LOG2("FSTOOLS","__fs_found_free_header_entry(): header_file_addr: 0x%.4X free_body_file_addr: 0x%.4X hmmm....", header_file_addr, HAL_EEPROM_READ_WORD(FREE_BODY_FILE_ADDR) ); BIOS_SETERR(ERR_OUT_OF_MEMORY); return; } /* note for code below: mark the free header not used - just in case we failed in the following code (updating the FREE_HEADER_FILE_ADDR pointer), we should be able to re-use this unused header at later time __r XXX we have a performance issue on create file because header file will be written twice ... */ addr = header_file.fid; header_file.fid = FID_BOGUS; __fs_save_file_header(); if (lasterr!=SUCCESS) return; header_file.fid = addr; /* update the pointer FREE_HEADER_FILE_ADDR */ if (HAL_EEPROM_WRITE_WORD(FREE_HEADER_FILE_ADDR,header_file_addr+SIZE_HEADER_FILE) != EEPROM_HAL_OK) { BIOS_SETERR(ERR_WRITE_ERROR); return; }}/* ============================================================================ __fs_create_file() current_DF would be the parent of the newly created file header_file is the file under creation. Some error code in lasterr if any problem. ========================================================================= */void __fs_create_file(void){ LOCAL(jword,free); /* free body area pointer */ LOCAL(jword,rsize); /* requested size */ LOCAL(jbyte,res); rsize = __fs_header_bodysize(); LOG4("FS","__fs_create_file(): fid=0x%.4X size=%d under DF %.4X/%.4X",header_file.fid,rsize,current_DF.fid,current_DF_addr); /* don't ask too much memory, please ! */ if (rsize >= MIN(0x7FFF,SIZE_EEPROM)) { LOG2("FS","__fs_create_file(): file fid=0x%.4X INVALID_LENGTH requested (%.4X) !",header_file.fid,rsize); BIOS_SETERR(ERR_INVALID_LENGTH); return; } if ((header_file.fdesc&FDESC_TYPE_LINEAR) == FDESC_TYPE_LINEAR) { LOG1("FS","__fs_create_file(): record file fid=0x%.4X some record parameter invalid !",header_file.fid); if ( (header_file.u4.record.nummax == 0) || (header_file.u4.record.nummax > 0xFE) || (header_file.u4.record.size == 0) ) { BIOS_SETERR(ERR_INVALID_PARAMETER); return; } } /* something to create ? */ if (((header_file.fdesc&FDESC_TYPE_MASK) != FDESC_TYPE_DF) && (rsize==0)) { LOG1("FS","__fs_create_file(): EF file fid=0x%.4X can't create 0 bytes content !",header_file.fid); BIOS_SETERR(ERR_INVALID_LENGTH); return; } /* check reserved FIDs and FID != FID of the parent */ if ((__fs_isreserved_fid(header_file.fid)) || (header_file.fid == current_DF.fid) ) { LOG1("FS","__fs_create_file(): file fid=0x%.4X INVALID !",header_file.fid); BIOS_SETERR(ERR_INVALID_FID); return; } /* check that we have append access in the current DF */ gGlobalSem = JSEC_FAIL; res = FS_CHECK_AC(ACC_CHECK_DF|ACC_CREATE_FILE); gGlobalSem++; if (res != JSEC_OK) { BIOS_SETERR(ERR_ACCESS_DENIED); return; } if (gGlobalSem!=JSEC_SEM) { LOG("ATTACK","__fs_create_file() #1 - check security failure !"); BIOS_SETERR(ERR_ACCESS_DENIED); HAL_HALT(); return; } /* check that the file doesn't already exist (check file id) */ FS_LOOKUP_FID(header_file.fid,LOOKUP_MODE_DEFAULT); if (lasterr==ERR_FILE_NOT_FOUND) { LOG1("FS","__fs_create_file(): file fid=0x%.4X not found - can create it",header_file.fid); lasterr = SUCCESS; /* we can continue ... */ } else if (lasterr==SUCCESS) { /* file already exist ! */ LOG1("FS","__fs_create_file(): file fid=0x%.4X ALREADY EXIST !",header_file.fid); BIOS_SETERR(ERR_FILE_ALREADY_EXIST); return; } else { /* internal fault to report */ LOG2("FS","__fs_create_file(): fid=0x%.4X err=%d INTERNAL FAULT !",header_file.fid,lasterr); /* __r XXX internal fault ?! */ return; } /* reserve the header place in EEPROM and update header_file_addr according */ __fs_found_free_header_entry(); if (lasterr!=SUCCESS) return; LOG3("FS","__fs_create_file(): FOUND fid=0x%.4X header_file_addr=0x%.4X body_addr=%.4X", header_file.fid, header_file_addr, header_file.u3.body_ef ); /* reserve the body in EEPROM if required and fill header_file.u3.body_ef with it */ if ((header_file.fdesc&FDESC_TYPE_MASK)!=FDESC_TYPE_DF) { if (header_file.u3.body_ef==0) { /* not already reserved by recyclage of a previous deleted file */ header_file.u3.body_ef = HAL_EEPROM_READ_WORD(FREE_BODY_FILE_ADDR) - rsize; free = header_file.u3.body_ef - 1; /* enough room ? */ if (free<=HAL_EEPROM_READ_WORD(FREE_HEADER_FILE_ADDR)) { LOG3("FS","__fs_create_file(): file fid=0x%.4X OUT OF MEMORY free=%.4X FREE_HEADER_FILE_ADDR=%.4X", header_file.fid,free,HAL_EEPROM_READ_WORD(FREE_HEADER_FILE_ADDR)); BIOS_SETERR(ERR_OUT_OF_MEMORY); return; } /* update the pointer FREE_BODY_FILE_ADDR */ if (HAL_EEPROM_WRITE_WORD(FREE_BODY_FILE_ADDR,free) != EEPROM_HAL_OK) { BIOS_SETERR(ERR_WRITE_ERROR); return; } LOG3("FS","__fs_create_file(): file fid=0x%.4X body=%.4X FREE_BODY_FILE_ADDR=%.4X", header_file.fid,header_file.u3.body_ef,HAL_EEPROM_READ_WORD(FREE_BODY_FILE_ADDR)); } } else { /* link the DF with its parent */ header_file.u3.parent = current_DF_addr; } LOG4("FS","__fs_create_file(): update parent DF %.4X/%.4X link ; next:%.4X first:%.4X",current_DF.fid,current_DF_addr,current_DF.u4.first_file,header_file_addr); header_file.u2.next_file = current_DF.u4.first_file; current_DF.u4.first_file = header_file_addr; /* flush the headers to EEPROM */ __fs_save_file_header(); if (lasterr!=SUCCESS) return; __fs_save_DF_header(); if (lasterr!=SUCCESS) return; /* CHECKME __r hmmm */}/* ========================================================================= That's all folks ! ========================================================================= */#endif/* JAYA_FILESYSTEM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -