summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/android/app/src/main/jni/native.cpp44
-rw-r--r--src/core/file_sys/registered_cache.cpp37
-rw-r--r--src/core/hle/kernel/k_process.cpp25
-rw-r--r--src/core/hle/kernel/k_process.h7
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp4
-rw-r--r--src/core/hle/service/service.h4
-rw-r--r--src/core/hle/service/sockets/bsd.cpp5
-rw-r--r--src/core/hle/service/sockets/bsd.h3
-rw-r--r--src/core/hle/service/ssl/ssl.cpp10
-rw-r--r--src/core/hle/service/ssl/ssl_backend_openssl.cpp3
-rw-r--r--src/core/hle/service/ssl/ssl_backend_schannel.cpp25
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp2
-rw-r--r--src/core/loader/kip.cpp2
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/reporter.cpp4
-rw-r--r--src/yuzu/main.cpp38
-rw-r--r--src/yuzu/main.h1
18 files changed, 171 insertions, 47 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index c23b2f19e..8b99d1d6e 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -30,6 +30,7 @@
30#include "core/cpu_manager.h" 30#include "core/cpu_manager.h"
31#include "core/crypto/key_manager.h" 31#include "core/crypto/key_manager.h"
32#include "core/file_sys/card_image.h" 32#include "core/file_sys/card_image.h"
33#include "core/file_sys/content_archive.h"
33#include "core/file_sys/registered_cache.h" 34#include "core/file_sys/registered_cache.h"
34#include "core/file_sys/submission_package.h" 35#include "core/file_sys/submission_package.h"
35#include "core/file_sys/vfs.h" 36#include "core/file_sys/vfs.h"
@@ -224,6 +225,42 @@ public:
224 m_system.Renderer().NotifySurfaceChanged(); 225 m_system.Renderer().NotifySurfaceChanged();
225 } 226 }
226 227
228 void ConfigureFilesystemProvider(const std::string& filepath) {
229 const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read);
230 if (!file) {
231 return;
232 }
233
234 auto loader = Loader::GetLoader(m_system, file);
235 if (!loader) {
236 return;
237 }
238
239 const auto file_type = loader->GetFileType();
240 if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
241 return;
242 }
243
244 u64 program_id = 0;
245 const auto res2 = loader->ReadProgramId(program_id);
246 if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
247 m_manual_provider->AddEntry(FileSys::TitleType::Application,
248 FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
249 program_id, file);
250 } else if (res2 == Loader::ResultStatus::Success &&
251 (file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
252 const auto nsp = file_type == Loader::FileType::NSP
253 ? std::make_shared<FileSys::NSP>(file)
254 : FileSys::XCI{file}.GetSecurePartitionNSP();
255 for (const auto& title : nsp->GetNCAs()) {
256 for (const auto& entry : title.second) {
257 m_manual_provider->AddEntry(entry.first.first, entry.first.second, title.first,
258 entry.second->GetBaseFile());
259 }
260 }
261 }
262 }
263
227 Core::SystemResultStatus InitializeEmulation(const std::string& filepath) { 264 Core::SystemResultStatus InitializeEmulation(const std::string& filepath) {
228 std::scoped_lock lock(m_mutex); 265 std::scoped_lock lock(m_mutex);
229 266
@@ -254,8 +291,14 @@ public:
254 std::move(android_keyboard), // Software Keyboard 291 std::move(android_keyboard), // Software Keyboard
255 nullptr, // Web Browser 292 nullptr, // Web Browser
256 }); 293 });
294
295 // Initialize filesystem.
296 m_manual_provider = std::make_unique<FileSys::ManualContentProvider>();
257 m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); 297 m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
298 m_system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
299 m_manual_provider.get());
258 m_system.GetFileSystemController().CreateFactories(*m_vfs); 300 m_system.GetFileSystemController().CreateFactories(*m_vfs);
301 ConfigureFilesystemProvider(filepath);
259 302
260 // Initialize account manager 303 // Initialize account manager
261 m_profile_manager = std::make_unique<Service::Account::ProfileManager>(); 304 m_profile_manager = std::make_unique<Service::Account::ProfileManager>();
@@ -489,6 +532,7 @@ private:
489 bool m_is_paused{}; 532 bool m_is_paused{};
490 SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; 533 SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
491 std::unique_ptr<Service::Account::ProfileManager> m_profile_manager; 534 std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
535 std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
492 536
493 // GPU driver parameters 537 // GPU driver parameters
494 std::shared_ptr<Common::DynamicLibrary> m_vulkan_library; 538 std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index a28af3594..f70adab82 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -606,9 +606,9 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
606 const auto result = RemoveExistingEntry(title_id); 606 const auto result = RemoveExistingEntry(title_id);
607 607
608 // Install Metadata File 608 // Install Metadata File
609 const auto res = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data); 609 const auto meta_result = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data);
610 if (res != InstallResult::Success) { 610 if (meta_result != InstallResult::Success) {
611 return res; 611 return meta_result;
612 } 612 }
613 613
614 // Install all the other NCAs 614 // Install all the other NCAs
@@ -621,9 +621,19 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
621 if (nca == nullptr) { 621 if (nca == nullptr) {
622 return InstallResult::ErrorCopyFailed; 622 return InstallResult::ErrorCopyFailed;
623 } 623 }
624 const auto res2 = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id); 624 if (nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS &&
625 if (res2 != InstallResult::Success) { 625 nca->GetTitleId() != title_id) {
626 return res2; 626 // Create fake cnmt for patch to multiprogram application
627 const auto sub_nca_result =
628 InstallEntry(*nca, TitleType::Update, overwrite_if_exists, copy);
629 if (sub_nca_result != InstallResult::Success) {
630 return sub_nca_result;
631 }
632 continue;
633 }
634 const auto nca_result = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id);
635 if (nca_result != InstallResult::Success) {
636 return nca_result;
627 } 637 }
628 } 638 }
629 639
@@ -663,6 +673,8 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
663} 673}
664 674
665bool RegisteredCache::RemoveExistingEntry(u64 title_id) const { 675bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
676 bool removed_data = false;
677
666 const auto delete_nca = [this](const NcaID& id) { 678 const auto delete_nca = [this](const NcaID& id) {
667 const auto path = GetRelativePathFromNcaID(id, false, true, false); 679 const auto path = GetRelativePathFromNcaID(id, false, true, false);
668 680
@@ -706,11 +718,18 @@ bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
706 const auto deleted_html = delete_nca(html_id); 718 const auto deleted_html = delete_nca(html_id);
707 const auto deleted_legal = delete_nca(legal_id); 719 const auto deleted_legal = delete_nca(legal_id);
708 720
709 return deleted_meta && (deleted_meta || deleted_program || deleted_data || 721 removed_data |= (deleted_meta || deleted_program || deleted_data || deleted_control ||
710 deleted_control || deleted_html || deleted_legal); 722 deleted_html || deleted_legal);
711 } 723 }
712 724
713 return false; 725 // If patch entries for any program exist in yuzu meta, remove them
726 for (u8 i = 0; i < 0x10; i++) {
727 const auto meta_dir = dir->CreateDirectoryRelative("yuzu_meta");
728 const auto filename = GetCNMTName(TitleType::Update, title_id + i);
729 removed_data |= meta_dir->DeleteFile(filename);
730 }
731
732 return removed_data;
714} 733}
715 734
716InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy, 735InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index e573e2a57..703049ede 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -38,7 +38,7 @@ namespace {
38 */ 38 */
39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, 39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
40 KProcessAddress stack_top) { 40 KProcessAddress stack_top) {
41 const KProcessAddress entry_point = owner_process.GetPageTable().GetCodeRegionStart(); 41 const KProcessAddress entry_point = owner_process.GetEntryPoint();
42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1)); 42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
43 43
44 KThread* thread = KThread::Create(system.Kernel()); 44 KThread* thread = KThread::Create(system.Kernel());
@@ -358,6 +358,21 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
358 m_system_resource_size = metadata.GetSystemResourceSize(); 358 m_system_resource_size = metadata.GetSystemResourceSize();
359 m_image_size = code_size; 359 m_image_size = code_size;
360 360
361 if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit) {
362 // For 39-bit processes, the ASLR region starts at 0x800'0000 and is ~512GiB large.
363 // However, some (buggy) programs/libraries like skyline incorrectly depend on the
364 // existence of ASLR pages before the entry point, so we will adjust the load address
365 // to point to about 2GiB into the ASLR region.
366 m_code_address = 0x8000'0000;
367 } else {
368 // All other processes can be mapped at the beginning of the code region.
369 if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is36Bit) {
370 m_code_address = 0x800'0000;
371 } else {
372 m_code_address = 0x20'0000;
373 }
374 }
375
361 KScopedResourceReservation memory_reservation( 376 KScopedResourceReservation memory_reservation(
362 m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size); 377 m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size);
363 if (!memory_reservation.Succeeded()) { 378 if (!memory_reservation.Succeeded()) {
@@ -368,15 +383,15 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
368 // Initialize process address space 383 // Initialize process address space
369 if (const Result result{m_page_table.InitializeForProcess( 384 if (const Result result{m_page_table.InitializeForProcess(
370 metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, 385 metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
371 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit, 386 this->GetEntryPoint(), code_size, std::addressof(m_kernel.GetAppSystemResource()),
372 m_kernel.System().ApplicationMemory())}; 387 m_resource_limit, m_kernel.System().ApplicationMemory())};
373 result.IsError()) { 388 result.IsError()) {
374 R_RETURN(result); 389 R_RETURN(result);
375 } 390 }
376 391
377 // Map process code region 392 // Map process code region
378 if (const Result result{m_page_table.MapProcessCode(m_page_table.GetCodeRegionStart(), 393 if (const Result result{m_page_table.MapProcessCode(this->GetEntryPoint(), code_size / PageSize,
379 code_size / PageSize, KMemoryState::Code, 394 KMemoryState::Code,
380 KMemoryPermission::None)}; 395 KMemoryPermission::None)};
381 result.IsError()) { 396 result.IsError()) {
382 R_RETURN(result); 397 R_RETURN(result);
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index c9b37e138..4fdeaf11a 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -177,6 +177,10 @@ public:
177 return m_program_id; 177 return m_program_id;
178 } 178 }
179 179
180 KProcessAddress GetEntryPoint() const {
181 return m_code_address;
182 }
183
180 /// Gets the resource limit descriptor for this process 184 /// Gets the resource limit descriptor for this process
181 KResourceLimit* GetResourceLimit() const; 185 KResourceLimit* GetResourceLimit() const;
182 186
@@ -485,6 +489,9 @@ private:
485 /// Address indicating the location of the process' dedicated TLS region. 489 /// Address indicating the location of the process' dedicated TLS region.
486 KProcessAddress m_plr_address = 0; 490 KProcessAddress m_plr_address = 0;
487 491
492 /// Address indicating the location of the process's entry point.
493 KProcessAddress m_code_address = 0;
494
488 /// Random values for svcGetInfo RandomEntropy 495 /// Random values for svcGetInfo RandomEntropy
489 std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{}; 496 std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{};
490 497
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 07e570a9f..7d7bb8687 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -204,9 +204,11 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) {
204 if (!mapping->fixed) { 204 if (!mapping->fixed) {
205 auto& allocator{mapping->big_page ? *vm.big_page_allocator : *vm.small_page_allocator}; 205 auto& allocator{mapping->big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
206 u32 page_size_bits{mapping->big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS}; 206 u32 page_size_bits{mapping->big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
207 u32 page_size{mapping->big_page ? vm.big_page_size : VM::YUZU_PAGESIZE};
208 u64 aligned_size{Common::AlignUp(mapping->size, page_size)};
207 209
208 allocator.Free(static_cast<u32>(mapping->offset >> page_size_bits), 210 allocator.Free(static_cast<u32>(mapping->offset >> page_size_bits),
209 static_cast<u32>(mapping->size >> page_size_bits)); 211 static_cast<u32>(aligned_size >> page_size_bits));
210 } 212 }
211 213
212 // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state 214 // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 45b2c43b7..d539ed0f4 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -79,8 +79,8 @@ protected:
79 using HandlerFnP = void (Self::*)(HLERequestContext&); 79 using HandlerFnP = void (Self::*)(HLERequestContext&);
80 80
81 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. 81 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
82 [[nodiscard]] std::scoped_lock<std::mutex> LockService() { 82 [[nodiscard]] virtual std::unique_lock<std::mutex> LockService() {
83 return std::scoped_lock{lock_service}; 83 return std::unique_lock{lock_service};
84 } 84 }
85 85
86 /// System context that the service operates under. 86 /// System context that the service operates under.
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 11f8efbac..d8509c1dd 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -1029,6 +1029,11 @@ BSD::~BSD() {
1029 } 1029 }
1030} 1030}
1031 1031
1032std::unique_lock<std::mutex> BSD::LockService() {
1033 // Do not lock socket IClient instances.
1034 return {};
1035}
1036
1032BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} { 1037BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
1033 // clang-format off 1038 // clang-format off
1034 static const FunctionInfo functions[] = { 1039 static const FunctionInfo functions[] = {
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index 430edb97c..161f22b9b 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -186,6 +186,9 @@ private:
186 186
187 // Callback identifier for the OnProxyPacketReceived event. 187 // Callback identifier for the OnProxyPacketReceived event.
188 Network::RoomMember::CallbackHandle<Network::ProxyPacket> proxy_packet_received; 188 Network::RoomMember::CallbackHandle<Network::ProxyPacket> proxy_packet_received;
189
190protected:
191 virtual std::unique_lock<std::mutex> LockService() override;
189}; 192};
190 193
191class BSDCFG final : public ServiceFramework<BSDCFG> { 194class BSDCFG final : public ServiceFramework<BSDCFG> {
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index 2cba9e5c9..6c8427b0d 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -139,7 +139,6 @@ private:
139 bool do_not_close_socket = false; 139 bool do_not_close_socket = false;
140 bool get_server_cert_chain = false; 140 bool get_server_cert_chain = false;
141 std::shared_ptr<Network::SocketBase> socket; 141 std::shared_ptr<Network::SocketBase> socket;
142 bool did_set_host_name = false;
143 bool did_handshake = false; 142 bool did_handshake = false;
144 143
145 Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) { 144 Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) {
@@ -174,11 +173,7 @@ private:
174 Result SetHostNameImpl(const std::string& hostname) { 173 Result SetHostNameImpl(const std::string& hostname) {
175 LOG_DEBUG(Service_SSL, "called. hostname={}", hostname); 174 LOG_DEBUG(Service_SSL, "called. hostname={}", hostname);
176 ASSERT(!did_handshake); 175 ASSERT(!did_handshake);
177 Result res = backend->SetHostName(hostname); 176 return backend->SetHostName(hostname);
178 if (res == ResultSuccess) {
179 did_set_host_name = true;
180 }
181 return res;
182 } 177 }
183 178
184 Result SetVerifyOptionImpl(u32 option) { 179 Result SetVerifyOptionImpl(u32 option) {
@@ -208,9 +203,6 @@ private:
208 203
209 Result DoHandshakeImpl() { 204 Result DoHandshakeImpl() {
210 ASSERT_OR_EXECUTE(!did_handshake && socket, { return ResultNoSocket; }); 205 ASSERT_OR_EXECUTE(!did_handshake && socket, { return ResultNoSocket; });
211 ASSERT_OR_EXECUTE_MSG(
212 did_set_host_name, { return ResultInternalError; },
213 "Expected SetHostName before DoHandshake");
214 Result res = backend->DoHandshake(); 206 Result res = backend->DoHandshake();
215 did_handshake = res.IsSuccess(); 207 did_handshake = res.IsSuccess();
216 return res; 208 return res;
diff --git a/src/core/hle/service/ssl/ssl_backend_openssl.cpp b/src/core/hle/service/ssl/ssl_backend_openssl.cpp
index b2dd37cd4..5714e6f3c 100644
--- a/src/core/hle/service/ssl/ssl_backend_openssl.cpp
+++ b/src/core/hle/service/ssl/ssl_backend_openssl.cpp
@@ -167,9 +167,8 @@ public:
167 } 167 }
168 168
169 ~SSLConnectionBackendOpenSSL() { 169 ~SSLConnectionBackendOpenSSL() {
170 // these are null-tolerant: 170 // this is null-tolerant:
171 SSL_free(ssl); 171 SSL_free(ssl);
172 BIO_free(bio);
173 } 172 }
174 173
175 static void KeyLogCallback(const SSL* ssl, const char* line) { 174 static void KeyLogCallback(const SSL* ssl, const char* line) {
diff --git a/src/core/hle/service/ssl/ssl_backend_schannel.cpp b/src/core/hle/service/ssl/ssl_backend_schannel.cpp
index bda12b761..d834a0c1f 100644
--- a/src/core/hle/service/ssl/ssl_backend_schannel.cpp
+++ b/src/core/hle/service/ssl/ssl_backend_schannel.cpp
@@ -31,9 +31,9 @@ CredHandle cred_handle;
31static void OneTimeInit() { 31static void OneTimeInit() {
32 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; 32 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
33 schannel_cred.dwFlags = 33 schannel_cred.dwFlags =
34 SCH_USE_STRONG_CRYPTO | // don't allow insecure protocols 34 SCH_USE_STRONG_CRYPTO | // don't allow insecure protocols
35 SCH_CRED_AUTO_CRED_VALIDATION | // validate certs 35 SCH_CRED_NO_SERVERNAME_CHECK | // don't validate server names
36 SCH_CRED_NO_DEFAULT_CREDS; // don't automatically present a client certificate 36 SCH_CRED_NO_DEFAULT_CREDS; // don't automatically present a client certificate
37 // ^ I'm assuming that nobody would want to connect Yuzu to a 37 // ^ I'm assuming that nobody would want to connect Yuzu to a
38 // service that requires some OS-provided corporate client 38 // service that requires some OS-provided corporate client
39 // certificate, and presenting one to some arbitrary server 39 // certificate, and presenting one to some arbitrary server
@@ -227,16 +227,15 @@ public:
227 ciphertext_read_buf.size()); 227 ciphertext_read_buf.size());
228 } 228 }
229 229
230 const SECURITY_STATUS ret = 230 char* hostname_ptr = hostname ? const_cast<char*>(hostname->c_str()) : nullptr;
231 InitializeSecurityContextA(&cred_handle, initial_call_done ? &ctxt : nullptr, 231 const SECURITY_STATUS ret = InitializeSecurityContextA(
232 // Caller ensured we have set a hostname: 232 &cred_handle, initial_call_done ? &ctxt : nullptr, hostname_ptr, req,
233 const_cast<char*>(hostname.value().c_str()), req, 233 0, // Reserved1
234 0, // Reserved1 234 0, // TargetDataRep not used with Schannel
235 0, // TargetDataRep not used with Schannel 235 initial_call_done ? &input_desc : nullptr,
236 initial_call_done ? &input_desc : nullptr, 236 0, // Reserved2
237 0, // Reserved2 237 initial_call_done ? nullptr : &ctxt, &output_desc, &attr,
238 initial_call_done ? nullptr : &ctxt, &output_desc, &attr, 238 nullptr); // ptsExpiry
239 nullptr); // ptsExpiry
240 239
241 if (output_buffers[0].pvBuffer) { 240 if (output_buffers[0].pvBuffer) {
242 const std::span span(static_cast<u8*>(output_buffers[0].pvBuffer), 241 const std::span span(static_cast<u8*>(output_buffers[0].pvBuffer),
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index e04ad19db..f4eaf3331 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -153,7 +153,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
153 153
154 // Load NSO modules 154 // Load NSO modules
155 modules.clear(); 155 modules.clear();
156 const VAddr base_address{GetInteger(process.GetPageTable().GetCodeRegionStart())}; 156 const VAddr base_address{GetInteger(process.GetEntryPoint())};
157 VAddr next_load_addr{base_address}; 157 VAddr next_load_addr{base_address};
158 const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), 158 const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
159 system.GetContentProvider()}; 159 system.GetContentProvider()};
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index ffe976b94..d722459c6 100644
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
96 } 96 }
97 97
98 codeset.memory = std::move(program_image); 98 codeset.memory = std::move(program_image);
99 const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); 99 const VAddr base_address = GetInteger(process.GetEntryPoint());
100 process.LoadModule(std::move(codeset), base_address); 100 process.LoadModule(std::move(codeset), base_address);
101 101
102 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); 102 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address);
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 506808b5d..d7562b4bc 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -203,7 +203,7 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector<u8>& data)
203 203
204 // Load codeset for current process 204 // Load codeset for current process
205 codeset.memory = std::move(program_image); 205 codeset.memory = std::move(program_image);
206 process.LoadModule(std::move(codeset), process.GetPageTable().GetCodeRegionStart()); 206 process.LoadModule(std::move(codeset), process.GetEntryPoint());
207 207
208 return true; 208 return true;
209} 209}
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 74cc9579f..549822506 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
167 modules.clear(); 167 modules.clear();
168 168
169 // Load module 169 // Load module
170 const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); 170 const VAddr base_address = GetInteger(process.GetEntryPoint());
171 if (!LoadModule(process, system, *file, base_address, true, true)) { 171 if (!LoadModule(process, system, *file, base_address, true, true)) {
172 return {ResultStatus::ErrorLoadingNSO, {}}; 172 return {ResultStatus::ErrorLoadingNSO, {}};
173 } 173 }
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index b5b3e7eda..ed875d444 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -117,8 +117,8 @@ json GetProcessorStateDataAuto(Core::System& system) {
117 arm.SaveContext(context); 117 arm.SaveContext(context);
118 118
119 return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32", 119 return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32",
120 GetInteger(process->GetPageTable().GetCodeRegionStart()), 120 GetInteger(process->GetEntryPoint()), context.sp, context.pc,
121 context.sp, context.pc, context.pstate, context.cpu_registers); 121 context.pstate, context.cpu_registers);
122} 122}
123 123
124json GetBacktraceData(Core::System& system) { 124json GetBacktraceData(Core::System& system) {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index a9d035f3d..8e933af64 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1811,6 +1811,43 @@ bool GMainWindow::SelectAndSetCurrentUser(
1811 return true; 1811 return true;
1812} 1812}
1813 1813
1814void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
1815 // Ensure all NCAs are registered before launching the game
1816 const auto file = vfs->OpenFile(filepath, FileSys::Mode::Read);
1817 if (!file) {
1818 return;
1819 }
1820
1821 auto loader = Loader::GetLoader(*system, file);
1822 if (!loader) {
1823 return;
1824 }
1825
1826 const auto file_type = loader->GetFileType();
1827 if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
1828 return;
1829 }
1830
1831 u64 program_id = 0;
1832 const auto res2 = loader->ReadProgramId(program_id);
1833 if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
1834 provider->AddEntry(FileSys::TitleType::Application,
1835 FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()), program_id,
1836 file);
1837 } else if (res2 == Loader::ResultStatus::Success &&
1838 (file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
1839 const auto nsp = file_type == Loader::FileType::NSP
1840 ? std::make_shared<FileSys::NSP>(file)
1841 : FileSys::XCI{file}.GetSecurePartitionNSP();
1842 for (const auto& title : nsp->GetNCAs()) {
1843 for (const auto& entry : title.second) {
1844 provider->AddEntry(entry.first.first, entry.first.second, title.first,
1845 entry.second->GetBaseFile());
1846 }
1847 }
1848 }
1849}
1850
1814void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, 1851void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
1815 StartGameType type) { 1852 StartGameType type) {
1816 LOG_INFO(Frontend, "yuzu starting..."); 1853 LOG_INFO(Frontend, "yuzu starting...");
@@ -1825,6 +1862,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1825 1862
1826 last_filename_booted = filename; 1863 last_filename_booted = filename;
1827 1864
1865 ConfigureFilesystemProvider(filename.toStdString());
1828 const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); 1866 const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
1829 const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index); 1867 const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index);
1830 1868
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 2cfb96257..1b7055122 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -399,6 +399,7 @@ private:
399 void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); 399 void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
400 bool CheckDarkMode(); 400 bool CheckDarkMode();
401 bool CheckSystemArchiveDecryption(); 401 bool CheckSystemArchiveDecryption();
402 void ConfigureFilesystemProvider(const std::string& filepath);
402 403
403 QString GetTasStateDescription() const; 404 QString GetTasStateDescription() const;
404 bool CreateShortcut(const std::string& shortcut_path, const std::string& title, 405 bool CreateShortcut(const std::string& shortcut_path, const std::string& title,