cake
/
libg1m
Archived
1
0
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libg1m/src/parse/main.c

125 lines
3.7 KiB
C

/* ************************************************************************** */
/* _____ _ */
/* parse/main.c |_ _|__ _ _| |__ ___ _ _ */
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2016/11/02 14:47:49 |___/ */
/* */
/* ************************************************************************** */
#include <libg1m/internals.h>
/**
* get_main_id:
* Get numerical main ID based on the main ID string.
*
* @arg s the 8-bytes buffer containing the ID.
* @return the main ID or -1 if the main ID is unknown.
*/
static int get_main_id(unsigned char *s)
{
if (!memcmp(s, "USBPower", 8))
return (g1m_mid_usbpower);
if (!memcmp(s, "Ly755 ", 8))
return (g1m_mid_ly755);
return (-1);
}
/**
* g1m_parse:
* Parse a G1M file.
*
* Read the standard header, correct endianness, check magic numbers,
* then read subparts according to the G1M type.
*
* @arg handle the handle.
* @arg stream the stream to parse from.
* @return the error code (0 if ok).
*/
int g1m_parse(g1m_t *handle, FILE *stream)
{
/* initialize the handle */
bzero(handle, sizeof(g1m_t));
/* get the standard header */
DREAD(hd, standard_header)
/* reverse */
uint8_t *u = (uint8_t*)&hd;
for (size_t i = 0; i < sizeof(struct standard_header); i++) u[i] = ~u[i];
/* print header */
log_info("Raw standard header is:");
logm_info(&hd, sizeof(struct standard_header));
/* correct standard header endianess */
hd.filesize = be32toh(hd.filesize);
hd.number = be16toh(hd.number);
/* check standard header magics */
if (hd.control != ((hd.filesize + 0x41) & 0xff)) {
log_info("First control byte isn't right.");
return (g1m_error_magic);
} else if (hd.control2 != ((hd.filesize + 0xb8) & 0xff)) {
log_info("Second control byte isn't right.");
return (g1m_error_magic);
}
/* get the main ID */
int main_id = get_main_id(hd.main_id);
if (main_id < 0) {
log_fatal("Main ID is unknown: '%.8s'", hd.main_id);
return (g1m_error_magic);
}
/* log some data */
log_info("Standard Header Main ID is '%.8s'", hd.main_id);
log_info("Standard Header Type is '%s' (0x%02x)",
g1m_get_type_string(main_id, hd.type), hd.type);
log_info("Standard Header filesize is %uo", hd.filesize);
log_info("Standard Header num is %d.", hd.number);
/* subparse. */
handle->is_cg = 0;
switch (main_id) {
case g1m_mid_usbpower:
switch (hd.type) {
case g1m_usbpower_type_addin:
handle->type = g1m_type_addin;
return (g1m_parse_addin(handle, stream));
case g1m_usbpower_type_addin_cg:
handle->type = g1m_type_addin;
handle->is_cg = 1;
return (g1m_parse_addin_cg(handle, stream, &hd));
case g1m_usbpower_type_g2r:
case g1m_usbpower_type_mcs:
handle->type = g1m_type_mcs;
return (g1m_parse_mcs(handle, stream, hd.number));
case g1m_usbpower_type_eact:
handle->type = g1m_type_eact;
return (g1m_parse_eact(handle, stream));
case g1m_usbpower_type_g3p:
handle->type = g1m_type_pict;
handle->is_cg = 1;
return (g1m_parse_g3p(handle, stream, &hd));
default:
log_info("Type not managed (yet?): 0x%02x", hd.type);
}
break;
case g1m_mid_ly755:
switch (hd.type) {
case g1m_ly755_type_lang:
log_info("Lang type isn't managed yet.");
break;
default:
log_info("Type not managed (yet?): 0x%02x", hd.type);
}
break;
}
/* no error */
return (0);
}