ctr_Repair/trunk/ConsoleDataMigration/sources/common/Util.cpp
N2614 487b92c8f2 BOMを付加
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@607 385bec56-5757-e545-9c3a-d8741f4650f1
2012-01-26 05:33:57 +00:00

418 lines
10 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: Util.cpp
Copyright (C)2010-2011 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$
*---------------------------------------------------------------------------*/
#include <cctype>
#include <nn.h>
#include <nn/ptm/CTR/ptm_ApiSysmenu.h>
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
#include <nn/fs/CTR/MPCore/fs_ApiIntegrityVerificationSeed.h>
#include <nn/fs/fs_ApiSysSaveData.h>
#include <nn/cfg/CTR/cfg_Api.h>
#include <nn/cfg/CTR/cfg_ApiInit.h>
#include <nn/cfg/CTR/cfg_ApiSys.h>
#include <nn/friends.h>
#include <nn/friends/CTR/friends_ApiPrivate.h>
#include <nn/ps.h>
#include <nn/drivers/mcu/CTR/driverMcuRegisterMap.h>
#include <nn/ac.h>
#include <nn/ac/private/ac.h>
#include <nn/ac/CTR/private/ac_InternalApi.h>
#include <nn/ac/CTR/private/ac_NetworkSetting.h>
#include "Util.h"
#include "FileName.h"
#include "CommonLogger.h"
#include "HeapManager.h"
#include "FileTransfer.h"
namespace common
{
Util::Util() :
m_FriendCode(0), mp_Ivs(NULL), m_SizeofIvs(0), m_SerialNoWithoutCGLen(0), m_BatteryRemain(100), m_CanReadSerialNumber(false), m_CanReadIvs(
false), m_HasReadFriendCode(false)
{
}
Util::~Util()
{
}
void Util::InitializeForBackup()
{
Initialize();
}
void Util::InitializeForRestore()
{
Initialize();
// friendsの初期化
nn::Result result = nn::friends::detail::Initialize();
// フレンドコードの取得
nn::friends::CTR::FriendKey friendKey;
result = nn::friends::CTR::GetMyFriendKey(&friendKey);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
m_FriendCode = nn::friends::CTR::FriendKeyToFriendCode(friendKey);
m_HasReadFriendCode = true;
}
void Util::Initialize()
{
nn::Result result;
// mcuの初期化
nn::mcu::CTR::InitializeHwCheck(&m_McuSession);
mp_Mcu = new nn::mcu::CTR::HwCheck(m_McuSession);
// シリアルナンバーの取得
std::memset(m_SerialNo, '\0',
nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
result = nn::cfg::CTR::system::GetSerialNo(m_SerialNo);
if(result.IsSuccess())
{
m_CanReadSerialNumber = true;
}
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
AddCheckDigit(reinterpret_cast<char*>(m_SerialNo));
// デバイスIDの取得
result = nn::ps::CTR::GetDeviceId(&m_DeviceId);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
// リージョンの取得
m_Region = nn::cfg::CTR::GetRegion();
// バージョンの取得
common::GetSystemVersion(&m_VerData, m_Region);
// IVSの取得
ReadIvs(m_VerData.cup.majorVersion);
// MACアドレスの取得
nn::nwm::Mac mac;
result = nn::nwm::GetMacAddress(mac);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
mac.GetString(m_MacAddress);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
}
void Util::FinalizeForBackup()
{
Finalize();
}
void Util::FinalizeForRestore()
{
nn::friends::detail::Finalize();
}
void Util::Finalize()
{
nn::mcu::CTR::FinalizeHwCheck(&m_McuSession);
}
void Util::ReadIvs(u8 cupMajorVersion)
{
if (cupMajorVersion < common::CUP_MAJOR_VER_2ND_NUP)
{
nn::Result result;
// 完全性検証SEEDの取得
result = nn::fs::MountSpecialArchive(common::NAND_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
if (result.IsSuccess())
{
nn::fs::FileInputStream fis;
result = fis.TryInitialize(common::IVS_NAND_PATHNAME);
if (result.IsSuccess())
{
s64 fileSize = fis.GetSize();
s32 ret;
void* addr = NULL;
addr = ForceAllocate(fileSize);
if (addr != NULL)
{
mp_Ivs = addr;
m_SizeofIvs = fileSize;
result = fis.TryRead(&ret, addr, fileSize);
if (result.IsSuccess())
{
m_CanReadIvs = true;
}
// 後でIVSを参照するのでFreeしない
}
}
fis.Finalize();
}
// 一旦アンマウントしておく
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
}
else
{
nn::Result result;
void* pSeed = ForceAllocate(sizeof(nn::fs::CTR::IntegrityVerificationSeed));
if(pSeed != NULL)
{
result = nn::fs::CTR::ExportIntegrityVerificationSeed(
reinterpret_cast<nn::fs::CTR::IntegrityVerificationSeed*>(pSeed));
if(result.IsSuccess())
{
mp_Ivs = pSeed;
m_SizeofIvs = sizeof(nn::fs::CTR::IntegrityVerificationSeed);
m_CanReadIvs = true;
}
// 後でIVSを参照するのでFreeしない
}
}
}
// NULL終端されたシリアルナンバーを受け取る
// NULL終端された場所にチェックデジットを付加して新たにNULL終端する
void Util::AddCheckDigit(char* serial)
{
m_SerialNoWithoutCGLen = std::strlen(serial);
u8 digit = 0;
bool odd = true;
for(u8 i = m_SerialNoWithoutCGLen - 1; i > 0 && std::isdigit(serial[i]); i--)
{
if(odd)
{
digit += (serial[i] - '0') * 3;
}
else
{
digit += (serial[i] - '0');
}
odd = !odd;
}
if(digit % 10 != 0)
{
serial[m_SerialNoWithoutCGLen] = 10 - (digit % 10) + '0';
}
else
{
serial[m_SerialNoWithoutCGLen] = '0';
}
serial[m_SerialNoWithoutCGLen + 1] = '\0';
}
// /Nintendo 3DS/6ea6b9d6ab70493ea9edd8b947d5d819/853600b24760a87f534430320002544d
// から、6ea6b9d6ab70493ea9edd8b947d5d819 を取り出す
void Util::GetSaveDataDirectoryRoot(::std::string& sysSaveRoot)
{
nn::Result result;
wchar_t path[512];
result = nn::fs::GetSdmcCtrRootPath(path, sizeof(path));
COMMON_LOGGER_RETURN_VOID_IF_FAILED(result);
NN_LOG("%ls\n", path);
std::string sdmcRootPath = common::GetCharStr(path);
sysSaveRoot = sdmcRootPath.substr(sizeof("Nintendo 3DS/"), 32);
NN_LOG("saveRoot = %s\n", sysSaveRoot.c_str());
}
bool Util::IsAdapterConnected()
{
static nn::os::Tick last(0);
static bool lastResult = false;
const u8 UPDATE_INTERVAL = 100;
nn::os::Tick now = nn::os::Tick::GetSystemCurrent();
if(last == 0 || (now - last).ToTimeSpan().GetMilliSeconds() > UPDATE_INTERVAL)
{
u8 buf;
nn::Result result = mp_Mcu->ReadByReceive(nn::drivers::mcu::CTR::MCU_PERIPHERAL_STATUS_ADDR, &buf, sizeof(buf));
if(result.IsSuccess())
{
last = now;
lastResult = buf & nn::drivers::mcu::CTR::MCU_STATUS_ADAPTER_MASK;
}
}
return lastResult;
}
bool Util::IsBatteryLower()
{
m_BatteryRemain = GetBatteryRemain();
return m_BatteryRemain <= 10;
}
bool Util::CanReadIVS()
{
return m_CanReadIvs;
}
bool Util::CanReadSerialNumber()
{
return m_CanReadSerialNumber;
}
void Util::GetSerialNumber(u8** serial, size_t* size)
{
*serial = m_SerialNo;
*size = nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN;
}
u8* Util::GetSerialNumber()
{
return m_SerialNo;
}
void Util::GetSerialNumberWithoutCD(u8* serial)
{
std::memcpy(serial, m_SerialNo, nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
serial[m_SerialNoWithoutCGLen] = '\0';
}
void Util::GetIvs(void** ivs, size_t* size)
{
*ivs = mp_Ivs;
*size = m_SizeofIvs;
}
bit32 Util::GetDeviceId()
{
return m_DeviceId;
}
u8 Util::GetCupMajorVersion()
{
return m_VerData.cup.majorVersion;
}
u8 Util::GetCupMinorVersion()
{
return m_VerData.cup.minorVersion;
}
u8 Util::GetCupMicroVersion()
{
return m_VerData.cup.microVersion;
}
u8 Util::GetNupVersion()
{
return m_VerData.nup.majorVersion;
}
nn::Handle Util::GetMcuHandle()
{
return m_McuSession;
}
u32 Util::GetBatteryRemain()
{
u8 remain;
mp_Mcu->GetBatteryRemain(&remain);
return remain;
}
u64 Util::GetInfraDeviceId()
{
bit64 infraDeviceId;
infraDeviceId = m_DeviceId + common::INFRA_DEVICE_ID_OFFSET;
return infraDeviceId;
}
u64 Util::GetFriendcode()
{
return m_FriendCode;
}
char8* Util::GetMacAddress()
{
return m_MacAddress;
}
nn::cfg::CTR::CfgRegionCode Util::GetRegion()
{
return m_Region;
}
const char* Util::GetRegionCodeA3()
{
return nn::cfg::GetRegionCodeA3(m_Region);
}
void Util::GetVersionData(common::VerDef* version)
{
*version = m_VerData;
}
bool Util::HasReadFriendCode()
{
return m_HasReadFriendCode;
}
nn::Result InitializeNetwork(void)
{
nn::Result result;
nn::ac::Config config;
result = nn::ac::InitializeInternal();
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
// 接続要求用のパラメータを作成
result = nn::ac::CreateDefaultConfig(&config);
if (result.IsFailure())
{
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
return result;
}
// デバッグ用に接続テストを無効化
nn::ac::DebugSetNetworkArea(&config, nn::ac::NETWORK_AREA_LAN);
// 接続要求を発行
result = nn::ac::ConnectWithoutEula(config);
if (result.IsFailure())
{
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
return result;
}
return nn::ResultSuccess();
}
nn::Result FinalizeNetwork(void)
{
nn::Result result;
// 接続要求用のパラメータを作成
result = nn::ac::Close();
NN_UTIL_RETURN_IF_FAILED(result);
result = nn::ac::FinalizeInternal();
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
return nn::ResultSuccess();
}
}