mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-23 21:51:02 +00:00
Dynamically update KUSD system time
This commit is contained in:
@@ -19,6 +19,20 @@ inline void deserialize(utils::buffer_deserializer& buffer, std::chrono::steady_
|
||||
tp = time_point{duration{count}};
|
||||
}
|
||||
|
||||
inline void serialize(utils::buffer_serializer& buffer, const std::chrono::system_clock::time_point& tp)
|
||||
{
|
||||
buffer.write(tp.time_since_epoch().count());
|
||||
}
|
||||
|
||||
inline void deserialize(utils::buffer_deserializer& buffer, std::chrono::system_clock::time_point& tp)
|
||||
{
|
||||
using time_point = std::chrono::system_clock::time_point;
|
||||
using duration = time_point::duration;
|
||||
|
||||
const auto count = buffer.read<duration::rep>();
|
||||
tp = time_point{duration{count}};
|
||||
}
|
||||
|
||||
inline void serialize(utils::buffer_serializer& buffer, const std::filesystem::path& path)
|
||||
{
|
||||
buffer.write_string<wchar_t>(path.wstring());
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "kusd_mmio.hpp"
|
||||
#include "syscall_utils.hpp"
|
||||
#include "windows_emulator.hpp"
|
||||
|
||||
#include <address_utils.hpp>
|
||||
@@ -103,6 +104,7 @@ kusd_mmio::kusd_mmio(windows_emulator& win_emu, const bool use_relative_time, co
|
||||
, win_emu_(&win_emu)
|
||||
{
|
||||
setup_kusd(this->kusd_, use_relative_time);
|
||||
this->start_time_ = convert_from_ksystem_time(this->kusd_.SystemTime);
|
||||
|
||||
if (perform_registration)
|
||||
{
|
||||
@@ -118,6 +120,7 @@ kusd_mmio::~kusd_mmio()
|
||||
kusd_mmio::kusd_mmio(kusd_mmio&& obj) // throws!
|
||||
: use_relative_time_(obj.use_relative_time_)
|
||||
, win_emu_(obj.win_emu_)
|
||||
, start_time_(obj.start_time_)
|
||||
{
|
||||
memcpy(&this->kusd_, &obj.kusd_, sizeof(this->kusd_));
|
||||
|
||||
@@ -137,12 +140,14 @@ void kusd_mmio::serialize(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
buffer.write(this->use_relative_time_);
|
||||
buffer.write(this->kusd_);
|
||||
buffer.write(this->start_time_);
|
||||
}
|
||||
|
||||
void kusd_mmio::deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.read(this->use_relative_time_);
|
||||
buffer.read(this->kusd_);
|
||||
buffer.read(this->start_time_);
|
||||
|
||||
this->register_mmio();
|
||||
}
|
||||
@@ -185,7 +190,22 @@ void kusd_mmio::write(const uint64_t /*addr*/, const size_t /*size*/, const uint
|
||||
|
||||
void kusd_mmio::update()
|
||||
{
|
||||
// TODO
|
||||
auto time = this->start_time_;
|
||||
|
||||
if (this->use_relative_time_)
|
||||
{
|
||||
const auto passed_time = this->win_emu_->process().executed_instructions;
|
||||
const auto clock_frequency = this->kusd_.QpcFrequency;
|
||||
|
||||
using duration = std::chrono::system_clock::duration;
|
||||
time += duration(passed_time * duration::period::den / clock_frequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
time = std::chrono::system_clock::now();
|
||||
}
|
||||
|
||||
convert_to_ksystem_time(&this->kusd_.SystemTime, time);
|
||||
}
|
||||
|
||||
void kusd_mmio::register_mmio()
|
||||
|
||||
@@ -39,6 +39,7 @@ private:
|
||||
bool use_relative_time_{};
|
||||
windows_emulator* win_emu_{};
|
||||
KUSER_SHARED_DATA kusd_{};
|
||||
std::chrono::system_clock::time_point start_time_{};
|
||||
|
||||
uint64_t read(uint64_t addr, size_t size);
|
||||
void write(uint64_t addr, size_t size, uint64_t data);
|
||||
|
||||
@@ -175,11 +175,12 @@ void write_attribute(emulator& emu, const PS_ATTRIBUTE& attribute, const T& valu
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto HUNDRED_NANOSECONDS_IN_ONE_SECOND = 10000000LL;
|
||||
constexpr auto EPOCH_DIFFERENCE_1601_TO_1970_SECONDS = 11644473600LL;
|
||||
constexpr auto WINDOWS_EPOCH_DIFFERENCE = EPOCH_DIFFERENCE_1601_TO_1970_SECONDS * HUNDRED_NANOSECONDS_IN_ONE_SECOND;
|
||||
|
||||
inline std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(const LARGE_INTEGER delay_interval)
|
||||
{
|
||||
constexpr auto HUNDRED_NANOSECONDS_IN_ONE_SECOND = 10000000LL;
|
||||
constexpr auto EPOCH_DIFFERENCE_1601_TO_1970_SECONDS = 11644473600LL;
|
||||
|
||||
if (delay_interval.QuadPart <= 0)
|
||||
{
|
||||
const auto relative_time = -delay_interval.QuadPart;
|
||||
@@ -207,3 +208,38 @@ inline std::chrono::steady_clock::time_point convert_delay_interval_to_time_poin
|
||||
|
||||
return std::chrono::steady_clock::now() + duration_until_target;
|
||||
}
|
||||
|
||||
inline 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<std::chrono::nanoseconds>(duration);
|
||||
|
||||
const auto total_ticks = ns_duration.count() / 100 + WINDOWS_EPOCH_DIFFERENCE;
|
||||
|
||||
KSYSTEM_TIME time{};
|
||||
time.LowPart = static_cast<uint32_t>(total_ticks);
|
||||
time.High1Time = static_cast<int32_t>(total_ticks >> 32);
|
||||
time.High2Time = time.High1Time;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
inline 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<KSYSTEM_TIME*>(dest), &time, sizeof(*dest));
|
||||
}
|
||||
|
||||
inline std::chrono::system_clock::time_point convert_from_ksystem_time(const KSYSTEM_TIME& time)
|
||||
{
|
||||
auto totalTicks = (static_cast<int64_t>(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);
|
||||
}
|
||||
|
||||
inline std::chrono::system_clock::time_point convert_from_ksystem_time(const volatile KSYSTEM_TIME& time)
|
||||
{
|
||||
return convert_from_ksystem_time(*const_cast<const KSYSTEM_TIME*>(&time));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user