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

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

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);
if(heap.GetAddr() != NULL)
{
SavedataChecker checker(heap.GetAddr(), bufSize);
NandSavedataChecker checker(heap.GetAddr(), bufSize);
nn::Result result = checker.CleanUp();
return result.IsSuccess();
}

View File

@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: SavedataChecker.cpp
File: NandSavedataChecker.cpp
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 自動生成されたコンストラクター・スタブ
}
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
}
nn::Result SavedataChecker::CleanUp()
nn::Result NandSavedataChecker::CleanUp()
{
nn::Result result;
{
SharedExtSavedataChecker sharedExtSaveChecker(m_Buf, m_Bufsize);
result = sharedExtSaveChecker.CleanUp();
NN_UTIL_RETURN_IF_FAILED(result);
}
{
SystemSavedataChecker syssaveChecker(m_Buf, m_Bufsize);
result = syssaveChecker.CleanUp();
NN_UTIL_RETURN_IF_FAILED(result);
}
{
SharedExtSavedataChecker sharedExtSaveChecker(m_Buf, m_Bufsize);
result = sharedExtSaveChecker.CleanUp();
NN_UTIL_RETURN_IF_FAILED(result);
}
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()));
result = nn::fs::DeleteSystemSaveData(SYSTEM_SAVEDATA_COUPLE_LIST[i].id);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
}
}
else
@ -103,12 +201,12 @@ nn::Result SystemSavedataChecker::CleanUp()
NN_LOG("Mount %ls\n", SYSTEM_SAVEDATA_COUPLE_LIST[i].name.c_str());
// ファイルを個別にチェックする
result = CleanUpFilesRecursively(&modified, L"ssave:/");
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
if(modified)
{
result = nn::fs::CommitSystemSaveData(SYSTEM_SAVEDATA_ARCHIVE_NAME);
}
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = nn::fs::Unmount("ssave:");
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
@ -119,98 +217,11 @@ nn::Result SystemSavedataChecker::CleanUp()
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(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 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();
}

View File

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