diff --git a/kernel/src/Api/Filesystem.hpp b/kernel/src/Api/Filesystem.hpp index d6aef9c..9e1892c 100644 --- a/kernel/src/Api/Filesystem.hpp +++ b/kernel/src/Api/Filesystem.hpp @@ -7,6 +7,8 @@ #pragma once #include +#include +#include #include #include #include @@ -126,4 +128,11 @@ namespace Montauk { static int Sys_DriveLabel(int driveNumber, char* outLabel, int maxLen) { return Fs::Vfs::VfsDriveLabel(driveNumber, outLabel, maxLen); } + + static int Sys_DriveKind(int driveNumber) { + int blockDev = Fs::FsProbe::GetBlockDeviceForDrive(driveNumber); + if (blockDev < 0) return 0; + auto* dev = Drivers::Storage::GetBlockDevice(blockDev); + return dev ? (int)dev->Kind : 0; + } }; diff --git a/kernel/src/Api/Syscall.cpp b/kernel/src/Api/Syscall.cpp index a65d51e..30e9ca4 100644 --- a/kernel/src/Api/Syscall.cpp +++ b/kernel/src/Api/Syscall.cpp @@ -217,6 +217,8 @@ namespace Montauk { if ((int64_t)frame->arg3 <= 0) return -1; if (!UserMemory::Range(frame->arg2, frame->arg3, true)) return -1; return (int64_t)Sys_DriveLabel((int)frame->arg1, (char*)frame->arg2, (int)frame->arg3); + case SYS_DRIVEKIND: + return (int64_t)Sys_DriveKind((int)frame->arg1); case SYS_TERMSCALE: return Sys_TermScale(frame->arg1, frame->arg2); case SYS_RESOLVE: diff --git a/kernel/src/Api/Syscall.hpp b/kernel/src/Api/Syscall.hpp index 9410e4d..4c576fa 100644 --- a/kernel/src/Api/Syscall.hpp +++ b/kernel/src/Api/Syscall.hpp @@ -225,6 +225,7 @@ namespace Montauk { /* Filesystem.hpp */ static constexpr uint64_t SYS_DRIVELABEL = 124; + static constexpr uint64_t SYS_DRIVEKIND = 127; /* Net.hpp */ static constexpr uint64_t SYS_NETSTATUS = 125; diff --git a/kernel/src/Fs/FsProbe.cpp b/kernel/src/Fs/FsProbe.cpp index b962eb1..96ca425 100644 --- a/kernel/src/Fs/FsProbe.cpp +++ b/kernel/src/Fs/FsProbe.cpp @@ -142,6 +142,18 @@ namespace Fs::FsProbe { return -1; } + int GetBlockDeviceForDrive(int driveNum) { + if (driveNum < 0) return -1; + int partCount = Drivers::Storage::Gpt::GetPartitionCount(); + for (int i = 0; i < partCount && i < Drivers::Storage::Gpt::MaxPartitions; i++) { + if (g_mounted[i] && g_driveForPart[i] == driveNum) { + auto* part = Drivers::Storage::Gpt::GetPartition(i); + if (part) return part->BlockDevIndex; + } + } + return -1; + } + int UnmountPartitionsForBlockDevice(int blockDevIndex) { int partCount = Drivers::Storage::Gpt::GetPartitionCount(); int unmounted = 0; diff --git a/kernel/src/Fs/FsProbe.hpp b/kernel/src/Fs/FsProbe.hpp index 72cc3d8..aa836b8 100644 --- a/kernel/src/Fs/FsProbe.hpp +++ b/kernel/src/Fs/FsProbe.hpp @@ -34,4 +34,8 @@ namespace Fs::FsProbe { // mount bookkeeping to match Gpt::RemovePartitionsForBlockDevice(). int UnmountPartitionsForBlockDevice(int blockDevIndex); + // Return the block-device index backing a mounted VFS drive, or -1 if the + // drive isn't backed by a partition (e.g. ramdisk). + int GetBlockDeviceForDrive(int driveNum); + }; diff --git a/programs/include/Api/Syscall.hpp b/programs/include/Api/Syscall.hpp index ca75747..fa255ef 100644 --- a/programs/include/Api/Syscall.hpp +++ b/programs/include/Api/Syscall.hpp @@ -160,6 +160,7 @@ namespace Montauk { static constexpr uint64_t SYS_INPUT_WAIT = 123; static constexpr uint64_t SYS_DRIVELABEL = 124; static constexpr uint64_t SYS_NETSTATUS = 125; + static constexpr uint64_t SYS_DRIVEKIND = 127; static constexpr uint32_t CLIPBOARD_MAX_TEXT_BYTES = 256 * 1024; diff --git a/programs/include/gui/desktop.hpp b/programs/include/gui/desktop.hpp index a5e1cf0..7852bd4 100644 --- a/programs/include/gui/desktop.hpp +++ b/programs/include/gui/desktop.hpp @@ -123,6 +123,8 @@ struct DesktopState { SvgIcon icon_exec_lg; SvgIcon icon_drive; SvgIcon icon_drive_lg; + SvgIcon icon_drive_usb; + SvgIcon icon_drive_usb_lg; SvgIcon icon_delete; SvgIcon icon_copy; SvgIcon icon_cut; diff --git a/programs/include/montauk/syscall.h b/programs/include/montauk/syscall.h index 51a60dd..449acc7 100644 --- a/programs/include/montauk/syscall.h +++ b/programs/include/montauk/syscall.h @@ -164,6 +164,11 @@ namespace montauk { inline int drivelabel(int drive, char* outLabel, int maxLen) { return (int)syscall3(Montauk::SYS_DRIVELABEL, (uint64_t)drive, (uint64_t)outLabel, (uint64_t)maxLen); } + // Returns the kernel BlockDeviceKind backing the drive: 0=unknown/ramdisk, + // 1=SATA, 2=SATAPI, 3=NVMe, 4=USB MSC. + inline int drivekind(int drive) { + return (int)syscall1(Montauk::SYS_DRIVEKIND, (uint64_t)drive); + } // Memory inline void* alloc(uint64_t size) { return (void*)syscall1(Montauk::SYS_ALLOC, size); } diff --git a/programs/libs/libprintersapplet/obj/src/libprintersapplet.o b/programs/libs/libprintersapplet/obj/src/libprintersapplet.o index a75e69b..d577fdc 100644 Binary files a/programs/libs/libprintersapplet/obj/src/libprintersapplet.o and b/programs/libs/libprintersapplet/obj/src/libprintersapplet.o differ diff --git a/programs/libs/libtimezonesapplet/obj/src/libtimezonesapplet.o b/programs/libs/libtimezonesapplet/obj/src/libtimezonesapplet.o index a61cdbe..1c12087 100644 Binary files a/programs/libs/libtimezonesapplet/obj/src/libtimezonesapplet.o and b/programs/libs/libtimezonesapplet/obj/src/libtimezonesapplet.o differ diff --git a/programs/src/desktop/apps/filemanager/app.cpp b/programs/src/desktop/apps/filemanager/app.cpp index 8baeebb..284b428 100644 --- a/programs/src/desktop/apps/filemanager/app.cpp +++ b/programs/src/desktop/apps/filemanager/app.cpp @@ -72,6 +72,8 @@ void ensure_filemanager_icons_loaded(DesktopState* ds) { Color defColor = colors::ICON_COLOR; ds->icon_drive = svg_load("0:/icons/drive-harddisk.svg", 16, 16, defColor); ds->icon_drive_lg = svg_load("0:/icons/drive-harddisk.svg", 48, 48, defColor); + ds->icon_drive_usb = svg_load("0:/icons/drive-harddisk-usb.svg", 16, 16, defColor); + ds->icon_drive_usb_lg = svg_load("0:/icons/drive-harddisk-usb.svg", 48, 48, defColor); ds->icon_home_folder = svg_load("0:/icons/folder-blue-home.svg", 16, 16, defColor); ds->icon_home_folder_lg = svg_load("0:/icons/folder-blue-home.svg", 48, 48, defColor); ds->icon_apps = svg_load("0:/icons/folder-blue-development.svg", 16, 16, defColor); diff --git a/programs/src/desktop/apps/filemanager/filemanager_internal.hpp b/programs/src/desktop/apps/filemanager/filemanager_internal.hpp index ed45516..2350166 100644 --- a/programs/src/desktop/apps/filemanager/filemanager_internal.hpp +++ b/programs/src/desktop/apps/filemanager/filemanager_internal.hpp @@ -68,6 +68,7 @@ struct FileManagerState { DesktopState* desktop; bool grid_view; int drive_indices[64]; // drive number or special-folder index for Computer view entries + int drive_kinds[64]; // kernel BlockDeviceKind for FM_ENTRY_DRIVE entries (4 = USB MSC) // Clipboard char clipboard_path[256]; diff --git a/programs/src/desktop/apps/filemanager/filesystem.cpp b/programs/src/desktop/apps/filemanager/filesystem.cpp index bcd9297..3510011 100644 --- a/programs/src/desktop/apps/filemanager/filesystem.cpp +++ b/programs/src/desktop/apps/filemanager/filesystem.cpp @@ -39,6 +39,10 @@ static void filemanager_add_root_entry(FileManagerState* fm, fm->entry_sizes[idx] = 0; fm->is_dir[idx] = true; fm->drive_indices[idx] = drive_index; + fm->drive_kinds[idx] = 0; + if (type == FM_ENTRY_DRIVE && drive_index >= 0) { + fm->drive_kinds[idx] = montauk::drivekind(drive_index); + } } static int filemanager_add_virtual_entry(FileManagerState* fm, diff --git a/programs/src/desktop/apps/filemanager/render.cpp b/programs/src/desktop/apps/filemanager/render.cpp index 8005a14..06d04fc 100644 --- a/programs/src/desktop/apps/filemanager/render.cpp +++ b/programs/src/desktop/apps/filemanager/render.cpp @@ -333,7 +333,10 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) { } else if (ds && fm->entry_types[i] == FM_ENTRY_HOME && ds->icon_home_folder_lg.pixels) { c.icon(icon_x, icon_y, ds->icon_home_folder_lg); } else if (ds && fm->entry_types[i] == FM_ENTRY_DRIVE && ds->icon_drive_lg.pixels) { - c.icon(icon_x, icon_y, ds->icon_drive_lg); + // Kind 4 = USB MSC (kernel BlockDeviceKind enum) + const SvgIcon& di = (fm->drive_kinds[i] == 4 && ds->icon_drive_usb_lg.pixels) + ? ds->icon_drive_usb_lg : ds->icon_drive_lg; + c.icon(icon_x, icon_y, di); } else if (ds && fm->entry_types[i] == FM_ENTRY_DIR && ds->icon_folder_lg.pixels) { c.icon(icon_x, icon_y, ds->icon_folder_lg); } else if (ds && fm->entry_types[i] == FM_ENTRY_EXEC && ds->icon_exec_lg.pixels) { @@ -464,7 +467,9 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) { } else if (ds && fm->entry_types[i] == FM_ENTRY_HOME && ds->icon_home_folder.pixels) { c.icon(ico_x, ico_y, ds->icon_home_folder); } else if (ds && fm->entry_types[i] == FM_ENTRY_DRIVE && ds->icon_drive.pixels) { - c.icon(ico_x, ico_y, ds->icon_drive); + const SvgIcon& di = (fm->drive_kinds[i] == 4 && ds->icon_drive_usb.pixels) + ? ds->icon_drive_usb : ds->icon_drive; + c.icon(ico_x, ico_y, di); } else if (ds && fm->entry_types[i] == FM_ENTRY_DIR && ds->icon_folder.pixels) { c.icon(ico_x, ico_y, ds->icon_folder); } else if (ds && fm->entry_types[i] == FM_ENTRY_EXEC && ds->icon_exec.pixels) {