共有拡張セーブデータをチェックするように

アーカイブ内のファイルを個別に削除できるように

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@413 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2011-08-01 06:55:00 +00:00
parent c2a810b8c4
commit 718e114848
3 changed files with 193 additions and 129 deletions

View File

@ -27,7 +27,7 @@ bool CheckSaveData()
common::HeapManager heap(bufSize); common::HeapManager heap(bufSize);
if(heap.GetAddr() != NULL) if(heap.GetAddr() != NULL)
{ {
SavedataChecker checker(heap.GetAddr(), bufSize); NandSavedataChecker checker(heap.GetAddr(), bufSize);
nn::Result result = checker.CleanUp(); nn::Result result = checker.CleanUp();
return result.IsSuccess(); return result.IsSuccess();
} }

View File

@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Project: Horizon Project: Horizon
File: SavedataChecker.cpp File: NandSavedataChecker.cpp
Copyright 2009 Nintendo. All rights reserved. Copyright 2009 Nintendo. All rights reserved.
@ -28,37 +28,134 @@ namespace
} }
SavedataCheckerBase::SavedataCheckerBase(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size)
{
SavedataChecker::SavedataChecker() }
nn::Result SavedataCheckerBase::CleanUpFilesRecursively(bool* modified, std::wstring currentDirectory)
{
nn::fs::Directory dir;
nn::fs::DirectoryEntry entry;
nn::Result result;
COMMON_LOGGER("%s\n", common::GetCharStr(currentDirectory.c_str()));
result = dir.TryInitialize(currentDirectory.c_str());
if(result.IsFailure())
{
COMMON_LOGGER_WARN("Delete Directory %s\n", common::GetCharStr(currentDirectory.c_str()));
result = nn::fs::TryDeleteDirectory(currentDirectory.c_str());
*modified = true;
return result;
}
for (;;)
{
s32 numRead;
result = dir.TryRead(&numRead, &entry, 1);
if(result.IsFailure())
{
dir.Finalize();
COMMON_LOGGER_WARN("Delete Directory %s\n", common::GetCharStr(currentDirectory.c_str()));
result = nn::fs::TryDeleteDirectoryRecursively(currentDirectory.c_str());
*modified = true;
continue;
}
if(numRead == 0)
{
break;
}
if (std::wcscmp(entry.entryName, L".") == 0 || std::wcscmp(entry.entryName, L"..") == 0)
{
continue;
}
// ディレクトリの場合
if (entry.attributes.isDirectory)
{
return CleanUpFilesRecursively(modified, currentDirectory + std::wstring(entry.entryName) + std::wstring(L"/"));
}
// ファイルの場合
else
{
nn::fs::FileInputStream file;
std::wstring filePath = (currentDirectory + std::wstring(entry.entryName)).c_str();
const wchar_t* path = filePath.c_str();
COMMON_LOGGER("%s\n", common::GetCharStr(path));
result = file.TryInitialize(path);
if(result.IsFailure())
{
nn::dbg::PrintResult(result);
COMMON_LOGGER("Cannot Initialize %s, delete.\n", common::GetCharStr(path));
result = nn::fs::TryDeleteFile(path);
*modified = true;
continue;
}
for (;;)
{
s32 readSize;
result = file.TryRead(&readSize, m_Buf, m_Bufsize);
if(result.IsFailure())
{
nn::dbg::PrintResult(result);
COMMON_LOGGER("Cannot read %s, delete.\n", common::GetCharStr(path));
file.Finalize();
result = nn::fs::TryDeleteFile(path);
COMMON_LOGGER_RESULT_IF_FAILED(result);
*modified = true;
break;
}
if(readSize == 0)
{
break;
}
}
}
}
return nn::ResultSuccess();
}
NandSavedataChecker::NandSavedataChecker()
{ {
// TODO 自動生成されたコンストラクター・スタブ // TODO 自動生成されたコンストラクター・スタブ
} }
SavedataChecker::SavedataChecker(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size) NandSavedataChecker::NandSavedataChecker(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size)
{ {
} }
SavedataChecker::~SavedataChecker() NandSavedataChecker::~NandSavedataChecker()
{ {
// TODO Auto-generated destructor stub // TODO Auto-generated destructor stub
} }
nn::Result SavedataChecker::CleanUp() nn::Result NandSavedataChecker::CleanUp()
{ {
nn::Result result; nn::Result result;
{
SharedExtSavedataChecker sharedExtSaveChecker(m_Buf, m_Bufsize);
result = sharedExtSaveChecker.CleanUp();
NN_UTIL_RETURN_IF_FAILED(result);
}
{ {
SystemSavedataChecker syssaveChecker(m_Buf, m_Bufsize); SystemSavedataChecker syssaveChecker(m_Buf, m_Bufsize);
result = syssaveChecker.CleanUp(); result = syssaveChecker.CleanUp();
NN_UTIL_RETURN_IF_FAILED(result); NN_UTIL_RETURN_IF_FAILED(result);
} }
{
SharedExtSavedataChecker sharedExtSaveChecker(m_Buf, m_Bufsize);
result = sharedExtSaveChecker.CleanUp();
NN_UTIL_RETURN_IF_FAILED(result);
}
return nn::ResultSuccess(); return nn::ResultSuccess();
} }
@ -68,7 +165,7 @@ SystemSavedataChecker::SystemSavedataChecker()
} }
SystemSavedataChecker::SystemSavedataChecker(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size) SystemSavedataChecker::SystemSavedataChecker(void* buf, size_t size) : SavedataCheckerBase(buf, size)
{ {
} }
@ -96,6 +193,7 @@ nn::Result SystemSavedataChecker::CleanUp()
// 削除する // 削除する
COMMON_LOGGER_WARN("Delete Savedata %s\n", common::GetCharStr(SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str())); COMMON_LOGGER_WARN("Delete Savedata %s\n", common::GetCharStr(SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str()));
result = nn::fs::DeleteSystemSaveData(SYSTEM_SAVEDATA_COUPLE_LIST[i].id); result = nn::fs::DeleteSystemSaveData(SYSTEM_SAVEDATA_COUPLE_LIST[i].id);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
} }
} }
else else
@ -103,12 +201,12 @@ nn::Result SystemSavedataChecker::CleanUp()
NN_LOG("Mount %ls\n", SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str()); NN_LOG("Mount %ls\n", SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str());
// ファイルを個別にチェックする // ファイルを個別にチェックする
result = CleanUpFilesRecursively(&modified, L"ssave:/"); result = CleanUpFilesRecursively(&modified, L"ssave:/");
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
if(modified) if(modified)
{ {
result = nn::fs::CommitSystemSaveData(SYSTEM_SAVEDATA_ARCHIVE_NAME); result = nn::fs::CommitSystemSaveData(SYSTEM_SAVEDATA_ARCHIVE_NAME);
} }
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = nn::fs::Unmount("ssave:"); result = nn::fs::Unmount("ssave:");
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
@ -119,98 +217,11 @@ nn::Result SystemSavedataChecker::CleanUp()
return result; return result;
} }
nn::Result SystemSavedataChecker::CleanUpFilesRecursively(bool* modifiled, std::wstring currentDirectory)
{
nn::fs::Directory dir;
nn::fs::DirectoryEntry entry;
nn::Result result;
COMMON_LOGGER("%s\n", common::GetCharStr(currentDirectory.c_str()));
result = dir.TryInitialize(currentDirectory.c_str());
if(result.IsFailure())
{
COMMON_LOGGER_WARN("Delete Directory %s\n", common::GetCharStr(currentDirectory.c_str()));
result = nn::fs::TryDeleteDirectory(currentDirectory.c_str());
*modifiled = true;
return result;
}
for (;;)
{
s32 numRead;
result = dir.TryRead(&numRead, &entry, 1);
if(result.IsFailure())
{
COMMON_LOGGER_WARN("Delete Directory %s\n", common::GetCharStr(currentDirectory.c_str()));
result = nn::fs::TryDeleteDirectoryRecursively(currentDirectory.c_str());
*modifiled = true;
continue;
}
if(numRead == 0)
{
break;
}
if (std::wcscmp(entry.entryName, L".") == 0 || std::wcscmp(entry.entryName, L"..") == 0)
{
continue;
}
// ディレクトリの場合
if (entry.attributes.isDirectory)
{
return CleanUpFilesRecursively(modifiled, currentDirectory + std::wstring(entry.entryName) + std::wstring(L"/"));
}
// ファイルの場合
else
{
nn::fs::FileInputStream file;
std::wstring filePath = (currentDirectory + std::wstring(entry.entryName)).c_str();
const wchar_t* path = filePath.c_str();
COMMON_LOGGER("%s\n", common::GetCharStr(path));
result = file.TryInitialize(path);
if(result.IsFailure())
{
COMMON_LOGGER("Cannot Initialize %ls, delete.\n", common::GetCharStr(path));
result = nn::fs::TryDeleteFile(path);
*modifiled = true;
continue;
}
for (;;)
{
s32 readSize;
result = file.TryRead(&readSize, m_Buf, m_Bufsize);
if(result.IsFailure())
{
COMMON_LOGGER("Cannot read %ls, delete.\n", common::GetCharStr(path));
result = nn::fs::TryDeleteFile(path);
*modifiled = true;
break;
}
if(readSize == 0)
{
break;
}
}
}
}
return nn::ResultSuccess();
}
SharedExtSavedataChecker::SharedExtSavedataChecker() SharedExtSavedataChecker::SharedExtSavedataChecker()
{ {
} }
SharedExtSavedataChecker::SharedExtSavedataChecker(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size) SharedExtSavedataChecker::SharedExtSavedataChecker(void* buf, size_t size) : SavedataCheckerBase(buf, size)
{ {
} }
@ -223,6 +234,60 @@ SharedExtSavedataChecker::~SharedExtSavedataChecker()
nn::Result SharedExtSavedataChecker::CleanUp() nn::Result SharedExtSavedataChecker::CleanUp()
{ {
nn::Result result;
const size_t ARRAY_SIZE = 256;
s32 numId;
bit32 IdArray[ARRAY_SIZE];
result = nn::fs::EnumerateSharedExtSaveData(&numId, IdArray, ARRAY_SIZE);
NN_UTIL_RETURN_IF_FAILED(result);
NN_LOG_DEBUG("ExtData num = %d\n", numId);
bool modified = false;
for (s32 i = 0; i < numId; i++ )
{
if (nn::fs::MountSharedExtSaveData(SHARED_EXT_SAVEDATA_ARCHIVE_NAME, IdArray[i]).IsSuccess())
{
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);
}
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);
}
}
else
{
// アーカイブごと削除する
if(result <= nn::fs::ResultVerificationFailed())
{
NN_LOG("Mount Error: %x\n", IdArray[i]);
// 削除する
COMMON_LOGGER_WARN("Delete Shared-Ext-Savedata %x\n", IdArray[i]);
result = nn::fs::DeleteSharedExtSaveData(IdArray[i]);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
}
}
}
return nn::ResultSuccess(); return nn::ResultSuccess();
} }

