ctr_Repair/trunk/ConsoleDataMigration/sources/ConsoleBackup/SavedataChecker.cpp
N2614 718e114848 共有拡張セーブデータをチェックするように
アーカイブ内のファイルを個別に削除できるように

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
2011-08-01 06:55:00 +00:00

295 lines
8.5 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: NandSavedataChecker.cpp
Copyright 2009 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 <nn/fs/fs_ApiSysSaveData.h>
#include <nn/fs/fs_ApiSharedExtSaveData.h>
#include "SavedataChecker.h"
#include "CommonLogger.h"
#include "FileTransfer.h"
namespace ConsoleBackup
{
namespace
{
}
SavedataCheckerBase::SavedataCheckerBase(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size)
{
}
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 自動生成されたコンストラクター・スタブ
}
NandSavedataChecker::NandSavedataChecker(void* buf, size_t size) : m_Buf(buf), m_Bufsize(size)
{
}
NandSavedataChecker::~NandSavedataChecker()
{
// TODO Auto-generated destructor stub
}
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);
}
return nn::ResultSuccess();
}
SystemSavedataChecker::SystemSavedataChecker()
{
}
SystemSavedataChecker::SystemSavedataChecker(void* buf, size_t size) : SavedataCheckerBase(buf, size)
{
}
SystemSavedataChecker::~SystemSavedataChecker()
{
}
nn::Result SystemSavedataChecker::CleanUp()
{
nn::Result result;
bool modified = false;
std::wstring currentDirectory;
for (s32 i = 0; i < SYSTEM_SAVE_DATA_NUM; i++)
{
result = nn::fs::MountSystemSaveData(SYSTEM_SAVEDATA_ARCHIVE_NAME, SYSTEM_SAVEDATA_COUPLE_LIST[i].id );
if (result.IsFailure())
{
if(result <= nn::fs::ResultVerificationFailed())
{
NN_LOG("Mount Error: %ls\n", 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);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
}
}
else
{
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);
}
result = nn::fs::Unmount("ssave:");
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
}
}
return result;
}
SharedExtSavedataChecker::SharedExtSavedataChecker()
{
}
SharedExtSavedataChecker::SharedExtSavedataChecker(void* buf, size_t size) : SavedataCheckerBase(buf, size)
{
}
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();
}
} /* namespace ConsoleBackup */