mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-21 18:22:33 +01:00
sys_fs: Improved sys_fs_fcntl(0xc0000015&0xc000001c)
This commit is contained in:
parent
e0fe7989e9
commit
d2dc57585c
@ -559,6 +559,18 @@ void cfg::log_entry::from_default()
|
||||
set_map({});
|
||||
}
|
||||
|
||||
std::pair<u16, u16> cfg::device_info::get_usb_ids() const
|
||||
{
|
||||
auto string_to_hex = [](const std::string& str) -> u16
|
||||
{
|
||||
u16 value = 0x0000;
|
||||
if (!str.empty() && std::from_chars(str.data(), str.data() + str.size(), value, 16).ec != std::errc{})
|
||||
cfg_log.error("Failed to parse hex from string \"%s\"", str);
|
||||
return value;
|
||||
};
|
||||
return {string_to_hex(vid), string_to_hex(pid)};
|
||||
}
|
||||
|
||||
void cfg::device_entry::set_map(map_of_type<device_info>&& map)
|
||||
{
|
||||
m_map = std::move(map);
|
||||
|
@ -644,6 +644,7 @@ namespace cfg
|
||||
std::string serial;
|
||||
std::string vid;
|
||||
std::string pid;
|
||||
std::pair<u16, u16> get_usb_ids() const;
|
||||
};
|
||||
|
||||
class device_entry final : public _base
|
||||
|
@ -37,6 +37,12 @@ std::string utf16_to_utf8(std::u16string_view src)
|
||||
return converter.to_bytes(src.data());
|
||||
}
|
||||
|
||||
std::u16string utf8_to_utf16(std::string_view src)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter{};
|
||||
return converter.from_bytes(src.data());
|
||||
}
|
||||
|
||||
std::wstring utf8_to_wchar(std::string_view src)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -11,6 +11,7 @@
|
||||
std::wstring utf8_to_wchar(std::string_view src);
|
||||
std::string wchar_to_utf8(std::wstring_view src);
|
||||
std::string utf16_to_utf8(std::u16string_view src);
|
||||
std::u16string utf8_to_utf16(std::string_view src);
|
||||
|
||||
// Copy null-terminated string from a std::string or a char array to a char array with truncation
|
||||
template <typename D, typename T>
|
||||
|
@ -12,10 +12,8 @@
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/system_utils.hpp"
|
||||
#include "Emu/Cell/lv2/sys_process.h"
|
||||
#include "Emu/RSX/Overlays/overlay_utils.h" // for ascii8_to_utf16
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
#include <charconv>
|
||||
#include <span>
|
||||
|
||||
LOG_CHANNEL(sys_fs);
|
||||
@ -2117,33 +2115,8 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
|
||||
}
|
||||
|
||||
const cfg::device_info device = g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, vpath);
|
||||
std::tie(arg->vendorID, arg->productID) = device.get_usb_ids();
|
||||
|
||||
if (device.path.empty() || device.vid.empty() || device.pid.empty())
|
||||
{
|
||||
arg->out_code = CELL_ENOTSUP;
|
||||
break;
|
||||
}
|
||||
|
||||
u16 vid{};
|
||||
{
|
||||
auto [ptr, err] = std::from_chars(device.vid.data(), device.vid.data() + device.vid.size(), vid, 16);
|
||||
if (err != std::errc())
|
||||
{
|
||||
fmt::throw_exception("Failed to read hex string: %s", std::make_error_code(err).message());
|
||||
}
|
||||
}
|
||||
|
||||
u16 pid{};
|
||||
{
|
||||
auto [ptr, err] = std::from_chars(device.pid.data(), device.pid.data() + device.pid.size(), pid, 16);
|
||||
if (err != std::errc())
|
||||
{
|
||||
fmt::throw_exception("Failed to read hex string: %s", std::make_error_code(err).message());
|
||||
}
|
||||
}
|
||||
|
||||
arg->vendorID = vid;
|
||||
arg->productID = pid;
|
||||
arg->out_code = CELL_OK;
|
||||
|
||||
sys_fs.trace("sys_fs_fcntl(0xc0000015): found device '%s' (vid=0x%x, pid=0x%x)", vpath, arg->vendorID, arg->productID);
|
||||
@ -2192,49 +2165,11 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
|
||||
}
|
||||
|
||||
const cfg::device_info device = g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, vpath);
|
||||
|
||||
if (device.path.empty() || device.vid.empty() || device.pid.empty())
|
||||
{
|
||||
arg->out_code = CELL_ENOTSUP;
|
||||
break;
|
||||
}
|
||||
|
||||
u16 vid{};
|
||||
{
|
||||
auto [ptr, err] = std::from_chars(device.vid.data(), device.vid.data() + device.vid.size(), vid, 16);
|
||||
if (err != std::errc())
|
||||
{
|
||||
fmt::throw_exception("Failed to read hex string: %s", std::make_error_code(err).message());
|
||||
}
|
||||
}
|
||||
|
||||
u16 pid{};
|
||||
{
|
||||
auto [ptr, err] = std::from_chars(device.pid.data(), device.pid.data() + device.pid.size(), pid, 16);
|
||||
if (err != std::errc())
|
||||
{
|
||||
fmt::throw_exception("Failed to read hex string: %s", std::make_error_code(err).message());
|
||||
}
|
||||
}
|
||||
|
||||
arg->vendorID = vid;
|
||||
arg->productID = pid;
|
||||
std::tie(arg->vendorID, arg->productID) = device.get_usb_ids();
|
||||
|
||||
// Serial needs to be encoded to utf-16 BE
|
||||
const std::u16string serial = ascii8_to_utf16(device.serial);
|
||||
ensure((serial.size() * sizeof(u16)) <= sizeof(arg->serial));
|
||||
|
||||
std::memset(arg->serial, 0, sizeof(arg->serial));
|
||||
|
||||
const auto write_byteswapped = [](const void* src, void* dst) -> void
|
||||
{
|
||||
*static_cast<u16*>(dst) = *static_cast<const be_t<u16>*>(src);
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < serial.size(); i++)
|
||||
{
|
||||
write_byteswapped(&serial[i], &arg->serial[i * 2]);
|
||||
}
|
||||
const std::u16string serial = utf8_to_utf16(device.serial);
|
||||
std::copy_n(serial.begin(), std::min(serial.size(), sizeof(arg->serial) / sizeof(u16)), arg->serial);
|
||||
|
||||
arg->out_code = CELL_OK;
|
||||
|
||||
|
@ -533,7 +533,7 @@ struct lv2_file_c000001c : lv2_file_op
|
||||
be_t<u16> vendorID;
|
||||
be_t<u16> productID;
|
||||
be_t<u32> out_code; // set to 0
|
||||
u8 serial[64];
|
||||
be_t<u16> serial[32];
|
||||
};
|
||||
|
||||
CHECK_SIZE(lv2_file_c000001c, 0x60);
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "sys_ppu_thread.h"
|
||||
#include "sys_sync.h"
|
||||
|
||||
#include <charconv>
|
||||
#include <queue>
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
@ -295,30 +294,7 @@ usb_handler_thread::usb_handler_thread()
|
||||
|
||||
for (int i = 0; i < 8; i++) // Add VFS USB mass storage devices (/dev_usbXXX) to the USB device list
|
||||
{
|
||||
const cfg::device_info device = g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, fmt::format("/dev_usb%03d", i));
|
||||
|
||||
if (device.path.empty() || device.vid.empty() || device.pid.empty())
|
||||
continue;
|
||||
|
||||
u16 vid{};
|
||||
{
|
||||
auto [ptr, err] = std::from_chars(device.vid.data(), device.vid.data() + device.vid.size(), vid, 16);
|
||||
if (err != std::errc())
|
||||
{
|
||||
fmt::throw_exception("Failed to read hex string: %s", std::make_error_code(err).message());
|
||||
}
|
||||
}
|
||||
|
||||
u16 pid{};
|
||||
{
|
||||
auto [ptr, err] = std::from_chars(device.pid.data(), device.pid.data() + device.pid.size(), pid, 16);
|
||||
if (err != std::errc())
|
||||
{
|
||||
fmt::throw_exception("Failed to read hex string: %s", std::make_error_code(err).message());
|
||||
}
|
||||
}
|
||||
|
||||
usb_devices.push_back(std::make_shared<usb_device_vfs>(get_new_location(), vid, pid, device.serial));
|
||||
usb_devices.push_back(std::make_shared<usb_device_vfs>(g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, fmt::format("/dev_usb%03d", i)), get_new_location()));
|
||||
}
|
||||
|
||||
if (!found_skylander)
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_usbd.h"
|
||||
#include "Emu/Io/usb_device.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
#include <libusb.h>
|
||||
|
||||
LOG_CHANNEL(sys_usbd);
|
||||
@ -244,13 +244,11 @@ u32 usb_device_emulated::get_descriptor(u8 type, u8 index, u8* buf, u32 buf_size
|
||||
}
|
||||
else
|
||||
{
|
||||
const u8 len = std::min(strings[index - 1].size() * 2 + 2, static_cast<size_t>(0xFF));
|
||||
const std::u16string u16str = utf8_to_utf16(strings[index - 1]);
|
||||
const u8 len = std::min(u16str.size() * sizeof(u16) + 2, static_cast<size_t>(0xFF));
|
||||
buf[0] = len;
|
||||
expected_count = std::min(len, ::narrow<u8>(buf_size));
|
||||
for (u32 i = 0; i < expected_count - 2; i++)
|
||||
{
|
||||
buf[i + 2] = i % 2 == 0 ? strings[index - 1].data()[i / 2] : 0;
|
||||
}
|
||||
memcpy(buf + 2, u16str.data(), expected_count - 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -3,9 +3,11 @@
|
||||
|
||||
LOG_CHANNEL(usb_vfs);
|
||||
|
||||
usb_device_vfs::usb_device_vfs(const std::array<u8, 7>& location, const u16 vid, const u16 pid, const std::string& serial)
|
||||
usb_device_vfs::usb_device_vfs(const cfg::device_info& device_info, const std::array<u8, 7>& location)
|
||||
: usb_device_emulated(location)
|
||||
{
|
||||
const auto [vid, pid] = device_info.get_usb_ids();
|
||||
|
||||
device = UsbDescriptorNode(USB_DESCRIPTOR_DEVICE,
|
||||
UsbDeviceDescriptor{
|
||||
.bcdUSB = 0x0200,
|
||||
@ -54,7 +56,7 @@ usb_device_vfs::usb_device_vfs(const std::array<u8, 7>& location, const u16 vid,
|
||||
.wMaxPacketSize = 0x0200,
|
||||
.bInterval = 0xFF}));
|
||||
|
||||
strings = {"SMI Corporation", "USB DISK", serial}; // Manufacturer, Product, SerialNumber
|
||||
strings = {"SMI Corporation", "USB DISK", device_info.serial}; // Manufacturer, Product, SerialNumber
|
||||
}
|
||||
|
||||
usb_device_vfs::~usb_device_vfs()
|
||||
|
@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "Emu/Io/usb_device.h"
|
||||
#include "Utilities/Config.h"
|
||||
|
||||
class usb_device_vfs : public usb_device_emulated
|
||||
{
|
||||
public:
|
||||
usb_device_vfs(const std::array<u8, 7>& location, const u16 vid, const u16 pid, const std::string& serial);
|
||||
usb_device_vfs(const cfg::device_info& device_info, const std::array<u8, 7>& location);
|
||||
~usb_device_vfs();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user