#include "time.hpp" #include namespace utils { std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(clock& c, const LARGE_INTEGER delay_interval, const LARGE_INTEGER infinite_value) { if (delay_interval.QuadPart == infinite_value.QuadPart) { return std::chrono::steady_clock::time_point::min(); } if (delay_interval.QuadPart <= 0) { const auto relative_time = -delay_interval.QuadPart; const auto relative_ticks_in_ms = relative_time / 10; const auto relative_fraction_ns = (relative_time % 10) * 100; const auto relative_duration = std::chrono::microseconds(relative_ticks_in_ms) + std::chrono::nanoseconds(relative_fraction_ns); return c.steady_now() + relative_duration; } const auto delay_seconds_since_1601 = delay_interval.QuadPart / HUNDRED_NANOSECONDS_IN_ONE_SECOND; const auto delay_fraction_ns = (delay_interval.QuadPart % HUNDRED_NANOSECONDS_IN_ONE_SECOND) * 100; const auto delay_seconds_since_1970 = delay_seconds_since_1601 - EPOCH_DIFFERENCE_1601_TO_1970_SECONDS; const auto target_time = std::chrono::system_clock::from_time_t(delay_seconds_since_1970) + std::chrono::nanoseconds(delay_fraction_ns); const auto now_system = c.system_now(); const auto duration_until_target = std::chrono::duration_cast(target_time - now_system); return c.steady_now() + duration_until_target; } KSYSTEM_TIME convert_to_ksystem_time(const std::chrono::system_clock::time_point& tp) { const auto duration = tp.time_since_epoch(); const auto ns_duration = std::chrono::duration_cast(duration); const auto total_ticks = ns_duration.count() / 100 + WINDOWS_EPOCH_DIFFERENCE; KSYSTEM_TIME time{}; time.LowPart = static_cast(total_ticks); time.High1Time = static_cast(total_ticks >> 32); time.High2Time = time.High1Time; return time; } void convert_to_ksystem_time(volatile KSYSTEM_TIME* dest, const std::chrono::system_clock::time_point& tp) { const auto time = convert_to_ksystem_time(tp); memcpy(const_cast(dest), &time, sizeof(*dest)); } std::chrono::system_clock::time_point convert_from_ksystem_time(const KSYSTEM_TIME& time) { auto totalTicks = (static_cast(time.High1Time) << 32) | time.LowPart; totalTicks -= WINDOWS_EPOCH_DIFFERENCE; const auto duration = std::chrono::system_clock::duration(totalTicks * 100); return std::chrono::system_clock::time_point(duration); } std::chrono::system_clock::time_point convert_from_ksystem_time(const volatile KSYSTEM_TIME& time) { return convert_from_ksystem_time(*const_cast(&time)); } #ifndef OS_WINDOWS using __time64_t = int64_t; #endif LARGE_INTEGER convert_unix_to_windows_time(const __time64_t unix_time) { LARGE_INTEGER windows_time{}; windows_time.QuadPart = (unix_time + EPOCH_DIFFERENCE_1601_TO_1970_SECONDS) * HUNDRED_NANOSECONDS_IN_ONE_SECOND; return windows_time; } }