ヒープチェックを行ってOKになったサイズまでのヒープを使うように

VersionDetectでヒープを使わないように

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@525 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2011-11-25 01:54:00 +00:00
parent 4133476962
commit a032646cb4
7 changed files with 194 additions and 75 deletions

View File

@ -19,6 +19,7 @@
#include "HeapManager.h"
#include "SaveDataChecker.h"
#include <nn/drivers/aes/CTR/ARM946ES/driverAes_Types.h>
#include "HeapChecker.h"
namespace ConsoleBackup
{
@ -58,6 +59,7 @@ void CheckSaveDataThreadFunc(bool erase)
common::HeapManager heap(bufSize);
if (heap.GetAddr() != NULL)
{
bufSize = GetCheckedHeapSize();
s_pChecker = new NandSavedataChecker(heap.GetAddr(), bufSize);
s_CheckerResult = s_pChecker->CleanUp(erase);
}

View File

@ -31,6 +31,7 @@ namespace
typedef enum BackupState
{
STARTUP, // 初期値
CHECK_FCRAM, // FCRAMの確認
CHECK_SAVEDATA, // セーブデータの確認
EXPORT_TWL_NAND, // TWLセーブデータ領域の吸出し中
EXPORT_TWL_SOUND, // TWLサウンド領域の吸出し中
@ -198,18 +199,48 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
if (nextStep && !error)
{
COMMON_LOGGER("Checking SaveData\n");
COMMON_LOGGER("Checking Memory\n");
if(forceDelete)
{
s_BackupMode = BACKUP_MODE_DELETE_IF_FAILED;
}
s_BackupState = CHECK_SAVEDATA;
s_BackupState = CHECK_FCRAM;
}
}
break;
case CHECK_FCRAM:
{
static bool init = true;
if (init)
{
// ヒープをチェックする
CheckFcram(manager);
init = false;
}
PutAliveMessage(operationMessage, "Checking Memory");
// 処理が完了した
if (IsExportThreadFinished())
{
FinalizeExportThread();
if (IsExportSucceeded())
{
COMMON_LOGGER("Checking SaveData\n");
s_BackupState = CHECK_SAVEDATA;
}
else
{
s_BackupState = FAIL;
}
}
}
break;
case CHECK_SAVEDATA:
{
static bool init = true;

View File

@ -162,24 +162,34 @@ nn::Result WriteTwlTitleList(std::vector<std::wstring>& programIdList)
}
common::HeapManager manager(heapSize);
char* titleListBuf = reinterpret_cast<char*> (manager.GetAddr());
size_t writeSize = 0;
if (titleListBuf != NULL)
if (manager.GetAddr() != 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');
}
heapSize = GetCheckedHeapSize();
char* titleListBuf = reinterpret_cast<char*>(manager.GetAddr());
common::SdReaderWriter sdWriter;
return sdWriter.WriteBufWithCmac(common::TWL_TITLELIST_PATHNAME, titleListBuf, writeSize);
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);
}
}
else
{
return nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
return nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_APPLICATION,
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
}
}
@ -501,6 +511,7 @@ void WriteTwlData(enum common::TWL_PATH_INDEX path)
void* buf = writeHeap.GetAddr();
if (buf != NULL)
{
bufSize = GetCheckedHeapSize();
nn::fs::FileOutputStream list;
result = list.TryInitialize(common::FILE_LIST_PATHNAME, true);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
@ -628,6 +639,7 @@ void WriteTwlSaveData()
void* buf = writeHeap.GetAddr();
if (buf != NULL)
{
bufSize = GetCheckedHeapSize();
nn::fs::FileOutputStream list;
result = list.TryInitialize(common::FILE_LIST_PATHNAME, true);
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
@ -758,7 +770,7 @@ nn::Result WriteMcuRtcData(common::HardwareStateManager& manager)
return nn::ResultSuccess();
}
void ExportThreadFunc(std::wstring saveRoot)
void ExportThreadFunc()
{
nn::Result result;
s_IsExportSucceeded = true;
@ -779,15 +791,7 @@ void ExportThreadFunc(std::wstring saveRoot)
void* buf = writeHeap.GetAddr();
if (buf != NULL)
{
NN_LOG("HeapCheck Start : %lld\n", nn::os::Tick::GetSystemCurrent().ToTimeSpan().GetMilliSeconds());
HeapChecker heapChecker;
result = heapChecker.Check(saveRoot, buf, bufSize);
if(result.IsFailure())
{
s_IsExportSucceeded = false;
return;
}
NN_LOG("HeapCheck End : %lld\n", nn::os::Tick::GetSystemCurrent().ToTimeSpan().GetMilliSeconds());
bufSize = GetCheckedHeapSize();
nn::fs::FileOutputStream list;
result = list.TryInitialize(common::FILE_LIST_PATHNAME, true);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
@ -826,7 +830,7 @@ void ExportThreadFunc(std::wstring saveRoot)
NN_LOG("Export Thread Finalize\n");
}
nn::Result WriteSaveData(::std::string& sysSaveRoot)
nn::Result WriteSaveData()
{
// NANDからSDカードに書き出し
nn::Result result;
@ -847,8 +851,6 @@ nn::Result WriteSaveData(::std::string& sysSaveRoot)
// 進捗表示用
common::InitializeTransferProgress(fileSize);
::std::mbstowcs(s_RootName, sysSaveRoot.c_str(), sysSaveRoot.size() + 1);
NN_LOG("%ls\n", (::std::wstring(common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH) + ::std::wstring(s_RootName) + ::std::wstring(L"/")).c_str());
// セーブデータディレクトリ以下のデータをSDカードにコピー
@ -861,11 +863,7 @@ nn::Result WriteSaveData(::std::string& sysSaveRoot)
COMMON_LOGGER("Export NAND Data Start...\n");
// SDにコピーするためのスレッドの作成
s_ExportThread.Start(
ExportThreadFunc,
::std::wstring(common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH) + ::std::wstring(s_RootName)
+ ::std::wstring(L"/"), s_ExportThreadStack
);
s_ExportThread.Start(ExportThreadFunc, s_ExportThreadStack);
return result;
}
@ -920,6 +918,55 @@ void AddShutDownPtmEvent()
nn::fnd::DateTime::GetNow());
}
void HeapCheckerFunc()
{
s_IsExportSucceeded = true;
size_t heapSize = common::GetAllocatableSize();
if(heapSize > common::FILE_COPY_HEAP_SIZE)
{
heapSize = common::FILE_COPY_HEAP_SIZE;
}
common::HeapManager heap(heapSize);
nn::Result result;
result = nn::fs::MountSpecialArchive(common::NAND_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
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);
result = CheckHeap(
(::std::wstring(common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH) + ::std::wstring(s_RootName)
+ ::std::wstring(L"/")).c_str(), heap.GetAddr(), heapSize);
if(result.IsFailure())
{
s_IsExportSucceeded = false;
}
result = common::SdMountManager::Unmount();
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
result = nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
}
void CheckFcram(common::HardwareStateManager& manager)
{
::std::string sysSaveRoot;
void* ivs;
size_t size;
manager.GetIvs(&ivs, &size);
// IVSからセーブデータディレクトリ名を計算
common::Util::GetSaveDataDirectoryRoot(sysSaveRoot, ivs, size);
::std::mbstowcs(s_RootName, sysSaveRoot.c_str(), sysSaveRoot.size() + 1);
NN_LOG("%ls\n", (::std::wstring(common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH) + ::std::wstring(s_RootName) + ::std::wstring(L"/")).c_str());
s_ExportThread.Start(HeapCheckerFunc, s_ExportThreadStack);
}
bool ExportData(common::HardwareStateManager& manager)
{
static bool init = true;
@ -963,15 +1010,8 @@ bool ExportData(common::HardwareStateManager& manager)
result = WriteVersionData(manager);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
::std::string systemSaveRoot;
void* ivs;
size_t size;
manager.GetIvs(&ivs, &size);
// IVSからセーブデータディレクトリ名を計算
common::Util::GetSaveDataDirectoryRoot(systemSaveRoot, ivs, size);
// NANDのセーブデータをSDに書き出す
result = WriteSaveData(systemSaveRoot);
result = WriteSaveData();
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
init = false;

View File

@ -54,6 +54,9 @@ void FinalizeExportThread();
// 出力が成功したかどうか
bool IsExportSucceeded();
// 新たにスレッドを起動して、メモリチェックを行う
void CheckFcram(common::HardwareStateManager& manager);
}
#endif /* EXPORTER_H_ */

