Esempio n. 1
0
static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, rsdos_dirent &ent, int *position = nullptr)
{
	int i;
	floperr_t ferr;
	std::string fnamebuf;

	i = 0;

	do
	{
		do
		{
			ferr = get_rsdos_dirent(f, i++, ent);
			if (ferr)
				return imgtool_floppy_error(ferr);
		}
		while(ent.filename[0] == '\0');


		if (ent.filename[0] != -1)
			fnamebuf = get_dirent_fname(ent);
	}
	while((ent.filename[0] != -1) && core_stricmp(fnamebuf.c_str(), fname));

	if (ent.filename[0] == -1)
		return IMGTOOLERR_FILENOTFOUND;

	if (position)
		*position = i - 1;
	return (imgtoolerr_t)0;
}
Esempio n. 2
0
static imgtoolerr_t rsdos_diskimage_nextenum(imgtool::directory &enumeration, imgtool_dirent &ent)
{
	floperr_t ferr;
	imgtoolerr_t err;
	size_t filesize;
	rsdos_direnum *rsenum;
	rsdos_dirent rsent;

	imgtool::image &image(enumeration.image());
	rsenum = (rsdos_direnum *) enumeration.extra_bytes();

	/* Did we hit the end of file before? */
	if (rsenum->eof)
		goto eof;

	do
	{
		if (rsenum->index >= MAX_DIRENTS)
			goto eof;

		ferr = get_rsdos_dirent(image, rsenum->index++, rsent);
		if (ferr)
			return imgtool_floppy_error(ferr);
	}
	while(rsent.filename[0] == '\0');

	// now are we at the eof point?
	if (rsent.filename[0] == -1)
	{
		rsenum->eof = 1;
eof:
		ent.eof = 1;
	}
	else
	{
		/* Not the end of file */
		err = process_rsdos_file(&rsent, image, nullptr, filesize);
		if (err)
			return err;

		if (filesize == ((size_t) -1))
		{
			/* corrupt! */
			ent.filesize = 0;
			ent.corrupt = 1;
		}
		else
		{
			ent.filesize = filesize;
			ent.corrupt = 0;
		}
		ent.eof = 0;

		std::string fname = get_dirent_fname(rsent);

		snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", fname.c_str());
		snprintf(ent.attr, ARRAY_LENGTH(ent.attr), "%d %c", (int) rsent.ftype, (char) (rsent.asciiflag + 'B'));
	}
	return IMGTOOLERR_SUCCESS;
}
Esempio n. 3
0
static imgtoolerr_t lookup_rsdos_file(imgtool_image *f, const char *fname, struct rsdos_dirent *ent, int *position)
{
    int i;
    floperr_t ferr;
    char fnamebuf[13];

    i = 0;
    fnamebuf[0] = '\0';

    do
    {
        do
        {
            ferr = get_rsdos_dirent(f, i++, ent);
            if (ferr)
                return imgtool_floppy_error(ferr);
        }
        while(ent->fname[0] == '\0');


        if (ent->fname[0] != -1)
            get_dirent_fname(fnamebuf, ent);
    }
    while((ent->fname[0] != -1) && core_stricmp(fnamebuf, fname));

    if (ent->fname[0] == -1)
        return IMGTOOLERR_FILENOTFOUND;

    if (position)
        *position = i - 1;
    return (imgtoolerr_t)0;
}
Esempio n. 4
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(partition.image());
	struct rsdos_dirent ent, ent2;
	size_t i;
	uint64_t sz;
	uint64_t freespace = 0;
	unsigned char g;
	unsigned char *gptr;
	uint8_t granule_count;
	uint8_t 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 = sourcef.size();
	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_t(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_t(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.filename[0] != '\0') && strcmp(ent.filename, ent2.filename) && (ent2.filename[0] != -1));

	// delete file if it already exists
	if (ent2.filename[0] && (ent2.filename[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;
}
Esempio n. 5
0
static imgtoolerr_t rsdos_diskimage_nextenum(imgtool_directory *enumeration, imgtool_dirent *ent)
{
    floperr_t ferr;
    imgtoolerr_t err;
    size_t filesize;
    struct rsdos_direnum *rsenum;
    struct rsdos_dirent rsent;
    char fname[13];
    imgtool_image *image;

    image = imgtool_directory_image(enumeration);
    rsenum = (struct rsdos_direnum *) imgtool_directory_extrabytes(enumeration);

    /* Did we hit the end of file before? */
    if (rsenum->eof)
        goto eof;

    do
    {
        if (rsenum->index >= MAX_DIRENTS)
            goto eof;

        ferr = get_rsdos_dirent(image, rsenum->index++, &rsent);
        if (ferr)
            return imgtool_floppy_error(ferr);
    }
    while(rsent.fname[0] == '\0');

    /* Now are we at the eof point? */
    if (rsent.fname[0] == -1)
    {
        rsenum->eof = 1;
eof:
        ent->eof = 1;
    }
    else
    {
        /* Not the end of file */
        err = process_rsdos_file(&rsent, image, NULL, &filesize);
        if (err)
            return err;

        if (filesize == ((size_t) -1))
        {
            /* corrupt! */
            ent->filesize = 0;
            ent->corrupt = 1;
        }
        else
        {
            ent->filesize = filesize;
            ent->corrupt = 0;
        }
        ent->eof = 0;

        get_dirent_fname(fname, &rsent);

        snprintf(ent->filename, ARRAY_LENGTH(ent->filename), "%s", fname);
        snprintf(ent->attr, ARRAY_LENGTH(ent->attr), "%d %c", (int) rsent.ftype, (char) (rsent.asciiflag + 'B'));
    }
    return IMGTOOLERR_SUCCESS;
}
Esempio n. 6
0
static imgtoolerr_t rsdos_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);
	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 = option_resolution_lookup_int(writeoptions, RSDOS_OPTIONS_FTYPE);
	ent.asciiflag = ((UINT8) option_resolution_lookup_int(writeoptions, 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 = MIN(sz, (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;
}