mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@474 385bec56-5757-e545-9c3a-d8741f4650f1
205 lines
6.1 KiB
C++
205 lines
6.1 KiB
C++
/*---------------------------------------------------------------------------*
|
|
Project: Horizon
|
|
File: SaveDataMover.cpp
|
|
|
|
Copyright 2009-2011 Nintendo. All rights reserved.
|
|
|
|
These coded instructions, statements, and computer programs contain
|
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
|
Company Ltd., and are protected by Federal copyright law. They may
|
|
not be disclosed to third parties or copied or duplicated in any form,
|
|
in whole or in part, without the prior written consent of Nintendo.
|
|
|
|
$Rev$
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
#include <string>
|
|
|
|
#include <nn/fs/fs_ApiSysSaveData.h>
|
|
#include <nn/fs/fs_ApiDeviceMove.h>
|
|
|
|
#include <nn/ndm.h>
|
|
|
|
#include "SaveDataMover.h"
|
|
#include "CommonLogger.h"
|
|
#include "FileName.h"
|
|
#include "SdReaderWriter.h"
|
|
|
|
|
|
namespace common
|
|
{
|
|
|
|
namespace
|
|
{
|
|
const s32 MAX_SYSTEM_SAVE_DATA_ID_NUM = 256;
|
|
nn::fs::SystemSaveDataId s_SystemSaveDataIdList[MAX_SYSTEM_SAVE_DATA_ID_NUM * sizeof(bit32)];
|
|
|
|
|
|
bool IsNotMovedId(bit32 id)
|
|
{
|
|
return id == 0x0001002c; // nim
|
|
}
|
|
|
|
}
|
|
|
|
|
|
SaveDataMover::SaveDataMover() :
|
|
m_Progress(0), m_FinishedSize(0), m_TotalSize(0), m_Result(nn::ResultSuccess())
|
|
{
|
|
// TODO 自動生成されたコンストラクター・スタブ
|
|
}
|
|
|
|
SaveDataMover::~SaveDataMover()
|
|
{
|
|
// TODO Auto-generated destructor stub
|
|
}
|
|
|
|
void SaveDataMover::StartExport(void* buf, size_t bufSize, u64* progress)
|
|
{
|
|
SetupExport();
|
|
CalculateFileSize();
|
|
if(GetLastResult().IsFailure())
|
|
{
|
|
return;
|
|
}
|
|
ExportSystemSaveData(buf, bufSize, progress);
|
|
}
|
|
|
|
nn::Result SaveDataMover::GetLastResult()
|
|
{
|
|
return m_Result;
|
|
}
|
|
|
|
void SaveDataMover::SetupExport()
|
|
{
|
|
// 1. デーモンの停止
|
|
m_Result = nn::ndm::Initialize();
|
|
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
|
m_Result = nn::ndm::SuspendScheduler();
|
|
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
|
|
|
// 2. StartDeviceMoveAsSource
|
|
nn::fs::DeviceMoveContext moveContext;
|
|
m_Result = nn::fs::StartDeviceMoveAsSource(&moveContext);
|
|
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
|
|
|
// 3. 出力用ディレクトリの作成
|
|
common::SdReaderWriter sdWriter;
|
|
m_Result = sdWriter.CreateDirectory((::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(
|
|
common::SD_SAVEDATA_ROOT_NAME) + std::wstring(common::SD_SAEVDATA_SYS_NAME)).c_str());
|
|
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
|
}
|
|
|
|
void SaveDataMover::CalculateFileSize()
|
|
{
|
|
s32 systemSaveDataIdNum;
|
|
m_Result = nn::fs::EnumerateSystemSaveData(&systemSaveDataIdNum, s_SystemSaveDataIdList, MAX_SYSTEM_SAVE_DATA_ID_NUM);
|
|
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
|
|
|
for(int i = 0; i < systemSaveDataIdNum; ++i)
|
|
{
|
|
nn::fs::FileInputStream input;
|
|
|
|
bit32 id = s_SystemSaveDataIdList[i];
|
|
if(IsNotMovedId(id))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
m_Result = nn::fs::OpenSystemSaveDataRawStorageFile(&input, id);
|
|
if(m_Result.IsFailure())
|
|
{
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(m_Result);
|
|
continue;
|
|
}
|
|
|
|
m_TotalSize += input.GetSize();
|
|
}
|
|
}
|
|
|
|
void SaveDataMover::ExportSystemSaveData(void* buf, size_t bufSize, u64* progress)
|
|
{
|
|
s64 totalFileSize = 0;
|
|
|
|
// 0. ID の列挙を行う。
|
|
s32 systemSaveDataIdNum;
|
|
m_Result = nn::fs::EnumerateSystemSaveData(&systemSaveDataIdNum, s_SystemSaveDataIdList, MAX_SYSTEM_SAVE_DATA_ID_NUM);
|
|
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
|
|
|
for(int i = 0; i < systemSaveDataIdNum; ++i)
|
|
{
|
|
nn::fs::FileInputStream input;
|
|
|
|
bit32 id = s_SystemSaveDataIdList[i];
|
|
if(IsNotMovedId(id))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
NN_LOG("id: %08x\n", id);
|
|
|
|
// 1. fs::OpenSystemSaveDataRawStorageFile を呼び
|
|
// ID に対するセーブデータの FileInputStream を得る。
|
|
m_Result = nn::fs::OpenSystemSaveDataRawStorageFile(&input, id);
|
|
if(m_Result.IsFailure())
|
|
{
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(m_Result);
|
|
continue;
|
|
}
|
|
NN_LOG("fileSize = %lld\n", input.GetSize());
|
|
totalFileSize += input.GetSize();
|
|
|
|
// SD へコピー
|
|
{
|
|
char outPath[64];
|
|
nn::nstd::TSNPrintf(outPath, 64, "%s/%08x", SD_SAVEDATA_SYS_ROOT_PATH, id);
|
|
NN_LOG("outPath = %s\n", outPath);
|
|
nn::fs::FileOutputStream output;
|
|
m_Result = output.TryInitialize(outPath, true);
|
|
if(m_Result.IsFailure())
|
|
{
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(m_Result);
|
|
continue;
|
|
}
|
|
|
|
// 2. 1 で得たストリームからデータを読み込む。
|
|
// 本来はここで読み込んだデータを引っ越し先に転送するが
|
|
// ここでは SD カードにエクスポートする。
|
|
m_Result = CopyFile(input, output, buf, bufSize, progress);
|
|
if(m_Result.IsFailure())
|
|
{
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(m_Result);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
NN_LOG("\n");
|
|
|
|
NN_LOG("totalFileSize = %lld\n", totalFileSize);
|
|
}
|
|
|
|
// ファイルの読み書き
|
|
nn::Result SaveDataMover::CopyFile(nn::fs::FileInputStream& is, nn::fs::FileOutputStream& os, void* pBuffer,
|
|
const s32 bufferSize, u64* progress)
|
|
{
|
|
s64 restSize;
|
|
NN_UTIL_RETURN_IF_FAILED(is.TryGetSize(&restSize));
|
|
|
|
while (restSize > 0)
|
|
{
|
|
s32 readSize = restSize > bufferSize ? bufferSize : restSize;
|
|
s32 read = 0;
|
|
s32 write = 0;
|
|
NN_UTIL_RETURN_IF_FAILED(is.TryRead(&read, pBuffer, readSize));
|
|
NN_UTIL_RETURN_IF_FAILED(os.TryWrite(&write, pBuffer, read));
|
|
|
|
restSize -= read;
|
|
m_FinishedSize += read;
|
|
*progress = m_FinishedSize * 100 / m_TotalSize;
|
|
NN_LOG("progress = %lld\n", *progress);
|
|
}
|
|
return nn::ResultSuccess();
|
|
}
|
|
|
|
} /* namespace common */
|