// _ParsePrimary
status_t
PartitionMapParser::_ParsePrimary(const partition_table* table,
	bool& hadToReFitSize)
{
	if (table == NULL)
		return B_BAD_VALUE;

	// check the signature
	if (table->signature != kPartitionTableSectorSignature) {
		TRACE(("intel: _ParsePrimary(): invalid PartitionTable signature: %lx\n",
			(uint32)table->signature));
		return B_BAD_DATA;
	}

	hadToReFitSize = false;

	// examine the table
	for (int32 i = 0; i < 4; i++) {
		const partition_descriptor* descriptor = &table->table[i];
		PrimaryPartition* partition = fMap->PrimaryPartitionAt(i);
		partition->SetTo(descriptor, 0, fBlockSize);

		// work-around potential BIOS/OS problems
		hadToReFitSize |= partition->FitSizeToSession(fSessionSize);

		// ignore, if location is bad
		if (!partition->CheckLocation(fSessionSize)) {
			TRACE(("intel: _ParsePrimary(): partition %ld: bad location, "
				"ignoring\n", i));
			partition->Unset();
		}
	}

	// allocate a partition_table buffer
	fPartitionTable = new(nothrow) partition_table;
	if (fPartitionTable == NULL)
		return B_NO_MEMORY;

	// parse extended partitions
	status_t error = B_OK;
	for (int32 i = 0; error == B_OK && i < 4; i++) {
		PrimaryPartition* primary = fMap->PrimaryPartitionAt(i);
		if (primary->IsExtended())
			error = _ParseExtended(primary, primary->Offset());
	}

	// cleanup
	delete fPartitionTable;
	fPartitionTable = NULL;

	return error;
}
void
LogicalPartition::GetPartitionDescriptor(partition_descriptor* descriptor,
	bool inner) const
{
	PrimaryPartition* primary = GetPrimaryPartition();
	if (inner) {
		descriptor->start = (PartitionTableOffset() - primary->Offset())
			/ BlockSize();
		descriptor->type = primary->Type();
	} else {
		descriptor->start = (Offset() - PartitionTableOffset()) / BlockSize();
		descriptor->type = Type();
	}

	descriptor->size = Size() / BlockSize();
	descriptor->active = 0x00;
	descriptor->begin.Unset();
	descriptor->end.Unset();
}
Exemple #3
0
status_t
PartitionMapHandle::GetPartitioningInfo(BPartitioningInfo* info)
{
    // init to the full size (minus the first sector)
    off_t size = Partition()->ContentSize();
    status_t error = info->SetTo(Partition()->BlockSize(),
                                 size - Partition()->BlockSize());
    if (error != B_OK)
        return error;

    // exclude the space of the existing partitions
    for (int32 i = 0; i < 4; i++) {
        PrimaryPartition* primary = fPartitionMap.PrimaryPartitionAt(i);
        if (!primary->IsEmpty()) {
            error = info->ExcludeOccupiedSpace(primary->Offset(),
                                               primary->Size());
            if (error != B_OK)
                return error;
        }
    }

    return B_OK;
}
Exemple #4
0
// pm_scan_partition
static status_t
pm_scan_partition(int fd, partition_data* partition, void* cookie)
{
	// check parameters
	if (fd < 0 || !partition || !cookie)
		return B_ERROR;

	TRACE(("intel: pm_scan_partition(%d, %ld: %lld, %lld, %ld)\n", fd,
		   partition->id, partition->offset, partition->size,
		   partition->block_size));

	PartitionMapCookie* map = (PartitionMapCookie*)cookie;
	// fill in the partition_data structure
	partition->status = B_PARTITION_VALID;
	partition->flags |= B_PARTITION_PARTITIONING_SYSTEM;
	partition->content_size = partition->size;
	// (no content_name and content_parameters)
	// (content_type is set by the system)

	partition->content_cookie = map;
	// children
	status_t error = B_OK;
	int32 index = 0;
	for (int32 i = 0; i < 4; i++) {
		PrimaryPartition* primary = map->PrimaryPartitionAt(i);
		if (!primary->IsEmpty()) {
			partition_data* child = create_child_partition(partition->id,
				index, partition->offset + primary->Offset(), primary->Size(),
				-1);
			index++;
			if (!child) {
				// something went wrong
				error = B_ERROR;
				break;
			}

			child->block_size = partition->block_size;

			// (no name)
			char type[B_FILE_NAME_LENGTH];
			primary->GetTypeString(type);
			child->type = strdup(type);
			// parameters
			char buffer[128];
			sprintf(buffer, "type = %u ; active = %d", primary->Type(),
				primary->Active());
			child->parameters = strdup(buffer);
			child->cookie = primary;
			// check for allocation problems
			if (!child->type || !child->parameters) {
				error = B_NO_MEMORY;
				break;
			}
		}
	}

	// keep map on success or cleanup on error
	if (error == B_OK) {
		atomic_add(&map->ref_count, 1);
	} else {
		partition->content_cookie = NULL;
		for (int32 i = 0; i < partition->child_count; i++) {
			if (partition_data* child = get_child_partition(partition->id, i))
				child->cookie = NULL;
		}
	}

	return error;
}