IOS HLE: Deduplicate request code in WFS

This commit is contained in:
Léo Lam 2017-01-15 15:07:33 +01:00
parent 4af67abb55
commit 8629a1f11c
4 changed files with 52 additions and 84 deletions

View File

@ -29,17 +29,11 @@ CWII_IPC_HLE_Device_usb_wfssrv::CWII_IPC_HLE_Device_usb_wfssrv(u32 device_id,
m_device_name = "msc01"; 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; int return_error_code = IPC_SUCCESS;
switch (command) switch (request.request)
{ {
case IOCTL_WFS_INIT: case IOCTL_WFS_INIT:
// TODO(wfs): Implement. // TODO(wfs): Implement.
@ -48,56 +42,56 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address)
case IOCTL_WFS_DEVICE_INFO: case IOCTL_WFS_DEVICE_INFO:
INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_DEVICE_INFO"); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_DEVICE_INFO");
Memory::Write_U64(16ull << 30, buffer_out); // 16GB storage. Memory::Write_U64(16ull << 30, request.buffer_out); // 16GB storage.
Memory::Write_U8(4, buffer_out + 8); Memory::Write_U8(4, request.buffer_out + 8);
break; break;
case IOCTL_WFS_GET_DEVICE_NAME: case IOCTL_WFS_GET_DEVICE_NAME:
{ {
INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GET_DEVICE_NAME"); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GET_DEVICE_NAME");
Memory::Write_U8(static_cast<u8>(m_device_name.size()), buffer_out); Memory::Write_U8(static_cast<u8>(m_device_name.size()), request.buffer_out);
Memory::CopyToEmu(buffer_out + 1, m_device_name.data(), m_device_name.size()); Memory::CopyToEmu(request.buffer_out + 1, m_device_name.data(), m_device_name.size());
break; break;
} }
case IOCTL_WFS_ATTACH_DETACH_2: case IOCTL_WFS_ATTACH_DETACH_2:
// TODO(wfs): Implement. // TODO(wfs): Implement.
INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH_2(%d)", command); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH_2(%u)", request.request);
Memory::Write_U32(1, buffer_out); Memory::Write_U32(1, request.buffer_out);
Memory::Write_U32(0, buffer_out + 4); // device id? Memory::Write_U32(0, request.buffer_out + 4); // device id?
Memory::Write_U32(0, buffer_out + 8); Memory::Write_U32(0, request.buffer_out + 8);
break; break;
case IOCTL_WFS_ATTACH_DETACH: case IOCTL_WFS_ATTACH_DETACH:
INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH(%d)", command); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH(%u)", request.request);
Memory::Write_U32(1, buffer_out); Memory::Write_U32(1, request.buffer_out);
Memory::Write_U32(0, buffer_out + 4); Memory::Write_U32(0, request.buffer_out + 4);
Memory::Write_U32(0, buffer_out + 8); Memory::Write_U32(0, request.buffer_out + 8);
return GetNoReply(); return GetNoReply();
// TODO(wfs): Globbing is not really implemented, we just fake the one case // TODO(wfs): Globbing is not really implemented, we just fake the one case
// (listing /vol/*) which is required to get the installer to work. // (listing /vol/*) which is required to get the installer to work.
case IOCTL_WFS_GLOB_START: case IOCTL_WFS_GLOB_START:
INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_START(%d)", command); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_START(%u)", request.request);
Memory::Memset(buffer_out, 0, buffer_out_size); Memory::Memset(request.buffer_out, 0, request.buffer_out_size);
memcpy(Memory::GetPointer(buffer_out + 0x14), m_device_name.data(), m_device_name.size()); Memory::CopyToEmu(request.buffer_out + 0x14, m_device_name.data(), m_device_name.size());
break; break;
case IOCTL_WFS_GLOB_NEXT: 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; return_error_code = WFS_EEMPTY;
break; break;
case IOCTL_WFS_GLOB_END: case IOCTL_WFS_GLOB_END:
INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_END(%d)", command); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_END(%u)", request.request);
Memory::Memset(buffer_out, 0, buffer_out_size); Memory::Memset(request.buffer_out, 0, request.buffer_out_size);
break; break;
case IOCTL_WFS_OPEN: case IOCTL_WFS_OPEN:
{ {
u32 mode = Memory::Read_U32(buffer_in); u32 mode = Memory::Read_U32(request.buffer_in);
u16 path_len = Memory::Read_U16(buffer_in + 0x20); u16 path_len = Memory::Read_U16(request.buffer_in + 0x20);
std::string path = Memory::GetString(buffer_in + 0x22, path_len); std::string path = Memory::GetString(request.buffer_in + 0x22, path_len);
u16 fd = GetNewFileDescriptor(); u16 fd = GetNewFileDescriptor();
FileDescriptor* fd_obj = &m_fds[fd]; 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); 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; break;
} }
case IOCTL_WFS_CLOSE: 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); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_CLOSE(%d)", fd);
ReleaseFileDescriptor(fd); ReleaseFileDescriptor(fd);
break; break;
@ -129,9 +123,9 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address)
case IOCTL_WFS_READ: case IOCTL_WFS_READ:
{ {
u32 addr = Memory::Read_U32(buffer_in); u32 addr = Memory::Read_U32(request.buffer_in);
u16 fd = Memory::Read_U16(buffer_in + 0xC); u16 fd = Memory::Read_U16(request.buffer_in + 0xC);
u32 size = Memory::Read_U32(buffer_in + 8); u32 size = Memory::Read_U32(request.buffer_in + 8);
FileDescriptor* fd_obj = FindFileDescriptor(fd); FileDescriptor* fd_obj = FindFileDescriptor(fd);
if (fd_obj == nullptr) if (fd_obj == nullptr)
@ -158,15 +152,12 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address)
default: default:
// TODO(wfs): Should be returning -3. However until we have everything // TODO(wfs): Should be returning -3. However until we have everything
// properly stubbed it's easier to simulate the methods succeeding. // 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", request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE, LogTypes::LWARNING);
m_name.c_str(), command, buffer_in_size, buffer_out_size, Memory::Memset(request.buffer_out, 0, request.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);
break; break;
} }
Memory::Write_U32(return_error_code, command_address + 4); request.SetReturnValue(return_error_code);
return GetDefaultReply(); return GetDefaultReply();
} }

