Esempio n. 1
0
/* in this function */
static int
hfs_extent_key_cmp(HfsPrivateGenericKey* a, HfsPrivateGenericKey* b)
{
	HfsExtentKey* key1 = (HfsExtentKey*) a;
	HfsExtentKey* key2 = (HfsExtentKey*) b;

	/* do NOT use a substraction, because */
	/* 0xFFFFFFFF - 1 = 0xFFFFFFFE so this */
	/* would return -2, despite the fact */
	/* 0xFFFFFFFF > 1 !!! (this is the 2.4 bug) */
	if (key1->file_ID != key2->file_ID)
		return PED_BE32_TO_CPU(key1->file_ID) <
		       PED_BE32_TO_CPU(key2->file_ID) ?
				-1 : +1;

	if (key1->type != key2->type)
		return (int)(key1->type - key2->type);

	if (key1->start == key2->start)
		return 0;
	/* the whole thing wont work with 16 bits ints */
	/* anyway */
	return (int)( PED_BE16_TO_CPU(key1->start) -
		      PED_BE16_TO_CPU(key2->start) );
}
Esempio n. 2
0
static HfsCPrivateCache*
hfsplus_cache_extents(PedFileSystem* fs, PedTimer* timer)
{
	HfsPPrivateFSData*	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsCPrivateCache*	ret;
	unsigned int		file_number, block_number;

	file_number = PED_BE32_TO_CPU(priv_data->vh->file_count);
	block_number = PED_BE32_TO_CPU(priv_data->vh->total_blocks);
	ret = hfsc_new_cache(block_number, file_number);
	if (!ret) return NULL;

	if (!hfsplus_cache_from_vh(ret, fs, timer) ||
	    !hfsplus_cache_from_catalog(ret, fs, timer) ||
	    !hfsplus_cache_from_extent(ret, fs, timer) ||
	    !hfsplus_cache_from_attributes(ret, fs, timer)) {
		ped_exception_throw(
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Could not cache the file system in memory."));
		hfsc_delete_cache(ret);
		return NULL;
	}

	return ret;
}
Esempio n. 3
0
static PedGeometry*
xfs_probe (PedGeometry* geom)
{
	PedSector	block_size;
	PedSector	block_count;
	union {
		struct xfs_sb	sb;
		char		bytes [512];
	} buf;

	if (geom->length < XFS_SB_DADDR + 1)
		return NULL;
	if (!ped_geometry_read (geom, &buf, XFS_SB_DADDR, 1))
		return NULL;

	if (PED_LE32_TO_CPU (buf.sb.sb_magicnum) == XFS_SB_MAGIC) {
		block_size = PED_LE32_TO_CPU (buf.sb.sb_blocksize) / 512;
		block_count = PED_LE64_TO_CPU (buf.sb.sb_dblocks);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}

	if (PED_BE32_TO_CPU (buf.sb.sb_magicnum) == XFS_SB_MAGIC) {
		block_size = PED_BE32_TO_CPU (buf.sb.sb_blocksize) / 512;
		block_count = PED_BE64_TO_CPU (buf.sb.sb_dblocks);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}

	return NULL;
}
Esempio n. 4
0
/* return 0 on error */
int
hfs_file_write_sector (HfsPrivateFile* file, void *buf, PedSector sector)
{
	PedSector	abs_sector;

	if (sector >= file->sect_nb) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Trying to write HFS file with CNID %X behind EOF."),
			  PED_BE32_TO_CPU(file->CNID));		
		return 0;
	}

	abs_sector = hfs_file_find_sector (file, sector);
	if (!abs_sector) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Could not find sector %lli of HFS file with "
			  "CNID %X."),
			sector, PED_BE32_TO_CPU(file->CNID));
		return 0;
	}

	return ped_geometry_write (file->fs->geom, buf, abs_sector, 1);
}
Esempio n. 5
0
static struct AmigaBlock *
_amiga_read_block (const PedDevice *dev, struct AmigaBlock *blk,
                   PedSector block, struct AmigaIds *ids)
{
	if (!ped_device_read (dev, blk, block, 1))
		return NULL;
	if (ids && !_amiga_id_in_list(PED_BE32_TO_CPU(blk->amiga_ID), ids))
		return NULL;
	if (_amiga_checksum (blk) != 0) {
		switch (ped_exception_throw(PED_EXCEPTION_ERROR,
			PED_EXCEPTION_FIX | PED_EXCEPTION_IGNORE | PED_EXCEPTION_CANCEL,
			_("%s : Bad checksum on block %llu of type %s."),
			__func__, block, _amiga_block_id(PED_BE32_TO_CPU(blk->amiga_ID))))
		{
			case PED_EXCEPTION_CANCEL :
				return NULL;
			case PED_EXCEPTION_FIX :
				_amiga_calculate_checksum(AMIGA(blk));
				if (!ped_device_write ((PedDevice*)dev, blk, block, 1))
					return NULL;
			case PED_EXCEPTION_IGNORE :
			case PED_EXCEPTION_UNHANDLED :
			default :
				return blk;
		}
	}
	return blk;
}
Esempio n. 6
0
File: ufs.c Progetto: Excito/parted
static PedGeometry*
ufs_probe_sun (PedGeometry* geom)
{
	int8_t buf[512 * 3];
	struct ufs_super_block *sb;

	if (geom->length < 5)
		return 0;
	if (!ped_geometry_read (geom, buf, 16, 3))
		return 0;

	sb = (struct ufs_super_block *)buf;

	if (PED_BE32_TO_CPU(sb->fs_magic) == UFS_MAGIC) {
		PedSector block_size = PED_BE32_TO_CPU(sb->fs_bsize) / 512;
		PedSector block_count = PED_BE32_TO_CPU(sb->fs_size);
		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}
	if (PED_LE32_TO_CPU(sb->fs_magic) == UFS_MAGIC) {
		PedSector block_size = PED_LE32_TO_CPU(sb->fs_bsize) / 512;
		PedSector block_count = PED_LE32_TO_CPU(sb->fs_size);
		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}
	return NULL;
}
Esempio n. 7
0
static PedGeometry*
_generic_apfs_probe (PedGeometry* geom, uint32_t kind)
{
	uint32_t *block;
	PedSector root;
	struct PartitionBlock * part;
	uint32_t blocksize = 1, reserved = 2;

	PED_ASSERT (geom != NULL);
	PED_ASSERT (geom->dev != NULL);
	if (geom->dev->sector_size != 512)
		return NULL;

	/* Finds the blocksize and reserved values of the partition block */
	if (!(part = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("%s : Failed to allocate partition block\n"), __func__);
		goto error_part;
	}
	if (amiga_find_part(geom, part) != NULL) {
		reserved = PED_BE32_TO_CPU (part->de_Reserved);
		blocksize = PED_BE32_TO_CPU (part->de_SizeBlock)
			* PED_BE32_TO_CPU (part->de_SectorPerBlock) / 128;
	}
	free (part);

	/* Test boot block */
	if (!(block = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("%s : Failed to allocate block\n"), __func__);
		goto error_block;
	}
	if (!ped_device_read (geom->dev, block, geom->start, blocksize)) {
		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("%s : Couldn't read boot block %llu\n"), __func__, geom->start);
		goto error;
	}
	if (PED_BE32_TO_CPU (block[0]) != kind) {
		goto error;
	}

	/* Find and test the root block */
	root = geom->start+reserved*blocksize;
	if (!ped_device_read (geom->dev, block, root, blocksize)) {
		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("%s : Couldn't read root block %llu\n"), __func__, root);
		goto error;
	}
	if (_apfs_probe_root(block, blocksize, kind) == 1) {
		free(block);
		return ped_geometry_duplicate (geom);
	}

error:
	free (block);
error_block:
error_part:
	return NULL;
}
Esempio n. 8
0
static int
_amiga_find_free_blocks(const PedDisk *disk, uint32_t *table,
	struct LinkedBlock *block, uint32_t first, uint32_t type)
{
	PedSector next;

	PED_ASSERT(disk != NULL);
	PED_ASSERT(disk->dev != NULL);

	for (next = first; next != LINK_END; next = PED_BE32_TO_CPU(block->lk_Next)) {
		if (table[next] != IDNAME_FREE) {
			switch (ped_exception_throw(PED_EXCEPTION_ERROR,
				PED_EXCEPTION_FIX | PED_EXCEPTION_IGNORE | PED_EXCEPTION_CANCEL,
				_("%s : Loop detected at block %d."), __func__, next))
			{
				case PED_EXCEPTION_CANCEL :
					return 0;
				case PED_EXCEPTION_FIX :
					/* TODO : Need to add fixing code */
				case PED_EXCEPTION_IGNORE :
				case PED_EXCEPTION_UNHANDLED :
				default :
					return 1;
			}
		}

		if (!_amiga_read_block (disk->dev, AMIGA(block), next, NULL)) {
			return 0;
		}
		if (PED_BE32_TO_CPU(block->lk_ID) != type) {
			switch (ped_exception_throw(PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("%s : The %s list seems bad at block %s."),
				__func__, _amiga_block_id(PED_BE32_TO_CPU(block->lk_ID)), next))
			{
				/* TODO : to more subtile things here */
				case PED_EXCEPTION_CANCEL :
				case PED_EXCEPTION_UNHANDLED :
				default :
					return 0;
			}
		}
		table[next] = type;
		if (PED_BE32_TO_CPU(block->lk_ID) == IDNAME_FILESYSHEADER) {
			if (_amiga_find_free_blocks(disk, table, block,
				PED_BE32_TO_CPU(LNK2(block)->lk2_Linked),
				IDNAME_LOADSEG) == 0) return 0;
		}
	}
	return 1;
}
Esempio n. 9
0
static int
_amiga_checksum (struct AmigaBlock *blk) {
	uint32_t *rdb = (uint32_t *) blk;
	uint32_t sum;
	int i, end;

	sum = PED_BE32_TO_CPU (rdb[0]);
	end = PED_BE32_TO_CPU (rdb[1]);

	if (end > PED_SECTOR_SIZE_DEFAULT) end = PED_SECTOR_SIZE_DEFAULT;

	for (i = 1; i < end; i++) sum += PED_BE32_TO_CPU (rdb[i]);

	return sum;
}
Esempio n. 10
0
/* save any dirty sector of the allocation bitmap file */
static int
hfsplus_save_allocation(PedFileSystem *fs)
{
	HfsPPrivateFSData*	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	unsigned int		map_sectors, i, j;
	int			ret = 1;

	map_sectors = ( PED_BE32_TO_CPU (priv_data->vh->total_blocks)
			+ PED_SECTOR_SIZE_DEFAULT * 8 - 1 ) / (PED_SECTOR_SIZE_DEFAULT * 8);

	for (i = 0; i < map_sectors;) {
		for (j = i;
		     (TST_BLOC_OCCUPATION(priv_data->dirty_alloc_map,j));
		     ++j)
			CLR_BLOC_OCCUPATION(priv_data->dirty_alloc_map,j);
		if (j-i) {
			ret = hfsplus_file_write(priv_data->allocation_file,
				    priv_data->alloc_map + i * PED_SECTOR_SIZE_DEFAULT,
				    i, j-i) && ret;
			i = j;
		} else
			++i;
	}

	return ret;
}
Esempio n. 11
0
File: hfs.c Progetto: Excito/parted
static int
hfsplus_clobber (PedGeometry* geom)
{
	unsigned int i = 1;
	uint8_t				buf[PED_SECTOR_SIZE_DEFAULT];
	HfsMasterDirectoryBlock		*mdb;

	mdb = (HfsMasterDirectoryBlock *) buf;

	if (!ped_geometry_read (geom, buf, 2, 1))
		return 0;

	if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE) {
		/* embedded hfs+ */
		PedGeometry	*embedded;

		i = PED_BE32_TO_CPU(mdb->block_size) / PED_SECTOR_SIZE_DEFAULT;
		embedded = ped_geometry_new (
		    geom->dev,
		    (PedSector) geom->start
		     + PED_BE16_TO_CPU (mdb->start_block)
		     + (PedSector) PED_BE16_TO_CPU (
			mdb->old_new.embedded.location.start_block ) * i,
		    (PedSector) PED_BE16_TO_CPU (
			mdb->old_new.embedded.location.block_count ) * i );
		if (!embedded) i = 0;
		else {
			i = hfs_clobber (embedded);
			ped_geometry_destroy (embedded);
		}
	}

	/* non-embedded or envelop destroy as hfs */
	return ( hfs_clobber (geom) && i );
}
Esempio n. 12
0
int
hfsj_update_jl(PedFileSystem* fs, uint32_t block)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedSector		sector;
	uint64_t		offset;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						    fs->type_specific;
	HfsJJournalInfoBlock*	jib;
	int			binsect;

	binsect = PED_BE32_TO_CPU(priv_data->vh->block_size) / PED_SECTOR_SIZE_DEFAULT;
	sector = (PedSector) priv_data->jib_start_block * binsect;
	if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
		return 0;
	jib = (HfsJJournalInfoBlock*) buf;

	offset = (uint64_t)block * PED_SECTOR_SIZE_DEFAULT * binsect;
	jib->offset = PED_CPU_TO_BE64(offset);

	if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
	    || !ped_geometry_sync(priv_data->plus_geom))
		return 0;

	priv_data->jl_start_block = block;
	return 1;
}
Esempio n. 13
0
static void
_amiga_calculate_checksum (struct AmigaBlock *blk) {
	blk->amiga_ChkSum = PED_CPU_TO_BE32(
		PED_BE32_TO_CPU(blk->amiga_ChkSum) -
		_amiga_checksum((struct AmigaBlock *) blk));
	return;
}
Esempio n. 14
0
static PedPartition*
_parse_boot_file (PedDisk* disk, struct volume_directory* vd)
{
	PedPartition*	part;
	DVHPartData*	dvh_part_data;
	PedSector	start = PED_BE32_TO_CPU (vd->vd_lbn);
	int		length = PED_BE32_TO_CPU (vd->vd_nbytes);

	part = ped_partition_new (disk, PED_PARTITION_LOGICAL, NULL,
				  start, start + length/512 - 1);
	if (!part)
		return NULL;

	dvh_part_data = part->disk_specific;
	dvh_part_data->real_file_size = length;

	strncpy (dvh_part_data->name, vd->vd_name, VDNAMESIZE);
	dvh_part_data->name[VDNAMESIZE] = 0;
	return part;
}
Esempio n. 15
0
/* two's complement 32-bit checksum */
static uint32_t _GL_ATTRIBUTE_PURE
_checksum (const uint32_t* base, size_t size)
{
	uint32_t	sum = 0;
	size_t		i;

	for (i = 0; i < size / sizeof (uint32_t); i++)
		sum = sum - PED_BE32_TO_CPU (base[i]);

	return sum;
}
Esempio n. 16
0
static PedPartition*
_parse_partition (PedDisk* disk, struct partition_table* pt)
{
	PedPartition*	part;
	DVHPartData*	dvh_part_data;
	PedSector	start = PED_BE32_TO_CPU (pt->pt_firstlbn);
	PedSector	length = PED_BE32_TO_CPU (pt->pt_nblks);

	part = ped_partition_new (disk,
			          pt->pt_type ? 0 : PED_PARTITION_EXTENDED,
				  NULL,
				  start, start + length - 1);
	if (!part)
		return NULL;

	dvh_part_data = part->disk_specific;
	dvh_part_data->type = PED_BE32_TO_CPU (pt->pt_type);
	strcpy (dvh_part_data->name, "");

	return part;
}
Esempio n. 17
0
File: ufs.c Progetto: Excito/parted
static PedGeometry*
ufs_probe_hp (PedGeometry* geom)
{
	int8_t buf[1536];
	struct ufs_super_block *sb;
	PedSector block_size;
	PedSector block_count;

	if (geom->length < 5)
		return 0;
	if (!ped_geometry_read (geom, buf, 16, 3))
		return 0;

	sb = (struct ufs_super_block *)buf;

	/* Try sane bytesex */
	switch (PED_BE32_TO_CPU(sb->fs_magic)) {
		case UFS_MAGIC_LFN:
		case UFS_MAGIC_FEA:
		case UFS_MAGIC_4GB:
			block_size = PED_BE32_TO_CPU(sb->fs_bsize) / 512;
			block_count = PED_BE32_TO_CPU(sb->fs_size);
			return ped_geometry_new (geom->dev, geom->start,
						 block_size * block_count);
	}

	/* Try perverted bytesex */
	switch (PED_LE32_TO_CPU(sb->fs_magic)) {
		case UFS_MAGIC_LFN:
		case UFS_MAGIC_FEA:
		case UFS_MAGIC_4GB:
			block_size = PED_LE32_TO_CPU(sb->fs_bsize) / 512;
			block_count = PED_LE32_TO_CPU(sb->fs_size);
			return ped_geometry_new (geom->dev, geom->start,
						 block_size * block_count);
	}
	return NULL;
}
Esempio n. 18
0
/* Used by hfsplus_probe and hfs_probe */
PedGeometry*
hfs_and_wrapper_probe (PedGeometry* geom)
{
	uint8_t		buf[PED_SECTOR_SIZE_DEFAULT];
	HfsMasterDirectoryBlock	*mdb;
	PedGeometry*	geom_ret;
	PedSector	search, max;

	PED_ASSERT (geom != NULL);
	PED_ASSERT (hfsc_can_use_geom (geom));

	mdb = (HfsMasterDirectoryBlock *) buf;

	/* is 5 an intelligent value ? */
	if ((geom->length < 5)
	    || (!ped_geometry_read (geom, buf, 2, 1))
	    || (mdb->signature != PED_CPU_TO_BE16 (HFS_SIGNATURE)) )
		return NULL;

	search = ((PedSector) PED_BE16_TO_CPU (mdb->start_block)
		  + ((PedSector) PED_BE16_TO_CPU (mdb->total_blocks)
		     * (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE_DEFAULT )));
	max = search + (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE_DEFAULT);
	if (!(geom_ret = ped_geometry_new (geom->dev, geom->start, search + 2)))
		return NULL;

	for (; search < max; search++) {
		if (!ped_geometry_set (geom_ret, geom_ret->start, search + 2)
		    || !ped_geometry_read (geom_ret, buf, search, 1))
			break;
		if (mdb->signature == PED_CPU_TO_BE16 (HFS_SIGNATURE))
			return geom_ret;
	}

	ped_geometry_destroy (geom_ret);
	return NULL;
}
Esempio n. 19
0
static int
dvh_probe (const PedDevice *dev)
{
	struct volume_header *vh;

	void *label;
	if (!ptt_read_sector (dev, 0, &label))
		return 0;

	vh = (struct volume_header *) label;

        bool found = PED_BE32_TO_CPU (vh->vh_magic) == VHMAGIC;
	free (label);
	return found;
}
Esempio n. 20
0
static uint32_t
_amiga_find_rdb (PedDevice *dev, struct RigidDiskBlock *rdb) {
	int i;
	struct AmigaIds *ids;

	ids = _amiga_add_id (IDNAME_RIGIDDISK, NULL);

	for (i = 0; i<RDB_LOCATION_LIMIT; i++) {
		if (!_amiga_read_block (dev, AMIGA(rdb), i, ids)) {
			continue;
		}
		if (PED_BE32_TO_CPU (rdb->rdb_ID) == IDNAME_RIGIDDISK) {
			_amiga_free_ids (ids);
			return i;
		}
	}
	_amiga_free_ids (ids);
	return AMIGA_RDB_NOT_FOUND;
}
Esempio n. 21
0
/* On error this function returns 0 */
PedSector
hfs_get_empty_end (const PedFileSystem *fs)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	HfsMasterDirectoryBlock* mdb = priv_data->mdb;
	unsigned int		block, last_bad, end_free_blocks;

	/* find the next block to the last bad block of the volume */
	if (!hfs_read_bad_blocks (fs))
		return 0;

	HfsPrivateLinkExtent*	l;
	last_bad = 0;
	for (l = priv_data->bad_blocks_xtent_list; l; l = l->next) {
		if ((unsigned int) PED_BE16_TO_CPU (l->extent.start_block)
		    + PED_BE16_TO_CPU (l->extent.block_count) > last_bad)
			last_bad = PED_BE16_TO_CPU (l->extent.start_block)
			           + PED_BE16_TO_CPU (l->extent.block_count);
	}

	/* Count the free blocks from last_bad to the end of the volume */
	end_free_blocks = 0;
	for (block = last_bad;
	     block < PED_BE16_TO_CPU (mdb->total_blocks);
	     block++) {
		if (!TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
			end_free_blocks++;
	}

	/* Calculate the block that will by the first free at the
	   end of the volume */
	block = PED_BE16_TO_CPU (mdb->total_blocks) - end_free_blocks;

	return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
		+ (PedSector) block * (PED_BE32_TO_CPU (mdb->block_size)
				       / PED_SECTOR_SIZE_DEFAULT);
}
Esempio n. 22
0
/* 1 => Success, the journal has been completly replayed, or don't need to */
int
hfsj_replay_journal(PedFileSystem* fs)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedSector		sector, length;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						    fs->type_specific;
	HfsJJournalInfoBlock*	jib;
	HfsJJournalHeader*	jh;
	int			binsect;
	uint32_t		cksum;

	binsect = PED_BE32_TO_CPU(priv_data->vh->block_size) / PED_SECTOR_SIZE_DEFAULT;
	priv_data->jib_start_block =
		PED_BE32_TO_CPU(priv_data->vh->journal_info_block);
	sector  = (PedSector) priv_data->jib_start_block * binsect;
	if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
		return 0;
	jib = (HfsJJournalInfoBlock*) buf;

	if (    (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_IN_FS))
	    && !(jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_OTHER_DEV)) ) {
		priv_data->jl_start_block = HFS_64_TO_CPU(jib->offset, is_le)
					    / ( PED_SECTOR_SIZE_DEFAULT * binsect );
	}

	if (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_NEED_INIT))
		return 1;

	if (  !(jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_IN_FS))
	    || (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_OTHER_DEV)) ) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Journal stored outside of the volume are "
			  "not supported.  Try to desactivate the "
			  "journal and run Parted again."));
		return 0;
	}

	if (   (PED_BE64_TO_CPU(jib->offset) % PED_SECTOR_SIZE_DEFAULT)
	    || (PED_BE64_TO_CPU(jib->size)   % PED_SECTOR_SIZE_DEFAULT) ) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Journal offset or size is not multiple of "
			  "the sector size."));
		return 0;
	}

	sector = PED_BE64_TO_CPU(jib->offset) / PED_SECTOR_SIZE_DEFAULT;
	length = PED_BE64_TO_CPU(jib->size)   / PED_SECTOR_SIZE_DEFAULT;

	jib = NULL;
	if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
		return 0;
	jh = (HfsJJournalHeader*) buf;

	if (jh->endian == PED_LE32_TO_CPU(HFSJ_ENDIAN_MAGIC))
	    is_le = 1;

	if (   (jh->magic  != HFS_32_TO_CPU(HFSJ_HEADER_MAGIC, is_le))
	    || (jh->endian != HFS_32_TO_CPU(HFSJ_ENDIAN_MAGIC, is_le)) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Incorrect magic values in the journal header."));
		return 0;
	}

	if ( (HFS_64_TO_CPU(jh->size, is_le)%PED_SECTOR_SIZE_DEFAULT)
	  || (HFS_64_TO_CPU(jh->size, is_le)/PED_SECTOR_SIZE_DEFAULT
		  != (uint64_t)length) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Journal size mismatch between journal info block "
			  "and journal header."));
		return 0;
	}

	if (   (HFS_64_TO_CPU(jh->start, is_le) % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_64_TO_CPU(jh->end, is_le)   % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_32_TO_CPU(jh->blhdr_size, is_le) % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_32_TO_CPU(jh->jhdr_size, is_le)  % PED_SECTOR_SIZE_DEFAULT) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Some header fields are not multiple of the sector "
			  "size."));
		return 0;
	}

	if (HFS_32_TO_CPU(jh->jhdr_size, is_le) != PED_SECTOR_SIZE_DEFAULT) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("The sector size stored in the journal is not 512 "
			  "bytes.  Parted only supports 512 bytes length "
			  "sectors."));
		return 0;
	}

	cksum = HFS_32_TO_CPU(jh->checksum, is_le);
	jh->checksum = 0;
	if (cksum != hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh))) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Bad journal checksum."));
		return 0;
	}
	jh->checksum = HFS_CPU_TO_32(cksum, is_le);

	/* The 2 following test are in the XNU Darwin source code */
	/* so I assume they're needed */
	if (jh->start == jh->size)
		jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT, is_le);
	if (jh->end   == jh->size)
		jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT, is_le);

	if (jh->start == jh->end)
		return 1;

	if (ped_exception_throw (
		PED_EXCEPTION_WARNING,
		PED_EXCEPTION_FIX | PED_EXCEPTION_CANCEL,
		_("The journal is not empty.  Parted must replay the "
		  "transactions before opening the file system.  This will "
		  "modify the file system."))
			!= PED_EXCEPTION_FIX)
		return 0;

	while (jh->start != jh->end) {
		/* Replay one complete transaction */
		if (!hfsj_replay_transaction(fs, jh, sector, length))
			return 0;

		/* Recalculate cksum of the journal header */
		jh->checksum = 0; /* need to be 0 while calculating the cksum */
		cksum = hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh));
		jh->checksum = HFS_CPU_TO_32(cksum, is_le);

		/* Update the Journal Header */
		if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
		    || !ped_geometry_sync(priv_data->plus_geom))
			return 0;
	}

	if (hfsj_vh_replayed) {
		/* probe could have reported incorrect info ! */
		/* is there a way to ask parted to quit ? */
		ped_exception_throw(
			PED_EXCEPTION_WARNING,
			PED_EXCEPTION_OK,
			_("The volume header or the master directory block has "
			  "changed while replaying the journal.  You should "
			  "restart Parted."));
		return 0;
	}

	return 1;
}
Esempio n. 23
0
/* return 0 on error */
int
hfsplus_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
				    PedTimer* timer, unsigned int to_free)
{
	PedSector		bytes_buff;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsPVolumeHeader*	vh = priv_data->vh;
	HfsCPrivateCache*	cache;
	unsigned int 		to_fblock = fblock;
	unsigned int		start = fblock;
	unsigned int		divisor = PED_BE32_TO_CPU (vh->total_blocks)
				          + 1 - start - to_free;
	int			ret;

	PED_ASSERT (!hfsp_block);

	cache = hfsplus_cache_extents (fs, timer);
	if (!cache)
		return 0;

	/* Calculate the size of the copy buffer :
	 * Takes BLOCK_MAX_BUFF HFS blocks, but if > BYTES_MAX_BUFF
	 * takes the maximum number of HFS blocks so that the buffer
	 * will remain smaller than or equal to BYTES_MAX_BUFF, with
	 * a minimum of 1 HFS block */
	bytes_buff = PED_BE32_TO_CPU (priv_data->vh->block_size)
		     * (PedSector) BLOCK_MAX_BUFF;
	if (bytes_buff > BYTES_MAX_BUFF) {
		hfsp_block_count = BYTES_MAX_BUFF
				 / PED_BE32_TO_CPU (priv_data->vh->block_size);
		if (!hfsp_block_count)
			hfsp_block_count = 1;
		bytes_buff = (PedSector) hfsp_block_count
			     * PED_BE32_TO_CPU (priv_data->vh->block_size);
	} else
		hfsp_block_count = BLOCK_MAX_BUFF;

	/* If the cache code requests more space, give it to him */
	if (bytes_buff < hfsc_cache_needed_buffer (cache))
		bytes_buff = hfsc_cache_needed_buffer (cache);

	hfsp_block = (uint8_t*) ped_malloc (bytes_buff);
	if (!hfsp_block)
		goto error_cache;

	if (!hfsplus_read_bad_blocks (fs)) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Bad blocks list could not be loaded."));
		goto error_alloc;
	}

	while ( fblock < ( priv_data->plus_geom->length - 2 )
			 / ( PED_BE32_TO_CPU (vh->block_size)
			     / PED_SECTOR_SIZE_DEFAULT ) ) {
		if (TST_BLOC_OCCUPATION (priv_data->alloc_map, fblock)
		    && (!hfsplus_is_bad_block (fs, fblock))) {
			if (!(ret = hfsplus_move_extent_starting_at (fs,
						&fblock, &to_fblock, cache)))
				to_fblock = ++fblock;
			else if (ret == -1) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("An error occurred during extent "
					  "relocation."));
				goto error_alloc;
			}
		} else {
			fblock++;
		}

		ped_timer_update(timer, (float)(to_fblock - start) / divisor);
	}

	free (hfsp_block); hfsp_block = NULL; hfsp_block_count = 0;
	hfsc_delete_cache (cache);
	return 1;

error_alloc:
	free (hfsp_block); hfsp_block = NULL; hfsp_block_count = 0;
error_cache:
	hfsc_delete_cache (cache);
	return 0;
}
Esempio n. 24
0
static int
hfsplus_cache_from_attributes(HfsCPrivateCache* cache, PedFileSystem* fs,
			      PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	uint8_t			node_1[PED_SECTOR_SIZE_DEFAULT];
	uint8_t*		node;
	HfsPHeaderRecord*	header;
	HfsPPrivateGenericKey*	generic_key;
	HfsPForkDataAttr*	fork_ext_data;
	HfsPExtDescriptor*	extent;
	unsigned int		leaf_node, record_number;
	unsigned int		i, j, size, bsize;

	/* attributes file is facultative */
	if (!priv_data->attributes_file->sect_nb)
		return 1;

	/* Search the extent starting at *ptr_block in the catalog file */
	if (!hfsplus_file_read_sector (priv_data->attributes_file, node_1, 0))
		return 0;
	header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
	leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
	bsize = PED_BE16_TO_CPU (header->node_size);
	size = bsize / PED_SECTOR_SIZE_DEFAULT;
	PED_ASSERT(size < 256);

	node = (uint8_t*) ped_malloc(bsize);
	if (!node) return 0;
	HfsPNodeDescriptor *desc = (HfsPNodeDescriptor*) node;

	for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
		if (!hfsplus_file_read (priv_data->attributes_file, node,
					(PedSector) leaf_node * size, size)) {
			free (node);
			return 0;
		}
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = 1; i <= record_number; i++) {
			unsigned int	skip;
			generic_key = (HfsPPrivateGenericKey*)
				(node + PED_BE16_TO_CPU(*((uint16_t *)
					    (node+(bsize - 2*i)))));
			skip = ( 2 + PED_BE16_TO_CPU (generic_key->key_length)
			         + 1 ) & ~1;
			fork_ext_data = (HfsPForkDataAttr*)
					    (((uint8_t*)generic_key) + skip);
			/* check for obvious error in FS */
			if (((uint8_t*)generic_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)fork_ext_data - node
			        >= (signed) bsize
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				free (node);
				return 0;
			}

			if (fork_ext_data->record_type
			    == PED_CPU_TO_BE32 ( HFSP_ATTR_FORK ) ) {
				extent = fork_ext_data->fork_res.fork.extents;
				for (j = 0; j < HFSP_EXT_NB; ++j) {
					if (!extent[j].block_count) break;
					if (!hfsc_cache_add_extent(
						cache,
						PED_BE32_TO_CPU (
							extent[j].start_block ),
						PED_BE32_TO_CPU (
							extent[j].block_count ),
						leaf_node,
						(uint8_t*)extent-node,
						size,
						CR_BTREE_ATTR,
						j )
					   ) {
						free(node);
						return 0;
					}
				}
			} else if (fork_ext_data->record_type
			    == PED_CPU_TO_BE32 ( HFSP_ATTR_EXTENTS ) ) {
				extent = fork_ext_data->fork_res.extents;
				for (j = 0; j < HFSP_EXT_NB; ++j) {
					if (!extent[j].block_count) break;
					if (!hfsc_cache_add_extent(
						cache,
						PED_BE32_TO_CPU (
							extent[j].start_block ),
						PED_BE32_TO_CPU (
							extent[j].block_count ),
						leaf_node,
						(uint8_t*)extent-node,
						size,
						CR_BTREE_ATTR,
						j )
					   ) {
						free(node);
						return 0;
					}
				}
			} else continue;
		}
	}

	free (node);
	return 1;
}
Esempio n. 25
0
static int
hfsplus_cache_from_extent(HfsCPrivateCache* cache, PedFileSystem* fs,
			  PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	uint8_t			node_1[PED_SECTOR_SIZE_DEFAULT];
	uint8_t*		node;
	HfsPHeaderRecord*	header;
	HfsPExtentKey*		extent_key;
	HfsPExtDescriptor*	extent;
	unsigned int		leaf_node, record_number;
	unsigned int		i, j, size, bsize;

	if (!priv_data->extents_file->sect_nb) {
		ped_exception_throw (
			PED_EXCEPTION_INFORMATION,
			PED_EXCEPTION_OK,
			_("This HFS+ volume has no extents overflow "
			  "file.  This is quite unusual!"));
		return 1;
	}

	if (!hfsplus_file_read_sector (priv_data->extents_file, node_1, 0))
		return 0;
	header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
	leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
	bsize = PED_BE16_TO_CPU (header->node_size);
	size = bsize / PED_SECTOR_SIZE_DEFAULT;
	PED_ASSERT(size < 256);

	node = (uint8_t*) ped_malloc (bsize);
	if (!node) return -1;
	HfsPNodeDescriptor *desc = (HfsPNodeDescriptor*) node;

	for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
		if (!hfsplus_file_read (priv_data->extents_file, node,
					(PedSector) leaf_node * size, size)) {
			free (node);
			return 0;
		}
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = 1; i <= record_number; i++) {
			uint8_t where;
			extent_key = (HfsPExtentKey*)
			    (node + PED_BE16_TO_CPU(*((uint16_t *)
					    (node+(bsize - 2*i)))));
			extent = (HfsPExtDescriptor*)
			    (((uint8_t*)extent_key) + sizeof (HfsPExtentKey));
			/* check for obvious error in FS */
			if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)extent - node
			        >= (signed)bsize
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				free (node);
				return -1;
			}

			switch (extent_key->file_ID) {
			    case PED_CPU_TO_BE32 (HFS_XTENT_ID) :
				if (ped_exception_throw (
					PED_EXCEPTION_WARNING,
					PED_EXCEPTION_IGNORE_CANCEL,
					_("The extents overflow file should not"
					" contain its own extents!  You should "
					"check the file system."))
						!= PED_EXCEPTION_IGNORE)
					return 0;
				where = CR_BTREE_EXT_EXT;
				break;
			    case PED_CPU_TO_BE32 (HFS_CATALOG_ID) :
				where = CR_BTREE_EXT_CAT;
				break;
			    case PED_CPU_TO_BE32 (HFSP_ALLOC_ID) :
				where = CR_BTREE_EXT_ALLOC;
				break;
			    case PED_CPU_TO_BE32 (HFSP_STARTUP_ID) :
				where = CR_BTREE_EXT_START;
				break;
			    case PED_CPU_TO_BE32 (HFSP_ATTRIB_ID) :
			    	where = CR_BTREE_EXT_ATTR;
				break;
			    default :
			    	where = CR_BTREE_EXT_0;
				break;
			}

			for (j = 0; j < HFSP_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE32_TO_CPU(extent[j].start_block),
					PED_BE32_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					size,
					where,
					j )
				   ) {
					free (node);
					return 0;
				}
			}
		}
	}

	free (node);
	return 1;
}
Esempio n. 26
0
/* -1 is ok because there can only be 2^32-1 blocks, so the max possible
   last one is 2^32-2 (and anyway it contains Alternate VH), so
   -1 (== 2^32-1[2^32]) never represent a valid block */
static int
hfsplus_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
			    unsigned int *ptr_to_fblock, unsigned int size)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	unsigned int		i, ok = 0;
	unsigned int		next_to_fblock;
	unsigned int		start, stop;

	PED_ASSERT (hfsp_block != NULL);
	PED_ASSERT (*ptr_to_fblock <= *ptr_fblock);
	/* quiet GCC */
	start = stop = 0;

/*
	Try to fit the extent AT or _BEFORE_ the wanted place,
	or then in the gap between dest and source.
	If failed try to fit the extent after source, for 2 pass relocation
	The extent is always copied in a non overlapping way
*/

	/* Backward search */
	/* 1 pass relocation AT or BEFORE *ptr_to_fblock */
	if (*ptr_to_fblock != *ptr_fblock) {
		start = stop = *ptr_fblock < *ptr_to_fblock+size ?
			       *ptr_fblock : *ptr_to_fblock+size;
		while (start && stop-start != size) {
			--start;
			if (TST_BLOC_OCCUPATION(priv_data->alloc_map,start))
				stop = start;
		}
		ok = (stop-start == size);
	}

	/* Forward search */
	/* 1 pass relocation in the gap merged with 2 pass reloc after source */
	if (!ok && *ptr_to_fblock != *ptr_fblock) {
		start = stop = *ptr_to_fblock+1;
		while (stop < PED_BE32_TO_CPU(priv_data->vh->total_blocks)
		       && stop-start != size) {
			if (TST_BLOC_OCCUPATION(priv_data->alloc_map,stop))
				start = stop + 1;
			++stop;
		}
		ok = (stop-start == size);
	}

	/* new non overlapping room has been found ? */
	if (ok) {
		/* enough room */
		PedSector	abs_sector;
		unsigned int	ai, j, block;
		unsigned int 	block_sz = (PED_BE32_TO_CPU (
					priv_data->vh->block_size)
					/ PED_SECTOR_SIZE_DEFAULT);

		if (stop > *ptr_to_fblock && stop <= *ptr_fblock)
			/* Fit in the gap */
			next_to_fblock = stop;
		else
			/* Before or after the gap */
			next_to_fblock = *ptr_to_fblock;

		/* move blocks */
		for (i = 0; i < size; /*i++*/) {
			j = size - i; j = (j < hfsp_block_count) ?
					   j : hfsp_block_count ;

			abs_sector = (PedSector) (*ptr_fblock + i) * block_sz;
			if (!ped_geometry_read (priv_data->plus_geom,
						hfsp_block, abs_sector,
						block_sz * j))
				return -1;

			abs_sector = (PedSector) (start + i) * block_sz;
			if (!ped_geometry_write (priv_data->plus_geom,
						 hfsp_block, abs_sector,
						 block_sz * j))
				return -1;

			for (ai = i+j; i < ai; i++) {
				/* free source block */
				block = *ptr_fblock + i;
				CLR_BLOC_OCCUPATION(priv_data->alloc_map,block);
				SET_BLOC_OCCUPATION(priv_data->dirty_alloc_map,
						    block/(PED_SECTOR_SIZE_DEFAULT*8));

				/* set dest block */
				block = start + i;
				SET_BLOC_OCCUPATION(priv_data->alloc_map,block);
				SET_BLOC_OCCUPATION(priv_data->dirty_alloc_map,
						    block/(PED_SECTOR_SIZE_DEFAULT*8));
			}
		}
		if (!ped_geometry_sync_fast (priv_data->plus_geom))
			return -1;

		*ptr_fblock += size;
		*ptr_to_fblock = next_to_fblock;
	} else {
		if (*ptr_fblock != *ptr_to_fblock)
			/* not enough room */
			ped_exception_throw (PED_EXCEPTION_WARNING,
			      PED_EXCEPTION_IGNORE,
			      _("An extent has not been relocated."));
		start = *ptr_fblock;
		*ptr_fblock = *ptr_to_fblock = start + size;
	}

	return start;
}
Esempio n. 27
0
static int
hfsplus_cache_from_catalog(HfsCPrivateCache* cache, PedFileSystem* fs,
			   PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	uint8_t			node_1[PED_SECTOR_SIZE_DEFAULT];
	uint8_t*		node;
	HfsPHeaderRecord*	header;
	HfsPCatalogKey*		catalog_key;
	HfsPCatalog*		catalog_data;
	HfsPExtDescriptor*	extent;
	unsigned int		leaf_node, record_number;
	unsigned int		i, j, size, bsize;
	uint32_t		jib = priv_data->jib_start_block,
				jl  = priv_data->jl_start_block;

	if (!priv_data->catalog_file->sect_nb) {
		ped_exception_throw (
			PED_EXCEPTION_INFORMATION,
			PED_EXCEPTION_OK,
			_("This HFS+ volume has no catalog file.  "
			  "This is very unusual!"));
		return 1;
	}

	/* Search the extent starting at *ptr_block in the catalog file */
	if (!hfsplus_file_read_sector (priv_data->catalog_file, node_1, 0))
		return 0;
	header = (HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC);
	leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
	bsize = PED_BE16_TO_CPU (header->node_size);
	size = bsize / PED_SECTOR_SIZE_DEFAULT;
	PED_ASSERT(size < 256);

	node = (uint8_t*) ped_malloc(bsize);
	if (!node) return 0;
	HfsPNodeDescriptor *desc = (HfsPNodeDescriptor*) node;

	for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
		if (!hfsplus_file_read (priv_data->catalog_file, node,
					(PedSector) leaf_node * size, size)) {
			free (node);
			return 0;
		}
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = 1; i <= record_number; i++) {
			unsigned int	skip;
			uint8_t		where;

			catalog_key = (HfsPCatalogKey*)
			    ( node + PED_BE16_TO_CPU (*((uint16_t *)
					(node+(bsize - 2*i)))) );
			skip = ( 2 + PED_BE16_TO_CPU (catalog_key->key_length)
				 + 1) & ~1;
			catalog_data = (HfsPCatalog*)
					    (((uint8_t*)catalog_key) + skip);
			/* check for obvious error in FS */
			if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)catalog_data - node
			        >= (signed) bsize
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				free (node);
				return 0;
			}

			if (PED_BE16_TO_CPU(catalog_data->type)!=HFS_CAT_FILE)
				continue;

			extent = catalog_data->sel.file.data_fork.extents;
			for (j = 0; j < HFSP_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				where = CR_BTREE_CAT;
				if ( PED_BE32_TO_CPU(extent[j].start_block)
				     == jib ) {
					jib = 0;
					where = CR_BTREE_CAT_JIB;
				} else
				  if ( PED_BE32_TO_CPU(extent[j].start_block)
				       == jl ) {
					jl = 0;
					where = CR_BTREE_CAT_JL;
				}
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE32_TO_CPU(extent[j].start_block),
					PED_BE32_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					size,
					where,
					j )
				   ) {
					free (node);
				 	return 0;
				}
			}

			extent = catalog_data->sel.file.res_fork.extents;
			for (j = 0; j < HFSP_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE32_TO_CPU(extent[j].start_block),
					PED_BE32_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					size,
					CR_BTREE_CAT,
					j )
				   ) {
					free (node);
				 	return 0;
				}
			}
		}
	}

	free (node);
	return 1;
}
Esempio n. 28
0
static int
hfsplus_cache_from_vh(HfsCPrivateCache* cache, PedFileSystem* fs,
		      PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsPExtDescriptor*	extent;
	unsigned int		j;

	extent = priv_data->vh->allocation_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_ALLOC,
			j )
		   )
			return 0;
	}

	extent = priv_data->vh->extents_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_EXT,
			j )
		   )
			return 0;
	}

	extent = priv_data->vh->catalog_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_CAT,
			j )
		   )
			return 0;
	}

	extent = priv_data->vh->attributes_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_ATTR,
			j )
		   )
			return 0;
	}

	extent = priv_data->vh->startup_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_START,
			j )
		   )
			return 0;
	}

	return 1;
}
Esempio n. 29
0
static int
dvh_read (PedDisk* disk)
{
	DVHDiskData*		dvh_disk_data = disk->disk_specific;
	int			i;
	struct volume_header	vh;
	char			boot_name [BFNAMESIZE + 1];
#ifndef DISCOVER_ONLY
	int			write_back = 0;
#endif

	PED_ASSERT (dvh_disk_data != NULL);

	ped_disk_delete_all (disk);

	void *s0;
	if (!ptt_read_sector (disk->dev, 0, &s0))
		return 0;
	memcpy (&vh, s0, sizeof vh);
	free (s0);

	if (_checksum ((uint32_t*) &vh, sizeof (struct volume_header))) {
		if (ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Checksum is wrong, indicating the partition "
			  "table is corrupt."))
				== PED_EXCEPTION_CANCEL)
			return 0;
	}

	PED_ASSERT (PED_BE32_TO_CPU (vh.vh_magic) == VHMAGIC);

	dvh_disk_data->dev_params = vh.vh_dp;
	strncpy (boot_name, vh.vh_bootfile, BFNAMESIZE);
	boot_name[BFNAMESIZE] = 0;

	/* normal partitions */
	for (i = 0; i < NPARTAB; i++) {
		PedPartition* part;

		if (!vh.vh_pt[i].pt_nblks)
			continue;
		/* Skip the whole-disk partition, parted disklikes overlap */
		if (PED_BE32_TO_CPU (vh.vh_pt[i].pt_type) == PTYPE_VOLUME)
			continue;

		part = _parse_partition (disk, &vh.vh_pt[i]);
		if (!part)
			goto error_delete_all;

		part->fs_type = ped_file_system_probe (&part->geom);
		part->num = i + 1;

		if (PED_BE16_TO_CPU (vh.vh_rootpt) == i)
			ped_partition_set_flag (part, PED_PARTITION_ROOT, 1);
		if (PED_BE16_TO_CPU (vh.vh_swappt) == i)
			ped_partition_set_flag (part, PED_PARTITION_SWAP, 1);

		PedConstraint *constraint_exact
		  = ped_constraint_exact (&part->geom);
		bool ok = ped_disk_add_partition (disk, part, constraint_exact);
		ped_constraint_destroy (constraint_exact);
		if (!ok) {
			ped_partition_destroy (part);
			goto error_delete_all;
		}
	}

	if (!ped_disk_extended_partition (disk)) {
#ifdef DISCOVER_ONLY
		return 1;
#else
		switch (_handle_no_volume_header (disk)) {
			case PED_EXCEPTION_CANCEL:
				return 0;
			case PED_EXCEPTION_IGNORE:
				return 1;
			case PED_EXCEPTION_FIX:
				write_back = 1;
				break;
			default:
				break;
		}
#endif
	}

	/* boot partitions */
	for (i = 0; i < NVDIR; i++) {
		PedPartition* part;

		if (!vh.vh_vd[i].vd_nbytes)
			continue;

		part = _parse_boot_file (disk, &vh.vh_vd[i]);
		if (!part)
			goto error_delete_all;

		part->fs_type = ped_file_system_probe (&part->geom);
		part->num = NPARTAB + i + 1;

		if (!strcmp (boot_name, ped_partition_get_name (part)))
			ped_partition_set_flag (part, PED_PARTITION_BOOT, 1);

		PedConstraint *constraint_exact
		  = ped_constraint_exact (&part->geom);
		bool ok = ped_disk_add_partition (disk, part, constraint_exact);
		ped_constraint_destroy (constraint_exact);
		if (!ok) {
			ped_partition_destroy (part);
			goto error_delete_all;
		}
	}
