📄 fsrecords.c
字号:
/* ============================================================================ Project Name : jayaCard Module Name : proto/bios/fs/fsrecords.c Version : $Id: fsrecords.c,v 1.11 2004/01/11 09:56:30 dgil Exp $ Description: Records management 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 050703 dgil wrote it from scratch ============================================================================*/#include "precomp.h"#ifdef JAYA_FILESYSTEM_RECORD/* ============================================================================ Import from fstools.c ========================================================================= */void __fs_save_EF_header(void);/* ============================================================================ __fs_set_record_EF(logical_recnum,command) Convert logical record number to physical record number, updating current_recnum. logical_recnum : 0 -> keep the current physical record number Assume: - current_EF must be a linear or cyclic file - current_recnum positionned to the current physical record number ========================================================================= */void __fs_set_record_EF(jbyte logrecnum,jbyte cmd){ if ((current_EF.fdesc&FDESC_TYPE_MASK)==FDESC_TYPE_CYCLIC) { /* cyclic record based */ switch (cmd) { case LAST_RECORD: { current_recnum = current_EF.u5.record.top; goto check_recnum_cyclic; } break; case NEXT_RECORD: { current_recnum = current_recnum + 1; if (current_recnum > current_EF.u5.record.top) { current_recnum = 0; } goto check_recnum_cyclic; } break; case PREV_RECORD: { if (current_recnum>0) { current_recnum = current_recnum - 1 ; } else { current_recnum = current_EF.u5.record.top; } goto check_recnum_cyclic; } break; case FIRST_RECORD: { logrecnum = 1;check_recnum_cyclic: if (current_recnum>=current_EF.u5.record.num) { BIOS_SETERR(ERR_RECORD_NOT_FOUND); current_recnum = current_EF.u5.record.top; } } // fall-through case SET_RECORD: default: { /* current record number */ if (logrecnum==0) return; /* check the record number */ if (logrecnum>current_EF.u5.record.num) { BIOS_SETERR(ERR_RECORD_NOT_FOUND); current_recnum = current_EF.u5.record.top; } else { current_recnum = (current_EF.u5.record.top - logrecnum) % current_EF.u4.record.nummax; } } break; } } else { switch (cmd) { case FIRST_RECORD: { current_recnum = 0; goto check_recnum_flat; } break; case PREV_RECORD: { if (current_recnum>0) { current_recnum = current_recnum - 1 ; goto check_recnum_flat; } BIOS_SETERR(ERR_RECORD_NOT_FOUND); current_recnum = 0; } break; case LAST_RECORD: { current_recnum = current_EF.u5.record.num - 1; goto check_recnum_flat; } break; case NEXT_RECORD: { current_recnum = current_recnum + 1 ; goto check_recnum_flat; } break; case SET_RECORD: default: { /* current record number */ if (logrecnum==0) return; /* linear record based */ current_recnum = logrecnum - 1;check_recnum_flat: /* check the record number */ if (current_recnum>=current_EF.u5.record.num) { BIOS_SETERR(ERR_RECORD_NOT_FOUND); current_recnum = 0; } } break; } }}/* ============================================================================ __fs_append_record_EF() append a physical record number, updating both current_EF header and current_recnum. Assume: - current_EF must be a linear or cyclic file ========================================================================= */void __fs_append_record_EF(void){ if ((current_EF.fdesc&FDESC_TYPE_MASK)==FDESC_TYPE_CYCLIC) { /* cyclic record based*/ if (current_EF.u5.record.num<current_EF.u4.record.nummax) { /* one more in use ! */ current_EF.u5.record.num++; } current_recnum = current_EF.u5.record.top; current_EF.u5.record.top = (current_EF.u5.record.top + 1) % current_EF.u4.record.nummax; } else { /* linear file : append at the end if enough space */ /* check we have enough space */ if (current_EF.u5.record.num>=current_EF.u4.record.nummax) { LOG1("RECORD","__fs_append_record_EF() - no more room ! max=%d ",current_EF.u4.record.nummax); BIOS_SETERR(ERR_OUT_OF_MEMORY); return; } /* set the current physical record number */ current_recnum = current_EF.u5.record.num; current_EF.u5.record.num++; LOG2("RECORD","__fs_append_record_EF() - current_recnum = %d max = %d ",current_recnum,current_EF.u5.record.num); }}/* ============================================================================ __fs_check_record_EF Parameters: len number of bytes to access Assume: - current_EF must be a linear or cyclic file - current_recnum positionned to the current physical record number Secure: use the global semaphore ========================================================================= */void __fs_check_record_EF(jbyte len){ gGlobalSem = JSEC_OK; /* check we have a current EF */ if (current_EF_addr==NO_CURRENT_FILE) { LOG("RECORD","__fs_check_record_EF() - no current file !"); BIOS_SETERR(ERR_NO_EF_SELECTED); return; } /* check it is a record exportable content __r XXX: Life vs InternalEF */ if ((current_EF.fdesc&(FDESC_TYPE_LINEAR|FDESC_INTERNAL_EF))!=(FDESC_TYPE_LINEAR)) { LOG1("RECORD","__fs_check_record_EF() - invalid file type fdesc=%.2X",current_EF.fdesc); BIOS_SETERR(ERR_INVALID_FILE_TYPE); return; } gGlobalSem++; /* check record number */ if (current_recnum>=current_EF.u5.record.num) { LOG2("RECORD","__fs_check_record_EF() - current_recnum %d not found (num=%d)",current_recnum,current_EF.u5.record.num); BIOS_SETERR(ERR_RECORD_NOT_FOUND); return; } gGlobalSem--; /* check len */ if ((len==0) || (len>current_EF.u4.record.size)) { LOG2("RECORD","__fs_check_record_EF() - invalid length %d (max=%d)",len,current_EF.u4.record.size); BIOS_SETERR(ERR_INVALID_LENGTH); return; } /* ok, all seems perfect */ gGlobalSem++;}/* ============================================================================ __fs_read_record_EF() Parameters: len number of bytes to read Use: streamSrc to read the file from the EEPROM streamDest to output the bytes Assume: - current_EF must be a linear or cyclic file - current_EF is not an internal EF - current_recnum positionned to the current physical record number ========================================================================= */void __fs_read_record_EF(jbyte len){ LOG2("RECORD","__fs_read_record_EF() - current_recnum=%d len=%d",current_recnum,len); /* check file type, record number and requested size */ gGlobalSem = JSEC_FAIL; __fs_check_record_EF(len); if (lasterr!=NOERR) return; gGlobalSem++; /* initialize the stream */ BIOS_INIT_STREAM_FROM_CURRENT_EF(&streamSrc); if (lasterr != SUCCESS) { LOG1("RECORD","__fs_read_record_EF() - BIOS_INIT_STREAM_FROM_CURRENT_EF reports error %d !",lasterr); return; } if ((streamSrc.m_flags & READ_STREAM) != READ_STREAM) { /* Read access not allowed */ BIOS_SETERR(ERR_ACCESS_DENIED); return; } streamDest.m_flags = WRITE_STREAM|IO_STREAM; /* __x XXX |CIPHER_STREAM if SM */ streamDest.m_flags2 = INS_IND_STREAM; /* update the source stream with the offset */ streamSrc.m_pos += current_recnum*current_EF.u4.record.size; /* check security */ if (gGlobalSem!=JSEC_SEM) { LOG("RECORD","__fs_read_record_EF() - check security failure !"); HAL_HALT(); return; } /* stream to stream */ (void)BIOS_STREAM2STREAM(&streamDest,&streamSrc,len);}/* ============================================================================ __fs_update_record_EF() Parameters: len number of bytes to write bAfterAppend update just after an append has been done Use: streamSrc to get the input bytes streamDest to update the bytes in the EEPROM Assume: - current_EF must be a linear or cyclic file - current_EF is not an internal EF - current_recnum positionned to the current physical record number ========================================================================= */void __fs_update_record_EF(jbyte len,jbool bAfterAppend){ LOCAL(jbyte,lSec); LOG3("RECORD","__fs_update_record_EF() - current_recnum=%d len=%d bAfterAppend=%d",current_recnum,len,bAfterAppend); /* check file type, record number and requested size */ gGlobalSem = JSEC_FAIL; __fs_check_record_EF(len); if (lasterr!=NOERR) return; gGlobalSem++; /* initialize the stream */ BIOS_INIT_STREAM_FROM_CURRENT_EF(&streamDest); if (lasterr != SUCCESS) { LOG1("RECORD","__fs_update_record_EF() - BIOS_INIT_STREAM_FROM_CURRENT_EF reports error %d !",lasterr); return; } /* check security */ if (gGlobalSem!=JSEC_SEM) { LOG("ATTACK","__fs_update_record_EF() #1 - check security failure !"); HAL_HALT(); return; } if (bAfterAppend) { /* append a record : we must have APPEND access ! */ LOG("RECORD","__fs_update_record_EF() - APPEND mode check access !"); streamDest.m_flags &= ~WRITE_STREAM; gGlobalSem = JSEC_FAIL; lSec = FS_CHECK_AC(ACC_CHECK_EF|ACC_APPEND); gGlobalSem++; if ((JSEC_OK == lSec) && (gGlobalSem == JSEC_SEM)) streamDest.m_flags |= WRITE_STREAM; if (gGlobalSem!=JSEC_SEM) { LOG("ATTACK","__fs_update_record_EF() #2 - check security failure !"); HAL_HALT(); return; } } /* update a record : we must have WRITE access ! */ if ((streamDest.m_flags & WRITE_STREAM) != WRITE_STREAM) { /* write (or append) access not allowed */ LOG("RECORD","__fs_update_record_EF() - WRITE/APPEND ACCESS DENIED !"); BIOS_SETERR(ERR_ACCESS_DENIED); return; } streamSrc.m_flags = READ_STREAM|IO_STREAM; /* __x XXX |CIPHER_STREAM if SM */ streamSrc.m_flags2 = 0x00; /* update the destination stream with the offset */ streamDest.m_pos += current_recnum*current_EF.u4.record.size; streamDest.m_flags2 |= INS_IND_STREAM; /* stream to stream */ (void)BIOS_STREAM2STREAM(&streamDest,&streamSrc,len); if (lasterr!=NOERR) return; /* update the file header now ! */ if (bAfterAppend) { LOG("RECORD","__fs_update_record_EF() - APPEND: update the header file with new record pointers !"); __fs_save_EF_header(); }}/* ========================================================================= That's all folks ! ========================================================================= */#endif/* JAYA_FILESYSTEM_RECORD */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -