summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-06-05 12:16:02 -0400
committerGravatar Zach Hilman2019-06-24 20:05:11 -0400
commit675aa5f71929466d5aa214f00b76f436d53c2a0b (patch)
tree70553383a12f2d06d9c2c31fdd33584a28c647a8 /src/core/hle
parentyuzu: Accept default applets for Parental Controls and ECommerce (diff)
downloadyuzu-675aa5f71929466d5aa214f00b76f436d53c2a0b.tar.gz
yuzu-675aa5f71929466d5aa214f00b76f436d53c2a0b.tar.xz
yuzu-675aa5f71929466d5aa214f00b76f436d53c2a0b.zip
web_browser: Correct structures and properly parse TLVs/ShimKind
Much, much more HW-accurate and allows us to easily support all of the different web 'shim' types.
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp222
-rw-r--r--src/core/hle/service/am/applets/web_browser.h7
2 files changed, 168 insertions, 61 deletions
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index 7878f5136..6918bda02 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -19,7 +19,9 @@
19#include "core/file_sys/nca_metadata.h" 19#include "core/file_sys/nca_metadata.h"
20#include "core/file_sys/registered_cache.h" 20#include "core/file_sys/registered_cache.h"
21#include "core/file_sys/romfs.h" 21#include "core/file_sys/romfs.h"
22#include "core/file_sys/system_archive/system_archive.h"
22#include "core/file_sys/vfs_types.h" 23#include "core/file_sys/vfs_types.h"
24#include "core/frontend/applets/general_frontend.h"
23#include "core/frontend/applets/web_browser.h" 25#include "core/frontend/applets/web_browser.h"
24#include "core/hle/kernel/process.h" 26#include "core/hle/kernel/process.h"
25#include "core/hle/service/am/applets/web_browser.h" 27#include "core/hle/service/am/applets/web_browser.h"
@@ -28,74 +30,186 @@
28 30
29namespace Service::AM::Applets { 31namespace Service::AM::Applets {
30 32
31// TODO(DarkLordZach): There are other arguments in the WebBuffer structure that are currently not 33enum class WebArgTLVType : u16 {
32// parsed, for example footer mode and left stick mode. Some of these are not particularly relevant, 34 InitialURL = 0x1,
33// but some may be worth an implementation. 35 ShopArgumentsURL = 0x2, ///< TODO(DarkLordZach): This is not the official name.
34constexpr u16 WEB_ARGUMENT_URL_TYPE = 0x6; 36 CallbackURL = 0x3,
37 CallbackableURL = 0x4,
38 ApplicationID = 0x5,
39 DocumentPath = 0x6,
40 DocumentKind = 0x7,
41 SystemDataID = 0x8,
42 ShareStartPage = 0x9,
43 Whitelist = 0xA,
44 News = 0xB,
45 UserID = 0xE,
46 AlbumEntry0 = 0xF,
47 ScreenShotEnabled = 0x10,
48 EcClientCertEnabled = 0x11,
49 Unk12 = 0x12,
50 PlayReportEnabled = 0x13,
51 Unk14 = 0x14,
52 Unk15 = 0x15,
53 BootDisplayKind = 0x17,
54 BackgroundKind = 0x18,
55 FooterEnabled = 0x19,
56 PointerEnabled = 0x1A,
57 LeftStickMode = 0x1B,
58 KeyRepeatFrame1 = 0x1C,
59 KeyRepeatFrame2 = 0x1D,
60 BootAsMediaPlayerInv = 0x1E,
61 DisplayUrlKind = 0x1F,
62 BootAsMediaPlayer = 0x21,
63 ShopJumpEnabled = 0x22,
64 MediaAutoPlayEnabled = 0x23,
65 LobbyParameter = 0x24,
66 ApplicationAlbumEntry = 0x26,
67 JsExtensionEnabled = 0x27,
68 AdditionalCommentText = 0x28,
69 TouchEnabledOnContents = 0x29,
70 UserAgentAdditionalString = 0x2A,
71 AdditionalMediaData0 = 0x2B,
72 MediaPlayerAutoCloseEnabled = 0x2C,
73 PageCacheEnabled = 0x2D,
74 WebAudioEnabled = 0x2E,
75 Unk2F = 0x2F,
76 YouTubeVideoWhitelist = 0x31,
77 FooterFixedKind = 0x32,
78 PageFadeEnabled = 0x33,
79 MediaCreatorApplicationRatingAge = 0x34,
80 BootLoadingIconEnabled = 0x35,
81 PageScrollIndicationEnabled = 0x36,
82 MediaPlayerSpeedControlEnabled = 0x37,
83 AlbumEntry1 = 0x38,
84 AlbumEntry2 = 0x39,
85 AlbumEntry3 = 0x3A,
86 AdditionalMediaData1 = 0x3B,
87 AdditionalMediaData2 = 0x3C,
88 AdditionalMediaData3 = 0x3D,
89 BootFooterButton = 0x3E,
90 OverrideWebAudioVolume = 0x3F,
91 OverrideMediaAudioVolume = 0x40,
92 BootMode = 0x41,
93 WebSessionEnabled = 0x42,
94};
95
96enum class ShimKind : u32 {
97 Shop = 1,
98 Login = 2,
99 Offline = 3,
100 Share = 4,
101 Web = 5,
102 Wifi = 6,
103 Lobby = 7,
104};
105
106constexpr std::size_t SHIM_KIND_COUNT = 0x8;
35 107
36struct WebBufferHeader { 108struct WebArgHeader {
37 u16 count; 109 u16 count;
38 INSERT_PADDING_BYTES(6); 110 INSERT_PADDING_BYTES(2);
111 ShimKind kind;
39}; 112};
40static_assert(sizeof(WebBufferHeader) == 0x8, "WebBufferHeader has incorrect size."); 113static_assert(sizeof(WebArgHeader) == 0x8, "WebArgHeader has incorrect size.");
41 114
42struct WebArgumentHeader { 115struct WebArgTLV {
43 u16 type; 116 WebArgTLVType type;
44 u16 size; 117 u16 size;
45 u32 offset; 118 u32 offset;
46}; 119};
47static_assert(sizeof(WebArgumentHeader) == 0x8, "WebArgumentHeader has incorrect size."); 120static_assert(sizeof(WebArgTLV) == 0x8, "WebArgTLV has incorrect size.");
48 121
49struct WebArgumentResult { 122struct WebCommonReturnValue {
50 u32 result_code; 123 u32 result_code;
124 INSERT_PADDING_BYTES(0x4);
51 std::array<char, 0x1000> last_url; 125 std::array<char, 0x1000> last_url;
52 u64 last_url_size; 126 u64 last_url_size;
53}; 127};
54static_assert(sizeof(WebArgumentResult) == 0x1010, "WebArgumentResult has incorrect size."); 128static_assert(sizeof(WebCommonReturnValue) == 0x1010, "WebCommonReturnValue has incorrect size.");
55 129
56static std::vector<u8> GetArgumentDataForTagType(const std::vector<u8>& data, u16 type) { 130struct WebWifiPageArg {
57 WebBufferHeader header; 131 INSERT_PADDING_BYTES(4);
58 ASSERT(sizeof(WebBufferHeader) <= data.size()); 132 std::array<char, 0x100> connection_test_url;
59 std::memcpy(&header, data.data(), sizeof(WebBufferHeader)); 133 std::array<char, 0x400> initial_url;
60 134 std::array<u8, 0x10> nifm_network_uuid;
61 u64 offset = sizeof(WebBufferHeader); 135 u32 nifm_requirement;
62 for (u16 i = 0; i < header.count; ++i) { 136};
63 WebArgumentHeader arg; 137static_assert(sizeof(WebWifiPageArg) == 0x518, "WebWifiPageArg has incorrect size.");
64 ASSERT(offset + sizeof(WebArgumentHeader) <= data.size()); 138
65 std::memcpy(&arg, data.data() + offset, sizeof(WebArgumentHeader)); 139struct WebWifiReturnValue {
66 offset += sizeof(WebArgumentHeader); 140 INSERT_PADDING_BYTES(4);
67 141 u32 result;
68 if (arg.type == type) { 142};
69 std::vector<u8> out(arg.size); 143static_assert(sizeof(WebWifiReturnValue) == 0x8, "WebWifiReturnValue has incorrect size.");
70 offset += arg.offset; 144
71 ASSERT(offset + arg.size <= data.size()); 145enum class OfflineWebSource : u32 {
72 std::memcpy(out.data(), data.data() + offset, out.size()); 146 OfflineHtmlPage = 0x1,
147 ApplicationLegalInformation = 0x2,
148 SystemDataPage = 0x3,
149};
150
151enum class ShopWebTarget {
152 ApplicationInfo,
153 AddOnContentList,
154 SubscriptionList,
155 ConsumableItemList,
156 Home,
157 Settings,
158};
159
160namespace {
161
162std::map<WebArgTLVType, std::vector<u8>> GetWebArguments(const std::vector<u8>& arg) {
163 WebArgHeader header{};
164 if (arg.size() < sizeof(WebArgHeader))
165 return {};
166
167 std::memcpy(&header, arg.data(), sizeof(WebArgHeader));
168
169 std::map<WebArgTLVType, std::vector<u8>> out;
170 u64 offset = sizeof(WebArgHeader);
171 for (std::size_t i = 0; i < header.count; ++i) {
172 WebArgTLV tlv{};
173 if (arg.size() < (offset + sizeof(WebArgTLV)))
73 return out; 174 return out;
74 }
75 175
76 offset += arg.offset + arg.size; 176 std::memcpy(&tlv, arg.data() + offset, sizeof(WebArgTLV));
77 } 177 offset += sizeof(WebArgTLV);
78 178
79 return {}; 179 offset += tlv.offset;
80} 180 if (arg.size() < (offset + tlv.size))
181 return out;
81 182
82static FileSys::VirtualFile GetManualRomFS() { 183 std::vector<u8> data(tlv.size);
83 auto& loader{Core::System::GetInstance().GetAppLoader()}; 184 std::memcpy(data.data(), arg.data() + offset, tlv.size);
185 offset += tlv.size;
84 186
85 FileSys::VirtualFile out; 187 out.insert_or_assign(tlv.type, data);
86 if (loader.ReadManualRomFS(out) == Loader::ResultStatus::Success) 188 }
87 return out;
88 189
190 return out;
191}
192
193FileSys::VirtualFile GetApplicationRomFS(u64 title_id, FileSys::ContentRecordType type) {
89 const auto& installed{Core::System::GetInstance().GetContentProvider()}; 194 const auto& installed{Core::System::GetInstance().GetContentProvider()};
90 const auto res = installed.GetEntry(Core::System::GetInstance().CurrentProcess()->GetTitleID(), 195 const auto res = installed.GetEntry(title_id, type);
91 FileSys::ContentRecordType::Manual);
92 196
93 if (res != nullptr) 197 if (res != nullptr) {
94 return res->GetRomFS(); 198 return res->GetRomFS();
199 }
200
201 if (type == FileSys::ContentRecordType::Data) {
202 return FileSys::SystemArchive::SynthesizeSystemArchive(title_id);
203 }
204
95 return nullptr; 205 return nullptr;
96} 206}
97 207
98WebBrowser::WebBrowser(Core::Frontend::WebBrowserApplet& frontend) : frontend(frontend) {} 208} // Anonymous namespace
209
210WebBrowser::WebBrowser(Core::Frontend::WebBrowserApplet& frontend,
211 Core::Frontend::ECommerceApplet* frontend_e_commerce)
212 : frontend(frontend), frontend_e_commerce(frontend_e_commerce) {}
99 213
100WebBrowser::~WebBrowser() = default; 214WebBrowser::~WebBrowser() = default;
101 215
@@ -111,24 +225,12 @@ void WebBrowser::Initialize() {
111 ASSERT(web_arg_storage != nullptr); 225 ASSERT(web_arg_storage != nullptr);
112 const auto& web_arg = web_arg_storage->GetData(); 226 const auto& web_arg = web_arg_storage->GetData();
113 227
114 const auto url_data = GetArgumentDataForTagType(web_arg, WEB_ARGUMENT_URL_TYPE); 228 ASSERT(web_arg.size() >= 0x8);
115 filename = Common::StringFromFixedZeroTerminatedBuffer( 229 std::memcpy(&kind, web_arg.data() + 0x4, sizeof(ShimKind));
116 reinterpret_cast<const char*>(url_data.data()), url_data.size());
117 230
118 temporary_dir = FileUtil::SanitizePath(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + 231 args = GetWebArguments(web_arg);
119 "web_applet_manual",
120 FileUtil::DirectorySeparator::PlatformDefault);
121 FileUtil::DeleteDirRecursively(temporary_dir);
122
123 manual_romfs = GetManualRomFS();
124 if (manual_romfs == nullptr) {
125 status = ResultCode(-1);
126 LOG_ERROR(Service_AM, "Failed to find manual for current process!");
127 }
128 232
129 filename = 233 InitializeInternal();
130 FileUtil::SanitizePath(temporary_dir + DIR_SEP + "html-document" + DIR_SEP + filename,
131 FileUtil::DirectorySeparator::PlatformDefault);
132} 234}
133 235
134bool WebBrowser::TransactionComplete() const { 236bool WebBrowser::TransactionComplete() const {
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h
index 7e0f34c7d..2474675de 100644
--- a/src/core/hle/service/am/applets/web_browser.h
+++ b/src/core/hle/service/am/applets/web_browser.h
@@ -10,6 +10,9 @@
10 10
11namespace Service::AM::Applets { 11namespace Service::AM::Applets {
12 12
13enum class ShimKind : u32;
14enum class WebArgTLVType : u16;
15
13class WebBrowser final : public Applet { 16class WebBrowser final : public Applet {
14public: 17public:
15 WebBrowser(Core::Frontend::WebBrowserApplet& frontend); 18 WebBrowser(Core::Frontend::WebBrowserApplet& frontend);
@@ -38,7 +41,9 @@ private:
38 bool unpacked = false; 41 bool unpacked = false;
39 ResultCode status = RESULT_SUCCESS; 42 ResultCode status = RESULT_SUCCESS;
40 43
41 FileSys::VirtualFile manual_romfs; 44 ShimKind kind;
45 std::map<WebArgTLVType, std::vector<u8>> args;
46
42 std::string temporary_dir; 47 std::string temporary_dir;
43 std::string filename; 48 std::string filename;
44}; 49};