mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
ファイルサイズ計算をFileTransferに移す
CARDBOARD用APIで共有拡張セーブデータを出力するように git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@475 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
parent
2d011dee6f
commit
dda865745d
@ -179,61 +179,7 @@ nn::Result SavedataCheckerBase::CleanUpFilesRecursively(bool* modified, std::str
|
||||
|
||||
nn::Result SavedataCheckerBase::GetFileSize(std::wstring currentDirectory)
|
||||
{
|
||||
nn::fs::Directory dir;
|
||||
nn::fs::DirectoryEntry entry;
|
||||
nn::Result result;
|
||||
|
||||
NN_LOG("%s\n", common::GetCharStr(currentDirectory.c_str()));
|
||||
result = dir.TryInitialize(currentDirectory.c_str());
|
||||
if(result.IsFailure())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
s32 numRead;
|
||||
result = dir.TryRead(&numRead, &entry, 1);
|
||||
if(result.IsFailure())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(numRead == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (std::wcscmp(entry.entryName, L".") == 0 || std::wcscmp(entry.entryName, L"..") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// ディレクトリの場合
|
||||
if (entry.attributes.isDirectory)
|
||||
{
|
||||
return GetFileSize(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();
|
||||
|
||||
result = file.TryInitialize(path);
|
||||
if(result.IsFailure())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_CalculatedFileSize += file.GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
return nn::ResultSuccess();
|
||||
return common::CalculateFileSizeRecursively(currentDirectory, m_CalculatedFileSize);
|
||||
}
|
||||
|
||||
s64 SavedataCheckerBase::GetCalculatedSize()
|
||||
|
||||
@ -71,6 +71,7 @@ const wchar_t* const MOVE_CONTEXT_PATHNAME = L"sdmc:/CTR_Console_Repair/MoveCont
|
||||
const wchar_t* const SD_NINTENDO_3DS_ROOT_PATH = L"sdmc:/Nintendo 3DS/";
|
||||
|
||||
const wchar_t* const SD_SAEVDATA_SYS_NAME = L"sysdata";
|
||||
const wchar_t* const SD_SAEVDATA_EXT_NAME = L"extdata";
|
||||
|
||||
enum TWL_PATH_INDEX
|
||||
{
|
||||
|
||||
@ -766,4 +766,63 @@ bool AddPathNameAndUpdateContext(nn::fs::FileOutputStream* file, const wchar_t *
|
||||
return true;
|
||||
}
|
||||
|
||||
nn::Result CalculateFileSizeRecursively(std::wstring currentDirectory, s64& fileSize)
|
||||
{
|
||||
nn::fs::Directory dir;
|
||||
nn::fs::DirectoryEntry entry;
|
||||
nn::Result result;
|
||||
|
||||
NN_LOG("%s\n", common::GetCharStr(currentDirectory.c_str()));
|
||||
result = dir.TryInitialize(currentDirectory.c_str());
|
||||
if(result.IsFailure())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
s32 numRead;
|
||||
result = dir.TryRead(&numRead, &entry, 1);
|
||||
if(result.IsFailure())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(numRead == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (std::wcscmp(entry.entryName, L".") == 0 || std::wcscmp(entry.entryName, L"..") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// ディレクトリの場合
|
||||
if (entry.attributes.isDirectory)
|
||||
{
|
||||
return CalculateFileSizeRecursively(currentDirectory + std::wstring(entry.entryName) + std::wstring(L"/"), fileSize);
|
||||
}
|
||||
// ファイルの場合
|
||||
else
|
||||
{
|
||||
nn::fs::FileInputStream file;
|
||||
std::wstring filePath = (currentDirectory + std::wstring(entry.entryName)).c_str();
|
||||
const wchar_t* path = filePath.c_str();
|
||||
|
||||
result = file.TryInitialize(path);
|
||||
if(result.IsFailure())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fileSize += file.GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -59,6 +59,9 @@ const char* GetCharStr(const wchar_t* path);
|
||||
|
||||
void AddPkcsPadding(u8* paddingSize, void* buf, size_t bufSize, s32* readSize);
|
||||
|
||||
// ディレクトリ以下のファイルサイズを計算する
|
||||
nn::Result CalculateFileSizeRecursively(std::wstring currentDirectory, s64& fileSize);
|
||||
|
||||
}
|
||||
|
||||
#endif /* FILETRANSFER_H_ */
|
||||
|
||||
@ -16,7 +16,9 @@
|
||||
#include <string>
|
||||
|
||||
#include <nn/fs/fs_ApiSysSaveData.h>
|
||||
#include <nn/fs/fs_ApiSharedExtSaveData.h>
|
||||
#include <nn/fs/fs_ApiDeviceMove.h>
|
||||
#include <nn/fs/fs_ResultPrivate.h>
|
||||
|
||||
#include <nn/ndm.h>
|
||||
|
||||
@ -24,6 +26,7 @@
|
||||
#include "CommonLogger.h"
|
||||
#include "FileName.h"
|
||||
#include "SdReaderWriter.h"
|
||||
#include "FileTransfer.h"
|
||||
|
||||
|
||||
namespace common
|
||||
@ -31,9 +34,12 @@ namespace common
|
||||
|
||||
namespace
|
||||
{
|
||||
const char* ARC_NAME = "sext:";
|
||||
|
||||
const s32 MAX_SYSTEM_SAVE_DATA_ID_NUM = 256;
|
||||
nn::fs::SystemSaveDataId s_SystemSaveDataIdList[MAX_SYSTEM_SAVE_DATA_ID_NUM * sizeof(bit32)];
|
||||
|
||||
const s32 MAX_SHARED_EXT_SAVE_DATA_ID_NUM = 10;
|
||||
nn::fs::SharedExtSaveDataId s_SharedExtSaveDataIdList[MAX_SHARED_EXT_SAVE_DATA_ID_NUM * sizeof(bit32)];
|
||||
|
||||
bool IsNotMovedId(bit32 id)
|
||||
{
|
||||
@ -46,23 +52,21 @@ namespace
|
||||
SaveDataMover::SaveDataMover() :
|
||||
m_Progress(0), m_FinishedSize(0), m_TotalSize(0), m_Result(nn::ResultSuccess())
|
||||
{
|
||||
// TODO 自動生成されたコンストラクター・スタブ
|
||||
}
|
||||
|
||||
SaveDataMover::~SaveDataMover()
|
||||
{
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
void SaveDataMover::StartExport(void* buf, size_t bufSize, u64* progress)
|
||||
{
|
||||
SetupExport();
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
CalculateFileSize();
|
||||
if(GetLastResult().IsFailure())
|
||||
{
|
||||
return;
|
||||
}
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
ExportSystemSaveData(buf, bufSize, progress);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
ExportSharedExtSaveData(buf, bufSize, progress);
|
||||
}
|
||||
|
||||
nn::Result SaveDataMover::GetLastResult()
|
||||
@ -84,19 +88,33 @@ void SaveDataMover::SetupExport()
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
// 3. 出力用ディレクトリの作成
|
||||
// 3.1 システムセーブデータ用ディレクトリ
|
||||
common::SdReaderWriter sdWriter;
|
||||
m_Result = sdWriter.CreateDirectory((::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(
|
||||
common::SD_SAVEDATA_ROOT_NAME) + std::wstring(common::SD_SAEVDATA_SYS_NAME)).c_str());
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
// 3.2 共有拡張セーブデータ用ディレクトリ
|
||||
m_Result = sdWriter.CreateDirectory((::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(
|
||||
common::SD_SAVEDATA_ROOT_NAME) + std::wstring(common::SD_SAEVDATA_EXT_NAME)).c_str());
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
}
|
||||
|
||||
void SaveDataMover::CalculateFileSize()
|
||||
{
|
||||
CalculateSystemSaveDataSize();
|
||||
CalculateSharedExtSaveDataSize();
|
||||
}
|
||||
|
||||
void SaveDataMover::CalculateSystemSaveDataSize()
|
||||
{
|
||||
s32 systemSaveDataIdNum;
|
||||
m_Result = nn::fs::EnumerateSystemSaveData(&systemSaveDataIdNum, s_SystemSaveDataIdList, MAX_SYSTEM_SAVE_DATA_ID_NUM);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
for(int i = 0; i < systemSaveDataIdNum; ++i)
|
||||
// システムセーブデータのサイズを確認する
|
||||
for(s32 i = 0; i < systemSaveDataIdNum; ++i)
|
||||
{
|
||||
nn::fs::FileInputStream input;
|
||||
|
||||
@ -117,6 +135,35 @@ void SaveDataMover::CalculateFileSize()
|
||||
}
|
||||
}
|
||||
|
||||
void SaveDataMover::CalculateSharedExtSaveDataSize()
|
||||
{
|
||||
// 共有拡張セーブデータのサイズを確認する
|
||||
// 0. ID の列挙を行う。
|
||||
s32 sharedExtSaveDataIdNum;
|
||||
m_Result = nn::fs::EnumerateSharedExtSaveData(&sharedExtSaveDataIdNum, s_SharedExtSaveDataIdList,
|
||||
MAX_SHARED_EXT_SAVE_DATA_ID_NUM);
|
||||
for(s32 i = 0; i < sharedExtSaveDataIdNum; ++i)
|
||||
{
|
||||
bit32 id = s_SharedExtSaveDataIdList[i];
|
||||
|
||||
// 1. fs::MountSharedExtSaveDataRawStorage を呼び
|
||||
// ID に対応するアーカイブをマウントする。
|
||||
// 既存の共有拡張セーブデータ領域へのアーカイブをマウントします。
|
||||
m_Result = nn::fs::MountSharedExtSaveDataRawStorage(ARC_NAME, id);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
// 2. アーカイブ内を走査して、含まれるファイルと
|
||||
// ディレクトリを、その構造を保ったまま
|
||||
// エクスポートする。
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(common::CalculateFileSizeRecursively(L"sext:/", m_TotalSize));
|
||||
|
||||
// 3. アンマウントする
|
||||
m_Result = nn::fs::Unmount(ARC_NAME);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
}
|
||||
NN_LOG("calculatedSize = %lld\n", m_TotalSize);
|
||||
}
|
||||
|
||||
void SaveDataMover::ExportSystemSaveData(void* buf, size_t bufSize, u64* progress)
|
||||
{
|
||||
s64 totalFileSize = 0;
|
||||
@ -126,7 +173,7 @@ void SaveDataMover::ExportSystemSaveData(void* buf, size_t bufSize, u64* progres
|
||||
m_Result = nn::fs::EnumerateSystemSaveData(&systemSaveDataIdNum, s_SystemSaveDataIdList, MAX_SYSTEM_SAVE_DATA_ID_NUM);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
for(int i = 0; i < systemSaveDataIdNum; ++i)
|
||||
for(s32 i = 0; i < systemSaveDataIdNum; ++i)
|
||||
{
|
||||
nn::fs::FileInputStream input;
|
||||
|
||||
@ -178,27 +225,132 @@ void SaveDataMover::ExportSystemSaveData(void* buf, size_t bufSize, u64* progres
|
||||
NN_LOG("totalFileSize = %lld\n", totalFileSize);
|
||||
}
|
||||
|
||||
void SaveDataMover::ExportSharedExtSaveData(void* buf, size_t bufSize, u64* progress)
|
||||
{
|
||||
// 0. ID の列挙を行う。
|
||||
s32 sharedExtSaveDataIdNum;
|
||||
m_Result = nn::fs::EnumerateSharedExtSaveData(&sharedExtSaveDataIdNum, s_SharedExtSaveDataIdList,
|
||||
MAX_SHARED_EXT_SAVE_DATA_ID_NUM);
|
||||
for(s32 i = 0; i < sharedExtSaveDataIdNum; ++i)
|
||||
{
|
||||
bit32 id = s_SharedExtSaveDataIdList[i];
|
||||
NN_LOG("Export: %08x\n", id);
|
||||
|
||||
// 1. fs::MountSharedExtSaveDataRawStorage を呼び
|
||||
// ID に対応するアーカイブをマウントする。
|
||||
// 既存の共有拡張セーブデータ領域へのアーカイブをマウントします。
|
||||
m_Result = nn::fs::MountSharedExtSaveDataRawStorage(ARC_NAME, id);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
m_Result = Export(buf, bufSize, id, progress);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
// 3. アンマウントする
|
||||
m_Result = nn::fs::Unmount(ARC_NAME);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nn::Result SaveDataMover::Export(void* buf, size_t bufSize, bit32 id, u64* progress)
|
||||
{
|
||||
const s32 MAX_PATH_LEN = 127;
|
||||
char destRoot[MAX_PATH_LEN + 1];
|
||||
|
||||
nn::nstd::TSNPrintf(destRoot, MAX_PATH_LEN, "%s/%08x", SD_SAVEDATA_EXT_ROOT_PATH, id);
|
||||
NN_LOG("destRoot = %s\n", destRoot);;
|
||||
|
||||
// 出力先ディレクトリを作成
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(nn::fs::TryCreateDirectory(destRoot));
|
||||
|
||||
// 2. アーカイブ内を走査して、含まれるファイルと
|
||||
// ディレクトリを、その構造を保ったまま
|
||||
// エクスポートする。
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(CopyRecursivly(buf, bufSize, ARC_NAME, destRoot, progress));
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
// ファイルの読み書き
|
||||
nn::Result SaveDataMover::CopyFile(nn::fs::FileInputStream& is, nn::fs::FileOutputStream& os, void* pBuffer,
|
||||
const s32 bufferSize, u64* progress)
|
||||
{
|
||||
s64 restSize;
|
||||
NN_UTIL_RETURN_IF_FAILED(is.TryGetSize(&restSize));
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(is.TryGetSize(&restSize));
|
||||
|
||||
while (restSize > 0)
|
||||
{
|
||||
s32 readSize = restSize > bufferSize ? bufferSize : restSize;
|
||||
s32 read = 0;
|
||||
s32 write = 0;
|
||||
NN_UTIL_RETURN_IF_FAILED(is.TryRead(&read, pBuffer, readSize));
|
||||
NN_UTIL_RETURN_IF_FAILED(os.TryWrite(&write, pBuffer, read));
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(is.TryRead(&read, pBuffer, readSize));
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(os.TryWrite(&write, pBuffer, read));
|
||||
|
||||
restSize -= read;
|
||||
m_FinishedSize += read;
|
||||
*progress = m_FinishedSize * 100 / m_TotalSize;
|
||||
NN_LOG("FinishedSize = %lld\n", m_FinishedSize);
|
||||
NN_LOG("progress = %lld\n", *progress);
|
||||
}
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
// ディレクトリ内を再帰的にコピー
|
||||
// INFO: 本当は再帰を使わないで書く
|
||||
nn::Result SaveDataMover::CopyRecursivly(void* buf, size_t bufSize, const char* src, const char* dest, u64* progress)
|
||||
{
|
||||
char srcPath[128];
|
||||
char destPath[128];
|
||||
char entryName[128];
|
||||
|
||||
nn::nstd::TSNPrintf(srcPath, sizeof(srcPath), "%s/", src);
|
||||
nn::fs::Directory srcDir;
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(srcDir.TryInitialize(srcPath));
|
||||
|
||||
while (1)
|
||||
{
|
||||
nn::fs::DirectoryEntry entry;
|
||||
s32 numRead;
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(srcDir.TryRead(&numRead, &entry, 1));
|
||||
if (numRead == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
std::wcstombs(entryName, entry.entryName, sizeof(entryName) - 1);
|
||||
entryName[sizeof(entryName) - 1] = '\0';
|
||||
nn::nstd::TSNPrintf(srcPath, sizeof(srcPath), "%s/%s", src, entryName);
|
||||
nn::nstd::TSNPrintf(destPath, sizeof(destPath), "%s/%s", dest, entryName);
|
||||
|
||||
if (entry.attributes.isDirectory)
|
||||
{
|
||||
nn::Result result = nn::fs::TryCreateDirectory(destPath);
|
||||
if (result.IsFailure())
|
||||
{
|
||||
if (result.GetDescription() == nn::fs::DESCRIPTION_FAT_ALREADY_EXISTS
|
||||
&& result.GetModule() == nn::Result::MODULE_NN_FS)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
m_Result = CopyRecursivly(buf, bufSize, srcPath, destPath, progress);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(m_Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
nn::fs::FileInputStream input;
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(input.TryInitialize(srcPath));
|
||||
|
||||
nn::fs::FileOutputStream output;
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(output.TryInitialize(destPath, true));
|
||||
|
||||
CopyFile(input, output, buf, bufSize, progress);
|
||||
}
|
||||
}
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
} /* namespace common */
|
||||
|
||||
@ -43,16 +43,27 @@ private:
|
||||
//! @brief 出力するファイルサイズを計算します
|
||||
void CalculateFileSize();
|
||||
|
||||
void CalculateSystemSaveDataSize();
|
||||
void CalculateSharedExtSaveDataSize();
|
||||
|
||||
//! @brief システムセーブデータを出力します
|
||||
void ExportSystemSaveData(void* buf, size_t bufSize, u64* progress);
|
||||
|
||||
//! @brief 共有拡張セーブデータを出力します
|
||||
void ExportSharedExtSaveData(void* buf, size_t bufSize, u64* progress);
|
||||
|
||||
//! @breif 共有拡張セーブデータを出力します
|
||||
nn::Result Export(void* buf, size_t bufSize, bit32 id, u64* progress);
|
||||
|
||||
nn::Result CopyFile(nn::fs::FileInputStream& is, nn::fs::FileOutputStream& os, void* pBuffer, const s32 bufferSize,
|
||||
u64* progress);
|
||||
|
||||
nn::Result CopyRecursivly(void* buf, size_t bufSize, const char* src, const char* dest, u64* progress);
|
||||
|
||||
NN_PADDING4;
|
||||
u64 m_Progress;
|
||||
u64 m_FinishedSize;
|
||||
u64 m_TotalSize;
|
||||
s64 m_Progress;
|
||||
s64 m_FinishedSize;
|
||||
s64 m_TotalSize;
|
||||
|
||||
nn::Result m_Result;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user