View File

@ -23,8 +23,7 @@ class CWII_IPC_HLE_Device_usb_wfssrv : public IWII_IPC_HLE_Device
public: public:
CWII_IPC_HLE_Device_usb_wfssrv(u32 device_id, const std::string& device_name); CWII_IPC_HLE_Device_usb_wfssrv(u32 device_id, const std::string& device_name);
IPCCommandResult IOCtl(u32 command_address) override; IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override;
IPCCommandResult IOCtlV(u32 command_address) override;
private: private:
// WFS device name, e.g. msc01/msc02. // WFS device name, e.g. msc01/msc02.

View File

@ -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; u32 return_error_code = IPC_SUCCESS;
switch (command) switch (request.request)
{ {
case IOCTL_WFSI_PREPARE_DEVICE: case IOCTL_WFSI_PREPARE_DEVICE:
{ {
u32 tmd_addr = Memory::Read_U32(buffer_in); u32 tmd_addr = Memory::Read_U32(request.buffer_in);
u32 tmd_size = Memory::Read_U32(buffer_in + 4); u32 tmd_size = Memory::Read_U32(request.buffer_in + 4);
INFO_LOG(WII_IPC_HLE, "IOCTL_WFSI_PREPARE_DEVICE"); 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: case IOCTL_WFSI_PREPARE_CONTENT:
{ {
const char* ioctl_name = command == IOCTL_WFSI_PREPARE_PROFILE ? "IOCTL_WFSI_PREPARE_PROFILE" : const char* ioctl_name = request.request == IOCTL_WFSI_PREPARE_PROFILE ?
"IOCTL_WFSI_PREPARE_PROFILE" :
"IOCTL_WFSI_PREPARE_CONTENT"; "IOCTL_WFSI_PREPARE_CONTENT";
// Initializes the IV from the index of the content in the TMD contents. // 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; TMDReader::Content content_info;
if (!m_tmd.FindContentById(content_id, &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_PROFILE:
case IOCTL_WFSI_IMPORT_CONTENT: case IOCTL_WFSI_IMPORT_CONTENT:
{ {
const char* ioctl_name = command == IOCTL_WFSI_IMPORT_PROFILE ? "IOCTL_WFSI_IMPORT_PROFILE" : const char* ioctl_name = request.request == IOCTL_WFSI_IMPORT_PROFILE ?
"IOCTL_WFSI_IMPORT_PROFILE" :
"IOCTL_WFSI_IMPORT_CONTENT"; "IOCTL_WFSI_IMPORT_CONTENT";
u32 content_id = Memory::Read_U32(buffer_in + 0xC); u32 content_id = Memory::Read_U32(request.buffer_in + 0xC);
u32 input_ptr = Memory::Read_U32(buffer_in + 0x10); u32 input_ptr = Memory::Read_U32(request.buffer_in + 0x10);
u32 input_size = Memory::Read_U32(buffer_in + 0x14); 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, INFO_LOG(WII_IPC_HLE, "%s: %08x bytes of data at %08x from content id %d", ioctl_name,
content_id, input_ptr, input_size); 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_PROFILE:
case IOCTL_WFSI_FINALIZE_CONTENT: 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_PROFILE" :
"IOCTL_WFSI_FINALIZE_CONTENT"; "IOCTL_WFSI_FINALIZE_CONTENT";
INFO_LOG(WII_IPC_HLE, "%s", ioctl_name); 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: case IOCTL_WFSI_SET_DEVICE_NAME:
INFO_LOG(WII_IPC_HLE, "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; break;
case IOCTL_WFSI_APPLY_TITLE_PROFILE: 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 // TODO(wfs): Should be returning an error. However until we have
// everything properly stubbed it's easier to simulate the methods // everything properly stubbed it's easier to simulate the methods
// succeeding. // succeeding.
WARN_LOG(WII_IPC_HLE, "%s unimplemented IOCtl(0x%08x, size_in=%08x, size_out=%08x)\n%s\n%s", request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE, LogTypes::LWARNING);
m_name.c_str(), command, buffer_in_size, buffer_out_size, Memory::Memset(request.buffer_out, 0, request.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);
break; break;
} }
Memory::Write_U32(return_error_code, command_address + 4); request.SetReturnValue(return_error_code);
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);
return GetDefaultReply(); return GetDefaultReply();
} }

View File

@ -34,9 +34,7 @@ class CWII_IPC_HLE_Device_wfsi : public IWII_IPC_HLE_Device
public: public:
CWII_IPC_HLE_Device_wfsi(u32 device_id, const std::string& device_name); CWII_IPC_HLE_Device_wfsi(u32 device_id, const std::string& device_name);
IPCCommandResult Open(u32 command_address, u32 mode) override; IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override;
IPCCommandResult IOCtl(u32 command_address) override;
IPCCommandResult IOCtlV(u32 command_address) override;
private: private:
std::string m_device_name; std::string m_device_name;