View File

@ -22,9 +22,25 @@
namespace ConsoleBackup
{
HeapChecker::HeapChecker()
namespace
{
HeapChecker s_HeapChecker;
}
nn::Result CheckHeap(std::wstring saveRoot, void* buf, size_t& bufSize)
{
return s_HeapChecker.Check(saveRoot, buf, bufSize);
}
size_t GetCheckedHeapSize()
{
return s_HeapChecker.GetCheckedSize();
}
HeapChecker::HeapChecker() :
m_CheckedSize(0), m_IsAlreadyChecked(false)
{
// TODO 自動生成されたコンストラクター・スタブ
}
@ -35,6 +51,12 @@ HeapChecker::~HeapChecker()
nn::Result HeapChecker::Check(std::wstring saveRoot, void* buf, size_t& bufSize)
{
// 2回目のチェックは行わない
if(m_IsAlreadyChecked)
{
NN_PANIC("HeapChecker Already checked");
}
nn::Result result;
common::SdReaderWriter sdReaderWriter;
@ -44,6 +66,9 @@ nn::Result HeapChecker::Check(std::wstring saveRoot, void* buf, size_t& bufSize)
result = nandFile.TryInitialize(std::wstring(saveRoot + std::wstring(L"sysdata/00010026/00000000")).c_str());
if (result <= nn::fs::ResultNotFound())
{
COMMON_LOGGER("No Reference Data. Use Default Memory Size.\n");
m_CheckedSize = bufSize;
m_IsAlreadyChecked = true;
return nn::ResultSuccess();
}
}
@ -130,8 +155,22 @@ nn::Result HeapChecker::Check(std::wstring saveRoot, void* buf, size_t& bufSize)
}
else
{
m_CheckedSize = bufSize;
m_IsAlreadyChecked = true;
return nn::ResultSuccess();
}
}
size_t HeapChecker::GetCheckedSize()
{
if(m_IsAlreadyChecked)
{
return m_CheckedSize;
}
else
{
return 0;
}
}
} /* namespace ConsoleBackup */

