ダウンロード前にSDカードの容量チェックをしてからタイトルデータベースを作るように

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@604 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2012-01-25 07:54:55 +00:00
parent 86a7f1526b
commit 4667e4e1c0
5 changed files with 262 additions and 50 deletions

View File

@ -86,6 +86,12 @@ bool s_ExecuteTwlTitleDownload = false;
// TWLタイトルのダウンロードを何回リトライしたか // TWLタイトルのダウンロードを何回リトライしたか
u32 s_TwlTitleDownloadRetryCount = 0; u32 s_TwlTitleDownloadRetryCount = 0;
// プリインストールタイトルのダウンロード準備を開始したかどうか
bool s_ExecutePreparePreinstallTitleDownload = false;
// プリインストールタイトルのダウンロード準備を何回リトライしたか
u32 s_PreparePreinstallTitleDownloadRetryCount = 0;
// プリインストールタイトルのダウンロードを開始したかどうか // プリインストールタイトルのダウンロードを開始したかどうか
bool s_ExecutePreinstallTitleDownload = false; bool s_ExecutePreinstallTitleDownload = false;
// プリインストールタイトルのダウンロードを何回リトライしたか // プリインストールタイトルのダウンロードを何回リトライしたか
@ -159,10 +165,12 @@ typedef enum RestoreState
// プリインストールダウンロードモード // プリインストールダウンロードモード
PREINSTALL_WAIT_SYNC_TICKET, // 開始ボタン待ち PREINSTALL_WAIT_SYNC_TICKET, // 開始ボタン待ち
PREINSTALL_WAIT_USER_SD_INSERT, // ユーザSD挿入待ち PREINSTALL_WAIT_USER_SD_INSERT, // ユーザSD挿入待ち
PREINSTALL_CHECK_USER_SD_INSERT, // ユーザSDの挿入チェック
PREINSTALL_CHECK_USER_SD, // ユーザSDのチェック PREINSTALL_CHECK_USER_SD, // ユーザSDのチェック
PREINSTALL_CHECK_SD_FAIL, // ユーザSDのチェック失敗 PREINSTALL_CHECK_SD_FAIL, // ユーザSDのチェック失敗
PREINSTALL_FAIL_CHECK_REPAIR_SD, // ユーザSDのチェック失敗後の修理用SDのチェック PREINSTALL_FAIL_CHECK_REPAIR_SD, // ユーザSDのチェック失敗後の修理用SDのチェック
PREINSTALL_DOWNLOAD_APP, // アプリダウンロード PREINSTALL_DOWNLOAD_APP, // アプリダウンロード
PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE, // アプリダウンロード失敗、空き容量不足
PREINSTALL_WAIT_USER_SD_EJECT, // ユーザSD抜き出し待ち PREINSTALL_WAIT_USER_SD_EJECT, // ユーザSD抜き出し待ち
PREINSTALL_CHECK_REPAIR_SD // 修理用SDのチェック PREINSTALL_CHECK_REPAIR_SD // 修理用SDのチェック
} RestoreState; } RestoreState;
@ -1450,7 +1458,7 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
if (s_TwlTitleDownloadRetryCount++ < RETRY_MAX) if (s_TwlTitleDownloadRetryCount++ < RETRY_MAX)
{ {
// エラーのためやり直す // エラーのためやり直す
COMMON_LOGGER_RESULT_IF_FAILED(GetShopOperationSingleResult()); COMMON_LOGGER_RESULT_IF_FAILED(GetTitleDownloadResult());
COMMON_LOGGER("Download Twl Title Failed. Retrying... %d\n", s_TwlTitleDownloadRetryCount); COMMON_LOGGER("Download Twl Title Failed. Retrying... %d\n", s_TwlTitleDownloadRetryCount);
s_ExecuteTwlTitleDownload = false; s_ExecuteTwlTitleDownload = false;
@ -1646,9 +1654,9 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
} }
break; break;
case PREINSTALL_CHECK_USER_SD: case PREINSTALL_CHECK_USER_SD_INSERT:
{ {
RestoreState saved = PREINSTALL_CHECK_USER_SD; RestoreState saved = PREINSTALL_CHECK_USER_SD_INSERT;
if (nn::fs::IsSdmcInserted()) if (nn::fs::IsSdmcInserted())
{ {
NN_LOG("Check User's SD Card\n"); NN_LOG("Check User's SD Card\n");
@ -1662,14 +1670,71 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
{ {
// SD挿抜が起こったら抜ける // SD挿抜が起こったら抜ける
BREAK_IF_STATE_CHANGED(saved, s_RestoreState); BREAK_IF_STATE_CHANGED(saved, s_RestoreState);
if (PreparePreinstallTitleDownload()) ChangeState(saved, s_RestoreState, PREINSTALL_CHECK_USER_SD);
}
}
}
break;
case PREINSTALL_CHECK_USER_SD:
{ {
ChangeState(saved, s_RestoreState, PREINSTALL_DOWNLOAD_APP); if (!s_ExecutePreparePreinstallTitleDownload)
{
COMMON_LOGGER("Checking User's SD Card\n");
s_ExecutePreparePreinstallTitleDownload = true;
bit64 deviceId = manager.GetDeviceId() + 0x400000000;
u8 serial[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
manager.GetSerialNumberWithoutCD(serial);
StartPreparePreinstallTitleDownload(deviceId, serial);
}
// 動いていることを表示
{
PutAliveMessage(operationMessage, "Checking User's SD Card");
}
if (IsDownloadTitleFinished())
{
FinalizeTitleDownload();
if (DownloadTitleSucceeded())
{
s_RestoreState = PREINSTALL_DOWNLOAD_APP;
} }
else else
{ {
COMMON_LOGGER("Error: Valid User Savedata Exists.\n"); if (s_PreparePreinstallTitleDownloadRetryCount++ < RETRY_MAX)
ChangeState(saved, s_RestoreState, PREINSTALL_CHECK_SD_FAIL); {
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_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;
} }
} }
} }
@ -1713,10 +1778,7 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
{ {
COMMON_LOGGER("Download PreInstall Application\n"); COMMON_LOGGER("Download PreInstall Application\n");
s_ExecutePreinstallTitleDownload = true; s_ExecutePreinstallTitleDownload = true;
bit64 deviceId = manager.GetDeviceId() + 0x400000000; StartPreinstallTitleDownload();
u8 serial[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
manager.GetSerialNumberWithoutCD(serial);
StartPreinstallTitleDownload(deviceId, serial);
} }
// 動いていることを表示 // 動いていることを表示
@ -1737,11 +1799,21 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
if (s_PreinstallTitleDownloadRetryCount++ < RETRY_MAX) if (s_PreinstallTitleDownloadRetryCount++ < RETRY_MAX)
{ {
// エラーのためやり直す // エラーのためやり直す
COMMON_LOGGER_RESULT_IF_FAILED(GetShopOperationSingleResult()); 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 PreInstall Title Failed. Retrying... %d\n", s_PreinstallTitleDownloadRetryCount); COMMON_LOGGER("Download PreInstall Title Failed. Retrying... %d\n", s_PreinstallTitleDownloadRetryCount);
s_ExecutePreinstallTitleDownload = false; s_ExecutePreinstallTitleDownload = false;
} }
}
else else
{ {
s_RestoreState = PREINSTALL_WAIT_USER_SD_EJECT; s_RestoreState = PREINSTALL_WAIT_USER_SD_EJECT;
@ -1751,6 +1823,14 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
} }
break; break;
case PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE:
{
operationMessage.push_back(::std::string("Not enough space on User's SD Card"));
operationMessage.push_back(::std::string("Pull out User's SD Card"));
operationMessage.push_back(::std::string("and Insert Repairing SD Card"));
}
break;
case PREINSTALL_WAIT_USER_SD_EJECT: case PREINSTALL_WAIT_USER_SD_EJECT:
{ {
operationMessage.push_back(::std::string("Pull out User's SD Card")); operationMessage.push_back(::std::string("Pull out User's SD Card"));
@ -1826,12 +1906,13 @@ void OnSdEjected()
// IVSチェック時はユーザのSDカードを挿入してもらうため // IVSチェック時はユーザのSDカードを挿入してもらうため
// プリインストール時はユーザのSDカードを挿入してもらうため // プリインストール時はユーザのSDカードを挿入してもらうため
else if (s_RestoreState != FAIL && s_RestoreState != CHECK_IVS && s_RestoreState != PREINSTALL_WAIT_USER_SD_INSERT 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_WAIT_USER_SD_EJECT && s_RestoreState != PREINSTALL_CHECK_SD_FAIL &&
s_RestoreState != PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE)
{ {
InitializeState(); InitializeState();
ClearFileReadResult(); ClearFileReadResult();
} }
else if(s_RestoreState == PREINSTALL_CHECK_USER_SD) else if(s_RestoreState == PREINSTALL_CHECK_USER_SD_INSERT)
{ {
s_RestoreState = PREINSTALL_WAIT_USER_SD_INSERT; s_RestoreState = PREINSTALL_WAIT_USER_SD_INSERT;
} }
@ -1853,7 +1934,7 @@ void OnSdInserted()
{ {
// SDカードが変わるのでファイルチェックは初期化する // SDカードが変わるのでファイルチェックは初期化する
common::InitializeFileCheck(); common::InitializeFileCheck();
s_RestoreState = PREINSTALL_CHECK_USER_SD; s_RestoreState = PREINSTALL_CHECK_USER_SD_INSERT;
} }
else if(s_RestoreState == PREINSTALL_WAIT_USER_SD_EJECT) else if(s_RestoreState == PREINSTALL_WAIT_USER_SD_EJECT)
{ {
@ -1861,7 +1942,7 @@ void OnSdInserted()
common::InitializeFileCheck(); common::InitializeFileCheck();
s_RestoreState = PREINSTALL_CHECK_REPAIR_SD; s_RestoreState = PREINSTALL_CHECK_REPAIR_SD;
} }
else if(s_RestoreState == PREINSTALL_CHECK_SD_FAIL) else if(s_RestoreState == PREINSTALL_CHECK_SD_FAIL || s_RestoreState == PREINSTALL_DOWNLOAD_APP_NOT_ENOUGH_SPACE)
{ {
// SDカードが変わるのでファイルチェックは初期化する // SDカードが変わるのでファイルチェックは初期化する
common::InitializeFileCheck(); common::InitializeFileCheck();

View File

@ -19,6 +19,7 @@
#include <nn/CTR/CTR_ProgramId.h> #include <nn/CTR/CTR_ProgramId.h>
#include <nn/cfg/CTR/cfg_ApiSys.h> #include <nn/cfg/CTR/cfg_ApiSys.h>
#include "SdMountManager.h"
#include "common_Types.h" #include "common_Types.h"
#include "FileName.h" #include "FileName.h"
#include "CommonLogger.h" #include "CommonLogger.h"
@ -34,6 +35,11 @@ namespace
bit8 s_buffer1[400 * 1024]; bit8 s_buffer1[400 * 1024];
// ダウンロードするタイトルの個数
size_t s_ProgramIdNum = 0;
// ダウンロードするタイトルのProgramIdの配列
nn::ProgramId s_ProgramIdList[256];
const size_t TITLE_DOWNLOADER_STACK_SIZE = 0x2000; const size_t TITLE_DOWNLOADER_STACK_SIZE = 0x2000;
nn::os::Thread s_TitleDownloaderThread; nn::os::Thread s_TitleDownloaderThread;
nn::os::StackBuffer<TITLE_DOWNLOADER_STACK_SIZE> s_TitleDownloaderThreadStack; nn::os::StackBuffer<TITLE_DOWNLOADER_STACK_SIZE> s_TitleDownloaderThreadStack;
@ -90,20 +96,22 @@ nn::Result GetEntry(ES_NAMESPACE::ESTitleId titleId, EC_NAMESPACE::ECTitleCatalo
return result; return result;
} }
nn::Result GetTitleConfig(const ES_NAMESPACE::ESTitleId titleId, nn::nim::TitleConfig *titleConfig) nn::Result GetTitleConfig(const ES_NAMESPACE::ESTitleId titleId, nn::nim::TitleConfig *titleConfig, s64* requiredSize)
{ {
EC_NAMESPACE::ECTitleCatalogEntry *entry; EC_NAMESPACE::ECTitleCatalogEntry *entry;
NN_UTIL_RETURN_IF_FAILED(GetEntry(titleId, &entry)); NN_UTIL_RETURN_IF_FAILED(GetEntry(titleId, &entry));
titleConfig->titleId=titleId; titleConfig->titleId =titleId;
titleConfig->version=std::strtoull(GetAttribute(entry->attributes, entry->nAttributes, "Version"), NULL, 10); titleConfig->version=std::strtoull(GetAttribute(entry->attributes, entry->nAttributes, "Version"), NULL, 10);
titleConfig->ratingAge=0; titleConfig->ratingAge=0;
titleConfig->media=GetMediaType(titleId); titleConfig->media=GetMediaType(titleId);
*requiredSize=std::strtoull(GetAttribute(entry->attributes, entry->nAttributes, "MaxUserFileSize"), NULL, 10);
COMMON_LOGGER_DETAIL("titleId : 0x%016llx\n", titleConfig->titleId); COMMON_LOGGER_DETAIL("titleId : 0x%016llx\n", titleConfig->titleId);
COMMON_LOGGER_DETAIL("version : %lld\n" , titleConfig->version); COMMON_LOGGER_DETAIL("version : %lld\n" , titleConfig->version);
COMMON_LOGGER_DETAIL("ratingAge : %d\n" , titleConfig->ratingAge); COMMON_LOGGER_DETAIL("ratingAge : %d\n" , titleConfig->ratingAge);
COMMON_LOGGER_DETAIL("media : %d\n" , titleConfig->media); COMMON_LOGGER_DETAIL("media : %d\n" , titleConfig->media);
COMMON_LOGGER_DETAIL("size : %lld\n" , *requiredSize);
return nn::ResultSuccess(); return nn::ResultSuccess();
@ -122,25 +130,18 @@ void TwlTitleDownloaderThreadFunc()
TitleDownloader TwlTitleDownloader; TitleDownloader TwlTitleDownloader;
s_Progress = 0; s_Progress = 0;
size_t num = 0; TitleDownloader::m_Result = ListUpTwlTitles(s_ProgramIdList, &s_ProgramIdNum);
nn::ProgramId list[256];
TitleDownloader::m_Result = ListUpTwlTitles(list, &num);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(TitleDownloader::m_Result); COMMON_LOGGER_RETURN_VOID_IF_FAILED(TitleDownloader::m_Result);
TwlTitleDownloader.SetupTitleList(list, num); TwlTitleDownloader.SetupTitleList(s_ProgramIdList, s_ProgramIdNum);
TwlTitleDownloader.Start(); TwlTitleDownloader.Start();
} }
void PreinstallTitleDownloaderThreadFunc(PreinstallListupParam param) void PreinstallTitleDownloaderThreadFunc()
{ {
TitleDownloader PreinstallTitleDownloader; TitleDownloader PreinstallTitleDownloader;
PreinstallImporter importer; PreinstallImporter importer;
s_Progress = 0; s_Progress = 0;
size_t num = 0;
nn::ProgramId list[256];
TitleDownloader::m_Result = importer.ListTitles(list, &num, param.deviceId, param.serialNo);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(TitleDownloader::m_Result);
PreinstallTitleDownloader.SetupTitleList(list, num);
PreinstallTitleDownloader.Start(); PreinstallTitleDownloader.Start();
} }
@ -150,27 +151,60 @@ void StartTwlTitleDownload()
} }
bool PreparePreinstallTitleDownload() void PreparePreinstallTitleDownloadThreadFunc(PreinstallListupParam param)
{ {
PreinstallImporter importer; PreinstallImporter importer;
bool isAlreadyAvailable = false; bool isAlreadyAvailable = false;
TitleDownloader::m_Result = importer.SetupSd(&isAlreadyAvailable); TitleDownloader preinstallTitleDownloader;
preinstallTitleDownloader.m_Result = importer.ListTitles(s_ProgramIdList, &s_ProgramIdNum, param.deviceId, param.serialNo);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(preinstallTitleDownloader.m_Result);
if(isAlreadyAvailable) preinstallTitleDownloader.SetupTitleList(s_ProgramIdList, s_ProgramIdNum);
s64 requiredSize;
preinstallTitleDownloader.CalculateRequiredSize(&requiredSize);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(preinstallTitleDownloader.m_Result);
s64 total;
s64 free;
preinstallTitleDownloader.m_Result= common::SdMountManager::Mount();
COMMON_LOGGER_RETURN_VOID_IF_FAILED(preinstallTitleDownloader.m_Result);
preinstallTitleDownloader.m_Result = nn::fs::GetSdmcSize(&total, &free);
NN_LOG("total = %lld, free = %lld\n", total, free);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(preinstallTitleDownloader.m_Result);
preinstallTitleDownloader.m_Result= common::SdMountManager::Unmount();
COMMON_LOGGER_RETURN_VOID_IF_FAILED(preinstallTitleDownloader.m_Result);
NN_LOG("requiredSize = %lld\n", requiredSize + 8 * 1024 * 1024);
// TODO: SDデータベースの正確なサイズを反映する
if(free < requiredSize + 8 * 1024 * 1024)
{ {
return false; preinstallTitleDownloader.m_Result = nn::MakePermanentResult(nn::Result::SUMMARY_OUT_OF_RESOURCE,
nn::Result::MODULE_APPLICATION, nn::Result::DESCRIPTION_OUT_OF_MEMORY);
return;
}
preinstallTitleDownloader.m_Result = importer.SetupSd(&isAlreadyAvailable);
if(isAlreadyAvailable)
{
preinstallTitleDownloader.m_Result = nn::MakePermanentResult(nn::Result::SUMMARY_INVALID_STATE,
nn::Result::MODULE_APPLICATION, nn::Result::DESCRIPTION_ALREADY_INITIALIZED);
return;
} }
return TitleDownloader::m_Result.IsSuccess();
} }
void StartPreinstallTitleDownload(bit64 deviceId, u8* serialNo) void StartPreparePreinstallTitleDownload(bit64 deviceId, u8* serialNo)
{ {
PreinstallListupParam param; PreinstallListupParam param;
param.deviceId = deviceId; param.deviceId = deviceId;
std::memcpy(param.serialNo, serialNo, nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN); std::memcpy(param.serialNo, serialNo, nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
s_TitleDownloaderThread.Start(PreinstallTitleDownloaderThreadFunc, param, s_TitleDownloaderThreadStack); s_TitleDownloaderThread.Start(PreparePreinstallTitleDownloadThreadFunc, param, s_TitleDownloaderThreadStack);
}
void StartPreinstallTitleDownload()
{
s_TitleDownloaderThread.Start(PreinstallTitleDownloaderThreadFunc, s_TitleDownloaderThreadStack);
} }
bool IsDownloadTitleFinished() bool IsDownloadTitleFinished()
@ -186,7 +220,12 @@ void FinalizeTitleDownload()
bool DownloadTitleSucceeded() bool DownloadTitleSucceeded()
{ {
return TitleDownloader::m_Result.IsSuccess() && GetShopOperationSingleResult().IsSuccess(); return TitleDownloader::m_Result.IsSuccess();
}
nn::Result GetTitleDownloadResult()
{
return TitleDownloader::m_Result;
} }
u32 GetTitleDownloadProgress() u32 GetTitleDownloadProgress()
@ -284,6 +323,19 @@ void WaitShopOperationAndFinalize()
FinalizeShopOperationSingle(); FinalizeShopOperationSingle();
} }
void StartShopOperationSingleRetry(ShopOperation op, u32 retryCount)
{
for(u32 i = 0; i < retryCount; i++)
{
StartShopOperationSingle(op);
WaitShopOperationAndFinalize();
if(GetShopOperationSingleResult().IsSuccess())
{
break;
}
}
}
void TitleDownloader::Start() void TitleDownloader::Start()
{ {
for(u8 i = 0; i < m_TiteNum; i++) for(u8 i = 0; i < m_TiteNum; i++)
@ -291,15 +343,18 @@ void TitleDownloader::Start()
s_Progress = i * 100 / m_TiteNum; s_Progress = i * 100 / m_TiteNum;
StartShopOperationSingle(SHOP_OPERATION_CONNECT_WITHOUT_CLOSE); StartShopOperationSingle(SHOP_OPERATION_CONNECT_WITHOUT_CLOSE);
WaitShopOperationAndFinalize(); WaitShopOperationAndFinalize();
m_Result = GetShopOperationSingleResult();
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
nn::nim::TitleConfig config; nn::nim::TitleConfig config;
m_Result = GetTitleConfig(m_ProgramIdList[i], &config); s64 requiredSize;
m_Result = GetTitleConfig(m_ProgramIdList[i], &config, &requiredSize);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(m_Result); COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(m_Result);
if (m_Result.IsSuccess())
{
StartShopOperationSingle(SHOP_OPERATION_DOWNLOAD_TITLE, config); StartShopOperationSingle(SHOP_OPERATION_DOWNLOAD_TITLE, config);
WaitShopOperationAndFinalize(); WaitShopOperationAndFinalize();
} m_Result = GetShopOperationSingleResult();
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
} }
} }
@ -313,4 +368,30 @@ void TitleDownloader::SetupTitleList(nn::ProgramId* list, size_t num)
m_TiteNum = listNum; m_TiteNum = listNum;
} }
void TitleDownloader::CalculateRequiredSize(s64* requiredSize)
{
*requiredSize = 0;
for(u8 i = 0; i < m_TiteNum; i++)
{
s_Progress = i * 100 / m_TiteNum;
StartShopOperationSingleRetry(SHOP_OPERATION_CONNECT_WITHOUT_CLOSE, 3);
m_Result = GetShopOperationSingleResult();
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
nn::nim::TitleConfig config;
s64 size;
for(u8 j = 0; j < 3; j++)
{
m_Result = GetTitleConfig(m_ProgramIdList[i], &config, &size);
if(m_Result.IsSuccess())
{
break;
}
}
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
*requiredSize += size;
}
}
} }

