Пример #1
0
IPCCommandResult ES::ImportTitleDone(Context& context, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(0, 0))
    return GetDefaultReply(ES_EINVAL);

  return GetDefaultReply(ImportTitleDone(context));
}
Пример #2
0
IPCCommandResult NetIPTop::HandleSetSockOptRequest(const IOCtlRequest& request)
{
  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, request.buffer_in + 0x10, optlen);

  INFO_LOG(IOS_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, 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))
    return GetDefaultReply(0);

  // Do the level/optname translation
  int nat_level = MapWiiSockOptLevelToNative(level);
  int nat_optname = MapWiiSockOptNameToNative(optname);

  int ret = setsockopt(WiiSockMan::GetInstance().GetHostSocket(fd), nat_level, nat_optname,
                       (char*)optval, optlen);
  return GetDefaultReply(WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false));
}
Пример #3
0
IPCCommandResult ES::DeleteSharedContent(const IOCtlVRequest& request)
{
  std::array<u8, 20> sha1;
  if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sha1.size())
    return GetDefaultReply(ES_EINVAL);
  Memory::CopyFromEmu(sha1.data(), request.in_vectors[0].address, request.in_vectors[0].size);
  return GetDefaultReply(DeleteSharedContent(sha1));
}
Пример #4
0
IPCCommandResult ES::DeleteTitle(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != 8)
    return GetDefaultReply(ES_EINVAL);

  const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
  return GetDefaultReply(DeleteTitle(title_id));
}
Пример #5
0
IPCCommandResult ES::ExportContentEnd(Context& context, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != 4)
    return GetDefaultReply(ES_EINVAL);

  const u32 content_fd = Memory::Read_U32(request.in_vectors[0].address);
  return GetDefaultReply(ExportContentEnd(context, content_fd));
}
Пример #6
0
IPCCommandResult ES::DeleteTicket(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 0) ||
      request.in_vectors[0].size != sizeof(IOS::ES::TicketView))
  {
    return GetDefaultReply(ES_EINVAL);
  }
  return GetDefaultReply(DeleteTicket(Memory::GetPointer(request.in_vectors[0].address)));
}
Пример #7
0
IPCCommandResult ES::ImportContentBegin(Context& context, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(2, 0))
    return GetDefaultReply(ES_EINVAL);

  u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
  u32 content_id = Memory::Read_U32(request.in_vectors[1].address);
  return GetDefaultReply(ImportContentBegin(context, title_id, content_id));
}
Пример #8
0
IPCCommandResult ES::GetTitleCount(const std::vector<u64>& titles, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != 4)
    return GetDefaultReply(ES_EINVAL);

  Memory::Write_U32(static_cast<u32>(titles.size()), request.io_vectors[0].address);

  return GetDefaultReply(IPC_SUCCESS);
}
Пример #9
0
IPCCommandResult ES::DeleteContent(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(2, 0) || request.in_vectors[0].size != sizeof(u64) ||
      request.in_vectors[1].size != sizeof(u32))
  {
    return GetDefaultReply(ES_EINVAL);
  }
  return GetDefaultReply(DeleteContent(Memory::Read_U64(request.in_vectors[0].address),
                                       Memory::Read_U32(request.in_vectors[1].address)));
}
Пример #10
0
IPCCommandResult ES::ImportContentData(Context& context, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(2, 0))
    return GetDefaultReply(ES_EINVAL);

  u32 content_fd = Memory::Read_U32(request.in_vectors[0].address);
  u8* data_start = Memory::GetPointer(request.in_vectors[1].address);
  return GetDefaultReply(
      ImportContentData(context, content_fd, data_start, request.in_vectors[1].size));
}
Пример #11
0
IPCCommandResult ES::ExportTitleInit(Context& context, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != 8)
    return GetDefaultReply(ES_EINVAL);

  const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
  u8* tmd_bytes = Memory::GetPointer(request.io_vectors[0].address);
  const u32 tmd_size = request.io_vectors[0].size;

  return GetDefaultReply(ExportTitleInit(context, title_id, tmd_bytes, tmd_size));
}
Пример #12
0
IPCCommandResult ES::GetStoredContents(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(2, 1) || request.in_vectors[0].size != sizeof(u64))
    return GetDefaultReply(ES_EINVAL);

  const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
  const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
  if (!tmd.IsValid())
    return GetDefaultReply(FS_ENOENT);
  return GetStoredContents(tmd, request);
}
Пример #13
0
IPCCommandResult ES::GetBoot2Version(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(0, 1))
    return GetDefaultReply(ES_EINVAL);

  INFO_LOG(IOS_ES, "IOCTL_ES_GETBOOT2VERSION");

  // as of 26/02/2012, this was latest bootmii version
  Memory::Write_U32(4, request.io_vectors[0].address);
  return GetDefaultReply(IPC_SUCCESS);
}
Пример #14
0
IPCCommandResult ES::GetSharedContentsCount(const IOCtlVRequest& request) const
{
  if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != sizeof(u32))
    return GetDefaultReply(ES_EINVAL);

  const u32 count = GetSharedContentsCount();
  Memory::Write_U32(count, request.io_vectors[0].address);

  INFO_LOG(IOS_ES, "GetSharedContentsCount: %u contents", count);
  return GetDefaultReply(IPC_SUCCESS);
}
Пример #15
0
IPCCommandResult ES::ImportTmd(Context& context, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 0))
    return GetDefaultReply(ES_EINVAL);

  if (!IOS::ES::IsValidTMDSize(request.in_vectors[0].size))
    return GetDefaultReply(ES_EINVAL);

  std::vector<u8> tmd(request.in_vectors[0].size);
  Memory::CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size);
  return GetDefaultReply(ImportTmd(context, tmd));
}
Пример #16
0
IPCCommandResult STMEventHook::IOCtl(const IOCtlRequest& request)
{
  if (request.request != IOCTL_STM_EVENTHOOK)
    return GetDefaultReply(IPC_EINVAL);

  if (s_event_hook_request)
    return GetDefaultReply(IPC_EEXIST);

  // IOCTL_STM_EVENTHOOK waits until the reset button or power button is pressed.
  s_event_hook_request = std::make_unique<IOCtlRequest>(request.address);
  return GetNoReply();
}
Пример #17
0
// Used by the GetStoredContents ioctlvs. This assumes that the first output vector
// is used for the content count (u32).
IPCCommandResult ES::GetStoredContentsCount(const IOS::ES::TMDReader& tmd,
                                            const IOCtlVRequest& request)
{
  if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid())
    return GetDefaultReply(ES_EINVAL);

  const u16 num_contents = static_cast<u16>(GetStoredContentsFromTMD(tmd).size());
  Memory::Write_U32(num_contents, request.io_vectors[0].address);

  INFO_LOG(IOS_ES, "GetStoredContentsCount (0x%x):  %u content(s) for %016" PRIx64, request.request,
           num_contents, tmd.GetTitleId());
  return GetDefaultReply(IPC_SUCCESS);
}
Пример #18
0
IPCCommandResult ES::GetTitles(const std::vector<u64>& titles, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 1))
    return GetDefaultReply(ES_EINVAL);

  const size_t max_count = Memory::Read_U32(request.in_vectors[0].address);
  for (size_t i = 0; i < std::min(max_count, titles.size()); i++)
  {
    Memory::Write_U64(titles[i], request.io_vectors[0].address + static_cast<u32>(i) * sizeof(u64));
    INFO_LOG(IOS_ES, "     title %016" PRIx64, titles[i]);
  }
  return GetDefaultReply(IPC_SUCCESS);
}
Пример #19
0
IPCCommandResult USBHost::HandleTransfer(std::shared_ptr<USB::Device> device, u32 request,
                                         std::function<s32()> submit) const
{
  if (!device)
    return GetDefaultReply(IPC_ENOENT);

  const s32 ret = submit();
  if (ret == IPC_SUCCESS)
    return GetNoReply();

  ERROR_LOG(IOS_USB, "[%04x:%04x] Failed to submit transfer (request %u): %s", device->GetVid(),
            device->GetPid(), request, device->GetErrorName(ret).c_str());
  return GetDefaultReply(ret <= 0 ? ret : IPC_EINVAL);
}
Пример #20
0
IPCCommandResult ES::ExportContentData(Context& context, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != 4 ||
      request.io_vectors[0].size == 0)
  {
    return GetDefaultReply(ES_EINVAL);
  }

  const u32 content_fd = Memory::Read_U32(request.in_vectors[0].address);
  u8* data = Memory::GetPointer(request.io_vectors[0].address);
  const u32 bytes_to_read = request.io_vectors[0].size;

  return GetDefaultReply(ExportContentData(context, content_fd, data, bytes_to_read));
}
Пример #21
0
IPCCommandResult FileIO::IOCtl(const IOCtlRequest& request)
{
  DEBUG_LOG(IOS_FILEIO, "FileIO: IOCtl (Device=%s)", m_name.c_str());
  s32 return_value = IPC_SUCCESS;

  switch (request.request)
  {
  case ISFS_IOCTL_GETFILESTATS:
  {
    if (m_file->IsOpen())
    {
      DEBUG_LOG(IOS_FILEIO, "File: %s, Length: %" PRIu64 ", Pos: %i", m_name.c_str(),
                m_file->GetSize(), m_SeekPos);
      Memory::Write_U32(static_cast<u32>(m_file->GetSize()), request.buffer_out);
      Memory::Write_U32(m_SeekPos, request.buffer_out + 4);
    }
    else
    {
      return_value = FS_ENOENT;
    }
  }
  break;

  default:
    request.Log(GetDeviceName(), LogTypes::IOS_FILEIO, LogTypes::LERROR);
  }

  return GetDefaultReply(return_value);
}
Пример #22
0
IPCCommandResult ES::GetSharedContents(const IOCtlVRequest& request) const
{
  if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != sizeof(u32))
    return GetDefaultReply(ES_EINVAL);

  const u32 max_count = Memory::Read_U32(request.in_vectors[0].address);
  if (request.io_vectors[0].size != 20 * max_count)
    return GetDefaultReply(ES_EINVAL);

  const std::vector<std::array<u8, 20>> hashes = GetSharedContents();
  const u32 count = std::min(static_cast<u32>(hashes.size()), max_count);
  Memory::CopyToEmu(request.io_vectors[0].address, hashes.data(), 20 * count);

  INFO_LOG(IOS_ES, "GetSharedContents: %u contents (%u requested)", count, max_count);
  return GetDefaultReply(IPC_SUCCESS);
}
Пример #23
0
IPCCommandResult CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress, bool _bForce)
{
    if (!_bForce)
        Memory::Write_U32(0, _CommandAddress + 4);
    m_Active = false;
    return GetDefaultReply();
}
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_base::IOCtl(u32 command_address)
{
  // NeoGamma (homebrew) is known to use this path.
  ERROR_LOG(WII_IPC_WIIMOTE, "Bad IOCtl to /dev/usb/oh1/57e/305");
  Memory::Write_U32(FS_EINVAL, command_address + 4);
  return GetDefaultReply();
}
Пример #25
0
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
{
  m_Mode = _Mode;
  u32 ReturnValue = 0;

  static const char* const Modes[] = {"Unk Mode", "Read only", "Write only", "Read and Write"};

  m_filepath = HLE_IPC_BuildFilename(m_Name);

  // 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))
  {
    INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode);
    OpenFile();
    ReturnValue = m_DeviceID;
  }
  else
  {
    WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[_Mode],
             m_filepath.c_str());
    ReturnValue = FS_FILE_NOT_EXIST;
  }

  if (_CommandAddress)
    Memory::Write_U32(ReturnValue, _CommandAddress + 4);
  m_Active = true;
  return GetDefaultReply();
}
Пример #26
0
IPCCommandResult CWII_IPC_HLE_Device_hid::Open(u32 _CommandAddress, u32 _Mode)
{
    DEBUG_LOG(WII_IPC_HID, "HID::Open");
    m_Active = true;
    Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
    return GetDefaultReply();
}
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
{
	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);

	if (m_file->IsOpen())
	{
		if (m_Mode == ISFS_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());
		}
		else
		{
			INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, 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))
			{
				ReturnValue = Size;
				m_SeekPos += Size;
			}
		}
	}
	else
	{
		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_FILE_NOT_EXIST;
	}

	Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
	return GetDefaultReply();
}
Пример #28
0
IPCCommandResult FileIO::Write(const ReadWriteRequest& request)
{
  s32 return_value = FS_EACCESS;
  if (m_file->IsOpen())
  {
    if (m_Mode == IOS_OPEN_READ)
    {
      WARN_LOG(IOS_FILEIO,
               "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(IOS_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(request.buffer), request.size))
      {
        return_value = request.size;
        m_SeekPos += request.size;
      }
    }
  }
  else
  {
    ERROR_LOG(IOS_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(), request.buffer, request.size);
    return_value = FS_ENOENT;
  }

  return GetDefaultReply(return_value);
}
Пример #29
0
IPCCommandResult SDIOSlot0::IOCtl(const IOCtlRequest& request)
{
  Memory::Memset(request.buffer_out, 0, request.buffer_out_size);

  switch (request.request)
  {
  case IOCTL_WRITEHCR:
    return WriteHCRegister(request);
  case IOCTL_READHCR:
    return ReadHCRegister(request);
  case IOCTL_RESETCARD:
    return ResetCard(request);
  case IOCTL_SETCLK:
    return SetClk(request);
  case IOCTL_SENDCMD:
    return SendCommand(request);
  case IOCTL_GETSTATUS:
    return GetStatus(request);
  case IOCTL_GETOCR:
    return GetOCRegister(request);
  default:
    ERROR_LOG(IOS_SD, "Unknown SD IOCtl command (0x%08x)", request.request);
    break;
  }

  return GetDefaultReply(IPC_SUCCESS);
}
Пример #30
0
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;
	}

	// DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer,
	// CommandBuffer.NumberPayloadBuffer, LogTypes::WII_IPC_SD);

	Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);

	return GetDefaultReply();
}