Compare commits

...

23 Commits

Author SHA1 Message Date
d9af082a1a Android #51 2023-08-26 00:57:29 +00:00
bc4e58eb51 Merge pull request #11377 from BenjaminHalko/reverse-slider-input
ui: Fixed inverted controls on ReverseSlider widgets
2023-08-25 18:06:03 -04:00
8674724ef0 Merge pull request #11378 from t895/game-flag
android: Use appCategory to specify the app is a game
2023-08-25 18:05:58 -04:00
a8edbb7019 Merge pull request #11370 from FearlessTobi/fix-filesize
filesystem: Return correct error for RenameFile when dest_path already exists
2023-08-25 18:02:54 -04:00
d8c8fbe41f Merge pull request #11371 from FearlessTobi/fix-cli-updates
yuzu/main: Ensure NCAs are registered in content provider when launching from CLI
2023-08-25 18:02:47 -04:00
234cc45192 ssl: tolerate handshake without hostname set (#11328) 2023-08-26 00:02:32 +02:00
b923f5aa7e registered_cache: create fake CNMT entries for program updates of multiprogram applications (#11319) 2023-08-26 00:00:15 +02:00
18ad55be0b kernel: offset code entry point for 39-bit address space type (#11326) 2023-08-25 23:59:32 +02:00
4e71628097 android: Use appCategory to specify the app is a game 2023-08-25 17:17:48 -04:00
92e6ff30a1 Merge pull request #11357 from liamwhite/lime-vfs
android: jni: ensure NCAs from loaded filepath are registered in manual content provider
2023-08-25 13:04:22 -07:00
49df2b9715 ui: Fixed inverted controls on ReverseSlider widgets
fixes: #11236
2023-08-25 10:06:34 -07:00
2f2de400e1 Merge pull request #11375 from liamwhite/nvhost-as-gpu
nvhost_as_gpu: ensure mappings are aligned to big page size when deallocated
2023-08-25 17:04:16 +02:00
9e134c3da2 nvhost_as_gpu: ensure mappings are aligned to big page size when deallocated 2023-08-25 09:39:18 -04:00
59b3c30f94 yuzu/main: Ensure NCAs are registered in content provider when launching from CLI
Fixes updates and DLC not being loaded when launching yuzu from the command line.

Similar to https://github.com/yuzu-emu/yuzu/pull/11357.
Fixes https://github.com/yuzu-emu/yuzu/issues/8352,
2023-08-24 18:48:02 +02:00
a669e37ddb filesystem: Return correct error for RenameFile when dest_path already exists
Allows Grid Autosport to boot.

Fixes https://github.com/yuzu-emu/yuzu/issues/8287.
2023-08-24 17:07:39 +02:00
7d89f2c146 Merge pull request #11327 from liamwhite/skyline-2
sockets: avoid locking around socket session calls
2023-08-24 10:33:53 -04:00
51ffc2c66c Merge pull request #11367 from FearlessTobi/fix-filesize
game_list_worker: Display correct size for NAX games
2023-08-24 10:33:42 -04:00
e41655960e game_list_worker: Display correct size for NAX games
This was a regression from https://github.com/yuzu-emu/yuzu/pull/1837.

Fixes https://github.com/yuzu-emu/yuzu/issues/1938.
2023-08-24 01:16:19 +02:00
ccd163ab2c Merge pull request #11352 from t895/recurse-subfolders
android: Search game directory recursively
2023-08-23 10:20:02 -04:00
182fb83556 android: Set default build variant to mainlineRelWithDebInfo (#11358) 2023-08-23 16:12:39 +02:00
2c4ebeb51d android: jni: ensure NCAs from loaded filepath are registered in manual content provider 2023-08-22 22:47:25 -04:00
35b77b9599 android: Search game directory recursively 2023-08-22 15:16:20 -04:00
0cd9d51e06 sockets: avoid locking around socket session calls 2023-08-19 23:09:35 -04:00
25 changed files with 232 additions and 67 deletions

View File

@ -1,3 +1,11 @@
| Pull Request | Commit | Title | Author | Merged? |
|----|----|----|----|----|
End of merge log. You can find the original README.md below the break.
-----
<!-- <!--
SPDX-FileCopyrightText: 2018 yuzu Emulator Project SPDX-FileCopyrightText: 2018 yuzu Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later

View File

@ -95,6 +95,7 @@ android {
// builds a release build that doesn't need signing // builds a release build that doesn't need signing
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
register("relWithDebInfo") { register("relWithDebInfo") {
isDefault = true
resValue("string", "app_name_suffixed", "yuzu Debug Release") resValue("string", "app_name_suffixed", "yuzu Debug Release")
signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.getByName("debug")
isMinifyEnabled = true isMinifyEnabled = true
@ -122,6 +123,7 @@ android {
flavorDimensions.add("version") flavorDimensions.add("version")
productFlavors { productFlavors {
create("mainline") { create("mainline") {
isDefault = true
dimension = "version" dimension = "version"
buildConfigField("Boolean", "PREMIUM", "false") buildConfigField("Boolean", "PREMIUM", "false")
} }

View File

@ -25,6 +25,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
android:hasFragileUserData="false" android:hasFragileUserData="false"
android:supportsRtl="true" android:supportsRtl="true"
android:isGame="true" android:isGame="true"
android:appCategory="game"
android:localeConfig="@xml/locales_config" android:localeConfig="@xml/locales_config"
android:banner="@drawable/tv_banner" android:banner="@drawable/tv_banner"
android:extractNativeLibs="true" android:extractNativeLibs="true"

View File

@ -11,6 +11,7 @@ import kotlinx.serialization.json.Json
import org.yuzu.yuzu_emu.NativeLibrary import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.YuzuApplication import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.model.Game import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.model.MinimalDocumentFile
object GameHelper { object GameHelper {
const val KEY_GAME_PATH = "game_path" const val KEY_GAME_PATH = "game_path"
@ -29,15 +30,7 @@ object GameHelper {
// Ensure keys are loaded so that ROM metadata can be decrypted. // Ensure keys are loaded so that ROM metadata can be decrypted.
NativeLibrary.reloadKeys() NativeLibrary.reloadKeys()
val children = FileUtil.listFiles(context, gamesUri) addGamesRecursive(games, FileUtil.listFiles(context, gamesUri), 3)
for (file in children) {
if (!file.isDirectory) {
// Check that the file has an extension we care about before trying to read out of it.
if (Game.extensions.contains(FileUtil.getExtension(file.uri))) {
games.add(getGame(file.uri))
}
}
}
// Cache list of games found on disk // Cache list of games found on disk
val serializedGames = mutableSetOf<String>() val serializedGames = mutableSetOf<String>()
@ -52,6 +45,30 @@ object GameHelper {
return games.toList() return games.toList()
} }
private fun addGamesRecursive(
games: MutableList<Game>,
files: Array<MinimalDocumentFile>,
depth: Int
) {
if (depth <= 0) {
return
}
files.forEach {
if (it.isDirectory) {
addGamesRecursive(
games,
FileUtil.listFiles(YuzuApplication.appContext, it.uri),
depth - 1
)
} else {
if (Game.extensions.contains(FileUtil.getExtension(it.uri))) {
games.add(getGame(it.uri))
}
}
}
}
private fun getGame(uri: Uri): Game { private fun getGame(uri: Uri): Game {
val filePath = uri.toString() val filePath = uri.toString()
var name = NativeLibrary.getTitle(filePath) var name = NativeLibrary.getTitle(filePath)

View File

@ -30,6 +30,7 @@
#include "core/cpu_manager.h" #include "core/cpu_manager.h"
#include "core/crypto/key_manager.h" #include "core/crypto/key_manager.h"
#include "core/file_sys/card_image.h" #include "core/file_sys/card_image.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/registered_cache.h" #include "core/file_sys/registered_cache.h"
#include "core/file_sys/submission_package.h" #include "core/file_sys/submission_package.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
@ -224,6 +225,42 @@ public:
m_system.Renderer().NotifySurfaceChanged(); m_system.Renderer().NotifySurfaceChanged();
} }
void ConfigureFilesystemProvider(const std::string& filepath) {
const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read);
if (!file) {
return;
}
auto loader = Loader::GetLoader(m_system, file);
if (!loader) {
return;
}
const auto file_type = loader->GetFileType();
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
return;
}
u64 program_id = 0;
const auto res2 = loader->ReadProgramId(program_id);
if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
m_manual_provider->AddEntry(FileSys::TitleType::Application,
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
program_id, file);
} else if (res2 == Loader::ResultStatus::Success &&
(file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
const auto nsp = file_type == Loader::FileType::NSP
? std::make_shared<FileSys::NSP>(file)
: FileSys::XCI{file}.GetSecurePartitionNSP();
for (const auto& title : nsp->GetNCAs()) {
for (const auto& entry : title.second) {
m_manual_provider->AddEntry(entry.first.first, entry.first.second, title.first,
entry.second->GetBaseFile());
}
}
}
}
Core::SystemResultStatus InitializeEmulation(const std::string& filepath) { Core::SystemResultStatus InitializeEmulation(const std::string& filepath) {
std::scoped_lock lock(m_mutex); std::scoped_lock lock(m_mutex);
@ -254,8 +291,14 @@ public:
std::move(android_keyboard), // Software Keyboard std::move(android_keyboard), // Software Keyboard
nullptr, // Web Browser nullptr, // Web Browser
}); });
// Initialize filesystem.
m_manual_provider = std::make_unique<FileSys::ManualContentProvider>();
m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
m_system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
m_manual_provider.get());
m_system.GetFileSystemController().CreateFactories(*m_vfs); m_system.GetFileSystemController().CreateFactories(*m_vfs);
ConfigureFilesystemProvider(filepath);
// Initialize account manager // Initialize account manager
m_profile_manager = std::make_unique<Service::Account::ProfileManager>(); m_profile_manager = std::make_unique<Service::Account::ProfileManager>();
@ -489,6 +532,7 @@ private:
bool m_is_paused{}; bool m_is_paused{};
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
std::unique_ptr<Service::Account::ProfileManager> m_profile_manager; std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
// GPU driver parameters // GPU driver parameters
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library; std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;

View File

@ -606,9 +606,9 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
const auto result = RemoveExistingEntry(title_id); const auto result = RemoveExistingEntry(title_id);
// Install Metadata File // Install Metadata File
const auto res = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data); const auto meta_result = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data);
if (res != InstallResult::Success) { if (meta_result != InstallResult::Success) {
return res; return meta_result;
} }
// Install all the other NCAs // Install all the other NCAs
@ -621,9 +621,19 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
if (nca == nullptr) { if (nca == nullptr) {
return InstallResult::ErrorCopyFailed; return InstallResult::ErrorCopyFailed;
} }
const auto res2 = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id); if (nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS &&
if (res2 != InstallResult::Success) { nca->GetTitleId() != title_id) {
return res2; // Create fake cnmt for patch to multiprogram application
const auto sub_nca_result =
InstallEntry(*nca, TitleType::Update, overwrite_if_exists, copy);
if (sub_nca_result != InstallResult::Success) {
return sub_nca_result;
}
continue;
}
const auto nca_result = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id);
if (nca_result != InstallResult::Success) {
return nca_result;
} }
} }
@ -663,6 +673,8 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
} }
bool RegisteredCache::RemoveExistingEntry(u64 title_id) const { bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
bool removed_data = false;
const auto delete_nca = [this](const NcaID& id) { const auto delete_nca = [this](const NcaID& id) {
const auto path = GetRelativePathFromNcaID(id, false, true, false); const auto path = GetRelativePathFromNcaID(id, false, true, false);
@ -706,11 +718,18 @@ bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
const auto deleted_html = delete_nca(html_id); const auto deleted_html = delete_nca(html_id);
const auto deleted_legal = delete_nca(legal_id); const auto deleted_legal = delete_nca(legal_id);
return deleted_meta && (deleted_meta || deleted_program || deleted_data || removed_data |= (deleted_meta || deleted_program || deleted_data || deleted_control ||
deleted_control || deleted_html || deleted_legal); deleted_html || deleted_legal);
} }
return false; // If patch entries for any program exist in yuzu meta, remove them
for (u8 i = 0; i < 0x10; i++) {
const auto meta_dir = dir->CreateDirectoryRelative("yuzu_meta");
const auto filename = GetCNMTName(TitleType::Update, title_id + i);
removed_data |= meta_dir->DeleteFile(filename);
}
return removed_data;
} }
InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy, InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,

