Example #1
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;
}
Example #2
0
static imgtoolerr_t os9_diskimage_create(imgtool_image *img, imgtool_stream *stream, option_resolution *opts)
{
	imgtoolerr_t err;
	dynamic_buffer header;
	UINT32 heads, tracks, sectors, sector_bytes, first_sector_id;
	UINT32 cluster_size, owner_id;
	UINT32 allocation_bitmap_bits, allocation_bitmap_lsns;
	UINT32 attributes, format_flags, disk_id;
	UINT32 i;
	INT32 total_allocated_sectors;
	const char *title;
	time_t t;
	struct tm *ltime;

	time(&t);
	ltime = localtime(&t);

	heads = option_resolution_lookup_int(opts, 'H');
	tracks = option_resolution_lookup_int(opts, 'T');
	sectors = option_resolution_lookup_int(opts, 'S');
	sector_bytes = option_resolution_lookup_int(opts, 'L');
	first_sector_id = option_resolution_lookup_int(opts, 'F');
	title = "";

	header.resize(sector_bytes);

	if (sector_bytes > 256)
		sector_bytes = 256;
	cluster_size = 1;
	owner_id = 1;
	disk_id = 1;
	attributes = 0;
	allocation_bitmap_bits = heads * tracks * sectors / cluster_size;
	allocation_bitmap_lsns = (allocation_bitmap_bits / 8 + sector_bytes - 1) / sector_bytes;
	format_flags = ((heads > 1) ? 0x01 : 0x00) | ((tracks > 40) ? 0x02 : 0x00);

	memset(&header[0], 0, sector_bytes);
	place_integer_be(&header[0],   0,  3, heads * tracks * sectors);
	place_integer_be(&header[0],   3,  1, sectors);
	place_integer_be(&header[0],   4,  2, (allocation_bitmap_bits + 7) / 8);
	place_integer_be(&header[0],   6,  2, cluster_size);
	place_integer_be(&header[0],   8,  3, 1 + allocation_bitmap_lsns);
	place_integer_be(&header[0],  11,  2, owner_id);
	place_integer_be(&header[0],  13,  1, attributes);
	place_integer_be(&header[0],  14,  2, disk_id);
	place_integer_be(&header[0],  16,  1, format_flags);
	place_integer_be(&header[0],  17,  2, sectors);
	place_string(&header[0],   31, 32, title);
	place_integer_be(&header[0], 103, 2, sector_bytes / 256);

	/* path descriptor options */
	place_integer_be(&header[0], 0x3f+0x00, 1, 1); /* device class */
	place_integer_be(&header[0], 0x3f+0x01, 1, 1); /* drive number */
	place_integer_be(&header[0], 0x3f+0x03, 1, 0x20); /* device type */
	place_integer_be(&header[0], 0x3f+0x04, 1, 1); /* density capability */
	place_integer_be(&header[0], 0x3f+0x05, 2, tracks); /* number of tracks */
	place_integer_be(&header[0], 0x3f+0x07, 1, heads); /* number of sides */
	place_integer_be(&header[0], 0x3f+0x09, 2, sectors); /* sectors per track */
	place_integer_be(&header[0], 0x3f+0x0b, 2, sectors); /* sectors on track zero */
	place_integer_be(&header[0], 0x3f+0x0d, 1, 3); /* sector interleave factor */
	place_integer_be(&header[0], 0x3f+0x0e, 1, 8); /* default sectors per allocation */

	err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id, 0, &header[0], sector_bytes, 0);    /* TODO: pass ddam argument from imgtool */
	if (err)
		goto done;

	total_allocated_sectors = 1 + allocation_bitmap_lsns + 1 + 7;

	for (i = 0; i < allocation_bitmap_lsns; i++)
	{
		memset(&header[0], 0x00, sector_bytes);

		if (total_allocated_sectors > (8 * 256))
		{
			memset(&header[0], 0xff, sector_bytes);
			total_allocated_sectors -= (8 * 256);
		}
		else if (total_allocated_sectors > 1 )
		{
			int offset;
			UINT8 mask;

			while( total_allocated_sectors >= 0 )
			{
				offset = total_allocated_sectors / 8;
				mask = 1 << (7 - ( total_allocated_sectors % 8 ) );

				header[offset] |= mask;
				total_allocated_sectors--;
			}
		}

		err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 1 + i, 0, &header[0], sector_bytes, 0);    /* TODO: pass ddam argument from imgtool */
		if (err)
			goto done;
	}

	memset(&header[0], 0, sector_bytes);
	header[0x00] = 0xBF;
	header[0x01] = 0x00;
	header[0x02] = 0x00;
	header[0x03] = (UINT8) ltime->tm_year;
	header[0x04] = (UINT8) ltime->tm_mon + 1;
	header[0x05] = (UINT8) ltime->tm_mday;
	header[0x06] = (UINT8) ltime->tm_hour;
	header[0x07] = (UINT8) ltime->tm_min;
	header[0x08] = 0x02;
	header[0x09] = 0x00;
	header[0x0A] = 0x00;
	header[0x0B] = 0x00;
	header[0x0C] = 0x40;
	header[0x0D] = (UINT8) (ltime->tm_year % 100);
	header[0x0E] = (UINT8) ltime->tm_mon;
	header[0x0F] = (UINT8) ltime->tm_mday;
	place_integer_be(&header[0], 0x10, 3, 1 + allocation_bitmap_lsns + 1);
	place_integer_be(&header[0], 0x13, 2, 8);

	err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 1 + allocation_bitmap_lsns, 0, &header[0], sector_bytes, 0);   /* TODO: pass ddam argument from imgtool */
	if (err)
		goto done;

	memset(&header[0], 0, sector_bytes);
	header[0x00] = 0x2E;
	header[0x01] = 0xAE;
	header[0x1F] = 1 + allocation_bitmap_lsns;
	header[0x20] = 0xAE;
	header[0x3F] = 1 + allocation_bitmap_lsns;
	err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 2 + allocation_bitmap_lsns, 0, &header[0], sector_bytes, 0);   /* TOOD: pass ddam argument from imgtool */
	if (err)
		goto done;

