ファイルサイズ計算を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:
N2614 2011-11-02 08:52:15 +00:00
parent 2d011dee6f
commit dda865745d
6 changed files with 242 additions and 70 deletions

View File

@ -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()

View File

@ -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
{

View File

@ -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();
}
}

View File

@ -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_ */

View File

@ -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 */

View File

@ -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;
};