126 lines
4.0 KiB
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);
|
|
}
|