Skip to content
LeviMC
English
AutoLightDark
LeviLamina
Loading...
Searching...
No Matches
SystemUtils.h
1#pragma once
2
3#include <concepts>
4#include <cstddef>
5#include <filesystem>
6#include <optional>
7#include <span>
8#include <string>
9
10#include "ll/api/base/CompilerPredefine.h"
11#include "ll/api/base/Macro.h"
12#include "ll/api/base/StdInt.h"
13#include "ll/api/data/TmWithMs.h"
14#include "ll/api/data/Version.h"
15
16namespace ll::inline utils::sys_utils {
17
18using HandleT = void*;
19
20[[nodiscard]] inline HandleT getCurrentModuleHandle() { return internal::getCurrentModuleHandle(); }
21
22LLNDAPI HandleT getModuleHandle(void* addr);
23
24LLNDAPI std::optional<std::filesystem::path> getModulePath(HandleT handle, HandleT process = nullptr);
25
26LLNDAPI std::string getModuleFileName(HandleT handle, HandleT process = nullptr);
27
28[[nodiscard]] inline std::string getCallerModuleFileName(void* addr = LL_RETURN_ADDRESS) {
29 return getModuleFileName(getModuleHandle(addr));
30}
31LLNDAPI std::span<std::byte> getImageRange(std::string_view name = "");
32
33LLNDAPI std::filesystem::path normalizePath(std::filesystem::path const& path);
34
35LLNDAPI std::string getSystemLocaleCode();
36
37LLNDAPI std::string const& getSystemName();
38
39LLNDAPI data::TmWithMs getLocalTime(); // tm & ms
40
41LLNDAPI std::string getEnvironmentVariable(std::string_view name);
42
43LLAPI bool setEnvironmentVariable(std::string_view name, std::string_view value);
44
45LLAPI bool addOrSetEnvironmentVariable(std::string_view name, std::string_view value);
46
47LLNDAPI bool isStdoutSupportAnsi();
48
49LLNDAPI bool isWine();
50
51LLNDAPI data::Version getSystemVersion();
52
53class DynamicLibrary {
54 HandleT lib = nullptr;
55
56public:
57 [[nodiscard]] DynamicLibrary() {}
58 [[nodiscard]] DynamicLibrary(std::filesystem::path const& path) { load(path); }
59 ~DynamicLibrary() {
60 if (lib) free();
61 }
62
63 DynamicLibrary(DynamicLibrary&&) noexcept = default;
64 DynamicLibrary& operator=(DynamicLibrary&&) noexcept = default;
65 DynamicLibrary(DynamicLibrary const&) = delete;
66 DynamicLibrary& operator=(DynamicLibrary const&) = delete;
67
68 LLAPI std::optional<std::system_error> load(std::filesystem::path const& path) noexcept;
69 LLAPI std::optional<std::system_error> free() noexcept;
70
71 LLNDAPI void* getAddress(char const* name) noexcept;
72
73 template <class T>
74 T getAddress(char const* name) noexcept {
75 return reinterpret_cast<T>(getAddress(name));
76 }
77
78 [[nodiscard]] constexpr HandleT handle() const noexcept { return lib; }
79};
80
81template <std::invocable<wchar_t*, size_t, size_t&> Fn>
82[[nodiscard]] inline std::optional<std::wstring> adaptFixedSizeToAllocatedResult(Fn&& callback) noexcept {
83 constexpr size_t arraySize = 256;
84
85 wchar_t value[arraySize]{};
86 size_t valueLengthNeededWithNull{};
87
88 std::optional<std::wstring> result{std::in_place};
89
90 if (!std::invoke(std::forward<Fn>(callback), value, arraySize, valueLengthNeededWithNull)) {
91 result.reset();
92 return result;
93 }
94 if (valueLengthNeededWithNull <= arraySize) {
95 return std::optional<std::wstring>{std::in_place, value, valueLengthNeededWithNull - 1};
96 }
97 do {
98 result->resize(valueLengthNeededWithNull - 1);
99 if (!std::invoke(std::forward<Fn>(callback), result->data(), result->size() + 1, valueLengthNeededWithNull)) {
100 result.reset();
101 return result;
102 }
103 } while (valueLengthNeededWithNull > result->size() + 1);
104 if (valueLengthNeededWithNull <= result->size()) {
105 result->resize(valueLengthNeededWithNull - 1);
106 }
107 return result;
108}
109} // namespace ll::inline utils::sys_utils