done:
	return err;
}
Example #3
0
static imgtoolerr_t os9_lookup_path(imgtool_image *img, const char *path,
	creation_policy_t create, struct os9_fileinfo *file_info,
	UINT32 *parent_lsn, UINT32 *dirent_lsn, UINT32 *dirent_index)
{
	imgtoolerr_t err = IMGTOOLERR_SUCCESS;
	struct os9_fileinfo dir_info;
	UINT32 index, current_lsn, dir_size;
	UINT32 entry_index = 0;
	UINT32 free_entry_index = 0xffffffff;
	UINT32 entry_lsn = 0;
	UINT32 allocated_lsn = 0;
	UINT8 entry[32];
	UINT8 block[64];
	char *filename;
	const os9_diskinfo *disk_info;

	disk_info = os9_get_diskinfo(img);
	current_lsn = disk_info->root_dir_lsn;

	if (parent_lsn)
		*parent_lsn = 0;

	/* we have to transverse each path element */
	while(*path)
	{
		if (parent_lsn)
			*parent_lsn = current_lsn;

		/* decode the directory header of this directory */
		err = os9_decode_file_header(img, current_lsn, &dir_info);
		if (err)
			goto done;
		dir_size = dir_info.file_size;

		/* sanity check directory */
		if (!dir_info.directory)
		{
			err = (current_lsn == disk_info->root_dir_lsn) ? IMGTOOLERR_CORRUPTIMAGE : IMGTOOLERR_INVALIDPATH;
			goto done;
		}

		/* walk the directory */
		for (index = 0; index < dir_size; index += 32)
		{
			entry_index = index;
			entry_lsn = os9_lookup_lsn(img, &dir_info, &entry_index);

			err = os9_read_lsn(img, entry_lsn, entry_index, entry, sizeof(entry));
			if (err)
				goto done;

			/* remember first free entry found */
			if( free_entry_index == 0xffffffff )
			{
				if( entry[0] == 0 )
					free_entry_index = index;
			}

			if (os9_interpret_dirent(entry, &filename, &current_lsn, NULL))
			{
				if (!strcmp(path, filename))
					break;
			}

		}

		/* at the end of the file? */
		if (index >= dir_size)
		{
			/* if we're not creating, or we are creating but we have not fully
			 * transversed the directory, error out */
			if (!create || path[strlen(path) + 1])
			{
				err = IMGTOOLERR_PATHNOTFOUND;
				goto done;
			}

			/* allocate a new LSN */
			err = os9_allocate_lsn(img, &allocated_lsn);
			if (err)
				goto done;

			/* write the file */
			memset(block, 0, sizeof(block));
			place_integer_be(block, 0, 1, 0x1B | ((create == CREATE_DIR) ? 0x80 : 0x00));
			err = os9_write_lsn(img, allocated_lsn, 0, block, sizeof(block));
			if (err)
				goto done;

			if( free_entry_index == 0xffffffff )
			{
				/* expand the directory to hold the new entry */
				err = os9_set_file_size(img, &dir_info, dir_size + 32);
				if (err)
					goto done;
			}
			else
				/* use first unused entry in directory */
				dir_size = free_entry_index;

			/* now prepare the directory entry */
			memset(entry, 0, sizeof(entry));
			place_string(entry, 0, 28, path);
			place_integer_be(entry, 29, 3, allocated_lsn);

			/* now write the directory entry */
			entry_index = dir_size;
			entry_lsn = os9_lookup_lsn(img, &dir_info, &entry_index);
			err = os9_write_lsn(img, entry_lsn, entry_index, entry, 32);
			if (err)
				goto done;

			/* directory entry append complete; no need to hold this lsn */
			current_lsn = allocated_lsn;
			allocated_lsn = 0;
		}
		path += strlen(path) + 1;
	}

	if (file_info)
	{
		err = os9_decode_file_header(img, current_lsn, file_info);
		if (err)
			goto done;
	}

	if (dirent_lsn)
		*dirent_lsn = entry_lsn;
	if (dirent_index)
		*dirent_index = entry_index;

done:
	if (allocated_lsn != 0)
		os9_deallocate_lsn(img, allocated_lsn);
	return err;
}
Example #4
0
static imgtoolerr_t os9_set_file_size(imgtool_image *image,
	struct os9_fileinfo *file_info, UINT32 new_size)
{
	imgtoolerr_t err;
	const os9_diskinfo *disk_info;
	UINT32 new_lsn_count, current_lsn_count;
	UINT32 free_lsns, lsn, i;
	int sector_map_length = -1;
	UINT8 header[256];

