From d8b9b3825cd2497918e7ecf8ac98745825428639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 14 Jan 2017 22:09:09 +0100 Subject: [PATCH 01/16] IOS HLE: Add resource request structs This adds well-defined structs that are responsible for parsing resource requests, instead of duplicating the logic and offsets all over IOS HLE. Command handler functions are now passed parsed requests instead of a command address. This may not seem like a very important change, but it removes the need to remember all of the struct offsets or copy/paste existing struct request variables. It also prevents nasty bugs which have occurred in the past, such as parsing an ioctl as if it were an ioctlv (that's way too easy to do if you pass command addresses directly); or writing something to 0x0, which can easily happen by mistake with a close handler that can be called with invalid command addresses. Bonus changes: - The return code is not an obscure Memory::Write_U32 anymore, but an explicit, more obvious SetReturnValue() call. (Which correctly takes a s32 instead of a u32, since return codes are signed.) - Open handlers are now only responsible for returning an IOS ret code, and Close handlers don't return anything and don't have to worry about checking whether the request is a real one anymore. - DumpAsync was moved to the ioctlv request struct, because it did not really make sense to make it part of the IOS device and it only works for ioctlvs. All current usages have been removed; they will be readded in a later commit. As of this commit, nothing uses the structs yet. Usages will be migrated progressively. --- .../Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp | 207 +++++++++++++----- Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h | 107 ++++++++- .../IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 3 - .../Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp | 1 - .../Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 4 - .../IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp | 8 - .../Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp | 1 - .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp | 4 - .../IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp | 3 - .../IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp | 2 - 10 files changed, 248 insertions(+), 92 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp index 0a3d9cf9a3..e4b33e12d7 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp @@ -2,12 +2,16 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "Core/IPC_HLE/WII_IPC_HLE.h" +#include + +#include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "Core/HW/Memmap.h" #include "Core/HW/SystemTimers.h" +#include "Core/IPC_HLE/WII_IPC_HLE.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device.h" +// TODO: remove this once all device classes have been migrated. SIOCtlVBuffer::SIOCtlVBuffer(const u32 address) : m_Address(address) { // These are the Ioctlv parameters in the IOS communication. The BufferVector @@ -46,6 +50,116 @@ SIOCtlVBuffer::SIOCtlVBuffer(const u32 address) : m_Address(address) } } +IOSRequest::IOSRequest(const u32 address_) : address(address_) +{ + command = static_cast(Memory::Read_U32(address)); + fd = Memory::Read_U32(address + 8); +} + +void IOSRequest::SetReturnValue(const s32 new_return_value) const +{ + Memory::Write_U32(static_cast(new_return_value), address + 4); +} + +IOSOpenRequest::IOSOpenRequest(const u32 address_) : IOSRequest(address_) +{ + path = Memory::GetString(Memory::Read_U32(address + 0xc)); + flags = static_cast(Memory::Read_U32(address + 0x10)); +} + +IOSReadWriteRequest::IOSReadWriteRequest(const u32 address_) : IOSRequest(address_) +{ + buffer = Memory::Read_U32(address + 0xc); + size = Memory::Read_U32(address + 0x10); +} + +IOSSeekRequest::IOSSeekRequest(const u32 address_) : IOSRequest(address_) +{ + offset = Memory::Read_U32(address + 0xc); + mode = static_cast(Memory::Read_U32(address + 0x10)); +} + +IOSIOCtlRequest::IOSIOCtlRequest(const u32 address_) : IOSRequest(address_) +{ + request = Memory::Read_U32(address + 0x0c); + buffer_in = Memory::Read_U32(address + 0x10); + buffer_in_size = Memory::Read_U32(address + 0x14); + buffer_out = Memory::Read_U32(address + 0x18); + buffer_out_size = Memory::Read_U32(address + 0x1c); +} + +IOSIOCtlVRequest::IOSIOCtlVRequest(const u32 address_) : IOSRequest(address_) +{ + request = Memory::Read_U32(address + 0x0c); + const u32 in_number = Memory::Read_U32(address + 0x10); + const u32 out_number = Memory::Read_U32(address + 0x14); + const u32 vectors_base = Memory::Read_U32(address + 0x18); // address to vectors + + u32 offset = 0; + for (size_t i = 0; i < (in_number + out_number); ++i) + { + IOVector vector; + vector.address = Memory::Read_U32(vectors_base + offset); + vector.size = Memory::Read_U32(vectors_base + offset + 4); + offset += 8; + if (i < in_number) + in_vectors.emplace_back(vector); + else + io_vectors.emplace_back(vector); + } +} + +bool IOSIOCtlVRequest::HasInputVectorWithAddress(const u32 vector_address) const +{ + return std::any_of(in_vectors.begin(), in_vectors.end(), + [&](const auto& in_vector) { return in_vector.address == vector_address; }); +} + +void IOSIOCtlRequest::Log(const std::string& device_name, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS verbosity) const +{ + GENERIC_LOG(type, verbosity, "%s (fd %u) - IOCtl 0x%x (in_size=0x%x, out_size=0x%x)", + device_name.c_str(), fd, request, buffer_in_size, buffer_out_size); +} + +void IOSIOCtlRequest::Dump(const std::string& description, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS level) const +{ + Log("===== " + description, type, level); + GENERIC_LOG(type, level, "In buffer\n%s", + HexDump(Memory::GetPointer(buffer_in), buffer_in_size).c_str()); + GENERIC_LOG(type, level, "Out buffer\n%s", + HexDump(Memory::GetPointer(buffer_out), buffer_out_size).c_str()); +} + +void IOSIOCtlRequest::DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS level) const +{ + Dump("Unknown IOCtl - " + description, type, level); +} + +void IOSIOCtlVRequest::Dump(const std::string& description, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS level) const +{ + GENERIC_LOG(type, level, "===== %s (fd %u) - IOCtlV 0x%x (%zu in, %zu io)", description.c_str(), + fd, request, in_vectors.size(), io_vectors.size()); + + size_t i = 0; + for (const auto& vector : in_vectors) + GENERIC_LOG(type, level, "in[%zu] (size=0x%x):\n%s", i++, vector.size, + HexDump(Memory::GetPointer(vector.address), vector.size).c_str()); + + i = 0; + for (const auto& vector : io_vectors) + GENERIC_LOG(type, level, "io[%zu] (size=0x%x)", i++, vector.size); +} + +void IOSIOCtlVRequest::DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS level) const +{ + Dump("Unknown IOCtlV - " + description, type, level); +} + IWII_IPC_HLE_Device::IWII_IPC_HLE_Device(const u32 device_id, const std::string& device_name, const DeviceType type) : m_name(device_name), m_device_id(device_id), m_device_type(type) @@ -66,18 +180,35 @@ void IWII_IPC_HLE_Device::DoStateShared(PointerWrap& p) p.Do(m_is_active); } +// TODO: remove the wrappers once all device classes have been migrated. +IOSReturnCode IWII_IPC_HLE_Device::Open(const IOSOpenRequest& request) +{ + Open(request.address, request.flags); + return static_cast(Memory::Read_U32(request.address + 4)); +} + IPCCommandResult IWII_IPC_HLE_Device::Open(u32 command_address, u32 mode) { m_is_active = true; return GetDefaultReply(); } +void IWII_IPC_HLE_Device::Close() +{ + Close(0, true); +} + IPCCommandResult IWII_IPC_HLE_Device::Close(u32 command_address, bool force) { m_is_active = false; return GetDefaultReply(); } +IPCCommandResult IWII_IPC_HLE_Device::Seek(const IOSSeekRequest& request) +{ + return Seek(request.address); +} + IPCCommandResult IWII_IPC_HLE_Device::Seek(u32 command_address) { WARN_LOG(WII_IPC_HLE, "%s does not support Seek()", m_name.c_str()); @@ -85,6 +216,11 @@ IPCCommandResult IWII_IPC_HLE_Device::Seek(u32 command_address) return GetDefaultReply(); } +IPCCommandResult IWII_IPC_HLE_Device::Read(const IOSReadWriteRequest& request) +{ + return Read(request.address); +} + IPCCommandResult IWII_IPC_HLE_Device::Read(u32 command_address) { WARN_LOG(WII_IPC_HLE, "%s does not support Read()", m_name.c_str()); @@ -92,6 +228,11 @@ IPCCommandResult IWII_IPC_HLE_Device::Read(u32 command_address) return GetDefaultReply(); } +IPCCommandResult IWII_IPC_HLE_Device::Write(const IOSReadWriteRequest& request) +{ + return Write(request.address); +} + IPCCommandResult IWII_IPC_HLE_Device::Write(u32 command_address) { WARN_LOG(WII_IPC_HLE, "%s does not support Write()", m_name.c_str()); @@ -99,6 +240,11 @@ IPCCommandResult IWII_IPC_HLE_Device::Write(u32 command_address) return GetDefaultReply(); } +IPCCommandResult IWII_IPC_HLE_Device::IOCtl(const IOSIOCtlRequest& request) +{ + return IOCtl(request.address); +} + IPCCommandResult IWII_IPC_HLE_Device::IOCtl(u32 command_address) { WARN_LOG(WII_IPC_HLE, "%s does not support IOCtl()", m_name.c_str()); @@ -106,6 +252,11 @@ IPCCommandResult IWII_IPC_HLE_Device::IOCtl(u32 command_address) return GetDefaultReply(); } +IPCCommandResult IWII_IPC_HLE_Device::IOCtlV(const IOSIOCtlVRequest& request) +{ + return IOCtlV(request.address); +} + IPCCommandResult IWII_IPC_HLE_Device::IOCtlV(u32 command_address) { WARN_LOG(WII_IPC_HLE, "%s does not support IOCtlV()", m_name.c_str()); @@ -125,57 +276,3 @@ IPCCommandResult IWII_IPC_HLE_Device::GetNoReply() { return {false, 0}; } - -// Write out the IPC struct from command_address to num_commands numbers -// of 4 byte commands. -void IWII_IPC_HLE_Device::DumpCommands(u32 command_address, size_t num_commands, - LogTypes::LOG_TYPE log_type, LogTypes::LOG_LEVELS verbosity) -{ - GENERIC_LOG(log_type, verbosity, "CommandDump of %s", GetDeviceName().c_str()); - for (u32 i = 0; i < num_commands; i++) - { - GENERIC_LOG(log_type, verbosity, " Command%02i: 0x%08x", i, - Memory::Read_U32(command_address + i * 4)); - } -} - -void IWII_IPC_HLE_Device::DumpAsync(u32 buffer_vector, u32 number_in_buffer, u32 number_io_buffer, - LogTypes::LOG_TYPE log_type, LogTypes::LOG_LEVELS verbosity) -{ - GENERIC_LOG(log_type, verbosity, "======= DumpAsync ======"); - - u32 BufferOffset = buffer_vector; - for (u32 i = 0; i < number_in_buffer; i++) - { - u32 InBuffer = Memory::Read_U32(BufferOffset); - BufferOffset += 4; - u32 InBufferSize = Memory::Read_U32(BufferOffset); - BufferOffset += 4; - - GENERIC_LOG(log_type, LogTypes::LINFO, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(), i); - - std::string Temp; - for (u32 j = 0; j < InBufferSize; j++) - { - Temp += StringFromFormat("%02x ", Memory::Read_U8(InBuffer + j)); - } - - GENERIC_LOG(log_type, LogTypes::LDEBUG, " Buffer: %s", Temp.c_str()); - } - - for (u32 i = 0; i < number_io_buffer; i++) - { - u32 OutBuffer = Memory::Read_U32(BufferOffset); - BufferOffset += 4; - u32 OutBufferSize = Memory::Read_U32(BufferOffset); - BufferOffset += 4; - - GENERIC_LOG(log_type, LogTypes::LINFO, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(), - i); - GENERIC_LOG(log_type, LogTypes::LINFO, " OutBuffer: 0x%08x (0x%x):", OutBuffer, - OutBufferSize); - - if (verbosity >= LogTypes::LOG_LEVELS::LINFO) - DumpCommands(OutBuffer, OutBufferSize, log_type, verbosity); - } -} diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h index 2894ba2bd3..b56b6ba4ec 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h @@ -11,7 +11,6 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" -#include "Common/StringUtil.h" #include "Core/IPC_HLE/WII_IPC_HLE.h" enum IOSReturnCode : s32 @@ -42,6 +41,7 @@ enum IOSReturnCode : s32 }; // A struct for IOS ioctlv calls +// TODO: remove this once nothing uses this anymore. struct SIOCtlVBuffer { explicit SIOCtlVBuffer(u32 address); @@ -59,6 +59,91 @@ struct SIOCtlVBuffer std::vector PayloadBuffer; }; +struct IOSRequest +{ + u32 address = 0; + IPCCommandType command = IPC_CMD_OPEN; + u32 fd = 0; + explicit IOSRequest(u32 address); + virtual ~IOSRequest() = default; + void SetReturnValue(s32 new_return_value) const; +}; + +enum IOSOpenMode : s32 +{ + IOS_OPEN_READ = 1, + IOS_OPEN_WRITE = 2, + IOS_OPEN_RW = (IOS_OPEN_READ | IOS_OPEN_WRITE) +}; + +struct IOSOpenRequest final : IOSRequest +{ + std::string path; + IOSOpenMode flags = IOS_OPEN_READ; + explicit IOSOpenRequest(u32 address); +}; + +struct IOSReadWriteRequest final : IOSRequest +{ + u32 buffer = 0; + u32 size = 0; + explicit IOSReadWriteRequest(u32 address); +}; + +struct IOSSeekRequest final : IOSRequest +{ + enum SeekMode + { + IOS_SEEK_SET = 0, + IOS_SEEK_CUR = 1, + IOS_SEEK_END = 2, + }; + u32 offset = 0; + SeekMode mode = IOS_SEEK_SET; + explicit IOSSeekRequest(u32 address); +}; + +struct IOSIOCtlRequest final : IOSRequest +{ + u32 request = 0; + u32 buffer_in = 0; + u32 buffer_in_size = 0; + // Contrary to the name, the output buffer can also be used for input. + u32 buffer_out = 0; + u32 buffer_out_size = 0; + explicit IOSIOCtlRequest(u32 address); + void Log(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LINFO) const; + void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LINFO) const; + void DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LERROR) const; +}; + +struct IOSIOCtlVRequest final : IOSRequest +{ + struct IOVector + { + u32 address = 0; + u32 size = 0; + }; + u32 request = 0; + // In vectors are *mostly* used for input buffers. Sometimes they are also used as + // output buffers (notably in the network code). + // IO vectors are *mostly* used for output buffers. However, as indicated in the name, + // they're also used as input buffers. + // So both of them are technically IO vectors. But we're keeping them separated because + // merging them into a single std::vector would make using the first out vector more complicated. + std::vector in_vectors; + std::vector io_vectors; + explicit IOSIOCtlVRequest(u32 address); + bool HasInputVectorWithAddress(u32 vector_address) const; + void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LINFO) const; + void DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LERROR) const; +}; + class IWII_IPC_HLE_Device { public: @@ -79,6 +164,16 @@ public: const std::string& GetDeviceName() const { return m_name; } u32 GetDeviceID() const { return m_device_id; } + // Replies to Open and Close requests are sent by WII_IPC_HLE, not by the devices themselves. + virtual IOSReturnCode Open(const IOSOpenRequest& request); + virtual void Close(); + virtual IPCCommandResult Seek(const IOSSeekRequest& request); + virtual IPCCommandResult Read(const IOSReadWriteRequest& request); + virtual IPCCommandResult Write(const IOSReadWriteRequest& request); + virtual IPCCommandResult IOCtl(const IOSIOCtlRequest& request); + virtual IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request); + + // TODO: remove these once all device classes have been migrated. virtual IPCCommandResult Open(u32 command_address, u32 mode); virtual IPCCommandResult Close(u32 command_address, bool force = false); virtual IPCCommandResult Seek(u32 command_address); @@ -99,14 +194,4 @@ protected: u32 m_device_id; DeviceType m_device_type; bool m_is_active = false; - - // Write out the IPC struct from command_address to number_of_commands numbers - // of 4 byte commands. - void DumpCommands(u32 command_address, size_t number_of_commands = 8, - LogTypes::LOG_TYPE log_type = LogTypes::WII_IPC_HLE, - LogTypes::LOG_LEVELS verbosity = LogTypes::LDEBUG); - - void DumpAsync(u32 buffer_vector, u32 number_in_buffer, u32 number_io_buffer, - LogTypes::LOG_TYPE log_type = LogTypes::WII_IPC_HLE, - LogTypes::LOG_LEVELS verbosity = LogTypes::LDEBUG); }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 8cd1f853a4..972dc6ea35 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -308,9 +308,6 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress) { DEBUG_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_name.c_str()); -#if defined(_DEBUG) || defined(DEBUGFAST) - DumpCommands(_CommandAddress); -#endif const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); u32 ReturnValue = 0; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp index dd20bbdb7d..c190bfdc63 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -1282,7 +1282,6 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) default: INFO_LOG(WII_IPC_ES, "CWII_IPC_HLE_Device_es: 0x%x", Buffer.Parameter); - DumpCommands(_CommandAddress, 8, LogTypes::WII_IPC_ES); INFO_LOG(WII_IPC_ES, "command.Parameter: 0x%08x", Buffer.Parameter); break; } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index ffb1d08103..829c5ff873 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -296,10 +296,6 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); INFO_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); INFO_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); -#if defined(_DEBUG) || defined(DEBUGFAST) - DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, - CommandBuffer.NumberPayloadBuffer); -#endif Memory::Write_U32(ReturnValue, _CommandAddress + 4); return GetDefaultReply(); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp index be712534cd..0a7bcf82cc 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp @@ -204,11 +204,6 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) break; } - // INFO_LOG(WII_IPC_SD, "InBuffer"); - // DumpCommands(BufferIn, BufferInSize / 4, LogTypes::WII_IPC_SD); - // INFO_LOG(WII_IPC_SD, "OutBuffer"); - // DumpCommands(BufferOut, BufferOutSize/4, LogTypes::WII_IPC_SD); - if (ReturnValue == RET_EVENT_REGISTER) { // async @@ -265,9 +260,6 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(u32 _CommandAddress) break; } - // DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, - // CommandBuffer.NumberPayloadBuffer, LogTypes::WII_IPC_SD); - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); return GetDefaultReply(); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp index 07d2747ba0..77f250a719 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp @@ -59,7 +59,6 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) case IOCTL_STM_VIDIMMING: // (Input: 20 bytes, Output: 20 bytes) INFO_LOG(WII_IPC_STM, "%s - IOCtl:", GetDeviceName().c_str()); INFO_LOG(WII_IPC_STM, " IOCTL_STM_VIDIMMING"); - // DumpCommands(buffer_in, buffer_in_size / 4, LogTypes::WII_IPC_STM); // Memory::Write_U32(1, buffer_out); // return_value = 1; break; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp index f81169a140..7902659c7c 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp @@ -268,10 +268,6 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAdd INFO_LOG(WII_IPC_WIIMOTE, " BufferVector: 0x%08x", CommandBuffer.BufferVector); INFO_LOG(WII_IPC_WIIMOTE, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); INFO_LOG(WII_IPC_WIIMOTE, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); -#if defined(_DEBUG) || defined(DEBUGFAST) - DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, - CommandBuffer.NumberPayloadBuffer); -#endif } break; } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp index ed8c3df786..2634dbcf8d 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp @@ -73,9 +73,6 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Close(u32 _CommandAddress, bool _b IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Write(u32 _CommandAddress) { DEBUG_LOG(WII_IPC_HLE, "Ignoring write to CWII_IPC_HLE_Device_usb_kbd"); -#if defined(_DEBUG) || defined(DEBUGFAST) - DumpCommands(_CommandAddress, 10, LogTypes::WII_IPC_HLE, LogTypes::LDEBUG); -#endif return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp index a613e39242..d448c38586 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp @@ -25,8 +25,6 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(u32 command_address) INFO_LOG(OSHLE, " NumberIn: 0x%08x", command_buffer.NumberInBuffer); INFO_LOG(OSHLE, " NumberOut: 0x%08x", command_buffer.NumberPayloadBuffer); INFO_LOG(OSHLE, " BufferVector: 0x%08x", command_buffer.BufferVector); - DumpAsync(command_buffer.BufferVector, command_buffer.NumberInBuffer, - command_buffer.NumberPayloadBuffer); Memory::Write_U32(0, command_address + 4); return GetNoReply(); From e2d072250faa89076d836ccc0f263d9e1d076dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 01:43:00 +0100 Subject: [PATCH 02/16] IOS HLE: Deduplicate request code in WII_IPC_HLE --- Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp | 83 ++++++++++++------------ Source/Core/Core/IPC_HLE/WII_IPC_HLE.h | 5 +- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp index fdca1f408c..170f142628 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp @@ -180,7 +180,7 @@ void Reset(bool hard) { if (!device) continue; - device->Close(0, true); + device->Close(); device.reset(); } @@ -348,12 +348,10 @@ static std::shared_ptr GetUnusedESDevice() } // Returns the FD for the newly opened device (on success) or an error code. -static s32 OpenDevice(const u32 address) +static s32 OpenDevice(const IOSOpenRequest& request) { - const std::string device_name = Memory::GetString(Memory::Read_U32(address + 0xC)); - const u32 open_mode = Memory::Read_U32(address + 0x10); const s32 new_fd = GetFreeDeviceID(); - INFO_LOG(WII_IPC_HLE, "Opening %s (mode %d, fd %d)", device_name.c_str(), open_mode, new_fd); + INFO_LOG(WII_IPC_HLE, "Opening %s (mode %d, fd %d)", request.path.c_str(), request.flags, new_fd); if (new_fd < 0 || new_fd >= IPC_MAX_FDS) { ERROR_LOG(WII_IPC_HLE, "Couldn't get a free fd, too many open files"); @@ -361,80 +359,78 @@ static s32 OpenDevice(const u32 address) } std::shared_ptr device; - if (device_name.find("/dev/es") == 0) + if (request.path == "/dev/es") { device = GetUnusedESDevice(); if (!device) return IPC_EESEXHAUSTED; } - else if (device_name.find("/dev/") == 0) + else if (request.path.find("/dev/") == 0) { - device = GetDeviceByName(device_name); + device = GetDeviceByName(request.path); } - else if (device_name.find('/') == 0) + else if (request.path.find('/') == 0) { - device = std::make_shared(new_fd, device_name); + device = std::make_shared(new_fd, request.path); } if (!device) { - ERROR_LOG(WII_IPC_HLE, "Unknown device: %s", device_name.c_str()); + ERROR_LOG(WII_IPC_HLE, "Unknown device: %s", request.path.c_str()); return IPC_ENOENT; } - Memory::Write_U32(new_fd, address + 4); - device->Open(address, open_mode); - const s32 open_return_code = Memory::Read_U32(address + 4); - if (open_return_code < 0) - return open_return_code; + const IOSReturnCode code = device->Open(request); + if (code < IPC_SUCCESS) + return code; s_fdmap[new_fd] = device; return new_fd; } -static IPCCommandResult HandleCommand(const u32 address) +static IPCCommandResult HandleCommand(const IOSRequest& request) { - const auto command = static_cast(Memory::Read_U32(address)); - if (command == IPC_CMD_OPEN) + if (request.command == IPC_CMD_OPEN) { - const s32 new_fd = OpenDevice(address); - Memory::Write_U32(new_fd, address + 4); + IOSOpenRequest open_request{request.address}; + const s32 new_fd = OpenDevice(open_request); + open_request.SetReturnValue(new_fd); return IWII_IPC_HLE_Device::GetDefaultReply(); } - const s32 fd = Memory::Read_U32(address + 8); - const auto device = (fd >= 0 && fd < IPC_MAX_FDS) ? s_fdmap[fd] : nullptr; + const auto device = (request.fd < IPC_MAX_FDS) ? s_fdmap[request.fd] : nullptr; if (!device) { - Memory::Write_U32(IPC_EINVAL, address + 4); + request.SetReturnValue(IPC_EINVAL); return IWII_IPC_HLE_Device::GetDefaultReply(); } - switch (command) + switch (request.command) { case IPC_CMD_CLOSE: - s_fdmap[fd].reset(); - // A close on a valid device returns IPC_SUCCESS. - Memory::Write_U32(IPC_SUCCESS, address + 4); - return device->Close(address); + s_fdmap[request.fd].reset(); + device->Close(); + request.SetReturnValue(IPC_SUCCESS); + return IWII_IPC_HLE_Device::GetDefaultReply(); case IPC_CMD_READ: - return device->Read(address); + return device->Read(IOSReadWriteRequest{request.address}); case IPC_CMD_WRITE: - return device->Write(address); + return device->Write(IOSReadWriteRequest{request.address}); case IPC_CMD_SEEK: - return device->Seek(address); + return device->Seek(IOSSeekRequest{request.address}); case IPC_CMD_IOCTL: - return device->IOCtl(address); + return device->IOCtl(IOSIOCtlRequest{request.address}); case IPC_CMD_IOCTLV: - return device->IOCtlV(address); + return device->IOCtlV(IOSIOCtlVRequest{request.address}); default: - _assert_msg_(WII_IPC_HLE, false, "Unexpected command: %x", command); + _assert_msg_(WII_IPC_HLE, false, "Unexpected command: %x", request.command); return IWII_IPC_HLE_Device::GetDefaultReply(); } } void ExecuteCommand(const u32 address) { - IPCCommandResult result = HandleCommand(address); + IOSRequest request{address}; + IPCCommandResult result = HandleCommand(request); // Ensure replies happen in order const s64 ticks_until_last_reply = s_last_reply_time - CoreTiming::GetTicks(); @@ -443,7 +439,7 @@ void ExecuteCommand(const u32 address) s_last_reply_time = CoreTiming::GetTicks() + result.reply_delay_ticks; if (result.send_reply) - EnqueueReply(address, static_cast(result.reply_delay_ticks)); + EnqueueReply(request, static_cast(result.reply_delay_ticks)); } // Happens AS SOON AS IPC gets a new pointer! @@ -453,13 +449,18 @@ void EnqueueRequest(u32 address) } // Called to send a reply to an IOS syscall -void EnqueueReply(u32 address, int cycles_in_future, CoreTiming::FromThread from) +void EnqueueReply(const IOSRequest& request, int cycles_in_future, CoreTiming::FromThread from) { // IOS writes back the command that was responded to in the FD field. - Memory::Write_U32(Memory::Read_U32(address), address + 8); + Memory::Write_U32(request.command, request.address + 8); // IOS also overwrites the command type with the reply type. - Memory::Write_U32(IPC_REPLY, address); - CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, address, from); + Memory::Write_U32(IPC_REPLY, request.address); + CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from); +} + +void EnqueueReply(u32 command_address, int cycles_in_future, CoreTiming::FromThread from) +{ + EnqueueReply(IOSRequest{command_address}, cycles_in_future, from); } void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h index c7b5de812c..c57924c1b4 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h @@ -12,6 +12,7 @@ #include "Core/CoreTiming.h" #include "Core/HW/SystemTimers.h" +struct IOSRequest; class IWII_IPC_HLE_Device; class PointerWrap; @@ -69,7 +70,9 @@ void UpdateDevices(); void ExecuteCommand(u32 address); void EnqueueRequest(u32 address); -void EnqueueReply(u32 address, int cycles_in_future = 0, +void EnqueueReply(const IOSRequest& request, int cycles_in_future = 0, + CoreTiming::FromThread from = CoreTiming::FromThread::CPU); +void EnqueueReply(u32 command_address, int cycles_in_future = 0, CoreTiming::FromThread from = CoreTiming::FromThread::CPU); void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future = 0); From d7b4e6ead5752eb2da1f72b81f8d5c5fb01ac9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 02:07:09 +0100 Subject: [PATCH 03/16] IOS HLE: Deduplicate request code in STM --- .../Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp | 87 +++++++------------ .../Core/IPC_HLE/WII_IPC_HLE_Device_stm.h | 8 +- 2 files changed, 32 insertions(+), 63 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp index 77f250a719..a8cb13e931 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp @@ -5,6 +5,7 @@ #include "Core/IPC_HLE/WII_IPC_HLE_Device_stm.h" #include +#include #include "Common/Assert.h" #include "Common/Logging/Log.h" @@ -16,22 +17,12 @@ void QueueHostJob(std::function job, bool run_during_stop); void Stop(); } -static u32 s_event_hook_address = 0; +static std::unique_ptr s_event_hook_request; -IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(const IOSIOCtlRequest& request) { - u32 parameter = Memory::Read_U32(command_address + 0x0C); - u32 buffer_in = Memory::Read_U32(command_address + 0x10); - u32 buffer_in_size = Memory::Read_U32(command_address + 0x14); - u32 buffer_out = Memory::Read_U32(command_address + 0x18); - u32 buffer_out_size = Memory::Read_U32(command_address + 0x1C); - - // Prepare the out buffer(s) with zeroes as a safety precaution - // to avoid returning bad values - Memory::Memset(buffer_out, 0, buffer_out_size); - u32 return_value = 0; - - switch (parameter) + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTL_STM_IDLE: case IOCTL_STM_SHUTDOWN: @@ -40,15 +31,15 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) break; case IOCTL_STM_RELEASE_EH: - if (s_event_hook_address == 0) + if (!s_event_hook_request) { return_value = IPC_ENOENT; break; } - Memory::Write_U32(0, Memory::Read_U32(s_event_hook_address + 0x18)); - Memory::Write_U32(IPC_SUCCESS, s_event_hook_address + 4); - WII_IPC_HLE_Interface::EnqueueReply(s_event_hook_address); - s_event_hook_address = 0; + Memory::Write_U32(0, s_event_hook_request->buffer_out); + s_event_hook_request->SetReturnValue(IPC_SUCCESS); + WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request); + s_event_hook_request.reset(); break; case IOCTL_STM_HOTRESET: @@ -69,79 +60,59 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) break; default: - { - _dbg_assert_msg_(WII_IPC_STM, 0, "CWII_IPC_HLE_Device_stm_immediate: 0x%x", parameter); - - INFO_LOG(WII_IPC_STM, "%s - IOCtl:", GetDeviceName().c_str()); - DEBUG_LOG(WII_IPC_STM, " parameter: 0x%x", parameter); - DEBUG_LOG(WII_IPC_STM, " InBuffer: 0x%08x", buffer_in); - DEBUG_LOG(WII_IPC_STM, " InBufferSize: 0x%08x", buffer_in_size); - DEBUG_LOG(WII_IPC_STM, " OutBuffer: 0x%08x", buffer_out); - DEBUG_LOG(WII_IPC_STM, " OutBufferSize: 0x%08x", buffer_out_size); - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_STM); } - // Write return value to the IPC call - Memory::Write_U32(return_value, command_address + 0x4); + request.SetReturnValue(return_value); return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::Close(u32 command_address, bool force) +void CWII_IPC_HLE_Device_stm_eventhook::Close() { - s_event_hook_address = 0; - + s_event_hook_request.reset(); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::IOCtl(const IOSIOCtlRequest& request) { - u32 parameter = Memory::Read_U32(command_address + 0x0C); - if (parameter != IOCTL_STM_EVENTHOOK) + if (request.request != IOCTL_STM_EVENTHOOK) { ERROR_LOG(WII_IPC_STM, "Bad IOCtl in CWII_IPC_HLE_Device_stm_eventhook"); - Memory::Write_U32(IPC_EINVAL, command_address + 4); + request.SetReturnValue(IPC_EINVAL); return GetDefaultReply(); } - if (s_event_hook_address != 0) + if (s_event_hook_request) { - Memory::Write_U32(FS_EEXIST, command_address + 4); + request.SetReturnValue(IPC_EEXIST); return GetDefaultReply(); } - // IOCTL_STM_EVENTHOOK waits until the reset button or power button - // is pressed. - s_event_hook_address = command_address; + // IOCTL_STM_EVENTHOOK waits until the reset button or power button is pressed. + s_event_hook_request = std::make_unique(request.address); return GetNoReply(); } bool CWII_IPC_HLE_Device_stm_eventhook::HasHookInstalled() const { - return s_event_hook_address != 0; + return s_event_hook_request != nullptr; } void CWII_IPC_HLE_Device_stm_eventhook::TriggerEvent(const u32 event) const { - if (!m_is_active || s_event_hook_address == 0) - { - // If the device isn't open, ignore the button press. + // If the device isn't open, ignore the button press. + if (!m_is_active || !s_event_hook_request) return; - } - // The reset button returns STM_EVENT_RESET. - u32 buffer_out = Memory::Read_U32(s_event_hook_address + 0x18); - Memory::Write_U32(event, buffer_out); - - Memory::Write_U32(IPC_SUCCESS, s_event_hook_address + 4); - WII_IPC_HLE_Interface::EnqueueReply(s_event_hook_address); - s_event_hook_address = 0; + Memory::Write_U32(event, s_event_hook_request->buffer_out); + s_event_hook_request->SetReturnValue(IPC_SUCCESS); + WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request); + s_event_hook_request.reset(); } void CWII_IPC_HLE_Device_stm_eventhook::ResetButton() const { - // The reset button returns STM_EVENT_RESET. + // The reset button triggers STM_EVENT_RESET. TriggerEvent(STM_EVENT_RESET); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.h index 879568ea15..b83a8dc4a3 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.h @@ -43,8 +43,7 @@ public: { } - ~CWII_IPC_HLE_Device_stm_immediate() override = default; - IPCCommandResult IOCtl(u32 command_address) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; }; // The /dev/stm/eventhook @@ -56,9 +55,8 @@ public: { } - ~CWII_IPC_HLE_Device_stm_eventhook() override = default; - IPCCommandResult Close(u32 command_address, bool force) override; - IPCCommandResult IOCtl(u32 command_address) override; + void Close() override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; bool HasHookInstalled() const; void ResetButton() const; From d536082e4273e878e2f93a85e9ab13aae804b95c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:45:16 +0100 Subject: [PATCH 04/16] IOS HLE: Deduplicate request code in USB_VEN --- .../IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp | 56 ++++++------------- .../Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h | 10 +--- 2 files changed, 18 insertions(+), 48 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp index d448c38586..db025b3d07 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp @@ -12,40 +12,23 @@ CWII_IPC_HLE_Device_usb_ven::CWII_IPC_HLE_Device_usb_ven(const u32 device_id, { } -CWII_IPC_HLE_Device_usb_ven::~CWII_IPC_HLE_Device_usb_ven() +IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(const IOSIOCtlVRequest& request) { -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(u32 command_address) -{ - SIOCtlVBuffer command_buffer(command_address); - - INFO_LOG(OSHLE, "%s - IOCtlV:", GetDeviceName().c_str()); - INFO_LOG(OSHLE, " Parameter: 0x%x", command_buffer.Parameter); - INFO_LOG(OSHLE, " NumberIn: 0x%08x", command_buffer.NumberInBuffer); - INFO_LOG(OSHLE, " NumberOut: 0x%08x", command_buffer.NumberPayloadBuffer); - INFO_LOG(OSHLE, " BufferVector: 0x%08x", command_buffer.BufferVector); - - Memory::Write_U32(0, command_address + 4); + request.Dump(GetDeviceName()); + request.SetReturnValue(IPC_SUCCESS); return GetNoReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(const IOSIOCtlRequest& request) { + request.Log(GetDeviceName(), LogTypes::OSHLE); + request.SetReturnValue(IPC_SUCCESS); + IPCCommandResult reply = GetDefaultReply(); - u32 command = Memory::Read_U32(command_address + 0x0c); - u32 buffer_in = Memory::Read_U32(command_address + 0x10); - u32 buffer_in_size = Memory::Read_U32(command_address + 0x14); - u32 buffer_out = Memory::Read_U32(command_address + 0x18); - u32 buffer_out_size = Memory::Read_U32(command_address + 0x1c); - - INFO_LOG(OSHLE, "%s - IOCtl: %x", GetDeviceName().c_str(), command); - INFO_LOG(OSHLE, "%x:%x %x:%x", buffer_in, buffer_in_size, buffer_out, buffer_out_size); - - switch (command) + switch (request.request) { case USBV5_IOCTL_GETVERSION: - Memory::Write_U32(0x50001, buffer_out); + Memory::Write_U32(0x50001, request.buffer_out); reply = GetDefaultReply(); break; @@ -60,7 +43,7 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 command_address) } // num devices - Memory::Write_U32(0, command_address + 4); + request.SetReturnValue(0); return reply; } break; @@ -70,33 +53,26 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 command_address) break; case USBV5_IOCTL_SUSPEND_RESUME: - DEBUG_LOG(OSHLE, "Device: %i Resumed: %i", Memory::Read_U32(buffer_in), - Memory::Read_U32(buffer_in + 4)); + DEBUG_LOG(OSHLE, "Device: %i Resumed: %i", Memory::Read_U32(request.buffer_in), + Memory::Read_U32(request.buffer_in + 4)); reply = GetDefaultReply(); break; case USBV5_IOCTL_GETDEVPARAMS: { - s32 device = Memory::Read_U32(buffer_in); - u32 unk = Memory::Read_U32(buffer_in + 4); + s32 device = Memory::Read_U32(request.buffer_in); + u32 unk = Memory::Read_U32(request.buffer_in + 4); DEBUG_LOG(OSHLE, "USBV5_IOCTL_GETDEVPARAMS device: %i unk: %i", device, unk); - Memory::Write_U32(0, buffer_out); + Memory::Write_U32(0, request.buffer_out); reply = GetDefaultReply(); } break; default: - DEBUG_LOG(OSHLE, "%x:%x %x:%x", buffer_in, buffer_in_size, buffer_out, buffer_out_size); - break; + request.Log(GetDeviceName(), LogTypes::OSHLE, LogTypes::LDEBUG); } - - Memory::Write_U32(0, command_address + 4); return reply; } - -void CWII_IPC_HLE_Device_usb_ven::DoState(PointerWrap& p) -{ -} diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h index 612400f1e0..7cb5406483 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h @@ -10,19 +10,13 @@ #include "Core/IPC_HLE/WII_IPC_HLE.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device.h" -class PointerWrap; - class CWII_IPC_HLE_Device_usb_ven final : public IWII_IPC_HLE_Device { public: CWII_IPC_HLE_Device_usb_ven(u32 device_id, const std::string& device_name); - ~CWII_IPC_HLE_Device_usb_ven() override; - - IPCCommandResult IOCtlV(u32 command_address) override; - IPCCommandResult IOCtl(u32 command_address) override; - - void DoState(PointerWrap& p) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: enum USBIOCtl From d4de87a9734f075b58b9939e5c60b2daa0bc1545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:45:53 +0100 Subject: [PATCH 05/16] IOS HLE: Deduplicate request code in USB_KBD --- .../IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp | 33 ++++--------------- .../Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h | 7 ++-- 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp index 2634dbcf8d..52af5fd684 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp @@ -38,17 +38,14 @@ CWII_IPC_HLE_Device_usb_kbd::CWII_IPC_HLE_Device_usb_kbd(u32 _DeviceID, { } -CWII_IPC_HLE_Device_usb_kbd::~CWII_IPC_HLE_Device_usb_kbd() -{ -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Open(u32 _CommandAddress, u32 _Mode) +IOSReturnCode CWII_IPC_HLE_Device_usb_kbd::Open(const IOSOpenRequest& request) { INFO_LOG(WII_IPC_HLE, "CWII_IPC_HLE_Device_usb_kbd: Open"); IniFile ini; ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); ini.GetOrCreateSection("USB Keyboard")->Get("Layout", &m_KeyboardLayout, KBD_LAYOUT_QWERTY); + m_MessageQueue = std::queue(); for (bool& pressed : m_OldKeyBuffer) { pressed = false; @@ -58,35 +55,17 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Open(u32 _CommandAddress, u32 _Mod // m_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, nullptr)); m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Close(u32 _CommandAddress, bool _bForce) +IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::IOCtl(const IOSIOCtlRequest& request) { - INFO_LOG(WII_IPC_HLE, "CWII_IPC_HLE_Device_usb_kbd: Close"); - while (!m_MessageQueue.empty()) - m_MessageQueue.pop(); - m_is_active = false; - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Write(u32 _CommandAddress) -{ - DEBUG_LOG(WII_IPC_HLE, "Ignoring write to CWII_IPC_HLE_Device_usb_kbd"); - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::IOCtl(u32 _CommandAddress) -{ - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - if (SConfig::GetInstance().m_WiiKeyboard && !Core::g_want_determinism && !m_MessageQueue.empty()) { - Memory::CopyToEmu(BufferOut, &m_MessageQueue.front(), sizeof(SMessageData)); + Memory::CopyToEmu(request.buffer_out, &m_MessageQueue.front(), sizeof(SMessageData)); m_MessageQueue.pop(); } - - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h index 4f0a852057..18b3efade0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h @@ -15,12 +15,9 @@ class CWII_IPC_HLE_Device_usb_kbd : public IWII_IPC_HLE_Device { public: CWII_IPC_HLE_Device_usb_kbd(u32 _DeviceID, const std::string& _rDeviceName); - virtual ~CWII_IPC_HLE_Device_usb_kbd(); - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - IPCCommandResult Write(u32 _CommandAddress) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; void Update() override; private: From f9e806fd715602c343505a3b3c9e698d457ad158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:46:50 +0100 Subject: [PATCH 06/16] IOS HLE: Deduplicate request code in OH1 --- .../WII_IPC_HLE_Device_usb_bt_base.cpp | 32 ++- .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h | 23 +- .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp | 205 +++++++----------- .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h | 32 +-- .../WII_IPC_HLE_Device_usb_bt_real.cpp | 64 +++--- .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h | 16 +- .../WII_IPC_HLE_Device_usb_bt_stub.cpp | 4 +- .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h | 5 +- Source/Core/Core/State.cpp | 2 +- 9 files changed, 150 insertions(+), 233 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp index 4f6b9d77b0..26a182d8ed 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp @@ -50,24 +50,23 @@ void RestoreBTInfoSection(SysConf* sysconf) File::Delete(filename); } -CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlMessage::CtrlMessage(const SIOCtlVBuffer& cmd_buffer) +CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlMessage::CtrlMessage(const IOSIOCtlVRequest& ioctlv) + : ios_request(ioctlv) { - request_type = Memory::Read_U8(cmd_buffer.InBuffer[0].m_Address); - request = Memory::Read_U8(cmd_buffer.InBuffer[1].m_Address); - value = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[2].m_Address)); - index = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[3].m_Address)); - length = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[4].m_Address)); - payload_addr = cmd_buffer.PayloadBuffer[0].m_Address; - address = cmd_buffer.m_Address; + request_type = Memory::Read_U8(ioctlv.in_vectors[0].address); + request = Memory::Read_U8(ioctlv.in_vectors[1].address); + value = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[2].address)); + index = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[3].address)); + length = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[4].address)); + payload_addr = ioctlv.io_vectors[0].address; } -CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::CtrlBuffer(const SIOCtlVBuffer& cmd_buffer, - const u32 command_address) +CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::CtrlBuffer(const IOSIOCtlVRequest& ioctlv) + : ios_request(ioctlv) { - m_endpoint = Memory::Read_U8(cmd_buffer.InBuffer[0].m_Address); - m_length = Memory::Read_U16(cmd_buffer.InBuffer[1].m_Address); - m_payload_addr = cmd_buffer.PayloadBuffer[0].m_Address; - m_cmd_address = command_address; + m_endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address); + m_length = Memory::Read_U16(ioctlv.in_vectors[1].address); + m_payload_addr = ioctlv.io_vectors[0].address; } void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8* src, @@ -77,8 +76,3 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8* m_length); Memory::CopyToEmu(m_payload_addr, src, size); } - -void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::SetRetVal(const u32 retval) const -{ - Memory::Write_U32(retval, m_cmd_address + 4); -} diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h index a880498fa1..d5580299c3 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h @@ -24,11 +24,6 @@ public: : IWII_IPC_HLE_Device(device_id, device_name) { } - virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_base() override = default; - - virtual IPCCommandResult Open(u32 command_address, u32 mode) override = 0; - - virtual void DoState(PointerWrap& p) override = 0; virtual void UpdateSyncButtonState(bool is_held) {} virtual void TriggerSyncButtonPressedEvent() {} @@ -56,31 +51,23 @@ protected: struct CtrlMessage { - CtrlMessage() = default; - CtrlMessage(const SIOCtlVBuffer& cmd_buffer); - + CtrlMessage(const IOSIOCtlVRequest& ioctlv); + IOSIOCtlVRequest ios_request; u8 request_type = 0; u8 request = 0; u16 value = 0; u16 index = 0; u16 length = 0; u32 payload_addr = 0; - u32 address = 0; }; - class CtrlBuffer + struct CtrlBuffer { - public: - CtrlBuffer() = default; - CtrlBuffer(const SIOCtlVBuffer& cmd_buffer, u32 command_address); - + CtrlBuffer(const IOSIOCtlVRequest& ioctlv); + IOSIOCtlVRequest ios_request; void FillBuffer(const u8* src, size_t size) const; - void SetRetVal(const u32 retval) const; - bool IsValid() const { return m_cmd_address != 0; } - void Invalidate() { m_cmd_address = m_payload_addr = 0; } u8 m_endpoint = 0; u16 m_length = 0; u32 m_payload_addr = 0; - u32 m_cmd_address = 0; }; }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp index 7902659c7c..e22df24c87 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp @@ -95,8 +95,6 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::CWII_IPC_HLE_Device_usb_oh1_57e_305_emu m_ControllerBD.b[4] = 0x00; m_ControllerBD.b[5] = 0xFF; - memset(m_PacketCount, 0, sizeof(m_PacketCount)); - Host_SetWiiMoteConnectionState(0); } @@ -106,6 +104,18 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::~CWII_IPC_HLE_Device_usb_oh1_57e_305_em SetUsbPointer(nullptr); } +template +static void DoStateForMessage(PointerWrap& p, std::unique_ptr& message) +{ + u32 request_address = (message != nullptr) ? message->ios_request.address : 0; + p.Do(request_address); + if (request_address != 0) + { + IOSIOCtlVRequest request{request_address}; + message = std::make_unique(request); + } +} + void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p) { bool passthrough_bluetooth = false; @@ -119,10 +129,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p) p.Do(m_is_active); p.Do(m_ControllerBD); - p.Do(m_CtrlSetup); - p.Do(m_ACLSetup); - p.DoPOD(m_HCIEndpoint); - p.DoPOD(m_ACLEndpoint); + DoStateForMessage(p, m_CtrlSetup); + DoStateForMessage(p, m_HCIEndpoint); + DoStateForMessage(p, m_ACLEndpoint); p.Do(m_last_ticks); p.DoArray(m_PacketCount); p.Do(m_ScanEnable); @@ -138,75 +147,41 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::RemoteDisconnect(u16 _connectionHa return SendEventDisconnect(_connectionHandle, 0x13); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Open(u32 _CommandAddress, u32 _Mode) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Close() { + // Clean up state m_ScanEnable = 0; - m_last_ticks = 0; memset(m_PacketCount, 0, sizeof(m_PacketCount)); - - m_HCIEndpoint.m_cmd_address = 0; - m_ACLEndpoint.m_cmd_address = 0; - - m_is_active = true; - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Close(u32 _CommandAddress, bool _bForce) -{ - m_ScanEnable = 0; - - m_last_ticks = 0; - memset(m_PacketCount, 0, sizeof(m_PacketCount)); - - m_HCIEndpoint.m_cmd_address = 0; - m_ACLEndpoint.m_cmd_address = 0; + m_HCIEndpoint.reset(); + m_ACLEndpoint.reset(); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(const IOSIOCtlVRequest& request) { - bool _SendReply = false; - - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - switch (CommandBuffer.Parameter) + bool send_reply = true; + switch (request.request) { case USBV0_IOCTL_CTRLMSG: // HCI command is received from the stack { - // This is the HCI datapath from CPU to Wii Remote, the USB stuff is little endian.. - m_CtrlSetup.bRequestType = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address); - m_CtrlSetup.bRequest = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address); - m_CtrlSetup.wValue = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address); - m_CtrlSetup.wIndex = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address); - m_CtrlSetup.wLength = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address); - m_CtrlSetup.m_PayLoadAddr = CommandBuffer.PayloadBuffer[0].m_Address; - m_CtrlSetup.m_PayLoadSize = CommandBuffer.PayloadBuffer[0].m_Size; - m_CtrlSetup.m_Address = CommandBuffer.m_Address; - - // check termination - _dbg_assert_msg_(WII_IPC_WIIMOTE, - *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[5].m_Address) == 0, - "WIIMOTE: Termination != 0"); - + m_CtrlSetup = std::make_unique(request); // Replies are generated inside - ExecuteHCICommandMessage(m_CtrlSetup); + ExecuteHCICommandMessage(*m_CtrlSetup); + m_CtrlSetup.reset(); + send_reply = false; + break; } - break; case USBV0_IOCTL_BLKMSG: { - const CtrlBuffer ctrl(CommandBuffer, _CommandAddress); + const CtrlBuffer ctrl{request}; switch (ctrl.m_endpoint) { case ACL_DATA_OUT: // ACL data is received from the stack { // This is the ACL datapath from CPU to Wii Remote - // Here we only need to record the command address in case we need to delay the reply - m_ACLSetup = CommandBuffer.m_Address; - const auto* acl_header = reinterpret_cast(Memory::GetPointer(ctrl.m_payload_addr)); @@ -216,65 +191,43 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAdd SendToDevice(HCI_CON_HANDLE(acl_header->con_handle), Memory::GetPointer(ctrl.m_payload_addr + sizeof(hci_acldata_hdr_t)), acl_header->length); - - _SendReply = true; + break; } - break; - case ACL_DATA_IN: // We are given an ACL buffer to fill { - CtrlBuffer temp(CommandBuffer, _CommandAddress); - m_ACLEndpoint = temp; - - DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", _CommandAddress); + m_ACLEndpoint = std::make_unique(request); + DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", request.address); + send_reply = false; + break; } - break; - default: - { _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_BLKMSG: %x", ctrl.m_endpoint); } break; - } } - break; case USBV0_IOCTL_INTRMSG: { - const CtrlBuffer ctrl(CommandBuffer, _CommandAddress); + const CtrlBuffer ctrl{request}; if (ctrl.m_endpoint == HCI_EVENT) // We are given a HCI buffer to fill { - CtrlBuffer temp(CommandBuffer, _CommandAddress); - m_HCIEndpoint = temp; - - DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", _CommandAddress); + m_HCIEndpoint = std::make_unique(request); + DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", request.address); + send_reply = false; } else { _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_INTRMSG: %x", ctrl.m_endpoint); } + break; } - break; default: - { - _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown CWII_IPC_HLE_Device_usb_oh1_57e_305: %x", - CommandBuffer.Parameter); - - INFO_LOG(WII_IPC_WIIMOTE, "%s - IOCtlV:", GetDeviceName().c_str()); - INFO_LOG(WII_IPC_WIIMOTE, " Parameter: 0x%x", CommandBuffer.Parameter); - INFO_LOG(WII_IPC_WIIMOTE, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - INFO_LOG(WII_IPC_WIIMOTE, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - INFO_LOG(WII_IPC_WIIMOTE, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - INFO_LOG(WII_IPC_WIIMOTE, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - INFO_LOG(WII_IPC_WIIMOTE, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_WIIMOTE); } - // write return value - Memory::Write_U32(0, _CommandAddress + 4); - return _SendReply ? GetDefaultReply() : GetNoReply(); + request.SetReturnValue(IPC_SUCCESS); + return send_reply ? GetDefaultReply() : GetNoReply(); } // Here we handle the USBV0_IOCTL_BLKMSG Ioctlv @@ -302,22 +255,22 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendACLPacket(u16 connection_handl { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet from %x ready to send to stack...", connection_handle); - if (m_ACLEndpoint.IsValid() && !m_HCIEndpoint.IsValid() && m_EventQueue.empty()) + if (m_ACLEndpoint && !m_HCIEndpoint && m_EventQueue.empty()) { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint valid, sending packet to %08x", - m_ACLEndpoint.m_cmd_address); + m_ACLEndpoint->ios_request.address); hci_acldata_hdr_t* header = - reinterpret_cast(Memory::GetPointer(m_ACLEndpoint.m_payload_addr)); + reinterpret_cast(Memory::GetPointer(m_ACLEndpoint->m_payload_addr)); header->con_handle = HCI_MK_CON_HANDLE(connection_handle, HCI_PACKET_START, HCI_POINT2POINT); header->length = size; // Write the packet to the buffer memcpy(reinterpret_cast(header) + sizeof(hci_acldata_hdr_t), data, header->length); - m_ACLEndpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size); - WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint.m_cmd_address); - m_ACLEndpoint.Invalidate(); + m_ACLEndpoint->ios_request.SetReturnValue(sizeof(hci_acldata_hdr_t) + size); + WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint->ios_request); + m_ACLEndpoint.reset(); } else { @@ -336,17 +289,17 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x completed...", ((hci_event_hdr_t*)_event.m_buffer)->event); - if (m_HCIEndpoint.IsValid()) + if (m_HCIEndpoint) { if (m_EventQueue.empty()) // fast path :) { DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint valid, sending packet to %08x", - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(_event.m_buffer, _event.m_size); - m_HCIEndpoint.SetRetVal(_event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(_event.m_buffer, _event.m_size); + m_HCIEndpoint->ios_request.SetReturnValue(_event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + m_HCIEndpoint.reset(); } else // push new one, pop oldest { @@ -357,12 +310,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x " "being written from queue (%zu) to %08x...", ((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1, - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size); - m_HCIEndpoint.SetRetVal(event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); + m_HCIEndpoint->ios_request.SetReturnValue(event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } } @@ -377,24 +330,27 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() { // check HCI queue - if (!m_EventQueue.empty() && m_HCIEndpoint.IsValid()) + if (!m_EventQueue.empty() && m_HCIEndpoint) { // an endpoint has become available, and we have a stored response. const SQueuedEvent& event = m_EventQueue.front(); DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x being written from queue (%zu) to %08x...", ((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1, - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size); - m_HCIEndpoint.SetRetVal(event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); + m_HCIEndpoint->ios_request.SetReturnValue(event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } // check ACL queue - if (!m_acl_pool.IsEmpty() && m_ACLEndpoint.IsValid() && m_EventQueue.empty()) - m_acl_pool.WriteToEndpoint(m_ACLEndpoint); + if (!m_acl_pool.IsEmpty() && m_ACLEndpoint && m_EventQueue.empty()) + { + m_acl_pool.WriteToEndpoint(*m_ACLEndpoint); + m_ACLEndpoint.reset(); + } // We wait for ScanEnable to be sent from the Bluetooth stack through HCI_CMD_WRITE_SCAN_ENABLE // before we initiate the connection. @@ -402,7 +358,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() // FiRES: TODO find a better way to do this // Create ACL connection - if (m_HCIEndpoint.IsValid() && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE)) + if (m_HCIEndpoint && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE)) { for (auto& wiimote : m_WiiMotes) { @@ -415,7 +371,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() } // Link channels when connected - if (m_ACLEndpoint.IsValid()) + if (m_ACLEndpoint) { for (auto& wiimote : m_WiiMotes) { @@ -469,7 +425,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from " "queue to %08x", - endpoint.m_cmd_address); + endpoint.ios_request.address); hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_payload_addr); pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT); @@ -478,12 +434,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe // Write the packet to the buffer std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t)); - endpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size); + endpoint.ios_request.SetReturnValue(sizeof(hci_acldata_hdr_t) + size); m_queue.pop_front(); - WII_IPC_HLE_Interface::EnqueueReply(endpoint.m_cmd_address); - endpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(endpoint.ios_request); } bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventInquiryComplete() @@ -1023,10 +978,10 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventConPacketTypeChange(u16 _ // Command dispatcher // This is called from the USBV0_IOCTL_CTRLMSG Ioctlv void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( - const SHCICommandMessage& _rHCICommandMessage) + const CtrlMessage& ctrl_message) { - u8* pInput = Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr + 3); - SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr); + u8* pInput = Memory::GetPointer(ctrl_message.payload_addr + 3); + SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(ctrl_message.payload_addr); u16 ocf = HCI_OCF(pMsg->Opcode); u16 ogf = HCI_OGF(pMsg->Opcode); @@ -1110,11 +1065,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( // vendor specific... case 0xFC4C: - CommandVendorSpecific_FC4C(pInput, _rHCICommandMessage.m_PayLoadSize - 3); + CommandVendorSpecific_FC4C(pInput, ctrl_message.length - 3); break; case 0xFC4F: - CommandVendorSpecific_FC4F(pInput, _rHCICommandMessage.m_PayLoadSize - 3); + CommandVendorSpecific_FC4F(pInput, ctrl_message.length - 3); break; case HCI_CMD_INQUIRY_CANCEL: @@ -1203,7 +1158,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( } // HCI command is finished, send a reply to command - WII_IPC_HLE_Interface::EnqueueReply(_rHCICommandMessage.m_Address); + WII_IPC_HLE_Interface::EnqueueReply(ctrl_message.ios_request); } // diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h index c2986ec676..c3b6ad2cc0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -43,10 +44,8 @@ public: virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_emu(); - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + void Close() override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void Update() override; @@ -62,31 +61,16 @@ public: void DoState(PointerWrap& p) override; private: - struct SHCICommandMessage - { - u8 bRequestType; - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; - - u32 m_PayLoadAddr; - u32 m_PayLoadSize; - u32 m_Address; - }; - bdaddr_t m_ControllerBD; // this is used to trigger connecting via ACL u8 m_ScanEnable = 0; - SHCICommandMessage m_CtrlSetup; - CtrlBuffer m_HCIEndpoint; + std::unique_ptr m_CtrlSetup; + std::unique_ptr m_HCIEndpoint; + std::unique_ptr m_ACLEndpoint; std::deque m_EventQueue; - u32 m_ACLSetup; - CtrlBuffer m_ACLEndpoint; - class ACLPool { struct Packet @@ -109,7 +93,7 @@ private: void DoState(PointerWrap& p) { p.Do(m_queue); } } m_acl_pool; - u32 m_PacketCount[MAX_BBMOTES]; + u32 m_PacketCount[MAX_BBMOTES] = {}; u64 m_last_ticks = 0; // Send ACL data to a device (wiimote) @@ -138,7 +122,7 @@ private: bool SendEventLinkKeyNotification(const u8 num_to_send); // Execute HCI Message - void ExecuteHCICommandMessage(const SHCICommandMessage& _rCtrlMessage); + void ExecuteHCICommandMessage(const CtrlMessage& ctrl_message); // OGF 0x01 - Link control commands and return parameters void CommandWriteInquiryMode(const u8* input); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp index c3dfb461a7..d4a59d6866 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp @@ -18,6 +18,7 @@ #include "Common/Assert.h" #include "Common/ChunkFile.h" +#include "Common/CommonFuncs.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" #include "Common/Network.h" @@ -89,7 +90,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_real::~CWII_IPC_HLE_Device_usb_oh1_57e_305_r SaveLinkKeys(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(const IOSOpenRequest& request) { libusb_device** list; const ssize_t cnt = libusb_get_device_list(m_libusb_context, &list); @@ -136,18 +137,18 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(u32 command_addr PanicAlertT("Bluetooth passthrough mode is enabled, " "but no usable Bluetooth USB device was found. Aborting."); Core::QueueHostJob(Core::Stop); - return GetNoReply(); + return IPC_ENOENT; } StartTransferThread(); m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close(u32 command_address, bool force) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close() { - if (!force) + if (m_handle) { libusb_release_interface(m_handle, 0); StopTransferThread(); @@ -156,10 +157,9 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close(u32 command_add } m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(const IOSIOCtlVRequest& request) { if (!m_is_wii_bt_module && s_need_reset_keys.TestAndClear()) { @@ -170,14 +170,13 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad WaitForHCICommandComplete(HCI_CMD_WRITE_STORED_LINK_KEY); } - const SIOCtlVBuffer cmd_buffer(command_address); - switch (cmd_buffer.Parameter) + switch (request.request) { // HCI commands to the Bluetooth adapter case USBV0_IOCTL_CTRLMSG: { - auto cmd = std::make_unique(cmd_buffer); - const u16 opcode = *reinterpret_cast(Memory::GetPointer(cmd->payload_addr)); + auto cmd = std::make_unique(request); + const u16 opcode = Common::swap16(Memory::Read_U16(cmd->payload_addr)); if (opcode == HCI_CMD_READ_BUFFER_SIZE) { m_fake_read_buffer_size_reply.Set(); @@ -220,25 +219,24 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad case USBV0_IOCTL_BLKMSG: case USBV0_IOCTL_INTRMSG: { - auto buffer = std::make_unique(cmd_buffer, command_address); - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear()) + auto buffer = std::make_unique(request); + if (request.request == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear()) { FakeReadBufferSizeReply(*buffer); return GetNoReply(); } - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear()) + if (request.request == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear()) { FakeVendorCommandReply(*buffer); return GetNoReply(); } - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && - m_sync_button_state == SyncButtonState::Pressed) + if (request.request == USBV0_IOCTL_INTRMSG && m_sync_button_state == SyncButtonState::Pressed) { Core::DisplayMessage("Scanning for Wii Remotes", 2000); FakeSyncButtonPressedEvent(*buffer); return GetNoReply(); } - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && + if (request.request == USBV0_IOCTL_INTRMSG && m_sync_button_state == SyncButtonState::LongPressed) { Core::DisplayMessage("Reset saved Wii Remote pairings", 2000); @@ -253,8 +251,8 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; transfer->length = buffer->m_length; transfer->timeout = TIMEOUT; - transfer->type = cmd_buffer.Parameter == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK : - LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->type = request.request == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK : + LIBUSB_TRANSFER_TYPE_INTERRUPT; transfer->user_data = buffer.release(); libusb_submit_transfer(transfer); break; @@ -387,7 +385,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_real::SendHCIStoreLinkKeyCommand() return true; } -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(CtrlBuffer& ctrl) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); auto* hci_event = reinterpret_cast(packet); @@ -395,8 +393,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const Ctrl hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2; hci_event->PacketIndicator = 0x01; hci_event->Opcode = m_fake_vendor_command_reply_opcode; - ctrl.SetRetVal(sizeof(SHCIEventCommand)); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + ctrl.ios_request.SetReturnValue(sizeof(SHCIEventCommand)); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); } // Due to how the widcomm stack which Nintendo uses is coded, we must never @@ -404,7 +402,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const Ctrl // - it will cause a u8 underflow and royally screw things up. // Therefore, the reply to this command has to be faked to avoid random, weird issues // (including Wiimote disconnects and "event mismatch" warning messages). -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(CtrlBuffer& ctrl) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); auto* hci_event = reinterpret_cast(packet); @@ -421,11 +419,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const Ctr reply.num_sco_pkts = SCO_PKT_NUM; memcpy(packet + sizeof(SHCIEventCommand), &reply, sizeof(hci_read_buffer_size_rp)); - ctrl.SetRetVal(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp)); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + ctrl.ios_request.SetReturnValue(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp)); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); } -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuffer& ctrl, +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(CtrlBuffer& ctrl, const u8* payload, const u8 size) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); @@ -433,15 +431,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuf hci_event->event = HCI_EVENT_VENDOR; hci_event->length = size; memcpy(packet + sizeof(hci_event_hdr_t), payload, size); - ctrl.SetRetVal(sizeof(hci_event_hdr_t) + size); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + ctrl.ios_request.SetReturnValue(sizeof(hci_event_hdr_t) + size); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); } // When the red sync button is pressed, a HCI event is generated: // > HCI Event: Vendor (0xff) plen 1 // 08 // This causes the emulated software to perform a BT inquiry and connect to found Wiimotes. -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(CtrlBuffer& ctrl) { NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button pressed' (0x08) event packet"); const u8 payload[1] = {0x08}; @@ -450,7 +448,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(const } // When the red sync button is held for 10 seconds, a HCI event with payload 09 is sent. -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonHeldEvent(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonHeldEvent(CtrlBuffer& ctrl) { NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button held' (0x09) event packet"); const u8 payload[1] = {0x09}; @@ -580,7 +578,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::CommandCallback(libusb_transfer* s_showed_failed_transfer.Clear(); } - WII_IPC_HLE_Interface::EnqueueReply(cmd->address, 0, CoreTiming::FromThread::NON_CPU); + WII_IPC_HLE_Interface::EnqueueReply(cmd->ios_request, 0, CoreTiming::FromThread::NON_CPU); } void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* tr) @@ -624,6 +622,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* } } - ctrl->SetRetVal(tr->actual_length); - WII_IPC_HLE_Interface::EnqueueReply(ctrl->m_cmd_address, 0, CoreTiming::FromThread::NON_CPU); + ctrl->ios_request.SetReturnValue(tr->actual_length); + WII_IPC_HLE_Interface::EnqueueReply(ctrl->ios_request, 0, CoreTiming::FromThread::NON_CPU); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h index 1925fca877..6c267264cb 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h @@ -42,9 +42,9 @@ public: CWII_IPC_HLE_Device_usb_oh1_57e_305_real(u32 device_id, const std::string& device_name); ~CWII_IPC_HLE_Device_usb_oh1_57e_305_real() override; - IPCCommandResult Open(u32 command_address, u32 mode) override; - IPCCommandResult Close(u32 command_address, bool force) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void DoState(PointerWrap& p) override; void UpdateSyncButtonState(bool is_held) override; @@ -80,11 +80,11 @@ private: void SendHCIResetCommand(); void SendHCIDeleteLinkKeyCommand(); bool SendHCIStoreLinkKeyCommand(); - void FakeVendorCommandReply(const CtrlBuffer& ctrl); - void FakeReadBufferSizeReply(const CtrlBuffer& ctrl); - void FakeSyncButtonEvent(const CtrlBuffer& ctrl, const u8* payload, u8 size); - void FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl); - void FakeSyncButtonHeldEvent(const CtrlBuffer& ctrl); + void FakeVendorCommandReply(CtrlBuffer& ctrl); + void FakeReadBufferSizeReply(CtrlBuffer& ctrl); + void FakeSyncButtonEvent(CtrlBuffer& ctrl, const u8* payload, u8 size); + void FakeSyncButtonPressedEvent(CtrlBuffer& ctrl); + void FakeSyncButtonHeldEvent(CtrlBuffer& ctrl); void LoadLinkKeys(); void SaveLinkKeys(); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp index e4cbd011eb..252cefadf7 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp @@ -12,11 +12,11 @@ namespace Core void DisplayMessage(const std::string& message, int time_in_ms); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::Open(const IOSOpenRequest& request) { PanicAlertT("Bluetooth passthrough mode is enabled, but Dolphin was built without libusb." " Passthrough mode cannot be used."); - return GetNoReply(); + return IPC_ENOENT; } void CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::DoState(PointerWrap& p) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h index 074c9cae5c..efb149496e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h @@ -16,11 +16,10 @@ class CWII_IPC_HLE_Device_usb_oh1_57e_305_stub final : public CWII_IPC_HLE_Device_usb_oh1_57e_305_base { public: - CWII_IPC_HLE_Device_usb_oh1_57e_305_stub(u32 device_id, const std::string& device_name) + CWII_IPC_HLE_Device_usb_oh1_57e_305_stub(const u32 device_id, const std::string& device_name) : CWII_IPC_HLE_Device_usb_oh1_57e_305_base(device_id, device_name) { } - ~CWII_IPC_HLE_Device_usb_oh1_57e_305_stub() override {} - IPCCommandResult Open(u32 command_address, u32 mode) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; void DoState(PointerWrap& p) override; }; diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 6d84534de5..428ccb339e 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 68; // Last changed in PR 4638 +static const u32 STATE_VERSION = 69; // Last changed in PR 4661 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list, From 84c8d0b66dda1693fe0f53bc820324de11d6592e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:47:05 +0100 Subject: [PATCH 07/16] IOS HLE: Deduplicate request code in stub --- .../Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp | 16 +++++++--------- .../Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h | 8 ++++---- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp index aa8dc57050..8f00b8188a 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp @@ -4,37 +4,35 @@ #include "Core/IPC_HLE/WII_IPC_HLE_Device_stub.h" #include "Common/Logging/Log.h" -#include "Core/HW/Memmap.h" CWII_IPC_HLE_Device_stub::CWII_IPC_HLE_Device_stub(u32 device_id, const std::string& device_name) : IWII_IPC_HLE_Device(device_id, device_name) { } -IPCCommandResult CWII_IPC_HLE_Device_stub::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_stub::Open(const IOSOpenRequest& request) { WARN_LOG(WII_IPC_HLE, "%s faking Open()", m_name.c_str()); m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_stub::Close(u32 command_address, bool force) +void CWII_IPC_HLE_Device_stub::Close() { WARN_LOG(WII_IPC_HLE, "%s faking Close()", m_name.c_str()); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtl(const IOSIOCtlRequest& request) { WARN_LOG(WII_IPC_HLE, "%s faking IOCtl()", m_name.c_str()); - Memory::Write_U32(IPC_SUCCESS, command_address + 4); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtlV(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtlV(const IOSIOCtlVRequest& request) { WARN_LOG(WII_IPC_HLE, "%s faking IOCtlV()", m_name.c_str()); - Memory::Write_U32(IPC_SUCCESS, command_address + 4); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h index 68449b8172..8dd7c72eab 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h @@ -15,8 +15,8 @@ class CWII_IPC_HLE_Device_stub : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_stub(u32 device_id, const std::string& device_name); - IPCCommandResult Open(u32 command_address, u32 mode) override; - IPCCommandResult Close(u32 command_address, bool force = false) override; - IPCCommandResult IOCtl(u32 command_address) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; }; From a04902086a7f2d244811b461fb72a6366a733c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:47:27 +0100 Subject: [PATCH 08/16] IOS HLE: Deduplicate request code in net/net_ssl --- .../Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp | 550 +++++++----------- .../Core/IPC_HLE/WII_IPC_HLE_Device_net.h | 38 +- .../IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp | 168 +++--- .../Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h | 4 +- Source/Core/Core/IPC_HLE/WII_Socket.cpp | 65 +-- Source/Core/Core/IPC_HLE/WII_Socket.h | 18 +- 6 files changed, 349 insertions(+), 494 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp index 3eae1d40e4..4eff039bfc 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp @@ -72,21 +72,15 @@ CWII_IPC_HLE_Device_net_kd_request::~CWII_IPC_HLE_Device_net_kd_request() WiiSockMan::GetInstance().Clean(); } -IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(const IOSIOCtlRequest& request) { - u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - u32 ReturnValue = 0; - switch (Parameter) + s32 return_value = 0; + switch (request.request) { case IOCTL_NWC24_SUSPEND_SCHEDULAR: // NWC24iResumeForCloseLib from NWC24SuspendScheduler (Input: none, Output: 32 bytes) INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_SUSPEND_SCHEDULAR - NI"); - Memory::Write_U32(0, BufferOut); // no error + Memory::Write_U32(0, request.buffer_out); // no error break; case IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR: // NWC24iResumeForCloseLib @@ -95,18 +89,17 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) case IOCTL_NWC24_EXEC_RESUME_SCHEDULAR: // NWC24iResumeForCloseLib INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_EXEC_RESUME_SCHEDULAR - NI"); - Memory::Write_U32(0, BufferOut); // no error + Memory::Write_U32(0, request.buffer_out); // no error break; case IOCTL_NWC24_STARTUP_SOCKET: // NWC24iStartupSocket - Memory::Write_U32(0, BufferOut); - Memory::Write_U32(0, BufferOut + 4); - ReturnValue = 0; + Memory::Write_U32(0, request.buffer_out); + Memory::Write_U32(0, request.buffer_out + 4); + return_value = 0; INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_STARTUP_SOCKET - NI"); break; case IOCTL_NWC24_CLEANUP_SOCKET: - Memory::Memset(BufferOut, 0, BufferOutSize); INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_CLEANUP_SOCKET - NI"); break; @@ -120,8 +113,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) case IOCTL_NWC24_REQUEST_REGISTER_USER_ID: INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_REGISTER_USER_ID"); - Memory::Write_U32(0, BufferOut); - Memory::Write_U32(0, BufferOut + 4); + Memory::Write_U32(0, request.buffer_out); + Memory::Write_U32(0, request.buffer_out + 4); break; case IOCTL_NWC24_REQUEST_GENERATED_USER_ID: // (Input: none, Output: 32 bytes) @@ -161,23 +154,23 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) config.SetCreationStage(NWC24::NWC24Config::NWC24_IDCS_GENERATED); config.WriteConfig(); - Memory::Write_U32(ret, BufferOut); + Memory::Write_U32(ret, request.buffer_out); } else { - Memory::Write_U32(NWC24::WC24_ERR_FATAL, BufferOut); + Memory::Write_U32(NWC24::WC24_ERR_FATAL, request.buffer_out); } } else if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_GENERATED) { - Memory::Write_U32(NWC24::WC24_ERR_ID_GENERATED, BufferOut); + Memory::Write_U32(NWC24::WC24_ERR_ID_GENERATED, request.buffer_out); } else if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_REGISTERED) { - Memory::Write_U32(NWC24::WC24_ERR_ID_REGISTERED, BufferOut); + Memory::Write_U32(NWC24::WC24_ERR_ID_REGISTERED, request.buffer_out); } - Memory::Write_U64(config.Id(), BufferOut + 4); - Memory::Write_U32(config.CreationStage(), BufferOut + 0xC); + Memory::Write_U64(config.Id(), request.buffer_out + 4); + Memory::Write_U32(config.CreationStage(), request.buffer_out + 0xC); break; case IOCTL_NWC24_GET_SCHEDULAR_STAT: @@ -194,13 +187,10 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) break; default: - INFO_LOG(WII_IPC_WC24, - "/dev/net/kd/request::IOCtl request 0x%x (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); - break; + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); } - Memory::Write_U32(ReturnValue, _CommandAddress + 4); + request.SetReturnValue(return_value); return GetDefaultReply(); } @@ -337,52 +327,49 @@ CWII_IPC_HLE_Device_net_ncd_manage::~CWII_IPC_HLE_Device_net_ncd_manage() { } -IPCCommandResult CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(const IOSIOCtlVRequest& request) { - u32 return_value = 0; + s32 return_value = IPC_SUCCESS; u32 common_result = 0; u32 common_vector = 0; - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - switch (CommandBuffer.Parameter) + switch (request.request) { case IOCTLV_NCD_LOCKWIRELESSDRIVER: break; case IOCTLV_NCD_UNLOCKWIRELESSDRIVER: - // Memory::Read_U32(CommandBuffer.InBuffer.at(0).m_Address); + // Memory::Read_U32(request.in_vectors.at(0).address); break; case IOCTLV_NCD_GETCONFIG: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETCONFIG"); - config.WriteToMem(CommandBuffer.PayloadBuffer.at(0).m_Address); + config.WriteToMem(request.io_vectors.at(0).address); common_vector = 1; break; case IOCTLV_NCD_SETCONFIG: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_SETCONFIG"); - config.ReadFromMem(CommandBuffer.InBuffer.at(0).m_Address); + config.ReadFromMem(request.in_vectors.at(0).address); break; case IOCTLV_NCD_READCONFIG: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_READCONFIG"); config.ReadConfig(); - config.WriteToMem(CommandBuffer.PayloadBuffer.at(0).m_Address); + config.WriteToMem(request.io_vectors.at(0).address); common_vector = 1; break; case IOCTLV_NCD_WRITECONFIG: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_WRITECONFIG"); - config.ReadFromMem(CommandBuffer.InBuffer.at(0).m_Address); + config.ReadFromMem(request.in_vectors.at(0).address); config.WriteConfig(); break; case IOCTLV_NCD_GETLINKSTATUS: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETLINKSTATUS"); // Always connected - Memory::Write_U32(Net::ConnectionSettings::LINK_WIRED, - CommandBuffer.PayloadBuffer.at(0).m_Address + 4); + Memory::Write_U32(Net::ConnectionSettings::LINK_WIRED, request.io_vectors.at(0).address + 4); break; case IOCTLV_NCD_GETWIRELESSMACADDRESS: @@ -390,20 +377,20 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress) u8 address[MAC_ADDRESS_SIZE]; GetMacAddress(address); - Memory::CopyToEmu(CommandBuffer.PayloadBuffer.at(1).m_Address, address, sizeof(address)); + Memory::CopyToEmu(request.io_vectors.at(1).address, address, sizeof(address)); break; default: - INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %#x", CommandBuffer.Parameter); + INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %#x", request.request); break; } - Memory::Write_U32(common_result, CommandBuffer.PayloadBuffer.at(common_vector).m_Address); + Memory::Write_U32(common_result, request.io_vectors.at(common_vector).address); if (common_vector == 1) { - Memory::Write_U32(common_result, CommandBuffer.PayloadBuffer.at(common_vector).m_Address + 4); + Memory::Write_U32(common_result, request.io_vectors.at(common_vector).address + 4); } - Memory::Write_U32(return_value, _CommandAddress + 4); + request.SetReturnValue(return_value); return GetDefaultReply(); } @@ -422,21 +409,19 @@ CWII_IPC_HLE_Device_net_wd_command::~CWII_IPC_HLE_Device_net_wd_command() // This is just for debugging / playing around. // There really is no reason to implement wd unless we can bend it such that // we can talk to the DS. -IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(u32 CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(const IOSIOCtlVRequest& request) { - u32 return_value = 0; + s32 return_value = IPC_SUCCESS; - SIOCtlVBuffer CommandBuffer(CommandAddress); - - switch (CommandBuffer.Parameter) + switch (request.request) { case IOCTLV_WD_SCAN: { // Gives parameters detailing type of scan and what to match // XXX - unused - // ScanInfo *scan = (ScanInfo *)Memory::GetPointer(CommandBuffer.InBuffer.at(0).m_Address); + // ScanInfo *scan = (ScanInfo *)Memory::GetPointer(request.in_vectors.at(0).m_Address); - u16* results = (u16*)Memory::GetPointer(CommandBuffer.PayloadBuffer.at(0).m_Address); + u16* results = (u16*)Memory::GetPointer(request.io_vectors.at(0).address); // first u16 indicates number of BSSInfo following results[0] = Common::swap16(1); @@ -459,7 +444,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(u32 CommandAddress) case IOCTLV_WD_GET_INFO: { - Info* info = (Info*)Memory::GetPointer(CommandBuffer.PayloadBuffer.at(0).m_Address); + Info* info = (Info*)Memory::GetPointer(request.io_vectors.at(0).address); memset(info, 0, sizeof(Info)); // Probably used to disallow certain channels? memcpy(info->country, "US", 2); @@ -488,27 +473,10 @@ IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(u32 CommandAddress) case IOCTLV_WD_RECV_FRAME: case IOCTLV_WD_RECV_NOTIFICATION: default: - INFO_LOG(WII_IPC_NET, "NET_WD_COMMAND IOCtlV %#x in %i out %i", CommandBuffer.Parameter, - CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); - for (u32 i = 0; i < CommandBuffer.NumberInBuffer; ++i) - { - DEBUG_LOG(WII_IPC_NET, "in %i addr %x size %i", i, CommandBuffer.InBuffer.at(i).m_Address, - CommandBuffer.InBuffer.at(i).m_Size); - DEBUG_LOG(WII_IPC_NET, "%s", - ArrayToString(Memory::GetPointer(CommandBuffer.InBuffer.at(i).m_Address), - CommandBuffer.InBuffer.at(i).m_Size) - .c_str()); - } - for (u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; ++i) - { - DEBUG_LOG(WII_IPC_NET, "out %i addr %x size %i", i, - CommandBuffer.PayloadBuffer.at(i).m_Address, - CommandBuffer.PayloadBuffer.at(i).m_Size); - } - break; + request.Dump(GetDeviceName(), LogTypes::WII_IPC_NET, LogTypes::LINFO); } - Memory::Write_U32(return_value, CommandAddress + 4); + request.SetReturnValue(return_value); return GetDefaultReply(); } @@ -581,61 +549,54 @@ static unsigned int opt_level_mapping[][2] = {{SOL_SOCKET, 0xFFFF}}; static unsigned int opt_name_mapping[][2] = { {SO_REUSEADDR, 0x4}, {SO_SNDBUF, 0x1001}, {SO_RCVBUF, 0x1002}, {SO_ERROR, 0x1009}}; -IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(const IOSIOCtlRequest& request) { if (Core::g_want_determinism) { - Memory::Write_U32(-1, _CommandAddress + 4); + request.SetReturnValue(-1); return GetDefaultReply(); } - u32 Command = Memory::Read_U32(_CommandAddress + 0x0C); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - u32 ReturnValue = 0; - switch (Command) + s32 return_value = 0; + switch (request.request) { case IOCTL_SO_STARTUP: { - INFO_LOG(WII_IPC_NET, "IOCTL_SO_STARTUP " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); break; } case IOCTL_SO_SOCKET: { - u32 af = Memory::Read_U32(BufferIn); - u32 type = Memory::Read_U32(BufferIn + 0x04); - u32 prot = Memory::Read_U32(BufferIn + 0x08); + u32 af = Memory::Read_U32(request.buffer_in); + u32 type = Memory::Read_U32(request.buffer_in + 4); + u32 prot = Memory::Read_U32(request.buffer_in + 8); WiiSockMan& sm = WiiSockMan::GetInstance(); - ReturnValue = sm.NewSocket(af, type, prot); + return_value = sm.NewSocket(af, type, prot); INFO_LOG(WII_IPC_NET, "IOCTL_SO_SOCKET " "Socket: %08x (%d,%d,%d), BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - ReturnValue, af, type, prot, BufferIn, BufferInSize, BufferOut, BufferOutSize); + return_value, af, type, prot, request.buffer_in, request.buffer_in_size, + request.buffer_out, request.buffer_out_size); break; } case IOCTL_SO_ICMPSOCKET: { - u32 pf = Memory::Read_U32(BufferIn); + u32 pf = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); - ReturnValue = sm.NewSocket(pf, SOCK_RAW, IPPROTO_ICMP); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_ICMPSOCKET(%x) %d", pf, ReturnValue); + return_value = sm.NewSocket(pf, SOCK_RAW, IPPROTO_ICMP); + INFO_LOG(WII_IPC_NET, "IOCTL_SO_ICMPSOCKET(%x) %d", pf, return_value); break; } case IOCTL_SO_CLOSE: case IOCTL_SO_ICMPCLOSE: { - u32 fd = Memory::Read_U32(BufferIn); + u32 fd = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); - ReturnValue = sm.DeleteSocket(fd); + return_value = sm.DeleteSocket(fd); INFO_LOG(WII_IPC_NET, "%s(%x) %x", - Command == IOCTL_SO_ICMPCLOSE ? "IOCTL_SO_ICMPCLOSE" : "IOCTL_SO_CLOSE", fd, - ReturnValue); + request.request == IOCTL_SO_ICMPCLOSE ? "IOCTL_SO_ICMPCLOSE" : "IOCTL_SO_CLOSE", fd, + return_value); break; } case IOCTL_SO_ACCEPT: @@ -643,9 +604,9 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) case IOCTL_SO_CONNECT: case IOCTL_SO_FCNTL: { - u32 fd = Memory::Read_U32(BufferIn); + u32 fd = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(fd, _CommandAddress, (NET_IOCTL)Command); + sm.DoSock(fd, request, static_cast(request.request)); return GetNoReply(); } ///////////////////////////////////////////////////////////// @@ -653,36 +614,30 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) ///////////////////////////////////////////////////////////// case IOCTL_SO_SHUTDOWN: { - INFO_LOG(WII_IPC_NET, "IOCTL_SO_SHUTDOWN " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); - u32 fd = Memory::Read_U32(BufferIn); - u32 how = Memory::Read_U32(BufferIn + 4); + u32 fd = Memory::Read_U32(request.buffer_in); + u32 how = Memory::Read_U32(request.buffer_in + 4); int ret = shutdown(fd, how); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_SHUTDOWN", false); + return_value = WiiSockMan::GetNetErrorCode(ret, "SO_SHUTDOWN", false); break; } case IOCTL_SO_LISTEN: { - u32 fd = Memory::Read_U32(BufferIn); - u32 BACKLOG = Memory::Read_U32(BufferIn + 0x04); + u32 fd = Memory::Read_U32(request.buffer_in); + u32 BACKLOG = Memory::Read_U32(request.buffer_in + 0x04); u32 ret = listen(fd, BACKLOG); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_LISTEN = %d " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + return_value = WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); break; } case IOCTL_SO_GETSOCKOPT: { - u32 fd = Memory::Read_U32(BufferOut); - u32 level = Memory::Read_U32(BufferOut + 4); - u32 optname = Memory::Read_U32(BufferOut + 8); + u32 fd = Memory::Read_U32(request.buffer_out); + u32 level = Memory::Read_U32(request.buffer_out + 4); + u32 optname = Memory::Read_U32(request.buffer_out + 8); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETSOCKOPT(%08x, %08x, %08x)" - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - fd, level, optname, BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); // Do the level/optname translation int nat_level = -1, nat_optname = -1; @@ -699,45 +654,46 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) u32 optlen = 4; int ret = getsockopt(fd, nat_level, nat_optname, (char*)&optval, (socklen_t*)&optlen); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_GETSOCKOPT", false); + return_value = WiiSockMan::GetNetErrorCode(ret, "SO_GETSOCKOPT", false); - Memory::Write_U32(optlen, BufferOut + 0xC); - Memory::CopyToEmu(BufferOut + 0x10, optval, optlen); + Memory::Write_U32(optlen, request.buffer_out + 0xC); + Memory::CopyToEmu(request.buffer_out + 0x10, optval, optlen); if (optname == SO_ERROR) { s32 last_error = WiiSockMan::GetInstance().GetLastNetError(); - Memory::Write_U32(sizeof(s32), BufferOut + 0xC); - Memory::Write_U32(last_error, BufferOut + 0x10); + Memory::Write_U32(sizeof(s32), request.buffer_out + 0xC); + Memory::Write_U32(last_error, request.buffer_out + 0x10); } break; } case IOCTL_SO_SETSOCKOPT: { - u32 fd = Memory::Read_U32(BufferIn); - u32 level = Memory::Read_U32(BufferIn + 4); - u32 optname = Memory::Read_U32(BufferIn + 8); - u32 optlen = Memory::Read_U32(BufferIn + 0xc); + u32 fd = Memory::Read_U32(request.buffer_in); + u32 level = Memory::Read_U32(request.buffer_in + 4); + u32 optname = Memory::Read_U32(request.buffer_in + 8); + u32 optlen = Memory::Read_U32(request.buffer_in + 0xc); u8 optval[20]; optlen = std::min(optlen, (u32)sizeof(optval)); - Memory::CopyFromEmu(optval, BufferIn + 0x10, optlen); + Memory::CopyFromEmu(optval, request.buffer_in + 0x10, optlen); INFO_LOG(WII_IPC_NET, "IOCTL_SO_SETSOCKOPT(%08x, %08x, %08x, %08x) " "BufferIn: (%08x, %i), BufferOut: (%08x, %i)" "%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx " "%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx", - fd, level, optname, optlen, BufferIn, BufferInSize, BufferOut, BufferOutSize, - optval[0], optval[1], optval[2], optval[3], optval[4], optval[5], optval[6], optval[7], - optval[8], optval[9], optval[10], optval[11], optval[12], optval[13], optval[14], - optval[15], optval[16], optval[17], optval[18], optval[19]); + fd, level, optname, optlen, request.buffer_in, request.buffer_in_size, + request.buffer_out, request.buffer_out_size, optval[0], optval[1], optval[2], + optval[3], optval[4], optval[5], optval[6], optval[7], optval[8], optval[9], + optval[10], optval[11], optval[12], optval[13], optval[14], optval[15], optval[16], + optval[17], optval[18], optval[19]); // TODO: bug booto about this, 0x2005 most likely timeout related, default value on Wii is , // 0x2001 is most likely tcpnodelay if (level == 6 && (optname == 0x2005 || optname == 0x2001)) { - ReturnValue = 0; + return_value = 0; break; } @@ -762,38 +718,36 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) } int ret = setsockopt(fd, nat_level, nat_optname, (char*)optval, optlen); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false); + return_value = WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false); break; } case IOCTL_SO_GETSOCKNAME: { - u32 fd = Memory::Read_U32(BufferIn); + u32 fd = Memory::Read_U32(request.buffer_in); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETSOCKNAME " - "Socket: %08X, BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - fd, BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); sockaddr sa; socklen_t sa_len; sa_len = sizeof(sa); int ret = getsockname(fd, &sa, &sa_len); - if (BufferOutSize < 2 + sizeof(sa.sa_data)) + if (request.buffer_out_size < 2 + sizeof(sa.sa_data)) WARN_LOG(WII_IPC_NET, "IOCTL_SO_GETSOCKNAME output buffer is too small. Truncating"); - if (BufferOutSize > 0) - Memory::Write_U8(BufferOutSize, BufferOut); - if (BufferOutSize > 1) - Memory::Write_U8(sa.sa_family & 0xFF, BufferOut + 1); - if (BufferOutSize > 2) - Memory::CopyToEmu(BufferOut + 2, &sa.sa_data, - std::min(sizeof(sa.sa_data), BufferOutSize - 2)); - ReturnValue = ret; + if (request.buffer_out_size > 0) + Memory::Write_U8(request.buffer_out_size, request.buffer_out); + if (request.buffer_out_size > 1) + Memory::Write_U8(sa.sa_family & 0xFF, request.buffer_out + 1); + if (request.buffer_out_size > 2) + Memory::CopyToEmu(request.buffer_out + 2, &sa.sa_data, + std::min(sizeof(sa.sa_data), request.buffer_out_size - 2)); + return_value = ret; break; } case IOCTL_SO_GETPEERNAME: { - u32 fd = Memory::Read_U32(BufferIn); + u32 fd = Memory::Read_U32(request.buffer_in); sockaddr sa; socklen_t sa_len; @@ -801,28 +755,26 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) int ret = getpeername(fd, &sa, &sa_len); - if (BufferOutSize < 2 + sizeof(sa.sa_data)) + if (request.buffer_out_size < 2 + sizeof(sa.sa_data)) WARN_LOG(WII_IPC_NET, "IOCTL_SO_GETPEERNAME output buffer is too small. Truncating"); - if (BufferOutSize > 0) - Memory::Write_U8(BufferOutSize, BufferOut); - if (BufferOutSize > 1) - Memory::Write_U8(AF_INET, BufferOut + 1); - if (BufferOutSize > 2) - Memory::CopyToEmu(BufferOut + 2, &sa.sa_data, - std::min(sizeof(sa.sa_data), BufferOutSize - 2)); + if (request.buffer_out_size > 0) + Memory::Write_U8(request.buffer_out_size, request.buffer_out); + if (request.buffer_out_size > 1) + Memory::Write_U8(AF_INET, request.buffer_out + 1); + if (request.buffer_out_size > 2) + Memory::CopyToEmu(request.buffer_out + 2, &sa.sa_data, + std::min(sizeof(sa.sa_data), request.buffer_out_size - 2)); INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETPEERNAME(%x)", fd); - ReturnValue = ret; + return_value = ret; break; } case IOCTL_SO_GETHOSTID: { - INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTID " - "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); #ifdef _WIN32 DWORD forwardTableSize, ipTableSize, result; @@ -869,7 +821,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) { if (ipTable->table[i].dwIndex == ifIndex) { - ReturnValue = Common::swap32(ipTable->table[i].dwAddr); + return_value = Common::swap32(ipTable->table[i].dwAddr); break; } } @@ -877,14 +829,14 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) #endif // default placeholder, in case of failure - if (ReturnValue == 0) - ReturnValue = 192 << 24 | 168 << 16 | 1 << 8 | 150; + if (return_value == 0) + return_value = 192 << 24 | 168 << 16 | 1 << 8 | 150; break; } case IOCTL_SO_INETATON: { - std::string hostname = Memory::GetString(BufferIn); + std::string hostname = Memory::GetString(request.buffer_in); struct hostent* remoteHost = gethostbyname(hostname.c_str()); if (remoteHost == nullptr || remoteHost->h_addr_list == nullptr || @@ -892,42 +844,43 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) { INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETATON = -1 " "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: None", - hostname.c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize); - ReturnValue = 0; + hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size); + return_value = 0; } else { - Memory::Write_U32(Common::swap32(*(u32*)remoteHost->h_addr_list[0]), BufferOut); + Memory::Write_U32(Common::swap32(*(u32*)remoteHost->h_addr_list[0]), request.buffer_out); INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETATON = 0 " "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: %08X", - hostname.c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize, - Common::swap32(*(u32*)remoteHost->h_addr_list[0])); - ReturnValue = 1; + hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size, Common::swap32(*(u32*)remoteHost->h_addr_list[0])); + return_value = 1; } break; } case IOCTL_SO_INETPTON: { - std::string address = Memory::GetString(BufferIn); + std::string address = Memory::GetString(request.buffer_in); INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETPTON " "(Translating: %s)", address.c_str()); - ReturnValue = inet_pton(address.c_str(), Memory::GetPointer(BufferOut + 4)); + return_value = inet_pton(address.c_str(), Memory::GetPointer(request.buffer_out + 4)); break; } case IOCTL_SO_INETNTOP: { // u32 af = Memory::Read_U32(BufferIn); - // u32 validAddress = Memory::Read_U32(BufferIn + 4); - // u32 src = Memory::Read_U32(BufferIn + 8); + // u32 validAddress = Memory::Read_U32(request.buffer_in + 4); + // u32 src = Memory::Read_U32(request.buffer_in + 8); char ip_s[16]; - sprintf(ip_s, "%i.%i.%i.%i", Memory::Read_U8(BufferIn + 8), Memory::Read_U8(BufferIn + 8 + 1), - Memory::Read_U8(BufferIn + 8 + 2), Memory::Read_U8(BufferIn + 8 + 3)); + sprintf(ip_s, "%i.%i.%i.%i", Memory::Read_U8(request.buffer_in + 8), + Memory::Read_U8(request.buffer_in + 8 + 1), Memory::Read_U8(request.buffer_in + 8 + 2), + Memory::Read_U8(request.buffer_in + 8 + 3)); INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETNTOP %s", ip_s); - Memory::Memset(BufferOut, 0, BufferOutSize); - Memory::CopyToEmu(BufferOut, (u8*)ip_s, strlen(ip_s)); + Memory::CopyToEmu(request.buffer_out, (u8*)ip_s, strlen(ip_s)); break; } @@ -943,10 +896,10 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) {POLLWRBAND, 0x0010}, {POLLERR, 0x0020}, {POLLHUP, 0x0040}, {POLLNVAL, 0x0080}, }; - u32 unknown = Memory::Read_U32(BufferIn); - u32 timeout = Memory::Read_U32(BufferIn + 4); + u32 unknown = Memory::Read_U32(request.buffer_in); + u32 timeout = Memory::Read_U32(request.buffer_in + 4); - int nfds = BufferOutSize / 0xc; + int nfds = request.buffer_out_size / 0xc; if (nfds == 0) ERROR_LOG(WII_IPC_NET, "Hidden POLL"); @@ -954,9 +907,9 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) for (int i = 0; i < nfds; ++i) { - ufds[i].fd = Memory::Read_U32(BufferOut + 0xc * i); // fd - int events = Memory::Read_U32(BufferOut + 0xc * i + 4); // events - ufds[i].revents = Memory::Read_U32(BufferOut + 0xc * i + 8); // revents + ufds[i].fd = Memory::Read_U32(request.buffer_out + 0xc * i); // fd + int events = Memory::Read_U32(request.buffer_out + 0xc * i + 4); // events + ufds[i].revents = Memory::Read_U32(request.buffer_out + 0xc * i + 8); // revents // Translate Wii to native events int unhandled_events = events; @@ -993,33 +946,34 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) } // No need to change fd or events as they are input only. - // Memory::Write_U32(ufds[i].fd, BufferOut + 0xc*i); //fd - // Memory::Write_U32(events, BufferOut + 0xc*i + 4); //events - Memory::Write_U32(revents, BufferOut + 0xc * i + 8); // revents + // Memory::Write_U32(ufds[i].fd, request.buffer_out + 0xc*i); //fd + // Memory::Write_U32(events, request.buffer_out + 0xc*i + 4); //events + Memory::Write_U32(revents, request.buffer_out + 0xc * i + 8); // revents DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_POLL socket %d wevents %08X events %08X revents %08X", i, revents, ufds[i].events, ufds[i].revents); } - ReturnValue = ret; + return_value = ret; break; } case IOCTL_SO_GETHOSTBYNAME: { - if (BufferOutSize != 0x460) + if (request.buffer_out_size != 0x460) { ERROR_LOG(WII_IPC_NET, "Bad buffer size for IOCTL_SO_GETHOSTBYNAME"); - ReturnValue = -1; + return_value = -1; break; } - std::string hostname = Memory::GetString(BufferIn); + std::string hostname = Memory::GetString(request.buffer_in); hostent* remoteHost = gethostbyname(hostname.c_str()); INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTBYNAME " "Address: %s, BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - hostname.c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize); + hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size); if (remoteHost) { @@ -1036,8 +990,6 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) DEBUG_LOG(WII_IPC_NET, "addr%i:%s", i, ip_s.c_str()); } - Memory::Memset(BufferOut, 0, BufferOutSize); - // Host name; located immediately after struct static const u32 GETHOSTBYNAME_STRUCT_SIZE = 0x10; static const u32 GETHOSTBYNAME_IP_LIST_OFFSET = 0x110; @@ -1046,11 +998,12 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) if (name_length > (GETHOSTBYNAME_IP_LIST_OFFSET - GETHOSTBYNAME_STRUCT_SIZE)) { ERROR_LOG(WII_IPC_NET, "Hostname too long in IOCTL_SO_GETHOSTBYNAME"); - ReturnValue = -1; + return_value = -1; break; } - Memory::CopyToEmu(BufferOut + GETHOSTBYNAME_STRUCT_SIZE, remoteHost->h_name, name_length); - Memory::Write_U32(BufferOut + GETHOSTBYNAME_STRUCT_SIZE, BufferOut); + Memory::CopyToEmu(request.buffer_out + GETHOSTBYNAME_STRUCT_SIZE, remoteHost->h_name, + name_length); + Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_STRUCT_SIZE, request.buffer_out); // IP address list; located at offset 0x110. u32 num_ip_addr = 0; @@ -1062,7 +1015,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) num_ip_addr = std::min(num_ip_addr, GETHOSTBYNAME_MAX_ADDRESSES); for (u32 i = 0; i < num_ip_addr; ++i) { - u32 addr = BufferOut + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4; + u32 addr = request.buffer_out + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4; Memory::Write_U32_Swap(*(u32*)(remoteHost->h_addr_list[i]), addr); } @@ -1070,30 +1023,31 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) // This must be exact: PPC code to convert the struct hardcodes // this offset. static const u32 GETHOSTBYNAME_IP_PTR_LIST_OFFSET = 0x340; - Memory::Write_U32(BufferOut + GETHOSTBYNAME_IP_PTR_LIST_OFFSET, BufferOut + 12); + Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET, + request.buffer_out + 12); for (u32 i = 0; i < num_ip_addr; ++i) { - u32 addr = BufferOut + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + i * 4; - Memory::Write_U32(BufferOut + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4, addr); + u32 addr = request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + i * 4; + Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4, addr); } - Memory::Write_U32(0, BufferOut + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4); + Memory::Write_U32(0, request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4); // Aliases - empty. (Hardware doesn't return anything.) - Memory::Write_U32(BufferOut + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4, - BufferOut + 4); + Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4, + request.buffer_out + 4); // Returned struct must be ipv4. _assert_msg_(WII_IPC_NET, remoteHost->h_addrtype == AF_INET && remoteHost->h_length == sizeof(u32), "returned host info is not IPv4"); - Memory::Write_U16(AF_INET, BufferOut + 8); - Memory::Write_U16(sizeof(u32), BufferOut + 10); + Memory::Write_U16(AF_INET, request.buffer_out + 8); + Memory::Write_U16(sizeof(u32), request.buffer_out + 10); - ReturnValue = 0; + return_value = 0; } else { - ReturnValue = -1; + return_value = -1; } break; @@ -1101,89 +1055,39 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) case IOCTL_SO_ICMPCANCEL: ERROR_LOG(WII_IPC_NET, "IOCTL_SO_ICMPCANCEL"); - goto default_; default: - INFO_LOG(WII_IPC_NET, "0x%x " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Command, BufferIn, BufferInSize, BufferOut, BufferOutSize); - default_: - if (BufferInSize) - { - ERROR_LOG(WII_IPC_NET, "in addr %x size %x", BufferIn, BufferInSize); - ERROR_LOG(WII_IPC_NET, "\n%s", - ArrayToString(Memory::GetPointer(BufferIn), BufferInSize, 4).c_str()); - } - - if (BufferOutSize) - { - ERROR_LOG(WII_IPC_NET, "out addr %x size %x", BufferOut, BufferOutSize); - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_NET); } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - + request.SetReturnValue(return_value); return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(const IOSIOCtlVRequest& request) { - SIOCtlVBuffer CommandBuffer(CommandAddress); - - s32 ReturnValue = 0; - - u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0; - u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0; - - u32 _BufferOut = 0, _BufferOut2 = 0; - u32 BufferOutSize = 0; - - if (CommandBuffer.InBuffer.size() > 0) - { - _BufferIn = CommandBuffer.InBuffer.at(0).m_Address; - BufferInSize = CommandBuffer.InBuffer.at(0).m_Size; - } - if (CommandBuffer.InBuffer.size() > 1) - { - _BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address; - BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size; - } - if (CommandBuffer.InBuffer.size() > 2) - { - _BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address; - BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size; - } - - if (CommandBuffer.PayloadBuffer.size() > 0) - { - _BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address; - BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size; - } - if (CommandBuffer.PayloadBuffer.size() > 1) - { - _BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address; - } + s32 return_value = 0; u32 param = 0, param2 = 0, param3, param4, param5 = 0; - - switch (CommandBuffer.Parameter) + switch (request.request) { case IOCTLV_SO_GETINTERFACEOPT: { - param = Memory::Read_U32(_BufferIn); - param2 = Memory::Read_U32(_BufferIn + 4); - param3 = Memory::Read_U32(_BufferOut); - param4 = Memory::Read_U32(_BufferOut2); - if (BufferOutSize >= 8) + param = Memory::Read_U32(request.in_vectors[0].address); + param2 = Memory::Read_U32(request.in_vectors[0].address + 4); + param3 = Memory::Read_U32(request.io_vectors[0].address); + param4 = Memory::Read_U32(request.io_vectors[1].address); + if (request.io_vectors[0].size >= 8) { - param5 = Memory::Read_U32(_BufferOut + 4); + param5 = Memory::Read_U32(request.io_vectors[0].address + 4); } INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETINTERFACEOPT(%08X, %08X, %X, %X, %X) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i) ", - param, param2, param3, param4, param5, _BufferIn, BufferInSize, _BufferIn2, - BufferInSize2); + param, param2, param3, param4, param5, request.in_vectors[0].address, + request.in_vectors[0].size, + request.in_vectors.size() > 1 ? request.in_vectors[1].address : 0, + request.in_vectors.size() > 1 ? request.in_vectors[1].size : 0); switch (param2) { @@ -1257,33 +1161,33 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) if (address == 0) address = 0x08080808; - Memory::Write_U32(address, _BufferOut); - Memory::Write_U32(0x08080404, _BufferOut + 4); + Memory::Write_U32(address, request.io_vectors[0].address); + Memory::Write_U32(0x08080404, request.io_vectors[0].address + 4); break; } case 0x1003: // error - Memory::Write_U32(0, _BufferOut); + Memory::Write_U32(0, request.io_vectors[0].address); break; case 0x1004: // mac address u8 address[MAC_ADDRESS_SIZE]; GetMacAddress(address); - Memory::CopyToEmu(_BufferOut, address, sizeof(address)); + Memory::CopyToEmu(request.io_vectors[0].address, address, sizeof(address)); break; case 0x1005: // link state - Memory::Write_U32(1, _BufferOut); + Memory::Write_U32(1, request.io_vectors[0].address); break; case 0x4002: // ip addr number - Memory::Write_U32(1, _BufferOut); + Memory::Write_U32(1, request.io_vectors[0].address); break; case 0x4003: // ip addr table - Memory::Write_U32(0xC, _BufferOut2); - Memory::Write_U32(10 << 24 | 1 << 8 | 30, _BufferOut); - Memory::Write_U32(255 << 24 | 255 << 16 | 255 << 8 | 0, _BufferOut + 4); - Memory::Write_U32(10 << 24 | 0 << 16 | 255 << 8 | 255, _BufferOut + 8); + Memory::Write_U32(0xC, request.io_vectors[1].address); + Memory::Write_U32(10 << 24 | 1 << 8 | 30, request.io_vectors[0].address); + Memory::Write_U32(255 << 24 | 255 << 16 | 255 << 8 | 0, request.io_vectors[0].address + 4); + Memory::Write_U32(10 << 24 | 0 << 16 | 255 << 8 | 255, request.io_vectors[0].address + 8); break; default: @@ -1294,17 +1198,17 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) } case IOCTLV_SO_SENDTO: { - u32 fd = Memory::Read_U32(_BufferIn2); + u32 fd = Memory::Read_U32(request.in_vectors[1].address); WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(fd, CommandAddress, IOCTLV_SO_SENDTO); + sm.DoSock(fd, request, IOCTLV_SO_SENDTO); return GetNoReply(); break; } case IOCTLV_SO_RECVFROM: { - u32 fd = Memory::Read_U32(_BufferIn); + u32 fd = Memory::Read_U32(request.in_vectors[0].address); WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(fd, CommandAddress, IOCTLV_SO_RECVFROM); + sm.DoSock(fd, request, IOCTLV_SO_RECVFROM); return GetNoReply(); break; } @@ -1312,13 +1216,13 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) { addrinfo hints; - if (BufferInSize3) + if (request.in_vectors.size() > 2 && request.in_vectors[2].size) { - hints.ai_flags = Memory::Read_U32(_BufferIn3); - hints.ai_family = Memory::Read_U32(_BufferIn3 + 0x4); - hints.ai_socktype = Memory::Read_U32(_BufferIn3 + 0x8); - hints.ai_protocol = Memory::Read_U32(_BufferIn3 + 0xC); - hints.ai_addrlen = Memory::Read_U32(_BufferIn3 + 0x10); + hints.ai_flags = Memory::Read_U32(request.in_vectors[2].address); + hints.ai_family = Memory::Read_U32(request.in_vectors[2].address + 0x4); + hints.ai_socktype = Memory::Read_U32(request.in_vectors[2].address + 0x8); + hints.ai_protocol = Memory::Read_U32(request.in_vectors[2].address + 0xC); + hints.ai_addrlen = Memory::Read_U32(request.in_vectors[2].address + 0x10); hints.ai_canonname = nullptr; hints.ai_addr = nullptr; hints.ai_next = nullptr; @@ -1328,23 +1232,25 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) // So we have to do a bit of juggling here. std::string nodeNameStr; const char* pNodeName = nullptr; - if (BufferInSize > 0) + if (request.in_vectors.size() > 0 && request.in_vectors[0].size > 0) { - nodeNameStr = Memory::GetString(_BufferIn, BufferInSize); + nodeNameStr = Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size); pNodeName = nodeNameStr.c_str(); } std::string serviceNameStr; const char* pServiceName = nullptr; - if (BufferInSize2 > 0) + if (request.in_vectors.size() > 1 && request.in_vectors[1].size > 0) { - serviceNameStr = Memory::GetString(_BufferIn2, BufferInSize2); + serviceNameStr = Memory::GetString(request.in_vectors[1].address, request.in_vectors[1].size); pServiceName = serviceNameStr.c_str(); } addrinfo* result = nullptr; - int ret = getaddrinfo(pNodeName, pServiceName, BufferInSize3 ? &hints : nullptr, &result); - u32 addr = _BufferOut; + int ret = getaddrinfo( + pNodeName, pServiceName, + (request.in_vectors.size() > 2 && request.in_vectors[2].size) ? &hints : nullptr, &result); + u32 addr = request.io_vectors[0].address; u32 sockoffset = addr + 0x460; if (ret == 0) { @@ -1394,11 +1300,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) ret = -305; } - INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO " - "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - _BufferIn, BufferInSize, _BufferOut, BufferOutSize); - INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO: %s", Memory::GetString(_BufferIn).c_str()); - ReturnValue = ret; + request.Dump(GetDeviceName(), LogTypes::WII_IPC_NET, LogTypes::LINFO); + return_value = ret; break; } case IOCTLV_SO_ICMPPING: @@ -1411,19 +1314,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) u32 ip; } ip_info; - u32 fd = Memory::Read_U32(_BufferIn); - u32 num_ip = Memory::Read_U32(_BufferIn + 4); - u64 timeout = Memory::Read_U64(_BufferIn + 8); + u32 fd = Memory::Read_U32(request.in_vectors[0].address); + u32 num_ip = Memory::Read_U32(request.in_vectors[0].address + 4); + u64 timeout = Memory::Read_U64(request.in_vectors[0].address + 8); if (num_ip != 1) { INFO_LOG(WII_IPC_NET, "IOCTLV_SO_ICMPPING %i IPs", num_ip); } - ip_info.length = Memory::Read_U8(_BufferIn + 16); - ip_info.addr_family = Memory::Read_U8(_BufferIn + 17); - ip_info.icmp_id = Memory::Read_U16(_BufferIn + 18); - ip_info.ip = Memory::Read_U32(_BufferIn + 20); + ip_info.length = Memory::Read_U8(request.in_vectors[0].address + 16); + ip_info.addr_family = Memory::Read_U8(request.in_vectors[0].address + 17); + ip_info.icmp_id = Memory::Read_U16(request.in_vectors[0].address + 18); + ip_info.ip = Memory::Read_U32(request.in_vectors[0].address + 20); if (ip_info.length != 8 || ip_info.addr_family != AF_INET) { @@ -1443,8 +1346,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) memset(data, 0, sizeof(data)); s32 icmp_length = sizeof(data); - if (BufferInSize2 == sizeof(data)) - Memory::CopyFromEmu(data, _BufferIn2, BufferInSize2); + if (request.in_vectors.size() > 1 && request.in_vectors[1].size == sizeof(data)) + Memory::CopyFromEmu(data, request.in_vectors[1].address, request.in_vectors[1].size); else { // TODO sequence number is incremented either statically, by @@ -1461,31 +1364,14 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) } // TODO proper error codes - ReturnValue = 0; + return_value = 0; break; } default: - INFO_LOG(WII_IPC_NET, "0x%x (BufferIn: (%08x, %i), BufferIn2: (%08x, %i)", - CommandBuffer.Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2); - for (u32 i = 0; i < CommandBuffer.NumberInBuffer; ++i) - { - ERROR_LOG(WII_IPC_NET, "in %i addr %x size %x", i, CommandBuffer.InBuffer.at(i).m_Address, - CommandBuffer.InBuffer.at(i).m_Size); - ERROR_LOG(WII_IPC_NET, "\n%s", - ArrayToString(Memory::GetPointer(CommandBuffer.InBuffer.at(i).m_Address), - CommandBuffer.InBuffer.at(i).m_Size, 4) - .c_str()); - } - for (u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; ++i) - { - ERROR_LOG(WII_IPC_NET, "out %i addr %x size %x", i, - CommandBuffer.PayloadBuffer.at(i).m_Address, - CommandBuffer.PayloadBuffer.at(i).m_Size); - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_NET); } - Memory::Write_U32(ReturnValue, CommandAddress + 4); + request.SetReturnValue(return_value); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h index 3e02819351..d2f9d5ca23 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h @@ -30,7 +30,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_kd_request(); - IPCCommandResult IOCtl(u32 _CommandAddress) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: enum @@ -86,35 +86,31 @@ public: } virtual ~CWII_IPC_HLE_Device_net_kd_time() {} - IPCCommandResult IOCtl(u32 _CommandAddress) override + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override { - u32 Parameter = Memory::Read_U32(_CommandAddress + 0x0C); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - - u32 result = 0; + s32 result = 0; u32 common_result = 0; // TODO Writes stuff to /shared2/nwc24/misc.bin // u32 update_misc = 0; - switch (Parameter) + switch (request.request) { case IOCTL_NW24_GET_UNIVERSAL_TIME: - Memory::Write_U64(GetAdjustedUTC(), BufferOut + 4); + Memory::Write_U64(GetAdjustedUTC(), request.buffer_out + 4); break; case IOCTL_NW24_SET_UNIVERSAL_TIME: - SetAdjustedUTC(Memory::Read_U64(BufferIn)); - // update_misc = Memory::Read_U32(BufferIn + 8); + SetAdjustedUTC(Memory::Read_U64(request.buffer_in)); + // update_misc = Memory::Read_U32(request.buffer_in + 8); break; case IOCTL_NW24_SET_RTC_COUNTER: - rtc = Memory::Read_U32(BufferIn); - // update_misc = Memory::Read_U32(BufferIn + 4); + rtc = Memory::Read_U32(request.buffer_in); + // update_misc = Memory::Read_U32(request.buffer_in + 4); break; case IOCTL_NW24_GET_TIME_DIFF: - Memory::Write_U64(GetAdjustedUTC() - rtc, BufferOut + 4); + Memory::Write_U64(GetAdjustedUTC() - rtc, request.buffer_out + 4); break; case IOCTL_NW24_UNIMPLEMENTED: @@ -122,13 +118,13 @@ public: break; default: - ERROR_LOG(WII_IPC_NET, "%s - unknown IOCtl: %x", GetDeviceName().c_str(), Parameter); + ERROR_LOG(WII_IPC_NET, "%s - unknown IOCtl: %x", GetDeviceName().c_str(), request.request); break; } // write return values - Memory::Write_U32(common_result, BufferOut); - Memory::Write_U32(result, _CommandAddress + 4); + Memory::Write_U32(common_result, request.buffer_out); + request.SetReturnValue(result); return GetDefaultReply(); } @@ -207,8 +203,8 @@ public: virtual ~CWII_IPC_HLE_Device_net_ip_top(); - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void Update() override; @@ -227,7 +223,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_ncd_manage(); - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; private: enum @@ -253,7 +249,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_wd_command(); - IPCCommandResult IOCtlV(u32 CommandAddress) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; private: enum diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp index ab77ef1596..1ecdb5ee60 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp @@ -75,72 +75,62 @@ int CWII_IPC_HLE_Device_net_ssl::GetSSLFreeID() const return 0; } -IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtl(const IOSIOCtlRequest& request) { - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - u32 Command = Memory::Read_U32(_CommandAddress + 0x0C); - - INFO_LOG(WII_IPC_SSL, "%s unknown %i " - "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - GetDeviceName().c_str(), Command, BufferIn, BufferInSize, BufferOut, BufferOutSize); - Memory::Write_U32(0, _CommandAddress + 0x4); + request.Log(GetDeviceName(), LogTypes::WII_IPC_SSL, LogTypes::LINFO); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(const IOSIOCtlVRequest& request) { - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0; + u32 BufferIn = 0, BufferIn2 = 0, BufferIn3 = 0; u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0; u32 BufferOut = 0, BufferOut2 = 0, BufferOut3 = 0; u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0; - if (CommandBuffer.InBuffer.size() > 0) + if (request.in_vectors.size() > 0) { - _BufferIn = CommandBuffer.InBuffer.at(0).m_Address; - BufferInSize = CommandBuffer.InBuffer.at(0).m_Size; + BufferIn = request.in_vectors.at(0).address; + BufferInSize = request.in_vectors.at(0).size; } - if (CommandBuffer.InBuffer.size() > 1) + if (request.in_vectors.size() > 1) { - _BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address; - BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size; + BufferIn2 = request.in_vectors.at(1).address; + BufferInSize2 = request.in_vectors.at(1).size; } - if (CommandBuffer.InBuffer.size() > 2) + if (request.in_vectors.size() > 2) { - _BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address; - BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size; + BufferIn3 = request.in_vectors.at(2).address; + BufferInSize3 = request.in_vectors.at(2).size; } - if (CommandBuffer.PayloadBuffer.size() > 0) + if (request.io_vectors.size() > 0) { - BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address; - BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size; + BufferOut = request.io_vectors.at(0).address; + BufferOutSize = request.io_vectors.at(0).size; } - if (CommandBuffer.PayloadBuffer.size() > 1) + if (request.io_vectors.size() > 1) { - BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address; - BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size; + BufferOut2 = request.io_vectors.at(1).address; + BufferOutSize2 = request.io_vectors.at(1).size; } - if (CommandBuffer.PayloadBuffer.size() > 2) + if (request.io_vectors.size() > 2) { - BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address; - BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size; + BufferOut3 = request.io_vectors.at(2).address; + BufferOutSize3 = request.io_vectors.at(2).size; } // I don't trust SSL to be deterministic, and this is never going to sync // as such (as opposed to forwarding IPC results or whatever), so - if (Core::g_want_determinism) { - Memory::Write_U32(-1, _CommandAddress + 0x4); + request.SetReturnValue(-1); return GetDefaultReply(); } - switch (CommandBuffer.Parameter) + switch (request.request) { case IOCTLV_NET_SSL_NEW: { @@ -187,20 +177,20 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) mbedtls_ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str()); ssl->active = true; - Memory::Write_U32(freeSSL, _BufferIn); + Memory::Write_U32(freeSSL, BufferIn); } else { _SSL_NEW_ERROR: - Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); + Memory::Write_U32(SSL_ERR_FAILED, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_NEW (%d, %s) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - verifyOption, hostname.c_str(), _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, - _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, + verifyOption, hostname.c_str(), BufferIn, BufferInSize, BufferIn2, BufferInSize2, + BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } @@ -226,18 +216,18 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) ssl->active = false; - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SHUTDOWN " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_SETROOTCA: @@ -246,8 +236,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) @@ -264,19 +254,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (ret) { - Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); + Memory::Write_U32(SSL_ERR_FAILED, BufferIn); } else { mbedtls_ssl_conf_ca_chain(&ssl->config, &ssl->cacert, nullptr); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA = %d", ret); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } break; } @@ -286,8 +276,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) @@ -302,19 +292,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) { mbedtls_x509_crt_free(&ssl->clicert); mbedtls_pk_free(&ssl->pk); - Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); + Memory::Write_U32(SSL_ERR_FAILED, BufferIn); } else { mbedtls_ssl_conf_own_cert(&ssl->config, &ssl->clicert, &ssl->pk); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = (%d, %d)", ret, pk_ret); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID); } break; @@ -325,8 +315,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) @@ -336,11 +326,11 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) mbedtls_pk_free(&ssl->pk); mbedtls_ssl_conf_own_cert(&ssl->config, nullptr, nullptr); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID); } break; @@ -357,25 +347,25 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (ret) { mbedtls_x509_crt_free(&ssl->clicert); - Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); + Memory::Write_U32(SSL_ERR_FAILED, BufferIn); } else { mbedtls_ssl_conf_ca_chain(&ssl->config, &ssl->cacert, nullptr); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA = %d", ret); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_CONNECT: @@ -388,18 +378,18 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) ssl->sockfd = Memory::Read_U32(BufferOut2); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", ssl->sockfd); mbedtls_ssl_set_bio(&ssl->ctx, &ssl->sockfd, mbedtls_net_send, mbedtls_net_recv, nullptr); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_DOHANDSHAKE: @@ -408,12 +398,12 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (SSLID_VALID(sslID)) { WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_DOHANDSHAKE); + sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_DOHANDSHAKE); return GetNoReply(); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } break; } @@ -423,19 +413,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (SSLID_VALID(sslID)) { WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_WRITE); + sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_WRITE); return GetNoReply(); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_WRITE " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); INFO_LOG(WII_IPC_SSL, "%s", Memory::GetString(BufferOut2).c_str()); break; } @@ -446,19 +436,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (SSLID_VALID(sslID)) { WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_READ); + sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_READ); return GetNoReply(); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ(%d)" "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - ret, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, + ret, BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } @@ -467,18 +457,18 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCADEFAULT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT: @@ -487,33 +477,25 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } break; } default: - ERROR_LOG(WII_IPC_SSL, "%i " - "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " - "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " - "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - CommandBuffer.Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, - _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, - BufferOut3, BufferOutSize3); - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_SSL); } // SSL return codes are written to BufferIn - Memory::Write_U32(0, _CommandAddress + 4); - + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h index b8ec088776..cdb689163b 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h @@ -87,8 +87,8 @@ public: virtual ~CWII_IPC_HLE_Device_net_ssl(); - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; int GetSSLFreeID() const; diff --git a/Source/Core/Core/IPC_HLE/WII_Socket.cpp b/Source/Core/Core/IPC_HLE/WII_Socket.cpp index 167d30d558..04e5abc987 100644 --- a/Source/Core/Core/IPC_HLE/WII_Socket.cpp +++ b/Source/Core/Core/IPC_HLE/WII_Socket.cpp @@ -187,28 +187,23 @@ void WiiSocket::Update(bool read, bool write, bool except) { s32 ReturnValue = 0; bool forceNonBlock = false; - IPCCommandType ct = static_cast(Memory::Read_U32(it->_CommandAddress)); + IPCCommandType ct = it->request.command; if (!it->is_ssl && ct == IPC_CMD_IOCTL) { - u32 BufferIn = Memory::Read_U32(it->_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(it->_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(it->_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(it->_CommandAddress + 0x1C); - + IOSIOCtlRequest ioctl{it->request.address}; switch (it->net_type) { case IOCTL_SO_FCNTL: { - u32 cmd = Memory::Read_U32(BufferIn + 4); - u32 arg = Memory::Read_U32(BufferIn + 8); + u32 cmd = Memory::Read_U32(ioctl.buffer_in + 4); + u32 arg = Memory::Read_U32(ioctl.buffer_in + 8); ReturnValue = FCntl(cmd, arg); break; } case IOCTL_SO_BIND: { - // u32 has_addr = Memory::Read_U32(BufferIn + 0x04); sockaddr_in local_name; - WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferIn + 0x08); + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(ioctl.buffer_in + 8); WiiSockMan::Convert(*wii_name, local_name); int ret = bind(fd, (sockaddr*)&local_name, sizeof(local_name)); @@ -220,9 +215,8 @@ void WiiSocket::Update(bool read, bool write, bool except) } case IOCTL_SO_CONNECT: { - // u32 has_addr = Memory::Read_U32(BufferIn + 0x04); sockaddr_in local_name; - WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferIn + 0x08); + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(ioctl.buffer_in + 8); WiiSockMan::Convert(*wii_name, local_name); int ret = connect(fd, (sockaddr*)&local_name, sizeof(local_name)); @@ -234,10 +228,10 @@ void WiiSocket::Update(bool read, bool write, bool except) } case IOCTL_SO_ACCEPT: { - if (BufferOutSize > 0) + if (ioctl.buffer_out_size > 0) { sockaddr_in local_name; - WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferOut); + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(ioctl.buffer_out); WiiSockMan::Convert(*wii_name, local_name); socklen_t addrlen = sizeof(sockaddr_in); @@ -254,10 +248,7 @@ void WiiSocket::Update(bool read, bool write, bool except) WiiSockMan::GetInstance().AddSocket(ReturnValue); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_ACCEPT " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); - + ioctl.Log("IOCTL_SO_ACCEPT", LogTypes::WII_IPC_NET); break; } default: @@ -275,34 +266,34 @@ void WiiSocket::Update(bool read, bool write, bool except) } else if (ct == IPC_CMD_IOCTLV) { - SIOCtlVBuffer CommandBuffer(it->_CommandAddress); + IOSIOCtlVRequest ioctlv{it->request.address}; u32 BufferIn = 0, BufferIn2 = 0; u32 BufferInSize = 0, BufferInSize2 = 0; u32 BufferOut = 0, BufferOut2 = 0; u32 BufferOutSize = 0, BufferOutSize2 = 0; - if (CommandBuffer.InBuffer.size() > 0) + if (ioctlv.in_vectors.size() > 0) { - BufferIn = CommandBuffer.InBuffer.at(0).m_Address; - BufferInSize = CommandBuffer.InBuffer.at(0).m_Size; + BufferIn = ioctlv.in_vectors.at(0).address; + BufferInSize = ioctlv.in_vectors.at(0).size; } - if (CommandBuffer.PayloadBuffer.size() > 0) + if (ioctlv.io_vectors.size() > 0) { - BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address; - BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size; + BufferOut = ioctlv.io_vectors.at(0).address; + BufferOutSize = ioctlv.io_vectors.at(0).size; } - if (CommandBuffer.PayloadBuffer.size() > 1) + if (ioctlv.io_vectors.size() > 1) { - BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address; - BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size; + BufferOut2 = ioctlv.io_vectors.at(1).address; + BufferOutSize2 = ioctlv.io_vectors.at(1).size; } - if (CommandBuffer.InBuffer.size() > 1) + if (ioctlv.in_vectors.size() > 1) { - BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address; - BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size; + BufferIn2 = ioctlv.in_vectors.at(1).address; + BufferInSize2 = ioctlv.in_vectors.at(1).size; } if (it->is_ssl) @@ -576,8 +567,8 @@ void WiiSocket::Update(bool read, bool write, bool except) "IOCTL(V) Sock: %08x ioctl/v: %d returned: %d nonBlock: %d forceNonBlock: %d", fd, it->is_ssl ? (int)it->ssl_type : (int)it->net_type, ReturnValue, nonBlock, forceNonBlock); - Memory::Write_U32(ReturnValue, it->_CommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(it->_CommandAddress); + it->request.SetReturnValue(ReturnValue); + WII_IPC_HLE_Interface::EnqueueReply(it->request); it = pending_sockops.erase(it); } else @@ -587,16 +578,16 @@ void WiiSocket::Update(bool read, bool write, bool except) } } -void WiiSocket::DoSock(u32 _CommandAddress, NET_IOCTL type) +void WiiSocket::DoSock(IOSRequest request, NET_IOCTL type) { - sockop so = {_CommandAddress, false}; + sockop so = {request, false}; so.net_type = type; pending_sockops.push_back(so); } -void WiiSocket::DoSock(u32 _CommandAddress, SSL_IOCTL type) +void WiiSocket::DoSock(IOSRequest request, SSL_IOCTL type) { - sockop so = {_CommandAddress, true}; + sockop so = {request, true}; so.ssl_type = type; pending_sockops.push_back(so); } diff --git a/Source/Core/Core/IPC_HLE/WII_Socket.h b/Source/Core/Core/IPC_HLE/WII_Socket.h index 93076576a1..b0c50d3df3 100644 --- a/Source/Core/Core/IPC_HLE/WII_Socket.h +++ b/Source/Core/Core/IPC_HLE/WII_Socket.h @@ -172,7 +172,7 @@ class WiiSocket { struct sockop { - u32 _CommandAddress; + IOSRequest request; bool is_ssl; union { @@ -191,8 +191,8 @@ private: s32 CloseFd(); s32 FCntl(u32 cmd, u32 arg); - void DoSock(u32 _CommandAddress, NET_IOCTL type); - void DoSock(u32 _CommandAddress, SSL_IOCTL type); + void DoSock(IOSRequest request, NET_IOCTL type); + void DoSock(IOSRequest request, SSL_IOCTL type); void Update(bool read, bool write, bool except); bool IsValid() const { return fd >= 0; } public: @@ -223,19 +223,19 @@ public: void SetLastNetError(s32 error) { errno_last = error; } void Clean() { WiiSockets.clear(); } template - void DoSock(s32 sock, u32 CommandAddress, T type) + void DoSock(s32 sock, const IOSRequest& request, T type) { auto socket_entry = WiiSockets.find(sock); if (socket_entry == WiiSockets.end()) { - ERROR_LOG(WII_IPC_NET, "DoSock: Error, fd not found (%08x, %08X, %08X)", sock, CommandAddress, - type); - Memory::Write_U32(-SO_EBADF, CommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(CommandAddress); + ERROR_LOG(WII_IPC_NET, "DoSock: Error, fd not found (%08x, %08X, %08X)", sock, + request.address, type); + request.SetReturnValue(-SO_EBADF); + WII_IPC_HLE_Interface::EnqueueReply(request); } else { - socket_entry->second.DoSock(CommandAddress, type); + socket_entry->second.DoSock(request, type); } } From 469a31db32b0466c5ffc0f4770b46bf9dc0b256a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:47:42 +0100 Subject: [PATCH 09/16] IOS HLE: Deduplicate request code in sdio_slot0 --- .../IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp | 165 +++++++----------- .../IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h | 27 ++- 2 files changed, 80 insertions(+), 112 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp index 0a7bcf82cc..ad1b5a06e8 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp @@ -38,15 +38,16 @@ void CWII_IPC_HLE_Device_sdio_slot0::DoState(PointerWrap& p) void CWII_IPC_HLE_Device_sdio_slot0::EventNotify() { + if (!m_event) + return; // Accessing SConfig variables like this isn't really threadsafe, // but this is how it's done all over the place... - if ((SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_INSERT) || - (!SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_REMOVE)) + if ((SConfig::GetInstance().m_WiiSDCard && m_event->type == EVENT_INSERT) || + (!SConfig::GetInstance().m_WiiSDCard && m_event->type == EVENT_REMOVE)) { - Memory::Write_U32(m_event.type, m_event.addr + 4); - WII_IPC_HLE_Interface::EnqueueReply(m_event.addr); - m_event.addr = 0; - m_event.type = EVENT_NONE; + m_event->request.SetReturnValue(m_event->type); + WII_IPC_HLE_Interface::EnqueueReply(m_event->request); + m_event.reset(); } } @@ -70,50 +71,35 @@ void CWII_IPC_HLE_Device_sdio_slot0::OpenInternal() } } -IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode) +IOSReturnCode CWII_IPC_HLE_Device_sdio_slot0::Open(const IOSOpenRequest& request) { - INFO_LOG(WII_IPC_SD, "Open"); - OpenInternal(); - m_registers.fill(0); + m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::Close(u32 _CommandAddress, bool _bForce) +void CWII_IPC_HLE_Device_sdio_slot0::Close() { - INFO_LOG(WII_IPC_SD, "Close"); - m_Card.Close(); m_BlockLength = 0; m_BusWidth = 0; m_is_active = false; - return GetDefaultReply(); } // The front SD slot -IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(const IOSIOCtlRequest& request) { - u32 Cmd = Memory::Read_U32(_CommandAddress + 0xC); - - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - // As a safety precaution we fill the out buffer with zeros to avoid - // returning nonsense values - Memory::Memset(BufferOut, 0, BufferOutSize); - - u32 ReturnValue = 0; - switch (Cmd) + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTL_WRITEHCR: { - u32 reg = Memory::Read_U32(BufferIn); - u32 val = Memory::Read_U32(BufferIn + 16); + u32 reg = Memory::Read_U32(request.buffer_in); + u32 val = Memory::Read_U32(request.buffer_in + 16); INFO_LOG(WII_IPC_SD, "IOCTL_WRITEHCR 0x%08x - 0x%08x", reg, val); @@ -143,7 +129,7 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) case IOCTL_READHCR: { - u32 reg = Memory::Read_U32(BufferIn); + u32 reg = Memory::Read_U32(request.buffer_in); if (reg >= m_registers.size()) { @@ -155,7 +141,7 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) INFO_LOG(WII_IPC_SD, "IOCTL_READHCR 0x%08x - 0x%08x", reg, val); // Just reading the register - Memory::Write_U32(val, BufferOut); + Memory::Write_U32(val, request.buffer_out); } break; @@ -164,7 +150,7 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) if (m_Card) m_Status |= CARD_INITIALIZED; // Returns 16bit RCA and 16bit 0s (meaning success) - Memory::Write_U32(0x9f620000, BufferOut); + Memory::Write_U32(0x9f620000, request.buffer_out); break; case IOCTL_SETCLK: @@ -172,15 +158,17 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) INFO_LOG(WII_IPC_SD, "IOCTL_SETCLK"); // libogc only sets it to 1 and makes sure the return isn't negative... // one half of the sdclk divisor: a power of two or zero. - u32 clock = Memory::Read_U32(BufferIn); + u32 clock = Memory::Read_U32(request.buffer_in); if (clock != 1) INFO_LOG(WII_IPC_SD, "Setting to %i, interesting", clock); } break; case IOCTL_SENDCMD: - INFO_LOG(WII_IPC_SD, "IOCTL_SENDCMD %x IPC:%08x", Memory::Read_U32(BufferIn), _CommandAddress); - ReturnValue = ExecuteCommand(BufferIn, BufferInSize, 0, 0, BufferOut, BufferOutSize); + INFO_LOG(WII_IPC_SD, "IOCTL_SENDCMD %x IPC:%08x", Memory::Read_U32(request.buffer_in), + request.address); + return_value = ExecuteCommand(request, request.buffer_in, request.buffer_in_size, 0, 0, + request.buffer_out, request.buffer_out_size); break; case IOCTL_GETSTATUS: @@ -191,81 +179,53 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) INFO_LOG(WII_IPC_SD, "IOCTL_GETSTATUS. Replying that SD card is %s%s", (m_Status & CARD_INSERTED) ? "inserted" : "not present", (m_Status & CARD_INITIALIZED) ? " and initialized" : ""); - Memory::Write_U32(m_Status, BufferOut); + Memory::Write_U32(m_Status, request.buffer_out); break; case IOCTL_GETOCR: INFO_LOG(WII_IPC_SD, "IOCTL_GETOCR"); - Memory::Write_U32(0x80ff8000, BufferOut); + Memory::Write_U32(0x80ff8000, request.buffer_out); break; default: - ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtl command (0x%08x)", Cmd); + ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtl command (0x%08x)", request.request); break; } - if (ReturnValue == RET_EVENT_REGISTER) + if (return_value == RET_EVENT_REGISTER) { - // async - m_event.addr = _CommandAddress; - Memory::Write_U32(0, _CommandAddress + 0x4); // Check if the condition is already true EventNotify(); return GetNoReply(); } - else if (ReturnValue == RET_EVENT_UNREGISTER) - { - // release returns 0 - // unknown sd int - // technically we do it out of order, oh well - Memory::Write_U32(EVENT_INVALID, m_event.addr + 4); - WII_IPC_HLE_Interface::EnqueueReply(m_event.addr); - m_event.addr = 0; - m_event.type = EVENT_NONE; - Memory::Write_U32(0, _CommandAddress + 0x4); - return GetDefaultReply(); - } - else - { - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - return GetDefaultReply(); - } -} - -IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(u32 _CommandAddress) -{ - // PPC sending commands - - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - // Prepare the out buffer(s) with zeros as a safety precaution - // to avoid returning bad values - for (const auto& buffer : CommandBuffer.PayloadBuffer) - Memory::Memset(buffer.m_Address, 0, buffer.m_Size); - - u32 ReturnValue = 0; - switch (CommandBuffer.Parameter) - { - case IOCTLV_SENDCMD: - DEBUG_LOG(WII_IPC_SD, "IOCTLV_SENDCMD 0x%08x", - Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address)); - ReturnValue = ExecuteCommand( - CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size, - CommandBuffer.InBuffer[1].m_Address, CommandBuffer.InBuffer[1].m_Size, - CommandBuffer.PayloadBuffer[0].m_Address, CommandBuffer.PayloadBuffer[0].m_Size); - break; - - default: - ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtlV command 0x%08x", CommandBuffer.Parameter); - break; - } - - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - + request.SetReturnValue(return_value); return GetDefaultReply(); } -u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 _rwBuffer, +IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(const IOSIOCtlVRequest& request) +{ + s32 return_value = IPC_SUCCESS; + switch (request.request) + { + case IOCTLV_SENDCMD: + DEBUG_LOG(WII_IPC_SD, "IOCTLV_SENDCMD 0x%08x", Memory::Read_U32(request.in_vectors[0].address)); + Memory::Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size); + return_value = + ExecuteCommand(request, request.in_vectors[0].address, request.in_vectors[0].size, + request.in_vectors[1].address, request.in_vectors[1].size, + request.io_vectors[0].address, request.io_vectors[0].size); + break; + + default: + ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtlV command 0x%08x", request.request); + } + + request.SetReturnValue(return_value); + return GetDefaultReply(); +} + +u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(const IOSRequest& request, u32 _BufferIn, + u32 _BufferInSize, u32 _rwBuffer, u32 _rwBufferSize, u32 _BufferOut, u32 _BufferOutSize) { @@ -421,15 +381,24 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS case EVENT_REGISTER: // async INFO_LOG(WII_IPC_SD, "Register event %x", req.arg); - m_event.type = (EventType)req.arg; + m_event = std::make_unique(static_cast(req.arg), request); ret = RET_EVENT_REGISTER; break; - case EVENT_UNREGISTER: // synchronous + // Used to cancel an event that was already registered. + case EVENT_UNREGISTER: + { INFO_LOG(WII_IPC_SD, "Unregister event %x", req.arg); - m_event.type = (EventType)req.arg; - ret = RET_EVENT_UNREGISTER; + if (!m_event) + return IPC_EINVAL; + // release returns 0 + // unknown sd int + // technically we do it out of order, oh well + m_event->request.SetReturnValue(EVENT_INVALID); + WII_IPC_HLE_Interface::EnqueueReply(m_event->request); + m_event.reset(); break; + } default: ERROR_LOG(WII_IPC_SD, "Unknown SD command 0x%08x", req.command); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h index 7d51547c0c..d8d409322c 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h @@ -23,11 +23,10 @@ public: void DoState(PointerWrap& p) override; - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void EventNotify(); @@ -63,7 +62,6 @@ private: RET_OK, RET_FAIL, RET_EVENT_REGISTER, // internal state only - not actually returned - RET_EVENT_UNREGISTER }; // Status @@ -100,9 +98,8 @@ private: enum EventType { - EVENT_NONE = 0, - EVENT_INSERT, - EVENT_REMOVE, + EVENT_INSERT = 1, + EVENT_REMOVE = 2, // from unregister, i think it is just meant to be invalid EVENT_INVALID = 0xc210000 }; @@ -110,9 +107,11 @@ private: // TODO do we need more than one? struct Event { - EventType type = EVENT_NONE; - u32 addr = 0; - } m_event; + Event(EventType type_, IOSRequest request_) : type(type_), request(request_) {} + EventType type; + IOSRequest request; + }; + std::unique_ptr m_event; u32 m_Status = CARD_NOT_EXIST; u32 m_BlockLength = 0; @@ -122,7 +121,7 @@ private: File::IOFile m_Card; - u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize, u32 BufferIn2, u32 BufferInSize2, - u32 _BufferOut, u32 BufferOutSize); + u32 ExecuteCommand(const IOSRequest& request, u32 BufferIn, u32 BufferInSize, u32 BufferIn2, + u32 BufferInSize2, u32 _BufferOut, u32 BufferOutSize); void OpenInternal(); }; From 5a5985f6746ba9f5f50a9d1c9b1577c947bd6217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:47:54 +0100 Subject: [PATCH 10/16] IOS HLE: Deduplicate request code in DI --- .../Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp | 83 +++++++------------ .../Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h | 6 +- 2 files changed, 33 insertions(+), 56 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp index 9e4276c792..84f59a9095 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp @@ -32,7 +32,7 @@ void CWII_IPC_HLE_Device_di::DoState(PointerWrap& p) p.Do(m_commands_to_execute); } -IPCCommandResult CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_di::IOCtl(const IOSIOCtlRequest& request) { // DI IOCtls are handled in a special way by Dolphin // compared to other WII_IPC_HLE functions. @@ -42,40 +42,25 @@ IPCCommandResult CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress) // are queued until DVDInterface is ready to handle them. bool ready_to_execute = m_commands_to_execute.empty(); - m_commands_to_execute.push_back(_CommandAddress); + m_commands_to_execute.push_back(request.address); if (ready_to_execute) - StartIOCtl(_CommandAddress); + StartIOCtl(request); // DVDInterface handles the timing and we handle the reply, // so WII_IPC_HLE shouldn't handle anything. return GetNoReply(); } -void CWII_IPC_HLE_Device_di::StartIOCtl(u32 command_address) +void CWII_IPC_HLE_Device_di::StartIOCtl(const IOSIOCtlRequest& request) { - u32 BufferIn = Memory::Read_U32(command_address + 0x10); - u32 BufferInSize = Memory::Read_U32(command_address + 0x14); - u32 BufferOut = Memory::Read_U32(command_address + 0x18); - u32 BufferOutSize = Memory::Read_U32(command_address + 0x1C); - - u32 command_0 = Memory::Read_U32(BufferIn); - u32 command_1 = Memory::Read_U32(BufferIn + 4); - u32 command_2 = Memory::Read_U32(BufferIn + 8); - - DEBUG_LOG(WII_IPC_DVD, "IOCtl Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)", - command_0, BufferIn, BufferInSize, BufferOut, BufferOutSize); - - // TATSUNOKO VS CAPCOM: Gets here with BufferOut == 0!!! - if (BufferOut != 0) - { - // Set out buffer to zeroes as a safety precaution - // to avoid answering nonsense values - Memory::Memset(BufferOut, 0, BufferOutSize); - } + const u32 command_0 = Memory::Read_U32(request.buffer_in); + const u32 command_1 = Memory::Read_U32(request.buffer_in + 4); + const u32 command_2 = Memory::Read_U32(request.buffer_in + 8); // DVDInterface's ExecuteCommand handles most of the work. // The IOCtl callback is used to generate a reply afterwards. - DVDInterface::ExecuteCommand(command_0, command_1, command_2, BufferOut, BufferOutSize, true); + DVDInterface::ExecuteCommand(command_0, command_1, command_2, request.buffer_out, + request.buffer_out_size, true); } void CWII_IPC_HLE_Device_di::FinishIOCtl(DVDInterface::DIInterruptType interrupt_type) @@ -89,58 +74,50 @@ void CWII_IPC_HLE_Device_di::FinishIOCtl(DVDInterface::DIInterruptType interrupt // This command has been executed, so it's removed from the queue u32 command_address = m_commands_to_execute.front(); m_commands_to_execute.pop_front(); + IOSIOCtlRequest request{command_address}; - // The DI interrupt type is used as a return value - Memory::Write_U32(interrupt_type, command_address + 4); - WII_IPC_HLE_Interface::EnqueueReply(command_address); + request.SetReturnValue(interrupt_type); + WII_IPC_HLE_Interface::EnqueueReply(request); // DVDInterface is now ready to execute another command, // so we start executing a command from the queue if there is one if (!m_commands_to_execute.empty()) - StartIOCtl(m_commands_to_execute.front()); + { + IOSIOCtlRequest next_request{m_commands_to_execute.front()}; + StartIOCtl(next_request); + } } -IPCCommandResult CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_di::IOCtlV(const IOSIOCtlVRequest& request) { - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - // Prepare the out buffer(s) with zeros as a safety precaution - // to avoid returning bad values - for (const auto& buffer : CommandBuffer.PayloadBuffer) - Memory::Memset(buffer.m_Address, 0, buffer.m_Size); - - u32 ReturnValue = 0; - switch (CommandBuffer.Parameter) + for (const auto& vector : request.io_vectors) + Memory::Memset(vector.address, 0, vector.size); + s32 return_value = IPC_SUCCESS; + switch (request.request) { case DVDInterface::DVDLowOpenPartition: { - _dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[1].m_Address == 0, + _dbg_assert_msg_(WII_IPC_DVD, request.in_vectors[1].address == 0, "DVDLowOpenPartition with ticket"); - _dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[2].m_Address == 0, + _dbg_assert_msg_(WII_IPC_DVD, request.in_vectors[2].address == 0, "DVDLowOpenPartition with cert chain"); - u64 const partition_offset = - ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2); + u64 const partition_offset = ((u64)Memory::Read_U32(request.in_vectors[0].address + 4) << 2); DVDInterface::ChangePartition(partition_offset); INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: partition_offset 0x%016" PRIx64, partition_offset); // Read TMD to the buffer std::vector tmd_buffer = DVDInterface::GetVolume().GetTMD(); - Memory::CopyToEmu(CommandBuffer.PayloadBuffer[0].m_Address, tmd_buffer.data(), - tmd_buffer.size()); + Memory::CopyToEmu(request.io_vectors[0].address, tmd_buffer.data(), tmd_buffer.size()); WII_IPC_HLE_Interface::ES_DIVerify(tmd_buffer); - ReturnValue = 1; - } - break; - - default: - ERROR_LOG(WII_IPC_DVD, "IOCtlV: %i", CommandBuffer.Parameter); - _dbg_assert_msg_(WII_IPC_DVD, 0, "IOCtlV: %i", CommandBuffer.Parameter); + return_value = 1; break; } - - Memory::Write_U32(ReturnValue, _CommandAddress + 4); + default: + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_DVD); + } + request.SetReturnValue(return_value); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h index f7af22998b..2e72c59c68 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h @@ -27,13 +27,13 @@ public: void DoState(PointerWrap& p) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void FinishIOCtl(DVDInterface::DIInterruptType interrupt_type); private: - void StartIOCtl(u32 command_address); + void StartIOCtl(const IOSIOCtlRequest& request); std::deque m_commands_to_execute; }; From 0e979ec75fdd161e71b696dad12725f3b3fa1650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:48:37 +0100 Subject: [PATCH 11/16] IOS HLE: Deduplicate request code in FileIO and FS --- .../IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 171 ++++++++---------- .../Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h | 28 +-- .../Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp | 133 ++++++-------- .../Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h | 11 +- 4 files changed, 134 insertions(+), 209 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 972dc6ea35..c5307e7404 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include #include @@ -70,11 +71,7 @@ CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 device_id, { } -CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO() -{ -} - -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce) +void CWII_IPC_HLE_Device_FileIO::Close() { INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_name.c_str(), m_device_id); m_Mode = 0; @@ -84,12 +81,11 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bF m_file.reset(); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_FileIO::Open(const IOSOpenRequest& request) { - m_Mode = mode; + m_Mode = request.flags; static const char* const Modes[] = {"Unk Mode", "Read only", "Write only", "Read and Write"}; @@ -97,21 +93,18 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Open(u32 command_address, u32 mode) // The file must exist before we can open it // It should be created by ISFS_CreateFile, not here - if (File::Exists(m_filepath) && !File::IsDirectory(m_filepath)) + if (!File::Exists(m_filepath) || File::IsDirectory(m_filepath)) { - INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_name.c_str(), Modes[mode], mode); - OpenFile(); - } - else - { - WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[mode], + WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[m_Mode], m_filepath.c_str()); - if (command_address) - Memory::Write_U32(FS_ENOENT, command_address + 4); + return FS_ENOENT; } + INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_name.c_str(), Modes[m_Mode], m_Mode); + OpenFile(); + m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } // This isn't theadsafe, but it's only called from the CPU thread. @@ -158,98 +151,91 @@ void CWII_IPC_HLE_Device_FileIO::OpenFile() } } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(const IOSSeekRequest& request) { - u32 ReturnValue = FS_EINVAL; - const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC); - const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10); + u32 return_value = FS_EINVAL; if (m_file->IsOpen()) { - ReturnValue = FS_EINVAL; - - const s32 fileSize = (s32)m_file->GetSize(); + const u32 file_size = static_cast(m_file->GetSize()); DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08x)", - SeekPosition, Mode, m_name.c_str(), fileSize); + request.offset, request.mode, m_name.c_str(), file_size); - switch (Mode) + switch (request.mode) { - case WII_SEEK_SET: + case IOSSeekRequest::IOS_SEEK_SET: { - if ((SeekPosition >= 0) && (SeekPosition <= fileSize)) + if (request.offset <= file_size) { - m_SeekPos = SeekPosition; - ReturnValue = m_SeekPos; + m_SeekPos = request.offset; + return_value = m_SeekPos; } break; } - case WII_SEEK_CUR: + case IOSSeekRequest::IOS_SEEK_CUR: { - s32 wantedPos = SeekPosition + m_SeekPos; - if (wantedPos >= 0 && wantedPos <= fileSize) + const u32 wanted_pos = request.offset + m_SeekPos; + if (wanted_pos <= file_size) { - m_SeekPos = wantedPos; - ReturnValue = m_SeekPos; + m_SeekPos = wanted_pos; + return_value = m_SeekPos; } break; } - case WII_SEEK_END: + case IOSSeekRequest::IOS_SEEK_END: { - s32 wantedPos = SeekPosition + fileSize; - if (wantedPos >= 0 && wantedPos <= fileSize) + const u32 wanted_pos = request.offset + file_size; + if (wanted_pos <= file_size) { - m_SeekPos = wantedPos; - ReturnValue = m_SeekPos; + m_SeekPos = wanted_pos; + return_value = m_SeekPos; } break; } default: { - PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", Mode); - ReturnValue = FS_EINVAL; + PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", request.mode); + return_value = FS_EINVAL; break; } } } else { - ReturnValue = FS_ENOENT; + return_value = FS_ENOENT; } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - + request.SetReturnValue(return_value); return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(const IOSReadWriteRequest& request) { - u32 ReturnValue = FS_EACCESS; - const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address - const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); - + s32 return_value = FS_EACCESS; if (m_file->IsOpen()) { - if (m_Mode == ISFS_OPEN_WRITE) + if (m_Mode == IOS_OPEN_WRITE) { WARN_LOG(WII_IPC_FILEIO, - "FileIO: Attempted to read 0x%x bytes to 0x%08x on a write-only file %s", Size, - Address, m_name.c_str()); + "FileIO: Attempted to read 0x%x bytes to 0x%08x on a write-only file %s", + request.size, request.buffer, m_name.c_str()); } else { - DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, - m_name.c_str()); + DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", request.size, + request.buffer, m_name.c_str()); m_file->Seek(m_SeekPos, SEEK_SET); // File might be opened twice, need to seek before we read - ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_file->GetHandle()); - if (ReturnValue != Size && ferror(m_file->GetHandle())) + return_value = static_cast( + fread(Memory::GetPointer(request.buffer), 1, request.size, m_file->GetHandle())); + if (static_cast(return_value) != request.size && ferror(m_file->GetHandle())) { - ReturnValue = FS_EACCESS; + return_value = FS_EACCESS; } else { - m_SeekPos += Size; + m_SeekPos += request.size; } } } @@ -257,39 +243,35 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) { ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file could " "not be opened or does not exist", - m_name.c_str(), Address, Size); - ReturnValue = FS_ENOENT; + m_name.c_str(), request.buffer, request.size); + return_value = FS_ENOENT; } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); + request.SetReturnValue(return_value); return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(const IOSReadWriteRequest& request) { - u32 ReturnValue = FS_EACCESS; - const u32 Address = - Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address - const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); - + s32 return_value = FS_EACCESS; if (m_file->IsOpen()) { - if (m_Mode == ISFS_OPEN_READ) + if (m_Mode == IOS_OPEN_READ) { WARN_LOG(WII_IPC_FILEIO, - "FileIO: Attempted to write 0x%x bytes from 0x%08x to a read-only file %s", Size, - Address, m_name.c_str()); + "FileIO: Attempted to write 0x%x bytes from 0x%08x to a read-only file %s", + request.size, request.buffer, m_name.c_str()); } else { - DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, - m_name.c_str()); + DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", request.size, + request.buffer, m_name.c_str()); m_file->Seek(m_SeekPos, SEEK_SET); // File might be opened twice, need to seek before we write - if (m_file->WriteBytes(Memory::GetPointer(Address), Size)) + if (m_file->WriteBytes(Memory::GetPointer(request.buffer), request.size)) { - ReturnValue = Size; - m_SeekPos += Size; + return_value = request.size; + m_SeekPos += request.size; } } } @@ -297,51 +279,42 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) { ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file could " "not be opened or does not exist", - m_name.c_str(), Address, Size); - ReturnValue = FS_ENOENT; + m_name.c_str(), request.buffer, request.size); + return_value = FS_ENOENT; } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); + request.SetReturnValue(return_value); return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(const IOSIOCtlRequest& request) { DEBUG_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_name.c_str()); - const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 ReturnValue = 0; + s32 return_value = IPC_SUCCESS; - switch (Parameter) + switch (request.request) { case ISFS_IOCTL_GETFILESTATS: { if (m_file->IsOpen()) { - u32 m_FileLength = (u32)m_file->GetSize(); - - const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - DEBUG_LOG(WII_IPC_FILEIO, " File: %s, Length: %i, Pos: %i", m_name.c_str(), m_FileLength, - m_SeekPos); - - Memory::Write_U32(m_FileLength, BufferOut); - Memory::Write_U32(m_SeekPos, BufferOut + 4); + DEBUG_LOG(WII_IPC_FILEIO, "File: %s, Length: %" PRIu64 ", Pos: %i", m_name.c_str(), + m_file->GetSize(), m_SeekPos); + Memory::Write_U32(static_cast(m_file->GetSize()), request.buffer_out); + Memory::Write_U32(m_SeekPos, request.buffer_out + 4); } else { - ReturnValue = FS_ENOENT; + return_value = FS_ENOENT; } } break; default: - { - PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter); - } - break; + request.Log(GetDeviceName(), LogTypes::WII_IPC_FILEIO, LogTypes::LERROR); } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - + request.SetReturnValue(return_value); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h index 3d49acc04b..84cd6d5a66 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h @@ -26,34 +26,18 @@ class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName); - virtual ~CWII_IPC_HLE_Device_FileIO(); - - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Seek(u32 _CommandAddress) override; - IPCCommandResult Read(u32 _CommandAddress) override; - IPCCommandResult Write(u32 _CommandAddress) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; + void Close() override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + IPCCommandResult Seek(const IOSSeekRequest& request) override; + IPCCommandResult Read(const IOSReadWriteRequest& request) override; + IPCCommandResult Write(const IOSReadWriteRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; void PrepareForState(PointerWrap::Mode mode) override; void DoState(PointerWrap& p) override; void OpenFile(); private: - enum - { - ISFS_OPEN_READ = 1, - ISFS_OPEN_WRITE = 2, - ISFS_OPEN_RW = (ISFS_OPEN_READ | ISFS_OPEN_WRITE) - }; - - enum - { - WII_SEEK_SET = 0, - WII_SEEK_CUR = 1, - WII_SEEK_END = 2, - }; - enum { ISFS_FUNCNULL = 0, diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp index fa9d4ed332..cc9aae5eac 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp @@ -32,10 +32,6 @@ CWII_IPC_HLE_Device_fs::CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& { } -CWII_IPC_HLE_Device_fs::~CWII_IPC_HLE_Device_fs() -{ -} - // ~1/1000th of a second is too short and causes hangs in Wii Party // Play it safe at 1/500th IPCCommandResult CWII_IPC_HLE_Device_fs::GetFSReply() const @@ -43,7 +39,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::GetFSReply() const return {true, SystemTimers::GetTicksPerSecond() / 500}; } -IPCCommandResult CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode) +IOSReturnCode CWII_IPC_HLE_Device_fs::Open(const IOSOpenRequest& request) { // clear tmp folder { @@ -53,7 +49,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode) } m_is_active = true; - return GetFSReply(); + return IPC_SUCCESS; } // Get total filesize of contents of a directory (recursive) @@ -71,27 +67,20 @@ static u64 ComputeTotalFileSize(const File::FSTEntry& parentEntry) return sizeOfFiles; } -IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(const IOSIOCtlVRequest& request) { - u32 ReturnValue = IPC_SUCCESS; - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - // Prepare the out buffer(s) with zeros as a safety precaution - // to avoid returning bad values - for (const auto& buffer : CommandBuffer.PayloadBuffer) - Memory::Memset(buffer.m_Address, 0, buffer.m_Size); - - switch (CommandBuffer.Parameter) + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTLV_READ_DIR: { const std::string relative_path = - Memory::GetString(CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size); + Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size); if (!IsValidWiiPath(relative_path)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", relative_path.c_str()); - ReturnValue = FS_EINVAL; + return_value = FS_EINVAL; break; } @@ -103,7 +92,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) if (!File::Exists(DirName)) { WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", DirName.c_str()); - ReturnValue = FS_ENOENT; + return_value = FS_ENOENT; break; } else if (!File::IsDirectory(DirName)) @@ -112,19 +101,19 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) // Games don't usually seem to care WHICH error they get, as long as it's < // Well the system menu CARES! WARN_LOG(WII_IPC_FILEIO, "\tNot a directory - return FS_EINVAL"); - ReturnValue = FS_EINVAL; + return_value = FS_EINVAL; break; } File::FSTEntry entry = File::ScanDirectoryTree(DirName, false); // it is one - if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1)) + if ((request.in_vectors.size() == 1) && (request.io_vectors.size() == 1)) { size_t numFile = entry.children.size(); INFO_LOG(WII_IPC_FILEIO, "\t%zu files found", numFile); - Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[0].m_Address); + Memory::Write_U32((u32)numFile, request.io_vectors[0].address); } else { @@ -140,13 +129,12 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) return one.virtualName < two.virtualName; }); - u32 MaxEntries = Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address); + u32 MaxEntries = Memory::Read_U32(request.in_vectors[0].address); - memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, - CommandBuffer.PayloadBuffer[0].m_Size); + memset(Memory::GetPointer(request.io_vectors[0].address), 0, request.io_vectors[0].size); size_t numFiles = 0; - char* pFilename = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address)); + char* pFilename = (char*)Memory::GetPointer((u32)(request.io_vectors[0].address)); for (size_t i = 0; i < entry.children.size() && i < MaxEntries; i++) { @@ -160,29 +148,29 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_FILEIO, "\tFound: %s", FileName.c_str()); } - Memory::Write_U32((u32)numFiles, CommandBuffer.PayloadBuffer[1].m_Address); + Memory::Write_U32((u32)numFiles, request.io_vectors[1].address); } - ReturnValue = IPC_SUCCESS; + return_value = IPC_SUCCESS; } break; case IOCTLV_GETUSAGE: { - _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer.size() == 2); - _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[0].m_Size == 4); - _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[1].m_Size == 4); + _dbg_assert_(WII_IPC_FILEIO, request.io_vectors.size() == 2); + _dbg_assert_(WII_IPC_FILEIO, request.io_vectors[0].size == 4); + _dbg_assert_(WII_IPC_FILEIO, request.io_vectors[1].size == 4); // this command sucks because it asks of the number of used // fsBlocks and inodes // It should be correct, but don't count on it... std::string relativepath = - Memory::GetString(CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size); + Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size); if (!IsValidWiiPath(relativepath)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", relativepath.c_str()); - ReturnValue = FS_EINVAL; + return_value = FS_EINVAL; break; } @@ -214,7 +202,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) fsBlocks = (u32)(totalSize / (16 * 1024)); // one bock is 16kb } - ReturnValue = IPC_SUCCESS; + return_value = IPC_SUCCESS; INFO_LOG(WII_IPC_FILEIO, "FS: fsBlock: %i, iNodes: %i", fsBlocks, iNodes); } @@ -222,54 +210,39 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) { fsBlocks = 0; iNodes = 0; - ReturnValue = IPC_SUCCESS; + return_value = IPC_SUCCESS; WARN_LOG(WII_IPC_FILEIO, "FS: fsBlock failed, cannot find directory: %s", path.c_str()); } - Memory::Write_U32(fsBlocks, CommandBuffer.PayloadBuffer[0].m_Address); - Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address); + Memory::Write_U32(fsBlocks, request.io_vectors[0].address); + Memory::Write_U32(iNodes, request.io_vectors[1].address); } break; default: - PanicAlert("CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_FILEIO); break; } - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - + request.SetReturnValue(return_value); return GetFSReply(); } -IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtl(const IOSIOCtlRequest& request) { - // u32 DeviceID = Memory::Read_U32(_CommandAddress + 8); - - u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - /* Prepare the out buffer(s) with zeroes as a safety precaution - to avoid returning bad values. */ - // LOG(WII_IPC_FILEIO, "Cleared %u bytes of the out buffer", _BufferOutSize); - Memory::Memset(BufferOut, 0, BufferOutSize); - - u32 ReturnValue = ExecuteCommand(Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); + const s32 return_value = ExecuteCommand(request); + request.SetReturnValue(return_value); return GetFSReply(); } -s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, - u32 _BufferOut, u32 _BufferOutSize) +s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(const IOSIOCtlRequest& request) { - switch (_Parameter) + switch (request.request) { case IOCTL_GET_STATS: { - if (_BufferOutSize < 0x1c) + if (request.buffer_out_size < 0x1c) return -1017; WARN_LOG(WII_IPC_FILEIO, "FS: GET STATS - returning static values for now"); @@ -285,7 +258,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B fs.Free_INodes = 0x146B; fs.Used_Inodes = 0x0394; - std::memcpy(Memory::GetPointer(_BufferOut), &fs, sizeof(NANDStat)); + std::memcpy(Memory::GetPointer(request.buffer_out), &fs, sizeof(NANDStat)); return IPC_SUCCESS; } @@ -293,8 +266,8 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_CREATE_DIR: { - _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); - u32 Addr = _BufferIn; + _dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0); + u32 Addr = request.buffer_in; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; @@ -325,7 +298,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_SET_ATTR: { - u32 Addr = _BufferIn; + u32 Addr = request.buffer_in; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; @@ -362,14 +335,14 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_GET_ATTR: { - _dbg_assert_msg_(WII_IPC_FILEIO, _BufferOutSize == 76, + _dbg_assert_msg_(WII_IPC_FILEIO, request.buffer_out_size == 76, " GET_ATTR needs an 76 bytes large output buffer but it is %i bytes large", - _BufferOutSize); + request.buffer_out_size); u32 OwnerID = 0; u16 GroupID = 0x3031; // this is also known as makercd, 01 (0x3031) for nintendo and 08 // (0x3038) for MH3 etc - const std::string wii_path = Memory::GetString(_BufferIn, 64); + const std::string wii_path = Memory::GetString(request.buffer_in, 64); if (!IsValidWiiPath(wii_path)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str()); @@ -400,14 +373,14 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B } // write answer to buffer - if (_BufferOutSize == 76) + if (request.buffer_out_size == 76) { - u32 Addr = _BufferOut; + u32 Addr = request.buffer_out; Memory::Write_U32(OwnerID, Addr); Addr += 4; Memory::Write_U16(GroupID, Addr); Addr += 2; - memcpy(Memory::GetPointer(Addr), Memory::GetPointer(_BufferIn), 64); + memcpy(Memory::GetPointer(Addr), Memory::GetPointer(request.buffer_in), 64); Addr += 64; Memory::Write_U8(OwnerPerm, Addr); Addr += 1; @@ -425,10 +398,10 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_DELETE_FILE: { - _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); + _dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0); int Offset = 0; - const std::string wii_path = Memory::GetString(_BufferIn + Offset, 64); + const std::string wii_path = Memory::GetString(request.buffer_in + Offset, 64); if (!IsValidWiiPath(wii_path)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str()); @@ -455,10 +428,10 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_RENAME_FILE: { - _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); + _dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0); int Offset = 0; - const std::string wii_path = Memory::GetString(_BufferIn + Offset, 64); + const std::string wii_path = Memory::GetString(request.buffer_in + Offset, 64); if (!IsValidWiiPath(wii_path)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str()); @@ -467,7 +440,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B std::string Filename = HLE_IPC_BuildFilename(wii_path); Offset += 64; - const std::string wii_path_rename = Memory::GetString(_BufferIn + Offset, 64); + const std::string wii_path_rename = Memory::GetString(request.buffer_in + Offset, 64); if (!IsValidWiiPath(wii_path_rename)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path_rename.c_str()); @@ -503,9 +476,9 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_CREATE_FILE: { - _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); + _dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0); - u32 Addr = _BufferIn; + u32 Addr = request.buffer_in; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u16 GroupID = Memory::Read_U16(Addr); @@ -563,9 +536,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B } break; default: - ERROR_LOG(WII_IPC_FILEIO, "CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter); - PanicAlert("CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter); - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_FILEIO); } return FS_EINVAL; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h index 50feefa92f..0ff31f4036 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h @@ -27,14 +27,12 @@ class CWII_IPC_HLE_Device_fs : public IWII_IPC_HLE_Device { public: CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& _rDeviceName); - virtual ~CWII_IPC_HLE_Device_fs(); void DoState(PointerWrap& p) override; - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; private: enum @@ -52,6 +50,5 @@ private: }; IPCCommandResult GetFSReply() const; - s32 ExecuteCommand(u32 Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, - u32 _BufferOutSize); + s32 ExecuteCommand(const IOSIOCtlRequest& request); }; From 6bf0b487d1a66b14a1110deed6c4adf2deae87a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:48:52 +0100 Subject: [PATCH 12/16] IOS HLE: Deduplicate request code in USB_HID --- .../Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 133 +++++++----------- .../Core/IPC_HLE/WII_IPC_HLE_Device_hid.h | 6 +- 2 files changed, 51 insertions(+), 88 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 829c5ff873..04d5002dbe 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -37,13 +37,10 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) std::lock_guard lk(hid->m_device_list_reply_mutex); if (hid->deviceCommandAddress != 0) { - hid->FillOutDevices(Memory::Read_U32(hid->deviceCommandAddress + 0x18), - Memory::Read_U32(hid->deviceCommandAddress + 0x1C)); - - // Return value - Memory::Write_U32(0, hid->deviceCommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(hid->deviceCommandAddress, 0, - CoreTiming::FromThread::NON_CPU); + IOSIOCtlRequest request{hid->deviceCommandAddress}; + hid->FillOutDevices(request); + request.SetReturnValue(IPC_SUCCESS); + WII_IPC_HLE_Interface::EnqueueReply(request, 0, CoreTiming::FromThread::NON_CPU); hid->deviceCommandAddress = 0; } } @@ -56,16 +53,16 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) void CWII_IPC_HLE_Device_hid::handleUsbUpdates(struct libusb_transfer* transfer) { - int ret = IPC_EINVAL; + s32 ret = IPC_EINVAL; u32 replyAddress = (u32)(size_t)transfer->user_data; if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { ret = transfer->length; } - // Return value - Memory::Write_U32(ret, replyAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(replyAddress, 0, CoreTiming::FromThread::NON_CPU); + IOSIOCtlRequest request{replyAddress}; + request.SetReturnValue(ret); + WII_IPC_HLE_Interface::EnqueueReply(request, 0, CoreTiming::FromThread::NON_CPU); } CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) @@ -105,53 +102,37 @@ CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() libusb_exit(nullptr); } -IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(const IOSIOCtlRequest& request) { if (Core::g_want_determinism) { - Memory::Write_U32(-1, _CommandAddress + 0x4); + request.SetReturnValue(-1); return GetDefaultReply(); } - u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - u32 ReturnValue = 0; - switch (Parameter) + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTL_HID_GET_ATTACHED: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); - deviceCommandAddress = _CommandAddress; + deviceCommandAddress = request.address; return GetNoReply(); } case IOCTL_HID_OPEN: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Open) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, - BufferInSize, BufferOut, BufferOutSize); - // hid version, apparently - ReturnValue = 0x40001; + return_value = 0x40001; break; } case IOCTL_HID_SET_SUSPEND: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Set Suspend) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); // not actually implemented in IOS - ReturnValue = 0; + return_value = IPC_SUCCESS; break; } case IOCTL_HID_CANCEL_INTERRUPT: { - DEBUG_LOG(WII_IPC_HID, - "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, - BufferInSize, BufferOut, BufferOutSize); - ReturnValue = 0; + return_value = IPC_SUCCESS; break; } case IOCTL_HID_CONTROL: @@ -161,15 +142,15 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) -4 Can't find device specified */ - u32 dev_num = Memory::Read_U32(BufferIn + 0x10); - u8 bmRequestType = Memory::Read_U8(BufferIn + 0x14); - u8 bRequest = Memory::Read_U8(BufferIn + 0x15); - u16 wValue = Memory::Read_U16(BufferIn + 0x16); - u16 wIndex = Memory::Read_U16(BufferIn + 0x18); - u16 wLength = Memory::Read_U16(BufferIn + 0x1A); - u32 data = Memory::Read_U32(BufferIn + 0x1C); + u32 dev_num = Memory::Read_U32(request.buffer_in + 0x10); + u8 bmRequestType = Memory::Read_U8(request.buffer_in + 0x14); + u8 bRequest = Memory::Read_U8(request.buffer_in + 0x15); + u16 wValue = Memory::Read_U16(request.buffer_in + 0x16); + u16 wIndex = Memory::Read_U16(request.buffer_in + 0x18); + u16 wLength = Memory::Read_U16(request.buffer_in + 0x1A); + u32 data = Memory::Read_U32(request.buffer_in + 0x1C); - ReturnValue = IPC_EINVAL; + return_value = IPC_EINVAL; libusb_device_handle* dev_handle = GetDeviceByDevNum(dev_num); @@ -185,12 +166,14 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength); Memory::CopyFromEmu(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength); libusb_fill_control_transfer(transfer, dev_handle, buffer, handleUsbUpdates, - (void*)(size_t)_CommandAddress, /* no timeout */ 0); + (void*)(size_t)request.address, /* no timeout */ 0); libusb_submit_transfer(transfer); - // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: + // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), + // request.buffer_out: // (%08x, %i)", - // bmRequestType, bRequest, BufferIn, BufferInSize, BufferOut, BufferOutSize); + // bmRequestType, bRequest, BufferIn, request.buffer_in_size, request.buffer_out, + // request.buffer_out_size); // It's the async way! return GetNoReply(); @@ -198,13 +181,13 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) case IOCTL_HID_INTERRUPT_OUT: case IOCTL_HID_INTERRUPT_IN: { - u32 dev_num = Memory::Read_U32(BufferIn + 0x10); - u32 endpoint = Memory::Read_U32(BufferIn + 0x14); - u32 length = Memory::Read_U32(BufferIn + 0x18); + u32 dev_num = Memory::Read_U32(request.buffer_in + 0x10); + u32 endpoint = Memory::Read_U32(request.buffer_in + 0x14); + u32 length = Memory::Read_U32(request.buffer_in + 0x18); - u32 data = Memory::Read_U32(BufferIn + 0x1C); + u32 data = Memory::Read_U32(request.buffer_in + 0x1C); - ReturnValue = IPC_EINVAL; + return_value = IPC_EINVAL; libusb_device_handle* dev_handle = GetDeviceByDevNum(dev_num); @@ -217,14 +200,9 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) struct libusb_transfer* transfer = libusb_alloc_transfer(0); transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, Memory::GetPointer(data), length, - handleUsbUpdates, (void*)(size_t)_CommandAddress, 0); + handleUsbUpdates, (void*)(size_t)request.address, 0); libusb_submit_transfer(transfer); - // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) (BufferIn: (%08x, %i), BufferOut: - // (%08x, %i)", - // Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, - // BufferIn, BufferInSize, BufferOut, BufferOutSize); - // It's the async way! return GetNoReply(); } @@ -233,27 +211,22 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) std::lock_guard lk(m_device_list_reply_mutex); if (deviceCommandAddress != 0) { - Memory::Write_U32(0xFFFFFFFF, Memory::Read_U32(deviceCommandAddress + 0x18)); - - // Return value - Memory::Write_U32(-1, deviceCommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(deviceCommandAddress); + IOSIOCtlRequest pending_request{deviceCommandAddress}; + Memory::Write_U32(0xFFFFFFFF, pending_request.buffer_out); + pending_request.SetReturnValue(-1); + WII_IPC_HLE_Interface::EnqueueReply(pending_request); deviceCommandAddress = 0; } INFO_LOG(WII_IPC_HID, "HID::IOCtl(Shutdown) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size); break; } default: - { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(0x%x) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); - break; - } + request.Log(GetDeviceName(), LogTypes::WII_IPC_HID); } - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - + request.SetReturnValue(return_value); return GetDefaultReply(); } @@ -283,21 +256,11 @@ bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle* dev) return true; } -IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtlV(const IOSIOCtlVRequest& request) { Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); - u32 ReturnValue = 0; - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - INFO_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); - INFO_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); - INFO_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - INFO_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - INFO_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - INFO_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - INFO_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); - - Memory::Write_U32(ReturnValue, _CommandAddress + 4); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HID); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } @@ -340,10 +303,10 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor* des dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); } -void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) +void CWII_IPC_HLE_Device_hid::FillOutDevices(const IOSIOCtlRequest& request) { static u16 check = 1; - int OffsetBuffer = BufferOut; + int OffsetBuffer = request.buffer_out; int OffsetStart = 0; // int OffsetDevice = 0; int d, c, ic, i, e; /* config, interface container, interface, endpoint */ diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h index 8a8d3ddb04..f88a42f4d0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -38,8 +38,8 @@ public: virtual ~CWII_IPC_HLE_Device_hid(); - IPCCommandResult IOCtlV(u32 _CommandAddress) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: enum @@ -115,7 +115,7 @@ private: }; u32 deviceCommandAddress; - void FillOutDevices(u32 BufferOut, u32 BufferOutSize); + void FillOutDevices(const IOSIOCtlRequest& request); int GetAvailableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check); bool ClaimDevice(libusb_device_handle* dev); From 4af67abb55f564c314fabf586579b66d4327dab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:49:03 +0100 Subject: [PATCH 13/16] IOS HLE: Deduplicate request code in ES --- .../Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp | 398 +++++++++--------- .../Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h | 11 +- 2 files changed, 195 insertions(+), 214 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp index c190bfdc63..159d735919 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -97,10 +97,6 @@ u8* CWII_IPC_HLE_Device_es::keyTable[11] = { key_empty, // Unknown }; -CWII_IPC_HLE_Device_es::~CWII_IPC_HLE_Device_es() -{ -} - void CWII_IPC_HLE_Device_es::LoadWAD(const std::string& _rContentFile) { m_ContentFile = _rContentFile; @@ -195,17 +191,16 @@ void CWII_IPC_HLE_Device_es::DoState(PointerWrap& p) } } -IPCCommandResult CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode) +IOSReturnCode CWII_IPC_HLE_Device_es::Open(const IOSOpenRequest& request) { OpenInternal(); if (m_is_active) INFO_LOG(WII_IPC_ES, "Device was re-opened."); - m_is_active = true; - return GetDefaultReply(); + return IWII_IPC_HLE_Device::Open(request); } -IPCCommandResult CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress, bool _bForce) +void CWII_IPC_HLE_Device_es::Close() { m_ContentAccessMap.clear(); m_TitleIDs.clear(); @@ -216,7 +211,6 @@ IPCCommandResult CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress, bool _bForce m_is_active = false; // clear the NAND content cache to make sure nothing remains open. DiscIO::CNANDContentManager::Access().ClearCache(); - return GetDefaultReply(); } u32 CWII_IPC_HLE_Device_es::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index) @@ -248,53 +242,43 @@ u32 CWII_IPC_HLE_Device_es::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index) return CFD; } -IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) { - SIOCtlVBuffer Buffer(_CommandAddress); - - DEBUG_LOG(WII_IPC_ES, "%s (0x%x)", GetDeviceName().c_str(), Buffer.Parameter); - - // Prepare the out buffer(s) with zeroes as a safety precaution - // to avoid returning bad values - for (const auto& buffer : Buffer.PayloadBuffer) + DEBUG_LOG(WII_IPC_ES, "%s (0x%x)", GetDeviceName().c_str(), request.request); + // Clear the IO buffers. Note that this is unsafe for other ioctlvs. + for (const auto& io_vector : request.io_vectors) { - // Don't zero an out buffer which is also one of the in buffers. - if (std::any_of(Buffer.InBuffer.begin(), Buffer.InBuffer.end(), - [&](const auto& in_buffer) { return in_buffer.m_Address == buffer.m_Address; })) - { - continue; - } - Memory::Memset(buffer.m_Address, 0, buffer.m_Size); + if (!request.HasInputVectorWithAddress(io_vector.address)) + Memory::Memset(io_vector.address, 0, io_vector.size); } - - switch (Buffer.Parameter) + switch (request.request) { case IOCTL_ES_ADDTICKET: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 3, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 3, "IOCTL_ES_ADDTICKET wrong number of inputs"); INFO_LOG(WII_IPC_ES, "IOCTL_ES_ADDTICKET"); - std::vector ticket(Buffer.InBuffer[0].m_Size); - Memory::CopyFromEmu(ticket.data(), Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size); + std::vector ticket(request.in_vectors[0].size); + Memory::CopyFromEmu(ticket.data(), request.in_vectors[0].address, request.in_vectors[0].size); DiscIO::AddTicket(ticket); break; } case IOCTL_ES_ADDTITLESTART: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 4, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 4, "IOCTL_ES_ADDTITLESTART wrong number of inputs"); INFO_LOG(WII_IPC_ES, "IOCTL_ES_ADDTITLESTART"); - std::vector tmd(Buffer.InBuffer[0].m_Size); - Memory::CopyFromEmu(tmd.data(), Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size); + std::vector tmd(request.in_vectors[0].size); + Memory::CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size); m_addtitle_tmd.SetBytes(tmd); if (!m_addtitle_tmd.IsValid()) { ERROR_LOG(WII_IPC_ES, "Invalid TMD while adding title (size = %zd)", tmd.size()); - Memory::Write_U32(ES_INVALID_TMD, _CommandAddress + 0x4); + request.SetReturnValue(ES_INVALID_TMD); return GetDefaultReply(); } @@ -310,17 +294,17 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_ADDCONTENTSTART: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, "IOCTL_ES_ADDCONTENTSTART wrong number of inputs"); - u64 title_id = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 content_id = Memory::Read_U32(Buffer.InBuffer[1].m_Address); + u64 title_id = Memory::Read_U64(request.in_vectors[0].address); + u32 content_id = Memory::Read_U32(request.in_vectors[1].address); if (m_addtitle_content_id != 0xFFFFFFFF) { ERROR_LOG(WII_IPC_ES, "Trying to add content when we haven't finished adding " "another content. Unsupported."); - Memory::Write_U32(ES_WRITE_FAILURE, _CommandAddress + 0x4); + request.SetReturnValue(ES_WRITE_FAILURE); return GetDefaultReply(); } m_addtitle_content_id = content_id; @@ -343,39 +327,39 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // no known content installer which performs content addition concurrently. // Instead we just log an error (see above) if this condition is detected. s32 content_fd = 0; - Memory::Write_U32(content_fd, _CommandAddress + 0x4); + request.SetReturnValue(content_fd); return GetDefaultReply(); } case IOCTL_ES_ADDCONTENTDATA: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, "IOCTL_ES_ADDCONTENTDATA wrong number of inputs"); - u32 content_fd = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + u32 content_fd = Memory::Read_U32(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_ADDCONTENTDATA: content fd %08x, " "size %d", - content_fd, Buffer.InBuffer[1].m_Size); + content_fd, request.in_vectors[1].size); - u8* data_start = Memory::GetPointer(Buffer.InBuffer[1].m_Address); - u8* data_end = data_start + Buffer.InBuffer[1].m_Size; + u8* data_start = Memory::GetPointer(request.in_vectors[1].address); + u8* data_end = data_start + request.in_vectors[1].size; m_addtitle_content_buffer.insert(m_addtitle_content_buffer.end(), data_start, data_end); break; } case IOCTL_ES_ADDCONTENTFINISH: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, "IOCTL_ES_ADDCONTENTFINISH wrong number of inputs"); - u32 content_fd = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + u32 content_fd = Memory::Read_U32(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_ADDCONTENTFINISH: content fd %08x", content_fd); // Try to find the title key from a pre-installed ticket. std::vector ticket = DiscIO::FindSignedTicket(m_addtitle_tmd.GetTitleId()); if (ticket.size() == 0) { - Memory::Write_U32(ES_NO_TICKET_INSTALLED, _CommandAddress + 0x4); + request.SetReturnValue(ES_NO_TICKET_INSTALLED); return GetDefaultReply(); } @@ -387,7 +371,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) TMDReader::Content content_info; if (!m_addtitle_tmd.FindContentById(m_addtitle_content_id, &content_info)) { - Memory::Write_U32(ES_INVALID_TMD, _CommandAddress + 0x4); + request.SetReturnValue(ES_INVALID_TMD); return GetDefaultReply(); } u8 iv[16] = {0}; @@ -417,23 +401,22 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_GETDEVICEID: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, - "IOCTL_ES_GETDEVICEID no out buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, + "IOCTL_ES_GETDEVICEID no io vectors"); EcWii& ec = EcWii::GetInstance(); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICEID %08X", ec.getNgId()); - Memory::Write_U32(ec.getNgId(), Buffer.PayloadBuffer[0].m_Address); - Memory::Write_U32(0, _CommandAddress + 0x4); + Memory::Write_U32(ec.getNgId(), request.io_vectors[0].address); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } - break; case IOCTL_ES_GETTITLECONTENTSCNT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 1); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID); u16 NumberOfPrivateContent = 0; @@ -442,14 +425,16 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) NumberOfPrivateContent = rNANDContent.GetNumEntries(); if ((u32)(TitleID >> 32) == 0x00010000) - Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U32(0, request.io_vectors[0].address); else - Memory::Write_U32(NumberOfPrivateContent, Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U32(NumberOfPrivateContent, request.io_vectors[0].address); - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); } else - Memory::Write_U32((u32)rNANDContent.GetContentSize(), _CommandAddress + 0x4); + { + request.SetReturnValue(static_cast(rNANDContent.GetContentSize())); + } INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTSCNT: TitleID: %08x/%08x content count %i", (u32)(TitleID >> 32), (u32)TitleID, @@ -461,12 +446,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_GETTITLECONTENTS: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, "IOCTL_ES_GETTITLECONTENTS bad in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLECONTENTS bad out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID); if (rNANDContent.IsValid()) // Not sure if dolphin will ever fail this check @@ -474,15 +459,15 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) for (u16 i = 0; i < rNANDContent.GetNumEntries(); i++) { Memory::Write_U32(rNANDContent.GetContentByIndex(i)->m_ContentID, - Buffer.PayloadBuffer[0].m_Address + i * 4); + request.io_vectors[0].address + i * 4); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Index %d: %08x", i, rNANDContent.GetContentByIndex(i)->m_ContentID); } - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); } else { - Memory::Write_U32((u32)rNANDContent.GetContentSize(), _CommandAddress + 0x4); + request.SetReturnValue(static_cast(rNANDContent.GetContentSize())); ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Unable to open content %zu", rNANDContent.GetContentSize()); } @@ -493,14 +478,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_OPENTITLECONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 3); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 3); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 0); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 Index = Memory::Read_U32(Buffer.InBuffer[2].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); + u32 Index = Memory::Read_U32(request.in_vectors[2].address); - u32 CFD = OpenTitleContent(m_AccessIdentID++, TitleID, Index); - Memory::Write_U32(CFD, _CommandAddress + 0x4); + s32 CFD = OpenTitleContent(m_AccessIdentID++, TitleID, Index); + request.SetReturnValue(CFD); INFO_LOG(WII_IPC_ES, "IOCTL_ES_OPENTITLECONTENT: TitleID: %08x/%08x Index %i -> got CFD %x", (u32)(TitleID >> 32), (u32)TitleID, Index, CFD); @@ -511,12 +496,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_OPENCONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); - u32 Index = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 0); + u32 Index = Memory::Read_U32(request.in_vectors[0].address); - u32 CFD = OpenTitleContent(m_AccessIdentID++, m_TitleID, Index); - Memory::Write_U32(CFD, _CommandAddress + 0x4); + s32 CFD = OpenTitleContent(m_AccessIdentID++, m_TitleID, Index); + request.SetReturnValue(CFD); INFO_LOG(WII_IPC_ES, "IOCTL_ES_OPENCONTENT: Index %i -> got CFD %x", Index, CFD); return GetDefaultReply(); @@ -525,17 +510,17 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_READCONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 1); - u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address); - u32 Size = Buffer.PayloadBuffer[0].m_Size; - u32 Addr = Buffer.PayloadBuffer[0].m_Address; + u32 CFD = Memory::Read_U32(request.in_vectors[0].address); + u32 Size = request.io_vectors[0].size; + u32 Addr = request.io_vectors[0].address; auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - Memory::Write_U32(-1, _CommandAddress + 0x4); + request.SetReturnValue(-1); return GetDefaultReply(); } SContentAccess& rContent = itr->second; @@ -573,24 +558,24 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) "IOCTL_ES_READCONTENT: CFD %x, Address 0x%x, Size %i -> stream pos %i (Index %i)", CFD, Addr, Size, rContent.m_Position, rContent.m_Index); - Memory::Write_U32(Size, _CommandAddress + 0x4); + request.SetReturnValue(Size); return GetDefaultReply(); } break; case IOCTL_ES_CLOSECONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 0); - u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + u32 CFD = Memory::Read_U32(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_CLOSECONTENT: CFD %x", CFD); auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - Memory::Write_U32(-1, _CommandAddress + 0x4); + request.SetReturnValue(-1); return GetDefaultReply(); } @@ -604,24 +589,24 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) m_ContentAccessMap.erase(itr); - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } break; case IOCTL_ES_SEEKCONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 3); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 3); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 0); - u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address); - u32 Addr = Memory::Read_U32(Buffer.InBuffer[1].m_Address); - u32 Mode = Memory::Read_U32(Buffer.InBuffer[2].m_Address); + u32 CFD = Memory::Read_U32(request.in_vectors[0].address); + u32 Addr = Memory::Read_U32(request.in_vectors[1].address); + u32 Mode = Memory::Read_U32(request.in_vectors[2].address); auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - Memory::Write_U32(-1, _CommandAddress + 0x4); + request.SetReturnValue(-1); return GetDefaultReply(); } SContentAccess& rContent = itr->second; @@ -644,19 +629,19 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) DEBUG_LOG(WII_IPC_ES, "IOCTL_ES_SEEKCONTENT: CFD %x, Address 0x%x, Mode %i -> Pos %i", CFD, Addr, Mode, rContent.m_Position); - Memory::Write_U32(rContent.m_Position, _CommandAddress + 0x4); + request.SetReturnValue(rContent.m_Position); return GetDefaultReply(); } break; case IOCTL_ES_GETTITLEDIR: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 1); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); - char* Path = (char*)Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); + char* Path = (char*)Memory::GetPointer(request.io_vectors[0].address); sprintf(Path, "/title/%08x/%08x/data", (u32)(TitleID >> 32), (u32)TitleID); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLEDIR: %s", Path); @@ -665,56 +650,56 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_GETTITLEID: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 0); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 0); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLEID no out buffer"); - Memory::Write_U64(m_TitleID, Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U64(m_TitleID, request.io_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLEID: %08x/%08x", (u32)(m_TitleID >> 32), (u32)m_TitleID); } break; case IOCTL_ES_SETUID: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_SETUID no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, "IOCTL_ES_SETUID no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 0, "IOCTL_ES_SETUID has a payload, it shouldn't"); // TODO: fs permissions based on this - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_SETUID titleID: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); } break; case IOCTL_ES_GETTITLECNT: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 0, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 0, "IOCTL_ES_GETTITLECNT has an in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLECNT has no out buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.PayloadBuffer[0].m_Size == 4, + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors[0].size == 4, "IOCTL_ES_GETTITLECNT payload[0].size != 4"); - Memory::Write_U32((u32)m_TitleIDs.size(), Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U32((u32)m_TitleIDs.size(), request.io_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECNT: Number of Titles %zu", m_TitleIDs.size()); - Memory::Write_U32(0, _CommandAddress + 0x4); - + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } break; case IOCTL_ES_GETTITLES: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETTITLES has an in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, + "IOCTL_ES_GETTITLES has an in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLES has no out buffer"); - u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + u32 MaxCount = Memory::Read_U32(request.in_vectors[0].address); u32 Count = 0; for (int i = 0; i < (int)m_TitleIDs.size(); i++) { - Memory::Write_U64(m_TitleIDs[i], Buffer.PayloadBuffer[0].m_Address + i * 8); + Memory::Write_U64(m_TitleIDs[i], request.io_vectors[0].address + i * 8); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: %08x/%08x", (u32)(m_TitleIDs[i] >> 32), (u32)m_TitleIDs[i]); Count++; @@ -723,18 +708,19 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) } INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: Number of titles returned %i", Count); - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } break; case IOCTL_ES_GETVIEWCNT: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETVIEWCNT no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, + "IOCTL_ES_GETVIEWCNT no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETVIEWCNT no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u32 retVal = 0; const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); @@ -774,20 +760,19 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETVIEWCNT for titleID: %08x/%08x (View Count = %i)", (u32)(TitleID >> 32), (u32)TitleID, ViewCount); - Memory::Write_U32(ViewCount, Buffer.PayloadBuffer[0].m_Address); - Memory::Write_U32(retVal, _CommandAddress + 0x4); + Memory::Write_U32(ViewCount, request.io_vectors[0].address); + request.SetReturnValue(retVal); return GetDefaultReply(); } break; case IOCTL_ES_GETVIEWS: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "IOCTL_ES_GETVIEWS no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, - "IOCTL_ES_GETVIEWS no out buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, "IOCTL_ES_GETVIEWS no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETVIEWS no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 maxViews = Memory::Read_U32(Buffer.InBuffer[1].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); + u32 maxViews = Memory::Read_U32(request.in_vectors[1].address); u32 retVal = 0; const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); @@ -808,9 +793,9 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) pFile.ReadBytes(FileTicket, DiscIO::CNANDContentLoader::TICKET_SIZE); ++View) { - Memory::Write_U32(View, Buffer.PayloadBuffer[0].m_Address + View * 0xD8); - Memory::CopyToEmu(Buffer.PayloadBuffer[0].m_Address + 4 + View * 0xD8, - FileTicket + 0x1D0, 212); + Memory::Write_U32(View, request.io_vectors[0].address + View * 0xD8); + Memory::CopyToEmu(request.io_vectors[0].address + 4 + View * 0xD8, FileTicket + 0x1D0, + 212); } } } @@ -820,7 +805,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // SDK or libogc, just passed to LaunchTitle, so this // shouldn't matter at all. Just fill out some fields just // to be on the safe side. - u32 Address = Buffer.PayloadBuffer[0].m_Address; + u32 Address = request.io_vectors[0].address; Memory::Memset(Address, 0, 0xD8); Memory::Write_U64(TitleID, Address + 4 + (0x1dc - 0x1d0)); // title ID Memory::Write_U16(0xffff, Address + 4 + (0x1e4 - 0x1d0)); // unnnown @@ -840,8 +825,8 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) static_cast(Loader.GetTicket().size()) / DiscIO::CNANDContentLoader::TICKET_SIZE; for (unsigned int view = 0; view != maxViews && view < view_count; ++view) { - Memory::Write_U32(view, Buffer.PayloadBuffer[0].m_Address + view * 0xD8); - Memory::CopyToEmu(Buffer.PayloadBuffer[0].m_Address + 4 + view * 0xD8, + Memory::Write_U32(view, request.io_vectors[0].address + view * 0xD8); + Memory::CopyToEmu(request.io_vectors[0].address + 4 + view * 0xD8, &ticket[0x1D0 + (view * DiscIO::CNANDContentLoader::TICKET_SIZE)], 212); } } @@ -849,18 +834,19 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETVIEWS for titleID: %08x/%08x (MaxViews = %i)", (u32)(TitleID >> 32), (u32)TitleID, maxViews); - Memory::Write_U32(retVal, _CommandAddress + 0x4); + request.SetReturnValue(retVal); return GetDefaultReply(); } break; case IOCTL_ES_GETTMDVIEWCNT: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETTMDVIEWCNT no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, + "IOCTL_ES_GETTMDVIEWCNT no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTMDVIEWCNT no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); @@ -873,9 +859,9 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) TMDViewCnt += (u32)Loader.GetContentSize() * (4 + 2 + 2 + 8); // content id, index, type, size } - Memory::Write_U32(TMDViewCnt, Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U32(TMDViewCnt, request.io_vectors[0].address); - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDViewCnt); @@ -885,12 +871,13 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_GETTMDVIEWS: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "IOCTL_ES_GETTMDVIEWCNT no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, + "IOCTL_ES_GETTMDVIEWCNT no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTMDVIEWCNT no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); + u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); @@ -899,7 +886,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) if (Loader.IsValid()) { - u32 Address = Buffer.PayloadBuffer[0].m_Address; + u32 Address = request.io_vectors[0].address; Memory::CopyToEmu(Address, Loader.GetTMDView(), DiscIO::CNANDContentLoader::TMD_VIEW_SIZE); Address += DiscIO::CNANDContentLoader::TMD_VIEW_SIZE; @@ -923,9 +910,9 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) } _dbg_assert_(WII_IPC_ES, - (Address - Buffer.PayloadBuffer[0].m_Address) == Buffer.PayloadBuffer[0].m_Size); + (Address - request.io_vectors[0].address) == request.io_vectors[0].size); } - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWS: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); @@ -934,51 +921,51 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) break; case IOCTL_ES_GETCONSUMPTION: // This is at least what crediar's ES module does - Memory::Write_U32(0, Buffer.PayloadBuffer[1].m_Address); - Memory::Write_U32(0, _CommandAddress + 0x4); - INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETCONSUMPTION:%d", Memory::Read_U32(_CommandAddress + 4)); + Memory::Write_U32(0, request.io_vectors[1].address); + request.SetReturnValue(IPC_SUCCESS); + INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETCONSUMPTION"); return GetDefaultReply(); case IOCTL_ES_DELETETICKET: { - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_DELETETICKET: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); if (File::Delete(Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT))) { - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); } else { // Presumably return -1017 when delete fails - Memory::Write_U32(ES_PARAMTER_SIZE_OR_ALIGNMENT, _CommandAddress + 0x4); + request.SetReturnValue(ES_PARAMETER_SIZE_OR_ALIGNMENT); } } break; case IOCTL_ES_DELETETITLECONTENT: { - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_DELETETITLECONTENT: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); if (DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID, Common::FROM_SESSION_ROOT)) { - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); } else { // Presumably return -1017 when title not installed TODO verify - Memory::Write_U32(ES_PARAMTER_SIZE_OR_ALIGNMENT, _CommandAddress + 0x4); + request.SetReturnValue(ES_PARAMETER_SIZE_OR_ALIGNMENT); } } break; case IOCTL_ES_GETSTOREDTMDSIZE: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, "IOCTL_ES_GETSTOREDTMDSIZE no in buffer"); - // _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_ES_GETSTOREDTMDSIZE + // _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_ES_GETSTOREDTMDSIZE // no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); _dbg_assert_(WII_IPC_ES, Loader.IsValid()); @@ -988,10 +975,10 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) TMDCnt += DiscIO::CNANDContentLoader::TMD_HEADER_SIZE; TMDCnt += (u32)Loader.GetContentSize() * DiscIO::CNANDContentLoader::CONTENT_HEADER_SIZE; } - if (Buffer.NumberPayloadBuffer) - Memory::Write_U32(TMDCnt, Buffer.PayloadBuffer[0].m_Address); + if (request.io_vectors.size()) + Memory::Write_U32(TMDCnt, request.io_vectors[0].address); - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDCnt); @@ -1000,28 +987,29 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) break; case IOCTL_ES_GETSTOREDTMD: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer > 0, "IOCTL_ES_GETSTOREDTMD no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() > 0, + "IOCTL_ES_GETSTOREDTMD no in buffer"); // requires 1 inbuffer and no outbuffer, presumably outbuffer required when second inbuffer is // used for maxcount (allocated mem?) // called with 1 inbuffer after deleting a titleid - //_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETSTOREDTMD no out + //_dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETSTOREDTMD no out // buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u32 MaxCount = 0; - if (Buffer.NumberInBuffer > 1) + if (request.in_vectors.size() > 1) { // TODO: actually use this param in when writing to the outbuffer :/ - MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); + MaxCount = Memory::Read_U32(request.in_vectors[1].address); } const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x buffer size: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); - if (Loader.IsValid() && Buffer.NumberPayloadBuffer) + if (Loader.IsValid() && request.io_vectors.size()) { - u32 Address = Buffer.PayloadBuffer[0].m_Address; + u32 Address = request.io_vectors[0].address; Memory::CopyToEmu(Address, Loader.GetTMDHeader(), DiscIO::CNANDContentLoader::TMD_HEADER_SIZE); @@ -1036,9 +1024,9 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) } _dbg_assert_(WII_IPC_ES, - (Address - Buffer.PayloadBuffer[0].m_Address) == Buffer.PayloadBuffer[0].m_Size); + (Address - request.io_vectors[0].address) == request.io_vectors[0].size); } - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); @@ -1048,12 +1036,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_ENCRYPT: { - u32 keyIndex = Memory::Read_U32(Buffer.InBuffer[0].m_Address); - u8* IV = Memory::GetPointer(Buffer.InBuffer[1].m_Address); - u8* source = Memory::GetPointer(Buffer.InBuffer[2].m_Address); - u32 size = Buffer.InBuffer[2].m_Size; - u8* newIV = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); - u8* destination = Memory::GetPointer(Buffer.PayloadBuffer[1].m_Address); + u32 keyIndex = Memory::Read_U32(request.in_vectors[0].address); + u8* IV = Memory::GetPointer(request.in_vectors[1].address); + u8* source = Memory::GetPointer(request.in_vectors[2].address); + u32 size = request.in_vectors[2].size; + u8* newIV = Memory::GetPointer(request.io_vectors[0].address); + u8* destination = Memory::GetPointer(request.io_vectors[1].address); mbedtls_aes_context AES_ctx; mbedtls_aes_setkey_enc(&AES_ctx, keyTable[keyIndex], 128); @@ -1067,12 +1055,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_DECRYPT: { - u32 keyIndex = Memory::Read_U32(Buffer.InBuffer[0].m_Address); - u8* IV = Memory::GetPointer(Buffer.InBuffer[1].m_Address); - u8* source = Memory::GetPointer(Buffer.InBuffer[2].m_Address); - u32 size = Buffer.InBuffer[2].m_Size; - u8* newIV = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); - u8* destination = Memory::GetPointer(Buffer.PayloadBuffer[1].m_Address); + u32 keyIndex = Memory::Read_U32(request.in_vectors[0].address); + u8* IV = Memory::GetPointer(request.in_vectors[1].address); + u8* source = Memory::GetPointer(request.in_vectors[2].address); + u32 size = request.in_vectors[2].size; + u8* newIV = Memory::GetPointer(request.io_vectors[0].address); + u8* destination = Memory::GetPointer(request.io_vectors[1].address); DecryptContent(keyIndex, IV, source, size, newIV, destination); @@ -1083,17 +1071,17 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_LAUNCH: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 2); bool bSuccess = false; bool bReset = false; u16 IOSv = 0xffff; - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 view = Memory::Read_U32(Buffer.InBuffer[1].m_Address); - u64 ticketid = Memory::Read_U64(Buffer.InBuffer[1].m_Address + 4); - u32 devicetype = Memory::Read_U32(Buffer.InBuffer[1].m_Address + 12); - u64 titleid = Memory::Read_U64(Buffer.InBuffer[1].m_Address + 16); - u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address + 24); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); + u32 view = Memory::Read_U32(request.in_vectors[1].address); + u64 ticketid = Memory::Read_U64(request.in_vectors[1].address + 4); + u32 devicetype = Memory::Read_U32(request.in_vectors[1].address + 12); + u64 titleid = Memory::Read_U64(request.in_vectors[1].address + 16); + u16 access = Memory::Read_U16(request.in_vectors[1].address + 24); // ES_LAUNCH should probably reset thw whole state, which at least means closing all open files. // leaving them open through ES_LAUNCH may cause hangs and other funky behavior @@ -1199,7 +1187,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // could clobber the DOL we just loaded. if (!bReset) { - Memory::Write_U32(0, _CommandAddress + 0x4); + request.SetReturnValue(IPC_SUCCESS); } ERROR_LOG(WII_IPC_ES, @@ -1213,14 +1201,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) if (!bReset) { // The command type is overwritten with the reply type. - Memory::Write_U32(IPC_REPLY, _CommandAddress); + Memory::Write_U32(IPC_REPLY, request.address); // IOS also writes back the command that was responded to in the FD field. - Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8); + Memory::Write_U32(IPC_CMD_IOCTLV, request.address + 8); } // Generate a "reply" to the IPC command. ES_LAUNCH is unique because it // involves restarting IOS; IOS generates two acknowledgements in a row. - WII_IPC_HLE_Interface::EnqueueCommandAcknowledgement(_CommandAddress, 0); + WII_IPC_HLE_Interface::EnqueueCommandAcknowledgement(request.address, 0); return GetNoReply(); } break; @@ -1231,14 +1219,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // -1017 // if the IOS didn't find the Korean keys and 0 if it does. 0 leads to a error 003 INFO_LOG(WII_IPC_ES, "IOCTL_ES_CHECKKOREAREGION: Title checked for Korean keys."); - Memory::Write_U32(ES_PARAMTER_SIZE_OR_ALIGNMENT, _CommandAddress + 0x4); + request.SetReturnValue(ES_PARAMETER_SIZE_OR_ALIGNMENT); return GetDefaultReply(); case IOCTL_ES_GETDEVICECERT: // (Input: none, Output: 384 bytes) { INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICECERT"); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); - u8* destination = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 1); + u8* destination = Memory::GetPointer(request.io_vectors[0].address); EcWii& ec = EcWii::GetInstance(); get_ng_cert(destination, ec.getNgId(), ec.getNgKeyId(), ec.getNgPriv(), ec.getNgSig()); @@ -1248,10 +1236,10 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_SIGN: { INFO_LOG(WII_IPC_ES, "IOCTL_ES_SIGN"); - u8* ap_cert_out = Memory::GetPointer(Buffer.PayloadBuffer[1].m_Address); - u8* data = Memory::GetPointer(Buffer.InBuffer[0].m_Address); - u32 data_size = Buffer.InBuffer[0].m_Size; - u8* sig_out = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); + u8* ap_cert_out = Memory::GetPointer(request.io_vectors[1].address); + u8* data = Memory::GetPointer(request.in_vectors[0].address); + u32 data_size = request.in_vectors[0].size; + u8* sig_out = Memory::GetPointer(request.io_vectors[0].address); EcWii& ec = EcWii::GetInstance(); get_ap_sig_and_cert(sig_out, ap_cert_out, m_TitleID, data, data_size, ec.getNgPriv(), @@ -1264,7 +1252,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETBOOT2VERSION"); Memory::Write_U32( - 4, Buffer.PayloadBuffer[0].m_Address); // as of 26/02/2012, this was latest bootmii version + 4, request.io_vectors[0].address); // as of 26/02/2012, this was latest bootmii version } break; @@ -1277,18 +1265,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_GETOWNEDTITLECNT: INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETOWNEDTITLECNT"); - Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U32(0, request.io_vectors[0].address); break; default: - INFO_LOG(WII_IPC_ES, "CWII_IPC_HLE_Device_es: 0x%x", Buffer.Parameter); - INFO_LOG(WII_IPC_ES, "command.Parameter: 0x%08x", Buffer.Parameter); - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE); } - // Write return value (0 means OK) - Memory::Write_U32(0, _CommandAddress + 0x4); - + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h index 9ca52d821e..9f4afe4c91 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h @@ -27,8 +27,6 @@ class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName); - virtual ~CWII_IPC_HLE_Device_es(); - void LoadWAD(const std::string& _rContentFile); // Internal implementation of the ES_DECRYPT ioctlv. @@ -38,10 +36,9 @@ public: void DoState(PointerWrap& p) override; - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; static u32 ES_DIVerify(const std::vector& tmd); @@ -116,7 +113,7 @@ private: ES_INVALID_TMD = -106, // or access denied ES_READ_LESS_DATA_THAN_EXPECTED = -1009, ES_WRITE_FAILURE = -1010, - ES_PARAMTER_SIZE_OR_ALIGNMENT = -1017, + ES_PARAMETER_SIZE_OR_ALIGNMENT = -1017, ES_HASH_DOESNT_MATCH = -1022, ES_MEM_ALLOC_FAILED = -1024, ES_INCORRECT_ACCESS_RIGHT = -1026, From 8629a1f11c755ab4860f5317eab53714dde73a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 15:07:33 +0100 Subject: [PATCH 14/16] IOS HLE: Deduplicate request code in WFS --- .../IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp | 71 ++++++++----------- .../IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h | 3 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp | 58 +++++---------- .../Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h | 4 +- 4 files changed, 52 insertions(+), 84 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp index 4fabc7200f..61af1d8e9c 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp @@ -29,17 +29,11 @@ CWII_IPC_HLE_Device_usb_wfssrv::CWII_IPC_HLE_Device_usb_wfssrv(u32 device_id, m_device_name = "msc01"; } -IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(const IOSIOCtlRequest& request) { - u32 command = Memory::Read_U32(command_address + 0xC); - u32 buffer_in = Memory::Read_U32(command_address + 0x10); - u32 buffer_in_size = Memory::Read_U32(command_address + 0x14); - u32 buffer_out = Memory::Read_U32(command_address + 0x18); - u32 buffer_out_size = Memory::Read_U32(command_address + 0x1C); - int return_error_code = IPC_SUCCESS; - switch (command) + switch (request.request) { case IOCTL_WFS_INIT: // TODO(wfs): Implement. @@ -48,56 +42,56 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) case IOCTL_WFS_DEVICE_INFO: INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_DEVICE_INFO"); - Memory::Write_U64(16ull << 30, buffer_out); // 16GB storage. - Memory::Write_U8(4, buffer_out + 8); + Memory::Write_U64(16ull << 30, request.buffer_out); // 16GB storage. + Memory::Write_U8(4, request.buffer_out + 8); break; case IOCTL_WFS_GET_DEVICE_NAME: { INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GET_DEVICE_NAME"); - Memory::Write_U8(static_cast(m_device_name.size()), buffer_out); - Memory::CopyToEmu(buffer_out + 1, m_device_name.data(), m_device_name.size()); + Memory::Write_U8(static_cast(m_device_name.size()), request.buffer_out); + Memory::CopyToEmu(request.buffer_out + 1, m_device_name.data(), m_device_name.size()); break; } case IOCTL_WFS_ATTACH_DETACH_2: // TODO(wfs): Implement. - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH_2(%d)", command); - Memory::Write_U32(1, buffer_out); - Memory::Write_U32(0, buffer_out + 4); // device id? - Memory::Write_U32(0, buffer_out + 8); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH_2(%u)", request.request); + Memory::Write_U32(1, request.buffer_out); + Memory::Write_U32(0, request.buffer_out + 4); // device id? + Memory::Write_U32(0, request.buffer_out + 8); break; case IOCTL_WFS_ATTACH_DETACH: - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH(%d)", command); - Memory::Write_U32(1, buffer_out); - Memory::Write_U32(0, buffer_out + 4); - Memory::Write_U32(0, buffer_out + 8); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH(%u)", request.request); + Memory::Write_U32(1, request.buffer_out); + Memory::Write_U32(0, request.buffer_out + 4); + Memory::Write_U32(0, request.buffer_out + 8); return GetNoReply(); // TODO(wfs): Globbing is not really implemented, we just fake the one case // (listing /vol/*) which is required to get the installer to work. case IOCTL_WFS_GLOB_START: - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_START(%d)", command); - Memory::Memset(buffer_out, 0, buffer_out_size); - memcpy(Memory::GetPointer(buffer_out + 0x14), m_device_name.data(), m_device_name.size()); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_START(%u)", request.request); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); + Memory::CopyToEmu(request.buffer_out + 0x14, m_device_name.data(), m_device_name.size()); break; case IOCTL_WFS_GLOB_NEXT: - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_NEXT(%d)", command); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_NEXT(%u)", request.request); return_error_code = WFS_EEMPTY; break; case IOCTL_WFS_GLOB_END: - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_END(%d)", command); - Memory::Memset(buffer_out, 0, buffer_out_size); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_END(%u)", request.request); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); break; case IOCTL_WFS_OPEN: { - u32 mode = Memory::Read_U32(buffer_in); - u16 path_len = Memory::Read_U16(buffer_in + 0x20); - std::string path = Memory::GetString(buffer_in + 0x22, path_len); + u32 mode = Memory::Read_U32(request.buffer_in); + u16 path_len = Memory::Read_U16(request.buffer_in + 0x20); + std::string path = Memory::GetString(request.buffer_in + 0x22, path_len); u16 fd = GetNewFileDescriptor(); FileDescriptor* fd_obj = &m_fds[fd]; @@ -115,13 +109,13 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) } INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_OPEN(%s, %d) -> %d", path.c_str(), mode, fd); - Memory::Write_U16(fd, buffer_out + 0x14); + Memory::Write_U16(fd, request.buffer_out + 0x14); break; } case IOCTL_WFS_CLOSE: { - u16 fd = Memory::Read_U16(buffer_in + 0x4); + u16 fd = Memory::Read_U16(request.buffer_in + 0x4); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_CLOSE(%d)", fd); ReleaseFileDescriptor(fd); break; @@ -129,9 +123,9 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) case IOCTL_WFS_READ: { - u32 addr = Memory::Read_U32(buffer_in); - u16 fd = Memory::Read_U16(buffer_in + 0xC); - u32 size = Memory::Read_U32(buffer_in + 8); + u32 addr = Memory::Read_U32(request.buffer_in); + u16 fd = Memory::Read_U16(request.buffer_in + 0xC); + u32 size = Memory::Read_U32(request.buffer_in + 8); FileDescriptor* fd_obj = FindFileDescriptor(fd); if (fd_obj == nullptr) @@ -158,15 +152,12 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) default: // TODO(wfs): Should be returning -3. However until we have everything // properly stubbed it's easier to simulate the methods succeeding. - WARN_LOG(WII_IPC_HLE, "%s unimplemented IOCtl(0x%08x, size_in=%08x, size_out=%08x)\n%s\n%s", - m_name.c_str(), command, buffer_in_size, buffer_out_size, - HexDump(Memory::GetPointer(buffer_in), buffer_in_size).c_str(), - HexDump(Memory::GetPointer(buffer_out), buffer_out_size).c_str()); - Memory::Memset(buffer_out, 0, buffer_out_size); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE, LogTypes::LWARNING); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); break; } - Memory::Write_U32(return_error_code, command_address + 4); + request.SetReturnValue(return_error_code); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h index f722bde402..5616424bd8 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h @@ -23,8 +23,7 @@ class CWII_IPC_HLE_Device_usb_wfssrv : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_usb_wfssrv(u32 device_id, const std::string& device_name); - IPCCommandResult IOCtl(u32 command_address) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: // WFS device name, e.g. msc01/msc02. diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp index 040ec001c0..bbdd2cb67d 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp @@ -79,28 +79,16 @@ CWII_IPC_HLE_Device_wfsi::CWII_IPC_HLE_Device_wfsi(u32 device_id, const std::str { } -IPCCommandResult CWII_IPC_HLE_Device_wfsi::Open(u32 command_address, u32 mode) +IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(const IOSIOCtlRequest& request) { - INFO_LOG(WII_IPC_HLE, "/dev/wfsi: Open"); - return IWII_IPC_HLE_Device::Open(command_address, mode); -} - -IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) -{ - u32 command = Memory::Read_U32(command_address + 0xC); - u32 buffer_in = Memory::Read_U32(command_address + 0x10); - u32 buffer_in_size = Memory::Read_U32(command_address + 0x14); - u32 buffer_out = Memory::Read_U32(command_address + 0x18); - u32 buffer_out_size = Memory::Read_U32(command_address + 0x1C); - u32 return_error_code = IPC_SUCCESS; - switch (command) + switch (request.request) { case IOCTL_WFSI_PREPARE_DEVICE: { - u32 tmd_addr = Memory::Read_U32(buffer_in); - u32 tmd_size = Memory::Read_U32(buffer_in + 4); + u32 tmd_addr = Memory::Read_U32(request.buffer_in); + u32 tmd_size = Memory::Read_U32(request.buffer_in + 4); INFO_LOG(WII_IPC_HLE, "IOCTL_WFSI_PREPARE_DEVICE"); @@ -135,11 +123,12 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) case IOCTL_WFSI_PREPARE_CONTENT: { - const char* ioctl_name = command == IOCTL_WFSI_PREPARE_PROFILE ? "IOCTL_WFSI_PREPARE_PROFILE" : - "IOCTL_WFSI_PREPARE_CONTENT"; + const char* ioctl_name = request.request == IOCTL_WFSI_PREPARE_PROFILE ? + "IOCTL_WFSI_PREPARE_PROFILE" : + "IOCTL_WFSI_PREPARE_CONTENT"; // Initializes the IV from the index of the content in the TMD contents. - u32 content_id = Memory::Read_U32(buffer_in + 8); + u32 content_id = Memory::Read_U32(request.buffer_in + 8); TMDReader::Content content_info; if (!m_tmd.FindContentById(content_id, &content_info)) { @@ -161,12 +150,13 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) case IOCTL_WFSI_IMPORT_PROFILE: case IOCTL_WFSI_IMPORT_CONTENT: { - const char* ioctl_name = command == IOCTL_WFSI_IMPORT_PROFILE ? "IOCTL_WFSI_IMPORT_PROFILE" : - "IOCTL_WFSI_IMPORT_CONTENT"; + const char* ioctl_name = request.request == IOCTL_WFSI_IMPORT_PROFILE ? + "IOCTL_WFSI_IMPORT_PROFILE" : + "IOCTL_WFSI_IMPORT_CONTENT"; - u32 content_id = Memory::Read_U32(buffer_in + 0xC); - u32 input_ptr = Memory::Read_U32(buffer_in + 0x10); - u32 input_size = Memory::Read_U32(buffer_in + 0x14); + u32 content_id = Memory::Read_U32(request.buffer_in + 0xC); + u32 input_ptr = Memory::Read_U32(request.buffer_in + 0x10); + u32 input_size = Memory::Read_U32(request.buffer_in + 0x14); INFO_LOG(WII_IPC_HLE, "%s: %08x bytes of data at %08x from content id %d", ioctl_name, content_id, input_ptr, input_size); @@ -181,7 +171,7 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) case IOCTL_WFSI_FINALIZE_PROFILE: case IOCTL_WFSI_FINALIZE_CONTENT: { - const char* ioctl_name = command == IOCTL_WFSI_FINALIZE_PROFILE ? + const char* ioctl_name = request.request == IOCTL_WFSI_FINALIZE_PROFILE ? "IOCTL_WFSI_FINALIZE_PROFILE" : "IOCTL_WFSI_FINALIZE_CONTENT"; INFO_LOG(WII_IPC_HLE, "%s", ioctl_name); @@ -225,7 +215,7 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) case IOCTL_WFSI_SET_DEVICE_NAME: INFO_LOG(WII_IPC_HLE, "IOCTL_WFSI_SET_DEVICE_NAME"); - m_device_name = Memory::GetString(buffer_in); + m_device_name = Memory::GetString(request.buffer_in); break; case IOCTL_WFSI_APPLY_TITLE_PROFILE: @@ -243,21 +233,11 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) // TODO(wfs): Should be returning an error. However until we have // everything properly stubbed it's easier to simulate the methods // succeeding. - WARN_LOG(WII_IPC_HLE, "%s unimplemented IOCtl(0x%08x, size_in=%08x, size_out=%08x)\n%s\n%s", - m_name.c_str(), command, buffer_in_size, buffer_out_size, - HexDump(Memory::GetPointer(buffer_in), buffer_in_size).c_str(), - HexDump(Memory::GetPointer(buffer_out), buffer_out_size).c_str()); - Memory::Memset(buffer_out, 0, buffer_out_size); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE, LogTypes::LWARNING); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); break; } - Memory::Write_U32(return_error_code, command_address + 4); - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtlV(u32 command_address) -{ - ERROR_LOG(WII_IPC_HLE, "IOCtlV on /dev/wfsi -- unsupported"); - Memory::Write_U32(IPC_EINVAL, command_address + 4); + request.SetReturnValue(return_error_code); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h index d5afa62a3a..68cffd0eee 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h @@ -34,9 +34,7 @@ class CWII_IPC_HLE_Device_wfsi : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_wfsi(u32 device_id, const std::string& device_name); - IPCCommandResult Open(u32 command_address, u32 mode) override; - IPCCommandResult IOCtl(u32 command_address) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: std::string m_device_name; From c6b1cfb222ed2bc6fa4c5128056da354c6b5a0b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 13:49:12 +0100 Subject: [PATCH 15/16] IOS HLE: Remove old structs and methods Now that everything has been changed to use the new structs, the old methods and structs can be removed. And while I was changing the base device class, I also moved the "unsupported command" code to a separate function. It was pretty silly to copy the same 3 lines for ~5 commands. --- Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp | 5 - Source/Core/Core/IPC_HLE/WII_IPC_HLE.h | 2 - .../Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp | 119 ++---------------- Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h | 42 ++----- .../IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp | 8 -- 5 files changed, 18 insertions(+), 158 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp index 170f142628..1b07160162 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp @@ -458,11 +458,6 @@ void EnqueueReply(const IOSRequest& request, int cycles_in_future, CoreTiming::F CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from); } -void EnqueueReply(u32 command_address, int cycles_in_future, CoreTiming::FromThread from) -{ - EnqueueReply(IOSRequest{command_address}, cycles_in_future, from); -} - void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future) { CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h index c57924c1b4..62284317a2 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h @@ -72,8 +72,6 @@ void ExecuteCommand(u32 address); void EnqueueRequest(u32 address); void EnqueueReply(const IOSRequest& request, int cycles_in_future = 0, CoreTiming::FromThread from = CoreTiming::FromThread::CPU); -void EnqueueReply(u32 command_address, int cycles_in_future = 0, - CoreTiming::FromThread from = CoreTiming::FromThread::CPU); void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future = 0); } // end of namespace WII_IPC_HLE_Interface diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp index e4b33e12d7..ca66e80fd6 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include "Common/Logging/Log.h" #include "Common/StringUtil.h" @@ -11,45 +12,6 @@ #include "Core/IPC_HLE/WII_IPC_HLE.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device.h" -// TODO: remove this once all device classes have been migrated. -SIOCtlVBuffer::SIOCtlVBuffer(const u32 address) : m_Address(address) -{ - // These are the Ioctlv parameters in the IOS communication. The BufferVector - // is a memory address offset at where the in and out buffer addresses are - // stored. - Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0 - NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1 - NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2 - BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3 - - // The start of the out buffer - u32 BufferVectorOffset = BufferVector; - - // Write the address and size for all in messages - for (u32 i = 0; i < NumberInBuffer; i++) - { - SBuffer Buffer; - Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); - BufferVectorOffset += 4; - Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); - BufferVectorOffset += 4; - InBuffer.push_back(Buffer); - DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address, Buffer.m_Size); - } - - // Write the address and size for all out or in-out messages - for (u32 i = 0; i < NumberPayloadBuffer; i++) - { - SBuffer Buffer; - Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); - BufferVectorOffset += 4; - Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); - BufferVectorOffset += 4; - PayloadBuffer.push_back(Buffer); - DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address, Buffer.m_Size); - } -} - IOSRequest::IOSRequest(const u32 address_) : address(address_) { command = static_cast(Memory::Read_U32(address)); @@ -180,87 +142,26 @@ void IWII_IPC_HLE_Device::DoStateShared(PointerWrap& p) p.Do(m_is_active); } -// TODO: remove the wrappers once all device classes have been migrated. IOSReturnCode IWII_IPC_HLE_Device::Open(const IOSOpenRequest& request) -{ - Open(request.address, request.flags); - return static_cast(Memory::Read_U32(request.address + 4)); -} - -IPCCommandResult IWII_IPC_HLE_Device::Open(u32 command_address, u32 mode) { m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } void IWII_IPC_HLE_Device::Close() -{ - Close(0, true); -} - -IPCCommandResult IWII_IPC_HLE_Device::Close(u32 command_address, bool force) { m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult IWII_IPC_HLE_Device::Seek(const IOSSeekRequest& request) +IPCCommandResult IWII_IPC_HLE_Device::Unsupported(const IOSRequest& request) { - return Seek(request.address); -} - -IPCCommandResult IWII_IPC_HLE_Device::Seek(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support Seek()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); -} - -IPCCommandResult IWII_IPC_HLE_Device::Read(const IOSReadWriteRequest& request) -{ - return Read(request.address); -} - -IPCCommandResult IWII_IPC_HLE_Device::Read(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support Read()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); -} - -IPCCommandResult IWII_IPC_HLE_Device::Write(const IOSReadWriteRequest& request) -{ - return Write(request.address); -} - -IPCCommandResult IWII_IPC_HLE_Device::Write(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support Write()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); -} - -IPCCommandResult IWII_IPC_HLE_Device::IOCtl(const IOSIOCtlRequest& request) -{ - return IOCtl(request.address); -} - -IPCCommandResult IWII_IPC_HLE_Device::IOCtl(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support IOCtl()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); -} - -IPCCommandResult IWII_IPC_HLE_Device::IOCtlV(const IOSIOCtlVRequest& request) -{ - return IOCtlV(request.address); -} - -IPCCommandResult IWII_IPC_HLE_Device::IOCtlV(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support IOCtlV()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); + static std::map names = {{{IPC_CMD_READ, "Read"}, + {IPC_CMD_WRITE, "Write"}, + {IPC_CMD_SEEK, "Seek"}, + {IPC_CMD_IOCTL, "IOCtl"}, + {IPC_CMD_IOCTLV, "IOCtlV"}}}; + WARN_LOG(WII_IPC_HLE, "%s does not support %s()", m_name.c_str(), names[request.command].c_str()); + request.SetReturnValue(IPC_EINVAL); return GetDefaultReply(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h index b56b6ba4ec..9f9113d44b 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h @@ -40,25 +40,6 @@ enum IOSReturnCode : s32 IPC_EESEXHAUSTED = -1016, // Max of 2 ES handles exceeded }; -// A struct for IOS ioctlv calls -// TODO: remove this once nothing uses this anymore. -struct SIOCtlVBuffer -{ - explicit SIOCtlVBuffer(u32 address); - - const u32 m_Address; - u32 Parameter; - u32 NumberInBuffer; - u32 NumberPayloadBuffer; - u32 BufferVector; - struct SBuffer - { - u32 m_Address, m_Size; - }; - std::vector InBuffer; - std::vector PayloadBuffer; -}; - struct IOSRequest { u32 address = 0; @@ -167,21 +148,11 @@ public: // Replies to Open and Close requests are sent by WII_IPC_HLE, not by the devices themselves. virtual IOSReturnCode Open(const IOSOpenRequest& request); virtual void Close(); - virtual IPCCommandResult Seek(const IOSSeekRequest& request); - virtual IPCCommandResult Read(const IOSReadWriteRequest& request); - virtual IPCCommandResult Write(const IOSReadWriteRequest& request); - virtual IPCCommandResult IOCtl(const IOSIOCtlRequest& request); - virtual IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request); - - // TODO: remove these once all device classes have been migrated. - virtual IPCCommandResult Open(u32 command_address, u32 mode); - virtual IPCCommandResult Close(u32 command_address, bool force = false); - virtual IPCCommandResult Seek(u32 command_address); - virtual IPCCommandResult Read(u32 command_address); - virtual IPCCommandResult Write(u32 command_address); - virtual IPCCommandResult IOCtl(u32 command_address); - virtual IPCCommandResult IOCtlV(u32 command_address); - + virtual IPCCommandResult Seek(const IOSSeekRequest& seek) { return Unsupported(seek); } + virtual IPCCommandResult Read(const IOSReadWriteRequest& read) { return Unsupported(read); } + virtual IPCCommandResult Write(const IOSReadWriteRequest& write) { return Unsupported(write); } + virtual IPCCommandResult IOCtl(const IOSIOCtlRequest& ioctl) { return Unsupported(ioctl); } + virtual IPCCommandResult IOCtlV(const IOSIOCtlVRequest& ioctlv) { return Unsupported(ioctlv); } virtual void Update() {} virtual DeviceType GetDeviceType() const { return m_device_type; } virtual bool IsOpened() const { return m_is_active; } @@ -194,4 +165,7 @@ protected: u32 m_device_id; DeviceType m_device_type; bool m_is_active = false; + +private: + IPCCommandResult Unsupported(const IOSRequest& request); }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp index 61af1d8e9c..3038a1871e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp @@ -161,14 +161,6 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(const IOSIOCtlRequest& re return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtlV(u32 command_address) -{ - SIOCtlVBuffer command_buffer(command_address); - ERROR_LOG(WII_IPC_HLE, "IOCtlV on /dev/usb/wfssrv -- unsupported"); - Memory::Write_U32(IPC_EINVAL, command_address + 4); - return GetDefaultReply(); -} - CWII_IPC_HLE_Device_usb_wfssrv::FileDescriptor* CWII_IPC_HLE_Device_usb_wfssrv::FindFileDescriptor(u16 fd) { From 25f89ccae83adce6188d76b2f06fdc525d2d894e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Tue, 17 Jan 2017 00:28:22 +0100 Subject: [PATCH 16/16] IOS HLE: Specify the return code when replying This makes more sense than setting the return code on the request struct first before replying. Ref: https://github.com/dolphin-emu/dolphin/pull/4661#discussion_r96273253 --- Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp | 19 ++- Source/Core/Core/IPC_HLE/WII_IPC_HLE.h | 3 +- .../Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp | 16 +-- Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h | 3 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp | 8 +- .../IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 12 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp | 125 ++++++------------ .../Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp | 10 +- .../Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h | 2 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 19 +-- .../Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp | 18 +-- .../Core/IPC_HLE/WII_IPC_HLE_Device_net.h | 3 +- .../IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp | 11 +- .../IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp | 12 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp | 17 +-- .../Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp | 6 +- .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp | 22 ++- .../WII_IPC_HLE_Device_usb_bt_real.cpp | 19 +-- .../IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp | 3 +- .../IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp | 16 +-- .../IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp | 3 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp | 3 +- Source/Core/Core/IPC_HLE/WII_Socket.cpp | 3 +- Source/Core/Core/IPC_HLE/WII_Socket.h | 3 +- 24 files changed, 126 insertions(+), 230 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp index 1b07160162..3b2e33e06e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp @@ -393,24 +393,19 @@ static IPCCommandResult HandleCommand(const IOSRequest& request) { IOSOpenRequest open_request{request.address}; const s32 new_fd = OpenDevice(open_request); - open_request.SetReturnValue(new_fd); - return IWII_IPC_HLE_Device::GetDefaultReply(); + return IWII_IPC_HLE_Device::GetDefaultReply(new_fd); } const auto device = (request.fd < IPC_MAX_FDS) ? s_fdmap[request.fd] : nullptr; if (!device) - { - request.SetReturnValue(IPC_EINVAL); - return IWII_IPC_HLE_Device::GetDefaultReply(); - } + return IWII_IPC_HLE_Device::GetDefaultReply(IPC_EINVAL); switch (request.command) { case IPC_CMD_CLOSE: s_fdmap[request.fd].reset(); device->Close(); - request.SetReturnValue(IPC_SUCCESS); - return IWII_IPC_HLE_Device::GetDefaultReply(); + return IWII_IPC_HLE_Device::GetDefaultReply(IPC_SUCCESS); case IPC_CMD_READ: return device->Read(IOSReadWriteRequest{request.address}); case IPC_CMD_WRITE: @@ -423,7 +418,7 @@ static IPCCommandResult HandleCommand(const IOSRequest& request) return device->IOCtlV(IOSIOCtlVRequest{request.address}); default: _assert_msg_(WII_IPC_HLE, false, "Unexpected command: %x", request.command); - return IWII_IPC_HLE_Device::GetDefaultReply(); + return IWII_IPC_HLE_Device::GetDefaultReply(IPC_EINVAL); } } @@ -439,7 +434,7 @@ void ExecuteCommand(const u32 address) s_last_reply_time = CoreTiming::GetTicks() + result.reply_delay_ticks; if (result.send_reply) - EnqueueReply(request, static_cast(result.reply_delay_ticks)); + EnqueueReply(request, result.return_value, static_cast(result.reply_delay_ticks)); } // Happens AS SOON AS IPC gets a new pointer! @@ -449,8 +444,10 @@ void EnqueueRequest(u32 address) } // Called to send a reply to an IOS syscall -void EnqueueReply(const IOSRequest& request, int cycles_in_future, CoreTiming::FromThread from) +void EnqueueReply(const IOSRequest& request, const s32 return_value, int cycles_in_future, + CoreTiming::FromThread from) { + Memory::Write_U32(static_cast(return_value), request.address + 4); // IOS writes back the command that was responded to in the FD field. Memory::Write_U32(request.command, request.address + 8); // IOS also overwrites the command type with the reply type. diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h index 62284317a2..11e9abb2a1 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h @@ -18,6 +18,7 @@ class PointerWrap; struct IPCCommandResult { + s32 return_value; bool send_reply; u64 reply_delay_ticks; }; @@ -70,7 +71,7 @@ void UpdateDevices(); void ExecuteCommand(u32 address); void EnqueueRequest(u32 address); -void EnqueueReply(const IOSRequest& request, int cycles_in_future = 0, +void EnqueueReply(const IOSRequest& request, s32 return_value, int cycles_in_future = 0, CoreTiming::FromThread from = CoreTiming::FromThread::CPU); void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future = 0); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp index ca66e80fd6..59d0b1191c 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp @@ -18,11 +18,6 @@ IOSRequest::IOSRequest(const u32 address_) : address(address_) fd = Memory::Read_U32(address + 8); } -void IOSRequest::SetReturnValue(const s32 new_return_value) const -{ - Memory::Write_U32(static_cast(new_return_value), address + 4); -} - IOSOpenRequest::IOSOpenRequest(const u32 address_) : IOSRequest(address_) { path = Memory::GetString(Memory::Read_U32(address + 0xc)); @@ -161,19 +156,18 @@ IPCCommandResult IWII_IPC_HLE_Device::Unsupported(const IOSRequest& request) {IPC_CMD_IOCTL, "IOCtl"}, {IPC_CMD_IOCTLV, "IOCtlV"}}}; WARN_LOG(WII_IPC_HLE, "%s does not support %s()", m_name.c_str(), names[request.command].c_str()); - request.SetReturnValue(IPC_EINVAL); - return GetDefaultReply(); + return GetDefaultReply(IPC_EINVAL); } // Returns an IPCCommandResult for a reply that takes 250 us (arbitrarily chosen value) -IPCCommandResult IWII_IPC_HLE_Device::GetDefaultReply() +IPCCommandResult IWII_IPC_HLE_Device::GetDefaultReply(const s32 return_value) { - return {true, SystemTimers::GetTicksPerSecond() / 4000}; + return {return_value, true, SystemTimers::GetTicksPerSecond() / 4000}; } // Returns an IPCCommandResult with no reply. Useful for async commands that will generate a reply -// later +// later. This takes no return value because it won't be used. IPCCommandResult IWII_IPC_HLE_Device::GetNoReply() { - return {false, 0}; + return {IPC_SUCCESS, false, 0}; } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h index 9f9113d44b..0112163594 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h @@ -47,7 +47,6 @@ struct IOSRequest u32 fd = 0; explicit IOSRequest(u32 address); virtual ~IOSRequest() = default; - void SetReturnValue(s32 new_return_value) const; }; enum IOSOpenMode : s32 @@ -156,7 +155,7 @@ public: virtual void Update() {} virtual DeviceType GetDeviceType() const { return m_device_type; } virtual bool IsOpened() const { return m_is_active; } - static IPCCommandResult GetDefaultReply(); + static IPCCommandResult GetDefaultReply(s32 return_value); static IPCCommandResult GetNoReply(); protected: diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp index 84f59a9095..9f207b4b97 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp @@ -74,10 +74,7 @@ void CWII_IPC_HLE_Device_di::FinishIOCtl(DVDInterface::DIInterruptType interrupt // This command has been executed, so it's removed from the queue u32 command_address = m_commands_to_execute.front(); m_commands_to_execute.pop_front(); - IOSIOCtlRequest request{command_address}; - - request.SetReturnValue(interrupt_type); - WII_IPC_HLE_Interface::EnqueueReply(request); + WII_IPC_HLE_Interface::EnqueueReply(IOSIOCtlRequest{command_address}, interrupt_type); // DVDInterface is now ready to execute another command, // so we start executing a command from the queue if there is one @@ -118,6 +115,5 @@ IPCCommandResult CWII_IPC_HLE_Device_di::IOCtlV(const IOSIOCtlVRequest& request) default: request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_DVD); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index c5307e7404..bf76810a96 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -207,8 +207,7 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(const IOSSeekRequest& request) { return_value = FS_ENOENT; } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(const IOSReadWriteRequest& request) @@ -247,8 +246,7 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(const IOSReadWriteRequest& req return_value = FS_ENOENT; } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(const IOSReadWriteRequest& request) @@ -283,8 +281,7 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(const IOSReadWriteRequest& re return_value = FS_ENOENT; } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(const IOSIOCtlRequest& request) @@ -314,8 +311,7 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(const IOSIOCtlRequest& reques request.Log(GetDeviceName(), LogTypes::WII_IPC_FILEIO, LogTypes::LERROR); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } void CWII_IPC_HLE_Device_FileIO::PrepareForState(PointerWrap::Mode mode) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp index 159d735919..3a8bfde24f 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -278,8 +278,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) if (!m_addtitle_tmd.IsValid()) { ERROR_LOG(WII_IPC_ES, "Invalid TMD while adding title (size = %zd)", tmd.size()); - request.SetReturnValue(ES_INVALID_TMD); - return GetDefaultReply(); + return GetDefaultReply(ES_INVALID_TMD); } // Write the TMD to title storage. @@ -304,8 +303,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) { ERROR_LOG(WII_IPC_ES, "Trying to add content when we haven't finished adding " "another content. Unsupported."); - request.SetReturnValue(ES_WRITE_FAILURE); - return GetDefaultReply(); + return GetDefaultReply(ES_WRITE_FAILURE); } m_addtitle_content_id = content_id; @@ -327,8 +325,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) // no known content installer which performs content addition concurrently. // Instead we just log an error (see above) if this condition is detected. s32 content_fd = 0; - request.SetReturnValue(content_fd); - return GetDefaultReply(); + return GetDefaultReply(content_fd); } case IOCTL_ES_ADDCONTENTDATA: @@ -359,8 +356,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) std::vector ticket = DiscIO::FindSignedTicket(m_addtitle_tmd.GetTitleId()); if (ticket.size() == 0) { - request.SetReturnValue(ES_NO_TICKET_INSTALLED); - return GetDefaultReply(); + return GetDefaultReply(ES_NO_TICKET_INSTALLED); } mbedtls_aes_context aes_ctx; @@ -371,8 +367,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) TMDReader::Content content_info; if (!m_addtitle_tmd.FindContentById(m_addtitle_content_id, &content_info)) { - request.SetReturnValue(ES_INVALID_TMD); - return GetDefaultReply(); + return GetDefaultReply(ES_INVALID_TMD); } u8 iv[16] = {0}; iv[0] = (content_info.index >> 8) & 0xFF; @@ -407,8 +402,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) EcWii& ec = EcWii::GetInstance(); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICEID %08X", ec.getNgId()); Memory::Write_U32(ec.getNgId(), request.io_vectors[0].address); - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } case IOCTL_ES_GETTITLECONTENTSCNT: @@ -420,6 +414,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID); u16 NumberOfPrivateContent = 0; + s32 return_value = IPC_SUCCESS; if (rNANDContent.IsValid()) // Not sure if dolphin will ever fail this check { NumberOfPrivateContent = rNANDContent.GetNumEntries(); @@ -428,19 +423,17 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) Memory::Write_U32(0, request.io_vectors[0].address); else Memory::Write_U32(NumberOfPrivateContent, request.io_vectors[0].address); - - request.SetReturnValue(IPC_SUCCESS); } else { - request.SetReturnValue(static_cast(rNANDContent.GetContentSize())); + return_value = static_cast(rNANDContent.GetContentSize()); } INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTSCNT: TitleID: %08x/%08x content count %i", (u32)(TitleID >> 32), (u32)TitleID, rNANDContent.IsValid() ? NumberOfPrivateContent : (u32)rNANDContent.GetContentSize()); - return GetDefaultReply(); + return GetDefaultReply(return_value); } break; @@ -454,6 +447,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID); + s32 return_value = IPC_SUCCESS; if (rNANDContent.IsValid()) // Not sure if dolphin will ever fail this check { for (u16 i = 0; i < rNANDContent.GetNumEntries(); i++) @@ -463,16 +457,15 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Index %d: %08x", i, rNANDContent.GetContentByIndex(i)->m_ContentID); } - request.SetReturnValue(IPC_SUCCESS); } else { - request.SetReturnValue(static_cast(rNANDContent.GetContentSize())); + return_value = static_cast(rNANDContent.GetContentSize()); ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Unable to open content %zu", rNANDContent.GetContentSize()); } - return GetDefaultReply(); + return GetDefaultReply(return_value); } break; @@ -485,12 +478,11 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) u32 Index = Memory::Read_U32(request.in_vectors[2].address); s32 CFD = OpenTitleContent(m_AccessIdentID++, TitleID, Index); - request.SetReturnValue(CFD); INFO_LOG(WII_IPC_ES, "IOCTL_ES_OPENTITLECONTENT: TitleID: %08x/%08x Index %i -> got CFD %x", (u32)(TitleID >> 32), (u32)TitleID, Index, CFD); - return GetDefaultReply(); + return GetDefaultReply(CFD); } break; @@ -501,10 +493,9 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) u32 Index = Memory::Read_U32(request.in_vectors[0].address); s32 CFD = OpenTitleContent(m_AccessIdentID++, m_TitleID, Index); - request.SetReturnValue(CFD); INFO_LOG(WII_IPC_ES, "IOCTL_ES_OPENCONTENT: Index %i -> got CFD %x", Index, CFD); - return GetDefaultReply(); + return GetDefaultReply(CFD); } break; @@ -520,8 +511,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - request.SetReturnValue(-1); - return GetDefaultReply(); + return GetDefaultReply(-1); } SContentAccess& rContent = itr->second; @@ -558,8 +548,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) "IOCTL_ES_READCONTENT: CFD %x, Address 0x%x, Size %i -> stream pos %i (Index %i)", CFD, Addr, Size, rContent.m_Position, rContent.m_Index); - request.SetReturnValue(Size); - return GetDefaultReply(); + return GetDefaultReply(Size); } break; @@ -575,8 +564,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - request.SetReturnValue(-1); - return GetDefaultReply(); + return GetDefaultReply(-1); } const DiscIO::CNANDContentLoader& ContentLoader = AccessContentDevice(itr->second.m_TitleID); @@ -589,8 +577,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) m_ContentAccessMap.erase(itr); - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; @@ -606,8 +593,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - request.SetReturnValue(-1); - return GetDefaultReply(); + return GetDefaultReply(-1); } SContentAccess& rContent = itr->second; @@ -629,8 +615,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) DEBUG_LOG(WII_IPC_ES, "IOCTL_ES_SEEKCONTENT: CFD %x, Address 0x%x, Mode %i -> Pos %i", CFD, Addr, Mode, rContent.m_Position); - request.SetReturnValue(rContent.m_Position); - return GetDefaultReply(); + return GetDefaultReply(rContent.m_Position); } break; @@ -683,8 +668,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECNT: Number of Titles %zu", m_TitleIDs.size()); - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; @@ -708,8 +692,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) } INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: Number of titles returned %i", Count); - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; @@ -761,8 +744,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) (u32)(TitleID >> 32), (u32)TitleID, ViewCount); Memory::Write_U32(ViewCount, request.io_vectors[0].address); - request.SetReturnValue(retVal); - return GetDefaultReply(); + return GetDefaultReply(retVal); } break; @@ -834,8 +816,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETVIEWS for titleID: %08x/%08x (MaxViews = %i)", (u32)(TitleID >> 32), (u32)TitleID, maxViews); - request.SetReturnValue(retVal); - return GetDefaultReply(); + return GetDefaultReply(retVal); } break; @@ -861,11 +842,9 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) } Memory::Write_U32(TMDViewCnt, request.io_vectors[0].address); - request.SetReturnValue(IPC_SUCCESS); - INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDViewCnt); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; @@ -912,52 +891,40 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) _dbg_assert_(WII_IPC_ES, (Address - request.io_vectors[0].address) == request.io_vectors[0].size); } - request.SetReturnValue(IPC_SUCCESS); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWS: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_GETCONSUMPTION: // This is at least what crediar's ES module does Memory::Write_U32(0, request.io_vectors[1].address); - request.SetReturnValue(IPC_SUCCESS); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETCONSUMPTION"); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); case IOCTL_ES_DELETETICKET: { u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_DELETETICKET: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); - if (File::Delete(Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT))) - { - request.SetReturnValue(IPC_SUCCESS); - } - else - { - // Presumably return -1017 when delete fails - request.SetReturnValue(ES_PARAMETER_SIZE_OR_ALIGNMENT); - } + // Presumably return -1017 when delete fails + if (!File::Delete(Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT))) + return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); + return GetDefaultReply(IPC_SUCCESS); } - break; + case IOCTL_ES_DELETETITLECONTENT: { u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_DELETETITLECONTENT: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); - if (DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID, Common::FROM_SESSION_ROOT)) - { - request.SetReturnValue(IPC_SUCCESS); - } - else - { - // Presumably return -1017 when title not installed TODO verify - request.SetReturnValue(ES_PARAMETER_SIZE_OR_ALIGNMENT); - } + // Presumably return -1017 when title not installed TODO verify + if (!DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID, Common::FROM_SESSION_ROOT)) + return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); + return GetDefaultReply(IPC_SUCCESS); } - break; + case IOCTL_ES_GETSTOREDTMDSIZE: { _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, @@ -978,11 +945,9 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) if (request.io_vectors.size()) Memory::Write_U32(TMDCnt, request.io_vectors[0].address); - request.SetReturnValue(IPC_SUCCESS); - INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDCnt); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_GETSTOREDTMD: @@ -1026,11 +991,10 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) _dbg_assert_(WII_IPC_ES, (Address - request.io_vectors[0].address) == request.io_vectors[0].size); } - request.SetReturnValue(IPC_SUCCESS); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; @@ -1182,13 +1146,8 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) Memory::Write_U16(0xFFFF, 0x00003142); Memory::Write_U32(Memory::Read_U32(0x00003140), 0x00003188); - // TODO: provide correct return code when bSuccess= false // Note: If we just reset the PPC, don't write anything to the command buffer. This // could clobber the DOL we just loaded. - if (!bReset) - { - request.SetReturnValue(IPC_SUCCESS); - } ERROR_LOG(WII_IPC_ES, "IOCTL_ES_LAUNCH %016" PRIx64 " %08x %016" PRIx64 " %08x %016" PRIx64 " %04x", @@ -1219,8 +1178,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) // -1017 // if the IOS didn't find the Korean keys and 0 if it does. 0 leads to a error 003 INFO_LOG(WII_IPC_ES, "IOCTL_ES_CHECKKOREAREGION: Title checked for Korean keys."); - request.SetReturnValue(ES_PARAMETER_SIZE_OR_ALIGNMENT); - return GetDefaultReply(); + return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); case IOCTL_ES_GETDEVICECERT: // (Input: none, Output: 384 bytes) { @@ -1272,8 +1230,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE); } - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } const DiscIO::CNANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u64 title_id) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp index cc9aae5eac..66397e9edb 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp @@ -34,9 +34,9 @@ CWII_IPC_HLE_Device_fs::CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& // ~1/1000th of a second is too short and causes hangs in Wii Party // Play it safe at 1/500th -IPCCommandResult CWII_IPC_HLE_Device_fs::GetFSReply() const +IPCCommandResult CWII_IPC_HLE_Device_fs::GetFSReply(const s32 return_value) const { - return {true, SystemTimers::GetTicksPerSecond() / 500}; + return {return_value, true, SystemTimers::GetTicksPerSecond() / 500}; } IOSReturnCode CWII_IPC_HLE_Device_fs::Open(const IOSOpenRequest& request) @@ -224,16 +224,14 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(const IOSIOCtlVRequest& request) break; } - request.SetReturnValue(return_value); - return GetFSReply(); + return GetFSReply(return_value); } IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtl(const IOSIOCtlRequest& request) { Memory::Memset(request.buffer_out, 0, request.buffer_out_size); const s32 return_value = ExecuteCommand(request); - request.SetReturnValue(return_value); - return GetFSReply(); + return GetFSReply(return_value); } s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(const IOSIOCtlRequest& request) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h index 0ff31f4036..5dd540033e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h @@ -49,6 +49,6 @@ private: IOCTL_SHUTDOWN = 0x0D }; - IPCCommandResult GetFSReply() const; + IPCCommandResult GetFSReply(s32 return_value) const; s32 ExecuteCommand(const IOSIOCtlRequest& request); }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 04d5002dbe..6945583f24 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -39,8 +39,8 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) { IOSIOCtlRequest request{hid->deviceCommandAddress}; hid->FillOutDevices(request); - request.SetReturnValue(IPC_SUCCESS); - WII_IPC_HLE_Interface::EnqueueReply(request, 0, CoreTiming::FromThread::NON_CPU); + WII_IPC_HLE_Interface::EnqueueReply(request, IPC_SUCCESS, 0, + CoreTiming::FromThread::NON_CPU); hid->deviceCommandAddress = 0; } } @@ -61,8 +61,7 @@ void CWII_IPC_HLE_Device_hid::handleUsbUpdates(struct libusb_transfer* transfer) } IOSIOCtlRequest request{replyAddress}; - request.SetReturnValue(ret); - WII_IPC_HLE_Interface::EnqueueReply(request, 0, CoreTiming::FromThread::NON_CPU); + WII_IPC_HLE_Interface::EnqueueReply(request, ret, 0, CoreTiming::FromThread::NON_CPU); } CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) @@ -106,8 +105,7 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(const IOSIOCtlRequest& request) { if (Core::g_want_determinism) { - request.SetReturnValue(-1); - return GetDefaultReply(); + return GetDefaultReply(IPC_EACCES); } s32 return_value = IPC_SUCCESS; @@ -213,8 +211,7 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(const IOSIOCtlRequest& request) { IOSIOCtlRequest pending_request{deviceCommandAddress}; Memory::Write_U32(0xFFFFFFFF, pending_request.buffer_out); - pending_request.SetReturnValue(-1); - WII_IPC_HLE_Interface::EnqueueReply(pending_request); + WII_IPC_HLE_Interface::EnqueueReply(pending_request, -1); deviceCommandAddress = 0; } INFO_LOG(WII_IPC_HID, "HID::IOCtl(Shutdown) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", @@ -226,8 +223,7 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(const IOSIOCtlRequest& request) request.Log(GetDeviceName(), LogTypes::WII_IPC_HID); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle* dev) @@ -260,8 +256,7 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtlV(const IOSIOCtlVRequest& request { Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HID); - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } void CWII_IPC_HLE_Device_hid::ConvertDeviceToWii(WiiHIDDeviceDescriptor* dest, diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp index 4eff039bfc..337afc2ac4 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp @@ -190,8 +190,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(const IOSIOCtlRequest request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } u8 CWII_IPC_HLE_Device_net_kd_request::GetAreaCode(const std::string& area) const @@ -390,8 +389,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(const IOSIOCtlVReque { Memory::Write_U32(common_result, request.io_vectors.at(common_vector).address + 4); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } // ********************************************************************************** @@ -476,8 +474,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(const IOSIOCtlVReque request.Dump(GetDeviceName(), LogTypes::WII_IPC_NET, LogTypes::LINFO); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } // ********************************************************************************** @@ -553,8 +550,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(const IOSIOCtlRequest& re { if (Core::g_want_determinism) { - request.SetReturnValue(-1); - return GetDefaultReply(); + return GetDefaultReply(IPC_EACCES); } s32 return_value = 0; @@ -1060,8 +1056,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(const IOSIOCtlRequest& re request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_NET); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(const IOSIOCtlVRequest& request) @@ -1371,8 +1366,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(const IOSIOCtlVRequest& request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_NET); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } void CWII_IPC_HLE_Device_net_ip_top::Update() diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h index d2f9d5ca23..2e82d20956 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h @@ -124,8 +124,7 @@ public: // write return values Memory::Write_U32(common_result, request.buffer_out); - request.SetReturnValue(result); - return GetDefaultReply(); + return GetDefaultReply(result); } private: diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp index 1ecdb5ee60..32d6129f7a 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp @@ -78,8 +78,7 @@ int CWII_IPC_HLE_Device_net_ssl::GetSSLFreeID() const IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtl(const IOSIOCtlRequest& request) { request.Log(GetDeviceName(), LogTypes::WII_IPC_SSL, LogTypes::LINFO); - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(const IOSIOCtlVRequest& request) @@ -125,10 +124,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(const IOSIOCtlVRequest& req // I don't trust SSL to be deterministic, and this is never going to sync // as such (as opposed to forwarding IPC results or whatever), so - if (Core::g_want_determinism) - { - request.SetReturnValue(-1); - return GetDefaultReply(); - } + return GetDefaultReply(IPC_EACCES); switch (request.request) { @@ -496,6 +492,5 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(const IOSIOCtlVRequest& req } // SSL return codes are written to BufferIn - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp index ad1b5a06e8..da985a72e6 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp @@ -45,8 +45,7 @@ void CWII_IPC_HLE_Device_sdio_slot0::EventNotify() if ((SConfig::GetInstance().m_WiiSDCard && m_event->type == EVENT_INSERT) || (!SConfig::GetInstance().m_WiiSDCard && m_event->type == EVENT_REMOVE)) { - m_event->request.SetReturnValue(m_event->type); - WII_IPC_HLE_Interface::EnqueueReply(m_event->request); + WII_IPC_HLE_Interface::EnqueueReply(m_event->request, m_event->type); m_event.reset(); } } @@ -198,8 +197,7 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(const IOSIOCtlRequest& re EventNotify(); return GetNoReply(); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(const IOSIOCtlVRequest& request) @@ -220,8 +218,7 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(const IOSIOCtlVRequest& ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtlV command 0x%08x", request.request); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(const IOSRequest& request, u32 _BufferIn, @@ -394,8 +391,7 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(const IOSRequest& request, u3 // release returns 0 // unknown sd int // technically we do it out of order, oh well - m_event->request.SetReturnValue(EVENT_INVALID); - WII_IPC_HLE_Interface::EnqueueReply(m_event->request); + WII_IPC_HLE_Interface::EnqueueReply(m_event->request, EVENT_INVALID); m_event.reset(); break; } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp index a8cb13e931..7a57814b15 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp @@ -37,8 +37,7 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(const IOSIOCtlRequest& break; } Memory::Write_U32(0, s_event_hook_request->buffer_out); - s_event_hook_request->SetReturnValue(IPC_SUCCESS); - WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request); + WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request, IPC_SUCCESS); s_event_hook_request.reset(); break; @@ -63,8 +62,7 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(const IOSIOCtlRequest& request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_STM); } - request.SetReturnValue(return_value); - return GetDefaultReply(); + return GetDefaultReply(return_value); } void CWII_IPC_HLE_Device_stm_eventhook::Close() @@ -78,15 +76,11 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::IOCtl(const IOSIOCtlRequest& if (request.request != IOCTL_STM_EVENTHOOK) { ERROR_LOG(WII_IPC_STM, "Bad IOCtl in CWII_IPC_HLE_Device_stm_eventhook"); - request.SetReturnValue(IPC_EINVAL); - return GetDefaultReply(); + return GetDefaultReply(IPC_EINVAL); } if (s_event_hook_request) - { - request.SetReturnValue(IPC_EEXIST); - return GetDefaultReply(); - } + return GetDefaultReply(IPC_EEXIST); // IOCTL_STM_EVENTHOOK waits until the reset button or power button is pressed. s_event_hook_request = std::make_unique(request.address); @@ -105,8 +99,7 @@ void CWII_IPC_HLE_Device_stm_eventhook::TriggerEvent(const u32 event) const return; Memory::Write_U32(event, s_event_hook_request->buffer_out); - s_event_hook_request->SetReturnValue(IPC_SUCCESS); - WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request); + WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request, IPC_SUCCESS); s_event_hook_request.reset(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp index 8f00b8188a..690182ab52 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp @@ -26,13 +26,11 @@ void CWII_IPC_HLE_Device_stub::Close() IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtl(const IOSIOCtlRequest& request) { WARN_LOG(WII_IPC_HLE, "%s faking IOCtl()", m_name.c_str()); - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtlV(const IOSIOCtlVRequest& request) { WARN_LOG(WII_IPC_HLE, "%s faking IOCtlV()", m_name.c_str()); - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp index e22df24c87..11d5371b55 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp @@ -226,8 +226,7 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(const IOSIOCtlV request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_WIIMOTE); } - request.SetReturnValue(IPC_SUCCESS); - return send_reply ? GetDefaultReply() : GetNoReply(); + return send_reply ? GetDefaultReply(IPC_SUCCESS) : GetNoReply(); } // Here we handle the USBV0_IOCTL_BLKMSG Ioctlv @@ -268,8 +267,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendACLPacket(u16 connection_handl // Write the packet to the buffer memcpy(reinterpret_cast(header) + sizeof(hci_acldata_hdr_t), data, header->length); - m_ACLEndpoint->ios_request.SetReturnValue(sizeof(hci_acldata_hdr_t) + size); - WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint->ios_request); + WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint->ios_request, + sizeof(hci_acldata_hdr_t) + size); m_ACLEndpoint.reset(); } else @@ -296,9 +295,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint valid, sending packet to %08x", m_HCIEndpoint->ios_request.address); m_HCIEndpoint->FillBuffer(_event.m_buffer, _event.m_size); - m_HCIEndpoint->ios_request.SetReturnValue(_event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request, _event.m_size); m_HCIEndpoint.reset(); } else // push new one, pop oldest @@ -312,9 +310,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent ((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1, m_HCIEndpoint->ios_request.address); m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); - m_HCIEndpoint->ios_request.SetReturnValue(event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request, event.m_size); m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } @@ -338,9 +335,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() ((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1, m_HCIEndpoint->ios_request.address); m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); - m_HCIEndpoint->ios_request.SetReturnValue(event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request, event.m_size); m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } @@ -434,11 +430,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe // Write the packet to the buffer std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t)); - endpoint.ios_request.SetReturnValue(sizeof(hci_acldata_hdr_t) + size); - m_queue.pop_front(); - WII_IPC_HLE_Interface::EnqueueReply(endpoint.ios_request); + WII_IPC_HLE_Interface::EnqueueReply(endpoint.ios_request, sizeof(hci_acldata_hdr_t) + size); } bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventInquiryComplete() @@ -1158,7 +1152,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( } // HCI command is finished, send a reply to command - WII_IPC_HLE_Interface::EnqueueReply(ctrl_message.ios_request); + WII_IPC_HLE_Interface::EnqueueReply(ctrl_message.ios_request, ctrl_message.length); } // diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp index d4a59d6866..70dca89afc 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp @@ -393,8 +393,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(CtrlBuffer hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2; hci_event->PacketIndicator = 0x01; hci_event->Opcode = m_fake_vendor_command_reply_opcode; - ctrl.ios_request.SetReturnValue(sizeof(SHCIEventCommand)); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request, static_cast(sizeof(SHCIEventCommand))); } // Due to how the widcomm stack which Nintendo uses is coded, we must never @@ -419,8 +418,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(CtrlBuffe reply.num_sco_pkts = SCO_PKT_NUM; memcpy(packet + sizeof(SHCIEventCommand), &reply, sizeof(hci_read_buffer_size_rp)); - ctrl.ios_request.SetReturnValue(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp)); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); + WII_IPC_HLE_Interface::EnqueueReply( + ctrl.ios_request, + static_cast(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp))); } void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(CtrlBuffer& ctrl, @@ -431,8 +431,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(CtrlBuffer& c hci_event->event = HCI_EVENT_VENDOR; hci_event->length = size; memcpy(packet + sizeof(hci_event_hdr_t), payload, size); - ctrl.ios_request.SetReturnValue(sizeof(hci_event_hdr_t) + size); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request, + static_cast(sizeof(hci_event_hdr_t) + size)); } // When the red sync button is pressed, a HCI event is generated: @@ -578,7 +578,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::CommandCallback(libusb_transfer* s_showed_failed_transfer.Clear(); } - WII_IPC_HLE_Interface::EnqueueReply(cmd->ios_request, 0, CoreTiming::FromThread::NON_CPU); + WII_IPC_HLE_Interface::EnqueueReply(cmd->ios_request, tr->actual_length, 0, + CoreTiming::FromThread::NON_CPU); } void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* tr) @@ -622,6 +623,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* } } - ctrl->ios_request.SetReturnValue(tr->actual_length); - WII_IPC_HLE_Interface::EnqueueReply(ctrl->ios_request, 0, CoreTiming::FromThread::NON_CPU); + WII_IPC_HLE_Interface::EnqueueReply(ctrl->ios_request, tr->actual_length, 0, + CoreTiming::FromThread::NON_CPU); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp index 52af5fd684..c5da572139 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp @@ -65,8 +65,7 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::IOCtl(const IOSIOCtlRequest& reque Memory::CopyToEmu(request.buffer_out, &m_MessageQueue.front(), sizeof(SMessageData)); m_MessageQueue.pop(); } - request.SetReturnValue(IPC_SUCCESS); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } bool CWII_IPC_HLE_Device_usb_kbd::IsKeyPressed(int _Key) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp index db025b3d07..384e2d0154 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp @@ -15,21 +15,19 @@ CWII_IPC_HLE_Device_usb_ven::CWII_IPC_HLE_Device_usb_ven(const u32 device_id, IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(const IOSIOCtlVRequest& request) { request.Dump(GetDeviceName()); - request.SetReturnValue(IPC_SUCCESS); return GetNoReply(); } IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(const IOSIOCtlRequest& request) { request.Log(GetDeviceName(), LogTypes::OSHLE); - request.SetReturnValue(IPC_SUCCESS); - IPCCommandResult reply = GetDefaultReply(); + IPCCommandResult reply = GetDefaultReply(IPC_SUCCESS); switch (request.request) { case USBV5_IOCTL_GETVERSION: Memory::Write_U32(0x50001, request.buffer_out); - reply = GetDefaultReply(); + reply = GetDefaultReply(IPC_SUCCESS); break; case USBV5_IOCTL_GETDEVICECHANGE: @@ -38,24 +36,24 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(const IOSIOCtlRequest& reque static bool firstcall = true; if (firstcall) { - reply = GetDefaultReply(); + reply = GetDefaultReply(IPC_SUCCESS); firstcall = false; } // num devices - request.SetReturnValue(0); + reply = GetDefaultReply(0); return reply; } break; case USBV5_IOCTL_ATTACHFINISH: - reply = GetDefaultReply(); + reply = GetDefaultReply(IPC_SUCCESS); break; case USBV5_IOCTL_SUSPEND_RESUME: DEBUG_LOG(OSHLE, "Device: %i Resumed: %i", Memory::Read_U32(request.buffer_in), Memory::Read_U32(request.buffer_in + 4)); - reply = GetDefaultReply(); + reply = GetDefaultReply(IPC_SUCCESS); break; case USBV5_IOCTL_GETDEVPARAMS: @@ -67,7 +65,7 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(const IOSIOCtlRequest& reque Memory::Write_U32(0, request.buffer_out); - reply = GetDefaultReply(); + reply = GetDefaultReply(IPC_SUCCESS); } break; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp index 3038a1871e..2d178db263 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp @@ -157,8 +157,7 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(const IOSIOCtlRequest& re break; } - request.SetReturnValue(return_error_code); - return GetDefaultReply(); + return GetDefaultReply(return_error_code); } CWII_IPC_HLE_Device_usb_wfssrv::FileDescriptor* diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp index bbdd2cb67d..b2497ee723 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp @@ -238,6 +238,5 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(const IOSIOCtlRequest& request) break; } - request.SetReturnValue(return_error_code); - return GetDefaultReply(); + return GetDefaultReply(return_error_code); } diff --git a/Source/Core/Core/IPC_HLE/WII_Socket.cpp b/Source/Core/Core/IPC_HLE/WII_Socket.cpp index 04e5abc987..233b39d6d9 100644 --- a/Source/Core/Core/IPC_HLE/WII_Socket.cpp +++ b/Source/Core/Core/IPC_HLE/WII_Socket.cpp @@ -567,8 +567,7 @@ void WiiSocket::Update(bool read, bool write, bool except) "IOCTL(V) Sock: %08x ioctl/v: %d returned: %d nonBlock: %d forceNonBlock: %d", fd, it->is_ssl ? (int)it->ssl_type : (int)it->net_type, ReturnValue, nonBlock, forceNonBlock); - it->request.SetReturnValue(ReturnValue); - WII_IPC_HLE_Interface::EnqueueReply(it->request); + WII_IPC_HLE_Interface::EnqueueReply(it->request, ReturnValue); it = pending_sockops.erase(it); } else diff --git a/Source/Core/Core/IPC_HLE/WII_Socket.h b/Source/Core/Core/IPC_HLE/WII_Socket.h index b0c50d3df3..793c02d1f2 100644 --- a/Source/Core/Core/IPC_HLE/WII_Socket.h +++ b/Source/Core/Core/IPC_HLE/WII_Socket.h @@ -230,8 +230,7 @@ public: { ERROR_LOG(WII_IPC_NET, "DoSock: Error, fd not found (%08x, %08X, %08X)", sock, request.address, type); - request.SetReturnValue(-SO_EBADF); - WII_IPC_HLE_Interface::EnqueueReply(request); + WII_IPC_HLE_Interface::EnqueueReply(request, -SO_EBADF); } else {