mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@769 385bec56-5757-e545-9c3a-d8741f4650f1
2157 lines
69 KiB
C++
2157 lines
69 KiB
C++
/*---------------------------------------------------------------------------*
|
||
Project: Horizon
|
||
File: Controller.cpp
|
||
|
||
Copyright 2009 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.
|
||
|
||
$Rev$
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
#include <nn.h>
|
||
#include <nn/ns.h>
|
||
#include <nn/CTR/CTR_DeliverArg.h>
|
||
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
|
||
#include <nn/ptm/CTR/ptm_ApiSysmenu.h>
|
||
#include <nn/ptm/CTR/ptm_ApiSystem.h>
|
||
#include <nn/pl/CTR/pl_PlayHistoryApiSysmenu.h>
|
||
#include <nn/cfg/CTR/cfg_ApiSys.h>
|
||
#include <nn/nwm.h>
|
||
#include <nn/am/am_ApiSystemMenu.h>
|
||
|
||
#include "Controller.h"
|
||
#include "FileChecker.h"
|
||
#include "SimplePlayer.h"
|
||
#include "CommonLogger.h"
|
||
#include "Importer.h"
|
||
#include "Updater.h"
|
||
#include "NtpClient.h"
|
||
#include "TitleDownloader.h"
|
||
#include "Shop.h"
|
||
#include "Util.h"
|
||
#include "ActCompleter.h"
|
||
|
||
namespace ConsoleRestore
|
||
{
|
||
|
||
namespace
|
||
{
|
||
|
||
// ネットワーク設定ファイルを読んだかどうか
|
||
bool s_ReadSettingDone = false;
|
||
// インターネット設定を読んだ結果
|
||
bool s_ReadSettingIsSuccess = false;
|
||
// NUP専用モードかどうか
|
||
bool s_NupOnlyMode = false;
|
||
// IVS取得専用モードかどうか
|
||
bool s_GetIvsOnlyMode = false;
|
||
// SDカード確認専用モード
|
||
bool s_CheckSdOnlyMode = false;
|
||
// NUPスキップモードかどうか
|
||
bool s_SkipNupMode = false;
|
||
// プリインストール書き込みモードかどうか
|
||
bool s_DownloadPreinstallMode = false;
|
||
// 強制プリインストール書き込みモードかどうか
|
||
bool s_ForceDownloadPreinstall = false;
|
||
|
||
// 失敗サウンドを鳴らしたかどうか
|
||
bool s_PlayedFailSound = false;
|
||
|
||
// ネットワークアップデートを開始したかどうか
|
||
bool s_ExecuteFgNup = false;
|
||
// FGNUPを何回リトライしたか
|
||
u32 s_FgNupRetryCount = 0;
|
||
// 時計同期モードかどうか
|
||
bool s_IsSyncClock = false;
|
||
// TWLタイトルのダウンロードを開始したかどうか
|
||
bool s_ExecuteTwlTitleDownload = false;
|
||
// TWLタイトルのダウンロードを何回リトライしたか
|
||
u32 s_TwlTitleDownloadRetryCount = 0;
|
||
|
||
// NNA転送完了を何回リトライしたか
|
||
u32 s_NNATransferRetryCount = 0;
|
||
|
||
// プリインストールタイトルのダウンロード準備を開始したかどうか
|
||
bool s_ExecutePreparePreinstallTitleDownload = false;
|
||
// プリインストールタイトルのダウンロード準備を何回リトライしたか
|
||
u32 s_PreparePreinstallTitleDownloadRetryCount = 0;
|
||
|
||
|
||
// プリインストールタイトルのダウンロードを開始したかどうか
|
||
bool s_ExecutePreinstallTitleDownload = false;
|
||
// プリインストールタイトルのダウンロードを何回リトライしたか
|
||
u32 s_PreinstallTitleDownloadRetryCount = 0;
|
||
// プリインストールタイトルのダウンロードが成功したかどうか
|
||
bool s_PreinstallTitleDownloadSuccess = false;
|
||
|
||
// ショップ処理を開始したかどうか
|
||
bool s_ShopOperationExecuted[SHOP_OPERATION_NUM_MAX];
|
||
// ショップ処理を何回リトライしたか
|
||
u32 s_ShopOperationRetryCount[SHOP_OPERATION_NUM_MAX];
|
||
|
||
void PutAliveMessage(common::OperationMessage& operationMessage, const char* str);
|
||
bool CheckAndReadAPSetting(common::OperationMessage& operationMessage);
|
||
|
||
bool NeedsAcAdater(common::HardwareStateManager& manager)
|
||
{
|
||
return manager.IsBatteryLower() && !manager.IsAdapterConnected();
|
||
}
|
||
|
||
bool HasValidRtcData()
|
||
{
|
||
return !s_CheckSdOnlyMode && !s_NupOnlyMode && !s_GetIvsOnlyMode && !s_DownloadPreinstallMode;
|
||
}
|
||
|
||
bool HasDeviceIdFile()
|
||
{
|
||
return HasValidRtcData();
|
||
}
|
||
|
||
typedef enum RestoreState
|
||
{
|
||
STARTUP, // 初期値
|
||
INITIALIZE_CONSOLE, // セーブデータ領域のNAND初期化を行う
|
||
SERIAL_IS_NOT_IN_SD, // シリアルナンバーファイルがSDカードにないことを表示
|
||
WAIT_START_UPDATE, // アップデート開始入力待ち
|
||
WAIT_START_IMPORT, // 書き込み開始入力待ち
|
||
WAIT_START_SYNC_CLOCK, // 時計合わせ開始入力待ち
|
||
IMPORT_RTC, // RTC同期
|
||
UPDATE_IN_PROGRESS, // アップデート中
|
||
UPDATE_DONE, // アップデート完了
|
||
NUP_ONLY_WAIT_SD_EJECT, // NUP_ONLYモードでSDカード抜き待ち
|
||
NUP_ONLY_WAIT_NEXT, // NUP_ONLYモードでキー入力待ち
|
||
WAIT_START_TRANSFER_ACCOUNT, // アカウント転送開始入力まち
|
||
TRANSFER_ACCOUNT, // アカウント転送を完了させる
|
||
TRANSFER_ACCOUNT_DONE, // アカウント転送完了
|
||
DOWNLOAD_IVS, // インフラからIVSを取得する
|
||
DOWNLOAD_IVS_DONE, // インフラからIVSを取得完了
|
||
DOWNLOAD_IVS_WAIT_NEXT, // IVS取得モードでキー入力待ち
|
||
CHECK_IVS, // IVSとSDカードのセーブデータディレクトリの一致を確認
|
||
CHECK_SD_DIRECTORY, // SDカードのIVS依存ディレクトリを探す
|
||
CHECK_SD_DIRECTORY_SUCCESS, // SDカードのIVS依存ディレクトリチェック完了
|
||
CHECK_SD_DIRECTORY_FAIL, // SDカードのIVS依存ディレクトリが見つからなかった
|
||
WAIT_START_DELETE_ACCOUNT, // ショップアカウント削除開始入力待ち,
|
||
DELETE_ACCOUNT, // ショップアカウントを削除する
|
||
DELETE_ACCOUNT_DONE, // ショップアカウント削除完了
|
||
SYNC_TICKET, // eTicketを同期する
|
||
READ_FILELIST, // ファイル一覧の読み込み
|
||
RESTORE_TWL_NAND, // TWL NANDの書き込み中
|
||
RESTORE_TWL_SOUND, // TWLサウンドの書き込み中
|
||
RESTORE_TWL_PHOTO, // TWL写真の書き込み中
|
||
RESTORE_IN_PROGRESS, // 書き込み中
|
||
POST_RESTORE, // 書き込み後の処理
|
||
RESTORE_DONE, // 書き込み完了
|
||
REBOOTING, // 再起動を行う
|
||
ERASE, // 削除処理を行う
|
||
COMPLETE_ACT, // actアカウント移行完了処理を行う
|
||
COMPLETE_ACT_WAIT, // actアカウント移行完了処理の完了待ち
|
||
RESTORE_CAL, // cfgの一部をcal値で上書きする
|
||
REPAIR_SIMPLE_ADDRESS_ID, // 本ツールで過去に破壊されたSimpleAddress.idを修正する
|
||
TIME_ADJUST, // 時計あわせを行う
|
||
DOWNLOAD_TWL, // TWLアプリ本体をダウンロードする
|
||
WAIT_SD_EJECT, // SDカードぬき待ち
|
||
ALL_DONE, // すべて完了
|
||
INITIALIZE_AND_SHUTDOWN, // 本体初期化後にシャットダウン中
|
||
FAIL, // 失敗
|
||
|
||
// プリインストールダウンロードモード
|
||
PREINSTALL_WAIT_START_UPDATE, // NUP開始待ち
|
||
PREINSTALL_WAIT_SYNC_TICKET, // 開始ボタン待ち
|
||
PREINSTALL_DELETE_PERSONALIZED_TICKET, // Personalized eTicketの削除
|
||
PREINSTALL_WAIT_USER_SD_INSERT, // ユーザSD挿入待ち
|
||
PREINSTALL_WAIT_USER_SD_INSERT_WAIT_NEXT, // ユーザSD挿入後Aボタン待ち
|
||
PREINSTALL_CHECK_USER_SD_INSERT, // ユーザSDの挿入チェック
|
||
PREINSTALL_CHECK_USER_SD, // ユーザSDのチェック
|
||
PREINSTALL_CHECK_USER_SD_ALREADY_INITIALIZED, // ユーザSDのチェック、既に初期化済み
|
||
PREINSTALL_CHECK_SD_FAIL, // ユーザSDのチェック失敗
|
||
PREINSTALL_FAIL_CHECK_REPAIR_SD, // ユーザSDのチェック失敗後の修理用SDのチェック
|
||
PREINSTALL_DOWNLOAD_APP, // アプリダウンロード
|
||
PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE, // アプリダウンロード失敗、空き容量不足
|
||
PREINSTALL_WAIT_USER_SD_EJECT, // ユーザSD抜き出し待ち
|
||
PREINSTALL_CHECK_REPAIR_SD_WAIT_NEXT, // 修理用SDのチェック・Aボタン待ち
|
||
PREINSTALL_CHECK_REPAIR_SD, // 修理用SDのチェック
|
||
|
||
RESTORE_STATE_MAX
|
||
} RestoreState;
|
||
|
||
enum AnnotationSound
|
||
{
|
||
ANNOTATION_SD_WRITE_PROTECT,
|
||
ANNOTATION_WIFI_OFF,
|
||
ANNOTATION_SETTING_NOT_FOUND,
|
||
ANNOTATION_INVALID_SETTING,
|
||
ANNOTATION_SERIAL_NUMBER_NOT_IN_SD,
|
||
|
||
ANNOTATION_MAX
|
||
};
|
||
|
||
bool s_PlayedCursorSound[RESTORE_STATE_MAX];
|
||
bool s_PlayedAnnotationSound[ANNOTATION_MAX];
|
||
|
||
void PlayCursorSound(RestoreState state)
|
||
{
|
||
if(!s_PlayedCursorSound[state])
|
||
{
|
||
common::PlaySound(common::SOUND_CURSOR);
|
||
s_PlayedCursorSound[state] = true;
|
||
}
|
||
}
|
||
|
||
void PlayAnnotationSound(AnnotationSound index)
|
||
{
|
||
if(!s_PlayedAnnotationSound[index])
|
||
{
|
||
common::PlaySound(common::SOUND_ANNOTATION);
|
||
s_PlayedAnnotationSound[index] = true;
|
||
}
|
||
}
|
||
|
||
#define BREAK_IF_STATE_CHANGED(saved, current) \
|
||
if(saved != current) \
|
||
{\
|
||
break;\
|
||
}\
|
||
|
||
|
||
// SD挿抜が起こらなかった時のみ次の状態に遷移する
|
||
void ChangeState(RestoreState saved, RestoreState& current, RestoreState next)
|
||
{
|
||
if(saved == current)
|
||
{
|
||
current = next;
|
||
s_PlayedCursorSound[next] = false;
|
||
}
|
||
}
|
||
|
||
// Restore状態管理
|
||
RestoreState s_RestoreState = STARTUP;
|
||
// Restoreモード管理
|
||
RestoreMode s_RestoreMode = RESTORE_MODE_RESTORE;
|
||
|
||
void CheckSdInserted(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckAcAdapter(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckSdWritable(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckApSetting(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckNupExecuted(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckDownloadIvs(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckAccountDeleted(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckAccountTransfered(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckWriteFinished(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckReadIvs(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckConsoleInitialized(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckExistsSerialNumber(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckIvsinSd(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
void CheckRegioinSd(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep);
|
||
|
||
bool DisplaySerialNumberinSD(common::OperationMessage& message)
|
||
{
|
||
u8 serial[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
|
||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(
|
||
ReadSerialNumber(serial));
|
||
|
||
::std::string serialStr(reinterpret_cast<char*>(serial));
|
||
message.Add((::std::string("Serial Number in SD : ") + serialStr).c_str());
|
||
return true;
|
||
}
|
||
|
||
|
||
// SDカード挿入チェック
|
||
void CheckSdInserted(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
if (nn::fs::IsSdmcInserted())
|
||
{
|
||
CheckAcAdapter(manager, message, goNextStep);
|
||
}
|
||
else
|
||
{
|
||
message.Add("Insert SD Card!!");
|
||
s_RestoreState = STARTUP;
|
||
}
|
||
}
|
||
|
||
// ACアダプタが必要かどうかチェック
|
||
void CheckAcAdapter(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
// ACアダプタが必要か?
|
||
if (NeedsAcAdater(manager))
|
||
{
|
||
message.Add("Connect AC Adapter!!");
|
||
s_RestoreState = STARTUP;
|
||
}
|
||
else
|
||
{
|
||
CheckSdWritable(manager, message, goNextStep);
|
||
}
|
||
}
|
||
|
||
// SDカード書き込みチェック
|
||
void CheckSdWritable(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
// SDカードに書き込みできるか?
|
||
if (nn::fs::IsSdmcWritable())
|
||
{
|
||
CheckApSetting(manager, message, goNextStep);
|
||
}
|
||
else
|
||
{
|
||
PlayAnnotationSound(ANNOTATION_SD_WRITE_PROTECT);
|
||
message.Add("Can't Write SD Card!!\n");
|
||
s_RestoreState = STARTUP;
|
||
}
|
||
}
|
||
|
||
|
||
// 設定ファイル書式チェック
|
||
void CheckApSetting(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
NN_UNUSED_VAR(manager);
|
||
NN_UNUSED_VAR(goNextStep);
|
||
|
||
if (CheckAndReadAPSetting(message))
|
||
{
|
||
s_RestoreState = IMPORT_RTC;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = STARTUP;
|
||
}
|
||
}
|
||
|
||
// NUP済みかどうかチェック
|
||
void CheckNupExecuted(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
if (common::ExistsUpdateCheckedFile())
|
||
{
|
||
if (s_NupOnlyMode)
|
||
{
|
||
s_RestoreState = WAIT_START_DELETE_ACCOUNT;
|
||
}
|
||
else if(s_DownloadPreinstallMode)
|
||
{
|
||
s_RestoreState = PREINSTALL_WAIT_SYNC_TICKET;
|
||
}
|
||
else
|
||
{
|
||
CheckAccountDeleted(manager, message, goNextStep);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// NUPを実行
|
||
if (CheckAndReadAPSetting(message))
|
||
{
|
||
if (nn::nwm::CTR::IsWifiOn())
|
||
{
|
||
if(s_DownloadPreinstallMode)
|
||
{
|
||
s_RestoreState = PREINSTALL_WAIT_START_UPDATE;
|
||
}
|
||
else
|
||
{
|
||
// ネットワークアップデートを行う
|
||
s_RestoreState = WAIT_START_UPDATE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
PlayAnnotationSound(ANNOTATION_WIFI_OFF);
|
||
message.Add("Wireless is Off\n");
|
||
s_RestoreState = STARTUP;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// インフラからIVS取得済みかチェック
|
||
void CheckDownloadIvs(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
NN_UNUSED_VAR(message);
|
||
NN_UNUSED_VAR(goNextStep);
|
||
|
||
// IVS取得確認ファイルがあるか?
|
||
if (common::ExistsDownloadIvsCheckedFile())
|
||
{
|
||
if(s_GetIvsOnlyMode)
|
||
{
|
||
s_RestoreState = DOWNLOAD_IVS_WAIT_NEXT;
|
||
}
|
||
else
|
||
{
|
||
CheckWriteFinished(manager, message, goNextStep);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
COMMON_LOGGER("Download SDCI\n");
|
||
s_RestoreState = DOWNLOAD_IVS;
|
||
}
|
||
|
||
}
|
||
|
||
// アカウント削除済みかチェック
|
||
void CheckAccountDeleted(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
// アカウント削除確認ファイルがあるか?
|
||
if (common::ExistsDeleteAccountChecked())
|
||
{
|
||
CheckAccountTransfered(manager, message, goNextStep);
|
||
}
|
||
else
|
||
{
|
||
if(HasDeviceIdFile())
|
||
{
|
||
if (ExistsDeviceIdFile().IsFailure())
|
||
{
|
||
// 異常なのでFAIL
|
||
COMMON_LOGGER("Can't Read Device Id!!");
|
||
s_RestoreState = FAIL;
|
||
return;
|
||
}
|
||
|
||
// 同一本体下記書き戻しの場合はアカウント削除しない
|
||
if (EqualsDeviceIdFileandDeviceId(manager))
|
||
{
|
||
CheckAccountTransfered(manager, message, goNextStep);
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = WAIT_START_DELETE_ACCOUNT;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = WAIT_START_DELETE_ACCOUNT;
|
||
}
|
||
}
|
||
}
|
||
|
||
// アカウント移行済みかチェック
|
||
void CheckAccountTransfered(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
// アカウント移行確認ファイルがあるか?
|
||
if (common::ExistsTransferAccountChecked())
|
||
{
|
||
CheckDownloadIvs(manager, message, goNextStep);
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = WAIT_START_TRANSFER_ACCOUNT;
|
||
}
|
||
}
|
||
|
||
// 書き込み完了かどうかチェック
|
||
void CheckWriteFinished(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
NN_UNUSED_VAR(goNextStep);
|
||
|
||
// SDカードに書き込み完了ファイルがあるか?
|
||
if (common::ExistsWriteFinishedFile())
|
||
{
|
||
if (CheckAndReadAPSetting(message))
|
||
{
|
||
if (nn::nwm::CTR::IsWifiOn())
|
||
{
|
||
// 削除処理を行う
|
||
s_RestoreState = WAIT_START_SYNC_CLOCK;
|
||
}
|
||
else
|
||
{
|
||
PlayAnnotationSound(ANNOTATION_WIFI_OFF);
|
||
message.Add("Wireless is Off\n");
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
CheckReadIvs(manager, message, goNextStep);
|
||
}
|
||
}
|
||
|
||
// IVSを読めるかどうかチェック
|
||
void CheckReadIvs(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
// IVSを読めるか?
|
||
if (manager.CanReadIvs())
|
||
{
|
||
CheckConsoleInitialized(manager, message, goNextStep);
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
COMMON_LOGGER("Can't Read SDCI!!");
|
||
}
|
||
}
|
||
|
||
// 本体初期化済みかどうかチェック
|
||
void CheckConsoleInitialized(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
// 本体初期化完了ファイルがあるか?
|
||
if (common::ExistsConsoleInitializedFile())
|
||
{
|
||
CheckRegioinSd(manager, message, goNextStep);
|
||
}
|
||
else
|
||
{
|
||
CheckIvsinSd(manager, message, goNextStep);
|
||
}
|
||
}
|
||
|
||
// シリアルナンバーがあるかどうかチェック
|
||
void CheckExistsSerialNumber(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
NN_UNUSED_VAR(manager);
|
||
NN_UNUSED_VAR(message);
|
||
NN_UNUSED_VAR(goNextStep);
|
||
|
||
|
||
// SDカードにシリアルナンバーがあるか?
|
||
if (common::ExistsSerialNumberFile())
|
||
{
|
||
u8 serial[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
|
||
nn::Result result = ReadSerialNumber(serial);
|
||
if (result.IsSuccess())
|
||
{
|
||
s_RestoreState = WAIT_START_IMPORT;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
COMMON_LOGGER("Can't Read Serial Number in SD Card!!\n");
|
||
s_RestoreState = SERIAL_IS_NOT_IN_SD;
|
||
}
|
||
}
|
||
|
||
// SDカードにIVSがあるかどうかチェック
|
||
void CheckIvsinSd(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
NN_UNUSED_VAR(manager);
|
||
NN_UNUSED_VAR(message);
|
||
NN_UNUSED_VAR(goNextStep);
|
||
|
||
if (common::ExistsIVSFile())
|
||
{
|
||
s_RestoreState = INITIALIZE_CONSOLE;
|
||
}
|
||
else
|
||
{
|
||
// 移行不能なのでFAIL
|
||
COMMON_LOGGER("Can't Read SDCI in SD Card!!\n");
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
|
||
// SDカードにリージョンデータがあるかどうかチェック
|
||
void CheckRegioinSd(common::HardwareStateManager& manager, common::OperationMessage& message, bool& goNextStep)
|
||
{
|
||
NN_UNUSED_VAR(message);
|
||
NN_UNUSED_VAR(goNextStep);
|
||
|
||
// SDカードにリージョンデータがあるか?
|
||
if (common::ExistsRegionData())
|
||
{
|
||
// リージョンデータは一致しているか?
|
||
if (EqualsRegionDataandRegion().IsFailure())
|
||
{
|
||
COMMON_LOGGER("Current Region and Region in SD differ!!\n");
|
||
s_RestoreState = FAIL;
|
||
}
|
||
else
|
||
{
|
||
CheckExistsSerialNumber(manager, message, goNextStep);
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
// 移行不能なのでFAIL
|
||
COMMON_LOGGER("Can't Read Region in SD Card!!\n");
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
|
||
void ShopOperationSuccess(ShopOperation op, const char* logMessage, RestoreState nextState)
|
||
{
|
||
COMMON_LOGGER("%s", logMessage);
|
||
if (op == SHOP_OPERATION_UNREGISTER || op == SHOP_OPERATION_FORCE_UNREGISTER)
|
||
{
|
||
CreateDeleteAccountFinishedFile();
|
||
}
|
||
else if (op == SHOP_OPERATION_GET_IVS)
|
||
{
|
||
CreateTransferAccountFinishedFile();
|
||
CreateDownloadIvsFinishedFile();
|
||
}
|
||
|
||
s_RestoreState = nextState;
|
||
|
||
}
|
||
|
||
void ShopOperationSingleTemplate(
|
||
common::HardwareStateManager& manager,
|
||
common::OperationMessage& message,
|
||
ShopOperation op,
|
||
const char* aliveMessage,
|
||
const char* logMessage,
|
||
const char* retryLogMessage,
|
||
RestoreState nextState
|
||
)
|
||
{
|
||
// ACアダプタが必要か?
|
||
if (NeedsAcAdater(manager))
|
||
{
|
||
message.Add("Connect AC Adapter!!");
|
||
}
|
||
|
||
// アップデートを行う
|
||
if (!s_ShopOperationExecuted[op])
|
||
{
|
||
if (ImportCountryLanguageData().IsSuccess())
|
||
{
|
||
StartShopOperationSingle(op);
|
||
s_ShopOperationExecuted[op] = true;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
|
||
// 動いていることを表示
|
||
{
|
||
PutAliveMessage(message, aliveMessage);
|
||
}
|
||
|
||
if (IsShopOperationSingleFinished())
|
||
{
|
||
FinalizeShopOperationSingle();
|
||
// エラーがあったら表示する
|
||
if (GetShopOperationSingleResult().IsSuccess())
|
||
{
|
||
ShopOperationSuccess(op, logMessage, nextState);
|
||
}
|
||
// IVSがアップロードされていない場合もあるため
|
||
// IVSを取得できない状況も成功として扱う
|
||
// IVSサイズが違う場合も成功として扱う
|
||
else if(op == SHOP_OPERATION_GET_IVS && ( GetShopOperationSingleResult() == nn::nim::ResultCannotGetIvs() ||
|
||
GetShopOperationSingleResult() == nn::nim::ResultInvalidData()
|
||
))
|
||
{
|
||
ShopOperationSuccess(op, logMessage, nextState);
|
||
}
|
||
else if(op == SHOP_OPERATION_CONNECT && nextState == TRANSFER_ACCOUNT_DONE &&
|
||
GetShopOperationSingleResult() == nn::nim::ResultNeedGetIvs())
|
||
|
||
{
|
||
NN_LOG("ResultNeedGetIvs\n");
|
||
ShopOperationSuccess(op, logMessage, nextState);
|
||
}
|
||
else
|
||
{
|
||
if (GetShopOperationSingleResult().IsFailure())
|
||
{
|
||
if (GetShopOperationSingleResult() == nn::ac::ResultFailedConnectAp())
|
||
{
|
||
COMMON_LOGGER("Failed Connect AccesPoint.");
|
||
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromSeconds(5));
|
||
}
|
||
|
||
|
||
// APが見つからない
|
||
if (GetUpdateResult() == nn::ac::ResultNotFoundAccessPoint())
|
||
{
|
||
COMMON_LOGGER("No Access Point Found!");
|
||
}
|
||
}
|
||
|
||
if (s_ShopOperationRetryCount[op]++ < RETRY_MAX)
|
||
{
|
||
// エラーのためやり直す
|
||
COMMON_LOGGER_RESULT_IF_FAILED(GetShopOperationSingleResult());
|
||
COMMON_LOGGER("%s %d\n", retryLogMessage, s_ShopOperationRetryCount[op]);
|
||
|
||
// スレッドを作るとこからやり直し
|
||
s_ShopOperationExecuted[op] = false;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
void UpdateOperation(common::HardwareStateManager& manager, common::OperationMessage& message, RestoreState nextState)
|
||
{
|
||
// ACアダプタが必要か?
|
||
if (NeedsAcAdater(manager))
|
||
{
|
||
message.Add("Connect AC Adapter!!");
|
||
}
|
||
|
||
// アップデートを行う
|
||
if (!s_ExecuteFgNup)
|
||
{
|
||
if (ImportCountryLanguageData().IsSuccess())
|
||
{
|
||
StartFGNetworkUpdate();
|
||
s_ExecuteFgNup = true;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
|
||
// 動いていることを表示
|
||
{
|
||
PutAliveMessage(message, "Updating");
|
||
}
|
||
|
||
if (IsNetworkUpdateFinished())
|
||
{
|
||
FinishFGNetworkUpdate();
|
||
// エラーがあったら表示する
|
||
if (GetUpdateResult().IsFailure())
|
||
{
|
||
// APが見つからない
|
||
if (GetUpdateResult() == nn::ac::ResultNotFoundAccessPoint())
|
||
{
|
||
COMMON_LOGGER("No Access Point Found!");
|
||
}
|
||
}
|
||
|
||
if (GetUpdateResult().IsSuccess())
|
||
{
|
||
COMMON_LOGGER("Network Update Finished.\n");
|
||
if(nextState == UPDATE_DONE)
|
||
{
|
||
// アップデート完了ファイルを作成
|
||
CreateUpdateFinishedFile();
|
||
}
|
||
|
||
s_RestoreState = nextState;
|
||
}
|
||
else
|
||
{
|
||
if (s_FgNupRetryCount++ < RETRY_MAX)
|
||
{
|
||
// エラーのためやり直す
|
||
COMMON_LOGGER_RESULT_IF_FAILED(GetUpdateResult());
|
||
COMMON_LOGGER("Network Update Failed. Retrying... %d\n", s_FgNupRetryCount);
|
||
|
||
// FGNUP用のスレッドを作るとこからやり直し
|
||
s_ExecuteFgNup = false;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
bool CheckAndReadAPSetting(common::OperationMessage& operationMessage)
|
||
{
|
||
using namespace common;
|
||
|
||
if (!ExistsAPSetting())
|
||
{
|
||
PlayAnnotationSound(ANNOTATION_SETTING_NOT_FOUND);
|
||
operationMessage.Add("Accsess_Point_Setting does not exist!");
|
||
return false;
|
||
}
|
||
|
||
// 設定ファイルからAP設定を読み込む
|
||
if (!s_ReadSettingDone)
|
||
{
|
||
s_ReadSettingDone = true;
|
||
s_ReadSettingIsSuccess = ReadSetting(&s_NupOnlyMode, &s_GetIvsOnlyMode, &s_CheckSdOnlyMode, &s_SkipNupMode, &s_DownloadPreinstallMode);
|
||
}
|
||
|
||
if (s_NupOnlyMode && s_GetIvsOnlyMode
|
||
|| s_GetIvsOnlyMode && s_CheckSdOnlyMode
|
||
|| s_CheckSdOnlyMode && s_NupOnlyMode)
|
||
{
|
||
operationMessage.Add("Only one special mode setting is valid!!");
|
||
s_ReadSettingIsSuccess = false;
|
||
}
|
||
else if(s_NupOnlyMode && s_SkipNupMode)
|
||
{
|
||
operationMessage.Add("Both NUP_ONLY and SKIP_NUP are described!!");
|
||
s_ReadSettingIsSuccess = false;
|
||
}
|
||
else
|
||
{
|
||
if (s_NupOnlyMode)
|
||
{
|
||
s_RestoreMode = RESTORE_MODE_NUP_ONLY;
|
||
}
|
||
|
||
if (s_GetIvsOnlyMode)
|
||
{
|
||
s_RestoreMode = RESTORE_MODE_GET_IVS;
|
||
}
|
||
|
||
if(s_CheckSdOnlyMode)
|
||
{
|
||
s_RestoreMode = RESTORE_MODE_CHECK_SD;
|
||
}
|
||
|
||
if(s_DownloadPreinstallMode)
|
||
{
|
||
s_RestoreMode = RESTORE_MODE_DOWNLOAD_PREINSTALL;
|
||
}
|
||
}
|
||
|
||
if (!s_ReadSettingIsSuccess)
|
||
{
|
||
operationMessage.Add("Invalid Accsess_Point_Setting format!");
|
||
PlayAnnotationSound(ANNOTATION_INVALID_SETTING);
|
||
}
|
||
|
||
return s_ReadSettingIsSuccess;
|
||
}
|
||
|
||
void PutAliveMessage(common::OperationMessage& operationMessage, const char* str)
|
||
{
|
||
std::string message = std::string(str);
|
||
static u8 i = 0;
|
||
if (i < 0xff / 4)
|
||
{
|
||
operationMessage.Add((message + std::string(" /")).c_str());
|
||
}
|
||
else if (i < 0xff * 2 / 4)
|
||
{
|
||
operationMessage.Add((message + std::string(" |")).c_str());
|
||
}
|
||
else if (i < 0xff * 3 / 4)
|
||
{
|
||
operationMessage.Add((message + std::string(" \\")).c_str());
|
||
}
|
||
else
|
||
{
|
||
operationMessage.Add((message + std::string(" -")).c_str());
|
||
}
|
||
i += 4;
|
||
}
|
||
|
||
nn::Result ExecSyncMcuRtc(common::HardwareStateManager& manager)
|
||
{
|
||
nn::Result result = nn::ResultSuccess();
|
||
if(!common::ExistsRtcSyncFinishedFile())
|
||
{
|
||
result = ImportMcuRtc(manager);
|
||
if(result.IsSuccess())
|
||
{
|
||
// RTCを同期完了ファイルを作る
|
||
CreateRtcSyncFinishedFile();
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
} // namespace <unnamed>
|
||
|
||
void ControlState(common::HardwareStateManager& manager, common::OperationMessage& operationMessage, bool& nextStep,
|
||
bool operateBmsDone, bool forcePreinstall, bool unregister)
|
||
{
|
||
using namespace common;
|
||
nn::Result result;
|
||
|
||
// 状態遷移Controller
|
||
switch (s_RestoreState)
|
||
{
|
||
// 起動時
|
||
case STARTUP:
|
||
{
|
||
CheckSdInserted(manager, operationMessage, nextStep);
|
||
}
|
||
break;
|
||
|
||
|
||
case INITIALIZE_CONSOLE:
|
||
{
|
||
COMMON_LOGGER("Initialize Console\n");
|
||
|
||
// 本体初期化完了ファイルを作る
|
||
CreateConsoleInitializedFile();
|
||
|
||
// ファイルシステムの初期化を行う
|
||
if(InitializeFileSystem())
|
||
{
|
||
s_RestoreState = REBOOTING;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
|
||
}
|
||
break;
|
||
|
||
case WAIT_START_UPDATE:
|
||
{
|
||
//シリアルが存在しない場合がある
|
||
if (common::ExistsSerialNumberFile() && !DisplaySerialNumberinSD(operationMessage))
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
|
||
operationMessage.Add("Push A or START Button");
|
||
operationMessage.Add("Network Update Mode");
|
||
PlayCursorSound(WAIT_START_UPDATE);
|
||
|
||
if (nextStep)
|
||
{
|
||
COMMON_LOGGER("Start Network Update\n");
|
||
// インポートコンテキストの削除
|
||
result = nn::am::DeleteAllImportContexts(nn::fs::MEDIA_TYPE_NAND);
|
||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||
nn::am::DeleteAllImportContexts(nn::fs::MEDIA_TYPE_SDMC);
|
||
s_RestoreState = UPDATE_IN_PROGRESS;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case WAIT_START_IMPORT:
|
||
{
|
||
// 必ずシリアルが存在するはず
|
||
if(!DisplaySerialNumberinSD(operationMessage))
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
|
||
operationMessage.Add("Push A or START Button");
|
||
operationMessage.Add("Import Data Mode");
|
||
PlayCursorSound(WAIT_START_IMPORT);
|
||
|
||
if (nextStep)
|
||
{
|
||
s_RestoreState = READ_FILELIST;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case WAIT_START_SYNC_CLOCK:
|
||
{
|
||
operationMessage.Add("Push A or START Button");
|
||
operationMessage.Add("DownLoad Twl Title and Clock Sync Mode");
|
||
PlayCursorSound(WAIT_START_SYNC_CLOCK);
|
||
|
||
if (nextStep)
|
||
{
|
||
COMMON_LOGGER("Erase Trash\n");
|
||
s_RestoreState = ERASE;
|
||
}
|
||
}
|
||
break;
|
||
|
||
// ここから各設定で処理が分岐する
|
||
case IMPORT_RTC:
|
||
{
|
||
result = nn::ResultSuccess();
|
||
if (HasValidRtcData())
|
||
{
|
||
result = ExecSyncMcuRtc(manager);
|
||
if (result <= nn::fs::ResultVerificationFailed())
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
else
|
||
{
|
||
if (s_SkipNupMode)
|
||
{
|
||
CheckAccountTransfered(manager, operationMessage, nextStep);
|
||
}
|
||
else
|
||
{
|
||
CheckNupExecuted(manager, operationMessage, nextStep);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(s_SkipNupMode)
|
||
{
|
||
CheckAccountTransfered(manager, operationMessage, nextStep);
|
||
}
|
||
else if (s_CheckSdOnlyMode)
|
||
{
|
||
s_RestoreState = CHECK_IVS;
|
||
}
|
||
else
|
||
{
|
||
CheckNupExecuted(manager, operationMessage, nextStep);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
// シリアルナンバーがSDカードにないこと警告
|
||
case SERIAL_IS_NOT_IN_SD:
|
||
{
|
||
operationMessage.Add("Serial Number Is Not In SD Card");
|
||
operationMessage.Add("Push A or START Button");
|
||
operationMessage.Add("Import Data Mode");
|
||
|
||
PlayAnnotationSound(ANNOTATION_SERIAL_NUMBER_NOT_IN_SD);
|
||
|
||
if (nextStep)
|
||
{
|
||
s_RestoreState = READ_FILELIST;
|
||
}
|
||
}
|
||
break;
|
||
|
||
// アップデート中
|
||
case UPDATE_IN_PROGRESS:
|
||
{
|
||
UpdateOperation(manager, operationMessage, UPDATE_DONE);
|
||
}
|
||
break;
|
||
|
||
// アップデート完了
|
||
case UPDATE_DONE:
|
||
{
|
||
operationMessage.Add("Network Update Done.");
|
||
operationMessage.Add("Press A or START Button to Reboot");
|
||
PlayCursorSound(UPDATE_DONE);
|
||
|
||
if (nextStep)
|
||
{
|
||
s_RestoreState = REBOOTING;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case DOWNLOAD_IVS:
|
||
{
|
||
ShopOperationSingleTemplate(manager, operationMessage, SHOP_OPERATION_GET_IVS, "Get SDCI",
|
||
"Get SDCI Finished.\n", "Get SDCI Failed. Retrying...", DOWNLOAD_IVS_DONE);
|
||
}
|
||
break;
|
||
|
||
|
||
case DOWNLOAD_IVS_DONE:
|
||
{
|
||
operationMessage.Add("Get SDCI Done.");
|
||
operationMessage.Add("Press A or START Button to Reboot");
|
||
PlayCursorSound(DOWNLOAD_IVS_DONE);
|
||
|
||
if (nextStep)
|
||
{
|
||
s_RestoreState = REBOOTING;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case CHECK_IVS:
|
||
{
|
||
operationMessage.Add("Insert User's SD Card");
|
||
}
|
||
break;
|
||
|
||
case CHECK_SD_DIRECTORY:
|
||
{
|
||
if (nn::fs::IsSdmcInserted())
|
||
{
|
||
NN_LOG("Check User's SD Card\n");
|
||
// ユーザのSDカードにはAP設定ファイルは無いはず
|
||
if (ExistsAPSetting())
|
||
{
|
||
NN_LOG("AP Setting Exists. Retry\n");
|
||
s_RestoreState = CHECK_IVS;
|
||
}
|
||
else
|
||
{
|
||
NN_LOG("Read User's SD Card\n");
|
||
std::string sysSaveRoot;
|
||
common::Util::GetSaveDataDirectoryRoot(sysSaveRoot);
|
||
if (ExistsIvsDirectory(sysSaveRoot))
|
||
{
|
||
s_RestoreState = CHECK_SD_DIRECTORY_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = CHECK_SD_DIRECTORY_FAIL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case CHECK_SD_DIRECTORY_SUCCESS:
|
||
{
|
||
operationMessage.Add("Check User's SD Card Succeeded.");
|
||
operationMessage.Add("Pull Out SD Card");
|
||
}
|
||
break;
|
||
|
||
case CHECK_SD_DIRECTORY_FAIL:
|
||
{
|
||
operationMessage.Add("Check User's SD Card Failed.");
|
||
operationMessage.Add("Pull Out SD Card");
|
||
}
|
||
break;
|
||
|
||
case WAIT_START_TRANSFER_ACCOUNT:
|
||
{
|
||
if(s_SkipNupMode)
|
||
{
|
||
operationMessage.Add("After Operating BMS Account Transfer,");
|
||
}
|
||
|
||
operationMessage.Add("Push A or START Button");
|
||
operationMessage.Add("Transfer Account Mode");
|
||
PlayCursorSound(WAIT_START_TRANSFER_ACCOUNT);
|
||
|
||
if (nextStep)
|
||
{
|
||
COMMON_LOGGER("Transfer Account\n");
|
||
s_RestoreState = TRANSFER_ACCOUNT;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case TRANSFER_ACCOUNT:
|
||
{
|
||
ShopOperationSingleTemplate(manager, operationMessage, SHOP_OPERATION_GET_IVS, "Transfer Account",
|
||
"Transfer Account Finished.\n", "Transfer Account Failed. Retrying...", DOWNLOAD_IVS_DONE);
|
||
}
|
||
break;
|
||
|
||
case WAIT_START_DELETE_ACCOUNT:
|
||
{
|
||
operationMessage.Add("Delete Account Mode.", nn::util::Color8(255, 153, 0, 255));
|
||
operationMessage.Add("Press Y Button to Continue");
|
||
PlayCursorSound(WAIT_START_DELETE_ACCOUNT);
|
||
|
||
if (unregister)
|
||
{
|
||
COMMON_LOGGER("Delete Account\n");
|
||
s_RestoreState = DELETE_ACCOUNT;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case DELETE_ACCOUNT:
|
||
{
|
||
if(s_NupOnlyMode)
|
||
{
|
||
ShopOperationSingleTemplate(manager, operationMessage, SHOP_OPERATION_FORCE_UNREGISTER, "Deleting Account",
|
||
"Delete Account Finished.\n", "Delete Account Failed. Retrying...", DELETE_ACCOUNT_DONE);
|
||
|
||
}
|
||
else
|
||
{
|
||
ShopOperationSingleTemplate(manager, operationMessage, SHOP_OPERATION_UNREGISTER, "Deleting Account",
|
||
"Delete Account Finished.\n", "Delete Account Failed. Retrying...", DELETE_ACCOUNT_DONE);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case DELETE_ACCOUNT_DONE:
|
||
{
|
||
if(s_NupOnlyMode)
|
||
{
|
||
s_RestoreState = NUP_ONLY_WAIT_SD_EJECT;
|
||
|
||
// リストア状態チェックファイルをすべて削除
|
||
DeleteAllCheckFiles();
|
||
}
|
||
else
|
||
{
|
||
operationMessage.Add("Delete Account Done.");
|
||
operationMessage.Add("Operate BMS and NNAS management Tool.", nn::util::Color8(0, 255, 255, 255));
|
||
operationMessage.Add("");
|
||
operationMessage.Add("Press Y Button to Continue");
|
||
PlayCursorSound(DELETE_ACCOUNT_DONE);
|
||
|
||
if (operateBmsDone)
|
||
{
|
||
s_RestoreState = STARTUP;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case READ_FILELIST:
|
||
{
|
||
result = SetupVersionAndFileList();
|
||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||
|
||
if (result.IsSuccess())
|
||
{
|
||
if (s_IsSyncClock)
|
||
{
|
||
s_RestoreState = RESTORE_TWL_NAND;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = RESTORE_TWL_SOUND;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
break;
|
||
|
||
// TWLサウンド領域の書き込み中
|
||
case RESTORE_TWL_SOUND:
|
||
{
|
||
static bool init = true;
|
||
if (init)
|
||
{
|
||
// データを書き込む
|
||
ImportTwlSoundData();
|
||
init = false;
|
||
}
|
||
|
||
PutAliveMessage(operationMessage, "Importing TWL Sound Data");
|
||
|
||
// 処理が完了した
|
||
if (IsImportThreadFinished())
|
||
{
|
||
FinalizeImportThread();
|
||
if(IsImportSucceeded())
|
||
{
|
||
s_RestoreState = RESTORE_TWL_PHOTO;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
|
||
}
|
||
}
|
||
break;
|
||
|
||
// TWL写真領域の書き込み
|
||
case RESTORE_TWL_PHOTO:
|
||
{
|
||
static bool init = true;
|
||
if (init)
|
||
{
|
||
// データを書き込む
|
||
ImportTwlPhotoData();
|
||
init = false;
|
||
}
|
||
|
||
PutAliveMessage(operationMessage, "Importing TWL Photo Data");
|
||
|
||
// 処理が完了した
|
||
if (IsImportThreadFinished())
|
||
{
|
||
FinalizeImportThread();
|
||
if(IsImportSucceeded())
|
||
{
|
||
s_RestoreState = RESTORE_IN_PROGRESS;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
|
||
}
|
||
}
|
||
break;
|
||
|
||
// 書き込み中
|
||
case RESTORE_IN_PROGRESS:
|
||
{
|
||
// ACアダプタが必要か?
|
||
if (NeedsAcAdater(manager))
|
||
{
|
||
operationMessage.Add("Connect AC Adapter!!");
|
||
}
|
||
|
||
// データを読み込む
|
||
if (ImportData().IsFailure())
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
else
|
||
{
|
||
PutAliveMessage(operationMessage, "Importing Nand Data");
|
||
|
||
// 処理が完了した
|
||
if (!NeedsAcAdater(manager) && IsImportThreadFinished())
|
||
{
|
||
if (IsImportSucceeded())
|
||
{
|
||
|
||
COMMON_LOGGER("Import NAND Data Finished.\n");
|
||
|
||
if (GetProgress() > 99)
|
||
{
|
||
s_RestoreState = POST_RESTORE;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
// リブート中
|
||
case REBOOTING:
|
||
{
|
||
static bool init = true;
|
||
|
||
if (init)
|
||
{
|
||
// ErrDispから引用
|
||
result = nn::ns::CTR::InitializeForShell();
|
||
if (result.IsSuccess())
|
||
{
|
||
COMMON_LOGGER("System Reboot.\n");
|
||
|
||
nn::ns::CTR::HardwareResetAsync(nn::CTR::MEMORY_ARRANGE_NORMAL);
|
||
while (!nn::applet::IsExpectedToCloseApplication())
|
||
{
|
||
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(5));
|
||
}
|
||
|
||
nn::ns::CTR::FinalizeForShell();
|
||
|
||
// INFO: リブートは非同期のため処理は継続
|
||
}
|
||
init = false;
|
||
}
|
||
}
|
||
break;
|
||
|
||
// 書き込み後の処理
|
||
case POST_RESTORE:
|
||
{
|
||
operationMessage.Add("Post Process...");
|
||
|
||
// SDカードのIVSファイルを書き込む
|
||
if(ImportIvsData())
|
||
{
|
||
// 書き込み完了ファイルを作成
|
||
CreateWriteFinishedFile();
|
||
|
||
s_RestoreState = RESTORE_DONE;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
break;
|
||
|
||
// 書き込み完了
|
||
case RESTORE_DONE:
|
||
{
|
||
operationMessage.Add("Restore Done.");
|
||
operationMessage.Add("Press A or START Button to Reboot");
|
||
PlayCursorSound(RESTORE_DONE);
|
||
|
||
if (nextStep)
|
||
{
|
||
s_RestoreState = REBOOTING;
|
||
}
|
||
}
|
||
break;
|
||
|
||
// 削除処理
|
||
case ERASE:
|
||
{
|
||
Cleanup();
|
||
s_RestoreState = RESTORE_CAL;
|
||
}
|
||
break;
|
||
|
||
// 削除処理
|
||
case RESTORE_CAL:
|
||
{
|
||
// ptmのセーブデータ移行後に時計を無効化する
|
||
nn::ptm::CTR::InvalidateSystemTime();
|
||
|
||
// cfgの本体固有値をcal値で初期化する
|
||
result = InitializeHardwareDependentSetting();
|
||
if (result.IsFailure())
|
||
{
|
||
COMMON_LOGGER_RESULT(result, __func__);
|
||
s_RestoreState = FAIL;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = COMPLETE_ACT;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case COMPLETE_ACT:
|
||
{
|
||
COMMON_LOGGER("Complete NNA Transfer\n");
|
||
if (ImportCountryLanguageData().IsSuccess())
|
||
{
|
||
ActCompleter::Start();
|
||
s_RestoreState = COMPLETE_ACT_WAIT;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case COMPLETE_ACT_WAIT:
|
||
{
|
||
PutAliveMessage(operationMessage, "Complete NNA Transfer");
|
||
if (ActCompleter::IsFinished())
|
||
{
|
||
ActCompleter::Finish();
|
||
result = ActCompleter::GetResult();
|
||
if (result.IsFailure())
|
||
{
|
||
if(++s_NNATransferRetryCount >= RETRY_MAX)
|
||
{
|
||
COMMON_LOGGER_RESULT(result, __func__);
|
||
s_RestoreState = FAIL;
|
||
}
|
||
else
|
||
{
|
||
COMMON_LOGGER("Complete NNA Transfer failed, Retrying...");
|
||
s_RestoreState = COMPLETE_ACT;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
COMMON_LOGGER("Sync eTicket\n");
|
||
s_RestoreState = SYNC_TICKET;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case SYNC_TICKET:
|
||
{
|
||
if(s_GetIvsOnlyMode)
|
||
{
|
||
ShopOperationSingleTemplate(manager, operationMessage, SHOP_OPERATION_CONNECT, "Shop Connect",
|
||
"Shop Connect Finished.\n", "Shop Connect Failed. Retrying...", WAIT_SD_EJECT);
|
||
}
|
||
else if(s_DownloadPreinstallMode)
|
||
{
|
||
ShopOperationSingleTemplate(manager, operationMessage, SHOP_OPERATION_CONNECT, "Shop Connect",
|
||
"Shop Connect Finished.\n", "Shop Connect Failed. Retrying...", REPAIR_SIMPLE_ADDRESS_ID);
|
||
}
|
||
else
|
||
{
|
||
ShopOperationSingleTemplate(manager, operationMessage, SHOP_OPERATION_CONNECT, "Shop Connect",
|
||
"Shop Connect Finished.\n", "Shop Connect Failed. Retrying...", DOWNLOAD_TWL);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case DOWNLOAD_TWL:
|
||
{
|
||
// ファイルリストがなければ次へ
|
||
if( !ExistsTwlTitleListFile())
|
||
{
|
||
s_IsSyncClock = true;
|
||
s_RestoreState = READ_FILELIST;
|
||
}
|
||
else
|
||
{
|
||
if (!s_ExecuteTwlTitleDownload)
|
||
{
|
||
COMMON_LOGGER("Download Twl Title\n");
|
||
s_ExecuteTwlTitleDownload = true;
|
||
StartTwlTitleDownload();
|
||
}
|
||
|
||
// 動いていることを表示
|
||
{
|
||
PutAliveMessage(operationMessage, "Download Twl Title");
|
||
}
|
||
|
||
if (IsDownloadTitleFinished())
|
||
{
|
||
FinalizeTitleDownload();
|
||
if (DownloadTitleSucceeded())
|
||
{
|
||
s_IsSyncClock = true;
|
||
s_RestoreState = READ_FILELIST;
|
||
}
|
||
else
|
||
{
|
||
if (s_TwlTitleDownloadRetryCount++ < RETRY_MAX)
|
||
{
|
||
// エラーのためやり直す
|
||
COMMON_LOGGER_RESULT_IF_FAILED(GetTitleDownloadResult());
|
||
COMMON_LOGGER("Download Twl Title Failed. Retrying... %d\n", s_TwlTitleDownloadRetryCount);
|
||
|
||
s_ExecuteTwlTitleDownload = false;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
// TWL NAND領域の書き込み中
|
||
case RESTORE_TWL_NAND:
|
||
{
|
||
static bool init = true;
|
||
if (init)
|
||
{
|
||
// データを書き込む
|
||
ImportTwlSaveData();
|
||
init = false;
|
||
}
|
||
|
||
PutAliveMessage(operationMessage, "Importing TWL SaveData");
|
||
|
||
// 処理が完了した
|
||
if (IsImportThreadFinished())
|
||
{
|
||
FinalizeImportThread();
|
||
s_RestoreState = REPAIR_SIMPLE_ADDRESS_ID;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case REPAIR_SIMPLE_ADDRESS_ID:
|
||
{
|
||
RepairSimpleAddress();
|
||
s_RestoreState = TIME_ADJUST;
|
||
}
|
||
break;
|
||
|
||
// 時計あわせ
|
||
case TIME_ADJUST:
|
||
{
|
||
static bool init = true;
|
||
if (init)
|
||
{
|
||
COMMON_LOGGER("Adjust Time\n");
|
||
AdjustTime();
|
||
init = false;
|
||
}
|
||
|
||
// 動いていることを表示
|
||
{
|
||
PutAliveMessage(operationMessage, "Sync Clock");
|
||
}
|
||
|
||
if (IsTimeAdjustFinished())
|
||
{
|
||
if (IsTimeAdjustSuccessed())
|
||
{
|
||
if(s_DownloadPreinstallMode)
|
||
{
|
||
s_RestoreState = PREINSTALL_WAIT_USER_SD_INSERT;
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = WAIT_SD_EJECT;
|
||
|
||
// インターネット設定を元に戻す
|
||
RestoreCurrentInternetSetting();
|
||
|
||
// リストア状態チェックファイルをすべて削除
|
||
DeleteAllCheckFiles();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// インターネット設定を元に戻す
|
||
RestoreCurrentInternetSetting();
|
||
|
||
s_RestoreState = FAIL;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
// すべて完了
|
||
case WAIT_SD_EJECT:
|
||
{
|
||
operationMessage.Add("ALL Done. Pull Out SD Card.");
|
||
// SDカード抜けのみで次の状態に遷移する
|
||
PlayCursorSound(WAIT_SD_EJECT);
|
||
|
||
}
|
||
break;
|
||
|
||
// すべて完了
|
||
case ALL_DONE:
|
||
{
|
||
operationMessage.Add("Restore Succeeded!!");
|
||
static bool init = true;
|
||
if (init)
|
||
{
|
||
PlaySound(SOUND_OK);
|
||
manager.SetWifiOff();
|
||
init = false;
|
||
}
|
||
}
|
||
break;
|
||
|
||
// 書き込み失敗
|
||
case FAIL:
|
||
{
|
||
static bool init = true;
|
||
if (init)
|
||
{
|
||
// 状態初期化
|
||
DeleteAllCheckFiles();
|
||
manager.SetWifiOff();
|
||
init = false;
|
||
}
|
||
|
||
operationMessage.Add("Failed.");
|
||
if (!s_PlayedFailSound)
|
||
{
|
||
PlaySound(SOUND_NG);
|
||
s_PlayedFailSound = true;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case NUP_ONLY_WAIT_SD_EJECT:
|
||
{
|
||
static bool init = true;
|
||
if(init)
|
||
{
|
||
manager.SetWifiOff();
|
||
init = false;
|
||
}
|
||
operationMessage.Add("Update Done. Pull Out SD Card.");
|
||
PlayCursorSound(NUP_ONLY_WAIT_SD_EJECT);
|
||
}
|
||
break;
|
||
|
||
case DOWNLOAD_IVS_WAIT_NEXT:
|
||
{
|
||
operationMessage.Add("Press A or START Button to Continue.");
|
||
if(nextStep)
|
||
{
|
||
s_RestoreState = COMPLETE_ACT;
|
||
DeleteAllCheckFiles();
|
||
}
|
||
}
|
||
break;
|
||
|
||
case NUP_ONLY_WAIT_NEXT:
|
||
{
|
||
operationMessage.Add("Press A or START Button to Shutdown.");
|
||
|
||
if (nextStep)
|
||
{
|
||
s_RestoreState = INITIALIZE_AND_SHUTDOWN;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case INITIALIZE_AND_SHUTDOWN:
|
||
{
|
||
// 本体初期化を行う
|
||
if(!InitializeFileSystem())
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
|
||
// シャットダウンする
|
||
nn::ptm::CTR::ShutdownAsync(0, nn::fnd::TimeSpan::FromSeconds(0));
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_WAIT_START_UPDATE:
|
||
{
|
||
operationMessage.Add("Operate BMS to Transfer PreInstalled Application", nn::util::Color8(0, 255, 255, 255));
|
||
operationMessage.Add("and NNAS management Tool.", nn::util::Color8(0, 255, 255, 255));
|
||
operationMessage.Add("Press Y Button to Continue.");
|
||
PlayCursorSound(PREINSTALL_WAIT_START_UPDATE);
|
||
|
||
if (operateBmsDone)
|
||
{
|
||
s_RestoreState = WAIT_START_UPDATE;
|
||
}
|
||
}
|
||
break;
|
||
|
||
|
||
case PREINSTALL_WAIT_SYNC_TICKET:
|
||
{
|
||
operationMessage.Add("Press A or START Button to Continue.");
|
||
PlayCursorSound(PREINSTALL_WAIT_SYNC_TICKET);
|
||
if(nextStep)
|
||
{
|
||
s_RestoreState = COMPLETE_ACT;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_WAIT_USER_SD_INSERT:
|
||
{
|
||
PlayCursorSound(PREINSTALL_WAIT_USER_SD_INSERT);
|
||
operationMessage.Add("Insert User's SD Card");
|
||
operationMessage.Add("and Press A or START Button.");
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_WAIT_USER_SD_INSERT_WAIT_NEXT:
|
||
{
|
||
operationMessage.Add("Insert User's SD Card");
|
||
operationMessage.Add("and Press A or START Button.");
|
||
|
||
if(nextStep)
|
||
{
|
||
s_RestoreState = PREINSTALL_CHECK_USER_SD_INSERT;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_CHECK_USER_SD_INSERT:
|
||
{
|
||
RestoreState saved = PREINSTALL_CHECK_USER_SD_INSERT;
|
||
if (nn::fs::IsSdmcInserted())
|
||
{
|
||
NN_LOG("Check User's SD Card\n");
|
||
// ユーザのSDカードにはAP設定ファイルは無いはず
|
||
if (ExistsAPSetting())
|
||
{
|
||
NN_LOG("AP Setting Exists. Retry\n");
|
||
ChangeState(saved, s_RestoreState, PREINSTALL_WAIT_USER_SD_INSERT);
|
||
}
|
||
else
|
||
{
|
||
// SD挿抜が起こったら抜ける
|
||
BREAK_IF_STATE_CHANGED(saved, s_RestoreState);
|
||
ChangeState(saved, s_RestoreState, PREINSTALL_CHECK_USER_SD);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_CHECK_USER_SD:
|
||
{
|
||
if (!s_ExecutePreparePreinstallTitleDownload)
|
||
{
|
||
COMMON_LOGGER("Checking User's SD Card\n");
|
||
s_ExecutePreparePreinstallTitleDownload = true;
|
||
StartPreparePreinstallTitleDownload(s_ForceDownloadPreinstall);
|
||
}
|
||
|
||
// 動いていることを表示
|
||
{
|
||
PutAliveMessage(operationMessage, "Checking User's SD Card");
|
||
}
|
||
|
||
if (IsDownloadTitleFinished())
|
||
{
|
||
FinalizeTitleDownload();
|
||
if (DownloadTitleSucceeded())
|
||
{
|
||
s_RestoreState = PREINSTALL_DOWNLOAD_APP;
|
||
}
|
||
else
|
||
{
|
||
if (s_PreparePreinstallTitleDownloadRetryCount++ < RETRY_MAX)
|
||
{
|
||
COMMON_LOGGER_RESULT_IF_FAILED(GetTitleDownloadResult());
|
||
if (GetTitleDownloadResult()
|
||
== nn::MakePermanentResult(nn::Result::SUMMARY_OUT_OF_RESOURCE,
|
||
nn::Result::MODULE_APPLICATION, nn::Result::DESCRIPTION_OUT_OF_MEMORY))
|
||
{
|
||
// SDカード容量不足
|
||
s_RestoreState = PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE;
|
||
}
|
||
else if(GetTitleDownloadResult() <= nn::fs::ResultNotEnoughSpace())
|
||
{
|
||
// SDカード容量不足
|
||
// 作成したデータを削除する
|
||
COMMON_LOGGER_RESULT_IF_FAILED(nn::fs::DeleteSdmcRoot());
|
||
s_RestoreState = PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE;
|
||
}
|
||
else if (GetTitleDownloadResult()
|
||
== nn::MakePermanentResult(nn::Result::SUMMARY_INVALID_STATE,
|
||
nn::Result::MODULE_APPLICATION, nn::Result::DESCRIPTION_ALREADY_INITIALIZED))
|
||
{
|
||
// ユーザSDが初期化済み
|
||
s_RestoreState = PREINSTALL_CHECK_USER_SD_ALREADY_INITIALIZED;
|
||
}
|
||
else if (GetTitleDownloadResult()
|
||
== nn::MakePermanentResult(nn::Result::SUMMARY_NOT_FOUND,
|
||
nn::Result::MODULE_APPLICATION, nn::Result::DESCRIPTION_NOT_FOUND))
|
||
{
|
||
// プリインストールテーブルが無い
|
||
COMMON_LOGGER("No PreInstalled Application Found\n");
|
||
s_RestoreState = PREINSTALL_CHECK_SD_FAIL;
|
||
}
|
||
else
|
||
{
|
||
// エラーのためやり直す
|
||
COMMON_LOGGER("Checking User's SD Card Failed. Retrying... %d\n", s_PreinstallTitleDownloadRetryCount);
|
||
s_ExecutePreparePreinstallTitleDownload = false;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = PREINSTALL_CHECK_SD_FAIL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_CHECK_USER_SD_ALREADY_INITIALIZED:
|
||
{
|
||
operationMessage.Add("User's SD Card is already initialized.");
|
||
operationMessage.Add("Press Y Button to Continue.", nn::util::Color8(0, 255, 255, 255));
|
||
operationMessage.Add("Press A or START Button to Abort");
|
||
if(nextStep)
|
||
{
|
||
s_RestoreState = PREINSTALL_CHECK_SD_FAIL;
|
||
}
|
||
else if(forcePreinstall)
|
||
{
|
||
s_RestoreState = PREINSTALL_CHECK_USER_SD;
|
||
s_ExecutePreparePreinstallTitleDownload = false;
|
||
s_ForceDownloadPreinstall = true;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_CHECK_SD_FAIL:
|
||
{
|
||
PlayCursorSound(PREINSTALL_CHECK_SD_FAIL);
|
||
operationMessage.Add("Check User's SD Card Failed.");
|
||
operationMessage.Add("Pull Out User's SD Card");
|
||
operationMessage.Add("and Insert Repairing SD Card");
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_FAIL_CHECK_REPAIR_SD:
|
||
{
|
||
operationMessage.Add("Press A or START Button to Continue.");
|
||
if(!nextStep)
|
||
{
|
||
break;
|
||
}
|
||
|
||
RestoreState saved = PREINSTALL_FAIL_CHECK_REPAIR_SD;
|
||
if (nn::fs::IsSdmcInserted())
|
||
{
|
||
NN_LOG("Check SD Card\n");
|
||
// 修理用SDカードにはAP設定ファイルがあるはず
|
||
if (ExistsAPSetting())
|
||
{
|
||
NN_LOG("AP Setting Exists. OK\n");
|
||
COMMON_LOGGER("Download PreInstalled Application failed\n");
|
||
|
||
// インターネット設定を元に戻す
|
||
RestoreCurrentInternetSetting();
|
||
|
||
ChangeState(saved, s_RestoreState, FAIL);
|
||
}
|
||
else
|
||
{
|
||
// SD挿抜が起こったら抜ける
|
||
BREAK_IF_STATE_CHANGED(saved, s_RestoreState);
|
||
ChangeState(saved, s_RestoreState, PREINSTALL_CHECK_SD_FAIL);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_DOWNLOAD_APP:
|
||
{
|
||
if (!s_ExecutePreinstallTitleDownload)
|
||
{
|
||
COMMON_LOGGER("Download PreInstalled Application\n");
|
||
s_ExecutePreinstallTitleDownload = true;
|
||
StartPreinstallTitleDownload();
|
||
}
|
||
|
||
// 動いていることを表示
|
||
{
|
||
PutAliveMessage(operationMessage, "Download PreInstalled Title");
|
||
}
|
||
|
||
if (IsDownloadTitleFinished())
|
||
{
|
||
FinalizeTitleDownload();
|
||
if (DownloadTitleSucceeded())
|
||
{
|
||
s_PreinstallTitleDownloadSuccess = true;
|
||
s_RestoreState = PREINSTALL_WAIT_USER_SD_EJECT;
|
||
}
|
||
else
|
||
{
|
||
if (s_PreinstallTitleDownloadRetryCount++ < RETRY_MAX)
|
||
{
|
||
// エラーのためやり直す
|
||
COMMON_LOGGER_RESULT_IF_FAILED(GetTitleDownloadResult());
|
||
if(GetTitleDownloadResult() <= nn::fs::ResultNotEnoughSpace())
|
||
{
|
||
// SDカード容量不足
|
||
// 作成したデータを削除する
|
||
COMMON_LOGGER_RESULT_IF_FAILED(nn::fs::DeleteSdmcRoot());
|
||
s_RestoreState = PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE;
|
||
}
|
||
else
|
||
{
|
||
COMMON_LOGGER("Download PreInstalled Title Failed. Retrying... %d\n", s_PreinstallTitleDownloadRetryCount);
|
||
|
||
s_ExecutePreinstallTitleDownload = false;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
s_RestoreState = PREINSTALL_WAIT_USER_SD_EJECT;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE:
|
||
{
|
||
PlayCursorSound(PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE);
|
||
operationMessage.Add("Not enough space on User's SD Card");
|
||
operationMessage.Add("Pull out User's SD Card");
|
||
operationMessage.Add("and Insert Repairing SD Card");
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_WAIT_USER_SD_EJECT:
|
||
{
|
||
PlayCursorSound(PREINSTALL_WAIT_USER_SD_EJECT);
|
||
operationMessage.Add("Pull out User's SD Card");
|
||
operationMessage.Add("and Insert Repairing SD Card");
|
||
}
|
||
break;
|
||
|
||
case PREINSTALL_CHECK_REPAIR_SD:
|
||
{
|
||
operationMessage.Add("Press A or START Button to Continue.");
|
||
if(!nextStep)
|
||
{
|
||
break;
|
||
}
|
||
|
||
RestoreState saved = PREINSTALL_CHECK_REPAIR_SD;
|
||
if (nn::fs::IsSdmcInserted())
|
||
{
|
||
NN_LOG("Check SD Card\n");
|
||
// 修理用SDカードにはAP設定ファイルがあるはず
|
||
if (ExistsAPSetting())
|
||
{
|
||
NN_LOG("AP Setting Exists. OK\n");
|
||
// インターネット設定を元に戻す
|
||
RestoreCurrentInternetSetting();
|
||
|
||
if(s_PreinstallTitleDownloadSuccess)
|
||
{
|
||
COMMON_LOGGER("Download PreInstalled Application done\n");
|
||
ChangeState(saved, s_RestoreState, WAIT_SD_EJECT);
|
||
// リストア状態チェックファイルをすべて削除
|
||
DeleteAllCheckFiles();
|
||
}
|
||
else
|
||
{
|
||
COMMON_LOGGER("Download PreInstalled Application failed\n");
|
||
ChangeState(saved, s_RestoreState, FAIL);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// SD挿抜が起こったら抜ける
|
||
BREAK_IF_STATE_CHANGED(saved, s_RestoreState);
|
||
ChangeState(saved, s_RestoreState, PREINSTALL_WAIT_USER_SD_EJECT);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
}
|
||
}
|
||
|
||
bool InProgress()
|
||
{
|
||
return s_RestoreState == RESTORE_IN_PROGRESS;
|
||
}
|
||
|
||
bool IsRestoreSucceeded()
|
||
{
|
||
return s_RestoreState == ALL_DONE;
|
||
}
|
||
|
||
bool IsRestoreFailed()
|
||
{
|
||
return s_RestoreState == FAIL;
|
||
}
|
||
|
||
void OnSdEjected()
|
||
{
|
||
if (s_RestoreState == WAIT_SD_EJECT || s_RestoreState == ALL_DONE || s_RestoreState == CHECK_SD_DIRECTORY_SUCCESS)
|
||
{
|
||
s_RestoreState = ALL_DONE;
|
||
}
|
||
else if (s_RestoreState == NUP_ONLY_WAIT_SD_EJECT || s_RestoreState == NUP_ONLY_WAIT_NEXT)
|
||
{
|
||
s_RestoreState = NUP_ONLY_WAIT_NEXT;
|
||
}
|
||
// ユーザのSDが抜かれてからFAILにする
|
||
else if (s_RestoreState == CHECK_SD_DIRECTORY_FAIL)
|
||
{
|
||
s_RestoreState = FAIL;
|
||
}
|
||
else if(s_RestoreState == PREINSTALL_CHECK_USER_SD_INSERT)
|
||
{
|
||
s_RestoreState = PREINSTALL_WAIT_USER_SD_INSERT;
|
||
}
|
||
else if(s_RestoreState == PREINSTALL_CHECK_REPAIR_SD)
|
||
{
|
||
s_RestoreState = PREINSTALL_WAIT_USER_SD_EJECT;
|
||
}
|
||
else if(s_RestoreState == PREINSTALL_FAIL_CHECK_REPAIR_SD)
|
||
{
|
||
s_RestoreState = PREINSTALL_CHECK_SD_FAIL;
|
||
}
|
||
// FAILのときは一旦電源を切らないと動かないようにしておく
|
||
// IVSチェック時はユーザのSDカードを挿入してもらうため
|
||
// プリインストール時はユーザのSDカードを挿入してもらうため
|
||
else if (s_RestoreState != FAIL && s_RestoreState != CHECK_IVS && s_RestoreState != PREINSTALL_WAIT_USER_SD_INSERT
|
||
&& s_RestoreState != PREINSTALL_WAIT_USER_SD_EJECT && s_RestoreState != PREINSTALL_CHECK_SD_FAIL &&
|
||
s_RestoreState != PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE && s_RestoreState != PREINSTALL_WAIT_USER_SD_INSERT_WAIT_NEXT)
|
||
{
|
||
InitializeState();
|
||
ClearFileReadResult();
|
||
}
|
||
}
|
||
|
||
void OnSdInserted()
|
||
{
|
||
if(s_RestoreState == CHECK_IVS)
|
||
{
|
||
// SDカードが変わるのでファイルチェックは初期化する
|
||
common::InitializeFileCheck();
|
||
s_RestoreState = CHECK_SD_DIRECTORY;
|
||
}
|
||
else if(s_RestoreState == PREINSTALL_WAIT_USER_SD_INSERT)
|
||
{
|
||
// SDカードが変わるのでファイルチェックは初期化する
|
||
common::InitializeFileCheck();
|
||
s_RestoreState = PREINSTALL_WAIT_USER_SD_INSERT_WAIT_NEXT;
|
||
}
|
||
else if(s_RestoreState == PREINSTALL_WAIT_USER_SD_EJECT)
|
||
{
|
||
// SDカードが変わるのでファイルチェックは初期化する
|
||
common::InitializeFileCheck();
|
||
s_RestoreState = PREINSTALL_CHECK_REPAIR_SD;
|
||
}
|
||
else if(s_RestoreState == PREINSTALL_CHECK_SD_FAIL || s_RestoreState == PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE)
|
||
{
|
||
// SDカードが変わるのでファイルチェックは初期化する
|
||
common::InitializeFileCheck();
|
||
s_RestoreState = PREINSTALL_FAIL_CHECK_REPAIR_SD;
|
||
}
|
||
}
|
||
|
||
void InitializeState()
|
||
{
|
||
s_RestoreState = STARTUP;
|
||
s_RestoreMode = RESTORE_MODE_RESTORE;
|
||
|
||
for(u32 i = 0; i < SHOP_OPERATION_NUM_MAX; i++)
|
||
{
|
||
s_ShopOperationExecuted[i] = false;
|
||
s_ShopOperationRetryCount[i] = 0;
|
||
}
|
||
|
||
for(u32 i = 0; i < RESTORE_STATE_MAX; i++)
|
||
{
|
||
s_PlayedCursorSound[i] = false;
|
||
}
|
||
|
||
for(u32 i = 0; i < ANNOTATION_MAX; i++)
|
||
{
|
||
s_PlayedAnnotationSound[i] = false;
|
||
}
|
||
|
||
common::InitializeFileCheck();
|
||
|
||
s_ReadSettingDone = false;
|
||
s_ReadSettingIsSuccess = false;
|
||
s_PlayedFailSound = false;
|
||
s_ExecuteFgNup = false;
|
||
s_FgNupRetryCount = 0;
|
||
s_NupOnlyMode = false;
|
||
s_GetIvsOnlyMode = false;
|
||
s_CheckSdOnlyMode = false;
|
||
s_SkipNupMode = false;
|
||
s_ExecutePreparePreinstallTitleDownload = false;
|
||
s_ExecutePreinstallTitleDownload = false;
|
||
s_PreinstallTitleDownloadSuccess = false;
|
||
}
|
||
|
||
u32 GetProgress()
|
||
{
|
||
if(s_RestoreState == RESTORE_TWL_SOUND ||
|
||
s_RestoreState == RESTORE_TWL_PHOTO ||
|
||
s_RestoreState == RESTORE_IN_PROGRESS ||
|
||
s_RestoreState == POST_RESTORE ||
|
||
s_RestoreState == RESTORE_DONE)
|
||
{
|
||
return GetImportProgress();
|
||
}
|
||
else if (s_RestoreState == RESTORE_TWL_NAND)
|
||
{
|
||
return GetImportProgressTwlNand();
|
||
}
|
||
else if(s_RestoreState == UPDATE_IN_PROGRESS ||
|
||
s_RestoreState == UPDATE_DONE)
|
||
{
|
||
return GetUpdateProgress();
|
||
}
|
||
else if (s_RestoreState == DOWNLOAD_TWL || s_RestoreState == PREINSTALL_DOWNLOAD_APP)
|
||
{
|
||
return GetTitleDownloadProgress();
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
}
|
||
|
||
RestoreMode GetRestoreMode()
|
||
{
|
||
return s_RestoreMode;
|
||
}
|
||
|
||
} // namespace ConsoleRestore
|