* Added open_partition to disk_device_manager
* Rewrote PartitionMapWriter * Updated style to match current style guide for the intel partitioning system. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32235 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -101,6 +101,8 @@ partition_data *get_partition(partition_id partitionID);
|
|||||||
partition_data *get_parent_partition(partition_id partitionID);
|
partition_data *get_parent_partition(partition_id partitionID);
|
||||||
partition_data *get_child_partition(partition_id partitionID, int32 index);
|
partition_data *get_child_partition(partition_id partitionID, int32 index);
|
||||||
|
|
||||||
|
int open_partition(partition_id partitionID, int openMode);
|
||||||
|
|
||||||
// partition write access
|
// partition write access
|
||||||
// (write lock required)
|
// (write lock required)
|
||||||
partition_data *create_child_partition(partition_id partitionID, int32 index,
|
partition_data *create_child_partition(partition_id partitionID, int32 index,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static const uint32 kDiskSystemFlags =
|
|||||||
// | B_DISK_SYSTEM_SUPPORTS_MOVING
|
// | B_DISK_SYSTEM_SUPPORTS_MOVING
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME
|
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS
|
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS
|
||||||
| B_DISK_SYSTEM_SUPPORTS_INITIALIZING
|
// | B_DISK_SYSTEM_SUPPORTS_INITIALIZING
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
// | B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
||||||
|
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
|
// | B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
|
||||||
@@ -92,7 +92,7 @@ bool
|
|||||||
ExtendedPartitionAddOn::CanInitialize(const BMutablePartition* partition)
|
ExtendedPartitionAddOn::CanInitialize(const BMutablePartition* partition)
|
||||||
{
|
{
|
||||||
// If it's big enough, we can initialize it.
|
// If it's big enough, we can initialize it.
|
||||||
return partition->Size() >= 2 * partition->BlockSize();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ ExtendedPartitionHandle::Init()
|
|||||||
uint32
|
uint32
|
||||||
ExtendedPartitionHandle::SupportedOperations(uint32 mask)
|
ExtendedPartitionHandle::SupportedOperations(uint32 mask)
|
||||||
{
|
{
|
||||||
uint32 flags = B_DISK_SYSTEM_SUPPORTS_INITIALIZING;
|
uint32 flags = 0;//B_DISK_SYSTEM_SUPPORTS_INITIALIZING;
|
||||||
|
|
||||||
// creating child
|
// creating child
|
||||||
if (mask & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD) {
|
if (mask & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD) {
|
||||||
@@ -254,10 +254,25 @@ ExtendedPartitionHandle::GetNextSupportedType(const BMutablePartition* child,
|
|||||||
TRACE("%p->ExtendedPartitionHandle::GetNextSupportedType(child: %p, "
|
TRACE("%p->ExtendedPartitionHandle::GetNextSupportedType(child: %p, "
|
||||||
"cookie: %ld)\n", this, child, *cookie);
|
"cookie: %ld)\n", this, child, *cookie);
|
||||||
|
|
||||||
if (*cookie != 0)
|
int32 index = *cookie;
|
||||||
|
const partition_type* nextType;
|
||||||
|
PartitionMap partitionMap;
|
||||||
|
while (true) {
|
||||||
|
nextType = partitionMap.GetNextSupportedPartitionType(index);
|
||||||
|
if (nextType == NULL)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
index++;
|
||||||
|
if (nextType->used
|
||||||
|
&& strcmp(nextType->name, kPartitionTypeIntelExtended) != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextType)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
*cookie = *cookie + 1;
|
|
||||||
*type = kPartitionTypeIntelLogical;
|
type->SetTo(nextType->name);
|
||||||
|
*cookie = index;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,39 +281,22 @@ ExtendedPartitionHandle::GetNextSupportedType(const BMutablePartition* child,
|
|||||||
status_t
|
status_t
|
||||||
ExtendedPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info)
|
ExtendedPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info)
|
||||||
{
|
{
|
||||||
// NOTE stippi: At first I tried to use the fPrimaryPartition
|
|
||||||
// here but it does not return any LogicalPartitions. What
|
|
||||||
// happens now is probably what used to happen before, though
|
|
||||||
// I don't understand *where*, since this handle type never
|
|
||||||
// implemented this virtual function.
|
|
||||||
|
|
||||||
// init to the full size (minus the first sector)
|
// init to the full size (minus the first sector)
|
||||||
BMutablePartition* partition = Partition();
|
BMutablePartition* partition = Partition();
|
||||||
off_t offset = partition->Offset();// + SECTOR_SIZE;
|
off_t offset = partition->Offset();
|
||||||
off_t size = partition->Size();//- SECTOR_SIZE;
|
off_t size = partition->Size();
|
||||||
status_t error = info->SetTo(offset, size);
|
status_t error = info->SetTo(offset, size);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
// exclude the space of the existing logical partitions
|
// exclude the space of the existing logical partitions
|
||||||
int32 count = partition->CountChildren();
|
int32 count = partition->CountChildren();
|
||||||
printf("%ld logical partitions\n", count);
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
BMutablePartition* child = partition->ChildAt(i);
|
BMutablePartition* child = partition->ChildAt(i);
|
||||||
// TODO: Does this correctly account for the partition table
|
|
||||||
// sectors? Preceeding each logical partition should be a
|
|
||||||
// sector for the partition table entry. Those entries form
|
|
||||||
// the linked list of "inner extended partition" + "real partition"
|
|
||||||
// Following the logic above (copied from PartitionMapAddOn),
|
|
||||||
// the outer size includes the first sector and is therefor
|
|
||||||
// what we need here.
|
|
||||||
error = info->ExcludeOccupiedSpace(child->Offset(), child->Size());
|
error = info->ExcludeOccupiedSpace(child->Offset(), child->Size());
|
||||||
printf(" %ld: offset = %lld (relative: %lld), size = %lld\n", i,
|
|
||||||
child->Offset(), child->Offset() - offset, child->Size());
|
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
info->PrintToStream();
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -309,7 +307,6 @@ status_t
|
|||||||
ExtendedPartitionHandle::GetChildCreationParameterEditor(const char* type,
|
ExtendedPartitionHandle::GetChildCreationParameterEditor(const char* type,
|
||||||
BPartitionParameterEditor** editor)
|
BPartitionParameterEditor** editor)
|
||||||
{
|
{
|
||||||
// TODO: We actually need an editor here.
|
|
||||||
*editor = NULL;
|
*editor = NULL;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -321,102 +318,98 @@ ExtendedPartitionHandle::ValidateCreateChild(off_t* _offset, off_t* _size,
|
|||||||
const char* typeString, BString* name, const char* parameters)
|
const char* typeString, BString* name, const char* parameters)
|
||||||
{
|
{
|
||||||
// check type
|
// check type
|
||||||
if (!typeString || strcmp(typeString, kPartitionTypeIntelLogical) != 0)
|
if (!typeString)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// check name
|
// check name
|
||||||
if (name)
|
if (name)
|
||||||
name->Truncate(0);
|
name->Truncate(0);
|
||||||
|
|
||||||
// check parameters
|
// check the free space situation
|
||||||
// TODO:...
|
BPartitioningInfo info;
|
||||||
|
status_t error = GetPartitioningInfo(&info);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
return B_NOT_SUPPORTED;
|
// any space in the partition at all?
|
||||||
// // check the free space situation
|
int32 spacesCount = info.CountPartitionableSpaces();
|
||||||
// BPartitioningInfo info;
|
if (spacesCount == 0)
|
||||||
// status_t error = GetPartitioningInfo(&info);
|
return B_BAD_VALUE;
|
||||||
// if (error != B_OK)
|
|
||||||
// return error;
|
// check offset and size
|
||||||
//
|
off_t offset = sector_align(*_offset, Partition()->BlockSize());
|
||||||
// // any space in the partition at all?
|
off_t size = sector_align(*_size, Partition()->BlockSize());
|
||||||
// int32 spacesCount = info.CountPartitionableSpaces();
|
// TODO: Rather round size up?
|
||||||
// if (spacesCount == 0)
|
off_t end = offset + size;
|
||||||
// return B_BAD_VALUE;
|
|
||||||
//
|
// get the first partitionable space the requested interval intersects with
|
||||||
// // check offset and size
|
int32 spaceIndex = -1;
|
||||||
// off_t offset = sector_align(*_offset);
|
int32 closestSpaceIndex = -1;
|
||||||
// off_t size = sector_align(*_size);
|
off_t closestSpaceDistance = 0;
|
||||||
// // TODO: Rather round size up?
|
for (int32 i = 0; i < spacesCount; i++) {
|
||||||
// off_t end = offset + size;
|
off_t spaceOffset, spaceSize;
|
||||||
//
|
info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
||||||
// // get the first partitionable space the requested interval intersects with
|
off_t spaceEnd = spaceOffset + spaceSize;
|
||||||
// int32 spaceIndex = -1;
|
|
||||||
// int32 closestSpaceIndex = -1;
|
if (spaceOffset >= offset && spaceOffset < end
|
||||||
// off_t closestSpaceDistance = 0;
|
|| offset >= spaceOffset && offset < spaceEnd) {
|
||||||
// for (int32 i = 0; i < spacesCount; i++) {
|
spaceIndex = i;
|
||||||
// off_t spaceOffset, spaceSize;
|
break;
|
||||||
// info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
}
|
||||||
// off_t spaceEnd = spaceOffset + spaceSize;
|
|
||||||
//
|
off_t distance;
|
||||||
// if (spaceOffset >= offset && spaceOffset < end
|
if (offset < spaceOffset)
|
||||||
// || offset >= spaceOffset && offset < spaceEnd) {
|
distance = spaceOffset - end;
|
||||||
// spaceIndex = i;
|
else
|
||||||
// break;
|
distance = spaceEnd - offset;
|
||||||
// }
|
|
||||||
//
|
if (closestSpaceIndex == -1 || distance < closestSpaceDistance) {
|
||||||
// off_t distance;
|
closestSpaceIndex = i;
|
||||||
// if (offset < spaceOffset)
|
closestSpaceDistance = distance;
|
||||||
// distance = spaceOffset - end;
|
}
|
||||||
// else
|
}
|
||||||
// distance = spaceEnd - offset;
|
|
||||||
//
|
// get the space we found
|
||||||
// if (closestSpaceIndex == -1 || distance < closestSpaceDistance) {
|
off_t spaceOffset, spaceSize;
|
||||||
// closestSpaceIndex = i;
|
info.GetPartitionableSpaceAt(
|
||||||
// closestSpaceDistance = distance;
|
spaceIndex >= 0 ? spaceIndex : closestSpaceIndex, &spaceOffset,
|
||||||
// }
|
&spaceSize);
|
||||||
// }
|
off_t spaceEnd = spaceOffset + spaceSize;
|
||||||
//
|
|
||||||
// // get the space we found
|
// If the requested intervald doesn't intersect with any space yet, move
|
||||||
// off_t spaceOffset, spaceSize;
|
// it, so that it does.
|
||||||
// info.GetPartitionableSpaceAt(
|
if (spaceIndex < 0) {
|
||||||
// spaceIndex >= 0 ? spaceIndex : closestSpaceIndex, &spaceOffset,
|
spaceIndex = closestSpaceIndex;
|
||||||
// &spaceSize);
|
if (offset < spaceOffset) {
|
||||||
// off_t spaceEnd = spaceOffset + spaceSize;
|
offset = spaceOffset;
|
||||||
//
|
end = offset + size;
|
||||||
// // If the requested intervald doesn't intersect with any space yet, move
|
} else {
|
||||||
// // it, so that it does.
|
end = spaceEnd;
|
||||||
// if (spaceIndex < 0) {
|
offset = end - size;
|
||||||
// spaceIndex = closestSpaceIndex;
|
}
|
||||||
// if (offset < spaceOffset) {
|
}
|
||||||
// offset = spaceOffset;
|
|
||||||
// end = offset + size;
|
// move/shrink the interval, so that it fully lies within the space
|
||||||
// } else {
|
if (offset < spaceOffset) {
|
||||||
// end = spaceEnd;
|
offset = spaceOffset;
|
||||||
// offset = end - size;
|
end = offset + size;
|
||||||
// }
|
if (end > spaceEnd) {
|
||||||
// }
|
end = spaceEnd;
|
||||||
//
|
size = end - offset;
|
||||||
// // move/shrink the interval, so that it fully lies within the space
|
}
|
||||||
// if (offset < spaceOffset) {
|
} else if (end > spaceEnd) {
|
||||||
// offset = spaceOffset;
|
end = spaceEnd;
|
||||||
// end = offset + size;
|
offset = end - size;
|
||||||
// if (end > spaceEnd) {
|
if (offset < spaceOffset) {
|
||||||
// end = spaceEnd;
|
offset = spaceOffset;
|
||||||
// size = end - offset;
|
size = end - offset;
|
||||||
// }
|
}
|
||||||
// } else if (end > spaceEnd) {
|
}
|
||||||
// end = spaceEnd;
|
|
||||||
// offset = end - size;
|
*_offset = offset;
|
||||||
// if (offset < spaceOffset) {
|
*_size = size;
|
||||||
// offset = spaceOffset;
|
|
||||||
// size = end - offset;
|
return B_OK;
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// *_offset = offset;
|
|
||||||
// *_size = size;
|
|
||||||
//
|
|
||||||
// return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -427,73 +420,69 @@ ExtendedPartitionHandle::CreateChild(off_t offset, off_t size,
|
|||||||
BMutablePartition** _child)
|
BMutablePartition** _child)
|
||||||
{
|
{
|
||||||
// check type
|
// check type
|
||||||
if (!typeString || strcmp(typeString, kPartitionTypeIntelLogical) != 0)
|
PartitionType type;
|
||||||
|
if (!type.SetType(typeString) || type.IsEmpty())
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// check name
|
// check name
|
||||||
if (name && strlen(name) > 0)
|
if (name && strlen(name) > 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// check parameters
|
// offset properly aligned?
|
||||||
// TODO:...
|
if (offset != sector_align(offset, Partition()->BlockSize())
|
||||||
|
|| size != sector_align(size, Partition()->BlockSize()))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
return B_NOT_SUPPORTED;
|
// check the free space situation
|
||||||
// // offset properly aligned?
|
BPartitioningInfo info;
|
||||||
// if (offset != sector_align(offset) || size != sector_align(size))
|
status_t error = GetPartitioningInfo(&info);
|
||||||
// return B_BAD_VALUE;
|
if (error != B_OK)
|
||||||
//
|
return error;
|
||||||
// // check the free space situation
|
|
||||||
// BPartitioningInfo info;
|
bool foundSpace = false;
|
||||||
// status_t error = GetPartitioningInfo(&info);
|
off_t end = offset + size;
|
||||||
// if (error != B_OK)
|
int32 spacesCount = info.CountPartitionableSpaces();
|
||||||
// return error;
|
for (int32 i = 0; i < spacesCount; i++) {
|
||||||
//
|
off_t spaceOffset, spaceSize;
|
||||||
// bool foundSpace = false;
|
info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
||||||
// off_t end = offset + size;
|
off_t spaceEnd = spaceOffset + spaceSize;
|
||||||
// int32 spacesCount = info.CountPartitionableSpaces();
|
|
||||||
// for (int32 i = 0; i < spacesCount; i++) {
|
if (offset >= spaceOffset && end <= spaceEnd) {
|
||||||
// off_t spaceOffset, spaceSize;
|
foundSpace = true;
|
||||||
// info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
break;
|
||||||
// off_t spaceEnd = spaceOffset + spaceSize;
|
}
|
||||||
//
|
}
|
||||||
// if (offset >= spaceOffset && end <= spaceEnd) {
|
|
||||||
// foundSpace = true;
|
if (!foundSpace)
|
||||||
// break;
|
return B_BAD_VALUE;
|
||||||
// }
|
|
||||||
// }
|
// everything looks good, do it
|
||||||
//
|
// create the child
|
||||||
// if (!foundSpace)
|
BMutablePartition* child;
|
||||||
// return B_BAD_VALUE;
|
error = Partition()->CreateChild(-1, typeString,
|
||||||
//
|
NULL, parameters, &child);
|
||||||
// // everything looks good, do it
|
if (error != B_OK)
|
||||||
//
|
return error;
|
||||||
// // create the child
|
|
||||||
// // (Note: the primary partition index is indeed the child index, since
|
// init the child
|
||||||
// // we picked the first empty primary partition.)
|
child->SetOffset(offset);
|
||||||
// BMutablePartition* partition = Partition();
|
child->SetSize(size);
|
||||||
// BMutablePartition* child;
|
child->SetBlockSize(Partition()->BlockSize());
|
||||||
// error = partition->CreateChild(primary->Index(), typeString, NULL,
|
//child->SetFlags(0);
|
||||||
// parameters, &child);
|
child->SetChildCookie(Partition());
|
||||||
// if (error != B_OK)
|
|
||||||
// return error;
|
*_child = child;
|
||||||
//
|
return B_OK;
|
||||||
// // init the child
|
|
||||||
// child->SetOffset(offset);
|
|
||||||
// child->SetSize(size);
|
|
||||||
// child->SetBlockSize(SECTOR_SIZE);
|
|
||||||
// //child->SetFlags(0);
|
|
||||||
// child->SetChildCookie(primary);
|
|
||||||
//
|
|
||||||
// // init the primary partition
|
|
||||||
// bool active = false;
|
|
||||||
// // TODO: Get from parameters!
|
|
||||||
// primary->SetTo(offset, size, type.Type(), active);
|
|
||||||
//
|
|
||||||
//// TODO: If the child is an extended partition, we should trigger its
|
|
||||||
//// initialization.
|
|
||||||
//
|
|
||||||
// *_child = child;
|
|
||||||
// return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DeleteChild
|
||||||
|
status_t
|
||||||
|
ExtendedPartitionHandle::DeleteChild(BMutablePartition* child)
|
||||||
|
{
|
||||||
|
BMutablePartition* parent = child->Parent();
|
||||||
|
status_t error = parent->DeleteChild(child);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ public:
|
|||||||
const char* type, const char* name,
|
const char* type, const char* name,
|
||||||
const char* parameters,
|
const char* parameters,
|
||||||
BMutablePartition** child);
|
BMutablePartition** child);
|
||||||
|
virtual status_t DeleteChild(BMutablePartition* child);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrimaryPartition* fPrimaryPartition;
|
PrimaryPartition* fPrimaryPartition;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -166,13 +166,13 @@ is_inside_partitions(off_t location, const Partition** partitions, int32 count)
|
|||||||
int32 upper = count - 1;
|
int32 upper = count - 1;
|
||||||
while (lower < upper) {
|
while (lower < upper) {
|
||||||
int32 mid = (lower + upper) / 2;
|
int32 mid = (lower + upper) / 2;
|
||||||
const Partition *midPartition = partitions[mid];
|
const Partition* midPartition = partitions[mid];
|
||||||
if (location >= midPartition->Offset() + midPartition->Size())
|
if (location >= midPartition->Offset() + midPartition->Size())
|
||||||
lower = mid + 1;
|
lower = mid + 1;
|
||||||
else
|
else
|
||||||
upper = mid;
|
upper = mid;
|
||||||
}
|
}
|
||||||
const Partition *partition = partitions[lower];
|
const Partition* partition = partitions[lower];
|
||||||
result = (location >= partition->Offset() &&
|
result = (location >= partition->Offset() &&
|
||||||
location < partition->Offset() + partition->Size());
|
location < partition->Offset() + partition->Size());
|
||||||
}
|
}
|
||||||
@@ -207,7 +207,7 @@ PartitionType::SetType(uint8 type)
|
|||||||
\param typeName Name of the partition type.
|
\param typeName Name of the partition type.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
PartitionType::SetType(const char *typeName)
|
PartitionType::SetType(const char* typeName)
|
||||||
{
|
{
|
||||||
for (int32 i = 0; kPartitionTypes[i].name ; i++) {
|
for (int32 i = 0; kPartitionTypes[i].name ; i++) {
|
||||||
if (!strcmp(typeName, kPartitionTypes[i].name)) {
|
if (!strcmp(typeName, kPartitionTypes[i].name)) {
|
||||||
@@ -237,7 +237,7 @@ PartitionType::SetType(const char *typeName)
|
|||||||
\param content_type Name of the content type, it is standardized by system.
|
\param content_type Name of the content type, it is standardized by system.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
PartitionType::SetContentType(const char *contentType)
|
PartitionType::SetContentType(const char* contentType)
|
||||||
{
|
{
|
||||||
for (int32 i = 0; kPartitionContentTypes[i].name ; i++) {
|
for (int32 i = 0; kPartitionContentTypes[i].name ; i++) {
|
||||||
if (!strcmp(contentType, kPartitionContentTypes[i].name)) {
|
if (!strcmp(contentType, kPartitionContentTypes[i].name)) {
|
||||||
@@ -319,7 +319,7 @@ Partition::Partition(const partition_descriptor* descriptor, off_t tableOffset,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Partition::SetTo(const partition_descriptor *descriptor, off_t tableOffset,
|
Partition::SetTo(const partition_descriptor* descriptor, off_t tableOffset,
|
||||||
off_t baseOffset, uint32 blockSize)
|
off_t baseOffset, uint32 blockSize)
|
||||||
{
|
{
|
||||||
TRACE(("Partition::SetTo(): active: %x\n", descriptor->active));
|
TRACE(("Partition::SetTo(): active: %x\n", descriptor->active));
|
||||||
@@ -356,19 +356,6 @@ Partition::Unset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Partition::GetPartitionDescriptor(partition_descriptor *descriptor,
|
|
||||||
off_t baseOffset) const
|
|
||||||
{
|
|
||||||
descriptor->start = (fOffset - baseOffset) / fBlockSize;
|
|
||||||
descriptor->size = fSize / fBlockSize;
|
|
||||||
descriptor->type = fType;
|
|
||||||
descriptor->active = fActive ? 0x80 : 0x00;
|
|
||||||
descriptor->begin.Unset();
|
|
||||||
descriptor->end.Unset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
void
|
void
|
||||||
Partition::AdjustSize(off_t sessionSize)
|
Partition::AdjustSize(off_t sessionSize)
|
||||||
@@ -389,7 +376,8 @@ Partition::CheckLocation(off_t sessionSize) const
|
|||||||
// lie within the session
|
// lie within the session
|
||||||
if (fPartitionTableOffset % fBlockSize != 0) {
|
if (fPartitionTableOffset % fBlockSize != 0) {
|
||||||
TRACE(("Partition::CheckLocation() - bad partition table offset: %lld "
|
TRACE(("Partition::CheckLocation() - bad partition table offset: %lld "
|
||||||
"(session: %lld)\n", fPartitionTableOffset, sessionSize));
|
"(session: %lld), (fBlockSize: %ld)\n", fPartitionTableOffset,
|
||||||
|
sessionSize, fBlockSize));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fOffset % fBlockSize != 0) {
|
if (fOffset % fBlockSize != 0) {
|
||||||
@@ -426,7 +414,8 @@ Partition::CheckLocation(off_t sessionSize) const
|
|||||||
|
|
||||||
|
|
||||||
PrimaryPartition::PrimaryPartition()
|
PrimaryPartition::PrimaryPartition()
|
||||||
: Partition(),
|
:
|
||||||
|
Partition(),
|
||||||
fHead(NULL),
|
fHead(NULL),
|
||||||
fTail(NULL),
|
fTail(NULL),
|
||||||
fLogicalPartitionCount(0)
|
fLogicalPartitionCount(0)
|
||||||
@@ -455,7 +444,7 @@ PrimaryPartition::SetTo(off_t offset, off_t size, uint8 type, bool active,
|
|||||||
void
|
void
|
||||||
PrimaryPartition::Unset()
|
PrimaryPartition::Unset()
|
||||||
{
|
{
|
||||||
while (LogicalPartition *partition = fHead) {
|
while (LogicalPartition* partition = fHead) {
|
||||||
fHead = partition->Next();
|
fHead = partition->Next();
|
||||||
delete partition;
|
delete partition;
|
||||||
}
|
}
|
||||||
@@ -470,13 +459,13 @@ status_t
|
|||||||
PrimaryPartition::Assign(const PrimaryPartition& other)
|
PrimaryPartition::Assign(const PrimaryPartition& other)
|
||||||
{
|
{
|
||||||
partition_descriptor descriptor;
|
partition_descriptor descriptor;
|
||||||
other.GetPartitionDescriptor(&descriptor, 0);
|
other.GetPartitionDescriptor(&descriptor);
|
||||||
SetTo(&descriptor, 0, other.BlockSize());
|
SetTo(&descriptor, 0, other.BlockSize());
|
||||||
|
|
||||||
const LogicalPartition* otherLogical = other.fHead;
|
const LogicalPartition* otherLogical = other.fHead;
|
||||||
while (otherLogical) {
|
while (otherLogical) {
|
||||||
off_t tableOffset = otherLogical->PartitionTableOffset();
|
off_t tableOffset = otherLogical->PartitionTableOffset();
|
||||||
otherLogical->GetPartitionDescriptor(&descriptor, tableOffset);
|
otherLogical->GetPartitionDescriptor(&descriptor);
|
||||||
|
|
||||||
LogicalPartition* logical = new(nothrow) LogicalPartition(
|
LogicalPartition* logical = new(nothrow) LogicalPartition(
|
||||||
&descriptor, tableOffset, this);
|
&descriptor, tableOffset, this);
|
||||||
@@ -492,10 +481,26 @@ PrimaryPartition::Assign(const PrimaryPartition& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PrimaryPartition::GetPartitionDescriptor(partition_descriptor* descriptor) const
|
||||||
|
{
|
||||||
|
if (IsEmpty()) {
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
} else {
|
||||||
|
descriptor->start = Offset() / BlockSize();
|
||||||
|
descriptor->size = Size() / BlockSize();
|
||||||
|
descriptor->type = Type();
|
||||||
|
descriptor->active = Active() ? 0x80 : 0x00;
|
||||||
|
descriptor->begin.Unset();
|
||||||
|
descriptor->end.Unset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LogicalPartition*
|
LogicalPartition*
|
||||||
PrimaryPartition::LogicalPartitionAt(int32 index) const
|
PrimaryPartition::LogicalPartitionAt(int32 index) const
|
||||||
{
|
{
|
||||||
LogicalPartition *partition = NULL;
|
LogicalPartition* partition = NULL;
|
||||||
if (index >= 0 && index < fLogicalPartitionCount) {
|
if (index >= 0 && index < fLogicalPartitionCount) {
|
||||||
for (partition = fHead; index > 0; index--)
|
for (partition = fHead; index > 0; index--)
|
||||||
partition = partition->Next();
|
partition = partition->Next();
|
||||||
@@ -530,8 +535,8 @@ PrimaryPartition::RemoveLogicalPartition(LogicalPartition* partition)
|
|||||||
if (!partition || partition->GetPrimaryPartition() != this)
|
if (!partition || partition->GetPrimaryPartition() != this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LogicalPartition *prev = partition->Previous();
|
LogicalPartition* prev = partition->Previous();
|
||||||
LogicalPartition *next = partition->Next();
|
LogicalPartition* next = partition->Next();
|
||||||
|
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->SetNext(next);
|
prev->SetNext(next);
|
||||||
@@ -554,7 +559,8 @@ PrimaryPartition::RemoveLogicalPartition(LogicalPartition* partition)
|
|||||||
|
|
||||||
|
|
||||||
LogicalPartition::LogicalPartition()
|
LogicalPartition::LogicalPartition()
|
||||||
: Partition(),
|
:
|
||||||
|
Partition(),
|
||||||
fPrimary(NULL),
|
fPrimary(NULL),
|
||||||
fNext(NULL),
|
fNext(NULL),
|
||||||
fPrevious(NULL)
|
fPrevious(NULL)
|
||||||
@@ -564,7 +570,8 @@ LogicalPartition::LogicalPartition()
|
|||||||
|
|
||||||
LogicalPartition::LogicalPartition(const partition_descriptor* descriptor,
|
LogicalPartition::LogicalPartition(const partition_descriptor* descriptor,
|
||||||
off_t tableOffset, PrimaryPartition* primary)
|
off_t tableOffset, PrimaryPartition* primary)
|
||||||
: Partition(),
|
:
|
||||||
|
Partition(),
|
||||||
fPrimary(NULL),
|
fPrimary(NULL),
|
||||||
fNext(NULL),
|
fNext(NULL),
|
||||||
fPrevious(NULL)
|
fPrevious(NULL)
|
||||||
@@ -601,7 +608,7 @@ LogicalPartition::SetTo(const partition_descriptor* descriptor,
|
|||||||
|
|
||||||
void
|
void
|
||||||
LogicalPartition::SetTo(off_t offset, off_t size, uint8 type, bool active,
|
LogicalPartition::SetTo(off_t offset, off_t size, uint8 type, bool active,
|
||||||
off_t tableOffset, PrimaryPartition *primary)
|
off_t tableOffset, PrimaryPartition* primary)
|
||||||
{
|
{
|
||||||
Unset();
|
Unset();
|
||||||
if (primary) {
|
if (primary) {
|
||||||
@@ -622,6 +629,27 @@ LogicalPartition::Unset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - PartitionMap
|
// #pragma mark - PartitionMap
|
||||||
|
|
||||||
|
|
||||||
@@ -661,7 +689,7 @@ PartitionMap::Assign(const PartitionMap& other)
|
|||||||
PrimaryPartition*
|
PrimaryPartition*
|
||||||
PartitionMap::PrimaryPartitionAt(int32 index)
|
PartitionMap::PrimaryPartitionAt(int32 index)
|
||||||
{
|
{
|
||||||
PrimaryPartition *partition = NULL;
|
PrimaryPartition* partition = NULL;
|
||||||
if (index >= 0 && index < 4)
|
if (index >= 0 && index < 4)
|
||||||
partition = fPrimaries + index;
|
partition = fPrimaries + index;
|
||||||
return partition;
|
return partition;
|
||||||
@@ -671,7 +699,7 @@ PartitionMap::PrimaryPartitionAt(int32 index)
|
|||||||
const PrimaryPartition*
|
const PrimaryPartition*
|
||||||
PartitionMap::PrimaryPartitionAt(int32 index) const
|
PartitionMap::PrimaryPartitionAt(int32 index) const
|
||||||
{
|
{
|
||||||
const PrimaryPartition *partition = NULL;
|
const PrimaryPartition* partition = NULL;
|
||||||
if (index >= 0 && index < 4)
|
if (index >= 0 && index < 4)
|
||||||
partition = fPrimaries + index;
|
partition = fPrimaries + index;
|
||||||
return partition;
|
return partition;
|
||||||
@@ -729,7 +757,7 @@ PartitionMap::CountNonEmptyPartitions() const
|
|||||||
Partition*
|
Partition*
|
||||||
PartitionMap::PartitionAt(int32 index)
|
PartitionMap::PartitionAt(int32 index)
|
||||||
{
|
{
|
||||||
Partition *partition = NULL;
|
Partition* partition = NULL;
|
||||||
int32 count = CountPartitions();
|
int32 count = CountPartitions();
|
||||||
if (index >= 0 && index < count) {
|
if (index >= 0 && index < count) {
|
||||||
if (index < 4)
|
if (index < 4)
|
||||||
@@ -776,7 +804,7 @@ PartitionMap::Check(off_t sessionSize) const
|
|||||||
int32 tableOffsetCount = 1; // primary partition table
|
int32 tableOffsetCount = 1; // primary partition table
|
||||||
tableOffsets[0] = 0; //
|
tableOffsets[0] = 0; //
|
||||||
for (int32 i = 0; i < partitionCount; i++) {
|
for (int32 i = 0; i < partitionCount; i++) {
|
||||||
const Partition *partition = PartitionAt(i);
|
const Partition* partition = PartitionAt(i);
|
||||||
if (!partition->IsExtended())
|
if (!partition->IsExtended())
|
||||||
byOffset[byOffsetCount++] = partition;
|
byOffset[byOffsetCount++] = partition;
|
||||||
|
|
||||||
@@ -795,7 +823,7 @@ PartitionMap::Check(off_t sessionSize) const
|
|||||||
// check for overlappings
|
// check for overlappings
|
||||||
off_t nextOffset = 0;
|
off_t nextOffset = 0;
|
||||||
for (int32 i = 0; i < byOffsetCount; i++) {
|
for (int32 i = 0; i < byOffsetCount; i++) {
|
||||||
const Partition *partition = byOffset[i];
|
const Partition* partition = byOffset[i];
|
||||||
if (partition->Offset() < nextOffset) {
|
if (partition->Offset() < nextOffset) {
|
||||||
TRACE(("intel: PartitionMap::Check(): overlapping partitions!"
|
TRACE(("intel: PartitionMap::Check(): overlapping partitions!"
|
||||||
"\n"));
|
"\n"));
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
// partition_type
|
// partition_type
|
||||||
struct partition_type {
|
struct partition_type {
|
||||||
uint8 type;
|
uint8 type;
|
||||||
const char *name;
|
const char* name;
|
||||||
bool used;
|
bool used;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,13 +54,13 @@ is_extended_type(uint8 type)
|
|||||||
|
|
||||||
// fill_buffer
|
// fill_buffer
|
||||||
static inline void
|
static inline void
|
||||||
fill_buffer(char *buffer, uint32 length, char ch)
|
fill_buffer(char* buffer, uint32 length, char ch)
|
||||||
{
|
{
|
||||||
for (uint32 i = 0; i < length; i++)
|
for (uint32 i = 0; i < length; i++)
|
||||||
buffer[i] = ch;
|
buffer[i] = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_partition_type_string(uint8 type, char *buffer);
|
void get_partition_type_string(uint8 type, char* buffer);
|
||||||
|
|
||||||
// chs
|
// chs
|
||||||
// NOTE: The CHS cannot express locations within larger disks and is therefor
|
// NOTE: The CHS cannot express locations within larger disks and is therefor
|
||||||
@@ -113,8 +113,8 @@ public:
|
|||||||
PartitionType();
|
PartitionType();
|
||||||
|
|
||||||
bool SetType(uint8 type);
|
bool SetType(uint8 type);
|
||||||
bool SetType(const char *typeName);
|
bool SetType(const char* typeName);
|
||||||
bool SetContentType(const char *contentType);
|
bool SetContentType(const char* contentType);
|
||||||
|
|
||||||
bool IsValid() const { return fValid; }
|
bool IsValid() const { return fValid; }
|
||||||
bool IsEmpty() const { return is_empty_type(fType); }
|
bool IsEmpty() const { return is_empty_type(fType); }
|
||||||
@@ -122,7 +122,7 @@ public:
|
|||||||
|
|
||||||
uint8 Type() const { return fType; }
|
uint8 Type() const { return fType; }
|
||||||
bool FindNext();
|
bool FindNext();
|
||||||
void GetTypeString(char *buffer) const
|
void GetTypeString(char* buffer) const
|
||||||
{ get_partition_type_string(fType, buffer); }
|
{ get_partition_type_string(fType, buffer); }
|
||||||
private:
|
private:
|
||||||
uint8 fType;
|
uint8 fType;
|
||||||
@@ -167,11 +167,8 @@ public:
|
|||||||
uint8 Type() const { return fType; }
|
uint8 Type() const { return fType; }
|
||||||
bool Active() const { return fActive; }
|
bool Active() const { return fActive; }
|
||||||
uint32 BlockSize() const { return fBlockSize; }
|
uint32 BlockSize() const { return fBlockSize; }
|
||||||
void GetTypeString(char *buffer) const
|
void GetTypeString(char* buffer) const
|
||||||
{ get_partition_type_string(fType, buffer); }
|
{ get_partition_type_string(fType, buffer); }
|
||||||
void GetPartitionDescriptor(
|
|
||||||
partition_descriptor* descriptor,
|
|
||||||
off_t baseOffset) const;
|
|
||||||
|
|
||||||
void SetPartitionTableOffset(off_t offset)
|
void SetPartitionTableOffset(off_t offset)
|
||||||
{ fPartitionTableOffset = offset; }
|
{ fPartitionTableOffset = offset; }
|
||||||
@@ -183,6 +180,8 @@ public:
|
|||||||
{ fType = type; }
|
{ fType = type; }
|
||||||
void SetActive(bool active)
|
void SetActive(bool active)
|
||||||
{ fActive = active; }
|
{ fActive = active; }
|
||||||
|
void SetBlockSize(uint32 blockSize)
|
||||||
|
{ fBlockSize = blockSize; }
|
||||||
|
|
||||||
bool CheckLocation(off_t sessionSize) const;
|
bool CheckLocation(off_t sessionSize) const;
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
@@ -215,6 +214,9 @@ public:
|
|||||||
|
|
||||||
int32 Index() const { return fIndex; }
|
int32 Index() const { return fIndex; }
|
||||||
void SetIndex(int32 index) { fIndex = index; }
|
void SetIndex(int32 index) { fIndex = index; }
|
||||||
|
void GetPartitionDescriptor(
|
||||||
|
partition_descriptor* descriptor) const;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
|
|
||||||
// only if extended
|
// only if extended
|
||||||
@@ -240,7 +242,7 @@ public:
|
|||||||
LogicalPartition(
|
LogicalPartition(
|
||||||
const partition_descriptor* descriptor,
|
const partition_descriptor* descriptor,
|
||||||
off_t tableOffset,
|
off_t tableOffset,
|
||||||
PrimaryPartition *primary);
|
PrimaryPartition* primary);
|
||||||
|
|
||||||
void SetTo(const partition_descriptor* descriptor,
|
void SetTo(const partition_descriptor* descriptor,
|
||||||
off_t tableOffset,
|
off_t tableOffset,
|
||||||
@@ -249,6 +251,10 @@ public:
|
|||||||
bool active, off_t tableOffset,
|
bool active, off_t tableOffset,
|
||||||
PrimaryPartition* primary);
|
PrimaryPartition* primary);
|
||||||
void Unset();
|
void Unset();
|
||||||
|
void GetPartitionDescriptor(
|
||||||
|
partition_descriptor* descriptor,
|
||||||
|
bool inner = false) const;
|
||||||
|
|
||||||
|
|
||||||
void SetPrimaryPartition(PrimaryPartition* primary)
|
void SetPrimaryPartition(PrimaryPartition* primary)
|
||||||
{ fPrimary = primary; }
|
{ fPrimary = primary; }
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ PartitionMapParser::_ParsePrimary(const partition_table* table)
|
|||||||
// parse extended partitions
|
// parse extended partitions
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
||||||
PrimaryPartition *primary = fMap->PrimaryPartitionAt(i);
|
PrimaryPartition* primary = fMap->PrimaryPartitionAt(i);
|
||||||
if (primary->IsExtended())
|
if (primary->IsExtended())
|
||||||
error = _ParseExtended(primary, primary->Offset());
|
error = _ParseExtended(primary, primary->Offset());
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,7 @@ PartitionMapParser::_ParsePrimary(const partition_table* table)
|
|||||||
|
|
||||||
// _ParseExtended
|
// _ParseExtended
|
||||||
status_t
|
status_t
|
||||||
PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
PartitionMapParser::_ParseExtended(PrimaryPartition* primary, off_t offset)
|
||||||
{
|
{
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
int32 partitionCount = 0;
|
int32 partitionCount = 0;
|
||||||
@@ -188,11 +188,11 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
|||||||
LogicalPartition extended;
|
LogicalPartition extended;
|
||||||
LogicalPartition nonExtended;
|
LogicalPartition nonExtended;
|
||||||
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
||||||
const partition_descriptor *descriptor = &fPartitionTable->table[i];
|
const partition_descriptor* descriptor = &fPartitionTable->table[i];
|
||||||
if (descriptor->is_empty())
|
if (descriptor->is_empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LogicalPartition *partition = NULL;
|
LogicalPartition* partition = NULL;
|
||||||
if (descriptor->is_extended()) {
|
if (descriptor->is_extended()) {
|
||||||
if (extended.IsEmpty()) {
|
if (extended.IsEmpty()) {
|
||||||
extended.SetTo(descriptor, offset, primary);
|
extended.SetTo(descriptor, offset, primary);
|
||||||
@@ -232,7 +232,7 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
|||||||
|
|
||||||
// add non-extended partition to list
|
// add non-extended partition to list
|
||||||
if (error == B_OK && !nonExtended.IsEmpty()) {
|
if (error == B_OK && !nonExtended.IsEmpty()) {
|
||||||
LogicalPartition *partition
|
LogicalPartition* partition
|
||||||
= new(nothrow) LogicalPartition(nonExtended);
|
= new(nothrow) LogicalPartition(nonExtended);
|
||||||
if (partition)
|
if (partition)
|
||||||
primary->AddLogicalPartition(partition);
|
primary->AddLogicalPartition(partition);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Tomas Kucera, [email protected]
|
* Bryce Groff, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PartitionMapWriter.h"
|
#include "PartitionMapWriter.h"
|
||||||
@@ -34,293 +34,225 @@ using std::nothrow;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// TODO: get rid of this - there is no such thing as a fixed sector size!
|
bool
|
||||||
static const uint32 SECTOR_SIZE = 512;
|
check_logical_location(const LogicalPartition* child,
|
||||||
|
const PrimaryPartition* parent)
|
||||||
|
{
|
||||||
|
if (child->PartitionTableOffset() % child->BlockSize() != 0) {
|
||||||
|
TRACE(("check_logical_location() - PartitionTableOffset: %lld not a "
|
||||||
|
"multiple of media's block size: %ld\n",
|
||||||
|
child->PartitionTableOffset(), child->BlockSize()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (child->Offset() % child->BlockSize() != 0) {
|
||||||
|
TRACE(("check_logical_location() - Parition offset: %lld "
|
||||||
|
"is not a multiple of block size: %ld\n", child->Offset(),
|
||||||
|
child->BlockSize()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (child->Size() % child->BlockSize() != 0) {
|
||||||
|
TRACE(("check_logical_location() - Size: (%lld) is not a multiple of"
|
||||||
|
" block size: (%ld)\n", child->Size(), child->BlockSize()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (child->PartitionTableOffset() < parent->Offset()
|
||||||
|
|| child->PartitionTableOffset() >= parent->Offset()
|
||||||
|
+ parent->Size()) {
|
||||||
|
TRACE(("check_logical_location() - Partition table: (%lld) not within "
|
||||||
|
"extended partition (start: %lld), (end: %lld)\n",
|
||||||
|
child->PartitionTableOffset(), parent->Offset(), parent->Offset()
|
||||||
|
+ parent->Size()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (child->Offset() + child->Size() > parent->Offset() + parent->Size()) {
|
||||||
|
TRACE(("check_logical_location() - logical paritition does not lie "
|
||||||
|
"within extended partition\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
PartitionMapWriter::PartitionMapWriter(int deviceFD, uint32 blockSize)
|
||||||
/*! \brief Creates the writer.
|
|
||||||
|
|
||||||
\param deviceFD File descriptor.
|
|
||||||
\param sessionOffset Disk offset of the partition with partitioning system.
|
|
||||||
\param sessionSize Size of the partition with partitioning system.
|
|
||||||
*/
|
|
||||||
PartitionMapWriter::PartitionMapWriter(int deviceFD, off_t sessionOffset,
|
|
||||||
off_t sessionSize)
|
|
||||||
:
|
:
|
||||||
fDeviceFD(deviceFD),
|
fDeviceFD(deviceFD),
|
||||||
fSessionOffset(sessionOffset),
|
fBlockSize(blockSize)
|
||||||
fSessionSize(sessionSize),
|
|
||||||
fMap(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
PartitionMapWriter::~PartitionMapWriter()
|
PartitionMapWriter::~PartitionMapWriter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// WriteMBR
|
|
||||||
/*! \brief Writes Master Boot Record to the first sector of the disk.
|
|
||||||
|
|
||||||
If a \a block is not specified, the sector is firstly read from the disk
|
|
||||||
and after changing relevant items it is written back to the disk.
|
|
||||||
This allows to keep code area in MBR intact.
|
|
||||||
\param pts Pointer to \c partition_table.
|
|
||||||
\param map Pointer to the PartitionMap structure describing disk partitions.
|
|
||||||
*/
|
|
||||||
status_t
|
status_t
|
||||||
PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
|
PartitionMapWriter::WriteMBR(const PartitionMap* map, bool clearCode)
|
||||||
{
|
{
|
||||||
if (!map)
|
if (map == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
fMap = map;
|
partition_table partitionTable;
|
||||||
|
if (clearCode) {
|
||||||
uint8 sector[SECTOR_SIZE];
|
partitionTable.clear_code_area();
|
||||||
partition_table* pts = (partition_table*)sector;
|
} else {
|
||||||
|
status_t error = _ReadBlock(0, partitionTable);
|
||||||
// If we shall not clear the first two sectors, we need to read the first
|
if (error != B_OK)
|
||||||
// sector in, first.
|
return error;
|
||||||
status_t error = B_OK;
|
|
||||||
if (clearSectors)
|
|
||||||
memset(sector, 0, SECTOR_SIZE);
|
|
||||||
else
|
|
||||||
error = _ReadSector(0, pts);
|
|
||||||
|
|
||||||
if (error == B_OK) {
|
|
||||||
error = _WritePrimary(pts);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _WriteSector(0, pts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the second sector, if desired. We do that to make the partition
|
partitionTable.signature = kPartitionTableSectorSignature;
|
||||||
// unrecognizable by BFS.
|
|
||||||
if (error == B_OK && clearSectors) {
|
for (int i = 0; i < 4; i++) {
|
||||||
memset(sector, 0, SECTOR_SIZE);
|
partition_descriptor* descriptor = &partitionTable.table[i];
|
||||||
error = _WriteSector(SECTOR_SIZE, pts);
|
const PrimaryPartition* partition = map->PrimaryPartitionAt(i);
|
||||||
|
|
||||||
|
partition->GetPartitionDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
fMap = NULL;
|
status_t error = _WriteBlock(0, partitionTable);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// WriteLogical
|
|
||||||
/*! \brief Writes Partition Table Sector of the logical \a partition to the
|
|
||||||
disk.
|
|
||||||
|
|
||||||
This function ensures that the connection of the following linked list
|
|
||||||
of logical partitions will be correct. It does nothing with the connection
|
|
||||||
of previous logical partitions (call this function on previous logical
|
|
||||||
partition to ensure it).
|
|
||||||
|
|
||||||
\param pts Pointer to \c partition_table.
|
|
||||||
\param partition Pointer to the logical partition.
|
|
||||||
*/
|
|
||||||
status_t
|
status_t
|
||||||
PartitionMapWriter::WriteLogical(partition_table* pts,
|
PartitionMapWriter::WriteLogical(const LogicalPartition* logical,
|
||||||
const LogicalPartition* partition)
|
const PrimaryPartition* primary, bool clearCode)
|
||||||
{
|
{
|
||||||
if (partition == NULL)
|
if (logical == NULL || primary == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
partition_table _pts;
|
if (!check_logical_location(logical, primary))
|
||||||
if (pts == NULL) {
|
|
||||||
// no partition table given, use stack based partition table and read
|
|
||||||
// from disk first
|
|
||||||
pts = &_pts;
|
|
||||||
status_t error = _ReadSector(partition->PartitionTableOffset(), pts);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t error = _WriteExtended(pts, partition, partition->Next());
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
return _WriteSector(partition->PartitionTableOffset(), pts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// WriteExtendedHead
|
|
||||||
/*! \brief Writes Extended Boot Record to the first sector of Extended
|
|
||||||
Partition.
|
|
||||||
|
|
||||||
Writes the head of linked list describing logical partitions.
|
|
||||||
|
|
||||||
If the \a firstPartition is not specified, it only initializes EBR and the
|
|
||||||
linked list contains no logical partitions.
|
|
||||||
|
|
||||||
\param pts Pointer to \c partition_table.
|
|
||||||
\param firstPartition Pointer to the first logical partition.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
PartitionMapWriter::WriteExtendedHead(partition_table* pts,
|
|
||||||
const LogicalPartition* firstPartition)
|
|
||||||
{
|
|
||||||
LogicalPartition partition;
|
|
||||||
if (firstPartition != NULL)
|
|
||||||
partition.SetPrimaryPartition(firstPartition->GetPrimaryPartition());
|
|
||||||
|
|
||||||
partition_table _pts;
|
|
||||||
if (pts == NULL) {
|
|
||||||
// no partition table given, use stack based partition table and read
|
|
||||||
// from disk first
|
|
||||||
pts = &_pts;
|
|
||||||
status_t error = _ReadSector(0, pts);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t error = _WriteExtended(pts, &partition, firstPartition);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
return _WriteSector(0, pts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - fill a partition table in memory
|
|
||||||
|
|
||||||
|
|
||||||
// _WritePrimary
|
|
||||||
status_t
|
|
||||||
PartitionMapWriter::_WritePrimary(partition_table* pts)
|
|
||||||
{
|
|
||||||
if (pts == NULL)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
// write the signature
|
|
||||||
pts->signature = kPartitionTableSectorSignature;
|
|
||||||
|
|
||||||
// write the table
|
|
||||||
for (int32 i = 0; i < 4; i++) {
|
|
||||||
partition_descriptor *descriptor = &pts->table[i];
|
|
||||||
const PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
|
||||||
|
|
||||||
// ignore, if location is bad
|
|
||||||
if (!partition->CheckLocation(fSessionSize)) {
|
|
||||||
TRACE(("intel: _WritePrimary(): partition %ld: bad location, "
|
|
||||||
"ignoring\n", i));
|
|
||||||
return B_BAD_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
partition->GetPartitionDescriptor(descriptor, 0);
|
|
||||||
// TODO: Should this be fSessionOffset?!
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// _WriteExtended
|
|
||||||
status_t
|
|
||||||
PartitionMapWriter::_WriteExtended(partition_table *pts,
|
|
||||||
const LogicalPartition *partition, const LogicalPartition *next)
|
|
||||||
{
|
|
||||||
if (pts == NULL || partition == NULL)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
// write the signature
|
|
||||||
pts->signature = kPartitionTableSectorSignature;
|
|
||||||
|
|
||||||
// check the partition's location
|
|
||||||
if (!partition->CheckLocation(fSessionSize)) {
|
|
||||||
TRACE(("intel: _WriteExtended(): Invalid partition "
|
|
||||||
"location: pts: %lld, offset: %lld, size: %lld, "
|
|
||||||
"fSessionSize: %lld\n",
|
|
||||||
partition->PartitionTableOffset(), partition->Offset(),
|
|
||||||
partition->Size(), fSessionSize));
|
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
|
partition_table partitionTable;
|
||||||
|
if (clearCode) {
|
||||||
|
partitionTable.clear_code_area();
|
||||||
|
} else {
|
||||||
|
status_t error = _ReadBlock(logical->PartitionTableOffset(),
|
||||||
|
partitionTable);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: The OS/2 boot manager needs the first entry to describe the
|
partitionTable.signature = kPartitionTableSectorSignature;
|
||||||
// data partition, while the second entry should describe the "inner
|
|
||||||
// extended" partition.
|
|
||||||
|
|
||||||
// write the table
|
partition_descriptor* descriptor = &partitionTable.table[0];
|
||||||
partition_descriptor* descriptor = &(pts->table[0]);
|
logical->GetPartitionDescriptor(descriptor);
|
||||||
partition->GetPartitionDescriptor(descriptor,
|
|
||||||
partition->PartitionTableOffset());
|
|
||||||
// location is relative to this partition's table offset
|
|
||||||
|
|
||||||
// Set offset and size of the next partition in the linked list.
|
descriptor = &partitionTable.table[1];
|
||||||
// This is done via a so called "inner extended" partition which is
|
if (logical->Next() != NULL)
|
||||||
// only used to point to the next partition table location (start sector of
|
logical->Next()->GetPartitionDescriptor(descriptor, true);
|
||||||
// the inner extended partition).
|
else
|
||||||
descriptor = &pts->table[1];
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
LogicalPartition extended;
|
|
||||||
if (next) {
|
|
||||||
extended.SetPartitionTableOffset(partition->PartitionTableOffset());
|
|
||||||
extended.SetOffset(next->PartitionTableOffset());
|
|
||||||
|
|
||||||
// Strictly speaking, the size is not relevant and just needs to
|
// last two descriptors are empty
|
||||||
// be non-zero. But some operating systems check the size of
|
|
||||||
// inner extended partitions and it needs to include the next data
|
|
||||||
// partition. Therefor the size is the size of the next data partition
|
|
||||||
// plus the offset between the next partition table and the data
|
|
||||||
// partition start offset.
|
|
||||||
// This assumes of course that the start offset is behind the partition
|
|
||||||
// table offset, which is actually not dictated by a minimal
|
|
||||||
// specification.
|
|
||||||
extended.SetSize(next->Size()
|
|
||||||
+ (next->Offset() - next->PartitionTableOffset()));
|
|
||||||
|
|
||||||
// Use the same extended partition type as the primary extended
|
|
||||||
// partition.
|
|
||||||
extended.SetType(partition->GetPrimaryPartition()->Type());
|
|
||||||
|
|
||||||
extended.GetPartitionDescriptor(descriptor, 0);
|
|
||||||
|
|
||||||
// Unsetting to get an empty descriptor for the remaining slots.
|
|
||||||
extended.Unset();
|
|
||||||
} else
|
|
||||||
extended.GetPartitionDescriptor(descriptor, 0);
|
|
||||||
|
|
||||||
// last two descriptors are empty ("extended" is unset)
|
|
||||||
for (int32 i = 2; i < 4; i++) {
|
for (int32 i = 2; i < 4; i++) {
|
||||||
descriptor = &(pts->table[i]);
|
descriptor = &partitionTable.table[i];
|
||||||
extended.GetPartitionDescriptor(descriptor, 0);
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t error = _WriteBlock(logical->PartitionTableOffset(),
|
||||||
|
partitionTable);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PartitionMapWriter::WriteExtendedHead(const LogicalPartition* logical,
|
||||||
|
const PrimaryPartition* primary, bool clearCode)
|
||||||
|
{
|
||||||
|
if (primary == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
partition_table partitionTable;
|
||||||
|
if (clearCode) {
|
||||||
|
partitionTable.clear_code_area();
|
||||||
|
} else {
|
||||||
|
status_t error = _ReadBlock(primary->Offset(), partitionTable);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
partitionTable.signature = kPartitionTableSectorSignature;
|
||||||
|
partition_descriptor* descriptor;
|
||||||
|
if (logical == NULL) {
|
||||||
|
for (int32 i = 0; i < 4; i++) {
|
||||||
|
descriptor = &partitionTable.table[i];
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogicalPartition partition;
|
||||||
|
partition.SetPartitionTableOffset(primary->Offset());
|
||||||
|
partition.SetBlockSize(logical->BlockSize());
|
||||||
|
partition.SetOffset(logical->Offset());
|
||||||
|
partition.SetSize(logical->Size());
|
||||||
|
partition.SetType(logical->Type());
|
||||||
|
|
||||||
|
// set the logicals partition table to the correct location
|
||||||
|
descriptor = &partitionTable.table[0];
|
||||||
|
partition.GetPartitionDescriptor(descriptor);
|
||||||
|
|
||||||
|
descriptor = &partitionTable.table[1];
|
||||||
|
LogicalPartition* next = logical->Next();
|
||||||
|
if (next != NULL)
|
||||||
|
next->GetPartitionDescriptor(descriptor, true);
|
||||||
|
else
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
|
||||||
|
// last two descriptors are empty
|
||||||
|
for (int32 i = 2; i < 4; i++) {
|
||||||
|
descriptor = &partitionTable.table[i];
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t error = _WriteBlock(primary->Offset(), partitionTable);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - to/from disk
|
|
||||||
|
|
||||||
|
|
||||||
// _ReadSector
|
|
||||||
/*! \brief Reads the sector from the disk.
|
|
||||||
*/
|
|
||||||
status_t
|
status_t
|
||||||
PartitionMapWriter::_ReadSector(off_t offset, partition_table* pts)
|
PartitionMapWriter::ClearExtendedHead(const PrimaryPartition* primary)
|
||||||
{
|
{
|
||||||
int32 toRead = sizeof(partition_table);
|
if (primary == NULL)
|
||||||
// same as SECTOR_SIZE actually
|
|
||||||
|
|
||||||
// check the offset
|
|
||||||
if (offset < 0 || offset + toRead > fSessionSize) {
|
|
||||||
TRACE(("intel: _ReadSector(): bad offset: %Ld\n", offset));
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
partition_table partitionTable;
|
||||||
|
partitionTable.clear_code_area();
|
||||||
|
partitionTable.signature = kPartitionTableSectorSignature;
|
||||||
|
|
||||||
|
partition_descriptor* descriptor;
|
||||||
|
for (int32 i = 0; i < 4; i++) {
|
||||||
|
descriptor = &partitionTable.table[i];
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// read
|
status_t error = _WriteBlock(primary->Offset(), partitionTable);
|
||||||
offset += fSessionOffset;
|
if (error != B_OK)
|
||||||
if (read_pos(fDeviceFD, offset, pts, toRead) != toRead) {
|
return error;
|
||||||
#ifndef _BOOT_MODE
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PartitionMapWriter::_ReadBlock(off_t partitionOffset,
|
||||||
|
partition_table& partitionTable)
|
||||||
|
{
|
||||||
|
if (partitionOffset < 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
// TODO: If fBlockSize > sizeof(partition_table) then stop/read NULL after
|
||||||
|
if (read_pos(fDeviceFD, partitionOffset, &partitionTable, fBlockSize)
|
||||||
|
!= fBlockSize) {
|
||||||
status_t error = errno;
|
status_t error = errno;
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = B_IO_ERROR;
|
error = B_IO_ERROR;
|
||||||
#else
|
|
||||||
status_t error = B_IO_ERROR;
|
|
||||||
#endif
|
|
||||||
TRACE(("intel: _ReadSector(): reading the partition table failed: %lx\n",
|
|
||||||
error));
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,31 +260,19 @@ PartitionMapWriter::_ReadSector(off_t offset, partition_table* pts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _WriteSector
|
|
||||||
/*! \brief Writes the sector to the disk.
|
|
||||||
*/
|
|
||||||
status_t
|
status_t
|
||||||
PartitionMapWriter::_WriteSector(off_t offset, const partition_table* pts)
|
PartitionMapWriter::_WriteBlock(off_t partitionOffset,
|
||||||
|
const partition_table& partitionTable)
|
||||||
{
|
{
|
||||||
int32 toWrite = sizeof(partition_table);
|
if (partitionOffset < 0)
|
||||||
// same as SECTOR_SIZE actually
|
|
||||||
|
|
||||||
// check the offset
|
|
||||||
if (offset < 0 || offset + toWrite > fSessionSize) {
|
|
||||||
TRACE(("intel: _WriteSector(): bad offset: %Ld\n", offset));
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
// TODO: If fBlockSize > sizeof(partition_table) then stop/write NULL after
|
||||||
|
if (write_pos(fDeviceFD, partitionOffset, &partitionTable, fBlockSize)
|
||||||
offset += fSessionOffset;
|
!= fBlockSize) {
|
||||||
|
|
||||||
// write
|
|
||||||
if (write_pos(fDeviceFD, offset, pts, toWrite) != toWrite) {
|
|
||||||
status_t error = errno;
|
status_t error = errno;
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = B_IO_ERROR;
|
error = B_IO_ERROR;
|
||||||
|
|
||||||
TRACE(("intel: _WriteSector(): writing the partition table failed: "
|
|
||||||
"%lx\n", error));
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Tomas Kucera, [email protected]
|
* Tomas Kucera, [email protected]
|
||||||
|
* Bryce Groff, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -26,8 +27,12 @@
|
|||||||
|
|
||||||
class PartitionMap;
|
class PartitionMap;
|
||||||
class LogicalPartition;
|
class LogicalPartition;
|
||||||
|
class PrimaryPartition;
|
||||||
struct partition_table;
|
struct partition_table;
|
||||||
|
|
||||||
|
bool check_logical_location(const LogicalPartition* logical,
|
||||||
|
const PrimaryPartition* primary);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Writer for "Intel" style partitions.
|
\brief Writer for "Intel" style partitions.
|
||||||
|
|
||||||
@@ -36,33 +41,32 @@ struct partition_table;
|
|||||||
class PartitionMapWriter {
|
class PartitionMapWriter {
|
||||||
public:
|
public:
|
||||||
PartitionMapWriter(int deviceFD,
|
PartitionMapWriter(int deviceFD,
|
||||||
off_t sessionOffset, off_t sessionSize);
|
uint32 blockSize);
|
||||||
~PartitionMapWriter();
|
~PartitionMapWriter();
|
||||||
|
|
||||||
status_t WriteMBR(const PartitionMap* map,
|
status_t WriteMBR(const PartitionMap* map,
|
||||||
bool clearSectors);
|
bool clearCode);
|
||||||
status_t WriteLogical(partition_table* pts,
|
status_t WriteLogical(const LogicalPartition* logical,
|
||||||
const LogicalPartition* partition);
|
const PrimaryPartition* primary,
|
||||||
status_t WriteExtendedHead(partition_table* pts,
|
bool clearCode);
|
||||||
const LogicalPartition* firstPartition);
|
status_t WriteExtendedHead(
|
||||||
|
const LogicalPartition* logical,
|
||||||
|
const PrimaryPartition* primary,
|
||||||
|
bool clearCode);
|
||||||
|
|
||||||
|
status_t ClearExtendedHead(
|
||||||
|
const PrimaryPartition* primary);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _WritePrimary(partition_table* pts);
|
status_t _ReadBlock(off_t offset,
|
||||||
status_t _WriteExtended(partition_table* pts,
|
partition_table& partitionTable);
|
||||||
const LogicalPartition* partition,
|
status_t _WriteBlock(off_t offset,
|
||||||
const LogicalPartition* next);
|
const partition_table& partitionTable);
|
||||||
|
|
||||||
status_t _ReadSector(off_t offset,
|
|
||||||
partition_table* pts);
|
|
||||||
status_t _WriteSector(off_t offset,
|
|
||||||
const partition_table* pts);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fDeviceFD;
|
int fDeviceFD;
|
||||||
off_t fSessionOffset;
|
int32 fBlockSize;
|
||||||
off_t fSessionSize;
|
|
||||||
|
|
||||||
const PartitionMap* fMap; // while writing
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PARTITION_MAP_WRITER_H
|
#endif // PARTITION_MAP_WRITER_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -154,6 +154,22 @@ get_child_partition(partition_id partitionID, int32 index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
open_partition(partition_id partitionID, int openMode)
|
||||||
|
{
|
||||||
|
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||||
|
KPartition *partition = manager->FindPartition(partitionID);
|
||||||
|
if (partition == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
int fd = -1;
|
||||||
|
status_t result = partition->Open(openMode, &fd);
|
||||||
|
if (result != B_OK)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
// create_child_partition
|
// create_child_partition
|
||||||
partition_data *
|
partition_data *
|
||||||
create_child_partition(partition_id partitionID, int32 index, off_t offset,
|
create_child_partition(partition_id partitionID, int32 index, off_t offset,
|
||||||
|
|||||||
Reference in New Issue
Block a user