mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-27 08:15:33 +01:00
Merge pull request #10053 from lioncash/kdreq
IOS/Network/KD: Minor tidy-up changes
This commit is contained in:
commit
95fcedeef3
@ -59,8 +59,8 @@ void NWC24Config::ResetConfig()
|
|||||||
memset(&m_data, 0, sizeof(m_data));
|
memset(&m_data, 0, sizeof(m_data));
|
||||||
|
|
||||||
SetMagic(0x57634366);
|
SetMagic(0x57634366);
|
||||||
SetUnk(8);
|
SetVersion(8);
|
||||||
SetCreationStage(NWC24_IDCS_INITIAL);
|
SetCreationStage(NWC24CreationStage::Initial);
|
||||||
SetEnableBooting(0);
|
SetEnableBooting(0);
|
||||||
SetEmail("@wii.com");
|
SetEmail("@wii.com");
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ s32 NWC24Config::CheckNwc24Config() const
|
|||||||
return -14;
|
return -14;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Unk() != 8)
|
if (Version() != 8)
|
||||||
return -27;
|
return -27;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -126,14 +126,14 @@ void NWC24Config::SetMagic(u32 magic)
|
|||||||
m_data.magic = Common::swap32(magic);
|
m_data.magic = Common::swap32(magic);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 NWC24Config::Unk() const
|
u32 NWC24Config::Version() const
|
||||||
{
|
{
|
||||||
return Common::swap32(m_data.unk_04);
|
return Common::swap32(m_data.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NWC24Config::SetUnk(u32 unk_04)
|
void NWC24Config::SetVersion(u32 version)
|
||||||
{
|
{
|
||||||
m_data.unk_04 = Common::swap32(unk_04);
|
m_data.version = Common::swap32(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 NWC24Config::IdGen() const
|
u32 NWC24Config::IdGen() const
|
||||||
@ -165,14 +165,14 @@ void NWC24Config::SetChecksum(u32 checksum)
|
|||||||
m_data.checksum = Common::swap32(checksum);
|
m_data.checksum = Common::swap32(checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 NWC24Config::CreationStage() const
|
NWC24CreationStage NWC24Config::CreationStage() const
|
||||||
{
|
{
|
||||||
return Common::swap32(m_data.creation_stage);
|
return NWC24CreationStage(Common::swap32(u32(m_data.creation_stage)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NWC24Config::SetCreationStage(u32 creation_stage)
|
void NWC24Config::SetCreationStage(NWC24CreationStage creation_stage)
|
||||||
{
|
{
|
||||||
m_data.creation_stage = Common::swap32(creation_stage);
|
m_data.creation_stage = NWC24CreationStage(Common::swap32(u32(creation_stage)));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 NWC24Config::EnableBooting() const
|
u32 NWC24Config::EnableBooting() const
|
||||||
|
@ -25,24 +25,16 @@ enum ErrorCode : s32
|
|||||||
WC24_ERR_ID_NOT_REGISTERED = -44,
|
WC24_ERR_ID_NOT_REGISTERED = -44,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class NWC24CreationStage : u32
|
||||||
|
{
|
||||||
|
Initial = 0,
|
||||||
|
Generated = 1,
|
||||||
|
Registered = 2
|
||||||
|
};
|
||||||
|
|
||||||
class NWC24Config final
|
class NWC24Config final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum
|
|
||||||
{
|
|
||||||
NWC24_IDCS_INITIAL = 0,
|
|
||||||
NWC24_IDCS_GENERATED = 1,
|
|
||||||
NWC24_IDCS_REGISTERED = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
URL_COUNT = 0x05,
|
|
||||||
MAX_URL_LENGTH = 0x80,
|
|
||||||
MAX_EMAIL_LENGTH = 0x40,
|
|
||||||
MAX_PASSWORD_LENGTH = 0x20,
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit NWC24Config(std::shared_ptr<FS::FileSystem> fs);
|
explicit NWC24Config(std::shared_ptr<FS::FileSystem> fs);
|
||||||
|
|
||||||
void ReadConfig();
|
void ReadConfig();
|
||||||
@ -55,8 +47,8 @@ public:
|
|||||||
u32 Magic() const;
|
u32 Magic() const;
|
||||||
void SetMagic(u32 magic);
|
void SetMagic(u32 magic);
|
||||||
|
|
||||||
u32 Unk() const;
|
u32 Version() const;
|
||||||
void SetUnk(u32 unk_04);
|
void SetVersion(u32 version);
|
||||||
|
|
||||||
u32 IdGen() const;
|
u32 IdGen() const;
|
||||||
void SetIdGen(u32 id_generation);
|
void SetIdGen(u32 id_generation);
|
||||||
@ -65,8 +57,12 @@ public:
|
|||||||
u32 Checksum() const;
|
u32 Checksum() const;
|
||||||
void SetChecksum(u32 checksum);
|
void SetChecksum(u32 checksum);
|
||||||
|
|
||||||
u32 CreationStage() const;
|
NWC24CreationStage CreationStage() const;
|
||||||
void SetCreationStage(u32 creation_stage);
|
void SetCreationStage(NWC24CreationStage creation_stage);
|
||||||
|
|
||||||
|
bool IsCreated() const { return CreationStage() == NWC24CreationStage::Initial; }
|
||||||
|
bool IsGenerated() const { return CreationStage() == NWC24CreationStage::Generated; }
|
||||||
|
bool IsRegistered() const { return CreationStage() == NWC24CreationStage::Registered; }
|
||||||
|
|
||||||
u32 EnableBooting() const;
|
u32 EnableBooting() const;
|
||||||
void SetEnableBooting(u32 enable_booting);
|
void SetEnableBooting(u32 enable_booting);
|
||||||
@ -78,14 +74,22 @@ public:
|
|||||||
void SetEmail(const char* email);
|
void SetEmail(const char* email);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
URL_COUNT = 0x05,
|
||||||
|
MAX_URL_LENGTH = 0x80,
|
||||||
|
MAX_EMAIL_LENGTH = 0x40,
|
||||||
|
MAX_PASSWORD_LENGTH = 0x20,
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct ConfigData final
|
struct ConfigData final
|
||||||
{
|
{
|
||||||
u32 magic; // 'WcCf' 0x57634366
|
u32 magic; // 'WcCf' 0x57634366
|
||||||
u32 unk_04; // must be 8
|
u32 version; // must be 8
|
||||||
u64 nwc24_id;
|
u64 nwc24_id;
|
||||||
u32 id_generation;
|
u32 id_generation;
|
||||||
u32 creation_stage; // 0:not_generated; 1:generated; 2:registered
|
NWC24CreationStage creation_stage;
|
||||||
char email[MAX_EMAIL_LENGTH];
|
char email[MAX_EMAIL_LENGTH];
|
||||||
char paswd[MAX_PASSWORD_LENGTH];
|
char paswd[MAX_PASSWORD_LENGTH];
|
||||||
char mlchkid[0x24];
|
char mlchkid[0x24];
|
||||||
|
@ -3,8 +3,11 @@
|
|||||||
|
|
||||||
#include "Core/IOS/Network/KD/NetKDRequest.h"
|
#include "Core/IOS/Network/KD/NetKDRequest.h"
|
||||||
|
|
||||||
#include <map>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "Common/CommonPaths.h"
|
#include "Common/CommonPaths.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
@ -21,6 +24,126 @@
|
|||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
enum class HardwareModel : u8
|
||||||
|
{
|
||||||
|
RVT = 0,
|
||||||
|
RVV = 0,
|
||||||
|
RVL = 1,
|
||||||
|
RVD = 2,
|
||||||
|
Unknown = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
u8 GetAreaCode(std::string_view area)
|
||||||
|
{
|
||||||
|
static constexpr std::array<std::pair<std::string_view, u8>, 13> regions{{
|
||||||
|
{"JPN", 0},
|
||||||
|
{"USA", 1},
|
||||||
|
{"EUR", 2},
|
||||||
|
{"AUS", 2},
|
||||||
|
{"BRA", 1},
|
||||||
|
{"TWN", 3},
|
||||||
|
{"ROC", 3},
|
||||||
|
{"KOR", 4},
|
||||||
|
{"HKG", 5},
|
||||||
|
{"ASI", 5},
|
||||||
|
{"LTN", 1},
|
||||||
|
{"SAF", 2},
|
||||||
|
{"CHN", 6},
|
||||||
|
}};
|
||||||
|
|
||||||
|
const auto entry_pos = std::find_if(regions.cbegin(), regions.cend(),
|
||||||
|
[&area](const auto& entry) { return entry.first == area; });
|
||||||
|
if (entry_pos != regions.end())
|
||||||
|
return entry_pos->second;
|
||||||
|
|
||||||
|
return 7; // Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
HardwareModel GetHardwareModel(std::string_view model)
|
||||||
|
{
|
||||||
|
static constexpr std::array<std::pair<std::string_view, HardwareModel>, 4> models{{
|
||||||
|
{"RVL", HardwareModel::RVL},
|
||||||
|
{"RVT", HardwareModel::RVT},
|
||||||
|
{"RVV", HardwareModel::RVV},
|
||||||
|
{"RVD", HardwareModel::RVD},
|
||||||
|
}};
|
||||||
|
|
||||||
|
const auto entry_pos = std::find_if(models.cbegin(), models.cend(),
|
||||||
|
[&model](const auto& entry) { return entry.first == model; });
|
||||||
|
if (entry_pos != models.cend())
|
||||||
|
return entry_pos->second;
|
||||||
|
|
||||||
|
return HardwareModel::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 NWC24MakeUserID(u64* nwc24_id, u32 hollywood_id, u16 id_ctr, HardwareModel hardware_model,
|
||||||
|
u8 area_code)
|
||||||
|
{
|
||||||
|
static constexpr std::array<u8, 8> table2{
|
||||||
|
0x1, 0x5, 0x0, 0x4, 0x2, 0x3, 0x6, 0x7,
|
||||||
|
};
|
||||||
|
static constexpr std::array<u8, 16> table1{
|
||||||
|
0x4, 0xB, 0x7, 0x9, 0xF, 0x1, 0xD, 0x3, 0xC, 0x2, 0x6, 0xE, 0x8, 0x0, 0xA, 0x5,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr auto u64_get_byte = [](u64 value, u32 shift) -> u8 { return u8(value >> (shift * 8)); };
|
||||||
|
|
||||||
|
constexpr auto u64_insert_byte = [](u64 value, u32 shift, u8 byte) -> u64 {
|
||||||
|
const u64 mask = 0x00000000000000FFULL << (shift * 8);
|
||||||
|
const u64 inst = u64{byte} << (shift * 8);
|
||||||
|
return (value & ~mask) | inst;
|
||||||
|
};
|
||||||
|
|
||||||
|
u64 mix_id = (u64{area_code} << 50) | (u64(hardware_model) << 47) | (u64{hollywood_id} << 15) |
|
||||||
|
(u64{id_ctr} << 10);
|
||||||
|
const u64 mix_id_copy1 = mix_id;
|
||||||
|
|
||||||
|
u32 ctr = 0;
|
||||||
|
for (ctr = 0; ctr <= 42; ctr++)
|
||||||
|
{
|
||||||
|
u64 value = mix_id >> (52 - ctr);
|
||||||
|
if ((value & 1) != 0)
|
||||||
|
{
|
||||||
|
value = 0x0000000000000635ULL << (42 - ctr);
|
||||||
|
mix_id ^= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mix_id = (mix_id_copy1 | (mix_id & 0xFFFFFFFFUL)) ^ 0x0000B3B3B3B3B3B3ULL;
|
||||||
|
mix_id = (mix_id >> 10) | ((mix_id & 0x3FF) << (11 + 32));
|
||||||
|
|
||||||
|
for (ctr = 0; ctr <= 5; ctr++)
|
||||||
|
{
|
||||||
|
const u8 ret = u64_get_byte(mix_id, ctr);
|
||||||
|
const u8 foobar = u8((u32{table1[(ret >> 4) & 0xF]} << 4) | table1[ret & 0xF]);
|
||||||
|
mix_id = u64_insert_byte(mix_id, ctr, foobar & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 mix_id_copy2 = mix_id;
|
||||||
|
|
||||||
|
for (ctr = 0; ctr <= 5; ctr++)
|
||||||
|
{
|
||||||
|
const u8 ret = u64_get_byte(mix_id_copy2, ctr);
|
||||||
|
mix_id = u64_insert_byte(mix_id, table2[ctr], ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
mix_id &= 0x001FFFFFFFFFFFFFULL;
|
||||||
|
mix_id = (mix_id << 1) | ((mix_id >> 52) & 1);
|
||||||
|
|
||||||
|
mix_id ^= 0x00005E5E5E5E5E5EULL;
|
||||||
|
mix_id &= 0x001FFFFFFFFFFFFFULL;
|
||||||
|
|
||||||
|
*nwc24_id = mix_id;
|
||||||
|
|
||||||
|
if (mix_id > 9999999999999999ULL)
|
||||||
|
return NWC24::WC24_ERR_FATAL;
|
||||||
|
|
||||||
|
return NWC24::WC24_OK;
|
||||||
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
NetKDRequestDevice::NetKDRequestDevice(Kernel& ios, const std::string& device_name)
|
NetKDRequestDevice::NetKDRequestDevice(Kernel& ios, const std::string& device_name)
|
||||||
: Device(ios, device_name), config{ios.GetFS()}
|
: Device(ios, device_name), config{ios.GetFS()}
|
||||||
{
|
{
|
||||||
@ -33,21 +156,47 @@ NetKDRequestDevice::~NetKDRequestDevice()
|
|||||||
|
|
||||||
std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
|
enum : u32
|
||||||
|
{
|
||||||
|
IOCTL_NWC24_SUSPEND_SCHEDULER = 0x01,
|
||||||
|
IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULER = 0x02,
|
||||||
|
IOCTL_NWC24_EXEC_RESUME_SCHEDULER = 0x03,
|
||||||
|
IOCTL_NWC24_KD_GET_TIME_TRIGGERS = 0x04,
|
||||||
|
IOCTL_NWC24_SET_SCHEDULE_SPAN = 0x05,
|
||||||
|
IOCTL_NWC24_STARTUP_SOCKET = 0x06,
|
||||||
|
IOCTL_NWC24_CLEANUP_SOCKET = 0x07,
|
||||||
|
IOCTL_NWC24_LOCK_SOCKET = 0x08,
|
||||||
|
IOCTL_NWC24_UNLOCK_SOCKET = 0x09,
|
||||||
|
IOCTL_NWC24_CHECK_MAIL_NOW = 0x0A,
|
||||||
|
IOCTL_NWC24_SEND_MAIL_NOW = 0x0B,
|
||||||
|
IOCTL_NWC24_RECEIVE_MAIL_NOW = 0x0C,
|
||||||
|
IOCTL_NWC24_SAVE_MAIL_NOW = 0x0D,
|
||||||
|
IOCTL_NWC24_DOWNLOAD_NOW_EX = 0x0E,
|
||||||
|
IOCTL_NWC24_REQUEST_GENERATED_USER_ID = 0x0F,
|
||||||
|
IOCTL_NWC24_REQUEST_REGISTER_USER_ID = 0x10,
|
||||||
|
IOCTL_NWC24_GET_SCHEDULER_STAT = 0x1E,
|
||||||
|
IOCTL_NWC24_SET_FILTER_MODE = 0x1F,
|
||||||
|
IOCTL_NWC24_SET_DEBUG_MODE = 0x20,
|
||||||
|
IOCTL_NWC24_KD_SET_NEXT_WAKEUP = 0x21,
|
||||||
|
IOCTL_NWC24_SET_SCRIPT_MODE = 0x22,
|
||||||
|
IOCTL_NWC24_REQUEST_SHUTDOWN = 0x28,
|
||||||
|
};
|
||||||
|
|
||||||
s32 return_value = 0;
|
s32 return_value = 0;
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
{
|
{
|
||||||
case IOCTL_NWC24_SUSPEND_SCHEDULAR:
|
case IOCTL_NWC24_SUSPEND_SCHEDULER:
|
||||||
// NWC24iResumeForCloseLib from NWC24SuspendScheduler (Input: none, Output: 32 bytes)
|
// NWC24iResumeForCloseLib from NWC24SuspendScheduler (Input: none, Output: 32 bytes)
|
||||||
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_SUSPEND_SCHEDULAR - NI");
|
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_SUSPEND_SCHEDULER - NI");
|
||||||
WriteReturnValue(0, request.buffer_out); // no error
|
WriteReturnValue(0, request.buffer_out); // no error
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR: // NWC24iResumeForCloseLib
|
case IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULER: // NWC24iResumeForCloseLib
|
||||||
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR - NI");
|
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULER - NI");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_NWC24_EXEC_RESUME_SCHEDULAR: // NWC24iResumeForCloseLib
|
case IOCTL_NWC24_EXEC_RESUME_SCHEDULER: // NWC24iResumeForCloseLib
|
||||||
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_EXEC_RESUME_SCHEDULAR - NI");
|
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_EXEC_RESUME_SCHEDULER - NI");
|
||||||
WriteReturnValue(0, request.buffer_out); // no error
|
WriteReturnValue(0, request.buffer_out); // no error
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -79,7 +228,7 @@ std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
|||||||
|
|
||||||
case IOCTL_NWC24_REQUEST_GENERATED_USER_ID: // (Input: none, Output: 32 bytes)
|
case IOCTL_NWC24_REQUEST_GENERATED_USER_ID: // (Input: none, Output: 32 bytes)
|
||||||
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_GENERATED_USER_ID");
|
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_GENERATED_USER_ID");
|
||||||
if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_INITIAL)
|
if (config.IsCreated())
|
||||||
{
|
{
|
||||||
const std::string settings_file_path =
|
const std::string settings_file_path =
|
||||||
Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/" WII_SETTING;
|
Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/" WII_SETTING;
|
||||||
@ -99,17 +248,17 @@ std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
|||||||
|
|
||||||
if (!area.empty() && !model.empty())
|
if (!area.empty() && !model.empty())
|
||||||
{
|
{
|
||||||
u8 area_code = GetAreaCode(area);
|
const u8 area_code = GetAreaCode(area);
|
||||||
u8 id_ctr = config.IdGen();
|
const u8 id_ctr = u8(config.IdGen());
|
||||||
u8 hardware_model = GetHardwareModel(model);
|
const HardwareModel hardware_model = GetHardwareModel(model);
|
||||||
|
|
||||||
u32 HollywoodID = m_ios.GetIOSC().GetDeviceId();
|
const u32 hollywood_id = m_ios.GetIOSC().GetDeviceId();
|
||||||
u64 UserID = 0;
|
u64 user_id = 0;
|
||||||
|
|
||||||
s32 ret = NWC24MakeUserID(&UserID, HollywoodID, id_ctr, hardware_model, area_code);
|
const s32 ret = NWC24MakeUserID(&user_id, hollywood_id, id_ctr, hardware_model, area_code);
|
||||||
config.SetId(UserID);
|
config.SetId(user_id);
|
||||||
config.IncrementIdGen();
|
config.IncrementIdGen();
|
||||||
config.SetCreationStage(NWC24::NWC24Config::NWC24_IDCS_GENERATED);
|
config.SetCreationStage(NWC24::NWC24CreationStage::Generated);
|
||||||
config.WriteConfig();
|
config.WriteConfig();
|
||||||
|
|
||||||
WriteReturnValue(ret, request.buffer_out);
|
WriteReturnValue(ret, request.buffer_out);
|
||||||
@ -119,20 +268,20 @@ std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
|||||||
WriteReturnValue(NWC24::WC24_ERR_FATAL, request.buffer_out);
|
WriteReturnValue(NWC24::WC24_ERR_FATAL, request.buffer_out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_GENERATED)
|
else if (config.IsGenerated())
|
||||||
{
|
{
|
||||||
WriteReturnValue(NWC24::WC24_ERR_ID_GENERATED, request.buffer_out);
|
WriteReturnValue(NWC24::WC24_ERR_ID_GENERATED, request.buffer_out);
|
||||||
}
|
}
|
||||||
else if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_REGISTERED)
|
else if (config.IsRegistered())
|
||||||
{
|
{
|
||||||
WriteReturnValue(NWC24::WC24_ERR_ID_REGISTERED, request.buffer_out);
|
WriteReturnValue(NWC24::WC24_ERR_ID_REGISTERED, request.buffer_out);
|
||||||
}
|
}
|
||||||
Memory::Write_U64(config.Id(), request.buffer_out + 4);
|
Memory::Write_U64(config.Id(), request.buffer_out + 4);
|
||||||
Memory::Write_U32(config.CreationStage(), request.buffer_out + 0xC);
|
Memory::Write_U32(u32(config.CreationStage()), request.buffer_out + 0xC);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_NWC24_GET_SCHEDULAR_STAT:
|
case IOCTL_NWC24_GET_SCHEDULER_STAT:
|
||||||
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_GET_SCHEDULAR_STAT - NI");
|
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_GET_SCHEDULER_STAT - NI");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_NWC24_SAVE_MAIL_NOW:
|
case IOCTL_NWC24_SAVE_MAIL_NOW:
|
||||||
@ -170,99 +319,4 @@ std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
|||||||
|
|
||||||
return IPCReply(return_value);
|
return IPCReply(return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 NetKDRequestDevice::GetAreaCode(const std::string& area) const
|
|
||||||
{
|
|
||||||
static const std::map<std::string, u8> regions = {
|
|
||||||
{"JPN", 0}, {"USA", 1}, {"EUR", 2}, {"AUS", 2}, {"BRA", 1}, {"TWN", 3}, {"ROC", 3},
|
|
||||||
{"KOR", 4}, {"HKG", 5}, {"ASI", 5}, {"LTN", 1}, {"SAF", 2}, {"CHN", 6},
|
|
||||||
};
|
|
||||||
|
|
||||||
auto entryPos = regions.find(area);
|
|
||||||
if (entryPos != regions.end())
|
|
||||||
return entryPos->second;
|
|
||||||
|
|
||||||
return 7; // Unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 NetKDRequestDevice::GetHardwareModel(const std::string& model) const
|
|
||||||
{
|
|
||||||
static const std::map<std::string, u8> models = {
|
|
||||||
{"RVL", MODEL_RVL},
|
|
||||||
{"RVT", MODEL_RVT},
|
|
||||||
{"RVV", MODEL_RVV},
|
|
||||||
{"RVD", MODEL_RVD},
|
|
||||||
};
|
|
||||||
|
|
||||||
auto entryPos = models.find(model);
|
|
||||||
if (entryPos != models.end())
|
|
||||||
return entryPos->second;
|
|
||||||
|
|
||||||
return MODEL_ELSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 u64_get_byte(u64 value, u8 shift)
|
|
||||||
{
|
|
||||||
return (u8)(value >> (shift * 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 u64_insert_byte(u64 value, u8 shift, u8 byte)
|
|
||||||
{
|
|
||||||
u64 mask = 0x00000000000000FFULL << (shift * 8);
|
|
||||||
u64 inst = (u64)byte << (shift * 8);
|
|
||||||
return (value & ~mask) | inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 NetKDRequestDevice::NWC24MakeUserID(u64* nwc24_id, u32 hollywood_id, u16 id_ctr,
|
|
||||||
u8 hardware_model, u8 area_code)
|
|
||||||
{
|
|
||||||
const u8 table2[8] = {0x1, 0x5, 0x0, 0x4, 0x2, 0x3, 0x6, 0x7};
|
|
||||||
const u8 table1[16] = {0x4, 0xB, 0x7, 0x9, 0xF, 0x1, 0xD, 0x3,
|
|
||||||
0xC, 0x2, 0x6, 0xE, 0x8, 0x0, 0xA, 0x5};
|
|
||||||
|
|
||||||
u64 mix_id = ((u64)area_code << 50) | ((u64)hardware_model << 47) | ((u64)hollywood_id << 15) |
|
|
||||||
((u64)id_ctr << 10);
|
|
||||||
u64 mix_id_copy1 = mix_id;
|
|
||||||
|
|
||||||
int ctr = 0;
|
|
||||||
for (ctr = 0; ctr <= 42; ctr++)
|
|
||||||
{
|
|
||||||
u64 value = mix_id >> (52 - ctr);
|
|
||||||
if (value & 1)
|
|
||||||
{
|
|
||||||
value = 0x0000000000000635ULL << (42 - ctr);
|
|
||||||
mix_id ^= value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mix_id = (mix_id_copy1 | (mix_id & 0xFFFFFFFFUL)) ^ 0x0000B3B3B3B3B3B3ULL;
|
|
||||||
mix_id = (mix_id >> 10) | ((mix_id & 0x3FF) << (11 + 32));
|
|
||||||
|
|
||||||
for (ctr = 0; ctr <= 5; ctr++)
|
|
||||||
{
|
|
||||||
u8 ret = u64_get_byte(mix_id, ctr);
|
|
||||||
u8 foobar = ((table1[(ret >> 4) & 0xF]) << 4) | (table1[ret & 0xF]);
|
|
||||||
mix_id = u64_insert_byte(mix_id, ctr, foobar & 0xff);
|
|
||||||
}
|
|
||||||
u64 mix_id_copy2 = mix_id;
|
|
||||||
|
|
||||||
for (ctr = 0; ctr <= 5; ctr++)
|
|
||||||
{
|
|
||||||
u8 ret = u64_get_byte(mix_id_copy2, ctr);
|
|
||||||
mix_id = u64_insert_byte(mix_id, table2[ctr], ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
mix_id &= 0x001FFFFFFFFFFFFFULL;
|
|
||||||
mix_id = (mix_id << 1) | ((mix_id >> 52) & 1);
|
|
||||||
|
|
||||||
mix_id ^= 0x00005E5E5E5E5E5EULL;
|
|
||||||
mix_id &= 0x001FFFFFFFFFFFFFULL;
|
|
||||||
|
|
||||||
*nwc24_id = mix_id;
|
|
||||||
|
|
||||||
if (mix_id > 9999999999999999ULL)
|
|
||||||
return NWC24::WC24_ERR_FATAL;
|
|
||||||
|
|
||||||
return NWC24::WC24_OK;
|
|
||||||
}
|
|
||||||
} // namespace IOS::HLE
|
} // namespace IOS::HLE
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
#include "Core/IOS/Device.h"
|
#include "Core/IOS/Device.h"
|
||||||
#include "Core/IOS/Network/KD/NWC24Config.h"
|
#include "Core/IOS/Network/KD/NWC24Config.h"
|
||||||
|
|
||||||
@ -23,46 +22,6 @@ public:
|
|||||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum
|
|
||||||
{
|
|
||||||
IOCTL_NWC24_SUSPEND_SCHEDULAR = 0x01,
|
|
||||||
IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR = 0x02,
|
|
||||||
IOCTL_NWC24_EXEC_RESUME_SCHEDULAR = 0x03,
|
|
||||||
IOCTL_NWC24_KD_GET_TIME_TRIGGERS = 0x04,
|
|
||||||
IOCTL_NWC24_SET_SCHEDULE_SPAN = 0x05,
|
|
||||||
IOCTL_NWC24_STARTUP_SOCKET = 0x06,
|
|
||||||
IOCTL_NWC24_CLEANUP_SOCKET = 0x07,
|
|
||||||
IOCTL_NWC24_LOCK_SOCKET = 0x08,
|
|
||||||
IOCTL_NWC24_UNLOCK_SOCKET = 0x09,
|
|
||||||
IOCTL_NWC24_CHECK_MAIL_NOW = 0x0A,
|
|
||||||
IOCTL_NWC24_SEND_MAIL_NOW = 0x0B,
|
|
||||||
IOCTL_NWC24_RECEIVE_MAIL_NOW = 0x0C,
|
|
||||||
IOCTL_NWC24_SAVE_MAIL_NOW = 0x0D,
|
|
||||||
IOCTL_NWC24_DOWNLOAD_NOW_EX = 0x0E,
|
|
||||||
IOCTL_NWC24_REQUEST_GENERATED_USER_ID = 0x0F,
|
|
||||||
IOCTL_NWC24_REQUEST_REGISTER_USER_ID = 0x10,
|
|
||||||
IOCTL_NWC24_GET_SCHEDULAR_STAT = 0x1E,
|
|
||||||
IOCTL_NWC24_SET_FILTER_MODE = 0x1F,
|
|
||||||
IOCTL_NWC24_SET_DEBUG_MODE = 0x20,
|
|
||||||
IOCTL_NWC24_KD_SET_NEXT_WAKEUP = 0x21,
|
|
||||||
IOCTL_NWC24_SET_SCRIPT_MODE = 0x22,
|
|
||||||
IOCTL_NWC24_REQUEST_SHUTDOWN = 0x28,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
MODEL_RVT = 0,
|
|
||||||
MODEL_RVV = 0,
|
|
||||||
MODEL_RVL = 1,
|
|
||||||
MODEL_RVD = 2,
|
|
||||||
MODEL_ELSE = 7
|
|
||||||
};
|
|
||||||
|
|
||||||
u8 GetAreaCode(const std::string& area) const;
|
|
||||||
u8 GetHardwareModel(const std::string& model) const;
|
|
||||||
|
|
||||||
s32 NWC24MakeUserID(u64* nwc24_id, u32 hollywood_id, u16 id_ctr, u8 hardware_model, u8 area_code);
|
|
||||||
|
|
||||||
NWC24::NWC24Config config;
|
NWC24::NWC24Config config;
|
||||||
};
|
};
|
||||||
} // namespace IOS::HLE
|
} // namespace IOS::HLE
|
||||||
|
@ -20,6 +20,15 @@ NetKDTimeDevice::~NetKDTimeDevice() = default;
|
|||||||
|
|
||||||
std::optional<IPCReply> NetKDTimeDevice::IOCtl(const IOCtlRequest& request)
|
std::optional<IPCReply> NetKDTimeDevice::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
|
enum : u32
|
||||||
|
{
|
||||||
|
IOCTL_NW24_GET_UNIVERSAL_TIME = 0x14,
|
||||||
|
IOCTL_NW24_SET_UNIVERSAL_TIME = 0x15,
|
||||||
|
IOCTL_NW24_UNIMPLEMENTED = 0x16,
|
||||||
|
IOCTL_NW24_SET_RTC_COUNTER = 0x17,
|
||||||
|
IOCTL_NW24_GET_TIME_DIFF = 0x18,
|
||||||
|
};
|
||||||
|
|
||||||
s32 result = 0;
|
s32 result = 0;
|
||||||
u32 common_result = 0;
|
u32 common_result = 0;
|
||||||
// TODO Writes stuff to /shared2/nwc24/misc.bin
|
// TODO Writes stuff to /shared2/nwc24/misc.bin
|
||||||
@ -76,13 +85,17 @@ std::optional<IPCReply> NetKDTimeDevice::IOCtl(const IOCtlRequest& request)
|
|||||||
|
|
||||||
u64 NetKDTimeDevice::GetAdjustedUTC() const
|
u64 NetKDTimeDevice::GetAdjustedUTC() const
|
||||||
{
|
{
|
||||||
return ExpansionInterface::CEXIIPL::GetEmulatedTime(ExpansionInterface::CEXIIPL::UNIX_EPOCH) +
|
using namespace ExpansionInterface;
|
||||||
utcdiff;
|
|
||||||
|
const u32 emulated_time = CEXIIPL::GetEmulatedTime(CEXIIPL::UNIX_EPOCH);
|
||||||
|
return u64(s64(emulated_time) + utcdiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetKDTimeDevice::SetAdjustedUTC(u64 wii_utc)
|
void NetKDTimeDevice::SetAdjustedUTC(u64 wii_utc)
|
||||||
{
|
{
|
||||||
utcdiff = ExpansionInterface::CEXIIPL::GetEmulatedTime(ExpansionInterface::CEXIIPL::UNIX_EPOCH) -
|
using namespace ExpansionInterface;
|
||||||
wii_utc;
|
|
||||||
|
const u32 emulated_time = CEXIIPL::GetEmulatedTime(CEXIIPL::UNIX_EPOCH);
|
||||||
|
utcdiff = s64(emulated_time - wii_utc);
|
||||||
}
|
}
|
||||||
} // namespace IOS::HLE
|
} // namespace IOS::HLE
|
||||||
|
@ -31,15 +31,6 @@ private:
|
|||||||
// what the host OS thinks
|
// what the host OS thinks
|
||||||
void SetAdjustedUTC(u64 wii_utc);
|
void SetAdjustedUTC(u64 wii_utc);
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
IOCTL_NW24_GET_UNIVERSAL_TIME = 0x14,
|
|
||||||
IOCTL_NW24_SET_UNIVERSAL_TIME = 0x15,
|
|
||||||
IOCTL_NW24_UNIMPLEMENTED = 0x16,
|
|
||||||
IOCTL_NW24_SET_RTC_COUNTER = 0x17,
|
|
||||||
IOCTL_NW24_GET_TIME_DIFF = 0x18,
|
|
||||||
};
|
|
||||||
|
|
||||||
u64 rtc = 0;
|
u64 rtc = 0;
|
||||||
s64 utcdiff = 0;
|
s64 utcdiff = 0;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user