ctr_Repair/trunk/ConsoleDataMigration/sources/ConsoleRestore/TitleDownloader.cpp
N2614 f3ca6f34b1 ディレクトリ移動
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@216 385bec56-5757-e545-9c3a-d8741f4650f1
2011-04-22 04:58:07 +00:00

230 lines
6.5 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: TitleDownloader.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/am.h>
#include <nn/nim.h>
#include <nn/CTR/CTR_ProgramId.h>
#include "CommonLogger.h"
#include "HeapManager.h"
#include "TitleDownloader.h"
#include "Shop.h"
namespace
{
bit8 s_buffer1[400 * 1024];
const size_t TITLE_DOWNLOADER_STACK_SIZE = 0x1000;
nn::os::Thread s_TitleDownloaderThread;
nn::os::StackBuffer<TITLE_DOWNLOADER_STACK_SIZE> s_TitleDownloaderThreadStack;
nn::fs::MediaType GetMediaType(const ES_NAMESPACE::ESTitleId titleId)
{
return (nn::CTR::IsTwlApp(titleId)) ?
nn::fs::MEDIA_TYPE_NAND : nn::fs::MEDIA_TYPE_SDMC;
}
const char *GetAttribute(EC_NAMESPACE::ECNameValuePair *attributes, u32 nAttributes, const char *attributeName)
{
for(int i=0; i<nAttributes; i++)
{
if(std::strcmp(attributes[i].name, attributeName)==0)
{
return attributes[i].value;
}
}
return NULL;
}
nn::Result GetEntry(ES_NAMESPACE::ESTitleId titleId, EC_NAMESPACE::ECTitleCatalogEntry **entry)
{
nn::nim::AttributeName returnAttribute[] =
{"Version", "TitleName", "TitleType", "TitleDescription", "Category", "Publisher", "MaxUserFileSize", "ReleaseDate"};
nn::nim::AttributeFilter attributeFilter[] = {
{"==", "string", "PricingSelection", "RELEASED"}
};
NN_LOG("ID: %016llx\n", titleId);
EC_NAMESPACE::ECTitleCatalog *titleCatalog;
nn::Result result = nn::nim::Shop::ListTitles(0, 1,
returnAttribute, sizeof(returnAttribute)/sizeof(returnAttribute[0]),
attributeFilter, sizeof(attributeFilter)/sizeof(attributeFilter[0]),
&(titleId), 1,
NULL, 0,
&titleCatalog, s_buffer1, sizeof(s_buffer1));
*entry = &(titleCatalog->entries[0]);
return result;
}
nn::Result GetTitleConfig(const ES_NAMESPACE::ESTitleId titleId, nn::nim::TitleConfig *titleConfig)
{
EC_NAMESPACE::ECTitleCatalogEntry *entry;
NN_UTIL_RETURN_IF_FAILED(GetEntry(titleId, &entry));
titleConfig->titleId=titleId;
titleConfig->version=std::strtoull(GetAttribute(entry->attributes, entry->nAttributes, "Version"), NULL, 10);
titleConfig->ratingAge=0;
titleConfig->media=GetMediaType(titleId);
NN_LOG("titleId : 0x%016llx\n", titleConfig->titleId);
NN_LOG("version : %lld\n" , titleConfig->version);
NN_LOG("ratingAge : %d\n" , titleConfig->ratingAge);
NN_LOG("media : %d\n" , titleConfig->media);
return nn::ResultSuccess();
}
} // namespace <unnamed>
namespace ConsoleRestore
{
nn::Result TitleDownloader::m_Result = nn::ResultSuccess();
void TitleDownloaderThreadFunc()
{
TitleDownloader TwlTitleDownloader;
TwlTitleDownloader.Start();
}
void StartTitleDownload()
{
s_TitleDownloaderThread.Start(TitleDownloaderThreadFunc, s_TitleDownloaderThreadStack);
}
bool DownloadTitleFinished()
{
return s_TitleDownloaderThread.IsValid() && !s_TitleDownloaderThread.IsAlive();
}
bool DownloadTitleSucceeded()
{
return TitleDownloader::m_Result.IsSuccess() && GetShopOperationSingleResult().IsSuccess();
}
TitleDownloader::TitleDownloader() : m_TwlTiteNum(0)
{
// TODO 自動生成されたコンストラクター・スタブ
for(u32 i = 0; i < TWL_IMPORTABLE_TITLE_MAX; i++)
{
m_ProgramIdList[i] = 0;
}
}
TitleDownloader::~TitleDownloader()
{
// TODO Auto-generated destructor stub
}
nn::Result WaitCancelled()
{
nn::nim::TitleProgress progress;
while(true)
{
// キャンセルがResultとして返ってくる / ダウンロード終了まで待つ
NN_UTIL_RETURN_IF_FAILED(nn::nim::Shop::GetProgress(&progress));
if(progress.lastResult==nn::nim::ResultCancelRequested() || progress.state==nn::nim::TITLE_STATE_FINISHED)
{
break;
}
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(100));
}
return nn::ResultSuccess();
}
void WaitShopOperationAndFinalize()
{
while (!IsShopOperationSingleFinished())
{
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(100));
}
FinalizeShopOperationSingle();
}
void TitleDownloader::Start()
{
nn::Result result;
result = ListUp();
if(result.IsFailure())
{
return;
}
for(u8 i = 0; i < m_TwlTiteNum; i++)
{
StartShopOperationSingle(SHOP_OPERATION_CONNECT_WITHOUT_CLOSE);
WaitShopOperationAndFinalize();
nn::nim::TitleConfig config;
result = GetTitleConfig(m_ProgramIdList[i], &config);
if (result.IsSuccess())
{
StartShopOperationSingle(SHOP_OPERATION_DOWNLOAD_TITLE, config);
WaitShopOperationAndFinalize();
}
}
}
nn::Result TitleDownloader::ListUp()
{
const u32 AM_TICKET_MAX = 8192;
s32 personalizedTicketNum;
nn::am::TicketInfo *ticketInfoBuffer =
reinterpret_cast<nn::am::TicketInfo*> (common::HeapManager::GetHeap()->Allocate(
sizeof(nn::am::TicketInfo) * AM_TICKET_MAX));
if(ticketInfoBuffer == NULL)
{
COMMON_LOGGER("Failed Allocate Heap!!\n");
m_Result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
return m_Result;
}
m_Result=nn::am::GetPersonalizedTicketInfoList(&personalizedTicketNum, ticketInfoBuffer, AM_TICKET_MAX); // 全部
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(m_Result);
for (u32 i = 0; i < personalizedTicketNum; i++)
{
if (nn::CTR::IsTwlApp(ticketInfoBuffer[i].titleId))
{
m_ProgramIdList[m_TwlTiteNum] = ticketInfoBuffer[i].titleId;
m_TwlTiteNum++;
NN_LOG("%016llx\n", m_ProgramIdList[m_TwlTiteNum - 1]);
}
}
return m_Result;
}
}