diff --git a/libstratosphere/include/stratosphere/fs.hpp b/libstratosphere/include/stratosphere/fs.hpp index 4428ac11..3b81c8af 100644 --- a/libstratosphere/include/stratosphere/fs.hpp +++ b/libstratosphere/include/stratosphere/fs.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/libstratosphere/include/stratosphere/fs/fs_i_event_notifier.hpp b/libstratosphere/include/stratosphere/fs/fs_i_event_notifier.hpp new file mode 100644 index 00000000..375ed1af --- /dev/null +++ b/libstratosphere/include/stratosphere/fs/fs_i_event_notifier.hpp @@ -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 . + */ +#pragma once +#include "fs_common.hpp" + +namespace ams::fs { + + class IEventNotifier { + public: + virtual ~IEventNotifier() { /* ... */ } + + Result BindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) { + AMS_ASSERT(out != nullptr); + return this->DoBindEvent(out, clear_mode); + } + private: + virtual Result DoBindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) = 0; + }; + +} diff --git a/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp b/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp index e27c1219..183f7bea 100644 --- a/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp +++ b/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp @@ -18,8 +18,14 @@ namespace ams::fs { + class IEventNotifier; + Result MountSdCard(const char *name); Result MountSdCardErrorReportDirectoryForAtmosphere(const char *name); + Result OpenSdCardDetectionEventNotifier(std::unique_ptr *out); + + bool IsSdCardInserted(); + } diff --git a/libstratosphere/include/stratosphere/fssrv.hpp b/libstratosphere/include/stratosphere/fssrv.hpp index a2fb95b3..70fa77bb 100644 --- a/libstratosphere/include/stratosphere/fssrv.hpp +++ b/libstratosphere/include/stratosphere/fssrv.hpp @@ -17,6 +17,7 @@ #pragma once #include #include +#include #include #include #include diff --git a/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_event_notifier.hpp b/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_event_notifier.hpp new file mode 100644 index 00000000..09036998 --- /dev/null +++ b/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_event_notifier.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 +#include + +#define AMS_FSSRV_I_EVENT_NOTIFIER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, GetEventHandle, (ams::sf::OutCopyHandle out), (out)) + +AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IEventNotifier, AMS_FSSRV_I_EVENT_NOTIFIER_INTERFACE_INFO) diff --git a/libstratosphere/source/fs/fs_sd_card.cpp b/libstratosphere/source/fs/fs_sd_card.cpp index d001cef8..b11982b1 100644 --- a/libstratosphere/source/fs/fs_sd_card.cpp +++ b/libstratosphere/source/fs/fs_sd_card.cpp @@ -15,6 +15,7 @@ */ #include #include "fsa/fs_mount_utils.hpp" +#include "impl/fs_event_notifier_object_adapter.hpp" namespace ams::fs { @@ -87,4 +88,30 @@ namespace ams::fs { return fsa::Register(name, std::move(subdir_fs)); } + Result OpenSdCardDetectionEventNotifier(std::unique_ptr *out) { + /* Try to open an event notifier. */ + FsEventNotifier notifier; + AMS_FS_R_TRY(fsOpenSdCardDetectionEventNotifier(std::addressof(notifier))); + + /* Create an event notifier adapter. */ + auto adapter = std::make_unique(notifier); + R_UNLESS(adapter != nullptr, fs::ResultAllocationFailureInSdCardB()); + + *out = std::move(adapter); + return ResultSuccess(); + } + + bool IsSdCardInserted() { + /* Open device operator. */ + FsDeviceOperator device_operator; + AMS_FS_R_ABORT_UNLESS(::fsOpenDeviceOperator(std::addressof(device_operator))); + ON_SCOPE_EXIT { ::fsDeviceOperatorClose(std::addressof(device_operator)); }; + + /* Get SD card inserted. */ + bool inserted; + AMS_FS_R_ABORT_UNLESS(::fsDeviceOperatorIsSdCardInserted(std::addressof(device_operator), std::addressof(inserted))); + + return inserted; + } + } diff --git a/libstratosphere/source/fs/impl/fs_event_notifier_object_adapter.hpp b/libstratosphere/source/fs/impl/fs_event_notifier_object_adapter.hpp new file mode 100644 index 00000000..ea0cc64f --- /dev/null +++ b/libstratosphere/source/fs/impl/fs_event_notifier_object_adapter.hpp @@ -0,0 +1,59 @@ +/* + * 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 + +namespace ams::fs::impl { + + class EventNotifierObjectAdapter final : public ::ams::fs::IEventNotifier, public ::ams::fs::impl::Newable { + private: + sf::SharedPointer m_object; + public: + EventNotifierObjectAdapter(sf::SharedPointer &&obj) : m_object(obj) { /* ... */ } + virtual ~EventNotifierObjectAdapter() { /* ... */ } + private: + virtual Result DoBindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) override { + /* Get the handle. */ + sf::CopyHandle handle; + AMS_FS_R_TRY(m_object->GetEventHandle(std::addressof(handle))); + + /* Create the system event. */ + os::AttachReadableHandleToSystemEvent(out, handle, true, clear_mode); + + return ResultSuccess(); + } + }; + + class RemoteEventNotifierObjectAdapter final : public ::ams::fs::IEventNotifier, public ::ams::fs::impl::Newable { + private: + ::FsEventNotifier m_notifier; + public: + RemoteEventNotifierObjectAdapter(::FsEventNotifier &n) : m_notifier(n) { /* ... */ } + virtual ~RemoteEventNotifierObjectAdapter() { fsEventNotifierClose(std::addressof(m_notifier)); } + private: + virtual Result DoBindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) override { + /* Get the handle. */ + ::Event e; + R_TRY(fsEventNotifierGetEventHandle(std::addressof(m_notifier), std::addressof(e), false)); + + /* Create the system event. */ + os::AttachReadableHandleToSystemEvent(out, e.revent, true, clear_mode); + + return ResultSuccess(); + } + }; + +}