View File

@ -38,7 +38,7 @@ namespace {
*/ */
void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
KProcessAddress stack_top) { KProcessAddress stack_top) {
const KProcessAddress entry_point = owner_process.GetPageTable().GetCodeRegionStart(); const KProcessAddress entry_point = owner_process.GetEntryPoint();
ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1)); ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
KThread* thread = KThread::Create(system.Kernel()); KThread* thread = KThread::Create(system.Kernel());
@ -358,6 +358,21 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
m_system_resource_size = metadata.GetSystemResourceSize(); m_system_resource_size = metadata.GetSystemResourceSize();
m_image_size = code_size; m_image_size = code_size;
if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit) {
// For 39-bit processes, the ASLR region starts at 0x800'0000 and is ~512GiB large.
// However, some (buggy) programs/libraries like skyline incorrectly depend on the
// existence of ASLR pages before the entry point, so we will adjust the load address
// to point to about 2GiB into the ASLR region.
m_code_address = 0x8000'0000;
} else {
// All other processes can be mapped at the beginning of the code region.
if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is36Bit) {
m_code_address = 0x800'0000;
} else {
m_code_address = 0x20'0000;
}
}
KScopedResourceReservation memory_reservation( KScopedResourceReservation memory_reservation(
m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size); m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size);
if (!memory_reservation.Succeeded()) { if (!memory_reservation.Succeeded()) {
@ -368,15 +383,15 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
// Initialize process address space // Initialize process address space
if (const Result result{m_page_table.InitializeForProcess( if (const Result result{m_page_table.InitializeForProcess(
metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit, this->GetEntryPoint(), code_size, std::addressof(m_kernel.GetAppSystemResource()),
m_kernel.System().ApplicationMemory())}; m_resource_limit, m_kernel.System().ApplicationMemory())};
result.IsError()) { result.IsError()) {
R_RETURN(result); R_RETURN(result);
} }
// Map process code region // Map process code region
if (const Result result{m_page_table.MapProcessCode(m_page_table.GetCodeRegionStart(), if (const Result result{m_page_table.MapProcessCode(this->GetEntryPoint(), code_size / PageSize,
code_size / PageSize, KMemoryState::Code, KMemoryState::Code,
KMemoryPermission::None)}; KMemoryPermission::None)};
result.IsError()) { result.IsError()) {
R_RETURN(result); R_RETURN(result);

View File

@ -177,6 +177,10 @@ public:
return m_program_id; return m_program_id;
} }
KProcessAddress GetEntryPoint() const {
return m_code_address;
}
/// Gets the resource limit descriptor for this process /// Gets the resource limit descriptor for this process
KResourceLimit* GetResourceLimit() const; KResourceLimit* GetResourceLimit() const;
@ -485,6 +489,9 @@ private:
/// Address indicating the location of the process' dedicated TLS region. /// Address indicating the location of the process' dedicated TLS region.
KProcessAddress m_plr_address = 0; KProcessAddress m_plr_address = 0;
/// Address indicating the location of the process's entry point.
KProcessAddress m_code_address = 0;
/// Random values for svcGetInfo RandomEntropy /// Random values for svcGetInfo RandomEntropy
std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{}; std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{};

View File

@ -4,6 +4,7 @@
#include <utility> #include <utility>
#include "common/assert.h" #include "common/assert.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h" #include "common/fs/path_util.h"
#include "common/settings.h" #include "common/settings.h"
#include "core/core.h" #include "core/core.h"
@ -154,10 +155,18 @@ Result VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
std::string src_path(Common::FS::SanitizePath(src_path_)); std::string src_path(Common::FS::SanitizePath(src_path_));
std::string dest_path(Common::FS::SanitizePath(dest_path_)); std::string dest_path(Common::FS::SanitizePath(dest_path_));
auto src = backing->GetFileRelative(src_path); auto src = backing->GetFileRelative(src_path);
auto dst = backing->GetFileRelative(dest_path);
if (Common::FS::GetParentPath(src_path) == Common::FS::GetParentPath(dest_path)) { if (Common::FS::GetParentPath(src_path) == Common::FS::GetParentPath(dest_path)) {
// Use more-optimized vfs implementation rename. // Use more-optimized vfs implementation rename.
if (src == nullptr) if (src == nullptr) {
return FileSys::ERROR_PATH_NOT_FOUND; return FileSys::ERROR_PATH_NOT_FOUND;
}
if (dst && Common::FS::Exists(dst->GetFullPath())) {
LOG_ERROR(Service_FS, "File at new_path={} already exists", dst->GetFullPath());
return FileSys::ERROR_PATH_ALREADY_EXISTS;
}
if (!src->Rename(Common::FS::GetFilename(dest_path))) { if (!src->Rename(Common::FS::GetFilename(dest_path))) {
// TODO(DarkLordZach): Find a better error code for this // TODO(DarkLordZach): Find a better error code for this
return ResultUnknown; return ResultUnknown;

View File

@ -204,9 +204,11 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) {
if (!mapping->fixed) { if (!mapping->fixed) {
auto& allocator{mapping->big_page ? *vm.big_page_allocator : *vm.small_page_allocator}; auto& allocator{mapping->big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
u32 page_size_bits{mapping->big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS}; u32 page_size_bits{mapping->big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
u32 page_size{mapping->big_page ? vm.big_page_size : VM::YUZU_PAGESIZE};
u64 aligned_size{Common::AlignUp(mapping->size, page_size)};
allocator.Free(static_cast<u32>(mapping->offset >> page_size_bits), allocator.Free(static_cast<u32>(mapping->offset >> page_size_bits),
static_cast<u32>(mapping->size >> page_size_bits)); static_cast<u32>(aligned_size >> page_size_bits));
} }
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state

View File

@ -79,8 +79,8 @@ protected:
using HandlerFnP = void (Self::*)(HLERequestContext&); using HandlerFnP = void (Self::*)(HLERequestContext&);
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
[[nodiscard]] std::scoped_lock<std::mutex> LockService() { [[nodiscard]] virtual std::unique_lock<std::mutex> LockService() {
return std::scoped_lock{lock_service}; return std::unique_lock{lock_service};
} }
/// System context that the service operates under. /// System context that the service operates under.

View File

@ -1029,6 +1029,11 @@ BSD::~BSD() {
} }
} }
std::unique_lock<std::mutex> BSD::LockService() {
// Do not lock socket IClient instances.
return {};
}
BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} { BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {

View File

@ -186,6 +186,9 @@ private:
// Callback identifier for the OnProxyPacketReceived event. // Callback identifier for the OnProxyPacketReceived event.
Network::RoomMember::CallbackHandle<Network::ProxyPacket> proxy_packet_received; Network::RoomMember::CallbackHandle<Network::ProxyPacket> proxy_packet_received;
protected:
virtual std::unique_lock<std::mutex> LockService() override;
}; };
class BSDCFG final : public ServiceFramework<BSDCFG> { class BSDCFG final : public ServiceFramework<BSDCFG> {

View File

@ -139,7 +139,6 @@ private:
bool do_not_close_socket = false; bool do_not_close_socket = false;
bool get_server_cert_chain = false; bool get_server_cert_chain = false;
std::shared_ptr<Network::SocketBase> socket; std::shared_ptr<Network::SocketBase> socket;
bool did_set_host_name = false;
bool did_handshake = false; bool did_handshake = false;
Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) { Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) {
@ -174,11 +173,7 @@ private:
Result SetHostNameImpl(const std::string& hostname) { Result SetHostNameImpl(const std::string& hostname) {
LOG_DEBUG(Service_SSL, "called. hostname={}", hostname); LOG_DEBUG(Service_SSL, "called. hostname={}", hostname);
ASSERT(!did_handshake); ASSERT(!did_handshake);
Result res = backend->SetHostName(hostname); return backend->SetHostName(hostname);
if (res == ResultSuccess) {
did_set_host_name = true;
}
return res;
} }
Result SetVerifyOptionImpl(u32 option) { Result SetVerifyOptionImpl(u32 option) {
@ -208,9 +203,6 @@ private:
Result DoHandshakeImpl() { Result DoHandshakeImpl() {
ASSERT_OR_EXECUTE(!did_handshake && socket, { return ResultNoSocket; }); ASSERT_OR_EXECUTE(!did_handshake && socket, { return ResultNoSocket; });
ASSERT_OR_EXECUTE_MSG(
did_set_host_name, { return ResultInternalError; },
"Expected SetHostName before DoHandshake");
Result res = backend->DoHandshake(); Result res = backend->DoHandshake();
did_handshake = res.IsSuccess(); did_handshake = res.IsSuccess();
return res; return res;

View File

@ -167,9 +167,8 @@ public:
} }
~SSLConnectionBackendOpenSSL() { ~SSLConnectionBackendOpenSSL() {
// these are null-tolerant: // this is null-tolerant:
SSL_free(ssl); SSL_free(ssl);
BIO_free(bio);
} }
static void KeyLogCallback(const SSL* ssl, const char* line) { static void KeyLogCallback(const SSL* ssl, const char* line) {

View File

@ -32,7 +32,7 @@ static void OneTimeInit() {
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
schannel_cred.dwFlags = schannel_cred.dwFlags =
SCH_USE_STRONG_CRYPTO | // don't allow insecure protocols SCH_USE_STRONG_CRYPTO | // don't allow insecure protocols
SCH_CRED_AUTO_CRED_VALIDATION | // validate certs SCH_CRED_NO_SERVERNAME_CHECK | // don't validate server names
SCH_CRED_NO_DEFAULT_CREDS; // don't automatically present a client certificate SCH_CRED_NO_DEFAULT_CREDS; // don't automatically present a client certificate
// ^ I'm assuming that nobody would want to connect Yuzu to a // ^ I'm assuming that nobody would want to connect Yuzu to a
// service that requires some OS-provided corporate client // service that requires some OS-provided corporate client
@ -227,10 +227,9 @@ public:
ciphertext_read_buf.size()); ciphertext_read_buf.size());
} }
const SECURITY_STATUS ret = char* hostname_ptr = hostname ? const_cast<char*>(hostname->c_str()) : nullptr;
InitializeSecurityContextA(&cred_handle, initial_call_done ? &ctxt : nullptr, const SECURITY_STATUS ret = InitializeSecurityContextA(
// Caller ensured we have set a hostname: &cred_handle, initial_call_done ? &ctxt : nullptr, hostname_ptr, req,
const_cast<char*>(hostname.value().c_str()), req,
0, // Reserved1 0, // Reserved1
0, // TargetDataRep not used with Schannel 0, // TargetDataRep not used with Schannel
initial_call_done ? &input_desc : nullptr, initial_call_done ? &input_desc : nullptr,

View File

@ -153,7 +153,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
// Load NSO modules // Load NSO modules
modules.clear(); modules.clear();
const VAddr base_address{GetInteger(process.GetPageTable().GetCodeRegionStart())}; const VAddr base_address{GetInteger(process.GetEntryPoint())};
VAddr next_load_addr{base_address}; VAddr next_load_addr{base_address};
const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
system.GetContentProvider()}; system.GetContentProvider()};

View File

@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
} }
codeset.memory = std::move(program_image); codeset.memory = std::move(program_image);
const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); const VAddr base_address = GetInteger(process.GetEntryPoint());
process.LoadModule(std::move(codeset), base_address); process.LoadModule(std::move(codeset), base_address);
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address);

View File

@ -203,7 +203,7 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector<u8>& data)
// Load codeset for current process // Load codeset for current process
codeset.memory = std::move(program_image); codeset.memory = std::move(program_image);
process.LoadModule(std::move(codeset), process.GetPageTable().GetCodeRegionStart()); process.LoadModule(std::move(codeset), process.GetEntryPoint());
return true; return true;
} }

