status_t
ExtendedPartitionHandle::Init()
{
	// initialize the extended partition from the mutable partition

	BMutablePartition* partition = Partition();

	// our parent has already set the child cookie to the primary partition.
	fPrimaryPartition = (PrimaryPartition*)partition->ChildCookie();
	if (!fPrimaryPartition)
		return B_BAD_VALUE;

	if (!fPrimaryPartition->IsExtended())
		return B_BAD_VALUE;

	// init the child partitions
	int32 count = partition->CountChildren();
	for (int32 i = 0; i < count; i++) {
		BMutablePartition* child = partition->ChildAt(i);

		PartitionType type;
		if (!type.SetType(child->Type()))
			return B_BAD_VALUE;

		void* handle = parse_driver_settings_string(child->Parameters());
		if (handle == NULL)
			return B_ERROR;

		bool active = get_driver_boolean_parameter(
			handle, "active", false, true);

		off_t ptsOffset = 0;
		const char* buffer = get_driver_parameter(handle,
			"partition_table_offset", NULL, NULL);
		if (buffer != NULL)
			ptsOffset = strtoull(buffer, NULL, 10);
		else {
			delete_driver_settings(handle);
			return B_BAD_VALUE;
		}
		delete_driver_settings(handle);

		LogicalPartition* logical = new(nothrow) LogicalPartition;
		if (!logical)
			return B_NO_MEMORY;

		logical->SetTo(child->Offset(), child->Size(), type.Type(), active,
			ptsOffset, fPrimaryPartition);

		child->SetChildCookie(logical);
	}

	return B_OK;
}
Example #2
0
// get_type_for_content_type (for both pm_* and ep_*)
static status_t
get_type_for_content_type(const char* contentType, char* type)
{
	TRACE(("intel: get_type_for_content_type(%s)\n",
		   contentType));

	if (!contentType || !type)
		return B_BAD_VALUE;

	PartitionType ptype;
	ptype.SetContentType(contentType);
	if (!ptype.IsValid())
		return B_NAME_NOT_FOUND;

	ptype.GetTypeString(type);
	return B_OK;
}
Example #3
0
status_t
PartitionMapHandle::Init()
{
    // initialize the partition map from the mutable partition

    BMutablePartition* partition = Partition();

    int32 count = partition->CountChildren();
    if (count > 4)
        return B_BAD_VALUE;

    int32 extendedCount = 0;

    for (int32 i = 0; i < count; i++) {
        BMutablePartition* child = partition->ChildAt(i);
        PartitionType type;
        if (!type.SetType(child->Type()))
            return B_BAD_VALUE;

        // only one extended partition is allowed
        if (type.IsExtended()) {
            if (++extendedCount > 1)
                return B_BAD_VALUE;
        }

        // TODO: Get these from the parameters.
        int32 index = i;
        bool active = false;

        PrimaryPartition* primary = fPartitionMap.PrimaryPartitionAt(index);
        primary->SetTo(child->Offset(), child->Size(), type.Type(), active,
                       partition->BlockSize());

        child->SetChildCookie(primary);
    }

    // The extended partition (if any) is initialized by
    // ExtendedPartitionHandle::Init().

    return B_OK;
}
status_t
ExtendedPartitionHandle::CreateChild(off_t offset, off_t size,
	const char* typeString, const char* name, const char* _parameters,
	BMutablePartition** _child)
{
	// check type
	PartitionType type;
	if (!type.SetType(typeString) || type.IsEmpty())
		return B_BAD_VALUE;

	// check name
	if (name != NULL && name[0] != '\0')
		return B_BAD_VALUE;

	// offset properly aligned?
	if (offset != sector_align(offset, Partition()->BlockSize())
		|| size != sector_align(size, Partition()->BlockSize()))
		return B_BAD_VALUE;

	// check the free space situation
	BPartitioningInfo info;
	status_t error = GetPartitioningInfo(&info);
	if (error != B_OK)
		return error;

	bool foundSpace = false;
	off_t end = offset + size;
	int32 spacesCount = info.CountPartitionableSpaces();
	for (int32 i = 0; i < spacesCount; i++) {
		off_t spaceOffset, spaceSize;
		info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
		off_t spaceEnd = spaceOffset + spaceSize;

		if (offset >= spaceOffset && end <= spaceEnd) {
			foundSpace = true;
			break;
		}
	}

	if (!foundSpace)
		return B_BAD_VALUE;

	BString parameters(_parameters);
	parameters << "partition_table_offset " << offset - PTS_OFFSET << " ;\n";
	// everything looks good, create the child
	BMutablePartition* child;
	error = Partition()->CreateChild(-1, typeString,
		NULL, parameters.String(), &child);
	if (error != B_OK)
		return error;

	// init the child
	child->SetOffset(offset);
	child->SetSize(size);
	child->SetBlockSize(Partition()->BlockSize());
	//child->SetFlags(0);
	child->SetChildCookie(Partition());

	*_child = child;
	return B_OK;
}
Example #5
0
status_t
PartitionMapHandle::CreateChild(off_t offset, off_t size,
                                const char* typeString, const char* name, const char* parameters,
                                BMutablePartition** _child)
{
    // check type
    PartitionType type;
    if (!type.SetType(typeString) || type.IsEmpty())
        return B_BAD_VALUE;
    if (type.IsExtended() && fPartitionMap.ExtendedPartitionIndex() >= 0)
        return B_BAD_VALUE;

    // check name
    if (name && *name != '\0')
        return B_BAD_VALUE;

    // check parameters
    void* handle = parse_driver_settings_string(parameters);
    if (handle == NULL)
        return B_ERROR;

    bool active = get_driver_boolean_parameter(handle, "active", false, true);
    delete_driver_settings(handle);

    // get a spare primary partition
    PrimaryPartition* primary = NULL;
    for (int32 i = 0; i < 4; i++) {
        if (fPartitionMap.PrimaryPartitionAt(i)->IsEmpty()) {
            primary = fPartitionMap.PrimaryPartitionAt(i);
            break;
        }
    }
    if (!primary)
        return B_BAD_VALUE;

    // offset properly aligned?
    if (offset != sector_align(offset, Partition()->BlockSize())
            || size != sector_align(size, Partition()->BlockSize()))
        return B_BAD_VALUE;

    // check the free space situation
    BPartitioningInfo info;
    status_t error = GetPartitioningInfo(&info);
    if (error != B_OK)
        return error;

    bool foundSpace = false;
    off_t end = offset + size;
    int32 spacesCount = info.CountPartitionableSpaces();
    for (int32 i = 0; i < spacesCount; i++) {
        off_t spaceOffset, spaceSize;
        info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
        off_t spaceEnd = spaceOffset + spaceSize;

        if (offset >= spaceOffset && end <= spaceEnd) {
            foundSpace = true;
            break;
        }
    }

    if (!foundSpace)
        return B_BAD_VALUE;

    // create the child
    // (Note: the primary partition index is indeed the child index, since
    // we picked the first empty primary partition.)
    BMutablePartition* partition = Partition();
    BMutablePartition* child;
    error = partition->CreateChild(primary->Index(), typeString, name,
                                   parameters, &child);
    if (error != B_OK)
        return error;

    // init the child
    child->SetOffset(offset);
    child->SetSize(size);
    child->SetBlockSize(partition->BlockSize());
    //child->SetFlags(0);
    child->SetChildCookie(primary);

    // init the primary partition
    primary->SetTo(offset, size, type.Type(), active, partition->BlockSize());

    *_child = child;
    return B_OK;
}
Example #6
0
status_t
PartitionMapHandle::ValidateCreateChild(off_t* _offset, off_t* _size,
                                        const char* typeString, BString* name, const char* parameters)
{
    // check type
    PartitionType type;
    if (!type.SetType(typeString) || type.IsEmpty())
        return B_BAD_VALUE;

    if (type.IsExtended() && fPartitionMap.ExtendedPartitionIndex() >= 0) {
        // There can only be a single extended partition
        return B_BAD_VALUE;
    }

    // check name
    if (name)
        name->Truncate(0);

    // check parameters
    void* handle = parse_driver_settings_string(parameters);
    if (handle == NULL)
        return B_ERROR;
    get_driver_boolean_parameter(handle, "active", false, true);
    delete_driver_settings(handle);

    // do we have a spare primary partition?
    if (fPartitionMap.CountNonEmptyPrimaryPartitions() == 4)
        return B_BAD_VALUE;

    // check the free space situation
    BPartitioningInfo info;
    status_t error = GetPartitioningInfo(&info);
    if (error != B_OK)
        return error;

    // any space in the partition at all?
    int32 spacesCount = info.CountPartitionableSpaces();
    if (spacesCount == 0)
        return B_BAD_VALUE;

    // check offset and size
    off_t offset = sector_align(*_offset, Partition()->BlockSize());
    off_t size = sector_align(*_size, Partition()->BlockSize());
    // TODO: Rather round size up?
    off_t end = offset + size;

    // get the first partitionable space the requested interval intersects with
    int32 spaceIndex = -1;
    int32 closestSpaceIndex = -1;
    off_t closestSpaceDistance = 0;
    for (int32 i = 0; i < spacesCount; i++) {
        off_t spaceOffset, spaceSize;
        info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
        off_t spaceEnd = spaceOffset + spaceSize;

        if ((spaceOffset >= offset && spaceOffset < end)
                || (offset >= spaceOffset && offset < spaceEnd)) {
            spaceIndex = i;
            break;
        }

        off_t distance;
        if (offset < spaceOffset)
            distance = spaceOffset - end;
        else
            distance = spaceEnd - offset;

        if (closestSpaceIndex == -1 || distance < closestSpaceDistance) {
            closestSpaceIndex = i;
            closestSpaceDistance = distance;
        }
    }

    // get the space we found
    off_t spaceOffset, spaceSize;
    info.GetPartitionableSpaceAt(
        spaceIndex >= 0 ? spaceIndex : closestSpaceIndex, &spaceOffset,
        &spaceSize);
    off_t spaceEnd = spaceOffset + spaceSize;

    // If the requested intervald doesn't intersect with any space yet, move
    // it, so that it does.
    if (spaceIndex < 0) {
        spaceIndex = closestSpaceIndex;
        if (offset < spaceOffset) {
            offset = spaceOffset;
            end = offset + size;
        } else {
            end = spaceEnd;
            offset = end - size;
        }
    }

    // move/shrink the interval, so that it fully lies within the space
    if (offset < spaceOffset) {
        offset = spaceOffset;
        end = offset + size;
        if (end > spaceEnd) {
            end = spaceEnd;
            size = end - offset;
        }
    } else if (end > spaceEnd) {
        end = spaceEnd;
        offset = end - size;
        if (offset < spaceOffset) {
            offset = spaceOffset;
            size = end - offset;
        }
    }

    *_offset = offset;
    *_size = size;

    return B_OK;
}