-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
set.mitm: language emulation (closes #489)
- Loading branch information
Showing
10 changed files
with
452 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* 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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <mutex> | ||
#include <algorithm> | ||
#include <switch.h> | ||
#include "set_mitm_service.hpp" | ||
#include "set_shim.h" | ||
|
||
void SetMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx) { | ||
/* No commands need postprocessing. */ | ||
} | ||
|
||
bool SetMitmService::IsValidLanguageCode(u64 lang_code) { | ||
static constexpr u64 s_valid_language_codes[] = { | ||
LanguageCode_Japanese, | ||
LanguageCode_AmericanEnglish, | ||
LanguageCode_French, | ||
LanguageCode_German, | ||
LanguageCode_Italian, | ||
LanguageCode_Spanish, | ||
LanguageCode_Chinese, | ||
LanguageCode_Korean, | ||
LanguageCode_Dutch, | ||
LanguageCode_Portuguese, | ||
LanguageCode_Russian, | ||
LanguageCode_Taiwanese, | ||
LanguageCode_BritishEnglish, | ||
LanguageCode_CanadianFrench, | ||
LanguageCode_LatinAmericanSpanish, | ||
LanguageCode_SimplifiedChinese, | ||
LanguageCode_TraditionalChinese, | ||
}; | ||
size_t num_language_codes = sizeof(s_valid_language_codes) / sizeof(s_valid_language_codes[0]); | ||
if (GetRuntimeFirmwareVersion() < FirmwareVersion_400) { | ||
/* 4.0.0 added simplified and traditional chinese. */ | ||
num_language_codes -= 2; | ||
} | ||
|
||
for (size_t i = 0; i < num_language_codes; i++) { | ||
if (lang_code == s_valid_language_codes[i]) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool SetMitmService::IsValidRegionCode(u32 region_code) { | ||
return region_code < RegionCode_Max; | ||
} | ||
|
||
void SetMitmService::EnsureLocale() { | ||
std::scoped_lock<HosMutex> lk(this->lock); | ||
|
||
if (!this->got_locale) { | ||
std::memset(&this->locale, 0xCC, sizeof(this->locale)); | ||
if (this->title_id == TitleId_Ns) { | ||
u64 app_pid = 0; | ||
u64 app_tid = 0; | ||
Result rc; | ||
if (R_FAILED((rc = pmdmntGetApplicationPid(&app_pid)))) { | ||
return; | ||
} | ||
if (R_FAILED((rc = pminfoGetTitleId(&app_tid, app_pid)))) { | ||
return; | ||
} | ||
this->locale = Utils::GetTitleOverrideLocale(app_tid); | ||
} else { | ||
this->locale = Utils::GetTitleOverrideLocale(this->title_id); | ||
this->got_locale = true; | ||
} | ||
} | ||
} | ||
|
||
Result SetMitmService::GetLanguageCode(Out<u64> out_lang_code) { | ||
this->EnsureLocale(); | ||
|
||
if (!IsValidLanguageCode(this->locale.language_code)) { | ||
return ResultAtmosphereMitmShouldForwardToSession; | ||
} | ||
|
||
out_lang_code.SetValue(this->locale.language_code); | ||
return ResultSuccess; | ||
} | ||
|
||
Result SetMitmService::GetRegionCode(Out<u32> out_region_code) { | ||
this->EnsureLocale(); | ||
|
||
if (!IsValidRegionCode(this->locale.region_code)) { | ||
return ResultAtmosphereMitmShouldForwardToSession; | ||
} | ||
|
||
out_region_code.SetValue(this->locale.region_code); | ||
return ResultSuccess; | ||
} | ||
|
||
Result SetMitmService::GetAvailableLanguageCodes(OutPointerWithClientSize<u64> out_language_codes, Out<s32> out_count) { | ||
return setGetAvailableLanguageCodesFwd(this->forward_service.get(), out_count.GetPointer(), out_language_codes.pointer, out_language_codes.num_elements); | ||
} |
68 changes: 68 additions & 0 deletions
68
stratosphere/ams_mitm/source/set_mitm/set_mitm_service.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* 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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#pragma once | ||
#include <switch.h> | ||
#include <stratosphere.hpp> | ||
|
||
#include "../utils.hpp" | ||
|
||
enum SetCmd : u32 { | ||
SetCmd_GetLanguageCode = 0, | ||
SetCmd_GetRegionCode = 4, | ||
|
||
/* Commands for which set:sys *must* act as a passthrough. */ | ||
/* TODO: Solve the relevant IPC detection problem. */ | ||
SetCmd_GetAvailableLanguageCodes = 1, | ||
}; | ||
|
||
class SetMitmService : public IMitmServiceObject { | ||
private: | ||
HosMutex lock; | ||
OverrideLocale locale; | ||
bool got_locale; | ||
public: | ||
SetMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) { | ||
this->got_locale = false; | ||
} | ||
|
||
static bool ShouldMitm(u64 pid, u64 tid) { | ||
/* Mitm all applications. */ | ||
return tid == TitleId_Ns || TitleIdIsApplication(tid); | ||
} | ||
|
||
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx); | ||
|
||
protected: | ||
static bool IsValidLanguageCode(u64 lang_code); | ||
static bool IsValidRegionCode(u32 region_code); | ||
|
||
void EnsureLocale(); | ||
protected: | ||
/* Overridden commands. */ | ||
Result GetLanguageCode(Out<u64> out_lang_code); | ||
Result GetRegionCode(Out<u32> out_region_code); | ||
|
||
/* Forced passthrough commands. */ | ||
Result GetAvailableLanguageCodes(OutPointerWithClientSize<u64> out_language_codes, Out<s32> out_count); | ||
public: | ||
DEFINE_SERVICE_DISPATCH_TABLE { | ||
MakeServiceCommandMeta<SetCmd_GetLanguageCode, &SetMitmService::GetLanguageCode>(), | ||
MakeServiceCommandMeta<SetCmd_GetRegionCode, &SetMitmService::GetRegionCode>(), | ||
|
||
MakeServiceCommandMeta<SetCmd_GetAvailableLanguageCodes, &SetMitmService::GetAvailableLanguageCodes>(), | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* 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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <string.h> | ||
#include <switch.h> | ||
#include "setsys_shim.h" | ||
|
||
/* Command forwarders. */ | ||
Result setGetAvailableLanguageCodesFwd(Service* s, s32 *total_entries, u64 *language_codes, size_t max_entries) { | ||
IpcCommand c; | ||
ipcInitialize(&c); | ||
ipcAddRecvStatic(&c, language_codes, max_entries * sizeof(*language_codes), 0); | ||
|
||
struct { | ||
u64 magic; | ||
u64 cmd_id; | ||
} *raw; | ||
|
||
raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw)); | ||
|
||
raw->magic = SFCI_MAGIC; | ||
raw->cmd_id = 1; | ||
|
||
Result rc = serviceIpcDispatch(s); | ||
|
||
if (R_SUCCEEDED(rc)) { | ||
IpcParsedCommand r; | ||
|
||
struct { | ||
u64 magic; | ||
u64 result; | ||
s32 total_entries; | ||
} *resp; | ||
|
||
serviceIpcParse(s, &r, sizeof(*resp)); | ||
resp = r.Raw; | ||
|
||
rc = resp->result; | ||
|
||
if (R_SUCCEEDED(rc)) { | ||
*total_entries = resp->total_entries; | ||
} | ||
} | ||
|
||
return rc; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* @file set_shim.h | ||
* @brief Settings Services (set) IPC wrapper. To be merged into libnx, eventually. | ||
* @author SciresM | ||
* @copyright libnx Authors | ||
*/ | ||
#pragma once | ||
#include <switch.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/* Command forwarders. */ | ||
Result setGetAvailableLanguageCodesFwd(Service* s, s32 *total_entries, u64 *language_codes, size_t max_entries); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.