Subversion Repositories display

Rev

Rev 288 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <stdio.h>
#include <time.h>
#include "garminimg.h"
#include "imgtypes.h"
#include "decoder.h"
#include "decode_img.h"

int decode_header (class Decoder *dec)
{
        class GarminImg *img= dec->img;
        short e1, e2;
        byte_t byte;
        string str;
        time_t ts;
        udword_t subfile_offset= 0xffffffff;
        byte_t dir_start;
       
        dec->set_outfile("DSKIMG", "header");
        dec->print("XOR byte 0x%02x", img->xorbyte);

        dec->print(NULL, img->get_string(9).c_str());

        dec->print("Update month %d", img->get_byte());
        dec->print("Update year %d", img->get_byte()+1900);

        dec->print(NULL, img->get_string(3).c_str());

        dec->print("Checksum 0x%02x", img->get_byte());

        dec->print("%s", img->get_string(7).c_str());

        dec->print("???", img->get_byte());
        dec->print("%u sectors?", img->get_uword());
        dec->print("%u heads?", img->get_uword());

        dec->print("%u cyls", img->get_uword());
        dec->print("???", img->get_word());

        dec->print("%s", img->get_string(25).c_str());

        ts= img->get_date();
        dec->print("Created %24.24s", ctime(&ts));

        dec->print("Dir start?", (dir_start = img->get_byte()));

        dec->print("%s", img->get_string(7).c_str());

        dec->print(NULL, img->get_byte());

        dec->print("Map description: %s", img->get_string(20).c_str());

        int heads = img->get_uword();
        dec->print("%u heads?", heads);
        int sectors = img->get_uword();
        dec->print("%u sectors?", sectors);

        e1= img->get_byte();
        dec->print("E1= %u", e1);
        e2= img->get_byte();
        dec->print("E2= %u", e2);
        img->block_size_exp(e1+e2);
        dec->comment("Block size= 2^(E1+E2)= %u", img->block_size());
        dec->print("nblocks %u", img->get_uword());

        dec->print("Map desc (cntd): %s", img->get_string(31).c_str());

        dec->rawprint("*\n");

        img->seek(0x1be);

        dec->banner("Partition Table");
        dec->print("%u boot?", img->get_byte());
        dec->print("%u start-head", img->get_byte());
        dec->print("%u start-sector", img->get_byte());
        dec->print("%u start-cylinder", img->get_byte());

        dec->print("%u partition-type", img->get_byte());

        int h = img->get_byte() & 0xff;
        dec->print("%u end-head", h);
        int s = img->get_byte() & 0xff;
        dec->print("%u end-sector", s & 0x3f);
        int c = img->get_byte() & 0xff;
        dec->print("%u end-cylinder", ((s << 2) & 0x300) + c);
        c = ((s << 2) & 0x300) + c;
        s = s & 0x3f;

        dec->print("%u start sector", img->get_udword());
        dec->print("%u sectors (from chs %u)", img->get_udword(), (c*heads+h)*sectors + (s-1));
        dec->print(NULL, img->get_string(48).c_str());
        dec->print("", img->get_uword());
        dec->banner("End Partition Table");

        dec->rawprint("*\n");

        img->seek(dir_start * 0x200);

        byte= img->get_byte();
        if ( ! byte) {
                img->seek(0x1000);
        } else {
                dec->print("???", img->get_byte());
                dec->print("???", img->get_string(11).c_str());
                dec->print("First subfile offset: 0x%06lx",
                        subfile_offset= img->get_udword());
                dec->print("???", img->get_byte());
                dec->print("", img->get_string(15).c_str());

                dec->print("Sequence block start", img->get_uword());
                dec->rawprint("*\n");

                off_t end = (dir_start+1) * 0x200;     
                dec->print("Sequence block end (block %u)",
                        img->last_seq_block(end));
                if ( img->tell() != end ) {
                        dec->print("Sequence block padding", img->get_uword());
                        dec->rawprint("*\n");
                }

                img->seek(end);
        }

        dec->banner("Begin FAT");
        while ( img->tell() < subfile_offset ) {
                img_fat_block_t fblock;
                off_t next_block;
                byte_t valid, part;
                udword_t seq;

                next_block= img->tell()+512;
               
                valid= img->get_byte();
                if ( valid ) dec->print("Subfile block");
                else dec->print("Dummy block");

                fblock.filename= img->get_string(8);
                dec->print("Filename: %s", fblock.filename.c_str());

                fblock.extension= img->get_string(3);
                dec->print("Type: %s", fblock.extension.c_str());

                fblock.fullname= fblock.filename + "." +
                        fblock.extension;
                dec->comment("%s", fblock.fullname.c_str());

                fblock.size= (off_t) img->get_udword();

                if ( fblock.size ) dec->print("%lu bytes", fblock.size);
                else dec->print(NULL);

                dec->print(NULL, img->get_byte());
                dec->print("Part %u", part= img->get_uword());
                dec->print("???", img->get_string(13).c_str());

                seq= img->get_uword();
                dec->print("Sequence block start", seq);
                dec->rawprint("*\n");
                dec->print("Sequence block end (block %u)",
                        img->last_seq_block(img->tell()+480));
       
                if ( img->tell() != next_block ) {
                        dec->print("Sequence block padding", img->get_uword());
                        dec->rawprint("*\n");
                        img->seek(next_block);
                }
                fblock.offset= seq*img->block_size();

                if ( ! fblock.offset ) valid= 0;

                if ( ! part && valid ) {
                        class ImgFile *ifile;
                        class ImgSubfile *subfile;

                        dec->comment("Subfile at offset 0x%06lx",
                                fblock.offset);
                        img->fat.insert(make_pair(fblock.fullname, fblock));

                        if ( fblock.offset && fblock.offset < subfile_offset )
                                subfile_offset= fblock.offset;

                        ifile= img->file_find(fblock.filename);
                        if ( ifile == NULL ) {
                                ifile= new ImgFile(img, fblock.filename);
                                img->files.insert(make_pair(fblock.filename,
                                        ifile));
                        }

                        (void) ifile->subfile_add(fblock.extension,
                                fblock.offset, fblock.size);
                }
                dec->rawprint("\n");
        }
        dec->banner("End FAT");

        // That's it for the header block

        return 0;
}

void decode_common_header (class Decoder *dec, class ImgSubfile *sub)
{
        class ImgFile *ifile= sub->ifile;
        class GarminImg *img= dec->img;
        time_t ts;

        dec->print("Header length %u bytes", sub->hlen= img->get_uword());
        dec->print("File type %s", img->get_string(10).c_str());
        dec->print("???", img->get_byte());

        sub->locked= img->get_byte();
        dec->print((sub->locked) ? "Locked" : "Not locked");

        ts= img->get_date();
        dec->print("Created %24.24s", ctime(&ts));
}