View File

@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
modules.clear(); modules.clear();
// Load module // Load module
const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); const VAddr base_address = GetInteger(process.GetEntryPoint());
if (!LoadModule(process, system, *file, base_address, true, true)) { if (!LoadModule(process, system, *file, base_address, true, true)) {
return {ResultStatus::ErrorLoadingNSO, {}}; return {ResultStatus::ErrorLoadingNSO, {}};
} }

View File

@ -117,8 +117,8 @@ json GetProcessorStateDataAuto(Core::System& system) {
arm.SaveContext(context); arm.SaveContext(context);
return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32", return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32",
GetInteger(process->GetPageTable().GetCodeRegionStart()), GetInteger(process->GetEntryPoint()), context.sp, context.pc,
context.sp, context.pc, context.pstate, context.cpu_registers); context.pstate, context.cpu_registers);
} }
json GetBacktraceData(Core::System& system) { json GetBacktraceData(Core::System& system) {

View File

@ -235,6 +235,7 @@ QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& gi
slider->setValue(std::stoi(setting.ToString())); slider->setValue(std::stoi(setting.ToString()));
slider->setInvertedAppearance(reversed); slider->setInvertedAppearance(reversed);
slider->setInvertedControls(reversed);
serializer = [this]() { return std::to_string(slider->value()); }; serializer = [this]() { return std::to_string(slider->value()); };
restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); }; restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); };

