NetworkUpdater_1-0-0としてビルドできるように
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@778 385bec56-5757-e545-9c3a-d8741f4650f1
@ -9,56 +9,13 @@ CTR_SDK-3_3 branch r45925 + r51434 + r54939
|
||||
-------
|
||||
ARM C/C++ Compiler, 4.1 [Build 1247] for Nintendo
|
||||
|
||||
ミドルウェア
|
||||
--------
|
||||
QRコードエンコーダ 1.2.3
|
||||
|
||||
ビルド時の注意
|
||||
------------
|
||||
### AES鍵の変更
|
||||
リリース用ビルドでは開発機・量産機でAES鍵を変えるため、
|
||||
|
||||
量産機用ビルドの場合
|
||||
./build.sh PROD
|
||||
|
||||
でビルドすること。
|
||||
|
||||
開発機用ビルドの場合
|
||||
./build.sh UNFIXEDKEY
|
||||
|
||||
でビルドすること。
|
||||
|
||||
### 自動無線ON/OFF
|
||||
無線ON/OFF切り替えのため、`sources/common/nwm_ExtAPI.cpp` を
|
||||
`$HORIZON_ROOT/sources/libraries/nwm/CTR`
|
||||
にコピーしてからnwmをリビルドする必要がある。
|
||||
|
||||
### NNA移行完了
|
||||
NNA移行完了のため、
|
||||
trunk r54688からactライブラリをコピーする必要がある。
|
||||
3_3 branch のcfgには無いシンボルを参照してしまうので、trunkでactライブラリをビルドする時に
|
||||
`sources/common/act_ApiAdmin.cpp.patch`を当ててからビルドすること。
|
||||
|
||||
#### trunkからコピーするファイル
|
||||
* $HORIZON_ROOT/include/nn/act
|
||||
* $HORIZON_ROOT/include/nn/mii
|
||||
* $HORIZON_ROOT/include/nn/Result.h
|
||||
* $HORIZON_ROOT/libraries/CTR-TS.Process.MPCore/release/libnn_act.fast.a
|
||||
* $HORIZON_ROOT/libraries/CTR-TS.Process.MPCore/release/libnn_act.small.a
|
||||
* $HORIZON_ROOT/libraries/CTR-TS.Process.MPCore/verbose/libnn_act.fast.a
|
||||
* $HORIZON_ROOT/libraries/CTR-TS.Process.MPCore/verbose/libnn_act.small.a
|
||||
|
||||
リリース時の注意
|
||||
=============
|
||||
|
||||
ConsoleRestoreのReleaseビルドは、ショップ接続時などにで無限ループする不具合があるためDevelopmentビルドを使用する。
|
||||
|
||||
その他
|
||||
=====
|
||||
|
||||
PC上でのgoogletestを使う場合BOM付きのUTF-8を
|
||||
コンパイルできるgccが必要。
|
||||
cygwin 1.7.9-1
|
||||
で動作確認済み。
|
||||
`sources/tests/googletest/common/common.om`にgtestのインストール先を指定する必要がある
|
||||
|
||||
Releaseビルドは、ショップ接続時などにで無限ループする不具合があるためDevelopmentビルドを使用する。
|
||||
|
||||
|
Before Width: | Height: | Size: 586 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 586 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 586 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 586 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 586 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 281 KiB |
@ -1,106 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: Checker.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 "common_Types.h"
|
||||
#include "CommonLogger.h"
|
||||
#include "HeapManager.h"
|
||||
#include "SaveDataChecker.h"
|
||||
#include <nn/drivers/aes/CTR/ARM946ES/driverAes_Types.h>
|
||||
|
||||
namespace ConsoleBackup
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const size_t CHECKER_STACK_SIZE = 0x4000;
|
||||
nn::os::Thread s_CheckerThread;
|
||||
nn::os::StackBuffer<CHECKER_STACK_SIZE> s_CheckerThreadStackSize;
|
||||
nn::Result s_CheckerResult;
|
||||
NandSavedataChecker* s_pChecker;
|
||||
bool s_CheckErrorOccured = false;
|
||||
|
||||
}
|
||||
|
||||
s32 GetCheckSaveDataProgress()
|
||||
{
|
||||
if(s_pChecker != NULL)
|
||||
{
|
||||
return s_pChecker->GetProgress();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CheckSaveDataThreadFunc(bool erase)
|
||||
{
|
||||
size_t bufSize = common::GetAllocatableSize();
|
||||
if(bufSize > common::FILE_COPY_HEAP_SIZE)
|
||||
{
|
||||
bufSize = common::FILE_COPY_HEAP_SIZE;
|
||||
}
|
||||
common::HeapManager heap(bufSize);
|
||||
if (heap.GetAddr() != NULL)
|
||||
{
|
||||
s_pChecker = new NandSavedataChecker(heap.GetAddr(), bufSize);
|
||||
s_CheckerResult = s_pChecker->CleanUp(erase);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_CheckerResult = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE,
|
||||
nn::Result::MODULE_COMMON, nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void StartSaveDataCheck(bool erase)
|
||||
{
|
||||
s_CheckerThread.Start(CheckSaveDataThreadFunc, erase, s_CheckerThreadStackSize);
|
||||
}
|
||||
|
||||
bool IsCheckSaveDataFinished()
|
||||
{
|
||||
return s_CheckerThread.IsValid() && !s_CheckerThread.IsAlive();
|
||||
}
|
||||
|
||||
void FinalizeSaveDataCheck()
|
||||
{
|
||||
s_CheckerThread.Join();
|
||||
s_CheckerThread.Finalize();
|
||||
|
||||
if(s_pChecker != NULL)
|
||||
{
|
||||
s_CheckErrorOccured = s_pChecker->GetCheckErrorOccured();
|
||||
delete s_pChecker;
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckSaveDataErrorOccured()
|
||||
{
|
||||
return s_CheckErrorOccured;
|
||||
}
|
||||
|
||||
bool CheckSaveDataSucceeded()
|
||||
{
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(s_CheckerResult);
|
||||
return s_CheckerResult.IsSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: Checker.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 CHECKER_H_
|
||||
#define CHECKER_H_
|
||||
|
||||
namespace ConsoleBackup
|
||||
{
|
||||
|
||||
s32 GetCheckSaveDataProgress();
|
||||
//!@ brief セーブデータのチェックを開始する
|
||||
//!@ param[in] erase エラー発生時にファイルを削除するかどうか
|
||||
void StartSaveDataCheck(bool erase);
|
||||
bool IsCheckSaveDataFinished();
|
||||
void FinalizeSaveDataCheck();
|
||||
bool CheckSaveDataErrorOccured();
|
||||
bool CheckSaveDataSucceeded();
|
||||
|
||||
}
|
||||
|
||||
#endif /* CHECKER_H_ */
|
||||
@ -1,316 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: ConsoleBackup.cpp
|
||||
|
||||
Copyright (C)2009 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 <nn.h>
|
||||
#include <nn/version.h>
|
||||
#include <nn/ptm/CTR/ptm_ApiSysmenu.h>
|
||||
#include <nn/mcu.h>
|
||||
#include <nn/cfg/CTR/cfg_Api.h>
|
||||
#include <nn/cfg/CTR/cfg_ApiInit.h>
|
||||
#include <nn/cfg/CTR/cfg_ApiSys.h>
|
||||
#include <nn/ps.h>
|
||||
#include <nn/nwm.h>
|
||||
#include <nn/ac.h>
|
||||
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
|
||||
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
|
||||
#include <nn/fs/fs_ApiSysSaveData.h>
|
||||
#include <nn/cfg/CTR/cfg_ApiNor.h>
|
||||
#include <nn/os/os_SharedInfo.h>
|
||||
#include <nn/pl/CTR/pl_Version.h>
|
||||
#include <nn/fs/fs_ApiSharedExtSaveData.h>
|
||||
#include <nn/nim.h>
|
||||
#include <nn/ndm.h>
|
||||
#include <nn/am.h>
|
||||
|
||||
#include "demo.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "DrawSystemState.h"
|
||||
#include "FileName.h"
|
||||
#include "Controller.h"
|
||||
#include "SimplePlayer.h"
|
||||
#include "Exporter.h"
|
||||
#include "CommonLogger.h"
|
||||
#include "SDMountManager.h"
|
||||
#include "HeapManager.h"
|
||||
#include "common_Types.h"
|
||||
#include "VersionDetect.h"
|
||||
#include "Util.h"
|
||||
#include "ResFont.h"
|
||||
#include "HardwareStateManager.h"
|
||||
#include "OperationMessage.h"
|
||||
|
||||
// バージョン表示用
|
||||
#include "version.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// グラフィックスに割り当てるメモリ
|
||||
const size_t s_GxHeapSize = 0x800000;
|
||||
|
||||
common::Util s_HwUtility;
|
||||
|
||||
} // namespace <unnamed>
|
||||
|
||||
extern "C" void nninitSetupDaemons(void)
|
||||
{
|
||||
}
|
||||
|
||||
namespace ConsoleBackup{
|
||||
|
||||
|
||||
extern "C" void nnMain(void)
|
||||
{
|
||||
nn::Result result;
|
||||
|
||||
// os の初期化
|
||||
nn::os::Initialize();
|
||||
|
||||
// fs の初期化
|
||||
nn::fs::Initialize();
|
||||
|
||||
// appletの初期化
|
||||
nn::applet::Enable( false );
|
||||
|
||||
// hid の初期化
|
||||
result = nn::hid::Initialize();
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
|
||||
// ndmの初期化
|
||||
result = nn::ndm::Initialize();
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
|
||||
// 全デーモンの自律動作をacの自動接続も含めて止める
|
||||
result = nn::ndm::SuspendScheduler();
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
|
||||
// cfg の初期化
|
||||
nn::cfg::CTR::init::Initialize();
|
||||
nn::cfg::CTR::system::Initialize();
|
||||
|
||||
// 時計設定用ptm初期化
|
||||
nn::ptm::CTR::InitializeForSystemMenu();
|
||||
|
||||
// ps の初期化
|
||||
nn::ps::Initialize();
|
||||
|
||||
// amの初期化
|
||||
nn::am::InitializeForLocalImporter();
|
||||
|
||||
// ヒープの確保
|
||||
common::InitializeHeap();
|
||||
|
||||
// RenderSystem の準備
|
||||
common::HeapManager gxHeapManager(s_GxHeapSize);
|
||||
uptr heapForGx = reinterpret_cast<uptr>(gxHeapManager.GetAddr());
|
||||
demo::RenderSystemDrawing renderSystem;
|
||||
renderSystem.Initialize(heapForGx, s_GxHeapSize);
|
||||
|
||||
// ResFontの初期化
|
||||
common::InitializeResFont();
|
||||
|
||||
// サウンドスレッドの起動
|
||||
common::InitializeSimplePlayer();
|
||||
|
||||
// ログ描画の初期化
|
||||
common::Logger::GetLoggerInstance()->Initialize(common::CONSOLE_WIDTH, common::CONSOLE_HEIGHT,
|
||||
common::CONSOLE_MAX_LINE, &renderSystem);
|
||||
|
||||
// RenderSystemを作ってからログが出せる
|
||||
common::Logger::InitializeEjectThread();
|
||||
common::Logger::SetEjectHandler(OnSdEjected);
|
||||
common::Logger::SetInsertHandler(OnSdInserted);
|
||||
// 起動時に削除
|
||||
common::Logger::GetLoggerInstance()->ClearSdLog();
|
||||
|
||||
COMMON_LOGGER("\n");
|
||||
COMMON_LOGGER("CTR Console Backup start\n");
|
||||
|
||||
// ボタン入力
|
||||
nn::hid::PadReader s_PadReader;
|
||||
nn::hid::PadStatus padStatus;
|
||||
|
||||
// データの準備
|
||||
s_HwUtility.InitializeForBackup();
|
||||
common::HardwareStateManager manager(s_HwUtility);
|
||||
|
||||
// 無線OFF
|
||||
s_HwUtility.SetWifiOff();
|
||||
|
||||
// 情報出力
|
||||
COMMON_LOGGER("CTR Console Backup %s-%s-%s\n", CONSOLE_REPAIR_VERSION_MAJOR, CONSOLE_REPAIR_VERSION_MINOR, CONSOLE_REPAIR_VERSION_MICRO);
|
||||
COMMON_LOGGER("System Ver. %d.%d.%d-%d\n",
|
||||
s_HwUtility.GetCupMajorVersion(),
|
||||
s_HwUtility.GetCupMinorVersion(),
|
||||
s_HwUtility.GetCupMicroVersion(),
|
||||
s_HwUtility.GetNupVersion());
|
||||
COMMON_LOGGER("System Region %s\n", s_HwUtility.GetRegionCodeA3());
|
||||
COMMON_LOGGER("Serial Number %s\n", s_HwUtility.GetSerialNumber());
|
||||
COMMON_LOGGER("Device ID %llu\n", s_HwUtility.GetInfraDeviceId());
|
||||
COMMON_LOGGER("MAC Address %s\n", s_HwUtility.GetMacAddress());
|
||||
|
||||
bool flip = false;
|
||||
bool continueBackup = false;
|
||||
bool forceDelete = false;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
bool nextStep = false;
|
||||
s_PadReader.ReadLatest(&padStatus);
|
||||
|
||||
// AまたはSTARTボタンで進行
|
||||
if(padStatus.trigger & nn::hid::BUTTON_A ||
|
||||
padStatus.trigger & nn::hid::BUTTON_START)
|
||||
{
|
||||
nextStep = true;
|
||||
if(padStatus.hold & nn::hid::BUTTON_LEFT)
|
||||
{
|
||||
forceDelete = true;
|
||||
}
|
||||
}
|
||||
|
||||
// LまたはRボタンで上下画面フリップ
|
||||
if(padStatus.trigger & nn::hid::BUTTON_R ||
|
||||
padStatus.trigger & nn::hid::BUTTON_L)
|
||||
{
|
||||
flip = !flip;
|
||||
}
|
||||
|
||||
// コンソールスクロール
|
||||
if(padStatus.hold & nn::hid::BUTTON_UP)
|
||||
{
|
||||
common::Logger::GetLoggerInstance()->ScrollUp();
|
||||
}
|
||||
|
||||
// コンソールスクロール
|
||||
if(padStatus.hold & nn::hid::BUTTON_DOWN)
|
||||
{
|
||||
common::Logger::GetLoggerInstance()->ScrollDown();
|
||||
}
|
||||
|
||||
// 情報更新
|
||||
// ACアダプタ
|
||||
std::string adapterState;
|
||||
if(manager.IsAdapterConnected())
|
||||
{
|
||||
adapterState += ::std::string("Connected");
|
||||
}
|
||||
else
|
||||
{
|
||||
adapterState += ::std::string("Not Connected");
|
||||
}
|
||||
|
||||
// 操作用メッセージ
|
||||
// 進捗確認メッセージを兼ねる?
|
||||
common::OperationMessage operationMessage;
|
||||
|
||||
ControlState(manager, operationMessage, nextStep, continueBackup, forceDelete);
|
||||
|
||||
nn::util::FloatColor titleColor;
|
||||
|
||||
titleColor.r = 0.3f;
|
||||
titleColor.g = 0.f;
|
||||
titleColor.b = 0.2f;
|
||||
|
||||
// 上画面表示
|
||||
common::DrawSystemState("CTR Console Backup",
|
||||
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(),
|
||||
IsBackupFailed(),
|
||||
IsBackupSucceeded(),
|
||||
IsBackupWarning(),
|
||||
s_HwUtility.GetMacAddress(),
|
||||
operationMessage,
|
||||
s_HwUtility.GetRegion(),
|
||||
s_HwUtility.GetSerialNumber(),
|
||||
s_HwUtility.HasReadFriendCode(),
|
||||
s_HwUtility.IsWifiOn()
|
||||
);
|
||||
|
||||
if (GetBackupMode() == BACKUP_MODE_DELETE_IF_FAILED)
|
||||
{
|
||||
const u8 spaceSize = 10;
|
||||
const u8 lineBottom = 23;
|
||||
const u32 screenWidth = 400;
|
||||
|
||||
renderSystem.SetColor(1.f, 1.f, 1.f);
|
||||
renderSystem.DrawText(0, lineBottom * spaceSize, "Delete Error File Mode");
|
||||
|
||||
renderSystem.SetColor(titleColor.r, titleColor.g, titleColor.b);
|
||||
renderSystem.FillRectangle(0, lineBottom * spaceSize, screenWidth, spaceSize);
|
||||
renderSystem.SetColor(1.f, 1.f, 1.f);
|
||||
}
|
||||
|
||||
renderSystem.SwapBuffers();
|
||||
|
||||
// デフォルトで下画面に描画するもの
|
||||
renderSystem.SetRenderTarget(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
|
||||
if(IsBackupSucceeded())
|
||||
{
|
||||
renderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), SUCCESS_COLOR);
|
||||
}
|
||||
if(IsBackupWarning())
|
||||
{
|
||||
renderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), WARN_COLOR);
|
||||
}
|
||||
else if(IsBackupFailed())
|
||||
{
|
||||
renderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), FAIL_COLOR);
|
||||
}
|
||||
renderSystem.Clear();
|
||||
renderSystem.SetColor(1.f, 1.f, 1.f);
|
||||
|
||||
common::Logger::GetLoggerInstance()->DrawConsole();
|
||||
renderSystem.SwapBuffers();
|
||||
|
||||
|
||||
renderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
|
||||
|
||||
// 電源長押しで終了
|
||||
if ( nn::applet::IsExpectedToCloseApplication())
|
||||
{
|
||||
common::Logger::GetLoggerInstance()->Finalize();
|
||||
// アンマウント
|
||||
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
|
||||
nn::fs::Unmount(common::SDMC_ARCHIVE_NAME);
|
||||
renderSystem.Finalize();
|
||||
|
||||
nn::ps::Finalize();
|
||||
nn::ptm::CTR::FinalizeForSystemMenu();
|
||||
nn::cfg::CTR::system::Finalize();
|
||||
nn::cfg::CTR::init::Finalize();
|
||||
nn::hid::Finalize();
|
||||
nn::fs::Finalize();
|
||||
|
||||
nn::applet::PrepareToCloseApplication();
|
||||
nn::applet::CloseApplication();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
BasicInfo:
|
||||
Title : ConsoleBackup
|
||||
ProductCode: CTR-P-22TA
|
||||
BackupMemoryType: None
|
||||
|
||||
TitleInfo:
|
||||
Use: Evaluation
|
||||
Category: Application
|
||||
UniqueId: 0xf8021
|
||||
Version: 0
|
||||
|
||||
SystemControlInfo:
|
||||
AppType : Application
|
||||
StackSize : 0x4000
|
||||
Dependency :
|
||||
- codec
|
||||
- hid
|
||||
- gsp
|
||||
- nwm
|
||||
|
||||
AccessControlInfo:
|
||||
Priority : 16
|
||||
DisableDebug : true
|
||||
|
||||
FileSystemAccess:
|
||||
- DirectSdmc
|
||||
- Core
|
||||
- CategoryFileSystemTool
|
||||
- ExportImportIvs
|
||||
|
||||
IoAccessControl:
|
||||
- FsMountNand
|
||||
- FsMountTwln
|
||||
|
||||
Option:
|
||||
FreeProductCode: true
|
||||
|
||||
CardInfo:
|
||||
CardDevice: None
|
||||
|
||||
Rom:
|
||||
# ROM に含めるファイルシステムのルートパスを指定します。
|
||||
HostRoot: "$(ROMFS_ROOT)"
|
||||
@ -1,516 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: Controller.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 "Controller.h"
|
||||
#include "FileChecker.h"
|
||||
#include "Exporter.h"
|
||||
#include "SimplePlayer.h"
|
||||
#include "CommonLogger.h"
|
||||
#include "Checker.h"
|
||||
#include "FileTransfer.h"
|
||||
|
||||
#include <nn.h>
|
||||
|
||||
namespace ConsoleBackup
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
typedef enum BackupState
|
||||
{
|
||||
STARTUP, // 初期値
|
||||
CHECK_SAVEDATA, // セーブデータの確認
|
||||
EXPORT_TWL_NAND, // TWLセーブデータ領域の吸出し中
|
||||
EXPORT_TWL_SOUND, // TWLサウンド領域の吸出し中
|
||||
EXPORT_TWL_PHOTO, // TWL写真領域の吸出し中
|
||||
EXPORT_CTR_NAND, // 吸出し中
|
||||
DELETE_NIM, // nimのシステムセーブデータ削除
|
||||
DONE, // 吸出し完了
|
||||
FINISHED, // SDカード抜き完了
|
||||
FAIL, // 失敗
|
||||
FAIL_CHECK, // セーブデータのチェック時エラー
|
||||
|
||||
STATE_MAX
|
||||
} BackupState;
|
||||
|
||||
|
||||
// Backupモード管理
|
||||
BackupMode s_BackupMode = BACKUP_MODE_CHECK;
|
||||
|
||||
// APSettingの書式が無い警告サウンドを鳴らしたかどうか
|
||||
bool s_ExistAPSettingAnnotation = false;
|
||||
// SDに書き込みできない警告サウンドを鳴らしたかどうか
|
||||
bool s_SdWriteProetctAnnotation = false;
|
||||
|
||||
BackupState s_BackupState = STARTUP;
|
||||
bool s_PlayedStartCursor = false;
|
||||
bool s_PlayedSdPullOutCursor = false;
|
||||
bool s_PlayedFinishedSound = false;
|
||||
bool s_PlayedFailSound = false;
|
||||
|
||||
} // namespace <unnamed>
|
||||
|
||||
void PutAliveMessage(common::OperationMessage& operationMessage, const char* str)
|
||||
{
|
||||
std::string message = std::string(str);
|
||||
static u8 i = 0;
|
||||
if (i < 0xff / 4)
|
||||
{
|
||||
operationMessage.Add((message + std::string(" /")).c_str());
|
||||
}
|
||||
else if (i < 0xff * 2 / 4)
|
||||
{
|
||||
operationMessage.Add((message + std::string(" |")).c_str());
|
||||
}
|
||||
else if (i < 0xff * 3 / 4)
|
||||
{
|
||||
operationMessage.Add((message + std::string(" \\")).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
operationMessage.Add((message + std::string(" -")).c_str());
|
||||
}
|
||||
i += 4;
|
||||
}
|
||||
|
||||
bool NeedsAcAdapter(common::HardwareStateManager& manager)
|
||||
{
|
||||
return manager.IsBatteryLower() && !manager.IsAdapterConnected();
|
||||
}
|
||||
|
||||
void ControlState(common::HardwareStateManager& manager, common::OperationMessage& operationMessage, bool& nextStep,
|
||||
bool& continueBackup, bool forceDelete)
|
||||
{
|
||||
// 状態遷移Controller
|
||||
switch (s_BackupState)
|
||||
{
|
||||
|
||||
// 起動時
|
||||
case STARTUP:
|
||||
{
|
||||
bool error = false;
|
||||
// 完全性検証SEEDを読めるか?
|
||||
if (manager.CanReadIvs())
|
||||
{
|
||||
// SDカードが挿入されているか?
|
||||
if (nn::fs::IsSdmcInserted())
|
||||
{
|
||||
// SDカードに書き込みできるか?
|
||||
if (!nn::fs::IsSdmcWritable())
|
||||
{
|
||||
if (!s_SdWriteProetctAnnotation)
|
||||
{
|
||||
s_SdWriteProetctAnnotation = true;
|
||||
common::PlaySound(common::SOUND_ANNOTATION);
|
||||
}
|
||||
operationMessage.Add("Can*t Write SD Card!!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// 無線設定ファイルがあるか?
|
||||
if (common::ExistsAPSetting())
|
||||
{
|
||||
// 書き込み中に抜かないように
|
||||
if (nextStep)
|
||||
{
|
||||
// シリアルナンバーを読み取れるか?
|
||||
if (!manager.CanReadSerialNumber())
|
||||
{
|
||||
common::PlaySound(common::SOUND_ANNOTATION);
|
||||
COMMON_LOGGER("Can't Read Serial Number\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = true;
|
||||
if (!s_ExistAPSettingAnnotation)
|
||||
{
|
||||
s_ExistAPSettingAnnotation = true;
|
||||
common::PlaySound(common::SOUND_ANNOTATION);
|
||||
}
|
||||
operationMessage.Add("Accsess_Point_Setting does not exist!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = true;
|
||||
operationMessage.Add("Insert SD Card!!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = true;
|
||||
operationMessage.Add("Can't Read SDCI!!");
|
||||
}
|
||||
|
||||
// ACアダプタが必要か?
|
||||
if (NeedsAcAdapter(manager))
|
||||
{
|
||||
error = true;
|
||||
operationMessage.Add("Connect AC Adapter!!");
|
||||
}
|
||||
|
||||
// エラーが無ければ進行用メッセージ表示
|
||||
if (!error)
|
||||
{
|
||||
operationMessage.Add("Push A or START Button");
|
||||
if (!s_PlayedStartCursor)
|
||||
{
|
||||
common::PlaySound(common::SOUND_CURSOR);
|
||||
s_PlayedStartCursor = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextStep && !error)
|
||||
{
|
||||
COMMON_LOGGER("Checking SaveData\n");
|
||||
|
||||
if(forceDelete)
|
||||
{
|
||||
s_BackupMode = BACKUP_MODE_DELETE_IF_FAILED;
|
||||
}
|
||||
s_BackupState = CHECK_SAVEDATA;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CHECK_SAVEDATA:
|
||||
{
|
||||
static bool init = true;
|
||||
if (init)
|
||||
{
|
||||
StartSaveDataCheck(s_BackupMode == BACKUP_MODE_DELETE_IF_FAILED);
|
||||
init = false;
|
||||
}
|
||||
|
||||
PutAliveMessage(operationMessage, "Checking SaveData");
|
||||
|
||||
if (IsCheckSaveDataFinished())
|
||||
{
|
||||
FinalizeSaveDataCheck();
|
||||
// 削除モードでなければエラーにする
|
||||
if (CheckSaveDataErrorOccured() && !forceDelete)
|
||||
{
|
||||
s_BackupState = FAIL_CHECK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckSaveDataSucceeded())
|
||||
{
|
||||
COMMON_LOGGER("Start Export Data\n");
|
||||
|
||||
s_BackupState = EXPORT_TWL_NAND;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// TWLセーブデータ領域の吸出し中
|
||||
case EXPORT_TWL_NAND:
|
||||
{
|
||||
static bool init = true;
|
||||
if (init)
|
||||
{
|
||||
// コンテキストを初期化する
|
||||
InitializeFileListContext();
|
||||
|
||||
// データを書き込む
|
||||
if (ExportTwlSaveData().IsFailure())
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
break;
|
||||
}
|
||||
init = false;
|
||||
}
|
||||
|
||||
PutAliveMessage(operationMessage, "Exporting TWL SaveData");
|
||||
|
||||
// 処理が完了した
|
||||
if (IsExportThreadFinished())
|
||||
{
|
||||
FinalizeExportThread();
|
||||
if (IsExportSucceeded())
|
||||
{
|
||||
s_BackupState = EXPORT_TWL_SOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// TWLサウンド領域の吸出し中
|
||||
case EXPORT_TWL_SOUND:
|
||||
{
|
||||
static bool init = true;
|
||||
if (init)
|
||||
{
|
||||
// データを書き込む
|
||||
ExportTwlSoundData();
|
||||
init = false;
|
||||
}
|
||||
|
||||
PutAliveMessage(operationMessage, "Exporting TWL Sound Data");
|
||||
|
||||
// 処理が完了した
|
||||
if (IsExportThreadFinished())
|
||||
{
|
||||
FinalizeExportThread();
|
||||
if (IsExportSucceeded())
|
||||
{
|
||||
s_BackupState = EXPORT_TWL_PHOTO;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// TWL写真領域の吸出し中
|
||||
case EXPORT_TWL_PHOTO:
|
||||
{
|
||||
static bool init = true;
|
||||
if (init)
|
||||
{
|
||||
// データを書き込む
|
||||
ExportTwlPhotoData();
|
||||
init = false;
|
||||
}
|
||||
|
||||
PutAliveMessage(operationMessage, "Exporting TWL Photo Data");
|
||||
|
||||
// 処理が完了した
|
||||
if (IsExportThreadFinished())
|
||||
{
|
||||
FinalizeExportThread();
|
||||
if (IsExportSucceeded())
|
||||
{
|
||||
s_BackupState = EXPORT_CTR_NAND;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// 吸出し中
|
||||
case EXPORT_CTR_NAND:
|
||||
{
|
||||
continueBackup = true;
|
||||
|
||||
// ACアダプタが必要か?
|
||||
if (NeedsAcAdapter(manager))
|
||||
{
|
||||
continueBackup = false;
|
||||
operationMessage.Add("Connect AC Adapter!!");
|
||||
}
|
||||
|
||||
PutAliveMessage(operationMessage, "Exporting Nand Data");
|
||||
|
||||
// データを書き込む
|
||||
if (!ExportData(manager))
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 処理が完了した
|
||||
if (continueBackup && IsExportThreadFinished())
|
||||
{
|
||||
FinalizeExportThread();
|
||||
if (IsExportSucceeded())
|
||||
{
|
||||
COMMON_LOGGER("Export NAND Data Finished.\n");
|
||||
|
||||
if (GetExportProgress() > 99)
|
||||
{
|
||||
s_BackupState = DELETE_NIM;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// nimのシステムセーブデータ削除
|
||||
case DELETE_NIM:
|
||||
{
|
||||
if (DeleteNimSaveData())
|
||||
{
|
||||
s_BackupState = DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_BackupState = FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
// 吸出し完了
|
||||
case DONE:
|
||||
{
|
||||
operationMessage.Add("Backup Done. Pull Out SD Card.");
|
||||
|
||||
static bool init = true;
|
||||
if(init)
|
||||
{
|
||||
manager.SetWifiOff();
|
||||
init = false;
|
||||
}
|
||||
|
||||
if (!s_PlayedSdPullOutCursor)
|
||||
{
|
||||
common::PlaySound(common::SOUND_CURSOR);
|
||||
s_PlayedSdPullOutCursor = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// SDカード抜き完了
|
||||
case FINISHED:
|
||||
{
|
||||
operationMessage.Add("Backup Succeeded!!\n");
|
||||
if (!s_PlayedFinishedSound)
|
||||
{
|
||||
common::PlaySound(common::SOUND_OK);
|
||||
s_PlayedFinishedSound = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// 吸出し失敗
|
||||
case FAIL:
|
||||
{
|
||||
operationMessage.Add("Backup Failed.");
|
||||
if (!s_PlayedFailSound)
|
||||
{
|
||||
common::PlaySound(common::SOUND_NG);
|
||||
s_PlayedFailSound = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FAIL_CHECK:
|
||||
{
|
||||
operationMessage.Add("Check Error.");
|
||||
if (!s_PlayedFailSound)
|
||||
{
|
||||
common::PlaySound(common::SOUND_NG);
|
||||
s_PlayedFailSound = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetProgress()
|
||||
{
|
||||
if(s_BackupState == CHECK_SAVEDATA)
|
||||
{
|
||||
return GetCheckSaveDataProgress();
|
||||
}
|
||||
else if (s_BackupState == EXPORT_TWL_NAND || s_BackupState == EXPORT_TWL_PHOTO|| s_BackupState == EXPORT_TWL_SOUND)
|
||||
{
|
||||
return common::GetProgress();
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetExportProgress();
|
||||
}
|
||||
}
|
||||
|
||||
// バックアップモードを取得する
|
||||
BackupMode GetBackupMode()
|
||||
{
|
||||
return s_BackupMode;
|
||||
}
|
||||
|
||||
bool InProgress()
|
||||
{
|
||||
return s_BackupState == EXPORT_CTR_NAND;
|
||||
}
|
||||
|
||||
bool IsBackupSucceeded()
|
||||
{
|
||||
return s_BackupState == FINISHED;
|
||||
}
|
||||
|
||||
bool IsBackupFailed()
|
||||
{
|
||||
return s_BackupState == FAIL;
|
||||
}
|
||||
|
||||
bool IsBackupWarning()
|
||||
{
|
||||
return s_BackupState == FAIL_CHECK;
|
||||
}
|
||||
|
||||
void OnSdEjected()
|
||||
{
|
||||
if(s_BackupState == DONE || s_BackupState == FINISHED)
|
||||
{
|
||||
s_BackupState = FINISHED;
|
||||
}
|
||||
else if(s_BackupState != FAIL && s_BackupState != FAIL_CHECK)
|
||||
{
|
||||
common::InitializeFileCheck();
|
||||
InitializeState();
|
||||
}
|
||||
}
|
||||
|
||||
void OnSdInserted()
|
||||
{
|
||||
common::Logger::GetLoggerInstance()->ClearSdLog();
|
||||
}
|
||||
|
||||
void InitializeState()
|
||||
{
|
||||
s_BackupState = STARTUP;
|
||||
s_PlayedFailSound = false;
|
||||
s_PlayedFinishedSound = false;
|
||||
s_ExistAPSettingAnnotation = false;
|
||||
s_PlayedStartCursor = false;
|
||||
s_PlayedSdPullOutCursor = false;
|
||||
s_SdWriteProetctAnnotation = false;
|
||||
}
|
||||
|
||||
} // namespace ConsoleBackup
|
||||
@ -1,72 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: Contoroller.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 CONTOROLLER_H_
|
||||
#define CONTOROLLER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "HardwareStateManager.h"
|
||||
#include "OperationMessage.h"
|
||||
|
||||
namespace ConsoleBackup
|
||||
{
|
||||
|
||||
typedef enum BackupMode
|
||||
{
|
||||
BACKUP_MODE_CHECK, // セーブデータのチェック後エラーが無ければ吸出し
|
||||
BACKUP_MODE_DELETE_IF_FAILED // 読み取りエラーのセーブデータを削除後吸出し
|
||||
|
||||
} BackupMode;
|
||||
|
||||
//! @brief 状態遷移を管理する
|
||||
//! @param[in] manager ハードウェア情報を取得するためのラッパ
|
||||
//! @param[in] operationMessage 操作情報として表示したい文字列
|
||||
//! @param[in] nextStep 次の状態に遷移してもよいかどうか
|
||||
//! @param[in] continueBackup 処理を続けてもよいかどうか
|
||||
//! @param[in] forceDelete チェックエラー発生時に削除を実行してもよいかどうか
|
||||
void ControlState(common::HardwareStateManager& manager, common::OperationMessage& operationMessage, bool& nextStep,
|
||||
bool& continueBackup, bool forceDelete);
|
||||
|
||||
// バックアップ処理中かどうか
|
||||
bool InProgress();
|
||||
|
||||
// バックアップが完了したかどうか
|
||||
bool IsBackupSucceeded();
|
||||
|
||||
// バックアップが失敗したかどうか
|
||||
bool IsBackupFailed();
|
||||
|
||||
// バックアップ時に警告があったかどうか
|
||||
bool IsBackupWarning();
|
||||
|
||||
// SDカードが抜き出されたときに実行したい関数
|
||||
void OnSdEjected();
|
||||
|
||||
// SDカードが挿し込まれたときに実行する処理
|
||||
void OnSdInserted();
|
||||
|
||||
// 状態を初期化する
|
||||
void InitializeState();
|
||||
|
||||
// 進捗を取得する
|
||||
u32 GetProgress();
|
||||
|
||||
// バックアップモードを取得する
|
||||
BackupMode GetBackupMode();
|
||||
|
||||
}
|
||||
|
||||
#endif /* CONTOROLLER_H_ */
|
||||
@ -1,985 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: Exporter.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 <vector>
|
||||
#include <cstdlib>
|
||||
#include <cwchar>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <nn/nstd.h>
|
||||
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
|
||||
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
|
||||
#include <nn/fs/fs_ApiDeviceMove.h>
|
||||
#include <nn/cfg/CTR/cfg_Api.h>
|
||||
#include <nn/cfg/CTR/cfg_ApiNor.h> // cfg:norの初期化に必要
|
||||
#include <nn/cfg/CTR/cfg_NtrSettings.h>
|
||||
#include <nn/ps/CTR/ps_API.h>
|
||||
#include <nn/drivers/aes/CTR/ARM946ES/driverAes_Types.h>
|
||||
#include <nn/crypto/crypto_AesCmac.h>
|
||||
#include <nn/crypto/crypto_SwAesCtrContext.h>
|
||||
#include <nn/crypto/crypto_Sha256.h>
|
||||
#include <nn/crypto/crypto_SwAesCmac.h>
|
||||
#include <nn/mcu.h>
|
||||
#include <nn/am.h>
|
||||
#include <nn/pl/CTR/pl_PlayHistoryApi.h>
|
||||
#include <nn/pl/CTR/pl_PlayHistoryApiSysmenu.h>
|
||||
#include <nn/nim.h>
|
||||
|
||||
#include "Exporter.h"
|
||||
#include "CommonLogger.h"
|
||||
#include "SDMountManager.h"
|
||||
#include "HeapManager.h"
|
||||
#include "SdReaderWriter.h"
|
||||
#include "FileName.h"
|
||||
#include "FileTransfer.h"
|
||||
#include "common_Types.h"
|
||||
#include "Aes_define.h"
|
||||
#include "VersionDetect.h"
|
||||
#include "Util.h"
|
||||
#include "SaveDataMover.h"
|
||||
|
||||
namespace ConsoleBackup
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
common::NtrNorData s_NtrNorData;
|
||||
common::CfgCountryLanguage s_CountryLanguage;
|
||||
|
||||
const size_t EXPORT_THREAD_STACK_SIZE = 0x4000;
|
||||
nn::os::Thread s_ExportThread;
|
||||
nn::os::StackBuffer<EXPORT_THREAD_STACK_SIZE> s_ExportThreadStack;
|
||||
bool s_IsExportSucceeded;
|
||||
|
||||
wchar_t s_RootName[256];
|
||||
|
||||
nn::crypto::Sha256Context s_FileListContext;
|
||||
|
||||
u64 s_ExportProgress = 0;
|
||||
|
||||
}
|
||||
|
||||
bool AddCmac(nn::fs::FileOutputStream* file, nn::crypto::Sha256Context* context);
|
||||
|
||||
nn::Result DeleteTrash(std::wstring currentDirectory)
|
||||
{
|
||||
// TODO: リードオンリーのファイルが消去できない
|
||||
|
||||
COMMON_LOGGER("Delete Trash.\n");
|
||||
|
||||
nn::fs::FileInputStream fis;
|
||||
nn::fs::Directory dir;
|
||||
nn::Result result;
|
||||
std::vector<nn::fs::DirectoryEntry> entryList; //カレントディレクトリのエントリ一覧を格納
|
||||
std::vector<nn::fs::DirectoryEntry>::iterator entryIndex;
|
||||
|
||||
result = common::SdMountManager::Mount();
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
result = dir.TryInitialize(currentDirectory.c_str());
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
nn::fs::DirectoryEntry entry;
|
||||
s32 numEntry;
|
||||
for (;;)
|
||||
{
|
||||
result = dir.TryRead(&numEntry, &entry, 1);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
if (numEntry == 0)
|
||||
{
|
||||
// ルートディレクトリを閉じる
|
||||
dir.Finalize();
|
||||
|
||||
// ルートディレクトリの子を開く
|
||||
for (entryIndex = entryList.begin(); entryIndex != entryList.end(); entryIndex++)
|
||||
{
|
||||
// ディレクトリなら削除する
|
||||
if (entryIndex->attributes.isDirectory)
|
||||
{
|
||||
NN_LOG("Try Delete %ls%ls/\n", currentDirectory.c_str(), entryIndex->entryName);
|
||||
result = nn::fs::TryDeleteDirectoryRecursively(
|
||||
(currentDirectory + ::std::wstring(entryIndex->entryName)).c_str());
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
}
|
||||
// ファイルならログとAP設定以外は削除する
|
||||
else
|
||||
{
|
||||
if (std::wcscmp(entryIndex->entryName, common::AP_SETTING_FILENAME) != 0
|
||||
&& std::wcscmp(entryIndex->entryName, common::LOG_FILENAME) != 0)
|
||||
{
|
||||
NN_LOG("Try Delete %ls%ls\n", currentDirectory.c_str(), entryIndex->entryName);
|
||||
result = nn::fs::TryDeleteFile(
|
||||
(currentDirectory + ::std::wstring(entryIndex->entryName)).c_str());
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 削除完了
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// vectorに保存する
|
||||
entryList.push_back(entry);
|
||||
if (entry.attributes.isDirectory)
|
||||
{
|
||||
NN_LOG("%ls%ls/\n", currentDirectory.c_str(), entry.entryName);
|
||||
}
|
||||
else
|
||||
{
|
||||
NN_LOG("%ls%ls\n", currentDirectory.c_str(), entry.entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = common::SdMountManager::Unmount();
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
nn::Result WriteTwlTitleList(std::vector<std::wstring>& programIdList)
|
||||
{
|
||||
nn::Result result;
|
||||
COMMON_LOGGER("Export TwlTitle List.\n");
|
||||
|
||||
size_t heapSize = common::GetAllocatableSize();
|
||||
if(heapSize > common::FILE_COPY_HEAP_SIZE)
|
||||
{
|
||||
heapSize = common::FILE_COPY_HEAP_SIZE;
|
||||
}
|
||||
|
||||
common::HeapManager manager(heapSize);
|
||||
char* titleListBuf = reinterpret_cast<char*> (manager.GetAddr());
|
||||
|
||||
size_t writeSize = 0;
|
||||
if (titleListBuf != NULL)
|
||||
{
|
||||
for (std::vector<std::wstring>::iterator it = programIdList.begin(); it != programIdList.end(); it++)
|
||||
{
|
||||
nn::nstd::TSNPrintf(titleListBuf + writeSize, heapSize - writeSize, "%s\n", common::GetCharStr(it->c_str()));
|
||||
NN_LOG("%ls\n", it->c_str());
|
||||
writeSize += it->size() + sizeof('\n');
|
||||
}
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::TWL_TITLELIST_PATHNAME, titleListBuf, writeSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
||||
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nn::Result WriteRegionData()
|
||||
{
|
||||
COMMON_LOGGER("Export Region Data.\n");
|
||||
|
||||
nn::cfg::CTR::CfgRegionCode region;
|
||||
region = nn::cfg::CTR::GetRegion();
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::REGION_DATA_PATHNAME, ®ion, sizeof(nn::cfg::CTR::CfgRegionCode));
|
||||
}
|
||||
|
||||
nn::Result WriteCountryLanguageData()
|
||||
{
|
||||
COMMON_LOGGER("Export Country and Language Data.\n");
|
||||
|
||||
nn::Result result;
|
||||
|
||||
nn::cfg::nor::CTR::Initialize();
|
||||
|
||||
// 国設定
|
||||
s_CountryLanguage.country = nn::cfg::CTR::GetCountry();
|
||||
if (s_CountryLanguage.country != nn::cfg::CTR::CFG_COUNTRY_UNKNOWN)
|
||||
{
|
||||
// 言語設定
|
||||
s_CountryLanguage.language = nn::cfg::CTR::GetLanguage();
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::COUNTRY_SETTING_PATHNAME, &s_CountryLanguage, sizeof(s_CountryLanguage));
|
||||
}
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
nn::Result WriteNorData()
|
||||
{
|
||||
COMMON_LOGGER("Export NOR Data.\n");
|
||||
|
||||
nn::Result result;
|
||||
|
||||
nn::cfg::nor::CTR::Initialize();
|
||||
|
||||
NN_LOG("Get NTR User Setting\n");
|
||||
|
||||
// NTR設定
|
||||
result = nn::cfg::nor::CTR::GetNtrSetting(&s_NtrNorData.ntrConfig.ncd, &s_NtrNorData.ntrConfig.ncd_ex);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
// TWL WiFi設定
|
||||
result = nn::cfg::nor::CTR::ReadTwlWifiSetting(0, s_NtrNorData.TwlWiFiSetting, common::TWL_WIFI_SETTING_SIZE);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
// NTR WiFi設定
|
||||
result = nn::cfg::nor::CTR::ReadNtrWifiSetting(0, s_NtrNorData.NtrWiFiSetting, common::NTR_WIFI_SETTING_SIZE);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::NOR_PATHNAME, &s_NtrNorData, sizeof(common::NtrNorData));
|
||||
}
|
||||
|
||||
nn::Result WriteSerialNumber(common::HardwareStateManager& manager)
|
||||
{
|
||||
COMMON_LOGGER("Export Serial Number.\n");
|
||||
|
||||
u8* serial;
|
||||
size_t size;
|
||||
manager.GetSerialNumber(&serial, &size);
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::SERIAL_PATHNAME, serial, size);
|
||||
}
|
||||
|
||||
nn::Result WriteDeviceId(common::HardwareStateManager& manager)
|
||||
{
|
||||
COMMON_LOGGER("Export Device ID.\n");
|
||||
|
||||
bit32 deviceId = manager.GetDeviceId();
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::DEVICE_ID_PATHNAME, &deviceId, sizeof(deviceId));
|
||||
}
|
||||
|
||||
nn::Result WriteIvs(common::HardwareStateManager& manager)
|
||||
{
|
||||
COMMON_LOGGER("Export SDCI.\n");
|
||||
|
||||
void* ivs;
|
||||
size_t size;
|
||||
manager.GetIvs(&ivs, &size);
|
||||
|
||||
void* enc;
|
||||
nn::Result result;
|
||||
common::HeapManager ivsHeap(size);
|
||||
enc = ivsHeap.GetAddr();
|
||||
if(enc != NULL)
|
||||
{
|
||||
// AES暗号化する
|
||||
nn::crypto::SwAesCtrContext swAesCtrContest;
|
||||
|
||||
swAesCtrContest.Initialize(common::iv, common::key, sizeof(common::key));
|
||||
swAesCtrContest.Encrypt(enc, ivs, size);
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::IVS_PATHNAME, enc, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
||||
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
void CreateTwlDirectory(enum common::TWL_PATH_INDEX path)
|
||||
{
|
||||
NN_ASSERT(path < common::TWL_PATHNAME_MAX);
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
sdWriter.CreateDirectory((::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) +
|
||||
std::wstring(common::SD_TWL_ROOTNAME_TABLE[path])).c_str());
|
||||
}
|
||||
|
||||
bool ListTwlSaveData(std::wstring currentDirectory, std::vector<common::SavePathInfo>* list)
|
||||
{
|
||||
nn::fs::Directory dir;
|
||||
nn::fs::DirectoryEntry entry;
|
||||
s32 numEntry;
|
||||
|
||||
nn::Result result = dir.TryInitialize(currentDirectory.c_str());
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
result = dir.TryRead(&numEntry, &entry, 1);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
if (numEntry == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
common::SavePathInfo pathInfo;
|
||||
pathInfo.name = currentDirectory + std::wstring(L"/") + std::wstring(entry.entryName);
|
||||
pathInfo.isDirectory = false;
|
||||
list->push_back(pathInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddCurrentProgramIdPath(std::vector<std::wstring>* programIdList, std::wstring currentDir)
|
||||
{
|
||||
std::wstring currentPath(currentDir);
|
||||
std::wstring token(common::NAND_TWL_DATA_ROOT_PATHNAME_WITHOUT_SLASH);
|
||||
|
||||
std::wstring::size_type pos;
|
||||
pos = currentPath.find(token);
|
||||
if(pos != std::wstring::npos)
|
||||
{
|
||||
std::wstring subStr = currentPath.substr(token.size());
|
||||
|
||||
std::wstring slash(L"/");
|
||||
pos = subStr.find(slash);
|
||||
while(pos != std::wstring::npos)
|
||||
{
|
||||
subStr.erase(pos, slash.size());
|
||||
pos = subStr.find(slash);
|
||||
}
|
||||
|
||||
std::wstring ctrProgramIdHi(L"00048");
|
||||
subStr.replace(0, ctrProgramIdHi.size(), ctrProgramIdHi);
|
||||
|
||||
programIdList->push_back(subStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
NN_LOG("Can't find %ls\n", common::NAND_TWL_DATA_ROOT_PATHNAME_WITHOUT_SLASH);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AddCurrentDirectory(std::vector<common::SavePathInfo>* list, std::wstring currentDir, wchar_t* currentEntry)
|
||||
{
|
||||
common::SavePathInfo pathInfo;
|
||||
|
||||
pathInfo.name = currentDir + std::wstring(L"/") + std::wstring(currentEntry) + std::wstring(L"/");
|
||||
pathInfo.isDirectory = true;
|
||||
list->push_back(pathInfo);
|
||||
}
|
||||
|
||||
// TWLセーブデータが存在するディレクトリの一覧をlistに追加する
|
||||
// return: dataディレクトリが存在するかどうか
|
||||
bool ListTwlSaveDataDirectory(std::wstring currentDirectory, u32 level, std::vector<common::SavePathInfo>* list,
|
||||
std::vector<std::wstring>* programIdList)
|
||||
{
|
||||
nn::fs::FileInputStream fis;
|
||||
nn::fs::Directory dir;
|
||||
nn::Result result;
|
||||
std::vector<nn::fs::DirectoryEntry> entryList; //カレントディレクトリのエントリ一覧を格納
|
||||
std::vector<nn::fs::DirectoryEntry>::iterator entryIndex;
|
||||
|
||||
// level 0 1 2
|
||||
// twln:/title/00030005/484e4441/data/
|
||||
const u8 TWL_SAVEDATA_DIRECTORY_LEVEL = 2; // data ディレクトリまでの階層
|
||||
const wchar_t* const TWL_SAVEDATA_DIRECTORY_NAME = L"data";
|
||||
|
||||
result = dir.TryInitialize(currentDirectory.c_str());
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
nn::fs::DirectoryEntry entry;
|
||||
s32 numEntry;
|
||||
for (;;)
|
||||
{
|
||||
result = dir.TryRead(&numEntry, &entry, 1);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
if (numEntry == 0)
|
||||
{
|
||||
dir.Finalize();
|
||||
|
||||
bool hasDataDirectory = false;
|
||||
for (entryIndex = entryList.begin(); entryIndex != entryList.end(); entryIndex++)
|
||||
{
|
||||
// レベル2未満のディレクトリなら再帰的に開く
|
||||
if (level < TWL_SAVEDATA_DIRECTORY_LEVEL)
|
||||
{
|
||||
if (entryIndex->attributes.isDirectory)
|
||||
{
|
||||
if (!ListTwlSaveDataDirectory(
|
||||
currentDirectory + std::wstring(L"/") + std::wstring(entryIndex->entryName), level + 1,
|
||||
list, programIdList))
|
||||
{
|
||||
hasDataDirectory |= false;
|
||||
}
|
||||
else
|
||||
{
|
||||
NN_LOG("%ls/%ls has data directory.\n", currentDirectory.c_str(), entryIndex->entryName);
|
||||
AddCurrentDirectory(list, currentDirectory, entryIndex->entryName);
|
||||
hasDataDirectory |= true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// レベル2のディレクトリなら data かどうかチェック
|
||||
else if (level == TWL_SAVEDATA_DIRECTORY_LEVEL && entryIndex->attributes.isDirectory)
|
||||
{
|
||||
if (std::wcscmp(entryIndex->entryName, TWL_SAVEDATA_DIRECTORY_NAME) == 0)
|
||||
{
|
||||
// ファイル一覧を取得する
|
||||
if (!ListTwlSaveData(
|
||||
currentDirectory + std::wstring(L"/") + std::wstring(entryIndex->entryName), list))
|
||||
{
|
||||
hasDataDirectory |= false;
|
||||
}
|
||||
|
||||
NN_LOG("%ls/%ls has data directory.\n", currentDirectory.c_str(), entryIndex->entryName);
|
||||
AddCurrentDirectory(list, currentDirectory, entryIndex->entryName);
|
||||
AddCurrentProgramIdPath(programIdList, currentDirectory);
|
||||
hasDataDirectory |= true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return hasDataDirectory;
|
||||
}
|
||||
else
|
||||
{
|
||||
// vectorに保存する
|
||||
entryList.push_back(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WriteTwlData(enum common::TWL_PATH_INDEX path)
|
||||
{
|
||||
NN_ASSERT(path < common::TWL_PATHNAME_MAX);
|
||||
|
||||
nn::Result result;
|
||||
s_IsExportSucceeded = true;
|
||||
|
||||
result = nn::fs::MountSpecialArchive(common::TWL_ARCHIVE_NAME_TABLE[path], common::TWL_FS_ARCHIVE_KIND[path]);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
result = common::SdMountManager::Mount();
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
u32 fileNum = 0;
|
||||
s64 fileSize = 0;
|
||||
result = common::CalculateFileNum(::std::wstring(common::NAND_TWL_ROOT_PATHNAME_WITH_SLASH_TABLE[path]), fileNum, fileSize);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
NN_LOG("File Number = %d\n", fileNum);
|
||||
NN_LOG("File Size = %lld\n", fileSize);
|
||||
// 進捗表示用
|
||||
common::InitializeTransferProgress(fileSize);
|
||||
|
||||
size_t bufSize = common::GetAllocatableSize(AES_BLOCK_SIZE * 2);
|
||||
NN_LOG("AllocatableSize = %d\n", bufSize);
|
||||
if(bufSize > common::FILE_COPY_HEAP_SIZE)
|
||||
{
|
||||
bufSize = common::FILE_COPY_HEAP_SIZE;
|
||||
}
|
||||
|
||||
common::HeapManager writeHeap(bufSize, AES_BLOCK_SIZE * 2);
|
||||
void* buf = writeHeap.GetAddr();
|
||||
if (buf != NULL)
|
||||
{
|
||||
nn::fs::FileOutputStream list;
|
||||
result = list.TryInitialize(common::FILE_LIST_PATHNAME, true);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
result = list.TryGetSize(&fileSize);
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
// 末尾に移動
|
||||
result = list.TrySetPosition(fileSize);
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
wchar_t archiveName[nn::fs::MAX_FILE_PATH_LENGTH];
|
||||
::std::mbstowcs(archiveName, common::TWL_ARCHIVE_NAME_TABLE[path],
|
||||
std::strlen(common::TWL_ARCHIVE_NAME_TABLE[path]) + 1);
|
||||
std::wstring archiveString(archiveName);
|
||||
if (!common::CopyDirectory(
|
||||
NULL,
|
||||
(archiveString + ::std::wstring(L"/")).c_str(),
|
||||
(common::SDMC_ROOT_DIRECTORY_PATH + ::std::wstring(common::SD_TWL_ROOTNAME_TABLE[path])).c_str(),
|
||||
buf, bufSize, true, &list, &s_FileListContext))
|
||||
{
|
||||
s_IsExportSucceeded = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list.TryFlush();
|
||||
list.Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
common::SdMountManager::Unmount();
|
||||
nn::fs::Unmount(common::TWL_ARCHIVE_NAME_TABLE[path]);
|
||||
}
|
||||
|
||||
nn::Result CalculateTwlSaveData(std::vector<common::SavePathInfo>* fileList, s64* fileSize)
|
||||
{
|
||||
NN_NULL_ASSERT(fileList);
|
||||
NN_NULL_ASSERT(fileSize);
|
||||
|
||||
*fileSize = 0;
|
||||
nn::Result result = nn::ResultSuccess();
|
||||
|
||||
for (std::vector<common::SavePathInfo>::iterator it = fileList->begin(); it != fileList->end(); it++)
|
||||
{
|
||||
if(!it->isDirectory)
|
||||
{
|
||||
nn::fs::FileInputStream file;
|
||||
result = file.TryInitialize(it->name.c_str());
|
||||
if(result.IsSuccess())
|
||||
{
|
||||
s64 size;
|
||||
result = file.TryGetSize(&size);
|
||||
if(result.IsSuccess())
|
||||
{
|
||||
*fileSize += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
void WriteTwlSaveData()
|
||||
{
|
||||
nn::Result result;
|
||||
s_IsExportSucceeded = true;
|
||||
std::vector<common::SavePathInfo> fileList;
|
||||
std::vector<std::wstring> programIdList;
|
||||
|
||||
COMMON_LOGGER("Export Twl Save Data.\n");
|
||||
|
||||
// ディレクトリ作成
|
||||
common::SdReaderWriter sdWriter;
|
||||
result = sdWriter.CreateDirectory((::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) +
|
||||
std::wstring(common::SD_SAVEDATA_TWL_ROOT_NAME)).c_str());
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
// セーブデータを含むディレクトリ一覧を生成
|
||||
result = nn::fs::MountSpecialArchive(common::NAND_TWL_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_TWL_NAND);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
if(!ListTwlSaveDataDirectory(std::wstring(common::NAND_TWL_DATA_ROOT_PATHNAME_WITHOUT_SLASH), 0, &fileList, & programIdList))
|
||||
{
|
||||
NN_LOG("No Twl Savedata\n");
|
||||
s_IsExportSucceeded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
NN_LOG("listup Twl Savedata Directory\n");
|
||||
for (std::vector<common::SavePathInfo>::reverse_iterator it = fileList.rbegin(); it != fileList.rend(); it++)
|
||||
{
|
||||
NN_LOG("%ls\n", it->name.c_str());
|
||||
}
|
||||
|
||||
result = WriteTwlTitleList(programIdList);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
// 合計サイズ取得
|
||||
s64 fileSize;
|
||||
result = CalculateTwlSaveData(&fileList, &fileSize);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
common::InitializeTransferProgress(fileSize);
|
||||
|
||||
NN_LOG("\n");
|
||||
// SDに書き出し
|
||||
result = common::SdMountManager::Mount();
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
size_t bufSize = common::GetAllocatableSize(AES_BLOCK_SIZE * 2);
|
||||
NN_LOG("AllocatableSize = %d\n", bufSize);
|
||||
if(bufSize > common::FILE_COPY_HEAP_SIZE)
|
||||
{
|
||||
bufSize = common::FILE_COPY_HEAP_SIZE;
|
||||
}
|
||||
|
||||
common::HeapManager writeHeap(bufSize, AES_BLOCK_SIZE * 2);
|
||||
void* buf = writeHeap.GetAddr();
|
||||
if (buf != NULL)
|
||||
{
|
||||
nn::fs::FileOutputStream list;
|
||||
result = list.TryInitialize(common::FILE_LIST_PATHNAME, true);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
result = list.TryGetSize(&fileSize);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
// 末尾に移動
|
||||
result = list.TrySetPosition(fileSize);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
|
||||
wchar_t archiveName[nn::fs::MAX_FILE_PATH_LENGTH];
|
||||
::std::mbstowcs(archiveName, common::NAND_TWL_ARCHIVE_NAME, std::strlen(common::NAND_TWL_ARCHIVE_NAME) + 1);
|
||||
std::wstring archiveString(archiveName);
|
||||
|
||||
for (std::vector<common::SavePathInfo>::reverse_iterator it = fileList.rbegin(); it != fileList.rend(); it++)
|
||||
{
|
||||
// twln:/title/をsdmc:/CTR_Console_Repair/TWLBackup/に置換
|
||||
std::wstring toPath(it->name.c_str());
|
||||
toPath.replace(0, std::wcslen(common::NAND_TWL_DATA_ROOT_PATHNAME_WITHOUT_SLASH) + 1,
|
||||
std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + std::wstring(common::SD_SAVEDATA_TWL_ROOT_NAME));
|
||||
|
||||
if (it->isDirectory)
|
||||
{
|
||||
if(!common::ExportTwlSaveDirectory(toPath.c_str(), &list, &s_FileListContext))
|
||||
{
|
||||
s_IsExportSucceeded = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!common::ExportTwlSaveFile(it->name.c_str(), toPath.c_str(), buf, bufSize, &list, &s_FileListContext))
|
||||
{
|
||||
s_IsExportSucceeded = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = list.TryFlush();
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
list.Finalize();
|
||||
}
|
||||
|
||||
result = common::SdMountManager::Unmount();
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
result = nn::fs::Unmount(common::NAND_TWL_ARCHIVE_NAME);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
|
||||
}
|
||||
|
||||
void WriteTwlPhotoData()
|
||||
{
|
||||
COMMON_LOGGER("Export Twl Photo Data.\n");
|
||||
CreateTwlDirectory(common::TWL_PHOTO);
|
||||
WriteTwlData(common::TWL_PHOTO);
|
||||
}
|
||||
|
||||
void WriteTwlSoundData()
|
||||
{
|
||||
COMMON_LOGGER("Export Twl Sound Data.\n");
|
||||
CreateTwlDirectory(common::TWL_SOUND);
|
||||
WriteTwlData(common::TWL_SOUND);
|
||||
}
|
||||
|
||||
void InitializeFileListContext()
|
||||
{
|
||||
s_FileListContext.Initialize();
|
||||
}
|
||||
|
||||
nn::Result ExportTwlSaveData()
|
||||
{
|
||||
// 不要なデータを削除する
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(
|
||||
DeleteTrash((std::wstring(common::LOG_ROOT_DIRECTORY_PATH) + std::wstring(L"/")).c_str()));
|
||||
|
||||
s_ExportThread.Start(WriteTwlSaveData, s_ExportThreadStack);
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
void ExportTwlPhotoData()
|
||||
{
|
||||
s_ExportThread.Start(WriteTwlPhotoData, s_ExportThreadStack);
|
||||
}
|
||||
|
||||
void ExportTwlSoundData()
|
||||
{
|
||||
s_ExportThread.Start(WriteTwlSoundData, s_ExportThreadStack);
|
||||
}
|
||||
|
||||
|
||||
nn::Result WriteMcuRtcData(common::HardwareStateManager& manager)
|
||||
{
|
||||
COMMON_LOGGER("Export RTC Data.\n");
|
||||
nn::Result result;
|
||||
nn::Handle handle = manager.GetMcuHandle();
|
||||
|
||||
if(handle.IsValid())
|
||||
{
|
||||
nn::mcu::CTR::HwCheck mcu(handle);
|
||||
|
||||
nn::mcu::CTR::RtcData rtc;
|
||||
const u8 RETRY = 10;
|
||||
for (u8 i = 0; i < RETRY; i++)
|
||||
{
|
||||
result = mcu.GetRtcAll(&rtc);
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
NN_LOG("RTC = 20%02d/%02d/%02d %02d:%02d:%02d\n", rtc.m_Year, rtc.m_Month, rtc.m_Day, rtc.m_Hour, rtc.m_Minute, rtc.m_Second);
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::MCU_RTC_PATHNAME, &rtc, sizeof(rtc));
|
||||
}
|
||||
nn::os::Thread::Sleep(
|
||||
nn::fnd::TimeSpan::FromMilliSeconds(
|
||||
nn::os::Tick::GetSystemCurrent().ToTimeSpan().GetMilliSeconds() % 100));
|
||||
}
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
NN_LOG("invalid handle\n");
|
||||
return nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_INVALID_STATE, nn::Result::MODULE_COMMON,
|
||||
nn::Result::DESCRIPTION_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
bool AddCmactoExportFileList()
|
||||
{
|
||||
nn::Result result;
|
||||
nn::fs::FileOutputStream list;
|
||||
result = list.TryInitialize(common::FILE_LIST_PATHNAME, true);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
s64 fileSize = 0;
|
||||
result = list.TryGetSize(&fileSize);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
// 末尾に移動
|
||||
result = list.TrySetPosition(fileSize);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
return AddCmac(&list, &s_FileListContext);
|
||||
}
|
||||
|
||||
void ExportThreadFunc()
|
||||
{
|
||||
nn::Result result;
|
||||
s_IsExportSucceeded = true;
|
||||
|
||||
result = common::SdMountManager::Mount();
|
||||
|
||||
size_t bufSize = common::GetAllocatableSize(AES_BLOCK_SIZE * 2);
|
||||
NN_LOG("AllocatableSize = %d\n", bufSize);
|
||||
if(bufSize > common::FILE_COPY_HEAP_SIZE)
|
||||
{
|
||||
bufSize = common::FILE_COPY_HEAP_SIZE;
|
||||
}
|
||||
|
||||
common::HeapManager writeHeap(bufSize, AES_BLOCK_SIZE * 2);
|
||||
void* buf = writeHeap.GetAddr();
|
||||
if (buf != NULL)
|
||||
{
|
||||
common::SaveDataMover saveDataMover;
|
||||
saveDataMover.StartExport(buf, bufSize, &s_ExportProgress);
|
||||
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(
|
||||
saveDataMover.GetLastResult(), s_IsExportSucceeded
|
||||
);
|
||||
}
|
||||
|
||||
// FileListにCMACを付加する
|
||||
if(!AddCmactoExportFileList())
|
||||
{
|
||||
s_IsExportSucceeded = false;
|
||||
}
|
||||
|
||||
common::SdMountManager::Unmount();
|
||||
|
||||
NN_LOG("Export Thread Finalize\n");
|
||||
}
|
||||
nn::Result WriteSaveData()
|
||||
{
|
||||
// NANDからSDカードに書き出し
|
||||
nn::Result result;
|
||||
|
||||
// セーブデータディレクトリ以下のデータをSDカードにコピー
|
||||
// コピー用ディレクトリ作成
|
||||
common::SdReaderWriter sdWriter;
|
||||
result = sdWriter.CreateDirectory((::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(
|
||||
common::SD_SAVEDATA_ROOT_NAME)).c_str());
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
COMMON_LOGGER("Export NAND Data Start...\n");
|
||||
|
||||
// SDにコピーするためのスレッドの作成
|
||||
s_ExportThread.Start(ExportThreadFunc, s_ExportThreadStack);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FinalizeExportThread()
|
||||
{
|
||||
s_ExportThread.Join();
|
||||
s_ExportThread.Finalize();
|
||||
}
|
||||
|
||||
nn::Result WriteVersionData(common::HardwareStateManager& manager)
|
||||
{
|
||||
COMMON_LOGGER("Export Version Data.\n");
|
||||
|
||||
common::VerDef versionData;
|
||||
manager.GetVersionData(&versionData);
|
||||
|
||||
common::SdReaderWriter sdWriter;
|
||||
return sdWriter.WriteBufWithCmac(common::VERSION_DATA_PATHNAME, &versionData, sizeof(common::VerDef));
|
||||
}
|
||||
|
||||
nn::Result DeleteNimSystemSaveData()
|
||||
{
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(
|
||||
nn::nim::InitializeForUpdater());
|
||||
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(
|
||||
nn::nim::CTR::Updater::FormatSaveData());
|
||||
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(
|
||||
nn::nim::FinalizeForUpdater());
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
bool DeleteNimSaveData()
|
||||
{
|
||||
nn::Result result;
|
||||
::std::wstring nimSaveDataPath =
|
||||
::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) +
|
||||
::std::wstring(common::SD_SAVEDATA_ROOT_NAME) +
|
||||
::std::wstring(s_RootName) +
|
||||
::std::wstring(L"/") +
|
||||
std::wstring(common::NIM_SAVEDATA_DIRECTORY_NAME);
|
||||
|
||||
result = common::SdMountManager::Mount();
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
NN_LOG("%ls\n", nimSaveDataPath.c_str());
|
||||
result = nn::fs::TryDeleteDirectoryRecursively(nimSaveDataPath.c_str());
|
||||
if (result.IsFailure() && !nn::fs::ResultNotFound::Includes(result))
|
||||
{
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
}
|
||||
|
||||
result = common::SdMountManager::Unmount();
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(
|
||||
DeleteNimSystemSaveData());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddShutDownPtmEvent()
|
||||
{
|
||||
nn::pl::CTR::NotifyPlayEvent(nn::pl::CTR::EVENTTYPE_TERMINATE, nn::CTR::INVALID_PROGRAM_ID,
|
||||
nn::fnd::DateTime::GetNow());
|
||||
}
|
||||
|
||||
bool ExportData(common::HardwareStateManager& manager)
|
||||
{
|
||||
static bool init = true;
|
||||
|
||||
if (init)
|
||||
{
|
||||
nn::Result result;
|
||||
|
||||
// 電源断の履歴をptmに追加する
|
||||
AddShutDownPtmEvent();
|
||||
|
||||
// リージョンデータをSDに書き込む
|
||||
result = WriteRegionData();
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
// 国データと言語データをSDに書き込む
|
||||
result = WriteCountryLanguageData();
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
// NORデータをSDカードに書き込む
|
||||
result = WriteNorData();
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
// シリアルナンバーをSDカードに書き込む
|
||||
result = WriteSerialNumber(manager);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
// デバイスIDをSDカードに書き込む
|
||||
result = WriteDeviceId(manager);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
// 完全性検証SEEDをSDカードに書き込む
|
||||
result = WriteIvs(manager);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
// RTCをSDに書き出す
|
||||
result = WriteMcuRtcData(manager);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
// バージョン情報をSDに書き出す
|
||||
result = WriteVersionData(manager);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
// NANDのセーブデータをSDに書き出す
|
||||
result = WriteSaveData();
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
init = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 GetExportProgress()
|
||||
{
|
||||
return s_ExportProgress;
|
||||
}
|
||||
|
||||
bool IsExportThreadFinished()
|
||||
{
|
||||
return s_ExportThread.IsValid() && !s_ExportThread.IsAlive();
|
||||
}
|
||||
|
||||
bool IsExportSucceeded()
|
||||
{
|
||||
return s_IsExportSucceeded;
|
||||
}
|
||||
|
||||
//!@ brief ファイルにSHA256から計算したAES-CMACを付加します
|
||||
//!@ param[in] file CMACを付加したいInitialize済みのファイル
|
||||
//!@ param[in] context CMAC計算元のSHA256コンテキスト
|
||||
bool AddCmac(nn::fs::FileOutputStream* file, nn::crypto::Sha256Context* context)
|
||||
{
|
||||
nn::Result result;
|
||||
|
||||
bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE];
|
||||
context->GetHash(sha256Hash);
|
||||
|
||||
bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE];
|
||||
result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
s32 writeSize;
|
||||
result = file->TryWrite(&writeSize, cmac, sizeof(cmac), false);
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
result = file->TryFlush();
|
||||
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: Exporter.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 EXPORTER_H_
|
||||
#define EXPORTER_H_
|
||||
|
||||
#include <nn.h>
|
||||
#include "HardwareStateManager.h"
|
||||
|
||||
namespace ConsoleBackup
|
||||
{
|
||||
|
||||
// 出力ファイルリストのコンテキストを初期化する。出力ファイルリストを
|
||||
// 生成する前に必ず呼び出す必要がある
|
||||
void InitializeFileListContext();
|
||||
|
||||
// 新たにスレッドを起動して、DSiWareのセーブデータをSDカードに出力する
|
||||
nn::Result ExportTwlSaveData();
|
||||
|
||||
// 新たにスレッドを起動して、TWL写真領域のデータをSDカードに出力する
|
||||
void ExportTwlPhotoData();
|
||||
|
||||
// 新たにスレッドを起動して、TWLサウンド領域のデータをSDカードに出力する
|
||||
void ExportTwlSoundData();
|
||||
|
||||
// 本体固有情報をSDカードに出力する
|
||||
// 新たにスレッドを起動して、CTR領域のセーブデータをSDカードに出力する
|
||||
bool ExportData(common::HardwareStateManager& manager);
|
||||
|
||||
// NIMのセーブデータをSDカードから削除する
|
||||
bool DeleteNimSaveData();
|
||||
|
||||
// 出力スレッドの進捗を返す
|
||||
u32 GetExportProgress();
|
||||
|
||||
// 出力スレッドが終了したかどうか
|
||||
bool IsExportThreadFinished();
|
||||
|
||||
// 出力スレッドを終了する
|
||||
void FinalizeExportThread();
|
||||
|
||||
// 出力が成功したかどうか
|
||||
bool IsExportSucceeded();
|
||||
|
||||
}
|
||||
|
||||
#endif /* EXPORTER_H_ */
|
||||
@ -1,78 +0,0 @@
|
||||
#!/usr/bin/env omake
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: Horizon
|
||||
# File: OMakefile
|
||||
#
|
||||
# Copyright (C)2009 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$
|
||||
#----------------------------------------------------------------------------
|
||||
SUPPORTED_TARGETS = CTR-T*.Process.MPCore.fast
|
||||
CTR_APPTYPE = CARD
|
||||
|
||||
TARGET_PROGRAM = ConsoleBackup
|
||||
|
||||
SAMPLED_DEMOS_COMMON_INCLUDE_DIR = $(dir $(HORIZON_ROOT)/../CTR/SampleDemos/common/include)
|
||||
INCLUDES += $(SAMPLED_DEMOS_COMMON_INCLUDE_DIR) \
|
||||
../common
|
||||
|
||||
SOURCES[] =
|
||||
ConsoleBackup.cpp
|
||||
Controller.cpp
|
||||
Exporter.cpp
|
||||
Checker.cpp
|
||||
SavedataChecker.cpp
|
||||
../common/Util.cpp
|
||||
../common/DrawSystemState.cpp
|
||||
../common/FileTransfer.cpp
|
||||
../common/FileChecker.cpp
|
||||
../common/SdReaderWriter.cpp
|
||||
../common/HeapManager.cpp
|
||||
../common/SdLogger.cpp
|
||||
../common/wave.cpp
|
||||
../common/SimplePlayer.cpp
|
||||
../common/LogConsole.cpp
|
||||
../common/CommonLogger.cpp
|
||||
../common/SdMountManager.cpp
|
||||
../common/VersionDetect.cpp
|
||||
../common/ResFont.cpp
|
||||
../common/HardwareStateManager.cpp
|
||||
../common/SaveDataMover.cpp
|
||||
../common/OperationMessage.cpp
|
||||
|
||||
include $(ROOT)/common/BuildSwitch.om
|
||||
|
||||
CTR_BANNER_SPEC = $(TARGET_NAME).bsf
|
||||
|
||||
ROMFS_ROOT = ../common/romfiles
|
||||
|
||||
SHADER_BIN = nnfont_RectDrawerShader.shbin
|
||||
SHADER_PATH = $(ROMFS_ROOT)/$(SHADER_BIN)
|
||||
|
||||
ROMFS_DEPENDENCIES = $(SHADER_PATH)
|
||||
|
||||
LIBS += libnn_cfg \
|
||||
libnn_crypto \
|
||||
libnn_mcu \
|
||||
libnn_i2c \
|
||||
libnn_ps \
|
||||
lib_demo \
|
||||
libnn_nwm \
|
||||
libnn_friends \
|
||||
libnn_nim \
|
||||
libnn_am \
|
||||
|
||||
INSTALL_SDK_TOOL = true
|
||||
|
||||
ROM_SPEC_FILE = $(TARGET_NAME).rsf
|
||||
DESCRIPTOR = $(HORIZON_ROOT)/resources/specfiles/private/RepairTool.desc
|
||||
|
||||
include $(ROOT_OMAKE)/modulerules
|
||||
|
||||
build: $(DEFAULT_TARGETS)
|
||||
@ -1,490 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: NandSavedataChecker.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/fs/fs_ApiSysSaveData.h>
|
||||
#include <nn/fs/fs_ApiSharedExtSaveData.h>
|
||||
#include <nn/fs/fs_ResultPrivate.h>
|
||||
|
||||
#include "SavedataChecker.h"
|
||||
#include "CommonLogger.h"
|
||||
#include "FileTransfer.h"
|
||||
#include "FileName.h"
|
||||
|
||||
namespace ConsoleBackup
|
||||
{
|
||||
|
||||
SavedataCheckerBase::SavedataCheckerBase(void* buf, size_t size) :
|
||||
m_Buf(buf), m_Bufsize(size), m_CalculatedFileSize(0), m_TotalReadSize(0), m_CheckErrorOccured(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SavedataCheckerBase::~SavedataCheckerBase()
|
||||
{
|
||||
NN_LOG("m_TotalReadSize = %lld\n", m_TotalReadSize);
|
||||
}
|
||||
|
||||
nn::Result SavedataCheckerBase::CleanUpFilesRecursively(bool* metaDataCrashed, bool* modified, std::string baseName,
|
||||
std::wstring currentDirectory, bool erase)
|
||||
{
|
||||
nn::fs::Directory dir;
|
||||
nn::fs::DirectoryEntry entry;
|
||||
nn::Result result;
|
||||
|
||||
NN_LOG("%s\n", common::GetCharStr(currentDirectory.c_str()));
|
||||
result = dir.TryInitialize(currentDirectory.c_str());
|
||||
if (result.IsFailure())
|
||||
{
|
||||
COMMON_LOGGER_WARN(
|
||||
"Error: %s/%s\n", baseName.c_str(), common::GetCharStr(GetFilePathWithoutArchive(currentDirectory).c_str()));
|
||||
m_CheckErrorOccured = true;
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
if (erase)
|
||||
{
|
||||
*metaDataCrashed = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
s32 numRead;
|
||||
result = dir.TryRead(&numRead, &entry, 1);
|
||||
if (result.IsFailure())
|
||||
{
|
||||
dir.Finalize();
|
||||
COMMON_LOGGER_WARN(
|
||||
"Error: %s/%s\n", baseName.c_str(), common::GetCharStr(GetFilePathWithoutArchive(currentDirectory).c_str()));
|
||||
m_CheckErrorOccured = true;
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
if (erase)
|
||||
{
|
||||
*metaDataCrashed = true;
|
||||
}
|
||||
// ディレクトリの読み取りエラーなので再度読み取ってもエラーになる
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
if(numRead == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (std::wcscmp(entry.entryName, L".") == 0 || std::wcscmp(entry.entryName, L"..") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// ディレクトリの場合
|
||||
if (entry.attributes.isDirectory)
|
||||
{
|
||||
result = CleanUpFilesRecursively(metaDataCrashed, modified, baseName,
|
||||
currentDirectory + std::wstring(entry.entryName) + std::wstring(L"/"), erase);
|
||||
if(erase && result.IsFailure())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// ファイルの場合
|
||||
else
|
||||
{
|
||||
nn::fs::FileInputStream file;
|
||||
std::wstring filePath = (currentDirectory + std::wstring(entry.entryName)).c_str();
|
||||
const wchar_t* path = filePath.c_str();
|
||||
NN_LOG("%s\n", common::GetCharStr(path));
|
||||
|
||||
result = file.TryInitialize(path);
|
||||
if(result.IsFailure())
|
||||
{
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
const bool silent = IsForceDeleteFile(common::GetCharStr(entry.entryName));
|
||||
if(!silent)
|
||||
{
|
||||
COMMON_LOGGER_WARN("Error: %s/%s\n", baseName.c_str(), common::GetCharStr(GetFilePathWithoutArchive(filePath).c_str()));
|
||||
m_CheckErrorOccured = true;
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
}
|
||||
if (erase || silent)
|
||||
{
|
||||
if(!silent)
|
||||
{
|
||||
COMMON_LOGGER_WARN("Deleting: %s/%s\n", baseName.c_str(), common::GetCharStr(GetFilePathWithoutArchive(filePath).c_str()));
|
||||
}
|
||||
result = nn::fs::TryDeleteFile(path);
|
||||
*modified = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
s32 readSize;
|
||||
result = file.TryRead(&readSize, m_Buf, m_Bufsize);
|
||||
if(result.IsFailure())
|
||||
{
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
const bool silent = IsForceDeleteFile(common::GetCharStr(entry.entryName));
|
||||
if(!silent)
|
||||
{
|
||||
COMMON_LOGGER_WARN("Error: %s/%s\n", baseName.c_str(), common::GetCharStr(GetFilePathWithoutArchive(filePath).c_str()));
|
||||
m_CheckErrorOccured = true;
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
}
|
||||
|
||||
m_TotalReadSize += file.GetSize();
|
||||
file.Finalize();
|
||||
if (erase || silent)
|
||||
{
|
||||
if(!silent)
|
||||
{
|
||||
COMMON_LOGGER_WARN("Deleting: %s/%s\n", baseName.c_str(), common::GetCharStr(GetFilePathWithoutArchive(filePath).c_str()));
|
||||
}
|
||||
result = nn::fs::TryDeleteFile(path);
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
*modified = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TotalReadSize += readSize;
|
||||
}
|
||||
|
||||
if(readSize == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
nn::Result SavedataCheckerBase::GetFileSize(std::wstring currentDirectory)
|
||||
{
|
||||
return common::CalculateFileSizeRecursively(currentDirectory, m_CalculatedFileSize);
|
||||
}
|
||||
|
||||
s64 SavedataCheckerBase::GetCalculatedSize()
|
||||
{
|
||||
return m_CalculatedFileSize;
|
||||
}
|
||||
|
||||
s64 SavedataCheckerBase::GetTotalReadSize()
|
||||
{
|
||||
return m_TotalReadSize;
|
||||
}
|
||||
|
||||
bool SavedataCheckerBase::GetCheckErrorOccured()
|
||||
{
|
||||
return m_CheckErrorOccured;
|
||||
}
|
||||
|
||||
std::wstring SavedataCheckerBase::GetFilePathWithoutArchive(std::wstring path)
|
||||
{
|
||||
std::wstring::size_type pos = path.find(L":/");
|
||||
if(pos != std::wstring::npos)
|
||||
{
|
||||
return path.substr(pos + sizeof(L""));
|
||||
}
|
||||
else
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
bool SavedataCheckerBase::IsForceDeleteFile(const char* name)
|
||||
{
|
||||
if((std::strcmp(common::BASHOTORYA_FILE_NAME, name) == 0) ||
|
||||
(std::strcmp(common::BASHOTORYA2_FILE_NAME, name) == 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NandSavedataChecker::NandSavedataChecker()
|
||||
{
|
||||
// TODO 自動生成されたコンストラクター・スタブ
|
||||
|
||||
}
|
||||
|
||||
NandSavedataChecker::NandSavedataChecker(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size)
|
||||
{
|
||||
m_pSharedExtSaveChecker = new SharedExtSavedataChecker(buf, size);
|
||||
m_pSysSaveChecker = new SystemSavedataChecker(buf, size);
|
||||
}
|
||||
|
||||
NandSavedataChecker::~NandSavedataChecker()
|
||||
{
|
||||
delete m_pSharedExtSaveChecker;
|
||||
delete m_pSysSaveChecker;
|
||||
}
|
||||
|
||||
nn::Result NandSavedataChecker::CleanUp(bool erase)
|
||||
{
|
||||
nn::Result result;
|
||||
|
||||
m_pSharedExtSaveChecker->CalculateFileSize();
|
||||
m_pSysSaveChecker->CalculateFileSize();
|
||||
|
||||
result = m_pSharedExtSaveChecker->CleanUp(erase);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
result = m_pSysSaveChecker->CleanUp(erase);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
s64 NandSavedataChecker::GetProgress()
|
||||
{
|
||||
if (m_pSharedExtSaveChecker->GetCalculatedSize() == 0 || m_pSysSaveChecker->GetCalculatedSize() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (m_pSharedExtSaveChecker->GetTotalReadSize() + m_pSysSaveChecker->GetTotalReadSize()) * 100
|
||||
/ (m_pSharedExtSaveChecker->GetCalculatedSize() + m_pSysSaveChecker->GetCalculatedSize());
|
||||
}
|
||||
}
|
||||
|
||||
bool NandSavedataChecker::GetCheckErrorOccured()
|
||||
{
|
||||
return m_pSharedExtSaveChecker->GetCheckErrorOccured() || m_pSysSaveChecker->GetCheckErrorOccured();
|
||||
}
|
||||
|
||||
SystemSavedataChecker::SystemSavedataChecker()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SystemSavedataChecker::SystemSavedataChecker(void* buf, size_t size) : SavedataCheckerBase(buf, size)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SystemSavedataChecker::~SystemSavedataChecker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
nn::Result SystemSavedataChecker::CleanUp(bool erase)
|
||||
{
|
||||
nn::Result result;
|
||||
|
||||
std::wstring currentDirectory;
|
||||
for (s32 i = 0; i < SYSTEM_SAVE_DATA_NUM; i++)
|
||||
{
|
||||
bool metaDataCrashed = false;
|
||||
bool modified = false;
|
||||
|
||||
// SPIDERのスキップ
|
||||
if(SYSTEM_SAVEDATA_COUPLE_LIST[i].id == 0x00020088 ||
|
||||
SYSTEM_SAVEDATA_COUPLE_LIST[i].id == 0x0002009d ||
|
||||
SYSTEM_SAVEDATA_COUPLE_LIST[i].id == 0x00020094)
|
||||
{
|
||||
NN_LOG("Skip SPIDER\n");
|
||||
continue;
|
||||
}
|
||||
result = nn::fs::MountSystemSaveData(SYSTEM_SAVEDATA_ARCHIVE_NAME, SYSTEM_SAVEDATA_COUPLE_LIST[i].id );
|
||||
if (result.IsFailure())
|
||||
{
|
||||
if(result <= nn::fs::ResultVerificationFailed())
|
||||
{
|
||||
NN_LOG("Mount Error: %s\n", SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str());
|
||||
COMMON_LOGGER_WARN(
|
||||
"Error: %s/\n", SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str());
|
||||
m_CheckErrorOccured = true;
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
if (erase)
|
||||
{
|
||||
COMMON_LOGGER_WARN(
|
||||
"Deleting: %s/\n", SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str());
|
||||
// 削除する
|
||||
result = nn::fs::DeleteSystemSaveData(SYSTEM_SAVEDATA_COUPLE_LIST[i].id);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NN_LOG("Mount %s\n", SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str());
|
||||
// ファイルを個別にチェックする
|
||||
result = CleanUpFilesRecursively(&metaDataCrashed, &modified, SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str(), L"ssave:/", erase);
|
||||
// メタデータエラーの場合は一旦アンマウントしてからアーカイブごと削除
|
||||
if (erase && metaDataCrashed)
|
||||
{
|
||||
// 削除する
|
||||
COMMON_LOGGER_WARN( "Deleting: %s/\n", SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str());
|
||||
result = nn::fs::Unmount(SYSTEM_SAVEDATA_ARCHIVE_NAME);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
result = nn::fs::DeleteSystemSaveData(SYSTEM_SAVEDATA_COUPLE_LIST[i].id);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
continue;
|
||||
}
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
if(modified)
|
||||
{
|
||||
result = nn::fs::CommitSystemSaveData(SYSTEM_SAVEDATA_ARCHIVE_NAME);
|
||||
}
|
||||
|
||||
result = nn::fs::Unmount(SYSTEM_SAVEDATA_ARCHIVE_NAME);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
}
|
||||
}
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
nn::Result SystemSavedataChecker::CalculateFileSize()
|
||||
{
|
||||
nn::Result result;
|
||||
|
||||
for (s32 i = 0; i < SYSTEM_SAVE_DATA_NUM; i++)
|
||||
{
|
||||
result = nn::fs::MountSystemSaveData(SYSTEM_SAVEDATA_ARCHIVE_NAME, SYSTEM_SAVEDATA_COUPLE_LIST[i].id );
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
result = GetFileSize(L"ssave:/");
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
result = nn::fs::Unmount(SYSTEM_SAVEDATA_ARCHIVE_NAME);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
}
|
||||
}
|
||||
|
||||
NN_LOG("CalculatedFileSize = %lld\n", m_CalculatedFileSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
SharedExtSavedataChecker::SharedExtSavedataChecker()
|
||||
{
|
||||
}
|
||||
|
||||
SharedExtSavedataChecker::SharedExtSavedataChecker(void* buf, size_t size) : SavedataCheckerBase(buf, size)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
SharedExtSavedataChecker::~SharedExtSavedataChecker()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
nn::Result SharedExtSavedataChecker::CleanUp(bool erase)
|
||||
{
|
||||
nn::Result result;
|
||||
|
||||
const size_t ARRAY_SIZE = 256;
|
||||
s32 numId;
|
||||
bit32 IdArray[ARRAY_SIZE];
|
||||
|
||||
result = nn::fs::EnumerateSharedExtSaveData(&numId, IdArray, ARRAY_SIZE);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
NN_LOG_DEBUG("ExtData num = %d\n", numId);
|
||||
for (s32 i = 0; i < numId; i++ )
|
||||
{
|
||||
bool metaDataCrashed = false;
|
||||
bool modified = false;
|
||||
|
||||
char baseName[10];
|
||||
nn::nstd::TSNPrintf(baseName, sizeof(baseName), "%X", IdArray[i]);
|
||||
result = nn::fs::MountSharedExtSaveData(SHARED_EXT_SAVEDATA_ARCHIVE_NAME, IdArray[i]);
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
NN_LOG("Mount %x\n", IdArray[i]);
|
||||
|
||||
// アーカイブ内のファイル・ディレクトリをチェックする
|
||||
result = CleanUpFilesRecursively(&metaDataCrashed, &modified, baseName, L"shext:/", erase);
|
||||
// メタデータが壊れていた場合はアンマウントしてから削除する
|
||||
if(erase && metaDataCrashed)
|
||||
{
|
||||
COMMON_LOGGER_WARN("Deleting %x/\n", IdArray[i]);
|
||||
result = nn::fs::Unmount(SHARED_EXT_SAVEDATA_ARCHIVE_NAME);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
result = nn::fs::DeleteSharedExtSaveData(IdArray[i]);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
continue;
|
||||
}
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
result = nn::fs::Unmount(SHARED_EXT_SAVEDATA_ARCHIVE_NAME);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// アーカイブごと削除する
|
||||
if(result <= nn::fs::ResultVerificationFailed() || result <= nn::fs::ResultDbmFileNotFound())
|
||||
{
|
||||
NN_LOG("Mount Error: %x\n", IdArray[i]);
|
||||
|
||||
COMMON_LOGGER_WARN("Error: %x/\n", IdArray[i]);
|
||||
m_CheckErrorOccured = true;
|
||||
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
||||
if (erase)
|
||||
{
|
||||
COMMON_LOGGER_WARN("Deleting %x/\n", IdArray[i]);
|
||||
result = nn::fs::DeleteSharedExtSaveData(IdArray[i]);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
nn::Result SharedExtSavedataChecker::CalculateFileSize()
|
||||
{
|
||||
nn::Result result;
|
||||
|
||||
const size_t ARRAY_SIZE = 256;
|
||||
s32 numId;
|
||||
bit32 IdArray[ARRAY_SIZE];
|
||||
|
||||
result = nn::fs::EnumerateSharedExtSaveData(&numId, IdArray, ARRAY_SIZE);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
NN_LOG_DEBUG("ExtData num = %d\n", numId);
|
||||
for (s32 i = 0; i < numId; i++ )
|
||||
{
|
||||
result = nn::fs::MountSharedExtSaveData(SHARED_EXT_SAVEDATA_ARCHIVE_NAME, IdArray[i]);
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
result = GetFileSize(L"shext:/");
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
|
||||
result = nn::fs::Unmount(SHARED_EXT_SAVEDATA_ARCHIVE_NAME);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
||||
}
|
||||
}
|
||||
|
||||
NN_LOG("CalculatedFileSize = %lld\n", m_CalculatedFileSize);
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
} /* namespace ConsoleBackup */
|
||||
@ -1,237 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: NandSavedataChecker.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 SAVEDATACHECKER_H_
|
||||
#define SAVEDATACHECKER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nn.h>
|
||||
#include <nn/fs/fs_ParametersForSystem.h>
|
||||
|
||||
namespace ConsoleBackup
|
||||
{
|
||||
|
||||
struct SystemSaveDataCouple
|
||||
{
|
||||
std::string name;
|
||||
nn::fs::SystemSaveDataId id;
|
||||
};
|
||||
|
||||
const SystemSaveDataCouple SYSTEM_SAVEDATA_COUPLE_LIST[] =
|
||||
{
|
||||
{"fill_data", 0x00010000 },
|
||||
{"cfg", 0x00010017 },
|
||||
{"ptm", 0x00010022 },
|
||||
{"cecd", 0x00010026 },
|
||||
{"nim", 0x0001002C },
|
||||
{"friends", 0x00010032 },
|
||||
{"boss", 0x00010034 },
|
||||
{"news", 0x00010035 },
|
||||
|
||||
{"ACTIVITY_LOG_JP", 0x00020202 },
|
||||
{"ACTIVITY_LOG_US", 0x00020212 },
|
||||
{"ACTIVITY_LOG_EU", 0x00020222 },
|
||||
|
||||
{"MII_MAKER_JP", 0x00020207 },
|
||||
{"MII_MAKER_US", 0x00020217 },
|
||||
{"MII_MAKER_EU", 0x00020227 },
|
||||
|
||||
{"PHOTO_JP", 0x00020204 },
|
||||
{"PHOTO_US", 0x00020214 },
|
||||
{"PHOTO_EU", 0x00020224 },
|
||||
|
||||
{"SOUND_JP", 0x00020205 },
|
||||
{"SOUND_US", 0x00020215 },
|
||||
{"SOUND_EU", 0x00020225 },
|
||||
|
||||
{"ESHOP_JP", 0x00020209 },
|
||||
{"ESHOP_US", 0x00020219 },
|
||||
{"ESHOP_EU", 0x00020229 },
|
||||
|
||||
{"ZONE_JP", 0x0002020b },
|
||||
{"ZONE_US", 0x0002021b },
|
||||
{"ZONE_EU", 0x0002022b },
|
||||
|
||||
{"MIGRATION_JP", 0x0002020a },
|
||||
{"MIGRATION_US", 0x0002021a },
|
||||
{"MIGRATION_EU", 0x0002022a },
|
||||
|
||||
{"DIARY_JP", 0x0002020c },
|
||||
{"DIARY_US", 0x0002021c },
|
||||
{"DIARY_EU", 0x0002022c },
|
||||
|
||||
{"MII_PLAZA_JP", 0x00020208 },
|
||||
{"MII_PLAZA_US", 0x00020218 },
|
||||
{"MII_PLAZA_EU", 0x00020228 },
|
||||
|
||||
{"ARGAMES_HAL_JP", 0x0002020d },
|
||||
{"ARGAMES_HAL_US", 0x0002021d },
|
||||
{"ARGAMES_HAL_EU", 0x0002022d },
|
||||
|
||||
{"ARGAMES_NCL_JP", 0x0002020e },
|
||||
{"ARGAMES_NCL_US", 0x0002021e },
|
||||
{"ARGAMES_NCL_EU", 0x0002022e },
|
||||
|
||||
{"MENU_JP", 0x00020081 },
|
||||
{"MENU_US", 0x0002008f },
|
||||
{"MENU_EU", 0x00020098 },
|
||||
|
||||
{"friend_JP", 0x0002008d },
|
||||
{"friend_US", 0x00020096 },
|
||||
{"friend_EU", 0x0002009f },
|
||||
|
||||
{"BROWSER_JP", 0x00020088 },
|
||||
{"BROWSER_US", 0x0002009d },
|
||||
{"BROWSER_EU", 0x00020094 },
|
||||
|
||||
{"ESPEC_JP", 0x00020086 },
|
||||
{"ESPEC_US", 0x00020092 },
|
||||
{"ESPEC_EU", 0x0002009b },
|
||||
|
||||
{"MEMO_JP", 0x00020087 },
|
||||
{"MEMO_US", 0x00020093 },
|
||||
{"MEMO_EU", 0x0002009c },
|
||||
|
||||
{"error", 0x000200c5 }
|
||||
|
||||
};
|
||||
|
||||
const char* const SYSTEM_SAVEDATA_ARCHIVE_NAME = "ssave:";
|
||||
const char* const SHARED_EXT_SAVEDATA_ARCHIVE_NAME = "shext:";
|
||||
|
||||
const size_t SYSTEM_SAVE_DATA_NUM = sizeof(SYSTEM_SAVEDATA_COUPLE_LIST)/sizeof(SYSTEM_SAVEDATA_COUPLE_LIST[0]);
|
||||
|
||||
class SavedataCheckerBase
|
||||
{
|
||||
public:
|
||||
SavedataCheckerBase() {}
|
||||
SavedataCheckerBase(void* buf, size_t size);
|
||||
~SavedataCheckerBase();
|
||||
|
||||
//! @brief セーブデータを調べて問題があるファイルを削除するインタフェース
|
||||
//! @param[in] erase 問題があるファイルを削除するかどうか
|
||||
virtual nn::Result CleanUp(bool erase) = 0;
|
||||
//! @brief ファイルサイズをチェックするインタフェース
|
||||
virtual nn::Result CalculateFileSize() = 0;
|
||||
|
||||
//! @return 事前に計算したサイズ
|
||||
s64 GetCalculatedSize();
|
||||
|
||||
//! @return 読み取ったサイズ
|
||||
s64 GetTotalReadSize();
|
||||
|
||||
//! @brief チェック時にエラーが起こったかどうか調べる
|
||||
//! @return エラーが起こったかどうか
|
||||
bool GetCheckErrorOccured();
|
||||
|
||||
protected:
|
||||
//! @brief ファイルとディレクトリを再帰的にチェックする。エラーがあれば削除する
|
||||
//! @param[out] metaDataCrashed メタデータが壊れていたかどうか。アーカイブごと削除するかどうかの判断に使用する
|
||||
//! @param[out] modified ファイルかディレクトリを削除したかどうか。Commitするかどうかの判断に使用する
|
||||
//! @param[in] baseName 削除するセーブデータの区別に表示するための名前
|
||||
//! @param[in] currentDirectory チェックを開始するディレクトリ。スラッシュで終端すること
|
||||
//! @param[in] erase ファイルかディレクトリを削除するかどうか
|
||||
nn::Result CleanUpFilesRecursively(bool* metaDataCrashed, bool* modified, std::string baseName, std::wstring currentDirectory,
|
||||
bool erase);
|
||||
|
||||
//! @brief ファイルサイズを取得する
|
||||
//! @param[out] size ファイルサイズ
|
||||
//! @param[in] currentDirectory チェックを開始するディレクトリ。スラッシュで終端すること。
|
||||
nn::Result GetFileSize(std::wstring currentDirectory);
|
||||
//! バッファ
|
||||
void* m_Buf;
|
||||
|
||||
//! バッファサイズ
|
||||
size_t m_Bufsize;
|
||||
|
||||
NN_PADDING4;
|
||||
|
||||
//! 事前読み取りサイズ
|
||||
s64 m_CalculatedFileSize;
|
||||
|
||||
//! 累計読み取りサイズ
|
||||
s64 m_TotalReadSize;
|
||||
|
||||
NN_PADDING3;
|
||||
//! @brief チェック時にエラーが起こったかどうか
|
||||
bool m_CheckErrorOccured;
|
||||
NN_PADDING4;
|
||||
|
||||
private:
|
||||
std::wstring GetFilePathWithoutArchive(std::wstring path);
|
||||
bool IsForceDeleteFile(const char* name);
|
||||
};
|
||||
|
||||
|
||||
//! @brief システムセーブデータをチェックするためのクラス
|
||||
class SystemSavedataChecker : public SavedataCheckerBase
|
||||
{
|
||||
public:
|
||||
SystemSavedataChecker();
|
||||
SystemSavedataChecker(void* buf, size_t size);
|
||||
~SystemSavedataChecker();
|
||||
|
||||
//! @brief システムセーブデータを調べて問題があるファイルを削除する
|
||||
//! @param[in] erase 問題があるファイルを削除するかどうか
|
||||
virtual nn::Result CleanUp(bool erase);
|
||||
|
||||
//! @brief ファイルサイズをチェックする
|
||||
virtual nn::Result CalculateFileSize();
|
||||
};
|
||||
|
||||
//! @brief 共有拡張セーブデータをチェックするためのクラス
|
||||
class SharedExtSavedataChecker : public SavedataCheckerBase
|
||||
{
|
||||
public:
|
||||
SharedExtSavedataChecker();
|
||||
SharedExtSavedataChecker(void* buf, size_t size);
|
||||
~SharedExtSavedataChecker();
|
||||
|
||||
//! @brief 共有拡張セーブデータを調べて問題があるファイルを削除する
|
||||
//! @param[in] erase 問題があるファイルを削除するかどうか
|
||||
virtual nn::Result CleanUp(bool erase);
|
||||
|
||||
//! @brief ファイルサイズをチェックする
|
||||
virtual nn::Result CalculateFileSize();
|
||||
};
|
||||
|
||||
|
||||
class NandSavedataChecker
|
||||
{
|
||||
public:
|
||||
NandSavedataChecker();
|
||||
NandSavedataChecker(void* buf, size_t size);
|
||||
~NandSavedataChecker();
|
||||
|
||||
nn::Result CleanUp(bool erase);
|
||||
|
||||
s64 GetProgress();
|
||||
|
||||
bool GetCheckErrorOccured();
|
||||
|
||||
private:
|
||||
SharedExtSavedataChecker* m_pSharedExtSaveChecker;
|
||||
SystemSavedataChecker* m_pSysSaveChecker;
|
||||
|
||||
//! バッファ
|
||||
void* m_Buf;
|
||||
|
||||
//! バッファサイズ
|
||||
size_t m_Bufsize;
|
||||
};
|
||||
|
||||
} /* namespace ConsoleBackup */
|
||||
#endif /* SAVEDATACHECKER_H_ */
|
||||
@ -1 +0,0 @@
|
||||
В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫ф8ф8фШчГГГГГГВ╫В╫8фВ╫В╫В╫В╫В╫ГГГГшчфГШФВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫yнВ╫yнВ╫В╫В╫В╫В╫YнВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫ГГГГШчyнYнВ╫шчшчВ╫В╫фВ╫В╫шчyнШчВ╫yнГГГГyнШФГГГГГшчВ╫В╫В╫В╫YнГyнГВ╫В╫В╫В╫В╫yнфшчГШФГYнyнВ╫В╫В╫yнВ╫╨жВ╫В╫В╫В╫В╫yнВ╫yнВ╫В╫В╫В╫В╫YнВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫yнГYнГВ╫В╫В╫В╫В╫фВ╫В╫ГyнГ8фВ╫В╫В╫В╫фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫
|
||||
@ -1 +0,0 @@
|
||||
В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫YнВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫8фВ╫В╫8ф8фВ╫В╫В╫╨ж8ф╨жГГшчГГГГГГГГГГГГГГГГГГГГГГГВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫8ф8фВ╫В╫фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫ГГГГГШФГГГГГГГГГГ жфГГВ╫В╫ жВ╫ГГГГГ жГГВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫8фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫шчВ╫шчВ╫В╫В╫В╫В╫ГВ╫ШчВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫╨жВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫ГГГГГГГГГГГГГГГГГГШФ8фШчшчВ╫В╫ жВ╫YнВ╫В╫В╫В╫В╫ГГYнyнГГyнфВ╫В╫В╫В╫В╫В╫В╫В╫фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫шчшчГшчШФВ╫В╫ГГYнГВ╫В╫В╫В╫В╫шчВ╫шчГГГГГГГГГГГГГГГГВ╫В╫YнШч жГГГГГГГГГГГГГГГГГГГГГГГГшч╨жВ╫ жВ╫шчВ╫В╫В╫В╫В╫ШФВ╫ШФВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫шчВ╫yнВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫YнВ╫ жГГГГВ╫шчВ╫шчГГГГВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫8фВ╫В╫╨жшчВ╫В╫В╫В╫В╫YнфyнГГГГГГГГГ жГГГГ╨жВ╫YнВ╫ШФYнВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫шч жВ╫В╫В╫В╫В╫В╫yнВ╫ГШФВ╫В╫фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫ШФВ╫ГГГГГВ╫ШчВ╫YнГГШФГВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫8фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫ГГГГ жВ╫шчВ╫ГГГшч жВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫8фВ╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫В╫
|
||||
@ -16,7 +16,7 @@
|
||||
SUPPORTED_TARGETS = CTR-T*.Process.MPCore.fast
|
||||
CTR_APPTYPE = CARD
|
||||
|
||||
TARGET_PROGRAM = ConsoleRestore
|
||||
TARGET_PROGRAM = NetworkUpdater
|
||||
|
||||
SAMPLED_DEMOS_COMMON_INCLUDE_DIR = $(dir $(HORIZON_ROOT)/../CTR/SampleDemos/common/include)
|
||||
INCLUDES += $(SAMPLED_DEMOS_COMMON_INCLUDE_DIR) \
|
||||