	/* easy way out? */
	if (file_info->file_size == new_size)
		return IMGTOOLERR_SUCCESS;

	disk_info = os9_get_diskinfo(image);

	free_lsns = os9_get_free_lsns(image);
	current_lsn_count = (file_info->file_size + disk_info->sector_size - 1) / disk_info->sector_size;
	new_lsn_count = (new_size + disk_info->sector_size - 1) / disk_info->sector_size;

	/* check to see if the file is growing and we do not have enough space */
	if ((new_lsn_count > current_lsn_count) && (new_lsn_count - current_lsn_count > free_lsns))
		return IMGTOOLERR_NOSPACE;

	if (current_lsn_count != new_lsn_count)
	{
		/* first find out the size of our sector map */
		sector_map_length = 0;
		lsn = 0;
		while((lsn < current_lsn_count) && (sector_map_length < ARRAY_LENGTH(file_info->sector_map)))
		{
			if (file_info->sector_map[sector_map_length].count == 0)
				return os9_corrupt_file_error(file_info);

			lsn += file_info->sector_map[sector_map_length].count;
			sector_map_length++;
		}

		/* keep in mind that the sector_map might not parallel our expected
		 * current LSN count; we should tolerate this abnormality */
		current_lsn_count = lsn;

		while(current_lsn_count > new_lsn_count)
		{
			/* shrink this file */
			lsn = file_info->sector_map[sector_map_length - 1].lsn +
				file_info->sector_map[sector_map_length - 1].count - 1;

			err = os9_deallocate_lsn(image, lsn);
			if (err)
				return err;

			file_info->sector_map[sector_map_length - 1].count--;
			while(sector_map_length > 0 && (file_info->sector_map[sector_map_length - 1].count == 0))
				sector_map_length--;
			current_lsn_count--;
		}

		while(current_lsn_count < new_lsn_count)
		{
			/* grow this file */
			err = os9_allocate_lsn(image, &lsn);
			if (err)
				return err;

			if ((sector_map_length > 0) && ((file_info->sector_map[sector_map_length - 1].lsn +
				file_info->sector_map[sector_map_length - 1].count) == lsn))
			{
				file_info->sector_map[sector_map_length - 1].count++;
			}
			else if (sector_map_length >= ARRAY_LENGTH(file_info->sector_map))
			{
				return IMGTOOLERR_NOSPACE;
			}
			else
			{
				file_info->sector_map[sector_map_length].lsn = lsn;
				file_info->sector_map[sector_map_length].count = 1;
				sector_map_length++;
				file_info->sector_map[sector_map_length].lsn = 0;
				file_info->sector_map[sector_map_length].count = 0;
			}
			current_lsn_count++;
		}
	}