View File

@ -191,8 +191,9 @@ QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager,
} }
QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::string& name, QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::string& name,
const std::vector<u8>& icon, Loader::AppLoader& loader, const std::size_t size, const std::vector<u8>& icon,
u64 program_id, const CompatibilityList& compatibility_list, Loader::AppLoader& loader, u64 program_id,
const CompatibilityList& compatibility_list,
const FileSys::PatchManager& patch) { const FileSys::PatchManager& patch) {
const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
@ -210,7 +211,7 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri
file_type_string, program_id), file_type_string, program_id),
new GameListItemCompat(compatibility), new GameListItemCompat(compatibility),
new GameListItem(file_type_string), new GameListItem(file_type_string),
new GameListItemSize(Common::FS::GetSize(path)), new GameListItemSize(size),
}; };
const auto patch_versions = GetGameListCachedObject( const auto patch_versions = GetGameListCachedObject(
@ -278,8 +279,8 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
GetMetadataFromControlNCA(patch, *control, icon, name); GetMetadataFromControlNCA(patch, *control, icon, name);
} }
emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id, emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, file->GetSize(), icon, *loader,
compatibility_list, patch), program_id, compatibility_list, patch),
parent_dir); parent_dir);
} }
} }
@ -354,8 +355,9 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
const FileSys::PatchManager patch{id, system.GetFileSystemController(), const FileSys::PatchManager patch{id, system.GetFileSystemController(),
system.GetContentProvider()}; system.GetContentProvider()};
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, id, emit EntryReady(MakeGameListEntry(physical_name, name,
compatibility_list, patch), Common::FS::GetSize(physical_name), icon,
*loader, id, compatibility_list, patch),
parent_dir); parent_dir);
} }
} else { } else {
@ -368,8 +370,9 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
const FileSys::PatchManager patch{program_id, system.GetFileSystemController(), const FileSys::PatchManager patch{program_id, system.GetFileSystemController(),
system.GetContentProvider()}; system.GetContentProvider()};
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, emit EntryReady(
program_id, compatibility_list, patch), MakeGameListEntry(physical_name, name, Common::FS::GetSize(physical_name),
icon, *loader, program_id, compatibility_list, patch),
parent_dir); parent_dir);
} }
} }

