mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-26 02:54:17 +01:00
nn_act: Make AcquireToken gracefully fail in offline mode + refactor
This commit is contained in:
parent
bf37a8281e
commit
bd13d4bdc3
@ -21,14 +21,18 @@
|
|||||||
|
|
||||||
using namespace iosu::kernel;
|
using namespace iosu::kernel;
|
||||||
|
|
||||||
|
using NexToken = NAPI::ACTNexToken;
|
||||||
|
static_assert(sizeof(NexToken) == 0x25C);
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool isInitialized;
|
bool isInitialized;
|
||||||
|
std::mutex actMutex;
|
||||||
}iosuAct = { };
|
}iosuAct = { };
|
||||||
|
|
||||||
// account manager
|
// account manager
|
||||||
|
|
||||||
typedef struct
|
struct actAccountData_t
|
||||||
{
|
{
|
||||||
bool isValid;
|
bool isValid;
|
||||||
// options
|
// options
|
||||||
@ -49,7 +53,12 @@ typedef struct
|
|||||||
// Mii
|
// Mii
|
||||||
FFLData_t miiData;
|
FFLData_t miiData;
|
||||||
uint16le miiNickname[ACT_NICKNAME_LENGTH];
|
uint16le miiNickname[ACT_NICKNAME_LENGTH];
|
||||||
}actAccountData_t;
|
|
||||||
|
bool IsNetworkAccount() const
|
||||||
|
{
|
||||||
|
return isNetworkAccount; // todo - IOSU only checks if accountId is not empty?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#define IOSU_ACT_ACCOUNT_MAX_COUNT (0xC)
|
#define IOSU_ACT_ACCOUNT_MAX_COUNT (0xC)
|
||||||
|
|
||||||
@ -159,161 +168,11 @@ uint32 iosuAct_getAccountIdOfCurrentAccount()
|
|||||||
|
|
||||||
// IOSU act API interface
|
// IOSU act API interface
|
||||||
|
|
||||||
namespace iosu
|
static const auto ACTResult_Ok = 0;
|
||||||
{
|
static const auto ACTResult_InvalidValue = BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_ACT, 0x12F00); // 0xC0712F00
|
||||||
namespace act
|
static const auto ACTResult_OutOfRange = BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_ACT, 0x12D80); // 0xC0712D80
|
||||||
{
|
static const auto ACTResult_AccountDoesNotExist = BUILD_NN_RESULT(NN_RESULT_LEVEL_STATUS, NN_RESULT_MODULE_NN_ACT, NN_ACT_RESULT_ACCOUNT_DOES_NOT_EXIST); // 0xA071F480
|
||||||
uint8 getCurrentAccountSlot()
|
static const auto ACTResult_NotANetworkAccount = BUILD_NN_RESULT(NN_RESULT_LEVEL_STATUS, NN_RESULT_MODULE_NN_ACT, 0x1FE80); // 0xA071FE80
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getPrincipalId(uint8 slot, uint32* principalId)
|
|
||||||
{
|
|
||||||
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
|
||||||
if (_actAccountData[accountIndex].isValid == false)
|
|
||||||
{
|
|
||||||
*principalId = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*principalId = _actAccountData[accountIndex].principalId;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getAccountId(uint8 slot, char* accountId)
|
|
||||||
{
|
|
||||||
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
|
||||||
if (_actAccountData[accountIndex].isValid == false)
|
|
||||||
{
|
|
||||||
*accountId = '\0';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
strcpy(accountId, _actAccountData[accountIndex].accountId);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns empty string if invalid
|
|
||||||
std::string getAccountId2(uint8 slot)
|
|
||||||
{
|
|
||||||
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
|
||||||
if (_actAccountData[accountIndex].isValid == false)
|
|
||||||
return {};
|
|
||||||
return {_actAccountData[accountIndex].accountId};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getMii(uint8 slot, FFLData_t* fflData)
|
|
||||||
{
|
|
||||||
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
|
||||||
if (_actAccountData[accountIndex].isValid == false)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(fflData, &_actAccountData[accountIndex].miiData, sizeof(FFLData_t));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return screenname in little-endian wide characters
|
|
||||||
bool getScreenname(uint8 slot, uint16 screenname[ACT_NICKNAME_LENGTH])
|
|
||||||
{
|
|
||||||
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
|
||||||
if (_actAccountData[accountIndex].isValid == false)
|
|
||||||
{
|
|
||||||
screenname[0] = '\0';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (sint32 i = 0; i < ACT_NICKNAME_LENGTH; i++)
|
|
||||||
{
|
|
||||||
screenname[i] = (uint16)_actAccountData[accountIndex].miiNickname[i];
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getCountryIndex(uint8 slot, uint32* countryIndex)
|
|
||||||
{
|
|
||||||
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
|
||||||
if (_actAccountData[accountIndex].isValid == false)
|
|
||||||
{
|
|
||||||
*countryIndex = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*countryIndex = _actAccountData[accountIndex].countryIndex;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetPersistentId(uint8 slot, uint32* persistentId)
|
|
||||||
{
|
|
||||||
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
|
||||||
if(!_actAccountData[accountIndex].isValid)
|
|
||||||
{
|
|
||||||
*persistentId = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*persistentId = _actAccountData[accountIndex].persistentId;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ActService : public iosu::nn::IPCService
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ActService() : iosu::nn::IPCService("/dev/act") {}
|
|
||||||
|
|
||||||
nnResult ServiceCall(uint32 serviceId, void* request, void* response) override
|
|
||||||
{
|
|
||||||
cemuLog_log(LogType::Force, "Unsupported service call to /dev/act");
|
|
||||||
cemu_assert_unimplemented();
|
|
||||||
return BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_ACT, 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ActService gActService;
|
|
||||||
|
|
||||||
void Initialize()
|
|
||||||
{
|
|
||||||
gActService.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stop()
|
|
||||||
{
|
|
||||||
gActService.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// IOSU act IO
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
/* +0x00 */ uint32be ukn00;
|
|
||||||
/* +0x04 */ uint32be ukn04;
|
|
||||||
/* +0x08 */ uint32be ukn08;
|
|
||||||
/* +0x0C */ uint32be subcommandCode;
|
|
||||||
/* +0x10 */ uint8 ukn10;
|
|
||||||
/* +0x11 */ uint8 ukn11;
|
|
||||||
/* +0x12 */ uint8 ukn12;
|
|
||||||
/* +0x13 */ uint8 accountSlot;
|
|
||||||
/* +0x14 */ uint32be unique; // is this command specific?
|
|
||||||
}cmdActRequest00_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32be returnCode;
|
|
||||||
uint8 transferableIdBase[8];
|
|
||||||
}cmdActGetTransferableIDResult_t;
|
|
||||||
|
|
||||||
#define ACT_SUBCMD_GET_TRANSFERABLE_ID 4
|
|
||||||
#define ACT_SUBCMD_INITIALIZE 0x14
|
|
||||||
|
|
||||||
#define _cancelIfAccountDoesNotExist() \
|
|
||||||
if (_actAccountData[accountIndex].isValid == false) \
|
|
||||||
{ \
|
|
||||||
/* account does not exist*/ \
|
|
||||||
ioctlReturnValue = 0; \
|
|
||||||
actCemuRequest->setACTReturnCode(BUILD_NN_RESULT(NN_RESULT_LEVEL_STATUS, NN_RESULT_MODULE_NN_ACT, NN_ACT_RESULT_ACCOUNT_DOES_NOT_EXIST)); /* 0xA071F480 */ \
|
|
||||||
actCemuRequest->resultU64.u64 = 0; \
|
|
||||||
iosuIoctl_completeRequest(ioQueueEntry, ioctlReturnValue); \
|
|
||||||
continue; \
|
|
||||||
}
|
|
||||||
|
|
||||||
nnResult ServerActErrorCodeToNNResult(NAPI::ACT_ERROR_CODE ec)
|
nnResult ServerActErrorCodeToNNResult(NAPI::ACT_ERROR_CODE ec)
|
||||||
{
|
{
|
||||||
@ -518,6 +377,291 @@ nnResult ServerActErrorCodeToNNResult(NAPI::ACT_ERROR_CODE ec)
|
|||||||
return nnResultStatus(NN_RESULT_MODULE_NN_ACT, NN_ERROR_CODE::ACT_UNKNOWN_SERVER_ERROR);
|
return nnResultStatus(NN_RESULT_MODULE_NN_ACT, NN_ERROR_CODE::ACT_UNKNOWN_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace iosu
|
||||||
|
{
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
uint8 getCurrentAccountSlot()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
actAccountData_t* GetAccountBySlotNo(uint8 slotNo)
|
||||||
|
{
|
||||||
|
// only call this while holding actMutex
|
||||||
|
uint8 accIndex;
|
||||||
|
if(slotNo == iosu::act::ACT_SLOT_CURRENT)
|
||||||
|
{
|
||||||
|
accIndex = getCurrentAccountSlot() - 1;
|
||||||
|
cemu_assert_debug(accIndex >= 0 && accIndex < IOSU_ACT_ACCOUNT_MAX_COUNT);
|
||||||
|
}
|
||||||
|
else if(slotNo > 0 && slotNo <= IOSU_ACT_ACCOUNT_MAX_COUNT)
|
||||||
|
accIndex = slotNo - 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if(!_actAccountData[accIndex].isValid)
|
||||||
|
return nullptr;
|
||||||
|
return &_actAccountData[accIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// has ownership of account data
|
||||||
|
// while any thread has a LockedAccount in non-null state no other thread can access the account data
|
||||||
|
class LockedAccount
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LockedAccount(uint8 slotNo)
|
||||||
|
{
|
||||||
|
iosuAct.actMutex.lock();
|
||||||
|
m_account = GetAccountBySlotNo(slotNo);
|
||||||
|
if(!m_account)
|
||||||
|
iosuAct.actMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~LockedAccount()
|
||||||
|
{
|
||||||
|
if(m_account)
|
||||||
|
iosuAct.actMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Release()
|
||||||
|
{
|
||||||
|
if(m_account)
|
||||||
|
iosuAct.actMutex.unlock();
|
||||||
|
m_account = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
actAccountData_t* operator->()
|
||||||
|
{
|
||||||
|
return m_account;
|
||||||
|
}
|
||||||
|
|
||||||
|
actAccountData_t& operator*()
|
||||||
|
{
|
||||||
|
return *m_account;
|
||||||
|
}
|
||||||
|
|
||||||
|
LockedAccount(const LockedAccount&) = delete;
|
||||||
|
LockedAccount& operator=(const LockedAccount&) = delete;
|
||||||
|
|
||||||
|
operator bool() const { return m_account != nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
actAccountData_t* m_account{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
bool getPrincipalId(uint8 slot, uint32* principalId)
|
||||||
|
{
|
||||||
|
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
||||||
|
if (_actAccountData[accountIndex].isValid == false)
|
||||||
|
{
|
||||||
|
*principalId = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*principalId = _actAccountData[accountIndex].principalId;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getAccountId(uint8 slot, char* accountId)
|
||||||
|
{
|
||||||
|
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
||||||
|
if (_actAccountData[accountIndex].isValid == false)
|
||||||
|
{
|
||||||
|
*accountId = '\0';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
strcpy(accountId, _actAccountData[accountIndex].accountId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns empty string if invalid
|
||||||
|
std::string getAccountId2(uint8 slot)
|
||||||
|
{
|
||||||
|
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
||||||
|
if (_actAccountData[accountIndex].isValid == false)
|
||||||
|
return {};
|
||||||
|
return {_actAccountData[accountIndex].accountId};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getMii(uint8 slot, FFLData_t* fflData)
|
||||||
|
{
|
||||||
|
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
||||||
|
if (_actAccountData[accountIndex].isValid == false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(fflData, &_actAccountData[accountIndex].miiData, sizeof(FFLData_t));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return screenname in little-endian wide characters
|
||||||
|
bool getScreenname(uint8 slot, uint16 screenname[ACT_NICKNAME_LENGTH])
|
||||||
|
{
|
||||||
|
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
||||||
|
if (_actAccountData[accountIndex].isValid == false)
|
||||||
|
{
|
||||||
|
screenname[0] = '\0';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (sint32 i = 0; i < ACT_NICKNAME_LENGTH; i++)
|
||||||
|
{
|
||||||
|
screenname[i] = (uint16)_actAccountData[accountIndex].miiNickname[i];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getCountryIndex(uint8 slot, uint32* countryIndex)
|
||||||
|
{
|
||||||
|
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
||||||
|
if (_actAccountData[accountIndex].isValid == false)
|
||||||
|
{
|
||||||
|
*countryIndex = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*countryIndex = _actAccountData[accountIndex].countryIndex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetPersistentId(uint8 slot, uint32* persistentId)
|
||||||
|
{
|
||||||
|
sint32 accountIndex = iosuAct_getAccountIndexBySlot(slot);
|
||||||
|
if(!_actAccountData[accountIndex].isValid)
|
||||||
|
{
|
||||||
|
*persistentId = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*persistentId = _actAccountData[accountIndex].persistentId;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nnResult AcquireNexToken(uint8 accountSlot, uint64 titleId, uint16 titleVersion, uint32 serverId, uint8* tokenOut, uint32 tokenLen)
|
||||||
|
{
|
||||||
|
if (accountSlot != ACT_SLOT_CURRENT)
|
||||||
|
return ACTResult_InvalidValue;
|
||||||
|
LockedAccount account(accountSlot);
|
||||||
|
if (!account)
|
||||||
|
return ACTResult_AccountDoesNotExist;
|
||||||
|
if (!account->IsNetworkAccount())
|
||||||
|
return ACTResult_NotANetworkAccount;
|
||||||
|
cemu_assert_debug(ActiveSettings::IsOnlineEnabled());
|
||||||
|
if (tokenLen != sizeof(NexToken))
|
||||||
|
return ACTResult_OutOfRange;
|
||||||
|
|
||||||
|
NAPI::AuthInfo authInfo;
|
||||||
|
NAPI::NAPI_MakeAuthInfoFromCurrentAccount(authInfo);
|
||||||
|
NAPI::ACTGetNexTokenResult nexTokenResult = NAPI::ACT_GetNexToken_WithCache(authInfo, titleId, titleVersion, serverId);
|
||||||
|
if (nexTokenResult.isValid())
|
||||||
|
{
|
||||||
|
memcpy(tokenOut, &nexTokenResult.nexToken, sizeof(NexToken));
|
||||||
|
return ACTResult_Ok;
|
||||||
|
}
|
||||||
|
else if (nexTokenResult.apiError == NAPI_RESULT::SERVICE_ERROR)
|
||||||
|
{
|
||||||
|
nnResult returnCode = ServerActErrorCodeToNNResult(nexTokenResult.serviceError);
|
||||||
|
cemu_assert_debug((returnCode&0x80000000) != 0);
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
return nnResultStatus(NN_RESULT_MODULE_NN_ACT, NN_ERROR_CODE::ACT_UNKNOWN_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
nnResult AcquireIndependentServiceToken(uint8 accountSlot, uint64 titleId, uint16 titleVersion, std::string_view clientId, uint8* tokenOut, uint32 tokenLen)
|
||||||
|
{
|
||||||
|
static constexpr size_t IndependentTokenMaxLength = 512+1; // 512 bytes + null terminator
|
||||||
|
if(accountSlot != ACT_SLOT_CURRENT)
|
||||||
|
return ACTResult_InvalidValue;
|
||||||
|
LockedAccount account(accountSlot);
|
||||||
|
if (!account)
|
||||||
|
return ACTResult_AccountDoesNotExist;
|
||||||
|
if (!account->IsNetworkAccount())
|
||||||
|
return ACTResult_NotANetworkAccount;
|
||||||
|
cemu_assert_debug(ActiveSettings::IsOnlineEnabled());
|
||||||
|
if (tokenLen < IndependentTokenMaxLength)
|
||||||
|
return ACTResult_OutOfRange;
|
||||||
|
NAPI::AuthInfo authInfo;
|
||||||
|
NAPI::NAPI_MakeAuthInfoFromCurrentAccount(authInfo);
|
||||||
|
account.Release();
|
||||||
|
NAPI::ACTGetIndependentTokenResult tokenResult = NAPI::ACT_GetIndependentToken_WithCache(authInfo, titleId, titleVersion, clientId);
|
||||||
|
uint32 returnCode = 0;
|
||||||
|
if (tokenResult.isValid())
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < std::min(tokenResult.token.size(), (size_t)IndependentTokenMaxLength); i++)
|
||||||
|
{
|
||||||
|
tokenOut[i] = tokenResult.token[i];
|
||||||
|
tokenOut[i + 1] = '\0';
|
||||||
|
}
|
||||||
|
returnCode = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnCode = 0x80000000; // todo - proper error codes
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActService : public iosu::nn::IPCService
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActService() : iosu::nn::IPCService("/dev/act") {}
|
||||||
|
|
||||||
|
nnResult ServiceCall(uint32 serviceId, void* request, void* response) override
|
||||||
|
{
|
||||||
|
cemuLog_log(LogType::Force, "Unsupported service call to /dev/act");
|
||||||
|
cemu_assert_unimplemented();
|
||||||
|
return BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_ACT, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ActService gActService;
|
||||||
|
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
gActService.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop()
|
||||||
|
{
|
||||||
|
gActService.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// IOSU act IO
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* +0x00 */ uint32be ukn00;
|
||||||
|
/* +0x04 */ uint32be ukn04;
|
||||||
|
/* +0x08 */ uint32be ukn08;
|
||||||
|
/* +0x0C */ uint32be subcommandCode;
|
||||||
|
/* +0x10 */ uint8 ukn10;
|
||||||
|
/* +0x11 */ uint8 ukn11;
|
||||||
|
/* +0x12 */ uint8 ukn12;
|
||||||
|
/* +0x13 */ uint8 accountSlot;
|
||||||
|
/* +0x14 */ uint32be unique; // is this command specific?
|
||||||
|
}cmdActRequest00_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32be returnCode;
|
||||||
|
uint8 transferableIdBase[8];
|
||||||
|
}cmdActGetTransferableIDResult_t;
|
||||||
|
|
||||||
|
#define ACT_SUBCMD_GET_TRANSFERABLE_ID 4
|
||||||
|
#define ACT_SUBCMD_INITIALIZE 0x14
|
||||||
|
|
||||||
|
#define _cancelIfAccountDoesNotExist() \
|
||||||
|
if (_actAccountData[accountIndex].isValid == false) \
|
||||||
|
{ \
|
||||||
|
/* account does not exist*/ \
|
||||||
|
ioctlReturnValue = 0; \
|
||||||
|
actCemuRequest->setACTReturnCode(BUILD_NN_RESULT(NN_RESULT_LEVEL_STATUS, NN_RESULT_MODULE_NN_ACT, NN_ACT_RESULT_ACCOUNT_DOES_NOT_EXIST)); /* 0xA071F480 */ \
|
||||||
|
actCemuRequest->resultU64.u64 = 0; \
|
||||||
|
iosuIoctl_completeRequest(ioQueueEntry, ioctlReturnValue); \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
int iosuAct_thread()
|
int iosuAct_thread()
|
||||||
{
|
{
|
||||||
SetThreadName("iosuAct_thread");
|
SetThreadName("iosuAct_thread");
|
||||||
@ -674,47 +818,13 @@ int iosuAct_thread()
|
|||||||
}
|
}
|
||||||
else if (actCemuRequest->requestCode == IOSU_ARC_ACQUIRENEXTOKEN)
|
else if (actCemuRequest->requestCode == IOSU_ARC_ACQUIRENEXTOKEN)
|
||||||
{
|
{
|
||||||
NAPI::AuthInfo authInfo;
|
nnResult r = iosu::act::AcquireNexToken(actCemuRequest->accountSlot, actCemuRequest->titleId, actCemuRequest->titleVersion, actCemuRequest->serverId, actCemuRequest->resultBinary.binBuffer, sizeof(NexToken));
|
||||||
NAPI::NAPI_MakeAuthInfoFromCurrentAccount(authInfo);
|
actCemuRequest->setACTReturnCode(r);
|
||||||
NAPI::ACTGetNexTokenResult nexTokenResult = NAPI::ACT_GetNexToken_WithCache(authInfo, actCemuRequest->titleId, actCemuRequest->titleVersion, actCemuRequest->serverId);
|
|
||||||
uint32 returnCode = 0;
|
|
||||||
if (nexTokenResult.isValid())
|
|
||||||
{
|
|
||||||
*(NAPI::ACTNexToken*)actCemuRequest->resultBinary.binBuffer = nexTokenResult.nexToken;
|
|
||||||
returnCode = NN_RESULT_SUCCESS;
|
|
||||||
}
|
|
||||||
else if (nexTokenResult.apiError == NAPI_RESULT::SERVICE_ERROR)
|
|
||||||
{
|
|
||||||
returnCode = ServerActErrorCodeToNNResult(nexTokenResult.serviceError);
|
|
||||||
cemu_assert_debug((returnCode&0x80000000) != 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
returnCode = nnResultStatus(NN_RESULT_MODULE_NN_ACT, NN_ERROR_CODE::ACT_UNKNOWN_SERVER_ERROR);
|
|
||||||
}
|
|
||||||
actCemuRequest->setACTReturnCode(returnCode);
|
|
||||||
}
|
}
|
||||||
else if (actCemuRequest->requestCode == IOSU_ARC_ACQUIREINDEPENDENTTOKEN)
|
else if (actCemuRequest->requestCode == IOSU_ARC_ACQUIREINDEPENDENTTOKEN)
|
||||||
{
|
{
|
||||||
NAPI::AuthInfo authInfo;
|
nnResult r = iosu::act::AcquireIndependentServiceToken(actCemuRequest->accountSlot, actCemuRequest->titleId, actCemuRequest->titleVersion, actCemuRequest->clientId, actCemuRequest->resultBinary.binBuffer, sizeof(actCemuRequest->resultBinary.binBuffer));
|
||||||
NAPI::NAPI_MakeAuthInfoFromCurrentAccount(authInfo);
|
actCemuRequest->setACTReturnCode(r);
|
||||||
NAPI::ACTGetIndependentTokenResult tokenResult = NAPI::ACT_GetIndependentToken_WithCache(authInfo, actCemuRequest->titleId, actCemuRequest->titleVersion, actCemuRequest->clientId);
|
|
||||||
|
|
||||||
uint32 returnCode = 0;
|
|
||||||
if (tokenResult.isValid())
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < std::min(tokenResult.token.size(), (size_t)200); i++)
|
|
||||||
{
|
|
||||||
actCemuRequest->resultBinary.binBuffer[i] = tokenResult.token[i];
|
|
||||||
actCemuRequest->resultBinary.binBuffer[i + 1] = '\0';
|
|
||||||
}
|
|
||||||
returnCode = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
returnCode = 0x80000000; // todo - proper error codes
|
|
||||||
}
|
|
||||||
actCemuRequest->setACTReturnCode(returnCode);
|
|
||||||
}
|
}
|
||||||
else if (actCemuRequest->requestCode == IOSU_ARC_ACQUIREPIDBYNNID)
|
else if (actCemuRequest->requestCode == IOSU_ARC_ACQUIREPIDBYNNID)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,7 @@ namespace iosu
|
|||||||
|
|
||||||
std::string getAccountId2(uint8 slot);
|
std::string getAccountId2(uint8 slot);
|
||||||
|
|
||||||
const uint8 ACT_SLOT_CURRENT = 0xFE;
|
static constexpr uint8 ACT_SLOT_CURRENT = 0xFE;
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
@ -114,6 +114,7 @@ namespace act
|
|||||||
{
|
{
|
||||||
memset(token, 0, sizeof(independentServiceToken_t));
|
memset(token, 0, sizeof(independentServiceToken_t));
|
||||||
actPrepareRequest();
|
actPrepareRequest();
|
||||||
|
actRequest->accountSlot = iosu::act::ACT_SLOT_CURRENT;
|
||||||
actRequest->requestCode = IOSU_ARC_ACQUIREINDEPENDENTTOKEN;
|
actRequest->requestCode = IOSU_ARC_ACQUIREINDEPENDENTTOKEN;
|
||||||
actRequest->titleId = CafeSystem::GetForegroundTitleId();
|
actRequest->titleId = CafeSystem::GetForegroundTitleId();
|
||||||
actRequest->titleVersion = CafeSystem::GetForegroundTitleVersion();
|
actRequest->titleVersion = CafeSystem::GetForegroundTitleVersion();
|
||||||
@ -611,6 +612,7 @@ void nnActExport_AcquireNexServiceToken(PPCInterpreter_t* hCPU)
|
|||||||
ppcDefineParamU32(serverId, 1);
|
ppcDefineParamU32(serverId, 1);
|
||||||
memset(token, 0, sizeof(nexServiceToken_t));
|
memset(token, 0, sizeof(nexServiceToken_t));
|
||||||
actPrepareRequest();
|
actPrepareRequest();
|
||||||
|
actRequest->accountSlot = iosu::act::ACT_SLOT_CURRENT;
|
||||||
actRequest->requestCode = IOSU_ARC_ACQUIRENEXTOKEN;
|
actRequest->requestCode = IOSU_ARC_ACQUIRENEXTOKEN;
|
||||||
actRequest->titleId = CafeSystem::GetForegroundTitleId();
|
actRequest->titleId = CafeSystem::GetForegroundTitleId();
|
||||||
actRequest->titleVersion = CafeSystem::GetForegroundTitleVersion();
|
actRequest->titleVersion = CafeSystem::GetForegroundTitleVersion();
|
||||||
@ -627,10 +629,8 @@ void nnActExport_AcquireNexServiceToken(PPCInterpreter_t* hCPU)
|
|||||||
void nnActExport_AcquireIndependentServiceToken(PPCInterpreter_t* hCPU)
|
void nnActExport_AcquireIndependentServiceToken(PPCInterpreter_t* hCPU)
|
||||||
{
|
{
|
||||||
ppcDefineParamMEMPTR(token, independentServiceToken_t, 0);
|
ppcDefineParamMEMPTR(token, independentServiceToken_t, 0);
|
||||||
ppcDefineParamMEMPTR(serviceToken, const char, 1);
|
ppcDefineParamMEMPTR(clientId, const char, 1);
|
||||||
uint32 result = nn::act::AcquireIndependentServiceToken(token.GetPtr(), serviceToken.GetPtr(), 0);
|
uint32 result = nn::act::AcquireIndependentServiceToken(token.GetPtr(), clientId.GetPtr(), 0);
|
||||||
cemuLog_logDebug(LogType::Force, "nn_act.AcquireIndependentServiceToken(0x{}, {}) -> {:x}", (void*)token.GetPtr(), serviceToken.GetPtr(), result);
|
|
||||||
cemuLog_logDebug(LogType::Force, "Token: {}", serviceToken.GetPtr());
|
|
||||||
osLib_returnFromFunction(hCPU, result);
|
osLib_returnFromFunction(hCPU, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,7 +640,6 @@ void nnActExport_AcquireIndependentServiceToken2(PPCInterpreter_t* hCPU)
|
|||||||
ppcDefineParamMEMPTR(clientId, const char, 1);
|
ppcDefineParamMEMPTR(clientId, const char, 1);
|
||||||
ppcDefineParamU32(cacheDurationInSeconds, 2);
|
ppcDefineParamU32(cacheDurationInSeconds, 2);
|
||||||
uint32 result = nn::act::AcquireIndependentServiceToken(token, clientId.GetPtr(), cacheDurationInSeconds);
|
uint32 result = nn::act::AcquireIndependentServiceToken(token, clientId.GetPtr(), cacheDurationInSeconds);
|
||||||
cemuLog_logDebug(LogType::Force, "Called nn_act.AcquireIndependentServiceToken2");
|
|
||||||
osLib_returnFromFunction(hCPU, result);
|
osLib_returnFromFunction(hCPU, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,7 +647,6 @@ void nnActExport_AcquireEcServiceToken(PPCInterpreter_t* hCPU)
|
|||||||
{
|
{
|
||||||
ppcDefineParamMEMPTR(pEcServiceToken, independentServiceToken_t, 0);
|
ppcDefineParamMEMPTR(pEcServiceToken, independentServiceToken_t, 0);
|
||||||
uint32 result = nn::act::AcquireIndependentServiceToken(pEcServiceToken.GetPtr(), "71a6f5d6430ea0183e3917787d717c46", 0);
|
uint32 result = nn::act::AcquireIndependentServiceToken(pEcServiceToken.GetPtr(), "71a6f5d6430ea0183e3917787d717c46", 0);
|
||||||
cemuLog_logDebug(LogType::Force, "Called nn_act.AcquireEcServiceToken");
|
|
||||||
osLib_returnFromFunction(hCPU, result);
|
osLib_returnFromFunction(hCPU, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user