summaryrefslogtreecommitdiff
path: root/src/core/hle/service/bcat
diff options
context:
space:
mode:
authorGravatar Morph2021-05-25 19:32:56 -0400
committerGravatar GitHub2021-05-25 19:32:56 -0400
commit065867e2c24e9856c360fc2d6b9a86c92aedc43e (patch)
tree7964e85ef4f01a3c2b8f44e850f37b384405b930 /src/core/hle/service/bcat
parentMerge pull request #6349 from german77/suppress_config_warning (diff)
downloadyuzu-065867e2c24e9856c360fc2d6b9a86c92aedc43e.tar.gz
yuzu-065867e2c24e9856c360fc2d6b9a86c92aedc43e.tar.xz
yuzu-065867e2c24e9856c360fc2d6b9a86c92aedc43e.zip
common: fs: Rework the Common Filesystem interface to make use of std::filesystem (#6270)
* common: fs: fs_types: Create filesystem types Contains various filesystem types used by the Common::FS library * common: fs: fs_util: Add std::string to std::u8string conversion utility * common: fs: path_util: Add utlity functions for paths Contains various utility functions for getting or manipulating filesystem paths used by the Common::FS library * common: fs: file: Rewrite the IOFile implementation * common: fs: Reimplement Common::FS library using std::filesystem * common: fs: fs_paths: Add fs_paths to replace common_paths * common: fs: path_util: Add the rest of the path functions * common: Remove the previous Common::FS implementation * general: Remove unused fs includes * string_util: Remove unused function and include * nvidia_flags: Migrate to the new Common::FS library * settings: Migrate to the new Common::FS library * logging: backend: Migrate to the new Common::FS library * core: Migrate to the new Common::FS library * perf_stats: Migrate to the new Common::FS library * reporter: Migrate to the new Common::FS library * telemetry_session: Migrate to the new Common::FS library * key_manager: Migrate to the new Common::FS library * bis_factory: Migrate to the new Common::FS library * registered_cache: Migrate to the new Common::FS library * xts_archive: Migrate to the new Common::FS library * service: acc: Migrate to the new Common::FS library * applets/profile: Migrate to the new Common::FS library * applets/web: Migrate to the new Common::FS library * service: filesystem: Migrate to the new Common::FS library * loader: Migrate to the new Common::FS library * gl_shader_disk_cache: Migrate to the new Common::FS library * nsight_aftermath_tracker: Migrate to the new Common::FS library * vulkan_library: Migrate to the new Common::FS library * configure_debug: Migrate to the new Common::FS library * game_list_worker: Migrate to the new Common::FS library * config: Migrate to the new Common::FS library * configure_filesystem: Migrate to the new Common::FS library * configure_per_game_addons: Migrate to the new Common::FS library * configure_profile_manager: Migrate to the new Common::FS library * configure_ui: Migrate to the new Common::FS library * input_profiles: Migrate to the new Common::FS library * yuzu_cmd: config: Migrate to the new Common::FS library * yuzu_cmd: Migrate to the new Common::FS library * vfs_real: Migrate to the new Common::FS library * vfs: Migrate to the new Common::FS library * vfs_libzip: Migrate to the new Common::FS library * service: bcat: Migrate to the new Common::FS library * yuzu: main: Migrate to the new Common::FS library * vfs_real: Delete the contents of an existing file in CreateFile Current usages of CreateFile expect to delete the contents of an existing file, retain this behavior for now. * input_profiles: Don't iterate the input profile dir if it does not exist Silences an error produced in the log if the directory does not exist. * game_list_worker: Skip parsing file if the returned VfsFile is nullptr Prevents crashes in GetLoader when the virtual file is nullptr * common: fs: Validate paths for path length * service: filesystem: Open the mod load directory as read only
Diffstat (limited to 'src/core/hle/service/bcat')
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.cpp68
1 files changed, 42 insertions, 26 deletions
diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp
index d6d2f52e5..3cc397604 100644
--- a/src/core/hle/service/bcat/backend/boxcat.cpp
+++ b/src/core/hle/service/bcat/backend/boxcat.cpp
@@ -15,6 +15,9 @@
15#pragma GCC diagnostic pop 15#pragma GCC diagnostic pop
16#endif 16#endif
17 17
18#include "common/fs/file.h"
19#include "common/fs/fs.h"
20#include "common/fs/path_util.h"
18#include "common/hex_util.h" 21#include "common/hex_util.h"
19#include "common/logging/backend.h" 22#include "common/logging/backend.h"
20#include "common/logging/log.h" 23#include "common/logging/log.h"
@@ -96,14 +99,14 @@ constexpr u32 PORT = 443;
96constexpr u32 TIMEOUT_SECONDS = 30; 99constexpr u32 TIMEOUT_SECONDS = 30;
97[[maybe_unused]] constexpr u64 VFS_COPY_BLOCK_SIZE = 1ULL << 24; // 4MB 100[[maybe_unused]] constexpr u64 VFS_COPY_BLOCK_SIZE = 1ULL << 24; // 4MB
98 101
99std::string GetBINFilePath(u64 title_id) { 102std::filesystem::path GetBINFilePath(u64 title_id) {
100 return fmt::format("{}bcat/{:016X}/launchparam.bin", 103 return Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "bcat" /
101 Common::FS::GetUserPath(Common::FS::UserPath::CacheDir), title_id); 104 fmt::format("{:016X}/launchparam.bin", title_id);
102} 105}
103 106
104std::string GetZIPFilePath(u64 title_id) { 107std::filesystem::path GetZIPFilePath(u64 title_id) {
105 return fmt::format("{}bcat/{:016X}/data.zip", 108 return Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "bcat" /
106 Common::FS::GetUserPath(Common::FS::UserPath::CacheDir), title_id); 109 fmt::format("{:016X}/data.zip", title_id);
107} 110}
108 111
109// If the error is something the user should know about (build ID mismatch, bad client version), 112// If the error is something the user should know about (build ID mismatch, bad client version),
@@ -187,7 +190,7 @@ bool VfsRawCopyDProgress(FileSys::VirtualDir src, FileSys::VirtualDir dest,
187 190
188class Boxcat::Client { 191class Boxcat::Client {
189public: 192public:
190 Client(std::string path_, u64 title_id_, u64 build_id_) 193 Client(std::filesystem::path path_, u64 title_id_, u64 build_id_)
191 : path(std::move(path_)), title_id(title_id_), build_id(build_id_) {} 194 : path(std::move(path_)), title_id(title_id_), build_id(build_id_) {}
192 195
193 DownloadResult DownloadDataZip() { 196 DownloadResult DownloadDataZip() {
@@ -217,10 +220,11 @@ private:
217 }; 220 };
218 221
219 if (Common::FS::Exists(path)) { 222 if (Common::FS::Exists(path)) {
220 Common::FS::IOFile file{path, "rb"}; 223 Common::FS::IOFile file{path, Common::FS::FileAccessMode::Read,
224 Common::FS::FileType::BinaryFile};
221 if (file.IsOpen()) { 225 if (file.IsOpen()) {
222 std::vector<u8> bytes(file.GetSize()); 226 std::vector<u8> bytes(file.GetSize());
223 file.ReadBytes(bytes.data(), bytes.size()); 227 void(file.Read(bytes));
224 const auto digest = DigestFile(bytes); 228 const auto digest = DigestFile(bytes);
225 headers.insert({std::string("If-None-Match"), Common::HexToString(digest, false)}); 229 headers.insert({std::string("If-None-Match"), Common::HexToString(digest, false)});
226 } 230 }
@@ -247,14 +251,23 @@ private:
247 return DownloadResult::InvalidContentType; 251 return DownloadResult::InvalidContentType;
248 } 252 }
249 253
250 Common::FS::CreateFullPath(path); 254 if (!Common::FS::CreateDirs(path)) {
251 Common::FS::IOFile file{path, "wb"};
252 if (!file.IsOpen())
253 return DownloadResult::GeneralFSError; 255 return DownloadResult::GeneralFSError;
254 if (!file.Resize(response->body.size())) 256 }
257
258 Common::FS::IOFile file{path, Common::FS::FileAccessMode::Append,
259 Common::FS::FileType::BinaryFile};
260 if (!file.IsOpen()) {
261 return DownloadResult::GeneralFSError;
262 }
263
264 if (!file.SetSize(response->body.size())) {
255 return DownloadResult::GeneralFSError; 265 return DownloadResult::GeneralFSError;
256 if (file.WriteBytes(response->body.data(), response->body.size()) != response->body.size()) 266 }
267
268 if (file.Write(response->body) != response->body.size()) {
257 return DownloadResult::GeneralFSError; 269 return DownloadResult::GeneralFSError;
270 }
258 271
259 return DownloadResult::Success; 272 return DownloadResult::Success;
260 } 273 }
@@ -267,7 +280,7 @@ private:
267 } 280 }
268 281
269 std::unique_ptr<httplib::SSLClient> client; 282 std::unique_ptr<httplib::SSLClient> client;
270 std::string path; 283 std::filesystem::path path;
271 u64 title_id; 284 u64 title_id;
272 u64 build_id; 285 u64 build_id;
273}; 286};
@@ -291,7 +304,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe
291 return; 304 return;
292 } 305 }
293 306
294 const auto zip_path{GetZIPFilePath(title.title_id)}; 307 const auto zip_path = GetZIPFilePath(title.title_id);
295 Boxcat::Client client{zip_path, title.title_id, title.build_id}; 308 Boxcat::Client client{zip_path, title.title_id, title.build_id};
296 309
297 progress.StartConnecting(); 310 progress.StartConnecting();
@@ -301,7 +314,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe
301 LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res); 314 LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
302 315
303 if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) { 316 if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
304 Common::FS::Delete(zip_path); 317 void(Common::FS::RemoveFile(zip_path));
305 } 318 }
306 319
307 HandleDownloadDisplayResult(applet_manager, res); 320 HandleDownloadDisplayResult(applet_manager, res);
@@ -311,11 +324,13 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe
311 324
312 progress.StartProcessingDataList(); 325 progress.StartProcessingDataList();
313 326
314 Common::FS::IOFile zip{zip_path, "rb"}; 327 Common::FS::IOFile zip{zip_path, Common::FS::FileAccessMode::Read,
328 Common::FS::FileType::BinaryFile};
315 const auto size = zip.GetSize(); 329 const auto size = zip.GetSize();
316 std::vector<u8> bytes(size); 330 std::vector<u8> bytes(size);
317 if (!zip.IsOpen() || size == 0 || zip.ReadBytes(bytes.data(), bytes.size()) != bytes.size()) { 331 if (!zip.IsOpen() || size == 0 || zip.Read(bytes) != bytes.size()) {
318 LOG_ERROR(Service_BCAT, "Boxcat failed to read ZIP file at path '{}'!", zip_path); 332 LOG_ERROR(Service_BCAT, "Boxcat failed to read ZIP file at path '{}'!",
333 Common::FS::PathToUTF8String(zip_path));
319 progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE); 334 progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
320 return; 335 return;
321 } 336 }
@@ -419,19 +434,19 @@ void Boxcat::SetPassphrase(u64 title_id, const Passphrase& passphrase) {
419} 434}
420 435
421std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title) { 436std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title) {
422 const auto path{GetBINFilePath(title.title_id)}; 437 const auto bin_file_path = GetBINFilePath(title.title_id);
423 438
424 if (Settings::values.bcat_boxcat_local) { 439 if (Settings::values.bcat_boxcat_local) {
425 LOG_INFO(Service_BCAT, "Boxcat using local data by override, skipping download."); 440 LOG_INFO(Service_BCAT, "Boxcat using local data by override, skipping download.");
426 } else { 441 } else {
427 Client launch_client{path, title.title_id, title.build_id}; 442 Client launch_client{bin_file_path, title.title_id, title.build_id};
428 443
429 const auto res = launch_client.DownloadLaunchParam(); 444 const auto res = launch_client.DownloadLaunchParam();
430 if (res != DownloadResult::Success) { 445 if (res != DownloadResult::Success) {
431 LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res); 446 LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
432 447
433 if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) { 448 if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
434 Common::FS::Delete(path); 449 void(Common::FS::RemoveFile(bin_file_path));
435 } 450 }
436 451
437 HandleDownloadDisplayResult(applet_manager, res); 452 HandleDownloadDisplayResult(applet_manager, res);
@@ -439,12 +454,13 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title)
439 } 454 }
440 } 455 }
441 456
442 Common::FS::IOFile bin{path, "rb"}; 457 Common::FS::IOFile bin{bin_file_path, Common::FS::FileAccessMode::Read,
458 Common::FS::FileType::BinaryFile};
443 const auto size = bin.GetSize(); 459 const auto size = bin.GetSize();
444 std::vector<u8> bytes(size); 460 std::vector<u8> bytes(size);
445 if (!bin.IsOpen() || size == 0 || bin.ReadBytes(bytes.data(), bytes.size()) != bytes.size()) { 461 if (!bin.IsOpen() || size == 0 || bin.Read(bytes) != bytes.size()) {
446 LOG_ERROR(Service_BCAT, "Boxcat failed to read launch parameter binary at path '{}'!", 462 LOG_ERROR(Service_BCAT, "Boxcat failed to read launch parameter binary at path '{}'!",
447 path); 463 Common::FS::PathToUTF8String(bin_file_path));
448 return std::nullopt; 464 return std::nullopt;
449 } 465 }
450 466