吸出し前にセーブデータをチェックするように

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@415 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2011-08-02 07:39:03 +00:00
parent 5405bf2a6d
commit 8c6fb30493
8 changed files with 180 additions and 85 deletions

View File

@ -21,20 +21,73 @@
namespace ConsoleBackup namespace ConsoleBackup
{ {
bool CheckSaveData() namespace
{
const size_t CHECKER_STACK_SIZE = 0x1000;
nn::os::Thread s_CheckerThread;
nn::os::StackBuffer<CHECKER_STACK_SIZE> s_CheckerThreadStackSize;
nn::Result s_CheckerResult;
NandSavedataChecker* s_pChecker;
}
s32 GetCheckSaveDataProgress()
{
if(s_pChecker != NULL)
{
return s_pChecker->GetProgress();
}
else
{
return 0;
}
}
void CheckSaveDataThreadFunc()
{ {
size_t bufSize = common::GetAllocatableSize(); size_t bufSize = common::GetAllocatableSize();
common::HeapManager heap(bufSize); common::HeapManager heap(bufSize);
if(heap.GetAddr() != NULL) if (heap.GetAddr() != NULL)
{ {
NandSavedataChecker checker(heap.GetAddr(), bufSize); s_pChecker = new NandSavedataChecker(heap.GetAddr(), bufSize);
nn::Result result = checker.CleanUp(); s_CheckerResult = s_pChecker->CleanUp();
return result.IsSuccess();
} }
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);
return false; }
}
void StartSaveDataCheck()
{
s_CheckerThread.Start(CheckSaveDataThreadFunc, s_CheckerThreadStackSize);
}
bool IsCheckSaveDataFinished()
{
return s_CheckerThread.IsValid() && !s_CheckerThread.IsAlive();
}
void FinalizeSaveDataCheck()
{
s_CheckerThread.Join();
s_CheckerThread.Finalize();
if(s_pChecker != NULL)
{
delete s_pChecker;
}
}
bool CheckSaveDataSucceeded()
{
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(s_CheckerResult);
return s_CheckerResult.IsSuccess();
} }
} }

View File

@ -19,7 +19,11 @@
namespace ConsoleBackup namespace ConsoleBackup
{ {
bool CheckSaveData(); s32 GetCheckSaveDataProgress();
void StartSaveDataCheck();
bool IsCheckSaveDataFinished();
void FinalizeSaveDataCheck();
bool CheckSaveDataSucceeded();
} }

View File

@ -18,6 +18,7 @@
#include "Exporter.h" #include "Exporter.h"
#include "SimplePlayer.h" #include "SimplePlayer.h"
#include "CommonLogger.h" #include "CommonLogger.h"
#include "Checker.h"
#include <nn.h> #include <nn.h>
@ -30,6 +31,7 @@ namespace
typedef enum BackupState typedef enum BackupState
{ {
STARTUP, // 初期値 STARTUP, // 初期値
CHECK_SAVEDATA, // セーブデータの確認
EXPORT_TWL_NAND, // TWLセーブデータ領域の吸出し中 EXPORT_TWL_NAND, // TWLセーブデータ領域の吸出し中
EXPORT_TWL_SOUND, // TWLサウンド領域の吸出し中 EXPORT_TWL_SOUND, // TWLサウンド領域の吸出し中
EXPORT_TWL_PHOTO, // TWL写真領域の吸出し中 EXPORT_TWL_PHOTO, // TWL写真領域の吸出し中
@ -145,14 +147,41 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
if (nextStep && !error) if (nextStep && !error)
{ {
COMMON_LOGGER("Start Export Data\n"); COMMON_LOGGER("Checking SaveData\n");
s_BackupState = EXPORT_TWL_NAND; s_BackupState = CHECK_SAVEDATA;
} }
} }
break; break;
case CHECK_SAVEDATA:
{
static bool init = true;
if (init)
{
StartSaveDataCheck();
init = false;
}
if (IsCheckSaveDataFinished())
{
FinalizeSaveDataCheck();
if (CheckSaveDataSucceeded())
{
COMMON_LOGGER("Start Export Data\n");
s_BackupState = EXPORT_TWL_NAND;
}
else
{
s_BackupState = FAIL;
}
}
}
break;
// TWLセーブデータ領域の吸出し中 // TWLセーブデータ領域の吸出し中
case EXPORT_TWL_NAND: case EXPORT_TWL_NAND:
{ {
@ -269,7 +298,7 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
{ {
COMMON_LOGGER("Export NAND Data Finished.\n"); COMMON_LOGGER("Export NAND Data Finished.\n");
if (GetProgress() > 99) if (GetExportProgress() > 99)
{ {
s_BackupState = DELETE_NIM; s_BackupState = DELETE_NIM;
} }
@ -342,6 +371,18 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
} }
} }
u32 GetProgress()
{
if(s_BackupState == CHECK_SAVEDATA)
{
return GetCheckSaveDataProgress();
}
else
{
return GetExportProgress();
}
}
bool InProgress() bool InProgress()
{ {
return s_BackupState == EXPORT_CTR_NAND; return s_BackupState == EXPORT_CTR_NAND;

View File

@ -46,6 +46,9 @@ void OnSdEjected();
// 状態を初期化する // 状態を初期化する
void InitializeState(); void InitializeState();
// 進捗を取得する
u32 GetProgress();
} }
#endif /* CONTOROLLER_H_ */ #endif /* CONTOROLLER_H_ */