View File

@ -1811,6 +1811,43 @@ bool GMainWindow::SelectAndSetCurrentUser(
return true; return true;
} }
void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
// Ensure all NCAs are registered before launching the game
const auto file = vfs->OpenFile(filepath, FileSys::Mode::Read);
if (!file) {
return;
}
auto loader = Loader::GetLoader(*system, file);
if (!loader) {
return;
}
const auto file_type = loader->GetFileType();
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
return;
}
u64 program_id = 0;
const auto res2 = loader->ReadProgramId(program_id);
if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
provider->AddEntry(FileSys::TitleType::Application,
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()), program_id,
file);
} else if (res2 == Loader::ResultStatus::Success &&
(file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
const auto nsp = file_type == Loader::FileType::NSP
? std::make_shared<FileSys::NSP>(file)
: FileSys::XCI{file}.GetSecurePartitionNSP();
for (const auto& title : nsp->GetNCAs()) {
for (const auto& entry : title.second) {
provider->AddEntry(entry.first.first, entry.first.second, title.first,
entry.second->GetBaseFile());
}
}
}
}
void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
StartGameType type) { StartGameType type) {
LOG_INFO(Frontend, "yuzu starting..."); LOG_INFO(Frontend, "yuzu starting...");
@ -1825,6 +1862,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
last_filename_booted = filename; last_filename_booted = filename;
ConfigureFilesystemProvider(filename.toStdString());
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index); const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index);

View File

@ -399,6 +399,7 @@ private:
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
bool CheckDarkMode(); bool CheckDarkMode();
bool CheckSystemArchiveDecryption(); bool CheckSystemArchiveDecryption();
void ConfigureFilesystemProvider(const std::string& filepath);
QString GetTasStateDescription() const; QString GetTasStateDescription() const;
bool CreateShortcut(const std::string& shortcut_path, const std::string& title, bool CreateShortcut(const std::string& shortcut_path, const std::string& title,