Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
static imgtoolerr_t os9_diskimage_createdir(imgtool_partition *partition, const char *path)
{
	imgtoolerr_t err;
	imgtool_image *image = imgtool_partition_image(partition);
	struct os9_fileinfo file_info;
	UINT8 dir_data[64];
	UINT32 parent_lsn;

	err = os9_lookup_path(image, path, CREATE_DIR, &file_info, &parent_lsn, NULL, NULL);
	if (err)
		goto done;

	err = os9_set_file_size(image, &file_info, 64);
	if (err)
		goto done;

	/* create intial directories */
	memset(dir_data, 0, sizeof(dir_data));
	place_string(dir_data,   0, 32, "..");
	place_integer_be(dir_data, 29,  3, parent_lsn);
	place_string(dir_data,  32, 32, ".");
	place_integer_be(dir_data, 61,  3, file_info.lsn);

	err = os9_write_lsn(image, file_info.sector_map[0].lsn, 0, dir_data, sizeof(dir_data));
	if (err)
		goto done;

done:
	return err;
}
Ejemplo n.º 3
0
static imgtoolerr_t os9_diskimage_readfile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf)
{
	imgtoolerr_t err;
	imgtool_image *img = imgtool_partition_image(partition);
	const os9_diskinfo *disk_info;
	struct os9_fileinfo file_info;
	UINT8 buffer[256];
	int i, j;
	UINT32 file_size;
	UINT32 used_size;

	disk_info = os9_get_diskinfo(img);

	err = os9_lookup_path(img, filename, CREATE_NONE, &file_info, NULL, NULL, NULL);
	if (err)
		return err;
	if (file_info.directory)
		return IMGTOOLERR_FILENOTFOUND;
	file_size = file_info.file_size;

	for (i = 0; file_info.sector_map[i].count > 0; i++)
	{
		for (j = 0; j < file_info.sector_map[i].count; j++)
		{
			used_size = MIN(file_size, disk_info->sector_size);
			err = os9_read_lsn(img, file_info.sector_map[i].lsn + j, 0,
				buffer, used_size);
			if (err)
				return err;
			stream_write(destf, buffer, used_size);
			file_size -= used_size;
		}
	}
	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 4
0
Archivo: os9.c Proyecto: poliva/mame-rr
static imgtoolerr_t os9_diskimage_writefile(imgtool_partition *partition, const char *path, const char *fork, imgtool_stream *sourcef, option_resolution *opts)
{
	imgtoolerr_t err;
	imgtool_image *image = imgtool_partition_image(partition);
	struct os9_fileinfo file_info;
	size_t write_size;
	void *buf = NULL;
	int i = -1;
	UINT32 lsn = 0;
	UINT32 count = 0;
	UINT32 sz;
	const os9_diskinfo *disk_info;

	disk_info = os9_get_diskinfo(image);

	buf = malloc(disk_info->sector_size);
	if (!buf)
	{
		err = IMGTOOLERR_OUTOFMEMORY;
		goto done;
	}

	err = os9_lookup_path(image, path, CREATE_FILE, &file_info, NULL, NULL, NULL);
	if (err)
		goto done;

	sz = (UINT32) stream_size(sourcef);

	err = os9_set_file_size(image, &file_info, sz);
	if (err)
		goto done;

	while(sz > 0)
	{
		write_size = (size_t) MIN(sz, (UINT64) disk_info->sector_size);

		stream_read(sourcef, buf, write_size);

		while(count == 0)
		{
			i++;
			lsn = file_info.sector_map[i].lsn;
			count = file_info.sector_map[i].count;
		}

		err = os9_write_lsn(image, lsn, 0, buf, write_size);
		if (err)
			goto done;

		lsn++;
		count--;
		sz -= write_size;
	}

done:
	if (buf)
		free(buf);
	return err;
}
Ejemplo n.º 5
0
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);
	}
