mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-06 22:04:10 +08:00
先把cheatlib的代码放上去,本地改个版本试试windows上的运行结果,修完bug再更新
This commit is contained in:
parent
a2bada407d
commit
22194bdb64
@ -9,60 +9,61 @@
|
|||||||
#define ACL_ENTRY_HOLE 1
|
#define ACL_ENTRY_HOLE 1
|
||||||
#define ACL_ENTRY_KEY 2
|
#define ACL_ENTRY_KEY 2
|
||||||
|
|
||||||
|
#define ACHTLIB_SUCCESS 0
|
||||||
|
#define ACHTLIB_NOT_OPEN 1
|
||||||
|
#define ACHTLIB_NOT_FOUND 2
|
||||||
|
#define ACHTLIB_INVALID 3
|
||||||
|
#define ACHTLIB_NOMEM 4
|
||||||
|
|
||||||
typedef int acl_error_t;
|
typedef int acl_error_t;
|
||||||
typedef void * acl_lib_t;
|
|
||||||
typedef void * acl_list_t;
|
|
||||||
typedef void * acl_config_t;
|
|
||||||
typedef void * acl_entry_t;
|
|
||||||
typedef const char* acl_text_t;
|
typedef const char* acl_text_t;
|
||||||
typedef uint8_t acl_boolean_t;
|
typedef uint8_t acl_boolean_t;
|
||||||
typedef uint8_t acl_cheatid_t;
|
typedef uint32_t acl_chtid_t;
|
||||||
|
typedef uint32_t acl_chtpos_t;
|
||||||
|
typedef char acl_region_t;
|
||||||
typedef uint32_t acl_entryid_t;
|
typedef uint32_t acl_entryid_t;
|
||||||
typedef uint8_t acl_entrytype_t;
|
typedef uint16_t acl_elemlen_t;
|
||||||
typedef uint16_t acl_entrylen_t;
|
|
||||||
typedef uint16_t acl_index_t;
|
typedef uint16_t acl_index_t;
|
||||||
|
typedef uint32_t acl_count_t;
|
||||||
typedef uint32_t acl_armcode_t;
|
typedef uint32_t acl_armcode_t;
|
||||||
|
|
||||||
acl_error_t acl_open_lib(
|
acl_error_t acl_open_lib(
|
||||||
INPUT(acl_text_t) path_for_cht_file,
|
INPUT(acl_text_t) path_for_cht_file
|
||||||
OUTPUT(acl_lib_t) library_instance
|
);
|
||||||
|
|
||||||
|
acl_error_t acl_close_lib(
|
||||||
|
void
|
||||||
);
|
);
|
||||||
|
|
||||||
acl_error_t acl_select_game(
|
acl_error_t acl_select_game(
|
||||||
INPUT(acl_lib_t) library_instance,
|
INPUT(acl_text_t) code_for_game,
|
||||||
INPUT(acl_text_t) code_for_game,
|
INPUT(acl_boolean_t) check_language_for_code,
|
||||||
INPUT(acl_boolean_t) check_language_for_code,
|
OUTPUT(acl_count_t) cheat_set_count_for_game
|
||||||
OUTPUT(acl_list_t) cheat_list_instance
|
|
||||||
);
|
);
|
||||||
|
|
||||||
acl_error_t acl_load_cheat(
|
acl_error_t acl_query_cheat_set(
|
||||||
INPUT(acl_list_t) cheat_list_instance,
|
INPUT(acl_index_t) cheat_set_index,
|
||||||
INPUT(acl_cheatid_t) cheat_id,
|
OUTPUT(acl_chtid_t) cheat_set_id,
|
||||||
OUTPUT(acl_config_t) config_instance
|
OUTPUT(acl_region_t) cheat_set_region
|
||||||
);
|
);
|
||||||
|
|
||||||
acl_error_t acl_visit_config(
|
acl_error_t acl_select_cheat_set(
|
||||||
INPUT(acl_config_t) config_instance,
|
INPUT(acl_index_t) cheat_set_id
|
||||||
INPUT(acl_entryid_t) entry_id,
|
|
||||||
OUTPUT(acl_entry_t) entry_instance
|
|
||||||
);
|
);
|
||||||
|
|
||||||
acl_entrytype_t acl_entry_type(
|
acl_error_t acl_select_entry(
|
||||||
INPUT(acl_entry_t) entry_instance
|
INPUT(acl_entryid_t) entry_id,
|
||||||
|
OUTPUT(acl_elemlen_t) entry_element_count
|
||||||
);
|
);
|
||||||
|
|
||||||
acl_entrylen_t acl_entry_length(
|
acl_error_t acl_entry_get_label(
|
||||||
INPUT(acl_entry_t) entry_instance
|
INPUT(acl_index_t) index_of_entry_element,
|
||||||
|
OUTPUT(acl_text_t) label_of_entry_element
|
||||||
);
|
);
|
||||||
|
|
||||||
acl_text_t acl_entry_label(
|
acl_error_t acl_entry_get_armcode(
|
||||||
INPUT(acl_entry_t) entry_instance,
|
INPUT(acl_index_t) index_of_entry_element,
|
||||||
INPUT(acl_index_t) index_of_entry
|
OUTPUT(acl_armcode_t) arm_code_of_entry_element
|
||||||
);
|
|
||||||
|
|
||||||
acl_armcode_t acl_entry_value(
|
|
||||||
IPUT(acl_entry_t) entry_instance,
|
|
||||||
INPUT(acl_index_t) index_of_entry
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif//_ANOD_CHEAT_LIBRARY_
|
#endif//_ANOD_CHEAT_LIBRARY_
|
419
source/arm11/acl.c
Normal file
419
source/arm11/acl.c
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
#include "arm11/acl.h"
|
||||||
|
#include "fs.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t typeloc;
|
||||||
|
uint32_t cfgid;
|
||||||
|
} CheatCfg;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FHandle fd; // acl文件
|
||||||
|
uint16_t serc; // serial前3字节总数量
|
||||||
|
CheatCfg *list; // 调用select_game后保存serial对应的一组cheat配置
|
||||||
|
uint16_t listc; // list的个数
|
||||||
|
uint32_t setid; // 选中的cheat_set的id
|
||||||
|
} CheatLib;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t entid; // entry的id
|
||||||
|
uint32_t offset; // entry对应数据在cheat_set的偏移
|
||||||
|
uint32_t datasz; // 此entry对应的数据长度(hole对应key数量,key对应gamecode数量)
|
||||||
|
} CheatEntry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t seek; // 在acl文件中的基础偏移
|
||||||
|
uint32_t entc; // 此cheat_set所有的entry总数
|
||||||
|
CheatEntry entry; // 当选选中的entry的数据
|
||||||
|
char *strings; // 字符串表
|
||||||
|
void *entdata; // 当前选中的entry对应的列表数据
|
||||||
|
} CheatSet;
|
||||||
|
|
||||||
|
static CheatLib gblcht = {0, 0, NULL, 0, 0};
|
||||||
|
static CheatSet gblset = {0, 0, {0,0,0}, NULL};
|
||||||
|
|
||||||
|
#define ACL_MAGIC_CODE 0x4c4341
|
||||||
|
#define ACL_GBA_CODELEN 4
|
||||||
|
#define ACL_HEADER_LEN 8
|
||||||
|
#define ACL_SERIAL_LEN(n) ((n)*3)
|
||||||
|
#define ACL_INDEX_OFFSET(i) ((i)*sizeof(uint16_t))
|
||||||
|
#define ACL_CONFIG_OFFSET(i) ((i)*sizeof(CheatCfg))
|
||||||
|
|
||||||
|
#define serial_count(n) ((n) & 0xffff)
|
||||||
|
#define max_cheat_count(n) ((n) >> 16)
|
||||||
|
|
||||||
|
acl_error_t acl_open_lib( acl_text_t filename )
|
||||||
|
{
|
||||||
|
FHandle cheatfile;
|
||||||
|
uint32_t readed;
|
||||||
|
if( RES_OK != fOpen(&cheatfile, filename, FA_OPEN_EXISTING | FA_READ) )
|
||||||
|
return ACHTLIB_NOT_FOUND;
|
||||||
|
|
||||||
|
// 验证magic number
|
||||||
|
uint32_t num;
|
||||||
|
if( RES_OK != fRead(cheatfile, &num, sizeof(num), &readed)
|
||||||
|
|| readed != sizeof(num) )
|
||||||
|
{
|
||||||
|
fClose( cheatfile );
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (num & 0xffffff) != ACL_MAGIC_CODE )
|
||||||
|
{
|
||||||
|
fClose( cheatfile );
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( RES_OK != fRead( cheatfile, &num, sizeof(num), &readed)
|
||||||
|
|| readed != sizeof( num ) )
|
||||||
|
{
|
||||||
|
fClose( cheatfile );
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheatCfg *cfglist = (CheatCfg*)malloc( max_cheat_count(num) * sizeof(CheatCfg) );
|
||||||
|
if( cfglist == NULL )
|
||||||
|
{
|
||||||
|
fClose( cheatfile );
|
||||||
|
return ACHTLIB_NOMEM;
|
||||||
|
}
|
||||||
|
cfglist[0].cfgid = 0;
|
||||||
|
|
||||||
|
gblcht.fd = cheatfile;
|
||||||
|
gblcht.serc = serial_count(num);
|
||||||
|
gblcht.list = cfglist;
|
||||||
|
|
||||||
|
return ACHTLIB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
acl_error_t acl_close_lib( void )
|
||||||
|
{
|
||||||
|
if( gblcht.serc != 0 )
|
||||||
|
{
|
||||||
|
fClose( gblcht.fd );
|
||||||
|
gblcht.fd = 0;
|
||||||
|
|
||||||
|
free( gblcht.list );
|
||||||
|
gblcht.list = NULL;
|
||||||
|
|
||||||
|
gblcht.serc = gblcht.listc = 0;
|
||||||
|
|
||||||
|
if( gblset.strings ){
|
||||||
|
free( gblset.strings );
|
||||||
|
gblset.strings = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( gblset.entdata ){
|
||||||
|
free( gblset.entdata );
|
||||||
|
gblset.entdata = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ACHTLIB_SUCCESS;
|
||||||
|
}
|
||||||
|
else return ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t bin_search( acl_text_t game )
|
||||||
|
{
|
||||||
|
if( RES_OK != fLseek(gblcht.fd, ACL_HEADER_LEN) ){
|
||||||
|
return -ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = ACL_SERIAL_LEN(gblcht.serc);
|
||||||
|
const char *serials = (char*)malloc( size );
|
||||||
|
if( serials == NULL ){
|
||||||
|
return -ACHTLIB_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
uint32_t readed;
|
||||||
|
if( RES_OK != fRead(gblcht.fd, serials, size, &readed)
|
||||||
|
|| readed != size )
|
||||||
|
{
|
||||||
|
free( serials );
|
||||||
|
return -ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
int start = 0, end = gblcht.serc - 1;
|
||||||
|
size = ACL_SERIAL_LEN(1);
|
||||||
|
int found = -1;
|
||||||
|
while( start < end )
|
||||||
|
{
|
||||||
|
int mid = (start+end) >> 1;
|
||||||
|
int res = strncmp( game, &serials[ACL_SERIAL_LEN(mid)], size );
|
||||||
|
if( res == 0 )
|
||||||
|
{
|
||||||
|
found = mid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( res > 0 )// serial < game
|
||||||
|
{
|
||||||
|
start = mid + 1;
|
||||||
|
}
|
||||||
|
else end = mid - 1;
|
||||||
|
}
|
||||||
|
free( serials );
|
||||||
|
|
||||||
|
if( found >= 0 )
|
||||||
|
{
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
else return -ACHTLIB_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define config_type(n) ( (n) & 0xff )
|
||||||
|
acl_error_t acl_select_game( acl_text_t game, acl_boolean_t filter, acl_count_t *n )
|
||||||
|
{
|
||||||
|
CheatLib *inst = (CheatLib*)&gblcht;
|
||||||
|
if( inst->serc == 0 ) return ACHTLIB_NOT_OPEN;
|
||||||
|
if( strlen(game) != ACL_GBA_CODELEN ) return ACHTLIB_NOT_FOUND;
|
||||||
|
|
||||||
|
int32_t index = bin_search( game );
|
||||||
|
if( index < 0 ) return index * -1;
|
||||||
|
|
||||||
|
uint32_t offset = ACL_HEADER_LEN + ACL_SERIAL_LEN(inst->serc);
|
||||||
|
offset += ACL_INDEX_OFFSET(index);
|
||||||
|
|
||||||
|
uint32_t readed;
|
||||||
|
uint16_t groups[2];
|
||||||
|
if( RES_OK != fLseek(inst->fd, offset) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
if( RES_OK != fRead(inst->fd, groups, sizeof(groups), &readed)
|
||||||
|
|| readed != sizeof(groups) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
offset = ACL_HEADER_LEN + ACL_SERIAL_LEN(inst->serc) + ACL_INDEX_OFFSET(inst->serc+1);
|
||||||
|
offset += ACL_CONFIG_OFFSET(groups[0]);
|
||||||
|
|
||||||
|
uint32_t gcount = groups[1] - groups[0];
|
||||||
|
if( RES_OK != fLseek(inst->fd, offset) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
CheatCfg *cfg = inst->list;
|
||||||
|
if( RES_OK != fRead(inst->fd, cfg, gcount * sizeof(CheatCfg), &readed) // 可能需要多次fread
|
||||||
|
|| readed != gcount * sizeof(CheatCfg) )
|
||||||
|
{
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( filter )
|
||||||
|
{
|
||||||
|
char reg = game[3];
|
||||||
|
index = -1;
|
||||||
|
for( int i=0; i < gcount; ++i )
|
||||||
|
{
|
||||||
|
if( config_type(cfg[i].typeloc) == reg )
|
||||||
|
{
|
||||||
|
if( index < 0 ) index = i;
|
||||||
|
}
|
||||||
|
else if( index >= 0 )
|
||||||
|
{
|
||||||
|
gcount = i-index;
|
||||||
|
memcpy( cfg, cfg+index, gcount * sizeof(CheatCfg) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inst->listc = gcount;
|
||||||
|
inst->setid = 0;
|
||||||
|
*n = gcount;
|
||||||
|
|
||||||
|
return ACHTLIB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
acl_error_t acl_query_cheat_set( acl_index_t index, acl_chtid_t *chtid, acl_region_t *region )
|
||||||
|
{
|
||||||
|
CheatLib *inst = &gblcht;
|
||||||
|
if( inst->serc == 0 ) return ACHTLIB_NOT_OPEN;
|
||||||
|
if( inst->listc == 0 ) return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
if( index >= inst->listc ) return ACHTLIB_NOT_FOUND;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CheatCfg *cfg = inst->list;
|
||||||
|
*chtid = cfg[index].cfgid;
|
||||||
|
*region = config_type( cfg[index].typeloc );
|
||||||
|
return ACHTLIB_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static acl_error_t init_cheatset( uint32_t offset )
|
||||||
|
{
|
||||||
|
gblset.seek = offset;
|
||||||
|
if( gblset.strings )
|
||||||
|
{
|
||||||
|
free( gblset.strings );
|
||||||
|
gblset.strings = NULL;
|
||||||
|
}
|
||||||
|
if( gblset.entdata )
|
||||||
|
{
|
||||||
|
free( gblset.entdata );
|
||||||
|
gblset.entdata = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t readed;
|
||||||
|
if( RES_OK != fLseek(gblcht.fd, offset) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
uint16_t entc;
|
||||||
|
if( RES_OK != fRead(gblcht.fd, &entc, sizeof(entc), &readed)
|
||||||
|
|| readed != sizeof( entc ) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
gblset.entc = entc;
|
||||||
|
|
||||||
|
if( RES_OK != fRead(gblcht.fd, &gblset.entry, sizeof(CheatEntry), &readed)
|
||||||
|
|| readed != sizeof(CheatEntry) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
if( gblset.entry.entid != 0 ) return ACHTLIB_INVALID;
|
||||||
|
offset = gblset.seek + sizeof(entc) + entc*sizeof(CheatEntry);
|
||||||
|
if( RES_OK != fLseek(gblcht.fd, offset) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
uint32_t size = gblset.entry.offset - sizeof(entc) - entc*sizeof(CheatEntry);
|
||||||
|
char *table = (char*)malloc( size );
|
||||||
|
if( !table ) return ACHTLIB_NOMEM;
|
||||||
|
|
||||||
|
if( RES_OK != fRead(gblcht.fd, table, size, &readed) // TODO: 多次read
|
||||||
|
|| readed != size )
|
||||||
|
{
|
||||||
|
free( table );
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
gblset.strings = table;
|
||||||
|
return ACHTLIB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static acl_error_t load_data()
|
||||||
|
{
|
||||||
|
if( gblset.entdata != NULL )
|
||||||
|
{
|
||||||
|
free( gblset.entdata );
|
||||||
|
gblset.entdata = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int elemlen = gblset.entry.entid > 0xffff ? sizdof(uint32_t) : sizeof(uint16_t);
|
||||||
|
int total = gblset.entry.datasz * elemlen;
|
||||||
|
if( total == 0 ) return ACHTLIB_SUCCESS;
|
||||||
|
|
||||||
|
uint8_t *d = (uint8_t*)malloc( total );
|
||||||
|
if( d == NULL ) return ACHTLIB_NOMEM;
|
||||||
|
|
||||||
|
if( RES_OK != fLseek(gblcht.fd, gblset.entry.offset))
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
uint32_t readed;
|
||||||
|
if( RES_OK != fRead(gblcht.fd, d, total, &readed)
|
||||||
|
|| readed != total )
|
||||||
|
{
|
||||||
|
free( d );
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
gblset.entdata = d;
|
||||||
|
return ACHTLIB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define config_offset(n) ( (n & ~0xff) >> 3 )
|
||||||
|
|
||||||
|
acl_error_t acl_select_cheat_set( acl_cheatid_t id )
|
||||||
|
{
|
||||||
|
CheatLib *inst = &gblcht;
|
||||||
|
if( inst->serc == 0 ) return ACHTLIB_NOT_OPEN;
|
||||||
|
if( inst->listc == 0 ) return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
acl_boolean_t found = 0;
|
||||||
|
uint32_t offset = 0;
|
||||||
|
CheatCfg *cfg = inst->list;
|
||||||
|
for( int i=0; i < inst->listc; ++i )
|
||||||
|
{
|
||||||
|
if( cfg[i].cfgid == id )
|
||||||
|
{
|
||||||
|
offset = config_offset( cfg[i].typeloc );
|
||||||
|
acl_error_t r = init_cheatset( offset );
|
||||||
|
if( r == ACHTLIB_SUCCESS )
|
||||||
|
{
|
||||||
|
inst->setid = id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( found ) return load_data();
|
||||||
|
else return ACHTLIB_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define READ_CACHE_SIZE 16
|
||||||
|
acl_error_t acl_select_entry( acl_entryid_t id, acl_elemlen_t *count)
|
||||||
|
{
|
||||||
|
if( gblcht.serc == 0 ) return ACHTLIB_NOT_OPEN;
|
||||||
|
if( gblcht.listc == 0 ) return ACHTLIB_INVALID;
|
||||||
|
if( gblcht.setid == 0 ) return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
if( gblset.entry.entid != id )
|
||||||
|
{
|
||||||
|
// update gblset.entry
|
||||||
|
if( RES_OK != fLseek(gblcht.fd, gblset.seek + sizeof(uint16_t)) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
CheatEntry cache[READ_CACHE_SIZE];
|
||||||
|
uint32_t readed;
|
||||||
|
for( int i = 0; i < gblset.entc; i += READ_CACHE_SIZE )
|
||||||
|
{
|
||||||
|
if( RES_OK != fRead(gblcht.fd, cache, sizeof(cache), &readed)
|
||||||
|
|| readed != sizeof(cache) )
|
||||||
|
return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
acl_boolean_t found = 0;
|
||||||
|
for( int j=0; j < READ_CACHE_SIZE; ++j )
|
||||||
|
{
|
||||||
|
if( cache[j].entid == id )
|
||||||
|
{
|
||||||
|
memcpy( &gblset.entry, &cache[i], sizeof(CheatEntry) );
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( found ) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*count = gblset.entry.datasz;
|
||||||
|
|
||||||
|
return load_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
acl_error_t acl_entry_get_label( acl_index_t index, acl_text_t *label )
|
||||||
|
{
|
||||||
|
if( gblcht.serc == 0 ) return ACHTLIB_NOT_OPEN;
|
||||||
|
if( gblcht.listc == 0 ) return ACHTLIB_INVALID;
|
||||||
|
if( gblcht.setid == 0 ) return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
if( index < gblset.entry.datasz )
|
||||||
|
{
|
||||||
|
uint16_t *d = (uint16_t*)gblset.entdata;
|
||||||
|
*label = gblset.strings + d[index];
|
||||||
|
return ACHTLIB_SUCCESS;
|
||||||
|
}
|
||||||
|
else return ACHTLIB_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
acl_error_t acl_entry_get_armcode( acl_index_t index, acl_armcode_t *code )
|
||||||
|
{
|
||||||
|
if( gblcht.serc == 0 ) return ACHTLIB_NOT_OPEN;
|
||||||
|
if( gblcht.listc == 0 ) return ACHTLIB_INVALID;
|
||||||
|
if( gblcht.setid == 0 ) return ACHTLIB_INVALID;
|
||||||
|
|
||||||
|
if( index < gblset.entry.datasz )
|
||||||
|
{
|
||||||
|
uint32_t *d = (uint32_t*)gblset.entdata;
|
||||||
|
*code = d[index];
|
||||||
|
return ACHTLIB_SUCCESS;
|
||||||
|
}
|
||||||
|
else return ACHTLIB_NOT_FOUND;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user