From 4667e4e1c0a475cc3dc6743360ea8b30dc2ada29 Mon Sep 17 00:00:00 2001 From: N2614 Date: Wed, 25 Jan 2012 07:54:55 +0000 Subject: [PATCH] =?UTF-8?q?=E3=83=80=E3=82=A6=E3=83=B3=E3=83=AD=E3=83=BC?= =?UTF-8?q?=E3=83=89=E5=89=8D=E3=81=ABSD=E3=82=AB=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=AE=E5=AE=B9=E9=87=8F=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF?= =?UTF-8?q?=E3=82=92=E3=81=97=E3=81=A6=E3=81=8B=E3=82=89=E3=82=BF=E3=82=A4?= =?UTF-8?q?=E3=83=88=E3=83=AB=E3=83=87=E3=83=BC=E3=82=BF=E3=83=99=E3=83=BC?= =?UTF-8?q?=E3=82=B9=E3=82=92=E4=BD=9C=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../sources/ConsoleRestore/Controller.cpp | 117 ++++++++++++--- .../ConsoleRestore/TitleDownloader.cpp | 133 ++++++++++++++---- .../sources/ConsoleRestore/TitleDownloader.h | 17 ++- .../sources/common/SdLogger.cpp | 1 + .../TitleDownloader/test_TitleDownloader.cpp | 44 +++++- 5 files changed, 262 insertions(+), 50 deletions(-) diff --git a/trunk/ConsoleDataMigration/sources/ConsoleRestore/Controller.cpp b/trunk/ConsoleDataMigration/sources/ConsoleRestore/Controller.cpp index 73cd2bb..ee68357 100644 --- a/trunk/ConsoleDataMigration/sources/ConsoleRestore/Controller.cpp +++ b/trunk/ConsoleDataMigration/sources/ConsoleRestore/Controller.cpp @@ -86,6 +86,12 @@ bool s_ExecuteTwlTitleDownload = false; // TWLタイトルのダウンロードを何回リトライしたか u32 s_TwlTitleDownloadRetryCount = 0; +// プリインストールタイトルのダウンロード準備を開始したかどうか +bool s_ExecutePreparePreinstallTitleDownload = false; +// プリインストールタイトルのダウンロード準備を何回リトライしたか +u32 s_PreparePreinstallTitleDownloadRetryCount = 0; + + // プリインストールタイトルのダウンロードを開始したかどうか bool s_ExecutePreinstallTitleDownload = false; // プリインストールタイトルのダウンロードを何回リトライしたか @@ -159,10 +165,12 @@ typedef enum RestoreState // プリインストールダウンロードモード PREINSTALL_WAIT_SYNC_TICKET, // 開始ボタン待ち PREINSTALL_WAIT_USER_SD_INSERT, // ユーザSD挿入待ち + PREINSTALL_CHECK_USER_SD_INSERT, // ユーザSDの挿入チェック PREINSTALL_CHECK_USER_SD, // ユーザ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 // 修理用SDのチェック } RestoreState; @@ -1450,7 +1458,7 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector #include +#include "SdMountManager.h" #include "common_Types.h" #include "FileName.h" #include "CommonLogger.h" @@ -34,6 +35,11 @@ namespace bit8 s_buffer1[400 * 1024]; +// ダウンロードするタイトルの個数 +size_t s_ProgramIdNum = 0; +// ダウンロードするタイトルのProgramIdの配列 +nn::ProgramId s_ProgramIdList[256]; + const size_t TITLE_DOWNLOADER_STACK_SIZE = 0x2000; nn::os::Thread s_TitleDownloaderThread; nn::os::StackBuffer s_TitleDownloaderThreadStack; @@ -90,20 +96,22 @@ nn::Result GetEntry(ES_NAMESPACE::ESTitleId titleId, EC_NAMESPACE::ECTitleCatalo 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; 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->ratingAge=0; 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("version : %lld\n" , titleConfig->version); COMMON_LOGGER_DETAIL("ratingAge : %d\n" , titleConfig->ratingAge); COMMON_LOGGER_DETAIL("media : %d\n" , titleConfig->media); + COMMON_LOGGER_DETAIL("size : %lld\n" , *requiredSize); return nn::ResultSuccess(); @@ -122,25 +130,18 @@ void TwlTitleDownloaderThreadFunc() TitleDownloader TwlTitleDownloader; s_Progress = 0; - size_t num = 0; - nn::ProgramId list[256]; - TitleDownloader::m_Result = ListUpTwlTitles(list, &num); + TitleDownloader::m_Result = ListUpTwlTitles(s_ProgramIdList, &s_ProgramIdNum); COMMON_LOGGER_RETURN_VOID_IF_FAILED(TitleDownloader::m_Result); - TwlTitleDownloader.SetupTitleList(list, num); + TwlTitleDownloader.SetupTitleList(s_ProgramIdList, s_ProgramIdNum); TwlTitleDownloader.Start(); } -void PreinstallTitleDownloaderThreadFunc(PreinstallListupParam param) +void PreinstallTitleDownloaderThreadFunc() { TitleDownloader PreinstallTitleDownloader; PreinstallImporter importer; 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(); } @@ -150,27 +151,60 @@ void StartTwlTitleDownload() } -bool PreparePreinstallTitleDownload() +void PreparePreinstallTitleDownloadThreadFunc(PreinstallListupParam param) { PreinstallImporter importer; 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; param.deviceId = deviceId; 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() @@ -186,7 +220,12 @@ void FinalizeTitleDownload() bool DownloadTitleSucceeded() { - return TitleDownloader::m_Result.IsSuccess() && GetShopOperationSingleResult().IsSuccess(); + return TitleDownloader::m_Result.IsSuccess(); +} + +nn::Result GetTitleDownloadResult() +{ + return TitleDownloader::m_Result; } u32 GetTitleDownloadProgress() @@ -284,6 +323,19 @@ void WaitShopOperationAndFinalize() FinalizeShopOperationSingle(); } +void StartShopOperationSingleRetry(ShopOperation op, u32 retryCount) +{ + for(u32 i = 0; i < retryCount; i++) + { + StartShopOperationSingle(op); + WaitShopOperationAndFinalize(); + if(GetShopOperationSingleResult().IsSuccess()) + { + break; + } + } +} + void TitleDownloader::Start() { for(u8 i = 0; i < m_TiteNum; i++) @@ -291,15 +343,18 @@ void TitleDownloader::Start() s_Progress = i * 100 / m_TiteNum; StartShopOperationSingle(SHOP_OPERATION_CONNECT_WITHOUT_CLOSE); WaitShopOperationAndFinalize(); + m_Result = GetShopOperationSingleResult(); + COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result); 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); - if (m_Result.IsSuccess()) - { - StartShopOperationSingle(SHOP_OPERATION_DOWNLOAD_TITLE, config); - WaitShopOperationAndFinalize(); - } + + StartShopOperationSingle(SHOP_OPERATION_DOWNLOAD_TITLE, config); + 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; } +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; + } +} + } diff --git a/trunk/ConsoleDataMigration/sources/ConsoleRestore/TitleDownloader.h b/trunk/ConsoleDataMigration/sources/ConsoleRestore/TitleDownloader.h index 6dd9617..628d6cc 100644 --- a/trunk/ConsoleDataMigration/sources/ConsoleRestore/TitleDownloader.h +++ b/trunk/ConsoleDataMigration/sources/ConsoleRestore/TitleDownloader.h @@ -24,15 +24,16 @@ namespace ConsoleRestore // 新たにスレッドを立て、TWLタイトルのダウンロードを開始する void StartTwlTitleDownload(); -//! @brief SDカードをインポート可能状態にします +//! @brief プリインストールタイトルをSDカードにインポート可能かどうかサイズを確認し、
+//! 可能であればSDカードをインポート可能状態にします +//! @param[in] deviceId デバイスID +//! @param[in] serialNo シリアルナンバー //! @return 正常に初期化できたかどうか -bool PreparePreinstallTitleDownload(); +void StartPreparePreinstallTitleDownload(bit64 deviceId, u8* serialNo); //! @brief 新たにスレッドを立て、プリインストールタイトルのダウンロードを開始します
//! SDカードはインポート可能な状態にしておく必要があります。 -//! @param[in] deviceId デバイスID -//! @param[in] serialNo シリアルナンバー -void StartPreinstallTitleDownload(bit64 deviceId, u8* serialNo); +void StartPreinstallTitleDownload(); // プリインストール情報取得に必要なパラメータをまとめた構造体 @@ -51,6 +52,9 @@ bool IsDownloadTitleFinished(); // タイトルのダウンロードスレッドが成功したかどうか bool DownloadTitleSucceeded(); +// タイトルのダウンロード結果を取得する +nn::Result GetTitleDownloadResult(); + // タイトルのダウンロードスレッドを終了する void FinalizeTitleDownload(); @@ -67,6 +71,9 @@ public: //! @brief タイトルリストを設定する void SetupTitleList(nn::ProgramId* list, size_t num); + //! @brief タイトルをダウンロードするのに必要なサイズを計算します + void CalculateRequiredSize(s64* requiredSize); + // タイトルのダウンロードを開始する void Start(); diff --git a/trunk/ConsoleDataMigration/sources/common/SdLogger.cpp b/trunk/ConsoleDataMigration/sources/common/SdLogger.cpp index d2dbb05..e7d56ba 100644 --- a/trunk/ConsoleDataMigration/sources/common/SdLogger.cpp +++ b/trunk/ConsoleDataMigration/sources/common/SdLogger.cpp @@ -145,6 +145,7 @@ void SdLogger::Print(const char* fmt, ::std::va_list arg) NN_LOG("SD Write Not Permitted\n"); m_Buffer.push_back(std::string(str)); m_BufferSize += stringSize * sizeof(char); + SdMountManager::Unmount(); return; } diff --git a/trunk/ConsoleDataMigration/sources/tests/ConsoleRestore/TitleDownloader/test_TitleDownloader.cpp b/trunk/ConsoleDataMigration/sources/tests/ConsoleRestore/TitleDownloader/test_TitleDownloader.cpp index 915a645..87a249b 100644 --- a/trunk/ConsoleDataMigration/sources/tests/ConsoleRestore/TitleDownloader/test_TitleDownloader.cpp +++ b/trunk/ConsoleDataMigration/sources/tests/ConsoleRestore/TitleDownloader/test_TitleDownloader.cpp @@ -41,10 +41,12 @@ public: SUITE_NAME("TestUtil"); TEST_ADD(TitleDownloaderTest::ListUp); TEST_ADD(TitleDownloaderTest::DownloadPreinstall); + TEST_ADD(TitleDownloaderTest::CalculateRequiredSize); } private: void ListUp(); void DownloadPreinstall(); + void CalculateRequiredSize(); }; namespace @@ -114,12 +116,52 @@ void TitleDownloaderTest::ListUp() void TitleDownloaderTest::DownloadPreinstall() { - ConsoleRestore::StartPreinstallTitleDownload(17179924184, reinterpret_cast(const_cast("EJA20305940"))); + ConsoleRestore::StartPreparePreinstallTitleDownload(17179924184, reinterpret_cast(const_cast("EJA20305940"))); while(!ConsoleRestore::IsDownloadTitleFinished()) { 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)