Exemple #1
0
static bool_t dos_partition(struct disk * disk, size_t sector, size_t relative)
{
	struct dos_partition_mbr mbr;
	struct partition * part;
	size_t start;
	int i;

	if(!disk || !disk->name)
		return FALSE;

	if((disk->sector_size <= 0) || (disk->sector_count <=0))
		return FALSE;

	if((!disk->read_sectors) || (!disk->write_sectors))
		return FALSE;

	if(disk_read(disk, (u8_t *)(&mbr), (loff_t)(sector * disk->sector_size) , sizeof(struct dos_partition_mbr)) != sizeof(struct dos_partition_mbr))
		return FALSE;

	/*
	 * check dos partition's signature
	 */
	if((mbr.signature[0] != 0x55) || mbr.signature[1] != 0xaa)
		return FALSE;

	for(i=0; i<4; i++)
	{
		if((mbr.entry[i].type != 0) && (is_dos_extended(mbr.entry[i].type)==FALSE))
		{
			part = malloc(sizeof(struct partition));
			if(!part)
				return FALSE;

			strlcpy((char *)part->name, (const char *)"", sizeof(part->name));
			part->sector_from = sector + ((mbr.entry[i].start[3] << 24) | (mbr.entry[i].start[2] << 16) | (mbr.entry[i].start[1] << 8) | (mbr.entry[i].start[0] << 0));
			part->sector_to = part->sector_from + ((mbr.entry[i].length[3] << 24) | (mbr.entry[i].length[2] << 16) | (mbr.entry[i].length[1] << 8) | (mbr.entry[i].length[0] << 0)) - 1;
			part->sector_size = disk->sector_size;
			list_add_tail(&part->entry, &(disk->info.entry));
		}
	}

	for(i=0; i<4; i++)
	{
		if(is_dos_extended(mbr.entry[i].type)==TRUE)
		{
			start = ((mbr.entry[i].start[3] << 24) | (mbr.entry[i].start[2] << 16) | (mbr.entry[i].start[1] << 8) | (mbr.entry[i].start[0] << 0)) + relative;
			return dos_partition(disk, start, (sector == 0) ? start : relative);
		}
	}

	return TRUE;
}
Exemple #2
0
Retcode
dos_partition(Environ *e, Filesys_action what, Instance *disk,
		Byte *path, uLong loc, uLong start_unused, uByte *buf, uInt size,
		uByte *retbuf, uLong *val)
{
	int i, j;
	Retcode ret = NO_ERROR;
	int partition = -1;
	struct bootsector50 *bs = (struct bootsector50*)buf;
	struct dos_partition part[NDOSPART];
	static int indent = 0;

	DPRINTF(("\ndos_partition: enter\n"));

	if (size < DOS_BLOCK_SIZE)
		return E_BLOCKSIZE;

	/* first see if this is a DOS boot-block */
	ret = filesys_read_bytes(e, disk, loc, size, buf);

	if (ret != NO_ERROR)
		return ret;

	DPRINTF(("dos-partition: boot_sect_sig0/1=%#x.%#x jump=%#x"
			" boot_signature=%#x drive_number=%#x\n",
			bs->boot_sect_sig[0], bs->boot_sect_sig[1],
			bs->jump[0], bs->boot_signature, bs->drive_number));

	if (bs->boot_sect_sig[0] != BOOTSIG0 ||
		bs->boot_sect_sig[1] != BOOTSIG1 ||
		((bs->jump[0] == 0xE9 || bs->jump[0] == 0xEB) &&
			bs->boot_signature != 0x29 &&
			bs->boot_signature != 0x13 &&
			bs->boot_signature != 0x7C &&
			bs->boot_signature != 0xBC))
		return E_NO_FILESYS;

	/* copy the partition info */
	memcpy((void*)part, buf + DOSPARTOFF, sizeof part);

	/* see if we have any partitions - may not be a partition table */
	for (i = 0; i < 4; i++)
	{
		if (part[i].typ != DP_UNUSED)
			break;
	}

	if (i >= 4)
		return E_NO_FILESYS;

	if (*path >= '0' && *path <= '3')
	{
		partition = *path - '0';
		path = strchr(path, ',');

		if (path == NULL)
			path = "";
		else
			path++;
	}
	else if (*path)
	{
		cprintf(e, "dos-partition: unknown partition %s\n", path);
		return E_ABORT;
	}

	if (what == FS_PROBE)
		strcat((char*)retbuf, ",dos-partition");

	for (i = 0; i < 4; i++)
	{
		struct dos_partition *p = &part[i];
		uInt start, size;

		/* handle alignment and endian problems */
		start = p->start[0] |
				(p->start[1] << BYTE_SIZE) |
				(p->start[2] << BYTE_SIZE * 2) |
				(p->start[3] << BYTE_SIZE * 3);
		size = p->size[0] |
				(p->size[1] << BYTE_SIZE) |
				(p->size[2] << BYTE_SIZE * 2) |
				(p->size[3] << BYTE_SIZE * 3);
		DPRINTF(("dos_partition: partition=%d size=%#x start=%#x typ=%#x\n"
				"\tflag=%#x shd=%#x ssect=%#x scyl=%#x ehd=%#x"
				" esect=%#x ecyl=%#x\n",
				i, size, start, p->typ, p->flag, p->shd, p->ssect, p->scyl,
				p->ehd, p->esect, p->ecyl));

		/* find matching fstype */
		if (what == FS_LIST && partition < 0)
		{
			DPtype *fs;

			for (fs = g_dplist; fs->name; fs++)
				if (fs->type == p->typ)
					break;

			for (j = 0; j < indent; j++)
				cprintf(e, " ");

			cprintf(e, "DOS partition %d: %s (%#x)\n", i,
					fs->name ? fs->name : "<unknown>", p->typ);
		}

		/* make sure we have something in this partition */
		if (size == 0 || p->typ == DP_UNUSED)
		{
			if (i == partition && what != FS_PROBE)
				return E_NO_FILESYS;

			continue;
		}

		if (p->typ == DP_EXTENDED)
		{
			indent += 4;
			ret = dos_partition(e, what, disk, path,
					loc + start * DOS_BLOCK_SIZE, start,
					buf, DOS_BLOCK_SIZE, retbuf, val);
			indent -= 4;

			if (ret != NO_ERROR && ret != E_NO_FILESYS && ret != R_END)
				return ret;

			continue;
		}

		/* handle filesystems inside our partitions */
		switch (what)
		{
		case FS_PROBE:
			ret = file_system(e, what, disk, path,
					loc + start * DOS_BLOCK_SIZE, start,
					buf, DOS_BLOCK_SIZE, retbuf, val);

			if (ret != NO_ERROR && ret != E_NO_FILESYS)
				return ret;

			break;

		case FS_LIST:
			if (i == partition)
			{
				ret = file_system(e, what, disk, path,
						loc + start * DOS_BLOCK_SIZE, start,
						buf, DOS_BLOCK_SIZE, retbuf, val);

				return (ret == E_NO_FILESYS) ?  E_UNSUPPORTED_FILESYS : ret;
			}

			break;

		case FS_LOAD:
			if (i == partition)
			{
				if (*path)
				{
					ret = file_system(e, what, disk, path,
							loc + start * DOS_BLOCK_SIZE, start,
							buf, DOS_BLOCK_SIZE, retbuf, val);

					return (ret == E_NO_FILESYS) ?  E_UNSUPPORTED_FILESYS : ret;
				}

				/* no path specified - try to load this partition's bootblock */
				return filesys_read_bytes(e, disk, loc + start * DOS_BLOCK_SIZE,
						*val = DOS_BLOCK_SIZE, retbuf);
			}
			else if (i < 0)
				/* no partition specified - try to load MBR */
				return filesys_read_bytes(e, disk, loc * DOS_BLOCK_SIZE,
						*val = DOS_BLOCK_SIZE, retbuf);

			break;
		}
	}

	/* no other partitions or filesystems should be on this volume */
	DPRINTF(("dos_partition: return R_END\n"));
	return R_END;
}
Exemple #3
0
static bool_t parser_probe_dos(struct disk * disk)
{
	return dos_partition(disk, 0, 0);
}
Exemple #4
0
int
fatfindfile(char *fname)
{
	int		rc, i, j;

	putstr("--MBR--\n");
	rc = readblock(DOSBBSECTOR, buf);

	if (dos_partition(0)->dp_typ != 6) {
		putstr("bad partition type\n");
		return -1;
	};

	start = getulong(dos_partition(0)->dp_start);
	dump_long("start ", start);

	putstr("--BOOT--\n");
	rc = readblock(start, buf);
	if (getushort(bootsector->bpbBytesPerSec) != 512) {
		putstr("bad sector size\n");
		return -1;
	};

	cluster_size = bootsector->bpbSecPerClust;
	dump_long("cluster_size ", cluster_size);

	start_fat = start + getushort(bootsector->bpbResSectors);
	dump_long("start_fat ", start_fat);

	root_size = getushort(bootsector->bpbRootDirEnts);
	root_size = (root_size * 32+511)/512;
	dump_long("root_size ", root_size);

	dump_long("FATsecs ", getushort(bootsector->bpbFATsecs));
	dump_long("FATs ", bootsector->bpbFATs);
	start_root = start_fat + bootsector->bpbFATs * getushort(bootsector->bpbFATsecs);
	start = start_root + root_size - 2 * cluster_size; /* first data sector for 0-based clusters */
	dump_long("start_root ", start_root);

	current_cluster = 0;

	putstr("--ROOT--\n");
	for(j = 0; j<root_size; j++) {
		rc = readblock(start_root + j, buf);
		for(i = 0; i<16; i++) {
			rc = (direntry(i)->deName)[0];
			if (rc == SLOT_EMPTY || rc == SLOT_DELETED) continue;

			rc = direntry(i)->deAttributes & (ATTR_VOLUME|ATTR_DIRECTORY);
			if (rc) continue;

			current_cluster = getushort(direntry(i)->deStartCluster);
			bytes_left = getulong(direntry(i)->deFileSize);

			putstr(direntry(i)->deName);
			putnl();
			/* printf("%12s %02x %ld %ld\n", 
					direntry(i)->deName, 
					direntry(i)->deAttributes & 0x18, 
					current_cluster,
					bytes_left
					); */

			if (!strncmp(direntry(i)->deName, fname, 11)) {
				break;
			};
			current_cluster = 0;
		};
		if (current_cluster) break;
	};

	if (!current_cluster) {
		putstr("file not found\n");
		return -1;
	};
	current_sector = 0;
	putstr("File ok\n");
	return 0;
}