View File

@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Project: Horizon Project: Horizon
File: SavedataChecker.h File: NandSavedataChecker.h
Copyright 2009 Nintendo. All rights reserved. Copyright 2009 Nintendo. All rights reserved.
@ -110,11 +110,31 @@ const SystemSaveDataCouple SYSTEM_SAVEDATA_COUPLE_LIST[] =
}; };
const char* const SYSTEM_SAVEDATA_ARCHIVE_NAME = "ssave:"; 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]); 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() {}
protected:
nn::Result CleanUpFilesRecursively(bool* modified, std::wstring currentDirectory);
//! バッファ
void* m_Buf;
//! バッファサイズ
size_t m_Bufsize;
};
//! @brief システムセーブデータをチェックするためのクラス //! @brief システムセーブデータをチェックするためのクラス
class SystemSavedataChecker class SystemSavedataChecker : public SavedataCheckerBase
{ {
public: public:
SystemSavedataChecker(); SystemSavedataChecker();
@ -123,20 +143,10 @@ public:
//! @brief システムセーブデータを調べて問題があるファイルを削除する //! @brief システムセーブデータを調べて問題があるファイルを削除する
nn::Result CleanUp(); nn::Result CleanUp();
private:
//! @brief システムセーブデータアーカイブ内のファイルを調べて問題があるファイルを削除する
nn::Result CleanUpFilesRecursively(bool* modified, std::wstring currentDirectory);
//! バッファ
void* m_Buf;
//! バッファサイズ
size_t m_Bufsize;
}; };
//! @brief 共有拡張セーブデータをチェックするためのクラス //! @brief 共有拡張セーブデータをチェックするためのクラス
class SharedExtSavedataChecker class SharedExtSavedataChecker : public SavedataCheckerBase
{ {
public: public:
SharedExtSavedataChecker(); SharedExtSavedataChecker();
@ -145,26 +155,15 @@ public:
//! @brief 共有拡張セーブデータを調べて問題があるファイルを削除する //! @brief 共有拡張セーブデータを調べて問題があるファイルを削除する
nn::Result CleanUp(); nn::Result CleanUp();
private:
//! @brief 共有拡張セーブデータアーカイブ内のファイルを調べて問題があるファイルを削除する
nn::Result CleanUpFilesRecursively(bool* modified, std::wstring currentDirectory);
//! バッファ
void* m_Buf;
//! バッファサイズ
size_t m_Bufsize;
}; };
class SavedataChecker class NandSavedataChecker
{ {
public: public:
SavedataChecker(); NandSavedataChecker();
SavedataChecker(void* buf, size_t size); NandSavedataChecker(void* buf, size_t size);
~SavedataChecker(); ~NandSavedataChecker();
nn::Result CleanUp(); nn::Result CleanUp();