diff --git a/libraries/libstratosphere/include/stratosphere/fs.hpp b/libraries/libstratosphere/include/stratosphere/fs.hpp index 95256ae54..0fb067c34 100644 --- a/libraries/libstratosphere/include/stratosphere/fs.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs.hpp @@ -29,3 +29,4 @@ #include "fs/fs_mount.hpp" #include "fs/fs_path_tool.hpp" #include "fs/fs_path_utils.hpp" +#include "fs/fs_sd_card.hpp" diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp new file mode 100644 index 000000000..981620719 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include "fs_common.hpp" + +namespace ams::fs { + + Result MountSdCard(const char *name); + +} diff --git a/libraries/libstratosphere/source/boot2/boot2_api.cpp b/libraries/libstratosphere/source/boot2/boot2_api.cpp index 14a594772..3ec5e9805 100644 --- a/libraries/libstratosphere/source/boot2/boot2_api.cpp +++ b/libraries/libstratosphere/source/boot2/boot2_api.cpp @@ -191,19 +191,20 @@ namespace ams::boot2 { template void IterateOverFlaggedProgramsOnSdCard(F f) { /* Validate that the contents directory exists. */ - DIR *contents_dir = opendir("sdmc:/atmosphere/contents"); - if (contents_dir == nullptr) { + fs::DirectoryHandle contents_dir; + if (R_FAILED(fs::OpenDirectory(&contents_dir, "sdmc:/atmosphere/contents", fs::OpenDirectoryMode_Directory))) { return; } - ON_SCOPE_EXIT { closedir(contents_dir); }; + ON_SCOPE_EXIT { fs::CloseDirectory(contents_dir); }; /* Iterate over entries in the contents directory */ - struct dirent *ent; - while ((ent = readdir(contents_dir)) != nullptr) { + fs::DirectoryEntry entry; + s64 count; + while (R_SUCCEEDED(fs::ReadDirectory(&count, &entry, contents_dir, 1)) && count == 1) { /* Check that the subdirectory can be converted to a program id. */ - if (std::strlen(ent->d_name) == 2 * sizeof(ncm::ProgramId) && IsHexadecimal(ent->d_name)) { + if (std::strlen(entry.name) == 2 * sizeof(ncm::ProgramId) && IsHexadecimal(entry.name)) { /* Check if we've already launched the program. */ - ncm::ProgramId program_id{std::strtoul(ent->d_name, nullptr, 16)}; + ncm::ProgramId program_id{std::strtoul(entry.name, nullptr, 16)}; /* Check if the program is flagged. */ if (!cfg::HasContentSpecificFlag(program_id, "boot2")) { @@ -224,14 +225,16 @@ namespace ams::boot2 { /* Read the mitm list off the SD card. */ { - char path[FS_MAX_PATH]; - std::snprintf(mitm_list, sizeof(mitm_list), "sdmc:/atmosphere/contents/%016lx/mitm.lst", static_cast(program_id)); - FILE *f = fopen(path, "rb"); - if (f == nullptr) { + char path[fs::EntryNameLengthMax]; + std::snprintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/mitm.lst", static_cast(program_id)); + + fs::FileHandle f; + if (R_FAILED(fs::OpenFile(&f, path, fs::OpenMode_Read))) { return; } - mitm_list_size = static_cast(fread(mitm_list, 1, sizeof(mitm_list), f)); - fclose(f); + ON_SCOPE_EXIT { fs::CloseFile(f); }; + + R_ABORT_UNLESS(fs::ReadFile(&mitm_list_size, f, 0, mitm_list, sizeof(mitm_list))); } /* Validate read size. */ diff --git a/libraries/libstratosphere/source/fs/fs_sd_card.cpp b/libraries/libstratosphere/source/fs/fs_sd_card.cpp new file mode 100644 index 000000000..2bdc2cb34 --- /dev/null +++ b/libraries/libstratosphere/source/fs/fs_sd_card.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::fs { + + Result MountSdCard(const char *name) { + /* Open the SD card. This uses libnx bindings. */ + FsFileSystem fs; + R_TRY(fsOpenSdCardFileSystem(std::addressof(fs))); + + /* Allocate a new filesystem wrapper. */ + std::unique_ptr fsa(new RemoteFileSystem(fs)); + R_UNLESS(fsa != nullptr, fs::ResultAllocationFailureInSdCardA()); + + /* Register. */ + return fsa::Register(name, std::move(fsa)); + } + +} diff --git a/libraries/libvapours/include/vapours/results/fs_results.hpp b/libraries/libvapours/include/vapours/results/fs_results.hpp index 621f1f3ff..02483283c 100644 --- a/libraries/libvapours/include/vapours/results/fs_results.hpp +++ b/libraries/libvapours/include/vapours/results/fs_results.hpp @@ -50,6 +50,8 @@ namespace ams::fs { R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorA, 3211); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorB, 3212); + R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardA, 3244); + R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardB, 3245); R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321); R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355); R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterA, 3365); diff --git a/stratosphere/boot2/source/boot2_main.cpp b/stratosphere/boot2/source/boot2_main.cpp index 00f62adc8..992e33249 100644 --- a/stratosphere/boot2/source/boot2_main.cpp +++ b/stratosphere/boot2/source/boot2_main.cpp @@ -79,13 +79,10 @@ void __appInit(void) { R_ABORT_UNLESS(gpioInitialize()); }); - R_ABORT_UNLESS(fsdevMountSdmc()); - ams::CheckApiVersion(); } void __appExit(void) { - fsdevUnmountAll(); gpioExit(); setsysExit(); pmshellExit(); @@ -96,6 +93,11 @@ void __appExit(void) { int main(int argc, char **argv) { + /* Mount the SD card. */ + R_ABORT_UNLESS(fs::MountSdCard("sdmc")); + ON_SCOPE_EXIT { fs::Unmount("sdmc"); }; + + /* Launch all programs off of SYSTEM/the SD. */ boot2::LaunchPostSdCardBootPrograms(); }