status_t ExtendedPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info) { // init to the full size (minus the first PTS_OFFSET) BMutablePartition* partition = Partition(); off_t offset = partition->Offset() + PTS_OFFSET; off_t size = partition->Size() - PTS_OFFSET; status_t error = info->SetTo(offset, size); if (error != B_OK) return error; // exclude the space of the existing logical partitions int32 count = partition->CountChildren(); for (int32 i = 0; i < count; i++) { BMutablePartition* child = partition->ChildAt(i); error = info->ExcludeOccupiedSpace(child->Offset(), child->Size() + PTS_OFFSET + Partition()->BlockSize()); if (error != B_OK) return error; LogicalPartition* logical = (LogicalPartition*)child->ChildCookie(); if (logical == NULL) return B_BAD_VALUE; error = info->ExcludeOccupiedSpace( logical->PartitionTableOffset(), PTS_OFFSET + Partition()->BlockSize()); if (error != B_OK) return error; } return B_OK; }
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; }
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; }