diff --git a/src/core/file_sys/quasifs/quasifs_inode.h b/src/core/file_sys/quasifs/quasifs_inode.h index c4f9c43bd..8136b0bca 100644 --- a/src/core/file_sys/quasifs/quasifs_inode.h +++ b/src/core/file_sys/quasifs/quasifs_inode.h @@ -142,8 +142,8 @@ public: struct Libraries::Kernel::OrbisKernelStat st{}; int chmod(u16 mode) { - u16* st_mode = &this->st.st_mode; - *st_mode = ((*st_mode) & (~0x1FF)) | (mode & 0x1FF); + u16& st_mode = this->st.st_mode; + st_mode = ((st_mode) & (~0x1FF)) | (mode & 0x1FF); st.st_birthtim.tv_sec = time(0); return 0; } diff --git a/src/core/file_sys/quasifs/quasifs_inode_quasi_directory.h b/src/core/file_sys/quasifs/quasifs_inode_quasi_directory.h index 4fda0ce03..0403d4998 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_quasi_directory.h +++ b/src/core/file_sys/quasifs/quasifs_inode_quasi_directory.h @@ -60,7 +60,7 @@ public: // s64 pread(void* buf, size_t count, u64 offset) override; // s64 pwrite(const void* buf, size_t count, u64 offset) override; - s32 ftruncate(s64 length) override { + s32 ftruncate(s64 length) final override { return -QUASI_EISDIR; } diff --git a/src/core/file_sys/quasifs/src/quasifs.cpp b/src/core/file_sys/quasifs/src/quasifs.cpp index 9839acffc..c2e959455 100644 --- a/src/core/file_sys/quasifs/src/quasifs.cpp +++ b/src/core/file_sys/quasifs/src/quasifs.cpp @@ -1,5 +1,7 @@ // INAA License @marecl 2025 +#include + #include "common/logging/log.h" #include "core/file_sys/quasifs/quasi_errno.h" @@ -66,16 +68,25 @@ void _printTree(const inode_ptr& node, const std::string& name, int depth) { std::tm* t = std::localtime(&st.st_mtim.tv_sec); std::strftime(timebuf, sizeof(timebuf), "%EY-%m-%d %H:%M", t); - LOG_INFO(Kernel_Fs, "[ls -la] {} {:08} {:03d} {}:{} {:>08} {}\t{}{}\n", - file_mode(st.st_mode), st.st_mode, st.st_nlink, /*st.st_uid*/ 0, /* st.st_gid*/ 0, - st.st_size, timebuf, depEnt, name); + // LOG_INFO(Kernel_Fs, "[ls -la] {} {:08} {:03d} {}:{} {:>08} {}\t{}{}\n", + // file_mode(st.st_mode), st.st_mode, st.st_nlink, /*st.st_uid*/ 0, /* st.st_gid*/ + // 0, st.st_size, timebuf, depEnt, name); + + std::string line = std::format( + "[ls -la] {} {:08o} {:03d} {}:{} {:>08} {}\t{}{}\n", file_mode(st.st_mode), st.st_mode, + st.st_nlink, /*st.st_uid*/ 0, /* st.st_gid*/ 0, st.st_size, timebuf, depEnt, name); + + std::cout << "[FileSystem]" << line; } else depth--; - if (node->is_link()) - LOG_INFO(Kernel_Fs, "[ls -la]\t\t\t\t\t\t\tsymlinked to ->{}\n", - std::static_pointer_cast(node)->follow().string()); - + if (node->is_link()) { + // LOG_INFO(Kernel_Fs, "[ls -la]\t\t\t\t\t\t\tsymlinked to ->{}\n", + // std::static_pointer_cast(node)->follow().string()); + std::string line = std::format("[ls -la]\t\t\t\t\t\t\t\t[->{}]\n", + std::static_pointer_cast(node)->follow().string()); + std::cout << "[FileSystem]" << line; + } if (node->is_dir()) { if ("." == name) return; @@ -84,7 +95,10 @@ void _printTree(const inode_ptr& node, const std::string& name, int depth) { auto dir = std::dynamic_pointer_cast(node); if (dir->mounted_root) { - LOG_INFO(Kernel_Fs, "[ls -la]\t\t\t\t\t\t\t|--{}{}\n", depEnt, "[MOUNTPOINT]"); + // LOG_INFO(Kernel_Fs, "[ls -la]\t\t\t\t\t\t\t|--{}{}\n", depEnt, "[MOUNTPOINT]"); + std::string line = + std::format("[ls -la]\t\t\t\t\t\t\t\t|--{}{}\n", depEnt, "[MOUNTPOINT]"); + std::cout << "[FileSystem]" << line; _printTree(dir->mounted_root, "", depth + 1); } else { for (auto& childName : dir->Entries()) { diff --git a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_file_virtual.cpp b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_file_virtual.cpp index cb5064528..31100a8e4 100644 --- a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_file_virtual.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_file_virtual.cpp @@ -8,14 +8,13 @@ namespace QuasiFS { s64 VirtualFile::pread(void* buf, size_t count, s64 offset) { - s64 idx; s64 read_amt = this->data.size() - offset - count; // if >= 0 - we're good to go // <0 - n-bytes are missing, won't enter loop read_amt = count + read_amt * (read_amt < 0); - for (idx = 0; idx < read_amt; idx++) { + for (s64 idx = 0; idx < read_amt; idx++) { char c = this->data.at(idx + offset); static_cast(buf)[idx] = c; } @@ -25,14 +24,14 @@ s64 VirtualFile::pread(void* buf, size_t count, s64 offset) { } s64 VirtualFile::pwrite(const void* buf, size_t count, s64 offset) { - auto size = &this->st.st_size; + auto& size = this->st.st_size; auto end_pos = offset + count; - *size = end_pos > *size ? end_pos : *size; + size = end_pos > size ? end_pos : size; // size can only be greater, so it will always scale up - this->data.resize(*size, 0); + this->data.resize(size, 0); - for (u64 idx = offset; idx < *size; idx++) + for (u64 idx = offset; idx < size; idx++) this->data[idx] = static_cast(buf)[idx]; st.st_mtim.tv_sec = time(0); diff --git a/src/emulator.cpp b/src/emulator.cpp index 848a3bda0..2b861054d 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -101,29 +101,24 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) { qfs::partition_ptr partition_dev = qfs::Partition::Create("", 0755, 16384, 16384); qfs->Operation.MKDir("/app0", 0555); - qfs->Operation.MKDir("/hostapp", 0555); qfs->Operation.MKDir("/av_contents", 0775); - qfs->Operation.MKDir("/av_contents/photo", 0755); - qfs->Operation.MKDir("/av_contents/thumbnails", 0755); - qfs->Operation.MKDir("/av_contents/video", 0755); - qfs->Operation.MKDir("/data", 0777); qfs->Operation.MKDir("/dev", 0555); - qfs->Operation.MKDir("/download0", 0777); // not sure about perms here + qfs->Operation.MKDir("/host", 0777); qfs->Operation.MKDir("/hostapp", 0777); - qfs->Operation.MKDir("/temp", 0777); - qfs->Operation.MKDir("/temp0", 0777); qfs->Mount("/app0", partition_app0, qfs::MountOptions::MOUNT_NOOPT); qfs->Mount("/av_contents", partition_av_contents, qfs::MountOptions::MOUNT_RW); + qfs->Mount("/dev", partition_dev, qfs::MountOptions::MOUNT_RW); + + // mounting av_contents would shadow these + qfs->Operation.MKDir("/av_contents/photo", 0755); + qfs->Operation.MKDir("/av_contents/thumbnails", 0755); + qfs->Operation.MKDir("/av_contents/video", 0755); qfs->Mount("/av_contents/photo", partition_av_contents_photo, qfs::MountOptions::MOUNT_RW); qfs->Mount("/av_contents/thumbnails", partition_av_contents_thumbs, qfs::MountOptions::MOUNT_RW); qfs->Mount("/av_contents/video", partition_av_contents_video, qfs::MountOptions::MOUNT_RW); - qfs->Mount("/dev", partition_dev, qfs::MountOptions::MOUNT_RW); - qfs->Mount("/hostapp", partition_app0, - qfs::MountOptions::MOUNT_NOOPT | qfs::MountOptions::MOUNT_BIND); - // // Setup /dev // @@ -156,11 +151,11 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) { qfs->Operation.Chmod("/dev/srandom", 0666); if (int fd_dev = qfs->Operation.Open("/dev/stdin", QUASI_O_RDONLY); fd_dev != 0) - LOG_CRITICAL(Kernel_Fs, "XDXDXD 0"); + LOG_CRITICAL(Kernel_Fs, "file descriptor of stdin is not 0 (it's {})", fd_dev); if (int fd_dev = qfs->Operation.Open("/dev/stdout", QUASI_O_WRONLY); fd_dev != 1) - LOG_CRITICAL(Kernel_Fs, "XDXDXD 1 != {}", fd_dev); + LOG_CRITICAL(Kernel_Fs, "file descriptor of stdout is not 1 (it's {})", fd_dev); if (int fd_dev = qfs->Operation.Open("/dev/stderr", QUASI_O_WRONLY); fd_dev != 2) - LOG_CRITICAL(Kernel_Fs, "XDXDXD 2 != {}", fd_dev); + LOG_CRITICAL(Kernel_Fs, "file descriptor of stderr is not 2 (it's {})", fd_dev); qfs->SyncHost(); @@ -201,8 +196,6 @@ void Emulator::Run(std::filesystem::path file, std::vector args, // Applications expect to be run from /app0 so mount the file's parent path as app0. auto* mnt = Common::Singleton::Instance(); mnt->Mount(game_folder, "/app0", true); - // Certain games may use /hostapp as well such as CUSA001100 - mnt->Mount(game_folder, "/hostapp", true); this->LoadFilesystem(game_folder); @@ -267,6 +260,10 @@ void Emulator::Run(std::filesystem::path file, std::vector args, } std::filesystem::create_directory(mount_temp_dir); + qfs->Operation.MKDir("/data", 0777); + qfs->Operation.MKDir("/download0", 0777); // not sure about perms here + qfs->Operation.MKDir("/temp", 0777); + qfs->Operation.MKDir("/temp0", 0777); qfs::partition_ptr partition_data = qfs::Partition::Create(mount_data_dir, 0777, 4096, 32768); qfs::partition_ptr partition_download = qfs::Partition::Create(mount_download_dir, 0777, 512, 65536); @@ -420,42 +417,13 @@ void Emulator::Run(std::filesystem::path file, std::vector args, g_window = window.get(); - // const auto& mount_data_dir = Common::FS::GetUserPath(Common::FS::PathType::GameDataDir) / id; - // if (!std::filesystem::exists(mount_data_dir)) { - // std::filesystem::create_directory(mount_data_dir); - // } - // mnt->Mount(mount_data_dir, "/data"); // should just exist, manually create with game serial - - // Mounting temp folders - // const auto& mount_temp_dir = Common::FS::GetUserPath(Common::FS::PathType::TempDataDir) / id; - // if (std::filesystem::exists(mount_temp_dir)) { - // // Temp folder should be cleared on each boot. - // std::filesystem::remove_all(mount_temp_dir); - // } - // std::filesystem::create_directory(mount_temp_dir); - // mnt->Mount(mount_temp_dir, "/temp0"); - // mnt->Mount(mount_temp_dir, "/temp"); - - // const auto& mount_download_dir = - // Common::FS::GetUserPath(Common::FS::PathType::DownloadDir) / id; - // if (!std::filesystem::exists(mount_download_dir)) { - // std::filesystem::create_directory(mount_download_dir); - // } - // mnt->Mount(mount_download_dir, "/download0"); - - // const auto& mount_captures_dir = - // Common::FS::GetUserPath(Common::FS::PathType::CapturesDir); - // if (!std::filesystem::exists(mount_captures_dir)) { - // std::filesystem::create_directory(mount_captures_dir); - // } - // VideoCore::SetOutputDir(mount_captures_dir, id); - // Initialize kernel and library facilities. Libraries::InitHLELibs(&linker->GetHLESymbols()); // Load the module with the linker auto guest_eboot_path = "/app0/" + eboot_name.generic_string(); - const auto eboot_path = mnt->GetHostPath(guest_eboot_path); + std::filesystem::path eboot_path{}; + qfs->GetHostPath(eboot_path, guest_eboot_path); if (linker->LoadModule(eboot_path) == -1) { LOG_CRITICAL(Loader, "Failed to load game's eboot.bin: {}", Common::FS::PathToUTF8String(std::filesystem::absolute(eboot_path)));