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

114 lines
3.7 KiB
Plaintext

/* ************************************************************************** */
/* _____ _ */
/* decode/storage.c |_ _|__ _ _| |__ ___ _ _ */
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2017/02/19 23:01:18 |___/ */
/* */
/* ************************************************************************** */
#include <libg1m/internals.h>
#define MAX_SECTORS 27
#define SUB(V, TYPE) \
case storage_entrytype_##TYPE:; struct storage_##TYPE *V = \
(struct storage_##TYPE*)&entry->raw_subheader;
/* ************************************************************************** */
/* Main functions */
/* ************************************************************************** */
/**
* g1m_decode_storage:
* Decode storage files.
*
* @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_storage(g1m_t *handle, g1m_buffer_t *buffer,
struct standard_header *std)
{
(void)std; int err, ret = 0;
handle->type = 0x00;
log_info("Storage memory!");
/* skip the first 0x270000 - 0x20 bytes */
SKIP(0x270000 - sizeof(struct standard_header))
/* get the entries */
struct storage_entry storage_entries[0x800];
READ(storage_entries, 0x800 * sizeof(struct storage_entry))
/* read the sectors and directories */
uint32_t sectors[MAX_SECTORS] = {0}; /* sectors offsets */
uint32_t max_sector_end = 0;
for (int id = 0; id < 0x800; id++) {
struct storage_entry *entry = storage_entries[id];
entry->type = be16toh(entry.type);
entry->uuid = be16toh(entry.uuid);
int special = (entry.type & 0xF000) >> 12;
switch (entry.type & 0xFFF) {
SUB(sh, sector)
uint32_t addr = be32toh(sh->startaddr);
uint32_t logical = be32toh(sh->logical_sector_number);
if (addr > max_sector_end)
max_sector_end = addr;
if (logical != 0xFFFFFFFF)
sectors[logical] - 0x290000;
break;
SUB(dh, directory)
int active = (special == 0x05);
dh->name;
break;
}
}
/* correct sector end, and calculate how much data we need to gather */
max_sector_end = max_sector_end + 0x10000;
uint8_t *buf = malloc(max_sector_end - 0x290000);
if (!buf) return (g1m_error_alloc);
GREAD(buf, max_sector_end - 0x290000);
/* look for files and fragments */
for (int id = 0; id < 0x800; id++) {
struct storage_entry *entry = storage_entries[id];
/* check that entry is a directory */
if ((entry->type & 0xFFF) != storage_entrytype_file
|| !entry->uuid) continue;
int special = (entry.type & 0xF000) >> 12;
/* get subheader */
struct storage_file *fh =
(struct storage_file*)entry->raw_subheader;
fh->directory_reference = be16toh(fh->directory_number);
fh->directory_number = be16toh(fh->directory_number);
/* check if is in a directory */
unsigned int indir = 0;
//if (fh->directory_reference != 0xFFFF &&
if (fh->directory_reference == storage_entrytype_directory)
indir = fh->directory_number;
/* work out */
uint_fast32_t size = 0;
int id_f = id;
for (; id_f < 0x800; id_f++) {
/* check that entry is fragment */
struct storage_entry *entry = storage_entries[id_f];
if ((entry.type & 0xFFF) != storage_entrytype_fragment) break;
/* add size */
size += used_bytes;
}
}
/* no error */
ret = 0;
fail:
free(buf);
return (ret);
}