View File

@ -24,15 +24,16 @@ namespace ConsoleRestore
// 新たにスレッドを立て、TWLタイトルのダウンロードを開始する // 新たにスレッドを立て、TWLタイトルのダウンロードを開始する
void StartTwlTitleDownload(); void StartTwlTitleDownload();
//! @brief SDカードをインポート可能状態にします //! @brief プリインストールタイトルをSDカードにインポート可能かどうかサイズを確認し、<BR/>
//! 可能であればSDカードをインポート可能状態にします
//! @param[in] deviceId デバイスID
//! @param[in] serialNo シリアルナンバー
//! @return 正常に初期化できたかどうか //! @return 正常に初期化できたかどうか
bool PreparePreinstallTitleDownload(); void StartPreparePreinstallTitleDownload(bit64 deviceId, u8* serialNo);
//! @brief 新たにスレッドを立て、プリインストールタイトルのダウンロードを開始します <BR/> //! @brief 新たにスレッドを立て、プリインストールタイトルのダウンロードを開始します <BR/>
//! SDカードはインポート可能な状態にしておく必要があります。 //! SDカードはインポート可能な状態にしておく必要があります。
//! @param[in] deviceId デバイスID void StartPreinstallTitleDownload();
//! @param[in] serialNo シリアルナンバー
void StartPreinstallTitleDownload(bit64 deviceId, u8* serialNo);
// プリインストール情報取得に必要なパラメータをまとめた構造体 // プリインストール情報取得に必要なパラメータをまとめた構造体
@ -51,6 +52,9 @@ bool IsDownloadTitleFinished();
// タイトルのダウンロードスレッドが成功したかどうか // タイトルのダウンロードスレッドが成功したかどうか
bool DownloadTitleSucceeded(); bool DownloadTitleSucceeded();
// タイトルのダウンロード結果を取得する
nn::Result GetTitleDownloadResult();
// タイトルのダウンロードスレッドを終了する // タイトルのダウンロードスレッドを終了する
void FinalizeTitleDownload(); void FinalizeTitleDownload();
@ -67,6 +71,9 @@ public:
//! @brief タイトルリストを設定する //! @brief タイトルリストを設定する
void SetupTitleList(nn::ProgramId* list, size_t num); void SetupTitleList(nn::ProgramId* list, size_t num);
//! @brief タイトルをダウンロードするのに必要なサイズを計算します
void CalculateRequiredSize(s64* requiredSize);
// タイトルのダウンロードを開始する // タイトルのダウンロードを開始する
void Start(); void Start();

