diff options
author | Samuel Bowman <sam@sambowman.tech> | 2022-03-01 20:01:52 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-07-21 20:13:44 +0100 |
commit | 9053d86b82dcd4a833b1f64e0dcdf77ac148fb86 (patch) | |
tree | 289b4119cf46c5bf50d343090b1ebfce0da9deb6 /Userland/Libraries/LibPartition | |
parent | 1a6ef03e4a360d9497ef0babbb38c7c7cb1df0e0 (diff) | |
download | serenity-9053d86b82dcd4a833b1f64e0dcdf77ac148fb86.zip |
Kernel+LibPartition: Move EBRPartitionTable into LibPartition
Diffstat (limited to 'Userland/Libraries/LibPartition')
-rw-r--r-- | Userland/Libraries/LibPartition/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibPartition/EBRPartitionTable.cpp | 72 | ||||
-rw-r--r-- | Userland/Libraries/LibPartition/EBRPartitionTable.h | 28 |
3 files changed, 101 insertions, 0 deletions
diff --git a/Userland/Libraries/LibPartition/CMakeLists.txt b/Userland/Libraries/LibPartition/CMakeLists.txt index a3f43660b8..adae3e4c98 100644 --- a/Userland/Libraries/LibPartition/CMakeLists.txt +++ b/Userland/Libraries/LibPartition/CMakeLists.txt @@ -1,5 +1,6 @@ set(SOURCES DiskPartitionMetadata.cpp + EBRPartitionTable.cpp MBRPartitionTable.cpp PartitionTable.cpp ) diff --git a/Userland/Libraries/LibPartition/EBRPartitionTable.cpp b/Userland/Libraries/LibPartition/EBRPartitionTable.cpp new file mode 100644 index 0000000000..ee2220d2d0 --- /dev/null +++ b/Userland/Libraries/LibPartition/EBRPartitionTable.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020-2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibPartition/EBRPartitionTable.h> + +namespace Partition { + +ErrorOr<NonnullOwnPtr<EBRPartitionTable>> EBRPartitionTable::try_to_initialize(Kernel::StorageDevice const& device) +{ + auto table = TRY(adopt_nonnull_own_or_enomem(new (nothrow) EBRPartitionTable(device))); + if (table->is_protective_mbr()) + return Error::from_errno(ENOTSUP); + if (!table->is_valid()) + return Error::from_errno(EINVAL); + return table; +} + +void EBRPartitionTable::search_extended_partition(Kernel::StorageDevice const& device, MBRPartitionTable& checked_ebr, u64 current_block_offset, size_t limit) +{ + if (limit == 0) + return; + // EBRs should not carry more than 2 partitions (because they need to form a linked list) + VERIFY(checked_ebr.partitions_count() <= 2); + auto checked_logical_partition = checked_ebr.partition(0); + + // If we are pointed to an invalid logical partition, something is seriously wrong. + VERIFY(checked_logical_partition.has_value()); + m_partitions.append(checked_logical_partition.value().offset(current_block_offset)); + if (!checked_ebr.contains_ebr()) + return; + current_block_offset += checked_ebr.partition(1).value().start_block(); + auto next_ebr = MBRPartitionTable::try_to_initialize(device, current_block_offset); + if (!next_ebr) + return; + search_extended_partition(device, *next_ebr, current_block_offset, (limit - 1)); +} + +EBRPartitionTable::EBRPartitionTable(Kernel::StorageDevice const& device) + : MBRPartitionTable(device) +{ + if (!is_header_valid()) + return; + m_valid = true; + + VERIFY(partitions_count() == 0); + + auto& header = this->header(); + for (size_t index = 0; index < 4; index++) { + auto& entry = header.entry[index]; + // Start enumerating all logical partitions + if (entry.type == 0xf) { + auto checked_ebr = MBRPartitionTable::try_to_initialize(device, entry.offset); + if (!checked_ebr) + continue; + // It's quite unlikely to see that amount of partitions, so stop at 128 partitions. + search_extended_partition(device, *checked_ebr, entry.offset, 128); + continue; + } + + if (entry.offset == 0x00) { + continue; + } + MUST(m_partitions.try_empend(entry.offset, (entry.offset + entry.length), entry.type)); + } +} + +EBRPartitionTable::~EBRPartitionTable() = default; + +} diff --git a/Userland/Libraries/LibPartition/EBRPartitionTable.h b/Userland/Libraries/LibPartition/EBRPartitionTable.h new file mode 100644 index 0000000000..d44f5a4490 --- /dev/null +++ b/Userland/Libraries/LibPartition/EBRPartitionTable.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020-2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibPartition/MBRPartitionTable.h> + +namespace Partition { + +struct EBRPartitionHeader; +class EBRPartitionTable : public MBRPartitionTable { +public: + ~EBRPartitionTable(); + + static ErrorOr<NonnullOwnPtr<EBRPartitionTable>> try_to_initialize(Kernel::StorageDevice const&); + explicit EBRPartitionTable(Kernel::StorageDevice const&); + virtual bool is_valid() const override { return m_valid; }; + +private: + void search_extended_partition(Kernel::StorageDevice const&, MBRPartitionTable&, u64, size_t limit); + + bool m_valid { false }; +}; + +} |