static imgtoolerr_t imgtool_floppy_open_internal(imgtool_image *image, imgtool_stream *f, int noclose) { floperr_t ferr; imgtoolerr_t err; struct imgtool_floppy_image *fimg; const imgtool_class *imgclass; const struct FloppyFormat *format; imgtoolerr_t (*open)(imgtool_image *image, imgtool_stream *f); fimg = (struct imgtool_floppy_image *) imgtool_image_extra_bytes(image); imgclass = &imgtool_image_module(image)->imgclass; format = (const struct FloppyFormat *) imgclass->derived_param; open = (imgtoolerr_t (*)(imgtool_image *, imgtool_stream *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_OPEN); /* open up the floppy */ ferr = floppy_open(f, noclose ? &imgtool_noclose_ioprocs : &imgtool_ioprocs, NULL, format, FLOPPY_FLAGS_READWRITE, &fimg->floppy); if (ferr) { err = imgtool_floppy_error(ferr); return err; } if (open) { err = open(image, NULL); if (err) return err; } return IMGTOOLERR_SUCCESS; }
static imgtoolerr_t datapack_read_file(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf) { imgtool_image *image = imgtool_partition_image(partition); psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); int index = seek_file_name(pack, filename); if (index >= 0) { if ((pack->pack_index[index].type & 0x7f) == 0x01) { // ODB files stream_seek(pack->stream, 0x10, SEEK_SET); get_odb(pack->stream, destf, pack->pack_index[index].type, pack->pack_index[index].id); } else if ((pack->pack_index[index].type & 0x7f) == 0x03) { // OB3/OPL files stream_seek(pack->stream, pack->pack_index[index].data_rec, SEEK_SET); get_ob3(pack->stream, destf, pack->pack_index[index].type, pack->pack_index[index].id); } else { // Other files return IMGTOOLERR_UNIMPLEMENTED; } return IMGTOOLERR_SUCCESS; } else return IMGTOOLERR_FILENOTFOUND; }
static imgtoolerr_t datapack_write_file( imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, util::option_resolution *opts) { imgtool_image *image = imgtool_partition_image(partition); psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); static const UINT8 data_head[4] = {0x02, 0x80, 0x00, 0x00}; UINT8 head[3]; UINT16 size = 0; UINT8 type = opts->lookup_int('T'); UINT8 file_id = opts->lookup_int('I'); if (!pack->eop) return IMGTOOLERR_CORRUPTIMAGE; // if not file_id is specified get the first free (for ODB only) if (file_id == 0 && type == 3) { file_id = get_free_file_id(pack); if (file_id == 0xff) return IMGTOOLERR_NOSPACE; } stream_read(sourcef, head, 3); stream_seek(pack->stream, pack->eop, SEEK_SET); if (type == 0) type = (!strncmp((char*)head, "ORG", 3)) ? 1 : 2; switch (type) { case 1: //OB3 file put_name_record(pack->stream, filename, 0x83, file_id); stream_write(pack->stream, data_head, 4); size = put_ob3(sourcef, pack->stream); break; case 2: //OPL file put_name_record(pack->stream, filename, 0x83, file_id); stream_write(pack->stream, data_head, 4); size = put_opl(sourcef, pack->stream); break; case 3: //ODB file put_name_record(pack->stream, filename, 0x81, file_id); size = put_odb(sourcef, pack->stream, file_id); break; } if (type != 3) { // update the OB3/OPL long record size stream_seek(pack->stream, pack->eop + 13, SEEK_SET); stream_putc(pack->stream, (size>>8) & 0xff); stream_putc(pack->stream, size & 0xff); }
static imgtoolerr_t datapack_free_space( imgtool_partition *partition, UINT64 *size) { imgtool_image *image = imgtool_partition_image( partition); psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); UINT32 pack_size = 0; stream_seek(pack->stream, 0x07, SEEK_SET); stream_read(pack->stream, &pack_size, 1); if (size) *size = (pack_size * 0x2000) - pack->eop; return IMGTOOLERR_SUCCESS; }
static imgtoolerr_t datapack_open( imgtool_image *image, imgtool_stream *stream) { psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); char opk_magic[4]; stream_read(stream, opk_magic, 4); if(strcmp(opk_magic, "OPK\0")) return IMGTOOLERR_UNEXPECTED; pack->stream = stream; if (update_pack_index(pack)) return IMGTOOLERR_SUCCESS; else return IMGTOOLERR_CORRUPTIMAGE; }
static imgtoolerr_t imgtool_floppy_create(imgtool_image *image, imgtool_stream *f, option_resolution *opts) { floperr_t ferr; imgtoolerr_t err = IMGTOOLERR_SUCCESS; struct imgtool_floppy_image *fimg; const imgtool_class *imgclass; const struct FloppyFormat *format; imgtoolerr_t (*create)(imgtool_image *, imgtool_stream *, option_resolution *); imgtoolerr_t (*open)(imgtool_image *image, imgtool_stream *f); fimg = (struct imgtool_floppy_image *) imgtool_image_extra_bytes(image); imgclass = &imgtool_image_module(image)->imgclass; format = (const struct FloppyFormat *) imgclass->derived_param; create = (imgtoolerr_t (*)(imgtool_image *, imgtool_stream *, option_resolution *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_CREATE); open = (imgtoolerr_t (*)(imgtool_image *, imgtool_stream *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_OPEN); /* open up the floppy */ ferr = floppy_create(f, &imgtool_ioprocs, format, opts, &fimg->floppy); if (ferr) { err = imgtool_floppy_error(ferr); goto done; } /* do we have to do extra stuff when creating the image? */ if (create) { err = create(image, NULL, opts); if (err) goto done; } /* do we have to do extra stuff when opening the image? */ if (open) { err = open(image, NULL); if (err) goto done; } done: return err; }
static imgtoolerr_t datapack_next_enum(imgtool_directory *enumeration, imgtool_dirent *ent) { imgtool_image *image = imgtool_directory_image(enumeration); psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); psion_iter *iter = (psion_iter*)imgtool_directory_extrabytes(enumeration); UINT8 data = 0; if (!pack->pack_index[iter->index].name_rec) { ent->eof = 1; return IMGTOOLERR_SUCCESS; } memcpy(ent->filename, pack->pack_index[iter->index].filename, 8); sprintf(ent->attr, "Type: %02x ID: %02x", pack->pack_index[iter->index].type, pack->pack_index[iter->index].id); if (pack->pack_index[iter->index].data_rec) { stream_seek(pack->stream, pack->pack_index[iter->index].data_rec + 2, SEEK_SET); ent->filesize = get_long_rec_size(pack->stream); } // seek all file's records if (pack->pack_index[iter->index].id >= 0x90) { stream_seek(pack->stream, 0x10, SEEK_SET); while (seek_next_record(pack->stream, pack->pack_index[iter->index].id)) { stream_read(pack->stream, &data, 1); stream_seek(pack->stream, data + 1, SEEK_CUR); ent->filesize +=data; } } iter->index++; return IMGTOOLERR_SUCCESS; }
static imgtoolerr_t datapack_create( imgtool_image *image, imgtool_stream *stream, util::option_resolution *opts) { psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); static const UINT8 opk_magic[4] = {'O', 'P', 'K', 0x00}; UINT8 pack_head[8] = {0x40, 0x00, 0x59, 0x01, 0x01, 0x01, 0x00, 0x00}; UINT16 checksum; pack_head[0] |= (opts->lookup_int('R')) ? 0x00 : 0x02; pack_head[0] |= (opts->lookup_int('P')) ? 0x04 : 0x00; pack_head[0] |= (opts->lookup_int('W')) ? 0x00 : 0x08; pack_head[0] |= (opts->lookup_int('B')) ? 0x00 : 0x10; pack_head[0] |= (opts->lookup_int('C')) ? 0x20 : 0x00; pack_head[1] = opts->lookup_int('S'); checksum = head_checksum(pack_head); stream_write(stream, opk_magic, 4); stream_fill(stream, 0x00, 2); stream_write(stream, pack_head, 8); stream_putc(stream, (checksum>>8) & 0xff); stream_putc(stream, checksum & 0xff); put_name_record(stream, "MAIN", 0x81, 0x90); stream_fill(stream, 0xff, 2); update_opk_head(stream); pack->stream = stream; if (update_pack_index(pack)) return IMGTOOLERR_SUCCESS; else return IMGTOOLERR_CORRUPTIMAGE; }
void *imgtool_floppy_extrabytes(imgtool_image *img) { struct imgtool_floppy_image *fimg; fimg = (struct imgtool_floppy_image *) imgtool_image_extra_bytes(img); return fimg + 1; }
floppy_image_legacy *imgtool_floppy(imgtool_image *img) { struct imgtool_floppy_image *fimg; fimg = (struct imgtool_floppy_image *) imgtool_image_extra_bytes(img); return fimg->floppy; }
static void datapack_close( imgtool_image *image) { psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); stream_close( pack->stream ); }