add system time, clean up pci into pci.sys, clean up syscall names, fix USERAPC1 typo

This commit is contained in:
maksw committed 2026-06-11 18:11:59 +02:00
1 parent c1a291c4c9
commit e41bf6e2c0
64 files changed
+4514 -2220

No files matched your search

+143 -28
View File
@@ -80,7 +80,7 @@ static uint32_t WinProtectToSysVm(DWORD protect) {
}
}
static DWORD SysVmProtectToWin(uint32_t protect) {
static DWORD SysProtectVmToWin(uint32_t protect) {
switch (protect) {
case SYS_VM_NOACCESS: return PAGE_NOACCESS;
case SYS_VM_READ: return PAGE_READONLY;
@@ -98,6 +98,17 @@ typedef struct _FILETIME {
DWORD dwHighDateTime;
} FILETIME;
typedef struct _SYSTEMTIME {
unsigned short wYear;
unsigned short wMonth;
unsigned short wDayOfWeek;
unsigned short wDay;
unsigned short wHour;
unsigned short wMinute;
unsigned short wSecond;
unsigned short wMilliseconds;
} SYSTEMTIME;
typedef struct _WIN32_FIND_DATAA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
@@ -234,8 +245,8 @@ static void K32WriteConsoleSpan(const char* data, size_t length) {
static void K32DebugPrintA(const char* s) {
if (!s) return;
SYS_DEBUG_PRINT_REQUEST req = { SysSvFromCstr(s) };
SysDebugPrint(&req);
SYS_PRINT_DEBUG_REQUEST req = { SysSvFromCstr(s) };
SysPrintDebug(&req);
}
#define WIN32_TLS_SLOTS 64
@@ -431,7 +442,7 @@ __declspec(dllexport) void* VirtualAlloc(void* lpAddress, size_t dwSize,
size_t pages = (dwSize + 4095u) / 4096u;
void* base = NULL;
uint32_t flags = lpAddress ? SYS_VM_FLAG_FIXED : SYS_VM_FLAG_NONE;
uint32_t s = SysVmAlloc(lpAddress, pages, WinProtectToSysVm(flProtect), flags, &base);
uint32_t s = SysAllocVm(lpAddress, pages, WinProtectToSysVm(flProtect), flags, &base);
if (s != SYS_STATUS_SUCCESS) {
gLastError = (s == SYS_STATUS_NOT_FOUND || s == SYS_STATUS_INVALID_PARAMETER) ? 87 : 8;
return NULL;
@@ -442,7 +453,7 @@ __declspec(dllexport) void* VirtualAlloc(void* lpAddress, size_t dwSize,
__declspec(dllexport) BOOL VirtualFree(void* lpAddress, size_t dwSize, DWORD dwFreeType) {
(void)dwSize; (void)dwFreeType;
if (!lpAddress) return TRUE;
uint32_t s = SysVmFree(lpAddress);
uint32_t s = SysFreeVm(lpAddress);
if (s != SYS_STATUS_SUCCESS) { gLastError = 87; return FALSE; }
return TRUE;
}
@@ -452,10 +463,10 @@ __declspec(dllexport) BOOL VirtualProtect(void* lpAddress, size_t dwSize,
if (!lpAddress || !dwSize) { gLastError = 87; return FALSE; }
size_t pages = (dwSize + 4095u) / 4096u;
uint32_t oldSysProtect = 0;
uint32_t s = SysVmProtect(lpAddress, pages, WinProtectToSysVm(flNewProtect),
uint32_t s = SysProtectVm(lpAddress, pages, WinProtectToSysVm(flNewProtect),
lpflOldProtect ? &oldSysProtect : NULL);
if (s != SYS_STATUS_SUCCESS) { gLastError = 87; return FALSE; }
if (lpflOldProtect) *lpflOldProtect = SysVmProtectToWin(oldSysProtect);
if (lpflOldProtect) *lpflOldProtect = SysProtectVmToWin(oldSysProtect);
return TRUE;
}
@@ -468,13 +479,13 @@ __declspec(dllexport) size_t VirtualQuery(const void* lpAddress,
}
SYS_VM_REGION_INFO info;
uint32_t s = SysVmQuery((void*)lpAddress, &info);
uint32_t s = SysQueryVm((void*)lpAddress, &info);
if (s != SYS_STATUS_SUCCESS) {
gLastError = 87;
return 0;
}
DWORD protect = SysVmProtectToWin(info.Protect);
DWORD protect = SysProtectVmToWin(info.Protect);
lpBuffer->BaseAddress = info.Base;
lpBuffer->AllocationBase = info.Base;
lpBuffer->AllocationProtect = protect;
@@ -490,13 +501,13 @@ __declspec(dllexport) size_t VirtualQuery(const void* lpAddress,
// GetAsyncKeyState implementation over the canonical input key namespace.
__declspec(dllexport) SHORT GetAsyncKeyState(int vKey) {
if (vKey == 0x11) { // VK_CONTROL
return (SysKbIsKeyDown(INPUT_KEY_LEFT_CTRL) || SysKbIsKeyDown(INPUT_KEY_RIGHT_CTRL)) ? (SHORT)0x8000 : 0;
return (SysIsKeyDown(INPUT_KEY_LEFT_CTRL) || SysIsKeyDown(INPUT_KEY_RIGHT_CTRL)) ? (SHORT)0x8000 : 0;
}
if (vKey == 0x10) { // VK_SHIFT
return (SysKbIsKeyDown(INPUT_KEY_LEFT_SHIFT) || SysKbIsKeyDown(INPUT_KEY_RIGHT_SHIFT)) ? (SHORT)0x8000 : 0;
return (SysIsKeyDown(INPUT_KEY_LEFT_SHIFT) || SysIsKeyDown(INPUT_KEY_RIGHT_SHIFT)) ? (SHORT)0x8000 : 0;
}
if (vKey == 0x12) { // VK_MENU / ALT
return (SysKbIsKeyDown(INPUT_KEY_LEFT_ALT) || SysKbIsKeyDown(INPUT_KEY_RIGHT_ALT)) ? (SHORT)0x8000 : 0;
return (SysIsKeyDown(INPUT_KEY_LEFT_ALT) || SysIsKeyDown(INPUT_KEY_RIGHT_ALT)) ? (SHORT)0x8000 : 0;
}
static const struct { int vk; INPUT_KEY key; } vk_to_key[] = {
@@ -539,7 +550,7 @@ __declspec(dllexport) SHORT GetAsyncKeyState(int vKey) {
for (size_t i = 0; i < sizeof(vk_to_key) / sizeof(vk_to_key[0]); ++i) {
if (vk_to_key[i].vk == vKey) {
if (SysKbIsKeyDown(vk_to_key[i].key))
if (SysIsKeyDown(vk_to_key[i].key))
return (SHORT)0x8000;
break;
}
@@ -551,15 +562,15 @@ __declspec(dllexport) SHORT GetAsyncKeyState(int vKey) {
__declspec(dllexport) BOOL FlushConsoleInputBuffer(HANDLE hConsoleInput) {
(void)hConsoleInput;
// Drain the keyboard buffer by reading until empty
while (SysKbPoll()) {
(void)SysKbReadChar();
while (SysPollKeyboard()) {
(void)SysReadKeyboardChar();
}
return TRUE;
}
// !Made-up! clear console api.
__declspec(dllexport) BOOL ClearConsoleScreenBuffer(HANDLE hConsole) {
SysScreenClear(0x012456);
SysClearScreen(0x012456);
return TRUE;
}
@@ -1245,7 +1256,7 @@ __declspec(dllexport) HANDLE GetStdHandle(DWORD nStdHandle) {
}
// ReadConsoleA: blocking read of up to nNumberOfCharsToRead characters.
// Each character is read individually via SysKbReadChar so the caller can
// Each character is read individually via SysReadKeyboardChar so the caller can
// do its own line-editing (echo, backspace, etc.) one char at a time.
__declspec(dllexport) BOOL ReadConsoleA(HANDLE hConsoleInput,
void* lpBuffer,
@@ -1259,7 +1270,7 @@ __declspec(dllexport) BOOL ReadConsoleA(HANDLE hConsoleInput,
DWORD i = 0; // Notice we switched to a while loop
while (i < nNumberOfCharsToRead) {
char c = SysKbReadChar();
char c = SysReadKeyboardChar();
// Ignore unmapped keys (Shift, Ctrl, etc.)
if (c == 0) continue;
@@ -1390,6 +1401,41 @@ static void SplitFindPath(const char* searchPath,
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020UL
#define FILE_ATTRIBUTE_NORMAL 0x00000080UL
static int K32DirIsLeapYear(unsigned int year) {
return ((year % 4u) == 0u && (year % 100u) != 0u) || ((year % 400u) == 0u);
}
static unsigned int K32DirDaysInMonth(unsigned int year, unsigned int month) {
static const unsigned char days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (month < 1u || month > 12u) return 31u;
if (month == 2u && K32DirIsLeapYear(year)) return 29u;
return days[month - 1u];
}
static uint64_t K32DirCalendarToEpochSeconds(const SYS_SYSTEM_TIME* st) {
uint64_t days = 0;
for (unsigned int y = 1970u; y < st->Year; y++)
days += K32DirIsLeapYear(y) ? 366u : 365u;
for (unsigned int m = 1u; m < st->Month; m++)
days += K32DirDaysInMonth(st->Year, m);
days += (uint64_t)(st->Day - 1u);
return (((days * 24u) + st->Hour) * 60u + st->Minute) * 60u + st->Second;
}
static void K32DirStoreFileTime(FILETIME* ft, const SYS_SYSTEM_TIME* st) {
if (!ft || !st || !(st->Flags & SYS_TIME_FLAG_VALID) || st->Year < 1970u) {
if (ft) { ft->dwLowDateTime = 0; ft->dwHighDateTime = 0; }
return;
}
const uint64_t WINDOWS_EPOCH_BIAS_SECONDS = 11644473600ULL;
uint64_t epoch = st->EpochSeconds ? st->EpochSeconds : K32DirCalendarToEpochSeconds(st);
uint64_t value = (epoch + WINDOWS_EPOCH_BIAS_SECONDS) * 10000000ULL +
((uint64_t)st->Millisecond * 10000ULL) +
((uint64_t)st->Nanosecond / 100ULL);
ft->dwLowDateTime = (DWORD)(value & 0xFFFFFFFFULL);
ft->dwHighDateTime = (DWORD)(value >> 32);
}
static void KdirToFindData(const KDIR_ENTRY* ke, WIN32_FIND_DATAA* fd) {
// Zero the entire struct (covers all FILETIME and reserved fields)
unsigned char* p = (unsigned char*)fd;
@@ -1402,6 +1448,9 @@ static void KdirToFindData(const KDIR_ENTRY* ke, WIN32_FIND_DATAA* fd) {
fd->nFileSizeLow = ke->FileSize;
fd->nFileSizeHigh = 0;
K32DirStoreFileTime(&fd->ftCreationTime, &ke->CreateTime);
K32DirStoreFileTime(&fd->ftLastAccessTime, &ke->LastAccessTime);
K32DirStoreFileTime(&fd->ftLastWriteTime, &ke->LastWriteTime);
size_t nameLen = strlen(ke->Name);
if (nameLen >= MAX_PATH) nameLen = MAX_PATH - 1;
@@ -1687,19 +1736,85 @@ __declspec(dllexport) BOOL QueryPerformanceCounter(LARGE_INTEGER* lpPerformanceC
return TRUE;
}
static BOOL K32IsLeapYear(unsigned int year) {
return ((year % 4u) == 0u && (year % 100u) != 0u) || ((year % 400u) == 0u);
}
static unsigned int K32DaysInMonth(unsigned int year, unsigned int month) {
static const unsigned char days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2u && K32IsLeapYear(year)) return 29u;
if (month < 1u || month > 12u) return 0u;
return days[month - 1u];
}
static uint64_t K32CalendarToEpochSeconds(const SYSTEMTIME* st) {
uint64_t days = 0;
for (unsigned int y = 1970u; y < st->wYear; y++)
days += K32IsLeapYear(y) ? 366u : 365u;
for (unsigned int m = 1u; m < st->wMonth; m++)
days += K32DaysInMonth(st->wYear, m);
days += (uint64_t)(st->wDay - 1u);
return (((days * 24u) + st->wHour) * 60u + st->wMinute) * 60u + st->wSecond;
}
static uint64_t K32EpochToFileTime(uint64_t epochSeconds, uint32_t nanosecond) {
const uint64_t WINDOWS_EPOCH_BIAS_SECONDS = 11644473600ULL;
return (epochSeconds + WINDOWS_EPOCH_BIAS_SECONDS) * 10000000ULL +
((uint64_t)nanosecond / 100ULL);
}
static void K32StoreFileTime(FILETIME* ft, uint64_t value) {
ft->dwLowDateTime = (DWORD)(value & 0xFFFFFFFFULL);
ft->dwHighDateTime = (DWORD)(value >> 32);
}
__declspec(dllexport) void GetSystemTime(SYSTEMTIME* lpSystemTime) {
if (!lpSystemTime) return;
SYS_SYSTEM_TIME st;
if (SysGetSystemTime(&st) != SYS_STATUS_SUCCESS) {
memset(lpSystemTime, 0, sizeof(*lpSystemTime));
return;
}
lpSystemTime->wYear = st.Year;
lpSystemTime->wMonth = st.Month;
lpSystemTime->wDayOfWeek = st.DayOfWeek;
lpSystemTime->wDay = st.Day;
lpSystemTime->wHour = st.Hour;
lpSystemTime->wMinute = st.Minute;
lpSystemTime->wSecond = st.Second;
lpSystemTime->wMilliseconds = st.Millisecond;
}
__declspec(dllexport) BOOL SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime,
FILETIME* lpFileTime) {
if (!lpSystemTime || !lpFileTime) return FALSE;
if (lpSystemTime->wYear < 1970 || lpSystemTime->wMonth < 1 ||
lpSystemTime->wMonth > 12 || lpSystemTime->wDay < 1 ||
lpSystemTime->wDay > K32DaysInMonth(lpSystemTime->wYear, lpSystemTime->wMonth) ||
lpSystemTime->wHour > 23 || lpSystemTime->wMinute > 59 ||
lpSystemTime->wSecond > 59 || lpSystemTime->wMilliseconds > 999) {
return FALSE;
}
uint64_t ft = K32EpochToFileTime(K32CalendarToEpochSeconds(lpSystemTime),
(uint32_t)lpSystemTime->wMilliseconds * 1000000u);
K32StoreFileTime(lpFileTime, ft);
return TRUE;
}
__declspec(dllexport) void GetSystemTimeAsFileTime(void* lpSystemTimeAsFileTime) {
if (!lpSystemTimeAsFileTime) return;
// Baseline: 2024-01-01 00:00:00 UTC in 100-ns intervals
const unsigned long long BASELINE_FT = 133485408000000000ULL;
// SysGetTick() is in microseconds.
// 1 microsecond = 10 units of 100-nanoseconds.
unsigned long long now_us = SysGetTick();
unsigned long long ft = BASELINE_FT + (now_us * 10ULL);
// Copy the 64-bit value into the output buffer.
// We use memcpy to safely handle potential alignment issues with the void pointer.
SYS_SYSTEM_TIME st;
uint64_t ft;
if (SysGetSystemTime(&st) == SYS_STATUS_SUCCESS) {
ft = K32EpochToFileTime(st.EpochSeconds, st.Nanosecond);
} else {
const uint64_t FALLBACK_2024_01_01_FT = 133485408000000000ULL;
ft = FALLBACK_2024_01_01_FT + (SysGetTick() * 10ULL);
}
memcpy(lpSystemTimeAsFileTime, &ft, sizeof(ft));
}