windows stuff

This commit is contained in:
alessandro bason 2025-10-11 20:35:40 +02:00
parent 7e7c371b9e
commit ae3536529b
3 changed files with 587 additions and 106 deletions

View file

@ -15,6 +15,50 @@
#endif
#endif
#ifndef PROCESSOR_ARCHITECTURE_ARM64
#define PROCESSOR_ARCHITECTURE_ARM64 12
#endif
const char win32__fg_colours[LOG_COL__COUNT][6] = {
[LOG_COL_RESET] = "\x1b[39m",
[LOG_COL_BLACK] = "\x1b[30m",
[LOG_COL_RED] = "\x1b[31m",
[LOG_COL_GREEN] = "\x1b[32m",
[LOG_COL_YELLOW] = "\x1b[33m",
[LOG_COL_BLUE] = "\x1b[34m",
[LOG_COL_MAGENTA] = "\x1b[35m",
[LOG_COL_CYAN] = "\x1b[36m",
[LOG_COL_WHITE] = "\x1b[37m",
[LOG_COL_DARK_GREY] = "\x1b[90m",
[LOG_COL_LIGHT_RED] = "\x1b[91m",
[LOG_COL_LIGHT_GREEN] = "\x1b[92m",
[LOG_COL_LIGHT_YELLOW] = "\x1b[93m",
[LOG_COL_LIGHT_BLUE] = "\x1b[94m",
[LOG_COL_LIGHT_MAGENTA] = "\x1b[95m",
[LOG_COL_LIGHT_CYAN] = "\x1b[96m",
};
const char win32__bg_colours[LOG_COL__COUNT][7] = {
[LOG_COL_RESET] = "\x1b[49m",
[LOG_COL_BLACK] = "\x1b[40m",
[LOG_COL_RED] = "\x1b[41m",
[LOG_COL_GREEN] = "\x1b[42m",
[LOG_COL_YELLOW] = "\x1b[43m",
[LOG_COL_BLUE] = "\x1b[44m",
[LOG_COL_MAGENTA] = "\x1b[45m",
[LOG_COL_CYAN] = "\x1b[46m",
[LOG_COL_WHITE] = "\x1b[47m",
[LOG_COL_DARK_GREY] = "\x1b[100m",
[LOG_COL_LIGHT_RED] = "\x1b[101m",
[LOG_COL_LIGHT_GREEN] = "\x1b[102m",
[LOG_COL_LIGHT_YELLOW] = "\x1b[103m",
[LOG_COL_LIGHT_BLUE] = "\x1b[104m",
[LOG_COL_LIGHT_MAGENTA] = "\x1b[105m",
[LOG_COL_LIGHT_CYAN] = "\x1b[106m",
};
void os__log_init(void);
str_t str_os_from_str16(arena_t *arena, str16_t src) {
str_t out = {0};
@ -144,11 +188,20 @@ void os_init(void) {
SYSTEM_INFO sysinfo = {0};
GetSystemInfo(&sysinfo);
os_arch_e architectures[] = {
[PROCESSOR_ARCHITECTURE_INTEL] = OS_ARCH_X86,
[PROCESSOR_ARCHITECTURE_ARM] = OS_ARCH_ARM,
[PROCESSOR_ARCHITECTURE_IA64] = OS_ARCH_IA64,
[PROCESSOR_ARCHITECTURE_AMD64] = OS_ARCH_AMD64,
[PROCESSOR_ARCHITECTURE_ARM64] = OS_ARCH_ARM64,
};
os_system_info_t *info = &w32_data.info;
info->processor_count = (u64)sysinfo.dwNumberOfProcessors;
info->page_size = sysinfo.dwPageSize;
info->architecture = architectures[sysinfo.wProcessorArchitecture];
w32_data.arena = arena_make(ARENA_VIRTUAL, OS_ARENA_SIZE);
w32_data.arena = arena_make(ARENA_VIRTUAL, COLLA_OS_ARENA_SIZE);
TCHAR namebuf[MAX_COMPUTERNAME_LENGTH + 1];
DWORD namebuflen = sizeof(namebuf);
@ -176,6 +229,7 @@ void os_init(void) {
else {
err("couldn't get console screen buffer info: %v", os_get_error_string(os_get_last_error()));
}
os__log_init();
}
void os_cleanup(void) {
@ -187,7 +241,9 @@ void os_cleanup(void) {
void os_abort(int code) {
#if COLLA_DEBUG
if (code != 0) abort();
if (code != 0) {
__debugbreak();
}
#endif
ExitProcess(code);
}
@ -218,8 +274,8 @@ str_t os_get_error_string(iptr error) {
}
os_wait_t os_wait_on_handles(oshandle_t *handles, int count, bool wait_all, u32 milliseconds) {
HANDLE win_handles[OS_MAX_WAITABLE_HANDLES] = {0};
colla_assert(count < MAXIMUM_WAIT_OBJECTS);
HANDLE win_handles[COLLA_OS_MAX_WAITABLE_HANDLES] = {0};
colla_assert(count < COLLA_OS_MAX_WAITABLE_HANDLES);
for (int i = 0; i < count; ++i) {
win_handles[i] = (HANDLE)(handles[i].data);
@ -252,16 +308,12 @@ os_system_info_t os_get_system_info(void) {
}
void os_log_set_colour(os_log_colour_e colour) {
WORD attribute = colour == LOG_COL_RESET ? w32_data.default_fg : (WORD)colour;
SetConsoleTextAttribute((HANDLE)w32_data.hstdout.data, attribute);
WriteFile((HANDLE)w32_data.hstdout.data, win32__fg_colours[colour], arrlen(win32__fg_colours[colour]), NULL, NULL);
}
void os_log_set_colour_bg(os_log_colour_e foreground, os_log_colour_e background) {
WORD fg_attr = foreground == LOG_COL_RESET ? w32_data.default_fg : (WORD)foreground;
WORD bg_attr = (background == LOG_COL_RESET ? w32_data.default_bg : (WORD)background) << 4;
WORD attribute = fg_attr | bg_attr;
SetConsoleTextAttribute((HANDLE)w32_data.hstdout.data, attribute);
WriteFile((HANDLE)w32_data.hstdout.data, win32__fg_colours[foreground], arrlen(win32__fg_colours[foreground]), NULL, NULL);
WriteFile((HANDLE)w32_data.hstdout.data, win32__bg_colours[background], arrlen(win32__bg_colours[background]), NULL, NULL);
}
oshandle_t os_stdout(void) {
@ -456,16 +508,20 @@ u64 os_file_time_fp(oshandle_t handle) {
// == DIR WALKER ================================
typedef struct dir_t {
WIN32_FIND_DATA find_data;
WIN32_FIND_DATAW find_data;
HANDLE handle;
dir_entry_t cur_entry;
dir_entry_t next_entry;
} dir_t;
dir_entry_t os__dir_entry_from_find_data(arena_t *arena, WIN32_FIND_DATA *fd) {
dir_entry_t os__dir_entry_from_find_data(arena_t *arena, WIN32_FIND_DATAW *fd) {
dir_entry_t out = {0};
out.name = str_from_tstr(arena, tstr_init(fd->cFileName, 0));
out.name = str_from_str16(arena, str16_init(fd->cFileName, 0));
if (strv_equals(strv(out.name), strv("cygwin"))) {
out.type = 0;
}
if (fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
out.type = DIRTYPE_DIR;
@ -482,33 +538,30 @@ dir_entry_t os__dir_entry_from_find_data(arena_t *arena, WIN32_FIND_DATA *fd) {
}
dir_t *os_dir_open(arena_t *arena, strview_t path) {
usize prev = arena_tell(arena);
dir_t* ctx = alloc(arena, dir_t);
arena_t scratch = *arena;
#if 0
u8 tmpbuf[KB(1)] = {0};
arena_t scratch = arena_make(ARENA_STATIC, sizeof(tmpbuf), tmpbuf);
#endif
str16_t winpath = strv_to_str16(&scratch, path);
DWORD pathlen = GetFullPathNameW(winpath.buf, 0, NULL, NULL);
WCHAR *fullpath = alloc(&scratch, WCHAR, pathlen + 10);
tstr_t winpath = strv_to_tstr(&scratch, path);
// get a little extra leeway
TCHAR fullpath[MAX_PATH + 16] = {0};
DWORD pathlen = GetFullPathName(winpath.buf, MAX_PATH, fullpath, NULL);
// add asterisk at the end of the path
if (fullpath[pathlen] != '\\' && fullpath[pathlen] != '/') {
fullpath[pathlen++] = '\\';
pathlen = GetFullPathNameW(winpath.buf, pathlen + 1, fullpath, NULL);
if (fullpath[pathlen] != L'\\' && fullpath[pathlen] != L'/') {
fullpath[pathlen++] = L'\\';
}
fullpath[pathlen++] = '*';
fullpath[pathlen++] = '\0';
fullpath[pathlen++] = L'*';
ctx->handle = FindFirstFile(fullpath, &ctx->find_data);
WIN32_FIND_DATAW first = {0};
HANDLE handle = FindFirstFileW(fullpath, &first);
if (ctx->handle == INVALID_HANDLE_VALUE) {
arena_rewind(arena, prev);
if (handle == INVALID_HANDLE_VALUE) {
return NULL;
}
dir_t *ctx = alloc(arena, dir_t);
ctx->handle = handle;
ctx->find_data = first;
ctx->next_entry = os__dir_entry_from_find_data(arena, &ctx->find_data);
return ctx;
@ -530,13 +583,18 @@ dir_entry_t *os_dir_next(arena_t *arena, dir_t *dir) {
dir->cur_entry = dir->next_entry;
dir->next_entry = (dir_entry_t){0};
if (FindNextFile(dir->handle, &dir->find_data)) {
while (true) {
dir->next_entry = (dir_entry_t){0};
if (!FindNextFileW(dir->handle, &dir->find_data)) {
os_dir_close(dir);
break;
}
// HACK: skip system files/directories
if (dir->find_data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {
continue;
}
dir->next_entry = os__dir_entry_from_find_data(arena, &dir->find_data);
}
else {
os_dir_close(dir);
break;
}
return &dir->cur_entry;
@ -956,7 +1014,7 @@ http_res_t http_request_cb(http_request_desc_t *req, http_request_callback_fn ca
(DWORD_PTR)NULL // userdata
);
if (!connection) {
err("call to InternetConnect failed: %u", os_get_error_string(os_get_last_error()));
err("call to InternetConnect failed: %u", os_get_last_error());
goto failed;
}
@ -1014,7 +1072,6 @@ http_res_t http_request_cb(http_request_desc_t *req, http_request_callback_fn ca
// buffer is not big enough, allocate one with the arena instead
if (!result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
info("buffer is too small");
buffer = alloc(req->arena, u8, bufsize + 1);
result = HttpQueryInfo(request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer, &bufsize, NULL);
}