	/* now lets write back the sector */
	err = os9_read_lsn(image, file_info->lsn, 0, header, sizeof(header));
	if (err)
		return err;

	file_info->file_size = new_size;
	place_integer_be(header, 9, 4, file_info->file_size);

	/* do we have to write the sector map? */
	if (sector_map_length >= 0)
	{
		for (i = 0; i < MIN(sector_map_length + 1, ARRAY_LENGTH(file_info->sector_map)); i++)
		{
			place_integer_be(header, 16 + (i * 5) + 0, 3, file_info->sector_map[i].lsn);
			place_integer_be(header, 16 + (i * 5) + 3, 2, file_info->sector_map[i].count);
		}
	}

	err = os9_write_lsn(image, file_info->lsn, 0, header, disk_info->sector_size);
	if (err)
		return err;

	return IMGTOOLERR_SUCCESS;
}
Example #5
0
static imgtoolerr_t macbinary_readfile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf)
{
	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;
	UINT8 header[128];
	const char *basename;
	int i;

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

	imgtool_forkent fork_entries[4];
	const imgtool_forkent *data_fork = NULL;
	const imgtool_forkent *resource_fork = NULL;
	UINT32 creation_time = 0;
	UINT32 lastmodified_time = 0;
	imgtool_attribute attr_values[10];

	/* get the forks */
	err = imgtool_partition_list_file_forks(partition, filename, fork_entries, sizeof(fork_entries));
	if (err)
		return err;
	for (i = 0; fork_entries[i].type != FORK_END; i++)
	{
		if (fork_entries[i].type == FORK_DATA)
			data_fork = &fork_entries[i];
		else if (fork_entries[i].type == FORK_RESOURCE)
			resource_fork = &fork_entries[i];
	}

	/* get the attributes */
	err = imgtool_partition_get_file_attributes(partition, filename, attrs, attr_values);
	if (err && (ERRORCODE(err) != IMGTOOLERR_UNIMPLEMENTED))
		return err;
	if (err == IMGTOOLERR_SUCCESS)
	{
		creation_time     = mac_setup_time(attr_values[0].t);
		lastmodified_time = mac_setup_time(attr_values[1].t);
		type_code         = attr_values[2].i;
		creator_code      = attr_values[3].i;
		finder_flags      = attr_values[4].i;
		coord_x           = attr_values[5].i;
		coord_y           = attr_values[6].i;
		finder_folder     = attr_values[7].i;
		script_code       = attr_values[8].i;
		extended_flags    = attr_values[9].i;
	}

	memset(header, 0, sizeof(header));

	/* place filename */
	basename = filename;
	while(basename[strlen(basename) + 1])
		basename += strlen(basename) + 1;
	pascal_from_c_string((unsigned char *) &header[1], 64, basename);

	place_integer_be(header,  65, 4, type_code);
	place_integer_be(header,  69, 4, creator_code);
	place_integer_be(header,  73, 1, (finder_flags >> 8) & 0xFF);
	place_integer_be(header,  75, 2, coord_x);
	place_integer_be(header,  77, 2, coord_y);
	place_integer_be(header,  79, 2, finder_folder);
	place_integer_be(header,  83, 4, data_fork ? data_fork->size : 0);
	place_integer_be(header,  87, 4, resource_fork ? resource_fork->size : 0);
	place_integer_be(header,  91, 4, creation_time);
	place_integer_be(header,  95, 4, lastmodified_time);
	place_integer_be(header, 101, 1, (finder_flags >> 0) & 0xFF);
	place_integer_be(header, 102, 4, 0x6D42494E);
	place_integer_be(header, 106, 1, script_code);
	place_integer_be(header, 107, 1, extended_flags);
	place_integer_be(header, 122, 1, 0x82);
	place_integer_be(header, 123, 1, 0x81);
	place_integer_be(header, 124, 2, ccitt_crc16(0, header, 124));

	stream_write(destf, header, sizeof(header));

	if (data_fork)
	{
		err = imgtool_partition_read_file(partition, filename, "", destf, NULL);
		if (err)
			return err;

		stream_fill(destf, 0, pad128(data_fork->size));
	}

	if (resource_fork)
	{
		err = imgtool_partition_read_file(partition, filename, "RESOURCE_FORK", destf, NULL);
		if (err)
			return err;

		stream_fill(destf, 0, pad128(resource_fork->size));
	}

	return IMGTOOLERR_SUCCESS;
}