mirror of
https://github.com/decompals/wibo.git
synced 2025-12-12 06:45:05 +00:00
262 lines
7.7 KiB
C++
262 lines
7.7 KiB
C++
#include "sysinfoapi.h"
|
|
|
|
#include "common.h"
|
|
#include "context.h"
|
|
#include "errors.h"
|
|
#include "internal.h"
|
|
#include "ntdll.h"
|
|
#include "timeutil.h"
|
|
|
|
#include <cstring>
|
|
#include <ctime>
|
|
#include <sys/time.h>
|
|
|
|
namespace {
|
|
|
|
constexpr WORD PROCESSOR_ARCHITECTURE_INTEL = 0;
|
|
constexpr DWORD PROCESSOR_INTEL_PENTIUM = 586;
|
|
|
|
constexpr uint64_t kUnixTimeZero = 11644473600ULL * 10000000ULL;
|
|
constexpr DWORD kMajorVersion = 6;
|
|
constexpr DWORD kMinorVersion = 2;
|
|
constexpr DWORD kBuildNumber = 0;
|
|
|
|
DWORD_PTR computeSystemProcessorMask(unsigned int cpuCount) {
|
|
const auto maskWidth = static_cast<unsigned int>(sizeof(DWORD_PTR) * 8);
|
|
if (cpuCount >= maskWidth) {
|
|
return static_cast<DWORD_PTR>(~static_cast<DWORD_PTR>(0));
|
|
}
|
|
DWORD_PTR mask = (static_cast<DWORD_PTR>(1) << cpuCount) - 1;
|
|
return mask == 0 ? 1 : mask;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
namespace kernel32 {
|
|
|
|
void WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
|
|
HOST_CONTEXT_GUARD();
|
|
DEBUG_LOG("GetSystemInfo(%p)\n", lpSystemInfo);
|
|
if (!lpSystemInfo) {
|
|
return;
|
|
}
|
|
|
|
std::memset(lpSystemInfo, 0, sizeof(*lpSystemInfo));
|
|
lpSystemInfo->wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
|
|
lpSystemInfo->dwOemId = lpSystemInfo->wProcessorArchitecture;
|
|
lpSystemInfo->dwProcessorType = PROCESSOR_INTEL_PENTIUM;
|
|
lpSystemInfo->wProcessorLevel = 6; // Pentium
|
|
|
|
long pageSize = sysconf(_SC_PAGESIZE);
|
|
if (pageSize <= 0) {
|
|
pageSize = 4096;
|
|
}
|
|
lpSystemInfo->dwPageSize = static_cast<DWORD>(pageSize);
|
|
|
|
lpSystemInfo->lpMinimumApplicationAddress = toGuestPtr(reinterpret_cast<void *>(0x00010000));
|
|
#ifdef _WIN64
|
|
lpSystemInfo->lpMaximumApplicationAddress = toGuestPtr(reinterpret_cast<void *>(0x00007FFFFFFEFFFFull));
|
|
#else
|
|
lpSystemInfo->lpMaximumApplicationAddress = toGuestPtr(reinterpret_cast<void *>(0x7FFEFFFF));
|
|
#endif
|
|
|
|
unsigned int cpuCount = 1;
|
|
long reported = sysconf(_SC_NPROCESSORS_ONLN);
|
|
if (reported > 0) {
|
|
cpuCount = static_cast<unsigned int>(reported);
|
|
}
|
|
lpSystemInfo->dwNumberOfProcessors = cpuCount;
|
|
lpSystemInfo->dwActiveProcessorMask = computeSystemProcessorMask(cpuCount);
|
|
|
|
lpSystemInfo->dwAllocationGranularity = 0x10000;
|
|
}
|
|
|
|
void WINAPI GetSystemTime(LPSYSTEMTIME lpSystemTime) {
|
|
HOST_CONTEXT_GUARD();
|
|
DEBUG_LOG("GetSystemTime(%p)\n", lpSystemTime);
|
|
if (!lpSystemTime) {
|
|
return;
|
|
}
|
|
|
|
time_t now = time(nullptr);
|
|
struct tm tmUtc{};
|
|
#if defined(_GNU_SOURCE) || defined(__APPLE__)
|
|
gmtime_r(&now, &tmUtc);
|
|
#else
|
|
struct tm *tmp = gmtime(&now);
|
|
if (!tmp) {
|
|
return;
|
|
}
|
|
tmUtc = *tmp;
|
|
#endif
|
|
|
|
lpSystemTime->wYear = static_cast<WORD>(tmUtc.tm_year + 1900);
|
|
lpSystemTime->wMonth = static_cast<WORD>(tmUtc.tm_mon + 1);
|
|
lpSystemTime->wDayOfWeek = static_cast<WORD>(tmUtc.tm_wday);
|
|
lpSystemTime->wDay = static_cast<WORD>(tmUtc.tm_mday);
|
|
lpSystemTime->wHour = static_cast<WORD>(tmUtc.tm_hour);
|
|
lpSystemTime->wMinute = static_cast<WORD>(tmUtc.tm_min);
|
|
lpSystemTime->wSecond = static_cast<WORD>(tmUtc.tm_sec);
|
|
lpSystemTime->wMilliseconds = 0;
|
|
}
|
|
|
|
void WINAPI GetLocalTime(LPSYSTEMTIME lpSystemTime) {
|
|
HOST_CONTEXT_GUARD();
|
|
DEBUG_LOG("GetLocalTime(%p)\n", lpSystemTime);
|
|
if (!lpSystemTime) {
|
|
return;
|
|
}
|
|
|
|
time_t now = time(nullptr);
|
|
struct tm tmLocal{};
|
|
#if defined(_GNU_SOURCE) || defined(__APPLE__)
|
|
localtime_r(&now, &tmLocal);
|
|
#else
|
|
struct tm *tmp = localtime(&now);
|
|
if (!tmp) {
|
|
return;
|
|
}
|
|
tmLocal = *tmp;
|
|
#endif
|
|
|
|
lpSystemTime->wYear = static_cast<WORD>(tmLocal.tm_year + 1900);
|
|
lpSystemTime->wMonth = static_cast<WORD>(tmLocal.tm_mon + 1);
|
|
lpSystemTime->wDayOfWeek = static_cast<WORD>(tmLocal.tm_wday);
|
|
lpSystemTime->wDay = static_cast<WORD>(tmLocal.tm_mday);
|
|
lpSystemTime->wHour = static_cast<WORD>(tmLocal.tm_hour);
|
|
lpSystemTime->wMinute = static_cast<WORD>(tmLocal.tm_min);
|
|
lpSystemTime->wSecond = static_cast<WORD>(tmLocal.tm_sec);
|
|
lpSystemTime->wMilliseconds = 0;
|
|
}
|
|
|
|
void WINAPI GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) {
|
|
HOST_CONTEXT_GUARD();
|
|
DEBUG_LOG("GetSystemTimeAsFileTime(%p)\n", lpSystemTimeAsFileTime);
|
|
if (!lpSystemTimeAsFileTime) {
|
|
return;
|
|
}
|
|
|
|
#if defined(CLOCK_REALTIME)
|
|
struct timespec ts{};
|
|
if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
|
|
uint64_t ticks = kUnixTimeZero;
|
|
ticks += static_cast<uint64_t>(ts.tv_sec) * 10000000ULL;
|
|
ticks += static_cast<uint64_t>(ts.tv_nsec) / 100ULL;
|
|
*lpSystemTimeAsFileTime = fileTimeFromDuration(ticks);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
struct timeval tv{};
|
|
if (gettimeofday(&tv, nullptr) == 0) {
|
|
uint64_t ticks = kUnixTimeZero;
|
|
ticks += static_cast<uint64_t>(tv.tv_sec) * 10000000ULL;
|
|
ticks += static_cast<uint64_t>(tv.tv_usec) * 10ULL;
|
|
*lpSystemTimeAsFileTime = fileTimeFromDuration(ticks);
|
|
return;
|
|
}
|
|
|
|
const FILETIME fallback = {static_cast<DWORD>(kUnixTimeZero & 0xFFFFFFFFULL),
|
|
static_cast<DWORD>(kUnixTimeZero >> 32)};
|
|
*lpSystemTimeAsFileTime = fallback;
|
|
}
|
|
|
|
DWORD WINAPI GetTickCount() {
|
|
HOST_CONTEXT_GUARD();
|
|
DEBUG_LOG("GetTickCount()\n");
|
|
#if defined(CLOCK_MONOTONIC)
|
|
struct timespec ts{};
|
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
|
|
uint64_t milliseconds =
|
|
static_cast<uint64_t>(ts.tv_sec) * 1000ULL + static_cast<uint64_t>(ts.tv_nsec) / 1000000ULL;
|
|
DWORD result = static_cast<DWORD>(milliseconds & 0xFFFFFFFFULL);
|
|
DEBUG_LOG(" -> %u\n", result);
|
|
return result;
|
|
}
|
|
#endif
|
|
struct timeval tv{};
|
|
if (gettimeofday(&tv, nullptr) == 0) {
|
|
uint64_t milliseconds =
|
|
static_cast<uint64_t>(tv.tv_sec) * 1000ULL + static_cast<uint64_t>(tv.tv_usec) / 1000ULL;
|
|
DWORD result = static_cast<DWORD>(milliseconds & 0xFFFFFFFFULL);
|
|
DEBUG_LOG(" -> %u\n", result);
|
|
return result;
|
|
}
|
|
DEBUG_LOG(" -> 0\n");
|
|
return 0;
|
|
}
|
|
|
|
DWORD WINAPI GetVersion() {
|
|
HOST_CONTEXT_GUARD();
|
|
DEBUG_LOG("GetVersion()\n");
|
|
return kMajorVersion | (kMinorVersion << 8) | (5 << 16) | (kBuildNumber << 24);
|
|
}
|
|
|
|
BOOL WINAPI GetVersionExA(LPOSVERSIONINFOA lpVersionInformation) {
|
|
HOST_CONTEXT_GUARD();
|
|
DEBUG_LOG("GetVersionExA(%p)\n", lpVersionInformation);
|
|
if (!lpVersionInformation) {
|
|
setLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD size = lpVersionInformation->dwOSVersionInfoSize;
|
|
if (size < sizeof(OSVERSIONINFOA)) {
|
|
setLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD requestSize = (size >= sizeof(OSVERSIONINFOEXA)) ? sizeof(OSVERSIONINFOEXW) : sizeof(OSVERSIONINFOW);
|
|
OSVERSIONINFOEXW wideInfo{};
|
|
wideInfo.dwOSVersionInfoSize = requestSize;
|
|
NTSTATUS status = ntdll::RtlGetVersion(reinterpret_cast<PRTL_OSVERSIONINFOW>(&wideInfo));
|
|
if (status != STATUS_SUCCESS) {
|
|
setLastError(wibo::winErrorFromNtStatus(status));
|
|
return FALSE;
|
|
}
|
|
|
|
std::memset(lpVersionInformation, 0, size);
|
|
lpVersionInformation->dwOSVersionInfoSize = size;
|
|
lpVersionInformation->dwMajorVersion = wideInfo.dwMajorVersion;
|
|
lpVersionInformation->dwMinorVersion = wideInfo.dwMinorVersion;
|
|
lpVersionInformation->dwBuildNumber = wideInfo.dwBuildNumber;
|
|
lpVersionInformation->dwPlatformId = wideInfo.dwPlatformId;
|
|
|
|
if (size >= sizeof(OSVERSIONINFOEXA)) {
|
|
auto extended = reinterpret_cast<OSVERSIONINFOEXA *>(lpVersionInformation);
|
|
extended->wServicePackMajor = wideInfo.wServicePackMajor;
|
|
extended->wServicePackMinor = wideInfo.wServicePackMinor;
|
|
extended->wSuiteMask = wideInfo.wSuiteMask;
|
|
extended->wProductType = wideInfo.wProductType;
|
|
extended->wReserved = wideInfo.wReserved;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI GetVersionExW(LPOSVERSIONINFOW lpVersionInformation) {
|
|
HOST_CONTEXT_GUARD();
|
|
DEBUG_LOG("GetVersionExW(%p)\n", lpVersionInformation);
|
|
if (!lpVersionInformation) {
|
|
setLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD size = lpVersionInformation->dwOSVersionInfoSize;
|
|
if (size < sizeof(OSVERSIONINFOW)) {
|
|
setLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
NTSTATUS status = ntdll::RtlGetVersion(reinterpret_cast<PRTL_OSVERSIONINFOW>(lpVersionInformation));
|
|
if (status != STATUS_SUCCESS) {
|
|
setLastError(wibo::winErrorFromNtStatus(status));
|
|
return FALSE;
|
|
}
|
|
|
|
lpVersionInformation->dwOSVersionInfoSize = size;
|
|
return TRUE;
|
|
}
|
|
|
|
} // namespace kernel32
|