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:
N2614 2011-11-07 02:37:42 +00:00
parent 665cb1a9d2
commit b635a64a1c
7 changed files with 274 additions and 36 deletions

View File

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

View File

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

View File

@ -35,7 +35,7 @@ nn::Result EqualsRegionDataandRegion();
nn::Result ReadSerialNumber(u8* serial);
// 出力ファイル一覧を読み込む
nn::Result SetupFileList();
nn::Result SetupVersionAndFileList();
// インポート用のスレッドを終了する
void FinalizeImportThread();

View File

@ -46,6 +46,7 @@ SOURCES[] =
../common/VersionDetect.cpp
../common/ResFont.cpp
../common/HardwareStateManager.cpp
../common/SaveDataMover.cpp
CTR_BANNER_SPEC = $(TARGET_PROGRAM).bsf

View File

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

View File

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

View File

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