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 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 diff --git a/AK/UUID.h b/AK/UUID.h index 3d69414346..066d301091 100644 --- a/AK/UUID.h +++ b/AK/UUID.h @@ -15,9 +15,14 @@ namespace AK { class UUID { public: + enum class Endianness { + Mixed, + Little + }; + UUID() = default; UUID(Array 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 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,