View File

@ -23,8 +23,11 @@
namespace ConsoleBackup
{
nn::Result CheckHeap(std::wstring saveRoot, void* buf, size_t& bufSize);
size_t GetCheckedHeapSize();
//! @brief チェックするヒープサイズの下限です。
const size_t HEAP_SIZE_MIN = 1024;
const size_t HEAP_SIZE_MIN = 512 * 1024;
//! @brief チェックに使うファイルへのパスです。
const wchar_t* const HEAP_CHECKER_FILE = L"sdmc:/CTR_Console_Repair/Check";
@ -36,9 +39,9 @@ public:
virtual ~HeapChecker();
/*!
@brief 使SDカードに書き出し
bufSizeが設定されます
@brief 使NANDから読み出したデータをSDカードに書き出し
bufSizeが設定されます
@param[in] saveRoot NANDセーブデータのルートディレクトリのパス
@param[in] buf
@ -49,6 +52,19 @@ public:
*/
nn::Result Check(std::wstring saveRoot, void* buf, size_t& bufSize);
/*!
@brief
@return Check関数 Check関数が呼び出されていない場合は0
*/
size_t GetCheckedSize();
private:
size_t m_CheckedSize;
NN_PADDING3;
bool m_IsAlreadyChecked;
};
} /* namespace ConsoleBackup */

View File

@ -18,7 +18,6 @@
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
#include "VersionDetect.h"
#include "HeapManager.h"
#include "CommonLogger.h"
namespace common
@ -43,20 +42,15 @@ void GetCupVersion(nn::pl::CTR::CardUpdateVersion* cup, nn::cfg::CTR::CfgRegionC
{
s64 fileSize = fis.GetSize();
NN_LOG("version.bin size = %lld\n", fileSize);
s32 ret;
void* addr = NULL;
common::HeapManager heap(fileSize);
addr = heap.GetAddr();
if (addr != NULL)
{
result = fis.TryRead(&ret, addr, fileSize);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
if (result.IsSuccess())
{
nn::pl::CTR::CardUpdateVersion* ver_buf = reinterpret_cast<nn::pl::CTR::CardUpdateVersion*> (addr);
u8 fileBuf[BUF_SIZE];
std::memcpy(cup, ver_buf, sizeof(nn::pl::CTR::CardUpdateVersion));
}
s32 ret;
result = fis.TryRead(&ret, fileBuf, fileSize);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
if (result.IsSuccess())
{
nn::pl::CTR::CardUpdateVersion* ver_buf = reinterpret_cast<nn::pl::CTR::CardUpdateVersion*>(fileBuf);
std::memcpy(cup, ver_buf, sizeof(nn::pl::CTR::CardUpdateVersion));
}
}
fis.Finalize();
@ -86,21 +80,15 @@ void GetNupVersion(nn::pl::CTR::NetworkUpdateVersion* nup, nn::cfg::CTR::CfgRegi
{
s64 fileSize = fis.GetSize();
NN_LOG("version.bin size = %lld\n", fileSize);
s32 ret;
void* addr = NULL;
common::HeapManager heap(fileSize);
addr = heap.GetAddr();
if (addr != NULL)
{
result = fis.TryRead(&ret, addr, fileSize);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
if (result.IsSuccess())
{
nn::pl::CTR::NetworkUpdateVersion* ver_buf =
reinterpret_cast<nn::pl::CTR::NetworkUpdateVersion*> (addr);
u8 fileBuf[BUF_SIZE];
std::memcpy(nup, ver_buf, sizeof(nn::pl::CTR::NetworkUpdateVersion));
}
s32 ret;
result = fis.TryRead(&ret, fileBuf, fileSize);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
if (result.IsSuccess())
{
nn::pl::CTR::NetworkUpdateVersion* ver_buf = reinterpret_cast<nn::pl::CTR::NetworkUpdateVersion*>(fileBuf);
std::memcpy(nup, ver_buf, sizeof(nn::pl::CTR::NetworkUpdateVersion));
}
}