diff --git a/trunk/ConsoleDataMigration/ConsoleBackup/Controller.cpp b/trunk/ConsoleDataMigration/ConsoleBackup/Controller.cpp index 32cd6b5..25d6645 100644 --- a/trunk/ConsoleDataMigration/ConsoleBackup/Controller.cpp +++ b/trunk/ConsoleDataMigration/ConsoleBackup/Controller.cpp @@ -156,6 +156,9 @@ void ControlState(::std::vector& operationMessage, bool& nextStep, static bool init = true; if(init) { + // コンテキストを初期化する + InitializeFileListContext(); + // データを書き込む ExportTwlSoundData(); init = false; diff --git a/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.cpp b/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.cpp index 766650e..de4bc64 100644 --- a/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.cpp +++ b/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.cpp @@ -25,7 +25,10 @@ #include #include #include +#include #include +#include +#include #include #include "Exporter.h" @@ -59,8 +62,12 @@ nn::os::StackBuffer s_ExportThreadStack; wchar_t s_RootName[256]; +nn::crypto::Sha256Context s_FileListContext; + } +void AddCmac(nn::fs::FileOutputStream* file, nn::crypto::Sha256Context* context); + void DeleteTrash(std::wstring currentDirectory) { // TODO: リードオンリーのファイルが消去できない @@ -316,7 +323,7 @@ void WriteTwlData(enum common::TWL_PATH_INDEX path) NN_LOG("AllocatableSize = %d\n", bufSize); u32 fileNum = 0; - u32 fileSize = 0; + s64 fileSize = 0; common::CalculateFileNum(::std::wstring(common::NAND_TWL_ROOT_PATHNAME_WITH_SLASH_TABLE[path]), fileNum, fileSize); nn::fs::Unmount(common::NAND_ARCHIVE_NAME); @@ -329,14 +336,32 @@ void WriteTwlData(enum common::TWL_PATH_INDEX path) void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE); if (buf != NULL) { - wchar_t archiveName[256]; - ::std::mbstowcs(archiveName, common::TWL_ARCHIVE_NAME_TABLE[path], std::strlen(common::TWL_ARCHIVE_NAME_TABLE[path]) + 1); - std::wstring archiveString(archiveName); - common::CopyDirectory( - (archiveString + ::std::wstring(L"/")).c_str(), - (common::SDMC_ROOT_DIRECTORY_PATH + ::std::wstring(common::SD_TWL_ROOTNAME_TABLE[path])).c_str(), - buf, bufSize, true); + nn::fs::FileOutputStream list; + result = list.TryInitialize(common::FILE_LIST_PATHNAME, true); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + if (result.IsSuccess()) + { + result = list.TryGetSize(&fileSize); + if (result.IsSuccess()) + { + // 末尾に移動 + result = list.TrySetPosition(fileSize); + if (result.IsSuccess()) + { + wchar_t archiveName[256]; + ::std::mbstowcs(archiveName, common::TWL_ARCHIVE_NAME_TABLE[path], + std::strlen(common::TWL_ARCHIVE_NAME_TABLE[path]) + 1); + std::wstring archiveString(archiveName); + common::CopyDirectory( + (archiveString + ::std::wstring(L"/")).c_str(), + (common::SDMC_ROOT_DIRECTORY_PATH + ::std::wstring(common::SD_TWL_ROOTNAME_TABLE[path])).c_str(), + buf, bufSize, true, &list, &s_FileListContext); + } + list.TryFlush(); + list.Finalize(); + } + } common::HeapManager::GetHeap()->Free(buf); } @@ -359,6 +384,12 @@ void WriteTwlSoundData() WriteTwlData(common::TWL_SOUND); } +void InitializeFileListContext() +{ + nn::crypto::Initialize(); + s_FileListContext.Initialize(); +} + void ExportTwlPhotoData() { s_ExportThread.Start(WriteTwlPhotoData, s_ExportThreadStack); @@ -411,12 +442,31 @@ void ExportThreadFunc() void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE); if (buf != NULL) { + nn::fs::FileOutputStream list; + result = list.TryInitialize(common::FILE_LIST_PATHNAME, true); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + if (result.IsSuccess()) + { + s64 fileSize; + result = list.TryGetSize(&fileSize); + if (result.IsSuccess()) + { + // 末尾に移動 + result = list.TrySetPosition(fileSize); + if (result.IsSuccess()) + { + common::CopyDirectory( + (::std::wstring(common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH) + ::std::wstring(s_RootName) + + ::std::wstring(L"/")).c_str(), + (common::SDMC_ROOT_DIRECTORY_PATH + ::std::wstring(common::SD_SAVEDATA_ROOT_NAME) + ::std::wstring( + s_RootName) + ::std::wstring(L"/")).c_str(), buf, bufSize, true, &list, &s_FileListContext); - common::CopyDirectory( - (::std::wstring(common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH) + ::std::wstring(s_RootName) + ::std::wstring(L"/")).c_str(), - (common::SDMC_ROOT_DIRECTORY_PATH + ::std::wstring(common::SD_SAVEDATA_ROOT_NAME) + ::std::wstring(s_RootName) + ::std::wstring(L"/")).c_str(), - buf, bufSize, true); - + AddCmac(&list, &s_FileListContext); + list.TryFlush(); + list.Finalize(); + } + } + } common::HeapManager::GetHeap()->Free(buf); } @@ -435,7 +485,7 @@ nn::Result WriteSaveData() COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); u32 fileNum = 0; - u32 fileSize = 0; + s64 fileSize = 0; common::CalculateFileNum(::std::wstring(common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH), fileNum, fileSize); nn::fs::Unmount(common::NAND_ARCHIVE_NAME); @@ -561,4 +611,24 @@ bool IsExportFinished() return s_ExportThread.IsValid() && !s_ExportThread.IsAlive(); } +//!@ brief ファイルにSHA256から計算したAES-CMACを付加します +//!@ param[in] file CMACを付加したいInitialize済みのファイル +//!@ param[in] context CMAC計算元のSHA256コンテキスト +void AddCmac(nn::fs::FileOutputStream* file, nn::crypto::Sha256Context* context) +{ + nn::Result result; + + bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE]; + context->GetHash(sha256Hash); + + bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE]; + result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + s32 writeSize; + result = file->TryWrite(&writeSize, cmac, sizeof(cmac), false); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + +} + } diff --git a/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.h b/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.h index 216a277..817af9c 100644 --- a/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.h +++ b/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.h @@ -21,6 +21,7 @@ namespace ConsoleBackup { +void InitializeFileListContext(); void ExportTwlPhotoData(); void ExportTwlSoundData(); void ExportData(); diff --git a/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp b/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp index 10c5e58..b9e48fc 100644 --- a/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp +++ b/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp @@ -671,7 +671,7 @@ void ImportThreadFunc() common::CopyDirectory( (::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(common::SD_SAVEDATA_ROOT_NAME)).c_str(), common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH, - buf, bufSize, false); + buf, bufSize, false, NULL, NULL); common::HeapManager::GetHeap()->Free(buf); } @@ -692,7 +692,7 @@ void ImportSaveData() // SDカードにあるセーブデータサイズを計算 u32 fileNum = 0; - u32 fileSize = 0; + s64 fileSize = 0; common::SdMountManager::Mount(); common::CalculateFileNum(::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(common::SD_SAVEDATA_ROOT_NAME), fileNum, fileSize); @@ -1305,7 +1305,7 @@ void ImportTwlData(enum common::TWL_PATH_INDEX path) u32 fileNum = 0; - u32 fileSize = 0; + s64 fileSize = 0; common::CalculateFileNum(::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring( common::SD_TWL_ROOTNAME_TABLE[path]), fileNum, fileSize); @@ -1325,7 +1325,7 @@ void ImportTwlData(enum common::TWL_PATH_INDEX path) common::CopyDirectory( (::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(common::SD_TWL_ROOTNAME_TABLE[path])).c_str(), (archiveString + ::std::wstring(L"/")).c_str(), - buf, bufSize, false); + buf, bufSize, false, NULL, NULL); common::HeapManager::GetHeap()->Free(buf); } diff --git a/trunk/ConsoleDataMigration/common/FileName.h b/trunk/ConsoleDataMigration/common/FileName.h index 2aeda6f..d175410 100644 --- a/trunk/ConsoleDataMigration/common/FileName.h +++ b/trunk/ConsoleDataMigration/common/FileName.h @@ -55,6 +55,7 @@ const wchar_t* const CFG_CALIBRATION_PATHNAME = L"sdmc:/CTR_Console_Repair/cfgCa const wchar_t* const VERSION_DATA_PATHNAME = L"sdmc:/CTR_Console_Repair/version.bin"; const wchar_t* const REGION_DATA_PATHNAME = L"sdmc:/CTR_Console_Repair/Region.bin"; const wchar_t* const DEVICE_ID_PATHNAME = L"sdmc:/CTR_Console_Repair/deviceId.bin"; +const wchar_t* const FILE_LIST_PATHNAME = L"sdmc:/CTR_Console_Repair/FileList.txt"; enum TWL_PATH_INDEX { diff --git a/trunk/ConsoleDataMigration/common/FileTransfer.cpp b/trunk/ConsoleDataMigration/common/FileTransfer.cpp index 7371393..309474d 100644 --- a/trunk/ConsoleDataMigration/common/FileTransfer.cpp +++ b/trunk/ConsoleDataMigration/common/FileTransfer.cpp @@ -24,6 +24,7 @@ #include "FileTransfer.h" #include "CommonLogger.h" #include "common_Types.h" +#include "FileName.h" namespace common { @@ -42,6 +43,7 @@ bool VerifyMac(nn::fs::FileInputStream* sdFile, nn::fs::FileStream* nandFile, s6 bool ConfirmFile(nn::fs::FileInputStream* from_file, nn::fs::FileStream* to_file, s64 sdFileSize, s64 nandFileSize, void* buf, size_t bufSize, const wchar_t* sdPath, const wchar_t* tmpPath, const wchar_t* truePath); void AddPkcsPadding(u8* paddingSize, void* buf, size_t bufSize, s32* readSize); +void AddPathNameAndUpdateContext(nn::fs::FileOutputStream* file, const wchar_t *str, nn::crypto::Sha256Context* context); const char* GetCharStr(const wchar_t* path) { @@ -52,7 +54,7 @@ const char* GetCharStr(const wchar_t* path) return filename; } -nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, u32& fileSize) +nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, s64& fileSize) { nn::fs::FileInputStream fis; nn::fs::Directory dir; @@ -111,7 +113,8 @@ nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, u32& fi // 書き込み先のディレクトリはあらかじめ消去しておくこと。 // 引数はスラッシュ付き // TODO:分割して短くする -bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf, const size_t bufSize, bool encode) +bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf, const size_t bufSize, bool encode, + nn::fs::FileOutputStream* list, nn::crypto::Sha256Context* listContext) { nn::fs::Directory from_dir; nn::fs::DirectoryEntry entry; @@ -164,8 +167,14 @@ bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf { target_from << L"/"; target_to << L"/"; + if(encode) + { + AddPathNameAndUpdateContext(list, target_to.str().c_str(), listContext); + } + + // 再帰処理 - if (!CopyDirectory(target_from.str().c_str(), target_to.str().c_str(), buf, bufSize, encode)) + if (!CopyDirectory(target_from.str().c_str(), target_to.str().c_str(), buf, bufSize, encode, list, listContext)) { ret_value = false; } @@ -178,6 +187,12 @@ bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf target_tmp.str(L""); target_tmp.clear(std::stringstream::goodbit); + if(encode) + { + AddPathNameAndUpdateContext(list, target_to.str().c_str(), listContext); + } + + if(!encode) { target_tmp << to_path << L"_" << entry.entryName; @@ -608,4 +623,23 @@ void AddPkcsPadding(u8* paddingSize, void* buf, size_t bufSize, s32* readSize) } } +//! @brief ファイルに文字列を改行付きで追加します +//! @param[in] file 文字列を出力したいファイル +//! @param[in] str 入力文字列 +void AddPathNameAndUpdateContext(nn::fs::FileOutputStream* file, const wchar_t *str, nn::crypto::Sha256Context* context) +{ + nn::Result result; + s32 writeSize; + + std::string output(GetCharStr(str)); + result = file->TryWrite(&writeSize, output.c_str(), output.size(), true); + context->Update(output.c_str(), output.size()); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + char newLine = '\n'; + result = file->TryWrite(&writeSize, &newLine, sizeof(newLine), true); + context->Update(&newLine, sizeof(newLine)); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); +} + } diff --git a/trunk/ConsoleDataMigration/common/FileTransfer.h b/trunk/ConsoleDataMigration/common/FileTransfer.h index 7af37f2..1147bf8 100644 --- a/trunk/ConsoleDataMigration/common/FileTransfer.h +++ b/trunk/ConsoleDataMigration/common/FileTransfer.h @@ -23,8 +23,9 @@ namespace common { -nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, u32& fileSize); -bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf, const size_t bufSize, bool encode); +nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, s64& fileSize); +bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf, const size_t bufSize, bool encode, + nn::fs::FileOutputStream* list, nn::crypto::Sha256Context* listContext); u32 GetProgress(); void InitializeTransferProgress(u64 totalSize);