add system time, clean up pci into pci.sys, clean up syscall names, fix USERAPC1 typo
This commit is contained in:
1 parent
c1a291c4c9
commit
e41bf6e2c0
64 files changed
+4514
-2220
No files matched your search
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user