View File

@ -949,7 +949,7 @@ bool ExportData(common::HardwareStateManager& manager)
return true; return true;
} }
u32 GetProgress() u32 GetExportProgress()
{ {
return common::GetProgress(); return common::GetProgress();
} }

View File

@ -43,7 +43,7 @@ bool ExportData(common::HardwareStateManager& manager);
bool DeleteNimSaveData(); bool DeleteNimSaveData();
// 出力スレッドの進捗を返す // 出力スレッドの進捗を返す
u32 GetProgress(); u32 GetExportProgress();
// 出力スレッドが終了したかどうか // 出力スレッドが終了したかどうか
bool IsExportThreadFinished(); bool IsExportThreadFinished();

View File

@ -36,7 +36,7 @@ SavedataCheckerBase::SavedataCheckerBase(void* buf, size_t size) :
SavedataCheckerBase::~SavedataCheckerBase() SavedataCheckerBase::~SavedataCheckerBase()
{ {
NN_LOG("m_TotalReadSize = %d\n", m_TotalReadSize); NN_LOG("m_TotalReadSize = %lld\n", m_TotalReadSize);
} }
nn::Result SavedataCheckerBase::CleanUpFilesRecursively(bool* modified, std::wstring currentDirectory) nn::Result SavedataCheckerBase::CleanUpFilesRecursively(bool* modified, std::wstring currentDirectory)
@ -45,7 +45,7 @@ nn::Result SavedataCheckerBase::CleanUpFilesRecursively(bool* modified, std::wst
nn::fs::DirectoryEntry entry; nn::fs::DirectoryEntry entry;
nn::Result result; nn::Result result;
COMMON_LOGGER("%s\n", common::GetCharStr(currentDirectory.c_str())); NN_LOG("%s\n", common::GetCharStr(currentDirectory.c_str()));
result = dir.TryInitialize(currentDirectory.c_str()); result = dir.TryInitialize(currentDirectory.c_str());
if(result.IsFailure()) if(result.IsFailure())
{ {
@ -92,13 +92,11 @@ nn::Result SavedataCheckerBase::CleanUpFilesRecursively(bool* modified, std::wst
std::wstring filePath = (currentDirectory + std::wstring(entry.entryName)).c_str(); std::wstring filePath = (currentDirectory + std::wstring(entry.entryName)).c_str();
const wchar_t* path = filePath.c_str(); const wchar_t* path = filePath.c_str();
COMMON_LOGGER("%s\n", common::GetCharStr(path));
result = file.TryInitialize(path); result = file.TryInitialize(path);
if(result.IsFailure()) if(result.IsFailure())
{ {
nn::dbg::PrintResult(result); nn::dbg::PrintResult(result);
COMMON_LOGGER("Cannot Initialize %s, delete.\n", common::GetCharStr(path)); COMMON_LOGGER_WARN("Cannot Initialize %s, delete.\n", common::GetCharStr(entry.entryName));
result = nn::fs::TryDeleteFile(path); result = nn::fs::TryDeleteFile(path);
*modified = true; *modified = true;
continue; continue;
@ -108,18 +106,21 @@ nn::Result SavedataCheckerBase::CleanUpFilesRecursively(bool* modified, std::wst
{ {
s32 readSize; s32 readSize;
result = file.TryRead(&readSize, m_Buf, m_Bufsize); result = file.TryRead(&readSize, m_Buf, m_Bufsize);
m_TotalReadSize += readSize;
if(result.IsFailure()) if(result.IsFailure())
{ {
nn::dbg::PrintResult(result); nn::dbg::PrintResult(result);
COMMON_LOGGER("Cannot read %s, delete.\n", common::GetCharStr(path)); COMMON_LOGGER_WARN("Cannot read %s, delete.\n", common::GetCharStr(entry.entryName));
m_TotalReadSize += file.GetSize();
file.Finalize(); file.Finalize();
result = nn::fs::TryDeleteFile(path); result = nn::fs::TryDeleteFile(path);
COMMON_LOGGER_RESULT_IF_FAILED(result); COMMON_LOGGER_RESULT_IF_FAILED(result);
*modified = true; *modified = true;
break; break;
} }
else
{
m_TotalReadSize += readSize;
}
if(readSize == 0) if(readSize == 0)
{ {
@ -138,7 +139,7 @@ nn::Result SavedataCheckerBase::GetFileSize(std::wstring currentDirectory)
nn::fs::DirectoryEntry entry; nn::fs::DirectoryEntry entry;
nn::Result result; nn::Result result;
COMMON_LOGGER("%s\n", common::GetCharStr(currentDirectory.c_str())); NN_LOG("%s\n", common::GetCharStr(currentDirectory.c_str()));
result = dir.TryInitialize(currentDirectory.c_str()); result = dir.TryInitialize(currentDirectory.c_str());
if(result.IsFailure()) if(result.IsFailure())
{ {
@ -178,8 +179,6 @@ nn::Result SavedataCheckerBase::GetFileSize(std::wstring currentDirectory)
std::wstring filePath = (currentDirectory + std::wstring(entry.entryName)).c_str(); std::wstring filePath = (currentDirectory + std::wstring(entry.entryName)).c_str();
const wchar_t* path = filePath.c_str(); const wchar_t* path = filePath.c_str();
COMMON_LOGGER("%s\n", common::GetCharStr(path));
result = file.TryInitialize(path); result = file.TryInitialize(path);
if(result.IsFailure()) if(result.IsFailure())
{ {
@ -193,20 +192,15 @@ nn::Result SavedataCheckerBase::GetFileSize(std::wstring currentDirectory)
return nn::ResultSuccess(); return nn::ResultSuccess();
} }
nn::Result SavedataCheckerBase::GetProgress(s32* progress) s64 SavedataCheckerBase::GetCalculatedSize()
{ {
if(m_CalculatedFileSize != 0) return m_CalculatedFileSize;
{
*progress = m_TotalReadSize * 100 / m_CalculatedFileSize;
}
else
{
*progress = 0;
}
return nn::ResultSuccess();
} }
s64 SavedataCheckerBase::GetTotalReadSize()
{
return m_TotalReadSize;
}
NandSavedataChecker::NandSavedataChecker() NandSavedataChecker::NandSavedataChecker()
@ -217,38 +211,45 @@ NandSavedataChecker::NandSavedataChecker()
NandSavedataChecker::NandSavedataChecker(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size) 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() NandSavedataChecker::~NandSavedataChecker()
{ {
// TODO Auto-generated destructor stub delete m_pSharedExtSaveChecker;
delete m_pSysSaveChecker;
} }
nn::Result NandSavedataChecker::CleanUp() nn::Result NandSavedataChecker::CleanUp()
{ {
nn::Result result; nn::Result result;
{ m_pSharedExtSaveChecker->CalculateFileSize();
SharedExtSavedataChecker sharedExtSaveChecker(m_Buf, m_Bufsize); m_pSysSaveChecker->CalculateFileSize();
result = sharedExtSaveChecker.CalculateFileSize();
NN_UTIL_RETURN_IF_FAILED(result);
result = sharedExtSaveChecker.CleanUp();
NN_UTIL_RETURN_IF_FAILED(result);
}
{ result = m_pSharedExtSaveChecker->CleanUp();
SystemSavedataChecker syssaveChecker(m_Buf, m_Bufsize); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = syssaveChecker.CalculateFileSize();
NN_UTIL_RETURN_IF_FAILED(result);
result = syssaveChecker.CleanUp();
NN_UTIL_RETURN_IF_FAILED(result);
}
result = m_pSysSaveChecker->CleanUp();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
return nn::ResultSuccess(); 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());
}
}
SystemSavedataChecker::SystemSavedataChecker() SystemSavedataChecker::SystemSavedataChecker()
{ {
@ -302,7 +303,7 @@ nn::Result SystemSavedataChecker::CleanUp()
} }
} }
return result; return nn::ResultSuccess();
} }
nn::Result SystemSavedataChecker::CalculateFileSize() nn::Result SystemSavedataChecker::CalculateFileSize()
@ -322,7 +323,7 @@ nn::Result SystemSavedataChecker::CalculateFileSize()
} }
} }
NN_LOG("CalculatedFileSize = %d\n", m_CalculatedFileSize); NN_LOG("CalculatedFileSize = %lld\n", m_CalculatedFileSize);
return result; return result;
} }
@ -350,7 +351,7 @@ nn::Result SharedExtSavedataChecker::CleanUp()
bit32 IdArray[ARRAY_SIZE]; bit32 IdArray[ARRAY_SIZE];
result = nn::fs::EnumerateSharedExtSaveData(&numId, IdArray, ARRAY_SIZE); result = nn::fs::EnumerateSharedExtSaveData(&numId, IdArray, ARRAY_SIZE);
NN_UTIL_RETURN_IF_FAILED(result); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
NN_LOG_DEBUG("ExtData num = %d\n", numId); NN_LOG_DEBUG("ExtData num = %d\n", numId);
bool modified = false; bool modified = false;
@ -359,28 +360,13 @@ nn::Result SharedExtSavedataChecker::CleanUp()
if (nn::fs::MountSharedExtSaveData(SHARED_EXT_SAVEDATA_ARCHIVE_NAME, IdArray[i]).IsSuccess()) if (nn::fs::MountSharedExtSaveData(SHARED_EXT_SAVEDATA_ARCHIVE_NAME, IdArray[i]).IsSuccess())
{ {
NN_LOG("Mount %x\n", IdArray[i]); NN_LOG("Mount %x\n", IdArray[i]);
s64 totalBlockSize;
s64 leftBlockSize;
s32 blockSize;
if (nn::fs::GetSharedExtSaveDataBlockSize(&totalBlockSize, &leftBlockSize, &blockSize, IdArray[i]).IsSuccess())
{
// アーカイブ内のファイル・ディレクトリをチェックする
result = CleanUpFilesRecursively(&modified, L"shext:/");
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = nn::fs::Unmount(SHARED_EXT_SAVEDATA_ARCHIVE_NAME); // アーカイブ内のファイル・ディレクトリをチェックする
NN_UTIL_RETURN_IF_FAILED(result); result = CleanUpFilesRecursively(&modified, L"shext:/");
} COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
else
{
// アーカイブごと削除する
result = nn::fs::Unmount(SHARED_EXT_SAVEDATA_ARCHIVE_NAME);
NN_UTIL_RETURN_IF_FAILED(result);
result = nn::fs::DeleteSharedExtSaveData(IdArray[i]);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
}
result = nn::fs::Unmount(SHARED_EXT_SAVEDATA_ARCHIVE_NAME);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
} }
else else
{ {
@ -409,7 +395,7 @@ nn::Result SharedExtSavedataChecker::CalculateFileSize()
bit32 IdArray[ARRAY_SIZE]; bit32 IdArray[ARRAY_SIZE];
result = nn::fs::EnumerateSharedExtSaveData(&numId, IdArray, ARRAY_SIZE); result = nn::fs::EnumerateSharedExtSaveData(&numId, IdArray, ARRAY_SIZE);
NN_UTIL_RETURN_IF_FAILED(result); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
NN_LOG_DEBUG("ExtData num = %d\n", numId); NN_LOG_DEBUG("ExtData num = %d\n", numId);
for (s32 i = 0; i < numId; i++ ) for (s32 i = 0; i < numId; i++ )
@ -418,14 +404,14 @@ nn::Result SharedExtSavedataChecker::CalculateFileSize()
if (result.IsSuccess()) if (result.IsSuccess())
{ {
result = GetFileSize(L"shext:/"); result = GetFileSize(L"shext:/");
NN_UTIL_RETURN_IF_FAILED(result); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = nn::fs::Unmount(SHARED_EXT_SAVEDATA_ARCHIVE_NAME); result = nn::fs::Unmount(SHARED_EXT_SAVEDATA_ARCHIVE_NAME);
NN_UTIL_RETURN_IF_FAILED(result); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
} }
} }
NN_LOG("CalculatedFileSize = %d\n", m_CalculatedFileSize); NN_LOG("CalculatedFileSize = %lld\n", m_CalculatedFileSize);
return nn::ResultSuccess(); return nn::ResultSuccess();
} }

