completely redesign how user mode memory is allocated, fix a few smp and scheduler bugs, terminating a process now terminates the process, telemetry, optimize text editor, new font, new color scheme
This commit is contained in:
1 parent
27b31f62b6
commit
325149006c
45 files changed
+2091
-760
No files matched your search
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
@@ -28,7 +29,7 @@ static void doom_print_wrapper(const char* msg)
|
||||
// ---------------------------------------------------------------------------
|
||||
static void* doom_malloc_wrapper(int size)
|
||||
{
|
||||
void* p = SysAlloc(size);
|
||||
void* p = malloc(size);
|
||||
if (!p) SysExitProcess(1);
|
||||
return p;
|
||||
}
|
||||
@@ -37,7 +38,7 @@ static void doom_free_wrapper(void* ptr)
|
||||
{
|
||||
if (!ptr) return;
|
||||
|
||||
SysFree(ptr);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -62,7 +63,7 @@ static void* doom_open_wrapper(const char* path, const char* mode)
|
||||
}
|
||||
if (result != 0) return 0;
|
||||
|
||||
DOOM_FILE_HANDLE* f = (DOOM_FILE_HANDLE*)SysAlloc(sizeof(DOOM_FILE_HANDLE));
|
||||
DOOM_FILE_HANDLE* f = (DOOM_FILE_HANDLE*)malloc(sizeof(DOOM_FILE_HANDLE));
|
||||
if (!f) {
|
||||
SysCloseHandle(handle);
|
||||
return 0;
|
||||
@@ -79,7 +80,7 @@ static void doom_close_wrapper(void* handle)
|
||||
if (!handle) return;
|
||||
DOOM_FILE_HANDLE* f = (DOOM_FILE_HANDLE*)handle;
|
||||
SysCloseHandle(f->Handle);
|
||||
SysFree(f);
|
||||
free(f);
|
||||
}
|
||||
|
||||
static int doom_read_wrapper(void* handle, void* buf, int count)
|
||||
|
||||
+75
-18
@@ -18,6 +18,8 @@
|
||||
#define MAX_LINE 256
|
||||
#define PATH_MAX2 260
|
||||
#define MSG_MAX 160
|
||||
#define MAX_SCREEN_COLS 256
|
||||
#define MAX_SCREEN_ROWS 128
|
||||
|
||||
#define COL_BG 0x000000u
|
||||
#define COL_FG 0xC8C8C8u
|
||||
@@ -61,8 +63,55 @@ static bool gQuitArmed = false;
|
||||
static char gFilename[PATH_MAX2] = "untitled.txt";
|
||||
static char gMessage[MSG_MAX] = "ready";
|
||||
|
||||
typedef struct SCREEN_CELL {
|
||||
char c;
|
||||
uint32_t fg;
|
||||
uint32_t bg;
|
||||
} SCREEN_CELL;
|
||||
|
||||
static SCREEN_CELL gScreenCache[MAX_SCREEN_COLS * MAX_SCREEN_ROWS];
|
||||
static bool gScreenCacheValid = false;
|
||||
|
||||
static void invalidate_screen_cache(void) {
|
||||
gScreenCacheValid = false;
|
||||
}
|
||||
|
||||
static void update_screen_size(void) {
|
||||
int pxW = 0, pxH = 0;
|
||||
int oldCols = gCols;
|
||||
int oldRows = gRows;
|
||||
|
||||
if (SysScreenGetSize(&pxW, &pxH) == 0 && pxW > 0 && pxH > 0) {
|
||||
gCols = pxW / GLYPH_W;
|
||||
gRows = pxH / GLYPH_H;
|
||||
|
||||
if (gCols < 20) gCols = 20;
|
||||
if (gRows < 5) gRows = 5;
|
||||
if (gCols > MAX_SCREEN_COLS) gCols = MAX_SCREEN_COLS;
|
||||
if (gRows > MAX_SCREEN_ROWS) gRows = MAX_SCREEN_ROWS;
|
||||
}
|
||||
|
||||
if (gCols != oldCols || gRows != oldRows)
|
||||
invalidate_screen_cache();
|
||||
}
|
||||
|
||||
static void put_cell(int col, int row, char c, uint32_t fg, uint32_t bg) {
|
||||
SysScreenPutChar(c ? c : ' ', col * GLYPH_W, row * GLYPH_H, fg, bg);
|
||||
if (col < 0 || row < 0 || col >= gCols || row >= gRows)
|
||||
return;
|
||||
|
||||
if (!c) c = ' ';
|
||||
|
||||
if (col < MAX_SCREEN_COLS && row < MAX_SCREEN_ROWS) {
|
||||
SCREEN_CELL* cell = &gScreenCache[row * MAX_SCREEN_COLS + col];
|
||||
if (gScreenCacheValid && cell->c == c && cell->fg == fg && cell->bg == bg)
|
||||
return;
|
||||
|
||||
cell->c = c;
|
||||
cell->fg = fg;
|
||||
cell->bg = bg;
|
||||
}
|
||||
|
||||
SysScreenPutChar(c, col * GLYPH_W, row * GLYPH_H, fg, bg);
|
||||
}
|
||||
|
||||
static void clear_row(int row, uint32_t bg) {
|
||||
@@ -151,13 +200,7 @@ static void ensure_visible(void) {
|
||||
}
|
||||
|
||||
static void render(void) {
|
||||
int pxW = 0, pxH = 0;
|
||||
if (SysScreenGetSize(&pxW, &pxH) == 0 && pxW > 0 && pxH > 0) {
|
||||
gCols = pxW / GLYPH_W;
|
||||
gRows = pxH / GLYPH_H;
|
||||
if (gCols < 20) gCols = 20;
|
||||
if (gRows < 5) gRows = 5;
|
||||
}
|
||||
update_screen_size();
|
||||
|
||||
clamp_cursor();
|
||||
ensure_visible();
|
||||
@@ -172,28 +215,40 @@ static void render(void) {
|
||||
append_str(status, sizeof(status), &p, ", Col ");
|
||||
append_u32(status, sizeof(status), &p, (uint32_t)(gCx + 1));
|
||||
|
||||
clear_row(0, COL_STATUS);
|
||||
draw_text(0, 0, status, COL_STATUSF, COL_STATUS);
|
||||
size_t statusLen = p;
|
||||
for (int sx = 0; sx < gCols; sx++) {
|
||||
char c = ((size_t)sx < statusLen) ? status[sx] : ' ';
|
||||
put_cell(sx, 0, c, COL_STATUSF, COL_STATUS);
|
||||
}
|
||||
|
||||
int textRows = gRows - 2;
|
||||
for (int sy = 0; sy < textRows; sy++) {
|
||||
int row = sy + 1;
|
||||
int li = gTop + sy;
|
||||
clear_row(row, COL_BG);
|
||||
if (li >= gLineCount) continue;
|
||||
|
||||
LINE* ln = &gLines[li];
|
||||
for (int sx = 0; sx < gCols; sx++) {
|
||||
int ci = gLeft + sx;
|
||||
char c = (ci < ln->len) ? ln->text[ci] : ' ';
|
||||
bool atCursor = (li == gCy && ci == gCx);
|
||||
char c = ' ';
|
||||
bool atCursor = false;
|
||||
|
||||
if (li < gLineCount) {
|
||||
LINE* ln = &gLines[li];
|
||||
c = (ci < ln->len) ? ln->text[ci] : ' ';
|
||||
atCursor = (li == gCy && ci == gCx);
|
||||
}
|
||||
|
||||
put_cell(sx, row, c, atCursor ? COL_CURSORF : COL_FG,
|
||||
atCursor ? COL_CURSOR : COL_BG);
|
||||
}
|
||||
}
|
||||
|
||||
clear_row(gRows - 1, COL_STATUS);
|
||||
draw_text(0, gRows - 1, gMessage, COL_STATUSF, COL_STATUS);
|
||||
size_t messageLen = strlen(gMessage);
|
||||
for (int sx = 0; sx < gCols; sx++) {
|
||||
char c = ((size_t)sx < messageLen) ? gMessage[sx] : ' ';
|
||||
put_cell(sx, gRows - 1, c, COL_STATUSF, COL_STATUS);
|
||||
}
|
||||
|
||||
gScreenCacheValid = true;
|
||||
}
|
||||
|
||||
static void insert_char_at_cursor(char c) {
|
||||
@@ -481,8 +536,10 @@ int main(void) {
|
||||
parse_filename_from_cmdline();
|
||||
load_file();
|
||||
SysScreenClear(COL_BG);
|
||||
invalidate_screen_cache();
|
||||
editor_loop();
|
||||
SysScreenClear(COL_BG);
|
||||
SysScreenClear(0x012456);
|
||||
invalidate_screen_cache();
|
||||
print("edit: goodbye\n");
|
||||
SysExitProcess(0);
|
||||
return 0;
|
||||
|
||||
@@ -95,6 +95,7 @@ static void cmd_help() {
|
||||
print("Available commands:\n"
|
||||
" help - Show this list\n"
|
||||
" mem - Show memory usage\n"
|
||||
" stats - Show scheduler/CPU/PMM telemetry\n"
|
||||
" ps - List running process IDs\n"
|
||||
" dir [path] - List directory contents\n"
|
||||
" cd <path> - Change directory\n"
|
||||
@@ -110,6 +111,96 @@ static void printSizeKiB(uint64_t bytes) {
|
||||
print(" KiB");
|
||||
}
|
||||
|
||||
|
||||
static void printPagesKiB(uint64_t pages) {
|
||||
printUInt64(pages * 4u);
|
||||
print(" KiB");
|
||||
}
|
||||
|
||||
static void printCpuFlags(uint32_t flags) {
|
||||
if (flags & SYS_CPU_FLAG_BSP) print("bsp ");
|
||||
if (flags & SYS_CPU_FLAG_ONLINE) print("online ");
|
||||
if (flags & SYS_CPU_FLAG_PARKED) print("parked ");
|
||||
if (flags & SYS_CPU_FLAG_PRIMARY) print("primary ");
|
||||
if (flags & SYS_CPU_FLAG_STARTED) print("started ");
|
||||
if (flags & SYS_CPU_FLAG_PRESENT) print("present ");
|
||||
}
|
||||
|
||||
static void cmd_stats(void) {
|
||||
SYS_SCHEDULER_STATS sched;
|
||||
SYS_PMM_STATS pmm;
|
||||
SYS_CPU_STATS cpu;
|
||||
uint32_t status;
|
||||
|
||||
status = SysQueryKernelStats(SYS_KERNEL_STATS_SCHEDULER, &sched, sizeof(sched), NULL);
|
||||
if (status != 0) {
|
||||
print("stats: scheduler query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
status = SysQueryKernelStats(SYS_KERNEL_STATS_PMM, &pmm, sizeof(pmm), NULL);
|
||||
if (status != 0) {
|
||||
print("stats: pmm query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
status = SysQueryKernelStats(SYS_KERNEL_STATS_CPU, &cpu, sizeof(cpu), NULL);
|
||||
if (status != 0) {
|
||||
print("stats: cpu query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
print("Scheduler:\n");
|
||||
print(" ticks: "); printUInt64(sched.Ticks); print("\n");
|
||||
print(" context switches: "); printUInt64(sched.ContextSwitches); print("\n");
|
||||
print(" quantum expires: "); printUInt64(sched.QuantumExpirations); print("\n");
|
||||
print(" priority preempts: "); printUInt64(sched.PriorityPreemptions); print("\n");
|
||||
print(" idle selections: "); printUInt64(sched.IdleSelections); print("\n");
|
||||
print(" keep-current: "); printUInt64(sched.KeepCurrentDecisions); print("\n");
|
||||
print(" demotions: "); printUInt64(sched.Demotions); print("\n");
|
||||
print(" aging promotions: "); printUInt64(sched.AgingPromotions); print("\n");
|
||||
print(" voluntary blocks: "); printUInt64(sched.VoluntaryBlocks); print("\n");
|
||||
print(" SMT deferrals: "); printUInt64(sched.SmtSiblingDeferrals); print("\n");
|
||||
print(" SMT primary pokes: "); printUInt64(sched.SmtPrimaryPokes); print("\n");
|
||||
|
||||
print("CPUs:\n");
|
||||
uint32_t n = cpu.CpuCount;
|
||||
if (n > SYS_KERNEL_STATS_MAX_CPUS)
|
||||
n = SYS_KERNEL_STATS_MAX_CPUS;
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
SYS_CPU_STAT* c = &cpu.Cpu[i];
|
||||
print(" cpu"); printUInt(c->CpuIndex);
|
||||
print(" lapic="); printUInt(c->LapicId);
|
||||
print(" tid="); printUInt(c->CurrentTid);
|
||||
print(" ticks="); printUInt64(c->SchedulerTicks);
|
||||
print(" switches="); printUInt64(c->ContextSwitches);
|
||||
print(" flags="); printCpuFlags(c->Flags);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
print("Physical memory:\n");
|
||||
print(" total: "); printPagesKiB(pmm.TotalFrames); print(" (frames="); printUInt64(pmm.TotalFrames); print(")\n");
|
||||
print(" used: "); printPagesKiB(pmm.UsedFrames); print(" (frames="); printUInt64(pmm.UsedFrames); print(")\n");
|
||||
print(" free: "); printPagesKiB(pmm.FreeFrames); print(" (frames="); printUInt64(pmm.FreeFrames); print(")\n");
|
||||
print(" largest free run: "); printPagesKiB(pmm.LargestFreeRun); print(" (frames="); printUInt64(pmm.LargestFreeRun); print(")\n");
|
||||
print(" free runs: "); printUInt64(pmm.FreeRunCount); print("\n");
|
||||
print(" run histogram:\n");
|
||||
print(" 1: "); printUInt64(pmm.FreeRunHistogram[0]); print("\n");
|
||||
print(" 2-3: "); printUInt64(pmm.FreeRunHistogram[1]); print("\n");
|
||||
print(" 4-7: "); printUInt64(pmm.FreeRunHistogram[2]); print("\n");
|
||||
print(" 8-15: "); printUInt64(pmm.FreeRunHistogram[3]); print("\n");
|
||||
print(" 16-63: "); printUInt64(pmm.FreeRunHistogram[4]); print("\n");
|
||||
print(" 64-255: "); printUInt64(pmm.FreeRunHistogram[5]); print("\n");
|
||||
print(" 256-1023: "); printUInt64(pmm.FreeRunHistogram[6]); print("\n");
|
||||
print(" 1024+: "); printUInt64(pmm.FreeRunHistogram[7]); print("\n");
|
||||
}
|
||||
|
||||
static void cmd_mem(void) {
|
||||
SYS_MEMORY_STATUS st;
|
||||
if (SysGetMemoryStatus(&st) != 0) {
|
||||
@@ -240,7 +331,7 @@ static int runCommand(const char* cmd) {
|
||||
if (!cmd || *cmd == '\0') return 0;
|
||||
if (strcmp(cmd, "exit") == 0) return 1;
|
||||
if (strcmp(cmd, "help") == 0) { cmd_help(); return 0; }
|
||||
if (strcmp(cmd, "clear") == 0) { SysScreenClear(0); return 0; }
|
||||
if (strcmp(cmd, "clear") == 0) { SysScreenClear(0x012456); return 0; }
|
||||
if (strncmp(cmd, "crash", 5) == 0) {
|
||||
// Check the sub-option trailing "crash " (offset 6)
|
||||
if (strcmp(cmd + 6, "void") == 0) {
|
||||
@@ -280,6 +371,7 @@ static int runCommand(const char* cmd) {
|
||||
}
|
||||
}
|
||||
if (strcmp(cmd, "mem") == 0) { cmd_mem(); return 0; }
|
||||
if (strcmp(cmd, "stats") == 0 || strcmp(cmd, "telemetry") == 0) { cmd_stats(); return 0; }
|
||||
if (strcmp(cmd, "ps") == 0) { cmd_ps(); return 0; }
|
||||
if (strcmp(cmd, "dir") == 0) { cmd_dir("."); return 0; }
|
||||
if (strncmp(cmd, "dir ", 4) == 0) { cmd_dir(cmd + 4); return 0; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// posix_dir.c - chdir, getcwd, opendir, readdir, closedir
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
#include <stdlib.h>
|
||||
#include "posix.h"
|
||||
#include "posix_path.h"
|
||||
|
||||
@@ -38,8 +39,8 @@ __declspec(dllexport) DIR* opendir(const char* path) {
|
||||
uint32_t s = SysOpenDir(&req);
|
||||
if (s != 0) { errno = ENOENT; return (DIR*)0; }
|
||||
|
||||
// Allocate DIR on the kernel heap (SysAlloc) so it outlives the stack.
|
||||
DIR* d = (DIR*)SysAlloc(sizeof(DIR));
|
||||
// Allocate DIR on the kernel heap (malloc) so it outlives the stack.
|
||||
DIR* d = (DIR*)malloc(sizeof(DIR));
|
||||
if (!d) { SysCloseHandle(kh); errno = ENOMEM; return (DIR*)0; }
|
||||
d->KHandle = kh;
|
||||
d->Valid = false;
|
||||
@@ -64,6 +65,6 @@ __declspec(dllexport) struct dirent* readdir(DIR* d) {
|
||||
__declspec(dllexport) int closedir(DIR* d) {
|
||||
if (!d) { errno = EBADF; return -1; }
|
||||
SysCloseHandle(d->KHandle);
|
||||
SysFree(d);
|
||||
free(d);
|
||||
return 0;
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "posix_path.h"
|
||||
|
||||
__declspec(dllexport) void clearscreen(void) {
|
||||
SysScreenClear(0x00000000);
|
||||
SysScreenClear(0x012456);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void clearkeyboard(void) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// posix_socket.c - POSIX-ish socket wrappers over native Sys* sockets.
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
@@ -324,7 +325,7 @@ __declspec(dllexport) int getsockopt(int fd, int level, int optname, void* optva
|
||||
__declspec(dllexport) int poll(struct pollfd* fds, nfds_t nfds, int timeout) {
|
||||
if (!fds || nfds == 0 || nfds > 64) { errno = EINVAL; return -1; }
|
||||
|
||||
SYS_POLLFD* kfds = (SYS_POLLFD*)SysAlloc(sizeof(SYS_POLLFD) * nfds);
|
||||
SYS_POLLFD* kfds = (SYS_POLLFD*)malloc(sizeof(SYS_POLLFD) * nfds);
|
||||
if (!kfds) { errno = ENOMEM; return -1; }
|
||||
|
||||
for (nfds_t i = 0; i < nfds; i++) {
|
||||
@@ -348,7 +349,7 @@ __declspec(dllexport) int poll(struct pollfd* fds, nfds_t nfds, int timeout) {
|
||||
uint32_t timeoutMs = timeout < 0 ? SYS_POLL_TIMEOUT_INFINITE : (uint32_t)timeout;
|
||||
uint32_t s = SysPoll(kfds, nfds, timeoutMs, &ready);
|
||||
if (s != 0) {
|
||||
SysFree(kfds);
|
||||
free(kfds);
|
||||
errno = PosixStatusToErrno(s);
|
||||
return -1;
|
||||
}
|
||||
@@ -365,7 +366,7 @@ __declspec(dllexport) int poll(struct pollfd* fds, nfds_t nfds, int timeout) {
|
||||
if (re) out++;
|
||||
}
|
||||
|
||||
SysFree(kfds);
|
||||
free(kfds);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -446,7 +447,7 @@ __declspec(dllexport) int getaddrinfo(const char* node, const char* service,
|
||||
a.Port = service ? ParsePort(service) : 0;
|
||||
|
||||
size_t total = sizeof(struct addrinfo) + sizeof(struct sockaddr_in);
|
||||
struct addrinfo* ai = (struct addrinfo*)SysAlloc(total);
|
||||
struct addrinfo* ai = (struct addrinfo*)malloc(total);
|
||||
if (!ai) return ENOMEM;
|
||||
memset(ai, 0, total);
|
||||
|
||||
@@ -467,5 +468,5 @@ __declspec(dllexport) int getaddrinfo(const char* node, const char* service,
|
||||
}
|
||||
|
||||
__declspec(dllexport) void freeaddrinfo(struct addrinfo* res) {
|
||||
if (res) SysFree(res);
|
||||
if (res) free(res);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
// posix_thread.c - pthread_create, pthread_join, pthread_exit, pthread_mutex_*
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <ntlite/syscall.h>
|
||||
#include "posix.h"
|
||||
|
||||
@@ -56,7 +57,7 @@ static void PthreadTrampoline(uintptr_t raw) {
|
||||
PTHREAD_SLOT* slot = PthreadSlotFind(pid, tid);
|
||||
if (!slot) slot = PthreadSlotAlloc(pid, tid);
|
||||
|
||||
SysFree(tr);
|
||||
free(tr);
|
||||
|
||||
void* retval = fn(arg);
|
||||
|
||||
@@ -76,7 +77,7 @@ __declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* att
|
||||
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
|
||||
PTHREAD_TRAMP* tr = (PTHREAD_TRAMP*)SysAlloc(sizeof(PTHREAD_TRAMP));
|
||||
PTHREAD_TRAMP* tr = (PTHREAD_TRAMP*)malloc(sizeof(PTHREAD_TRAMP));
|
||||
if (!tr) return ENOMEM;
|
||||
tr->Fn = fn;
|
||||
tr->Arg = arg;
|
||||
@@ -86,7 +87,7 @@ __declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* att
|
||||
uint32_t s = SysCreateThread((uint64_t)PthreadTrampoline,
|
||||
(uint64_t)tr, 1 /*PriorityNormal*/, &tid);
|
||||
if (s != 0) {
|
||||
SysFree(tr);
|
||||
free(tr);
|
||||
return EAGAIN;
|
||||
}
|
||||
// The trampoline allocates the retval slot itself after it knows its real
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// gdi32.c
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
#if defined(__SSE2__) || defined(_M_X64) || defined(_M_IX86)
|
||||
@@ -92,14 +93,14 @@ __declspec(dllexport) int StretchDIBits(
|
||||
// Only reallocate if the new size is LARGER than what we already have
|
||||
int requiredPixels = DestWidth * DestHeight;
|
||||
if (requiredPixels > currentDestCapacity) {
|
||||
SysFree(destBuffer);
|
||||
destBuffer = (uint32_t*)SysAlloc(requiredPixels * sizeof(uint32_t));
|
||||
free(destBuffer);
|
||||
destBuffer = (uint32_t*)malloc(requiredPixels * sizeof(uint32_t));
|
||||
currentDestCapacity = requiredPixels;
|
||||
}
|
||||
|
||||
if (DestWidth > currentXMapCapacity) {
|
||||
SysFree(srcX_map);
|
||||
srcX_map = (int*)SysAlloc(DestWidth * sizeof(int));
|
||||
free(srcX_map);
|
||||
srcX_map = (int*)malloc(DestWidth * sizeof(int));
|
||||
currentXMapCapacity = DestWidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// HANDLE_TO_KH / KH_TO_HANDLE do that conversion in one place.
|
||||
// - INVALID_HANDLE_VALUE maps to kernel handle 0 (the always-invalid slot).
|
||||
// - HeapAlloc / HeapFree / HeapReAlloc ignore the HANDLE heap argument and
|
||||
// always use the single kernel user-heap. This is fine: we don't expose
|
||||
// always use the single user-mode heap. This is fine: we don't expose
|
||||
// multiple heaps, and NULL is a legal (no-op) heap argument under Win32.
|
||||
// - Win32 per-thread state lives behind SYS_TEB::SubsystemData so the native
|
||||
// TEB ABI stays subsystem-neutral.
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
@@ -66,6 +67,31 @@ typedef struct _MEMORY_BASIC_INFORMATION {
|
||||
DWORD Type;
|
||||
} MEMORY_BASIC_INFORMATION;
|
||||
|
||||
static uint32_t WinProtectToSysVm(DWORD protect) {
|
||||
switch (protect) {
|
||||
case PAGE_NOACCESS: return SYS_VM_NOACCESS;
|
||||
case PAGE_READONLY: return SYS_VM_READ;
|
||||
case PAGE_READWRITE:
|
||||
case PAGE_WRITECOPY: return SYS_VM_READWRITE;
|
||||
case PAGE_EXECUTE: return SYS_VM_EXECUTE;
|
||||
case PAGE_EXECUTE_READ: return SYS_VM_EXECUTE_READ;
|
||||
case PAGE_EXECUTE_READWRITE: return SYS_VM_EXECUTE_READWRITE;
|
||||
default: return SYS_VM_READWRITE;
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD SysVmProtectToWin(uint32_t protect) {
|
||||
switch (protect) {
|
||||
case SYS_VM_NOACCESS: return PAGE_NOACCESS;
|
||||
case SYS_VM_READ: return PAGE_READONLY;
|
||||
case SYS_VM_READWRITE: return PAGE_READWRITE;
|
||||
case SYS_VM_EXECUTE: return PAGE_EXECUTE;
|
||||
case SYS_VM_EXECUTE_READ: return PAGE_EXECUTE_READ;
|
||||
case SYS_VM_EXECUTE_READWRITE: return PAGE_EXECUTE_READWRITE;
|
||||
default: return PAGE_NOACCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// File-find structures
|
||||
typedef struct _FILETIME {
|
||||
DWORD dwLowDateTime;
|
||||
@@ -228,7 +254,7 @@ static WIN32_THREAD_ENV* K32ThreadEnv(void) {
|
||||
|
||||
WIN32_THREAD_ENV* env = (WIN32_THREAD_ENV*)teb->SubsystemData;
|
||||
if (!env) {
|
||||
env = (WIN32_THREAD_ENV*)SysAlloc(sizeof(WIN32_THREAD_ENV));
|
||||
env = (WIN32_THREAD_ENV*)malloc(sizeof(WIN32_THREAD_ENV));
|
||||
if (!env) return &gFallbackThreadEnv;
|
||||
memset(env, 0, sizeof(*env));
|
||||
teb->SubsystemData = env;
|
||||
@@ -363,28 +389,27 @@ __declspec(dllexport) uint64_t GetTickCount64(void) {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Memory (heap argument is ignored - single kernel user-heap)
|
||||
// Memory (heap argument is ignored - single user-mode heap)
|
||||
// ---------------------------------------------------------------------------
|
||||
__declspec(dllexport) void* HeapAlloc(void* heap, DWORD flags, size_t size) {
|
||||
(void)heap;
|
||||
(void)heap; (void)flags;
|
||||
if (!size) return NULL;
|
||||
void* ptr = SysAlloc(size);
|
||||
void* ptr = malloc(size);
|
||||
if (!ptr) gLastError = 8; // ERROR_NOT_ENOUGH_MEMORY
|
||||
return ptr;
|
||||
}
|
||||
|
||||
__declspec(dllexport) BOOL HeapFree(void* heap, DWORD flags, void* ptr) {
|
||||
(void)heap; (void)flags;
|
||||
// Win32's HeapFree doesn't need the size; we pass 0 and the kernel's
|
||||
// allocator handles it (the block header carries the size).
|
||||
if (ptr) SysFree(ptr);
|
||||
// Win32's HeapFree doesn't need the size; we pass 0 and the user-mode heap carries the block size.
|
||||
if (ptr) free(ptr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
__declspec(dllexport) void* HeapReAlloc(void* heap, DWORD flags,
|
||||
void* ptr, size_t size) {
|
||||
(void)heap; (void)flags;
|
||||
void* newptr = SysRealloc(ptr, size);
|
||||
void* newptr = realloc(ptr, size);
|
||||
if (!newptr && size) gLastError = 8;
|
||||
return newptr;
|
||||
}
|
||||
@@ -400,23 +425,37 @@ __declspec(dllexport) void* GetProcessHeap(void) {
|
||||
// ---------------------------------------------------------------------------
|
||||
__declspec(dllexport) void* VirtualAlloc(void* lpAddress, size_t dwSize,
|
||||
DWORD flAllocationType, DWORD flProtect) {
|
||||
(void)lpAddress; (void)flAllocationType; (void)flProtect;
|
||||
(void)flAllocationType;
|
||||
if (!dwSize) return NULL;
|
||||
void* ptr = SysAlloc(dwSize);
|
||||
if (!ptr) gLastError = 8; // ERROR_NOT_ENOUGH_MEMORY
|
||||
return ptr;
|
||||
|
||||
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);
|
||||
if (s != SYS_STATUS_SUCCESS) {
|
||||
gLastError = (s == SYS_STATUS_NOT_FOUND || s == SYS_STATUS_INVALID_PARAMETER) ? 87 : 8;
|
||||
return NULL;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
__declspec(dllexport) BOOL VirtualFree(void* lpAddress, size_t dwSize, DWORD dwFreeType) {
|
||||
(void)dwSize; (void)dwFreeType;
|
||||
if (lpAddress) SysFree(lpAddress);
|
||||
if (!lpAddress) return TRUE;
|
||||
uint32_t s = SysVmFree(lpAddress);
|
||||
if (s != SYS_STATUS_SUCCESS) { gLastError = 87; return FALSE; }
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
__declspec(dllexport) BOOL VirtualProtect(void* lpAddress, size_t dwSize,
|
||||
DWORD flNewProtect, DWORD* lpflOldProtect) {
|
||||
(void)lpAddress; (void)dwSize; (void)flNewProtect;
|
||||
if (lpflOldProtect) *lpflOldProtect = PAGE_EXECUTE_READWRITE;
|
||||
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),
|
||||
lpflOldProtect ? &oldSysProtect : NULL);
|
||||
if (s != SYS_STATUS_SUCCESS) { gLastError = 87; return FALSE; }
|
||||
if (lpflOldProtect) *lpflOldProtect = SysVmProtectToWin(oldSysProtect);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -427,13 +466,21 @@ __declspec(dllexport) size_t VirtualQuery(const void* lpAddress,
|
||||
gLastError = 87; // ERROR_INVALID_PARAMETER
|
||||
return 0;
|
||||
}
|
||||
uintptr_t base = (uintptr_t)lpAddress & ~(uintptr_t)0xFFF;
|
||||
lpBuffer->BaseAddress = (void*)base;
|
||||
lpBuffer->AllocationBase = (void*)base;
|
||||
lpBuffer->AllocationProtect = PAGE_EXECUTE_READWRITE;
|
||||
lpBuffer->RegionSize = 0x1000;
|
||||
|
||||
SYS_VM_REGION_INFO info;
|
||||
uint32_t s = SysVmQuery((void*)lpAddress, &info);
|
||||
if (s != SYS_STATUS_SUCCESS) {
|
||||
gLastError = 87;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD protect = SysVmProtectToWin(info.Protect);
|
||||
lpBuffer->BaseAddress = info.Base;
|
||||
lpBuffer->AllocationBase = info.Base;
|
||||
lpBuffer->AllocationProtect = protect;
|
||||
lpBuffer->RegionSize = info.PageCount * 4096u;
|
||||
lpBuffer->State = MEM_COMMIT;
|
||||
lpBuffer->Protect = PAGE_EXECUTE_READWRITE;
|
||||
lpBuffer->Protect = protect;
|
||||
lpBuffer->Type = MEM_PRIVATE;
|
||||
return sizeof(MEMORY_BASIC_INFORMATION);
|
||||
}
|
||||
@@ -512,7 +559,7 @@ __declspec(dllexport) BOOL FlushConsoleInputBuffer(HANDLE hConsoleInput) {
|
||||
|
||||
// !Made-up! clear console api.
|
||||
__declspec(dllexport) BOOL ClearConsoleScreenBuffer(HANDLE hConsole) {
|
||||
SysScreenClear(0x00000000);
|
||||
SysScreenClear(0x012456);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// No COM infrastructure at this stage; all functions fail gracefully.
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -65,7 +66,7 @@ __declspec(dllexport) HRESULT CoCreateInstance(const GUID* clsid, IUnknown* oute
|
||||
// Memory
|
||||
// ---------------------------------------------------------------------------
|
||||
__declspec(dllexport) void CoTaskMemFree(void* pv) {
|
||||
if (pv) SysFree(pv);
|
||||
if (pv) free(pv);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
// heap.c - user-mode page-backed heap
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
#define USER_HEAP_PAGE_SIZE 4096u
|
||||
#define USER_HEAP_MIN_PAGES 16u
|
||||
#define USER_HEAP_ALIGN 16u
|
||||
#define USER_HEAP_MAGIC 0x48424C4Bu /* KLBH */
|
||||
|
||||
/*
|
||||
* Keep the mask pointer-sized. A 32-bit unsigned mask truncates high VA bits.
|
||||
*/
|
||||
#define ALIGN_UP(v, a) (((v) + ((uintptr_t)(a) - 1)) & ~((uintptr_t)(a) - 1))
|
||||
|
||||
typedef struct HEAP_BLOCK {
|
||||
uint32_t Magic;
|
||||
uint32_t Free;
|
||||
size_t Size;
|
||||
struct HEAP_BLOCK* Prev;
|
||||
struct HEAP_BLOCK* Next;
|
||||
} HEAP_BLOCK;
|
||||
|
||||
typedef struct HEAP_SEGMENT {
|
||||
struct HEAP_SEGMENT* Prev;
|
||||
struct HEAP_SEGMENT* Next;
|
||||
size_t PageCount;
|
||||
size_t Size;
|
||||
HEAP_BLOCK* First;
|
||||
} HEAP_SEGMENT;
|
||||
|
||||
static volatile long gHeapLock;
|
||||
static HEAP_SEGMENT* gSegments;
|
||||
|
||||
static void HeapLock(void) {
|
||||
while (_InterlockedCompareExchange(&gHeapLock, 1, 0) != 0)
|
||||
_mm_pause();
|
||||
_ReadWriteBarrier();
|
||||
}
|
||||
|
||||
static void HeapUnlock(void) {
|
||||
_ReadWriteBarrier();
|
||||
_InterlockedExchange(&gHeapLock, 0);
|
||||
}
|
||||
|
||||
static size_t AlignSize(size_t size) {
|
||||
return ALIGN_UP(size ? size : 1, USER_HEAP_ALIGN);
|
||||
}
|
||||
|
||||
static void* BlockPayload(HEAP_BLOCK* block) {
|
||||
return (void*)((uint8_t*)block + sizeof(HEAP_BLOCK));
|
||||
}
|
||||
|
||||
static HEAP_BLOCK* PayloadBlock(void* ptr) {
|
||||
return (HEAP_BLOCK*)((uint8_t*)ptr - sizeof(HEAP_BLOCK));
|
||||
}
|
||||
|
||||
static HEAP_SEGMENT* SegmentForPointer(void* ptr) {
|
||||
uintptr_t p = (uintptr_t)ptr;
|
||||
for (HEAP_SEGMENT* seg = gSegments; seg; seg = seg->Next) {
|
||||
uintptr_t base = (uintptr_t)seg;
|
||||
uintptr_t end = base + seg->Size;
|
||||
if (p > base && p < end)
|
||||
return seg;
|
||||
}
|
||||
return (HEAP_SEGMENT*)0;
|
||||
}
|
||||
|
||||
static void SplitBlock(HEAP_BLOCK* block, size_t size) {
|
||||
size_t aligned = AlignSize(size);
|
||||
if (block->Size < aligned + sizeof(HEAP_BLOCK) + USER_HEAP_ALIGN)
|
||||
return;
|
||||
|
||||
HEAP_BLOCK* tail = (HEAP_BLOCK*)((uint8_t*)BlockPayload(block) + aligned);
|
||||
tail->Magic = USER_HEAP_MAGIC;
|
||||
tail->Free = 1;
|
||||
tail->Size = block->Size - aligned - sizeof(HEAP_BLOCK);
|
||||
tail->Prev = block;
|
||||
tail->Next = block->Next;
|
||||
if (tail->Next) tail->Next->Prev = tail;
|
||||
|
||||
block->Size = aligned;
|
||||
block->Next = tail;
|
||||
}
|
||||
|
||||
static void CoalesceBlock(HEAP_BLOCK* block) {
|
||||
if (block->Next && block->Next->Magic == USER_HEAP_MAGIC && block->Next->Free) {
|
||||
HEAP_BLOCK* next = block->Next;
|
||||
block->Size += sizeof(HEAP_BLOCK) + next->Size;
|
||||
block->Next = next->Next;
|
||||
if (block->Next) block->Next->Prev = block;
|
||||
}
|
||||
|
||||
if (block->Prev && block->Prev->Magic == USER_HEAP_MAGIC && block->Prev->Free) {
|
||||
HEAP_BLOCK* prev = block->Prev;
|
||||
prev->Size += sizeof(HEAP_BLOCK) + block->Size;
|
||||
prev->Next = block->Next;
|
||||
if (prev->Next) prev->Next->Prev = prev;
|
||||
}
|
||||
}
|
||||
|
||||
static HEAP_SEGMENT* AddSegment(size_t payloadSize) {
|
||||
size_t need = sizeof(HEAP_SEGMENT) + sizeof(HEAP_BLOCK) + AlignSize(payloadSize);
|
||||
size_t pages = (need + USER_HEAP_PAGE_SIZE - 1) / USER_HEAP_PAGE_SIZE;
|
||||
if (pages < USER_HEAP_MIN_PAGES) pages = USER_HEAP_MIN_PAGES;
|
||||
|
||||
void* base = 0;
|
||||
uint32_t s = SysVmAlloc(0, pages, SYS_VM_READWRITE, SYS_VM_FLAG_NONE, &base);
|
||||
if (s != SYS_STATUS_SUCCESS || !base)
|
||||
return (HEAP_SEGMENT*)0;
|
||||
|
||||
HEAP_SEGMENT* seg = (HEAP_SEGMENT*)base;
|
||||
seg->Prev = 0;
|
||||
seg->Next = gSegments;
|
||||
if (gSegments) gSegments->Prev = seg;
|
||||
gSegments = seg;
|
||||
seg->PageCount = pages;
|
||||
seg->Size = pages * USER_HEAP_PAGE_SIZE;
|
||||
|
||||
uintptr_t blockAddr = ALIGN_UP((uintptr_t)(seg + 1), USER_HEAP_ALIGN);
|
||||
HEAP_BLOCK* block = (HEAP_BLOCK*)blockAddr;
|
||||
block->Magic = USER_HEAP_MAGIC;
|
||||
block->Free = 1;
|
||||
block->Size = seg->Size - (blockAddr - (uintptr_t)seg) - sizeof(HEAP_BLOCK);
|
||||
block->Prev = 0;
|
||||
block->Next = 0;
|
||||
seg->First = block;
|
||||
return seg;
|
||||
}
|
||||
|
||||
static void RemoveSegmentIfEmpty(HEAP_SEGMENT* seg) {
|
||||
if (!seg || !seg->First || !seg->First->Free || seg->First->Prev || seg->First->Next)
|
||||
return;
|
||||
|
||||
if (seg->Prev) seg->Prev->Next = seg->Next;
|
||||
else gSegments = seg->Next;
|
||||
if (seg->Next) seg->Next->Prev = seg->Prev;
|
||||
|
||||
SysVmFree(seg);
|
||||
}
|
||||
|
||||
void* _malloc(size_t size) {
|
||||
if (!size) return 0;
|
||||
size = AlignSize(size);
|
||||
|
||||
HeapLock();
|
||||
for (;;) {
|
||||
for (HEAP_SEGMENT* seg = gSegments; seg; seg = seg->Next) {
|
||||
for (HEAP_BLOCK* block = seg->First; block; block = block->Next) {
|
||||
if (block->Magic == USER_HEAP_MAGIC && block->Free && block->Size >= size) {
|
||||
SplitBlock(block, size);
|
||||
block->Free = 0;
|
||||
void* out = BlockPayload(block);
|
||||
HeapUnlock();
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!AddSegment(size)) {
|
||||
HeapUnlock();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _free(void* ptr) {
|
||||
if (!ptr) return;
|
||||
|
||||
HeapLock();
|
||||
HEAP_SEGMENT* seg = SegmentForPointer(ptr);
|
||||
if (!seg) {
|
||||
HeapUnlock();
|
||||
return;
|
||||
}
|
||||
|
||||
HEAP_BLOCK* block = PayloadBlock(ptr);
|
||||
if (block->Magic != USER_HEAP_MAGIC || block->Free) {
|
||||
HeapUnlock();
|
||||
return;
|
||||
}
|
||||
|
||||
block->Free = 1;
|
||||
CoalesceBlock(block);
|
||||
RemoveSegmentIfEmpty(seg);
|
||||
HeapUnlock();
|
||||
}
|
||||
|
||||
void* _calloc(size_t count, size_t size) {
|
||||
if (count && size > ((size_t)-1) / count)
|
||||
return 0;
|
||||
size_t total = count * size;
|
||||
void* ptr = _malloc(total);
|
||||
if (ptr) memset(ptr, 0, total);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* _realloc(void* ptr, size_t newSize) {
|
||||
if (!ptr) return _malloc(newSize);
|
||||
if (!newSize) {
|
||||
_free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HeapLock();
|
||||
HEAP_BLOCK* block = PayloadBlock(ptr);
|
||||
if (block->Magic != USER_HEAP_MAGIC || block->Free) {
|
||||
HeapUnlock();
|
||||
return 0;
|
||||
}
|
||||
size_t oldSize = block->Size;
|
||||
if (oldSize >= newSize) {
|
||||
SplitBlock(block, newSize);
|
||||
HeapUnlock();
|
||||
return ptr;
|
||||
}
|
||||
HeapUnlock();
|
||||
|
||||
void* newPtr = _malloc(newSize);
|
||||
if (!newPtr) return 0;
|
||||
memcpy(newPtr, ptr, oldSize);
|
||||
_free(ptr);
|
||||
return newPtr;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// heap_exports.c - public CRT allocator names
|
||||
// Intentionally includes nothing. MSVC/UCRT headers declare malloc/free with
|
||||
// compiler attributes that conflict with /Gz in this freestanding build.
|
||||
// Keep the real heap implementation in heap.c under private names and expose
|
||||
// only these tiny forwarding thunks here.
|
||||
|
||||
#ifdef USER_HEAP_EXPORTS
|
||||
#define HEAP_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define HEAP_EXPORT
|
||||
#endif
|
||||
|
||||
typedef unsigned __int64 size_t;
|
||||
|
||||
void* _malloc(size_t size);
|
||||
void _free(void* ptr);
|
||||
void* _calloc(size_t count, size_t size);
|
||||
void* _realloc(void* ptr, size_t size);
|
||||
|
||||
HEAP_EXPORT void* malloc(size_t size) {
|
||||
return _malloc(size);
|
||||
}
|
||||
|
||||
HEAP_EXPORT void free(void* ptr) {
|
||||
_free(ptr);
|
||||
}
|
||||
|
||||
HEAP_EXPORT void* calloc(size_t count, size_t size) {
|
||||
return _calloc(count, size);
|
||||
}
|
||||
|
||||
HEAP_EXPORT void* realloc(void* ptr, size_t size) {
|
||||
return _realloc(ptr, size);
|
||||
}
|
||||
@@ -1,94 +1,96 @@
|
||||
; syscall_nr.inc
|
||||
|
||||
SYS_EXIT_PROCESS EQU 0
|
||||
SYS_EXIT_THREAD EQU 1
|
||||
SYS_CREATE_PROCESS EQU 2
|
||||
SYS_WAIT_FOR_PROCESS EQU 3
|
||||
SYS_GET_PROCESS_EXIT_CODE EQU 4
|
||||
SYS_KILL_PROCESS EQU 5
|
||||
SYS_GET_PROCESS_LIST EQU 6
|
||||
SYS_GET_PROCESS_PID EQU 7
|
||||
SYS_CREATE_THREAD EQU 8
|
||||
SYS_WAIT_THREAD EQU 9
|
||||
SYS_GET_CURRENT_TID EQU 10
|
||||
SYS_GET_CURRENT_PID EQU 11
|
||||
SYS_SET_THREAD_PRIORITY EQU 12
|
||||
SYS_YIELD EQU 13
|
||||
SYS_SLEEP EQU 14
|
||||
SYS_SET_USER_APC_DISPATCHER EQU 15
|
||||
SYS_APC_RETURN EQU 16
|
||||
SYS_ALLOC EQU 17
|
||||
SYS_FREE EQU 18
|
||||
SYS_REALLOC EQU 19
|
||||
SYS_CLOSE_HANDLE EQU 20
|
||||
SYS_MUTEX_CREATE EQU 21
|
||||
SYS_MUTEX_ACQUIRE EQU 22
|
||||
SYS_MUTEX_TRY_ACQUIRE EQU 23
|
||||
SYS_MUTEX_RELEASE EQU 24
|
||||
SYS_SEM_CREATE EQU 25
|
||||
SYS_SEM_WAIT EQU 26
|
||||
SYS_SEM_TRY_WAIT EQU 27
|
||||
SYS_SEM_SIGNAL EQU 28
|
||||
SYS_EVENT_CREATE EQU 29
|
||||
SYS_EVENT_SIGNAL EQU 30
|
||||
SYS_EVENT_CLEAR EQU 31
|
||||
SYS_EVENT_WAIT EQU 32
|
||||
SYS_QUEUE_CREATE EQU 33
|
||||
SYS_QUEUE_SEND EQU 34
|
||||
SYS_QUEUE_RECV EQU 35
|
||||
SYS_PUBLISH_QUEUE EQU 36
|
||||
SYS_OPEN_NAMED_QUEUE EQU 37
|
||||
SYS_QUEUE_DUPLICATE EQU 38
|
||||
SYS_NAMED_QUEUE_OWNER_PID EQU 39
|
||||
SYS_OPEN_FILE EQU 40
|
||||
SYS_CREATE_FILE EQU 41
|
||||
SYS_READ_FILE EQU 42
|
||||
SYS_WRITE_FILE EQU 43
|
||||
SYS_READ_FILE_ASYNC EQU 44
|
||||
SYS_WRITE_FILE_ASYNC EQU 45
|
||||
SYS_CANCEL_IO EQU 46
|
||||
SYS_SEEK_FILE EQU 47
|
||||
SYS_GET_FILE_POS EQU 48
|
||||
SYS_GET_FILE_SIZE EQU 49
|
||||
SYS_TRUNCATE_FILE EQU 50
|
||||
SYS_DELETE_FILE EQU 51
|
||||
SYS_RENAME_FILE EQU 52
|
||||
SYS_OPEN_DIR EQU 53
|
||||
SYS_READ_DIR EQU 54
|
||||
SYS_CREATE_DIR EQU 55
|
||||
SYS_REMOVE_DIR EQU 56
|
||||
SYS_SET_CWD EQU 57
|
||||
SYS_GET_CWD EQU 58
|
||||
SYS_WRITE_CONSOLE EQU 59
|
||||
SYS_SCREEN_BLIT EQU 60
|
||||
SYS_SCREEN_CLEAR EQU 61
|
||||
SYS_SCREEN_GET_SIZE EQU 62
|
||||
SYS_SCREEN_PUT_CHAR EQU 63
|
||||
SYS_KB_POLL EQU 64
|
||||
SYS_KB_IS_KEY_DOWN EQU 65
|
||||
SYS_KB_READ_CHAR EQU 66
|
||||
SYS_KB_READ_KEY EQU 67
|
||||
SYS_KB_GET_MODIFIERS EQU 68
|
||||
SYS_MOUSE_POLL EQU 69
|
||||
SYS_MOUSE_READ EQU 70
|
||||
SYS_MOUSE_GET_POS EQU 71
|
||||
SYS_GET_TICK EQU 72
|
||||
SYS_DEBUG_PRINT EQU 73
|
||||
SYS_QUERY_TRAP_FRAME EQU 74
|
||||
SYS_SOCKET EQU 75
|
||||
SYS_BIND EQU 76
|
||||
SYS_LISTEN EQU 77
|
||||
SYS_ACCEPT EQU 78
|
||||
SYS_CONNECT EQU 79
|
||||
SYS_SEND EQU 80
|
||||
SYS_RECV EQU 81
|
||||
SYS_SHUTDOWN EQU 82
|
||||
SYS_SEND_TO EQU 83
|
||||
SYS_RECV_FROM EQU 84
|
||||
SYS_RESOLVE_HOST EQU 85
|
||||
SYS_SET_SOCKET_OPTION EQU 86
|
||||
SYS_GET_SOCKET_OPTION EQU 87
|
||||
SYS_POLL EQU 88
|
||||
SYS_GET_MEMORY_STATUS EQU 89
|
||||
SYS_EXIT_PROCESS EQU 0
|
||||
SYS_EXIT_THREAD EQU 1
|
||||
SYS_CREATE_PROCESS EQU 2
|
||||
SYS_WAIT_FOR_PROCESS EQU 3
|
||||
SYS_GET_PROCESS_EXIT_CODE EQU 4
|
||||
SYS_KILL_PROCESS EQU 5
|
||||
SYS_GET_PROCESS_LIST EQU 6
|
||||
SYS_GET_PROCESS_PID EQU 7
|
||||
SYS_CREATE_THREAD EQU 8
|
||||
SYS_WAIT_THREAD EQU 9
|
||||
SYS_GET_CURRENT_TID EQU 10
|
||||
SYS_GET_CURRENT_PID EQU 11
|
||||
SYS_SET_THREAD_PRIORITY EQU 12
|
||||
SYS_YIELD EQU 13
|
||||
SYS_SLEEP EQU 14
|
||||
SYS_SET_USER_APC_DISPATCHER EQU 15
|
||||
SYS_APC_RETURN EQU 16
|
||||
SYS_VM_ALLOC EQU 17
|
||||
SYS_VM_FREE EQU 18
|
||||
SYS_VM_PROTECT EQU 19
|
||||
SYS_VM_QUERY EQU 20
|
||||
SYS_CLOSE_HANDLE EQU 21
|
||||
SYS_MUTEX_CREATE EQU 22
|
||||
SYS_MUTEX_ACQUIRE EQU 23
|
||||
SYS_MUTEX_TRY_ACQUIRE EQU 24
|
||||
SYS_MUTEX_RELEASE EQU 25
|
||||
SYS_SEM_CREATE EQU 26
|
||||
SYS_SEM_WAIT EQU 27
|
||||
SYS_SEM_TRY_WAIT EQU 28
|
||||
SYS_SEM_SIGNAL EQU 29
|
||||
SYS_EVENT_CREATE EQU 30
|
||||
SYS_EVENT_SIGNAL EQU 31
|
||||
SYS_EVENT_CLEAR EQU 32
|
||||
SYS_EVENT_WAIT EQU 33
|
||||
SYS_QUEUE_CREATE EQU 34
|
||||
SYS_QUEUE_SEND EQU 35
|
||||
SYS_QUEUE_RECV EQU 36
|
||||
SYS_PUBLISH_QUEUE EQU 37
|
||||
SYS_OPEN_NAMED_QUEUE EQU 38
|
||||
SYS_QUEUE_DUPLICATE EQU 39
|
||||
SYS_NAMED_QUEUE_OWNER_PID EQU 40
|
||||
SYS_OPEN_FILE EQU 41
|
||||
SYS_CREATE_FILE EQU 42
|
||||
SYS_READ_FILE EQU 43
|
||||
SYS_WRITE_FILE EQU 44
|
||||
SYS_READ_FILE_ASYNC EQU 45
|
||||
SYS_WRITE_FILE_ASYNC EQU 46
|
||||
SYS_CANCEL_IO EQU 47
|
||||
SYS_SEEK_FILE EQU 48
|
||||
SYS_GET_FILE_POS EQU 49
|
||||
SYS_GET_FILE_SIZE EQU 50
|
||||
SYS_TRUNCATE_FILE EQU 51
|
||||
SYS_DELETE_FILE EQU 52
|
||||
SYS_RENAME_FILE EQU 53
|
||||
SYS_OPEN_DIR EQU 54
|
||||
SYS_READ_DIR EQU 55
|
||||
SYS_CREATE_DIR EQU 56
|
||||
SYS_REMOVE_DIR EQU 57
|
||||
SYS_SET_CWD EQU 58
|
||||
SYS_GET_CWD EQU 59
|
||||
SYS_WRITE_CONSOLE EQU 60
|
||||
SYS_SCREEN_BLIT EQU 61
|
||||
SYS_SCREEN_CLEAR EQU 62
|
||||
SYS_SCREEN_GET_SIZE EQU 63
|
||||
SYS_SCREEN_PUT_CHAR EQU 64
|
||||
SYS_KB_POLL EQU 65
|
||||
SYS_KB_IS_KEY_DOWN EQU 66
|
||||
SYS_KB_READ_CHAR EQU 67
|
||||
SYS_KB_READ_KEY EQU 68
|
||||
SYS_KB_GET_MODIFIERS EQU 69
|
||||
SYS_MOUSE_POLL EQU 70
|
||||
SYS_MOUSE_READ EQU 71
|
||||
SYS_MOUSE_GET_POS EQU 72
|
||||
SYS_GET_TICK EQU 73
|
||||
SYS_DEBUG_PRINT EQU 74
|
||||
SYS_QUERY_TRAP_FRAME EQU 75
|
||||
SYS_SOCKET EQU 76
|
||||
SYS_BIND EQU 77
|
||||
SYS_LISTEN EQU 78
|
||||
SYS_ACCEPT EQU 79
|
||||
SYS_CONNECT EQU 80
|
||||
SYS_SEND EQU 81
|
||||
SYS_RECV EQU 82
|
||||
SYS_SHUTDOWN EQU 83
|
||||
SYS_SEND_TO EQU 84
|
||||
SYS_RECV_FROM EQU 85
|
||||
SYS_RESOLVE_HOST EQU 86
|
||||
SYS_SET_SOCKET_OPTION EQU 87
|
||||
SYS_GET_SOCKET_OPTION EQU 88
|
||||
SYS_POLL EQU 89
|
||||
SYS_GET_MEMORY_STATUS EQU 90
|
||||
SYS_QUERY_KERNEL_STATS EQU 91
|
||||
|
||||
SYS_MAX EQU 90
|
||||
SYS_MAX EQU 92
|
||||
@@ -108,11 +108,12 @@ SysUserApcDispatcher_Failed:
|
||||
SysUserApcDispatcher ENDP
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Memory and handles
|
||||
; Virtual memory and handles
|
||||
; ---------------------------------------------------------------------------
|
||||
SYSCALL_STUB2 Alloc, SYS_ALLOC
|
||||
SYSCALL_STUB2 Free, SYS_FREE
|
||||
SYSCALL_STUB2 Realloc, SYS_REALLOC
|
||||
SYSCALL_STUB6 VmAlloc, SYS_VM_ALLOC
|
||||
SYSCALL_STUB2 VmFree, SYS_VM_FREE
|
||||
SYSCALL_STUB2 VmProtect, SYS_VM_PROTECT
|
||||
SYSCALL_STUB2 VmQuery, SYS_VM_QUERY
|
||||
SYSCALL_STUB2 CloseHandle, SYS_CLOSE_HANDLE
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
@@ -216,5 +217,6 @@ SYSCALL_STUB2 GetSocketOption, SYS_GET_SOCKET_OPTION
|
||||
SYSCALL_STUB2 Poll, SYS_POLL
|
||||
|
||||
SYSCALL_STUB2 GetMemoryStatus, SYS_GET_MEMORY_STATUS
|
||||
SYSCALL_STUB2 QueryKernelStats, SYS_QUERY_KERNEL_STATS
|
||||
|
||||
END
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
#include <ntlite/syscall.h>
|
||||
@@ -82,7 +83,7 @@ int main(void) {
|
||||
SysExitProcess(1);
|
||||
}
|
||||
|
||||
uint8_t* buffer = (uint8_t*)SysAlloc(512);
|
||||
uint8_t* buffer = (uint8_t*)malloc(512);
|
||||
if (!buffer) {
|
||||
print("async_apc: allocation failed\n");
|
||||
SysExitProcess(1);
|
||||
@@ -141,7 +142,7 @@ int main(void) {
|
||||
|
||||
SysCloseHandle(event);
|
||||
SysCloseHandle(file);
|
||||
SysFree(buffer);
|
||||
free(buffer);
|
||||
|
||||
if (!ok) {
|
||||
print("async_apc: FAIL\n");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
@@ -51,7 +52,7 @@ int main(void) {
|
||||
SysExitProcess(1);
|
||||
}
|
||||
|
||||
uint8_t* buffer = (uint8_t*)SysAlloc(512);
|
||||
uint8_t* buffer = (uint8_t*)malloc(512);
|
||||
if (!buffer) {
|
||||
print("async_cancel: alloc failed\n");
|
||||
SysExitProcess(1);
|
||||
@@ -101,7 +102,7 @@ int main(void) {
|
||||
SysCloseHandle(request);
|
||||
SysCloseHandle(event);
|
||||
SysCloseHandle(file);
|
||||
SysFree(buffer);
|
||||
free(buffer);
|
||||
|
||||
if (!ok) {
|
||||
print("async_cancel: FAIL\n");
|
||||
|
||||
Reference in new issue
Block a user