View File

@ -145,6 +145,7 @@ void SdLogger::Print(const char* fmt, ::std::va_list arg)
NN_LOG("SD Write Not Permitted\n"); NN_LOG("SD Write Not Permitted\n");
m_Buffer.push_back(std::string(str)); m_Buffer.push_back(std::string(str));
m_BufferSize += stringSize * sizeof(char); m_BufferSize += stringSize * sizeof(char);
SdMountManager::Unmount();
return; return;
} }

View File

@ -41,10 +41,12 @@ public:
SUITE_NAME("TestUtil"); SUITE_NAME("TestUtil");
TEST_ADD(TitleDownloaderTest::ListUp); TEST_ADD(TitleDownloaderTest::ListUp);
TEST_ADD(TitleDownloaderTest::DownloadPreinstall); TEST_ADD(TitleDownloaderTest::DownloadPreinstall);
TEST_ADD(TitleDownloaderTest::CalculateRequiredSize);
} }
private: private:
void ListUp(); void ListUp();
void DownloadPreinstall(); void DownloadPreinstall();
void CalculateRequiredSize();
}; };
namespace namespace
@ -114,12 +116,52 @@ void TitleDownloaderTest::ListUp()
void TitleDownloaderTest::DownloadPreinstall() void TitleDownloaderTest::DownloadPreinstall()
{ {
ConsoleRestore::StartPreinstallTitleDownload(17179924184, reinterpret_cast<u8*>(const_cast<char*>("EJA20305940"))); ConsoleRestore::StartPreparePreinstallTitleDownload(17179924184, reinterpret_cast<u8*>(const_cast<char*>("EJA20305940")));
while(!ConsoleRestore::IsDownloadTitleFinished()) while(!ConsoleRestore::IsDownloadTitleFinished())
{ {
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1)); nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1));
} }
ConsoleRestore::FinalizeTitleDownload();
ConsoleRestore::StartPreinstallTitleDownload();
while(!ConsoleRestore::IsDownloadTitleFinished())
{
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1));
}
ConsoleRestore::FinalizeTitleDownload();
}
void TitleDownloaderTest::CalculateRequiredSize()
{
nn::ProgramId id[] =
{
0x000400000FEEB000,
0x0004000005430000,
0x000400000A006000,
0x0004000005421000,
0x000400000A006100,
0x0004000005421100,
0x0004000001A01B00,
0x0004000001A01100,
0x000400000E000100,
0x0004008C09A00100,
0x0004008C01000100,
0x0004008C0D000000
};
ConsoleRestore::TitleDownloader dl;
s64 requiredSize;
do
{
dl.SetupTitleList(id, sizeof(id) / sizeof(id[0]));
dl.CalculateRequiredSize(&requiredSize);
}while(dl.m_Result.IsFailure());
NN_LOG("size = %llu\n", requiredSize);
} }
NN_TEST_DEFINE_MAIN(TitleDownloaderTest) NN_TEST_DEFINE_MAIN(TitleDownloaderTest)