mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
不要なファイル・コードを削除
NUPのみ行うように git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@779 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
parent
da4dba574e
commit
5eae609069
@ -1,92 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: ActCompleter.cpp
|
|
||||||
|
|
||||||
Copyright (C)2013 Nintendo Co., Ltd. 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 "ActCompleter.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "CommonLogger.h"
|
|
||||||
#include <nn/ac/CTR/private/ac_InternalApi.h>
|
|
||||||
#include <nn/act/act_ApiAdmin.h>
|
|
||||||
#include <nn/act/act_ApiTransfer.h>
|
|
||||||
#include <nn/act/act_ResultPrivate.h>
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
nn::Result ActCompleter::s_Result;
|
|
||||||
const size_t ActCompleter::STACK_SIZE;
|
|
||||||
nn::os::Thread ActCompleter::s_Thread;
|
|
||||||
nn::os::StackBuffer<ActCompleter::STACK_SIZE> ActCompleter::s_ThreadStack;
|
|
||||||
|
|
||||||
|
|
||||||
ActCompleter::ActCompleter()
|
|
||||||
{
|
|
||||||
// TODO 自動生成されたコンストラクター・スタブ
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ActCompleter::~ActCompleter()
|
|
||||||
{
|
|
||||||
// TODO Auto-generated destructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result ActCompleter::GetResult()
|
|
||||||
{
|
|
||||||
return s_Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActCompleter::Start()
|
|
||||||
{
|
|
||||||
s_Thread.Start(Exec, s_ThreadStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ActCompleter::IsFinished()
|
|
||||||
{
|
|
||||||
return s_Thread.IsValid() && !s_Thread.IsAlive();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActCompleter::Finish()
|
|
||||||
{
|
|
||||||
s_Thread.Join();
|
|
||||||
s_Thread.Finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActCompleter::Exec()
|
|
||||||
{
|
|
||||||
s_Result = ExecImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result ActCompleter::ExecImpl()
|
|
||||||
{
|
|
||||||
if(!nn::ac::IsConnected())
|
|
||||||
{
|
|
||||||
NN_UTIL_RETURN_IF_FAILED(
|
|
||||||
common::InitializeNetwork());
|
|
||||||
}
|
|
||||||
|
|
||||||
NN_UTIL_RETURN_IF_FAILED(
|
|
||||||
nn::act::InitializeAdmin());
|
|
||||||
|
|
||||||
NN_UTIL_RETURN_IF_FAILED(
|
|
||||||
nn::act::CompleteTransfer());
|
|
||||||
|
|
||||||
NN_UTIL_RETURN_IF_FAILED(
|
|
||||||
nn::act::FinalizeAdmin());
|
|
||||||
|
|
||||||
NN_UTIL_RETURN_IF_FAILED(
|
|
||||||
common::FinalizeNetwork());
|
|
||||||
|
|
||||||
return nn::ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace ConsoleRestore */
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: ActCompleter.h
|
|
||||||
|
|
||||||
Copyright (C)2013 Nintendo Co., Ltd. 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$
|
|
||||||
*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef ACTCOMPLETER_H_
|
|
||||||
#define ACTCOMPLETER_H_
|
|
||||||
|
|
||||||
#include <nn.h>
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
|
|
||||||
class ActCompleter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ActCompleter();
|
|
||||||
virtual ~ActCompleter();
|
|
||||||
|
|
||||||
static nn::Result GetResult();
|
|
||||||
static void Start();
|
|
||||||
static bool IsFinished();
|
|
||||||
static void Finish();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void Exec();
|
|
||||||
static nn::Result ExecImpl();
|
|
||||||
static nn::Result s_Result;
|
|
||||||
static const size_t STACK_SIZE = 0x1000;
|
|
||||||
static nn::os::Thread s_Thread;
|
|
||||||
static nn::os::StackBuffer<STACK_SIZE> s_ThreadStack;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace ConsoleRestore */
|
|
||||||
#endif /* ACTCOMPLETER_H_ */
|
|
||||||
@ -48,7 +48,6 @@
|
|||||||
#include "ResFont.h"
|
#include "ResFont.h"
|
||||||
#include "HardwareStateManager.h"
|
#include "HardwareStateManager.h"
|
||||||
#include "OperationMessage.h"
|
#include "OperationMessage.h"
|
||||||
#include "QrImage.h"
|
|
||||||
|
|
||||||
// バージョン表示用
|
// バージョン表示用
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@ -181,7 +180,6 @@ extern "C" void nnMain(void)
|
|||||||
|
|
||||||
|
|
||||||
bool flip = false;
|
bool flip = false;
|
||||||
bool qr = false;
|
|
||||||
InitializeState();
|
InitializeState();
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
@ -199,14 +197,6 @@ extern "C" void nnMain(void)
|
|||||||
{
|
{
|
||||||
nextStep = true;
|
nextStep = true;
|
||||||
}
|
}
|
||||||
// YボタンでBMS操作完了
|
|
||||||
// Yボタンで強制プリインストール
|
|
||||||
if(padStatus.trigger & nn::hid::BUTTON_Y)
|
|
||||||
{
|
|
||||||
operateBmsDone = true;
|
|
||||||
forcePreinstall = true;
|
|
||||||
unregister = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LまたはRボタンで上下画面フリップ
|
// LまたはRボタンで上下画面フリップ
|
||||||
if(padStatus.trigger & nn::hid::BUTTON_R ||
|
if(padStatus.trigger & nn::hid::BUTTON_R ||
|
||||||
@ -215,14 +205,6 @@ extern "C" void nnMain(void)
|
|||||||
flip = !flip;
|
flip = !flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 左ボタンでQR切替
|
|
||||||
if(padStatus.trigger & nn::hid::BUTTON_RIGHT)
|
|
||||||
{
|
|
||||||
qr = !qr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// コンソールスクロール
|
// コンソールスクロール
|
||||||
if(padStatus.hold & nn::hid::BUTTON_UP)
|
if(padStatus.hold & nn::hid::BUTTON_UP)
|
||||||
{
|
{
|
||||||
@ -252,108 +234,42 @@ extern "C" void nnMain(void)
|
|||||||
|
|
||||||
common::OperationMessage operationMessage;
|
common::OperationMessage operationMessage;
|
||||||
|
|
||||||
if(qr)
|
ControlState(manager, operationMessage, nextStep, operateBmsDone, forcePreinstall, unregister);
|
||||||
|
|
||||||
|
nn::util::FloatColor titleColor;
|
||||||
|
titleColor.r = 0.2f;
|
||||||
|
titleColor.g = 0.2f;
|
||||||
|
titleColor.b = 0.8f;
|
||||||
|
|
||||||
|
// 上画面表示
|
||||||
|
common::DrawSystemState("CTR Network Updater", s_RenderSystem, titleColor, flip, adapterState,
|
||||||
|
s_HwUtility.GetCupMajorVersion(), s_HwUtility.GetCupMinorVersion(), s_HwUtility.GetCupMicroVersion(),
|
||||||
|
s_HwUtility.GetNupVersion(), s_HwUtility.GetBatteryRemain(), s_HwUtility.GetInfraDeviceId(),
|
||||||
|
s_HwUtility.GetFriendcode(), GetProgress(), IsRestoreFailed(), IsRestoreSucceeded(), false,
|
||||||
|
s_HwUtility.GetMacAddress(), operationMessage, s_HwUtility.GetRegion(), s_HwUtility.GetSerialNumber(),
|
||||||
|
s_HwUtility.HasReadFriendCode(), s_HwUtility.IsWifiOn());
|
||||||
|
|
||||||
|
s_RenderSystem.SwapBuffers();
|
||||||
|
|
||||||
|
// デフォルトで下画面に描画するもの
|
||||||
|
s_RenderSystem.SetRenderTarget(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
|
||||||
|
if (IsRestoreSucceeded())
|
||||||
{
|
{
|
||||||
u8 serial[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
|
s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), SUCCESS_COLOR);
|
||||||
s_HwUtility.GetSerialNumberWithoutCD(serial);
|
}
|
||||||
common::QrImage::Draw(s_RenderSystem, s_HwUtility.GetInfraDeviceId(), serial, flip);
|
else if (IsRestoreFailed())
|
||||||
|
{
|
||||||
|
s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), FAIL_COLOR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ControlState(manager, operationMessage, nextStep, operateBmsDone, forcePreinstall, unregister);
|
s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), NORMAL_COLOR);
|
||||||
|
|
||||||
nn::util::FloatColor titleColor;
|
|
||||||
|
|
||||||
if (GetRestoreMode() == RESTORE_MODE_RESTORE)
|
|
||||||
{
|
|
||||||
titleColor.r = 0.1f;
|
|
||||||
titleColor.g = 0.25f;
|
|
||||||
titleColor.b = 0.1f;
|
|
||||||
}
|
|
||||||
else if (GetRestoreMode() == RESTORE_MODE_NUP_ONLY)
|
|
||||||
{
|
|
||||||
titleColor.r = 0.35f;
|
|
||||||
titleColor.g = 0.35f;
|
|
||||||
titleColor.b = 0.f;
|
|
||||||
}
|
|
||||||
else if (GetRestoreMode() == RESTORE_MODE_GET_IVS)
|
|
||||||
{
|
|
||||||
titleColor.r = 1.0f;
|
|
||||||
titleColor.g = 0.2f;
|
|
||||||
titleColor.b = 0.2f;
|
|
||||||
}
|
|
||||||
else if (GetRestoreMode() == RESTORE_MODE_CHECK_SD)
|
|
||||||
{
|
|
||||||
titleColor.r = 0.2f;
|
|
||||||
titleColor.g = 0.2f;
|
|
||||||
titleColor.b = 1.2f;
|
|
||||||
}
|
|
||||||
else if (GetRestoreMode() == RESTORE_MODE_DOWNLOAD_PREINSTALL)
|
|
||||||
{
|
|
||||||
titleColor.r = 1.0f;
|
|
||||||
titleColor.g = 0.55f;
|
|
||||||
titleColor.b = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上画面表示
|
|
||||||
common::DrawSystemState("CTR Console Restore", s_RenderSystem, titleColor, flip, adapterState,
|
|
||||||
s_HwUtility.GetCupMajorVersion(), s_HwUtility.GetCupMinorVersion(),
|
|
||||||
s_HwUtility.GetCupMicroVersion(), s_HwUtility.GetNupVersion(), s_HwUtility.GetBatteryRemain(),
|
|
||||||
s_HwUtility.GetInfraDeviceId(), s_HwUtility.GetFriendcode(), GetProgress(), IsRestoreFailed(),
|
|
||||||
IsRestoreSucceeded(), false, s_HwUtility.GetMacAddress(), operationMessage, s_HwUtility.GetRegion(),
|
|
||||||
s_HwUtility.GetSerialNumber(), s_HwUtility.HasReadFriendCode(), s_HwUtility.IsWifiOn());
|
|
||||||
|
|
||||||
if (GetRestoreMode() != RESTORE_MODE_RESTORE)
|
|
||||||
{
|
|
||||||
const u8 spaceSize = 10;
|
|
||||||
const u8 lineBottom = 23;
|
|
||||||
const u32 screenWidth = 400;
|
|
||||||
|
|
||||||
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
|
|
||||||
|
|
||||||
if (GetRestoreMode() == RESTORE_MODE_NUP_ONLY)
|
|
||||||
{
|
|
||||||
s_RenderSystem.DrawText(0, lineBottom * spaceSize, "NUP-Only Mode");
|
|
||||||
}
|
|
||||||
else if (GetRestoreMode() == RESTORE_MODE_GET_IVS)
|
|
||||||
{
|
|
||||||
s_RenderSystem.DrawText(0, lineBottom * spaceSize, "GET-SDCI Mode");
|
|
||||||
}
|
|
||||||
else if (GetRestoreMode() == RESTORE_MODE_CHECK_SD)
|
|
||||||
{
|
|
||||||
s_RenderSystem.DrawText(0, lineBottom * spaceSize, "CHECK-SD Mode");
|
|
||||||
}
|
|
||||||
else if (GetRestoreMode() == RESTORE_MODE_DOWNLOAD_PREINSTALL)
|
|
||||||
{
|
|
||||||
s_RenderSystem.DrawText(0, lineBottom * spaceSize, "DL_PREINATALL Mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
s_RenderSystem.SetColor(titleColor.r, titleColor.g, titleColor.b);
|
|
||||||
s_RenderSystem.FillRectangle(0, lineBottom * spaceSize, screenWidth, spaceSize);
|
|
||||||
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
|
|
||||||
}
|
|
||||||
s_RenderSystem.SwapBuffers();
|
|
||||||
|
|
||||||
// デフォルトで下画面に描画するもの
|
|
||||||
s_RenderSystem.SetRenderTarget(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
|
|
||||||
if (IsRestoreSucceeded())
|
|
||||||
{
|
|
||||||
s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), SUCCESS_COLOR);
|
|
||||||
}
|
|
||||||
else if (IsRestoreFailed())
|
|
||||||
{
|
|
||||||
s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), FAIL_COLOR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), NORMAL_COLOR);
|
|
||||||
}
|
|
||||||
s_RenderSystem.Clear();
|
|
||||||
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
|
|
||||||
|
|
||||||
common::Logger::GetLoggerInstance()->DrawConsole();
|
|
||||||
s_RenderSystem.SwapBuffers();
|
|
||||||
}
|
}
|
||||||
|
s_RenderSystem.Clear();
|
||||||
|
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
|
||||||
|
|
||||||
|
common::Logger::GetLoggerInstance()->DrawConsole();
|
||||||
|
s_RenderSystem.SwapBuffers();
|
||||||
|
|
||||||
s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
|
s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -27,11 +27,9 @@ namespace ConsoleRestore
|
|||||||
|
|
||||||
typedef enum RestoreMode
|
typedef enum RestoreMode
|
||||||
{
|
{
|
||||||
RESTORE_MODE_RESTORE,
|
RESTORE_MODE_NUP_WITHOUT_REBOOT,
|
||||||
RESTORE_MODE_NUP_ONLY,
|
|
||||||
RESTORE_MODE_GET_IVS,
|
RESTORE_MODE_MAX
|
||||||
RESTORE_MODE_CHECK_SD,
|
|
||||||
RESTORE_MODE_DOWNLOAD_PREINSTALL
|
|
||||||
|
|
||||||
} RestoreMode;
|
} RestoreMode;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -25,86 +25,6 @@
|
|||||||
namespace ConsoleRestore
|
namespace ConsoleRestore
|
||||||
{
|
{
|
||||||
|
|
||||||
// SDカードのデバイスIDファイルが存在するか
|
|
||||||
nn::Result ExistsDeviceIdFile();
|
|
||||||
|
|
||||||
// SDカードのデバイスIDファイルと本体のデバイスIDが一致しているかどうか
|
|
||||||
bool EqualsDeviceIdFileandDeviceId(common::HardwareStateManager& manager);
|
|
||||||
|
|
||||||
// SDカードのリージョンと本体のリージョンが一致しているかどうか
|
|
||||||
nn::Result EqualsRegionDataandRegion();
|
|
||||||
|
|
||||||
// シリアルナンバーを取得する
|
|
||||||
nn::Result ReadSerialNumber(u8* serial);
|
|
||||||
|
|
||||||
// 出力ファイル一覧を読み込む
|
|
||||||
nn::Result SetupVersionAndFileList();
|
|
||||||
|
|
||||||
// インポート用のスレッドを終了する
|
|
||||||
void FinalizeImportThread();
|
|
||||||
|
|
||||||
// インポート用のスレッドが終了したかどうか
|
|
||||||
bool IsImportThreadFinished();
|
|
||||||
|
|
||||||
// 新たにスレッドを立て、TWLサウンド領域をインポートする
|
|
||||||
void ImportTwlSoundData();
|
|
||||||
|
|
||||||
// 新たにスレッドを立て、TWL-NAND領域をインポートする
|
|
||||||
void ImportTwlSaveData();
|
|
||||||
|
|
||||||
// 新たにスレッドを立て、TWL写真領域をインポートする
|
|
||||||
void ImportTwlPhotoData();
|
|
||||||
|
|
||||||
// 本体固有データを読み込む
|
|
||||||
// 新たにスレッドを立て、CTRセーブデータ領域をインポートする
|
|
||||||
nn::Result ImportData();
|
|
||||||
|
|
||||||
// インポート完了ファイルを作る
|
|
||||||
void CreateWriteFinishedFile();
|
|
||||||
|
|
||||||
// ネットワークアップデート完了ファイルを作る
|
|
||||||
void CreateUpdateFinishedFile();
|
|
||||||
|
|
||||||
// 本体初期化完了ファイルを作る
|
|
||||||
void CreateConsoleInitializedFile();
|
|
||||||
|
|
||||||
// RTC書き込み完了ファイルを作る
|
|
||||||
void CreateRtcSyncFinishedFile();
|
|
||||||
|
|
||||||
// IVSダウンロード完了ファイルを作る
|
|
||||||
void CreateDownloadIvsFinishedFile();
|
|
||||||
|
|
||||||
// アカウント削除完了ファイルを作る
|
|
||||||
void CreateDeleteAccountFinishedFile();
|
|
||||||
|
|
||||||
// アカウント移行完了ファイルを作る
|
|
||||||
void CreateTransferAccountFinishedFile();
|
|
||||||
|
|
||||||
// インポートスレッドの進捗を取得する
|
|
||||||
u32 GetImportProgress();
|
|
||||||
|
|
||||||
// インポートスレッドの進捗を取得する
|
|
||||||
u32 GetImportProgressTwlNand();
|
|
||||||
|
|
||||||
// NANDのごみを削除する
|
|
||||||
nn::Result Cleanup();
|
|
||||||
|
|
||||||
|
|
||||||
// ファイルが存在するかどうか確認するためのテーブル
|
|
||||||
const wchar_t* const CHECK_FILENAME_TABLE[] =
|
|
||||||
{
|
|
||||||
common::UPDATE_CHECK_PATHNAME,
|
|
||||||
common::INITIALIZED_CHECK_PATHNAME,
|
|
||||||
common::WRITE_FINISHED_CHECK_PATHNAME,
|
|
||||||
common::RTC_SYNC_CHECK_PATHNAME,
|
|
||||||
common::DOWNLOAD_IVS_CHECK_PATHNAME,
|
|
||||||
common::DELETE_ACCOUNT_CHECK_PATHNAME,
|
|
||||||
common::TRANSFER_ACCOUNT_CHECK_PATHNAME
|
|
||||||
};
|
|
||||||
|
|
||||||
// ファイル存在確認をクリアする
|
|
||||||
void DeleteAllCheckFiles();
|
|
||||||
|
|
||||||
struct TimeZone
|
struct TimeZone
|
||||||
{
|
{
|
||||||
u32 hour;
|
u32 hour;
|
||||||
@ -114,15 +34,7 @@ struct TimeZone
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ネットワーク設定ファイルを読み込む
|
// ネットワーク設定ファイルを読み込む
|
||||||
bool ReadSetting(bool* nupOnly, bool* getIvs, bool* checkSd, bool* skipNup, bool* dlPreinstall);
|
bool ReadSetting();
|
||||||
|
|
||||||
// ネットワーク設定ファイルからNTPサーバの名前を取得する
|
|
||||||
// 先にReadSettingが成功している必要がある
|
|
||||||
char* GetNtpServerName();
|
|
||||||
|
|
||||||
// ネットワーク設定ファイルからタイムゾーンを取得する
|
|
||||||
// 先にReadSettingが成功している必要がある
|
|
||||||
TimeZone GetTimeZone();
|
|
||||||
|
|
||||||
// インターネット設定をユーザの設定に戻す
|
// インターネット設定をユーザの設定に戻す
|
||||||
void RestoreCurrentInternetSetting();
|
void RestoreCurrentInternetSetting();
|
||||||
|
|||||||
@ -1,309 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: NtpClient.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/socket.h>
|
|
||||||
#include <nn/ac.h>
|
|
||||||
#include <nn/ptm.h>
|
|
||||||
#include <nn/ptm/CTR/ptm_ApiSysmenu.h>
|
|
||||||
#include <nn/ac/private/ac.h>
|
|
||||||
#include <nn/ac/CTR/private/ac_InternalApi.h>
|
|
||||||
#include <nn/ac/CTR/private/ac_NetworkSetting.h>
|
|
||||||
#include <nn/math.h>
|
|
||||||
|
|
||||||
#include "Importer.h"
|
|
||||||
#include "CommonLogger.h"
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const size_t NTP_THREAD_STACK_SIZE = 0x1000;
|
|
||||||
nn::os::Thread s_NtpThread;
|
|
||||||
nn::os::StackBuffer<NTP_THREAD_STACK_SIZE> s_NtpThreadStack;
|
|
||||||
bool s_NtpSyncSuccessed = false;
|
|
||||||
|
|
||||||
|
|
||||||
struct NTP_Packet{ // NTPパケット
|
|
||||||
u32 controlWord;
|
|
||||||
u32 rootDelay;
|
|
||||||
u32 rootDispersion;
|
|
||||||
u32 referenceId;
|
|
||||||
s64 referenceTimestamp;
|
|
||||||
s64 startTimestamp;
|
|
||||||
s64 receiveTimestamp;
|
|
||||||
u32 transmitTimestampSeconds;
|
|
||||||
u32 transmitTimestampFractions;
|
|
||||||
};
|
|
||||||
|
|
||||||
const size_t TIMEOUT_MILLISECOND = 5000; // タイムアウト ミリ秒数
|
|
||||||
NTP_Packet s_NTPSendPacket; // 送信するNTPパケット
|
|
||||||
NTP_Packet s_NTPRecvPacket; // 受信するNTPパケット
|
|
||||||
const u32 NTP_PORT_NUM = 123;
|
|
||||||
|
|
||||||
bool GetNtpTime(u32* ntpTime)
|
|
||||||
{
|
|
||||||
nn::Result result;
|
|
||||||
|
|
||||||
bool retval = true;
|
|
||||||
NN_LOG("Initializing network.\n");
|
|
||||||
|
|
||||||
// 本体に書き込まれているネットワーク設定を使ってネットワーク接続を初期化
|
|
||||||
if(!nn::ac::IsConnected())
|
|
||||||
{
|
|
||||||
result = common::InitializeNetwork();
|
|
||||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
NN_LOG("Initializing socket..\n");
|
|
||||||
|
|
||||||
// 一つのスレッドからソケット API を利用する
|
|
||||||
const s32 sessionCount = 1;
|
|
||||||
// ソケットの送受信バッファとして 64 KB を割り当て
|
|
||||||
const size_t bufferSizeForSockets = 65536;
|
|
||||||
// ソケットライブラリに必要なワークサイズを求める
|
|
||||||
const size_t workSizeForLibrary = nn::socket::GetRequiredMemorySize(bufferSizeForSockets, sessionCount);
|
|
||||||
|
|
||||||
// ワークメモリを確保して 4KB にアラインにする
|
|
||||||
u8* pWorkMemory = new u8[workSizeForLibrary + 4096];
|
|
||||||
uptr workMemoryAddress = nn::math::RoundUp<uptr>(reinterpret_cast<uptr> (pWorkMemory), 4096);
|
|
||||||
|
|
||||||
// ソケットライブラリの初期化
|
|
||||||
result = nn::socket::Initialize(workMemoryAddress, workSizeForLibrary, bufferSizeForSockets, sessionCount);
|
|
||||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
|
||||||
|
|
||||||
{
|
|
||||||
s32 ret;
|
|
||||||
nn::socket::InAddr addr, netmask;
|
|
||||||
ret = nn::socket::GetPrimaryAddress(reinterpret_cast<u8*> (&addr), reinterpret_cast<u8*> (&netmask));
|
|
||||||
NN_ASSERT(ret == 0);
|
|
||||||
COMMON_LOGGER("host : %s\n", nn::socket::InetNtoA(addr));
|
|
||||||
COMMON_LOGGER("netmask : %s\n", nn::socket::InetNtoA(netmask));
|
|
||||||
|
|
||||||
nn::socket::InAddr dns1, dns2;
|
|
||||||
ret = nn::socket::GetResolver(reinterpret_cast<u8*> (&dns1), reinterpret_cast<u8*> (&dns2));
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("dns1 : %s\n", nn::socket::InetNtoA(dns1));
|
|
||||||
COMMON_LOGGER("dns2 : %s\n", nn::socket::InetNtoA(dns2));
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::socket::InAddr gateway;
|
|
||||||
ret = nn::socket::GetDefaultGateway(reinterpret_cast<u8*> (&gateway));
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("gateway : %s\n", nn::socket::InetNtoA(gateway));
|
|
||||||
}
|
|
||||||
|
|
||||||
COMMON_LOGGER("\n");
|
|
||||||
#ifndef NN_SWITCH_DISABLE_DEBUG_PRINT
|
|
||||||
nn::socket::DumpRoutingTable();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
s32 socket = nn::socket::Socket(nn::socket::PF_INET, nn::socket::SOCK_DGRAM, 0);
|
|
||||||
NN_LOG("socket = %d\n", socket);
|
|
||||||
|
|
||||||
// クライアントアドレスの設定
|
|
||||||
nn::socket::SockAddrIn host_addr;
|
|
||||||
host_addr.len = sizeof(nn::socket::SockAddrIn);
|
|
||||||
host_addr.family = nn::socket::AF_INET;
|
|
||||||
host_addr.addr.addr = 0;
|
|
||||||
host_addr.port = nn::socket::HtoNs(NTP_PORT_NUM);
|
|
||||||
|
|
||||||
// ローカルアドレスをバインド
|
|
||||||
s32 ret = nn::socket::Bind(socket, &host_addr);
|
|
||||||
NN_LOG("bind = %d\n", ret);
|
|
||||||
|
|
||||||
// ********************************************************************************
|
|
||||||
// NTPパケットを生成して送る
|
|
||||||
// ********************************************************************************
|
|
||||||
|
|
||||||
// サーバアドレスの設定
|
|
||||||
nn::socket::SockAddrIn serverSockAddrIn;
|
|
||||||
serverSockAddrIn.len = sizeof(nn::socket::SockAddrIn);
|
|
||||||
serverSockAddrIn.family = nn::socket::AF_INET;
|
|
||||||
|
|
||||||
// GetHostByNameを使う場合
|
|
||||||
nn::socket::HostEnt* serverHostent;
|
|
||||||
u64 serveraddr = 0;
|
|
||||||
serverHostent = nn::socket::GetHostByName(GetNtpServerName());
|
|
||||||
if (serverHostent == NULL)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Error: GetHostByName %s\n", GetNtpServerName());
|
|
||||||
retval = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// サーバのホスト情報からIPアドレスをコピー
|
|
||||||
serveraddr = *(reinterpret_cast<u64 *> (serverHostent->addrList[0]));
|
|
||||||
}
|
|
||||||
serverSockAddrIn.addr.addr = serveraddr;
|
|
||||||
COMMON_LOGGER("Destination address: %s\n", nn::socket::InetNtoA(serverSockAddrIn.addr));
|
|
||||||
serverSockAddrIn.port = nn::socket::HtoNs(NTP_PORT_NUM); // ポート番号
|
|
||||||
|
|
||||||
// NTPパケットをSNTP用に初期化する
|
|
||||||
s_NTPSendPacket.controlWord = nn::socket::HtoNl(0x0B000000);
|
|
||||||
s_NTPSendPacket.rootDelay = 0;
|
|
||||||
s_NTPSendPacket.rootDispersion = 0;
|
|
||||||
s_NTPSendPacket.referenceId = 0;
|
|
||||||
s_NTPSendPacket.referenceTimestamp = 0;
|
|
||||||
s_NTPSendPacket.startTimestamp = 0;
|
|
||||||
s_NTPSendPacket.receiveTimestamp = 0;
|
|
||||||
s_NTPSendPacket.transmitTimestampSeconds = 0;
|
|
||||||
s_NTPSendPacket.transmitTimestampFractions = 0;
|
|
||||||
|
|
||||||
// サーバを指定してNTPパケットを送信する
|
|
||||||
if ((ret = nn::socket::SendTo(socket, reinterpret_cast<const void*> (&s_NTPSendPacket), sizeof(s_NTPSendPacket), 0,
|
|
||||||
&serverSockAddrIn)) < 0)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Error: Failed Send to Server, %d\n", ret);
|
|
||||||
retval = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NN_LOG("SendTo finished\n");
|
|
||||||
|
|
||||||
// 受信待ち
|
|
||||||
nn::socket::PollFd pollFd;
|
|
||||||
pollFd.fd = socket;
|
|
||||||
pollFd.events = nn::socket::POLLRDNORM;
|
|
||||||
if ((ret = nn::socket::Poll(&pollFd, 1, TIMEOUT_MILLISECOND)) < 0)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Error: recv error, %d\n", ret);
|
|
||||||
retval = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NN_LOG("Poll Finished\n");
|
|
||||||
|
|
||||||
switch (pollFd.revents)
|
|
||||||
{
|
|
||||||
case nn::socket::POLLERR: // ソケットにエラーが発生しました。
|
|
||||||
COMMON_LOGGER("Error: POLLERR %s %d\n", __func__, __LINE__);
|
|
||||||
retval = false;
|
|
||||||
break;
|
|
||||||
case nn::socket::POLLHUP: // ストリーム・ソケットが未接続です。
|
|
||||||
COMMON_LOGGER("Error: POLLHUP %s %d\n", __func__, __LINE__);
|
|
||||||
retval = false;
|
|
||||||
break;
|
|
||||||
case nn::socket::POLLNVAL: // 不正なソケット記述子です。
|
|
||||||
COMMON_LOGGER("Error: POLLNVAL %s %d\n", __func__, __LINE__);
|
|
||||||
retval = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// サーバから時刻情報を受信する
|
|
||||||
// サーバを指定して受信を行う
|
|
||||||
// 受信するまで待たされる
|
|
||||||
if ((ret = nn::socket::RecvFrom(socket, reinterpret_cast<void*> (&s_NTPRecvPacket), sizeof(s_NTPRecvPacket), nn::socket::MSG_DONTWAIT,
|
|
||||||
&serverSockAddrIn)) < 0)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Error: RecvFrom, %d\n", ret);
|
|
||||||
retval = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NN_LOG("RecvFrom finished\n");
|
|
||||||
|
|
||||||
// NTPサーバから取得した時刻を現地時間に変換する
|
|
||||||
*ntpTime = nn::socket::NtoHl(s_NTPRecvPacket.transmitTimestampSeconds) - 2208988800; /* 1970/01/01 からの秒数に変換 */
|
|
||||||
NN_LOG("ntp_time = %d\n", ntpTime);
|
|
||||||
|
|
||||||
nn::socket::Close(socket);
|
|
||||||
NN_UNUSED_VAR(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
NN_LOG("Finalizing socket..\n");
|
|
||||||
// ソケットライブラリの終了
|
|
||||||
result = nn::socket::Finalize();
|
|
||||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
NN_LOG("Finalizing network.\n");
|
|
||||||
result = common::FinalizeNetwork();
|
|
||||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void NtpThreadFunc()
|
|
||||||
{
|
|
||||||
// NTP時間を取得する
|
|
||||||
u32 ntpTime;
|
|
||||||
if (GetNtpTime(&ntpTime))
|
|
||||||
{
|
|
||||||
// タイムゾーンを考慮してDateTimeに変換する
|
|
||||||
TimeZone timeZone = GetTimeZone();
|
|
||||||
|
|
||||||
// 1970/01/01
|
|
||||||
nn::fnd::DateTime utc = nn::fnd::DateTime(1970, 1, 1, 0, 0, 0, 0);
|
|
||||||
nn::fnd::DateTime current = utc + nn::fnd::TimeSpan::FromSeconds(ntpTime);
|
|
||||||
|
|
||||||
if (timeZone.isMinus)
|
|
||||||
{
|
|
||||||
current -= (nn::fnd::TimeSpan::FromHours(timeZone.hour) + nn::fnd::TimeSpan::FromMinutes(timeZone.minutes));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current += nn::fnd::TimeSpan::FromHours(timeZone.hour) + nn::fnd::TimeSpan::FromMinutes(timeZone.minutes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SWCを書き込む
|
|
||||||
nn::ptm::CTR::SetUserTime(current);
|
|
||||||
|
|
||||||
COMMON_LOGGER("Set User Time %04d/%02d/%02d %02d:%02d:%02d\n",
|
|
||||||
current.GetYear(), current.GetMonth(), current.GetDay(), current.GetHour(), current.GetMinute(), current.GetSecond());
|
|
||||||
|
|
||||||
s_NtpSyncSuccessed = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Failed Get Ntp Time\n");
|
|
||||||
s_NtpSyncSuccessed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsTimeAdjustFinished()
|
|
||||||
{
|
|
||||||
// Initialize済みかつ終了
|
|
||||||
return s_NtpThread.IsValid() && !s_NtpThread.IsAlive();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsTimeAdjustSuccessed()
|
|
||||||
{
|
|
||||||
return s_NtpSyncSuccessed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdjustTime()
|
|
||||||
{
|
|
||||||
nn::Result result;
|
|
||||||
|
|
||||||
result = nn::ac::CTR::InitializeInternal();
|
|
||||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
|
||||||
|
|
||||||
if(IsTimeAdjustFinished())
|
|
||||||
{
|
|
||||||
s_NtpThread.Join();
|
|
||||||
s_NtpThread.Finalize();
|
|
||||||
}
|
|
||||||
s_NtpThread.Start( NtpThreadFunc, s_NtpThreadStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: NtpClient.h
|
|
||||||
|
|
||||||
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$
|
|
||||||
*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef NTPCLIENT_H_
|
|
||||||
#define NTPCLIENT_H_
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
|
|
||||||
// 新たにスレッドを立て、NTPサーバと同期する
|
|
||||||
u32 AdjustTime();
|
|
||||||
|
|
||||||
// NTPサーバとの同期が終了したかどうか
|
|
||||||
bool IsTimeAdjustFinished();
|
|
||||||
|
|
||||||
// NTPサーバとの同期が完了したかどうか
|
|
||||||
bool IsTimeAdjustSuccessed();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NTPCLIENT_H_ */
|
|
||||||
@ -28,17 +28,9 @@ SOURCES[] =
|
|||||||
Controller.cpp
|
Controller.cpp
|
||||||
Importer.cpp
|
Importer.cpp
|
||||||
Updater.cpp
|
Updater.cpp
|
||||||
Ntpclient.cpp
|
|
||||||
TitleDownloader.cpp
|
|
||||||
Shop.cpp
|
|
||||||
RegionIdModifier.cpp
|
|
||||||
PreinstallImporter.cpp
|
|
||||||
ActCompleter.cpp
|
|
||||||
../common/Util.cpp
|
../common/Util.cpp
|
||||||
../common/DrawSystemState.cpp
|
|
||||||
../common/FileTransfer.cpp
|
|
||||||
../common/FileChecker.cpp
|
../common/FileChecker.cpp
|
||||||
../common/SdReaderWriter.cpp
|
../common/DrawSystemState.cpp
|
||||||
../common/HeapManager.cpp
|
../common/HeapManager.cpp
|
||||||
../common/SdLogger.cpp
|
../common/SdLogger.cpp
|
||||||
../common/wave.cpp
|
../common/wave.cpp
|
||||||
@ -50,9 +42,7 @@ SOURCES[] =
|
|||||||
../common/VersionDetect.cpp
|
../common/VersionDetect.cpp
|
||||||
../common/ResFont.cpp
|
../common/ResFont.cpp
|
||||||
../common/HardwareStateManager.cpp
|
../common/HardwareStateManager.cpp
|
||||||
../common/SaveDataMover.cpp
|
|
||||||
../common/OperationMessage.cpp
|
../common/OperationMessage.cpp
|
||||||
../common/QrImage.cpp
|
|
||||||
|
|
||||||
include $(ROOT)/common/BuildSwitch.om
|
include $(ROOT)/common/BuildSwitch.om
|
||||||
|
|
||||||
|
|||||||
@ -1,83 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: PreinstallImporter.cpp
|
|
||||||
|
|
||||||
Copyright 2009-2011 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 "CommonLogger.h"
|
|
||||||
#include "HeapManager.h"
|
|
||||||
#include "PreinstallImporter.h"
|
|
||||||
#include <cstring>
|
|
||||||
#include <nn/am/am_ApiSystemMenu.h>
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
|
|
||||||
PreinstallImporter::PreinstallImporter()
|
|
||||||
{
|
|
||||||
// TODO 自動生成されたコンストラクター・スタブ
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PreinstallImporter::~PreinstallImporter()
|
|
||||||
{
|
|
||||||
// TODO Auto-generated destructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result PreinstallImporter::SetupSd(bool* isAlreadyAvailable, bool forcePreinstall)
|
|
||||||
{
|
|
||||||
// SDカードがインポート可能状態かどうかチェック
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(
|
|
||||||
nn::am::QueryAvailableExternalTitleDatabase(isAlreadyAvailable)
|
|
||||||
);
|
|
||||||
|
|
||||||
// タイトルデータベースを作成する
|
|
||||||
if (!*isAlreadyAvailable)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(
|
|
||||||
nn::am::InitializeExternalTitleDatabase()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(forcePreinstall)
|
|
||||||
{
|
|
||||||
// 未初期化として返す
|
|
||||||
*isAlreadyAvailable = false;
|
|
||||||
}
|
|
||||||
return nn::ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result PreinstallImporter::ListTitlesBasedOnTickets(nn::ProgramId* list, size_t* num)
|
|
||||||
{
|
|
||||||
s32 personalizedTicketNum;
|
|
||||||
nn::am::TicketInfo ticketInfo[256];
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(
|
|
||||||
nn::am::GetPersonalizedTicketInfoList(&personalizedTicketNum, ticketInfo, 256)
|
|
||||||
);
|
|
||||||
|
|
||||||
if(personalizedTicketNum == 0)
|
|
||||||
{
|
|
||||||
return nn::MakePermanentResult(nn::Result::SUMMARY_NOT_FOUND,
|
|
||||||
nn::Result::MODULE_APPLICATION, nn::Result::DESCRIPTION_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
*num = 0;
|
|
||||||
for(s32 i = 0; i < personalizedTicketNum; i++)
|
|
||||||
{
|
|
||||||
list[*num] = ticketInfo[i].titleId;
|
|
||||||
(*num)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nn::ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace ConsoleRestore */
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: PreinstallImporter.h
|
|
||||||
|
|
||||||
Copyright 2009-2011 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$
|
|
||||||
*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef PREINSTALLIMPORTER_H_
|
|
||||||
#define PREINSTALLIMPORTER_H_
|
|
||||||
|
|
||||||
#include <nn.h>
|
|
||||||
#include <nn/xml/simple/xml_simple_SimpleXmlParser.h>
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
|
|
||||||
//! @brief プリインストールをSDカードに書き込むためのクラスです
|
|
||||||
class PreinstallImporter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PreinstallImporter();
|
|
||||||
virtual ~PreinstallImporter();
|
|
||||||
|
|
||||||
//! @brief 外部タイトルデータベースを作成します
|
|
||||||
//! @param[out] list SDカードが初期化済みかどうか
|
|
||||||
//! @param[in] forcePreinstall SDカードが初期化済みでもプリインストールを書き込むかどうか
|
|
||||||
nn::Result SetupSd(bool* isAlreadyAvailable, bool forcePreinstall);
|
|
||||||
|
|
||||||
//!@ brief プリインストールタイトルをeTicketに基づいてリストアップする
|
|
||||||
nn::Result ListTitlesBasedOnTickets(nn::ProgramId* list, size_t* num);
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace ConsoleRestore */
|
|
||||||
#endif /* PREINSTALLIMPORTER_H_ */
|
|
||||||
@ -1,153 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: RegionIdModifier.cpp
|
|
||||||
|
|
||||||
Copyright (C)2011 Nintendo Co., Ltd. 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 "RegionIdModifier.h"
|
|
||||||
#include <cwchar>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
struct CountryData
|
|
||||||
{
|
|
||||||
u32 id; // 上記定数にあるように、国IDと地域IDを組み合わせたID
|
|
||||||
u16 regionName[nn::cfg::CTR::CFG_SIMPLE_ADDRESS_NUM_LANGUAGES][nn::cfg::CTR::CFG_SIMPLE_ADDRESS_NAME_LENGTH]; // NULL終端込み
|
|
||||||
u8 order[nn::cfg::CTR::CFG_SIMPLE_ADDRESS_NUM_LANGUAGES]; // 言語ごとの地域名並び順(「未設定」が0になるので、最初の地域は1)
|
|
||||||
u16 latitude; // リストの値を 65536/360 倍して格納して下さい
|
|
||||||
u16 longitude; // リストの値を 65536/360 倍して格納して下さい
|
|
||||||
};
|
|
||||||
|
|
||||||
const size_t NUP_VERSION_TO_REGIONNUM[] =
|
|
||||||
{
|
|
||||||
1, // ローンチ(0)
|
|
||||||
1, // 0thNUP(1)
|
|
||||||
2, // 1stNUP(2)
|
|
||||||
2, // 1.05NUP(3)
|
|
||||||
2, // 1.1NUP(4)
|
|
||||||
3, // 2ndNUP(5)
|
|
||||||
3, // 2.1NUP(6)
|
|
||||||
};
|
|
||||||
|
|
||||||
const wchar_t* DIR_PATH[] =
|
|
||||||
{
|
|
||||||
L"0/JP/",
|
|
||||||
L"0/US/",
|
|
||||||
L"0/EU/",
|
|
||||||
L"2/JP/",
|
|
||||||
L"2/US/",
|
|
||||||
L"2/EU/",
|
|
||||||
L"5/JP/",
|
|
||||||
L"5/US/",
|
|
||||||
L"5/EU/"
|
|
||||||
};
|
|
||||||
|
|
||||||
RegionIdModifier::RegionIdModifier(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName)
|
|
||||||
{
|
|
||||||
m_Id = id;
|
|
||||||
m_NupVersion = nupVersion;
|
|
||||||
m_RegionCode = regionCode;
|
|
||||||
if (regionName != NULL)
|
|
||||||
{
|
|
||||||
std::wcsncpy(m_RegionName, regionName, sizeof(m_RegionName) / sizeof(wchar_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RegionIdModifier::IsValid()
|
|
||||||
{
|
|
||||||
return (m_Id & 0x00ff) != 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PathList* RegionIdModifier::GetDirectoryPath()
|
|
||||||
{
|
|
||||||
// 範囲外のリージョン
|
|
||||||
if (nn::cfg::CTR::CFG_REGION_EUROPE < m_RegionCode)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u8 i = 0; i < nn::cfg::CTR::CFG_REGION_EUROPE + 1; i++)
|
|
||||||
{
|
|
||||||
std::wcsncpy(m_DirectoryPathBuf[i].path, DIR_PATH[m_RegionCode + i * (nn::cfg::CTR::CFG_REGION_EUROPE + 1)],
|
|
||||||
PATHLIST_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_DirectoryPathBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t RegionIdModifier::GetDirectoryPathNum()
|
|
||||||
{
|
|
||||||
// 範囲外のリージョン
|
|
||||||
if (nn::cfg::CTR::CFG_REGION_EUROPE < m_RegionCode)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t countryNum = sizeof(NUP_VERSION_TO_REGIONNUM) / sizeof(NUP_VERSION_TO_REGIONNUM[0]);
|
|
||||||
if (m_NupVersion > countryNum - 1)
|
|
||||||
{
|
|
||||||
return NUP_VERSION_TO_REGIONNUM[countryNum - 1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NUP_VERSION_TO_REGIONNUM[m_NupVersion];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const wchar_t* RegionIdModifier::GetFileName()
|
|
||||||
{
|
|
||||||
std::swprintf(m_FileNameBuf, sizeof(m_FileNameBuf), L"%d_LZ.bin", m_Id >> 8);
|
|
||||||
return m_FileNameBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PathList* RegionIdModifier::GetFilePath()
|
|
||||||
{
|
|
||||||
std::memset(m_FilePathBuf, 0, sizeof(m_FilePathBuf));
|
|
||||||
GetDirectoryPath();
|
|
||||||
for (u8 i = 0; i < GetDirectoryPathNum(); i++)
|
|
||||||
{
|
|
||||||
size_t writeSize = std::wcslen(m_DirectoryPathBuf[i].path);
|
|
||||||
std::wcsncpy(m_FilePathBuf[i].path, m_DirectoryPathBuf[i].path, writeSize);
|
|
||||||
std::wcsncat(m_FilePathBuf[i].path, GetFileName(), PATHLIST_LENGTH - writeSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_FilePathBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t RegionIdModifier::GetFilePathNum()
|
|
||||||
{
|
|
||||||
return GetDirectoryPathNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RegionIdModifier::GetValidRegionId(void* buf, size_t size, u8* id)
|
|
||||||
{
|
|
||||||
if (buf == NULL || size == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 numRegion; // その国に含まれる地域の数
|
|
||||||
numRegion = *reinterpret_cast<u32*>(buf);
|
|
||||||
|
|
||||||
CountryData* pCountry;
|
|
||||||
pCountry = reinterpret_cast<CountryData*>(&reinterpret_cast<u32*>(buf)[1]);
|
|
||||||
|
|
||||||
for (u32 i = 0; i < numRegion + 1; i++)
|
|
||||||
{
|
|
||||||
if (std::wcscmp(m_RegionName, reinterpret_cast<wchar_t*>(pCountry->regionName[0])) == 0)
|
|
||||||
{
|
|
||||||
*id = (pCountry->id >> 16) & 0x00ff;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
pCountry++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: RegionIdModifier.h
|
|
||||||
|
|
||||||
Copyright (C)2011 Nintendo Co., Ltd. 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:$
|
|
||||||
*---------------------------------------------------------------------------*/
|
|
||||||
#ifndef _REGION_ID_MODIFIER_H_
|
|
||||||
#define _REGION_ID_MODIFIER_H_
|
|
||||||
|
|
||||||
#if defined(__ARMCC_VERSION)
|
|
||||||
#include <nn.h>
|
|
||||||
#include <nn/cfg.h>
|
|
||||||
#else
|
|
||||||
#include "test_common.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const size_t PATHLIST_LENGTH = 32;
|
|
||||||
struct PathList
|
|
||||||
{
|
|
||||||
wchar_t path[PATHLIST_LENGTH];
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief データ移行ツールで破壊した地域idを修正するためのクラスです
|
|
||||||
class RegionIdModifier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! @brief パラメータを与えて初期化します。
|
|
||||||
//! @param[in] id SimpleAddressの上位16ビット
|
|
||||||
//! @param[in] nupVersion NUPバージョン
|
|
||||||
//! @param[in] regionCode リージョン
|
|
||||||
//! @param[in] regionName 地域名
|
|
||||||
RegionIdModifier(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName);
|
|
||||||
~RegionIdModifier() {};
|
|
||||||
|
|
||||||
//! @brief 正しいIDかどうか
|
|
||||||
bool IsValid();
|
|
||||||
|
|
||||||
//! @brief バージョン、リージョンに応じたディレクトリパスの配列を取得します
|
|
||||||
//! @return パス名。バージョン・リージョンが正しくない場合はNULL
|
|
||||||
const PathList* GetDirectoryPath();
|
|
||||||
|
|
||||||
//! @brief バージョン、リージョンに応じたディレクトリパス数を取得します
|
|
||||||
size_t GetDirectoryPathNum();
|
|
||||||
|
|
||||||
//! @brief 国idに応じたファイル名を取得します
|
|
||||||
const wchar_t* GetFileName();
|
|
||||||
|
|
||||||
//! @brief バージョン、リージョン、国idに応じたファイルパスの配列を取得します
|
|
||||||
const PathList* GetFilePath();
|
|
||||||
|
|
||||||
//! @brief バージョン、リージョン、国idに応じたファイルパス数を取得します
|
|
||||||
size_t GetFilePathNum();
|
|
||||||
|
|
||||||
//! @brief 与えられたバッファから正しい地域idを取得します
|
|
||||||
//! @param[in] buf 展開済みの地域データの入ったバッファ
|
|
||||||
//! @param[in] size バッファサイズ
|
|
||||||
//! @param[out] id 正しいid
|
|
||||||
//! @return 正しいidが見つかったかどうか
|
|
||||||
bool GetValidRegionId(void* buf , size_t size, u8* id);
|
|
||||||
|
|
||||||
private:
|
|
||||||
//! @brief SimpleAddressの上位16ビット
|
|
||||||
// 上位8ビットが国id,下位8ビットが地域
|
|
||||||
u16 m_Id;
|
|
||||||
|
|
||||||
//! @brief NUPバージョン番号
|
|
||||||
u8 m_NupVersion;
|
|
||||||
//! @brief リージョンコード
|
|
||||||
u8 m_RegionCode;
|
|
||||||
//! @brief 地域名
|
|
||||||
wchar_t m_RegionName[nn::cfg::CTR::CFG_SIMPLE_ADDRESS_NAME_LENGTH];
|
|
||||||
|
|
||||||
//! @brief ファイル名を保存するバッファ
|
|
||||||
wchar_t m_FileNameBuf[PATHLIST_LENGTH];
|
|
||||||
//! @brief ディレクトリパスを保存するバッファ
|
|
||||||
PathList m_DirectoryPathBuf[nn::cfg::CTR::CFG_REGION_EUROPE + 1];
|
|
||||||
//! @brief ファイルパスを保存するバッファ
|
|
||||||
PathList m_FilePathBuf[nn::cfg::CTR::CFG_REGION_EUROPE + 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _REGION_ID_MODIFIER_H_
|
|
||||||
@ -1,503 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: Shop.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/os.h>
|
|
||||||
#include <nn/Handle.h>
|
|
||||||
#include <nn/dbg.h>
|
|
||||||
#include <nn/nim.h>
|
|
||||||
#include <nn/ac/private/ac.h>
|
|
||||||
#include <nn/ac/CTR/private/ac_InternalApi.h>
|
|
||||||
#include <nn/nim/CTR/private/nim_ShopPrivateApi.h>
|
|
||||||
#include <nn/CTR/CTR_ProgramId.h>
|
|
||||||
#include <nn/am.h>
|
|
||||||
|
|
||||||
#include "Shop.h"
|
|
||||||
#include "CommonLogger.h"
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
using namespace ES_NAMESPACE;
|
|
||||||
using namespace EC_NAMESPACE;
|
|
||||||
|
|
||||||
#define NIM_SHOP_RESULT_CHECK(result) \
|
|
||||||
do { \
|
|
||||||
::nn::Result shopResult = (result); \
|
|
||||||
if (shopResult.IsFailure()) \
|
|
||||||
{ \
|
|
||||||
ECCustomerSupportCode csc; \
|
|
||||||
nn::nim::Shop::GetCustomerSupportCode(&csc); \
|
|
||||||
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)
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
nn::Result s_ShopResult = nn::ResultSuccess();
|
|
||||||
|
|
||||||
const size_t SHOP_OPERATION_THREAD_STACK_SIZE = 0x1000;
|
|
||||||
nn::os::Thread s_ShopOperationThread;
|
|
||||||
nn::os::StackBuffer<SHOP_OPERATION_THREAD_STACK_SIZE> s_ShopOperationThreadStack;
|
|
||||||
|
|
||||||
const size_t EC_BUFFER_SIZE = 128 * 1024;
|
|
||||||
u8 s_EcBufffer[EC_BUFFER_SIZE];
|
|
||||||
bool s_IsNimShopInitialized = false;
|
|
||||||
|
|
||||||
struct ShopThreadParam
|
|
||||||
{
|
|
||||||
ConsoleRestore::ShopOperation op;
|
|
||||||
NN_PADDING3;
|
|
||||||
NN_PADDING4;
|
|
||||||
nn::nim::TitleConfig config;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TitleProgress の ==, != を定義
|
|
||||||
bool operator==(
|
|
||||||
nn::nim::TitleProgress& lhs,
|
|
||||||
nn::nim::TitleProgress& rhs)
|
|
||||||
{
|
|
||||||
return (lhs.state == rhs.state &&
|
|
||||||
lhs.lastResult == rhs.lastResult &&
|
|
||||||
lhs.downloadedSize == rhs.downloadedSize &&
|
|
||||||
lhs.totalSize == rhs.totalSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(
|
|
||||||
nn::nim::TitleProgress& lhs,
|
|
||||||
nn::nim::TitleProgress& rhs)
|
|
||||||
{
|
|
||||||
return (! (lhs == rhs));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TitleState の文字列を取得
|
|
||||||
#ifdef COMMON_LOGGER_DETAIL_ENABLE
|
|
||||||
const char* GetTitleStateString(nn::nim::TitleState state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case nn::nim::TITLE_STATE_NOT_INITIALIZED:
|
|
||||||
return "NOT_INITIALIZED";
|
|
||||||
case nn::nim::TITLE_STATE_INITIALIZED:
|
|
||||||
return "INITIALIZED";
|
|
||||||
case nn::nim::TITLE_STATE_DOWNLOAD_TMD:
|
|
||||||
return "DOWNLOAD_TMD";
|
|
||||||
case nn::nim::TITLE_STATE_PREPARE_SAVE_DATA:
|
|
||||||
return "PREPARE_SAVE_DATA";
|
|
||||||
case nn::nim::TITLE_STATE_DOWNLOAD_CONTENTS:
|
|
||||||
return "DOWNLOAD_CONTENTS";
|
|
||||||
case nn::nim::TITLE_STATE_WAIT_COMMIT:
|
|
||||||
return "WAIT_COMMIT";
|
|
||||||
case nn::nim::TITLE_STATE_COMMITTING:
|
|
||||||
return "COMMITTING";
|
|
||||||
case nn::nim::TITLE_STATE_FINISHED:
|
|
||||||
return "FINISHED";
|
|
||||||
case nn::nim::TITLE_STATE_VERSION_MISMATCH:
|
|
||||||
return "VERSION_MISMATCH";
|
|
||||||
default:
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// 空文字列と NULL ポインタをそれぞれ <empty> と NULL として返す
|
|
||||||
#ifdef COMMON_LOGGER_DETAIL_ENABLE
|
|
||||||
const char* Cstr(const char* p)
|
|
||||||
{
|
|
||||||
return p ? (p[0] ? p : "<empty>") : "NULL";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ECTicketVersions を出力
|
|
||||||
void PrintECTicketVersions(const ECTicketVersions& ticketVersions)
|
|
||||||
{
|
|
||||||
if (ticketVersions.nTicketVersions == 0)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("No TicketVersions\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("----- ECTicketVersions -----\n");
|
|
||||||
for (u32 i = 0; i < ticketVersions.nTicketVersions; i++)
|
|
||||||
{
|
|
||||||
#ifdef COMMON_LOGGER_DETAIL_ENABLE
|
|
||||||
ECTicketVersion version = ticketVersions.ticketVersions[i];
|
|
||||||
#endif
|
|
||||||
COMMON_LOGGER_DETAIL("%03d: 0x%016llx v%d\n", i, version.ticketId, version.version);
|
|
||||||
}
|
|
||||||
COMMON_LOGGER_DETAIL("---------------------------\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ECAccountInfo の情報を出力
|
|
||||||
void PrintECAccountInfo(const ECAccountInfo& accountInfo)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("========== ECAccountInfo ==========\n");
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("accountId\n %s\n", Cstr(accountInfo.accountId));
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("accountStatus\n %s\n", Cstr(accountInfo.accountStatus));
|
|
||||||
|
|
||||||
if (accountInfo.accountBalance == NULL)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("accountBalance\n NULL\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("accountBalance->amount\n %s\n",
|
|
||||||
Cstr(accountInfo.accountBalance->amount));
|
|
||||||
COMMON_LOGGER_DETAIL("accountBalance->currency\n %s\n",
|
|
||||||
Cstr(accountInfo.accountBalance->currency));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accountInfo.agreedEULAVersion == NULL)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("agreedEULAVersion\n NULL\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("agreedEULAVersion\n %lld\n",
|
|
||||||
*accountInfo.agreedEULAVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accountInfo.latestEULAVersion == NULL)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("latestEULAVersion\n NULL\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("latestEULAVersion\n %lld\n",
|
|
||||||
*accountInfo.latestEULAVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("country\n %s\n", Cstr(accountInfo.country));
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("extAccountId\n %s\n", Cstr(accountInfo.extAccountId));
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("deviceToken\n %s\n", Cstr(accountInfo.deviceToken));
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("weakToken\n %s\n", Cstr(accountInfo.weakToken));
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("isStandbyMode\n %d\n", accountInfo.isStandbyMode);
|
|
||||||
|
|
||||||
if (accountInfo.owned == NULL)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("owned\n NULL\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PrintECTicketVersions(*(accountInfo.owned));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace ConsoleRestore{
|
|
||||||
|
|
||||||
nn::Result ShopOperationConnect();
|
|
||||||
nn::Result ShopOperationFinalize();
|
|
||||||
|
|
||||||
|
|
||||||
nn::Result CheckStandbyMode(s32 isStandbyMode)
|
|
||||||
{
|
|
||||||
if(isStandbyMode)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Shop is Standby Mode\n");
|
|
||||||
return nn::MakePermanentResult(nn::Result::SUMMARY_INVALID_STATE, nn::Result::MODULE_COMMON,
|
|
||||||
nn::Result::DESCRIPTION_NOT_AUTHORIZED);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return nn::ResultSuccess();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result ShopOperationConnect(ECAccountInfo** pAccountInfo)
|
|
||||||
{
|
|
||||||
nn::Result result = nn::ResultSuccess();
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
Connect
|
|
||||||
-------------------------------------------------------------------- */
|
|
||||||
COMMON_LOGGER_DETAIL("nim::Shop::Connect\n");
|
|
||||||
result = nn::nim::Shop::Connect(pAccountInfo, s_EcBufffer, EC_BUFFER_SIZE);
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
||||||
result = CheckStandbyMode((*pAccountInfo)->isStandbyMode);
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
||||||
|
|
||||||
PrintECAccountInfo(**pAccountInfo);
|
|
||||||
COMMON_LOGGER_DETAIL("\n");
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result ShopOperationInitialize()
|
|
||||||
{
|
|
||||||
nn::Result result = nn::ResultSuccess();
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
Initialize
|
|
||||||
-------------------------------------------------------------------- */
|
|
||||||
if (!s_IsNimShopInitialized)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("nim::InitializeForShop\n");
|
|
||||||
result = nn::nim::InitializeForShop();
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
||||||
s_IsNimShopInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
SetParameter
|
|
||||||
-------------------------------------------------------------------- */
|
|
||||||
COMMON_LOGGER_DETAIL("nim::Shop::SetApplication Id\n");
|
|
||||||
|
|
||||||
nn::nim::Shop::SetApplicationId();
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("nim::Shop::SetTIN\n");
|
|
||||||
result = nn::nim::Shop::SetTin(CONSOLE_RESTORE_TIN);
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result ShopOperationConnect()
|
|
||||||
{
|
|
||||||
nn::Result result;
|
|
||||||
result = ShopOperationInitialize();
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
Connect
|
|
||||||
-------------------------------------------------------------------- */
|
|
||||||
ECAccountInfo* pAccountInfo;
|
|
||||||
result = ShopOperationConnect(&pAccountInfo);
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result ShopOperationFinalize()
|
|
||||||
{
|
|
||||||
nn::Result result = nn::ResultSuccess();
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
Finalize
|
|
||||||
-------------------------------------------------------------------- */
|
|
||||||
COMMON_LOGGER_DETAIL("nim::FinalizeForShop\n");
|
|
||||||
result = nn::nim::FinalizeForShop();
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
||||||
s_IsNimShopInitialized = false;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
void ShopOperationUnregisterCore(bool force)
|
|
||||||
{
|
|
||||||
nn::Result result;
|
|
||||||
result = ShopOperationInitialize();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
ECAccountInfo* pAccountInfo;
|
|
||||||
result = ShopOperationConnect(&pAccountInfo);
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
if (force)
|
|
||||||
{
|
|
||||||
if (pAccountInfo->accountStatus && (pAccountInfo->accountStatus[0] == 'R' || pAccountInfo->accountStatus[0]
|
|
||||||
== 'T'))
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("nim::Shop::Unregister\n");
|
|
||||||
result = nn::nim::Shop::Unregister();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pAccountInfo->accountStatus && (pAccountInfo->accountStatus[0] == 'R'))
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("nim::Shop::Unregister\n");
|
|
||||||
result = nn::nim::Shop::Unregister();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("Not registered.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// メイン関数
|
|
||||||
void ShopOperationSingleThreadFunc(ShopThreadParam param)
|
|
||||||
{
|
|
||||||
nn::Result result;
|
|
||||||
|
|
||||||
s_ShopResult = nn::ResultSuccess();
|
|
||||||
|
|
||||||
if(!nn::ac::IsConnected())
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("util::ac::Initialize\n");
|
|
||||||
result = common::InitializeNetwork();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(param.op)
|
|
||||||
{
|
|
||||||
case SHOP_OPERATION_CONNECT:
|
|
||||||
{
|
|
||||||
result = ShopOperationConnect();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHOP_OPERATION_GET_IVS:
|
|
||||||
{
|
|
||||||
result = ShopOperationInitialize();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
// IVSを取得する
|
|
||||||
result = nn::nim::Shop::ImportIvsFromInfrastructure();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHOP_OPERATION_UNREGISTER:
|
|
||||||
{
|
|
||||||
ShopOperationUnregisterCore(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHOP_OPERATION_FORCE_UNREGISTER:
|
|
||||||
{
|
|
||||||
ShopOperationUnregisterCore(true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHOP_OPERATION_CONNECT_WITHOUT_CLOSE:
|
|
||||||
{
|
|
||||||
result = ShopOperationConnect();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
case SHOP_OPERATION_DOWNLOAD_TITLE:
|
|
||||||
COMMON_LOGGER_DETAIL("Try Download %016llx\n", param.config.titleId);
|
|
||||||
result = nn::nim::Shop::StartDownload(param.config);
|
|
||||||
|
|
||||||
if (result == nn::nim::ResultBusy() || result == nn::nim::ResultAlreadyDone())
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Download Content -> Nim is busy\n");
|
|
||||||
}
|
|
||||||
else if (result == nn::nim::ResultInvalidTitle())
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Download Content -> Invalid Title\n");
|
|
||||||
}
|
|
||||||
else if (result.IsFailure())
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Download Content -> Failure %x\n", result.GetPrintableBits());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
GetProgress
|
|
||||||
-------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("nim::Shop::GetProgress()\n");
|
|
||||||
nn::nim::TitleProgress before;
|
|
||||||
nn::nim::TitleProgress latest;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
result = nn::nim::Shop::GetProgress(&latest);
|
|
||||||
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
NIM_SHOP_RESULT_CHECK(latest.lastResult);
|
|
||||||
|
|
||||||
// Print progress
|
|
||||||
if (latest != before)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("%8lld / %8lld (%d:%s)\n",
|
|
||||||
latest.downloadedSize,
|
|
||||||
latest.totalSize,
|
|
||||||
latest.state.Get(),
|
|
||||||
GetTitleStateString(latest.state));
|
|
||||||
|
|
||||||
if (latest.state == nn::nim::TITLE_STATE_FINISHED)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("Finished Download\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
before = latest;
|
|
||||||
}
|
|
||||||
|
|
||||||
// あまりにも頻繁に GetProgress を呼ぶと、ダウンロード処理の速度に
|
|
||||||
// 影響が出てしまいます。少なくとも数フレーム以上の間隔をあけて
|
|
||||||
// GetProgress することを推奨します。
|
|
||||||
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(100));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ShopOperationFinalize();
|
|
||||||
NIM_SHOP_RESULT_CHECK(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartShopOperationSingle(ShopOperation op, nn::nim::TitleConfig config)
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("Start ShopOperationSingle, %s\n", SHOP_OPERATION_STR[op]);
|
|
||||||
|
|
||||||
ShopThreadParam param;
|
|
||||||
param.op = op;
|
|
||||||
param.config = config;
|
|
||||||
s_ShopOperationThread.Start(ShopOperationSingleThreadFunc, param, s_ShopOperationThreadStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartShopOperationSingle(ShopOperation op)
|
|
||||||
{
|
|
||||||
ShopThreadParam param;
|
|
||||||
param.op = op;
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("Start ShopOperationSingle, %s\n", SHOP_OPERATION_STR[op]);
|
|
||||||
s_ShopOperationThread.Start(ShopOperationSingleThreadFunc, param, s_ShopOperationThreadStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FinalizeShopOperationSingle()
|
|
||||||
{
|
|
||||||
COMMON_LOGGER_DETAIL("Finalize ShopOperationSingle\n");
|
|
||||||
s_ShopOperationThread.Join();
|
|
||||||
s_ShopOperationThread.Finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsShopOperationSingleFinished()
|
|
||||||
{
|
|
||||||
return s_ShopOperationThread.IsValid() && !s_ShopOperationThread.IsAlive();
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result GetShopOperationSingleResult()
|
|
||||||
{
|
|
||||||
return s_ShopResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: Shop.h
|
|
||||||
|
|
||||||
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$
|
|
||||||
*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef SHOP_H_
|
|
||||||
#define SHOP_H_
|
|
||||||
|
|
||||||
#include <nn.h>
|
|
||||||
#include <nn/nim.h>
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
|
|
||||||
// ショップサーバにConsoleResotoreが接続するためのTINコード
|
|
||||||
const char* const CONSOLE_RESTORE_TIN = "987654321";
|
|
||||||
|
|
||||||
typedef enum SHOP_OPERATION
|
|
||||||
{
|
|
||||||
SHOP_OPERATION_CONNECT, // Shop::ConnectしてCloseするだけ
|
|
||||||
SHOP_OPERATION_GET_IVS, // Shop::ImportIvsFromInfrastructureを実行
|
|
||||||
SHOP_OPERATION_UNREGISTER, // Shop::Unregisterを実行
|
|
||||||
SHOP_OPERATION_FORCE_UNREGISTER, // アカウント移行後でもUnregisterを実行
|
|
||||||
SHOP_OPERATION_CONNECT_WITHOUT_CLOSE, // Shop::ConnectしてCloseしない
|
|
||||||
SHOP_OPERATION_DOWNLOAD_TITLE, // Titleをダウンロードする
|
|
||||||
SHOP_OPERATION_NUM_MAX
|
|
||||||
|
|
||||||
} ShopOperation;
|
|
||||||
|
|
||||||
// ショップ操作のモード表示用文字列(デバッグ用)
|
|
||||||
const char* const SHOP_OPERATION_STR[] =
|
|
||||||
{
|
|
||||||
"Connect",
|
|
||||||
"Get SDCI",
|
|
||||||
"Unregister",
|
|
||||||
"Force Unregister",
|
|
||||||
"Connect Without Close",
|
|
||||||
"Download Title"
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新たにスレッドを立て、ショップ操作を開始する
|
|
||||||
void StartShopOperationSingle(ShopOperation op, nn::nim::TitleConfig config);
|
|
||||||
|
|
||||||
// 新たにスレッドを立て、ショップ操作を開始する
|
|
||||||
void StartShopOperationSingle(ShopOperation op);
|
|
||||||
|
|
||||||
// ショップ操作スレッドを終了する
|
|
||||||
void FinalizeShopOperationSingle();
|
|
||||||
|
|
||||||
// ショップ操作スレッドが終了したかどうか
|
|
||||||
bool IsShopOperationSingleFinished();
|
|
||||||
|
|
||||||
// ショップ操作のResultを取得する
|
|
||||||
nn::Result GetShopOperationSingleResult();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SHOP_H_ */
|
|
||||||
@ -1,441 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
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 <nn/cfg/CTR/cfg_ApiSys.h>
|
|
||||||
|
|
||||||
#include "SdMountManager.h"
|
|
||||||
#include "common_Types.h"
|
|
||||||
#include "FileName.h"
|
|
||||||
#include "CommonLogger.h"
|
|
||||||
#include "HeapManager.h"
|
|
||||||
#include "TitleDownloader.h"
|
|
||||||
#include "Shop.h"
|
|
||||||
#include "SdReaderWriter.h"
|
|
||||||
#include "PreinstallImporter.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
bit8 s_buffer1[400 * 1024];
|
|
||||||
|
|
||||||
// ダウンロードするタイトルの個数
|
|
||||||
size_t s_ProgramIdNum = 0;
|
|
||||||
// ダウンロードするタイトルのProgramIdの配列
|
|
||||||
nn::ProgramId s_ProgramIdList[256];
|
|
||||||
// ダウンロード済みのタイトルの個数
|
|
||||||
size_t s_FinishedTitleNum = 0;
|
|
||||||
|
|
||||||
const size_t TITLE_DOWNLOADER_STACK_SIZE = 0x2000;
|
|
||||||
nn::os::Thread s_TitleDownloaderThread;
|
|
||||||
nn::os::StackBuffer<TITLE_DOWNLOADER_STACK_SIZE> s_TitleDownloaderThreadStack;
|
|
||||||
u64 s_Progress;
|
|
||||||
|
|
||||||
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"}
|
|
||||||
};
|
|
||||||
|
|
||||||
COMMON_LOGGER_DETAIL("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));
|
|
||||||
|
|
||||||
if(result.IsSuccess())
|
|
||||||
{
|
|
||||||
if(titleCatalog->nEntries == 1)
|
|
||||||
{
|
|
||||||
*entry = &(titleCatalog->entries[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return nn::MakeStatusResult(nn::Result::SUMMARY_NOT_FOUND, nn::Result::MODULE_COMMON, nn::Result::DESCRIPTION_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result GetTitleConfig(const ES_NAMESPACE::ESTitleId titleId, nn::nim::TitleConfig *titleConfig, s64* requiredSize)
|
|
||||||
{
|
|
||||||
EC_NAMESPACE::ECTitleCatalogEntry *entry;
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_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);
|
|
||||||
*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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace <unnamed>
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
|
|
||||||
nn::Result TitleDownloader::m_Result = nn::ResultSuccess();
|
|
||||||
|
|
||||||
void TwlTitleDownloaderThreadFunc()
|
|
||||||
{
|
|
||||||
TitleDownloader TwlTitleDownloader;
|
|
||||||
|
|
||||||
s_Progress = 0;
|
|
||||||
TitleDownloader::m_Result = ListUpTwlTitles(s_ProgramIdList, &s_ProgramIdNum);
|
|
||||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(TitleDownloader::m_Result);
|
|
||||||
TwlTitleDownloader.SetupTitleList(s_ProgramIdList, s_ProgramIdNum, s_FinishedTitleNum);
|
|
||||||
TwlTitleDownloader.Start();
|
|
||||||
s_FinishedTitleNum = TwlTitleDownloader.GetFinishedTitleNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PreinstallTitleDownloaderThreadFunc()
|
|
||||||
{
|
|
||||||
TitleDownloader PreinstallTitleDownloader;
|
|
||||||
|
|
||||||
s_Progress = 0;
|
|
||||||
s_FinishedTitleNum = 0;
|
|
||||||
PreinstallTitleDownloader.SetupTitleList(s_ProgramIdList, s_ProgramIdNum, s_FinishedTitleNum);
|
|
||||||
PreinstallTitleDownloader.Start();
|
|
||||||
s_FinishedTitleNum = PreinstallTitleDownloader.GetFinishedTitleNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartTwlTitleDownload()
|
|
||||||
{
|
|
||||||
s_TitleDownloaderThread.Start(TwlTitleDownloaderThreadFunc, s_TitleDownloaderThreadStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PreparePreinstallTitleDownloadThreadFunc(PreinstallListupParam param)
|
|
||||||
{
|
|
||||||
PreinstallImporter importer;
|
|
||||||
bool isAlreadyAvailable = false;
|
|
||||||
TitleDownloader preinstallTitleDownloader;
|
|
||||||
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);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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, param.forcePreinstall);
|
|
||||||
if(isAlreadyAvailable)
|
|
||||||
{
|
|
||||||
preinstallTitleDownloader.m_Result = nn::MakePermanentResult(nn::Result::SUMMARY_INVALID_STATE,
|
|
||||||
nn::Result::MODULE_APPLICATION, nn::Result::DESCRIPTION_ALREADY_INITIALIZED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartPreparePreinstallTitleDownload(bool forcePreinstall)
|
|
||||||
{
|
|
||||||
PreinstallListupParam param;
|
|
||||||
param.forcePreinstall = forcePreinstall;
|
|
||||||
|
|
||||||
s_TitleDownloaderThread.Start(PreparePreinstallTitleDownloadThreadFunc, param, s_TitleDownloaderThreadStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartPreinstallTitleDownload()
|
|
||||||
{
|
|
||||||
s_TitleDownloaderThread.Start(PreinstallTitleDownloaderThreadFunc, s_TitleDownloaderThreadStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsDownloadTitleFinished()
|
|
||||||
{
|
|
||||||
return s_TitleDownloaderThread.IsValid() && !s_TitleDownloaderThread.IsAlive();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FinalizeTitleDownload()
|
|
||||||
{
|
|
||||||
s_TitleDownloaderThread.Join();
|
|
||||||
s_TitleDownloaderThread.Finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DownloadTitleSucceeded()
|
|
||||||
{
|
|
||||||
return TitleDownloader::m_Result.IsSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result GetTitleDownloadResult()
|
|
||||||
{
|
|
||||||
return TitleDownloader::m_Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GetTitleDownloadProgress()
|
|
||||||
{
|
|
||||||
return s_Progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TitleDownloader::TitleDownloader() : m_TiteNum(0), m_FinishedTitleNum(0)
|
|
||||||
{
|
|
||||||
for(u32 i = 0; i < IMPORTABLE_TITLE_MAX; i++)
|
|
||||||
{
|
|
||||||
m_ProgramIdList[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TitleDownloader::~TitleDownloader()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result ListUpTwlTitles(nn::ProgramId* list, size_t* num)
|
|
||||||
{
|
|
||||||
nn::Result result;
|
|
||||||
COMMON_LOGGER("Read TwlTitle List.\n");
|
|
||||||
|
|
||||||
*num = 0;
|
|
||||||
size_t heapSize = common::GetAllocatableSize();
|
|
||||||
if(heapSize > common::FILE_COPY_HEAP_SIZE)
|
|
||||||
{
|
|
||||||
heapSize = common::FILE_COPY_HEAP_SIZE;
|
|
||||||
}
|
|
||||||
common::HeapManager heap(heapSize);
|
|
||||||
char* titleListBuf = reinterpret_cast<char*> (heap.GetAddr());
|
|
||||||
|
|
||||||
size_t readSize = 0;
|
|
||||||
if (titleListBuf != NULL)
|
|
||||||
{
|
|
||||||
common::SdReaderWriter sdReader;
|
|
||||||
result = sdReader.ReadBufWithCmac(common::TWL_TITLELIST_PATHNAME, titleListBuf, heapSize, &readSize);
|
|
||||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
|
||||||
if (result.IsSuccess())
|
|
||||||
{
|
|
||||||
u32 listHead = 0;
|
|
||||||
for (u32 i = 0; i < readSize; i++)
|
|
||||||
{
|
|
||||||
if (titleListBuf[i] == '\n')
|
|
||||||
{
|
|
||||||
char ProgramIdStr[32];
|
|
||||||
char *error;
|
|
||||||
std::memcpy(ProgramIdStr, &titleListBuf[listHead], i - listHead);
|
|
||||||
list[*num] = std::strtoull(ProgramIdStr, &error, 16);
|
|
||||||
(*num)++;
|
|
||||||
COMMON_LOGGER_DETAIL("%016llx\n", list[*num - 1]);
|
|
||||||
|
|
||||||
listHead = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
COMMON_LOGGER("%d Title(s) found.\n", *num);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
||||||
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
nn::Result WaitCancelled()
|
|
||||||
{
|
|
||||||
nn::nim::TitleProgress progress;
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
// キャンセルがResultとして返ってくる / ダウンロード終了まで待つ
|
|
||||||
COMMON_LOGGER_RETURN_RESULT_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 StartShopOperationSingleRetry(ShopOperation op, u32 retryCount)
|
|
||||||
{
|
|
||||||
for(u32 i = 0; i < retryCount; i++)
|
|
||||||
{
|
|
||||||
StartShopOperationSingle(op);
|
|
||||||
WaitShopOperationAndFinalize();
|
|
||||||
if(GetShopOperationSingleResult().IsSuccess())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TitleDownloader::Start()
|
|
||||||
{
|
|
||||||
COMMON_LOGGER("Download %d Title(s).\n", m_TiteNum);
|
|
||||||
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();
|
|
||||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
|
||||||
|
|
||||||
nn::nim::TitleConfig config;
|
|
||||||
s64 requiredSize;
|
|
||||||
m_Result = GetTitleConfig(m_ProgramIdList[i], &config, &requiredSize);
|
|
||||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
const size_t listNum = nn::math::Min(num, IMPORTABLE_TITLE_MAX);
|
|
||||||
for(u32 i = 0; i < listNum; i++)
|
|
||||||
{
|
|
||||||
m_ProgramIdList[i] = list[i];
|
|
||||||
}
|
|
||||||
m_TiteNum = listNum;
|
|
||||||
m_FinishedTitleNum = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 TitleDownloader::GetFinishedTitleNum()
|
|
||||||
{
|
|
||||||
return m_FinishedTitleNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*
|
|
||||||
Project: Horizon
|
|
||||||
File: TitleDownloader.h
|
|
||||||
|
|
||||||
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$
|
|
||||||
*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef TITLEDOWNLOADER_H_
|
|
||||||
#define TITLEDOWNLOADER_H_
|
|
||||||
|
|
||||||
#include <nn.h>
|
|
||||||
|
|
||||||
namespace ConsoleRestore
|
|
||||||
{
|
|
||||||
|
|
||||||
// 新たにスレッドを立て、TWLタイトルのダウンロードを開始する
|
|
||||||
void StartTwlTitleDownload();
|
|
||||||
|
|
||||||
//! @brief プリインストールタイトルをSDカードにインポート可能かどうかサイズを確認し、<BR/>
|
|
||||||
//! 可能であればSDカードをインポート可能状態にします
|
|
||||||
//! @param[in] serialNo 強制的にプリインストールを書き込むかどうか
|
|
||||||
//! @return 正常に初期化できたかどうか
|
|
||||||
void StartPreparePreinstallTitleDownload(bool forcePreinstall);
|
|
||||||
|
|
||||||
//! @brief 新たにスレッドを立て、プリインストールタイトルのダウンロードを開始します <BR/>
|
|
||||||
//! SDカードはインポート可能な状態にしておく必要があります。
|
|
||||||
void StartPreinstallTitleDownload();
|
|
||||||
|
|
||||||
|
|
||||||
// プリインストール情報取得に必要なパラメータをまとめた構造体
|
|
||||||
struct PreinstallListupParam
|
|
||||||
{
|
|
||||||
bool forcePreinstall;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief ダウンロードするTWLタイトルをSDカードからリストアップする
|
|
||||||
nn::Result ListUpTwlTitles(nn::ProgramId* list, size_t* num);
|
|
||||||
|
|
||||||
// タイトルのダウンロードスレッドが終了したかどうか
|
|
||||||
bool IsDownloadTitleFinished();
|
|
||||||
|
|
||||||
// タイトルのダウンロードスレッドが成功したかどうか
|
|
||||||
bool DownloadTitleSucceeded();
|
|
||||||
|
|
||||||
// タイトルのダウンロード結果を取得する
|
|
||||||
nn::Result GetTitleDownloadResult();
|
|
||||||
|
|
||||||
// タイトルのダウンロードスレッドを終了する
|
|
||||||
void FinalizeTitleDownload();
|
|
||||||
|
|
||||||
// タイトルダウンロードの進捗を取得する
|
|
||||||
u32 GetTitleDownloadProgress();
|
|
||||||
|
|
||||||
// ショップからタイトルをダウンロードするためのクラス
|
|
||||||
class TitleDownloader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TitleDownloader();
|
|
||||||
virtual ~TitleDownloader();
|
|
||||||
|
|
||||||
//! @brief タイトルリストを設定する
|
|
||||||
void SetupTitleList(nn::ProgramId* list, size_t num, u32 index);
|
|
||||||
|
|
||||||
//! @brief タイトルをダウンロードするのに必要なサイズを計算します
|
|
||||||
void CalculateRequiredSize(s64* requiredSize);
|
|
||||||
|
|
||||||
//! @brief ダウンロードが完了したタイトルの数を取得します
|
|
||||||
u32 GetFinishedTitleNum();
|
|
||||||
|
|
||||||
// タイトルのダウンロードを開始する
|
|
||||||
void Start();
|
|
||||||
|
|
||||||
NN_PADDING4;
|
|
||||||
static nn::Result m_Result;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t IMPORTABLE_TITLE_MAX = 256;
|
|
||||||
|
|
||||||
nn::ProgramID m_ProgramIdList[IMPORTABLE_TITLE_MAX];
|
|
||||||
u32 m_TiteNum;
|
|
||||||
u32 m_FinishedTitleNum;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TITLEDOWNLOADER_H_ */
|
|
||||||
Loading…
Reference in New Issue
Block a user