mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
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@480 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
parent
665cb1a9d2
commit
b635a64a1c
@ -1124,7 +1124,7 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
|
||||
|
||||
case READ_FILELIST:
|
||||
{
|
||||
result = SetupFileList();
|
||||
result = SetupVersionAndFileList();
|
||||
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
||||
|
||||
if (result.IsSuccess())
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
#include "configLoader.h"
|
||||
#include "FileChecker.h"
|
||||
#include "VersionDetect.h"
|
||||
#include "SaveDataMover.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
@ -99,11 +100,15 @@ common::VerDef s_SDVersionData;
|
||||
// SDカードから読み込んだファイル一覧
|
||||
common::ImportDataList s_FileLists;
|
||||
|
||||
u64 s_ImportProgress = 0;
|
||||
|
||||
}
|
||||
|
||||
// SDからファイル一覧を読み込む
|
||||
nn::Result ReadFileList(SdFileSize* sdFileSize, common::ImportDataList* fileList);
|
||||
|
||||
bool RequiresImportApi();
|
||||
|
||||
CheckedNetworkSetting s_CurrentNetowrkSetting1;
|
||||
|
||||
void ConvertTimeZoneString(const char* str)
|
||||
@ -659,7 +664,15 @@ nn::Result ImportIvs()
|
||||
{
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
if (s_SDVersionData.cup.majorVersion < common::CUP_MAJOR_VER_2ND_NUP)
|
||||
// 2ndNUPからはAPI経由で書き込む
|
||||
if (RequiresImportApi())
|
||||
{
|
||||
result = nn::fs::CTR::ImportIntegrityVerificationSeed(
|
||||
*reinterpret_cast<nn::fs::CTR::IntegrityVerificationSeed*>(dec));
|
||||
NN_UTIL_RETURN_IF_FAILED(result);
|
||||
COMMON_LOGGER("Import SDCI.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 writeSize;
|
||||
result = fos.TryWrite(&writeSize, dec, readSize, true);
|
||||
@ -668,14 +681,6 @@ nn::Result ImportIvs()
|
||||
COMMON_LOGGER("Import SDCI.\n");
|
||||
}
|
||||
}
|
||||
// 2ndNUPからはAPI経由で書き込む
|
||||
else
|
||||
{
|
||||
result = nn::fs::CTR::ImportIntegrityVerificationSeed(
|
||||
*reinterpret_cast<nn::fs::CTR::IntegrityVerificationSeed*>(dec));
|
||||
NN_UTIL_RETURN_IF_FAILED(result);
|
||||
COMMON_LOGGER("Import SDCI.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -706,6 +711,11 @@ bool ImportIvsData()
|
||||
return ImportIvs().IsSuccess();
|
||||
}
|
||||
|
||||
bool RequiresImportApi()
|
||||
{
|
||||
return common::CUP_MAJOR_VER_2ND_NUP <= s_SDVersionData.cup.majorVersion;
|
||||
}
|
||||
|
||||
void ImportThreadFunc()
|
||||
{
|
||||
nn::Result result;
|
||||
@ -728,14 +738,27 @@ void ImportThreadFunc()
|
||||
void* buf = heap.GetAddr();
|
||||
if (buf != NULL)
|
||||
{
|
||||
if(!common::CopyDirectory(
|
||||
&s_FileLists,
|
||||
(::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, NULL, NULL))
|
||||
// 吸い出したバージョンによって書き込み関数を変える
|
||||
if(RequiresImportApi())
|
||||
{
|
||||
s_IsImportSucceeded = false;
|
||||
return;
|
||||
common::SaveDataMover saveDataMover;
|
||||
saveDataMover.StartImport(buf, bufSize, &s_ImportProgress);
|
||||
if(saveDataMover.GetLastResult().IsFailure())
|
||||
{
|
||||
s_IsImportSucceeded = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!common::CopyDirectory(
|
||||
&s_FileLists,
|
||||
(::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, NULL, NULL))
|
||||
{
|
||||
s_IsImportSucceeded = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1036,7 +1059,14 @@ void CreateTransferAccountFinishedFile()
|
||||
|
||||
u32 GetImportProgress()
|
||||
{
|
||||
return common::GetProgress();
|
||||
if(RequiresImportApi())
|
||||
{
|
||||
return s_ImportProgress;
|
||||
}
|
||||
else
|
||||
{
|
||||
return common::GetProgress();
|
||||
}
|
||||
}
|
||||
|
||||
bool UpdateNetworkSetting(nn::ac::NetworkSetting& networkSetting)
|
||||
@ -1769,7 +1799,7 @@ nn::Result InitializeHardwareDependentSetting()
|
||||
return result;
|
||||
}
|
||||
|
||||
nn::Result SetupFileList()
|
||||
nn::Result SetupVersionAndFileList()
|
||||
{
|
||||
std::memset(&s_SdFileSize, 0, sizeof(s_SdFileSize));
|
||||
|
||||
@ -1777,6 +1807,10 @@ nn::Result SetupFileList()
|
||||
nn::Result result = ReadFileList(&s_SdFileSize, &s_FileLists);
|
||||
NN_UTIL_RETURN_IF_FAILED(result);
|
||||
|
||||
// バージョンデータを読み込む
|
||||
result = ReadVersionData();
|
||||
NN_UTIL_RETURN_IF_FAILED(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ nn::Result EqualsRegionDataandRegion();
|
||||
nn::Result ReadSerialNumber(u8* serial);
|
||||
|
||||
// 出力ファイル一覧を読み込む
|
||||
nn::Result SetupFileList();
|
||||
nn::Result SetupVersionAndFileList();
|
||||
|
||||
// インポート用のスレッドを終了する
|
||||
void FinalizeImportThread();
|
||||
|
||||
@ -46,6 +46,7 @@ SOURCES[] =
|
||||
../common/VersionDetect.cpp
|
||||
../common/ResFont.cpp
|
||||
../common/HardwareStateManager.cpp
|
||||
../common/SaveDataMover.cpp
|
||||
|
||||
CTR_BANNER_SPEC = $(TARGET_PROGRAM).bsf
|
||||
|
||||
|
||||
@ -803,7 +803,8 @@ nn::Result CalculateFileSizeRecursively(std::wstring currentDirectory, s64& file
|
||||
// ディレクトリの場合
|
||||
if (entry.attributes.isDirectory)
|
||||
{
|
||||
return CalculateFileSizeRecursively(currentDirectory + std::wstring(entry.entryName) + std::wstring(L"/"), fileSize);
|
||||
result = CalculateFileSizeRecursively(currentDirectory + std::wstring(entry.entryName) + std::wstring(L"/"), fileSize);
|
||||
NN_UTIL_RETURN_IF_FAILED(result);
|
||||
}
|
||||
// ファイルの場合
|
||||
else
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: SaveDataMover.cpp
|
||||
|
||||
@ -49,6 +49,31 @@ namespace
|
||||
return id == 0x0001002c; // nim
|
||||
}
|
||||
|
||||
bit32 HexStringToBit32(const char* hex, int maxLen)
|
||||
{
|
||||
bit32 val = 0;
|
||||
for(int i = 0; i < maxLen; ++i)
|
||||
{
|
||||
val *= 16;
|
||||
if(hex[i] >= '0' && hex[i] <= '9')
|
||||
{
|
||||
val += (hex[i] - '0');
|
||||
}
|
||||
else if(hex[i] >= 'a' && hex[i] <= 'f')
|
||||
{
|
||||
val += (hex[i] - 'a' + 10);
|
||||
}
|
||||
else if(hex[i] >= 'A' && hex[i] <= 'F')
|
||||
{
|
||||
val += (hex[i] - 'A' + 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -65,13 +90,25 @@ void SaveDataMover::StartExport(void* buf, size_t bufSize, u64* progress)
|
||||
{
|
||||
SetupExport();
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
CalculateFileSize();
|
||||
CalculateExportFileSize();
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
ExportSystemSaveData(buf, bufSize, progress);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
ExportSharedExtSaveData(buf, bufSize, progress);
|
||||
}
|
||||
|
||||
void SaveDataMover::StartImport(void* buf, size_t bufSize, u64* progress)
|
||||
{
|
||||
SetupImport(buf, bufSize);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
CalculateImportFileSize();
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
ImportSystemSaveData(buf, bufSize, progress);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
ImportSharedExtSaveData(buf, bufSize, progress);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
|
||||
}
|
||||
|
||||
nn::Result SaveDataMover::GetLastResult()
|
||||
{
|
||||
return m_Result;
|
||||
@ -120,13 +157,13 @@ void SaveDataMover::SetupExport()
|
||||
|
||||
}
|
||||
|
||||
void SaveDataMover::CalculateFileSize()
|
||||
void SaveDataMover::CalculateExportFileSize()
|
||||
{
|
||||
CalculateSystemSaveDataSize();
|
||||
CalculateSharedExtSaveDataSize();
|
||||
CalculateExportSystemSaveDataSize();
|
||||
CalculateExportSharedExtSaveDataSize();
|
||||
}
|
||||
|
||||
void SaveDataMover::CalculateSystemSaveDataSize()
|
||||
void SaveDataMover::CalculateExportSystemSaveDataSize()
|
||||
{
|
||||
s32 systemSaveDataIdNum;
|
||||
m_Result = nn::fs::EnumerateSystemSaveData(&systemSaveDataIdNum, s_SystemSaveDataIdList, MAX_SYSTEM_SAVE_DATA_ID_NUM);
|
||||
@ -154,7 +191,7 @@ void SaveDataMover::CalculateSystemSaveDataSize()
|
||||
}
|
||||
}
|
||||
|
||||
void SaveDataMover::CalculateSharedExtSaveDataSize()
|
||||
void SaveDataMover::CalculateExportSharedExtSaveDataSize()
|
||||
{
|
||||
// 共有拡張セーブデータのサイズを確認する
|
||||
// 0. ID の列挙を行う。
|
||||
@ -171,10 +208,9 @@ void SaveDataMover::CalculateSharedExtSaveDataSize()
|
||||
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));
|
||||
// 2. アーカイブ内を走査して、含まれるファイルサイズを計算する
|
||||
m_Result = common::CalculateFileSizeRecursively(L"sext:/", m_TotalSize);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
// 3. アンマウントする
|
||||
m_Result = nn::fs::Unmount(ARC_NAME);
|
||||
@ -290,6 +326,152 @@ nn::Result SaveDataMover::Export(void* buf, size_t bufSize, bit32 id, u64* progr
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
void SaveDataMover::SetupImport(void* buf, size_t bufSize)
|
||||
{
|
||||
// 引っ越しコンテクストを取得
|
||||
nn::fs::DeviceMoveContext moveContext;
|
||||
|
||||
// コンテキストのSDからの入力
|
||||
size_t readSize;
|
||||
common::SdReaderWriter sdReader;
|
||||
m_Result = sdReader.ReadBufWithCmac(common::MOVE_CONTEXT_PATHNAME, buf, bufSize, &readSize);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
// AES復号化する
|
||||
nn::crypto::SwAesCtrContext swAesCtrContest;
|
||||
|
||||
swAesCtrContest.Initialize(common::iv, common::key, sizeof(common::key));
|
||||
m_Result = swAesCtrContest.Decrypt(&moveContext, buf, readSize);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
// 1. StartDeviceMoveAsDestination
|
||||
m_Result = StartDeviceMoveAsDestination(moveContext);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
}
|
||||
|
||||
void SaveDataMover::ImportSystemSaveData(void* buf, size_t bufSize, u64* progress)
|
||||
{
|
||||
// セーブデータが格納されているディレクトリを開く
|
||||
nn::fs::Directory root;
|
||||
m_Result = root.TryInitialize(SD_SAVEDATA_SYS_ROOT_PATH);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
nn::fs::DirectoryEntry entry;
|
||||
s32 numOut = 0;
|
||||
|
||||
// ディレクトリ内を見てセーブデータをインポートする。
|
||||
while(1)
|
||||
{
|
||||
root.TryRead(&numOut, &entry, 1);
|
||||
if(numOut == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
bit32 id = HexStringToBit32(entry.shortName.body, 8);
|
||||
if(id == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
NN_LOG("id: %08x\n", id);
|
||||
|
||||
nn::fs::FileInputStream input;
|
||||
char name[64];
|
||||
nn::nstd::TSNPrintf(name, 64, "%s/%s", SD_SAVEDATA_SYS_ROOT_PATH, entry.shortName.body);
|
||||
m_Result = input.TryInitialize(name);
|
||||
if(m_Result.IsFailure())
|
||||
{
|
||||
NN_LOG("Failed to open save data file, r = %08x\n", m_Result.GetPrintableBits());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. fs::CreateAndOpenNewSystemSaveDataRawStorageFile を呼び
|
||||
// ID に対する FileOutputStream を得る。
|
||||
nn::fs::FileOutputStream output;
|
||||
m_Result = nn::fs::CreateAndOpenNewSystemSaveDataRawStorageFile(&output, id, input.GetSize());
|
||||
if(m_Result.IsFailure())
|
||||
{
|
||||
NN_LOG("Failed to open storage on nand, r = %08x\n", m_Result.GetPrintableBits());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// 2. 1 で得たストリームに対して書き込みを行う。
|
||||
// 本来は引っ越し元からデータを受け取り、書き込むが
|
||||
// ここでは SD から読み込んだデータを書き込む。
|
||||
m_Result = CopyFile(input, output, buf, bufSize, progress);
|
||||
if(m_Result.IsFailure())
|
||||
{
|
||||
NN_LOG("Failed to copy, r = %08x\n", m_Result.GetPrintableBits());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NN_LOG("\n");
|
||||
}
|
||||
|
||||
void SaveDataMover::ImportSharedExtSaveData(void* buf, size_t bufSize, u64* progress)
|
||||
{
|
||||
nn::fs::Directory srcRoot;
|
||||
m_Result = srcRoot.TryInitialize(SD_SAVEDATA_EXT_ROOT_PATH);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
|
||||
nn::fs::DirectoryEntry entry;
|
||||
s32 numEntry;
|
||||
while(1)
|
||||
{
|
||||
srcRoot.TryRead(&numEntry, &entry, 1);
|
||||
if(numEntry == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
bit32 id = HexStringToBit32(entry.shortName.body, 8);
|
||||
NN_LOG("Import: %08x\n", id);
|
||||
|
||||
m_Result = Import(buf, bufSize, id, progress);
|
||||
if(m_Result.IsFailure())
|
||||
{
|
||||
NN_LOG("Failed to import. result = %08x\n", m_Result.GetPrintableBits());
|
||||
}
|
||||
|
||||
}
|
||||
NN_LOG("\n");
|
||||
}
|
||||
|
||||
nn::Result SaveDataMover::Import(void* buf, size_t bufSize, bit32 id, u64* progress)
|
||||
{
|
||||
const char* ARC_NAME = "sext:";
|
||||
|
||||
const int MAX_PATH_LEN = 127;
|
||||
char srcRoot[MAX_PATH_LEN + 1];
|
||||
|
||||
NN_UTIL_RETURN_IF_FAILED(nn::fs::CreateNewSharedExtSaveDataRawStorage(id));
|
||||
|
||||
// 2. fs::CreateNewSharedExtSaveDataRawStorage を呼び
|
||||
// 書き込み用の領域を作成します。
|
||||
nn::nstd::TSNPrintf(srcRoot, MAX_PATH_LEN, "%s/%08x", SD_SAVEDATA_EXT_ROOT_PATH, id);
|
||||
|
||||
m_Result = nn::fs::MountNewSharedExtSaveDataRawStorage(ARC_NAME, id);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(m_Result);
|
||||
|
||||
// 4. 3 でマウントした領域に、引っ越し元のアーカイブと
|
||||
// 同じ構造でファイルとディレクトリを置く。
|
||||
m_Result = CopyRecursivly(buf, bufSize, srcRoot, ARC_NAME, progress);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(m_Result);
|
||||
|
||||
m_Result = nn::fs::Unmount(ARC_NAME);
|
||||
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(m_Result);
|
||||
|
||||
return nn::ResultSuccess();
|
||||
}
|
||||
|
||||
void SaveDataMover::CalculateImportFileSize()
|
||||
{
|
||||
m_Result = common::CalculateFileSizeRecursively(
|
||||
(::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(common::SD_SAVEDATA_ROOT_NAME)).c_str(),
|
||||
m_TotalSize);
|
||||
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
|
||||
}
|
||||
|
||||
// ファイルの読み書き
|
||||
nn::Result SaveDataMover::CopyFile(nn::fs::FileInputStream& is, nn::fs::FileOutputStream& os, void* pBuffer,
|
||||
const s32 bufferSize, u64* progress)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: SaveDataMover.h
|
||||
|
||||
@ -37,14 +37,15 @@ public:
|
||||
nn::Result GetLastResult();
|
||||
|
||||
private:
|
||||
//******************** 出力用API群 ********************
|
||||
//! @brief 出力を準備します
|
||||
void SetupExport();
|
||||
|
||||
//! @brief 出力するファイルサイズを計算します
|
||||
void CalculateFileSize();
|
||||
void CalculateExportFileSize();
|
||||
|
||||
void CalculateSystemSaveDataSize();
|
||||
void CalculateSharedExtSaveDataSize();
|
||||
void CalculateExportSystemSaveDataSize();
|
||||
void CalculateExportSharedExtSaveDataSize();
|
||||
|
||||
//! @brief システムセーブデータを出力します
|
||||
void ExportSystemSaveData(void* buf, size_t bufSize, u64* progress);
|
||||
@ -55,6 +56,24 @@ private:
|
||||
//! @breif 共有拡張セーブデータを出力します
|
||||
nn::Result Export(void* buf, size_t bufSize, bit32 id, u64* progress);
|
||||
|
||||
|
||||
//******************** 入力用API群 ********************
|
||||
//!@ brief 入力を準備します
|
||||
void SetupImport(void* buf, size_t bufSize);
|
||||
|
||||
//! @brief システムセーブデータを入力します
|
||||
void ImportSystemSaveData(void* buf, size_t bufSize, u64* progress);
|
||||
|
||||
//! @brief 共有拡張セーブデータを入力します
|
||||
void ImportSharedExtSaveData(void* buf, size_t bufSize, u64* progress);
|
||||
|
||||
//! @brief 共有拡張セーブデータを出力します
|
||||
nn::Result Import(void* buf, size_t bufSize, bit32 id, u64* progress);
|
||||
|
||||
//! @brief 入力するファイルサイズを計算します
|
||||
void CalculateImportFileSize();
|
||||
|
||||
|
||||
nn::Result CopyFile(nn::fs::FileInputStream& is, nn::fs::FileOutputStream& os, void* pBuffer, const s32 bufferSize,
|
||||
u64* progress);
|
||||
|
||||
@ -65,6 +84,7 @@ private:
|
||||
s64 m_FinishedSize;
|
||||
s64 m_TotalSize;
|
||||
|
||||
NN_PADDING4;
|
||||
nn::Result m_Result;
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user