src/internal/module_name.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef DETOURMODKIT_INTERNAL_MODULE_NAME_HPP | ||
| 2 | #define DETOURMODKIT_INTERNAL_MODULE_NAME_HPP | ||
| 3 | |||
| 4 | /** | ||
| 5 | * @file module_name.hpp | ||
| 6 | * @brief Shared bounded UTF-8 -> UTF-16 widening for module-name lookups. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include "internal/utf8_conversion.hpp" | ||
| 10 | |||
| 11 | #include <climits> | ||
| 12 | #include <cstddef> | ||
| 13 | #include <new> | ||
| 14 | #include <string> | ||
| 15 | #include <string_view> | ||
| 16 | |||
| 17 | namespace DetourModKit | ||
| 18 | { | ||
| 19 | namespace detail | ||
| 20 | { | ||
| 21 | /** | ||
| 22 | * @brief Reports whether a module-name byte count fits the Win32 conversion API. | ||
| 23 | * @param length The byte count to test. | ||
| 24 | * @return True when @p length can be represented by the converter's signed count. | ||
| 25 | */ | ||
| 26 | 163 | [[nodiscard]] constexpr bool module_name_length_fits_win32(std::size_t length) noexcept | |
| 27 | { | ||
| 28 | 163 | return length <= static_cast<std::size_t>(INT_MAX); | |
| 29 | } | ||
| 30 | |||
| 31 | /** | ||
| 32 | * @brief Widens a pointer/count UTF-8 module name after validating its Win32 length. | ||
| 33 | * @details The length check precedes construction of a view and every access through @p data. Embedded NUL and | ||
| 34 | * malformed UTF-8 are rejected because GetModuleHandleW would otherwise observe a different name. | ||
| 35 | * @param data The first name byte; may be null only when @p length is zero or oversized. | ||
| 36 | * @param length The number of name bytes. | ||
| 37 | * @return The UTF-16 name, or an empty string when validation, conversion, or allocation fails. | ||
| 38 | * @pre When @p length is nonzero and at most INT_MAX, @p data addresses @p length readable bytes. | ||
| 39 | */ | ||
| 40 | 164 | [[nodiscard]] inline std::wstring widen_module_name_bytes(const char *data, std::size_t length) noexcept | |
| 41 | { | ||
| 42 | 164 | if (length == 0 || !module_name_length_fits_win32(length) || data == nullptr) | |
| 43 | { | ||
| 44 | 2 | return std::wstring{}; | |
| 45 | } | ||
| 46 | try | ||
| 47 | { | ||
| 48 | 162 | return widen_utf8(std::string_view{data, length}); | |
| 49 | } | ||
| 50 | 1 | catch (const std::bad_alloc &) | |
| 51 | { | ||
| 52 | 1 | return std::wstring{}; | |
| 53 | 1 | } | |
| 54 | } | ||
| 55 | |||
| 56 | /** | ||
| 57 | * @brief Widens a UTF-8 module name to the UTF-16 the Win32 module APIs expect. | ||
| 58 | * @details Reads exactly @c name.size() bytes, so a non-NUL-terminated view is safe. | ||
| 59 | * @param name The bounded UTF-8 module name. | ||
| 60 | * @return The UTF-16 name, or an empty string when validation, conversion, or allocation fails. | ||
| 61 | */ | ||
| 62 | 163 | [[nodiscard]] inline std::wstring widen_module_name(std::string_view name) noexcept | |
| 63 | { | ||
| 64 | 163 | return widen_module_name_bytes(name.data(), name.size()); | |
| 65 | } | ||
| 66 | } // namespace detail | ||
| 67 | } // namespace DetourModKit | ||
| 68 | |||
| 69 | #endif // DETOURMODKIT_INTERNAL_MODULE_NAME_HPP | ||
| 70 |