ctr_Repair/trunk/ConsoleDataMigration/sources/ConsoleBackup/Controller.cpp
N2614 87c368fec0 バックアップ開始前に権利の無いタイトルとセーブデータを削除するように
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@829 385bec56-5757-e545-9c3a-d8741f4650f1
2014-11-19 06:30:15 +00:00

540 lines
15 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
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 "Controller.h"
#include "FileChecker.h"
#include "Exporter.h"
#include "SimplePlayer.h"
#include "CommonLogger.h"
#include "Checker.h"
#include "FileTransfer.h"
#include "MenuSavedataModifier.h"
#include <nn/am/am_ApiSystemMenu.h>
#include <nn.h>
namespace ConsoleBackup
{
namespace
{
typedef enum BackupState
{
STARTUP, // 初期値
MODIFY_MENU_SAVEDATA, // MMENセーブデータの修正
CHECK_SAVEDATA, // セーブデータの確認
EXPORT_TWL_NAND, // TWLセーブデータ領域の吸出し中
EXPORT_TWL_SOUND, // TWLサウンド領域の吸出し中
EXPORT_TWL_PHOTO, // TWL写真領域の吸出し中
EXPORT_CTR_NAND, // 吸出し中
DELETE_NIM, // nimのシステムセーブデータ削除
DONE, // 吸出し完了
FINISHED, // SDカード抜き完了
FAIL, // 失敗
FAIL_CHECK, // セーブデータのチェック時エラー
STATE_MAX
} BackupState;
// Backupモード管理
BackupMode s_BackupMode = BACKUP_MODE_CHECK;
// APSettingの書式が無い警告サウンドを鳴らしたかどうか
bool s_ExistAPSettingAnnotation = false;
// SDに書き込みできない警告サウンドを鳴らしたかどうか
bool s_SdWriteProetctAnnotation = false;
BackupState s_BackupState = STARTUP;
bool s_PlayedStartCursor = false;
bool s_PlayedSdPullOutCursor = false;
bool s_PlayedFinishedSound = false;
bool s_PlayedFailSound = false;
} // namespace <unnamed>
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;
}
bool NeedsAcAdapter(common::HardwareStateManager& manager)
{
return manager.IsBatteryLower() && !manager.IsAdapterConnected();
}
void ControlState(common::HardwareStateManager& manager, common::OperationMessage& operationMessage, bool& nextStep,
bool& continueBackup, bool forceDelete)
{
// 状態遷移Controller
switch (s_BackupState)
{
// 起動時
case STARTUP:
{
bool error = false;
// 完全性検証SEEDを読めるか
if (manager.CanReadIvs())
{
// SDカードが挿入されているか
if (nn::fs::IsSdmcInserted())
{
// SDカードに書き込みできるか
if (!nn::fs::IsSdmcWritable())
{
if (!s_SdWriteProetctAnnotation)
{
s_SdWriteProetctAnnotation = true;
common::PlaySound(common::SOUND_ANNOTATION);
}
operationMessage.Add("Can*t Write SD Card!!\n");
break;
}
// 無線設定ファイルがあるか?
if (common::ExistsAPSetting())
{
// 書き込み中に抜かないように
if (nextStep)
{
// シリアルナンバーを読み取れるか?
if (!manager.CanReadSerialNumber())
{
common::PlaySound(common::SOUND_ANNOTATION);
COMMON_LOGGER("Can't Read Serial Number\n");
}
}
}
else
{
error = true;
if (!s_ExistAPSettingAnnotation)
{
s_ExistAPSettingAnnotation = true;
common::PlaySound(common::SOUND_ANNOTATION);
}
operationMessage.Add("Accsess_Point_Setting does not exist!");
}
}
else
{
error = true;
operationMessage.Add("Insert SD Card!!");
}
}
else
{
error = true;
operationMessage.Add("Can't Read SDCI!!");
}
// ACアダプタが必要か
if (NeedsAcAdapter(manager))
{
error = true;
operationMessage.Add("Connect AC Adapter!!");
}
// エラーが無ければ進行用メッセージ表示
if (!error)
{
operationMessage.Add("Push A or START Button");
if (!s_PlayedStartCursor)
{
common::PlaySound(common::SOUND_CURSOR);
s_PlayedStartCursor = true;
}
}
if (nextStep && !error)
{
COMMON_LOGGER("Checking SaveData\n");
if(forceDelete)
{
s_BackupMode = BACKUP_MODE_DELETE_IF_FAILED;
}
s_BackupState = MODIFY_MENU_SAVEDATA;
}
}
break;
case MODIFY_MENU_SAVEDATA:
{
MenuSavedataModifier modifier;
common::VerDef version;
manager.GetVersionData(&version);
nn::Result result = modifier.Modify(nn::cfg::GetRegion(), version.cup);
COMMON_LOGGER_RESULT_IF_FAILED(result);
s_BackupState = CHECK_SAVEDATA;
}
break;
case CHECK_SAVEDATA:
{
static bool init = true;
if (init)
{
StartSaveDataCheck(s_BackupMode == BACKUP_MODE_DELETE_IF_FAILED);
init = false;
}
PutAliveMessage(operationMessage, "Checking SaveData");
if (IsCheckSaveDataFinished())
{
FinalizeSaveDataCheck();
// 削除モードでなければエラーにする
if (CheckSaveDataErrorOccured() && !forceDelete)
{
s_BackupState = FAIL_CHECK;
}
else
{
if (CheckSaveDataSucceeded())
{
COMMON_LOGGER("Start Export Data\n");
s_BackupState = EXPORT_TWL_NAND;
}
else
{
s_BackupState = FAIL;
}
}
}
}
break;
// TWLセーブデータ領域の吸出し中
case EXPORT_TWL_NAND:
{
static bool init = true;
if (init)
{
// 権利の無いタイトルを削除する
if(nn::am::DeleteAllExpiredUserPrograms().IsFailure())
{
COMMON_LOGGER("Can't delete expired titles");
s_BackupState = FAIL;
break;
}
// コンテキストを初期化する
InitializeFileListContext();
// データを書き込む
if (ExportTwlSaveData().IsFailure())
{
s_BackupState = FAIL;
break;
}
init = false;
}
PutAliveMessage(operationMessage, "Exporting TWL SaveData");
// 処理が完了した
if (IsExportThreadFinished())
{
FinalizeExportThread();
if (IsExportSucceeded())
{
s_BackupState = EXPORT_TWL_SOUND;
}
else
{
s_BackupState = FAIL;
}
}
}
break;
// TWLサウンド領域の吸出し中
case EXPORT_TWL_SOUND:
{
static bool init = true;
if (init)
{
// データを書き込む
ExportTwlSoundData();
init = false;
}
PutAliveMessage(operationMessage, "Exporting TWL Sound Data");
// 処理が完了した
if (IsExportThreadFinished())
{
FinalizeExportThread();
if (IsExportSucceeded())
{
s_BackupState = EXPORT_TWL_PHOTO;
}
else
{
s_BackupState = FAIL;
}
}
}
break;
// TWL写真領域の吸出し中
case EXPORT_TWL_PHOTO:
{
static bool init = true;
if (init)
{
// データを書き込む
ExportTwlPhotoData();
init = false;
}
PutAliveMessage(operationMessage, "Exporting TWL Photo Data");
// 処理が完了した
if (IsExportThreadFinished())
{
FinalizeExportThread();
if (IsExportSucceeded())
{
s_BackupState = EXPORT_CTR_NAND;
}
else
{
s_BackupState = FAIL;
}
}
}
break;
// 吸出し中
case EXPORT_CTR_NAND:
{
continueBackup = true;
// ACアダプタが必要か
if (NeedsAcAdapter(manager))
{
continueBackup = false;
operationMessage.Add("Connect AC Adapter!!");
}
PutAliveMessage(operationMessage, "Exporting Nand Data");
// データを書き込む
if (!ExportData(manager))
{
s_BackupState = FAIL;
}
else
{
// 処理が完了した
if (continueBackup && IsExportThreadFinished())
{
FinalizeExportThread();
if (IsExportSucceeded())
{
COMMON_LOGGER("Export NAND Data Finished.\n");
if (GetExportProgress() > 99)
{
s_BackupState = DELETE_NIM;
}
else
{
s_BackupState = FAIL;
}
}
else
{
s_BackupState = FAIL;
}
}
}
}
break;
// nimのシステムセーブデータ削除
case DELETE_NIM:
{
if (DeleteNimSaveData())
{
s_BackupState = DONE;
}
else
{
s_BackupState = FAIL;
}
}
break;
// 吸出し完了
case DONE:
{
operationMessage.Add("Backup Done. Pull Out SD Card.");
static bool init = true;
if(init)
{
manager.SetWifiOff();
init = false;
}
if (!s_PlayedSdPullOutCursor)
{
common::PlaySound(common::SOUND_CURSOR);
s_PlayedSdPullOutCursor = true;
}
}
break;
// SDカード抜き完了
case FINISHED:
{
operationMessage.Add("Backup Succeeded!!\n");
if (!s_PlayedFinishedSound)
{
common::PlaySound(common::SOUND_OK);
s_PlayedFinishedSound = true;
}
}
break;
// 吸出し失敗
case FAIL:
{
operationMessage.Add("Backup Failed.");
if (!s_PlayedFailSound)
{
common::PlaySound(common::SOUND_NG);
s_PlayedFailSound = true;
}
}
break;
case FAIL_CHECK:
{
operationMessage.Add("Check Error.");
if (!s_PlayedFailSound)
{
common::PlaySound(common::SOUND_NG);
s_PlayedFailSound = true;
}
}
break;
}
}
u32 GetProgress()
{
if(s_BackupState == CHECK_SAVEDATA)
{
return GetCheckSaveDataProgress();
}
else if (s_BackupState == EXPORT_TWL_NAND || s_BackupState == EXPORT_TWL_PHOTO|| s_BackupState == EXPORT_TWL_SOUND)
{
return common::GetProgress();
}
else
{
return GetExportProgress();
}
}
// バックアップモードを取得する
BackupMode GetBackupMode()
{
return s_BackupMode;
}
bool InProgress()
{
return s_BackupState == EXPORT_CTR_NAND;
}
bool IsBackupSucceeded()
{
return s_BackupState == FINISHED;
}
bool IsBackupFailed()
{
return s_BackupState == FAIL;
}
bool IsBackupWarning()
{
return s_BackupState == FAIL_CHECK;
}
void OnSdEjected()
{
if(s_BackupState == DONE || s_BackupState == FINISHED)
{
s_BackupState = FINISHED;
}
else if(s_BackupState != FAIL && s_BackupState != FAIL_CHECK)
{
common::InitializeFileCheck();
InitializeState();
}
}
void OnSdInserted()
{
common::Logger::GetLoggerInstance()->ClearSdLog();
}
void InitializeState()
{
s_BackupState = STARTUP;
s_PlayedFailSound = false;
s_PlayedFinishedSound = false;
s_ExistAPSettingAnnotation = false;
s_PlayedStartCursor = false;
s_PlayedSdPullOutCursor = false;
s_SdWriteProetctAnnotation = false;
}
} // namespace ConsoleBackup