Ejemplo n.º 6
0
static imgtoolerr_t os9_diskimage_freespace(imgtool_partition *partition, UINT64 *size)
{
	imgtool_image *image = imgtool_partition_image(partition);
	const os9_diskinfo *disk_info;
	UINT32 free_lsns;

	disk_info = os9_get_diskinfo(image);
	free_lsns = os9_get_free_lsns(image);

	*size = free_lsns * disk_info->sector_size;
	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 7
0
static imgtoolerr_t rsdos_diskimage_deletefile(imgtool_partition *partition, const char *fname)
{
    imgtoolerr_t err;
    imgtool_image *image = imgtool_partition_image(partition);
    int pos;
    struct rsdos_dirent ent;

    err = lookup_rsdos_file(image, fname, &ent, &pos);
    if (err)
        return err;

    return delete_entry(image, &ent, pos);
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
static imgtoolerr_t vzdos_diskimage_suggesttransfer(imgtool_partition *partition, const char *fname, imgtool_transfer_suggestion *suggestions, size_t suggestions_length)
{
	imgtoolerr_t ret;
	imgtool_image *image = imgtool_partition_image(partition);
	vzdos_dirent entry;

	if (fname) {

		ret = vzdos_get_dirent_fname(image, fname, &entry);
		if (ret) return ret;

		switch (entry.ftype) {
			case 'B':
				suggestions[0].viability = SUGGESTION_RECOMMENDED;
				suggestions[0].filter = filter_vzsnapshot_getinfo;
				suggestions[0].description = "VZ Snapshot";
				suggestions[1].viability = SUGGESTION_POSSIBLE;
				suggestions[1].filter = NULL;
				suggestions[1].description = "Raw";
				break;
			case 'T':
				suggestions[0].viability = SUGGESTION_RECOMMENDED;
				suggestions[0].filter = filter_vzsnapshot_getinfo;
				suggestions[0].description = "VZ Snapshot";
				suggestions[1].viability = SUGGESTION_POSSIBLE;
				suggestions[1].filter = NULL;
				suggestions[1].description = "Raw";
				suggestions[2].viability = SUGGESTION_POSSIBLE;
				suggestions[2].filter = filter_vzbas_getinfo;
				suggestions[2].description = "Tokenized Basic";
				break;
			default:
				suggestions[0].viability = SUGGESTION_RECOMMENDED;
				suggestions[0].filter = NULL;
				suggestions[0].description = "Raw";
		}

	} else {
		suggestions[0].viability = SUGGESTION_RECOMMENDED;
		suggestions[0].filter = NULL;
		suggestions[0].description = "Raw";
		suggestions[1].viability = SUGGESTION_POSSIBLE;
		suggestions[1].filter = filter_vzsnapshot_getinfo;
		suggestions[1].description = "VZ Snapshot";
	}

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 10
0
static imgtoolerr_t vzdos_diskimage_readfile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf)
{
	imgtoolerr_t ret;
	imgtool_image *image = imgtool_partition_image(partition);
	int filesize, track, sector;
	vzdos_dirent ent;
	UINT8 buffer[DATA_SIZE + 2];

	ret = vzdos_get_dirent_fname(image, filename, &ent);
	if (ret) return ret;

	filesize = ent.end_address - ent.start_address;
	track = ent.start_track;
	sector = ent.start_sector;

	while (filesize > 0) {
		int towrite;

		ret = vzdos_read_sector_data(image, track, sector, buffer);
		if (ret) return ret;

		/* detect sectors pointing to themselfs */
		if ((track == pick_integer_le(buffer, DATA_SIZE, 1)) && (sector == pick_integer_le(buffer, DATA_SIZE + 1, 1)))
			return IMGTOOLERR_CORRUPTIMAGE;

		/* load next track and sector values */
		track  = pick_integer_le(buffer, DATA_SIZE, 1);
		sector = pick_integer_le(buffer, DATA_SIZE + 1, 1);

		/* track 0 is invalid */
		if ((track == 0) && (filesize > DATA_SIZE))
			return IMGTOOLERR_CORRUPTIMAGE;

		/* write either DATA_SIZE or the remaining bytes */
		towrite = filesize > DATA_SIZE ? DATA_SIZE : filesize;

		if (stream_write(destf, buffer, towrite) != towrite)
			return IMGTOOLERR_WRITEERROR;

		filesize -= DATA_SIZE;
	}

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 11
0
static imgtoolerr_t vzsnapshot_readfile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf)
{
	imgtoolerr_t ret;
	imgtool_image *image = imgtool_partition_image(partition);
	vzdos_dirent entry;
	UINT8 header[24];

	/* get directory entry from disk */
	ret = vzdos_get_dirent_fname(image, filename, &entry);
	if (ret) return ret;

	/* prepare header */
	header[0] = 'V';
	header[1] = 'Z';
	header[2] = 'F';

	switch (entry.ftype) {
		case 'B':
			header[3] = '1';
			header[21] = 0xF1;
			break;
		case 'T':
			header[3] = '0';
			header[21] = 0xF0;
			break;
		default:
			memset(header, 0x00, 4);
			header[21] = 0x00;
	}

	memset(header + 4, 0x00, 17);
	memcpy(header + 4, entry.fname, vzdos_get_fname_len(entry.fname) + 1);
	place_integer_le(header, 22, 2, entry.start_address);

	/* write header to file */
	stream_write(destf, header, sizeof(header));

	/* write data to file */
	ret = vzdos_diskimage_readfile(partition, filename, "", destf);
	if (ret) return ret;

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 12
0
static imgtoolerr_t rsdos_diskimage_suggesttransfer(imgtool_partition *partition, const char *fname, imgtool_transfer_suggestion *suggestions, size_t suggestions_length)
{
    imgtoolerr_t err;
    imgtool_image *image = imgtool_partition_image(partition);
    struct rsdos_dirent ent;
    int pos;

    if (fname)
    {
        err = lookup_rsdos_file(image, fname, &ent, &pos);
        if (err)
            return err;

        if (ent.asciiflag == (char) 0xFF)
        {
            /* ASCII file */
            suggestions[0].viability = SUGGESTION_RECOMMENDED;
            suggestions[0].filter = filter_eoln_getinfo;
            suggestions[1].viability = SUGGESTION_POSSIBLE;
            suggestions[1].filter = NULL;
        }
        else if (ent.ftype == 0)
        {
            /* tokenized BASIC file */
            suggestions[0].viability = SUGGESTION_RECOMMENDED;
            suggestions[0].filter = NULL;
            suggestions[1].viability = SUGGESTION_POSSIBLE;
            suggestions[1].filter = filter_cocobas_getinfo;
        }
    }
    else
    {
        suggestions[0].viability = SUGGESTION_RECOMMENDED;
        suggestions[0].filter = NULL;
        suggestions[1].viability = SUGGESTION_POSSIBLE;
        suggestions[1].filter = filter_eoln_getinfo;
        suggestions[2].viability = SUGGESTION_POSSIBLE;
        suggestions[2].filter = filter_cocobas_getinfo;
    }

    return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 13
0
static imgtoolerr_t rsdos_diskimage_readfile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *destf)
{
    imgtoolerr_t err;
    struct rsdos_dirent ent;
    size_t size;
    imgtool_image *img = imgtool_partition_image(partition);

    err = lookup_rsdos_file(img, fname, &ent, NULL);
    if (err)
        return err;

    err = process_rsdos_file(&ent, img, destf, &size);
    if (err)
        return err;

    if (size == (size_t) -1)
        return IMGTOOLERR_CORRUPTIMAGE;

    return (imgtoolerr_t)0;
}
Ejemplo n.º 14
0
static imgtoolerr_t rsdos_diskimage_freespace(imgtool_partition *partition, UINT64 *size)
{
    floperr_t ferr;
    UINT8 i;
    size_t s = 0;
    UINT8 granule_count;
    UINT8 granule_map[MAX_GRANULEMAP_SIZE];
    imgtool_image *image = imgtool_partition_image(partition);

    ferr = get_granule_map(image, granule_map, &granule_count);
    if (ferr)
        return imgtool_floppy_error(ferr);

    for (i = 0; i < granule_count; i++)
    {
        if (granule_map[i] == 0xff)
            s += (9 * 256);
    }
    *size = s;
    return (imgtoolerr_t)FLOPPY_ERROR_SUCCESS;
}
Ejemplo n.º 15
0
/* TRK 0 sector 15 is used to hold the track map of the disk with one bit
   corresponding to a sector used. */
static imgtoolerr_t vzdos_diskimage_freespace(imgtool_partition *partition, UINT64 *size)
{
	imgtoolerr_t ret;
	int i;
	imgtool_image *image = imgtool_partition_image(partition);
	UINT8 c, v, buffer[DATA_SIZE + 2];
	*size = 0;

	ret = vzdos_read_sector_data(image, 0, 15, buffer);
	if (ret) return ret;

	for (i = 0; i < DATA_SIZE; i++) {
		v = buffer[i];
		for (c = 0; v; c++) {
			v &= v - 1;
		}
		*size += c * DATA_SIZE;
	}
	*size = (DATA_SIZE * 16 * 39) - *size;

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 16
0
/* deletes directory entry, clears trackmap entries and sectors */
static imgtoolerr_t vzdos_diskimage_deletefile(imgtool_partition *partition, const char *fname)
{
	imgtoolerr_t ret;
	imgtool_image *img = imgtool_partition_image(partition);
	int index, filesize, track, sector, next_track, next_sector;
	vzdos_dirent entry, next_entry;
	UINT8 buffer[DATA_SIZE + 2];

	ret = vzdos_get_dirent_fname(img, fname, &entry);
	if (ret) return ret;

	ret = (imgtoolerr_t)floppy_read_sector(imgtool_floppy(img), 0, entry.start_track, sector_order[entry.start_sector], 24, &buffer, DATA_SIZE + 2);
	if (ret) return ret;

	filesize = entry.end_address - entry.start_address;
	track    = entry.start_track;
	sector   = entry.start_sector;

	/* delete directory entry */
	ret = vzdos_searchentry(img, fname, &index);
	if (ret) return ret;

	ret = vzdos_get_dirent(img, index + 1, &next_entry);

	if (ret == IMGTOOLERR_FILENOTFOUND) {

		/* we are the last directory entry, just delete it */
		ret = vzdos_clear_dirent(img, index);
		if (ret) return ret;

	} else if (ret) {

		/* an error occured */
		return ret;

	} else {

		ret = vzdos_set_dirent(img, index++, next_entry);
		if (ret) return ret;

		while ((ret = vzdos_get_dirent(img, index + 1, &next_entry)) != IMGTOOLERR_FILENOTFOUND) {
			if (ret) return ret;
			ret = vzdos_set_dirent(img, index++, next_entry);
			if (ret) return ret;
		}

		ret = vzdos_clear_dirent(img, index);
		if (ret) return ret;

	}

	/* clear sectors and trackmap entries */
	while (filesize > 0) {

		filesize -= DATA_SIZE;

		/* clear trackmap entry */
		ret = vzdos_clear_trackmap(img, track, sector);
		if (ret) return ret;

		/* load next track and sector values */
		next_track  = pick_integer_le(buffer, DATA_SIZE, 1);
		next_sector = pick_integer_le(buffer, DATA_SIZE + 1, 1);

		/* overwrite sector with default values */
		ret = vzdos_clear_sector(img, track, sector);
		if (ret) return ret;

		/* read next sector */
		track  = next_track;
		sector = next_sector;

		if (filesize > 0) {
			ret = (imgtoolerr_t)floppy_read_sector(imgtool_floppy(img), 0, track, sector_order[sector], 24, &buffer, DATA_SIZE + 2);
			if (ret) return ret;
		}

	}

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 17
0
static imgtoolerr_t macbinary_writefile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts)
{
	static const UINT32 attrs[] =
	{
		IMGTOOLATTR_TIME_CREATED,
		IMGTOOLATTR_TIME_LASTMODIFIED,
		IMGTOOLATTR_INT_MAC_TYPE,
		IMGTOOLATTR_INT_MAC_CREATOR,
		IMGTOOLATTR_INT_MAC_FINDERFLAGS,
		IMGTOOLATTR_INT_MAC_COORDX,
		IMGTOOLATTR_INT_MAC_COORDY,
		IMGTOOLATTR_INT_MAC_FINDERFOLDER,
		IMGTOOLATTR_INT_MAC_SCRIPTCODE,
		IMGTOOLATTR_INT_MAC_EXTENDEDFLAGS,
		0
	};
	imgtoolerr_t err;
	imgtool_image *image = imgtool_partition_image(partition);
	UINT8 header[128];
	UINT32 datafork_size;
	UINT32 resourcefork_size;
	UINT64 total_size;
	UINT32 creation_time;
	UINT32 lastmodified_time;
	//int version;
	imgtool_attribute attr_values[10];

	UINT32 type_code;
	UINT32 creator_code;
	UINT16 finder_flags;
	UINT16 coord_x;
	UINT16 coord_y;
	UINT16 finder_folder;
	UINT8 script_code = 0;
	UINT8 extended_flags = 0;

	/* read in the header */
	memset(header, 0, sizeof(header));
	stream_read(sourcef, header, sizeof(header));

	/* check magic and zero fill bytes */
	if (header[0] != 0x00)
		return IMGTOOLERR_CORRUPTFILE;
	if (header[74] != 0x00)
		return IMGTOOLERR_CORRUPTFILE;
	if (header[82] != 0x00)
		return IMGTOOLERR_CORRUPTFILE;

	datafork_size = pick_integer_be(header, 83, 4);
	resourcefork_size = pick_integer_be(header, 87, 4);
	total_size = stream_size(sourcef);

	/* size of a MacBinary header is always 128 bytes */
	if (total_size - pad128(datafork_size) - pad128(resourcefork_size) != 128)
		return IMGTOOLERR_CORRUPTFILE;

	/* check filename length byte */
	if ((header[1] <= 0x00) || (header[1] > 0x3F))
		return IMGTOOLERR_CORRUPTFILE;

	/* check the CRC */
	if (pick_integer_be(header, 124, 2) != ccitt_crc16(0, header, 124))
	{
		/* the CRC does not match; this file is MacBinary I */
		//version = 1;
	}
	else if (pick_integer_be(header, 102, 4) != 0x6D42494E)
	{
		/* did not see 'mBIN'; this file is MacBinary II */
		if (header[122] < 0x81)
			return IMGTOOLERR_CORRUPTFILE;
		if (header[123] < 0x81)
			return IMGTOOLERR_CORRUPTFILE;
		//version = 2;
	}
	else
	{
		/* we did see 'mBIN'; this file is MacBinary III */
		if (header[122] < 0x82)
			return IMGTOOLERR_CORRUPTFILE;
		if (header[123] < 0x81)
			return IMGTOOLERR_CORRUPTFILE;
		//version = 3;
	}

	type_code         = pick_integer_be(header, 65, 4);
	creator_code      = pick_integer_be(header, 69, 4);
	finder_flags      = pick_integer_be(header, 73, 1) << 8;
	coord_x           = pick_integer_be(header, 75, 2);
	coord_y           = pick_integer_be(header, 77, 2);
	finder_folder     = pick_integer_be(header, 79, 2);
	creation_time     = pick_integer_be(header, 91, 4);
	lastmodified_time = pick_integer_be(header, 95, 4);

	if (image)
	{
		/* write out both forks */
		err = write_fork(partition, filename, "", sourcef, sizeof(header), datafork_size, opts);
		if (err)
			return err;
		err = write_fork(partition, filename, "RESOURCE_FORK", sourcef, sizeof(header) + pad128(datafork_size), resourcefork_size, opts);
		if (err)
			return err;

		/* set up attributes */
		attr_values[0].t = mac_crack_time(creation_time);
		attr_values[1].t = mac_crack_time(lastmodified_time);
		attr_values[2].i = type_code;
		attr_values[3].i = creator_code;
		attr_values[4].i = finder_flags;
		attr_values[5].i = coord_x;
		attr_values[6].i = coord_y;
		attr_values[7].i = finder_folder;
		attr_values[8].i = script_code;
		attr_values[9].i = extended_flags;

		err = imgtool_partition_put_file_attributes(partition, filename, attrs, attr_values);
		if (err)
			return err;
	}

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 18
0
static imgtoolerr_t os9_diskimage_delete(imgtool_partition *partition, const char *path,
	unsigned int delete_directory)
{
	imgtoolerr_t err;
	imgtool_image *image = imgtool_partition_image(partition);
	//const os9_diskinfo *disk_info;
	struct os9_fileinfo file_info;
	UINT32 dirent_lsn, dirent_index;
	UINT32 entry_lsn, entry_index;
	UINT32 i, j, lsn;
	UINT8 b;

	//disk_info = os9_get_diskinfo(image);

	err = os9_lookup_path(image, path, CREATE_NONE, &file_info, NULL, &dirent_lsn, &dirent_index);
	if (err)
		return err;
	if (file_info.directory != delete_directory)
		return IMGTOOLERR_FILENOTFOUND;

	/* make sure that if we are deleting a directory, it is empty */
	if (delete_directory)
	{
		for (i = 64; i < file_info.file_size; i += 32)
		{
			entry_index = i;
			entry_lsn = os9_lookup_lsn(image, &file_info, &entry_index);

			err = os9_read_lsn(image, entry_lsn, entry_index, &b, 1);
			if (err)
				return err;

			/* this had better be a deleted file, if not we can't delete */
			if (b != 0)
				return IMGTOOLERR_DIRNOTEMPTY;
		}
	}

	/* zero out the file entry */
	b = '\0';
	err = os9_write_lsn(image, dirent_lsn, dirent_index, &b, 1);
	if (err)
		return err;

	/* get the link count */
	err = os9_read_lsn(image, file_info.lsn, 8, &b, 1);
	if (err)
		return err;

	if (b > 0)
		b--;
	if (b > 0)
	{
		/* link count is greater than zero */
		err = os9_write_lsn(image, file_info.lsn, 8, &b, 1);
		if (err)
			return err;
	}
	else
	{
		/* no more links; outright delete the file */
		err = os9_deallocate_lsn(image, file_info.lsn);
		if (err)
			return err;

		for (i = 0; (i < ARRAY_LENGTH(file_info.sector_map)) && file_info.sector_map[i].count; i++)
		{
			lsn = file_info.sector_map[i].lsn;
			for (j = 0;  j < file_info.sector_map[i].count; j++)
			{
				err = os9_deallocate_lsn(image, lsn + j);
				if (err)
					return err;
			}
		}
	}

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 19
0
static imgtoolerr_t bml3_diskimage_writefile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *sourcef, option_resolution *writeoptions)
{
	floperr_t ferr;
	imgtoolerr_t err;
	imgtool_image *img = imgtool_partition_image(partition);
	bml3_diskinfo *info = bml3_get_diskinfo(img);
	struct bml3_dirent ent, ent2;
	size_t i;
	UINT64 sz, read_sz;
	UINT64 freespace = 0;
	unsigned char g;
	unsigned char *gptr;
	UINT8 granule_count;
	UINT8 granule_map[MAX_GRANULEMAP_SIZE];
	UINT8 eof_buf[MAX_SECTOR_SIZE];

	// one-time setup of eof_buf
	memset(eof_buf, 0, sizeof(eof_buf));
	eof_buf[0] = 0x1A;

	/* can we write to this image? */
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	err = bml3_diskimage_freespace(partition, &freespace);
	if (err)
		return err;

	/* is there enough space? */
	sz = read_sz = stream_size(sourcef);
	if (info->variant == 0) {
		// also need to write EOF
		sz++;
	}
	if (sz > freespace)
		return IMGTOOLERR_NOSPACE;

	/* setup our directory entry */
	err = prepare_dirent(info->variant, &ent, fname);
	if (err)
		return err;

	ent.ftype = option_resolution_lookup_int(writeoptions, BML3_OPTIONS_FTYPE);
	ent.asciiflag = ((UINT8) option_resolution_lookup_int(writeoptions, BML3_OPTIONS_ASCII)) - 1;
	gptr = &ent.first_granule;

	ferr = get_granule_map(img, granule_map, &granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	g = 0x00;

	do
	{
		while (granule_map[g] != 0xff)
		{
			g++;
			if ((g >= granule_count) || (g == 0))
				return IMGTOOLERR_UNEXPECTED;   /* We should have already verified that there is enough space */
		}
		*gptr = g;
		gptr = &granule_map[g];


		i = MIN(read_sz, info->granule_sectors * info->sector_size);
		if (i > 0) {
			err = transfer_to_granule(img, g, i, sourcef);
			if (err)
				return err;
			read_sz -= i;
			sz -= i;
		}
		if (i < info->granule_sectors * info->sector_size && sz > 0) {
			// write EOF and trailing NULs in the final sector
			ferr = write_granule(img, g, i, (info->granule_sectors * info->sector_size - i - 1) % info->sector_size + 1, eof_buf);
			if (ferr)
				return imgtool_floppy_error(ferr);
			sz--;
			i++;
		}

		/* Go to next granule */
		g++;
	}
	while(sz > 0);

	/* Now that we are done with the file, we need to specify the final entry
	 * in the file allocation table
	 */
	*gptr = 0xc0 + ((i + info->sector_size-1) / info->sector_size) - (info->variant == 0 ? 1 : 0);
	ent.lastsectorbytes = (i - 1) % info->sector_size + 1;

	/* delete file if it already exists */
	err = bml3_diskimage_deletefile(partition, fname);
	if (err && err != IMGTOOLERR_FILENOTFOUND)
		return err;

	/* Now we need to find an empty directory entry */
	i = -1;
	do
	{
		ferr = get_bml3_dirent(img, ++i, &ent2);
		if (ferr)
			return imgtool_floppy_error(ferr);
	}
	while(ent2.fname[0] != '\0' && ent2.fname[0] != -1);

	ferr = put_bml3_dirent(img, i, &ent);
	if (ferr)
		return imgtool_floppy_error(ferr);

	/* write the granule map back out */
	ferr = put_granule_map(img, granule_map, granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
Ejemplo n.º 20
0
static imgtoolerr_t vzdos_writefile(imgtool_partition *partition, int offset, imgtool_stream *sourcef, vzdos_dirent *entry)
{
	imgtoolerr_t ret;
	imgtool_image *img = imgtool_partition_image(partition);
	int index, track, sector, toread, next_track, next_sector;
	vzdos_dirent temp_entry;
	UINT64 filesize = 0, freespace = 0;
	UINT8 buffer[DATA_SIZE + 2];
	char filename[9];

	/* is the image writeable? */
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	/* check for already existing filename -> overwrite */
	strcpy(filename, entry->fname);
	filename[vzdos_get_fname_len(entry->fname) + 1] = 0x00;
	ret = vzdos_get_dirent_fname(img, filename, &temp_entry);
	if (!ret) {
		/* file already exists, delete it */
		ret = vzdos_diskimage_deletefile(partition, filename);
		if (ret) return ret;
	} else if (ret != IMGTOOLERR_FILENOTFOUND) {
		/* another error occured, return it */
		return ret;
	}

	ret = (imgtoolerr_t)stream_seek(sourcef, offset, SEEK_SET);
	if (ret) return ret;

	/* check if there is enough space */
	filesize = stream_size(sourcef) - offset;

	ret = vzdos_diskimage_freespace(partition, &freespace);
	if (ret) return ret;

	if (filesize > freespace)
		return IMGTOOLERR_NOSPACE;

	/* get next free track and sector */
	ret = vzdos_free_trackmap(img, &track, &sector);
	if (ret) return ret;

	entry->end_address = entry->start_address + (unsigned int) filesize;
	entry->start_track   = track;
	entry->start_sector  = sector;

	/* search for next free directory entry */
	for (index = 0; index < MAX_DIRENTS; index++) {
		ret = vzdos_get_dirent(img, index, &temp_entry);
		if (ret == IMGTOOLERR_FILENOTFOUND)
			break;
		else if (ret)
			return (ret);
	}

	/* write directory entry to disk */
	ret = vzdos_set_dirent(img, index, *entry);
	if (ret) return ret;

	next_track  = 0;
	next_sector = 0;

	/* write data to disk */
	while (filesize > 0) {

		toread = filesize > DATA_SIZE ? DATA_SIZE : filesize;
		stream_read(sourcef, buffer, toread);

		filesize -= toread;

		/* mark sector as used */
		ret = vzdos_set_trackmap(img, track, sector);
		if (ret) return ret;

		/* get track and sector for next sector */
		if (filesize > 0) {
			ret = vzdos_free_trackmap(img, &next_track, &next_sector);
			if (ret) return ret;
		} else {
			next_track = 0;
			next_sector = 0;
		}
		buffer[DATA_SIZE]     = next_track;
		buffer[DATA_SIZE + 1] = next_sector;

		/* write sector to disk */
		ret = vzdos_write_sector_data(img, track, sector, buffer);
		if (ret) return ret;

		track  = next_track;
		sector = next_sector;
	}

	return IMGTOOLERR_SUCCESS;

}
Ejemplo n.º 21
0
static imgtoolerr_t rsdos_diskimage_writefile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *sourcef, util::option_resolution *writeoptions)
{
    floperr_t ferr;
    imgtoolerr_t err;
    imgtool_image *img = imgtool_partition_image(partition);
    struct rsdos_dirent ent, ent2;
    size_t i;
    UINT64 sz;
    UINT64 freespace = 0;
    unsigned char g;
    unsigned char *gptr;
    UINT8 granule_count;
    UINT8 granule_map[MAX_GRANULEMAP_SIZE];

    /* can we write to this image? */
    if (floppy_is_read_only(imgtool_floppy(img)))
        return IMGTOOLERR_READONLY;

    err = rsdos_diskimage_freespace(partition, &freespace);
    if (err)
        return err;

    /* is there enough space? */
    sz = stream_size(sourcef);
    if (sz > freespace)
        return IMGTOOLERR_NOSPACE;

    /* setup our directory entry */
    err = prepare_dirent(&ent, fname);
    if (err)
        return err;

    ent.ftype = writeoptions->lookup_int(RSDOS_OPTIONS_FTYPE);
    ent.asciiflag = UINT8(writeoptions->lookup_int(RSDOS_OPTIONS_ASCII)) - 1;
    ent.lastsectorbytes_lsb = sz % 256;
    ent.lastsectorbytes_msb = (((sz % 256) == 0) && (sz > 0)) ? 1 : 0;
    gptr = &ent.first_granule;

    ferr = get_granule_map(img, granule_map, &granule_count);
    if (ferr)
        return imgtool_floppy_error(ferr);

    g = 0x00;

    do
    {
        while (granule_map[g] != 0xff)
        {
            g++;
            if ((g >= granule_count) || (g == 0))
                return IMGTOOLERR_UNEXPECTED;   /* We should have already verified that there is enough space */
        }
        *gptr = g;
        gptr = &granule_map[g];


        i = std::min(sz, UINT64(9*256));
        err = transfer_to_granule(img, g, i, sourcef);
        if (err)
            return err;

        sz -= i;

        /* Go to next granule */
        g++;
    }
    while(sz > 0);

    /* Now that we are done with the file, we need to specify the final entry
     * in the file allocation table
     */
    *gptr = 0xc0 + ((i + 255) / 256);

    /* Now we need to find an empty directory entry */
    i = -1;
    do
    {
        ferr = get_rsdos_dirent(img, ++i, &ent2);
        if (ferr)
            return imgtool_floppy_error(ferr);
    }
    while((ent2.fname[0] != '\0') && strcmp(ent.fname, ent2.fname) && (ent2.fname[0] != -1));

    /* delete file if it already exists */
    if (ent2.fname[0] && (ent2.fname[0] != -1))
    {
        err = delete_entry(img, &ent2, i);
        if (err)
            return err;
    }

    ferr = put_rsdos_dirent(img, i, &ent);
    if (ferr)
        return imgtool_floppy_error(ferr);

    /* write the granule map back out */
    ferr = put_granule_map(img, granule_map, granule_count);
    if (ferr)
        return imgtool_floppy_error(ferr);

    return IMGTOOLERR_SUCCESS;
}