Exemple #1
0
IPCCommandResult ES::ImportTitleCancel(Context& context, const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(0, 0))
    return GetDefaultReply(ES_EINVAL);

  return GetDefaultReply(ImportTitleCancel(context));
}
Exemple #2
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));
}
Exemple #3
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));
}
Exemple #4
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));
}
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);
}
IPCCommandResult ES::GetTMDStoredContentsCount(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 1))
    return GetDefaultReply(ES_EINVAL);

  std::vector<u8> tmd_bytes(request.in_vectors[0].size);
  Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());
  return GetStoredContentsCount(IOS::ES::TMDReader{std::move(tmd_bytes)}, request);
}
Exemple #7
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)));
}
Exemple #8
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));
}
Exemple #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)));
}
Exemple #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));
}
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);
}
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);
}
Exemple #13
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));
}
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);
}
Exemple #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));
}
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);
}
Exemple #17
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));
}
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);
}
IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(1, 1))
    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);

  const u32 tmd_size = static_cast<u32>(tmd.GetBytes().size());
  Memory::Write_U32(tmd_size, request.io_vectors[0].address);

  INFO_LOG(IOS_ES, "GetStoredTMDSize: %u bytes  for %016" PRIx64, tmd_size, title_id);

  return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(2, 1))
    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);

  // TODO: actually use this param in when writing to the outbuffer :/
  const u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address);

  const std::vector<u8>& raw_tmd = tmd.GetBytes();
  if (raw_tmd.size() != request.io_vectors[0].size)
    return GetDefaultReply(ES_EINVAL);

  Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size());

  INFO_LOG(IOS_ES, "GetStoredTMD: title %016" PRIx64 " (buffer size: %u)", title_id, MaxCount);
  return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult ES::GetTMDStoredContents(const IOCtlVRequest& request)
{
  if (!request.HasNumberOfValidVectors(2, 1))
    return GetDefaultReply(ES_EINVAL);

  std::vector<u8> tmd_bytes(request.in_vectors[0].size);
  Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());

  const IOS::ES::TMDReader tmd{std::move(tmd_bytes)};
  if (!tmd.IsValid())
    return GetDefaultReply(ES_EINVAL);

  std::vector<u8> cert_store;
  ReturnCode ret = ReadCertStore(&cert_store);
  if (ret != IPC_SUCCESS)
    return GetDefaultReply(ret);

  ret = VerifyContainer(VerifyContainerType::TMD, VerifyMode::UpdateCertStore, tmd, cert_store);
  if (ret != IPC_SUCCESS)
    return GetDefaultReply(ret);

  return GetStoredContents(tmd, request);
}
Exemple #22
0
IPCCommandResult NetIPTop::HandleGetAddressInfoRequest(const IOCtlVRequest& request)
{
  addrinfo hints;

  if (request.in_vectors.size() > 2 && request.in_vectors[2].size)
  {
    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;
  }

  // getaddrinfo allows a null pointer for the nodeName or serviceName strings
  // So we have to do a bit of juggling here.
  std::string nodeNameStr;
  const char* pNodeName = nullptr;
  if (request.in_vectors.size() > 0 && request.in_vectors[0].size > 0)
  {
    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 (request.in_vectors.size() > 1 && request.in_vectors[1].size > 0)
  {
    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,
      (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)
  {
    constexpr size_t WII_ADDR_INFO_SIZE = 0x20;
    for (addrinfo* result_iter = result; result_iter != nullptr; result_iter = result_iter->ai_next)
    {
      Memory::Write_U32(result_iter->ai_flags, addr);
      Memory::Write_U32(result_iter->ai_family, addr + 0x04);
      Memory::Write_U32(result_iter->ai_socktype, addr + 0x08);
      Memory::Write_U32(result_iter->ai_protocol, addr + 0x0C);
      Memory::Write_U32((u32)result_iter->ai_addrlen, addr + 0x10);
      // what to do? where to put? the buffer of 0x834 doesn't allow space for this
      Memory::Write_U32(/*result->ai_cannonname*/ 0, addr + 0x14);

      if (result_iter->ai_addr)
      {
        Memory::Write_U32(sockoffset, addr + 0x18);
        Memory::Write_U8(result_iter->ai_addrlen & 0xFF, sockoffset);
        Memory::Write_U8(result_iter->ai_addr->sa_family & 0xFF, sockoffset + 0x01);
        Memory::CopyToEmu(sockoffset + 0x2, result_iter->ai_addr->sa_data,
                          sizeof(result_iter->ai_addr->sa_data));
        sockoffset += 0x1C;
      }
      else
      {
        Memory::Write_U32(0, addr + 0x18);
      }

      if (result_iter->ai_next)
      {
        Memory::Write_U32(addr + WII_ADDR_INFO_SIZE, addr + 0x1C);
      }
      else
      {
        Memory::Write_U32(0, addr + 0x1C);
      }

      addr += WII_ADDR_INFO_SIZE;
    }

    freeaddrinfo(result);
  }
  else
  {
    // Host not found
    ret = -305;
  }

  request.Dump(GetDeviceName(), LogTypes::IOS_NET, LogTypes::LINFO);
  return GetDefaultReply(ret);
}
Exemple #23
0
// 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 NetWDCommand::IOCtlV(const IOCtlVRequest& request)
{
  s32 return_value = IPC_SUCCESS;

  switch (request.request)
  {
  case IOCTLV_WD_SCAN:
  {
    // Gives parameters detailing type of scan and what to match
    // XXX - unused
    // ScanInfo *scan = (ScanInfo *)Memory::GetPointer(request.in_vectors.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);

    BSSInfo* bss = (BSSInfo*)&results[1];
    memset(bss, 0, sizeof(BSSInfo));

    bss->length = Common::swap16(sizeof(BSSInfo));
    bss->rssi = Common::swap16(0xffff);

    for (int i = 0; i < BSSID_SIZE; ++i)
      bss->bssid[i] = i;

    const char* ssid = "dolphin-emu";
    strcpy((char*)bss->ssid, ssid);
    bss->ssid_length = Common::swap16((u16)strlen(ssid));

    bss->channel = Common::swap16(2);
  }
  break;

  case IOCTLV_WD_GET_INFO:
  {
    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);
    info->ntr_allowed_channels = Common::swap16(0xfffe);

    u8 address[Common::MAC_ADDRESS_SIZE];
    GetMacAddress(address);
    memcpy(info->mac, address, sizeof(info->mac));
  }
  break;

  case IOCTLV_WD_GET_MODE:
  case IOCTLV_WD_SET_LINKSTATE:
  case IOCTLV_WD_GET_LINKSTATE:
  case IOCTLV_WD_SET_CONFIG:
  case IOCTLV_WD_GET_CONFIG:
  case IOCTLV_WD_CHANGE_BEACON:
  case IOCTLV_WD_DISASSOC:
  case IOCTLV_WD_MP_SEND_FRAME:
  case IOCTLV_WD_SEND_FRAME:
  case IOCTLV_WD_CALL_WL:
  case IOCTLV_WD_MEASURE_CHANNEL:
  case IOCTLV_WD_GET_LASTERROR:
  case IOCTLV_WD_CHANGE_GAMEINFO:
  case IOCTLV_WD_CHANGE_VTSF:
  case IOCTLV_WD_RECV_FRAME:
  case IOCTLV_WD_RECV_NOTIFICATION:
  default:
    request.Dump(GetDeviceName(), LogTypes::IOS_NET, LogTypes::LINFO);
  }

  return GetDefaultReply(return_value);
}