ctr_Repair/trunk/ConsoleDataMigration/ConsoleRestore/ConsoleRestore.cpp
N2614 89b4c7fdba RTCデータを移行するように
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@14 385bec56-5757-e545-9c3a-d8741f4650f1
2011-02-04 04:16:00 +00:00

458 lines
14 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: ConsoleRestore.cpp
Copyright (C)2009 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 <nn.h>
#include <nn/version.h>
#include <nn/ptm/CTR/ptm_ApiSysmenu.h>
#include <nn/mcu.h>
#include <nn/cfg/CTR/cfg_Api.h>
#include <nn/cfg/CTR/cfg_ApiInit.h>
#include <nn/cfg/CTR/cfg_ApiSys.h>
#include <nn/ps.h>
#include <nn/nwm.h>
#include <nn/ac.h>
#include <nn/friends.h>
#include <nn/friends/CTR/friends_ApiPrivate.h>
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
#include <nn/fs/fs_ApiSysSaveData.h>
#include <nn/cfg/CTR/cfg_ApiNor.h>
#include <nn/am/am_ApiSystemMenu.h>
#include <nn/os/os_SharedInfo.h>
#include "demo.h"
#include <vector>
#include <string>
#include "ConsoleRestore.h"
#include "Controller.h"
#include "SimplePlayer.h"
#include "CommonLogger.h"
#include "SDMountManager.h"
#include "HeapManager.h"
// svnリビジョン埋め込み用
#include "version.h"
#ifndef RESTORE_VERSION_NUM
#define RESOTRE_VERSION_NUM 0
#endif
namespace {
// グラフィックスに割り当てるメモリ
const size_t s_GxHeapSize = 0x800000;
demo::RenderSystemDrawing s_RenderSystem;
nn::Handle s_McuSession;
const u16 PROGRESS_MAX_LINES = 160;
// バッテリ残量
u8 batteryRemain = 100;
// シリアルナンバー
u8 s_SerialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
// シリアルナンバーが読めるかどうか
bool s_CanReadSerialNumber = false;
// IVSへのポインタ
void* sp_Ivs;
size_t s_SizeofIvs;
// IVSが読めるかどうか
bool s_CanReadIvs = false;
} // namespace <unnamed>
namespace ConsoleRestore{
u32 GetRenderTarget(u32 target, bool flip = false);
bool IsAdapterConnected()
{
return nn::ptm::CTR::GetAdapterState() == nn::ptm::CTR::ADAPTERSTATE_CONNECTED;
}
bool IsBatteryLower()
{
return batteryRemain <= 10;
}
bool CanReadIVS()
{
return s_CanReadIvs;
}
bool CanReadSerialNumber()
{
return s_CanReadSerialNumber;
}
void GetSerialNumber(u8** serial, size_t* size)
{
*serial = s_SerialNo;
*size = nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN;
}
void GetIvs(void** ivs, size_t* size)
{
*ivs = sp_Ivs;
*size = s_SizeofIvs;
}
u32 GetRenderTarget(u32 target, bool flip)
{
if(flip)
{
if(target == NN_GX_DISPLAY0)
{
return NN_GX_DISPLAY1;
}
else
{
return NN_GX_DISPLAY0;
}
}
else
{
return target;
}
}
void FinalizeAll()
{
common::Logger::GetLoggerInstance()->Finalize();
// アンマウント
nn::fs::Unmount("nand:");
nn::fs::Unmount("sdmc:");
s_RenderSystem.Finalize();
nn::mcu::CTR::FinalizeHwCheck(&s_McuSession);
nn::friends::detail::Finalize();
nn::ps::Finalize();
nn::ptm::CTR::FinalizeForSystemMenu();
nn::cfg::CTR::system::Finalize();
nn::cfg::CTR::init::Finalize();
nn::hid::Finalize();
nn::fs::Finalize();
nn::applet::PrepareToCloseApplication();
nn::applet::CloseApplication();
}
nn::Handle GetMcuHandle()
{
return s_McuSession;
}
extern "C" void nnMain(void)
{
nn::Result result;
// os の初期化
nn::os::Initialize();
// fs の初期化
nn::fs::Initialize();
// appletの初期化
nn::applet::Enable( false );
// hid の初期化
result = nn::hid::Initialize();
NN_UTIL_PANIC_IF_FAILED(result);
// cfg の初期化
nn::cfg::CTR::init::Initialize();
nn::cfg::CTR::system::Initialize();
// 時計設定用ptm初期化
nn::ptm::CTR::InitializeForSystemMenu();
// ps の初期化
nn::ps::Initialize();
// friendsの初期化
result = nn::friends::detail::Initialize();
// mcuの初期化
nn::mcu::CTR::InitializeHwCheck(&s_McuSession);
nn::mcu::CTR::HwCheck mcu(s_McuSession);
// amの初期化
nn::am::InitializeForSystemMenu();
// ヒープの確保
common::HeapManager::GetHeap()->Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(), nn::os::ALLOCATE_OPTION_LINEAR);
// RenderSystem の準備
uptr heapForGx = reinterpret_cast<uptr>(common::HeapManager::GetHeap()->Allocate(s_GxHeapSize));
s_RenderSystem.Initialize(heapForGx, s_GxHeapSize);
// サウンドスレッドの起動
common::InitializeSimplePlayer();
// ログ描画の初期化
common::Logger::GetLoggerInstance()->Initialize(CONSOLE_WIDTH, CONSOLE_HEIGHT, CONSOLE_MAX_LINE, &s_RenderSystem);
// RenderSystemを作ってからログが出せる
common::Logger::InitializeEjectThread();
common::Logger::SetEjectHandler(OnSdEjected);
COMMON_LOGGER("\n");
COMMON_LOGGER("CTR Console Restore start\n");
// ボタン入力
nn::hid::PadReader s_PadReader;
nn::hid::PadStatus padStatus;
// データの準備
// 完全性検証SEEDの取得
result = nn::fs::MountSpecialArchive("nand:", nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
if (result.IsSuccess())
{
nn::fs::FileInputStream fis;
result = fis.TryInitialize(L"nand:/private/movable.sed");
if (result.IsSuccess())
{
s64 fileSize = fis.GetSize();
s32 ret;
void* addr = NULL;
addr = common::HeapManager::GetHeap()->Allocate(fileSize);
if (addr != NULL)
{
sp_Ivs = addr;
s_SizeofIvs = fileSize;
result = fis.TryRead(&ret, addr, fileSize);
if (result.IsSuccess())
{
s_CanReadIvs = true;
}
}
}
fis.Finalize();
}
// 一旦アンマウントしておく
nn::fs::Unmount("nand:");
// リージョンの取得
nn::cfg::CTR::CfgRegionCode region;
region = nn::cfg::CTR::GetRegion();
// シリアルナンバーの取得
std::memset(s_SerialNo, '\0',
nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
result = nn::cfg::CTR::system::GetSerialNo(s_SerialNo);
if(result.IsSuccess())
{
s_CanReadSerialNumber = true;
}
common::Logger::GetLoggerInstance()->PrintResultIfFailed(result, __LINE__);
// デバイスIDの取得
bit32 deviceId;
result = nn::ps::CTR::GetDeviceId(&deviceId);
common::Logger::GetLoggerInstance()->PrintResultIfFailed(result, __LINE__);
// MACアドレスの取得
nn::nwm::Mac mac;
char8 macAddress[nn::nwm::Mac::MAC_STRING_SIZE];
result = nn::nwm::GetMacAddress(mac);
common::Logger::GetLoggerInstance()->PrintResultIfFailed(result, __LINE__);
mac.GetString(macAddress);
common::Logger::GetLoggerInstance()->PrintResultIfFailed(result, __LINE__);
// フレンドコードの取得
nn::friends::CTR::FriendKey friendKey;
result = nn::friends::CTR::GetMyFriendKey(&friendKey);
common::Logger::GetLoggerInstance()->PrintResultIfFailed(result , __LINE__);
u64 friendCode = nn::friends::CTR::FriendKeyToFriendCode(friendKey);
// ReadOnlySharedInfoの取得
const nn::os::ReadOnlySharedInfo& rosi = nn::os::GetReadOnlySharedInfo();
// 情報出力
COMMON_LOGGER("CTR Console Restore %s Rev.%s\n", __DATE__, RESTORE_VERSION_NUM);
COMMON_LOGGER("System Ver. %d.%d (Rev.%d)\n", rosi.versionHi, rosi.versionLo, rosi.revision);
COMMON_LOGGER("System Region %s\n", nn::cfg::CTR::GetRegionCodeA3(region));
COMMON_LOGGER("Serial Number %s\n", s_SerialNo);
COMMON_LOGGER("Device ID %X\n", deviceId);
COMMON_LOGGER("MAC Address %s\n", macAddress);
COMMON_LOGGER("Friend Code %04u-%04u-%04u\n",
static_cast<u32>(friendCode / 100000000ULL % 10000ULL),
static_cast<u32>(friendCode / 10000ULL % 10000ULL),
static_cast<u32>(friendCode % 10000ULL) );
bool flip = false;
bool continueRestore = false;
for(;;)
{
bool nextStep = false;
s_PadReader.ReadLatest(&padStatus);
// AまたはSTARTボタンで進行
if(padStatus.trigger & nn::hid::BUTTON_A ||
padStatus.trigger & nn::hid::BUTTON_START)
{
nextStep = true;
}
// LまたはRボタンで上下画面フリップ
if(padStatus.trigger & nn::hid::BUTTON_R ||
padStatus.trigger & nn::hid::BUTTON_L)
{
flip = !flip;
}
// コンソールスクロール
if(padStatus.hold & nn::hid::BUTTON_UP)
{
common::Logger::GetLoggerInstance()->ScrollUp();
}
// コンソールスクロール
if(padStatus.hold & nn::hid::BUTTON_DOWN)
{
common::Logger::GetLoggerInstance()->ScrollDown();
}
if(padStatus.hold & nn::hid::BUTTON_LEFT)
{
common::Logger::GetLoggerInstance()->ScrollToBegin();
}
if(padStatus.hold & nn::hid::BUTTON_RIGHT)
{
common::Logger::GetLoggerInstance()->ScrollToEnd();
}
// 情報更新
// バッテリ
mcu.GetBatteryRemain(&batteryRemain);
// ACアダプタ
std::string adapterState;
if(IsAdapterConnected())
{
adapterState += ::std::string("Connected");
}
else
{
adapterState += ::std::string("Not Connected");
}
// 操作用メッセージ
// 進捗確認メッセージを兼ねる?
::std::vector<std::string> operationMessage;
ControlState(operationMessage, nextStep, continueRestore);
// デフォルトで上画面に描画するもの
s_RenderSystem.SetRenderTarget(GetRenderTarget(NN_GX_DISPLAY0, flip));
if(IsRestoreSucceeded())
{
s_RenderSystem.SetClearColor(GetRenderTarget(NN_GX_DISPLAY0, flip), SUCCESS_COLOR);
}
else if(IsRestoreFailed())
{
s_RenderSystem.SetClearColor(GetRenderTarget(NN_GX_DISPLAY0, flip), FAIL_COLOR);
}
else
{
s_RenderSystem.SetClearColor(GetRenderTarget(NN_GX_DISPLAY0, flip), NORMAL_COLOR);
}
s_RenderSystem.Clear();
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
u32 line = 0;
s_RenderSystem.DrawText(0, line++ * 10, "CTR Console Restore %s Rev.%s", __DATE__, RESTORE_VERSION_NUM);
s_RenderSystem.SetColor(0.1f, 0.25f, 0.1f);
s_RenderSystem.FillRectangle(0 , (line-1) * 10, 400 , 10);
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
s_RenderSystem.DrawText(0, line++ * 10, "");
s_RenderSystem.DrawText(0, line++ * 10, "System Ver. %d.%d (Rev.%d)", rosi.versionHi, rosi.versionLo, rosi.revision);
s_RenderSystem.DrawText(0, line++ * 10, "System Region %s", nn::cfg::CTR::GetRegionCodeA3(region));
s_RenderSystem.DrawText(0, line++ * 10, "Serial No. %s", s_SerialNo);
s_RenderSystem.DrawText(0, line++ * 10, "Device ID %X", deviceId);
s_RenderSystem.DrawText(0, line++ * 10, "MAC Address %s", macAddress);
s_RenderSystem.DrawText(0, line++ * 10, "Friend Code %04u-%04u-%04u",
static_cast<u32>(friendCode / 100000000ULL % 10000ULL),
static_cast<u32>(friendCode / 10000ULL % 10000ULL),
static_cast<u32>(friendCode % 10000ULL) );
s_RenderSystem.DrawText(0, line++ * 10, "Battery %d%%", batteryRemain);
s_RenderSystem.DrawText(0, line++ * 10, "AC Adaper %s", adapterState.c_str());
s_RenderSystem.DrawText(0, line++ * 10, "Progress %02d%%", GetProgress());
s_RenderSystem.SetColor(0.f, 0.2f, 0.f);
s_RenderSystem.DrawLine(19 * 8, (line-1) * 10, 19 * 8 + PROGRESS_MAX_LINES, (line-1) * 10);
s_RenderSystem.DrawLine(19 * 8, (line-1) * 10, 19 * 8, (line) * 10);
s_RenderSystem.DrawLine(19 * 8, (line) * 10, 19 * 8 + PROGRESS_MAX_LINES, (line) * 10);
s_RenderSystem.DrawLine(19 * 8 + PROGRESS_MAX_LINES, (line-1) * 10, 19 * 8 + PROGRESS_MAX_LINES, (line) * 10 + 1);
s_RenderSystem.SetColor(0.f, 0.5f, 0.f);
s_RenderSystem.FillRectangle(19 * 8 , (line-1) * 10, GetProgress() * PROGRESS_MAX_LINES / 100+ 1, 10);
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
s_RenderSystem.DrawText(0, line++ * 10, "");
::std::vector<std::string>::iterator it;
for(it = operationMessage.begin(); it != operationMessage.end(); it++)
{
s_RenderSystem.DrawText(0, line++ * 10 , "%s", it->c_str());
}
s_RenderSystem.SwapBuffers();
// デフォルトで下画面に描画するもの
s_RenderSystem.SetRenderTarget(GetRenderTarget(NN_GX_DISPLAY1, flip));
if(IsRestoreSucceeded())
{
s_RenderSystem.SetClearColor(GetRenderTarget(NN_GX_DISPLAY1, flip), SUCCESS_COLOR);
}
else if(IsRestoreFailed())
{
s_RenderSystem.SetClearColor(GetRenderTarget(NN_GX_DISPLAY1, flip), FAIL_COLOR);
}
else
{
s_RenderSystem.SetClearColor(GetRenderTarget(NN_GX_DISPLAY1, flip), NORMAL_COLOR);
}
s_RenderSystem.Clear();
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
common::Logger::GetLoggerInstance()->DrawConsole();
s_RenderSystem.SwapBuffers();
s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
// 電源長押しで終了
if ( nn::applet::IsExpectedToCloseApplication())
{
FinalizeAll();
}
}
}
}