// KvcDrv.cpp #include "kvcDrv.h" #include "common.h" #include // IOCTL command codes for KVC driver communication constexpr DWORD RTC_IOCTL_MEMORY_READ = 0x80002048; constexpr DWORD RTC_IOCTL_MEMORY_WRITE = 0x8000204c; kvc::kvc() = default; kvc::~kvc() { Cleanup(); } // Force cleanup for atomic driver operations - critical for stability void kvc::Cleanup() noexcept { DEBUG(L"kvc::Cleanup() called"); if (m_deviceHandle) { DEBUG(L"Closing device handle..."); // Force the handle to close FlushFileBuffers(m_deviceHandle.get()); m_deviceHandle.reset(); // This should close the handle } m_deviceName.clear(); DEBUG(L"kvc cleanup completed"); } bool kvc::IsConnected() const noexcept { return m_deviceHandle && m_deviceHandle.get() != INVALID_HANDLE_VALUE; } // Driver connection establishment with device path bool kvc::Initialize() noexcept { if (IsConnected()) { return true; } if (m_deviceName.empty()) { m_deviceName = L"\\\\.\\" + GetServiceName(); } if (!InitDynamicAPIs()) return false; // SIMPLE DEVICE OPEN - without test operations HANDLE rawHandle = g_pCreateFileW(m_deviceName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); if (rawHandle == INVALID_HANDLE_VALUE) { return false; // Silently fail - this is normal when the driver is not running } m_deviceHandle = UniqueHandle(rawHandle); return true; } // Memory read operations with type safety std::optional kvc::Read8(ULONG_PTR address) noexcept { auto value = Read32(address); if (!value.has_value()) return std::nullopt; return static_cast(value.value() & 0xff); } std::optional kvc::Read16(ULONG_PTR address) noexcept { auto value = Read32(address); if (!value.has_value()) return std::nullopt; return static_cast(value.value() & 0xffff); } std::optional kvc::Read32(ULONG_PTR address) noexcept { return Read(address, sizeof(DWORD)); } std::optional kvc::Read64(ULONG_PTR address) noexcept { auto low = Read32(address); auto high = Read32(address + 4); if (!low || !high) return std::nullopt; return (static_cast(high.value()) << 32) | low.value(); } std::optional kvc::ReadPtr(ULONG_PTR address) noexcept { #ifdef _WIN64 auto value = Read64(address); if (!value.has_value()) return std::nullopt; return static_cast(value.value()); #else auto value = Read32(address); if (!value.has_value()) return std::nullopt; return static_cast(value.value()); #endif } // Memory write operations with type safety bool kvc::Write8(ULONG_PTR address, BYTE value) noexcept { return Write(address, sizeof(value), value); } bool kvc::Write16(ULONG_PTR address, WORD value) noexcept { return Write(address, sizeof(value), value); } bool kvc::Write32(ULONG_PTR address, DWORD value) noexcept { return Write(address, sizeof(value), value); } bool kvc::Write64(ULONG_PTR address, DWORD64 value) noexcept { DWORD low = static_cast(value & 0xffffffff); DWORD high = static_cast((value >> 32) & 0xffffffff); return Write32(address, low) && Write32(address + 4, high); } // Low-level driver communication via IOCTL std::optional kvc::Read(ULONG_PTR address, DWORD valueSize) noexcept { RTC_MEMORY_READ memoryRead{}; memoryRead.Address = address; memoryRead.Size = valueSize; if (!Initialize()) return std::nullopt; DWORD bytesReturned = 0; if (!DeviceIoControl(m_deviceHandle.get(), RTC_IOCTL_MEMORY_READ, &memoryRead, sizeof(memoryRead), &memoryRead, sizeof(memoryRead), &bytesReturned, nullptr)) return std::nullopt; return memoryRead.Value; } bool kvc::Write(ULONG_PTR address, DWORD valueSize, DWORD value) noexcept { RTC_MEMORY_WRITE memoryWrite{}; memoryWrite.Address = address; memoryWrite.Size = valueSize; memoryWrite.Value = value; if (!Initialize()) return false; DWORD bytesReturned = 0; return DeviceIoControl(m_deviceHandle.get(), RTC_IOCTL_MEMORY_WRITE, &memoryWrite, sizeof(memoryWrite), &memoryWrite, sizeof(memoryWrite), &bytesReturned, nullptr); }