Continued doing things. (GONE WRONG)
This commit is contained in:
parent
3797c67f18
commit
75719e98c0
|
@ -46,6 +46,8 @@ extern "C" {
|
|||
* ---
|
||||
* First, the none error. */
|
||||
# define g1m_noerror 0x00
|
||||
# define g1m_error_none 0x00
|
||||
# define g1m_error_success 0x00
|
||||
|
||||
/* Then, the miscallenous errors */
|
||||
# define g1m_error_unknown 0x01
|
||||
|
|
|
@ -96,12 +96,15 @@
|
|||
/* ************************************************************************** */
|
||||
/* Decoding functions */
|
||||
/* ************************************************************************** */
|
||||
/* with expected types */
|
||||
int g1m_decode_std(g1m_t *handle, const char *path, g1m_buffer_t *buffer,
|
||||
struct standard_header*, g1m_type_t expected_types);
|
||||
int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer,
|
||||
g1m_type_t expected_types);
|
||||
int g1m_decode_casemul(g1m_t *handle, g1m_buffer_t *buffer);
|
||||
|
||||
/* w/o expected types */
|
||||
int g1m_decode_casemul(g1m_t *handle, g1m_buffer_t *buffer);
|
||||
int g1m_decode_storage(g1m_t *handle, g1m_buffer_t *buffer);
|
||||
int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer);
|
||||
int g1m_decode_grc(g1m_t *handle, g1m_buffer_t *buffer);
|
||||
/* ************************************************************************** */
|
||||
/* "Std"-specific decoding functions */
|
||||
/* ************************************************************************** */
|
||||
|
@ -118,7 +121,6 @@ G1M_STDFUNC(addin_cg)
|
|||
G1M_STDFUNC(lang)
|
||||
G1M_STDFUNC(lang_cg)
|
||||
G1M_STDFUNC(fkey)
|
||||
G1M_STDFUNC(storage)
|
||||
|
||||
/* others */
|
||||
int g1m_decode_fkey_cg_content(g1m_t *handle, g1m_buffer_t *buffer,
|
||||
|
@ -183,6 +185,9 @@ int g1m_skip(g1m_buffer_t *buffer, size_t size, uint_fast32_t *checksum);
|
|||
uint8_t g1m_checksum8(void *mem, size_t size);
|
||||
uint32_t g1m_checksum32(void *mem, size_t size, uint32_t checksum);
|
||||
|
||||
/* Get extension */
|
||||
int g1m_getext(const char *path, char *buf, size_t n);
|
||||
|
||||
/* File buffer */
|
||||
int g1m_filebuffer_read(void *vcookie, unsigned char *buf, size_t size);
|
||||
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/* *****************************************************************************
|
||||
* core/decode.c -- decode a file.
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libg1m.
|
||||
* libg1m is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libg1m 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/**
|
||||
* g1m_decode:
|
||||
* Decode a file.
|
||||
*
|
||||
* Read the standard header, correct endianness, check magic numbers,
|
||||
* then read subparts according to the G1M type.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg path the file path.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg expected_types the expected types.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode(g1m_t *handle, const char *path, g1m_buffer_t *buffer,
|
||||
g1m_type_t expected_types)
|
||||
{
|
||||
/* initialize the handle */
|
||||
memset(handle, 0, sizeof(g1m_t));
|
||||
|
||||
/* identify a CAS file */
|
||||
unsigned char buf[0x20]; READ(buf, 1)
|
||||
if (buf[0] == ':')
|
||||
return (g1m_decode_cas(handle, buffer, expected_types));
|
||||
|
||||
/* identify a Casemul file */
|
||||
READ(&buf[1], 3)
|
||||
if (!memcmp(buf, "CAFS", 4)) {
|
||||
handle->platform |= g1m_platflag_be;
|
||||
return (g1m_decode_casemul(handle, buffer));
|
||||
} else if (!memcmp(buf, "ACFS", 4))
|
||||
return (g1m_decode_casemul(handle, buffer));
|
||||
|
||||
/* identify a standard header (send a _copy_) */
|
||||
READ(&buf[4], 0x1C)
|
||||
uint8_t altbuf[0x20]; memcpy(altbuf, buf, 0x20);
|
||||
return (g1m_decode_std(handle, path, buffer,
|
||||
(struct standard_header*)altbuf, expected_types));
|
||||
}
|
|
@ -111,6 +111,7 @@ static int decode_caspro_head(g1m_mcshead_t *head, struct caspro_header *hd)
|
|||
end = memchr(hd->aux, 0xFF, 8);
|
||||
len = end ? (size_t)(end - (char*)hd->aux) : 8;
|
||||
memcpy(head->password, hd->aux, len); head->password[len] = 0;
|
||||
log_info("Is a program of %" PRIuFAST32 " bytes", head->size);
|
||||
break;
|
||||
case g1m_mcstype_variable:
|
||||
if (hd->used) head->flags |= g1m_mcsflag_unfinished;
|
||||
|
@ -240,12 +241,10 @@ int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer)
|
|||
*
|
||||
* @arg handle the handle to create.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg expected_types the expected types.
|
||||
* @return the libg1m error.
|
||||
*/
|
||||
|
||||
int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer,
|
||||
g1m_type_t expected_types)
|
||||
int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -335,3 +334,19 @@ fail:
|
|||
g1m_free_mcs(handle);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_decode_grc:
|
||||
* Decode Graph Card file.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_grc(g1m_t *handle, g1m_buffer_t *buffer)
|
||||
{
|
||||
uint8_t intro[2]; READ(intro, 2) /* probably the file count? */
|
||||
uint8_t colon; READ(&colon, 1) /* read first colon */
|
||||
return (g1m_decode_cas(handle, buffer));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/* *****************************************************************************
|
||||
* decode/main.c -- decode a file.
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libg1m.
|
||||
* libg1m is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libg1m 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Check using extensions */
|
||||
/* ************************************************************************** */
|
||||
/* Decode function */
|
||||
typedef int (*decode_func)(g1m_t*, g1m_buffer_t*);
|
||||
|
||||
/* Correspondance type */
|
||||
struct corresp {
|
||||
/* extension */
|
||||
const char *ext;
|
||||
|
||||
/* expected types */
|
||||
g1m_type_t type;
|
||||
|
||||
/* function */
|
||||
decode_func decode;
|
||||
};
|
||||
|
||||
/* Correspondances */
|
||||
static struct corresp correspondances[] = {
|
||||
// {"g1s", g1m_type_storage, g1m_decode_storage},
|
||||
{"grc", g1m_type_mcs, g1m_decode_grc},
|
||||
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
|
||||
/**
|
||||
* lookup_extension:
|
||||
* Get the function using the type.
|
||||
*
|
||||
* @arg path the path.
|
||||
* @arg types the expected types.
|
||||
* @arg decode the decode function to set.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
static int lookup_extension(const char *path, g1m_type_t types,
|
||||
decode_func *func)
|
||||
{
|
||||
/* match the extension */
|
||||
char ext[5];
|
||||
if (!g1m_getext(path, ext, 5)) return (g1m_error_magic);
|
||||
struct corresp *c = correspondances - 1;
|
||||
while ((++c)->ext) if (!strcmp(c->ext, ext)) break;
|
||||
|
||||
/* check if correspondance is valid and expected */
|
||||
if (!c->ext) return (g1m_error_magic);
|
||||
if (types && !(types & c->type)) return (g1m_error_wrong_type);
|
||||
|
||||
/* return the decode function */
|
||||
*func = c->decode;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main decoding function */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_decode:
|
||||
* Decode a file.
|
||||
*
|
||||
* Read the standard header, correct endianness, check magic numbers,
|
||||
* then read subparts according to the G1M type.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg path the file path.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg expected_types the expected types.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode(g1m_t *handle, const char *path, g1m_buffer_t *buffer,
|
||||
g1m_type_t expected_types)
|
||||
{
|
||||
/* initialize the handle */
|
||||
memset(handle, 0, sizeof(g1m_t));
|
||||
|
||||
/* match using extension */
|
||||
decode_func decode;
|
||||
int err = lookup_extension(path, expected_types, &decode);
|
||||
if (err == g1m_error_wrong_type) return (g1m_error_wrong_type);
|
||||
else if (!err) return ((*decode)(handle, buffer));
|
||||
|
||||
/* identify a CAS file */
|
||||
unsigned char buf[0x20]; READ(buf, 1)
|
||||
if (buf[0] == ':') {
|
||||
if (expected_types && !(expected_types & g1m_type_mcs))
|
||||
return (g1m_error_wrong_type);
|
||||
return (g1m_decode_cas(handle, buffer));
|
||||
}
|
||||
|
||||
/* identify a Casemul file */
|
||||
READ(&buf[1], 3)
|
||||
if (!memcmp(buf, "CAFS", 4)) {
|
||||
handle->platform |= g1m_platflag_be;
|
||||
if (expected_types && !(expected_types & g1m_type_mcs))
|
||||
return (g1m_error_wrong_type);
|
||||
return (g1m_decode_casemul(handle, buffer));
|
||||
} else if (!memcmp(buf, "ACFS", 4)) {
|
||||
if (expected_types && !(expected_types & g1m_type_mcs))
|
||||
return (g1m_error_wrong_type);
|
||||
return (g1m_decode_casemul(handle, buffer));
|
||||
}
|
||||
|
||||
/* identify a standard header (send a _copy_) */
|
||||
READ(&buf[4], 0x1C)
|
||||
uint8_t altbuf[0x20]; memcpy(altbuf, buf, 0x20);
|
||||
return (g1m_decode_std(handle, path, buffer,
|
||||
(struct standard_header*)altbuf, expected_types));
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* *****************************************************************************
|
||||
* decode/std/storage.c -- decode a storage file.
|
||||
* decode/storage.c -- decode a storage file.
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libg1m.
|
||||
|
@ -31,18 +31,16 @@
|
|||
*
|
||||
* @arg handle the libg1m handle.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg std the standard header.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_std_storage(g1m_t *handle, g1m_buffer_t *buffer,
|
||||
struct standard_header *std)
|
||||
int g1m_decode_storage(g1m_t *handle, g1m_buffer_t *buffer)
|
||||
{
|
||||
(void)std; int err, ret = 0;
|
||||
handle->type = 0x00;
|
||||
log_info("Storage memory!");
|
||||
/* go to offset 0x270000 of the file */
|
||||
SKIP(0x270000 - sizeof(struct standard_header))
|
||||
SKIP(0x270000)
|
||||
|
||||
/* get the entries */
|
||||
struct storage_entry storage_entries[0x800];
|
|
@ -129,9 +129,6 @@ struct ext_corresp {
|
|||
|
||||
/* Extension correspondances */
|
||||
static struct ext_corresp ext_types[] = {
|
||||
/* storage files */
|
||||
{"g1s", "Storage file", g1m_platform_none, g1m_type_storage},
|
||||
|
||||
/* fx types with non-checked header */
|
||||
{"g1l", "fx language file", g1m_platform_fx, g1m_type_lang},
|
||||
{"g1n", "fx fkeys file", g1m_platform_fx, g1m_type_fkey},
|
||||
|
@ -144,31 +141,6 @@ static struct ext_corresp ext_types[] = {
|
|||
{NULL, NULL, 0, 0}
|
||||
};
|
||||
|
||||
/**
|
||||
* get_extension:
|
||||
* Get extension from a path.
|
||||
*
|
||||
* @arg path the path.
|
||||
* @arg extbuf the extension buffer.
|
||||
* @return extension.
|
||||
*/
|
||||
|
||||
static void get_extension(const char *path, char *extbuf)
|
||||
{
|
||||
/* get filename */
|
||||
const char *filename = strrchr(path, '/');
|
||||
filename = filename ? filename + 1 : path;
|
||||
|
||||
/* get extension */
|
||||
const char *ext = strrchr(filename, '.');
|
||||
ext = ext ? ext + 1 : filename;
|
||||
|
||||
/* copy it */
|
||||
extbuf[4] = 0; strncpy(extbuf, ext, 4);
|
||||
for (int i = 0; i < 3; i++)
|
||||
extbuf[i] = tolower(extbuf[i]);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main functions */
|
||||
/* ************************************************************************** */
|
||||
|
@ -197,7 +169,7 @@ int g1m_maketype_std(const char *path,
|
|||
&& !memcmp(subtype, "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) {
|
||||
log_info("Blank type! Let's use the extension to try and identify it.");
|
||||
if (!path) return (1);
|
||||
char ext[5]; get_extension(path, ext);
|
||||
char ext[5]; g1m_getext(path, ext, 5);
|
||||
|
||||
struct ext_corresp *e = ext_types - 1;
|
||||
while ((++e)->ext) {
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/* *****************************************************************************
|
||||
* utils/extension.c -- extension utilities.
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libg1m.
|
||||
* libg1m is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libg1m 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/**
|
||||
* g1m_getext:
|
||||
* Get extension from a path.
|
||||
*
|
||||
* @arg path the path.
|
||||
* @arg buf the extension buffer.
|
||||
* @arg n the extension buffer size.
|
||||
* @return the size of the extension.
|
||||
*/
|
||||
|
||||
int g1m_getext(const char *path, char *buf, size_t n)
|
||||
{
|
||||
/* no size? */
|
||||
if (!n) return (0);
|
||||
|
||||
/* get filename */
|
||||
const char *filename = strrchr(path, '/');
|
||||
filename = filename ? filename + 1 : path;
|
||||
|
||||
/* get extension */
|
||||
const char *ext = strrchr(filename, '.');
|
||||
ext = ext ? ext + 1 : "";
|
||||
|
||||
/* copy it */
|
||||
buf[n - 1] = 0; strncpy(buf, ext, n - 1);
|
||||
for (int i = 0; buf[i]; i++)
|
||||
buf[i] = tolower(buf[i]);
|
||||
|
||||
/* return the size */
|
||||
return (strlen(buf));
|
||||
}
|
Reference in New Issue