feat: added Files app USB medium detection

This commit is contained in:
2026-05-18 20:00:42 +02:00
parent 2ceefaf1ca
commit 47e3bb54a5
14 changed files with 50 additions and 2 deletions
+9
View File
@@ -7,6 +7,8 @@
#pragma once #pragma once
#include <Fs/Vfs.hpp> #include <Fs/Vfs.hpp>
#include <Fs/FsProbe.hpp>
#include <Drivers/Storage/BlockDevice.hpp>
#include <Sched/Scheduler.hpp> #include <Sched/Scheduler.hpp>
#include <Memory/PageFrameAllocator.hpp> #include <Memory/PageFrameAllocator.hpp>
#include <Memory/HHDM.hpp> #include <Memory/HHDM.hpp>
@@ -126,4 +128,11 @@ namespace Montauk {
static int Sys_DriveLabel(int driveNumber, char* outLabel, int maxLen) { static int Sys_DriveLabel(int driveNumber, char* outLabel, int maxLen) {
return Fs::Vfs::VfsDriveLabel(driveNumber, outLabel, 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;
}
}; };
+2
View File
@@ -217,6 +217,8 @@ namespace Montauk {
if ((int64_t)frame->arg3 <= 0) return -1; if ((int64_t)frame->arg3 <= 0) return -1;
if (!UserMemory::Range(frame->arg2, frame->arg3, true)) 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); 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: case SYS_TERMSCALE:
return Sys_TermScale(frame->arg1, frame->arg2); return Sys_TermScale(frame->arg1, frame->arg2);
case SYS_RESOLVE: case SYS_RESOLVE:
+1
View File
@@ -225,6 +225,7 @@ namespace Montauk {
/* Filesystem.hpp */ /* Filesystem.hpp */
static constexpr uint64_t SYS_DRIVELABEL = 124; static constexpr uint64_t SYS_DRIVELABEL = 124;
static constexpr uint64_t SYS_DRIVEKIND = 127;
/* Net.hpp */ /* Net.hpp */
static constexpr uint64_t SYS_NETSTATUS = 125; static constexpr uint64_t SYS_NETSTATUS = 125;
+12
View File
@@ -142,6 +142,18 @@ namespace Fs::FsProbe {
return -1; 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 UnmountPartitionsForBlockDevice(int blockDevIndex) {
int partCount = Drivers::Storage::Gpt::GetPartitionCount(); int partCount = Drivers::Storage::Gpt::GetPartitionCount();
int unmounted = 0; int unmounted = 0;
+4
View File
@@ -34,4 +34,8 @@ namespace Fs::FsProbe {
// mount bookkeeping to match Gpt::RemovePartitionsForBlockDevice(). // mount bookkeeping to match Gpt::RemovePartitionsForBlockDevice().
int UnmountPartitionsForBlockDevice(int blockDevIndex); 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);
}; };
+1
View File
@@ -160,6 +160,7 @@ namespace Montauk {
static constexpr uint64_t SYS_INPUT_WAIT = 123; static constexpr uint64_t SYS_INPUT_WAIT = 123;
static constexpr uint64_t SYS_DRIVELABEL = 124; static constexpr uint64_t SYS_DRIVELABEL = 124;
static constexpr uint64_t SYS_NETSTATUS = 125; static constexpr uint64_t SYS_NETSTATUS = 125;
static constexpr uint64_t SYS_DRIVEKIND = 127;
static constexpr uint32_t CLIPBOARD_MAX_TEXT_BYTES = 256 * 1024; static constexpr uint32_t CLIPBOARD_MAX_TEXT_BYTES = 256 * 1024;
+2
View File
@@ -123,6 +123,8 @@ struct DesktopState {
SvgIcon icon_exec_lg; SvgIcon icon_exec_lg;
SvgIcon icon_drive; SvgIcon icon_drive;
SvgIcon icon_drive_lg; SvgIcon icon_drive_lg;
SvgIcon icon_drive_usb;
SvgIcon icon_drive_usb_lg;
SvgIcon icon_delete; SvgIcon icon_delete;
SvgIcon icon_copy; SvgIcon icon_copy;
SvgIcon icon_cut; SvgIcon icon_cut;
+5
View File
@@ -164,6 +164,11 @@ namespace montauk {
inline int drivelabel(int drive, char* outLabel, int maxLen) { inline int drivelabel(int drive, char* outLabel, int maxLen) {
return (int)syscall3(Montauk::SYS_DRIVELABEL, (uint64_t)drive, (uint64_t)outLabel, (uint64_t)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 // Memory
inline void* alloc(uint64_t size) { return (void*)syscall1(Montauk::SYS_ALLOC, size); } inline void* alloc(uint64_t size) { return (void*)syscall1(Montauk::SYS_ALLOC, size); }
@@ -72,6 +72,8 @@ void ensure_filemanager_icons_loaded(DesktopState* ds) {
Color defColor = colors::ICON_COLOR; Color defColor = colors::ICON_COLOR;
ds->icon_drive = svg_load("0:/icons/drive-harddisk.svg", 16, 16, defColor); 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_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 = 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_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); ds->icon_apps = svg_load("0:/icons/folder-blue-development.svg", 16, 16, defColor);
@@ -68,6 +68,7 @@ struct FileManagerState {
DesktopState* desktop; DesktopState* desktop;
bool grid_view; bool grid_view;
int drive_indices[64]; // drive number or special-folder index for Computer view entries 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 // Clipboard
char clipboard_path[256]; char clipboard_path[256];
@@ -39,6 +39,10 @@ static void filemanager_add_root_entry(FileManagerState* fm,
fm->entry_sizes[idx] = 0; fm->entry_sizes[idx] = 0;
fm->is_dir[idx] = true; fm->is_dir[idx] = true;
fm->drive_indices[idx] = drive_index; 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, static int filemanager_add_virtual_entry(FileManagerState* fm,
@@ -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) { } 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); 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) { } 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) { } 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); 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) { } 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) { } 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); c.icon(ico_x, ico_y, ds->icon_home_folder);
} else if (ds && fm->entry_types[i] == FM_ENTRY_DRIVE && ds->icon_drive.pixels) { } 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) { } else if (ds && fm->entry_types[i] == FM_ENTRY_DIR && ds->icon_folder.pixels) {
c.icon(ico_x, ico_y, ds->icon_folder); c.icon(ico_x, ico_y, ds->icon_folder);
} else if (ds && fm->entry_types[i] == FM_ENTRY_EXEC && ds->icon_exec.pixels) { } else if (ds && fm->entry_types[i] == FM_ENTRY_EXEC && ds->icon_exec.pixels) {