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
|
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
|
||||||
無線ON/OFF切り替えのため、`sources/common/nwm_ExtAPI.cpp` を
|
無線ON/OFF切り替えのため、`sources/common/nwm_ExtAPI.cpp` を
|
||||||
`$HORIZON_ROOT/sources/libraries/nwm/CTR`
|
`$HORIZON_ROOT/sources/libraries/nwm/CTR`
|
||||||
にコピーしてからnwmをリビルドする必要がある。
|
にコピーしてから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ビルドを使用する。
|
Releaseビルドは、ショップ接続時などにで無限ループする不具合があるためDevelopmentビルドを使用する。
|
||||||
|
|
||||||
その他
|
|
||||||
=====
|
|
||||||
|
|
||||||
PC上でのgoogletestを使う場合BOM付きのUTF-8を
|
|
||||||
コンパイルできるgccが必要。
|
|
||||||
cygwin 1.7.9-1
|
|
||||||
で動作確認済み。
|
|
||||||
`sources/tests/googletest/common/common.om`にgtestのインストール先を指定する必要がある
|
|
||||||
|
|
||||||
|
|||||||
|
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
|
SUPPORTED_TARGETS = CTR-T*.Process.MPCore.fast
|
||||||
CTR_APPTYPE = CARD
|
CTR_APPTYPE = CARD
|
||||||
|
|
||||||
TARGET_PROGRAM = ConsoleRestore
|
TARGET_PROGRAM = NetworkUpdater
|
||||||
|
|
||||||
SAMPLED_DEMOS_COMMON_INCLUDE_DIR = $(dir $(HORIZON_ROOT)/../CTR/SampleDemos/common/include)
|
SAMPLED_DEMOS_COMMON_INCLUDE_DIR = $(dir $(HORIZON_ROOT)/../CTR/SampleDemos/common/include)
|
||||||
INCLUDES += $(SAMPLED_DEMOS_COMMON_INCLUDE_DIR) \
|
INCLUDES += $(SAMPLED_DEMOS_COMMON_INCLUDE_DIR) \
|
||||||