プリインストールアプリをPersonalized eTicketでリストアップするように

インポート済みのタイトルはダウンロードしないように
ユーザSD書き込み後にFAILしてもリトライできるように

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@633 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2012-02-15 06:42:11 +00:00
parent e5af1a3526
commit 6aafdc6124
10 changed files with 95 additions and 20 deletions

View File

@ -185,6 +185,7 @@ extern "C" void nnMain(void)
{
bool nextStep = false;
bool operateBmsDone = false;
bool forcePreinstall = false;
s_PadReader.ReadLatest(&padStatus);
@ -195,9 +196,11 @@ extern "C" void nnMain(void)
nextStep = true;
}
// YボタンでBMS操作完了
// Yボタンで強制プリインストール
if(padStatus.trigger & nn::hid::BUTTON_Y)
{
operateBmsDone = true;
forcePreinstall = true;
}
// LまたはRボタンで上下画面フリップ
@ -246,7 +249,7 @@ extern "C" void nnMain(void)
common::OperationMessage operationMessage;
ControlState(manager, operationMessage, nextStep, operateBmsDone);
ControlState(manager, operationMessage, nextStep, operateBmsDone, forcePreinstall);
nn::util::FloatColor titleColor;

View File

@ -55,6 +55,8 @@ bool s_CheckSdOnlyMode = false;
bool s_SkipNupMode = false;
// プリインストール書き込みモードかどうか
bool s_DownloadPreinstallMode = false;
// 強制プリインストール書き込みモードかどうか
bool s_ForceDownloadPreinstall = false;
// 失敗サウンドを鳴らしたかどうか
bool s_PlayedFailSound = false;
@ -148,9 +150,11 @@ typedef enum RestoreState
// プリインストールダウンロードモード
PREINSTALL_WAIT_SYNC_TICKET, // 開始ボタン待ち
PREINSTALL_DELETE_PERSONALIZED_TICKET, // Personalized eTicketの削除
PREINSTALL_WAIT_USER_SD_INSERT, // ユーザSD挿入待ち
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, // アプリダウンロード
@ -820,7 +824,8 @@ nn::Result ExecSyncMcuRtc(common::HardwareStateManager& manager)
} // namespace <unnamed>
void ControlState(common::HardwareStateManager& manager, common::OperationMessage& operationMessage, bool& nextStep, bool operateBmsDone)
void ControlState(common::HardwareStateManager& manager, common::OperationMessage& operationMessage, bool& nextStep,
bool operateBmsDone, bool forcePreinstall)
{
using namespace common;
nn::Result result;
@ -1636,7 +1641,7 @@ void ControlState(common::HardwareStateManager& manager, common::OperationMessag
bit64 deviceId = manager.GetDeviceId() + 0x400000000;
u8 serial[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
manager.GetSerialNumberWithoutCD(serial);
StartPreparePreinstallTitleDownload(deviceId, serial);
StartPreparePreinstallTitleDownload(deviceId, serial, s_ForceDownloadPreinstall);
}
// 動いていることを表示
@ -1675,8 +1680,7 @@ void ControlState(common::HardwareStateManager& manager, common::OperationMessag
nn::Result::MODULE_APPLICATION, nn::Result::DESCRIPTION_ALREADY_INITIALIZED))
{
// ユーザSDが初期化済み
s_RestoreState = PREINSTALL_CHECK_SD_FAIL;
s_RestoreState = PREINSTALL_CHECK_USER_SD_ALREADY_INITIALIZED;
}
else if (GetTitleDownloadResult()
== nn::MakePermanentResult(nn::Result::SUMMARY_NOT_FOUND,
@ -1702,6 +1706,24 @@ void ControlState(common::HardwareStateManager& manager, common::OperationMessag
}
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);
@ -1823,6 +1845,8 @@ void ControlState(common::HardwareStateManager& manager, common::OperationMessag
{
COMMON_LOGGER("Download PreInstalled Application done\n");
ChangeState(saved, s_RestoreState, WAIT_SD_EJECT);
// リストア状態チェックファイルをすべて削除
DeleteAllCheckFiles();
}
else
{

View File

@ -43,7 +43,9 @@ const u32 RETRY_MAX = 3;
// operationMessage 操作情報として表示したい文字列
// nextStep 次の状態に遷移してもよいかどうか
// operateBmsDone BMS操作を完了したかどうか
void ControlState(common::HardwareStateManager& manager, common::OperationMessage& operationMessage, bool& nextStep, bool operateBmsDone);
// forcePreinstall ユーザSDが初期化済みだが、プリインストールアプリを書き込むかどうか
void ControlState(common::HardwareStateManager& manager, common::OperationMessage& operationMessage, bool& nextStep,
bool operateBmsDone, bool forcePreinstall);
// リストア処理中かどうか
bool InProgress();

View File

@ -36,7 +36,7 @@ PreinstallImporter::~PreinstallImporter()
// TODO Auto-generated destructor stub
}
nn::Result PreinstallImporter::SetupSd(bool* isAlreadyAvailable)
nn::Result PreinstallImporter::SetupSd(bool* isAlreadyAvailable, bool forcePreinstall)
{
// SDカードがインポート可能状態かどうかチェック
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(
@ -51,6 +51,11 @@ nn::Result PreinstallImporter::SetupSd(bool* isAlreadyAvailable)
);
}
if(forcePreinstall)
{
// 未初期化として返す
*isAlreadyAvailable = false;
}
return nn::ResultSuccess();
}

View File

@ -31,7 +31,9 @@ public:
virtual ~PreinstallImporter();
//! @brief 外部タイトルデータベースを作成します
nn::Result SetupSd(bool* isAlreadyAvailable);
//! @param[out] list    SDカードが初期化済みかどうか
//! @param[in] forcePreinstall    SDカードが初期化済みでもプリインストールを書き込むかどうか
nn::Result SetupSd(bool* isAlreadyAvailable, bool forcePreinstall);
//! @brief ダウンロードするプリインストールタイトルをBGS経由でリストアップする
//! @param[out] list    プリインストールタイトルの配列。十分に大きいものを渡すこと。

View File

@ -32,15 +32,19 @@ using namespace EC_NAMESPACE;
#define NIM_SHOP_RESULT_CHECK(result) \
do { \
if (result.IsFailure()) \
::nn::Result shopResult = (result); \
if (shopResult.IsFailure()) \
{ \
ECCustomerSupportCode csc; \
nn::nim::Shop::GetCustomerSupportCode(&csc); \
COMMON_LOGGER("CSCode: %d\n", csc); \
COMMON_LOGGER_RESULT_IF_FAILED(result); \
NN_DBG_PRINT_RESULT(result); \
COMMON_LOGGER_DETAIL("Result = %08X\n", result.GetPrintableBits()); \
s_ShopResult = result; \
if(csc != 0)\
{\
COMMON_LOGGER("CSCode: %d\n", csc); \
}\
COMMON_LOGGER_RESULT_IF_FAILED(shopResult); \
NN_DBG_PRINT_RESULT(shopResult); \
COMMON_LOGGER_DETAIL("Result = %08X\n", shopResult.GetPrintableBits()); \
s_ShopResult = shopResult; \
return; \
} \
} while(0)

View File

@ -160,7 +160,7 @@ void PreparePreinstallTitleDownloadThreadFunc(PreinstallListupParam param)
PreinstallImporter importer;
bool isAlreadyAvailable = false;
TitleDownloader preinstallTitleDownloader;
preinstallTitleDownloader.m_Result = importer.ListTitles(s_ProgramIdList, &s_ProgramIdNum, param.deviceId, param.serialNo);
preinstallTitleDownloader.m_Result = importer.ListTitlesBasedOnTickets(s_ProgramIdList, &s_ProgramIdNum);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(preinstallTitleDownloader.m_Result);
preinstallTitleDownloader.SetupTitleList(s_ProgramIdList, s_ProgramIdNum, s_FinishedTitleNum);
@ -187,7 +187,7 @@ void PreparePreinstallTitleDownloadThreadFunc(PreinstallListupParam param)
return;
}
preinstallTitleDownloader.m_Result = importer.SetupSd(&isAlreadyAvailable);
preinstallTitleDownloader.m_Result = importer.SetupSd(&isAlreadyAvailable, param.forcePreinstall);
if(isAlreadyAvailable)
{
preinstallTitleDownloader.m_Result = nn::MakePermanentResult(nn::Result::SUMMARY_INVALID_STATE,
@ -197,11 +197,12 @@ void PreparePreinstallTitleDownloadThreadFunc(PreinstallListupParam param)
}
void StartPreparePreinstallTitleDownload(bit64 deviceId, u8* serialNo)
void StartPreparePreinstallTitleDownload(bit64 deviceId, u8* serialNo, bool forcePreinstall)
{
PreinstallListupParam param;
param.deviceId = deviceId;
std::memcpy(param.serialNo, serialNo, nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
param.forcePreinstall = forcePreinstall;
s_TitleDownloaderThread.Start(PreparePreinstallTitleDownloadThreadFunc, param, s_TitleDownloaderThreadStack);
}
@ -346,6 +347,29 @@ void TitleDownloader::Start()
for(u8 i = m_FinishedTitleNum; i < m_TiteNum; i++)
{
s_Progress = i * 100 / m_TiteNum;
nn::am::ProgramInfo info;
// 既にインポート済みならスキップ
if (nn::CTR::IsTwlApp(m_ProgramIdList[i]))
{
m_Result = nn::am::GetProgramInfos(&info, nn::fs::MEDIA_TYPE_NAND, &m_ProgramIdList[i], 1);
if (m_Result.IsSuccess())
{
m_FinishedTitleNum++;
continue;
}
}
else if(nn::CTR::IsCtr(m_ProgramIdList[i]))
{
m_Result = nn::am::GetProgramInfos(&info, nn::fs::MEDIA_TYPE_SDMC, &m_ProgramIdList[i], 1);
if (m_Result.IsSuccess())
{
m_FinishedTitleNum++;
continue;
}
}
StartShopOperationSingle(SHOP_OPERATION_CONNECT_WITHOUT_CLOSE);
WaitShopOperationAndFinalize();
m_Result = GetShopOperationSingleResult();
@ -358,10 +382,19 @@ void TitleDownloader::Start()
StartShopOperationSingle(SHOP_OPERATION_DOWNLOAD_TITLE, config);
WaitShopOperationAndFinalize();
m_Result = GetShopOperationSingleResult();
// ダウンロード済みならスキップ
if(m_Result == nn::nim::ResultAlreadyDownloaded())
{
m_FinishedTitleNum++;
continue;
}
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
m_FinishedTitleNum++;
}
// 成功にセットしておく
m_Result = nn::ResultSuccess();
}
void TitleDownloader::SetupTitleList(nn::ProgramId* list, size_t num, u32 index)

View File

@ -28,8 +28,9 @@ void StartTwlTitleDownload();
//! 可能であればSDカードをインポート可能状態にします
//! @param[in] deviceId デバイスID
//! @param[in] serialNo シリアルナンバー
//! @param[in] serialNo 強制的にプリインストールを書き込むかどうか
//! @return 正常に初期化できたかどうか
void StartPreparePreinstallTitleDownload(bit64 deviceId, u8* serialNo);
void StartPreparePreinstallTitleDownload(bit64 deviceId, u8* serialNo, bool forcePreinstall);
//! @brief 新たにスレッドを立て、プリインストールタイトルのダウンロードを開始します <BR/>
//! SDカードはインポート可能な状態にしておく必要があります。
@ -41,6 +42,7 @@ struct PreinstallListupParam
{
bit64 deviceId;
u8 serialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
bool forcePreinstall;
};
//! @brief ダウンロードするTWLタイトルをSDカードからリストアップする

View File

@ -129,7 +129,7 @@ void PreinstallImporterTest::SetupSd()
ConsoleRestore::PreinstallImporter importer;
bool isAlreadyInitialized = false;
importer.SetupSd(&isAlreadyInitialized);
importer.SetupSd(&isAlreadyInitialized, false);
NN_TEST_ASSERT(isAlreadyInitialized);
}

View File

@ -116,7 +116,7 @@ void TitleDownloaderTest::ListUp()
void TitleDownloaderTest::DownloadPreinstall()
{
ConsoleRestore::StartPreparePreinstallTitleDownload(17179924184, reinterpret_cast<u8*>(const_cast<char*>("EJA20305940")));
ConsoleRestore::StartPreparePreinstallTitleDownload(17179924184, reinterpret_cast<u8*>(const_cast<char*>("EJA20305940")), false);
while(!ConsoleRestore::IsDownloadTitleFinished())
{