#ifndef DISCOVER_ONLY
	if (write_back)
		dvh_write (disk);
#endif
	return 1;

error_delete_all:
	ped_disk_delete_all (disk);
	return 0;
}
Esempio n. 30
0
/* 	     other BTrees has well */
int
hfs_btree_search (HfsPrivateFile* b_tree_file, HfsPrivateGenericKey* key,
		  void *record_out, unsigned int record_size,
		  HfsCPrivateLeafRec* record_ref)
{
	uint8_t			node[PED_SECTOR_SIZE_DEFAULT];
	HfsHeaderRecord*	header;
	HfsNodeDescriptor*	desc = (HfsNodeDescriptor*) node;
	HfsPrivateGenericKey*	record_key = NULL;
	unsigned int		node_number, record_number;
	int			i;

	/* Read the header node */
	if (!hfs_file_read_sector(b_tree_file, node, 0))
		return 0;
	header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
						(node+(PED_SECTOR_SIZE_DEFAULT-2))))));

	/* Get the node number of the root */
	node_number = PED_BE32_TO_CPU(header->root_node);
	if (!node_number)
		return 0;

	/* Read the root node */
	if (!hfs_file_read_sector(b_tree_file, node, node_number))
		return 0;

	/* Follow the white rabbit */
	while (1) {
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = record_number; i; i--) {
			record_key = (HfsPrivateGenericKey*)
				(node + PED_BE16_TO_CPU(*((uint16_t *)
					    (node+(PED_SECTOR_SIZE_DEFAULT - 2*i)))));
			/* check for obvious error in FS */
			if (((uint8_t*)record_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)record_key - node
				>= PED_SECTOR_SIZE_DEFAULT
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				return 0;
			}
			if (hfs_extent_key_cmp(record_key, key) <= 0)
				break;
		}
		if (!i) return 0;
		if (desc->type == HFS_IDX_NODE) {
			unsigned int 	skip;

			skip = (1 + record_key->key_length + 1) & ~1;
			node_number = PED_BE32_TO_CPU (*((uint32_t *)
					(((uint8_t *) record_key) + skip)));
			if (!hfs_file_read_sector(b_tree_file, node,
						  node_number))
				return 0;
		} else
			break;
	}

	/* copy the result if needed */
	if (record_size)
		memcpy (record_out, record_key, record_size);

	/* send record reference if needed */
	if (record_ref) {
		record_ref->node_size = 1;	/* in sectors */
		record_ref->node_number = node_number;
		record_ref->record_pos = (uint8_t*)record_key - node;
		record_ref->record_number = i;
	}

	/* success */
	return 1;
}