View File

@ -124,6 +124,12 @@ public:
virtual nn::Result CleanUp() = 0; virtual nn::Result CleanUp() = 0;
virtual nn::Result CalculateFileSize() = 0; virtual nn::Result CalculateFileSize() = 0;
//! @return 事前に計算したサイズ
s64 GetCalculatedSize();
//! @return 読み取ったサイズ
s64 GetTotalReadSize();
protected: protected:
//! @brief ファイルとディレクトリを再帰的にチェックする。エラーがあれば削除する //! @brief ファイルとディレクトリを再帰的にチェックする。エラーがあれば削除する
//! @param[out] modified ファイルかディレクトリを削除したかどうか //! @param[out] modified ファイルかディレクトリを削除したかどうか
@ -134,22 +140,19 @@ protected:
//! @param[out] size ファイルサイズ //! @param[out] size ファイルサイズ
//! @param[in] currentDirectory チェックを開始するディレクトリ。スラッシュで終端すること。 //! @param[in] currentDirectory チェックを開始するディレクトリ。スラッシュで終端すること。
nn::Result GetFileSize(std::wstring currentDirectory); nn::Result GetFileSize(std::wstring currentDirectory);
//! @brief 進捗を取得する
//! @param[out] progress 0~100で表される進捗
nn::Result GetProgress(s32* progress);
//! バッファ //! バッファ
void* m_Buf; void* m_Buf;
//! バッファサイズ //! バッファサイズ
size_t m_Bufsize; size_t m_Bufsize;
NN_PADDING4;
//! 事前読み取りサイズ //! 事前読み取りサイズ
size_t m_CalculatedFileSize; s64 m_CalculatedFileSize;
//! 累計読み取りサイズ //! 累計読み取りサイズ
size_t m_TotalReadSize; s64 m_TotalReadSize;
}; };
@ -194,7 +197,12 @@ public:
nn::Result CleanUp(); nn::Result CleanUp();
s64 GetProgress();
private: private:
SharedExtSavedataChecker* m_pSharedExtSaveChecker;
SystemSavedataChecker* m_pSysSaveChecker;
//! バッファ //! バッファ
void* m_Buf; void* m_Buf;