From 9a5bdc9b4f0fce30036391b780db9f878290cacd Mon Sep 17 00:00:00 2001 From: brian218 Date: Wed, 26 Jul 2023 17:36:57 +0800 Subject: [PATCH] sys_fs: Updated sys_fs_fcntl(0xc0000015&0xc000001c)'s error handling according to real hardware testing --- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 48 +++++++++++++++++------------------ rpcs3/Emu/Cell/lv2/sys_fs.h | 8 +++--- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 575000565f..bfcf0c09ec 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -2181,39 +2181,37 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 break; } - std::string_view vpath{arg->name.get_ptr(), arg->name_size}; + std::string_view vpath{arg->path.get_ptr(), arg->path_size}; + + if (vpath.size() == 0) + return CELL_ENOMEM; // Trim trailing '\0' if (const auto trim_pos = vpath.find('\0'); trim_pos != umax) vpath.remove_suffix(vpath.size() - trim_pos); - if (vfs::get(vpath).empty()) + arg->out_code = CELL_ENOTMOUNTED; // arg->out_code is set to CELL_ENOTMOUNTED on real hardware when the device doesn't exist or when the device isn't USB + + if (!vfs::get(vpath).empty()) { - arg->out_code = CELL_ENOTMOUNTED; - return {CELL_ENOTMOUNTED, vpath}; + if (const auto& mp = g_fxo->get().lookup(vpath, true); mp == &g_mp_sys_dev_usb) + { + const cfg::device_info device = g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, fmt::format("%s%s", mp->root, mp.device.substr(mp->device.size()))); + const auto usb_ids = device.get_usb_ids(); + std::tie(arg->vendorID, arg->productID) = usb_ids; + + if (with_serial) + { + const auto arg_c000001c = vm::static_ptr_cast(_arg); + const std::u16string serial = utf8_to_utf16(device.serial); // Serial needs to be encoded to utf-16 BE + std::copy_n(serial.begin(), std::min(serial.size(), sizeof(arg_c000001c->serial) / sizeof(u16)), arg_c000001c->serial); + } + + arg->out_code = CELL_OK; + sys_fs.trace("sys_fs_fcntl(0x%08x): found device \"%s\" (vid=0x%04x, pid=0x%04x, serial=\"%s\")", op, mp.device, usb_ids.first, usb_ids.second, device.serial); + } } - const auto& mp = g_fxo->get().lookup(vpath, true); - - if (mp != &g_mp_sys_dev_usb) - { - arg->out_code = CELL_ENOTSUP; - return {CELL_ENOTSUP, vpath}; - } - - const cfg::device_info device = g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, fmt::format("%s%s", mp->root, mp.device.substr(mp->device.size()))); - std::tie(arg->vendorID, arg->productID) = device.get_usb_ids(); - - if (with_serial) - { - const auto arg_c000001c = vm::static_ptr_cast(_arg); - const std::u16string serial = utf8_to_utf16(device.serial); // Serial needs to be encoded to utf-16 BE - std::copy_n(serial.begin(), std::min(serial.size(), sizeof(arg_c000001c->serial) / sizeof(u16)), arg_c000001c->serial); - } - - arg->out_code = CELL_OK; - - sys_fs.trace("sys_fs_fcntl(0x%08x): found device \"%s\" (vid=0x%04x, pid=0x%04x, serial=\"%s\")", op, mp.device, arg->vendorID, arg->productID, device.serial); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index 1f1e2c2ec1..79ee4636bd 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -562,8 +562,8 @@ struct lv2_file_c0000015 : lv2_file_op be_t size; // 0x20 be_t _x4; // 0x10 be_t _x8; // 0x18 - offset of out_code - be_t name_size; - vm::bcptr name; + be_t path_size; + vm::bcptr path; be_t _x14; // be_t vendorID; be_t productID; @@ -590,8 +590,8 @@ struct lv2_file_c000001c : lv2_file_op be_t size; // 0x60 be_t _x4; // 0x10 be_t _x8; // 0x18 - offset of out_code - be_t name_size; - vm::bcptr name; + be_t path_size; + vm::bcptr path; be_t unk1; be_t vendorID; be_t productID;