rewrite comments into one, unified style
This commit is contained in:
1 parent
6260de0085
commit
467a58c9c6
163 files changed
+3560
-2556
No files matched your search
@@ -1,9 +1,4 @@
|
||||
// edit.c - tiny native text editor for nt-lite
|
||||
// Controls:
|
||||
// arrows/home/end/pageup/pagedown move
|
||||
// enter/backspace/delete/tab edit
|
||||
// ctrl+s save
|
||||
// ctrl+q quit (press twice if dirty)
|
||||
// User application entry points for edit.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
@@ -72,10 +67,12 @@ typedef struct SCREEN_CELL {
|
||||
static SCREEN_CELL gScreenCache[MAX_SCREEN_COLS * MAX_SCREEN_ROWS];
|
||||
static bool gScreenCacheValid = false;
|
||||
|
||||
// Implements the invalidate screen cache operation.
|
||||
static void invalidate_screen_cache(void) {
|
||||
gScreenCacheValid = false;
|
||||
}
|
||||
|
||||
// Updates screen size.
|
||||
static void update_screen_size(void) {
|
||||
int pxW = 0, pxH = 0;
|
||||
int oldCols = gCols;
|
||||
@@ -95,6 +92,7 @@ static void update_screen_size(void) {
|
||||
invalidate_screen_cache();
|
||||
}
|
||||
|
||||
// Updates cell.
|
||||
static void put_cell(int col, int row, char c, uint32_t fg, uint32_t bg) {
|
||||
if (col < 0 || row < 0 || col >= gCols || row >= gRows)
|
||||
return;
|
||||
@@ -114,14 +112,17 @@ static void put_cell(int col, int row, char c, uint32_t fg, uint32_t bg) {
|
||||
SysPutScreenChar(c, col * GLYPH_W, row * GLYPH_H, fg, bg);
|
||||
}
|
||||
|
||||
// Clears row.
|
||||
static void clear_row(int row, uint32_t bg) {
|
||||
for (int x = 0; x < gCols; x++) put_cell(x, row, ' ', COL_FG, bg);
|
||||
}
|
||||
|
||||
// Draws text.
|
||||
static void draw_text(int col, int row, const char* s, uint32_t fg, uint32_t bg) {
|
||||
while (*s && col < gCols) put_cell(col++, row, *s++, fg, bg);
|
||||
}
|
||||
|
||||
// Implements the msg set operation.
|
||||
static void msg_set(const char* s) {
|
||||
size_t n = strlen(s);
|
||||
if (n >= sizeof(gMessage)) n = sizeof(gMessage) - 1;
|
||||
@@ -129,15 +130,18 @@ static void msg_set(const char* s) {
|
||||
gMessage[n] = 0;
|
||||
}
|
||||
|
||||
// Appends char.
|
||||
static void append_char(char* b, size_t cap, size_t* p, char c) {
|
||||
if (*p + 1 < cap) b[(*p)++] = c;
|
||||
b[*p < cap ? *p : cap - 1] = 0;
|
||||
}
|
||||
|
||||
// Appends str.
|
||||
static void append_str(char* b, size_t cap, size_t* p, const char* s) {
|
||||
while (*s) append_char(b, cap, p, *s++);
|
||||
}
|
||||
|
||||
// Appends u32.
|
||||
static void append_u32(char* b, size_t cap, size_t* p, uint32_t v) {
|
||||
char tmp[12];
|
||||
int n = 0;
|
||||
@@ -149,6 +153,7 @@ static void append_u32(char* b, size_t cap, size_t* p, uint32_t v) {
|
||||
while (n > 0) append_char(b, cap, p, tmp[--n]);
|
||||
}
|
||||
|
||||
// Implements the key to char operation.
|
||||
static char key_to_char(INPUT_KEY key, uint32_t mods) {
|
||||
if (key >= INPUT_KEY_A && key <= INPUT_KEY_Z) {
|
||||
bool shifted = (mods & INPUT_MOD_SHIFT) != 0;
|
||||
@@ -178,6 +183,7 @@ static char key_to_char(INPUT_KEY key, uint32_t mods) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the clamp cursor operation.
|
||||
static void clamp_cursor(void) {
|
||||
if (gLineCount < 1) gLineCount = 1;
|
||||
if (gCy < 0) gCy = 0;
|
||||
@@ -186,6 +192,7 @@ static void clamp_cursor(void) {
|
||||
if (gCx > gLines[gCy].len) gCx = gLines[gCy].len;
|
||||
}
|
||||
|
||||
// Implements the ensure visible operation.
|
||||
static void ensure_visible(void) {
|
||||
int textRows = gRows - 2;
|
||||
if (textRows < 1) textRows = 1;
|
||||
@@ -199,6 +206,7 @@ static void ensure_visible(void) {
|
||||
if (gLeft < 0) gLeft = 0;
|
||||
}
|
||||
|
||||
// Implements the render operation.
|
||||
static void render(void) {
|
||||
update_screen_size();
|
||||
|
||||
@@ -251,6 +259,7 @@ static void render(void) {
|
||||
gScreenCacheValid = true;
|
||||
}
|
||||
|
||||
// Inserts char at cursor.
|
||||
static void insert_char_at_cursor(char c) {
|
||||
LINE* ln = &gLines[gCy];
|
||||
if (ln->len >= MAX_LINE - 1) { msg_set("line too long"); return; }
|
||||
@@ -261,6 +270,7 @@ static void insert_char_at_cursor(char c) {
|
||||
gDirty = true;
|
||||
}
|
||||
|
||||
// Implements the newline at cursor operation.
|
||||
static void newline_at_cursor(void) {
|
||||
if (gLineCount >= MAX_LINES) { msg_set("too many lines"); return; }
|
||||
|
||||
@@ -282,6 +292,7 @@ static void newline_at_cursor(void) {
|
||||
gDirty = true;
|
||||
}
|
||||
|
||||
// Implements the backspace at cursor operation.
|
||||
static void backspace_at_cursor(void) {
|
||||
if (gCx > 0) {
|
||||
LINE* ln = &gLines[gCy];
|
||||
@@ -309,6 +320,7 @@ static void backspace_at_cursor(void) {
|
||||
gDirty = true;
|
||||
}
|
||||
|
||||
// Releases at cursor.
|
||||
static void delete_at_cursor(void) {
|
||||
LINE* ln = &gLines[gCy];
|
||||
if (gCx < ln->len) {
|
||||
@@ -330,26 +342,31 @@ static void delete_at_cursor(void) {
|
||||
gDirty = true;
|
||||
}
|
||||
|
||||
// Moves left.
|
||||
static void move_left(void) {
|
||||
if (gCx > 0) gCx--;
|
||||
else if (gCy > 0) { gCy--; gCx = gLines[gCy].len; }
|
||||
}
|
||||
|
||||
// Moves right.
|
||||
static void move_right(void) {
|
||||
if (gCx < gLines[gCy].len) gCx++;
|
||||
else if (gCy + 1 < gLineCount) { gCy++; gCx = 0; }
|
||||
}
|
||||
|
||||
// Moves up.
|
||||
static void move_up(void) {
|
||||
if (gCy > 0) gCy--;
|
||||
if (gCx > gLines[gCy].len) gCx = gLines[gCy].len;
|
||||
}
|
||||
|
||||
// Moves down.
|
||||
static void move_down(void) {
|
||||
if (gCy + 1 < gLineCount) gCy++;
|
||||
if (gCx > gLines[gCy].len) gCx = gLines[gCy].len;
|
||||
}
|
||||
|
||||
// Updates file.
|
||||
static void save_file(void) {
|
||||
uint32_t h = 0;
|
||||
SYS_PATH_HANDLE_REQUEST pathReq = { SysSvFromCstr(gFilename), &h };
|
||||
@@ -378,6 +395,7 @@ static void save_file(void) {
|
||||
msg_set("saved");
|
||||
}
|
||||
|
||||
// Implements the reset buffer operation.
|
||||
static void reset_buffer(void) {
|
||||
gLineCount = 1;
|
||||
gLines[0].len = 0;
|
||||
@@ -386,6 +404,7 @@ static void reset_buffer(void) {
|
||||
gDirty = false;
|
||||
}
|
||||
|
||||
// Loads file.
|
||||
static void load_file(void) {
|
||||
reset_buffer();
|
||||
|
||||
@@ -423,11 +442,13 @@ static void load_file(void) {
|
||||
msg_set(truncated ? "loaded, truncated long file" : "loaded");
|
||||
}
|
||||
|
||||
// Implements the skip spaces operation.
|
||||
static const char* skip_spaces(const char* s) {
|
||||
while (s && (*s == ' ' || *s == '\t')) s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
// Implements the skip token operation.
|
||||
static const char* skip_token(const char* s) {
|
||||
s = skip_spaces(s);
|
||||
if (!s || !*s) return s;
|
||||
@@ -441,6 +462,7 @@ static const char* skip_token(const char* s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Returns token.
|
||||
static bool read_token(const char* s, char* out, size_t cap) {
|
||||
s = skip_spaces(s);
|
||||
if (!s || !*s || cap == 0) return false;
|
||||
@@ -461,6 +483,7 @@ static bool read_token(const char* s, char* out, size_t cap) {
|
||||
return n != 0;
|
||||
}
|
||||
|
||||
// Parses filename from cmdline.
|
||||
static void parse_filename_from_cmdline(void) {
|
||||
SYS_PEB* peb = SysGetPeb();
|
||||
const char* cmd = (peb && peb->CommandLine.Data) ? peb->CommandLine.Data : NULL;
|
||||
@@ -469,6 +492,7 @@ static void parse_filename_from_cmdline(void) {
|
||||
strcpy(gFilename, "untitled.txt");
|
||||
}
|
||||
|
||||
// Implements the editor loop operation.
|
||||
static void editor_loop(void) {
|
||||
while (true) {
|
||||
render();
|
||||
@@ -527,11 +551,13 @@ static void editor_loop(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
parse_filename_from_cmdline();
|
||||
load_file();
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
// User application entry points for httpget.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) {
|
||||
if (s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); }
|
||||
}
|
||||
|
||||
// Prints char.
|
||||
static void print_char(char c) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(&c, 1) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Prints u64.
|
||||
static void print_u64(uint64_t v) {
|
||||
char buf[32];
|
||||
int n = 0;
|
||||
@@ -24,6 +29,7 @@ static void print_u64(uint64_t v) {
|
||||
while (n > 0) print_char(buf[--n]);
|
||||
}
|
||||
|
||||
// Appends char.
|
||||
static void append_char(char* dst, size_t cap, size_t* off, char c) {
|
||||
if (!dst || !off || cap == 0 || *off + 1 >= cap) return;
|
||||
dst[*off] = c;
|
||||
@@ -31,11 +37,13 @@ static void append_char(char* dst, size_t cap, size_t* off, char c) {
|
||||
dst[*off] = 0;
|
||||
}
|
||||
|
||||
// Appends str.
|
||||
static void append_str(char* dst, size_t cap, size_t* off, const char* s) {
|
||||
if (!s) return;
|
||||
while (*s) append_char(dst, cap, off, *s++);
|
||||
}
|
||||
|
||||
// Appends u8.
|
||||
static void append_u8(char* dst, size_t cap, size_t* off, uint8_t v) {
|
||||
if (v >= 100) {
|
||||
append_char(dst, cap, off, (char)('0' + v / 100));
|
||||
@@ -50,6 +58,7 @@ static void append_u8(char* dst, size_t cap, size_t* off, uint8_t v) {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the format ipv4 operation.
|
||||
static void format_ipv4(char* dst, size_t cap, const uint8_t ip[4]) {
|
||||
size_t off = 0;
|
||||
if (!dst || cap == 0) return;
|
||||
@@ -60,6 +69,7 @@ static void format_ipv4(char* dst, size_t cap, const uint8_t ip[4]) {
|
||||
append_u8(dst, cap, &off, ip[3]);
|
||||
}
|
||||
|
||||
// Parses u8.
|
||||
static bool parse_u8(const char** p, uint8_t* out) {
|
||||
const char* s = *p;
|
||||
uint32_t v = 0;
|
||||
@@ -76,6 +86,7 @@ static bool parse_u8(const char** p, uint8_t* out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses ipv4.
|
||||
static bool parse_ipv4(const char* s, uint8_t ip[4]) {
|
||||
if (!s || !ip) return false;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -88,6 +99,7 @@ static bool parse_ipv4(const char* s, uint8_t ip[4]) {
|
||||
return *s == 0;
|
||||
}
|
||||
|
||||
// Implements the next token operation.
|
||||
static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
if (!s || !out || outSize == 0) return NULL;
|
||||
while (*s == ' ' || *s == '\t') s++;
|
||||
@@ -102,11 +114,13 @@ static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Implements the usage operation.
|
||||
static void usage(void) {
|
||||
print("usage: httpget.exe [host-or-ipv4] [path]\n");
|
||||
print("default: httpget.exe 10.0.2.2 /\n");
|
||||
}
|
||||
|
||||
// Implements the resolve host operation.
|
||||
static uint32_t resolve_host(const char* host, uint8_t ip[4]) {
|
||||
if (parse_ipv4(host, ip))
|
||||
return SYS_STATUS_SUCCESS;
|
||||
@@ -134,6 +148,7 @@ static uint32_t resolve_host(const char* host, uint8_t ip[4]) {
|
||||
return SYS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
uint8_t ip[4] = {10, 0, 2, 2};
|
||||
char host[256];
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User application entry points for ping.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
@@ -11,15 +13,18 @@
|
||||
#define PING_PAYLOAD_BYTES 32u
|
||||
#define PING_PACKET_BYTES (8u + PING_PAYLOAD_BYTES)
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) {
|
||||
if (s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); }
|
||||
}
|
||||
|
||||
// Prints char.
|
||||
static void print_char(char c) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(&c, 1) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Prints u64.
|
||||
static void print_u64(uint64_t v) {
|
||||
char buf[32];
|
||||
int n = 0;
|
||||
@@ -31,11 +36,13 @@ static void print_u64(uint64_t v) {
|
||||
while (n > 0) print_char(buf[--n]);
|
||||
}
|
||||
|
||||
// Prints ipv4.
|
||||
static void print_ipv4(const uint8_t ip[4]) {
|
||||
print_u64(ip[0]); print("."); print_u64(ip[1]); print(".");
|
||||
print_u64(ip[2]); print("."); print_u64(ip[3]);
|
||||
}
|
||||
|
||||
// Prints rtt us.
|
||||
static void print_rtt_us(uint64_t us) {
|
||||
uint64_t whole = us / US_PER_MS;
|
||||
uint64_t frac = us % US_PER_MS;
|
||||
@@ -46,6 +53,7 @@ static void print_rtt_us(uint64_t us) {
|
||||
print_u64(frac);
|
||||
}
|
||||
|
||||
// Implements the format ipv4 operation.
|
||||
static void format_ipv4(char* out, size_t outSize, const uint8_t ip[4]) {
|
||||
if (!out || outSize == 0) return;
|
||||
size_t off = 0;
|
||||
@@ -62,6 +70,7 @@ static void format_ipv4(char* out, size_t outSize, const uint8_t ip[4]) {
|
||||
out[off < outSize ? off : outSize - 1] = 0;
|
||||
}
|
||||
|
||||
// Implements the next token operation.
|
||||
static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
if (!s || !out || outSize == 0) return NULL;
|
||||
while (*s == ' ' || *s == '\t') s++;
|
||||
@@ -76,6 +85,7 @@ static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Parses u8.
|
||||
static bool parse_u8(const char** p, uint8_t* out) {
|
||||
const char* s = *p;
|
||||
uint32_t v = 0;
|
||||
@@ -92,6 +102,7 @@ static bool parse_u8(const char** p, uint8_t* out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses ipv4.
|
||||
static bool parse_ipv4(const char* s, uint8_t ip[4]) {
|
||||
if (!s || !ip) return false;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -104,6 +115,7 @@ static bool parse_ipv4(const char* s, uint8_t ip[4]) {
|
||||
return *s == 0;
|
||||
}
|
||||
|
||||
// Parses u32.
|
||||
static bool parse_u32(const char* s, uint32_t* out) {
|
||||
if (!s || !*s || !out) return false;
|
||||
uint32_t v = 0;
|
||||
@@ -118,6 +130,7 @@ static bool parse_u32(const char* s, uint32_t* out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Implements the resolve host operation.
|
||||
static uint32_t resolve_host(const char* host, uint8_t ip[4]) {
|
||||
if (parse_ipv4(host, ip))
|
||||
return SYS_STATUS_SUCCESS;
|
||||
@@ -145,6 +158,7 @@ static uint32_t resolve_host(const char* host, uint8_t ip[4]) {
|
||||
return SYS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the icmp checksum operation.
|
||||
static uint16_t icmp_checksum(const uint8_t* data, size_t length) {
|
||||
uint32_t sum = 0;
|
||||
while (length >= 2) {
|
||||
@@ -160,6 +174,7 @@ static uint16_t icmp_checksum(const uint8_t* data, size_t length) {
|
||||
return (uint16_t)(~sum & 0xFFFFu);
|
||||
}
|
||||
|
||||
// Creates echo request.
|
||||
static void make_echo_request(uint8_t packet[PING_PACKET_BYTES], uint16_t ident, uint16_t seq) {
|
||||
memset(packet, 0, PING_PACKET_BYTES);
|
||||
packet[0] = 8; // echo request
|
||||
@@ -207,11 +222,13 @@ static bool parse_echo_reply(const uint8_t* buf, size_t len, uint16_t ident, uin
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implements the usage operation.
|
||||
static void usage(void) {
|
||||
print("usage: apps/ping.exe [host-or-ipv4] [count]\n");
|
||||
print("default: apps/ping.exe 10.0.2.2 4\n");
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
char host[256];
|
||||
char tok[256];
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
// User application entry points for resolve.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) {
|
||||
if (s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); }
|
||||
}
|
||||
|
||||
// Prints char.
|
||||
static void print_char(char c) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(&c, 1) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Prints u64.
|
||||
static void print_u64(uint64_t v) {
|
||||
char buf[32];
|
||||
int n = 0;
|
||||
@@ -23,6 +28,7 @@ static void print_u64(uint64_t v) {
|
||||
while (n > 0) print_char(buf[--n]);
|
||||
}
|
||||
|
||||
// Implements the next token operation.
|
||||
static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
if (!s || !out || outSize == 0) return NULL;
|
||||
while (*s == ' ' || *s == '\t') s++;
|
||||
@@ -37,11 +43,13 @@ static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Prints ipv4.
|
||||
static void print_ipv4(const uint8_t ip[4]) {
|
||||
print_u64(ip[0]); print("."); print_u64(ip[1]); print(".");
|
||||
print_u64(ip[2]); print("."); print_u64(ip[3]);
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
char name[256];
|
||||
const char* cmd = SysGetPeb()->CommandLine.Data;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User application entry points for shell_native.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
@@ -7,41 +9,46 @@
|
||||
#define MAX_CMD 256
|
||||
#define MAX_PROCS 64 // Maximum number of processes we will fetch at once
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output helpers.
|
||||
static void print(const char* s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); }
|
||||
|
||||
// Opens file.
|
||||
static uint32_t open_file(const char* path, uint32_t* handleOut) {
|
||||
SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut };
|
||||
return SysOpenFile(&req);
|
||||
}
|
||||
|
||||
// Creates file.
|
||||
static uint32_t create_file(const char* path, uint32_t* handleOut) {
|
||||
SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut };
|
||||
return SysCreateFile(&req);
|
||||
}
|
||||
|
||||
// Opens dir.
|
||||
static uint32_t open_dir(const char* path, uint32_t* handleOut) {
|
||||
SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut };
|
||||
return SysOpenDir(&req);
|
||||
}
|
||||
|
||||
// Updates cwd.
|
||||
static uint32_t set_cwd(const char* path) {
|
||||
SYS_PATH_REQUEST req = { SysSvFromCstr(path) };
|
||||
return SysSetCwd(&req);
|
||||
}
|
||||
|
||||
// Releases file.
|
||||
static uint32_t delete_file(const char* path) {
|
||||
SYS_PATH_REQUEST req = { SysSvFromCstr(path) };
|
||||
return SysDeleteFile(&req);
|
||||
}
|
||||
|
||||
// Creates process.
|
||||
static uint32_t create_process(const char* path, uint32_t* handleOut, const char* cmdline) {
|
||||
SYS_CREATE_PROCESS_REQUEST req = { SysSvFromCstr(path), SysSvFromCstr(cmdline), handleOut };
|
||||
return SysCreateProcess(&req);
|
||||
}
|
||||
|
||||
// Prints u Int.
|
||||
static void printUInt(uint32_t n) {
|
||||
char buf[12]; int i = 0;
|
||||
if (n == 0) { print("0"); return; }
|
||||
@@ -49,11 +56,13 @@ static void printUInt(uint32_t n) {
|
||||
while (i > 0) { char c[2] = { buf[--i], '\0' }; print(c); }
|
||||
}
|
||||
|
||||
// Prints int.
|
||||
static void printInt(int32_t n) {
|
||||
if (n < 0) { print("-"); printUInt((uint32_t)-(n + 1) + 1); }
|
||||
else { printUInt((uint32_t)n); }
|
||||
}
|
||||
|
||||
// Prints u Int64.
|
||||
static void printUInt64(uint64_t n) {
|
||||
if (n == 0) { print("0"); return; }
|
||||
char buf[20]; int i = 0;
|
||||
@@ -61,34 +70,40 @@ static void printUInt64(uint64_t n) {
|
||||
while (i > 0) { char c[2] = { buf[--i], '\0' }; print(c); }
|
||||
}
|
||||
|
||||
// Implements the u64 Digits operation.
|
||||
static uint32_t u64Digits(uint64_t n) {
|
||||
uint32_t digits = 1;
|
||||
while (n >= 10u) { n /= 10u; digits++; }
|
||||
return digits;
|
||||
}
|
||||
|
||||
// Prints spaces.
|
||||
static void printSpaces(size_t count) {
|
||||
while (count--) print(" ");
|
||||
}
|
||||
|
||||
// Prints u Int Width.
|
||||
static void printUIntWidth(uint32_t n, size_t width) {
|
||||
uint32_t digits = u64Digits(n);
|
||||
if (width > digits) printSpaces(width - digits);
|
||||
printUInt(n);
|
||||
}
|
||||
|
||||
// Prints u Int Zero Width.
|
||||
static void printUIntZeroWidth(uint32_t n, size_t width) {
|
||||
uint32_t digits = u64Digits(n);
|
||||
while (width > digits) { print("0"); width--; }
|
||||
printUInt(n);
|
||||
}
|
||||
|
||||
// Prints u Int64 Width.
|
||||
static void printUInt64Width(uint64_t n, size_t width) {
|
||||
uint32_t digits = u64Digits(n);
|
||||
if (width > digits) printSpaces(width - digits);
|
||||
printUInt64(n);
|
||||
}
|
||||
|
||||
// Prints hex32.
|
||||
static void printHex32(uint32_t v) {
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
char buf[9];
|
||||
@@ -100,6 +115,7 @@ static void printHex32(uint32_t v) {
|
||||
print(buf);
|
||||
}
|
||||
|
||||
// Prints dir Time.
|
||||
static void printDirTime(const SYS_SYSTEM_TIME* t) {
|
||||
if (!t || !(t->Flags & SYS_TIME_FLAG_VALID)) {
|
||||
print("---- -- -- --:-- ");
|
||||
@@ -117,15 +133,14 @@ static void printDirTime(const SYS_SYSTEM_TIME* t) {
|
||||
print(" ");
|
||||
}
|
||||
|
||||
// Prints string Width.
|
||||
static void printStringWidth(const char* s, size_t width) {
|
||||
size_t len = s ? strlen(s) : 0;
|
||||
if (s) print(s);
|
||||
if (width > len) printSpaces(width - len);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Line editor
|
||||
// ---------------------------------------------------------------------------
|
||||
// Line editor.
|
||||
static void readLine(char* buf, int len) {
|
||||
int pos = 0;
|
||||
while (true) {
|
||||
@@ -139,6 +154,7 @@ static void readLine(char* buf, int len) {
|
||||
buf[pos] = '\0';
|
||||
}
|
||||
|
||||
// Implements the trim operation.
|
||||
static char* trim(char* s) {
|
||||
while (*s == ' ') s++;
|
||||
int len = (int)strlen(s);
|
||||
@@ -147,9 +163,7 @@ static char* trim(char* s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Built-in commands
|
||||
// ---------------------------------------------------------------------------
|
||||
// Built-in commands.
|
||||
static void cmd_help() {
|
||||
print("Available commands:\n"
|
||||
" help - Show this list\n"
|
||||
@@ -167,17 +181,20 @@ static void cmd_help() {
|
||||
" exit - Close the shell\n");
|
||||
}
|
||||
|
||||
// Prints size Ki B.
|
||||
static void printSizeKiB(uint64_t bytes) {
|
||||
printUInt64(bytes / 1024u);
|
||||
print(" KiB");
|
||||
}
|
||||
|
||||
|
||||
// Prints pages Ki B.
|
||||
static void printPagesKiB(uint64_t pages) {
|
||||
printUInt64(pages * 4u);
|
||||
print(" KiB");
|
||||
}
|
||||
|
||||
// Prints cpu Flags.
|
||||
static void printCpuFlags(uint32_t flags) {
|
||||
if (flags & SYS_CPU_FLAG_BSP) print("bsp ");
|
||||
if (flags & SYS_CPU_FLAG_ONLINE) print("online ");
|
||||
@@ -187,6 +204,7 @@ static void printCpuFlags(uint32_t flags) {
|
||||
if (flags & SYS_CPU_FLAG_PRESENT) print("present ");
|
||||
}
|
||||
|
||||
// Implements the cmd stats operation.
|
||||
static void cmd_stats(void) {
|
||||
SYS_SCHEDULER_STATS sched;
|
||||
SYS_PMM_STATS pmm;
|
||||
@@ -263,6 +281,7 @@ static void cmd_stats(void) {
|
||||
}
|
||||
|
||||
|
||||
// Implements the cmd time operation.
|
||||
static void cmd_time(void) {
|
||||
SYS_SYSTEM_TIME t;
|
||||
uint32_t status = SysGetSystemTime(&t);
|
||||
@@ -290,6 +309,7 @@ static void cmd_time(void) {
|
||||
print("\n");
|
||||
}
|
||||
|
||||
// Prints display Caps.
|
||||
static void printDisplayCaps(uint32_t caps) {
|
||||
bool any = false;
|
||||
if (caps & DISPLAY_CAP_FRAMEBUFFER) { print("framebuffer"); any = true; }
|
||||
@@ -303,6 +323,7 @@ static void printDisplayCaps(uint32_t caps) {
|
||||
if (!any) print("none");
|
||||
}
|
||||
|
||||
// Prints display Stats.
|
||||
static void printDisplayStats(const char* title, const DISPLAY_STATS* st) {
|
||||
print(title); print(":\n");
|
||||
print(" blit: "); printUInt64(st->BlitCount); print("\n");
|
||||
@@ -318,6 +339,7 @@ static void printDisplayStats(const char* title, const DISPLAY_STATS* st) {
|
||||
print(" hide="); printUInt64(st->CursorHideCount); print("\n");
|
||||
}
|
||||
|
||||
// Implements the cmd display operation.
|
||||
static void cmd_display(void) {
|
||||
SYS_DISPLAY_INFO info;
|
||||
uint32_t status = SysQueryDisplayInfo(&info);
|
||||
@@ -338,6 +360,7 @@ static void cmd_display(void) {
|
||||
printDisplayStats("Provider counters", &info.DeviceStats);
|
||||
}
|
||||
|
||||
// Implements the cmd mem operation.
|
||||
static void cmd_mem(void) {
|
||||
SYS_MEMORY_STATUS st;
|
||||
if (SysGetMemoryStatus(&st) != 0) {
|
||||
@@ -355,6 +378,7 @@ static void cmd_mem(void) {
|
||||
print("\n");
|
||||
}
|
||||
|
||||
// Processes state Name.
|
||||
static const char* processStateName(uint32_t state) {
|
||||
switch (state) {
|
||||
case SYS_PROCESS_STATE_RUNNING: return "run";
|
||||
@@ -364,6 +388,7 @@ static const char* processStateName(uint32_t state) {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the cmd ps operation.
|
||||
static void cmd_ps(void) {
|
||||
SYS_PROCESS_INFO procs[MAX_PROCS];
|
||||
size_t count = 0;
|
||||
@@ -424,6 +449,7 @@ static void cmd_ps(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the cmd write operation.
|
||||
static void cmd_write(const char* args) {
|
||||
char filename[MAX_CMD]; int i = 0;
|
||||
while (args[i] != ' ' && args[i] != '\0' && i < MAX_CMD - 1) {
|
||||
@@ -439,6 +465,7 @@ static void cmd_write(const char* args) {
|
||||
print("File written successfully.\n");
|
||||
}
|
||||
|
||||
// Implements the cmd dir operation.
|
||||
static void cmd_dir(const char* path) {
|
||||
uint32_t hDir;
|
||||
const char* target = (path && *path != '\0') ? path : ".";
|
||||
@@ -452,7 +479,7 @@ static void cmd_dir(const char* path) {
|
||||
while (SysReadDir(hDir, &ke) == 0) {
|
||||
printDirTime(&ke.LastWriteTime);
|
||||
|
||||
// Corrected Attribute Check: 0x10 is the Directory bit in FAT
|
||||
// Corrected Attribute Check: 0x10 is the Directory bit in FAT.
|
||||
if (ke.Attr & 0x10) {
|
||||
print("<DIR> ");
|
||||
} else {
|
||||
@@ -461,7 +488,7 @@ static void cmd_dir(const char* path) {
|
||||
|
||||
print(ke.Name);
|
||||
|
||||
// Optional: print file size for non-directories
|
||||
// Optional: print file size for non-directories.
|
||||
if (!(ke.Attr & 0x10)) {
|
||||
print(" (");
|
||||
printUInt(ke.FileSize);
|
||||
@@ -473,6 +500,7 @@ static void cmd_dir(const char* path) {
|
||||
SysCloseHandle(hDir);
|
||||
}
|
||||
|
||||
// Implements the cmd type operation.
|
||||
static void cmd_type(const char* filename) {
|
||||
uint32_t hFile;
|
||||
if (open_file(filename, &hFile) != 0) { print("type: cannot open file\n"); return; }
|
||||
@@ -484,6 +512,7 @@ static void cmd_type(const char* filename) {
|
||||
}
|
||||
|
||||
|
||||
// Implements the extract Program Path operation.
|
||||
static bool extractProgramPath(const char* cmdline, char* out, size_t outSize) {
|
||||
if (!cmdline || !out || outSize == 0) return false;
|
||||
|
||||
@@ -504,24 +533,22 @@ static bool extractProgramPath(const char* cmdline, char* out, size_t outSize) {
|
||||
return pos != 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Run one command
|
||||
// ---------------------------------------------------------------------------
|
||||
// Run one command.
|
||||
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) { SysClearScreen(0x012456); return 0; }
|
||||
if (strncmp(cmd, "crash", 5) == 0) {
|
||||
// Check the sub-option trailing "crash " (offset 6)
|
||||
// Check the sub-option trailing "crash " (offset 6).
|
||||
if (strcmp(cmd + 6, "void") == 0) {
|
||||
// Jumping into the void
|
||||
// Jumping into the void.
|
||||
void (*invalid_func)(void) = NULL;
|
||||
invalid_func();
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(cmd + 6, "noncanonical") == 0) {
|
||||
// Non-canonical pointer dereference
|
||||
// Non-canonical pointer dereference.
|
||||
volatile int *ptr = (volatile int*)0x4242424242424242ULL;
|
||||
*ptr = 1337;
|
||||
return 0;
|
||||
@@ -531,21 +558,21 @@ static int runCommand(const char* cmd) {
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(cmd + 6, "nx") == 0) {
|
||||
// NX / DEP Violation
|
||||
// NX / DEP Violation.
|
||||
unsigned char code[] = { 0xC3 };
|
||||
void (*execute_stack)(void) = (void (*)(void))code;
|
||||
execute_stack();
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(cmd + 6, "divzero") == 0) {
|
||||
// Division by zero
|
||||
// Division by zero.
|
||||
volatile int zero = 0;
|
||||
volatile int result = 1 / zero;
|
||||
(void)result;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
// Default fallback if just "crash" or an unknown sub-option is passed
|
||||
// Default fallback if just "crash" or an unknown sub-option is passed.
|
||||
*(volatile int*)0 = 42;
|
||||
return 0;
|
||||
}
|
||||
@@ -574,6 +601,7 @@ static int runCommand(const char* cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
const char* cmdline = SysGetPeb()->CommandLine.Data;
|
||||
char lineBuf[MAX_CMD];
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User application entry points for shell_posix.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
@@ -28,8 +30,10 @@ extern void PosixFdInit(void);
|
||||
|
||||
static int hIn = 0; static int hOut = 1;
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) { write(hOut, s, strlen(s)); }
|
||||
|
||||
// Prints u Int.
|
||||
static void printUInt(uint32_t n) {
|
||||
char buf[12]; int i = 0;
|
||||
if (n == 0) { print("0"); return; }
|
||||
@@ -37,11 +41,13 @@ static void printUInt(uint32_t n) {
|
||||
while (i > 0) { char c[2] = { buf[--i], '\0' }; print(c); }
|
||||
}
|
||||
|
||||
// Prints int.
|
||||
static void printInt(int32_t n) {
|
||||
if (n < 0) { print("-"); n = -n; }
|
||||
printUInt((uint32_t)n);
|
||||
}
|
||||
|
||||
// Returns line.
|
||||
static void readLine(char* buf, int len) {
|
||||
int pos = 0;
|
||||
while (true) {
|
||||
@@ -55,6 +61,7 @@ static void readLine(char* buf, int len) {
|
||||
}
|
||||
|
||||
|
||||
// Implements the split Command Line operation.
|
||||
static int splitCommandLine(char* line, char** argv, int maxArgv) {
|
||||
int argc = 0;
|
||||
char* p = line;
|
||||
@@ -79,6 +86,7 @@ static int splitCommandLine(char* line, char** argv, int maxArgv) {
|
||||
return argc;
|
||||
}
|
||||
|
||||
// Implements the trim operation.
|
||||
static char* trim(char* s) {
|
||||
while (*s == ' ') s++;
|
||||
int len = (int)strlen(s);
|
||||
@@ -87,6 +95,7 @@ static char* trim(char* s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Implements the cmd help operation.
|
||||
static void cmd_help() {
|
||||
print("Available commands:\n"
|
||||
" help - Show this list\n"
|
||||
@@ -99,6 +108,7 @@ static void cmd_help() {
|
||||
" exit - Close the shell\n");
|
||||
}
|
||||
|
||||
// Implements the cmd write operation.
|
||||
static void cmd_write(const char* args) {
|
||||
char filename[MAX_CMD]; int i = 0;
|
||||
while (args[i] != ' ' && args[i] != '\0' && i < MAX_CMD - 1) {
|
||||
@@ -113,6 +123,7 @@ static void cmd_write(const char* args) {
|
||||
print("File written successfully.\n");
|
||||
}
|
||||
|
||||
// Implements the cmd dir operation.
|
||||
static void cmd_dir(const char* path) {
|
||||
const char* target = (path && *path != '\0') ? path : ".";
|
||||
DIR* d = opendir(target);
|
||||
@@ -125,6 +136,7 @@ static void cmd_dir(const char* path) {
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
// Implements the cmd type operation.
|
||||
static void cmd_type(const char* filename) {
|
||||
int fd = open(filename, 0); // O_RDONLY
|
||||
if (fd < 0) { print("type: cannot open file\n"); return; }
|
||||
@@ -133,6 +145,7 @@ static void cmd_type(const char* filename) {
|
||||
close(fd); print("\n");
|
||||
}
|
||||
|
||||
// Runs command.
|
||||
static int runCommand(const char* cmd) {
|
||||
if (!cmd || *cmd == '\0') return 0;
|
||||
if (strcmp(cmd, "exit") == 0) return 1;
|
||||
@@ -162,6 +175,7 @@ static int runCommand(const char* cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
PosixFdInit();
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User application entry points for shell_win32.
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
@@ -8,16 +10,17 @@
|
||||
static HANDLE hIn = INVALID_HANDLE_VALUE;
|
||||
static HANDLE hOut = INVALID_HANDLE_VALUE;
|
||||
|
||||
// External/Custom API
|
||||
// External/Custom API.
|
||||
BOOL ClearConsoleScreenBuffer(HANDLE hConsole);
|
||||
|
||||
// --- Output Helpers ---
|
||||
// --- Output Helpers ---.
|
||||
static void print(const char* s) {
|
||||
DWORD written;
|
||||
if (hOut != INVALID_HANDLE_VALUE) WriteConsoleA(hOut, s, (DWORD)strlen(s), &written, 0);
|
||||
else OutputDebugStringA(s);
|
||||
}
|
||||
|
||||
// Prints u Int.
|
||||
static void printUInt(uint32_t n) {
|
||||
char buf[12]; int i = 0;
|
||||
if (n == 0) { print("0"); return; }
|
||||
@@ -25,12 +28,13 @@ static void printUInt(uint32_t n) {
|
||||
while (i > 0) { char c[2] = { buf[--i], '\0' }; print(c); }
|
||||
}
|
||||
|
||||
// Prints int.
|
||||
static void printInt(int32_t n) {
|
||||
if (n < 0) { print("-"); n = -n; }
|
||||
printUInt((uint32_t)n);
|
||||
}
|
||||
|
||||
// --- Line Editor ---
|
||||
// --- Line Editor ---.
|
||||
static void readLine(char* buf, int len) {
|
||||
int pos = 0;
|
||||
while (true) {
|
||||
@@ -49,6 +53,7 @@ static void readLine(char* buf, int len) {
|
||||
buf[pos] = '\0';
|
||||
}
|
||||
|
||||
// Implements the trim operation.
|
||||
static char* trim(char* s) {
|
||||
while (*s == ' ') s++;
|
||||
int len = (int)strlen(s);
|
||||
@@ -57,7 +62,7 @@ static char* trim(char* s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// --- Built-in Commands ---
|
||||
// --- Built-in Commands ---.
|
||||
static void cmd_help() {
|
||||
print("Available commands:\n"
|
||||
" help - Show this list\n"
|
||||
@@ -70,6 +75,7 @@ static void cmd_help() {
|
||||
" exit - Close the shell\n");
|
||||
}
|
||||
|
||||
// Implements the cmd write operation.
|
||||
static void cmd_write(const char* args) {
|
||||
char filename[MAX_PATH]; int i = 0;
|
||||
while (args[i] != ' ' && args[i] != '\0' && i < MAX_PATH - 1) {
|
||||
@@ -88,6 +94,7 @@ static void cmd_write(const char* args) {
|
||||
print("File written successfully.\n");
|
||||
}
|
||||
|
||||
// Implements the cmd dir operation.
|
||||
static void cmd_dir(const char* path) {
|
||||
WIN32_FIND_DATAA fd;
|
||||
char search_path[MAX_PATH];
|
||||
@@ -107,6 +114,7 @@ static void cmd_dir(const char* path) {
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
// Implements the cmd type operation.
|
||||
static void cmd_type(const char* filename) {
|
||||
HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
if (hFile == INVALID_HANDLE_VALUE) { print("type: cannot open file\n"); return; }
|
||||
@@ -117,6 +125,7 @@ static void cmd_type(const char* filename) {
|
||||
CloseHandle(hFile); print("\n");
|
||||
}
|
||||
|
||||
// Runs command.
|
||||
static int runCommand(const char* cmd) {
|
||||
if (!cmd || *cmd == '\0') return 0;
|
||||
if (strcmp(cmd, "exit") == 0) return 1;
|
||||
@@ -145,6 +154,7 @@ static int runCommand(const char* cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
// User application entry points for tcpserve.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) {
|
||||
if (s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); }
|
||||
}
|
||||
|
||||
// Prints char.
|
||||
static void print_char(char c) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(&c, 1) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Prints u64.
|
||||
static void print_u64(uint64_t v) {
|
||||
char buf[32];
|
||||
int n = 0;
|
||||
@@ -24,11 +29,13 @@ static void print_u64(uint64_t v) {
|
||||
while (n > 0) print_char(buf[--n]);
|
||||
}
|
||||
|
||||
// Prints ipv4.
|
||||
static void print_ipv4(const uint8_t ip[4]) {
|
||||
print_u64(ip[0]); print("."); print_u64(ip[1]); print(".");
|
||||
print_u64(ip[2]); print("."); print_u64(ip[3]);
|
||||
}
|
||||
|
||||
// Implements the next token operation.
|
||||
static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
if (!s || !out || outSize == 0) return NULL;
|
||||
while (*s == ' ' || *s == '\t') s++;
|
||||
@@ -43,6 +50,7 @@ static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Parses port.
|
||||
static bool parse_port(const char* s, uint16_t* out) {
|
||||
if (!s || !*s || !out) return false;
|
||||
uint32_t v = 0;
|
||||
@@ -56,11 +64,13 @@ static bool parse_port(const char* s, uint16_t* out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Implements the usage operation.
|
||||
static void usage(void) {
|
||||
print("usage: tcpserve.exe [port]\n");
|
||||
print("default: tcpserve.exe 8080\n");
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
uint16_t port = 8080;
|
||||
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
// User application entry points for udp.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) {
|
||||
if (s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); }
|
||||
}
|
||||
|
||||
// Prints char.
|
||||
static void print_char(char c) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(&c, 1) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Prints u64.
|
||||
static void print_u64(uint64_t v) {
|
||||
char buf[32];
|
||||
int n = 0;
|
||||
@@ -24,11 +29,13 @@ static void print_u64(uint64_t v) {
|
||||
while (n > 0) print_char(buf[--n]);
|
||||
}
|
||||
|
||||
// Prints ipv4.
|
||||
static void print_ipv4(const uint8_t ip[4]) {
|
||||
print_u64(ip[0]); print("."); print_u64(ip[1]); print(".");
|
||||
print_u64(ip[2]); print("."); print_u64(ip[3]);
|
||||
}
|
||||
|
||||
// Implements the next token operation.
|
||||
static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
if (!s || !out || outSize == 0) return NULL;
|
||||
while (*s == ' ' || *s == '\t') s++;
|
||||
@@ -43,6 +50,7 @@ static const char* next_token(const char* s, char* out, size_t outSize) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Parses u8.
|
||||
static bool parse_u8(const char** p, uint8_t* out) {
|
||||
const char* s = *p;
|
||||
uint32_t v = 0;
|
||||
@@ -59,6 +67,7 @@ static bool parse_u8(const char** p, uint8_t* out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses ipv4.
|
||||
static bool parse_ipv4(const char* s, uint8_t ip[4]) {
|
||||
if (!s || !ip) return false;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -71,6 +80,7 @@ static bool parse_ipv4(const char* s, uint8_t ip[4]) {
|
||||
return *s == 0;
|
||||
}
|
||||
|
||||
// Parses port.
|
||||
static bool parse_port(const char* s, uint16_t* out) {
|
||||
if (!s || !*s || !out) return false;
|
||||
uint32_t v = 0;
|
||||
@@ -84,6 +94,7 @@ static bool parse_port(const char* s, uint16_t* out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Implements the usage operation.
|
||||
static void usage(void) {
|
||||
print("usage:\n");
|
||||
print(" udp.exe send <ipv4> <port> [message]\n");
|
||||
@@ -93,6 +104,7 @@ static void usage(void) {
|
||||
print(" udp.exe listen 9999\n");
|
||||
}
|
||||
|
||||
// Runs send.
|
||||
static int run_send(const char* cmd) {
|
||||
char tok[256];
|
||||
uint8_t ip[4];
|
||||
@@ -103,7 +115,7 @@ static int run_send(const char* cmd) {
|
||||
cmd = next_token(cmd, tok, sizeof(tok));
|
||||
if (!tok[0] || !parse_port(tok, &port)) { usage(); return 1; }
|
||||
|
||||
// Skip leading whitespace, then take the entire remaining command line
|
||||
// Skip leading whitespace, then take the entire remaining command line.
|
||||
if (cmd) {
|
||||
while (*cmd == ' ' || *cmd == '\t') {
|
||||
cmd++;
|
||||
@@ -151,6 +163,7 @@ static int run_send(const char* cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Runs listen.
|
||||
static int run_listen(const char* cmd) {
|
||||
char tok[64];
|
||||
uint16_t port = 0;
|
||||
@@ -211,6 +224,7 @@ static int run_listen(const char* cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
const char* cmd = SysGetPeb()->CommandLine.Data;
|
||||
char tok[64];
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User application entry points for video.
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
@@ -5,6 +7,7 @@
|
||||
#include <intrin.h>
|
||||
#include "bink.h"
|
||||
|
||||
// Implements the command Line Second Token operation.
|
||||
static const char* commandLineSecondToken(const char* cmdline, char* out, size_t outSize) {
|
||||
if (!out || outSize == 0) return "video.bk2";
|
||||
strcpy(out, "video.bk2");
|
||||
@@ -37,6 +40,7 @@ static const char* commandLineSecondToken(const char* cmdline, char* out, size_t
|
||||
return out;
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
const char* cmdline = GetCommandLineA();
|
||||
char videoPath[260];
|
||||
@@ -92,7 +96,7 @@ int main(void) {
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
// Prepare the Win32 BITMAPINFO structure
|
||||
// Prepare the Win32 BITMAPINFO structure.
|
||||
BITMAPINFO bmi;
|
||||
memset(&bmi, 0, sizeof(bmi));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
@@ -121,7 +125,7 @@ int main(void) {
|
||||
|
||||
// Welcome to the GDI pipeline!
|
||||
PAINTSTRUCT ps;
|
||||
// Using NULL/0 as the HWND since we don't have a real window handle yet
|
||||
// Using NULL/0 as the HWND since we don't have a real window handle yet.
|
||||
HDC hdc = BeginPaint((HWND)0, &ps);
|
||||
|
||||
StretchDIBits(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// POSIX compatibility support for posix.
|
||||
|
||||
#pragma once
|
||||
// posix.h - POSIX type and constant definitions for posix.dll
|
||||
// Covers just what open/read/write/close/lseek/spawn/pthread/chdir need.
|
||||
@@ -6,9 +8,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// errno
|
||||
// ---------------------------------------------------------------------------
|
||||
// errno.
|
||||
#ifdef errno
|
||||
#undef errno
|
||||
#endif
|
||||
@@ -59,9 +59,7 @@ extern int errno; // defined in posix_fd.c; single global in v1
|
||||
#define ETIMEDOUT 116
|
||||
#define ECONNRESET 104
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// open() flags
|
||||
// ---------------------------------------------------------------------------
|
||||
// open() flags.
|
||||
#define O_RDONLY 0x0000
|
||||
#define O_WRONLY 0x0001
|
||||
#define O_RDWR 0x0002
|
||||
@@ -69,25 +67,19 @@ extern int errno; // defined in posix_fd.c; single global in v1
|
||||
#define O_TRUNC 0x0200
|
||||
#define O_APPEND 0x0400
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// lseek() whence
|
||||
// ---------------------------------------------------------------------------
|
||||
// lseek() whence.
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Scalar types
|
||||
// ---------------------------------------------------------------------------
|
||||
// Scalar types.
|
||||
typedef int32_t pid_t;
|
||||
typedef int32_t off_t;
|
||||
typedef uint32_t mode_t;
|
||||
typedef int64_t ssize_t;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sockets
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sockets.
|
||||
typedef uint16_t sa_family_t;
|
||||
typedef uint16_t in_port_t;
|
||||
typedef uint32_t in_addr_t;
|
||||
@@ -195,25 +187,19 @@ __declspec(dllexport) struct hostent* gethostbyname(const char* name);
|
||||
__declspec(dllexport) int getaddrinfo(const char* node, const char* service, const struct addrinfo* hints, struct addrinfo** res);
|
||||
__declspec(dllexport) void freeaddrinfo(struct addrinfo* res);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// pthread types
|
||||
// ---------------------------------------------------------------------------
|
||||
// pthread types.
|
||||
typedef struct { uint32_t Tid; } pthread_t;
|
||||
typedef struct { uint32_t Handle; } pthread_mutex_t;
|
||||
typedef void* pthread_attr_t; // unused in v1
|
||||
typedef void* pthread_mutexattr_t;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// posix_spawn types (file_actions and attrp both ignored in v1)
|
||||
// ---------------------------------------------------------------------------
|
||||
// posix_spawn types (file_actions and attrp both ignored in v1).
|
||||
typedef void* posix_spawn_file_actions_t;
|
||||
typedef void* posix_spawnattr_t;
|
||||
|
||||
__declspec(dllexport) const char* posix_get_command_line(void);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// dirent (used by posix_dir.c)
|
||||
// ---------------------------------------------------------------------------
|
||||
// dirent (used by posix_dir.c).
|
||||
#define NAME_MAX 259
|
||||
|
||||
typedef struct dirent {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// posix_dir.c - chdir, getcwd, opendir, readdir, closedir
|
||||
// POSIX compatibility support for posix dir.
|
||||
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
#include <stdlib.h>
|
||||
@@ -10,6 +11,7 @@ typedef SYS_DIR_ENTRY KDIR_ENTRY;
|
||||
|
||||
#define KATTR_DIR 0x10
|
||||
|
||||
// Implements the chdir operation.
|
||||
__declspec(dllexport) int chdir(const char* path) {
|
||||
char native[512];
|
||||
PosixTranslatePath(path, native, sizeof(native));
|
||||
@@ -19,6 +21,7 @@ __declspec(dllexport) int chdir(const char* path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the getcwd operation.
|
||||
__declspec(dllexport) char* getcwd(char* buf, size_t size) {
|
||||
if (!buf || size == 0) { errno = EINVAL; return (char*)0; }
|
||||
char native[512];
|
||||
@@ -31,6 +34,7 @@ __declspec(dllexport) char* getcwd(char* buf, size_t size) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Implements the opendir operation.
|
||||
__declspec(dllexport) DIR* opendir(const char* path) {
|
||||
char native[512];
|
||||
PosixTranslatePath(path, native, sizeof(native));
|
||||
@@ -47,6 +51,7 @@ __declspec(dllexport) DIR* opendir(const char* path) {
|
||||
return d;
|
||||
}
|
||||
|
||||
// Implements the readdir operation.
|
||||
__declspec(dllexport) struct dirent* readdir(DIR* d) {
|
||||
if (!d) { errno = EBADF; return (struct dirent*)0; }
|
||||
KDIR_ENTRY ke;
|
||||
@@ -62,6 +67,7 @@ __declspec(dllexport) struct dirent* readdir(DIR* d) {
|
||||
return &d->Current;
|
||||
}
|
||||
|
||||
// Implements the closedir operation.
|
||||
__declspec(dllexport) int closedir(DIR* d) {
|
||||
if (!d) { errno = EBADF; return -1; }
|
||||
SysCloseHandle(d->KHandle);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// posix_fd.c - file descriptor table
|
||||
// POSIX compatibility support for posix fd.
|
||||
|
||||
#include <ntlite/syscall.h>
|
||||
#include "posix.h"
|
||||
#include "posix_fd.h"
|
||||
|
||||
int errno = 0;
|
||||
|
||||
// Implements the status To Errno operation.
|
||||
int PosixStatusToErrno(uint32_t s) {
|
||||
switch (s) {
|
||||
case 0x0000: return 0; // STATUS_SUCCESS
|
||||
@@ -26,6 +28,7 @@ int PosixStatusToErrno(uint32_t s) {
|
||||
|
||||
static FD_ENTRY gFdTable[FD_TABLE_PIDS][FD_MAX];
|
||||
|
||||
// Implements the fd Init operation.
|
||||
__declspec(dllexport) void PosixFdInit(void) {
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
uint32_t slot = pid % FD_TABLE_PIDS;
|
||||
@@ -40,6 +43,7 @@ __declspec(dllexport) void PosixFdInit(void) {
|
||||
gFdTable[slot][2] = (FD_ENTRY){ FD_CONSOLE_W, 0, true };
|
||||
}
|
||||
|
||||
// Implements the fd Alloc operation.
|
||||
__declspec(dllexport) int FdAlloc(uint32_t pid, FD_TYPE type, uint32_t khandle) {
|
||||
uint32_t slot = pid % FD_TABLE_PIDS;
|
||||
for (int fd = 3; fd < FD_MAX; fd++) {
|
||||
@@ -52,6 +56,7 @@ __declspec(dllexport) int FdAlloc(uint32_t pid, FD_TYPE type, uint32_t khandle)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Implements the fd Get operation.
|
||||
__declspec(dllexport) FD_ENTRY* FdGet(uint32_t pid, int fd) {
|
||||
if (fd < 0 || fd >= FD_MAX) { errno = EBADF; return (FD_ENTRY*)0; }
|
||||
uint32_t slot = pid % FD_TABLE_PIDS;
|
||||
@@ -60,6 +65,7 @@ __declspec(dllexport) FD_ENTRY* FdGet(uint32_t pid, int fd) {
|
||||
return e;
|
||||
}
|
||||
|
||||
// Implements the fd Free operation.
|
||||
__declspec(dllexport) void FdFree(uint32_t pid, int fd) {
|
||||
if (fd < 0 || fd >= FD_MAX) return;
|
||||
uint32_t slot = pid % FD_TABLE_PIDS;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// POSIX compatibility support for posix fd.
|
||||
|
||||
#pragma once
|
||||
// posix_fd.h - file descriptor table (internal to posix.dll)
|
||||
// posix_fd.h - file descriptor table (internal to posix.dll).
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// posix_io.c - open, read, write, close, lseek
|
||||
// POSIX compatibility support for posix io.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
@@ -6,14 +7,17 @@
|
||||
#include "posix_fd.h"
|
||||
#include "posix_path.h"
|
||||
|
||||
// Implements the clearscreen operation.
|
||||
__declspec(dllexport) void clearscreen(void) {
|
||||
SysClearScreen(0x012456);
|
||||
}
|
||||
|
||||
// Implements the clearkeyboard operation.
|
||||
__declspec(dllexport) void clearkeyboard(void) {
|
||||
while (SysPollKeyboard()) (void)SysReadKeyboardChar();
|
||||
}
|
||||
|
||||
// Opens the requested operation.
|
||||
__declspec(dllexport) int open(const char* path, int flags, ...) {
|
||||
char native[512];
|
||||
const char* p = PosixTranslatePath(path, native, sizeof(native));
|
||||
@@ -21,7 +25,7 @@ __declspec(dllexport) int open(const char* path, int flags, ...) {
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
FD_TYPE type = FD_FILE;
|
||||
|
||||
// Synthetic devices
|
||||
// Synthetic devices.
|
||||
if (strcmp(p, SYNTH_DEVNULL) == 0) {
|
||||
int fd = FdAlloc(pid, FD_DEVNULL, 0);
|
||||
return fd;
|
||||
@@ -53,6 +57,7 @@ __declspec(dllexport) int open(const char* path, int flags, ...) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
// Returns the requested value.
|
||||
__declspec(dllexport) ssize_t read(int fd, void* buf, size_t count) {
|
||||
if (count == 0) return 0;
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
@@ -92,6 +97,7 @@ __declspec(dllexport) ssize_t read(int fd, void* buf, size_t count) {
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the requested value.
|
||||
__declspec(dllexport) ssize_t write(int fd, const void* buf, size_t count) {
|
||||
if (count == 0) return 0;
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
@@ -125,6 +131,7 @@ __declspec(dllexport) ssize_t write(int fd, const void* buf, size_t count) {
|
||||
}
|
||||
}
|
||||
|
||||
// Releases the requested object.
|
||||
__declspec(dllexport) int close(int fd) {
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
FD_ENTRY* e = FdGet(pid, fd);
|
||||
@@ -135,6 +142,7 @@ __declspec(dllexport) int close(int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the unlink operation.
|
||||
__declspec(dllexport) int unlink(const char* path) {
|
||||
if (!path) { errno = EINVAL; return -1; }
|
||||
|
||||
@@ -152,6 +160,7 @@ __declspec(dllexport) int unlink(const char* path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the lseek operation.
|
||||
__declspec(dllexport) off_t lseek(int fd, off_t offset, int whence) {
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
FD_ENTRY* e = FdGet(pid, fd);
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
// posix_path.c - POSIX <-> native path translation
|
||||
// POSIX compatibility support for posix path.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "posix_path.h"
|
||||
|
||||
// Implements the flip Slashes operation.
|
||||
static void FlipSlashes(char* s) {
|
||||
for (; *s; s++) if (*s == '/') *s = '\\';
|
||||
}
|
||||
|
||||
// Checks whether drive Mount.
|
||||
static int IsDriveMount(const char* p) {
|
||||
return p && p[0] == '/' && p[1] >= '0' && p[1] <= '7' &&
|
||||
(p[2] == '\0' || p[2] == '/');
|
||||
@@ -50,6 +53,7 @@ const char* PosixTranslatePath(const char* in, char* out, size_t outSize) {
|
||||
return out;
|
||||
}
|
||||
|
||||
// Implements the native To Posix operation.
|
||||
void NativeToPosix(const char* in, char* out, size_t outSize) {
|
||||
if (!in || !out || outSize == 0) return;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// POSIX compatibility support for posix path.
|
||||
|
||||
#pragma once
|
||||
// posix_path.h - POSIX <-> native path translation
|
||||
// posix_path.h - POSIX <-> native path translation.
|
||||
|
||||
// SYNTHETIC sentinel returned from PosixTranslatePath for /dev/null and
|
||||
// /dev/zero; the caller must handle these before passing to any syscall.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// posix_proc.c - posix_spawn, waitpid, getpid
|
||||
// POSIX compatibility support for posix proc.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
@@ -8,18 +9,20 @@
|
||||
|
||||
static SYS_PEB* gProcessPeb = NULL;
|
||||
|
||||
// Implements the peb operation.
|
||||
static SYS_PEB* PosixPeb(void) {
|
||||
if (!gProcessPeb) gProcessPeb = SysGetPeb();
|
||||
return gProcessPeb;
|
||||
}
|
||||
|
||||
// Implements the posix get command line operation.
|
||||
__declspec(dllexport) const char* posix_get_command_line(void) {
|
||||
SYS_PEB* peb = PosixPeb();
|
||||
if (!peb || peb->Magic != SYS_PEB_MAGIC || !peb->CommandLine.Data) return "";
|
||||
return peb->CommandLine.Data;
|
||||
}
|
||||
|
||||
// pid -> proc handle table (user-mode side, for waitpid)
|
||||
// pid -> proc handle table (user-mode side, for waitpid).
|
||||
#define PROC_TABLE_SIZE 32
|
||||
typedef struct {
|
||||
pid_t pid;
|
||||
@@ -29,6 +32,7 @@ typedef struct {
|
||||
|
||||
static ProcEntry gProcTable[PROC_TABLE_SIZE];
|
||||
|
||||
// Implements the proc Table Insert operation.
|
||||
static void ProcTableInsert(pid_t pid, uint32_t handle) {
|
||||
for (int i = 0; i < PROC_TABLE_SIZE; i++) {
|
||||
if (!gProcTable[i].used) {
|
||||
@@ -39,6 +43,7 @@ static void ProcTableInsert(pid_t pid, uint32_t handle) {
|
||||
SysCloseHandle(handle);
|
||||
}
|
||||
|
||||
// Implements the proc Table Find operation.
|
||||
static uint32_t ProcTableFind(pid_t pid) {
|
||||
for (int i = 0; i < PROC_TABLE_SIZE; i++)
|
||||
if (gProcTable[i].used && gProcTable[i].pid == pid)
|
||||
@@ -46,6 +51,7 @@ static uint32_t ProcTableFind(pid_t pid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the proc Table Remove operation.
|
||||
static void ProcTableRemove(pid_t pid) {
|
||||
for (int i = 0; i < PROC_TABLE_SIZE; i++)
|
||||
if (gProcTable[i].used && gProcTable[i].pid == pid)
|
||||
@@ -72,9 +78,7 @@ static void BuildCmdline(char* const argv[], char* out, size_t outSize) {
|
||||
if (pos < outSize) out[pos] = '\0';
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// POSIX API
|
||||
// ---------------------------------------------------------------------------
|
||||
// POSIX API.
|
||||
|
||||
__declspec(dllexport) pid_t getpid(void) {
|
||||
return (pid_t)SysGetCurrentPid();
|
||||
@@ -133,6 +137,7 @@ __declspec(dllexport) pid_t waitpid(pid_t pid, int* status, int options) {
|
||||
return pid;
|
||||
}
|
||||
|
||||
// Implements the exit operation.
|
||||
__declspec(dllexport) void exit(int status) {
|
||||
SysExitProcess(status);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// posix_socket.c - POSIX-ish socket wrappers over native Sys* sockets.
|
||||
// POSIX compatibility support for posix socket.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -7,10 +8,12 @@
|
||||
#include "posix.h"
|
||||
#include "posix_fd.h"
|
||||
|
||||
// Implements the bswap16 operation.
|
||||
static uint16_t bswap16(uint16_t x) {
|
||||
return (uint16_t)((x << 8) | (x >> 8));
|
||||
}
|
||||
|
||||
// Implements the bswap32 operation.
|
||||
static uint32_t bswap32(uint32_t x) {
|
||||
return ((x & 0x000000FFu) << 24) |
|
||||
((x & 0x0000FF00u) << 8) |
|
||||
@@ -18,11 +21,16 @@ static uint32_t bswap32(uint32_t x) {
|
||||
((x & 0xFF000000u) >> 24);
|
||||
}
|
||||
|
||||
// Implements the htons operation.
|
||||
__declspec(dllexport) uint16_t htons(uint16_t x) { return bswap16(x); }
|
||||
// Implements the ntohs operation.
|
||||
__declspec(dllexport) uint16_t ntohs(uint16_t x) { return bswap16(x); }
|
||||
// Implements the htonl operation.
|
||||
__declspec(dllexport) uint32_t htonl(uint32_t x) { return bswap32(x); }
|
||||
// Implements the ntohl operation.
|
||||
__declspec(dllexport) uint32_t ntohl(uint32_t x) { return bswap32(x); }
|
||||
|
||||
// Parses byte.
|
||||
static int ParseByte(const char** p, uint8_t* out) {
|
||||
const char* s = *p;
|
||||
if (*s < '0' || *s > '9') return 0;
|
||||
@@ -37,6 +45,7 @@ static int ParseByte(const char** p, uint8_t* out) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Parses ipv4 Bytes.
|
||||
static int ParseIpv4Bytes(const char* text, uint8_t out[4]) {
|
||||
const char* p = text;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -49,6 +58,7 @@ static int ParseIpv4Bytes(const char* text, uint8_t out[4]) {
|
||||
return *p == '\0';
|
||||
}
|
||||
|
||||
// Implements the inet addr operation.
|
||||
__declspec(dllexport) in_addr_t inet_addr(const char* text) {
|
||||
uint8_t b[4];
|
||||
if (!text || !ParseIpv4Bytes(text, b)) return INADDR_NONE;
|
||||
@@ -58,6 +68,7 @@ __declspec(dllexport) in_addr_t inet_addr(const char* text) {
|
||||
return out;
|
||||
}
|
||||
|
||||
// Implements the inet ntoa operation.
|
||||
__declspec(dllexport) char* inet_ntoa(struct in_addr in) {
|
||||
static char buf[16];
|
||||
const uint8_t* p = (const uint8_t*)&in.s_addr;
|
||||
@@ -74,6 +85,7 @@ __declspec(dllexport) char* inet_ntoa(struct in_addr in) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Implements the sock Addr To Sys operation.
|
||||
static int SockAddrToSys(const struct sockaddr* addr, socklen_t addrlen, SYS_SOCKET_ADDRESS_IPV4* out) {
|
||||
if (!addr || !out || addrlen < sizeof(struct sockaddr_in)) { errno = EINVAL; return -1; }
|
||||
const struct sockaddr_in* in = (const struct sockaddr_in*)addr;
|
||||
@@ -90,6 +102,7 @@ static int SockAddrToSys(const struct sockaddr* addr, socklen_t addrlen, SYS_SOC
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the to Sock Addr operation.
|
||||
static void SysToSockAddr(const SYS_SOCKET_ADDRESS_IPV4* in, struct sockaddr* addr, socklen_t* addrlen) {
|
||||
if (!addr || !addrlen) return;
|
||||
if (*addrlen < sizeof(struct sockaddr_in)) {
|
||||
@@ -109,6 +122,7 @@ static void SysToSockAddr(const SYS_SOCKET_ADDRESS_IPV4* in, struct sockaddr* ad
|
||||
*addrlen = sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
// Implements the socket Fd Get operation.
|
||||
static FD_ENTRY* SocketFdGet(int fd) {
|
||||
FD_ENTRY* e = FdGet(SysGetCurrentPid(), fd);
|
||||
if (!e) return (FD_ENTRY*)0;
|
||||
@@ -116,6 +130,7 @@ static FD_ENTRY* SocketFdGet(int fd) {
|
||||
return e;
|
||||
}
|
||||
|
||||
// Implements the socket operation.
|
||||
__declspec(dllexport) int socket(int domain, int type, int protocol) {
|
||||
uint32_t kh = 0;
|
||||
uint32_t s = SysCreateSocket((uint32_t)domain, (uint32_t)type, (uint32_t)protocol, &kh);
|
||||
@@ -129,6 +144,7 @@ __declspec(dllexport) int socket(int domain, int type, int protocol) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
// Implements the bind operation.
|
||||
__declspec(dllexport) int bind(int fd, const struct sockaddr* addr, socklen_t addrlen) {
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
if (!e) return -1;
|
||||
@@ -139,6 +155,7 @@ __declspec(dllexport) int bind(int fd, const struct sockaddr* addr, socklen_t ad
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the listen operation.
|
||||
__declspec(dllexport) int listen(int fd, int backlog) {
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
if (!e) return -1;
|
||||
@@ -147,6 +164,7 @@ __declspec(dllexport) int listen(int fd, int backlog) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the accept operation.
|
||||
__declspec(dllexport) int accept(int fd, struct sockaddr* addr, socklen_t* addrlen) {
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
if (!e) return -1;
|
||||
@@ -167,6 +185,7 @@ __declspec(dllexport) int accept(int fd, struct sockaddr* addr, socklen_t* addrl
|
||||
return outfd;
|
||||
}
|
||||
|
||||
// Implements the connect operation.
|
||||
__declspec(dllexport) int connect(int fd, const struct sockaddr* addr, socklen_t addrlen) {
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
if (!e) return -1;
|
||||
@@ -177,6 +196,7 @@ __declspec(dllexport) int connect(int fd, const struct sockaddr* addr, socklen_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the send operation.
|
||||
__declspec(dllexport) ssize_t send(int fd, const void* buf, size_t len, int flags) {
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
if (!e) return -1;
|
||||
@@ -186,6 +206,7 @@ __declspec(dllexport) ssize_t send(int fd, const void* buf, size_t len, int flag
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
// Implements the recv operation.
|
||||
__declspec(dllexport) ssize_t recv(int fd, void* buf, size_t len, int flags) {
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
if (!e) return -1;
|
||||
@@ -240,6 +261,7 @@ __declspec(dllexport) ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
|
||||
return (ssize_t)got;
|
||||
}
|
||||
|
||||
// Implements the shutdown operation.
|
||||
__declspec(dllexport) int shutdown(int fd, int how) {
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
if (!e) return -1;
|
||||
@@ -248,12 +270,14 @@ __declspec(dllexport) int shutdown(int fd, int how) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the timeval To Ms operation.
|
||||
static uint32_t TimevalToMs(const struct timeval* tv) {
|
||||
if (!tv) return 0;
|
||||
uint64_t ms = (uint64_t)tv->tv_sec * 1000u + (uint64_t)(tv->tv_usec / 1000);
|
||||
return ms > 0xFFFFFFFFu ? 0xFFFFFFFFu : (uint32_t)ms;
|
||||
}
|
||||
|
||||
// Implements the setsockopt operation.
|
||||
__declspec(dllexport) int setsockopt(int fd, int level, int optname, const void* optval, socklen_t optlen) {
|
||||
if (level != SOL_SOCKET || !optval) { errno = EINVAL; return -1; }
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
@@ -285,6 +309,7 @@ __declspec(dllexport) int setsockopt(int fd, int level, int optname, const void*
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the getsockopt operation.
|
||||
__declspec(dllexport) int getsockopt(int fd, int level, int optname, void* optval, socklen_t* optlen) {
|
||||
if (level != SOL_SOCKET || !optval || !optlen) { errno = EINVAL; return -1; }
|
||||
FD_ENTRY* e = SocketFdGet(fd);
|
||||
@@ -322,6 +347,7 @@ __declspec(dllexport) int getsockopt(int fd, int level, int optname, void* optva
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Polls the requested operation.
|
||||
__declspec(dllexport) int poll(struct pollfd* fds, nfds_t nfds, int timeout) {
|
||||
if (!fds || nfds == 0 || nfds > 64) { errno = EINVAL; return -1; }
|
||||
|
||||
@@ -370,6 +396,7 @@ __declspec(dllexport) int poll(struct pollfd* fds, nfds_t nfds, int timeout) {
|
||||
return out;
|
||||
}
|
||||
|
||||
// Parses port.
|
||||
static unsigned ParsePort(const char* s) {
|
||||
unsigned v = 0;
|
||||
if (!s) return 0;
|
||||
@@ -381,6 +408,7 @@ static unsigned ParsePort(const char* s) {
|
||||
return *s == '\0' ? v : 0;
|
||||
}
|
||||
|
||||
// Implements the resolve Name Ipv4 operation.
|
||||
static int ResolveNameIpv4(const char* name, SYS_SOCKET_ADDRESS_IPV4* out) {
|
||||
uint8_t b[4];
|
||||
if (ParseIpv4Bytes(name, b)) {
|
||||
@@ -402,6 +430,7 @@ static int ResolveNameIpv4(const char* name, SYS_SOCKET_ADDRESS_IPV4* out) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the gethostbyname operation.
|
||||
__declspec(dllexport) struct hostent* gethostbyname(const char* name) {
|
||||
static struct hostent h;
|
||||
static char hname[256];
|
||||
@@ -467,6 +496,7 @@ __declspec(dllexport) int getaddrinfo(const char* node, const char* service,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the freeaddrinfo operation.
|
||||
__declspec(dllexport) void freeaddrinfo(struct addrinfo* res) {
|
||||
if (res) free(res);
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
// posix_thread.c - pthread_create, pthread_join, pthread_exit, pthread_mutex_*
|
||||
// POSIX compatibility support for posix thread.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <ntlite/syscall.h>
|
||||
#include "posix.h"
|
||||
|
||||
// Thread return-value table (PID-keyed like the fd table)
|
||||
// Thread return-value table (PID-keyed like the fd table).
|
||||
#define PTHREAD_TABLE_PIDS 32
|
||||
#define PTHREAD_TABLE_SIZE 32
|
||||
|
||||
@@ -16,6 +17,7 @@ typedef struct {
|
||||
|
||||
static PTHREAD_SLOT gPthreadTable[PTHREAD_TABLE_PIDS][PTHREAD_TABLE_SIZE];
|
||||
|
||||
// Implements the pthread Slot Alloc operation.
|
||||
static PTHREAD_SLOT* PthreadSlotAlloc(uint32_t pid, uint32_t tid) {
|
||||
PTHREAD_SLOT* table = gPthreadTable[pid % PTHREAD_TABLE_PIDS];
|
||||
for (int i = 0; i < PTHREAD_TABLE_SIZE; i++) {
|
||||
@@ -27,6 +29,7 @@ static PTHREAD_SLOT* PthreadSlotAlloc(uint32_t pid, uint32_t tid) {
|
||||
return (PTHREAD_SLOT*)0;
|
||||
}
|
||||
|
||||
// Implements the pthread Slot Find operation.
|
||||
static PTHREAD_SLOT* PthreadSlotFind(uint32_t pid, uint32_t tid) {
|
||||
PTHREAD_SLOT* table = gPthreadTable[pid % PTHREAD_TABLE_PIDS];
|
||||
for (int i = 0; i < PTHREAD_TABLE_SIZE; i++)
|
||||
@@ -35,15 +38,14 @@ static PTHREAD_SLOT* PthreadSlotFind(uint32_t pid, uint32_t tid) {
|
||||
return (PTHREAD_SLOT*)0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Trampoline - this is what actually runs as the new thread
|
||||
// ---------------------------------------------------------------------------
|
||||
// Trampoline - this is what actually runs as the new thread.
|
||||
typedef struct {
|
||||
void* (*Fn)(void*);
|
||||
void* Arg;
|
||||
uint32_t Pid; // owner pid, for the retval table
|
||||
} PTHREAD_TRAMP;
|
||||
|
||||
// Implements the pthread Trampoline operation.
|
||||
static void PthreadTrampoline(uintptr_t raw) {
|
||||
PTHREAD_TRAMP* tr = (PTHREAD_TRAMP*)raw;
|
||||
void* (*fn)(void*) = tr->Fn;
|
||||
@@ -67,9 +69,7 @@ static void PthreadTrampoline(uintptr_t raw) {
|
||||
SysExitThread(0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// pthread API
|
||||
// ---------------------------------------------------------------------------
|
||||
// pthread API.
|
||||
|
||||
__declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* attr,
|
||||
void* (*fn)(void*), void* arg) {
|
||||
@@ -85,7 +85,7 @@ __declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* att
|
||||
|
||||
uint32_t tid = 0;
|
||||
uint32_t s = SysCreateThread((uint64_t)PthreadTrampoline,
|
||||
(uint64_t)tr, 1 /*PriorityNormal*/, &tid);
|
||||
(uint64_t)tr, 1, &tid);
|
||||
if (s != 0) {
|
||||
free(tr);
|
||||
return EAGAIN;
|
||||
@@ -96,10 +96,11 @@ __declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* att
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the pthread join operation.
|
||||
__declspec(dllexport) int pthread_join(pthread_t t, void** retval) {
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
uint32_t s = SysWaitThread(t.Tid);
|
||||
// STATUS_NOT_FOUND (0x22) means already dead - treat as success
|
||||
// STATUS_NOT_FOUND (0x22) means already dead - treat as success.
|
||||
if (s != 0 && s != 0x0022) return ESRCH;
|
||||
|
||||
PTHREAD_SLOT* slot = PthreadSlotFind(pid, t.Tid);
|
||||
@@ -108,6 +109,7 @@ __declspec(dllexport) int pthread_join(pthread_t t, void** retval) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the pthread exit operation.
|
||||
__declspec(dllexport) void pthread_exit(void* retval) {
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
uint32_t tid = SysGetCurrentTid();
|
||||
@@ -117,6 +119,7 @@ __declspec(dllexport) void pthread_exit(void* retval) {
|
||||
while (1); // unreachable
|
||||
}
|
||||
|
||||
// Implements the pthread mutex init operation.
|
||||
__declspec(dllexport) int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr) {
|
||||
(void)attr;
|
||||
uint32_t h;
|
||||
@@ -126,22 +129,26 @@ __declspec(dllexport) int pthread_mutex_init(pthread_mutex_t* m, const pthread_m
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the pthread mutex destroy operation.
|
||||
__declspec(dllexport) int pthread_mutex_destroy(pthread_mutex_t* m) {
|
||||
SysCloseHandle(m->Handle);
|
||||
m->Handle = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the pthread mutex lock operation.
|
||||
__declspec(dllexport) int pthread_mutex_lock(pthread_mutex_t* m) {
|
||||
uint32_t s = SysAcquireMutex(m->Handle);
|
||||
return s == 0 ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
// Implements the pthread mutex trylock operation.
|
||||
__declspec(dllexport) int pthread_mutex_trylock(pthread_mutex_t* m) {
|
||||
uint32_t s = SysTryAcquireMutex(m->Handle);
|
||||
return s == 0 ? 0 : EAGAIN;
|
||||
}
|
||||
|
||||
// Implements the pthread mutex unlock operation.
|
||||
__declspec(dllexport) int pthread_mutex_unlock(pthread_mutex_t* m) {
|
||||
uint32_t s = SysReleaseMutex(m->Handle);
|
||||
return s == 0 ? 0 : EINVAL;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// gdi32.c
|
||||
// Win32 GDI compatibility stubs. This file provides enough drawing API surface for simple applications.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -10,9 +11,7 @@
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Win32 Base Types
|
||||
// ---------------------------------------------------------------------------
|
||||
// Win32 Base Types.
|
||||
typedef void* HDC;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned short WORD;
|
||||
@@ -23,14 +22,12 @@ typedef int BOOL;
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
// StretchDIBits Constants
|
||||
// StretchDIBits Constants.
|
||||
#define BI_RGB 0L
|
||||
#define DIB_RGB_COLORS 0
|
||||
#define SRCCOPY (DWORD)0x00CC0020
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GDI Structs
|
||||
// ---------------------------------------------------------------------------
|
||||
// GDI Structs.
|
||||
typedef struct tagBITMAPINFOHEADER {
|
||||
DWORD biSize;
|
||||
LONG biWidth;
|
||||
@@ -58,11 +55,9 @@ typedef struct tagBITMAPINFO {
|
||||
} BITMAPINFO;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GDI Exports
|
||||
// ---------------------------------------------------------------------------
|
||||
// GDI Exports.
|
||||
|
||||
// Static buffers to persist between function calls
|
||||
// Static buffers to persist between function calls.
|
||||
static uint32_t* destBuffer = NULL;
|
||||
static int* srcX_map = NULL;
|
||||
static int currentDestCapacity = 0;
|
||||
@@ -77,12 +72,12 @@ __declspec(dllexport) int StretchDIBits(
|
||||
{
|
||||
(void)hdc; (void)lpbmi; (void)iUsage; (void)rop;
|
||||
|
||||
// Safety check to prevent division by zero
|
||||
// Safety check to prevent division by zero.
|
||||
if (DestWidth <= 0 || DestHeight <= 0 || SrcWidth <= 0 || SrcHeight <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle trivial case (1:1 copy) to bypass allocation and scaling overhead
|
||||
// Handle trivial case (1:1 copy) to bypass allocation and scaling overhead.
|
||||
if (DestWidth == SrcWidth && DestHeight == SrcHeight && xSrc == 0 && ySrc == 0) {
|
||||
SysBlitScreen(xDest, yDest, DestWidth, DestHeight, (const uint32_t*)lpBits);
|
||||
return DestHeight;
|
||||
@@ -90,7 +85,7 @@ __declspec(dllexport) int StretchDIBits(
|
||||
|
||||
const uint32_t* srcPixels = (const uint32_t*)lpBits;
|
||||
|
||||
// Only reallocate if the new size is LARGER than what we already have
|
||||
// Only reallocate if the new size is LARGER than what we already have.
|
||||
int requiredPixels = DestWidth * DestHeight;
|
||||
if (requiredPixels > currentDestCapacity) {
|
||||
free(destBuffer);
|
||||
@@ -105,63 +100,63 @@ __declspec(dllexport) int StretchDIBits(
|
||||
}
|
||||
|
||||
for (int dx = 0; dx < DestWidth; ++dx) {
|
||||
// Nearest neighbor coordinate mapping
|
||||
// Nearest neighbor coordinate mapping.
|
||||
srcX_map[dx] = xSrc + (dx * SrcWidth) / DestWidth;
|
||||
|
||||
// Clamp to safe bounds
|
||||
// Clamp to safe bounds.
|
||||
if (srcX_map[dx] < 0) srcX_map[dx] = 0;
|
||||
if (srcX_map[dx] >= SrcWidth) srcX_map[dx] = SrcWidth - 1;
|
||||
}
|
||||
|
||||
// Process the image row by row
|
||||
// Process the image row by row.
|
||||
for (int dy = 0; dy < DestHeight; ++dy) {
|
||||
// Map destination Y to source Y
|
||||
// Map destination Y to source Y.
|
||||
int sy = ySrc + (dy * SrcHeight) / DestHeight;
|
||||
if (sy < 0) sy = 0;
|
||||
if (sy >= SrcHeight) sy = SrcHeight - 1;
|
||||
|
||||
// Assumes stride == SrcWidth (tightly packed 32bpp)
|
||||
// Assumes stride == SrcWidth (tightly packed 32bpp).
|
||||
const uint32_t* srcRow = srcPixels + (sy * SrcWidth);
|
||||
uint32_t* dstRow = destBuffer + (dy * DestWidth);
|
||||
|
||||
int dx = 0;
|
||||
|
||||
#if defined(__SSE2__) || defined(_M_X64)
|
||||
// Process 4 pixels (16 bytes) per loop iteration using SSE2
|
||||
// Process 4 pixels (16 bytes) per loop iteration using SSE2.
|
||||
for (; dx <= DestWidth - 4; dx += 4) {
|
||||
// Gather 4 source pixels using our precomputed X map.
|
||||
// Note: _mm_set_epi32 takes arguments in reverse order (3, 2, 1, 0)
|
||||
// Note: _mm_set_epi32 takes arguments in reverse order (3, 2, 1, 0).
|
||||
__m128i pixels = _mm_set_epi32(
|
||||
srcRow[srcX_map[dx + 3]],
|
||||
srcRow[srcX_map[dx + 2]],
|
||||
srcRow[srcX_map[dx + 1]],
|
||||
srcRow[srcX_map[dx + 0]]
|
||||
);
|
||||
// Issue a single 128-bit unaligned store
|
||||
// Issue a single 128-bit unaligned store.
|
||||
_mm_storeu_si128((__m128i*)&dstRow[dx], pixels);
|
||||
}
|
||||
#elif defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(_M_ARM64)
|
||||
// Process 4 pixels per loop iteration using ARM NEON
|
||||
// Process 4 pixels per loop iteration using ARM NEON.
|
||||
for (; dx <= DestWidth - 4; dx += 4) {
|
||||
// Initialize a vector and populate lanes (avoids stack-memory hop)
|
||||
// Initialize a vector and populate lanes (avoids stack-memory hop).
|
||||
uint32x4_t pixels = vdupq_n_u32(0);
|
||||
pixels = vsetq_lane_u32(srcRow[srcX_map[dx + 0]], pixels, 0);
|
||||
pixels = vsetq_lane_u32(srcRow[srcX_map[dx + 1]], pixels, 1);
|
||||
pixels = vsetq_lane_u32(srcRow[srcX_map[dx + 2]], pixels, 2);
|
||||
pixels = vsetq_lane_u32(srcRow[srcX_map[dx + 3]], pixels, 3);
|
||||
|
||||
// Issue a single 128-bit store
|
||||
// Issue a single 128-bit store.
|
||||
vst1q_u32(&dstRow[dx], pixels);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Epilogue: Handle remaining pixels if DestWidth isn't a multiple of 4
|
||||
// Epilogue: Handle remaining pixels if DestWidth isn't a multiple of 4.
|
||||
for (; dx < DestWidth; ++dx) {
|
||||
dstRow[dx] = srcRow[srcX_map[dx]];
|
||||
}
|
||||
}
|
||||
|
||||
// Direct mapping to kernel screen blit using the stretched buffer
|
||||
// Direct mapping to kernel screen blit using the stretched buffer.
|
||||
SysBlitScreen(xDest, yDest, DestWidth, DestHeight, destBuffer);
|
||||
|
||||
return DestHeight;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,13 +1,11 @@
|
||||
// ole32.c - Win32 COM / OLE stubs
|
||||
// No COM infrastructure at this stage; all functions fail gracefully.
|
||||
// Win32 OLE compatibility stubs. This file satisfies applications that probe COM initialization paths.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types.
|
||||
typedef long HRESULT;
|
||||
typedef void* IUnknown;
|
||||
|
||||
@@ -34,26 +32,23 @@ typedef struct {
|
||||
void* punkVal;
|
||||
unsigned char bVal;
|
||||
unsigned int ulVal;
|
||||
// ... (only common fields; full union is ~16 bytes)
|
||||
// ... (only common fields; full union is ~16 bytes).
|
||||
unsigned char padding[16];
|
||||
};
|
||||
} PROPVARIANT;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// COM initialisation
|
||||
// ---------------------------------------------------------------------------
|
||||
// COM initialisation.
|
||||
__declspec(dllexport) HRESULT CoInitializeEx(void* reserved, unsigned long coInit) {
|
||||
(void)reserved; (void)coInit;
|
||||
return S_OK; // Pretend success; no actual apartment is created.
|
||||
}
|
||||
|
||||
// Implements the co Uninitialize operation.
|
||||
__declspec(dllexport) void CoUninitialize(void) {
|
||||
// No-op.
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Object creation
|
||||
// ---------------------------------------------------------------------------
|
||||
// Object creation.
|
||||
__declspec(dllexport) HRESULT CoCreateInstance(const GUID* clsid, IUnknown* outer,
|
||||
unsigned long ctx, const GUID* iid,
|
||||
void** ppv) {
|
||||
@@ -62,16 +57,12 @@ __declspec(dllexport) HRESULT CoCreateInstance(const GUID* clsid, IUnknown* oute
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Memory
|
||||
// ---------------------------------------------------------------------------
|
||||
// Memory.
|
||||
__declspec(dllexport) void CoTaskMemFree(void* pv) {
|
||||
if (pv) free(pv);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// PROPVARIANT
|
||||
// ---------------------------------------------------------------------------
|
||||
// PROPVARIANT.
|
||||
__declspec(dllexport) HRESULT PropVariantClear(PROPVARIANT* pvar) {
|
||||
if (!pvar) return E_NOTIMPL;
|
||||
// Zero the entire structure; no deep release needed for stub types.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// user32.c - Win32 User Interface
|
||||
// Win32 user32 compatibility stubs. This file provides windowing and message APIs that applications may probe.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <ntlite/syscall.h>
|
||||
@@ -14,13 +15,14 @@ typedef struct tagPAINTSTRUCT {
|
||||
} PAINTSTRUCT;
|
||||
|
||||
|
||||
// Implements the user32 Debug Print A operation.
|
||||
static void User32DebugPrintA(const char* s) {
|
||||
if (!s) return;
|
||||
SYS_PRINT_DEBUG_REQUEST req = { SysSvFromCstr(s) };
|
||||
SysPrintDebug(&req);
|
||||
}
|
||||
|
||||
// --- Painting Functions ---
|
||||
// --- Painting Functions ---.
|
||||
__declspec(dllexport) HDC BeginPaint(HWND hwnd, PAINTSTRUCT* lpPaint) {
|
||||
(void)hwnd;
|
||||
if (lpPaint) {
|
||||
@@ -30,20 +32,24 @@ __declspec(dllexport) HDC BeginPaint(HWND hwnd, PAINTSTRUCT* lpPaint) {
|
||||
return (HDC)1;
|
||||
}
|
||||
|
||||
// Implements the end Paint operation.
|
||||
__declspec(dllexport) BOOL EndPaint(HWND hwnd, const PAINTSTRUCT* lp) { (void)hwnd; (void)lp; return 1; }
|
||||
|
||||
// --- Message Loop Stubs ---
|
||||
// --- Message Loop Stubs ---.
|
||||
__declspec(dllexport) int GetMessage(void* m, HWND h, uint32_t f, uint32_t l) {
|
||||
(void)m; (void)h; (void)f; (void)l; SysYield(); return 0;
|
||||
}
|
||||
// Returns message.
|
||||
__declspec(dllexport) int PeekMessage(void* m, HWND h, uint32_t f, uint32_t l, uint32_t r) {
|
||||
(void)m; (void)h; (void)f; (void)l; (void)r;
|
||||
return 0;
|
||||
}
|
||||
// Dispatches message.
|
||||
__declspec(dllexport) int DispatchMessage(const void* m) { (void)m; return 0; }
|
||||
// Translates message.
|
||||
__declspec(dllexport) int TranslateMessage(const void* m) { (void)m; return 0; }
|
||||
|
||||
// --- Dialogs & UI ---
|
||||
// --- Dialogs & UI ---.
|
||||
__declspec(dllexport) int MessageBoxA(HWND h, const char* txt, const char* cap, uint32_t type) {
|
||||
(void)h; (void)cap; (void)type;
|
||||
User32DebugPrintA("USER32: MessageBoxA: ");
|
||||
@@ -52,23 +58,29 @@ __declspec(dllexport) int MessageBoxA(HWND h, const char* txt, const char* cap,
|
||||
return 1; // IDOK
|
||||
}
|
||||
|
||||
// --- Window Queries ---
|
||||
// --- Window Queries ---.
|
||||
__declspec(dllexport) HWND GetDesktopWindow(void) { return (HWND)0; }
|
||||
// Returns active Window.
|
||||
__declspec(dllexport) HWND GetActiveWindow(void) { return (HWND)0; }
|
||||
// Returns top Window.
|
||||
__declspec(dllexport) HWND GetTopWindow(HWND hwnd){ (void)hwnd; return (HWND)0; }
|
||||
|
||||
// Returns window.
|
||||
__declspec(dllexport) HWND GetWindow(HWND hwnd, unsigned int cmd) {
|
||||
(void)hwnd; (void)cmd; return (HWND)0;
|
||||
}
|
||||
|
||||
// Returns window Long A.
|
||||
__declspec(dllexport) long GetWindowLongA(HWND hwnd, int index) {
|
||||
(void)hwnd; (void)index; return 0;
|
||||
}
|
||||
|
||||
// Returns window Long Ptr A.
|
||||
__declspec(dllexport) intptr_t GetWindowLongPtrA(HWND hwnd, int index) {
|
||||
(void)hwnd; (void)index; return 0;
|
||||
}
|
||||
|
||||
// Returns window Thread Process Id.
|
||||
__declspec(dllexport) unsigned long GetWindowThreadProcessId(HWND hwnd, unsigned long* pid) {
|
||||
(void)hwnd;
|
||||
if (pid) *pid = 1;
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// winmm.c - Win32 multimedia: waveform audio, timer
|
||||
// Stubs only; no audio hardware access at this stage.
|
||||
// Win32 multimedia compatibility stubs. This file provides minimal timing and sound API entry points.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types.
|
||||
typedef unsigned int MMRESULT;
|
||||
typedef void* HWAVEOUT;
|
||||
|
||||
@@ -48,17 +46,13 @@ typedef struct {
|
||||
} u;
|
||||
} MMTIME;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer.
|
||||
|
||||
__declspec(dllexport) unsigned long timeGetTime(void) {
|
||||
return (unsigned long)(SysGetTick() / 1000u);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Waveform audio (stubs - no audio hardware at this stage)
|
||||
// ---------------------------------------------------------------------------
|
||||
// Waveform audio (stubs - no audio hardware at this stage).
|
||||
|
||||
__declspec(dllexport) MMRESULT waveOutOpen(HWAVEOUT* phwo, unsigned int deviceId,
|
||||
const WAVEFORMATEX* fmt, uintptr_t callback,
|
||||
@@ -68,6 +62,7 @@ __declspec(dllexport) MMRESULT waveOutOpen(HWAVEOUT* phwo, unsigned int deviceId
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
// Implements the wave Out Close operation.
|
||||
__declspec(dllexport) MMRESULT waveOutClose(HWAVEOUT hwo) {
|
||||
(void)hwo; return MMSYSERR_NOERROR;
|
||||
}
|
||||
@@ -82,22 +77,27 @@ __declspec(dllexport) MMRESULT waveOutUnprepareHeader(HWAVEOUT hwo, WAVEHDR* hdr
|
||||
(void)hwo; (void)hdr; (void)size; return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
// Implements the wave Out Write operation.
|
||||
__declspec(dllexport) MMRESULT waveOutWrite(HWAVEOUT hwo, WAVEHDR* hdr, unsigned int size) {
|
||||
(void)hwo; (void)hdr; (void)size; return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
// Implements the wave Out Pause operation.
|
||||
__declspec(dllexport) MMRESULT waveOutPause(HWAVEOUT hwo) {
|
||||
(void)hwo; return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
// Implements the wave Out Restart operation.
|
||||
__declspec(dllexport) MMRESULT waveOutRestart(HWAVEOUT hwo) {
|
||||
(void)hwo; return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
// Implements the wave Out Reset operation.
|
||||
__declspec(dllexport) MMRESULT waveOutReset(HWAVEOUT hwo) {
|
||||
(void)hwo; return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
// Implements the wave Out Set Volume operation.
|
||||
__declspec(dllexport) MMRESULT waveOutSetVolume(HWAVEOUT hwo, unsigned long volume) {
|
||||
(void)hwo; (void)volume; return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
@@ -109,16 +109,15 @@ __declspec(dllexport) MMRESULT waveOutGetPosition(HWAVEOUT hwo, MMTIME* mmt,
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer resolution control
|
||||
// No hardware timer reprogramming at this stage; pretend success so callers
|
||||
// that wrap their audio/game loop in timeBeginPeriod(1) don't bail out.
|
||||
// ---------------------------------------------------------------------------
|
||||
__declspec(dllexport) MMRESULT timeBeginPeriod(unsigned int uPeriod) {
|
||||
(void)uPeriod;
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
// Implements the time End Period operation.
|
||||
__declspec(dllexport) MMRESULT timeEndPeriod(unsigned int uPeriod) {
|
||||
(void)uPeriod;
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// heap.c - user-mode page-backed heap
|
||||
// User-mode page-backed heap. This file owns segment allocation, block splitting, coalescing, and exported allocation primitives.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -8,11 +9,10 @@
|
||||
#define USER_HEAP_PAGE_SIZE 4096u
|
||||
#define USER_HEAP_MIN_PAGES 16u
|
||||
#define USER_HEAP_ALIGN 16u
|
||||
#define USER_HEAP_MAGIC 0x48424C4Bu /* KLBH */
|
||||
#define USER_HEAP_MAGIC 0x48424C4Bu // KLBH.
|
||||
|
||||
// The alignment mask must be pointer-sized because a 32-bit mask would truncate high user virtual addresses.
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
@@ -34,29 +34,35 @@ typedef struct HEAP_SEGMENT {
|
||||
static volatile long gHeapLock;
|
||||
static HEAP_SEGMENT* gSegments;
|
||||
|
||||
// Acquires the process-local heap lock.
|
||||
static void HeapLock(void) {
|
||||
while (_InterlockedCompareExchange(&gHeapLock, 1, 0) != 0)
|
||||
_mm_pause();
|
||||
_ReadWriteBarrier();
|
||||
}
|
||||
|
||||
// Releases the process-local heap lock.
|
||||
static void HeapUnlock(void) {
|
||||
_ReadWriteBarrier();
|
||||
_InterlockedExchange(&gHeapLock, 0);
|
||||
}
|
||||
|
||||
// Rounds requested allocation sizes up to the heap alignment while preserving non-zero allocation semantics.
|
||||
static size_t AlignSize(size_t size) {
|
||||
return ALIGN_UP(size ? size : 1, USER_HEAP_ALIGN);
|
||||
}
|
||||
|
||||
// Returns the user-visible payload address for a heap block.
|
||||
static void* BlockPayload(HEAP_BLOCK* block) {
|
||||
return (void*)((uint8_t*)block + sizeof(HEAP_BLOCK));
|
||||
}
|
||||
|
||||
// Returns the heap block header that owns a user-visible payload address.
|
||||
static HEAP_BLOCK* PayloadBlock(void* ptr) {
|
||||
return (HEAP_BLOCK*)((uint8_t*)ptr - sizeof(HEAP_BLOCK));
|
||||
}
|
||||
|
||||
// Finds the heap segment that contains a candidate payload pointer.
|
||||
static HEAP_SEGMENT* SegmentForPointer(void* ptr) {
|
||||
uintptr_t p = (uintptr_t)ptr;
|
||||
for (HEAP_SEGMENT* seg = gSegments; seg; seg = seg->Next) {
|
||||
@@ -68,6 +74,7 @@ static HEAP_SEGMENT* SegmentForPointer(void* ptr) {
|
||||
return (HEAP_SEGMENT*)0;
|
||||
}
|
||||
|
||||
// Splits a free block only when the tail can hold another aligned allocation.
|
||||
static void SplitBlock(HEAP_BLOCK* block, size_t size) {
|
||||
size_t aligned = AlignSize(size);
|
||||
if (block->Size < aligned + sizeof(HEAP_BLOCK) + USER_HEAP_ALIGN)
|
||||
@@ -85,6 +92,7 @@ static void SplitBlock(HEAP_BLOCK* block, size_t size) {
|
||||
block->Next = tail;
|
||||
}
|
||||
|
||||
// Implements the coalesce Block operation.
|
||||
static void CoalesceBlock(HEAP_BLOCK* block) {
|
||||
if (block->Next && block->Next->Magic == USER_HEAP_MAGIC && block->Next->Free) {
|
||||
HEAP_BLOCK* next = block->Next;
|
||||
@@ -101,6 +109,7 @@ static void CoalesceBlock(HEAP_BLOCK* block) {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the add Segment operation.
|
||||
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;
|
||||
@@ -130,6 +139,7 @@ static HEAP_SEGMENT* AddSegment(size_t payloadSize) {
|
||||
return seg;
|
||||
}
|
||||
|
||||
// Releases segment If Empty.
|
||||
static void RemoveSegmentIfEmpty(HEAP_SEGMENT* seg) {
|
||||
if (!seg || !seg->First || !seg->First->Free || seg->First->Prev || seg->First->Next)
|
||||
return;
|
||||
@@ -141,6 +151,7 @@ static void RemoveSegmentIfEmpty(HEAP_SEGMENT* seg) {
|
||||
SysFreeVm(seg);
|
||||
}
|
||||
|
||||
// Implements the malloc operation.
|
||||
void* _malloc(size_t size) {
|
||||
if (!size) return 0;
|
||||
size = AlignSize(size);
|
||||
@@ -166,6 +177,7 @@ void* _malloc(size_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
// Releases the requested object.
|
||||
void _free(void* ptr) {
|
||||
if (!ptr) return;
|
||||
|
||||
@@ -188,6 +200,7 @@ void _free(void* ptr) {
|
||||
HeapUnlock();
|
||||
}
|
||||
|
||||
// Implements the calloc operation.
|
||||
void* _calloc(size_t count, size_t size) {
|
||||
if (count && size > ((size_t)-1) / count)
|
||||
return 0;
|
||||
@@ -197,6 +210,7 @@ void* _calloc(size_t count, size_t size) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Implements the realloc operation.
|
||||
void* _realloc(void* ptr, size_t newSize) {
|
||||
if (!ptr) return _malloc(newSize);
|
||||
if (!newSize) {
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
// 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.
|
||||
// User-mode heap exports. This file exposes allocation entry points expected by user personality DLLs.
|
||||
|
||||
#ifdef USER_HEAP_EXPORTS
|
||||
#define HEAP_EXPORT __declspec(dllexport)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// init.c - first user-mode process
|
||||
// Init support.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@@ -6,24 +7,25 @@
|
||||
|
||||
#define STATUS_SUCCESS 0u
|
||||
|
||||
// Implements the itoa operation.
|
||||
void itoa(int num, char* str) {
|
||||
int i = 0;
|
||||
int is_negative = 0;
|
||||
|
||||
// Handle 0 explicitly
|
||||
// Handle 0 explicitly.
|
||||
if (num == 0) {
|
||||
str[i++] = '0';
|
||||
str[i] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle negative numbers
|
||||
// Handle negative numbers.
|
||||
if (num < 0) {
|
||||
is_negative = 1;
|
||||
num = -num;
|
||||
}
|
||||
|
||||
// Process individual digits (result is in reverse)
|
||||
// Process individual digits (result is in reverse).
|
||||
while (num != 0) {
|
||||
int rem = num % 10;
|
||||
str[i++] = rem + '0';
|
||||
@@ -36,7 +38,7 @@ void itoa(int num, char* str) {
|
||||
|
||||
str[i] = '\0'; // Null terminate
|
||||
|
||||
// Reverse the string
|
||||
// Reverse the string.
|
||||
int start = 0;
|
||||
int end = i - 1;
|
||||
while (start < end) {
|
||||
@@ -48,6 +50,7 @@ void itoa(int num, char* str) {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the debug print operation.
|
||||
static void debug_print(const char* s) {
|
||||
SYS_PRINT_DEBUG_REQUEST req = { SysSvFromCstr(s) };
|
||||
(void)SysPrintDebug(&req);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User-mode regression test for async_apc.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -7,16 +9,19 @@
|
||||
|
||||
#define EVENT_AUTO_RESET 0u
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Opens file.
|
||||
static uint32_t open_file(const char* path, uint32_t* handleOut) {
|
||||
SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut };
|
||||
return SysOpenFile(&req);
|
||||
}
|
||||
|
||||
// Prints hex8.
|
||||
static void print_hex8(uint8_t v) {
|
||||
static const char h[] = "0123456789ABCDEF";
|
||||
char b[3];
|
||||
@@ -26,6 +31,7 @@ static void print_hex8(uint8_t v) {
|
||||
print(b);
|
||||
}
|
||||
|
||||
// Prints u64.
|
||||
static void print_u64(uint64_t n) {
|
||||
char buf[32];
|
||||
int i = 0;
|
||||
@@ -46,6 +52,7 @@ typedef struct APC_TEST_STATE {
|
||||
volatile uint64_t Information;
|
||||
} APC_TEST_STATE;
|
||||
|
||||
// Implements the file apc operation.
|
||||
static void file_apc(void* context, SYS_IO_STATUS_BLOCK* iosb, uint64_t information) {
|
||||
APC_TEST_STATE* st = (APC_TEST_STATE*)context;
|
||||
st->Status = iosb ? iosb->Status : 0xFFFFFFFFu;
|
||||
@@ -54,6 +61,7 @@ static void file_apc(void* context, SYS_IO_STATUS_BLOCK* iosb, uint64_t informat
|
||||
do { SYS_PRINT_DEBUG_REQUEST req = { SYS_SV_LITERAL("async_apc: user APC callback ran\n") }; SysPrintDebug(&req); } while (0);
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
print("async_apc: start\n");
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User-mode regression test for async_cancel.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -6,16 +8,19 @@
|
||||
|
||||
#define EVENT_AUTO_RESET 0u
|
||||
|
||||
// Prints the requested operation.
|
||||
static void print(const char* s) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Opens file.
|
||||
static uint32_t open_file(const char* path, uint32_t* handleOut) {
|
||||
SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut };
|
||||
return SysOpenFile(&req);
|
||||
}
|
||||
|
||||
// Prints u64.
|
||||
static void print_u64(uint64_t v) {
|
||||
char buf[32];
|
||||
int i = 0;
|
||||
@@ -33,6 +38,7 @@ static void print_u64(uint64_t v) {
|
||||
}
|
||||
}
|
||||
|
||||
// Runs the requested operation.
|
||||
int main(void) {
|
||||
print("async_cancel: start\n");
|
||||
|
||||
|
||||
Reference in new issue
Block a user