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/storage.c

126 lines
4.0 KiB
C

/* ************************************************************************** */
/* _____ _ */
/* parse/storage.c |_ _|__ _ _| |__ ___ _ _ */
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2016/12/25 13:38:52 |___/ */
/* */
/* ************************************************************************** */
#include <libg1m/internals.h>
#define SUB(V, TYPE) \
case storage_entrytype_##TYPE:; \
struct storage_##TYPE *V = (struct storage_##TYPE*)&entry.raw_subheader;
/**
* rawfctombs:
* Temporary function, from raw FONTCHARACTER to multi-byte using buffers.
*
* @arg raw the raw buffer
* @arg count the number of fontcharacters in the count
* @arg final the final multi-byte buffer
*/
static void rawfctombs(FONTCHARACTER *raw, int count, char *final)
{
/* copy the raw data into a null-terminated buffer */
FONTCHARACTER traw[count + 1]; traw[count] = 0;
memcpy(traw, raw, count * sizeof(FONTCHARACTER));
/* big endian to host the raw buffer, and null terminate it */
int i;
for (i = 0; traw[i] != 0xffff && i < count; i++)
traw[i] = be16toh(traw[i]);
traw[i] = 0;
g1m_fcstombs(final, traw, 0);
}
/**
* g1m_parse_storage:
* Parse storage files.
*
* @arg handle the libg1m handle.
* @arg stream the stream to read from.
* @arg std the standard header.
* @return the error code (0 if ok).
*/
int g1m_parse_storage(g1m_t *handle, FILE *stream,
struct standard_header *std)
{
(void)std;
handle->type = 0x00;
/* skip the first 0x270000 - 0x20 bytes */
SKIP(0x270000 - sizeof(struct standard_header))
/* read */
log_info("Storage memory!");
/* read the entries */
for (int id = 1; id < 0x800; id++) {
/* read the entry */
DREAD(entry, storage_entry)
if (entry.type == 0xFFFF)
continue;
entry.type = be16toh(entry.type);
entry.uuid = be16toh(entry.uuid);
/* read it */
int special = (entry.type & 0xF000) >> 12;
switch (entry.type & 0xFFF) {
SUB(sh, sector)
int unused = (sh->logical_sector_number == 0xFFFFFFFF);
log_info("[%02d,%02" PRIu16 "] Is a%ssector.", id, entry.uuid,
(unused) ? "n unused " : " ");
sh->startaddr = be32toh(sh->startaddr);
log_info("- Starts at address 0x%08" PRIx32, sh->startaddr);
#if LOGLEVEL <= ll_info
sh->logical_sector_number = be32toh(sh->logical_sector_number);
if (!unused) log_info("- Logical number: 0x%08" PRIu32,
sh->logical_sector_number);
#endif
break;
SUB(dh, directory)
log_info("[%02d,%02" PRIu16 "] Is a%s directory.", id, entry.uuid,
(special == 0x05) ? "n active" : " deleted");
#if LOGLEVEL <= ll_info
char dirname[25]; rawfctombs(dh->name, 12, dirname);
log_info("- Directory name: %s", dirname);
#endif
break;
SUB(fh, file)
log_info("[%02d,%02" PRIu16 "] Is a%s file.", id, entry.uuid,
(special == 0x05) ? "n active" : " deleted");
#if LOGLEVEL <= ll_info
char filename[25]; rawfctombs(fh->name, 12, filename);
log_info("- File name: %s", filename);
if (be16toh(fh->directory_reference) == storage_entrytype_directory)
log_info("- Is in directory #%" PRIu16,
be16toh(fh->directory_number));
else log_info("- Is in root.");
#endif
break;
SUB(fgh, fragment)
log_info("[%02d,%02" PRIu16 "] Is a fragment.", id, entry.uuid);
log_info("- Points at sector #%" PRIu16,
be16toh(fgh->fragment_sector_id));
log_info("- Is %" PRIu16 "/%" PRIu16
" (%" PRIu16 "o at offset 0x%04" PRIx16 ")",
be16toh(fgh->fragment_id), be16toh(fgh->fragment_count),
be16toh(fgh->used_bytes), be16toh(fgh->used_bytes_offset));
break;
default: /* we should know all of the types, but we never know */
log_info("[%02d,%02" PRIu16 "] Is unknown.", id, entry.uuid);
}
}
/* no error */
return (0);
}