diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_am_mitm_service.cpp b/stratosphere/ams_mitm/source/ns_mitm/ns_am_mitm_service.cpp
new file mode 100644
index 000000000..1fd7e905e
--- /dev/null
+++ b/stratosphere/ams_mitm/source/ns_mitm/ns_am_mitm_service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018-2019 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
+#include "ns_am_mitm_service.hpp"
+#include "ns_shim.h"
+
+namespace ams::mitm::ns {
+
+ Result NsAmMitmService::GetApplicationContentPath(const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type) {
+ return nsamGetApplicationContentPathFwd(this->forward_service.get(), out_path.GetPointer(), out_path.GetSize(), static_cast(application_id), static_cast(content_type));
+ }
+
+ Result NsAmMitmService::ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type) {
+ /* Always succeed for web applets asking about HBL. */
+ /* This enables hbl html. */
+ bool is_hbl;
+ if (R_SUCCEEDED(pm::info::IsHblProgramId(&is_hbl, application_id)) && is_hbl) {
+ nsamResolveApplicationContentPathFwd(this->forward_service.get(), static_cast(application_id), static_cast(content_type));
+ return ResultSuccess();
+ }
+ return nsamResolveApplicationContentPathFwd(this->forward_service.get(), static_cast(application_id), static_cast(content_type));
+ }
+
+ Result NsAmMitmService::GetRunningApplicationProgramId(sf::Out out, ncm::ProgramId application_id) {
+ return nsamGetRunningApplicationProgramIdFwd(this->forward_service.get(), reinterpret_cast(out.GetPointer()), static_cast(application_id));
+ }
+
+}
diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_am_mitm_service.hpp b/stratosphere/ams_mitm/source/ns_mitm/ns_am_mitm_service.hpp
index a32166355..0d52d245e 100644
--- a/stratosphere/ams_mitm/source/ns_mitm/ns_am_mitm_service.hpp
+++ b/stratosphere/ams_mitm/source/ns_mitm/ns_am_mitm_service.hpp
@@ -18,23 +18,32 @@
namespace ams::mitm::ns {
- class NsAmMitmService : public sf::IMitmServiceObject {
+ class NsAmMitmService : public sf::IMitmServiceObject {
private:
enum class CommandId {
- /* TODO */
+ GetApplicationContentPath = 21,
+ ResolveApplicationContentPath = 23,
+ GetRunningApplicationProgramId = 92,
};
public:
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
- /* TODO */
- return false;
+ /* We will mitm:
+ * - web applets, to facilitate hbl web browser launching.
+ */
+ return ncm::IsWebAppletProgramId(client_info.program_id);
}
public:
SF_MITM_SERVICE_OBJECT_CTOR(NsAmMitmService) { /* ... */ }
protected:
- /* TODO */
+ /* Actual command API. */
+ Result GetApplicationContentPath(const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type);
+ Result ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type);
+ Result GetRunningApplicationProgramId(sf::Out out, ncm::ProgramId application_id);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
- /* TODO */
+ MAKE_SERVICE_COMMAND_META(GetApplicationContentPath),
+ MAKE_SERVICE_COMMAND_META(ResolveApplicationContentPath),
+ MAKE_SERVICE_COMMAND_META(GetRunningApplicationProgramId, hos::Version_600),
};
};
diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c
new file mode 100644
index 000000000..4f5dcefc1
--- /dev/null
+++ b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018-2019 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
+#include
+#include "ns_shim.h"
+
+/* Command forwarders. */
+Result nsGetDocumentInterfaceFwd(Service* s, NsDocumentInterface* out) {
+ return serviceDispatch(s, 7999,
+ .out_num_objects = 1,
+ .out_objects = &out->s,
+ );
+}
+
+static Result _nsGetApplicationContentPath(Service *s, void* out, size_t out_size, u64 app_id, NcmContentType content_type) {
+ const struct {
+ u8 content_type;
+ u64 app_id;
+ } in = { content_type, app_id };
+ return serviceDispatchIn(s, 21, in,
+ .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
+ .buffers = { { out, out_size } },
+ );
+}
+
+
+static Result _nsResolveApplicationContentPath(Service* s, u64 app_id, NcmContentType content_type) {
+ const struct {
+ u8 content_type;
+ u64 app_id;
+ } in = { content_type, app_id };
+ return serviceDispatchIn(s, 23, in);
+}
+
+static Result _nsGetRunningApplicationProgramId(Service* s, u64* out_program_id, u64 app_id) {
+ if (hosversionBefore(6, 0, 0)) {
+ return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
+ }
+ return serviceDispatchInOut(s, 92, app_id, *out_program_id);
+}
+
+/* Application Manager forwarders. */
+Result nsamGetApplicationContentPathFwd(Service* s, void* out, size_t out_size, u64 app_id, NcmContentType content_type) {
+ return _nsGetApplicationContentPath(s, out, out_size, app_id, content_type);
+}
+
+Result nsamResolveApplicationContentPathFwd(Service* s, u64 app_id, NcmContentType content_type) {
+ return _nsResolveApplicationContentPath(s, app_id, content_type);
+}
+
+Result nsamGetRunningApplicationProgramIdFwd(Service* s, u64* out_program_id, u64 app_id) {
+ return _nsGetRunningApplicationProgramId(s, out_program_id, app_id);
+}
+
+/* Web forwarders */
+Result nswebGetApplicationContentPath(NsDocumentInterface* doc, void* out, size_t out_size, u64 app_id, NcmContentType content_type) {
+ return _nsGetApplicationContentPath(&doc->s, out, out_size, app_id, content_type);
+}
+
+Result nswebResolveApplicationContentPath(NsDocumentInterface* doc, u64 app_id, NcmContentType content_type) {
+ return _nsResolveApplicationContentPath(&doc->s, app_id, content_type);
+}
+
+Result nswebGetRunningApplicationProgramId(NsDocumentInterface* doc, u64* out_program_id, u64 app_id) {
+ return _nsGetRunningApplicationProgramId(&doc->s, out_program_id, app_id);
+}
+
+void nsDocumentInterfaceClose(NsDocumentInterface* doc) {
+ serviceClose(&doc->s);
+}
+
diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h
new file mode 100644
index 000000000..7749bbf14
--- /dev/null
+++ b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h
@@ -0,0 +1,33 @@
+/**
+ * @file ns_shim.h
+ * @brief Nintendo Shell Services (ns) IPC wrapper.
+ * @author SciresM
+ * @copyright libnx Authors
+ */
+#pragma once
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ Service s;
+} NsDocumentInterface;
+
+/* Command forwarders. */
+Result nsGetDocumentInterfaceFwd(Service* s, NsDocumentInterface* out);
+
+Result nsamGetApplicationContentPathFwd(Service* s, void* out, size_t out_size, u64 app_id, NcmContentType content_type);
+Result nsamResolveApplicationContentPathFwd(Service* s, u64 app_id, NcmContentType content_type);
+Result nsamGetRunningApplicationProgramIdFwd(Service* s, u64* out_program_id, u64 app_id);
+
+Result nswebGetApplicationContentPath(NsDocumentInterface* doc, void* out, size_t out_size, u64 app_id, NcmContentType content_type);
+Result nswebResolveApplicationContentPath(NsDocumentInterface* doc, u64 app_id, NcmContentType content_type);
+Result nswebGetRunningApplicationProgramId(NsDocumentInterface* doc, u64* out_program_id, u64 app_id);
+
+void nsDocumentInterfaceClose(NsDocumentInterface* doc);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp
new file mode 100644
index 000000000..d475c1d59
--- /dev/null
+++ b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018-2019 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
+#include "ns_web_mitm_service.hpp"
+
+namespace ams::mitm::ns {
+
+ Result NsDocumentService::GetApplicationContentPath(const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type) {
+ return nswebGetApplicationContentPath(this->srv.get(), out_path.GetPointer(), out_path.GetSize(), static_cast(application_id), static_cast(content_type));
+ }
+
+ Result NsDocumentService::ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type) {
+ /* Always succeed for web applets asking about HBL. */
+ /* This enables hbl html. */
+ bool is_hbl;
+ if (R_SUCCEEDED(pm::info::IsHblProgramId(&is_hbl, application_id)) && is_hbl) {
+ nswebResolveApplicationContentPath(this->srv.get(), static_cast(application_id), static_cast(content_type));
+ return ResultSuccess();
+ }
+ return nswebResolveApplicationContentPath(this->srv.get(), static_cast(application_id), static_cast(content_type));
+ }
+
+ Result NsDocumentService::GetRunningApplicationProgramId(sf::Out out, ncm::ProgramId application_id) {
+ return nswebGetRunningApplicationProgramId(this->srv.get(), reinterpret_cast(out.GetPointer()), static_cast(application_id));
+ }
+
+ Result NsWebMitmService::GetDocumentInterface(sf::Out> out) {
+ /* Open a document interface. */
+ NsDocumentInterface doc;
+ R_TRY(nsGetDocumentInterfaceFwd(this->forward_service.get(), &doc));
+ const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(&doc.s)};
+
+ out.SetValue(std::make_shared(this->client_info, std::make_unique(doc)), target_object_id);
+ return ResultSuccess();
+ }
+
+}
diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp
index 09f540a56..68ac3b460 100644
--- a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp
+++ b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp
@@ -16,25 +16,58 @@
#pragma once
#include
+#include "ns_shim.h"
+
namespace ams::mitm::ns {
+ class NsDocumentService : public sf::IServiceObject {
+ private:
+ enum class CommandId {
+ GetApplicationContentPath = 21,
+ ResolveApplicationContentPath = 23,
+ GetRunningApplicationProgramId = 92,
+ };
+ private:
+ sm::MitmProcessInfo client_info;
+ std::unique_ptr<::NsDocumentInterface> srv;
+ public:
+ NsDocumentService(const sm::MitmProcessInfo &cl, std::unique_ptr<::NsDocumentInterface> s) : client_info(cl), srv(std::move(s)) { /* .. */ }
+
+ virtual ~NsDocumentService() {
+ nsDocumentInterfaceClose(this->srv.get());
+ }
+ protected:
+ /* Actual command API. */
+ Result GetApplicationContentPath(const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type);
+ Result ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type);
+ Result GetRunningApplicationProgramId(sf::Out out, ncm::ProgramId application_id);
+ public:
+ DEFINE_SERVICE_DISPATCH_TABLE {
+ MAKE_SERVICE_COMMAND_META(GetApplicationContentPath),
+ MAKE_SERVICE_COMMAND_META(ResolveApplicationContentPath),
+ MAKE_SERVICE_COMMAND_META(GetRunningApplicationProgramId, hos::Version_600),
+ };
+ };
+
class NsWebMitmService : public sf::IMitmServiceObject {
private:
enum class CommandId {
- /* TODO */
+ GetDocumentInterface = 7999,
};
public:
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
- /* TODO */
- return false;
+ /* We will mitm:
+ * - web applets, to facilitate hbl web browser launching.
+ */
+ return ncm::IsWebAppletProgramId(client_info.program_id);
}
public:
SF_MITM_SERVICE_OBJECT_CTOR(NsWebMitmService) { /* ... */ }
protected:
- /* TODO */
+ Result GetDocumentInterface(sf::Out> out);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
- /* TODO */
+ MAKE_SERVICE_COMMAND_META(GetDocumentInterface),
};
};
diff --git a/stratosphere/libstratosphere/include/stratosphere/ncm/ncm_types.hpp b/stratosphere/libstratosphere/include/stratosphere/ncm/ncm_types.hpp
index 0c13966b3..b21adb947 100644
--- a/stratosphere/libstratosphere/include/stratosphere/ncm/ncm_types.hpp
+++ b/stratosphere/libstratosphere/include/stratosphere/ncm/ncm_types.hpp
@@ -421,6 +421,14 @@ namespace ams::ncm {
return ProgramId::ApplicationStart <= program_id && program_id <= ProgramId::ApplicationEnd;
}
+ inline constexpr bool IsWebAppletProgramId(const ProgramId &program_id) {
+ return program_id == ProgramId::AppletWeb ||
+ program_id == ProgramId::AppletShop ||
+ program_id == ProgramId::AppletOfflineWeb ||
+ program_id == ProgramId::AppletLoginShare ||
+ program_id == ProgramId::AppletWifiWebAuth;
+ }
+
static_assert(sizeof(ProgramId) == sizeof(u64) && std::is_pod::value, "ProgramId definition!");
/* Program Location. */
diff --git a/stratosphere/libstratosphere/include/stratosphere/pm/pm_info_api.hpp b/stratosphere/libstratosphere/include/stratosphere/pm/pm_info_api.hpp
index 0b5e6dce9..6a56b13df 100644
--- a/stratosphere/libstratosphere/include/stratosphere/pm/pm_info_api.hpp
+++ b/stratosphere/libstratosphere/include/stratosphere/pm/pm_info_api.hpp
@@ -31,4 +31,7 @@ namespace ams::pm::info {
/* Information convenience API. */
bool HasLaunchedProgram(ncm::ProgramId program_id);
+ Result IsHblProcessId(bool *out, os::ProcessId process_id);
+ Result IsHblProgramId(bool *out, ncm::ProgramId program_id);
+
}
diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/sf_service_object.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/sf_service_object.hpp
index fd87ddb2a..f0c32f1b5 100644
--- a/stratosphere/libstratosphere/include/stratosphere/sf/sf_service_object.hpp
+++ b/stratosphere/libstratosphere/include/stratosphere/sf/sf_service_object.hpp
@@ -20,7 +20,10 @@
namespace ams::sf {
- class IServiceObject{};
+ class IServiceObject {
+ public:
+ virtual ~IServiceObject() { /* ... */ }
+ };
class IMitmServiceObject : public IServiceObject {
protected:
@@ -29,6 +32,8 @@ namespace ams::sf {
public:
IMitmServiceObject(std::shared_ptr<::Service> &&s, const sm::MitmProcessInfo &c) : forward_service(std::move(s)), client_info(c) { /* ... */ }
+ virtual ~IMitmServiceObject() { /* ... */ }
+
static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id);
};
diff --git a/stratosphere/libstratosphere/source/pm/pm_info_api.cpp b/stratosphere/libstratosphere/source/pm/pm_info_api.cpp
index e07a15310..e0028004e 100644
--- a/stratosphere/libstratosphere/source/pm/pm_info_api.cpp
+++ b/stratosphere/libstratosphere/source/pm/pm_info_api.cpp
@@ -73,4 +73,21 @@ namespace ams::pm::info {
return has_launched;
}
+
+ Result IsHblProcessId(bool *out, os::ProcessId process_id) {
+ ncm::ProgramLocation loc;
+ cfg::OverrideStatus override_status;
+ R_TRY(GetProcessInfo(&loc, &override_status, process_id));
+
+ *out = override_status.IsHbl();
+ return ResultSuccess();
+ }
+
+ Result IsHblProgramId(bool *out, ncm::ProgramId program_id) {
+ os::ProcessId process_id;
+ R_TRY(GetProcessId(&process_id, program_id));
+
+ return IsHblProcessId(out, process_id);
+ }
+
}