diff options
author | Liav A <liavalb@gmail.com> | 2022-01-28 20:21:40 +0200 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2022-01-29 13:35:54 +0200 |
commit | 308e54bc19615fb0fcb9ec71d6f02cca8c4b75d9 (patch) | |
tree | 7d27d27be3c0ca97775633e68b53c71ba659a790 | |
parent | 2d67d141e6c2ed76e8510e1838c600004803a9cf (diff) | |
download | serenity-308e54bc19615fb0fcb9ec71d6f02cca8c4b75d9.zip |
AK+Kernel: Implement UUID mixed endianness support
This is being used by GUID partitions so the first three dash-delimited
fields of the GUID are stored in little endian order but the last two
fields are stored in big endian order, hence it's a representation which
is mixed.
-rw-r--r-- | AK/UUID.cpp | 41 | ||||
-rw-r--r-- | AK/UUID.h | 10 | ||||
-rw-r--r-- | Kernel/Storage/StorageManagement.cpp | 2 |
3 files changed, 47 insertions, 6 deletions
diff --git a/AK/UUID.cpp b/AK/UUID.cpp index 4b30f33830..ac76da1464 100644 --- a/AK/UUID.cpp +++ b/AK/UUID.cpp @@ -16,7 +16,7 @@ UUID::UUID(Array<u8, 16> uuid_buffer) uuid_buffer.span().copy_to(m_uuid_buffer); } -void UUID::convert_string_view_to_uuid(StringView uuid_string_view) +void UUID::convert_string_view_to_little_endian_uuid(StringView uuid_string_view) { VERIFY(uuid_string_view.length() == 36); auto first_unit = MUST(decode_hex(uuid_string_view.substring_view(0, 8))); @@ -36,9 +36,44 @@ void UUID::convert_string_view_to_uuid(StringView uuid_string_view) m_uuid_buffer.span().overwrite(10, fifth_unit.data(), fifth_unit.size()); } -UUID::UUID(StringView uuid_string_view) +void UUID::convert_string_view_to_mixed_endian_uuid(StringView uuid_string_view) { - convert_string_view_to_uuid(uuid_string_view); + VERIFY(uuid_string_view.length() == 36); + auto first_unit = MUST(decode_hex(uuid_string_view.substring_view(0, 8))); + auto second_unit = MUST(decode_hex(uuid_string_view.substring_view(9, 4))); + auto third_unit = MUST(decode_hex(uuid_string_view.substring_view(14, 4))); + auto fourth_unit = MUST(decode_hex(uuid_string_view.substring_view(19, 4))); + auto fifth_unit = MUST(decode_hex(uuid_string_view.substring_view(24, 12))); + + VERIFY(first_unit.size() == 4 && second_unit.size() == 2 + && third_unit.size() == 2 && fourth_unit.size() == 2 + && fifth_unit.size() == 6); + + // Revert endianness for first 4 bytes + for (size_t index = 0; index < 4; index++) { + m_uuid_buffer[3 - index] = first_unit[index]; + } + + // Revert endianness for second 2 bytes and again for 2 bytes + for (size_t index = 0; index < 2; index++) { + m_uuid_buffer[3 + 2 - index] = second_unit[index]; + m_uuid_buffer[5 + 2 - index] = third_unit[index]; + } + + m_uuid_buffer.span().overwrite(8, fourth_unit.data(), fourth_unit.size()); + m_uuid_buffer.span().overwrite(10, fifth_unit.data(), fifth_unit.size()); +} + +UUID::UUID(StringView uuid_string_view, Endianness endianness) +{ + if (endianness == Endianness::Little) { + convert_string_view_to_little_endian_uuid(uuid_string_view); + return; + } else if (endianness == Endianness::Mixed) { + convert_string_view_to_mixed_endian_uuid(uuid_string_view); + return; + } + VERIFY_NOT_REACHED(); } String UUID::to_string() const @@ -15,9 +15,14 @@ namespace AK { class UUID { public: + enum class Endianness { + Mixed, + Little + }; + UUID() = default; UUID(Array<u8, 16> uuid_buffer); - UUID(StringView); + UUID(StringView, Endianness endianness = Endianness::Little); ~UUID() = default; bool operator==(const UUID&) const; @@ -31,7 +36,8 @@ public: bool is_zero() const; private: - void convert_string_view_to_uuid(StringView); + void convert_string_view_to_little_endian_uuid(StringView); + void convert_string_view_to_mixed_endian_uuid(StringView); Array<u8, 16> m_uuid_buffer {}; }; diff --git a/Kernel/Storage/StorageManagement.cpp b/Kernel/Storage/StorageManagement.cpp index 54fe0266bb..cfcdc5b274 100644 --- a/Kernel/Storage/StorageManagement.cpp +++ b/Kernel/Storage/StorageManagement.cpp @@ -219,7 +219,7 @@ UNMAP_AFTER_INIT void StorageManagement::determine_boot_device_with_partition_uu VERIFY(!m_storage_devices.is_empty()); VERIFY(m_boot_argument.starts_with(partition_uuid_prefix)); - auto partition_uuid = UUID(m_boot_argument.substring_view(partition_uuid_prefix.length())); + auto partition_uuid = UUID(m_boot_argument.substring_view(partition_uuid_prefix.length()), UUID::Endianness::Mixed); if (partition_uuid.to_string().length() != 36) { // FIXME: It would be helpful to output the specified and detected UUIDs in this case, |