Index: Horizon/@AccountSalvageKit@list =================================================================== --- Horizon/@AccountSalvageKit@list (revision 0) +++ Horizon/@AccountSalvageKit@list (working copy) @@ -0,0 +1,15 @@ +#--------------------------------------------------------------------------- +# package 名 : AccountSalvageKit +# +# 説明 : 修理ツールアカウントサルベージ用 private パッケージ +# +# 配布先 : 未定 +# +# 備考 : AccountManagementKit が必要 +#--------------------------------------------------------------------------- + +include/nn/actslv/actslv_Api.h + +libraries/CTR-T*.*MP*/**/libnn_actslv.* + +resources/specfiles/tools/RepairTool.desc Index: Horizon/include/nn/actslv/actslv_Api.h =================================================================== --- Horizon/include/nn/actslv/actslv_Api.h (revision 0) +++ Horizon/include/nn/actslv/actslv_Api.h (working copy) @@ -0,0 +1,81 @@ +サソ/*---------------------------------------------------------------------------* + Project: Horizon + File: actslv_Api.h + + Copyright (C)2009-2013 Nintendo Co., Ltd. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Rev: 50823 $ + *---------------------------------------------------------------------------*/ + +#ifndef NN_ACTSLV_ACTSLV_API_H_ +#define NN_ACTSLV_ACTSLV_API_H_ + +/*! @file + @brief 繧「繧ォ繧ヲ繝ウ繝医し繝ォ繝吶シ繧ク讖溯ス縺ォ髢「縺吶k API 縺ョ螳」險 +*/ + +#include + +#ifdef __cplusplus + +namespace nn { +namespace act { + +/*! + @brief 繧「繧ォ繧ヲ繝ウ繝医ョ繧オ繝ォ繝吶シ繧ク繧定。後>縺セ縺吶 + @n + 蛻晄悄蛹也峩蠕後ョ譛ャ菴薙〒縺ッシ瑚」ス蜩∝ョ滓ゥ溘ッ L1 縲髢狗匱螳滓ゥ溘ッ D1 縺ョ迺ー蠅縺ォ謗・邯壹&繧後∪縺吶 + 縺薙l繧貞、画峩縺吶k縺ォ縺ッ縲√い繧ォ繧ヲ繝ウ繝医槭ロ繝シ繧ク繝」繝繝シ繝ォ縺ァ縲後し繝ォ繝吶シ繧ク螳溯。梧凾縺ョ繧ォ繝ャ繝ウ繝医い繧ォ繧ヲ繝ウ繝医阪ョ謗・邯壼医r螟画峩縺励∪縺吶 + 10KB 遞句コヲ縺ョ繧ケ繧ソ繝繧ッ繧剃スソ逕ィ縺励∪縺吶 + + @return 髢「謨ー縺ョ螳溯。檎オ先棡繧定ソ斐@縺セ縺吶ょ、縺ッ莉・荳九ョ騾壹j縺ァ縺吶 + @retval ResultSuccess 謌仙粥縺励∪縺励◆縲 + @retval ResultRequestNotFound 遘サ陦御コ育エ縺輔l縺ヲ縺縺セ縺帙s縲ゅ≠繧九>縺ッ蜑企勁貂医∩繝サ髢「騾」莉倥¢辟。蜉ケ蛹悶&繧後◆繧「繧ォ繧ヲ繝ウ繝医@縺句ュ伜惠縺励∪縺帙s縲 +*/ +Result SalvageAccounts( void ); + +/*! + @brief 繧オ繝ォ繝吶シ繧ク縺輔l縺 Approval ID 繧貞叙蠕励@縺セ縺吶 + + @return Approval ID 繧定ソ斐@縺セ縺吶 + 繧オ繝ォ繝吶シ繧ク縺瑚。後o繧後※縺縺ェ縺蝣エ蜷医d縲√し繝ォ繝吶シ繧ク縺悟、ア謨励@縺ヲ縺繧句エ蜷医ッ 0 繧定ソ斐@縺セ縺吶 +*/ +u32 GetSalvagedApprovalId( void ); + +/*! + @brief 繧「繧ォ繧ヲ繝ウ繝医ョ蝗ス繧ウ繝シ繝峨r蜿門セ励@縺セ縺吶 + @n + 螟ア謨玲凾縺ォ繝舌ャ繝輔ぃ縺ク繧サ繝繝医&繧後k蛟、縺ッ菫晁ィシ縺輔l縺セ縺帙s縲 + + @param[out] pCountryCode 蝗ス繧ウ繝シ繝峨r譬シ邏阪☆繧九ヰ繝繝輔ぃ縺ク縺ョ繝昴う繝ウ繧ソ繧呈欠螳壹@縺セ縺吶 + + @return ResultSuccess 謌仙粥縺励∪縺励◆縲@n + ResultInvalidPointer 蠑墓焚縺ォ貂。縺励◆繝昴う繝ウ繧ソ縺御ク肴ュ」縺ァ縺呻シNULL 繝昴う繝ウ繧ソ縺ェ縺ゥシ峨@n + +*/ +Result GetCountryCodeAtSalvage( u32* pCountryCode ); + +/*! + @brief 繧オ繝ォ繝吶シ繧ク縺輔l縺溘い繧ォ繧ヲ繝ウ繝医ョ蟷エ鮨「繧貞叙蠕励@縺セ縺吶 + + 莉サ螟ゥ蝣ゅョ蜷繧キ繧ケ繝繝縺ォ縺翫¢繧九Θ繝シ繧カ繝シ縺ョ蟷エ鮨「縺ッ縲∝ア菴丞嵜繝サ蝨ー蝓溘↓繧医i縺 UTC + 12 譎る俣繧貞渕貅悶→縺励※豎ゅa縺セ縺吶 + 譌・譛ャ縺ョ繝ヲ繝シ繧カ繝シ縺ョ蝣エ蜷医ッ縲∬ェ慕函譌・蜑肴律縺ョ 21 譎ゅr繧ゅ▲縺ヲ蟷エ鮨「縺悟刈邂励&繧後k縺薙→縺ォ縺ェ繧翫∪縺吶 + + @return 繧オ繝ォ繝吶シ繧ク縺輔l縺溘い繧ォ繧ヲ繝ウ繝医ョ繝ヲ繝シ繧カ繝シ縺ョ蟷エ鮨「繧定ソ斐@縺セ縺吶 + 繧オ繝ォ繝吶シ繧ク縺瑚。後o繧後※縺縺ェ縺蝣エ蜷医d縲√し繝ォ繝吶シ繧ク縺悟、ア謨励@縺ヲ縺繧句エ蜷医ッ 0 繧定ソ斐@縺セ縺吶 +*/ +u8 GetAgeAtSalvage( void ); + + +} // end of namespace act +} // end of namespace nn + +#endif // __cplusplus + +#endif // ifndef NN_ACTSLV_ACTSLV_API_H_ Index: Horizon/sources/libraries/actslv/@ =================================================================== --- Horizon/sources/libraries/actslv/@ (revision 0) +++ Horizon/sources/libraries/actslv/@ (working copy) @@ -0,0 +1 @@ + Index: Horizon/sources/libraries/actslv/act_Config.h =================================================================== --- Horizon/sources/libraries/actslv/act_Config.h (revision 0) +++ Horizon/sources/libraries/actslv/act_Config.h (working copy) @@ -0,0 +1,27 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_ACT_CONFIG_H_ +#define LIBRARIES_ACTSLV_ACT_CONFIG_H_ + +#define NN_ACT_ENABLE_ASSERT_ON_IOP 0 + +#define NN_ACT_LOG_LEVEL_NONE 0 +#define NN_ACT_LOG_LEVEL_FATAL 1 +#define NN_ACT_LOG_LEVEL_ERROR 2 +#define NN_ACT_LOG_LEVEL_WARN 3 +#define NN_ACT_LOG_LEVEL_INFO 4 +#define NN_ACT_LOG_LEVEL_DEBUG 5 + +#define NN_ACT_LOG_LEVEL NN_ACT_LOG_LEVEL_DEBUG + +#endif // LIBRARIES_ACTSLV_ACT_CONFIG_H_ Index: Horizon/sources/libraries/actslv/act_SalvagedData.cpp =================================================================== --- Horizon/sources/libraries/actslv/act_SalvagedData.cpp (revision 0) +++ Horizon/sources/libraries/actslv/act_SalvagedData.cpp (working copy) @@ -0,0 +1,103 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#include + +#include "act_SalvagedData.h" + +#include "util/act_AccountPasswordHash.h" +#include "util/act_ConvertHostServerSettings.h" +#include "util/act_SystemInfoManager.h" +#include "util/act_StringContainerForSalvage.h" + +namespace nn +{ +namespace act +{ +namespace detail +{ + +SalvagedData::SalvagedData( void ) +{ + memset( &m_Members, 0, sizeof(m_Members) ); + + ConvertHostServerSettings::ToEnum( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN, ConvertHostServerSettings::INVALID_NNAS_NFS_ENV, + &m_Members.m_NnasType, &m_Members.m_NfsType, &m_Members.m_NfsNo ); + + // because "" is also valid value at production environment + m_Members.m_NnasSubDomain.Set( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN ); +} + +bool SalvagedData::operator==( const SalvagedData& rh ) const +{ + if( m_Members.m_PersistentId == rh.m_Members.m_PersistentId && + m_Members.m_TransferableIdBase == rh.m_Members.m_TransferableIdBase && + m_Members.m_Uuid == rh.m_Members.m_Uuid && + m_Members.m_AccountId == rh.m_Members.m_AccountId && + memcmp( &m_Members.m_MiiData, &rh.m_Members.m_MiiData, NN_MII_STORE_DATA_SIZE ) == 0 && + m_Members.m_MiiName == rh.m_Members.m_MiiName && + m_Members.m_AccountId == rh.m_Members.m_AccountId && + m_Members.m_BirthYear == rh.m_Members.m_BirthYear && + m_Members.m_BirthMonth == rh.m_Members.m_BirthMonth && + m_Members.m_BirthDay == rh.m_Members.m_BirthDay && + m_Members.m_Gender == rh.m_Members.m_Gender && + m_Members.m_IsMailAddressValidated == rh.m_Members.m_IsMailAddressValidated && + m_Members.m_Country == rh.m_Members.m_Country && + m_Members.m_SimpleAddressId == rh.m_Members.m_SimpleAddressId && + m_Members.m_TimeZoneId == rh.m_Members.m_TimeZoneId && + m_Members.m_UtcOffset == rh.m_Members.m_UtcOffset && + m_Members.m_PrincipalId == rh.m_Members.m_PrincipalId && + m_Members.m_MiiImageUrl == rh.m_Members.m_MiiImageUrl && + m_Members.m_NnasType == rh.m_Members.m_NnasType && + m_Members.m_NfsType == rh.m_Members.m_NfsType && + m_Members.m_NfsNo == rh.m_Members.m_NfsNo && + m_Members.m_NnasSubDomain ==rh.m_Members.m_NnasSubDomain && + m_Members.m_NnasNfsEnv == rh.m_Members.m_NnasNfsEnv && // + m_Members.m_LastUpdatedDate == rh.m_Members.m_LastUpdatedDate && + m_Members.m_CreatedDate == rh.m_Members.m_CreatedDate && + m_Members.m_ApprovalId == rh.m_Members.m_ApprovalId && + m_Members.m_CommonUuid == rh.m_Members.m_CommonUuid && + m_Members.m_CommonTransferableIdBase == rh.m_Members.m_CommonTransferableIdBase && + m_Members.m_CtrFpAccountId == rh.m_Members.m_CtrFpAccountId && + m_Members.m_FriendsPassword == rh.m_Members.m_FriendsPassword && + m_Members.m_FriendsEnv == rh.m_Members.m_FriendsEnv + ) + { + return true; + } + + return false; +} + +void SalvagedData::ClearMembers( void ) +{ + memset( &m_Members, 0, sizeof(m_Members) ); + + ConvertHostServerSettings::ToEnum( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN, ConvertHostServerSettings::INVALID_NNAS_NFS_ENV, + &m_Members.m_NnasType, &m_Members.m_NfsType, &m_Members.m_NfsNo ); + + // because "" is also valid value at production environment + m_Members.m_NnasSubDomain.Set( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN ); +} + +void SalvagedData::SetDefaultMembers( void ) +{ + ConvertHostServerSettings::ToEnum( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN, ConvertHostServerSettings::INVALID_NNAS_NFS_ENV, + &m_Members.m_NnasType, &m_Members.m_NfsType, &m_Members.m_NfsNo ); + + // because "" is also valid value at production environment + m_Members.m_NnasSubDomain.Set( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN ); +} + +} +} +} Index: Horizon/sources/libraries/actslv/act_SalvagedData.h =================================================================== --- Horizon/sources/libraries/actslv/act_SalvagedData.h (revision 0) +++ Horizon/sources/libraries/actslv/act_SalvagedData.h (working copy) @@ -0,0 +1,154 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_SALVAGED_DATA_H_ +#define LIBRARIES_ACTSLV_SALVAGED_DATA_H_ + +#include "act_Common.h" + +#include "act_Uuid.h" + +#include "save/act_KeyValueStore.h" +#include "util/act_AccountPasswordHash.h" +#include "util/act_StringContainerForSalvage.h" + +#include + +namespace nn +{ +namespace act +{ +namespace detail +{ + +class SalvagedData +{ + + typedef struct Members + { + u32 m_PersistentId; + u64 m_TransferableIdBase; + UuidInternal m_Uuid; + + nn::mii::StoreData m_MiiData; + MiiNameContainer m_MiiName; + + AccountIdContainer m_AccountId; + u16 m_BirthYear; + u8 m_BirthMonth; + u8 m_BirthDay; + Gender m_Gender; + bool m_IsMailAddressValidated; + u32 m_Country; + u32 m_SimpleAddressId; + TimeZoneIdContainer m_TimeZoneId; + s64 m_UtcOffset; + u32 m_PrincipalId; + MiiImageUrlContainer m_MiiImageUrl; + + NnasType m_NnasType; + NfsType m_NfsType; + u8 m_NfsNo; + + NnasSubDomainContainer m_NnasSubDomain; + NnasNfsEnvContainer m_NnasNfsEnv; + + NnasXmlDateContainer m_LastUpdatedDate; + NnasXmlDateContainer m_CreatedDate; + u32 m_ApprovalId; + UuidInternal m_CommonUuid; + u64 m_CommonTransferableIdBase; + CtrFpAccountContainer m_CtrFpAccountId; + FriendsPasswordContainer m_FriendsPassword; + NnasNfsEnvContainer m_FriendsEnv; + + } Members; + +private: + Members m_Members; + +public: + SalvagedData( void ); + virtual ~SalvagedData( void ) {}; + + bool operator==( const SalvagedData& rh ) const; + +public: + void SetAccountId( const char* pAccountId ) { m_Members.m_AccountId.Set( pAccountId ); } + void SetPrincipalId( u32 principalId ) { m_Members.m_PrincipalId = principalId; } + void SetBirthDate( u16 birthYear, u8 birthMonth, u8 birthDay ) { m_Members.m_BirthYear = birthYear; m_Members.m_BirthMonth = birthMonth; m_Members.m_BirthDay = birthDay; } + void SetCountry( u32 country ) { m_Members.m_Country = country; } + void SetGender( Gender gender ) { m_Members.m_Gender = gender; } + void SetSimpleAddressId( u32 simpleAddressId ) { m_Members.m_SimpleAddressId = simpleAddressId; } + void SetTimeZoneId( const char* timeZoneId ) { m_Members.m_TimeZoneId.Set( timeZoneId ); } + void SetUtcOffset( s64 utcOffset ) { m_Members.m_UtcOffset = utcOffset; } + void SetIsMailAddressValidated( bool isMailAddressValidated ) { m_Members.m_IsMailAddressValidated = isMailAddressValidated; } + void SetMiiData( const nn::mii::StoreData& miiData ) { memcpy( &m_Members.m_MiiData, &miiData, sizeof(miiData) ); } + void SetMiiName( const char16* miiName ) { m_Members.m_MiiName.Set( miiName ); } + void SetMiiImageUrl( const MiiImageUrlContainer& miiImageUrl ) { m_Members.m_MiiImageUrl.Set( miiImageUrl ); } + void SetUuid( const UuidInternal& uuid ) { m_Members.m_Uuid.Set( uuid ); } + void SetPersistentId( u32 persistentId ) { m_Members.m_PersistentId = persistentId; } + void SetTransferableIdBase( u64 transferableIdBase ) { m_Members.m_TransferableIdBase = transferableIdBase; } + void SetLastUpdatedDate( NnasXmlDateContainer& updated ) { m_Members.m_LastUpdatedDate.Set( updated ); } + void SetCreatedDate( NnasXmlDateContainer& created ) { m_Members.m_CreatedDate.Set( created ); } + void SetApprovalId( u32 approvalId ) { m_Members.m_ApprovalId = approvalId; } + void SetCommonUuid( const UuidInternal& uuid ) { m_Members.m_CommonUuid.Set( uuid ); } + void SetCommonTransferableIdBase( u64 commonTransferableIdBase ) { m_Members.m_CommonTransferableIdBase = commonTransferableIdBase; } + void SetNnasSubDomain( const NnasSubDomainContainer& subDomain ) { m_Members.m_NnasSubDomain.Set( subDomain ); } + void SetNnasNfsEnv( const NnasNfsEnvContainer& nnasNfsEnv ) { m_Members.m_NnasNfsEnv.Set( nnasNfsEnv ); } + void SetNnasType( NnasType nnasType ) { m_Members.m_NnasType = nnasType; } + void SetNfsType( NfsType nfsType ) { m_Members.m_NfsType = nfsType; } + void SetNfsNo( u8 nfsNo ) { m_Members.m_NfsNo = nfsNo; } + void SetCtrFpAccountId( const CtrFpAccountContainer& ctrFpAccountId ) { m_Members.m_CtrFpAccountId.Set( ctrFpAccountId ); } + void SetFriendsPassword( const FriendsPasswordContainer& friendsPassword ) { m_Members.m_FriendsPassword.Set( friendsPassword ); } + void SetFriendsEnv( const NnasNfsEnvContainer& friendsEnv ) { m_Members.m_FriendsEnv.Set( friendsEnv ); } + + const AccountIdContainer& GetAccountId( void ) const { return m_Members.m_AccountId; } + u32 GetCountry( void ) const { return m_Members.m_Country; } + u32 GetPersistentId( void ) const { return m_Members.m_PersistentId; } + u64 GetTransferableIdBase( void ) const { return m_Members.m_TransferableIdBase; } + u64 GetCommonTransferableIdBase( void ) const { return m_Members.m_CommonTransferableIdBase; } + const UuidInternal& GetUuid( void ) const { return m_Members.m_Uuid; } + const UuidInternal& GetCommonUuid( void ) const { return m_Members.m_CommonUuid; } + const NnasXmlDateContainer& GetLastUpdatedDate( void ) const { return m_Members.m_LastUpdatedDate; } + const NnasXmlDateContainer& GetCreatedDate( void ) const { return m_Members.m_CreatedDate; } + u32 GetApprovalId( void ) const { return m_Members.m_ApprovalId; } + const MiiImageUrlContainer& GetMiiImageUrl( void ) const { return m_Members.m_MiiImageUrl; } + const CtrFpAccountContainer& GetCtrFpAccountId( void ) const { return m_Members.m_CtrFpAccountId; } + const FriendsPasswordContainer& GetFriendsPassword( void ) const { return m_Members.m_FriendsPassword; } + const NnasNfsEnvContainer& GetFriendsEnv( void ) const { return m_Members.m_FriendsEnv; } + const nn::mii::StoreData& GetMiiData( void ) const { return m_Members.m_MiiData; } + const MiiNameContainer& GetMiiName( void ) const { return m_Members.m_MiiName; } + u16 GetBirthYear( void ) const { return m_Members.m_BirthYear; } + u8 GetBirthMonth( void ) const { return m_Members.m_BirthMonth; } + u8 GetBirthDay( void ) const { return m_Members.m_BirthDay; } + Gender GetGender( void ) const { return m_Members.m_Gender; } + s32 GetSimpleAddressId( void ) const { return m_Members.m_SimpleAddressId; } + const TimeZoneIdContainer& GetTimeZoneId( void ) const { return m_Members.m_TimeZoneId; } + s64 GetUtcOffset( void ) const { return m_Members.m_UtcOffset; } + u32 GetPrincipalId( void ) const { return m_Members.m_PrincipalId; } + bool GetIsMailAddressValidated( void ) const { return m_Members.m_IsMailAddressValidated; } + const NnasSubDomainContainer& GetNnasSubDomain( void ) const { return m_Members.m_NnasSubDomain; } + const NnasNfsEnvContainer& GetNnasNfsEnv( void ) const { return m_Members.m_NnasNfsEnv; } + NnasType GetNnasType( void ) const { return m_Members.m_NnasType; } + NfsType GetNfsType( void ) const { return m_Members.m_NfsType; } + u8 GetNfsNo( void ) const { return m_Members.m_NfsNo; } + + void ClearMembers( void ); + void SetDefaultMembers( void ); +}; + +} +} +} + +#endif // LIBRARIES_ACTSLV_SALVAGED_DATA_H_ Index: Horizon/sources/libraries/actslv/act_SalvageManager.cpp =================================================================== --- Horizon/sources/libraries/actslv/act_SalvageManager.cpp (revision 0) +++ Horizon/sources/libraries/actslv/act_SalvageManager.cpp (working copy) @@ -0,0 +1,358 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "act_SalvageManager.h" +#include "save/act_FileSystem.h" +#include "util/act_SystemInfoManager.h" +#include "util/act_ConvertHostServerSettings.h" + +#include "net/act_WebApi.h" +#include "net/act_ServerTime.h" + +namespace +{ +u8 s_NnasAccessContextBuffer[sizeof(nn::act::detail::NnasAccessContext)]; +// HTTP 縺ョ POST 繝繝シ繧ソ繧貞茜逕ィ縺吶k蝣エ蜷医↓蠢隕√↑繝舌ャ繝輔ぃ +u8 s_http_buffer[4096] NN_ATTRIBUTE_ALIGN(4096); +} + +namespace nn +{ +namespace act +{ +namespace detail +{ + +SalvageManager::SalvageManager() : +m_AcquiredInfoNum( 0 ), +m_NnasType( nn::act::NNAS_TYPE_GAME_DEV ), +m_NfsType( nn::act::NFS_TYPE_DEVELOPMENT ), +m_NfsNo( 1 ), +m_IsInitialized( false ), +m_IsCompleted( false ), +m_ApprovalId( 0 ) +{ +} + +SalvageManager::~SalvageManager() +{ +} + +void SalvageManager::ClearMembers( void ) +{ + m_AcquiredInfoNum = 0; + m_IsCompleted = false; + m_ApprovalId = 0; +} + +Result SalvageManager::Initialize( void ) +{ + ClearMembers(); + + nn::fs::Initialize(); + + nn::cfg::CTR::init::Initialize(); + NN_ERR_THROW_FATAL_ALL( nn::http::Initialize(reinterpret_cast(s_http_buffer), sizeof (s_http_buffer)) ); + NN_ERR_THROW_FATAL_ALL( nn::friends::Initialize() ); + + NN_ERR_THROW_FATAL_ALL( nn::act::detail::FileSystem::CreateSingleton() ); + NN_ERR_THROW_FATAL_ALL( nn::act::detail::SystemInfoManager::CreateSingleton() ); + + m_IsInitialized = true; + + return ResultSuccess(); +} + +Result SalvageManager::Finalize( bool completeFlg ) +{ + if ( m_IsInitialized ) + { + nn::act::detail::SystemInfoManager::DestroySingleton(); + nn::act::detail::FileSystem::DestroySingleton(); + + nn::friends::Finalize(); + nn::http::Finalize(); + + nn::cfg::CTR::init::Finalize(); + + m_IsCompleted = completeFlg; + } + + return ResultSuccess(); +} + +Result SalvageManager::AcquireInformation( WorkBuffer* pSalvagedDataList ) +{ + NN_ACT_RETURN_IF_NULL( pSalvagedDataList, ResultOutOfMemory() ); + + Result result = ResultSuccess(); + + // 謗・邯壼郁ィュ螳 + { + SystemInfoManager::GetSingleton().GetHostServerSettingsFromFpSettings( &m_NnasSubDomain, &m_NnasNfsEnv ); + } + + nn::act::detail::NnasAccessContext* pNnasAccessContext = new( s_NnasAccessContextBuffer ) nn::act::detail::NnasAccessContext; + result = nn::act::detail::WebApi::AcquireSalvageInfo( pNnasAccessContext, m_NnasSubDomain, m_NnasNfsEnv, pSalvagedDataList ); + + if ( result.IsFailure() ) + { + return result; + } + + // NNAS 縺九i蜿門セ励@縺溘い繧ォ繧ヲ繝ウ繝域焚 + m_AcquiredInfoNum = pSalvagedDataList->used; + + if ( !m_AcquiredInfoNum ) + { + return ResultAccountNotFound(); + } + + // NNID 譖エ譁ー譌・譎ゅ′譁ー縺励>鬆縺ォ繧ス繝シ繝 + result = Sort( pSalvagedDataList->buffer, m_AcquiredInfoNum, CompareUpdatedDateInv ); + SalvagedData &slvdata = pSalvagedDataList->buffer[0]; + + + // 蛟句挨繧「繧ォ繧ヲ繝ウ繝郁ィュ螳夲シ医た繝シ繝亥セ後ョ蜈磯ュ繧貞セゥ蜈シ + u32 newPersistentId = 0x80000000; + m_AccountInfo.SetPersistentId( newPersistentId ); // slvdata.GetPersistentId() + m_AccountInfo.SetUuid( slvdata.GetUuid() ); + m_AccountInfo.SetMiiData( slvdata.GetMiiData() ); + m_AccountInfo.SetMiiName( slvdata.GetMiiName().Get() ); + m_AccountInfo.SetAccountId( slvdata.GetAccountId().Get() ); + m_AccountInfo.SetBirthDate( slvdata.GetBirthYear(), slvdata.GetBirthMonth(), slvdata.GetBirthDay() ); + m_AccountInfo.SetGender( slvdata.GetGender() ); + m_AccountInfo.SetCountry( slvdata.GetCountry() ); + m_AccountInfo.SetSimpleAddressId( slvdata.GetSimpleAddressId() ); + m_AccountInfo.SetTimeZoneId( slvdata.GetTimeZoneId().Get() ); + m_AccountInfo.SetUtcOffset( slvdata.GetUtcOffset() ); + m_AccountInfo.SetPrincipalId( slvdata.GetPrincipalId() ); + m_AccountInfo.SetMiiImageUrl( slvdata.GetMiiImageUrl() ); + m_AccountInfo.SetIsMailAddressValidated( slvdata.GetIsMailAddressValidated() ); + m_AccountInfo.SetParentalControlSlotNo( 1 ); // + m_AccountInfo.SetNnasSubDomain( m_NnasSubDomain ); + m_AccountInfo.SetNnasNfsEnv( m_NnasNfsEnv ); + m_AccountInfo.SetNnasType( m_NnasType ); + m_AccountInfo.SetNfsType( m_NfsType ); + m_AccountInfo.SetNfsNo( m_NfsNo ); + m_AccountInfo.SetFpLocalAccountId( nn::friends::GetMyLocalAccountId() ); // default + m_AccountInfo.SetLastAuthenticationResult( nn::act::ResultUnauthenticatedAfterSalvage() ); + m_AccountInfo.SetIsCommitted( true ); + ACT_LOG_INFO( "Salvaged AccountId: %s\n", slvdata.GetAccountId().Get() ); + + // Approval ID 縺ッシ悟叙蠕玲ュ蝣ア縺吶∋縺ヲ縺ョ荳ュ縺九i謗「邏「 + for ( u8 i=0; ibuffer[i].GetApprovalId(); + if ( m_ApprovalId ) + { + break; + } + } + + // 繧「繧ォ繧ヲ繝ウ繝亥ア騾夊ィュ螳 + m_CommonInfo.SetPersistentId( 1, newPersistentId ); + m_CommonInfo.SetCommonUuid( slvdata.GetCommonUuid() ); // sorted by Inv Created Date -> slvdata is the latest account + m_CommonInfo.SetCommonTransferableIdBase( 0 ); //default + m_CommonInfo.SetDefaultNnasSubDomain( m_NnasSubDomain ); + m_CommonInfo.SetDefaultNnasNfsEnv( m_NnasNfsEnv ); + m_CommonInfo.SetDefaultNnasType( m_NnasType ); + m_CommonInfo.SetDefaultNfsType( m_NfsType ); + m_CommonInfo.SetDefaultNfsNo( m_NfsNo ); + + // PersisId 險ュ螳 + m_PersisIdInfo.SetPersistentIdHead( newPersistentId-1 ); + + // TransId 險ュ螳 + m_TransIdInfo.SetCounter( 0 ); //default + + // UUID 險ュ螳 + u16 maxCS_64 = FindMaxUuidClockSequence( pSalvagedDataList ) + 64; + maxCS_64 = maxCS_64 > 0x3FFF ? maxCS_64 - 0x3FFF : maxCS_64; + m_UuidInfo.SetClockSequence( maxCS_64 ); // 14bit + nn::cfg::CTR::system::SetUuidClockSequence( maxCS_64 ); + m_UuidInfo.SetLastTime( 1 ); + + return result; +} + +Result SalvageManager::RestoreInformation( void ) +{ + Result result = ResultSuccess(); + + NN_ACT_UPDATE_RESULT_IF_FAILED( result, nn::cfg::system::FlushConfig() ); + + NN_ACT_UPDATE_RESULT_IF_FAILED( result, m_AccountInfo.Save() ); + NN_ACT_UPDATE_RESULT_IF_FAILED( result, m_CommonInfo.Save() ); + NN_ACT_UPDATE_RESULT_IF_FAILED( result, m_PersisIdInfo.Save() ); + NN_ACT_UPDATE_RESULT_IF_FAILED( result, m_TransIdInfo.Save() ); + NN_ACT_UPDATE_RESULT_IF_FAILED( result, m_UuidInfo.Save() ); + + if ( result.IsSuccess() ) + { + result = FileSystem::GetSingleton().FlushQuota( NN_ACT_NAND_QUOTA_PATH ); + } + + return result; +} + +u16 SalvageManager::FindMaxUuidClockSequence( WorkBuffer* infoList ) +{ + u16 maxClockSequence = 0; + u32 num = infoList->used; + + for ( u8 i = 0; ibuffer[i].GetUuid(); + u16 clockSequence = uuid.GetClockSequence(); + maxClockSequence = maxClockSequence < clockSequence ? clockSequence : maxClockSequence; + } + + return maxClockSequence; +} + +u32 SalvageManager::GetApprovalId( void ) const +{ + return m_IsCompleted ? m_ApprovalId : 0; +} + +Result SalvageManager::GetAge( u16* pAge ) const +{ + if ( !m_IsCompleted ) + { + return ResultInternalError(); + } + + u16 year = m_AccountInfo.GetBirthYear(); + u8 month = m_AccountInfo.GetBirthMonth(); + u8 day = m_AccountInfo.GetBirthDay(); + + if ( !nn::fnd::DateTime::IsValidDate( year, month, day ) || !ServerTime::IsValid() ) + { + return ResultInternalError(); + } + else + { + nn::fnd::DateTime utcTimePlus12 = ServerTime::Get() + nn::fnd::TimeSpan::FromHours( 12 ); + nn::fnd::DateTime birthDay = nn::fnd::DateTime( year, month, day ); + + u32 networkTimeSerialized = ( utcTimePlus12.GetYear() << 16 ) | ( utcTimePlus12.GetMonth() << 8 ) | utcTimePlus12.GetDay(); + u32 birthdaySerialized = ( year << 16 ) | ( month << 8 ) | day; + + if ( birthdaySerialized > networkTimeSerialized ) + { + return ResultInternalError(); + } + else + { + *pAge = ( networkTimeSerialized - birthdaySerialized ) >> 16; + } + } + + return ResultSuccess(); +} + +Result SalvageManager::GetCountry( char* pCountry ) const +{ + if ( !m_IsCompleted ) + { + return ResultInternalError(); + } + + char country[NN_ACT_COUNTRY_SIZE] = {0}; + Result result = SystemInfoManager::GetSingleton().ConvertCountry( country, NN_ACT_COUNTRY_SIZE, m_AccountInfo.GetCountry() ); + if ( ResultConfigInvalidCountryCodeError().Includes( result ) ) + { + result = ResultSuccess(); + country[0] = '\0'; + } + + if( result.IsSuccess() ) + { + Strlcpy( pCountry, country, NN_ACT_COUNTRY_SIZE ); + } + + return result; +} + +Result SalvageManager::GetCountryCode( u32* pCountryCode ) const +{ + if ( !m_IsCompleted ) + { + return ResultInternalError(); + } + + *pCountryCode = m_AccountInfo.GetCountry(); + + return ResultSuccess(); +} + +// sort +int SalvageManager::CompareUpdatedDate( const SalvagedData* p1, const SalvagedData* p2 ) +{ + NnasXmlDateContainer updated1, updated2; + updated1 = p1->GetLastUpdatedDate(); + updated2 = p2->GetLastUpdatedDate(); + + return strncmp( updated1.Get(), updated2.Get(), updated1.GetMaxLength()+1 ); +} + +int SalvageManager::CompareUpdatedDateInv( const SalvagedData* p1, const SalvagedData* p2 ) +{ + return CompareUpdatedDate( p2, p1 ); +} + +int SalvageManager::CompareCreatedDate( const SalvagedData* p1, const SalvagedData* p2 ) +{ + NnasXmlDateContainer created1, created2; + created1 = p1->GetCreatedDate(); + created2 = p2->GetCreatedDate(); + + return strncmp( created1.Get(), created2.Get(), created1.GetMaxLength()+1 ); +} + +int SalvageManager::CompareCreatedDateInv( const SalvagedData* p1, const SalvagedData* p2 ) +{ + return CompareCreatedDate( p2, p1 ); +} + +int SalvageManager::ComparePersistentId( const SalvagedData* p1, const SalvagedData* p2 ) +{ + return p1->GetPersistentId() - p2->GetPersistentId(); +} + +int SalvageManager::ComparePersistentIdInv( const SalvagedData* p1, const SalvagedData* p2 ) +{ + return ComparePersistentId( p2, p1 ); +} + +Result SalvageManager::Sort( SalvagedData* list, size_t num, int( *cmp )( const SalvagedData*, const SalvagedData* ) ) +{ + qsort( list, num, sizeof( SalvagedData ), reinterpret_cast(cmp) ); + + return ResultSuccess(); +} + +} +} +} Index: Horizon/sources/libraries/actslv/act_SalvageManager.h =================================================================== --- Horizon/sources/libraries/actslv/act_SalvageManager.h (revision 0) +++ Horizon/sources/libraries/actslv/act_SalvageManager.h (working copy) @@ -0,0 +1,99 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_ACT_SALVAGE_H_ +#define LIBRARIES_ACTSLV_ACT_SALVAGE_H_ + +#include "act_Common.h" + +#include "util/act_StringContainer.h" + +#include "act_SalvagedData.h" +#include "save/act_AccountInstanceNandData.h" +#include "save/act_AccountManagerNandData.h" +#include "save/act_PersistentIdManagerNandData.h" +#include "save/act_TransferableIdManagerNandData.h" +#include "save/act_UuidManagerNandData.h" + +namespace nn +{ +namespace act +{ +namespace detail +{ + +class SalvageManager +{ +private: + + AccountInstanceNandData m_AccountInfo; + AccountManagerNandData m_CommonInfo; + PersistentIdManagerNandData m_PersisIdInfo; + TransferableIdManagerNandData m_TransIdInfo; + UuidManagerNandData m_UuidInfo; + + u32 m_AcquiredInfoNum; // NNAS 縺九i蜿門セ励@縺溘い繧ォ繧ヲ繝ウ繝域ュ蝣ア謨ー + + NnasType m_NnasType; + NfsType m_NfsType; + u8 m_NfsNo; + NnasSubDomainContainer m_NnasSubDomain; + NnasNfsEnvContainer m_NnasNfsEnv; + + bool m_IsInitialized; + bool m_IsCompleted; + + u32 m_ApprovalId; + +private: + + void ClearMembers( void ); + static u16 FindMaxUuidClockSequence( WorkBuffer* infoList ); + +private: + + static void UnmountThreadFunc( void* ptrArg ); + +private: + + // sort + static int CompareUpdatedDate( const SalvagedData* p1, const SalvagedData* p2 ); + static int CompareUpdatedDateInv( const SalvagedData* p1, const SalvagedData* p2 ); + static int CompareCreatedDate( const SalvagedData* p1, const SalvagedData* p2 ); + static int CompareCreatedDateInv( const SalvagedData* p1, const SalvagedData* p2 ); + static int ComparePersistentId( const SalvagedData* p1, const SalvagedData* p2 ); + static int ComparePersistentIdInv( const SalvagedData* p1, const SalvagedData* p2 ); + + Result Sort( SalvagedData* list, size_t num, int( *cmp )( const SalvagedData*, const SalvagedData* ) ); + +public: + + SalvageManager(); + virtual ~SalvageManager(); + + Result Initialize( void ); + Result Finalize( bool completeFlg = true ); + + Result AcquireInformation( WorkBuffer* pSalvagedDataList ); + Result RestoreInformation( void ); + + u32 GetApprovalId( void ) const; + Result GetAge( u16* pAge ) const; + Result GetCountry( char* pCountry ) const; + Result GetCountryCode( u32* pCountryCode ) const; +}; + +} +} +} + +#endif // LIBRARIES_ACTSLV_ACT_SALVAGE_H_ Index: Horizon/sources/libraries/actslv/act_Uuid.h =================================================================== --- Horizon/sources/libraries/actslv/act_Uuid.h (revision 0) +++ Horizon/sources/libraries/actslv/act_Uuid.h (working copy) @@ -0,0 +1,117 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2013 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_ACT_UUID_H_ +#define LIBRARIES_ACTSLV_ACT_UUID_H_ + +#include "act_Common.h" + +#define ACT_UUID_SIZE (128/8) +#define ACT_UUID_NODE_SIZE (48/8) +#define ACT_UUID_STR_SIZE sizeof("12345678-1234-1234-1234-123456789012") + +namespace nn +{ +namespace act +{ +namespace detail +{ + +class UuidInternal +{ + friend class UuidManager; + +private: + typedef struct Data { + u32 time_low; + u16 time_mid; + u16 time_hi_and_version; + u8 clock_seq_hi_and_reserved; + u8 clock_seq_low; + u8 node[6]; + } Data; + + Data m_Data; + +public: + + UuidInternal( void ) { memset(&m_Data, 0, sizeof(m_Data)); } + UuidInternal( const UuidInternal& obj ) { memcpy(&m_Data, &obj.m_Data, sizeof(m_Data)); } + + bool operator==( const UuidInternal &obj ) const + { + return Compare( obj ); + } + bool operator!=( const UuidInternal &obj ) const { return !(*this==obj); } + + bool Compare( const UuidInternal &obj, u8 size=16 ) const + { + return memcmp(&m_Data, &obj.m_Data, size>16?16:size)==0 ? true : false; + } + + void Set( const UuidInternal& obj ) { memcpy(&m_Data, &obj.m_Data, sizeof(m_Data)); } + void Set( const void* data ) { memcpy(&m_Data, data, sizeof(m_Data)); } + + const Uuid& GetACTUuid() const { return *reinterpret_cast(&m_Data); } + size_t GetSize( void ) const { return sizeof(Data); } + + bool IsEmpty( void ) const { return m_Data.time_hi_and_version == 0; } + void Clear( void ) { memset(&m_Data, 0, sizeof(m_Data)); } + + void ToStr( char *str ) const + { + if( str ) + { + const u8* p = GetACTUuid().data; + nn::nstd::TSNPrintf( str, ACT_UUID_STR_SIZE, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]); + } + } + + void FromStr( const char* pStr ) + { + + if (Strnlen( pStr, ACT_UUID_STR_SIZE ) != ACT_UUID_STR_SIZE - 1) + { + return; + } + + u8* data = reinterpret_cast(&m_Data); + + while (*pStr != '\0') + { + if (*pStr++ == '-') + { + continue; + } + + char c2[3]; + Strlcpy( c2, pStr - 1, 3 ); + + char* pEndPtr; + *data = StrToU8( c2, &pEndPtr, 16 ); + ++data; + ++pStr; + } + } + + u16 GetClockSequence( void ) + { + return ((m_Data.clock_seq_hi_and_reserved & 0x3F) << 8) | m_Data.clock_seq_low; + } +}; + +} +} +} + +#endif // LIBRARIES_ACTSLV_ACT_UUID_H_ Index: Horizon/sources/libraries/actslv/CTR/act_ApiSalvage.cpp =================================================================== --- Horizon/sources/libraries/actslv/CTR/act_ApiSalvage.cpp (revision 0) +++ Horizon/sources/libraries/actslv/CTR/act_ApiSalvage.cpp (working copy) @@ -0,0 +1,131 @@ +サソ/*---------------------------------------------------------------------------* + Project: Horizon + File: act_ApiSalvage.cpp + + Copyright (C)2009-2013 Nintendo Co., Ltd. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Rev: 50823 $ + *---------------------------------------------------------------------------*/ + +#include "../act_SalvageManager.h" +#include "../act_SalvagedData.h" + +#define NN_ACTSLV_FINALIZE_AND_RETURN_IF_FAILED( exp, finalize_func ) \ + do \ + { \ + nn::Result resultActReturnIfFailed_ = exp; \ + if ( resultActReturnIfFailed_.IsFailure() ) \ + { \ + finalize_func; \ + return resultActReturnIfFailed_; \ + } \ + } while (0) + +#define ACQUIRE_ACCOUNT_INFO_MAX (8) // NNAS 縺九i蜿門セ励〒縺阪k繧「繧ォ繧ヲ繝ウ繝域ュ蝣ア縺ョ譛螟ァ謨ー + +namespace +{ +nn::act::detail::SalvageManager s_SalvageManager; + +// NNAS 縺九i繧オ繝ォ繝吶シ繧ク諠蝣ア繧貞女縺大叙繧九ヰ繝繝輔ぃ +u8 s_HeapBuffer[6 * 1024] NN_ATTRIBUTE_ALIGN( 8 ); +nn::fnd::ExpHeap s_SalvageHeap; + +template +nn::act::WorkBuffer* AllocateWorkBuffer( size_t count ) +{ + size_t size = sizeof( nn::act::WorkBuffer ) + ( count - 1 )*sizeof( T ); + nn::act::WorkBuffer* pWorkBuffer = reinterpret_cast*>( s_SalvageHeap.Allocate( size, 8 ) ); + if ( !pWorkBuffer ) + { + return NULL; + } + + pWorkBuffer->total = count; + pWorkBuffer->used = 0; + + return pWorkBuffer; +} + +template +void FreeWorkBuffer( nn::act::WorkBuffer* p ) +{ + s_SalvageHeap.Free( p ); +} +} + +namespace nn { +namespace act { + +Result SalvageAccounts( void ) +{ + ACT_LOG_DEBUG( ">> SalvageAccounts Initialize" ); + NN_ACT_RETURN_IF_FAILED( s_SalvageManager.Initialize() ); + + ACT_LOG_DEBUG( ">> SalvageAccounts AcquireInformation" ); + s_SalvageHeap.Initialize( reinterpret_cast( s_HeapBuffer ), 6 * 1024 ); + WorkBuffer* pSalvagedDataList = AllocateWorkBuffer( static_cast( ACQUIRE_ACCOUNT_INFO_MAX ) ); + NN_ACTSLV_FINALIZE_AND_RETURN_IF_FAILED( s_SalvageManager.AcquireInformation( pSalvagedDataList ), s_SalvageManager.Finalize( false ) ); + FreeWorkBuffer( pSalvagedDataList ); + s_SalvageHeap.Finalize(); + + ACT_LOG_DEBUG( ">> SalvageAccounts RestoreInformation" ); + NN_ACTSLV_FINALIZE_AND_RETURN_IF_FAILED( s_SalvageManager.RestoreInformation(), s_SalvageManager.Finalize(false) ); + + ACT_LOG_DEBUG( ">> SalvageAccounts Finalize" ); + NN_ACT_RETURN_IF_FAILED( s_SalvageManager.Finalize() ); + + ACT_LOG_DEBUG( ">> SalvageAccounts Done" ); + + return ResultSuccess(); +} + +u32 GetSalvagedApprovalId( void ) +{ + return s_SalvageManager.GetApprovalId(); +} + +bool IsOverAgeAtSalvage( u8 age ) +{ + u16 userAge = 0; + Result result = s_SalvageManager.GetAge( &userAge ); + + return result.IsSuccess() ? userAge >= age : false; +} + +u8 GetAgeAtSalvage( void ) +{ + u16 userAge = 0; + Result result = s_SalvageManager.GetAge( &userAge ); + + return result.IsSuccess() ? static_cast( userAge ) : 0; +} + +Result GetCountryAtSalvage( char* pCountry ) +{ + NN_ACT_RETURN_RESULT_IF_NULL( pCountry ); + + return s_SalvageManager.GetCountry( pCountry ); +} + +Result GetCountryCodeAtSalvage( u32* pCountryCode ) +{ + NN_ACT_RETURN_RESULT_IF_NULL( pCountryCode ); + + return s_SalvageManager.GetCountryCode( pCountryCode ); +} + +} // act +} // nn + +extern "C" { + +// nothing to do + +} Index: Horizon/sources/libraries/actslv/net/act_NnasAccessContext.cpp =================================================================== --- Horizon/sources/libraries/actslv/net/act_NnasAccessContext.cpp (revision 0) +++ Horizon/sources/libraries/actslv/net/act_NnasAccessContext.cpp (working copy) @@ -0,0 +1,371 @@ +サソ +#include +#include +#include "act_NnasAccessContext.h" +#include "../util/act_SystemInfoManager.h" + + +using namespace nn::act::detail; + +#define ACT_RETURN_AND_CONVERT_IF_FAILED( exp ) \ + do \ + { \ + nn::Result resultActReturnIfFailed_ = exp; \ + if ( resultActReturnIfFailed_.IsFailure() ) \ + { \ + return ConvertToActResult(resultActReturnIfFailed_); \ + } \ + } while (0) + +void NnasAccessContext::GetDefaultHostServerSettings(NnasSubDomainContainer* pSubDomain, NnasNfsEnvContainer* pNfsEnv) +{ + // Get Default settings for exceptional input according to environment + ConvertHostServerSettings::ToStr( pSubDomain, pNfsEnv, + ConvertHostServerSettings::INVALID_NNAS_TYPE, ConvertHostServerSettings::INVALID_NFS_TYPE, ConvertHostServerSettings::INVALID_NFS_NO ); +} + +NnasAccessContext::NnasAccessContext() + : m_IsCanceled(false) +{ + // TODO + // 蜷後§ CertStore 繧ェ繝悶ず繧ァ繧ッ繝医r菴ソ縺縺セ繧上&縺ェ縺縺ィ SSL Resumption 縺ッ譛牙柑縺ォ縺ェ繧峨↑縺縺ョ縺ァ + // NnasAccessContext 蜀縺ァ譛牙柑縺ェ CertStore 繧呈戟縺、繧医≧縺ォ縺吶k縲 Initialize/Finalize 縺ァ縺ッ荳榊、峨 + NN_PANIC_IF_FAILED(m_CertStore.Initialize()); + NN_PANIC_IF_FAILED(m_CertStore.RegisterCert(nn::ssl::CACERT_NINTENDO_CA_G3)); +} + + // 繝繧ケ繝医Λ繧ッ繧ソ縺ァ縺吶 +NnasAccessContext::~NnasAccessContext() +{ + m_CertStore.Finalize(); +} + +nn::Result NnasAccessContext::Initialize(const NnasRequestParameters& params, + const NnasSubDomainContainer& subDomain, + const NnasNfsEnvContainer& nfsEnv) +{ + NnasSubDomainContainer optionalSubDomain; + optionalSubDomain.Set(params.GetSubDomain()); + + ACT_RETURN_AND_CONVERT_IF_FAILED(InitializeBaseUrl(subDomain, optionalSubDomain)); + if(std::strlen(params.GetUrl()) != 0) + { + ACT_RETURN_AND_CONVERT_IF_FAILED(m_RequestUrlBuilder.AddUrl(params.GetUrl())); + } + + ACT_RETURN_AND_CONVERT_IF_FAILED(InitializeConnection(nfsEnv, params.GetHttpMethod())); + + for(int i = 0; i < params.GetHeaderFieldNumber(); ++i) + { + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField(params.GetHeaderFieldKey(i), params.GetHeaderFieldValue(i))); + } + + // TODO Header + Post 繝繝シ繧ソ縺ァ 4 KB 繧定カ縺医k蝣エ蜷医ッ LazyPost 繧剃スソ逕ィ縺励↑縺縺ィ鬧逶ョ + // 4 KB 縺ッ http::Initialize() 縺ォ貂。縺励※縺繧九ヰ繝繝輔ぃ繧オ繧、繧コ縺ェ縺ョ縺ァ縲∝「励d縺帙ー荳蠢懷ッセ蠢懷庄閭ス + + for(int i = 0; i < params.GetPostDataNumber(); ++i) + { + switch(params.GetPostDataType(i)) + { + case NnasRequestParameters::TYPE_ASCII: + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddPostDataAscii(params.GetPostDataKey(i), params.GetPostDataAscii(i))); + break; + case NnasRequestParameters::TYPE_BINARY: + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddPostDataBinary(params.GetPostDataKey(i), params.GetPostDataBinary(i), params.GetPostDataBinarySize(i))); + break; + case NnasRequestParameters::TYPE_RAW: + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddPostDataRaw(params.GetHeaderFieldValue(i), params.GetPostDataBinarySize(i))); + break; + default: + return ResultInvalidArgument(); + } + } + return ResultSuccess(); +} + + +///////////////////////////////////////////////////////////////////////////// +// 蛻晄悄蛹悶サ邨ゆコ +nn::Result NnasAccessContext::InitializeBaseUrl(const NnasSubDomainContainer& subDomain, + const NnasSubDomainContainer& optionalSubDomain) +{ + for(int i = 0; i < subDomain.GetLength(); ++i) + { + if(subDomain.Get()[i] == '/') + { + return ResultInvalidArgument(); + } + } + for(int i = 0; i < optionalSubDomain.GetLength(); ++i) + { + if(optionalSubDomain.Get()[i] == '/') + { + return ResultInvalidArgument(); + } + } + + char url[128] = {0}; + nn::nstd::TSNPrintf(url, 128, "https://%s%saccount.nintendo.net/v1/api/", subDomain.Get(), optionalSubDomain.Get()); + + m_RequestUrlBuilder.SetUrl(url); + + return ResultSuccess(); +} + + + +nn::Result NnasAccessContext::InitializeConnection(const NnasNfsEnvContainer& nfsEnv, HttpMethod method) +{ + nn::http::RequestMethod nnhttpMethod = nn::http::REQUEST_METHOD_GET; + switch(method) + { + case HTTP_METHOD_GET: + nnhttpMethod = nn::http::REQUEST_METHOD_GET; + break; + case HTTP_METHOD_POST: + nnhttpMethod = nn::http::REQUEST_METHOD_POST; + break; + case HTTP_METHOD_PUT: + nnhttpMethod = nn::http::REQUEST_METHOD_PUT; + break; + case HTTP_METHOD_DELETE: + nnhttpMethod = nn::http::REQUEST_METHOD_DELETE; + break; + case HTTP_METHOD_POST_NODATA: + nnhttpMethod = nn::http::REQUEST_METHOD_POST_NODATA; + break; + case HTTP_METHOD_PUT_NODATA: + nnhttpMethod = nn::http::REQUEST_METHOD_PUT_NODATA; + break; + default: + break; + } + + ACT_LOG_INFO("URL:%u %s", method, m_RequestUrlBuilder.GetUrl()); + + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.Initialize(m_RequestUrlBuilder.GetUrl(), nnhttpMethod)); + ACT_RETURN_AND_CONVERT_IF_FAILED(AddHeadersTo(nfsEnv)); + ACT_RETURN_AND_CONVERT_IF_FAILED(BindSslContextTo()); + ACT_RETURN_AND_CONVERT_IF_FAILED(AddDeviceCertHeaderTo()); + + return nn::ResultSuccess(); +} + +nn::Result NnasAccessContext::Finalize() +{ + m_ClientInformation.Clear(); + m_IsCanceled = false; + m_NextAccountIdContainer.Set( "" ); + + return FinalizeConnection(); +} + +nn::Result NnasAccessContext::FinalizeConnection() +{ + nn::Result result = m_Connection.Finalize(); + + // ResultNotConnectedErr 縺ッ Initialize 縺悟他縺ー繧後※縺縺ェ縺縺ョ縺ァ豌励↓縺励↑縺 + if(result.IsSuccess() || result == nn::http::ResultNotConnectedErr()) + { + return nn::ResultSuccess(); + } + return result; +} + +///////////////////////////////////////////////////////////////////////////// +// 騾壻ソ。 + +// 繝倥ャ繝諠蝣ア縺ョ霑ス蜉 +nn::Result NnasAccessContext::AddHeaderField(const char* pName, const char* pValue) +{ + return ConvertToActResult(m_Connection.AddHeaderField(pName, pValue)); +} + +nn::Result NnasAccessContext::AddPostDataAscii(const char* pLabel, const char* pValue) +{ + return ConvertToActResult(m_Connection.AddPostDataAscii(pLabel, pValue)); +} + +nn::Result NnasAccessContext::AddPostDataRaw(const void* pValue, size_t valueSize) +{ + return ConvertToActResult(m_Connection.AddPostDataRaw(pValue, valueSize)); +} + +// 謗・邯壹@縺セ縺 +nn::Result NnasAccessContext::Connect() +{ + // 繝悶Ο繝繧ッ縺励◆縺上↑縺縺ョ縺ァ ConnectAsync + return ConvertToActResult(m_Connection.ConnectAsync()); +} + +// HTTP繝ャ繧ケ繝昴Φ繧ケ繧定ェュ縺ソ蜿悶j縺セ縺吶UimeoutMilliSecond 縺ォ 0 繧呈欠螳壹@縺溷エ蜷医√ち繧、繝繧「繧ヲ繝医@縺セ縺帙s縲よ嫌蜍輔ッnn::http::Connection::Read()縺ォ貅匁侠 +nn::Result NnasAccessContext::Read(u8* pBodyBuf, size_t bufLen, s64 timeoutMilliSecond) +{ + if(timeoutMilliSecond == 0) + { + return ConvertToActResult(m_Connection.Read(pBodyBuf, bufLen)); + } + else + { + return ConvertToActResult(m_Connection.Read(pBodyBuf, bufLen, nn::fnd::TimeSpan::FromMilliSeconds(timeoutMilliSecond))); + } +} + +// HTTP繝ャ繧ケ繝昴Φ繧ケ縺ョ繝。繝繧サ繝シ繧ク繝懊ョ繧」蜿嶺ソ。縺ョ騾イ謐礼憾豕√r蜿門セ励@縺セ縺 +nn::Result NnasAccessContext::GetProgress(size_t* pReceivedLen, size_t* pContentLen) const +{ + return ConvertToActResult(m_Connection.GetProgress(pReceivedLen, pContentLen)); +} + +// 蜿嶺ソ。縺励◆HTTP繝ャ繧ケ繝昴Φ繧ケ縺ョ繧ケ繝繝シ繧ソ繧ケ繧ウ繝シ繝峨r蜿門セ励@縺セ縺 +nn::Result NnasAccessContext::GetStatusCode(s32* pStatusCodeCourier) const +{ + return ConvertToActResult(m_Connection.GetStatusCode(pStatusCodeCourier)); +} + +// 蜿嶺ソ。縺励◆HTTP繝ャ繧ケ繝昴Φ繧ケ縺ョ繝。繝繧サ繝シ繧ク繝倥ャ繝縺九i縲∵欠螳壹@縺溘Λ繝吶Ν縺ォ荳閾エ縺吶k繝輔ぅ繝シ繝ォ繝峨ョ蛟、繧貞叙蠕励@縺セ縺 +nn::Result NnasAccessContext::GetHeaderField(const char* pLabel, char* pFieldBuf, size_t bufSize, size_t* pFieldLengthCourier) const +{ + return ConvertToActResult(m_Connection.GetHeaderField(pLabel, pFieldBuf, bufSize, pFieldLengthCourier)); +} + +// LazyPost 逕ィ. Curl 縺ィ莉墓ァ倥′驕輔≧縺ョ縺ァ縲√◎縺ョ縺セ縺セ繧繧九→蠕後〒蝗ー繧九°繧 +nn::Result NnasAccessContext::SetLazyPostSetting() +{ + return ConvertToActResult(m_Connection.SetLazyPostDataSetting(nn::http::POST_DATA_TYPE_RAW)); +} +// nn::Result SendPostDataAscii(); +nn::Result NnasAccessContext::NotifyFinishSendPostData() +{ + return ConvertToActResult(m_Connection.NotifyFinishSendPostData()); +} + +nn::Result NnasAccessContext::Cancel() +{ + m_IsCanceled = true; + + // Connect 縺励※縺繧医≧縺後>縺セ縺縺後く繝」繝ウ繧サ繝ォ繧偵°縺代k + m_Connection.Cancel(); + + return ResultSuccess(); +} + +///////////////////////////////////////////////////////////////////////////// +// 繝繧ケ繝育畑髢「謨ー鄒、 + +///////////////////////////////////////////////////////////////////////////// +// 荳サ縺ォ蛻晄悄蛹也畑髢「謨ー鄒、 + +// NNAS 縺ォ繧「繧ッ繧サ繧ケ縺吶k縺溘a縺ョ諠蝣ア繧 HTTP 繧ウ繝阪け繧キ繝ァ繝ウ繧ェ繝悶ず繧ァ繧ッ繝医↓霑ス蜉縺励∪縺吶 +nn::Result NnasAccessContext::AddHeadersTo(const NnasNfsEnvContainer& nfsEnv) +{ + char buffer[NN_ACT_NET_U32_STRING_SIZE] = {0}; + + // 譛ャ菴灘崋譛牙、 + u8 platformId = 0; + ACT_RETURN_AND_CONVERT_IF_FAILED(SystemInfoManager::GetSingleton().ReadPlatformId(&platformId)); + nn::nstd::TSNPrintf(buffer, sizeof(buffer), "%u", platformId); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Platform-ID", buffer)); + + // 譛ャ菴楢ィュ螳壼、 + if ( SystemInfoManager::GetSingleton().IsDevelopmentDevice() ) + { + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Device-Type", "1")); + } + else + { + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Device-Type", "2")); + } + + // 譛ャ菴灘崋譛牙、 + u32 deviceId = SystemInfoManager::GetSingleton().GetDeviceId(); + nn::nstd::TSNPrintf(buffer, sizeof(buffer), "%u", deviceId); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Device-ID", buffer)); + ACT_LOG_INFO( "X-Nintendo-Device-ID:%u\n", buffer ); + + // 譛ャ菴灘崋譛牙、 + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Serial-Number", SystemInfoManager::GetSingleton().GetSerialId())); + + // 譛ャ菴楢ィュ螳壼、 + u16 systemVersion = SystemInfoManager::GetSingleton().GetSystemVersion(); + nn::nstd::TSNPrintf(buffer, sizeof(buffer), "%04X", systemVersion); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-System-Version", buffer)); + + // 譛ャ菴楢ィュ螳壼、 + u32 region = 0; + ACT_RETURN_AND_CONVERT_IF_FAILED(SystemInfoManager::GetSingleton().ReadRegion(®ion)); + nn::nstd::TSNPrintf(buffer, sizeof(buffer), "%u", region); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Region", buffer)); + + // 譛ャ菴楢ィュ螳壼、 + ACT_RETURN_AND_CONVERT_IF_FAILED(SystemInfoManager::GetSingleton().ReadCountry(buffer, sizeof(buffer))); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Country", buffer)); + + // 譛ャ菴楢ィュ螳壼、 + ACT_RETURN_AND_CONVERT_IF_FAILED(SystemInfoManager::GetSingleton().ReadLanguage(buffer, sizeof(buffer))); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("Accept-Language", buffer)); + + // 螳壽焚(讖溷ッ諠蝣ア) 菫ョ逅繝繝シ繝ォ逕ィ + ACT_RETURN_AND_CONVERT_IF_FAILED( m_Connection.AddHeaderField( "X-Nintendo-Client-ID", "c2e4ae18c34b116b837bc8274eb13edd" ) ); + + // 螳壽焚(讖溷ッ諠蝣ア) 菫ョ逅繝繝シ繝ォ逕ィ + ACT_RETURN_AND_CONVERT_IF_FAILED( m_Connection.AddHeaderField( "X-Nintendo-Client-Secret", "7806c7e2cd76d37c8c7c22dbd3d4e868" ) ); + + // 螳壽焚 + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("Accept", "*/*")); + + // 螳壽焚(TODO) + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-API-Version", "0100")); + + // 螳壽焚(TODO) + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-FPD-Version", "0000")); + + // 譛ャ菴楢ィュ螳壼、 + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Environment", nfsEnv.Get())); + + // 繧ソ繧、繝医Ν ID + char titleId[17] = "0000000000000000"; + nn::nstd::TSNPrintf(titleId, 17, "%016llX", m_ClientInformation.GetTitleId()); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Title-ID", titleId)); + + // 繝ヲ繝九シ繧ッ ID + char uniqueId[6] = "00000"; + nn::nstd::TSNPrintf(uniqueId, 6, "%05X", m_ClientInformation.GetUniqueId()); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Unique-ID", uniqueId)); + + // 繧ソ繧、繝医Ν繝舌シ繧ク繝ァ繝ウ + char titleVersion[5] = "0000"; + nn::nstd::TSNPrintf(titleVersion, 5, "%04X", m_ClientInformation.GetTitleVersion()); + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Application-Version", titleVersion)); + + return nn::ResultSuccess(); +} + +// 繝繝舌う繧ケ險シ譏取嶌繧 HTTP 繧ウ繝阪け繧キ繝ァ繝ウ繧ェ繝悶ず繧ァ繧ッ繝医↓霑ス蜉縺励∪縺吶 +nn::Result NnasAccessContext::AddDeviceCertHeaderTo() +{ + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.AddHeaderField("X-Nintendo-Device-Cert", SystemInfoManager::GetSingleton().GetDeviceCertBase64())); + + return nn::ResultSuccess(); +} + +// NNAS 縺ォ繧「繧ッ繧サ繧ケ縺吶k縺溘a縺ョ SSL 繧ウ繝ウ繝繧ュ繧ケ繝医r HTTP 繧ウ繝阪け繧キ繝ァ繝ウ繧ェ繝悶ず繧ァ繧ッ繝医↓邏蝉サ倥¢縺セ縺吶 +nn::Result NnasAccessContext::BindSslContextTo() +{ + // SSL 繧ェ繝励す繝ァ繝ウ + { + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.SetVerifyOption(nn::ssl::USE_SESSION_CACHE)); + } + // 繧ッ繝ゥ繧、繧「繝ウ繝郁ィシ譏取嶌 + { + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.SetClientCert(nn::ssl::CLIENTCERT_DEFAULT)); + } + // 隱崎ィシ螻 + { + ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.SetRootCaStore(m_CertStore)); + //ACT_RETURN_AND_CONVERT_IF_FAILED(m_Connection.SetRootCa(nn::ssl::CACERT_NINTENDO_CA_G3)); + } + + return nn::ResultSuccess(); +} + Index: Horizon/sources/libraries/actslv/net/act_ServerTime.cpp =================================================================== --- Horizon/sources/libraries/actslv/net/act_ServerTime.cpp (revision 0) +++ Horizon/sources/libraries/actslv/net/act_ServerTime.cpp (working copy) @@ -0,0 +1,50 @@ +サソ +#include "act_ServerTime.h" + +using namespace nn::act::detail; + +namespace +{ + // 繧オ繝シ繝先凾蛻サ縺ィRTC縺ョ蟾ョ蛻 + nn::fnd::TimeSpan s_ServerTimeDifference; + + // 譛牙柑繝輔Λ繧ー + bool s_isValid = false; + + nn::fnd::DateTime GetRtcTime() + { + return nn::fnd::DateTime::GetNow() - nn::cfg::GetUserTimeOffset(); + } +} + +void ServerTime::Set(nn::fnd::TimeSpan unixTime) +{ + //NN_ACT_GET_SCOPED_SCHEDULER_LOCK(); + + nn::fnd::DateTime serverTime = nn::fnd::DateTime(1970, 1, 1) + unixTime; + + s_ServerTimeDifference = serverTime - GetRtcTime(); + + s_isValid = true; +} + +nn::fnd::DateTime ServerTime::Get() +{ + //NN_ACT_GET_SCOPED_SCHEDULER_LOCK(); + + return GetRtcTime() + s_ServerTimeDifference; +} + +nn::fnd::TimeSpan ServerTime::GetServerTimeDifference() +{ + //NN_ACT_GET_SCOPED_SCHEDULER_LOCK(); + + return s_ServerTimeDifference - nn::cfg::GetUserTimeOffset(); +} + +bool ServerTime::IsValid() +{ + //NN_ACT_GET_SCOPED_SCHEDULER_LOCK(); + + return s_isValid; +} Index: Horizon/sources/libraries/actslv/net/act_WebApi.cpp =================================================================== --- Horizon/sources/libraries/actslv/net/act_WebApi.cpp (revision 0) +++ Horizon/sources/libraries/actslv/net/act_WebApi.cpp (working copy) @@ -0,0 +1,224 @@ +サソ +#include "act_WebApi.h" +#include "act_RequestUrlBuilder.h" +#include "act_ServerTime.h" + +#include "parser/act_ResponseParser.h" +#include "parser/act_AcquireSalvageInfoResponseParser.h" + +#include "../util/act_SystemInfoManager.h" + + +using namespace nn::act::detail; +using namespace nn::act; + +namespace { +nn::Result ConvertHttpStatusCode( s32 statusCode ) +{ + ACT_LOG_INFO("STATUS %d\n", statusCode); + + if (statusCode / 100 == 2) + { + return nn::ResultSuccess(); + } + else if (statusCode / 100 == 4) + { + switch (statusCode) + { + case 400: + return ResultBadFormatRequest(); + case 403: + return ResultRequestForbidden(); + case 404: + return ResultRequestNotFound(); + case 405: + return ResultWrongHttpMethod(); + default: + return ResultUnknownServerError(); + } + } + else if (statusCode == 500) + { + return ResultInternalServerError(); + } + else + { + return ResultUnknownServerError(); + } +} + +nn::Result PushBuffer(WorkBuffer* pRawResponse, const char* pBuffer, size_t size) +{ + if ( pRawResponse == NULL || pBuffer == NULL || size == 0) + { + return nn::ResultSuccess(); + } + + if ( pRawResponse->used + size > pRawResponse->total ) + { + return ResultOutOfUserHeap(); + } + + std::memcpy( &pRawResponse->buffer[pRawResponse->used], pBuffer, size); + pRawResponse->used += (size); + + return nn::ResultSuccess(); +} + +} // namespace + +nn::Result WebApi::ParseResponse(NnasAccessContext* pNnasAccessContext, ResponseParser* pParser, WorkBuffer* pRawResponse) +{ + nn::fnd::TimeSpan timeout = nn::fnd::TimeSpan::FromSeconds(60); + + size_t readTotal = 0; + + while (1) + { + const size_t BUFFER_SIZE = 1024; + + char body[BUFFER_SIZE] = {0}; + + nn::os::Tick beginTick = nn::os::Tick::GetSystemCurrent(); + + nn::Result result = pNnasAccessContext->Read(reinterpret_cast(body), BUFFER_SIZE, timeout.GetMilliSeconds()); + + nn::os::Tick elapsedTick = nn::os::Tick::GetSystemCurrent() - beginTick; + + // 邨碁℃譎る俣蛻縺縺代ち繧、繝繧「繧ヲ繝域凾髢薙r貂帙i縺 + timeout -= elapsedTick.ToTimeSpan(); + + if (result.IsSuccess()) + { + size_t received; + size_t contentLength; + + // 繝繝シ繧ソ繧オ繧、繧コ繧貞叙蠕励☆繧 + NN_UTIL_RETURN_IF_FAILED(pNnasAccessContext->GetProgress(&received, &contentLength)); + + // 蜿嶺ソ。繧オ繧、繧コ繧医j繝繝シ繧ソ繧オ繧、繧コ縺悟、ァ縺阪>縺ョ縺ッ縺翫°縺励> + if ( received < readTotal) + { + return ResultBadFormatResponse(); + } + + //ACT_LOG_DEBUG("http-body %s", body); + + // 繧ッ繝ゥ繧、繧「繝ウ繝医°繧画ク。縺輔l縺溘Γ繝「繝ェ繧定ァヲ繧句庄閭ス諤ァ縺後≠繧九ョ縺ァ繝ュ繝繧ッ繧貞叙蠕励☆繧 + { + //NN_ACT_GET_SCOPED_SCHEDULER_LOCK(); + + NN_ACT_RETURN_IF_TRUE(pNnasAccessContext->IsCanceled(), nn::act::ResultCanceled()); + + pParser->Push(body, received - readTotal); + + NN_ACT_RETURN_IF_FAILED( PushBuffer(pRawResponse, body, received - readTotal) ); + } + + break; + } + else if (!nn::act::ResultHttpErResBodybufShortage().Includes(result)) + { + return result; + } + + // 蛻晏屓縺ョRead縺ァ螳御コ(Success)縺励◆蝣エ蜷医↓縺ッ縺薙%縺ォ縺ッ譚・縺ェ縺 + //ACT_LOG_DEBUG("http-body %s", body); + + // 繧ッ繝ゥ繧、繧「繝ウ繝医°繧画ク。縺輔l縺溘Γ繝「繝ェ繧定ァヲ繧句庄閭ス諤ァ縺後≠繧九ョ縺ァ繝ュ繝繧ッ繧貞叙蠕励☆繧 + { + //NN_ACT_GET_SCOPED_SCHEDULER_LOCK(); + + NN_ACT_RETURN_IF_TRUE(pNnasAccessContext->IsCanceled(), nn::act::ResultCanceled()); + + pParser->Push(body, BUFFER_SIZE); + + NN_ACT_RETURN_IF_FAILED( PushBuffer(pRawResponse, body, BUFFER_SIZE) ); + } + + readTotal += BUFFER_SIZE; + } + + + char field[20] = {0}; + + if (pNnasAccessContext->GetHeaderField("X-Nintendo-Date", field, 20).IsSuccess()) + { + char* pEnd; + int errorCode = 0; + u64 ms = StrToU64(field, &pEnd, 10, &errorCode); + + if (*pEnd == '\0' && errorCode == 0) + { + // 繧オ繝シ繝先凾蛻サ繧呈峩譁ー縺吶k + ServerTime::Set(nn::fnd::TimeSpan::FromMilliSeconds(static_cast(ms))); + } + } + + { + //NN_ACT_GET_SCOPED_SCHEDULER_LOCK(); + + NN_ACT_RETURN_IF_TRUE(pNnasAccessContext->IsCanceled(), nn::act::ResultCanceled()); + + pParser->End(); + + s32 statusCode = 0; + NN_ACT_RETURN_IF_FAILED( pNnasAccessContext->GetStatusCode( &statusCode ) ); + + nn::Result statusCodeResult = ConvertHttpStatusCode( statusCode ); + + if ( pParser->GetParseResult().IsFailure() ) + { + if ( statusCodeResult.IsSuccess() ) + { + return pParser->GetParseResult(); + } + else + { + return statusCodeResult; + } + } + + if ( pParser->GetNnasResult().IsFailure() ) + { + // 縺ゅ∪繧願憶縺上↑縺縺 繧「繧ォ繧ヲ繝ウ繝ID譖エ譁ー譎ゅッ縺薙%縺ァ繧サ繝繝医☆繧 + if ( ResultAccountIdChanged().Includes( pParser->GetNnasResult() ) ) + { + pNnasAccessContext->SetNextAccountId( pParser->GetNnasError().GetMessage() ); + } + return pParser->GetNnasResult(); + } + + NN_ACT_RETURN_IF_FAILED( statusCodeResult ); + NN_ACT_RETURN_IF_FAILED( pParser->Commit() ); + } + + return nn::ResultSuccess(); +} + +nn::Result WebApi::AcquireSalvageInfo( + NnasAccessContext* pNnasAccessContext, + const NnasSubDomainContainer& subDomain, + const NnasNfsEnvContainer& nfsEnv, + WorkBuffer* pSalvagedDataList ) +{ + { + //NN_ACT_GET_SCOPED_SCHEDULER_LOCK(); + NN_ACT_RETURN_IF_TRUE( pNnasAccessContext->IsCanceled(), nn::act::ResultCanceled() ); + + std::memset( pSalvagedDataList->buffer, 0, pSalvagedDataList->total ); + + NN_ACT_RETURN_IF_FAILED( pNnasAccessContext->InitializeBaseUrl( subDomain, "" ) ); + NN_ACT_RETURN_IF_FAILED( pNnasAccessContext->GetRequestUrlBuilder( ).AddUrl( "admin/people/pending_migration" ) ); + NN_ACT_RETURN_IF_FAILED( pNnasAccessContext->InitializeConnection( nfsEnv, HTTP_METHOD_GET ) ); + + NN_ACT_RETURN_IF_FAILED( pNnasAccessContext->Connect() ); + } + + { + AcquireSalvageInfoResponseParser parser( pSalvagedDataList ); + NN_ACT_RETURN_IF_FAILED( ParseResponse( pNnasAccessContext, &parser ) ); + } + + return nn::ResultSuccess(); +} Index: Horizon/sources/libraries/actslv/net/act_WebApi.h =================================================================== --- Horizon/sources/libraries/actslv/net/act_WebApi.h (revision 0) +++ Horizon/sources/libraries/actslv/net/act_WebApi.h (working copy) @@ -0,0 +1,40 @@ +サソ +#ifndef LIBRARIES_ACTSLV_NET_ACT_WEB_API_H_ +#define LIBRARIES_ACTSLV_NET_ACT_WEB_API_H_ + +#include + +#include "../act_Common.h" +#include "../act_SalvagedData.h" +#include "../util/act_StringContainer.h" + +#include "act_NnasAccessContext.h" + +namespace nn { +namespace act { + +class EulaList; + +namespace detail { + +class ResponseParser; + +namespace WebApi +{ + + // 騾壻ソ。繧定。後>縲√し繝シ繝舌°繧峨ョ蠢懃ュ斐r繝代シ繧ケ縺励∪縺 + nn::Result ParseResponse(NnasAccessContext* pNnasAccessContext, + ResponseParser* pParser, + WorkBuffer* pRawResponse = NULL); + + nn::Result AcquireSalvageInfo( + NnasAccessContext* pNnasAccessContext, + const NnasSubDomainContainer& subDomain, + const NnasNfsEnvContainer& nfsEnv, + WorkBuffer* pSalvagedDataList + ); +} + +}}} + +#endif // LIBRARIES_ACTSLV_NET_ACT_WEB_API_H_ Index: Horizon/sources/libraries/actslv/net/parser/act_AcquireSalvageInfoResponseParser.cpp =================================================================== --- Horizon/sources/libraries/actslv/net/parser/act_AcquireSalvageInfoResponseParser.cpp (revision 0) +++ Horizon/sources/libraries/actslv/net/parser/act_AcquireSalvageInfoResponseParser.cpp (working copy) @@ -0,0 +1,347 @@ +サソ +#include + +#include "act_AcquireSalvageInfoResponseParser.h" +#include "../../util/act_SystemInfoManager.h" + +#define NN_ACT_RETURN_BAD_FORMAT_RESPONSE_IF_OUT_OF_RANGE( v1, v2 ) \ +do \ +{ \ + if( GetContentLength() < v1 || GetContentLength() > v2 ) \ + { \ + SetParseResult( ResultBadFormatResponse() ); \ + return; \ + } \ +} while (0) + + + +using namespace nn::act::detail; + +AcquireSalvageInfoResponseParser::AcquireSalvageInfoResponseParser(WorkBuffer* pSalvagedDataList ) +:m_pSalvagedDataList( pSalvagedDataList ), + m_Count( pSalvagedDataList->total ), + m_Index( 0 ), + m_ReceivedDeviceAttribute( 0 ), + m_ReceivedAccountInfo( 0 ) +{ + m_MiiImage.Clear(); + m_EMail.Clear(); + m_Parent.Clear(); + m_Attribute.Clear(); +} + +nn::Result AcquireSalvageInfoResponseParser::ValidateParsedData( void ) +{ + // lack of necessary data + if( m_pSalvagedDataList->buffer[m_Index].GetAccountId().Get()[0] == '\0' ) + { + ACT_LOG_INFO( "There is not AccountId." ); + return ResultBadFormatResponse(); + } + + if ( ( m_ReceivedDeviceAttribute & NECESSARY_DEVICE_ATTRIBUTES ) != NECESSARY_DEVICE_ATTRIBUTES ) + { + ACT_LOG_INFO( "There is imcomplete DeviceInfo : %u(%u).", m_ReceivedDeviceAttribute, ( m_ReceivedDeviceAttribute & NECESSARY_DEVICE_ATTRIBUTES ) ); + return ResultBadFormatResponse(); + } + + if ( ( m_ReceivedAccountInfo & NECESSARY_ACCOUNT_INFO ) != NECESSARY_ACCOUNT_INFO ) + { + ACT_LOG_INFO( "There is imcomplete AccountInfo : %u(%u).", m_ReceivedAccountInfo, ( m_ReceivedAccountInfo & NECESSARY_ACCOUNT_INFO ) ); + return ResultBadFormatResponse(); + } + + // duplicate unique ID + for( u8 i=0; ibuffer[i].GetAccountId() == m_pSalvagedDataList->buffer[m_Index].GetAccountId() ) + { + ACT_LOG_INFO( "There is duplicated Account ID." ); + return ResultBadFormatResponse(); + } + } + + return ResultSuccess(); +} + +void AcquireSalvageInfoResponseParser::OnEndElement(const Element* pElements, size_t depth) +{ + // break all data if an parse error occurs + if( GetParseResult().IsFailure() || m_Count <= m_Index ) + { + // m_Count <= m_Index 縺縺代〒縺ッ SetParseResult 縺励↑縺シ育炊隲紋ク翫ッ繧オ繝シ繝舌°繧 100 莉カ縺セ縺ァ霑斐&繧後kシ + return; + } + + char* pContents = GetContentBuffer(); + + char buffer[1024]; + ACT_LOG_INFO(">>> %s", GetElementPath(pElements, depth, buffer, 1024)); + ACT_LOG_INFO(" >>> %s", pContents); + + if(CompareElement(pElements[0], "people")) + { + if( depth==2 && CompareElementPath( pElements, depth, "/people/person" )) + { + SetParseResult( ValidateParsedData() ); + + if( GetParseResult().IsSuccess() ) + { + m_ReceivedDeviceAttribute = 0; + m_ReceivedAccountInfo = 0; + m_pSalvagedDataList->buffer[m_Index].SetDefaultMembers(); + ++m_Index; + } + else // broken data + { + m_ReceivedDeviceAttribute = 0; + m_ReceivedAccountInfo = 0; + m_pSalvagedDataList->buffer[m_Index].ClearMembers(); + } + } + + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/user_id" )) + { + m_pSalvagedDataList->buffer[m_Index].SetAccountId( pContents ); + //m_pSalvagedDataList->buffer[m_Index].SetStickyAccountId( pContents ); + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/pid" )) + { + m_pSalvagedDataList->buffer[m_Index].SetPrincipalId( ParseU32( pContents ) ); + //m_ppAccountInstanceNandDataList[m_Index]->SetStickyPrincipalId( ParseU32( pContents ) ); + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/birth_date" )) + { + // yyyy-mm-dd + pContents[4] = '\0'; + pContents[7] = '\0'; + pContents[10] = '\0'; + m_pSalvagedDataList->buffer[m_Index].SetBirthDate( ParseU16(&pContents[0]), ParseU16(&pContents[5]), ParseU16(&pContents[8]) ); + + m_ReceivedAccountInfo |= BIRTH_DATE; + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/gender" )) + { + m_pSalvagedDataList->buffer[m_Index].SetGender(pContents[0] == 'M' ? GENDER_MALE : GENDER_FEMALE); + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/region" )) + { + m_pSalvagedDataList->buffer[m_Index].SetSimpleAddressId( ParseU32( pContents ) ); + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/tz_name" )) + { + m_pSalvagedDataList->buffer[m_Index].SetTimeZoneId( pContents ); + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/utc_offset" )) + { + m_pSalvagedDataList->buffer[m_Index].SetUtcOffset(ParseS32(pContents) * 1000000LL); + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/country" )) + { + u32 country = 0; + Result result = SystemInfoManager::GetSingleton().ConvertCountry( &country, pContents ); + + if(result.IsSuccess()) + { + m_pSalvagedDataList->buffer[m_Index].SetCountry( country ); + m_ReceivedAccountInfo |= COUNTRY; + } + else + { + ACT_LOG_INFO( "Fail to convert country." ); + SetParseResult( ResultBadFormatResponse() ); + } + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/create_date" )) + { + NnasXmlDateContainer created; + created.Set( pContents ); + m_pSalvagedDataList->buffer[m_Index].SetCreatedDate( created ); + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/updated" )) + { + NnasXmlDateContainer updated; + updated.Set( pContents ); + m_pSalvagedDataList->buffer[m_Index].SetLastUpdatedDate( updated ); + } + + else if( depth==5 && CompareElementPath( pElements, depth, "/people/person/mii/mii_images/mii_image" )) + { + if( m_MiiImage.isStandard && !m_MiiImage.url.Equals("") ) + { + m_pSalvagedDataList->buffer[m_Index].SetMiiImageUrl( m_MiiImage.url ); + } + + m_MiiImage.Clear(); + } + else if( depth==6 && CompareElementPath( pElements, depth, "/people/person/mii/mii_images/mii_image/type" )) + { + if( strncmp( pContents, "standard", sizeof("standard") ) == 0 ) + { + m_MiiImage.isStandard = true; + } + } + else if( depth==6 && CompareElementPath( pElements, depth, "/people/person/mii/mii_images/mii_image/url" )) + { + if( strncmp( pContents, "https://", sizeof("https://")-1 ) == 0 ) + { + m_MiiImage.url.Set( pContents ); + } + } + + else if( depth==4 && CompareElementPath( pElements, depth, "/people/person/mii/name" )) + { + char16 miiName[NN_ACT_MII_NAME_SIZE] = {0}; + s32 outSize = NN_ACT_MII_NAME_SIZE; + s32 inSize = NN_ACT_MII_NAME_SIZE * 4; + + Result result = nn::enc::ConvertStringUtf8ToUtf16Native( reinterpret_cast(miiName), &outSize, reinterpret_cast(pContents), &inSize ); + if( result.IsSuccess() ) + { + m_pSalvagedDataList->buffer[m_Index].SetMiiName( miiName ); + } + else + { + ACT_LOG_INFO( "SetParseResult:mii name" ); + SetParseResult( ResultBadFormatResponse() ); + } + } + else if( depth==4 && CompareElementPath( pElements, depth, "/people/person/mii/data" )) + { + const size_t ENCODED_SIZE = NN_MII_STORE_DATA_SIZE * 4 / 3 + 1; + + char encodedData[ENCODED_SIZE] = {0}; + Strlcpy(encodedData, pContents, ENCODED_SIZE); + + nnmiiStoreData storeData; + + size_t num = 0; + nn::util::Base64::FromBase64String(encodedData, &storeData, NN_MII_STORE_DATA_SIZE, &num); + + if (num == NN_MII_STORE_DATA_SIZE) + { + m_pSalvagedDataList->buffer[m_Index].SetMiiData(storeData); + } + else + { + ACT_LOG_INFO( "SetParseResult:mii data" ); + SetParseResult( ResultBadFormatResponse() ); + } + } + else if( depth==4 && CompareElementPath( pElements, depth, "/people/person/email/validated" )) + { + m_EMail.isValidated = pContents[0] == 'Y'; + } + else if( depth==4 && CompareElementPath( pElements, depth, "/people/person/email/type" )) + { + if( strncmp( pContents, "DEFAULT", sizeof("DEFAULT") )==0 ) + { + m_EMail.isDefault = true; + } + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/email" )) + { + if( m_EMail.isDefault ) + { + m_pSalvagedDataList->buffer[m_Index].SetIsMailAddressValidated( m_EMail.isValidated ); + } + + m_EMail.Clear(); + } + + else if( depth==5 && CompareElementPath( pElements, depth, "/people/person/parental_consents/parental_consent/approval_id" )) + { + m_Parent.approvalId = ParseU32( pContents ); + } + else if( depth==5 && CompareElementPath( pElements, depth, "/people/person/parental_consents/parental_consent/scope" )) + { + m_Parent.scope = ParseU16( pContents ); + } + else if( depth==4 && CompareElementPath( pElements, depth, "/people/person/parental_consents/parental_consent" )) + { + if( m_Parent.approvalId )//&& m_Parent.scope==0 ) + { + m_pSalvagedDataList->buffer[m_Index].SetApprovalId( m_Parent.approvalId ); + } + + m_Parent.Clear(); + } + else if( depth==7 && CompareElementPath( pElements, depth, "/people/person/devices/device/device_attributes/device_attribute/name" )) + { + m_Attribute.name.Set( pContents ); + } + else if( depth==7 && CompareElementPath( pElements, depth, "/people/person/devices/device/device_attributes/device_attribute/value" )) + { + m_Attribute.value.Set( pContents ); + } + else if( depth==6 && CompareElementPath( pElements, depth, "/people/person/devices/device/device_attributes/device_attribute" )) + { + if( m_Attribute.name.Equals( "uuid_account" ) ) + { + UuidInternal uuid; + uuid.FromStr( m_Attribute.value.Get() ); + m_pSalvagedDataList->buffer[m_Index].SetUuid( uuid ); + m_ReceivedDeviceAttribute |= ACCOUNT_UUID; + //ACT_LOG_INFO(">>[%d] %s", m_Index, pContents); + } + else if( m_Attribute.name.Equals( "uuid_common" ) ) + { + UuidInternal uuid; + uuid.FromStr( m_Attribute.value.Get() ); + m_pSalvagedDataList->buffer[m_Index].SetCommonUuid( uuid ); + m_ReceivedDeviceAttribute |= COMMON_UUID; + //ACT_LOG_INFO(">>[%d] %s", m_Index, pContents); + } + else if( m_Attribute.name.Equals( "ctr_nex_account" ) ) + { + m_pSalvagedDataList->buffer[m_Index].SetCtrFpAccountId( m_Attribute.value.Get() ); + m_ReceivedDeviceAttribute |= CTR_NEX_ACCOUNT; + //ACT_LOG_INFO(">>[%d] %s", m_Index, pContents); + } + else if( m_Attribute.name.Equals( "ctr_nex_password" ) ) + { + m_pSalvagedDataList->buffer[m_Index].SetFriendsPassword( m_Attribute.value.Get() ); + m_ReceivedDeviceAttribute |= CTR_NEX_PASSWORD; + //ACT_LOG_INFO(">>[%d] %s", m_Index, pContents); + } + else if( m_Attribute.name.Equals( "ctr_nex_environment" ) ) + { + m_pSalvagedDataList->buffer[m_Index].SetFriendsEnv( m_Attribute.value.Get() ); + m_ReceivedDeviceAttribute |= CTR_NEX_ENVIRONMENT; + //ACT_LOG_INFO(">>[%d] %s", m_Index, pContents); + } + else if( m_Attribute.name.Equals( "transferable_id_base" ) ) + { + } + else if( m_Attribute.name.Equals( "transferable_id_base_common" ) ) + { + } + else if( m_Attribute.name.Equals( "persistent_id" ) ) + { + } + + m_Attribute.Clear(); + } + else if( depth==5 && CompareElementPath( pElements, depth, "/people/person/devices/device/device_attributes" )) + { + } + else if( depth==4 && CompareElementPath( pElements, depth, "/people/person/devices/device" )) + { + } + else if( depth==3 && CompareElementPath( pElements, depth, "/people/person/devices" )) + { + } + } + else + { + ResponseParser::OnEndElement(pElements, depth); + } +} + +nn::Result AcquireSalvageInfoResponseParser::Commit() +{ + ACT_LOG_INFO( "Commit" ); + m_pSalvagedDataList->used = m_Index; + return GetParseResult(); +} Index: Horizon/sources/libraries/actslv/net/parser/act_AcquireSalvageInfoResponseParser.h =================================================================== --- Horizon/sources/libraries/actslv/net/parser/act_AcquireSalvageInfoResponseParser.h (revision 0) +++ Horizon/sources/libraries/actslv/net/parser/act_AcquireSalvageInfoResponseParser.h (working copy) @@ -0,0 +1,91 @@ +サソ +#ifndef LIBRARIES_ACTSLV_NET_PARSER_ACT_ACQUIRE_SALVAGE_INFO_RESPONSE_PARSER_H_ +#define LIBRARIES_ACTSLV_NET_PARSER_ACT_ACQUIRE_SALVAGE_INFO_RESPONSE_PARSER_H_ + +#include "act_ResponseParser.h" + +#include "../../act_SalvagedData.h" + +namespace nn { namespace act { namespace detail { + +class AcquireSalvageInfoResponseParser : public ResponseParser +{ + +public: + // 繧ウ繝ウ繧ケ繝医Λ繧ッ繧ソ縺ァ縺吶 + AcquireSalvageInfoResponseParser(WorkBuffer* pSalvagedDataList ); + // 繝繧ケ繝医Λ繧ッ繧ソ縺ァ縺吶 + virtual ~AcquireSalvageInfoResponseParser() {} + + // 隕∫エ縺ョ邨ゆコ繧、繝吶Φ繝医r蜃ヲ逅縺励∪縺吶 + virtual void OnEndElement(const Element* pElements, size_t depth); + + // 繝繝シ繧ソ繧偵さ繝溘ャ繝医@縺セ縺吶 + virtual nn::Result Commit(); + +protected: + +private: + WorkBuffer* m_pSalvagedDataList; + const u32 m_Count; + u32 m_Index; + + Result ValidateParsedData( void ); + + // mii + typedef struct + { + MiiImageUrlContainer url; + bool isStandard; + void Clear() { url.Set(""); isStandard=false; } + } MiiImage; + MiiImage m_MiiImage; + + // email + typedef struct + { + bool isDefault; + bool isValidated; + void Clear() { isDefault=false; isValidated=false; } + } EMail; + EMail m_EMail; + + // parental + typedef struct + { + u8 scope; + u32 approvalId; + void Clear() { scope=0; approvalId=0; } + } ParentalConsent; + ParentalConsent m_Parent; + + // device attribute + typedef struct + { + DeviceAttributeName name; + DeviceAttributeValue value; + void Clear() { name.Set(""); value.Set(""); } + } DeviceAttribute; + DeviceAttribute m_Attribute; + + static const u8 ACCOUNT_UUID = 1 << 0; + static const u8 COMMON_UUID = 1 << 1; + static const u8 CTR_NEX_ACCOUNT = 1 << 2; + static const u8 CTR_NEX_PASSWORD = 1 << 3; + static const u8 CTR_NEX_ENVIRONMENT = 1 << 4; + static const u8 NECESSARY_DEVICE_ATTRIBUTES = ACCOUNT_UUID + | COMMON_UUID; + + u8 m_ReceivedDeviceAttribute; + + static const u32 COUNTRY = 1 << 0; + static const u32 BIRTH_DATE = 1 << 1; + static const u32 NECESSARY_ACCOUNT_INFO = COUNTRY + | BIRTH_DATE; + + u32 m_ReceivedAccountInfo; +}; + +}}} + +#endif // LIBRARIES_ACTSLV_NET_PARSER_ACT_ACQUIRE_SALVAGE_INFO_RESPONSE_PARSER_H_ Index: Horizon/sources/libraries/actslv/OMakefile =================================================================== --- Horizon/sources/libraries/actslv/OMakefile (revision 0) +++ Horizon/sources/libraries/actslv/OMakefile (working copy) @@ -0,0 +1,132 @@ +#!/usr/bin/env omake +#---------------------------------------------------------------------------- +# Project: Horizon +# File: OMakefile +# +# Copyright (C)2009-2013 Nintendo Co., Ltd. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Rev: 50823 $ +#---------------------------------------------------------------------------- +SUPPORTED_TARGETS = CTR-T*.Process.MPCore.* + +PROCESSES_SOURCES[] = + net/act_NnasError.cpp + net/act_RequestUrlBuilder.cpp + net/parser/act_ResponseParser.cpp + net/xml/act_StreamParser.cpp + net/xml/act_StreamBuilder.cpp + save/act_Directory.cpp + save/act_File.cpp + save/act_FileInputStream.cpp + save/act_FileOutputStream.cpp + save/act_FileSystem.cpp + save/act_KeyValueStore.cpp + save/act_KeyValueStoreFileReader.cpp + save/act_KeyValueStoreFileWriter.cpp + util/act_AccountPasswordHash.cpp + util/act_ConvertHostServerSettings.cpp + util/act_SystemInfoManager.cpp + act_ClientInformation.cpp + +PROCESSES_HEADERS[] = + act_ClientInformation.h + act_Common.h + CTR/act_AutoHandle.h + net/act_NnasAccessContext.h + net/act_NnasError.h + net/act_RequestUrlBuilder.h + net/act_ServerTime.h + net/parser/act_ResponseParser.h + net/xml/act_StreamBuilder.h + net/xml/act_StreamParser.h + save/act_Directory.h + save/act_File.h + save/act_FileInputStream.h + save/act_FileOutputStream.h + save/act_FileSystem.h + save/act_KeyValueStore.h + save/act_KeyValueStoreFileReader.h + save/act_KeyValueStoreFileWriter.h + util/act_AccountPasswordHash.h + util/act_ConvertHostServerSettings.h + util/act_InputStream.h + util/act_Macros.h + util/act_Mutex.h + util/act_OutputStream.h + util/act_ScopedLock.h + util/act_StringContainer.h + util/act_SystemInfoManager.h + util/act_WithInitialize.h + +LIBRARIES_SOURCES[] = + act_NnasRequestParameters.cpp + +MODIFIED_SOURCES[] = + net/act_WebApi.cpp + net/act_ServerTime.cpp + save/act_AccountInstanceNandData.cpp + save/act_AccountManagerNandData.cpp + save/act_UuidManagerNandData.cpp + save/act_PersistentIdManagerNandData.cpp + save/act_TransferableIdManagerNandData.cpp + net/act_NnasAccessContext.cpp + +MODIFIED_HEADERS[] = + act_Config.h + net/act_WebApi.h + save/act_AccountInstanceNandData.h + save/act_AccountManagerNandData.h + save/act_UuidManagerNandData.h + save/act_PersistentIdManagerNandData.h + save/act_TransferableIdManagerNandData.h + +EXTRA_SOURCES[] = + act_SalvageManager.cpp + act_SalvagedData.cpp + net/parser/act_AcquireSalvageInfoResponseParser.cpp + CTR/act_ApiSalvage.cpp + +SOURCES[] = + $(PROCESSES_SOURCES) + $(LIBRARIES_SOURCES) + $(MODIFIED_SOURCES) + $(EXTRA_SOURCES) + +TARGET_LIBRARY = libnn_actslv + +CCFLAGS_BUILD += --diag_style gnu +CCFLAGS_MACRO += -DNN_LOG_LEVEL=NN_LOG_LEVEL_DEBUG + +CCFLAGS_WARNING += --diag_suppress 1301,2530 + + +INSTALL_SOURCE_ROOT_PROC = ../../processes/act +INSTALL_SOURCE_ROOT_LIB = ../act +HEADER_FILES_PROC = $(PROCESSES_SOURCES) $(PROCESSES_HEADERS) +HEADER_FILES_LIB = $(LIBRARIES_SOURCES) +INSTALL_ROOT = . + +INSTALL_FILES_PROC = $(InstallFiles $(INSTALL_SOURCE_ROOT_PROC), $(HEADER_FILES_PROC), $(INSTALL_ROOT)) +INSTALL_FILES_LIB = $(InstallFiles $(INSTALL_SOURCE_ROOT_LIB), $(HEADER_FILES_LIB), $(INSTALL_ROOT)) +install-addins: $(INSTALL_FILES_PROC) $(INSTALL_FILES_LIB) + +RequireSetup(install-addins) + +include $(ROOT_OMAKE)/modulerules + +clean: + foreach(FILE, $(PROCESSES_SOURCES) $(PROCESSES_HEADERS) $(LIBRARIES_SOURCES)) + rm -rf $(FILE) + \find . -type d -empty -delete + +build: $(DEFAULT_TARGETS) + +if $(IsTestBuild) + .SUBDIRS: $(exist-dirs tests) + \ No newline at end of file Index: Horizon/sources/libraries/actslv/save/act_AccountInstanceNandData.cpp =================================================================== --- Horizon/sources/libraries/actslv/save/act_AccountInstanceNandData.cpp (revision 0) +++ Horizon/sources/libraries/actslv/save/act_AccountInstanceNandData.cpp (working copy) @@ -0,0 +1,878 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#include + +#include "../act_Common.h" + +#include "act_AccountInstanceNandData.h" + +#include "act_File.h" +#include "act_Directory.h" +#include "act_FileSystem.h" + +#include "../util/act_AccountPasswordHash.h" +#include "../util/act_ConvertHostServerSettings.h" +#include "../util/act_SystemInfoManager.h" + +#include "../util/act_StringContainer.h" + +#define ACT_ACCOUNT_FILE_NAME L"account.dat" + +#define ACT_KEY_VALUE_ENTRY_LOCAL( keyname ) NN_ACT_KEY_VALUE_ENTRY( AccountInstanceNandData, keyname ) + + +namespace nn +{ +namespace act +{ +namespace detail +{ + +const AccountInstanceNandData::KeyValueEntry AccountInstanceNandData::s_EntryList[] = +{ + ACT_KEY_VALUE_ENTRY_LOCAL( PersistentId ), + ACT_KEY_VALUE_ENTRY_LOCAL( TransferableIdBase ), + ACT_KEY_VALUE_ENTRY_LOCAL( Uuid ), + ACT_KEY_VALUE_ENTRY_LOCAL( ParentalControlSlotNo ), + ACT_KEY_VALUE_ENTRY_LOCAL( MiiData ), + ACT_KEY_VALUE_ENTRY_LOCAL( MiiName ), + ACT_KEY_VALUE_ENTRY_LOCAL( IsMiiUpdated ), + ACT_KEY_VALUE_ENTRY_LOCAL( AccountId ), + ACT_KEY_VALUE_ENTRY_LOCAL( BirthYear ), + ACT_KEY_VALUE_ENTRY_LOCAL( BirthMonth ), + ACT_KEY_VALUE_ENTRY_LOCAL( BirthDay ), + ACT_KEY_VALUE_ENTRY_LOCAL( Gender ), + ACT_KEY_VALUE_ENTRY_LOCAL( IsMailAddressValidated ), + ACT_KEY_VALUE_ENTRY_LOCAL( Country ), + ACT_KEY_VALUE_ENTRY_LOCAL( SimpleAddressId ), + ACT_KEY_VALUE_ENTRY_LOCAL( TimeZoneId ), + ACT_KEY_VALUE_ENTRY_LOCAL( UtcOffset ), + ACT_KEY_VALUE_ENTRY_LOCAL( PrincipalId ), + ACT_KEY_VALUE_ENTRY_LOCAL( NfsPassword ), + ACT_KEY_VALUE_ENTRY_LOCAL( EciVirtualAccount ), + ACT_KEY_VALUE_ENTRY_LOCAL( NeedsToDownloadMiiImage ), + ACT_KEY_VALUE_ENTRY_LOCAL( MiiImageUrl ), + + ACT_KEY_VALUE_ENTRY_LOCAL( AccountPasswordHash ), + ACT_KEY_VALUE_ENTRY_LOCAL( IsPasswordCacheEnabled ), + ACT_KEY_VALUE_ENTRY_LOCAL( AccountPasswordCache ), + ACT_KEY_VALUE_ENTRY_LOCAL( NnasType ), + ACT_KEY_VALUE_ENTRY_LOCAL( NfsType ), + ACT_KEY_VALUE_ENTRY_LOCAL( NfsNo ), + + ACT_KEY_VALUE_ENTRY_LOCAL( NnasSubDomain ), + ACT_KEY_VALUE_ENTRY_LOCAL( NnasNfsEnv ), + + ACT_KEY_VALUE_ENTRY_LOCAL( UploadedAccountInfoVersion ), + + ACT_KEY_VALUE_ENTRY_LOCAL( FpLocalAccountId ), + + ACT_KEY_VALUE_ENTRY_LOCAL( LastAuthenticationResult ), + ACT_KEY_VALUE_ENTRY_LOCAL( AssignedAccountId ), + ACT_KEY_VALUE_ENTRY_LOCAL( AssignedPrincipalId ), + ACT_KEY_VALUE_ENTRY_LOCAL( IsServerAccountDeleted ), + + ACT_KEY_VALUE_ENTRY_LOCAL( MiiImageLastModifiedDate ), + + ACT_KEY_VALUE_ENTRY_LOCAL( IsCommitted ) +}; + +AccountInstanceNandData::AccountInstanceNandData( void ) +: m_IsAssignedPrincipalIdSet( false ), + m_IsNewEntryAdded( false ) +{ + memset( &m_Members, 0, sizeof(m_Members) ); + + ConvertHostServerSettings::ToEnum( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN, ConvertHostServerSettings::INVALID_NNAS_NFS_ENV, + &m_Members.m_NnasType, &m_Members.m_NfsType, &m_Members.m_NfsNo ); + + // because "" is also valid value at production environment + m_Members.m_NnasSubDomain.Set( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN ); +} + +void AccountInstanceNandData::Set( const AccountInstanceNandData& accountInstanceNandData ) +{ + memcpy( &m_Members, &accountInstanceNandData.m_Members, sizeof(m_Members) ); + m_IsAssignedPrincipalIdSet = accountInstanceNandData.m_IsAssignedPrincipalIdSet; + m_IsNewEntryAdded = accountInstanceNandData.m_IsNewEntryAdded; +} + +bool AccountInstanceNandData::IsEqual( const AccountInstanceNandData& accountInstanceNandData ) const +{ + return memcmp( &m_Members, &accountInstanceNandData.m_Members, sizeof(m_Members) ) == 0; +} + +const char* AccountInstanceNandData::GetTypeName( void ) const +{ + return "AccountInstance"; +} + +u32 AccountInstanceNandData::GetVersion( void ) const +{ + return NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION; +} + +s32 AccountInstanceNandData::GetEntryNum( void ) const +{ + return NN_ACT_NELEMS( s_EntryList ); +} + +const char* AccountInstanceNandData::GetKey( s32 index ) const +{ + return s_EntryList[index].pKey; +} + +void AccountInstanceNandData::SetValue( s32 index, const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + (this->*(s_EntryList[index].Set))( pStr, version ); +} + +void AccountInstanceNandData::GetValue( s32 index, char* pStr, size_t size ) const +{ + (this->*(s_EntryList[index].Get))( pStr, size ); +} + +void AccountInstanceNandData::SetPersistentId( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_PersistentId = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetTransferableIdBase( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_TransferableIdBase = ConvertStrToU64( pStr ); +} + +void AccountInstanceNandData::SetUuid( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + u8 uuidData[ACT_UUID_SIZE]; + DecodeU8Array( reinterpret_cast(uuidData), pStr, m_Members.m_Uuid.GetSize() ); + m_Members.m_Uuid.Set( uuidData ); +} + +void AccountInstanceNandData::SetParentalControlSlotNo( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_ParentalControlSlotNo = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetMiiData( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + DecodeU8Array( reinterpret_cast(&m_Members.m_MiiData), pStr, sizeof(m_Members.m_MiiData) ); +} + +void AccountInstanceNandData::SetMiiName( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + char16 miiName[NN_ACT_MII_NAME_SIZE]; + DecodeU16Array( reinterpret_cast(miiName), pStr, NN_ACT_MII_NAME_SIZE ); + m_Members.m_MiiName.Set( miiName ); +} + +void AccountInstanceNandData::SetIsMiiUpdated( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_IsMiiUpdated = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetAccountId( const char* pStr, u32 version ) +{ + m_Members.m_AccountId.Set( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? pStr : "" ); +} + +void AccountInstanceNandData::SetBirthYear( const char* pStr, u32 version ) +{ + m_Members.m_BirthYear = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : 0; +} + +void AccountInstanceNandData::SetBirthMonth( const char* pStr, u32 version ) +{ + m_Members.m_BirthMonth = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : 0; +} + +void AccountInstanceNandData::SetBirthDay( const char* pStr, u32 version ) +{ + m_Members.m_BirthDay = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : 0; +} + +void AccountInstanceNandData::SetGender( const char* pStr, u32 version ) +{ + m_Members.m_Gender = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : GENDER_UNKNOWN; +} + +void AccountInstanceNandData::SetIsMailAddressValidated( const char* pStr, u32 version ) +{ + m_Members.m_IsMailAddressValidated = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : false; +} + +void AccountInstanceNandData::SetCountry( const char* pStr, u32 version ) +{ + m_Members.m_Country = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : 0; +} + +void AccountInstanceNandData::SetSimpleAddressId( const char* pStr, u32 version ) +{ + m_Members.m_SimpleAddressId = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : 0; +} + +void AccountInstanceNandData::SetTimeZoneId( const char* pStr, u32 version ) +{ + m_Members.m_TimeZoneId.Set( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? pStr : "" ); +} + +void AccountInstanceNandData::SetUtcOffset( const char* pStr, u32 version ) +{ + m_Members.m_UtcOffset = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : 0LL; +} + +void AccountInstanceNandData::SetPrincipalId( const char* pStr, u32 version ) +{ + m_Members.m_PrincipalId = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : NN_ACT_INVALID_PRINCIPAL_ID; +} + +void AccountInstanceNandData::SetNfsPassword( const char* pStr, u32 version ) +{ + m_Members.m_NfsPassword.Set( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? pStr : "" ); +} + +void AccountInstanceNandData::SetEciVirtualAccount( const char* pStr, u32 version ) +{ + m_Members.m_EciVirtualAccount.Set( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? pStr : "" ); +} + +void AccountInstanceNandData::SetNeedsToDownloadMiiImage( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_NeedsToDownloadMiiImage = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetMiiImageUrl( const char* pStr, u32 version ) +{ + m_Members.m_MiiImageUrl.Set( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? pStr : "" ); +} + +void AccountInstanceNandData::SetAccountPasswordHash( const char* pStr, u32 version ) +{ + if ( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ) + { + u8 accountPasswordHash[AccountPasswordHashBase::HASHED_DATA_SIZE]; + DecodeU8Array( accountPasswordHash, pStr, AccountPasswordHashBase::HASHED_DATA_SIZE ); + m_Members.m_AccountPasswordHash.Set( accountPasswordHash ); + } + else + { + m_Members.m_AccountPasswordHash.Clear(); + } +} + +void AccountInstanceNandData::SetIsPasswordCacheEnabled( const char* pStr, u32 version ) +{ + m_Members.m_IsPasswordCacheEnabled = version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? static_cast(ConvertStrToU64( pStr )) : false; +} + +void AccountInstanceNandData::SetAccountPasswordCache( const char* pStr, u32 version ) +{ + if ( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ) + { + u8 accountPasswordCache[AccountPasswordHashBase::HASHED_DATA_SIZE]; + DecodeU8Array( accountPasswordCache, pStr, AccountPasswordHashBase::HASHED_DATA_SIZE ); + m_Members.m_AccountPasswordCache.Set( accountPasswordCache ); + } + else + { + m_Members.m_AccountPasswordCache.Clear(); + } +} + +void AccountInstanceNandData::SetNnasType( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_NnasType = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetNfsType( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_NfsType = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetNfsNo( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_NfsNo = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetNnasSubDomain( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_NnasSubDomain.Set( pStr ); +} + +void AccountInstanceNandData::SetNnasNfsEnv( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_NnasNfsEnv.Set( pStr ); +} + +void AccountInstanceNandData::SetUploadedAccountInfoVersion( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_UploadedAccountInfoVersion = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetFpLocalAccountId( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_FpLocalAccountId = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetLastAuthenticationResult( const char* pStr, u32 version ) +{ + if ( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ) + { + nnResult nnresult; + nnresult.value = static_cast(ConvertStrToU64( pStr )); + m_Members.m_LastAuthenticationResult = nnresult; + } + else + { + m_Members.m_LastAuthenticationResult = ResultNotNetworkAccount(); + } +} + +void AccountInstanceNandData::SetAssignedAccountId( const char* pStr, u32 version ) +{ + m_Members.m_AssignedAccountId.Set( version >= NN_ACT_ACCOUNT_INSTANCE_NAND_DATA_VERSION_CURRENT_SERVER ? pStr : "" ); +} + +void AccountInstanceNandData::SetAssignedPrincipalId( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_AssignedPrincipalId = static_cast(ConvertStrToU64( pStr )); + m_IsAssignedPrincipalIdSet = true; +} + +void AccountInstanceNandData::SetIsServerAccountDeleted( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_IsServerAccountDeleted = static_cast(ConvertStrToU64( pStr )); +} + +void AccountInstanceNandData::SetMiiImageLastModifiedDate( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_MiiImageLastModifiedDate.Set( pStr ); +} + +void AccountInstanceNandData::SetIsCommitted( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_IsCommitted = static_cast(ConvertStrToU64( pStr )); +} + + +void AccountInstanceNandData::GetPersistentId( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_PersistentId ); +} + +void AccountInstanceNandData::GetTransferableIdBase( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_TransferableIdBase ); +} + +void AccountInstanceNandData::GetUuid( char* pStr, size_t size ) const +{ + NN_UNUSED_VAR(size); + EncodeU8Array( pStr, m_Members.m_Uuid.GetACTUuid().data, m_Members.m_Uuid.GetSize() ); +} + +void AccountInstanceNandData::GetParentalControlSlotNo( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_ParentalControlSlotNo ); +} + +void AccountInstanceNandData::GetMiiData( char* pStr, size_t size ) const +{ + NN_UNUSED_VAR(size); + EncodeU8Array( pStr, reinterpret_cast(&m_Members.m_MiiData), sizeof(m_Members.m_MiiData) ); +} + +void AccountInstanceNandData::GetMiiName( char* pStr, size_t size ) const +{ + NN_UNUSED_VAR(size); + EncodeU16Array( pStr, reinterpret_cast(m_Members.m_MiiName.Get()), m_Members.m_MiiName.GetMaxLength() + 1 ); +} + +void AccountInstanceNandData::GetIsMiiUpdated( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_IsMiiUpdated ); +} + +void AccountInstanceNandData::GetAccountId( char* pStr, size_t size ) const +{ + m_Members.m_AccountId.Get( pStr, size ); +} + +void AccountInstanceNandData::GetBirthYear( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_BirthYear ); +} + +void AccountInstanceNandData::GetBirthMonth( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_BirthMonth ); +} + +void AccountInstanceNandData::GetBirthDay( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_BirthDay ); +} + +void AccountInstanceNandData::GetGender( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_Gender ); +} + +void AccountInstanceNandData::GetIsMailAddressValidated( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_IsMailAddressValidated ); +} + +void AccountInstanceNandData::GetCountry( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_Country ); +} + +void AccountInstanceNandData::GetSimpleAddressId( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_SimpleAddressId ); +} + +void AccountInstanceNandData::GetTimeZoneId( char* pStr, size_t size ) const +{ + m_Members.m_TimeZoneId.Get( pStr, size ); +} + +void AccountInstanceNandData::GetUtcOffset( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, static_cast(m_Members.m_UtcOffset) ); +} + +void AccountInstanceNandData::GetPrincipalId( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_PrincipalId ); +} + +void AccountInstanceNandData::GetNfsPassword( char* pStr, size_t size ) const +{ + m_Members.m_NfsPassword.Get( pStr, size ); +} + +void AccountInstanceNandData::GetEciVirtualAccount( char* pStr, size_t size ) const +{ + m_Members.m_EciVirtualAccount.Get( pStr, size ); +} + +void AccountInstanceNandData::GetNeedsToDownloadMiiImage( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_NeedsToDownloadMiiImage ); +} + +void AccountInstanceNandData::GetMiiImageUrl( char* pStr, size_t size ) const +{ + m_Members.m_MiiImageUrl.Get( pStr, size ); +} + +void AccountInstanceNandData::GetAccountPasswordHash( char* pStr, size_t size ) const +{ + NN_UNUSED_VAR(size); + EncodeU8Array( pStr, m_Members.m_AccountPasswordHash.Get(), AccountPasswordHashBase::HASHED_DATA_SIZE ); +} + +void AccountInstanceNandData::GetIsPasswordCacheEnabled( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_IsPasswordCacheEnabled ); +} + +void AccountInstanceNandData::GetAccountPasswordCache( char* pStr, size_t size ) const +{ + NN_UNUSED_VAR(size); + EncodeU8Array( pStr, m_Members.m_AccountPasswordCache.Get(), AccountPasswordHashBase::HASHED_DATA_SIZE ); +} + +void AccountInstanceNandData::GetNnasType( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_NnasType ); +} + +void AccountInstanceNandData::GetNfsType( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_NfsType ); +} + +void AccountInstanceNandData::GetNfsNo( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_NfsNo ); +} + + +void AccountInstanceNandData::GetNnasSubDomain( char* pStr, size_t size ) const +{ + m_Members.m_NnasSubDomain.Get( pStr, size ); +} + +void AccountInstanceNandData::GetNnasNfsEnv( char* pStr, size_t size ) const +{ + m_Members.m_NnasNfsEnv.Get( pStr, size ); +} + +void AccountInstanceNandData::GetUploadedAccountInfoVersion( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_UploadedAccountInfoVersion ); +} + +void AccountInstanceNandData::GetFpLocalAccountId( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_FpLocalAccountId ); +} + +void AccountInstanceNandData::GetLastAuthenticationResult( char* pStr, size_t size ) const +{ + nnResult nnresult = m_Members.m_LastAuthenticationResult; + + ConvertU64ToStr( pStr, size, nnresult.value ); +} + +void AccountInstanceNandData::GetAssignedAccountId( char* pStr, size_t size ) const +{ + m_Members.m_AssignedAccountId.Get( pStr, size ); +} + +void AccountInstanceNandData::GetAssignedPrincipalId( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_AssignedPrincipalId ); +} + +void AccountInstanceNandData::GetIsServerAccountDeleted( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_IsServerAccountDeleted ); +} + +void AccountInstanceNandData::GetMiiImageLastModifiedDate( char* pStr, size_t size ) const +{ + m_Members.m_MiiImageLastModifiedDate.Get( pStr, size ); +} + +void AccountInstanceNandData::GetIsCommitted( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_IsCommitted ); +} + + +void AccountInstanceNandData::ResolveDirectoryPath( char16* pPath, u32 persistentId ) +{ + int length = nn::nstd::TSNPrintf( pPath, FILE_PATH_SIZE_MAX, NN_ACT_NAND_QUOTA_PATH L"/%08x", persistentId ); + + NN_UNUSED_VAR( length ); + NN_ACT_ASSERT( length >= 0 && static_cast(length) < FILE_PATH_SIZE_MAX ); +} + +void AccountInstanceNandData::ResolveFilePath( char16* pPath, u32 persistentId, const char16* pFileName ) +{ + int length = nn::nstd::TSNPrintf( pPath, FILE_PATH_SIZE_MAX, NN_ACT_NAND_QUOTA_PATH L"/%08x/%ls", persistentId, pFileName ); + + NN_UNUSED_VAR( length ); + NN_ACT_ASSERT( length >= 0 && static_cast(length) < FILE_PATH_SIZE_MAX ); +} + +void AccountInstanceNandData::ResolveMiiImageFilePath( char16* pPath, u32 persistentId, MiiImageType imageType, bool isTemporary ) +{ + NN_ACT_ASSERT( imageType >= 0 && imageType < MII_IMAGE_TYPE_NUM ); + + char16 fileName[32]; + ResolveMiiImageFileName( fileName, imageType, isTemporary ); + + ResolveFilePath( pPath, persistentId, fileName ); +} + +void AccountInstanceNandData::ResolveMiiImageFileName( char16* pName, MiiImageType imageType, bool isTemporary ) +{ + NN_ACT_ASSERT( imageType >= 0 && imageType < MII_IMAGE_TYPE_NUM ); + + int length = nn::nstd::TSNPrintf( pName, 32, L"miiimg%02u.dat%s", imageType, isTemporary ? ".tmp" : "" ); + + NN_UNUSED_VAR( length ); + NN_ACT_ASSERT( length >= 0 && static_cast(length) < 32 ); +} + +Result AccountInstanceNandData::Save( void ) const +{ + ACT_LOG_INFO( "%s(%08x)", __FUNCTION__, m_Members.m_PersistentId ); + + char16 path[FILE_PATH_SIZE_MAX]; + + ResolveFilePath( path, m_Members.m_PersistentId, L"" ); + Result result = FileSystem::GetSingleton().EnsureDirectory( path ); + + if ( result.IsSuccess() ) + { + ResolveFilePath( path, m_Members.m_PersistentId, ACT_ACCOUNT_FILE_NAME ); + result = KeyValueStore::Save( path ); + } + + return result; +} + +Result AccountInstanceNandData::Load( u32 persistentId ) +{ + ACT_LOG_INFO( "%s(%08x)", __FUNCTION__, persistentId ); + + char16 path[FILE_PATH_SIZE_MAX]; + + ResolveFilePath( path, persistentId, ACT_ACCOUNT_FILE_NAME ); + + return KeyValueStore::Load( path ); +} + +Result AccountInstanceNandData::Remove( u32 persistentId ) +{ + ACT_LOG_INFO( "%s(%08x)", __FUNCTION__, persistentId ); + + char16 path[FILE_PATH_SIZE_MAX]; + + ResolveFilePath( path, persistentId, L"" ); + Result result = FileSystem::GetSingleton().RemoveDirectoryRecursively( path ); + + return result; +} + +Result AccountInstanceNandData::ReadMiiImageFile( + u32 persistentId, + MiiImageType imageType, + size_t* pOut, + u8* pImageBuffer, + size_t size +) +{ + NN_ACT_ASSERT( pOut ); + + char16 filePath[FILE_PATH_SIZE_MAX]; + size_t fileSize; + + ResolveMiiImageFilePath( filePath, persistentId, imageType, false ); + + *pOut = 0; + + Result result = FileSystem::GetSingleton().GetFileSize( &fileSize, filePath ); + + if ( result.IsSuccess() ) + { + if ( fileSize <= size ) + { + File file; + + result = file.Open( filePath, "r" ); + + if ( result.IsSuccess() ) + { + result = file.Read(pOut, pImageBuffer, fileSize); + + file.Close(); + } + } + else + { + result = ResultInvalidSize(); + } + } + + if ( result.IsFailure() ) + { + *pOut = 0; + } + + return result; +} + +Result AccountInstanceNandData::WriteTempMiiImageFile( + u32 persistentId, + MiiImageType imageType, + const u8* pImageBuffer, + size_t size +) +{ + char16 tempFilePath[FILE_PATH_SIZE_MAX]; + + ResolveMiiImageFilePath( tempFilePath, persistentId, imageType, true ); + + File file; + + Result result = file.Open( tempFilePath, "w" ); + + if ( result.IsSuccess() ) + { + size_t out; + result = file.WriteDirectly( &out, pImageBuffer, size ); + + if ( result.IsSuccess() && out < size ) + { + result = ResultFileIoError(); + } + + file.Close(); + } + + return result; +} + +Result AccountInstanceNandData::WriteMiiImageFile( + u32 persistentId, + MiiImageType imageType, + const void* pImage, + size_t size +) +{ + char16 tempFilePath[FILE_PATH_SIZE_MAX]; + + ResolveMiiImageFilePath( tempFilePath, persistentId, imageType, false ); + + File file; + + Result result = file.Open( tempFilePath, "w" ); + + if ( result.IsSuccess() ) + { + size_t out; + result = file.WriteDirectly( &out, pImage, size ); + + if ( result.IsSuccess() && out < size ) + { + result = ResultFileIoError(); + } + + file.Close(); + } + + return result; +} + +Result AccountInstanceNandData::CommitMiiImageFiles( u32 persistentId ) +{ + Result result; + + if ( !IsRequiredToCommit( persistentId ) ) + { + return ResultSuccess(); + } + + for ( int i = 0; i < MII_IMAGE_TYPE_NUM; ++i ) + { + MiiImageType imageType = static_cast(i); + + char16 tempFilePath[FILE_PATH_SIZE_MAX]; + char16 filePath[FILE_PATH_SIZE_MAX]; + + ResolveMiiImageFilePath( tempFilePath, persistentId, imageType, true ); + ResolveMiiImageFilePath( filePath, persistentId, imageType, false ); + + result = FileSystem::GetSingleton().RemoveFile( filePath ); + if ( result.IsSuccess() || ResultFileNotFound().Includes( result ) ) + { + result = FileSystem::GetSingleton().RenameFile( tempFilePath, filePath ); + } + } + + return result; +} + +bool AccountInstanceNandData::IsRequiredToCommit( u32 persistentId ) +{ + const size_t tmpFileLen = 16; + char16 tmpFileNameBase[] = L"miiimg00.dat.tmp"; + int tmpFileCount = 0; + + char16 directoryPath[FILE_PATH_SIZE_MAX]; + ResolveDirectoryPath( directoryPath, persistentId ); + Directory directory; + Result result = directory.Open( directoryPath ); + if ( result.IsSuccess() ) + { + while ( directory.GoNext() ) + { + if ( directory.GetEntry().IsDirectory() ) + { + continue; + } + + const char16* pName = directory.GetEntry().GetName(); + char16 name[tmpFileLen + 1]; + if ( Strlcpy( name, pName, tmpFileLen + 1 ) != tmpFileLen ) + { + continue; + } + + name[6] = L'0'; + name[7] = L'0'; + if ( std::wcsncmp( name, tmpFileNameBase, tmpFileLen ) == 0 ) + { + tmpFileCount++; + } + } + + directory.Close(); + } + + return tmpFileCount == MII_IMAGE_TYPE_NUM; +} + +size_t AccountInstanceNandData::GetPersistentIdList( u32* pPersistentIdList, size_t size ) +{ + size_t num = 0; + + Directory directory; + Result result = directory.Open( NN_ACT_NAND_QUOTA_PATH ); + + if ( result.IsSuccess() ) + { + while ( directory.GoNext() && num < size ) + { + if ( directory.GetEntry().IsDirectory() ) + { + const char16* pName = directory.GetEntry().GetName(); + char16* pEndPtr; + + u32 persistentId = std::wcstoul( pName, &pEndPtr, 16 ); + + if ( pEndPtr - pName == 8 && *pEndPtr == L'\0' ) + { + ACT_LOG_DEBUG( "found account instance directory: %ls", pName ); + pPersistentIdList[num++] = persistentId; + } + } + } + + directory.Close(); + } + + return num; +} + + +} +} +} Index: Horizon/sources/libraries/actslv/save/act_AccountInstanceNandData.h =================================================================== --- Horizon/sources/libraries/actslv/save/act_AccountInstanceNandData.h (revision 0) +++ Horizon/sources/libraries/actslv/save/act_AccountInstanceNandData.h (working copy) @@ -0,0 +1,290 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_SAVE_ACT_ACCOUNT_INSTANCE_NAND_DATA_H_ +#define LIBRARIES_ACTSLV_SAVE_ACT_ACCOUNT_INSTANCE_NAND_DATA_H_ + +#include "../act_Common.h" + +#include "act_KeyValueStore.h" +#include "../act_Uuid.h" + +#include "../util/act_AccountPasswordHash.h" +#include "../util/act_StringContainer.h" + +namespace nn +{ +namespace act +{ +namespace detail +{ + +class AccountInstanceNandData : public KeyValueStore +{ +public: + static const size_t FILE_PATH_SIZE_MAX = 256; + +private: + typedef void (AccountInstanceNandData::*SetFunc)( const char* pStr, u32 version ); + typedef void (AccountInstanceNandData::*GetFunc)( char* pStr, size_t size ) const; + + typedef struct KeyValueEntry + { + const char* pKey; + SetFunc Set; + GetFunc Get; + } KeyValueEntry; + + static const KeyValueEntry s_EntryList[]; + + typedef struct Members + { + u32 m_PersistentId; + u64 m_TransferableIdBase; + UuidInternal m_Uuid; + u8 m_ParentalControlSlotNo; + + nn::mii::StoreData m_MiiData; + MiiNameContainer m_MiiName; + bool m_IsMiiUpdated; + + AccountIdContainer m_AccountId; + u16 m_BirthYear; + u8 m_BirthMonth; + u8 m_BirthDay; + Gender m_Gender; + bool m_IsMailAddressValidated; + u32 m_Country; + u32 m_SimpleAddressId; + TimeZoneIdContainer m_TimeZoneId; + s64 m_UtcOffset; + u32 m_PrincipalId; + NfsPasswordContainer m_NfsPassword; + EciVirtualAccountContainer m_EciVirtualAccount; + bool m_NeedsToDownloadMiiImage; + MiiImageUrlContainer m_MiiImageUrl; + + AccountPasswordSecondHash m_AccountPasswordHash; + bool m_IsPasswordCacheEnabled; + AccountPasswordFirstHash m_AccountPasswordCache; + NnasType m_NnasType; + NfsType m_NfsType; + u8 m_NfsNo; + + NnasSubDomainContainer m_NnasSubDomain; + NnasNfsEnvContainer m_NnasNfsEnv; + + u32 m_UploadedAccountInfoVersion; + + u8 m_FpLocalAccountId; + + Result m_LastAuthenticationResult; + AccountIdContainer m_AssignedAccountId; + u32 m_AssignedPrincipalId; + bool m_IsServerAccountDeleted; + + Rfc1123DateContainer m_MiiImageLastModifiedDate; + + bool m_IsCommitted; + + u32 m_MiiDataUpdateCounter; // not to be saved + } Members; + +private: + Members m_Members; + + bool m_IsAssignedPrincipalIdSet; + bool m_IsNewEntryAdded; + +private: + void SetDefaultValueForNewEntry( void ); + +private: + void SetPersistentId( const char* pStr, u32 version ); + void SetTransferableIdBase( const char* pStr, u32 version ); + void SetUuid( const char* pStr, u32 version ); + void SetParentalControlSlotNo( const char* pStr, u32 version ); + void SetMiiData( const char* pStr, u32 version ); + void SetMiiName( const char* pStr, u32 version ); + void SetIsMiiUpdated( const char* pStr, u32 version ); + void SetAccountId( const char* pStr, u32 version ); + void SetBirthYear( const char* pStr, u32 version ); + void SetBirthMonth( const char* pStr, u32 version ); + void SetBirthDay( const char* pStr, u32 version ); + void SetGender( const char* pStr, u32 version ); + void SetIsMailAddressValidated( const char* pStr, u32 version ); + void SetCountry( const char* pStr, u32 version ); + void SetSimpleAddressId( const char* pStr, u32 version ); + void SetTimeZoneId( const char* pStr, u32 version ); + void SetUtcOffset( const char* pStr, u32 version ); + void SetPrincipalId( const char* pStr, u32 version ); + void SetNfsPassword( const char* pStr, u32 version ); + void SetEciVirtualAccount( const char* pStr, u32 version ); + void SetNeedsToDownloadMiiImage( const char* pStr, u32 version ); + void SetMiiImageUrl( const char* pStr, u32 version ); + void SetAccountPasswordHash( const char* pStr, u32 version ); + void SetIsPasswordCacheEnabled( const char* pStr, u32 version ); + void SetAccountPasswordCache( const char* pStr, u32 version ); + void SetNnasType( const char* pStr, u32 version ); + void SetNfsType( const char* pStr, u32 version ); + void SetNfsNo( const char* pStr, u32 version ); + void SetNnasSubDomain( const char* pStr, u32 version ); + void SetNnasNfsEnv( const char* pStr, u32 version ); + void SetUploadedAccountInfoVersion( const char* pStr, u32 version ); + void SetFpLocalAccountId( const char* pStr, u32 version ); + void SetLastAuthenticationResult( const char* pStr, u32 version ); + void SetAssignedAccountId( const char* pStr, u32 version ); + void SetAssignedPrincipalId( const char* pStr, u32 version ); + void SetIsServerAccountDeleted( const char* pStr, u32 version ); + void SetMiiImageLastModifiedDate( const char* pStr, u32 version ); + void SetIsCommitted( const char* pStr, u32 version ); + + void GetPersistentId( char* pStr, size_t size ) const; + void GetTransferableIdBase( char* pStr, size_t size ) const; + void GetUuid( char* pStr, size_t size ) const; + void GetParentalControlSlotNo( char* pStr, size_t size ) const; + void GetMiiData( char* pStr, size_t size ) const; + void GetMiiName( char* pStr, size_t size ) const; + void GetIsMiiUpdated( char* pStr, size_t size ) const; + void GetAccountId( char* pStr, size_t size ) const; + void GetBirthYear( char* pStr, size_t size ) const; + void GetBirthMonth( char* pStr, size_t size ) const; + void GetBirthDay( char* pStr, size_t size ) const; + void GetGender( char* pStr, size_t size ) const; + void GetIsMailAddressValidated( char* pStr, size_t size ) const; + void GetCountry( char* pStr, size_t size ) const; + void GetSimpleAddressId( char* pStr, size_t size ) const; + void GetTimeZoneId( char* pStr, size_t size ) const; + void GetUtcOffset( char* pStr, size_t size ) const; + void GetPrincipalId( char* pStr, size_t size ) const; + void GetNfsPassword( char* pStr, size_t size ) const; + void GetEciVirtualAccount( char* pStr, size_t size ) const; + void GetNeedsToDownloadMiiImage( char* pStr, size_t size ) const; + void GetMiiImageUrl( char* pStr, size_t size ) const; + void GetAccountPasswordHash( char* pStr, size_t size ) const; + void GetIsPasswordCacheEnabled( char* pStr, size_t size ) const; + void GetAccountPasswordCache( char* pStr, size_t size ) const; + void GetNnasType( char* pStr, size_t size ) const; + void GetNfsType( char* pStr, size_t size ) const; + void GetNfsNo( char* pStr, size_t size ) const; + void GetNnasSubDomain( char* pStr, size_t size ) const; + void GetNnasNfsEnv( char* pStr, size_t size ) const; + void GetUploadedAccountInfoVersion( char* pStr, size_t size ) const; + void GetFpLocalAccountId( char* pStr, size_t size ) const; + void GetLastAuthenticationResult( char* pStr, size_t size ) const; + void GetAssignedAccountId( char* pStr, size_t size ) const; + void GetAssignedPrincipalId( char* pStr, size_t size ) const; + void GetIsServerAccountDeleted( char* pStr, size_t size ) const; + void GetMiiImageLastModifiedDate( char* pStr, size_t size ) const; + void GetIsCommitted( char* pStr, size_t size ) const; + + static bool IsRequiredToCommit( u32 persistentId ); + +protected: + virtual const char* GetTypeName( void ) const; + virtual u32 GetVersion( void ) const; + virtual s32 GetEntryNum( void ) const; + virtual const char* GetKey( s32 index ) const; + virtual void SetValue( s32 index, const char* pStr, u32 version ); + virtual void GetValue( s32 index, char* pStr, size_t size ) const; + +public: + static void ResolveDirectoryPath( char16* pPath, u32 persistentId ); + static void ResolveFilePath( char16* pPath, u32 persistentId, const char16* pFileName ); + static void ResolveMiiImageFilePath( char16* pPath, u32 persistentId, MiiImageType imageType, bool isTemporary ); + static void ResolveMiiImageFileName( char16* pName, MiiImageType imageType, bool isTemporary ); + +public: + void SetAccountId( const char* pAccountId ) { m_Members.m_AccountId.Set( pAccountId ); } + void SetPrincipalId( u32 principalId ) { m_Members.m_PrincipalId = principalId; } + void SetBirthDate( u16 birthYear, u8 birthMonth, u8 birthDay ) { m_Members.m_BirthYear = birthYear; m_Members.m_BirthMonth = birthMonth; m_Members.m_BirthDay = birthDay; } + void SetCountry( u32 country ) { m_Members.m_Country = country; } + void SetGender( Gender gender ) { m_Members.m_Gender = gender; } + void SetSimpleAddressId( u32 simpleAddressId ) { m_Members.m_SimpleAddressId = simpleAddressId; } + void SetTimeZoneId( const char* timeZoneId ) { m_Members.m_TimeZoneId.Set( timeZoneId ); } + void SetUtcOffset( s64 utcOffset ) { m_Members.m_UtcOffset = utcOffset; } + void SetIsMailAddressValidated( bool isMailAddressValidated ) { m_Members.m_IsMailAddressValidated = isMailAddressValidated; } + void SetMiiData( const nn::mii::StoreData& miiData ) { memcpy( &m_Members.m_MiiData, &miiData, sizeof(miiData) ); } + void SetMiiName( const char16* miiName ) { m_Members.m_MiiName.Set( miiName ); } + void SetMiiImageUrl( const MiiImageUrlContainer& miiImageUrl ) { m_Members.m_MiiImageUrl.Set( miiImageUrl ); } + void SetUuid( const UuidInternal& uuid ) { m_Members.m_Uuid.Set( uuid ); } + void SetPersistentId( u32 persistentId ) { m_Members.m_PersistentId = persistentId; } + void SetTransferableIdBase( u64 transferableIdBase ) { m_Members.m_TransferableIdBase = transferableIdBase; } + void SetLastAuthenticationResult( const Result& result ) { m_Members.m_LastAuthenticationResult = result; } + void SetIsCommitted( bool isCommitted ) { m_Members.m_IsCommitted = isCommitted; } + void SetParentalControlSlotNo( u8 slotNo ) { m_Members.m_ParentalControlSlotNo = slotNo; } + void SetNnasSubDomain( const NnasSubDomainContainer& subDomain ) { m_Members.m_NnasSubDomain.Set( subDomain ); } + void SetNnasNfsEnv( const NnasNfsEnvContainer& nnasNfsEnv ) { m_Members.m_NnasNfsEnv.Set( nnasNfsEnv ); } + void SetNnasType( NnasType nnasType ) { m_Members.m_NnasType = nnasType; } + void SetNfsType( NfsType nfsType ) { m_Members.m_NfsType = nfsType; } + void SetNfsNo( u8 nfsNo ) { m_Members.m_NfsNo = nfsNo; } + void SetFpLocalAccountId( u8 fpLocalAccountId ) { m_Members.m_FpLocalAccountId = fpLocalAccountId; } + + u32 GetPersistentId( void ) const { return m_Members.m_PersistentId; } + const UuidInternal& GetUuid( void ) const { return m_Members.m_Uuid; } + MiiImageUrlContainer& GetMiiImageUrl( void ) { return m_Members.m_MiiImageUrl; } + u16 GetBirthYear( void ) const { return m_Members.m_BirthYear; } + u8 GetBirthMonth( void ) const { return m_Members.m_BirthMonth; } + u8 GetBirthDay( void ) const { return m_Members.m_BirthDay; } + u32 GetCountry( void ) const { return m_Members.m_Country; } + +public: + AccountInstanceNandData( void ); + virtual ~AccountInstanceNandData( void ) {}; + + void Set( const AccountInstanceNandData& accountInstanceNandData ); + bool IsEqual( const AccountInstanceNandData& accountInstanceNandData ) const; + + Result Save( void ) const; + Result Load( u32 persistentId ); + + inline u32 GetMiiDataUpdateCounter( void ) const + { + return m_Members.m_MiiDataUpdateCounter; + } + + inline bool IsNewEntryAdded( void ) const { return m_IsNewEntryAdded; } + + static Result Remove( u32 persistentId ); + + static Result ReadMiiImageFile( + u32 persistentId, + MiiImageType imageType, + size_t* pOut, + u8* pImageBuffer, + size_t size + ); + + static Result WriteTempMiiImageFile( + u32 persistentId, + MiiImageType imageType, + const u8* pImageBuffer, + size_t size + ); + + static Result WriteMiiImageFile( + u32 persistentId, + MiiImageType imageType, + const void* pImage, + size_t size + ); + + static Result CommitMiiImageFiles( u32 persistentId ); + + static size_t GetPersistentIdList( u32* pPersistentIdList, size_t size ); +}; + +} +} +} + +#endif // LIBRARIES_ACTSLV_SAVE_ACT_ACCOUNT_INSTANCE_NAND_DATA_H_ Index: Horizon/sources/libraries/actslv/save/act_AccountManagerNandData.cpp =================================================================== --- Horizon/sources/libraries/actslv/save/act_AccountManagerNandData.cpp (revision 0) +++ Horizon/sources/libraries/actslv/save/act_AccountManagerNandData.cpp (working copy) @@ -0,0 +1,271 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#include "../act_Common.h" + +#include "act_AccountManagerNandData.h" + +#include "../util/act_ConvertHostServerSettings.h" +#include "../util/act_SystemInfoManager.h" + + +#define ACT_COMMON_FILE_PATH NN_ACT_NAND_QUOTA_PATH L"/common.dat" + +#define ACT_KEY_VALUE_ENTRY_LOCAL( keyname ) NN_ACT_KEY_VALUE_ENTRY( AccountManagerNandData, keyname ) + + +namespace nn +{ +namespace act +{ +namespace detail +{ + +const AccountManagerNandData::KeyValueEntry AccountManagerNandData::s_EntryList[] = +{ + ACT_KEY_VALUE_ENTRY_LOCAL( PersistentIdList ), + + ACT_KEY_VALUE_ENTRY_LOCAL( DefaultAccountPersistentId ), + + ACT_KEY_VALUE_ENTRY_LOCAL( CommonTransferableIdBase ), + + ACT_KEY_VALUE_ENTRY_LOCAL( CommonUuid ), + + ACT_KEY_VALUE_ENTRY_LOCAL( IsApplicationUpdateRequired ), + + ACT_KEY_VALUE_ENTRY_LOCAL( DefaultNnasType ), + + ACT_KEY_VALUE_ENTRY_LOCAL( DefaultNfsType ), + + ACT_KEY_VALUE_ENTRY_LOCAL( DefaultNfsNo ), + + ACT_KEY_VALUE_ENTRY_LOCAL( DefaultNnasSubDomain ), + + ACT_KEY_VALUE_ENTRY_LOCAL( DefaultNnasNfsEnv ) +}; + +AccountManagerNandData::AccountManagerNandData( void ) +: m_IsNewEntryAdded( false ) +{ + memset( &m_Members, 0, sizeof(m_Members) ); + + ConvertHostServerSettings::ToEnum( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN, ConvertHostServerSettings::INVALID_NNAS_NFS_ENV, + &m_Members.m_DefaultNnasType, &m_Members.m_DefaultNfsType, &m_Members.m_DefaultNfsNo ); + + // because "" is also valid value at production environment + m_Members.m_DefaultNnasSubDomain.Set( ConvertHostServerSettings::INVALID_NNAS_SUB_DOMAIN ); +} + +void AccountManagerNandData::Set( const AccountManagerNandData& accountManagerNandData ) +{ + memcpy( &m_Members, &accountManagerNandData.m_Members, sizeof(m_Members) ); + m_IsNewEntryAdded = accountManagerNandData.m_IsNewEntryAdded; +} + +bool AccountManagerNandData::IsEqual( const AccountManagerNandData& accountManagerNandData ) const +{ + return memcmp( &m_Members, &accountManagerNandData.m_Members, sizeof(m_Members) ) == 0; +} + +const char* AccountManagerNandData::GetTypeName( void ) const +{ + return "AccountManager"; +} + +u32 AccountManagerNandData::GetVersion( void ) const +{ + return NN_ACT_ACCOUNT_MANAGER_NAND_DATA_VERSION; +} + +s32 AccountManagerNandData::GetEntryNum( void ) const +{ + return NN_ACT_NELEMS( s_EntryList ); +} + +const char* AccountManagerNandData::GetKey( s32 index ) const +{ + return s_EntryList[index].pKey; +} + +void AccountManagerNandData::SetValue( s32 index, const char* pStr, u32 version ) +{ + (this->*(s_EntryList[index].Set))( pStr, version ); +} + +void AccountManagerNandData::GetValue( s32 index, char* pStr, size_t size ) const +{ + (this->*(s_EntryList[index].Get))( pStr, size ); +} + +void AccountManagerNandData::SetPersistentIdList( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + const char* pSrc = pStr; + + for ( size_t i = 0; i < NN_ACT_NELEMS( m_Members.m_PersistentIdList ); ++i ) + { + static const size_t BUFFER_SIZE = 16; + + char buffer[BUFFER_SIZE]; + const char* pNextSrc; + + size_t length = UnescapeToken( buffer, pSrc, BUFFER_SIZE, &pNextSrc ); + if ( length < BUFFER_SIZE ) + { + m_Members.m_PersistentIdList[i] = static_cast(ConvertStrToU64( buffer )); + } + pSrc = pNextSrc; + } +} + + +void AccountManagerNandData::SetDefaultAccountPersistentId( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_DefaultAccountPersistentId = static_cast(ConvertStrToU64( pStr )); +} + +void AccountManagerNandData::SetCommonTransferableIdBase( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_CommonTransferableIdBase = ConvertStrToU64( pStr ); +} + +void AccountManagerNandData::SetCommonUuid( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + u8 uuidData[ACT_UUID_SIZE]; + DecodeU8Array( uuidData, pStr, m_Members.m_CommonUuid.GetSize() ); + m_Members.m_CommonUuid.Set( uuidData ); +} + +void AccountManagerNandData::SetIsApplicationUpdateRequired( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_IsApplicationUpdateRequired = static_cast(ConvertStrToU64( pStr )); +} + +void AccountManagerNandData::SetDefaultNnasType( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_DefaultNnasType = static_cast(ConvertStrToU64( pStr )); +} + +void AccountManagerNandData::SetDefaultNfsType( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_DefaultNfsType = static_cast(ConvertStrToU64( pStr )); +} + +void AccountManagerNandData::SetDefaultNfsNo( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_DefaultNfsNo = static_cast(ConvertStrToU64( pStr )); +} + +void AccountManagerNandData::SetDefaultNnasSubDomain( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_DefaultNnasSubDomain.Set( pStr ); +} + +void AccountManagerNandData::SetDefaultNnasNfsEnv( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_DefaultNnasNfsEnv.Set( pStr ); +} + + +void AccountManagerNandData::GetPersistentIdList( char* pStr, size_t size ) const +{ + char* pDst = pStr; + + for ( size_t i = 0; i < NN_ACT_NELEMS( m_Members.m_PersistentIdList ); ++i ) + { + static const size_t BUFFER_SIZE = 16; + + char buffer[BUFFER_SIZE]; + ConvertU64ToStr( buffer, size, m_Members.m_PersistentIdList[i] ); + + size_t length = EscapeToken( pDst, buffer, BUFFER_SIZE ); + if ( length < BUFFER_SIZE ) + { + pDst += length; + } + } +} + + +void AccountManagerNandData::GetDefaultAccountPersistentId( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_DefaultAccountPersistentId ); +} + +void AccountManagerNandData::GetCommonTransferableIdBase( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_CommonTransferableIdBase ); +} + +void AccountManagerNandData::GetCommonUuid( char* pStr, size_t size ) const +{ + NN_UNUSED_VAR(size); + EncodeU8Array( pStr, m_Members.m_CommonUuid.GetACTUuid().data, m_Members.m_CommonUuid.GetSize() ); +} + +void AccountManagerNandData::GetIsApplicationUpdateRequired( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_IsApplicationUpdateRequired ); +} + +void AccountManagerNandData::GetDefaultNnasType( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, static_cast(m_Members.m_DefaultNnasType) ); +} + +void AccountManagerNandData::GetDefaultNfsType( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, static_cast(m_Members.m_DefaultNfsType) ); +} + +void AccountManagerNandData::GetDefaultNfsNo( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, static_cast(m_Members.m_DefaultNfsNo) ); +} + +void AccountManagerNandData::GetDefaultNnasSubDomain( char* pStr, size_t size ) const +{ + m_Members.m_DefaultNnasSubDomain.Get( pStr, size ); +} + +void AccountManagerNandData::GetDefaultNnasNfsEnv( char* pStr, size_t size ) const +{ + m_Members.m_DefaultNnasNfsEnv.Get( pStr, size ); +} + +Result AccountManagerNandData::Save( void ) const +{ + ACT_LOG_INFO( "%s", __FUNCTION__ ); + + return KeyValueStore::Save( ACT_COMMON_FILE_PATH ); +} + +Result AccountManagerNandData::Load( void ) +{ + ACT_LOG_INFO( "%s", __FUNCTION__ ); + + return KeyValueStore::Load( ACT_COMMON_FILE_PATH ); +} + + +} +} +} Index: Horizon/sources/libraries/actslv/save/act_AccountManagerNandData.h =================================================================== --- Horizon/sources/libraries/actslv/save/act_AccountManagerNandData.h (revision 0) +++ Horizon/sources/libraries/actslv/save/act_AccountManagerNandData.h (working copy) @@ -0,0 +1,138 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_SAVE_ACT_ACCOUNT_MANAGER_NAND_DATA_H_ +#define LIBRARIES_ACTSLV_SAVE_ACT_ACCOUNT_MANAGER_NAND_DATA_H_ + +#include "../act_Common.h" + +#include "act_KeyValueStore.h" + +#include "../act_Uuid.h" +#include "../util/act_StringContainer.h" + +namespace nn +{ +namespace act +{ +namespace detail +{ + +class AccountManagerNandData : public KeyValueStore +{ +private: + typedef void (AccountManagerNandData::*SetFunc)( const char* pStr, u32 version ); + typedef void (AccountManagerNandData::*GetFunc)( char* pStr, size_t size ) const; + + typedef struct KeyValueEntry + { + const char* pKey; + SetFunc Set; + GetFunc Get; + } KeyValueEntry; + + static const KeyValueEntry s_EntryList[]; + + typedef struct Members + { + u32 m_PersistentIdList[NN_ACT_SLOT_NUM]; + + u32 m_DefaultAccountPersistentId; + + u64 m_CommonTransferableIdBase; + + UuidInternal m_CommonUuid; + + bool m_IsApplicationUpdateRequired; + + NnasType m_DefaultNnasType; + NfsType m_DefaultNfsType; + u8 m_DefaultNfsNo; + + NnasSubDomainContainer m_DefaultNnasSubDomain; + NnasNfsEnvContainer m_DefaultNnasNfsEnv; + + } Members; + +private: + Members m_Members; + + bool m_IsNewEntryAdded; + +private: + void SetDefaultValueForNewEntry( void ); + +private: + void SetPersistentIdList( const char* pStr, u32 version ); + void SetDefaultAccountPersistentId( const char* pStr, u32 version ); + void SetCommonTransferableIdBase( const char* pStr, u32 version ); + void SetCommonUuid( const char* pStr, u32 version ); + void SetIsApplicationUpdateRequired( const char* pStr, u32 version ); + void SetDefaultNnasType( const char* pStr, u32 version ); + void SetDefaultNfsType( const char* pStr, u32 version ); + void SetDefaultNfsNo( const char* pStr, u32 version ); + void SetDefaultNnasSubDomain( const char* pStr, u32 version ); + void SetDefaultNnasNfsEnv( const char* pStr, u32 version ); + + void GetPersistentIdList( char* pStr, size_t size ) const; + void GetDefaultAccountPersistentId( char* pStr, size_t size ) const; + void GetCommonTransferableIdBase( char* pStr, size_t size ) const; + void GetCommonUuid( char* pStr, size_t size ) const; + void GetIsApplicationUpdateRequired( char* pStr, size_t size ) const; + void GetDefaultNnasType( char* pStr, size_t size ) const; + void GetDefaultNfsType( char* pStr, size_t size ) const; + void GetDefaultNfsNo( char* pStr, size_t size ) const; + void GetDefaultNnasSubDomain( char* pStr, size_t version ) const; + void GetDefaultNnasNfsEnv( char* pStr, size_t version ) const; + +protected: + virtual const char* GetTypeName( void ) const; + virtual u32 GetVersion( void ) const; + virtual s32 GetEntryNum( void ) const; + virtual const char* GetKey( s32 index ) const; + virtual void SetValue( s32 index, const char* pStr, u32 version ); + virtual void GetValue( s32 index, char* pStr, size_t size ) const; + +public: + void SetCommonUuid( const UuidInternal& uuid ) { m_Members.m_CommonUuid.Set( uuid ); } + void SetDefaultNnasSubDomain( const NnasSubDomainContainer& subDomain ) { m_Members.m_DefaultNnasSubDomain.Set( subDomain ); } + void SetDefaultNnasNfsEnv( const NnasNfsEnvContainer& nnasNfsEnv ) { m_Members.m_DefaultNnasNfsEnv.Set( nnasNfsEnv ); } + void SetDefaultNnasType( NnasType nnasType ) { m_Members.m_DefaultNnasType = nnasType; } + void SetDefaultNfsType( NfsType nfsType ) { m_Members.m_DefaultNfsType = nfsType; } + void SetDefaultNfsNo( u8 nfsNo ) { m_Members.m_DefaultNfsNo = nfsNo; } + void SetCommonTransferableIdBase( u64 transferableIdBase ) { m_Members.m_CommonTransferableIdBase = transferableIdBase; } + void SetPersistentId( u8 slotNo, u32 persistentId ) + { + if (slotNo <= NN_ACT_SLOT_NUM) + { + m_Members.m_PersistentIdList[slotNo - 1] = persistentId; + } + } + +public: + AccountManagerNandData( void ); + virtual ~AccountManagerNandData( void ) {}; + + void Set( const AccountManagerNandData& accountManagerNandData ); + bool IsEqual( const AccountManagerNandData& accountManagerNandData ) const; + + Result Save( void ) const; + Result Load( void ); + + inline bool IsNewEntryAdded( void ) const { return m_IsNewEntryAdded; } +}; + +} +} +} + +#endif // LIBRARIES_ACTSLV_SAVE_ACT_ACCOUNT_MANAGER_NAND_DATA_H_ Index: Horizon/sources/libraries/actslv/save/act_PersistentIdManagerNandData.cpp =================================================================== --- Horizon/sources/libraries/actslv/save/act_PersistentIdManagerNandData.cpp (revision 0) +++ Horizon/sources/libraries/actslv/save/act_PersistentIdManagerNandData.cpp (working copy) @@ -0,0 +1,112 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#include "../act_Common.h" + +#include "act_PersistentIdManagerNandData.h" + +//#include "../act_PersistentIdManager.h" + + +#define ACT_PERSISTENT_ID_FILE_PATH NN_ACT_NAND_QUOTA_PATH L"/persisid.dat" + +#define ACT_KEY_VALUE_ENTRY_LOCAL( keyname ) NN_ACT_KEY_VALUE_ENTRY( PersistentIdManagerNandData, keyname ) + + +namespace nn +{ +namespace act +{ +namespace detail +{ + +const PersistentIdManagerNandData::KeyValueEntry PersistentIdManagerNandData::s_EntryList[] = +{ + ACT_KEY_VALUE_ENTRY_LOCAL( PersistentIdHead ) +}; + +PersistentIdManagerNandData::PersistentIdManagerNandData( void ) +{ + memset( &m_Members, 0, sizeof(m_Members) ); +} + +void PersistentIdManagerNandData::Set( const PersistentIdManagerNandData& persistentIdManagerNandData ) +{ + memcpy( &m_Members, &persistentIdManagerNandData.m_Members, sizeof(m_Members) ); +} + +bool PersistentIdManagerNandData::IsEqual( const PersistentIdManagerNandData& persistentIdManagerNandData ) const +{ + return memcmp( &m_Members, &persistentIdManagerNandData.m_Members, sizeof(m_Members) ) == 0; +} + +const char* PersistentIdManagerNandData::GetTypeName( void ) const +{ + return "PersistentIdManager"; +} + +u32 PersistentIdManagerNandData::GetVersion( void ) const +{ + return NN_ACT_PERSISTENT_ID_MANAGER_NAND_DATA_VERSION; +} + +s32 PersistentIdManagerNandData::GetEntryNum( void ) const +{ + return NN_ACT_NELEMS( s_EntryList ); +} + +const char* PersistentIdManagerNandData::GetKey( s32 index ) const +{ + return s_EntryList[index].pKey; +} + +void PersistentIdManagerNandData::SetValue( s32 index, const char* pStr, u32 version ) +{ + (this->*(s_EntryList[index].Set))( pStr, version ); +} + +void PersistentIdManagerNandData::GetValue( s32 index, char* pStr, size_t size ) const +{ + (this->*(s_EntryList[index].Get))( pStr, size ); +} + + +void PersistentIdManagerNandData::SetPersistentIdHead( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_PersistentIdHead = static_cast(ConvertStrToU64( pStr )); +} + + +void PersistentIdManagerNandData::GetPersistentIdHead( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_PersistentIdHead ); +} + +Result PersistentIdManagerNandData::Save( void ) const +{ + ACT_LOG_INFO( "%s", __FUNCTION__ ); + + return KeyValueStore::Save( ACT_PERSISTENT_ID_FILE_PATH ); +} + +Result PersistentIdManagerNandData::Load( void ) +{ + ACT_LOG_INFO( "%s", __FUNCTION__ ); + + return KeyValueStore::Load( ACT_PERSISTENT_ID_FILE_PATH ); +} + + +} +} +} Index: Horizon/sources/libraries/actslv/save/act_PersistentIdManagerNandData.h =================================================================== --- Horizon/sources/libraries/actslv/save/act_PersistentIdManagerNandData.h (revision 0) +++ Horizon/sources/libraries/actslv/save/act_PersistentIdManagerNandData.h (working copy) @@ -0,0 +1,84 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_SAVE_ACT_PERSISTENT_ID_MANAGER_NAND_DATA_H_ +#define LIBRARIES_ACTSLV_SAVE_ACT_PERSISTENT_ID_MANAGER_NAND_DATA_H_ + +#include "../act_Common.h" + +#include "act_KeyValueStore.h" + + +namespace nn +{ +namespace act +{ +namespace detail +{ + +class PersistentIdManager; + +class PersistentIdManagerNandData : public KeyValueStore +{ +private: + typedef void (PersistentIdManagerNandData::*SetFunc)( const char* pStr, u32 version ); + typedef void (PersistentIdManagerNandData::*GetFunc)( char* pStr, size_t size ) const; + + typedef struct KeyValueEntry + { + const char* pKey; + SetFunc Set; + GetFunc Get; + } KeyValueEntry; + + static const KeyValueEntry s_EntryList[]; + + typedef struct Members + { + u32 m_PersistentIdHead; + } Members; + +private: + Members m_Members; + +private: + void SetPersistentIdHead( const char* pStr, u32 version ); + + void GetPersistentIdHead( char* pStr, size_t size ) const; + +protected: + virtual const char* GetTypeName( void ) const; + virtual u32 GetVersion( void ) const; + virtual s32 GetEntryNum( void ) const; + virtual const char* GetKey( s32 index ) const; + virtual void SetValue( s32 index, const char* pStr, u32 version ); + virtual void GetValue( s32 index, char* pStr, size_t size ) const; + +public: + PersistentIdManagerNandData( void ); + virtual ~PersistentIdManagerNandData( void ) {}; + + void Set( const PersistentIdManagerNandData& persistentIdManagerNandData ); + bool IsEqual( const PersistentIdManagerNandData& persistentIdManagerNandData ) const; + + Result Save( void ) const; + Result Load( void ); + +public: + void SetPersistentIdHead( u32 persistentIdHead ) { m_Members.m_PersistentIdHead = persistentIdHead; } +}; + +} +} +} + +#endif // LIBRARIES_ACTSLV_SAVE_ACT_PERSISTENT_ID_MANAGER_NAND_DATA_H_ Index: Horizon/sources/libraries/actslv/save/act_TransferableIdManagerNandData.cpp =================================================================== --- Horizon/sources/libraries/actslv/save/act_TransferableIdManagerNandData.cpp (revision 0) +++ Horizon/sources/libraries/actslv/save/act_TransferableIdManagerNandData.cpp (working copy) @@ -0,0 +1,112 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#include "../act_Common.h" + +#include "act_TransferableIdManagerNandData.h" + +//#include "../act_TransferableIdManager.h" + + +#define ACT_TRANSFERABLE_ID_FILE_PATH NN_ACT_NAND_QUOTA_PATH L"/transid.dat" + +#define ACT_KEY_VALUE_ENTRY_LOCAL( keyname ) NN_ACT_KEY_VALUE_ENTRY( TransferableIdManagerNandData, keyname ) + + +namespace nn +{ +namespace act +{ +namespace detail +{ + +const TransferableIdManagerNandData::KeyValueEntry TransferableIdManagerNandData::s_EntryList[] = +{ + ACT_KEY_VALUE_ENTRY_LOCAL( Counter ) +}; + +TransferableIdManagerNandData::TransferableIdManagerNandData( void ) +{ + memset( &m_Members, 0, sizeof(m_Members) ); +} + +void TransferableIdManagerNandData::Set( const TransferableIdManagerNandData& transferableIdManagerNandData ) +{ + memcpy( &m_Members, &transferableIdManagerNandData.m_Members, sizeof(m_Members) ); +} + +bool TransferableIdManagerNandData::IsEqual( const TransferableIdManagerNandData& transferableIdManagerNandData ) const +{ + return memcmp( &m_Members, &transferableIdManagerNandData.m_Members, sizeof(m_Members) ) == 0; +} + +const char* TransferableIdManagerNandData::GetTypeName( void ) const +{ + return "TransferableIdManager"; +} + +u32 TransferableIdManagerNandData::GetVersion( void ) const +{ + return NN_ACT_TRANSFERABLE_ID_MANAGER_NAND_DATA_VERSION; +} + +s32 TransferableIdManagerNandData::GetEntryNum( void ) const +{ + return NN_ACT_NELEMS( s_EntryList ); +} + +const char* TransferableIdManagerNandData::GetKey( s32 index ) const +{ + return s_EntryList[index].pKey; +} + +void TransferableIdManagerNandData::SetValue( s32 index, const char* pStr, u32 version ) +{ + (this->*(s_EntryList[index].Set))( pStr, version ); +} + +void TransferableIdManagerNandData::GetValue( s32 index, char* pStr, size_t size ) const +{ + (this->*(s_EntryList[index].Get))( pStr, size ); +} + + +void TransferableIdManagerNandData::SetCounter( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_Counter = static_cast(ConvertStrToU64( pStr )); +} + + +void TransferableIdManagerNandData::GetCounter( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_Counter ); +} + +Result TransferableIdManagerNandData::Save( void ) const +{ + ACT_LOG_INFO( "%s", __FUNCTION__ ); + + return KeyValueStore::Save( ACT_TRANSFERABLE_ID_FILE_PATH ); +} + +Result TransferableIdManagerNandData::Load( void ) +{ + ACT_LOG_INFO( "%s", __FUNCTION__ ); + + return KeyValueStore::Load( ACT_TRANSFERABLE_ID_FILE_PATH ); +} + + +} +} +} Index: Horizon/sources/libraries/actslv/save/act_TransferableIdManagerNandData.h =================================================================== --- Horizon/sources/libraries/actslv/save/act_TransferableIdManagerNandData.h (revision 0) +++ Horizon/sources/libraries/actslv/save/act_TransferableIdManagerNandData.h (working copy) @@ -0,0 +1,84 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_SAVE_ACT_TRANSFERABLE_ID_MANAGER_NAND_DATA_H_ +#define LIBRARIES_ACTSLV_SAVE_ACT_TRANSFERABLE_ID_MANAGER_NAND_DATA_H_ + +#include "../act_Common.h" + +#include "act_KeyValueStore.h" + + +namespace nn +{ +namespace act +{ +namespace detail +{ + +class TransferableIdManager; + +class TransferableIdManagerNandData : public KeyValueStore +{ +private: + typedef void (TransferableIdManagerNandData::*SetFunc)( const char* pStr, u32 version ); + typedef void (TransferableIdManagerNandData::*GetFunc)( char* pStr, size_t size ) const; + + typedef struct KeyValueEntry + { + const char* pKey; + SetFunc Set; + GetFunc Get; + } KeyValueEntry; + + static const KeyValueEntry s_EntryList[]; + + typedef struct Members + { + u32 m_Counter; + } Members; + +private: + Members m_Members; + +private: + void SetCounter( const char* pStr, u32 version ); + + void GetCounter( char* pStr, size_t size ) const; + +protected: + virtual const char* GetTypeName( void ) const; + virtual u32 GetVersion( void ) const; + virtual s32 GetEntryNum( void ) const; + virtual const char* GetKey( s32 index ) const; + virtual void SetValue( s32 index, const char* pStr, u32 version ); + virtual void GetValue( s32 index, char* pStr, size_t size ) const; + +public: + TransferableIdManagerNandData( void ); + virtual ~TransferableIdManagerNandData( void ) {}; + + void Set( const TransferableIdManagerNandData& transferableIdManagerNandData ); + bool IsEqual( const TransferableIdManagerNandData& transferableIdManagerNandData ) const; + + Result Save( void ) const; + Result Load( void ); + +public: + void SetCounter( u32 counter ) { m_Members.m_Counter = counter; } +}; + +} +} +} + +#endif // LIBRARIES_ACTSLV_SAVE_ACT_TRANSFERABLE_ID_MANAGER_NAND_DATA_H_ Index: Horizon/sources/libraries/actslv/save/act_UuidManagerNandData.cpp =================================================================== --- Horizon/sources/libraries/actslv/save/act_UuidManagerNandData.cpp (revision 0) +++ Horizon/sources/libraries/actslv/save/act_UuidManagerNandData.cpp (working copy) @@ -0,0 +1,123 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#include "../act_Common.h" + +//#include "../act_UuidManager.h" + +#include "act_UuidManagerNandData.h" + + +#define ACT_UUID_FILE_PATH NN_ACT_NAND_QUOTA_PATH L"/uuid.dat" + +#define ACT_KEY_VALUE_ENTRY_LOCAL( keyname ) NN_ACT_KEY_VALUE_ENTRY( UuidManagerNandData, keyname ) + + +namespace nn +{ +namespace act +{ +namespace detail +{ + +const UuidManagerNandData::KeyValueEntry UuidManagerNandData::s_EntryList[] = +{ + ACT_KEY_VALUE_ENTRY_LOCAL( ClockSequence ), + ACT_KEY_VALUE_ENTRY_LOCAL( LastTime ) +}; + +UuidManagerNandData::UuidManagerNandData( void ) +{ + memset( &m_Members, 0, sizeof(m_Members) ); +} + +void UuidManagerNandData::Set( const UuidManagerNandData& UuidManagerNandData ) +{ + memcpy( &m_Members, &UuidManagerNandData.m_Members, sizeof(m_Members) ); +} + +bool UuidManagerNandData::IsEqual( const UuidManagerNandData& UuidManagerNandData ) const +{ + return memcmp( &m_Members, &UuidManagerNandData.m_Members, sizeof(m_Members) ) == 0; +} + +const char* UuidManagerNandData::GetTypeName( void ) const +{ + return "UuidManager"; +} + +u32 UuidManagerNandData::GetVersion( void ) const +{ + return NN_ACT_UUID_MANAGER_NAND_DATA_VERSION; +} + +s32 UuidManagerNandData::GetEntryNum( void ) const +{ + return NN_ACT_NELEMS( s_EntryList ); +} + +const char* UuidManagerNandData::GetKey( s32 index ) const +{ + return s_EntryList[index].pKey; +} + +void UuidManagerNandData::SetValue( s32 index, const char* pStr, u32 version ) +{ + (this->*(s_EntryList[index].Set))( pStr, version ); +} + +void UuidManagerNandData::GetValue( s32 index, char* pStr, size_t size ) const +{ + (this->*(s_EntryList[index].Get))( pStr, size ); +} + + +void UuidManagerNandData::SetClockSequence( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_ClockSequence = static_cast(ConvertStrToU64( pStr )); +} + +void UuidManagerNandData::SetLastTime( const char* pStr, u32 version ) +{ + NN_UNUSED_VAR(version); + m_Members.m_LastTime = ConvertStrToU64( pStr ); +} + +void UuidManagerNandData::GetClockSequence( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_ClockSequence ); +} + +void UuidManagerNandData::GetLastTime( char* pStr, size_t size ) const +{ + ConvertU64ToStr( pStr, size, m_Members.m_LastTime ); +} + +Result UuidManagerNandData::Save( void ) const +{ + ACT_LOG_INFO( "%s", __FUNCTION__ ); + + return KeyValueStore::Save( ACT_UUID_FILE_PATH ); +} + +Result UuidManagerNandData::Load( void ) +{ + ACT_LOG_INFO( "%s", __FUNCTION__ ); + + return KeyValueStore::Load( ACT_UUID_FILE_PATH ); +} + + +} +} +} Index: Horizon/sources/libraries/actslv/save/act_UuidManagerNandData.h =================================================================== --- Horizon/sources/libraries/actslv/save/act_UuidManagerNandData.h (revision 0) +++ Horizon/sources/libraries/actslv/save/act_UuidManagerNandData.h (working copy) @@ -0,0 +1,88 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_UUID_MANAGER_NAND_DATA_H_ +#define LIBRARIES_ACTSLV_UUID_MANAGER_NAND_DATA_H_ + +#include "../act_Common.h" + +#include "act_KeyValueStore.h" + + +namespace nn +{ +namespace act +{ +namespace detail +{ + +class UuidManager; + +class UuidManagerNandData : public KeyValueStore +{ +private: + typedef void (UuidManagerNandData::*SetFunc)( const char* pStr, u32 version ); + typedef void (UuidManagerNandData::*GetFunc)( char* pStr, size_t size ) const; + + typedef struct KeyValueEntry + { + const char* pKey; + SetFunc Set; + GetFunc Get; + } KeyValueEntry; + + static const KeyValueEntry s_EntryList[]; + + typedef struct Members + { + u16 m_ClockSequence; + u64 m_LastTime; + } Members; + +private: + Members m_Members; + +private: + void SetClockSequence( const char* pStr, u32 version ); + void SetLastTime( const char* pStr, u32 version ); + + void GetClockSequence( char* pStr, size_t size ) const; + void GetLastTime( char* pStr, size_t size ) const; + +protected: + virtual const char* GetTypeName( void ) const; + virtual u32 GetVersion( void ) const; + virtual s32 GetEntryNum( void ) const; + virtual const char* GetKey( s32 index ) const; + virtual void SetValue( s32 index, const char* pStr, u32 version ); + virtual void GetValue( s32 index, char* pStr, size_t size ) const; + +public: + UuidManagerNandData( void ); + virtual ~UuidManagerNandData( void ) {}; + + void Set( const UuidManagerNandData& UuidManagerNandData ); + bool IsEqual( const UuidManagerNandData& UuidManagerNandData ) const; + + Result Save( void ) const; + Result Load( void ); + +public: + inline void SetClockSequence( u16 clockSequence ) { m_Members.m_ClockSequence = ( clockSequence & 0x3FFF ); } + inline void SetLastTime( u64 lastTime ) { m_Members.m_LastTime = lastTime; } +}; + +} +} +} + +#endif // LIBRARIES_ACTSLV_UUID_MANAGER_NAND_DATA_H_ Index: Horizon/sources/libraries/actslv/tests/CTR/OMakefile =================================================================== --- Horizon/sources/libraries/actslv/tests/CTR/OMakefile (revision 0) +++ Horizon/sources/libraries/actslv/tests/CTR/OMakefile (working copy) @@ -0,0 +1,46 @@ +#!/usr/bin/env omake +#---------------------------------------------------------------------------- +# Project: Horizon +# File: OMakefile +# +# Copyright (C)2009-2013 Nintendo Co., Ltd. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Rev: 50823 $ +#---------------------------------------------------------------------------- + +include $(makePlatformDefsPath tests) + +SUPPORTED_TARGETS = CTR-TS.Process.MPCore.* + +SOURCES_TEST[] = + test_salvage.cpp + test_salvageFixedAccountJP.cpp + test_salvageValidationJP.cpp + test_salvageFixedAccountUS.cpp + test_salvageValidationUS.cpp + +CCFLAGS_WARNING += --diag_suppress 177,1301,2530 + +LIBS += libnn_actslv libnn_mii libnn_enc + +ROM_SPEC_FILE = Test.rsf +DESCRIPTOR = $(CTRSDK_ROOT)/resources/specfiles/tools/RepairTool.desc +CTR_ICON = $(CTRSDK_ROOT)/resources/banner/Default.icn + +DEPEND_PROCESSES[] = + @$(HORIZON_ROOT_IMAGES)$(DIRSEP)processes$(DIRSEP)act$(DIRSEP)CTR-TS.Process.MPCore.small$(DIRSEP)$`(TARGET.buildtype)$(DIRSEP)act.cdi + +TEST_ATTRIBUTES[] = + +TEST_ENVIRONMENT_PROCESSLIST = true +TEST_ENVIRONMENT_EMUMEM = true + +include $(makePlatformDefsPath build.tests) + +tests: $(TEST_TARGETS) Index: Horizon/sources/libraries/actslv/tests/CTR/Test.rsf =================================================================== --- Horizon/sources/libraries/actslv/tests/CTR/Test.rsf (revision 0) +++ Horizon/sources/libraries/actslv/tests/CTR/Test.rsf (working copy) @@ -0,0 +1,21 @@ +BasicInfo: + Title: test + +AccessControlInfo: + Priority: 16 + FileSystemAccess: + - CategoryFileSystemTool + +Rom: + HostRoot : $(ROMFS_ROOT) + +SystemControlInfo: + AppType: Application + StackSize : 0x32000 + +CardInfo: + CardDevice: None + +TitleInfo: + UniqueId: 0xFE078 + Use: Evaluation \ No newline at end of file Index: Horizon/sources/libraries/actslv/tests/CTR/test_salvage.cpp =================================================================== --- Horizon/sources/libraries/actslv/tests/CTR/test_salvage.cpp (revision 0) +++ Horizon/sources/libraries/actslv/tests/CTR/test_salvage.cpp (working copy) @@ -0,0 +1,151 @@ +サソ/*---------------------------------------------------------------------------* + Project: Horizon + File: test_salvage.cpp + + Copyright 2010-2011 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + +* ---------------------------------------------------------------------------*/ + +#include "../test_actUtil.h" + +#include "../../save/act_FileOutputStream.h" + +#include +#include + +#include +#include + +namespace +{ +nn::os::Thread s_Thread; +nn::os::StackBuffer<32 * 1024> s_StackBuffer; +nn::os::Event beginEvent; +nn::os::Event endEvent; + +const size_t BUFFER_SIZE = 4 * 1024; +u8 s_ActInitializeBuffer[BUFFER_SIZE] NN_ATTRIBUTE_ALIGN( 4096 ); + +void UnmountThreadFunc( void* result ) +{ + *reinterpret_cast( result ) = nn::act::KeepUnmountAndBlock( &beginEvent, &endEvent ); +} +} + +class ActTestSalvage : public nn::test::Suite +{ +private: + bool m_IsInitialized; + +public: + nn::Result m_UnmountResult; + +public: + ActTestSalvage() + : m_IsInitialized( false ) + { + SUITE_NAME("ActTestSalvage"); + + TEST_ADD( ActTestSalvage::TestSalvage ); + } + +private: + virtual bool InitializeSuite( void ) + { + InitializeSuiteImpl(); + + return true; + } + + void InitializeSuiteImpl( void ) + { + nn::cfg::CTR::init::Initialize(); + nn::fs::Initialize(); + nn::ac::CTR::InitializeInternal(); + + nn::ac::Config config; + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::CreateDefaultConfig( &config ) ); + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::Connect( config ) ); + + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::fs::MountSdmc("sdmc:") ); + + //nn::Result result = nn::friends::InitializeAdmin(); + + nn::act::Initialize(); + + m_IsInitialized = true; + } + + void TestSalvage_SalvageImpl( void ) + { + // act 蛻晄悄蛹 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::InitializeAdmin( reinterpret_cast( s_ActInitializeBuffer ), 4 * 1024 ) ); + + // 遘サ陦御コ育エシ主ョ滄圀縺ッ莠医a NNAS 邂。逅繝繝シ繝ォ縺ァ遘サ陦御コ育エ縺励※縺翫¥ + nn::act::TransferDeviceInfo info; + info.deviceId = TEST_ACTSLV_DEVICE_ID; + strlcpy( info.serialId, TEST_ACTSLV_SERIAL_ID, NN_ACT_DEVICE_INFO_SERIAL_ID_SIZE ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::ReserveTransfer( info, NULL ) ); + + // nn::act::KeepUnmountAndBlock + beginEvent.Initialize( false ); + endEvent.Initialize( false ); + + s_Thread.Start( UnmountThreadFunc, &m_UnmountResult, s_StackBuffer ); + beginEvent.Wait(); + + // 繧「繧ォ繧ヲ繝ウ繝医し繝ォ繝吶シ繧ク + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::SalvageAccounts() ); + TEST_REPORT( "---------------------------------\n" ); + TEST_REPORT( "Approval ID:%u\n", nn::act::GetSalvagedApprovalId() ); + TEST_REPORT( "---------------------------------\n" ); + + // 繧オ繝ォ繝吶シ繧ク邨ゆコ繧偵す繧ケ繝繝縺ォ騾夂衍 + endEvent.Signal(); + + // nn::act::KeepUnmountAndBlock 邨ゆコ + if ( s_Thread.IsValid() ) + { + s_Thread.Join(); + s_Thread.Finalize(); + } + beginEvent.Finalize(); + endEvent.Finalize(); + + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( m_UnmountResult ); + + // 遘サ陦悟ョ御コ + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CompleteTransfer() ); + + // act 邨ゆコ + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::Finalize() ); + } + + void TestSalvage( void ) + { + ACT_TEST_ASSERT_FATAL( m_IsInitialized ); + + TestSalvage_SalvageImpl(); + } + + virtual void FinalizeSuite( void ) + { + nn::fs::Unmount( "sdmc:" ); + } +}; + +#define SYSTEM_HEAP_SIZE 0x00100000 + +extern "C" void nninitStartUp(void) +{ + // 繝偵シ繝怜晄悄蛹門捉繧翫r繧ェ繝シ繝舌Λ繧、繝 + nn::test::InitializeAllocator(SYSTEM_HEAP_SIZE); +} + +NN_TEST_DEFINE_MAIN(ActTestSalvage) Index: Horizon/sources/libraries/actslv/tests/CTR/test_salvageFixedAccountJP.cpp =================================================================== --- Horizon/sources/libraries/actslv/tests/CTR/test_salvageFixedAccountJP.cpp (revision 0) +++ Horizon/sources/libraries/actslv/tests/CTR/test_salvageFixedAccountJP.cpp (working copy) @@ -0,0 +1,200 @@ +サソ/*---------------------------------------------------------------------------* + Project: Horizon + File: test_salvage.cpp + + Copyright 2010-2011 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + +* ---------------------------------------------------------------------------*/ + +#include "../test_actUtil.h" + +#include "../../save/act_FileOutputStream.h" + +#include +#include + +#include +#include + +namespace +{ +nn::os::Thread s_Thread; +nn::os::StackBuffer<32 * 1024> s_StackBuffer; +nn::os::Event beginEvent; +nn::os::Event endEvent; + +const size_t BUFFER_SIZE = 4 * 1024; +u8 s_ActInitializeBuffer[BUFFER_SIZE] NN_ATTRIBUTE_ALIGN( 4096 ); + +void UnmountThreadFunc( void* result ) +{ + *reinterpret_cast( result ) = nn::act::KeepUnmountAndBlock( &beginEvent, &endEvent ); +} +} + +class ActTestSalvage : public nn::test::Suite +{ +private: + bool m_IsInitialized; + +public: + nn::Result m_UnmountResult; + +public: + ActTestSalvage() + : m_IsInitialized( false ) + { + SUITE_NAME("ActTestSalvage"); + + TEST_ADD( ActTestSalvage::TestSalvage ); + } + +private: + virtual bool InitializeSuite( void ) + { + InitializeSuiteImpl(); + + return true; + } + + void InitializeSuiteImpl( void ) + { + nn::cfg::CTR::init::Initialize(); + nn::fs::Initialize(); + nn::ac::CTR::InitializeInternal(); + + nn::ac::Config config; + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::CreateDefaultConfig( &config ) ); + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::Connect( config ) ); + + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::fs::MountSdmc("sdmc:") ); + + //nn::Result result = nn::friends::InitializeAdmin(); + + nn::act::Initialize(); + + m_IsInitialized = true; + } + + void TestSalvage_SalvageImpl( void ) + { + // act 蛻晄悄蛹 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::InitializeAdmin( reinterpret_cast( s_ActInitializeBuffer ), 4 * 1024 ) ); + + // 繝繝輔か繝ォ繝域磁邯壼医′ T1 莉・螟悶ョ蝣エ蜷医ッ繝繧ケ繝医〒縺阪↑縺 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::SetDefaultHostServerSettings( "library-dev.", "T1" ) ); + char nnasSubDomain[NN_ACT_NNAS_SUB_DOMAIN_SIZE]; + char nnasNfsEnv[NN_ACT_NNAS_NFS_ENV_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetDefaultHostServerSettings( nnasSubDomain, nnasNfsEnv ) ); + TEST_REPORT( "subdomain: %s\n", nnasSubDomain ); + TEST_REPORT( "nfsenv: %s\n", nnasNfsEnv ); + ACT_TEST_ASSERT_FATAL( strncmp( nnasSubDomain, "library-dev.", NN_ACT_NNAS_SUB_DOMAIN_SIZE ) == 0 ); + ACT_TEST_ASSERT_FATAL( strncmp( nnasNfsEnv, "T1", NN_ACT_NNAS_NFS_ENV_SIZE ) == 0 ); + + // 蜈ィ繧「繧ォ繧ヲ繝ウ繝亥炎髯、 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CreateConsoleAccount() ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::LoadConsoleAccount( nn::act::GetNumOfAccounts(), nn::act::LOAD_OPTION_NO_PASSWORD_CHECK, NULL ) ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::DeleteDeviceAssociation() ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::UnloadConsoleAccount() ); + u8 numOfAccounts = nn::act::GetNumOfAccounts(); + TEST_REPORT( "num = %u\n", numOfAccounts ); + for ( u8 i = numOfAccounts; i > 0; --i ) + { + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::DeleteConsoleAccount(i) ); + } + + // 遘サ陦悟ッセ雎。繧「繧ォ繧ヲ繝ウ繝医ョ菴懈撰シlibrary-devシ + //ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( CreateFpAccount() ); + //ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( LoadFpAccount() ); + u32 approvalId; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CreateConsoleAccount() ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::LoadConsoleAccount( 1, nn::act::LOAD_OPTION_NO_PASSWORD_CHECK, NULL ) ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::BindToExistentServerAccount( &approvalId, "ido200", "Password", "ido@dummy.nintendo.net" ) ); // 繧オ繝ォ繝吶シ繧ク縺輔l縺ェ縺 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CreateConsoleAccount() ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::LoadConsoleAccount( 2, nn::act::LOAD_OPTION_NO_PASSWORD_CHECK, NULL ) ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::BindToExistentServerAccount( &approvalId, TEST_ACTSLV_ACCOUNT_ID, TEST_ACTSLV_PASSWORD, TEST_ACTSLV_EMAIL_ADDRESS ) ); + + // 繧オ繝ォ繝吶シ繧ク縺輔l繧倶コ亥ョ壹ョ UUID -> SD 縺ォ菫晏ュ + nn::act::Uuid orgUuid; + nn::act::Uuid orgCommonUuid; + nn::act::GetUuidEx( &orgUuid, NN_ACT_SLOT_NO_CURRENT, NN_ACT_UNIQUE_ID_ADMIN ); + nn::act::GetUuidEx( &orgCommonUuid, NN_ACT_SLOT_NO_COMMON, NN_ACT_UNIQUE_ID_ADMIN ); + + nn::fs::FileOutputStream outputStream( "sdmc:/salvage_params", true ); + outputStream.Write( &orgUuid, sizeof( nn::act::Uuid ), false ); + outputStream.Write( &orgCommonUuid, sizeof( nn::act::Uuid ), false ); + outputStream.Flush(); + + // 遘サ陦御コ育エシ主ョ滄圀縺ッ莠医a NNAS 邂。逅繝繝シ繝ォ縺ァ遘サ陦御コ育エ縺励※縺翫¥ + nn::act::TransferDeviceInfo info; + info.deviceId = TEST_ACTSLV_DEVICE_ID; + strlcpy( info.serialId, TEST_ACTSLV_SERIAL_ID, NN_ACT_DEVICE_INFO_SERIAL_ID_SIZE ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::ReserveTransfer( info, NULL ) ); + + // nn::act::KeepUnmountAndBlock + beginEvent.Initialize( false ); + endEvent.Initialize( false ); + + s_Thread.Start( UnmountThreadFunc, &m_UnmountResult, s_StackBuffer ); + beginEvent.Wait(); + + // 繧「繧ォ繧ヲ繝ウ繝医し繝ォ繝吶シ繧ク + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::SalvageAccounts() ); + ACT_TEST_ASSERT_FATAL( nn::act::GetSalvagedApprovalId() == 0 ); + ACT_TEST_ASSERT_FATAL( nn::act::GetAgeAtSalvage() == 36 ); // 1977/12/1 + u32 countryCode; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetCountryCodeAtSalvage( &countryCode ) ); + ACT_TEST_ASSERT_FATAL( countryCode == 1 ); // JP + TEST_REPORT( "---------------------------------\n" ); + TEST_REPORT( "Approval ID:%u\n", nn::act::GetSalvagedApprovalId() ); + TEST_REPORT( "---------------------------------\n" ); + + // 繧オ繝ォ繝吶シ繧ク邨ゆコ繧偵す繧ケ繝繝縺ォ騾夂衍 + endEvent.Signal(); + + // nn::act::KeepUnmountAndBlock 邨ゆコ + if ( s_Thread.IsValid() ) + { + s_Thread.Join(); + s_Thread.Finalize(); + } + beginEvent.Finalize(); + endEvent.Finalize(); + + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( m_UnmountResult ); + + // 遘サ陦悟ョ御コ + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CompleteTransfer() ); + + // act 邨ゆコ + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::Finalize() ); + } + + void TestSalvage( void ) + { + ACT_TEST_ASSERT_FATAL( m_IsInitialized ); + + TestSalvage_SalvageImpl(); + } + + virtual void FinalizeSuite( void ) + { + nn::fs::Unmount( "sdmc:" ); + } +}; + +#define SYSTEM_HEAP_SIZE 0x00100000 + +extern "C" void nninitStartUp(void) +{ + // 繝偵シ繝怜晄悄蛹門捉繧翫r繧ェ繝シ繝舌Λ繧、繝 + nn::test::InitializeAllocator(SYSTEM_HEAP_SIZE); +} + +NN_TEST_DEFINE_MAIN(ActTestSalvage) Index: Horizon/sources/libraries/actslv/tests/CTR/test_salvageFixedAccountUS.cpp =================================================================== --- Horizon/sources/libraries/actslv/tests/CTR/test_salvageFixedAccountUS.cpp (revision 0) +++ Horizon/sources/libraries/actslv/tests/CTR/test_salvageFixedAccountUS.cpp (working copy) @@ -0,0 +1,200 @@ +サソ/*---------------------------------------------------------------------------* + Project: Horizon + File: test_salvage.cpp + + Copyright 2010-2011 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + +* ---------------------------------------------------------------------------*/ + +#include "../test_actUtil.h" + +#include "../../save/act_FileOutputStream.h" + +#include +#include + +#include +#include + +namespace +{ +nn::os::Thread s_Thread; +nn::os::StackBuffer<32 * 1024> s_StackBuffer; +nn::os::Event beginEvent; +nn::os::Event endEvent; + +const size_t BUFFER_SIZE = 4 * 1024; +u8 s_ActInitializeBuffer[BUFFER_SIZE] NN_ATTRIBUTE_ALIGN( 4096 ); + +void UnmountThreadFunc( void* result ) +{ + *reinterpret_cast( result ) = nn::act::KeepUnmountAndBlock( &beginEvent, &endEvent ); +} +} + +class ActTestSalvage : public nn::test::Suite +{ +private: + bool m_IsInitialized; + +public: + nn::Result m_UnmountResult; + +public: + ActTestSalvage() + : m_IsInitialized( false ) + { + SUITE_NAME("ActTestSalvage"); + + TEST_ADD( ActTestSalvage::TestSalvage ); + } + +private: + virtual bool InitializeSuite( void ) + { + InitializeSuiteImpl(); + + return true; + } + + void InitializeSuiteImpl( void ) + { + nn::cfg::CTR::init::Initialize(); + nn::fs::Initialize(); + nn::ac::CTR::InitializeInternal(); + + nn::ac::Config config; + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::CreateDefaultConfig( &config ) ); + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::Connect( config ) ); + + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::fs::MountSdmc("sdmc:") ); + + //nn::Result result = nn::friends::InitializeAdmin(); + + nn::act::Initialize(); + + m_IsInitialized = true; + } + + void TestSalvage_SalvageImpl( void ) + { + // act 蛻晄悄蛹 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::InitializeAdmin( reinterpret_cast( s_ActInitializeBuffer ), 4 * 1024 ) ); + + // 繝繝輔か繝ォ繝域磁邯壼医′ T1 莉・螟悶ョ蝣エ蜷医ッ繝繧ケ繝医〒縺阪↑縺 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::SetDefaultHostServerSettings( "library-dev.", "T1" ) ); + char nnasSubDomain[NN_ACT_NNAS_SUB_DOMAIN_SIZE]; + char nnasNfsEnv[NN_ACT_NNAS_NFS_ENV_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetDefaultHostServerSettings( nnasSubDomain, nnasNfsEnv ) ); + TEST_REPORT( "subdomain: %s\n", nnasSubDomain ); + TEST_REPORT( "nfsenv: %s\n", nnasNfsEnv ); + ACT_TEST_ASSERT_FATAL( strncmp( nnasSubDomain, "library-dev.", NN_ACT_NNAS_SUB_DOMAIN_SIZE ) == 0 ); + ACT_TEST_ASSERT_FATAL( strncmp( nnasNfsEnv, "T1", NN_ACT_NNAS_NFS_ENV_SIZE ) == 0 ); + + // 蜈ィ繧「繧ォ繧ヲ繝ウ繝亥炎髯、 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CreateConsoleAccount() ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::LoadConsoleAccount( nn::act::GetNumOfAccounts(), nn::act::LOAD_OPTION_NO_PASSWORD_CHECK, NULL ) ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::DeleteDeviceAssociation() ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::UnloadConsoleAccount() ); + u8 numOfAccounts = nn::act::GetNumOfAccounts(); + TEST_REPORT( "num = %u\n", numOfAccounts ); + for ( u8 i = numOfAccounts; i > 0; --i ) + { + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::DeleteConsoleAccount(i) ); + } + + // 遘サ陦悟ッセ雎。繧「繧ォ繧ヲ繝ウ繝医ョ菴懈撰シlibrary-devシ + //ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( CreateFpAccount() ); + //ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( LoadFpAccount() ); + u32 approvalId; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CreateConsoleAccount() ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::LoadConsoleAccount( 1, nn::act::LOAD_OPTION_NO_PASSWORD_CHECK, NULL ) ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::BindToExistentServerAccount( &approvalId, "ido200us", "Password", "ido@dummy.nintendo.net" ) ); // 繧オ繝ォ繝吶シ繧ク縺輔l縺ェ縺 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CreateConsoleAccount() ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::LoadConsoleAccount( 2, nn::act::LOAD_OPTION_NO_PASSWORD_CHECK, NULL ) ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::BindToExistentServerAccount( &approvalId, TEST_ACTSLV_ACCOUNT_ID_US, TEST_ACTSLV_PASSWORD, TEST_ACTSLV_EMAIL_ADDRESS ) ); + + // 繧オ繝ォ繝吶シ繧ク縺輔l繧倶コ亥ョ壹ョ UUID -> SD 縺ォ菫晏ュ + nn::act::Uuid orgUuid; + nn::act::Uuid orgCommonUuid; + nn::act::GetUuidEx( &orgUuid, NN_ACT_SLOT_NO_CURRENT, NN_ACT_UNIQUE_ID_ADMIN ); + nn::act::GetUuidEx( &orgCommonUuid, NN_ACT_SLOT_NO_COMMON, NN_ACT_UNIQUE_ID_ADMIN ); + + nn::fs::FileOutputStream outputStream( "sdmc:/salvage_paramsUS", true ); + outputStream.Write( &orgUuid, sizeof( nn::act::Uuid ), false ); + outputStream.Write( &orgCommonUuid, sizeof( nn::act::Uuid ), false ); + outputStream.Flush(); + + // 遘サ陦御コ育エシ主ョ滄圀縺ッ莠医a NNAS 邂。逅繝繝シ繝ォ縺ァ遘サ陦御コ育エ縺励※縺翫¥ + nn::act::TransferDeviceInfo info; + info.deviceId = TEST_ACTSLV_DEVICE_ID; + strlcpy( info.serialId, TEST_ACTSLV_SERIAL_ID, NN_ACT_DEVICE_INFO_SERIAL_ID_SIZE ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::ReserveTransfer( info, NULL ) ); + + // nn::act::KeepUnmountAndBlock + beginEvent.Initialize( false ); + endEvent.Initialize( false ); + + s_Thread.Start( UnmountThreadFunc, &m_UnmountResult, s_StackBuffer ); + beginEvent.Wait(); + + // 繧「繧ォ繧ヲ繝ウ繝医し繝ォ繝吶シ繧ク + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::SalvageAccounts() ); + ACT_TEST_ASSERT_FATAL( nn::act::GetSalvagedApprovalId() == 9999 ); + ACT_TEST_ASSERT_FATAL( nn::act::GetAgeAtSalvage() == 3 ); // 2010/12/1 + u32 countryCode; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetCountryCodeAtSalvage( &countryCode ) ); + ACT_TEST_ASSERT_FATAL( countryCode == 49 ); // US + TEST_REPORT( "---------------------------------\n" ); + TEST_REPORT( "Approval ID:%u\n", nn::act::GetSalvagedApprovalId() ); + TEST_REPORT( "---------------------------------\n" ); + + // 繧オ繝ォ繝吶シ繧ク邨ゆコ繧偵す繧ケ繝繝縺ォ騾夂衍 + endEvent.Signal(); + + // nn::act::KeepUnmountAndBlock 邨ゆコ + if ( s_Thread.IsValid() ) + { + s_Thread.Join(); + s_Thread.Finalize(); + } + beginEvent.Finalize(); + endEvent.Finalize(); + + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( m_UnmountResult ); + + // 遘サ陦悟ョ御コ + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CompleteTransfer() ); + + // act 邨ゆコ + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::Finalize() ); + } + + void TestSalvage( void ) + { + ACT_TEST_ASSERT_FATAL( m_IsInitialized ); + + TestSalvage_SalvageImpl(); + } + + virtual void FinalizeSuite( void ) + { + nn::fs::Unmount( "sdmc:" ); + } +}; + +#define SYSTEM_HEAP_SIZE 0x00100000 + +extern "C" void nninitStartUp(void) +{ + // 繝偵シ繝怜晄悄蛹門捉繧翫r繧ェ繝シ繝舌Λ繧、繝 + nn::test::InitializeAllocator(SYSTEM_HEAP_SIZE); +} + +NN_TEST_DEFINE_MAIN(ActTestSalvage) Index: Horizon/sources/libraries/actslv/tests/CTR/test_salvageValidationJP.cpp =================================================================== --- Horizon/sources/libraries/actslv/tests/CTR/test_salvageValidationJP.cpp (revision 0) +++ Horizon/sources/libraries/actslv/tests/CTR/test_salvageValidationJP.cpp (working copy) @@ -0,0 +1,305 @@ +サソ/*---------------------------------------------------------------------------* + Project: Horizon + File: test_salvage.cpp + + Copyright 2010-2011 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + +* ---------------------------------------------------------------------------*/ + +#include "../test_actUtil.h" + +#include +#include + +#include +#include + +#include + +namespace +{ +nn::os::Thread s_Thread; +nn::os::StackBuffer<32 * 1024> s_StackBuffer; +nn::os::Event beginEvent; +nn::os::Event endEvent; + +const size_t BUFFER_SIZE = 4 * 1024; +u8 s_ActInitializeBuffer[BUFFER_SIZE] NN_ATTRIBUTE_ALIGN( 4096 ); + +void UnmountThreadFunc( void* ptrArg ) +{ + NN_UNUSED_VAR( ptrArg ); + + nn::act::KeepUnmountAndBlock( &beginEvent, &endEvent ); +} +} + +class ActTestSalvageValidation : public nn::test::Suite +{ +private: + bool m_IsInitialized; + int : 24; + +public: + ActTestSalvageValidation() + : m_IsInitialized( false ) + { + SUITE_NAME("ActTestSalvageValidation"); + + TEST_ADD( ActTestSalvageValidation::TestSalvage ); + } + +private: + virtual bool InitializeSuite( void ) + { + InitializeSuiteImpl(); + + return true; + } + + void InitializeSuiteImpl( void ) + { + nn::cfg::CTR::init::Initialize(); + nn::fs::Initialize(); + nn::ac::CTR::InitializeInternal(); + + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::friends::Initialize() ); + + nn::ac::Config config; + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::CreateDefaultConfig( &config ) ); + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::Connect( config ) ); + + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::fs::MountSdmc( "sdmc:" ) ); + + nn::act::Initialize(); + + m_IsInitialized = true; + } + + void TestSalvage_ValidateImpl( void ) + { + nn::act::Uuid orgUuid; + nn::act::Uuid orgCommonUuid; + { + nn::fs::FileStream stream( "sdmc:/salvage_params", true ); + stream.Read( &orgUuid, sizeof(nn::act::Uuid ) ); + stream.Read( &orgCommonUuid, sizeof(nn::act::Uuid ) ); + } + // act 蛻晄悄蛹 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::InitializeAdmin( reinterpret_cast( s_ActInitializeBuffer ), 4 * 1024 ) ); + + ACT_TEST_ASSERT( nn::act::GetNumOfAccounts() == 1 ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::LoadConsoleAccount( 1, nn::act::LOAD_OPTION_NO_PASSWORD_CHECK, NULL ) ); + + // ******************************** + // 讀懆ィシ + // ******************************** + + // Slot ID + ACT_TEST_ASSERT_FATAL( nn::act::GetSlotNo() == 1 ); + { + // Persistent ID + ACT_TEST_ASSERT_FATAL( nn::act::GetPersistentIdEx( 1 ) == 0x80000000 ); + // Transferable ID Base + u64 unscrambledTransferableId = UnscrambleTransferableId( nn::act::GetTransferableId( TEST_UNIQUE_ID ) ); + NN_TEST_ASSERT_EQUAL( ( unscrambledTransferableId & COUNTER_MASK ) >> MaskToShift( COUNTER_MASK ), 0 ); + NN_TEST_ASSERT_EQUAL( ( unscrambledTransferableId & UNIQUE_ID_MASK ) >> MaskToShift( UNIQUE_ID_MASK ), 0 ); + NN_TEST_ASSERT_EQUAL( ( unscrambledTransferableId & PLATFORM_CODE_MASK ) >> MaskToShift( PLATFORM_CODE_MASK ), 0 ); + NN_TEST_ASSERT_EQUAL( ( unscrambledTransferableId & DEVICE_ID_MASK ) >> MaskToShift( DEVICE_ID_MASK ), 0 ); + // account UUID + nn::act::Uuid uuid; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetUuidEx( &uuid, NN_ACT_SLOT_NO_CURRENT, NN_ACT_UNIQUE_ID_ADMIN ) ); + ACT_TEST_ASSERT_FATAL( memcmp( uuid.data, orgUuid.data, sizeof( nn::act::Uuid ) ) == 0 ); + // Parental Control Slot No + NN_TEST_ASSERT_EQUAL( nn::act::GetParentalControlSlotNo(), 1 ); + // Mii Data + nn::mii::StoreData mii; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetMii( &mii ) ); + { + u8 i = NN_MII_STORE_DATA_SIZE; + TEST_REPORT( "salvaged Mii Data\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i] + ); + i = NN_MII_STORE_DATA_SIZE; + TEST_REPORT( "original Mii Data\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i] + ); + } + // Author ID 縺悟、牙喧縺吶k + //ACT_TEST_ASSERT_FATAL( memcmp( mii.data, TEST_ACTSLV_MII_DATA.data, 96 ) == 0 ); + // Mii Name + char16 miiName[NN_ACT_MII_NAME_SIZE] = {L'\0'}; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetMiiName( miiName ) ); + ACT_TEST_ASSERT_FATAL( nn::act::Strncmp( miiName, TEST_ACTSLV_MII_NAME, NN_ACT_MII_NAME_SIZE ) == 0 ); + // Is Mii Updated + NN_TEST_ASSERT_EQUAL( nn::act::IsMiiUpdated(), false ); + // Account ID + char accountId[NN_ACT_ACCOUNT_ID_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetAccountId( accountId ) ); + /*ACT_TEST_ASSERT_FATAL*/( strncmp( accountId, TEST_ACTSLV_ACCOUNT_ID, NN_ACT_ACCOUNT_ID_SIZE ) == 0 ); + // Birth Year/Month/Day + u16 year; + u8 month; + u8 day; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetBirthday( &year, &month, &day ) ); + NN_TEST_ASSERT_EQUAL( year, TEST_ACTSLV_BIRTH_YEAR ); + NN_TEST_ASSERT_EQUAL( month, TEST_ACTSLV_BIRTH_MONTH ); + NN_TEST_ASSERT_EQUAL( day, TEST_ACTSLV_BIRTH_DAY ); + // Gender + NN_TEST_ASSERT_EQUAL( nn::act::GetGender(), nn::act::GENDER_MALE ); + // IsMailAddressValidated + NN_TEST_ASSERT_EQUAL( nn::act::IsMailAddressValidated(), false ); + // Country + char country[NN_ACT_COUNTRY_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetCountry( country ) ); + NN_TEST_ASSERT_FATAL( nn::act::Strncmp( country, TEST_ACTSLV_COUNTRY, NN_ACT_COUNTRY_SIZE ) == 0 ); + // SimpleAddressId + NN_TEST_ASSERT_EQUAL( nn::act::GetSimpleAddressId(), TEST_ACTSLV_SMPLE_ADDRESS_ID ); + // Time Zone + char timeZoneId[NN_ACT_TIME_ZONE_ID_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetTimeZoneId( timeZoneId ) ); + NN_TEST_ASSERT_FATAL( nn::act::Strncmp( timeZoneId, TEST_ACTSLV_TIME_ZONE_ID, NN_ACT_TIME_ZONE_ID_SIZE ) == 0 ); + // UTC offset + NN_TEST_ASSERT_EQUAL( nn::act::GetUtcOffset(), TEST_ACTSLV_UTC_OFFSET ); + // Principal ID + NN_TEST_ASSERT_EQUAL( nn::act::GetPrincipalId(), TEST_ACTSLV_PID ); + // Nfs Passwordシ亥セゥ譌ァ縺輔l縺ェ縺シ + char nfsPassword[NN_ACT_NFS_PASSWORD_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetNfsPassword( nfsPassword ) ); + NN_TEST_ASSERT_FATAL( nn::act::Strncmp( nfsPassword, "", NN_ACT_NFS_PASSWORD_SIZE ) == 0 ); + // EciVirtualAccountシ亥セゥ譌ァ縺輔l縺ェ縺シ + // NeedsToDownloadMiiImageシ亥セゥ譌ァ縺輔l縺ェ縺シ + // MiiImageUrl + char miiImageUrl[NN_ACT_MII_IMAGE_URL_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetMiiImageUrlEx( miiImageUrl, 1 ) ); + ACT_TEST_ASSERT( nn::act::Strncmp( miiImageUrl, TEST_ACTSLV_MII_IMAGE_URL, NN_ACT_MII_IMAGE_URL_SIZE ) == 0 ); + // Account Password Hashシ亥セゥ譌ァ縺輔l縺ェ縺シ + // Is Password Cached Enabled + NN_TEST_ASSERT_EQUAL( nn::act::IsPasswordCacheEnabled(), false ); + // Account Password Cacheシ亥セゥ譌ァ縺輔l縺ェ縺シ + // NnasType, NfsType, NfsNo + nn::act::NnasType nnasType; + nn::act::NfsType nfsType; + u8 nfsNo; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetHostServerSettings( &nnasType, &nfsType, &nfsNo, 1 ) ); + NN_TEST_ASSERT_EQUAL( nnasType, TEST_ACTSLV_NNASTYPE ); + NN_TEST_ASSERT_EQUAL( nfsType, TEST_ACTSLV_NFSTYPE ); + NN_TEST_ASSERT_EQUAL( nfsNo, TEST_ACTSLV_NFSNO ); + // NnasSubDmain, NnasNfsEnv + char nnasSubDomain[NN_ACT_NNAS_SUB_DOMAIN_SIZE]; + char nnasNfsEnv[NN_ACT_NNAS_NFS_ENV_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetHostServerSettings( nnasSubDomain, nnasNfsEnv, 1 ) ); + // UploadedAccountInfoVersionシ亥セゥ譌ァ縺輔l縺ェ縺シ + // FpLocalAccountId + NN_TEST_ASSERT_EQUAL( nn::act::GetFpLocalAccountId(), nn::friends::GetMyLocalAccountId() ); + // LastAuthenticationResult + ACT_TEST_ASSERT_RESULT_EQUAL( nn::act::ResultUnauthenticatedAfterSalvage(), nn::act::GetLastAuthenticationResult() ); + // AssignedAccountIdシ亥セゥ譌ァ縺輔l縺ェ縺シ + // AssignedPrincipalIdシ亥セゥ譌ァ縺輔l縺ェ縺シ + // IsServerAccountDeletedシ亥セゥ譌ァ縺輔l縺ェ縺シ + // MiiImageLastModifiedDateシ亥セゥ譌ァ縺輔l縺ェ縺シ + // IsCommitted + NN_TEST_ASSERT_EQUAL( nn::act::IsCommitted(), true ); + } + + { + // Persistent ID List + // Default Account Persistent ID + // CommonTransferableIdBase + // common UUID + nn::act::Uuid uuid; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetUuidEx( &uuid, NN_ACT_SLOT_NO_COMMON, NN_ACT_UNIQUE_ID_ADMIN ) ); + ACT_TEST_ASSERT_FATAL( memcmp( uuid.data, orgCommonUuid.data, sizeof( nn::act::Uuid ) ) == 0 ); + // IsApplicationUpdateRequired + // NnasType, NfsType, NfsNo + nn::act::NnasType nnasType; + nn::act::NfsType nfsType; + u8 nfsNo; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetDefaultHostServerSettings( &nnasType, &nfsType, &nfsNo ) ); + NN_TEST_ASSERT_EQUAL( nnasType, TEST_ACTSLV_NNASTYPE ); + NN_TEST_ASSERT_EQUAL( nfsType, TEST_ACTSLV_NFSTYPE ); + NN_TEST_ASSERT_EQUAL( nfsNo, TEST_ACTSLV_NFSNO ); + // NnasSubDmain, NnasNfsEnv + char nnasSubDomain[NN_ACT_NNAS_SUB_DOMAIN_SIZE]; + char nnasNfsEnv[NN_ACT_NNAS_NFS_ENV_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetDefaultHostServerSettings( nnasSubDomain, nnasNfsEnv ) ); + } + + { + // Persistent ID Head + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CreateConsoleAccount() ); + NN_TEST_ASSERT_EQUAL( nn::act::GetNumOfAccounts(), 2 ); + NN_TEST_ASSERT_EQUAL( nn::act::GetPersistentIdEx( 2 ), 0x80000001 ); + } + + { + // Counter + } + + { + // ClockSequence + nn::act::Uuid uuid; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetUuidEx( &uuid, 2, NN_ACT_UNIQUE_ID_ADMIN ) ); + u32 clockSqeunce = ( ( uuid.data[8] & 0x3f ) << 8 ) | uuid.data[9]; + u32 orgClockSequence = ( ( orgUuid.data[8] & 0x3f ) << 8 ) | orgUuid.data[9]; + NN_TEST_ASSERT_EQUAL( clockSqeunce, orgClockSequence + 64 ); + // Last Time + + } + + // act 邨ゆコ + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::Finalize() ); + } + + void TestSalvage( void ) + { + ACT_TEST_ASSERT_FATAL( m_IsInitialized ); + + TestSalvage_ValidateImpl(); + } + + virtual void FinalizeSuite( void ) + { + nn::fs::Unmount( "sdmc:" ); + + nn::friends::Finalize(); + } +}; + +#define SYSTEM_HEAP_SIZE 0x00100000 + +extern "C" void nninitStartUp(void) +{ + // 繝偵シ繝怜晄悄蛹門捉繧翫r繧ェ繝シ繝舌Λ繧、繝 + nn::test::InitializeAllocator(SYSTEM_HEAP_SIZE); +} + +NN_TEST_DEFINE_MAIN(ActTestSalvageValidation) Index: Horizon/sources/libraries/actslv/tests/CTR/test_salvageValidationUS.cpp =================================================================== --- Horizon/sources/libraries/actslv/tests/CTR/test_salvageValidationUS.cpp (revision 0) +++ Horizon/sources/libraries/actslv/tests/CTR/test_salvageValidationUS.cpp (working copy) @@ -0,0 +1,315 @@ +サソ/*---------------------------------------------------------------------------* + Project: Horizon + File: test_salvage.cpp + + Copyright 2010-2011 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + +* ---------------------------------------------------------------------------*/ + +#include "../test_actUtil.h" + +#include +#include + +#include +#include + +#include + +namespace +{ +nn::os::Thread s_Thread; +nn::os::StackBuffer<32 * 1024> s_StackBuffer; +nn::os::Event beginEvent; +nn::os::Event endEvent; + +const size_t BUFFER_SIZE = 4 * 1024; +u8 s_ActInitializeBuffer[BUFFER_SIZE] NN_ATTRIBUTE_ALIGN( 4096 ); + +void UnmountThreadFunc( void* ptrArg ) +{ + NN_UNUSED_VAR( ptrArg ); + + nn::act::KeepUnmountAndBlock( &beginEvent, &endEvent ); +} +} + +class ActTestSalvageValidation : public nn::test::Suite +{ +private: + bool m_IsInitialized; + int : 24; + +public: + ActTestSalvageValidation() + : m_IsInitialized( false ) + { + SUITE_NAME("ActTestSalvageValidation"); + + TEST_ADD( ActTestSalvageValidation::TestSalvage ); + } + +private: + virtual bool InitializeSuite( void ) + { + InitializeSuiteImpl(); + + return true; + } + + void InitializeSuiteImpl( void ) + { + nn::cfg::CTR::init::Initialize(); + nn::fs::Initialize(); + nn::ac::CTR::InitializeInternal(); + + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::friends::Initialize() ); + + nn::ac::Config config; + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::CreateDefaultConfig( &config ) ); + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::ac::Connect( config ) ); + + ACT_EXIT_INITIALIZE_IF_FAILURE( nn::fs::MountSdmc( "sdmc:" ) ); + + nn::act::Initialize(); + + m_IsInitialized = true; + } + + void TestSalvage_ValidateImpl( void ) + { + nn::act::Uuid orgUuid; + nn::act::Uuid orgCommonUuid; + { + nn::fs::FileStream stream( "sdmc:/salvage_paramsUS", true ); + stream.Read( &orgUuid, sizeof(nn::act::Uuid ) ); + stream.Read( &orgCommonUuid, sizeof(nn::act::Uuid ) ); + } + // act 蛻晄悄蛹 + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::InitializeAdmin( reinterpret_cast( s_ActInitializeBuffer ), 4 * 1024 ) ); + + ACT_TEST_ASSERT( nn::act::GetNumOfAccounts() == 1 ); + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::LoadConsoleAccount( 1, nn::act::LOAD_OPTION_NO_PASSWORD_CHECK, NULL ) ); + + // ******************************** + // 讀懆ィシ + // ******************************** + + // Slot ID + ACT_TEST_ASSERT_FATAL( nn::act::GetSlotNo() == 1 ); + { + // Persistent ID + ACT_TEST_ASSERT_FATAL( nn::act::GetPersistentIdEx( 1 ) == 0x80000000 ); + // Transferable ID Base + u64 unscrambledTransferableId = UnscrambleTransferableId( nn::act::GetTransferableId( TEST_UNIQUE_ID ) ); + NN_TEST_ASSERT_EQUAL( ( unscrambledTransferableId & COUNTER_MASK ) >> MaskToShift( COUNTER_MASK ), 0 ); + NN_TEST_ASSERT_EQUAL( ( unscrambledTransferableId & UNIQUE_ID_MASK ) >> MaskToShift( UNIQUE_ID_MASK ), 0 ); + NN_TEST_ASSERT_EQUAL( ( unscrambledTransferableId & PLATFORM_CODE_MASK ) >> MaskToShift( PLATFORM_CODE_MASK ), 0 ); + NN_TEST_ASSERT_EQUAL( ( unscrambledTransferableId & DEVICE_ID_MASK ) >> MaskToShift( DEVICE_ID_MASK ), 0 ); + // account UUID + nn::act::Uuid uuid; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetUuidEx( &uuid, NN_ACT_SLOT_NO_CURRENT, NN_ACT_UNIQUE_ID_ADMIN ) ); + { + const u8* p = uuid.data; + TEST_REPORT( "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] ); + } + { + const u8* p = orgUuid.data; + TEST_REPORT( "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] ); + } + ACT_TEST_ASSERT_FATAL( memcmp( uuid.data, orgUuid.data, sizeof( nn::act::Uuid ) ) == 0 ); + // Parental Control Slot No + NN_TEST_ASSERT_EQUAL( nn::act::GetParentalControlSlotNo(), 1 ); + // Mii Data + nn::mii::StoreData mii; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetMii( &mii ) ); + { + u8 i = NN_MII_STORE_DATA_SIZE; + TEST_REPORT( "salvaged Mii Data\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], + mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i], mii.data[--i] + ); + i = NN_MII_STORE_DATA_SIZE; + TEST_REPORT( "original Mii Data\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n" + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], + TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i], TEST_ACTSLV_MII_DATA.data[--i] + ); + } + // Author ID 縺悟、牙喧縺吶k + //ACT_TEST_ASSERT_FATAL( memcmp( mii.data, TEST_ACTSLV_MII_DATA.data, 96 ) == 0 ); + // Mii Name + char16 miiName[NN_ACT_MII_NAME_SIZE] = {L'\0'}; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetMiiName( miiName ) ); + ACT_TEST_ASSERT_FATAL( nn::act::Strncmp( miiName, TEST_ACTSLV_MII_NAME_US, NN_ACT_MII_NAME_SIZE ) == 0 ); + // Is Mii Updated + NN_TEST_ASSERT_EQUAL( nn::act::IsMiiUpdated(), false ); + // Account ID + char accountId[NN_ACT_ACCOUNT_ID_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetAccountId( accountId ) ); + ACT_TEST_ASSERT_FATAL( strncmp( accountId, TEST_ACTSLV_ACCOUNT_ID_US, NN_ACT_ACCOUNT_ID_SIZE ) == 0 ); + // Birth Year/Month/Day + u16 year; + u8 month; + u8 day; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetBirthday( &year, &month, &day ) ); + NN_TEST_ASSERT_EQUAL( year, TEST_ACTSLV_BIRTH_YEAR_US ); + NN_TEST_ASSERT_EQUAL( month, TEST_ACTSLV_BIRTH_MONTH ); + NN_TEST_ASSERT_EQUAL( day, TEST_ACTSLV_BIRTH_DAY ); + // Gender + NN_TEST_ASSERT_EQUAL( nn::act::GetGender(), nn::act::GENDER_MALE ); + // IsMailAddressValidated + NN_TEST_ASSERT_EQUAL( nn::act::IsMailAddressValidated(), false ); + // Country + char country[NN_ACT_COUNTRY_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetCountry( country ) ); + NN_TEST_ASSERT_FATAL( nn::act::Strncmp( country, TEST_ACTSLV_COUNTRY_US, NN_ACT_COUNTRY_SIZE ) == 0 ); + // SimpleAddressId + NN_TEST_ASSERT_EQUAL( nn::act::GetSimpleAddressId(), TEST_ACTSLV_SMPLE_ADDRESS_ID_US ); + // Time Zone + char timeZoneId[NN_ACT_TIME_ZONE_ID_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetTimeZoneId( timeZoneId ) ); + NN_TEST_ASSERT_FATAL( nn::act::Strncmp( timeZoneId, TEST_ACTSLV_TIME_ZONE_ID_US, NN_ACT_TIME_ZONE_ID_SIZE ) == 0 ); + // UTC offset + NN_TEST_ASSERT_EQUAL( nn::act::GetUtcOffset(), TEST_ACTSLV_UTC_OFFSET_US ); + // Principal ID + NN_TEST_ASSERT_EQUAL( nn::act::GetPrincipalId(), TEST_ACTSLV_PID_US ); + // Nfs Passwordシ亥セゥ譌ァ縺輔l縺ェ縺シ + char nfsPassword[NN_ACT_NFS_PASSWORD_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetNfsPassword( nfsPassword ) ); + NN_TEST_ASSERT_FATAL( nn::act::Strncmp( nfsPassword, "", NN_ACT_NFS_PASSWORD_SIZE ) == 0 ); + // EciVirtualAccountシ亥セゥ譌ァ縺輔l縺ェ縺シ + // NeedsToDownloadMiiImageシ亥セゥ譌ァ縺輔l縺ェ縺シ + // MiiImageUrl + char miiImageUrl[NN_ACT_MII_IMAGE_URL_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetMiiImageUrlEx( miiImageUrl, 1 ) ); + ACT_TEST_ASSERT( nn::act::Strncmp( miiImageUrl, TEST_ACTSLV_MII_IMAGE_URL_US, NN_ACT_MII_IMAGE_URL_SIZE ) == 0 ); + // Account Password Hashシ亥セゥ譌ァ縺輔l縺ェ縺シ + // Is Password Cached Enabled + NN_TEST_ASSERT_EQUAL( nn::act::IsPasswordCacheEnabled(), false ); + // Account Password Cacheシ亥セゥ譌ァ縺輔l縺ェ縺シ + // NnasType, NfsType, NfsNo + nn::act::NnasType nnasType; + nn::act::NfsType nfsType; + u8 nfsNo; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetHostServerSettings( &nnasType, &nfsType, &nfsNo, 1 ) ); + NN_TEST_ASSERT_EQUAL( nnasType, TEST_ACTSLV_NNASTYPE ); + NN_TEST_ASSERT_EQUAL( nfsType, TEST_ACTSLV_NFSTYPE ); + NN_TEST_ASSERT_EQUAL( nfsNo, TEST_ACTSLV_NFSNO ); + // NnasSubDmain, NnasNfsEnv + char nnasSubDomain[NN_ACT_NNAS_SUB_DOMAIN_SIZE]; + char nnasNfsEnv[NN_ACT_NNAS_NFS_ENV_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetHostServerSettings( nnasSubDomain, nnasNfsEnv, 1 ) ); + // UploadedAccountInfoVersionシ亥セゥ譌ァ縺輔l縺ェ縺シ + // FpLocalAccountId + NN_TEST_ASSERT_EQUAL( nn::act::GetFpLocalAccountId(), nn::friends::GetMyLocalAccountId() ); + // LastAuthenticationResult + ACT_TEST_ASSERT_RESULT_EQUAL( nn::act::ResultUnauthenticatedAfterSalvage(), nn::act::GetLastAuthenticationResult() ); + // AssignedAccountIdシ亥セゥ譌ァ縺輔l縺ェ縺シ + // AssignedPrincipalIdシ亥セゥ譌ァ縺輔l縺ェ縺シ + // IsServerAccountDeletedシ亥セゥ譌ァ縺輔l縺ェ縺シ + // MiiImageLastModifiedDateシ亥セゥ譌ァ縺輔l縺ェ縺シ + // IsCommitted + NN_TEST_ASSERT_EQUAL( nn::act::IsCommitted(), true ); + } + + { + // Persistent ID List + // Default Account Persistent ID + // CommonTransferableIdBase + // common UUID + nn::act::Uuid uuid; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetUuidEx( &uuid, NN_ACT_SLOT_NO_COMMON, NN_ACT_UNIQUE_ID_ADMIN ) ); + ACT_TEST_ASSERT_FATAL( memcmp( uuid.data, orgCommonUuid.data, sizeof( nn::act::Uuid ) ) == 0 ); + // IsApplicationUpdateRequired + // NnasType, NfsType, NfsNo + nn::act::NnasType nnasType; + nn::act::NfsType nfsType; + u8 nfsNo; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetDefaultHostServerSettings( &nnasType, &nfsType, &nfsNo ) ); + NN_TEST_ASSERT_EQUAL( nnasType, TEST_ACTSLV_NNASTYPE ); + NN_TEST_ASSERT_EQUAL( nfsType, TEST_ACTSLV_NFSTYPE ); + NN_TEST_ASSERT_EQUAL( nfsNo, TEST_ACTSLV_NFSNO ); + // NnasSubDmain, NnasNfsEnv + char nnasSubDomain[NN_ACT_NNAS_SUB_DOMAIN_SIZE]; + char nnasNfsEnv[NN_ACT_NNAS_NFS_ENV_SIZE]; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetDefaultHostServerSettings( nnasSubDomain, nnasNfsEnv ) ); + } + + { + // Persistent ID Head + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::CreateConsoleAccount() ); + NN_TEST_ASSERT_EQUAL( nn::act::GetNumOfAccounts(), 2 ); + NN_TEST_ASSERT_EQUAL( nn::act::GetPersistentIdEx( 2 ), 0x80000001 ); + } + + { + // Counter + } + + { + // ClockSequence + nn::act::Uuid uuid; + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::GetUuidEx( &uuid, 2, NN_ACT_UNIQUE_ID_ADMIN ) ); + u32 clockSqeunce = ( ( uuid.data[8] & 0x3f ) << 8 ) | uuid.data[9]; + u32 orgClockSequence = ( ( orgUuid.data[8] & 0x3f ) << 8 ) | orgUuid.data[9]; + NN_TEST_ASSERT_EQUAL( clockSqeunce, orgClockSequence + 64 ); + // Last Time + + } + + // act 邨ゆコ + ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( nn::act::Finalize() ); + } + + void TestSalvage( void ) + { + ACT_TEST_ASSERT_FATAL( m_IsInitialized ); + + TestSalvage_ValidateImpl(); + } + + virtual void FinalizeSuite( void ) + { + nn::fs::Unmount( "sdmc:" ); + + nn::friends::Finalize(); + } +}; + +#define SYSTEM_HEAP_SIZE 0x00100000 + +extern "C" void nninitStartUp(void) +{ + // 繝偵シ繝怜晄悄蛹門捉繧翫r繧ェ繝シ繝舌Λ繧、繝 + nn::test::InitializeAllocator(SYSTEM_HEAP_SIZE); +} + +NN_TEST_DEFINE_MAIN(ActTestSalvageValidation) Index: Horizon/sources/libraries/actslv/tests/OMakefile =================================================================== --- Horizon/sources/libraries/actslv/tests/OMakefile (revision 0) +++ Horizon/sources/libraries/actslv/tests/OMakefile (working copy) @@ -0,0 +1,19 @@ + +#!/usr/bin/env omake +#---------------------------------------------------------------------------- +# Project: Horizon +# File: OMakefile +# +# Copyright (C)2009-2013 Nintendo Co., Ltd. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Rev: 50823 $ +#---------------------------------------------------------------------------- + +.SUBDIRS: CTR + Index: Horizon/sources/libraries/actslv/tests/test_actUtil.h =================================================================== --- Horizon/sources/libraries/actslv/tests/test_actUtil.h (revision 0) +++ Horizon/sources/libraries/actslv/tests/test_actUtil.h (working copy) @@ -0,0 +1,700 @@ +サソ/*---------------------------------------------------------------------------* + + Copyright (C)2012 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + *---------------------------------------------------------------------------*/ + +#ifndef NN_ACT_TEST_UTIL_H_ +#define NN_ACT_TEST_UTIL_H_ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define ENABLE_TEST_REPORT 1 +#define ENABLE_TEST_SLEEP_FOR_CACHE 0 + +#if ENABLE_TEST_REPORT +#define TEST_REPORT( fmt, ... ) \ + do { \ + PrintCalendarTime(); \ + NN_LOG( fmt, ##__VA_ARGS__ ); \ + } while(0) + +#else +#define TEST_REPORT( fmt, ... ) +#endif + +#if ENABLE_TEST_SLEEP_FOR_CACHE +#define ACT_SLEEP_FOR_CACHE_UPDATE( time ) WaitSeconds( time ) +#else +#define ACT_SLEEP_FOR_CACHE_UPDATE( time ) +#endif + +#define ACT_EXIT_INITIALIZE_IF_FALSE( exp ) \ + do { \ + bool actExitInitializeIfFailBool_ = (exp); \ + if ( !actExitInitializeIfFailBool_ ) \ + { \ + NN_LOG("Initialization Failed. [%s] File: %s Line: %d\n", #exp, __FILE__, __LINE__); \ + return; \ + } \ + } while(0) + +#define ACT_EXIT_INITIALIZE_IF_FAILURE( exp ) \ + do { \ + nn::Result actExitInitializeIfFailureResult_ = (exp); \ + if ( actExitInitializeIfFailureResult_.IsFailure() ) \ + { \ + NN_LOG("Initialization Failed. [%s] File:%s Line:%d\n", #exp, __FILE__, __LINE__); \ + NN_DBG_PRINT_RESULT( actExitInitializeIfFailureResult_ ); \ + return; \ + } \ + } while(0) + +#define ACT_TEST_ASSERT( exp ) \ + do { \ + bool exp_ = (exp); \ + if ( !exp_ ) \ + { \ + PrintCalendarTime(); \ + NN_LOG("\n"); \ + NN_TEST_FAIL( exp ); \ + } \ + } while(0) + +#define ACT_TEST_ASSERT_FATAL( exp ) \ + do { \ + bool exp_ = (exp); \ + if ( !exp_ ) \ + { \ + PrintCalendarTime(); \ + NN_LOG("\n"); \ + NN_TEST_ASSERT_FATAL( exp ); \ + } \ + } while(0) + +#define ACT_TEST_ASSERT_RESULT_SUCCESS( result ) \ + do { \ + nn::Result nn_testex_assert_result = result; \ + if ( nn_testex_assert_result.IsFailure() ) \ + { \ + PrintCalendarTime(); \ + NN_LOG("\n"); \ + nn::test::PrintResult(nn_testex_assert_result); \ + NN_TEST_FAIL( result ); \ + } \ + } while(0) + +#define ACT_TEST_ASSERT_RESULT_SUCCESS_FATAL( result ) \ + do { \ + nn::Result nn_testex_assert_result = result; \ + if ( nn_testex_assert_result.IsFailure() ) \ + { \ + PrintCalendarTime(); \ + NN_LOG("\n"); \ + nn::test::PrintResult( nn_testex_assert_result ); \ + NN_TEST_FAIL_FATAL( result ); \ + } \ + } while(0) + +#define ACT_TEST_ASSERT_RESULT_EQUAL( expect, result ) \ + do { \ + nn::Result nn_testex_assert_result = result; \ + if( nn_testex_assert_result.GetValue() != expect.Value ) \ + { \ + PrintCalendarTime(); \ + NN_LOG("\n"); \ + nn::test::PrintResult( nn_testex_assert_result ); \ + NN_TEST_FAIL( expect.Value == (result).GetValue() ); \ + } \ + } while(0) + +#define ACT_TEST_ASSERT_RESULT_EQUAL_FATAL( expect, result ) \ + do { \ + nn::Result nn_testex_assert_result = result; \ + if( nn_testex_assert_result.GetValue() != expect.Value ) \ + { \ + PrintCalendarTime(); \ + NN_LOG("\n"); \ + nn::test::PrintResult( nn_testex_assert_result ); \ + NN_TEST_FAIL_FATAL( expect.Value == (result).GetValue() ); \ + } \ + } while(0) + + +#define NELEMS( array ) (sizeof(array) / sizeof(array[0])) + + +namespace +{ + char testNnasSubDomain[NN_ACT_NNAS_SUB_DOMAIN_SIZE] = ""; + char testNnasNfsEnv[NN_ACT_NNAS_NFS_ENV_SIZE] = ""; + + const char TEST_ACT_SUB_DOMAIN[] = NN_ACT_SUB_DOMAIN_SYSTEM_DEV; + const char TEST_ACT_NFS_ENV[] = "J1"; + const char16 TEST_XML_ROOT_PATH[] = L"rom:/xml"; + const char16 TEST_SAVE_ROOT_PATH[] = L"rom:/save"; + const char16 TEST_SDMC_ROOT_PATH[] = L"sdmc:/test"; + const char TEST_ACCOUNT_PASSWORD[] = "Password0"; + const char TEST_ACCOUNT_PASSWORD2[] = "Password1"; + const char TEST_MAIL_ADDRESS[] = "takeuchi_takaaki@nintendo.co.jp"; + const char TEST_MAIL_ADDRESS2[] = "nakano_keigo@nintendo.co.jp"; + const u16 TEST_BIRTH_YEAR = 2004; + const u8 TEST_BIRTH_MONTH = 2; + const u8 TEST_BIRTH_DAY = 29; + const nn::fnd::DateTime TEST_BIRTH_DATE = nn::fnd::DateTime(2004, 2,29); + const nn::act::Gender TEST_GENDER = nn::act::GENDER_MALE; + const u8 TEST_COUNTRY = 1; + const u8 TEST_COUNTRY_COPPA = 49; + const u8 TEST_COUNTRY_SIMPLE_ADDRESS = 110; + const char TEST_COUNTRY_STR[] = "JP"; + const char TEST_COUNTRY_STR_COPPA[] = "US"; + const char TEST_COUNTRY_STR_SIMPLE_ADDRESS[] = "GB"; + const u8 TEST_AREA = 0x04; + const u32 TEST_SIMPLE_ADDRESS_ID = NN_ACT_SIMPLE_ADDRESS_ID( TEST_COUNTRY, TEST_AREA ); + const u32 TEST_SIMPLE_ADDRESS_ID_SIMPLE_ADDRESS = 0x6E040000; // NN_ACT_SIMPLE_ADDRESS_ID( TEST_COUNTRY_SIMPLE_ADDRESS, TEST_AREA ); + const u32 TEST_SIMPLE_ADDRESS_ID_SIMPLE_ADDRESS_1 = 0x6E050000; + const u32 TEST_SIMPLE_ADDRESS_ID_SIMPLE_ADDRESS_2 = 0x6E070000; + const u32 TEST_SIMPLE_ADDRESS_ID_SIMPLE_ADDRESS_WIIU = 0x6E050000; + const u32 TEST_SIMPLE_ADDRESS_ID_SIMPLE_ADDRESS_WIIU_1 = 0x6E060000; + const u32 TEST_SIMPLE_ADDRESS_ID_SIMPLE_ADDRESS_WIIU_2 = 0x6E030000; + const nn::act::TimeZone TEST_TIME_ZONE = { "Asia/Tokyo", "(UTC+09:00) Osaka, Sapporo, Tokyo", 9ULL * 60 * 60 * 1000 * 1000 }; // TODO + const nn::act::TimeZone TEST_TIME_ZONE2 = { "Pacific/Midway", "Midway Island, Samoa", -11LL * 60 * 60 * 1000 * 1000 }; // TODO + const nn::act::EulaInfo TEST_AGREED_EULA = { "JP", "jp", 0x0100 }; + const nn::act::EulaInfo TEST_AGREED_EULA_SIMPLE_ADDRESS = { "GB", "en", 0x0100 }; + const nn::act::EulaInfo TEST_AGREED_EULA_SIMPLE_ADDRESS_AU = { "AU", "en", 0x0100 }; + const nn::fnd::DateTime TEST_AGREED_EULA_TIME = nn::fnd::DateTime(2012, 4, 27, 12, 0, 0); + const u32 TEST_UNIQUE_ID = 0x00000U; + const u32 TEST_GAME_ID = 0x00000000U; + const char TEST_NFS_PASSWORD[] = "TestNfsPassword0"; + const char16 TEST_MII_NAME[] = L"ABCDEFGHIJ"; + const char16 TEST_MII_NAME2[] = L"BCDEFGHIJK"; + + const char TEST_CLIENT_ID_INDEPENDENT[] = "6fbbd052f6785f7514ed69272ba2f94e"; + + const char TEST_WRONG_ACCOUNT_ID[] = "wrongid"; + const char TEST_WRONG_ACCOUNT_PASSWORD[] = "wrongpassword"; + const char TEST_TOO_LONG_ACCOUNT_ID[] = "ctrwiiutest234567"; + const char TEST_TOO_LONG_ACCOUNT_PASSWORD[] = "abcdefgHIJ1234567"; + const char TEST_TOO_LONG_MAIL_ADDRESS[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.com"; + + const u8 TEST_UNDEFINED_COUNTRY = 0; + const u8 TEST_UNDEFINED_LANGUAGE = 255; + + const u64 DEVICE_ID_MASK = 0x00000003FFFFFFFFULL; + const u64 PLATFORM_CODE_MASK = 0x0000003C00000000ULL; + const u64 UNIQUE_ID_MASK = 0x003FFFC000000000ULL; + const u64 COUNTER_MASK = 0xFFC0000000000000ULL; + + const u8 PLATFORM_CODE_WIIU = 1U; + + const char ALL_MARKS[] = { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~', ' ' }; + const char ACCEPTABLE_MARKS_FOR_ACCOUNT_PASSWORD[] = { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' }; + const char ACCEPTABLE_MARKS_FOR_MAIL_ADDRESS_LOCAL[] = { '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '/', '=', '?', '^', '_', '`', '{', '|', '}', '~' }; + const char ACCEPTABLE_MARKS_FOR_MAIL_ADDRESS_DOMAIN[] = { '-', '.' }; + const char ACCEPTABLE_MARKS_FOR_ACCOUNT_ID[] = { '-', '.' , '_' }; + + const char TEST_SUB_DOMAIN_LENGTH32[] = "max_sub_domain_name_length_is32."; + const char TEST_SUB_DOMAIN_TOO_LONG[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."; + + // salvage + const char TEST_ACTSLV_SERIAL_ID[] = "EJM90901256"; + const u32 TEST_ACTSLV_DEVICE_ID = 462573; + const char TEST_ACTSLV_ACCOUNT_ID[] = "ido305"; + const char TEST_ACTSLV_ACCOUNT_ID_US[] = "ido305us"; + const char TEST_ACTSLV_PASSWORD[] = "Password"; + const char TEST_ACTSLV_EMAIL_ADDRESS[] = "ido@dummy.nintendo.net"; + const u16 TEST_ACTSLV_BIRTH_YEAR = 1977; + const u16 TEST_ACTSLV_BIRTH_YEAR_US = 2010; + const u8 TEST_ACTSLV_BIRTH_MONTH = 12; + const u8 TEST_ACTSLV_BIRTH_DAY = 1; + const nn::mii::StoreData TEST_ACTSLV_MII_DATA = { + 0x03,0x00,0x00,0x30,0xf1,0xd8,0xd7,0x86,0x7c,0x44,0x70,0x50,0x93,0xc3,0x99,0x3e, + 0xd8,0x6b,0xf7,0x1a,0x93,0x34,0x00,0x00,0x00,0x60,0x6c,0x30,0x61,0x30,0x64,0x30, + 0x6d,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x4c, + 0x14,0x00,0x37,0x06,0x16,0x69,0x44,0x18,0x36,0x34,0x47,0x14,0x81,0x12,0x13,0x68, + 0x0d,0x00,0x00,0x29,0x05,0x52,0x48,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x08, + }; + const char16 TEST_ACTSLV_MII_NAME[] = L"縺ャ縺。縺、縺ュ"; + const char16 TEST_ACTSLV_MII_NAME_US[] = L"Mii 3"; + const char TEST_ACTSLV_COUNTRY[] = "JP"; + const char TEST_ACTSLV_COUNTRY_US[] = "US"; + const u32 TEST_ACTSLV_SMPLE_ADDRESS_ID = NN_ACT_SIMPLE_ADDRESS_ID( 1, 1 ); + const u32 TEST_ACTSLV_SMPLE_ADDRESS_ID_US = NN_ACT_SIMPLE_ADDRESS_ID( 49, 4 ); + const char TEST_ACTSLV_TIME_ZONE_ID[] = "Asia/Tokyo"; + const char TEST_ACTSLV_TIME_ZONE_ID_US[] = "Pacific/Midway"; + s64 TEST_ACTSLV_UTC_OFFSET = 9LL * 60 * 60 * 1000 * 1000; + s64 TEST_ACTSLV_UTC_OFFSET_US = -11LL * 60 * 60 * 1000 * 1000; + u32 TEST_ACTSLV_PID = 1799742571; + u32 TEST_ACTSLV_PID_US = 1799731913; + const char TEST_ACTSLV_MII_IMAGE_URL[] = "https://library-dev-mii-secure.account.nintendo.net/1zfrkm3zf1vzz_standard.tga"; + const char TEST_ACTSLV_MII_IMAGE_URL_US[] = "https://library-dev-mii-secure.account.nintendo.net/29jzrshgc6sdt_standard.tga"; + const nn::act::NnasType TEST_ACTSLV_NNASTYPE = nn::act::NNAS_TYPE_LIBRARY_DEV; + const nn::act::NfsType TEST_ACTSLV_NFSTYPE = nn::act::NFS_TYPE_TEST; + const u8 TEST_ACTSLV_NFSNO = 1; + + u8 eulaBuffer[820000]; // TODO + + u8 s_heapBuffer[1024 * 1024]; + nn::fnd::ThreadSafeExpHeap s_ExpHeap; + + void SetOnetimeAccountId( char* pAccountId ); + void SetDummyMiiData( nn::mii::StoreData* pMiiStoreData ); + void SetDummyMiiData2( nn::mii::StoreData* pMiiStoreData ); + + u64 Transpose( u64 value ); + u64 Unmask( u64 transferableId ); + u16 UnscrambleCounter( u64 transferableId ); + u32 UnscrambleUniqueId( u64 transferableId ); + u8 UnscramblePlatformCode( u64 transferableId ); + u64 UnscrambleDeviceId( u64 transferableId ); + + void SetOnetimeAccountId( char* pAccountId ) + { + u64 ms = (nn::fnd::DateTime::GetNow() - nn::fnd::DateTime(1999,1,1)).GetMilliSeconds(); // OSTicksToMilliseconds( OSGetTime() ); + + for ( int i = 11; i >= 0; --i ) + { + pAccountId[i] = (ms & 0xF) + 'A'; + ms >>= 4; + } + pAccountId[12] = '\0'; + } + + void SetDummyMiiData( nn::mii::StoreData* pMiiStoreData ) + { + for ( int i = 0; i < sizeof(*pMiiStoreData); ++i ) + { + pMiiStoreData->data[i] = (i + 1) & 0xFF; + } + } + + void SetDummyMiiData2( nn::mii::StoreData* pMiiStoreData ) + { + for ( int i = 0; i < sizeof(*pMiiStoreData); ++i ) + { + pMiiStoreData->data[i] = (i + 2) & 0xff; + } + } + + void AdjustMiiData( nn::mii::StoreData* pMiiStoreData, bool adjustCrc, bool adjustAuthorId, bool adjustBirthPlatform = false ) + { + nn::mii::StoreDataAccessor storeDataAccessor( pMiiStoreData ); + + if ( adjustAuthorId ) + { + nn::mii::AuthorId authorId; + nn::mii::GetHomeAuthorId( &authorId ); + + storeDataAccessor.SetAuthorId( authorId ); + } + + if ( adjustBirthPlatform ) + { + if ( storeDataAccessor.GetBirthPlatform() > nn::mii::BIRTH_PLATFORM_CTR && + storeDataAccessor.GetBirthPlatform() <= nn::mii::BIRTH_PLATFORM_MAX ) + { + storeDataAccessor.SetBirthPlatform( nn::mii::BIRTH_PLATFORM_CTR ); + } + } + + if ( adjustCrc ) + { + storeDataAccessor.RecalculateCrc(); + } + } + + void InitializeExtHeap() + { + s_ExpHeap.Initialize(reinterpret_cast(s_heapBuffer), 1024 * 1024); + } + + void InitializeRomfs() + { + const size_t ROMFS_BUFFER_SIZE = 1024 * 64; + static char buffer[ROMFS_BUFFER_SIZE]; + NN_UTIL_PANIC_IF_FAILED( + nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE)); + } + + void InitializeTestUtil() + { + InitializeExtHeap(); + InitializeRomfs(); + } + + void FinalizeExpHeap() + { + s_ExpHeap.Finalize(); + } + + void FinalizeTestUtil() + { + FinalizeExpHeap(); + } + + void LoadMiiImages( u8** ppMiiImageBufferList, u32* pMiiImageSizeList ) + { +#if 0 + const char* MII_IMAGE_FILE_PATH_LIST[MII_IMAGE_TYPE_NUM] = { + "/vol/content/test/nn/act/account.tga", // ACT_MII_IMAGE_TYPE_CAFE_MENU + "/vol/content/test/nn/act/face_normal.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_NORMAL + "/vol/content/test/nn/act/face_happy.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_HAPPY + "/vol/content/test/nn/act/face_like.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_LIKE + "/vol/content/test/nn/act/face_surprised.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_SURPRIZED + "/vol/content/test/nn/act/face_frustrated.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_FRUSTRATED + "/vol/content/test/nn/act/face_puzzled.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_PUZZLED + "/vol/content/test/nn/act/body.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_LARGE_NORMAL + "/vol/content/test/nn/act/account.tga.zlib" // ACT_MII_IMAGE_TYPE_CAFE_MENU_COMPRESSED + }; +#endif + const char* MII_IMAGE_FILE_PATH_LIST[nn::act::MII_IMAGE_TYPE_NUM] = { + "rom:/account.tga", // ACT_MII_IMAGE_TYPE_CAFE_MENU + "rom:/face_normal.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_NORMAL + "rom:/face_happy.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_HAPPY + "rom:/face_like.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_LIKE + "rom:/face_surprised.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_SURPRIZED + "rom:/face_frustrated.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_FRUSTRATED + "rom:/face_puzzled.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_SMALL_PUZZLED + "rom:/body.tga.zlib", // ACT_MII_IMAGE_TYPE_OLV_LARGE_NORMAL + "rom:/account.tga.zlib" // ACT_MII_IMAGE_TYPE_CAFE_MENU_COMPRESSED + }; + + for ( int i = 0; i < nn::act::MII_IMAGE_TYPE_NUM; ++i ) + { + ppMiiImageBufferList[i] = NULL; + } + + nn::Result result = nn::ResultSuccess(); + for ( int i = 0; i < nn::act::MII_IMAGE_TYPE_NUM && result.IsSuccess(); ++i ) + { + nn::fs::FileReader reader; + result = reader.TryInitialize(MII_IMAGE_FILE_PATH_LIST[i]); + + if ( result.IsSuccess() ) + { + size_t fileSize = reader.GetSize(); + + ppMiiImageBufferList[i] = reinterpret_cast(s_ExpHeap.Allocate(fileSize)); + pMiiImageSizeList[i] = fileSize; + + reader.Read(ppMiiImageBufferList[i], fileSize); + + reader.Finalize(); + } + } + } + + void FreeMiiImages( u8** ppMiiImageBufferList ) + { + for ( int i = 0; i < nn::act::MII_IMAGE_TYPE_NUM; ++i ) + { + if ( ppMiiImageBufferList[i] ) + { + s_ExpHeap.Free(ppMiiImageBufferList[i]); + } + } + } + + u64 Transpose( u64 value ) + { + u32 x = value & 0xFFFFFFFFU; + u32 y = (value >> 32) & 0xFFFFFFFFU; + + x = ((x << 24) & 0xFF000000U) | ((x << 8) & 0x00FF0000U) | ((x >> 8) & 0x0000FF00U) | ((x >> 24) & 0x000000FFU); + y = ((y << 24) & 0xFF000000U) | ((y << 8) & 0x00FF0000U) | ((y >> 8) & 0x0000FF00U) | ((y >> 24) & 0x000000FFU); + + u32 t; + + t = (x ^ (x >> 7)) & 0x00AA00AAU; x = x ^ t ^ (t << 7); + t = (y ^ (y >> 7)) & 0x00AA00AAU; y = y ^ t ^ (t << 7); + + t = (x ^ (x >> 14)) & 0x0000CCCCU; x = x ^ t ^ (t << 14); + t = (y ^ (y >> 14)) & 0x0000CCCCU; y = y ^ t ^ (t << 14); + + t = (x & 0xF0F0F0F0U) | ((y >> 4) & 0x0F0F0F0FU); + y = ((x << 4) & 0xF0F0F0F0U) | (y & 0x0F0F0F0FU); + x = t; + + x = ((x << 24) & 0xFF000000U) | ((x << 8) & 0x00FF0000U) | ((x >> 8) & 0x0000FF00U) | ((x >> 24) & 0x000000FFU); + y = ((y << 24) & 0xFF000000U) | ((y << 8) & 0x00FF0000U) | ((y >> 8) & 0x0000FF00U) | ((y >> 24) & 0x000000FFU); + + return (u64)x | ((u64)y << 32); + } + + u64 Unmask( u64 transferableId ) + { + u64 mask; + + mask = (transferableId >> 38) & 0x007ULL; + mask |= mask << 54; + mask |= (((transferableId ^ mask) >> 48) & 0x1C0ULL) | (((transferableId ^ mask) << 3) & 0x038ULL); + mask |= (mask << 63) | (mask << 54) | (mask << 45) | (mask << 36) | (mask << 27) | (mask << 18) | (mask << 9); + mask &= 0xFFFFFE3FFFFFFFFFULL; + + return transferableId ^ mask; + } + + u64 UnscrambleTransferableId( u64 transferableId ) + { + return Unmask( Transpose( transferableId ) ); + } + + int MaskToShift( u64 mask ) + { + mask = ~mask & (mask - 1); + + mask = (mask & 0x5555555555555555ULL) + ((mask >> 1) & 0x5555555555555555ULL); + mask = (mask & 0x3333333333333333ULL) + ((mask >> 2) & 0x3333333333333333ULL); + mask = (mask & 0x0F0F0F0F0F0F0F0FULL) + ((mask >> 4) & 0x0F0F0F0F0F0F0F0FULL); + mask = (mask & 0x00FF00FF00FF00FFULL) + ((mask >> 8) & 0x00FF00FF00FF00FFULL); + mask = (mask & 0x0000FFFF0000FFFFULL) + ((mask >> 16) & 0x0000FFFF0000FFFFULL); + mask = (mask & 0x00000000FFFFFFFFULL) + ((mask >> 32) & 0x00000000FFFFFFFFULL); + + return static_cast(mask); + } + + void CastToLowerCase( char* pDst, const char* pSrc ) + { + char c; + + do + { + c = *pSrc++; + + if ( c >= 'A' && c <= 'Z' ) + { + c += 'a' - 'A'; + } + + *pDst++ = c; + } while ( c ); + } + + bool IsLeapYear( u16 year ) + { + return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; + } +/* + bool SetNetworkTimeForDebug( u16 year, u8 month, u8 day, s64 offset = 0 ) + { + static const u8 DAYS_OF_MONTH_COMMON[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + static const u8 DAYS_OF_MONTH_LEAP[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + u64 year64 = static_cast(year) - 2000; + + u64 days = year64 * 365 + (year64 + 3) / 4 - (year64 + 99) / 100 + (year64 + 399) / 400; + + const u8* pDaysOfMonth = IsLeapYear( year ) ? DAYS_OF_MONTH_LEAP : DAYS_OF_MONTH_COMMON; + + for ( int i = 0; i < month - 1; ++i ) + { + days += pDaysOfMonth[i]; + } + + days += day - 1; + + nn::fnd::DateTime networkTime = nn::fnd::DateTime(2000, 1, 1) + nn::fnd::TimeSpan::FromDays(days) + nn::fnd::TimeSpan::FromMicroSeconds(offset); + + nn::Result result = nn::act::SetNetworkTime( networkTime ); + if ( result.IsFailure() ) + { + NN_DBG_PRINT_RESULT( result ); + } + + return result.IsSuccess(); + } + + bool SetParentalAccountNetCommunicationOnGameForDebug(bool isRestricted, u8 slotNo) + { + NN_UNUSED_VAR(isRestricted); + NN_UNUSED_VAR(slotNo); + + return true; + } +*/ + nn::Result CreateFpAccount(u8 fpSlotNo = 0, const char* nnasNfsEnv = NULL) + { + // FP 縺ョ遨コ縺縺ヲ縺繧 SlotNo 繧呈、懃エ「 + if (fpSlotNo == 0) + { + bool occupiedFplocalAccountId[NN_ACT_SLOT_NUM + 1] = {false}; + for (int i = 1; i <= NN_ACT_SLOT_NUM; ++i) + { + if( nn::act::GetFpLocalAccountIdEx(i) != NN_FRIENDS_INVALID_LOCAL_ACCOUNT_ID ) + { + occupiedFplocalAccountId[nn::act::GetFpLocalAccountIdEx(i)] = true; + } + } + + for (int i = 1; i <= NN_ACT_SLOT_NUM; ++i ) + { + if (!occupiedFplocalAccountId[i]) + { + fpSlotNo = i; + break; + } + } + } + + nn::friends::UnloadLocalAccount(); + + nn::friends::NasType nasType = nn::friends::NAS_TEST; + nn::friends::NfsType nfsType = nn::friends::NFS_UNKNOWN; + + char nnasSubDomain[NN_ACT_NNAS_SUB_DOMAIN_SIZE] = {0}; + char defaultNnasNfsEnv[NN_ACT_NNAS_NFS_ENV_SIZE] = {0}; + + nn::act::GetDefaultHostServerSettings(nnasSubDomain, defaultNnasNfsEnv); + + char nfsEnvChar = nnasNfsEnv ? nnasNfsEnv[0] : defaultNnasNfsEnv[0]; + + switch ( nfsEnvChar ) + { + case 'L': + nfsType = nn::friends::NFS_LIVE; + break; + case 'D': + nfsType = nn::friends::NFS_DEV; + break; + case 'T': + nfsType = nn::friends::NFS_TEST; + break; + case 'S': + nfsType = nn::friends::NFS_STAGING; + break; + case 'I': + nfsType = nn::friends::NFS_INTERNAL; + break; + case 'J': + nfsType = nn::friends::NFS_JOIN; + break; + case 'X': + nfsType = nn::friends::NFS_SANDBOX; + break; + default: + break; + } + + char nfsNumberChar = nnasNfsEnv ? nnasNfsEnv[1] : defaultNnasNfsEnv[1]; + u8 nfsNumber = nfsNumberChar - '0'; + + NN_LOG("nfsEnvChar %c nfsNumber %d\n", nfsEnvChar, nfsNumber); + + return nn::friends::CreateLocalAccount( fpSlotNo, nasType, nfsType, nfsNumber ); + } + + nn::Result LoadFpAccount() + { + u8 localAccountId = nn::act::GetFpLocalAccountId(); + + nn::friends::UnloadLocalAccount(); + + nn::Result result = nn::friends::LoadLocalAccount( localAccountId ); + + return result; + } + + void PrintCalendarTime() + { +// nn::fnd::TimeSpan interval; +// nn::Result result = nn::friends::CTR::GetServerTimeInterval(&interval); +// +// if(result.IsSuccess()) +// { +// nn::fnd::DateTime serverTime = nn::fnd::DateTime::GetNow() + interval; +// +// NN_LOG( "[%04d-%02d-%02d %02d:%02d:%02d UTC] ", serverTime.GetYear(), +// serverTime.GetMonth(), +// serverTime.GetDay(), +// serverTime.GetHour(), +// serverTime.GetMinute(), +// serverTime.GetSecond()); +// } +// else // NFS 縺ォ繝ュ繧ー繧、繝ウ縺励※縺縺ェ縺縺ィ縺 + { +// NN_LOG("Failed to nn::friends::CTR::GetServerTimeInterval() %x.", result.GetPrintableBits()); + nn::fnd::DateTime serverTime = nn::fnd::DateTime::GetNow(); + + NN_LOG( "[%04d-%02d-%02d %02d:%02d:%02d RTC] ", serverTime.GetYear(), + serverTime.GetMonth(), + serverTime.GetDay(), + serverTime.GetHour(), + serverTime.GetMinute(), + serverTime.GetSecond()); + } + } + + void WaitSeconds( u32 seconds ) + { + static const char* anim[] = { "-", "/", "|", "\\" }; + + if ( seconds ) + { + TEST_REPORT( "Waiting... " ); + + do + { + NN_LOG( "\b%s", anim[seconds % 4] ); + nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromSeconds(1)); + } while ( --seconds ); + + NN_LOG( "\n" ); + } + } + + int wstrncmp( const char16* pWstr1, const char16* pWstr2, size_t size ) + { + while ( size-- ) + { + if ( *pWstr1 > *pWstr2 ) + { + return 1; + } + else if ( *pWstr1 < *pWstr2 ) + { + return -1; + } + else if ( *pWstr1 == L'\0' ) + { + return 0; + } + + ++pWstr1; + ++pWstr2; + } + + return 0; + } +} + + + +#endif // NN_ACT_TEST_UTIL_H_ Index: Horizon/sources/libraries/actslv/util/act_StringContainerForSalvage.h =================================================================== --- Horizon/sources/libraries/actslv/util/act_StringContainerForSalvage.h (revision 0) +++ Horizon/sources/libraries/actslv/util/act_StringContainerForSalvage.h (working copy) @@ -0,0 +1,43 @@ +/*---------------------------------------------------------------------------* + +Copyright (C)2012 Nintendo. All rights reserved. + +These coded instructions, statements, and computer programs contain +proprietary information of Nintendo of America Inc. and/or Nintendo +Company Ltd., and are protected by Federal copyright law. They may +not be disclosed to third parties or copied or duplicated in any form, +in whole or in part, without the prior written consent of Nintendo. + +*---------------------------------------------------------------------------*/ + +#ifndef LIBRARIES_ACTSLV_UTIL_STRING_CONTAINER_FOR_SALVAGE_H_ +#define LIBRARIES_ACTSLV_UTIL_STRING_CONTAINER_FOR_SALVAGE_H_ + +#include "act_StringContainer.h" + +#define NN_ACT_DEVICE_ATTRIBUTE_NAME_LENGTH_MAX (64) +#define NN_ACT_DEVICE_ATTRIBUTE_NAME_SIZE NN_ACT_DEVICE_ATTRIBUTE_NAME_LENGTH_MAX+1 +#define NN_ACT_DEVICE_ATTRIBUTE_VALUE_LENGTH_MAX (128) +#define NN_ACT_DEVICE_ATTRIBUTE_VALUE_SIZE NN_ACT_DEVICE_ATTRIBUTE_VALUE_LENGTH_MAX+1 + +#define NN_ACT_NNAS_XML_DATE_SIZE sizeof("2000-01-01T00:00:00") +#define NN_ACT_NNAS_XML_DATE_LENGTH_MAX NN_ACT_NNAS_XML_DATE_SIZE-1 + +#define NN_FRIENDS_PASSWORD_MAX_LENGTH (31) +//#define NN_FRIENDS_PASSWORD_MAX_SIZE NN_FRIENDS_PASSWORD_MAX_LENGTH+1 + +namespace nn +{ +namespace act +{ +namespace detail +{ +typedef StringContainer DeviceAttributeName; +typedef StringContainer DeviceAttributeValue; +typedef StringContainer NnasXmlDateContainer; +typedef StringContainer FriendsPasswordContainer; +} +} +} + +#endif // LIBRARIES_ACTSLV_UTIL_STRING_CONTAINER_FOR_SALVAGE_H_ Index: Horizon/sources/libraries/OMakefile =================================================================== --- Horizon/sources/libraries/OMakefile (revision 56466) +++ Horizon/sources/libraries/OMakefile (working copy) @@ -118,6 +118,7 @@ mii neia zlib + actslv if $(not $(and $(defined CTR_WITHOUT_ADDINS), $(equal $(CTR_WITHOUT_ADDINS), true))) .SUBDIRS: $(exist-dirs \