diff --git a/README.md b/README.md index f7256c7..1f61af9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Brew OS 1.43 Beta +# Brew OS 1.44 Beta BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable. ## Brewkernel is now BrewOS! diff --git a/brewos.iso b/brewos.iso index 0f8a015..bce38cc 100644 Binary files a/brewos.iso and b/brewos.iso differ diff --git a/build/about.o b/build/about.o index 98c6712..d1a563a 100644 Binary files a/build/about.o and b/build/about.o differ diff --git a/build/brewos.elf b/build/brewos.elf index 9de5e19..b835dc1 100755 Binary files a/build/brewos.elf and b/build/brewos.elf differ diff --git a/build/calculator.o b/build/calculator.o index 94f1433..f59d671 100644 Binary files a/build/calculator.o and b/build/calculator.o differ diff --git a/build/cli_apps/about.o b/build/cli_apps/about.o index fc2b700..f835ab7 100644 Binary files a/build/cli_apps/about.o and b/build/cli_apps/about.o differ diff --git a/build/cli_apps/net.o b/build/cli_apps/net.o index 0e8518f..a4fc647 100644 Binary files a/build/cli_apps/net.o and b/build/cli_apps/net.o differ diff --git a/build/cmd.o b/build/cmd.o index 902e322..644eb7e 100644 Binary files a/build/cmd.o and b/build/cmd.o differ diff --git a/build/explorer.o b/build/explorer.o index 0533de6..cc74a93 100644 Binary files a/build/explorer.o and b/build/explorer.o differ diff --git a/build/fat32.o b/build/fat32.o index d0f30ef..047caa3 100644 Binary files a/build/fat32.o and b/build/fat32.o differ diff --git a/build/graphics.o b/build/graphics.o index c7c9a63..a5f33cf 100644 Binary files a/build/graphics.o and b/build/graphics.o differ diff --git a/build/markdown.o b/build/markdown.o index e54cb0c..f7a09ed 100644 Binary files a/build/markdown.o and b/build/markdown.o differ diff --git a/build/memory_manager.o b/build/memory_manager.o index 7ee93e5..94251a6 100644 Binary files a/build/memory_manager.o and b/build/memory_manager.o differ diff --git a/build/tcp.o b/build/tcp.o index e99ca42..204675a 100644 Binary files a/build/tcp.o and b/build/tcp.o differ diff --git a/build/wm.o b/build/wm.o index ba5e8d3..3e1e4f9 100644 Binary files a/build/wm.o and b/build/wm.o differ diff --git a/iso_root/README.md b/iso_root/README.md index f7256c7..1f61af9 100644 --- a/iso_root/README.md +++ b/iso_root/README.md @@ -1,4 +1,4 @@ -# Brew OS 1.43 Beta +# Brew OS 1.44 Beta BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable. ## Brewkernel is now BrewOS! diff --git a/iso_root/brewos.elf b/iso_root/brewos.elf index 9de5e19..b835dc1 100755 Binary files a/iso_root/brewos.elf and b/iso_root/brewos.elf differ diff --git a/iso_root/limine.cfg b/iso_root/limine.cfg index 66ca4be..dc8d714 100644 --- a/iso_root/limine.cfg +++ b/iso_root/limine.cfg @@ -1,12 +1,8 @@ -# Timeout in seconds that Limine will wait before automatically booting. TIMEOUT=3 -# The entry name that will be displayed in the boot menu. :BrewOS - # We use the Limine boot protocol. PROTOCOL=limine - # Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located. KERNEL_PATH=boot:///brewos.elf #FRAMEBUFFER_WIDTH=1280 diff --git a/limine.cfg b/limine.cfg index 66ca4be..dc8d714 100644 --- a/limine.cfg +++ b/limine.cfg @@ -1,12 +1,8 @@ -# Timeout in seconds that Limine will wait before automatically booting. TIMEOUT=3 -# The entry name that will be displayed in the boot menu. :BrewOS - # We use the Limine boot protocol. PROTOCOL=limine - # Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located. KERNEL_PATH=boot:///brewos.elf #FRAMEBUFFER_WIDTH=1280 diff --git a/linker.ld b/linker.ld index a593f55..ea360c0 100644 --- a/linker.ld +++ b/linker.ld @@ -1,14 +1,10 @@ -/* Tell the linker that we want an x86_64 ELF64 output file */ OUTPUT_FORMAT(elf64-x86-64) OUTPUT_ARCH(i386:x86-64) -/* We want the symbol _start to be our entry point */ ENTRY(_start) -/* Define the memory layout for the kernel */ SECTIONS { - /* We want to be loaded in the upper half of memory */ . = 0xffffffff80000000; .text : { diff --git a/src/kernel/about.c b/src/kernel/about.c index 85fd729..cc4fb0d 100644 --- a/src/kernel/about.c +++ b/src/kernel/about.c @@ -32,7 +32,7 @@ static void about_paint(Window *win) { // Version info draw_string(offset_x, offset_y + 105, "BrewOS", COLOR_BLACK); - draw_string(offset_x, offset_y + 120, "BrewOS Version 1.43", COLOR_BLACK); + draw_string(offset_x, offset_y + 120, "BrewOS Version 1.44", COLOR_BLACK); draw_string(offset_x, offset_y + 135, "Kernel Version 2.3.1", COLOR_BLACK); // Copyright diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index 598878d..f45af19 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -11,7 +11,6 @@ _start: ; Ensure interrupts are disabled cli - ; Setup stack is handled by Limine, but we can re-align if paranoid ; (Limine guarantees 16-byte alignment) ; Call the C kernel entry point diff --git a/src/kernel/calculator.c b/src/kernel/calculator.c index e8d3f8e..986c1c7 100644 --- a/src/kernel/calculator.c +++ b/src/kernel/calculator.c @@ -60,7 +60,6 @@ static void fixed_to_str(long long n, char *buf) { } frac_buf[f_idx] = 0; - // If we have a fraction, add it to buffer (reversed first) if (f_idx > 0) { for (int i = f_idx - 1; i >= 0; i--) { temp[pos++] = frac_buf[i]; diff --git a/src/kernel/cli_apps/about.c b/src/kernel/cli_apps/about.c index eaadde4..6629695 100644 --- a/src/kernel/cli_apps/about.c +++ b/src/kernel/cli_apps/about.c @@ -2,6 +2,6 @@ void cli_cmd_brewver(char *args) { (void)args; - cli_write("BrewOS v1.43 Beta\n"); + cli_write("BrewOS v1.44 Beta\n"); cli_write("BrewOS Kernel V2.3.1 Beta\n"); } diff --git a/src/kernel/cli_apps/net.c b/src/kernel/cli_apps/net.c index 20fcdcd..4c6ab26 100644 --- a/src/kernel/cli_apps/net.c +++ b/src/kernel/cli_apps/net.c @@ -140,7 +140,6 @@ void cli_cmd_udptest(char *args){ void cli_cmd_msgrc(char *args) { (void)args; - // Reset message count since we are viewing them cmd_reset_msg_count(); FAT32_FileHandle *fh = fat32_open("messages", "r"); diff --git a/src/kernel/cmd.c b/src/kernel/cmd.c index 4fcd5ee..6e2231e 100644 --- a/src/kernel/cmd.c +++ b/src/kernel/cmd.c @@ -957,7 +957,7 @@ static void create_test_files(void) { fh = fat32_open("README.md", "w"); if (fh) { const char *content = - "# Brew OS 1.40 Beta\n\n" + "# Brew OS 1.44 Beta\n\n" "BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable.\n" "## Brewkernel is now BrewOS!\n" "Brewkernel will from now on be deprecated as it's core became too messy. I have built a less bloated kernel and wrote a DE above it, which is why it is now an OS instead of a kernel (in my opinion).\n\n" diff --git a/src/kernel/explorer.c b/src/kernel/explorer.c index e7e8e3f..0d93ed6 100644 --- a/src/kernel/explorer.c +++ b/src/kernel/explorer.c @@ -75,7 +75,7 @@ static void explorer_handle_right_click(Window *win, int x, int y); static void explorer_handle_file_context_menu_click(Window *win, int x, int y); static void explorer_perform_paste(Window *win, const char *dest_dir); static void explorer_perform_move_internal(Window *win, const char *source_path, const char *dest_dir); -static void explorer_copy_recursive(const char *src_path, const char *dest_path); +static bool explorer_copy_recursive(const char *src_path, const char *dest_path); Window* explorer_create_window(const char *path); extern bool is_dragging_file; @@ -433,11 +433,11 @@ bool explorer_clipboard_has_content(void) { return clipboard_action != 0 && clipboard_path[0] != 0; } -static void explorer_copy_recursive(const char *src_path, const char *dest_path) { +static bool explorer_copy_recursive(const char *src_path, const char *dest_path) { if (fat32_is_directory(src_path)) { - fat32_mkdir(dest_path); + if (!fat32_mkdir(dest_path)) return false; FAT32_FileInfo *files = (FAT32_FileInfo*)kmalloc(64 * sizeof(FAT32_FileInfo)); - if (!files) return; + if (!files) return false; int count = fat32_list_directory(src_path, files, 64); for (int i = 0; i < count; i++) { @@ -452,23 +452,29 @@ static void explorer_copy_recursive(const char *src_path, const char *dest_path) if (d_sub[explorer_strlen(d_sub)-1] != '/') explorer_strcat(d_sub, "/"); explorer_strcat(d_sub, files[i].name); - explorer_copy_recursive(s_sub, d_sub); + if (!explorer_copy_recursive(s_sub, d_sub)) { kfree(files); return false; } } kfree(files); + return true; } else { // Copy file FAT32_FileHandle *src = fat32_open(src_path, "r"); FAT32_FileHandle *dst = fat32_open(dest_path, "w"); + bool success = false; if (src && dst) { uint8_t *buf = (uint8_t*)kmalloc(4096); if (buf) { int bytes; - while ((bytes = fat32_read(src, buf, 4096)) > 0) fat32_write(dst, buf, bytes); + success = true; + while ((bytes = fat32_read(src, buf, 4096)) > 0) { + if (fat32_write(dst, buf, bytes) != bytes) { success = false; break; } + } kfree(buf); } } if (src) fat32_close(src); if (dst) fat32_close(dst); + return success; } } @@ -513,8 +519,16 @@ void explorer_clipboard_paste(Window *win, const char *dest_dir) { ExplorerState *state = (ExplorerState*)win->data; if (!explorer_clipboard_has_content()) return; + // Prevent pasting a directory into itself or its subdirectories + if (explorer_str_starts_with(dest_dir, clipboard_path)) { + int src_len = explorer_strlen(clipboard_path); + if (dest_dir[src_len] == '\0' || dest_dir[src_len] == '/') { + return; + } + } + // Check for collision - char filename[256]; + char filename[FAT32_MAX_FILENAME]; int len = explorer_strlen(clipboard_path); int i = len - 1; while (i >= 0 && clipboard_path[i] != '/') i--; @@ -522,7 +536,7 @@ void explorer_clipboard_paste(Window *win, const char *dest_dir) { for (int k = i + 1; k < len; k++) filename[j++] = clipboard_path[k]; filename[j] = 0; - char dest_path[256]; + char dest_path[FAT32_MAX_PATH]; explorer_strcpy(dest_path, dest_dir); if (dest_path[explorer_strlen(dest_path) - 1] != '/') { explorer_strcat(dest_path, "/"); @@ -1760,7 +1774,7 @@ void explorer_refresh_all(void) { static void explorer_perform_move_internal(Window *win, const char *source_path, const char *dest_dir) { (void)win; // 1. Extract filename - char filename[256]; + char filename[FAT32_MAX_FILENAME]; int len = explorer_strlen(source_path); int i = len - 1; while (i >= 0 && source_path[i] != '/') i--; @@ -1769,7 +1783,7 @@ static void explorer_perform_move_internal(Window *win, const char *source_path, filename[j] = 0; // 2. Build dest path - char dest_path[256]; + char dest_path[FAT32_MAX_PATH]; explorer_strcpy(dest_path, dest_dir); if (dest_path[explorer_strlen(dest_path) - 1] != '/') { explorer_strcat(dest_path, "/"); @@ -1782,7 +1796,7 @@ static void explorer_perform_move_internal(Window *win, const char *source_path, } if (explorer_str_starts_with(dest_path, "/RecycleBin") && !explorer_str_starts_with(source_path, "/RecycleBin")) { - char origin_path[256]; + char origin_path[FAT32_MAX_PATH]; explorer_strcpy(origin_path, dest_path); explorer_strcat(origin_path, ".origin"); FAT32_FileHandle *fh = fat32_open(origin_path, "w"); @@ -1793,16 +1807,16 @@ static void explorer_perform_move_internal(Window *win, const char *source_path, } if (!explorer_str_starts_with(dest_path, "/RecycleBin") && explorer_str_starts_with(source_path, "/RecycleBin")) { - char origin_path[256]; + char origin_path[FAT32_MAX_PATH]; explorer_strcpy(origin_path, source_path); explorer_strcat(origin_path, ".origin"); fat32_delete(origin_path); } - explorer_copy_recursive(source_path, dest_path); - - // 4. Delete source (Move operation) - explorer_delete_permanently(source_path); + if (explorer_copy_recursive(source_path, dest_path)) { + // 4. Delete source (Move operation) + explorer_delete_permanently(source_path); + } // Refresh explorer_refresh_all(); @@ -1810,8 +1824,17 @@ static void explorer_perform_move_internal(Window *win, const char *source_path, void explorer_import_file_to(Window *win, const char *source_path, const char *dest_dir) { ExplorerState *state = (ExplorerState*)win->data; + + // Prevent moving a directory into itself or its subdirectories + if (explorer_str_starts_with(dest_dir, source_path)) { + int src_len = explorer_strlen(source_path); + if (dest_dir[src_len] == '\0' || dest_dir[src_len] == '/') { + return; + } + } + // Check for collision - char filename[256]; + char filename[FAT32_MAX_FILENAME]; int len = explorer_strlen(source_path); int i = len - 1; while (i >= 0 && source_path[i] != '/') i--; @@ -1819,7 +1842,7 @@ void explorer_import_file_to(Window *win, const char *source_path, const char *d for (int k = i + 1; k < len; k++) filename[j++] = source_path[k]; filename[j] = 0; - char dest_path[256]; + char dest_path[FAT32_MAX_PATH]; explorer_strcpy(dest_path, dest_dir); if (dest_path[explorer_strlen(dest_path) - 1] != '/') explorer_strcat(dest_path, "/"); explorer_strcat(dest_path, filename); diff --git a/src/kernel/fat32.c b/src/kernel/fat32.c index 96f0f7f..bfe6d34 100644 --- a/src/kernel/fat32.c +++ b/src/kernel/fat32.c @@ -1,4 +1,6 @@ #include "fat32.h" +#include "memory_manager.h" +#include "io.h" #include #include @@ -116,6 +118,9 @@ static void extract_parent_path(const char *path, char *parent) { // Normalize path (remove .., ., etc) void fat32_normalize_path(const char *path, char *normalized) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); + char temp[FAT32_MAX_PATH]; int temp_len = 0; @@ -173,6 +178,7 @@ void fat32_normalize_path(const char *path, char *normalized) { } fs_strcpy(normalized, temp); + asm volatile("push %0; popfq" : : "r"(rflags)); } // Find file entry by path @@ -237,8 +243,10 @@ static bool check_desktop_limit(const char *normalized_path) { } // Count files in /Desktop - FAT32_FileInfo info[256]; // Temp buffer + FAT32_FileInfo *info = (FAT32_FileInfo*)kmalloc(256 * sizeof(FAT32_FileInfo)); + if (!info) return true; int count = fat32_list_directory("/Desktop", info, 256); + kfree(info); if (count >= desktop_file_limit) return false; } return true; @@ -276,6 +284,9 @@ void fat32_set_desktop_limit(int limit) { } FAT32_FileHandle* fat32_open(const char *path, const char *mode) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); + char normalized[FAT32_MAX_PATH]; fat32_normalize_path(path, normalized); @@ -284,24 +295,32 @@ FAT32_FileHandle* fat32_open(const char *path, const char *mode) { if (mode[0] == 'r') { // Read mode if (!entry || (entry->attributes & ATTR_DIRECTORY)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return NULL; // File not found or is directory } } else if (mode[0] == 'w' || (mode[0] == 'a')) { // Write/append mode - create if not exists if (!entry) { if (!check_desktop_limit(normalized)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return NULL; } entry = find_free_entry(); - if (!entry) return NULL; + if (!entry) { + asm volatile("push %0; popfq" : : "r"(rflags)); + return NULL; + } entry->used = true; fs_strcpy(entry->full_path, normalized); extract_filename(normalized, entry->filename); extract_parent_path(normalized, entry->parent_path); entry->start_cluster = allocate_cluster(); - if (!entry->start_cluster) return NULL; + if (!entry->start_cluster) { + asm volatile("push %0; popfq" : : "r"(rflags)); + return NULL; + } entry->size = 0; entry->attributes = 0; // Regular file } @@ -313,7 +332,10 @@ FAT32_FileHandle* fat32_open(const char *path, const char *mode) { // Find free handle FAT32_FileHandle *handle = find_free_handle(); - if (!handle) return NULL; + if (!handle) { + asm volatile("push %0; popfq" : : "r"(rflags)); + return NULL; + } handle->valid = true; handle->cluster = entry->start_cluster; @@ -341,17 +363,24 @@ FAT32_FileHandle* fat32_open(const char *path, const char *mode) { handle->cluster = current_cluster; } + asm volatile("push %0; popfq" : : "r"(rflags)); return handle; } void fat32_close(FAT32_FileHandle *handle) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); if (handle) { handle->valid = false; } + asm volatile("push %0; popfq" : : "r"(rflags)); } int fat32_read(FAT32_FileHandle *handle, void *buffer, int size) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); if (!handle || !handle->valid || handle->mode != 0) { + asm volatile("push %0; popfq" : : "r"(rflags)); return -1; } @@ -388,11 +417,15 @@ int fat32_read(FAT32_FileHandle *handle, void *buffer, int size) { } } + asm volatile("push %0; popfq" : : "r"(rflags)); return bytes_read; } int fat32_write(FAT32_FileHandle *handle, const void *buffer, int size) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); if (!handle || !handle->valid || (handle->mode != 1 && handle->mode != 2)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return -1; } @@ -404,7 +437,10 @@ int fat32_write(FAT32_FileHandle *handle, const void *buffer, int size) { uint32_t next = fat_table[handle->cluster]; if (next >= 0xFFFFFFF8) { next = allocate_cluster(); - if (!next) return 0; + if (!next) { + asm volatile("push %0; popfq" : : "r"(rflags)); + return 0; + } fat_table[handle->cluster] = next; } handle->cluster = next; @@ -451,11 +487,15 @@ int fat32_write(FAT32_FileHandle *handle, const void *buffer, int size) { } } + asm volatile("push %0; popfq" : : "r"(rflags)); return bytes_written; } int fat32_seek(FAT32_FileHandle *handle, int offset, int whence) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); if (!handle || !handle->valid) { + asm volatile("push %0; popfq" : : "r"(rflags)); return -1; } @@ -474,23 +514,31 @@ int fat32_seek(FAT32_FileHandle *handle, int offset, int whence) { } handle->position = new_position; + asm volatile("push %0; popfq" : : "r"(rflags)); return new_position; } bool fat32_mkdir(const char *path) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); char normalized[FAT32_MAX_PATH]; fat32_normalize_path(path, normalized); if (find_file(normalized)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return false; // Already exists } if (!check_desktop_limit(normalized)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return false; } FileEntry *entry = find_free_entry(); - if (!entry) return false; + if (!entry) { + asm volatile("push %0; popfq" : : "r"(rflags)); + return false; + } entry->used = true; fs_strcpy(entry->full_path, normalized); @@ -500,43 +548,58 @@ bool fat32_mkdir(const char *path) { entry->size = 0; entry->attributes = ATTR_DIRECTORY; + asm volatile("push %0; popfq" : : "r"(rflags)); return true; } bool fat32_rmdir(const char *path) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); char normalized[FAT32_MAX_PATH]; fat32_normalize_path(path, normalized); FileEntry *entry = find_file(normalized); if (!entry || !(entry->attributes & ATTR_DIRECTORY)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return false; } entry->used = false; + asm volatile("push %0; popfq" : : "r"(rflags)); return true; } bool fat32_delete(const char *path) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); char normalized[FAT32_MAX_PATH]; fat32_normalize_path(path, normalized); FileEntry *entry = find_file(normalized); if (!entry || (entry->attributes & ATTR_DIRECTORY)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return false; } entry->used = false; + asm volatile("push %0; popfq" : : "r"(rflags)); return true; } bool fat32_exists(const char *path) { - return find_file(path) != NULL; + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); + bool res = find_file(path) != NULL; + asm volatile("push %0; popfq" : : "r"(rflags)); + return res; } bool fat32_rename(const char *old_path, const char *new_path) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); FileEntry *entry = find_file(old_path); - if (!entry) return false; - if (find_file(new_path)) return false; // Destination exists + if (!entry) { asm volatile("push %0; popfq" : : "r"(rflags)); return false; } + if (find_file(new_path)) { asm volatile("push %0; popfq" : : "r"(rflags)); return false; } // Destination exists int old_len = fs_strlen(old_path); @@ -572,20 +635,28 @@ bool fat32_rename(const char *old_path, const char *new_path) { fs_strcat(files[i].parent_path, suffix); } } + asm volatile("push %0; popfq" : : "r"(rflags)); return true; } bool fat32_is_directory(const char *path) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); FileEntry *entry = find_file(path); - return entry && (entry->attributes & ATTR_DIRECTORY); + bool res = entry && (entry->attributes & ATTR_DIRECTORY); + asm volatile("push %0; popfq" : : "r"(rflags)); + return res; } int fat32_list_directory(const char *path, FAT32_FileInfo *entries, int max_entries) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); char normalized[FAT32_MAX_PATH]; fat32_normalize_path(path, normalized); FileEntry *dir = find_file(normalized); if (!dir || !(dir->attributes & ATTR_DIRECTORY)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return 0; // Not a directory } @@ -600,23 +671,30 @@ int fat32_list_directory(const char *path, FAT32_FileInfo *entries, int max_entr } } + asm volatile("push %0; popfq" : : "r"(rflags)); return count; } bool fat32_chdir(const char *path) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); char normalized[FAT32_MAX_PATH]; fat32_normalize_path(path, normalized); FileEntry *entry = find_file(normalized); if (!entry || !(entry->attributes & ATTR_DIRECTORY)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return false; } fs_strcpy(current_dir, normalized); + asm volatile("push %0; popfq" : : "r"(rflags)); return true; } void fat32_get_current_dir(char *buffer, int size) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); int len = fs_strlen(current_dir); if (len >= size) len = size - 1; @@ -624,4 +702,5 @@ void fat32_get_current_dir(char *buffer, int size) { buffer[i] = current_dir[i]; } buffer[len] = 0; + asm volatile("push %0; popfq" : : "r"(rflags)); } diff --git a/src/kernel/graphics.c b/src/kernel/graphics.c index 99256ce..b030309 100644 --- a/src/kernel/graphics.c +++ b/src/kernel/graphics.c @@ -1,6 +1,7 @@ #include #include "graphics.h" #include "font.h" +#include "io.h" static struct limine_framebuffer *g_fb = NULL; static uint32_t g_bg_color = 0xFF696969; // Dark gray background @@ -69,6 +70,9 @@ static void merge_dirty_rect(int x, int y, int w, int h) { } void graphics_mark_dirty(int x, int y, int w, int h) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); + // Clamp to screen bounds if (x < 0) { w += x; @@ -85,9 +89,13 @@ void graphics_mark_dirty(int x, int y, int w, int h) { h = get_screen_height() - y; } - if (w <= 0 || h <= 0) return; + if (w <= 0 || h <= 0) { + asm volatile("push %0; popfq" : : "r"(rflags)); + return; + } merge_dirty_rect(x, y, w, h); + asm volatile("push %0; popfq" : : "r"(rflags)); } void graphics_mark_screen_dirty(void) { @@ -103,7 +111,10 @@ DirtyRect graphics_get_dirty_rect(void) { } void graphics_clear_dirty(void) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); g_dirty.active = false; + asm volatile("push %0; popfq" : : "r"(rflags)); } void put_pixel(int x, int y, uint32_t color) { diff --git a/src/kernel/interrupts.asm b/src/kernel/interrupts.asm index 2c8b1cb..8926f4e 100644 --- a/src/kernel/interrupts.asm +++ b/src/kernel/interrupts.asm @@ -11,10 +11,7 @@ send_eoi: push rax mov al, 0x20 out 0x20, al ; Master PIC - ; If IRQ > 7, send to Slave too (Mouse is IRQ 12) - ; We'll handle this in the specific wrappers or C code. - ; Actually, simpler to do EOI in C or here. - ; Let's just do it in C. + pop rax ret diff --git a/src/kernel/markdown.c b/src/kernel/markdown.c index e5d1e8d..f0d8135 100644 --- a/src/kernel/markdown.c +++ b/src/kernel/markdown.c @@ -116,10 +116,6 @@ static void md_parse_line(const char *raw_line, char *output, MDLineType *type, *type = MD_LINE_BLOCKQUOTE; i++; if (raw_line[i] == ' ') i++; - } else if (raw_line[i] == '`') { - // Code block - *type = MD_LINE_CODE; - i++; } // Parse inline formatting and copy content @@ -215,26 +211,36 @@ void markdown_open_file(const char *filename) { int line = 0; int col = 0; char raw_line[256] = ""; + bool in_code_block = false; for (int i = 0; i < bytes_read && line < MD_MAX_LINES; i++) { char ch = buffer[i]; if (ch == '\n') { raw_line[col] = 0; - - // Parse the raw line - char parsed_content[256]; - MDLineType type; - int indent; - md_parse_line(raw_line, parsed_content, &type, &indent); - - // Store parsed line - md_strcpy(lines[line].content, parsed_content); - lines[line].length = md_strlen(parsed_content); - lines[line].type = type; - lines[line].indent_level = indent; - - line++; + + if (raw_line[0] == '`' && raw_line[1] == '`' && raw_line[2] == '`') { + in_code_block = !in_code_block; + } else { + if (in_code_block) { + md_strcpy(lines[line].content, raw_line); + lines[line].length = md_strlen(raw_line); + lines[line].type = MD_LINE_CODE; + lines[line].indent_level = 0; + line++; + } else { + char parsed_content[256]; + MDLineType type; + int indent; + md_parse_line(raw_line, parsed_content, &type, &indent); + md_strcpy(lines[line].content, parsed_content); + lines[line].length = md_strlen(parsed_content); + lines[line].type = type; + lines[line].indent_level = indent; + line++; + } + } + col = 0; raw_line[0] = 0; } else if (col < 255) { @@ -245,16 +251,24 @@ void markdown_open_file(const char *filename) { // Handle last line if no trailing newline if (col > 0 && line < MD_MAX_LINES) { raw_line[col] = 0; - char parsed_content[256]; - MDLineType type; - int indent; - md_parse_line(raw_line, parsed_content, &type, &indent); - - md_strcpy(lines[line].content, parsed_content); - lines[line].length = md_strlen(parsed_content); - lines[line].type = type; - lines[line].indent_level = indent; - line++; + if (raw_line[0] == '`' && raw_line[1] == '`' && raw_line[2] == '`') { + } else if (in_code_block) { + md_strcpy(lines[line].content, raw_line); + lines[line].length = md_strlen(raw_line); + lines[line].type = MD_LINE_CODE; + lines[line].indent_level = 0; + line++; + } else { + char parsed_content[256]; + MDLineType type; + int indent; + md_parse_line(raw_line, parsed_content, &type, &indent); + md_strcpy(lines[line].content, parsed_content); + lines[line].length = md_strlen(parsed_content); + lines[line].type = type; + lines[line].indent_level = indent; + line++; + } } line_count = line; @@ -331,7 +345,7 @@ static void md_paint(Window *win) { text_color = 0xFF808080; // Gray break; case MD_LINE_CODE: - text_color = 0xFF800000; // Dark red + text_color = COLOR_WHITE; break; default: text_color = COLOR_BLACK; @@ -371,7 +385,6 @@ static void md_paint(Window *win) { } line_segment[segment_len] = 0; - // Word-based wrapping: if we didn't reach end of string, find last space if (char_idx < text_len && segment_len > 0) { // Look for the last space in the segment int last_space = -1; @@ -382,7 +395,6 @@ static void md_paint(Window *win) { } } - // If we found a space, break there if (last_space > 0) { segment_len = last_space; line_segment[segment_len] = 0; @@ -395,6 +407,10 @@ static void md_paint(Window *win) { } } + if (line->type == MD_LINE_CODE && segment_len > 0) { + draw_rect(x_offset - 2, line_y - 2, (segment_len * MD_CHAR_WIDTH) + 4, 12, COLOR_BLACK); + } + // Draw special elements for first wrapped line of this markdown line if (local_display_line == 0) { switch (line->type) { @@ -414,10 +430,6 @@ static void md_paint(Window *win) { // Draw left border draw_rect(x_offset - 4, line_y, 2, line_height, 0xFF404080); break; - case MD_LINE_CODE: - // Draw background for code - draw_rect(x_offset - 2, line_y, (max_chars_per_line * MD_CHAR_WIDTH) + 4, line_height, 0xFFF0F0F0); - break; default: break; } @@ -438,8 +450,7 @@ static void md_paint(Window *win) { if (char_idx >= text_len) break; } - // Move display line forward by the actual number of wrapped lines created - // Each wrapped line uses one MD_LINE_HEIGHT worth of space + display_line += wrapped_line_count; i++; @@ -451,8 +462,7 @@ static void md_paint(Window *win) { static void md_handle_key(Window *win, char c) { (void)win; // Suppress unused warning - // Handle scrolling with arrow keys and W/S - // 17 = UP arrow, 18 = DOWN arrow (from ps2 keyboard mapping) + if (c == 'w' || c == 'W' || c == 17) { // Page up or UP arrow scroll_top -= 3; if (scroll_top < 0) scroll_top = 0; diff --git a/src/kernel/memory_manager.c b/src/kernel/memory_manager.c index 5256ba0..c966208 100644 --- a/src/kernel/memory_manager.c +++ b/src/kernel/memory_manager.c @@ -148,23 +148,30 @@ void* kmalloc(size_t size) { memory_manager_init(); } + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); + if (size == 0 || size > memory_pool_size) { + asm volatile("push %0; popfq" : : "r"(rflags)); return NULL; } // Check if we can allocate if (total_allocated + size > memory_pool_size) { + asm volatile("push %0; popfq" : : "r"(rflags)); return NULL; } // Find free space void *ptr = find_free_space(size); if (ptr == NULL) { + asm volatile("push %0; popfq" : : "r"(rflags)); return NULL; } // Add block entry if (block_count >= MAX_ALLOCATIONS) { + asm volatile("push %0; popfq" : : "r"(rflags)); return NULL; } @@ -185,6 +192,7 @@ void* kmalloc(size_t size) { // Clear memory mem_memset(ptr, 0, size); + asm volatile("push %0; popfq" : : "r"(rflags)); return ptr; } @@ -193,6 +201,9 @@ void kfree(void *ptr) { return; } + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); + // Find and free the block for (int i = 0; i < block_count; i++) { if (block_list[i].allocated && block_list[i].address == ptr) { @@ -204,9 +215,11 @@ void kfree(void *ptr) { block_list[j] = block_list[j + 1]; } block_count--; + asm volatile("push %0; popfq" : : "r"(rflags)); return; } } + asm volatile("push %0; popfq" : : "r"(rflags)); } void* krealloc(void *ptr, size_t new_size) { diff --git a/src/kernel/tcp.c b/src/kernel/tcp.c index 8c0a1d9..40f700c 100644 --- a/src/kernel/tcp.c +++ b/src/kernel/tcp.c @@ -195,7 +195,6 @@ void tcp_close(tcp_socket_t *sock) { int tcp_read(tcp_socket_t *sock, char *buffer, int max_len) { if (!sock) return 0; - // Simple copy of what we have int count = 0; for (int i = 0; i < sock->rx_pos && i < max_len; i++) { buffer[i] = sock->rx_buffer[i]; diff --git a/src/kernel/wm.c b/src/kernel/wm.c index 2bef269..125c9a7 100644 --- a/src/kernel/wm.c +++ b/src/kernel/wm.c @@ -976,6 +976,7 @@ void wm_handle_click(int x, int y) { } if (can_paste) { + int old_count = desktop_icon_count; if (desktop_menu_target_icon != -1 && desktop_icons[desktop_menu_target_icon].type == 1) { // Paste into folder char path[128] = "/Desktop/"; @@ -987,6 +988,20 @@ void wm_handle_click(int x, int y) { explorer_clipboard_paste(&win_explorer, "/Desktop"); } refresh_desktop_icons(); + + // If auto-align is OFF and we pasted to the background, place at click location + if (!desktop_auto_align && desktop_icon_count > old_count && desktop_menu_target_icon == -1) { + int new_idx = desktop_icon_count - 1; + desktop_icons[new_idx].x = desktop_menu_x - 20; + desktop_icons[new_idx].y = desktop_menu_y - 20; + if (desktop_snap_to_grid) { + int col = (desktop_icons[new_idx].x - 20 + 40) / 80; + int row = (desktop_icons[new_idx].y - 20 + 40) / 80; + if (col < 0) col = 0; if (row < 0) row = 0; + desktop_icons[new_idx].x = 20 + col * 80; + desktop_icons[new_idx].y = 20 + row * 80; + } + } } } else if (item == 3 && desktop_menu_target_icon != -1) { // Delete @@ -1496,20 +1511,17 @@ void wm_handle_right_click(int x, int y) { wm_show_message("Error", "Desktop is full!"); } else { explorer_import_file_to(&win_explorer, drag_file_path, "/Desktop"); - refresh_desktop_icons(); } // Handle insertion at specific position + char filename[64]; + int len = 0; while(drag_file_path[len]) len++; + int s = len - 1; while(s >= 0 && drag_file_path[s] != '/') s--; + s++; + int d = 0; while(drag_file_path[s] && d < 63) filename[d++] = drag_file_path[s++]; + filename[d] = 0; + if (desktop_auto_align && !msg_box_visible) { - // Find the newly added icon (it will be at the end) - // Extract filename from drag_file_path - char filename[64]; - int len = 0; while(drag_file_path[len]) len++; - int s = len - 1; while(s >= 0 && drag_file_path[s] != '/') s--; - s++; - int d = 0; while(drag_file_path[s] && d < 63) filename[d++] = drag_file_path[s++]; - filename[d] = 0; - int new_idx = -1; for(int i=0; i