descの変更。不要ファイルの削除

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@792 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2014-04-21 07:08:36 +00:00
parent 0d68cd0ac4
commit 547ed73c72
381 changed files with 9 additions and 2796 deletions

View File

@ -115,17 +115,10 @@ extern "C" void nnMain(void)
NN_ERR_THROW_FATAL_IF_FATAL_ONLY(result); NN_ERR_THROW_FATAL_IF_FATAL_ONLY(result);
// cfg の初期化 // cfg の初期化
nn::cfg::CTR::init::Initialize(); nn::cfg::CTR::Initialize();
nn::cfg::CTR::system::Initialize();
// 時計設定用ptm初期化
nn::ptm::CTR::InitializeForSystemMenu();
// ps の初期化
nn::ps::Initialize();
// amの初期化 // amの初期化
nn::am::InitializeForLocalImporter(); nn::am::InitializeForSystemMenu();
// ヒープの確保 // ヒープの確保
common::InitializeHeap(); common::InitializeHeap();
@ -170,14 +163,6 @@ extern "C" void nnMain(void)
s_HwUtility.GetCupMicroVersion(), s_HwUtility.GetCupMicroVersion(),
s_HwUtility.GetNupVersion()); s_HwUtility.GetNupVersion());
COMMON_LOGGER("System Region %s\n", s_HwUtility.GetRegionCodeA3()); COMMON_LOGGER("System Region %s\n", s_HwUtility.GetRegionCodeA3());
COMMON_LOGGER("Serial Number %s\n", s_HwUtility.GetSerialNumber());
COMMON_LOGGER("Device ID %llu\n", s_HwUtility.GetInfraDeviceId());
COMMON_LOGGER("MAC Address %s\n", s_HwUtility.GetMacAddress());
COMMON_LOGGER("Friend Code %04u-%04u-%04u\n",
static_cast<u32>(s_HwUtility.GetFriendcode() / 100000000ULL % 10000ULL),
static_cast<u32>(s_HwUtility.GetFriendcode() / 10000ULL % 10000ULL),
static_cast<u32>(s_HwUtility.GetFriendcode() % 10000ULL) );
bool flip = false; bool flip = false;
InitializeState(); InitializeState();
@ -244,10 +229,8 @@ extern "C" void nnMain(void)
// 上画面表示 // 上画面表示
common::DrawSystemState("CTR Network Updater", s_RenderSystem, titleColor, flip, adapterState, common::DrawSystemState("CTR Network Updater", s_RenderSystem, titleColor, flip, adapterState,
s_HwUtility.GetCupMajorVersion(), s_HwUtility.GetCupMinorVersion(), s_HwUtility.GetCupMicroVersion(), s_HwUtility.GetCupMajorVersion(), s_HwUtility.GetCupMinorVersion(), s_HwUtility.GetCupMicroVersion(),
s_HwUtility.GetNupVersion(), s_HwUtility.GetBatteryRemain(), s_HwUtility.GetInfraDeviceId(), s_HwUtility.GetNupVersion(), s_HwUtility.GetBatteryRemain(), GetProgress(), IsRestoreFailed(), IsRestoreSucceeded(), false,
s_HwUtility.GetFriendcode(), GetProgress(), IsRestoreFailed(), IsRestoreSucceeded(), false, operationMessage, s_HwUtility.GetRegion(), s_HwUtility.IsWifiOn());
s_HwUtility.GetMacAddress(), operationMessage, s_HwUtility.GetRegion(), s_HwUtility.GetSerialNumber(),
s_HwUtility.HasReadFriendCode(), s_HwUtility.IsWifiOn());
s_RenderSystem.SwapBuffers(); s_RenderSystem.SwapBuffers();

View File

@ -27,13 +27,6 @@ AccessControlInfo:
FileSystemAccess: FileSystemAccess:
- DirectSdmc - DirectSdmc
- Core
- CategoryFileSystemTool
- ExportImportIvs
IoAccessControl:
- FsMountNand
- FsMountTwln
Option: Option:
FreeProductCode: true FreeProductCode: true

View File

@ -74,7 +74,7 @@ LIBFILES += $`(addprefix $(CTRMW_QRE_ROOT)$(DIRSEP)$(SUBDIR_LIBRARIES
INSTALL_SDK_TOOL = true INSTALL_SDK_TOOL = true
ROM_SPEC_FILE = $(TARGET_NAME).rsf ROM_SPEC_FILE = $(TARGET_NAME).rsf
DESCRIPTOR = $(HORIZON_ROOT)/resources/specfiles/private/RepairTool.desc DESCRIPTOR = $(HORIZON_ROOT)/resources/specfiles/private/NetworkUpdaterForRepair.desc
include $(ROOT_OMAKE)/modulerules include $(ROOT_OMAKE)/modulerules

View File

@ -1,70 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: Aes_define.h
Copyright 2009 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#ifndef AES_DEFINE_H_
#define AES_DEFINE_H_
//マスタリング用ビルド時に有効にする
//#define USE_PROD_KEY
#include <nn/drivers/aes/CTR/ARM946ES/driverAes_Types.h>
namespace common
{
#ifndef USE_PROD_KEY
const bit8 key[AES_KEY_SIZE] NN_ATTRIBUTE_ALIGN(4) =
{
0x81, 0x35, 0xc6, 0x54, 0x19, 0x1a, 0x47, 0x2a,
0x6b, 0x78, 0xbe, 0x25, 0x90, 0xf6, 0xee, 0x74
};
const bit8 cmacKey[AES_KEY_SIZE] =
{
0x87, 0xdd, 0xc6, 0xd6, 0xf2, 0xe0, 0x2c, 0xa6,
0x04, 0x21, 0x9c, 0x5e, 0x33, 0x8c, 0x3d, 0xaa
};
const bit8 iv[AES_BLOCK_SIZE] NN_ATTRIBUTE_ALIGN(4) =
{
0xdf, 0x0f, 0xf9, 0x1b, 0x34, 0x47, 0x70, 0x7f,
0x7d, 0x06, 0x85, 0xe6, 0xe7, 0xb6, 0x4e, 0xe9
};
#else
const bit8 key[AES_KEY_SIZE] NN_ATTRIBUTE_ALIGN(4) =
{
0x64, 0x02, 0x6d, 0xbd, 0x9f, 0xb6, 0x62, 0x39,
0x86, 0x90, 0x67, 0x8a, 0xe2, 0xfa, 0xe1, 0x6e
};
const bit8 cmacKey[AES_KEY_SIZE] =
{
0xdf, 0x3c, 0x58, 0xeb, 0xeb, 0xbf, 0x45, 0x6d,
0xc9, 0xbe, 0xe3, 0x10, 0xe2, 0x23, 0xfc, 0x30
};
const bit8 iv[AES_BLOCK_SIZE] NN_ATTRIBUTE_ALIGN(4) =
{
0xe4, 0xcf, 0x58, 0xe5, 0xc9, 0xd6, 0xac, 0x7d,
0xf1, 0xb9, 0x82, 0xf9, 0xa2, 0xd8, 0xda, 0x7b
};
#endif
}
#endif /* AES_DEFINE_H_ */

View File

@ -32,15 +32,10 @@ u8 s_CupMinor;
u8 s_CupMicro; u8 s_CupMicro;
u8 s_NupMajor; u8 s_NupMajor;
nn::cfg::CTR::CfgRegionCode s_Region; nn::cfg::CTR::CfgRegionCode s_Region;
u8 s_SerialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN + 1];
char s_DeviceIdStr[30];
char8 s_MacAddress[nn::nwm::Mac::MAC_STRING_SIZE];
u64 s_FriendCode;
u8 s_BatteryRemain; u8 s_BatteryRemain;
std::string s_AdapterState; std::string s_AdapterState;
u8 s_Progress; u8 s_Progress;
OperationMessage* s_OperationMessage; OperationMessage* s_OperationMessage;
bool s_ReadFriendCode;
bool s_IsWifiOn; bool s_IsWifiOn;
} }
@ -66,16 +61,6 @@ void SetTextWriterCore()
GetTextWriter()->SetTextColor(nn::util::Color8(255, 255, 255, 255)); GetTextWriter()->SetTextColor(nn::util::Color8(255, 255, 255, 255));
} }
GetTextWriter()->Printf("System Region %s\n", nn::cfg::CTR::GetRegionCodeA3(s_Region)); GetTextWriter()->Printf("System Region %s\n", nn::cfg::CTR::GetRegionCodeA3(s_Region));
GetTextWriter()->Printf("Serial No. %s\n", s_SerialNo);
GetTextWriter()->Printf("Device ID %s\n", s_DeviceIdStr);
GetTextWriter()->Printf("MAC Address %s\n", s_MacAddress);
if (s_ReadFriendCode)
{
GetTextWriter()->Printf("Friend Code %04u-%04u-%04u\n",
static_cast<u32>(s_FriendCode / 100000000ULL % 10000ULL), static_cast<u32> (s_FriendCode / 10000ULL % 10000ULL),
static_cast<u32> (s_FriendCode % 10000ULL));
}
GetTextWriter()->Printf("Battery %d%%\n", s_BatteryRemain); GetTextWriter()->Printf("Battery %d%%\n", s_BatteryRemain);
GetTextWriter()->Printf("AC Adapter %s\n", s_AdapterState.c_str()); GetTextWriter()->Printf("AC Adapter %s\n", s_AdapterState.c_str());
GetTextWriter()->Printf("Progress %02d%%\n", s_Progress); GetTextWriter()->Printf("Progress %02d%%\n", s_Progress);
@ -102,17 +87,12 @@ void DrawSystemState
u8 cupMicroVersion, u8 cupMicroVersion,
u8 nupVersion, u8 nupVersion,
u8 batteryRemain, u8 batteryRemain,
u64 deviceId,
u64 friendCode,
u32 progress, u32 progress,
bool isProcessFailed, bool isProcessFailed,
bool isProcessSucceeded, bool isProcessSucceeded,
bool isProcessWarning, bool isProcessWarning,
char8* macAddress,
OperationMessage& operationMessage, OperationMessage& operationMessage,
nn::cfg::CTR::CfgRegionCode region, nn::cfg::CTR::CfgRegionCode region,
u8* serialNo,
bool readFriendCode,
bool isWifiOn bool isWifiOn
) )
@ -124,18 +104,9 @@ void DrawSystemState
s_CupMicro = cupMicroVersion; s_CupMicro = cupMicroVersion;
s_NupMajor = nupVersion; s_NupMajor = nupVersion;
s_BatteryRemain = batteryRemain; s_BatteryRemain = batteryRemain;
nn::nstd::TSNPrintf(s_DeviceIdStr, sizeof(s_DeviceIdStr), "%llu", deviceId);
std::string deviceIdString(s_DeviceIdStr);
Util::SplitDeviceidWithSpace(deviceIdString);
std::memcpy(s_DeviceIdStr, deviceIdString.c_str(), deviceIdString.size());
s_FriendCode = friendCode;
s_Progress = progress; s_Progress = progress;
std::memcpy(s_MacAddress, macAddress, sizeof(s_MacAddress));
s_Region = region; s_Region = region;
std::memcpy(s_SerialNo, serialNo, sizeof(s_SerialNo));
s_SerialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN] = '\0';
s_OperationMessage = &operationMessage; s_OperationMessage = &operationMessage;
s_ReadFriendCode = readFriendCode;
s_IsWifiOn = isWifiOn; s_IsWifiOn = isWifiOn;
@ -182,17 +153,10 @@ void DrawSystemState
// プログレスバー // プログレスバー
fontwidth = 8; fontwidth = 8;
fontheight = 14; fontheight = 14;
if(readFriendCode) line += 5;
{
line += 9;
}
else
{
line += 8;
}
const u8 offset = 19; const u8 offset = 19;
const u8 diff = 4; const u8 diff = 8;
renderSystem.SetColor(0.f, 0.2f, 0.f); renderSystem.SetColor(0.f, 0.2f, 0.f);
renderSystem.DrawLine(offset * fontwidth, (line - 1) * fontheight - diff, offset * fontwidth + PROGRESS_MAX_LINES, (line - 1) renderSystem.DrawLine(offset * fontwidth, (line - 1) * fontheight - diff, offset * fontwidth + PROGRESS_MAX_LINES, (line - 1)
* fontheight - diff); * fontheight - diff);

View File

@ -59,17 +59,12 @@ void DrawSystemState
u8 cupMicroVersion, u8 cupMicroVersion,
u8 nupVersion, u8 nupVersion,
u8 batteryRemain, u8 batteryRemain,
u64 deviceId,
u64 friendCode,
u32 progress, u32 progress,
bool isProcessFailed, bool isProcessFailed,
bool isProcessSucceeded, bool isProcessSucceeded,
bool isProcessWarning, bool isProcessWarning,
char8* macAddress,
OperationMessage& operationMessage, OperationMessage& operationMessage,
nn::cfg::CTR::CfgRegionCode region, nn::cfg::CTR::CfgRegionCode region,
u8* s_SerialNo,
bool readFriendCode,
bool isWifiOn bool isWifiOn
); );

View File

@ -76,76 +76,11 @@ void ClearFileCheck(FileExistsCheck index)
s_FileExistsChecked[index] = false; s_FileExistsChecked[index] = false;
} }
bool ExistsUpdateCheckedFile()
{
return ExistsFile(EXISTS_UPDATE_FINISHED);
}
bool ExistsSerialNumberFile()
{
return ExistsFile(EXISTS_SERIAL_NUMBER);
}
bool ExistsIVSFile()
{
return ExistsFile(EXISTS_IVS);
}
bool ExistsConsoleInitializedFile()
{
return ExistsFile(EXISTS_CONSOLE_INTIALIZED);
}
bool ExistsWriteFinishedFile()
{
return ExistsFile(EXISTS_WRITE_FINISHED);
}
bool ExistsAPSetting() bool ExistsAPSetting()
{ {
return ExistsFile(EXISTS_AP_SETTING); return ExistsFile(EXISTS_AP_SETTING);
} }
bool ExistsRtcSyncFinishedFile()
{
return ExistsFile(EXISTS_RTC_SYNC_FINISHED);
}
bool ExistsCountryLanguageFile()
{
return ExistsFile(EXISTS_COUNTRY_LANGUAGE);
}
bool ExistsRegionData()
{
return ExistsFile(EXISTS_REGION_DATA);
}
bool ExistsDeleteAccountChecked()
{
return ExistsFile(EXISTS_DELETE_ACCOUNT);
}
bool ExistsTransferAccountChecked()
{
return ExistsFile(EXISTS_TRANSFER_ACCOUNT);
}
bool ExistsDownloadIvsCheckedFile()
{
return ExistsFile(EXISTS_DOWNLOAD_IVS);
}
bool ExistsTwlTitleListFile()
{
return ExistsFile(EXISTS_TWL_TITLELIST);
}
bool ExistsFileMoveContextFile()
{
return ExistsFile(EXISTS_MOVE_CONTEXT);
}
void InitializeFileCheck() void InitializeFileCheck()
{ {
for(u32 i = 0; i < EXISTS_MAX; i++) for(u32 i = 0; i < EXISTS_MAX; i++)

View File

@ -24,20 +24,7 @@ namespace common
// チェックしたいファイルのリスト // チェックしたいファイルのリスト
typedef enum FILE_EXISTS_CHECK typedef enum FILE_EXISTS_CHECK
{ {
EXISTS_UPDATE_FINISHED, // ネットワークアップデート完了
EXISTS_SERIAL_NUMBER, // シリアルナンバー
EXISTS_IVS, // IVS
EXISTS_CONSOLE_INTIALIZED, // 本体初期化完了
EXISTS_WRITE_FINISHED, // 書き込み完了
EXISTS_AP_SETTING, // 無線設定ファイル EXISTS_AP_SETTING, // 無線設定ファイル
EXISTS_RTC_SYNC_FINISHED, // RTC書き込み完了
EXISTS_COUNTRY_LANGUAGE, // 国設定書き込み完了
EXISTS_REGION_DATA, // リージョン
EXISTS_DELETE_ACCOUNT, // アカウント削除完了
EXISTS_TRANSFER_ACCOUNT, // アカウント移行完了
EXISTS_DOWNLOAD_IVS, // IVSダウロード完了
EXISTS_TWL_TITLELIST, // TWLタイトルリストファイル
EXISTS_MOVE_CONTEXT, // ファイル移動用コンテキスト
EXISTS_MAX EXISTS_MAX
} FileExistsCheck; } FileExistsCheck;
@ -45,39 +32,13 @@ typedef enum FILE_EXISTS_CHECK
// チェックしたいファイルのリストに対応したパス // チェックしたいファイルのリストに対応したパス
const wchar_t* const FILENAME_TABLE[EXISTS_MAX] = const wchar_t* const FILENAME_TABLE[EXISTS_MAX] =
{ {
common::UPDATE_CHECK_PATHNAME,
common::SERIAL_PATHNAME,
common::IVS_PATHNAME,
common::INITIALIZED_CHECK_PATHNAME,
common::WRITE_FINISHED_CHECK_PATHNAME,
common::AP_SETTING_PATHNAME, common::AP_SETTING_PATHNAME,
common::RTC_SYNC_CHECK_PATHNAME,
common::COUNTRY_SETTING_PATHNAME,
common::REGION_DATA_PATHNAME,
common::DELETE_ACCOUNT_CHECK_PATHNAME,
common::TRANSFER_ACCOUNT_CHECK_PATHNAME,
common::DOWNLOAD_IVS_CHECK_PATHNAME,
common::TWL_TITLELIST_PATHNAME,
common::MOVE_CONTEXT_PATHNAME
}; };
// ファイルが存在するかどうか // ファイルが存在するかどうか
bool CheckFileExists(const wchar_t* path); bool CheckFileExists(const wchar_t* path);
bool ExistsUpdateCheckedFile();
bool ExistsSerialNumberFile();
bool ExistsIVSFile();
bool ExistsConsoleInitializedFile();
bool ExistsWriteFinishedFile();
bool ExistsAPSetting(); bool ExistsAPSetting();
bool ExistsRtcSyncFinishedFile();
bool ExistsCountryLanguageFile();
bool ExistsRegionData();
bool ExistsDeleteAccountChecked();
bool ExistsTransferAccountChecked();
bool ExistsDownloadIvsCheckedFile();
bool ExistsTwlTitleListFile();
bool ExistsFileMoveContextFile();
// ファイルチェックの結果を初期化する // ファイルチェックの結果を初期化する
// 一度チェックするとその結果を保持するため // 一度チェックするとその結果を保持するため

View File

@ -1,811 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: FileTransfer.cpp
Copyright 2009 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#include <vector>
#include <string>
#include <nn/crypto/crypto_AesCmac.h>
#include <nn/crypto/crypto_SwAesCtrContext.h>
#include <nn/crypto/crypto_Sha256.h>
#include <nn/crypto/crypto_SwAesCmac.h>
#include "Aes_define.h"
#include "FileTransfer.h"
#include "CommonLogger.h"
#include "common_Types.h"
#include "FileName.h"
namespace common
{
namespace
{
u64 s_TotalFileSize;
u64 s_FinishedFileSize = 0;
u64 s_Progress = 0;
}
bool VerifyMac(nn::fs::FileInputStream* sdFile, nn::fs::FileStream* nandFile, s64 sdFileSize, s64 nandFileSize,
const wchar_t* nandPath, void* buf, size_t bufSize);
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);
bool AddPathNameAndUpdateContext(nn::fs::FileOutputStream* file, const wchar_t *str, s64 fileSize,
nn::crypto::Sha256Context* context);
const char* GetCharStr(const wchar_t* path)
{
static char filename[nn::fs::MAX_FILE_PATH_LENGTH];
std::memset(filename, 0, sizeof(filename));
std::wcstombs(filename, path, sizeof(filename));
filename[sizeof(filename) - 1] = '\0';
return filename;
}
nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, s64& fileSize)
{
nn::fs::Directory dir;
nn::Result result;
std::vector<nn::fs::DirectoryEntry> entryList; //カレントディレクトリのエントリ一覧を格納
std::vector<nn::fs::DirectoryEntry>::iterator entryIndex;
result = dir.TryInitialize(currentDirectory.c_str());
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
nn::fs::DirectoryEntry entry;
s32 numEntry;
for (;;)
{
result = dir.TryRead(&numEntry, &entry, 1);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
if (numEntry == 0)
{
// カレントディレクトリを閉じる
dir.Finalize();
// カレントディレクトリの子を開く
for (entryIndex = entryList.begin(); entryIndex != entryList.end(); entryIndex++)
{
if (entryIndex->attributes.isDirectory)
{
result = CalculateFileNum(currentDirectory + std::wstring(entryIndex->entryName) + std::wstring(L"/"),
fileNum, fileSize);
}
}
return result;
}
entryList.push_back(entry);
fileNum++;
fileSize += entry.entrySize;
}
}
bool ExistsInList(ImportDataList* fileList, const wchar_t* path, bool isDirectory)
{
std::wstring sdPath(path);
if(isDirectory)
{
sdPath += std::wstring(L"/");
}
char str[nn::fs::MAX_FILE_PATH_LENGTH];
std::strlcpy(str, GetCharStr(sdPath.c_str()), sizeof(str));
bool returnValue = false;
for(ImportDataList::iterator it = fileList->begin(); it != fileList->end(); it++)
{
if(std::strcmp(str, it->fileName.c_str()) == 0)
{
returnValue = true;
NN_LOG("%s exists in FileList.txt\n", str);
break;
}
}
return returnValue;
}
bool ExportTwlSaveDirectory(const wchar_t* dirPath, nn::fs::FileOutputStream* list,
nn::crypto::Sha256Context* listContext)
{
NN_LOG("Create Directory %ls\n", dirPath);
nn::Result result = nn::fs::TryCreateDirectory(dirPath);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
return AddPathNameAndUpdateContext(list, dirPath, -1, listContext);
}
bool ExportTwlSaveFile(const wchar_t* from_path, const wchar_t* to_path, void* buf, const size_t bufSize,
nn::fs::FileOutputStream* list, nn::crypto::Sha256Context* listContext)
{
NN_LOG("from = %ls\n", from_path);
NN_LOG("to = %ls\n", to_path);
nn::Result result;
// ファイル作成
nn::fs::FileInputStream from_file;
nn::fs::FileStream to_file;
s64 filesize;
s32 readsize;
s32 writesize;
NN_LOG("Copy File %ls\n", from_path);
// 読み込み対象ファイル開く
result = from_file.TryInitialize(from_path);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
// 読み込み対象ファイルのサイズ取得
result = from_file.TryGetSize(&filesize);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
if (!AddPathNameAndUpdateContext(list, to_path, filesize, listContext))
{
return false;
}
nn::crypto::SwAesCtrContext swAesCtrContext;
swAesCtrContext.Initialize(iv, common::key, sizeof(key));
size_t totalReadSize = 0;
nn::crypto::Sha256Context context;
context.Initialize();
// ファイルサイズをヘッダに書いておく
// 書き込み対象ファイル作成
result = nn::fs::TryCreateFile(to_path, filesize);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
result = to_file.TryInitialize(to_path,
nn::fs::OPEN_MODE_READ | nn::fs::OPEN_MODE_WRITE | nn::fs::OPEN_MODE_CREATE);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
// フルパスをハッシュに含める
context.Update(from_path, std::wcslen(from_path) * sizeof(wchar_t));
BackupDataHeader header;
BackupDataHeader enc;
std::memset(&header, 0, sizeof(header));
std::memset(&enc, 0, sizeof(enc));
header.size = filesize;
result = swAesCtrContext.Encrypt(&enc, &header, sizeof(header));
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context.Update(&enc, sizeof(enc));
s32 writeSize;
result = to_file.TryWrite(&writeSize, &enc, sizeof(enc), false);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
while (1)
{
// バッファの後半半分を暗号・復号用に使う
result = from_file.TryRead(&readsize, buf, bufSize / 2);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
totalReadSize += readsize;
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
if (readsize == 0)
{
NN_LOG("Add CMAC %ls\n", from_path);
// SHA256を計算してCMACを付加する
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_RETURN_FALSE_IF_FAILED(result);
result = to_file.TryWrite(&writesize, cmac, sizeof(cmac), true);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
result = to_file.TryFlush();
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
break;
}
else
{
NN_LOG("EncryptSize = %d\n", readsize);
u8 paddingSize = 0;
AddPkcsPadding(&paddingSize, reinterpret_cast<bit8*>(buf), bufSize / 2, &readsize);
// 暗号化後SHA256を計算しつつ書き込み
result = swAesCtrContext.Encrypt(reinterpret_cast<bit8*>(buf) + bufSize / 2, buf, readsize);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context.Update(reinterpret_cast<bit8*>(buf) + bufSize / 2, readsize);
result = to_file.TryWrite(&writesize, reinterpret_cast<bit8*>(buf) + bufSize / 2, readsize, false);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
// 事前計算したファイルサイズに一致させるためパディング分減算
readsize -= paddingSize;
s_FinishedFileSize += readsize;
s_Progress = s_FinishedFileSize * 100 / s_TotalFileSize;
NN_LOG( "finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress);
}
}
to_file.Finalize();
from_file.Finalize();
return true;
}
bool CopyDirectory(ImportDataList* fileList, 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;
s32 numread = 0;
std::wostringstream target_from;
std::wostringstream target_to;
nn::Result result = from_dir.TryInitialize(from_path);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
while (1)
{
result = from_dir.TryRead(&numread, &entry, 1);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
if(numread == 0)
{
break;
}
if (std::wcscmp(entry.entryName, L".") == 0 || std::wcscmp(entry.entryName, L"..") == 0)
{
continue;
}
target_from.str(L"");
target_from.clear(std::stringstream::goodbit);
target_from << from_path << entry.entryName;
target_to.str(L"");
target_to.clear(std::stringstream::goodbit);
target_to << to_path << entry.entryName;
// NAND書き込みの場合はリストに存在するかチェックする
if (!encode)
{
if (!ExistsInList(fileList, target_from.str().c_str(), entry.attributes.isDirectory))
{
NN_LOG("============No such file %ls in FileList.txt. Skip=============\n", target_from.str().c_str());
continue;
}
}
// ディレクトリの場合
if (entry.attributes.isDirectory)
{
// ディレクトリ作成
NN_LOG("Create Directory %ls\n", target_to.str().c_str());
result = nn::fs::TryCreateDirectory(target_to.str().c_str());
if (result.IsSuccess() || result.IsFailure() && result <= nn::fs::ResultAlreadyExists())
{
target_from << L"/";
target_to << L"/";
if(encode)
{
if(!AddPathNameAndUpdateContext(list, target_to.str().c_str(), -1, listContext))
{
return false;
}
}
// 再帰処理
if (!CopyDirectory(fileList, target_from.str().c_str(), target_to.str().c_str(), buf, bufSize, encode, list, listContext))
{
return false;
}
}
else
{
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
}
}
// ファイルの場合
else
{
std::wostringstream target_tmp;
target_tmp.str(L"");
target_tmp.clear(std::stringstream::goodbit);
if(!encode)
{
target_tmp << to_path << L"_" << entry.entryName;
}
else
{
target_tmp << target_to.str();
}
// ファイル作成
nn::fs::FileInputStream from_file;
nn::fs::FileStream to_file;
s64 filesize;
s64 fileSizeWithoutHeaderAndFooter;
s32 readsize;
s32 writesize;
NN_LOG("Copy File %ls\n", target_from.str().c_str());
// 読み込み対象ファイル開く
result = from_file.TryInitialize(target_from.str().c_str());
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
// 読み込み対象ファイルのサイズ取得
result = from_file.TryGetSize(&filesize);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
if (encode)
{
if (!AddPathNameAndUpdateContext(list, target_to.str().c_str(), filesize, listContext))
{
return false;
}
}
nn::crypto::SwAesCtrContext swAesCtrContext;
swAesCtrContext.Initialize(iv, common::key, sizeof(key));
size_t totalReadSize = 0;
nn::crypto::Sha256Context context;
context.Initialize();
// ファイルサイズをヘッダに書いておく
if (encode)
{
// 書き込み対象ファイル作成
result = nn::fs::TryCreateFile(target_tmp.str().c_str(), filesize);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
result = to_file.TryInitialize(target_tmp.str().c_str(),
nn::fs::OPEN_MODE_READ | nn::fs::OPEN_MODE_WRITE | nn::fs::OPEN_MODE_CREATE);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
// フルパスをハッシュに含める
context.Update(target_from.str().c_str(), target_from.str().size() * sizeof(wchar_t));
BackupDataHeader header;
BackupDataHeader enc;
std::memset(&header, 0, sizeof(header));
std::memset(&enc, 0, sizeof(enc));
header.size = filesize;
result = swAesCtrContext.Encrypt(&enc, &header, sizeof(header));
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context.Update(&enc, sizeof(enc));
s32 writeSize;
result = to_file.TryWrite(&writeSize, &enc, sizeof(enc), false);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
}
else
{
// ヘッダを読む
// ハッシュの計算は終わっているので復号化のみ
BackupDataHeader header;
BackupDataHeader dec;
std::memset(&header, 0, sizeof(header));
std::memset(&dec, 0, sizeof(dec));
s32 readSize;
result = from_file.TryRead(&readSize, &header, sizeof(header));
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
swAesCtrContext.Decrypt(&dec, &header, sizeof(header));
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
fileSizeWithoutHeaderAndFooter = dec.size;
// 書き込み対象ファイル作成
result = nn::fs::TryCreateFile(target_tmp.str().c_str(), fileSizeWithoutHeaderAndFooter);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
result = to_file.TryInitialize(target_tmp.str().c_str(),
nn::fs::OPEN_MODE_READ | nn::fs::OPEN_MODE_WRITE | nn::fs::OPEN_MODE_CREATE);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
}
while (1)
{
// バッファの後半半分を暗号・復号用に使う
result = from_file.TryRead(&readsize, buf, bufSize / 2);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
totalReadSize += readsize;
if (readsize == 0)
{
if (encode)
{
NN_LOG("Add CMAC %ls\n", target_from.str().c_str());
// SHA256を計算してCMACを付加する
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_RETURN_FALSE_IF_FAILED(result);
result = to_file.TryWrite(&writesize, cmac, sizeof(cmac), true);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
}
result = to_file.TryFlush();
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
// 復号済みなら検証する
if (!encode)
{
if (!ConfirmFile(&from_file, &to_file, filesize, fileSizeWithoutHeaderAndFooter, buf, bufSize,
target_from.str().c_str(), target_tmp.str().c_str(), target_to.str().c_str()))
{
return false;
}
}
break;
}
else
{
if (encode)
{
NN_LOG("EncryptSize = %d\n", readsize);
u8 paddingSize = 0;
AddPkcsPadding(&paddingSize, reinterpret_cast<bit8*>(buf), bufSize / 2, &readsize);
// 暗号化後SHA256を計算しつつ書き込み
result = swAesCtrContext.Encrypt(reinterpret_cast<bit8*>(buf) + bufSize / 2, buf, readsize);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context.Update(reinterpret_cast<bit8*>(buf) + bufSize / 2, readsize);
result = to_file.TryWrite(&writesize, reinterpret_cast<bit8*>(buf) + bufSize / 2, readsize,
false);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
// 事前計算したファイルサイズに一致させるためパディング分減算
readsize -= paddingSize;
s_FinishedFileSize += readsize;
s_Progress = s_FinishedFileSize * 100 / s_TotalFileSize;
NN_LOG(
"finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress);
}
else
{
// ハッシュ検証は通っているので復号化しつつ書き込み
// パディング以降は書き込まないよう書き込みサイズを変更する
NN_LOG("DecryptSize = %d\n", readsize);
result = swAesCtrContext.Decrypt(reinterpret_cast<bit8*>(buf) + bufSize / 2, buf, readsize);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
// パディングまで読んだかどうか
bool readDone = false;
// パディングまで読んでいたら書き込みサイズを減らす
if (fileSizeWithoutHeaderAndFooter < totalReadSize)
{
readsize -= totalReadSize - fileSizeWithoutHeaderAndFooter;
readDone = true;
}
result = to_file.TryWrite(&writesize, reinterpret_cast<bit8*>(buf) + bufSize / 2, readsize,
false);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
s_FinishedFileSize += readsize;
s_Progress = s_FinishedFileSize * 100 / s_TotalFileSize;
NN_LOG(
"finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress);
// 読みきったので次のファイルへ
if (readDone)
{
result = to_file.TryFlush();
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
if (!ConfirmFile(&from_file, &to_file, filesize, fileSizeWithoutHeaderAndFooter, buf,
bufSize, target_from.str().c_str(), target_tmp.str().c_str(),
target_to.str().c_str()))
{
return false;
}
break;
}
}
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
}
}
to_file.Finalize();
from_file.Finalize();
}
}
from_dir.Finalize();
return true;
}
u32 GetProgress()
{
return s_Progress;
}
void InitializeTransferProgress(u64 totalSize)
{
s_TotalFileSize = totalSize;
s_FinishedFileSize = 0;
}
bool CalculateAndCompareCmac(nn::crypto::Sha256Context* context, bit8* sdCmac)
{
nn::Result result;
bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE];
bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE];
context->GetHash(sha256Hash);
context->Finalize();
result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, sizeof(sha256Hash), common::cmacKey);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
return std::memcmp(cmac, sdCmac, sizeof(cmac)) == 0;
}
bool VerifyMac(nn::fs::FileInputStream* sdFile, nn::fs::FileStream* nandFile, s64 sdFileSize, s64 nandFileSize,
const wchar_t* nandPath, void* buf, size_t bufSize)
{
nn::Result result;
bit8 sdCmac[nn::crypto::AES_CMAC_MAC_SIZE];
// ハッシュが付加されていないとエラー
if(sdFileSize < nn::crypto::AES_CMAC_MAC_SIZE)
{
return false;
}
s32 readSize;
// ハッシュを取得する
result = sdFile->TrySetPosition(sdFileSize - nn::crypto::AES_CMAC_MAC_SIZE);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
result = sdFile->TryRead(&readSize, sdCmac, sizeof(sdCmac));
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
sdFile->Finalize();
nandFile->SetPosition(0);
// ハッシュを計算する
nn::crypto::SwAesCtrContext swAesCtrContext;
swAesCtrContext.Initialize(iv, common::key, sizeof(key));
nn::crypto::Sha256Context context;
context.Initialize();
// NAND上のフルパスをハッシュに含めている
context.Update(nandPath, std::wcslen(nandPath) * sizeof(wchar_t));
BackupDataHeader header;
BackupDataHeader enc;
std::memset(&header, 0, sizeof(header));
std::memset(&enc, 0, sizeof(enc));
header.size = nandFileSize;
result = swAesCtrContext.Encrypt(&enc, &header, sizeof(header));
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context.Update(&enc, sizeof(enc));
bool retValue = false;
size_t totalReadSize = 0;
while (1)
{
result = nandFile->TryRead(&readSize, buf, bufSize / 2);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
totalReadSize += readSize;
if (readSize == 0)
{
retValue = CalculateAndCompareCmac(&context, sdCmac);
break;
}
else
{
u8 paddingSize = 0;
AddPkcsPadding(&paddingSize, reinterpret_cast<bit8*>(buf), bufSize / 2, &readSize);
result = swAesCtrContext.Encrypt(reinterpret_cast<bit8*>(buf) + bufSize / 2, buf, readSize);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context.Update(reinterpret_cast<bit8*>(buf) + bufSize / 2, readSize);
}
}
nandFile->Finalize();
return retValue;
}
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)
{
nn::Result result;
NN_LOG("Verify CMAC %ls\n", sdPath);
if (!VerifyMac(from_file, to_file, sdFileSize, nandFileSize, truePath, buf, bufSize))
{
// 検証に失敗したので削除する
s_FinishedFileSize -= nandFileSize;
COMMON_LOGGER("**********Verification Failed %s, Delete**********\n", GetCharStr(sdPath));
result = nn::fs::TryDeleteFile(tmpPath);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
return false;
}
else
{
NN_LOG("Verification Success %s, Rename\n", GetCharStr(sdPath));
// 書き込み先を削除する
result = nn::fs::TryDeleteFile(truePath);
if (result.IsFailure() && !nn::fs::ResultNotFound::Includes(result))
{
COMMON_LOGGER("**********Verification Failed %s, Delete**********\n", GetCharStr(sdPath));
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
}
// 正しいファイル名にリネームする
result = nn::fs::TryRenameFile(tmpPath, truePath);
COMMON_LOGGER_RESULT_IF_FAILED(result);
if (result.IsFailure())
{
COMMON_LOGGER("**********Verification Failed %s, Delete**********\n", GetCharStr(sdPath));
s_FinishedFileSize -= nandFileSize;
return false;
}
}
return true;
}
//! @brief 入力データの末尾16バイトをPKCS5で必要バイト数パディングする
//! @param[out] paddingSize パディングしたバイト数
//! @param[in] buf 入力データの入ったバッファ
//! @param[in] bufSize バッファサイズ
//! @param[inout] readSize バッファに読み込んだバイト数。書き込み時に参照するためパディングしたら増加させる
void AddPkcsPadding(u8* paddingSize, void* buf, size_t bufSize, s32* readSize)
{
if (*readSize < bufSize)
{
if ((*readSize % AES_BLOCK_SIZE) != 0)
{
*paddingSize = AES_BLOCK_SIZE - *readSize % AES_BLOCK_SIZE;
std::memset(reinterpret_cast<bit8*>(buf) + *readSize, *paddingSize, *paddingSize);
*readSize += *paddingSize;
}
}
}
//! @brief パスにnimのセーブデータディレクトリが含まれているかどうかを返します
//! @param[in] str パス
//! @return パスにnimのセーブデータディレクトリが含まれているか
bool ContainsNimSaveDataDir(const wchar_t* str)
{
return std::wcsstr(str, common::NIM_SAVEDATA_DIRECTORY_NAME) != NULL;
}
//! @brief ファイルに文字列とサイズをカンマ区切り、改行付きで追加します
//! @param[in] file 文字列を出力したいファイル
//! @param[in] str 入力文字列
//! @param[in] fileSize サイズ
//! @param[in] context SHA-256計算用コンテキスト
bool AddPathNameAndUpdateContext(nn::fs::FileOutputStream* file, const wchar_t *str, s64 fileSize,
nn::crypto::Sha256Context* context)
{
nn::Result result;
s32 writeSize;
if(ContainsNimSaveDataDir(str))
{
return true;
}
std::string output(GetCharStr(str));
result = file->TryWrite(&writeSize, output.c_str(), output.size(), true);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context->Update(output.c_str(), output.size());
char comma = ',';
result = file->TryWrite(&writeSize, &comma, sizeof(comma), true);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context->Update(&comma, sizeof(comma));
char sizeStr[10];
std::memset(sizeStr, 0, sizeof(sizeStr));
s32 sizeStrSize = std::snprintf(sizeStr, sizeof(sizeStr), "%lld", fileSize);
result = file->TryWrite(&writeSize, sizeStr, sizeStrSize, true);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context->Update(sizeStr, sizeStrSize);
char newLine = '\n';
result = file->TryWrite(&writeSize, &newLine, sizeof(newLine), true);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
context->Update(&newLine, sizeof(newLine));
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());
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(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)
{
result = CalculateFileSizeRecursively(currentDirectory + std::wstring(entry.entryName) + std::wstring(L"/"), fileSize);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
}
// ファイルの場合
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

@ -1,67 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: FileTransfer.h
Copyright 2009 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#ifndef FILETRANSFER_H_
#define FILETRANSFER_H_
#include <nn.h>
#include <string>
#include <sstream>
#include "common_Types.h"
namespace common
{
// currentDirectory以下のファイル数、ファイルサイズを再帰的に計算する
nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, s64& fileSize);
// 単一のディレクトリを作成する
// アーカイブはマウント済みにしておく
bool ExportTwlSaveDirectory(const wchar_t* dirPath, nn::fs::FileOutputStream* list,
nn::crypto::Sha256Context* listContext);
// 単一のファイルをコピーする
// アーカイブはマウント済みにしておく
bool ExportTwlSaveFile(const wchar_t* from_path, const wchar_t* to_path, void* buf, const size_t bufSize,
nn::fs::FileOutputStream* list, nn::crypto::Sha256Context* listContext);
// ディレクトリ間のコピー
// アーカイブ越しのコピーが可能
// アーカイブにマウントした状態で呼び出す必要あり
// 書き込み先のディレクトリはあらかじめ消去しておくこと。
// 引数はスラッシュ付き
// TODO:分割して短くする
bool CopyDirectory(ImportDataList* fileList, 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);
// ファイル転送の進捗を取得する
// InitializeTransferProgress で設定した値を100とする割合が返される
u32 GetProgress();
// ファイル転送の目標値を設定する
void InitializeTransferProgress(u64 totalSize);
// wchar_t* を char* に変換する。
// 内部のバッファを使用するためスレッドアンセーフ
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

@ -28,16 +28,6 @@ HardwareStateManager::~HardwareStateManager()
} }
bool HardwareStateManager::CanReadIvs()
{
return m_pUtil->CanReadIVS();
}
bool HardwareStateManager::CanReadSerialNumber()
{
return m_pUtil->CanReadSerialNumber();
}
bool HardwareStateManager::IsBatteryLower() bool HardwareStateManager::IsBatteryLower()
{ {
return m_pUtil->IsBatteryLower(); return m_pUtil->IsBatteryLower();
@ -48,31 +38,11 @@ bool HardwareStateManager::IsAdapterConnected()
return m_pUtil->IsAdapterConnected(); return m_pUtil->IsAdapterConnected();
} }
bit32 HardwareStateManager::GetDeviceId()
{
return m_pUtil->GetDeviceId();
}
void HardwareStateManager::GetIvs(void** ivs, size_t* size)
{
return m_pUtil->GetIvs(ivs, size);
}
nn::Handle HardwareStateManager::GetMcuHandle() nn::Handle HardwareStateManager::GetMcuHandle()
{ {
return m_pUtil->GetMcuHandle(); return m_pUtil->GetMcuHandle();
} }
void HardwareStateManager::GetSerialNumber(u8** serial, size_t* size)
{
return m_pUtil->GetSerialNumber(serial, size);
}
void HardwareStateManager::GetSerialNumberWithoutCD(u8* serial)
{
return m_pUtil->GetSerialNumberWithoutCD(serial);
}
void HardwareStateManager::GetVersionData(common::VerDef* version) void HardwareStateManager::GetVersionData(common::VerDef* version)
{ {
return m_pUtil->GetVersionData(version); return m_pUtil->GetVersionData(version);

View File

@ -29,15 +29,9 @@ public:
explicit HardwareStateManager(Util& hwUtility); explicit HardwareStateManager(Util& hwUtility);
virtual ~HardwareStateManager(); virtual ~HardwareStateManager();
bool CanReadIvs();
bool CanReadSerialNumber();
bool IsBatteryLower(); bool IsBatteryLower();
bool IsAdapterConnected(); bool IsAdapterConnected();
bit32 GetDeviceId();
void GetIvs(void** ivs, size_t* size);
nn::Handle GetMcuHandle(); nn::Handle GetMcuHandle();
void GetSerialNumber(u8** serial, size_t* size);
void GetSerialNumberWithoutCD(u8* serial);
void GetVersionData(common::VerDef* version); void GetVersionData(common::VerDef* version);
void SetWifiOn(); void SetWifiOn();
void SetWifiOff(); void SetWifiOff();

View File

@ -1,253 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: QrImage.cpp
Copyright 2009-2011 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#include "QrImage.h"
#include "HeapManager.h"
#include "Util.h"
#include <cstring>
#include <string>
#include "ResFont.h"
#include <qre.h>
namespace
{
char s_DeviceIdStr[32];
char s_SerialNumberStr[32];
}
namespace common
{
QrImage::QrImage()
{
// TODO 自動生成されたコンストラクター・スタブ
}
QrImage::~QrImage()
{
// TODO Auto-generated destructor stub
}
void DrawDeviceId()
{
GetTextWriter()->Printf("DeviceId = %s", s_DeviceIdStr);
}
void DrawSerialNumber()
{
GetTextWriter()->Printf("SerialNo. = %s", s_SerialNumberStr);
}
void QrImage::Draw(demo::RenderSystemDrawing& renderSystem, bit64 deviceId, u8* serialNo, bool flip)
{
char deviceIdStr[32];
nn::nstd::TSNPrintf(deviceIdStr, sizeof(deviceIdStr), "%llu", deviceId);
std::string deviceIdString(deviceIdStr);
Util::SplitDeviceidWithSpace(deviceIdString);
std::strlcpy(s_DeviceIdStr, deviceIdString.c_str(), sizeof(s_DeviceIdStr));
std::strlcpy(s_SerialNumberStr, reinterpret_cast<char*>(serialNo), sizeof(s_SerialNumberStr));
renderSystem.SetRenderTarget(Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
renderSystem.Clear();
GetTextWriter()->SetTextColor(nn::util::Color8(255, 255, 255, 255));
SetDrawTextHandler(DrawDeviceId);
DrawResFont(Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
DrawStringinQr(renderSystem, reinterpret_cast<u8*>(deviceIdStr), Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
renderSystem.SwapBuffers();
renderSystem.SetRenderTarget(Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
renderSystem.Clear();
GetTextWriter()->SetTextColor(nn::util::Color8(255, 255, 255, 255));
SetDrawTextHandler(DrawSerialNumber);
DrawResFont(Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
DrawStringinQr(renderSystem, serialNo, Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
renderSystem.SwapBuffers();
}
void QrImage::DrawStringinQr(demo::RenderSystemDrawing& renderSystem, u8* str, u32 target)
{
using namespace mw::qre;
QREncoder *encoder = new QREncoder;
u32 dataSize = std::strlen(reinterpret_cast<char*>(str));
u32 requiredMemorySize = QREncoder::GetEncodeBufferSize(dataSize, 3, 1);
common::HeapManager heap(requiredMemorySize);
if(!heap.GetAddr())
{
NN_LOG("not enough memory\n");
return;
}
encoder->InitMemory(heap.GetAddr(), requiredMemorySize);
/* 作成するQRコードの情報を設定 */
EncodeData info;
// バージョン2で数字34文字OK
info.version = 10;
/* 誤り訂正レベルH */
info.ecc_level = ECC_LEVEL_H;
/* コンテンツ文字列の情報 */
info.size = dataSize;
info.data = str;
/*
*
*
*/
info.total = 1;
/* セルのサイズ設定 */
info.cell_size = 3;
/* エンコード実行 */
if (!encoder->Encode(&info))
{
/* エンコードに失敗 */
NN_LOG("QR encode failed...\n");
}
int qr_size = encoder->GetQRSize(0, false);
ImageInfo QRImage;
QRImage.rgb888Data = reinterpret_cast<u8*>(common::ForceAllocate(qr_size));
if (!QRImage.rgb888Data) {
NN_LOG("Memory allocation failed...\n");
return;
}
if(!encoder->GetQRData(&QRImage, 0))
{
NN_LOG("Get QRData Failed\n");
return;
}
delete encoder;
DrawImage(renderSystem, QRImage.rgb888Data, QRImage.width, QRImage.height, target);
common::ForceFree(QRImage.rgb888Data);
}
void QrImage::DrawImage(demo::RenderSystemDrawing& renderSystem, u8* textureDataPtr, u32 width, u32 height, u32 renderTarget)
{
static GLuint textureId = 0;
if (textureId != 0)
{
renderSystem.DeleteTexture(textureId);
}
GLenum target = GL_TEXTURE_2D;
GLenum internalFormat = GL_RGB_NATIVE_DMP;
GLenum format = GL_RGB_NATIVE_DMP;
GLenum type = GL_UNSIGNED_BYTE;
u32 textureWidth = width;
u32 textureHeight = height;
u8* textureDataBuffer = GetTextureDataFromRawData(width, height,
textureDataPtr,
textureWidth,
textureHeight);
renderSystem.GenerateTexture(target, internalFormat, textureWidth, textureHeight,
format, type, textureDataBuffer, textureId);
common::ForceFree(textureDataBuffer);
f32 windowPositionX = 0.0f;
f32 windowPositionY = 0.0f;
if (renderTarget == NN_GX_DISPLAY0)
{
windowPositionX = (nn::gx::DISPLAY0_HEIGHT / 2) - (width / 2);
if (height < nn::gx::DISPLAY0_WIDTH)
{
windowPositionY = (nn::gx::DISPLAY0_WIDTH / 2) - (height / 2);
}
}
else
{
windowPositionX = (nn::gx::DISPLAY1_HEIGHT / 2) - (width / 2);
if (height < nn::gx::DISPLAY1_WIDTH)
{
windowPositionY = (nn::gx::DISPLAY1_WIDTH / 2) - (height / 2);
}
}
f32 rectangleWidth = static_cast<f32>(width);
f32 rectangleHeight = static_cast<f32>(height);
renderSystem.FillTexturedRectangle(textureId,
windowPositionX, windowPositionY,
rectangleWidth, rectangleHeight,
static_cast<f32>(width),
static_cast<f32>(height),
static_cast<f32>(textureWidth),
static_cast<f32>(textureHeight));
}
u8* QrImage::GetTextureDataFromRawData(const u32& width,
const u32& height,
u8* rawDataBuffer,
u32& textureWidth,
u32& textureHeight)
{
textureWidth = GetTextureLength(width);
textureHeight = GetTextureLength(height);
u32 textureSize = textureWidth * textureHeight * 3;
u8* textureGLDataBuffer = reinterpret_cast<u8*>(common::ForceAllocate(textureSize));
u8* dstPtr = textureGLDataBuffer;
u32 y = 0;
for (; y < height; y++) {
// FLIP対応
// ConvertGLTextureToNative()にてFLIPしている。
u8* srcPtr = rawDataBuffer + width * (height - y - 1) * 3;
u32 x = 0;
for (; x < width; x++) {
dstPtr[0] = srcPtr[2];
dstPtr[1] = srcPtr[1];
dstPtr[2] = srcPtr[0];
dstPtr += 3;
srcPtr += 3;
}
for (; x < textureWidth; x++) {
dstPtr[0] = dstPtr[1] = dstPtr[2] = 0x00;
dstPtr += 3;
}
}
for (; y < textureHeight; y++) {
for (u32 x = 0; x < textureWidth; x++) {
dstPtr[0] = dstPtr[1] = dstPtr[2] = 0x00;
dstPtr += 3;
}
}
u8* textureDataBuffer = reinterpret_cast<u8*>(common::ForceAllocate(textureSize));
GLenum format = GL_RGB_NATIVE_DMP;
bool result = demo::ConvertGLTextureToNative(format, textureWidth, textureHeight,
textureGLDataBuffer, textureDataBuffer);
if (!result) {
NN_LOG(" Convert to GL_RGB_NATIVE_DMP failed.\n");
NN_ASSERT(0);
}
common::ForceFree(textureGLDataBuffer);
return textureDataBuffer;
}
u32 QrImage::GetTextureLength(const u32& imageLength)
{
u32 textureLength = 8;
// 8, 16, 32, 64, 128, 256, 512, 1024
for (u32 i = 0; i < 7; i++) {
if (imageLength < textureLength)
return textureLength;
textureLength *= 2;
}
return 1024;
}
} /* namespace common */

View File

@ -1,47 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: QrImage.h
Copyright 2009-2011 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#ifndef QRIMAGE_H_
#define QRIMAGE_H_
#include <nn.h>
#include "demo.h"
namespace common
{
class QrImage
{
public:
QrImage();
virtual ~QrImage();
static void Draw(demo::RenderSystemDrawing& renderSystem, bit64 deviceId, u8* serialNo, bool flip);
private:
// NULL終端された文字列を受け取り、QRコードにして表示する
static void DrawStringinQr(demo::RenderSystemDrawing& renderSystem, u8* str, u32 target);
static void DrawImage(demo::RenderSystemDrawing& renderSystem, u8* textureDataPtr, u32 width, u32 height, u32 renderTarget);
static u8* GetTextureDataFromRawData(const u32& width,
const u32& height,
u8* rawDataBuffer,
u32& textureWidth,
u32& textureHeight);
static u32 GetTextureLength(const u32& imageLength);
};
} /* namespace common */
#endif /* QRIMAGE_H_ */

View File

@ -1,570 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: SaveDataMover.cpp
Copyright 2009-2011 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#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/crypto/crypto_SwAesCtrContext.h>
#include <nn/ndm.h>
#include "Aes_define.h"
#include "SaveDataMover.h"
#include "CommonLogger.h"
#include "FileName.h"
#include "SdReaderWriter.h"
#include "FileTransfer.h"
#include "HeapManager.h"
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)
{
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;
}
}
SaveDataMover::SaveDataMover() :
m_Progress(0), m_FinishedSize(0), m_TotalSize(0), m_Result(nn::ResultSuccess())
{
}
SaveDataMover::~SaveDataMover()
{
}
void SaveDataMover::StartExport(void* buf, size_t bufSize, u64* progress)
{
SetupExport();
COMMON_LOGGER_RETURN_VOID_IF_FAILED(GetLastResult());
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;
}
void SaveDataMover::SetupExport()
{
// 1. デーモンの停止
m_Result = nn::ndm::Initialize();
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
m_Result = nn::ndm::SuspendScheduler();
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
// 2. StartDeviceMoveAsSource
nn::fs::DeviceMoveContext moveContext;
m_Result = nn::fs::StartDeviceMoveAsSource(&moveContext);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
// コンテキストのSDへの出力
common::HeapManager contextHeap(sizeof(moveContext));
void* enc;
enc = contextHeap.GetAddr();
if(!enc)
{
m_Result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_APPLICATION,
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
return;
}
// AES暗号化する
nn::crypto::SwAesCtrContext swAesCtrContest;
swAesCtrContest.Initialize(common::iv, common::key, sizeof(common::key));
m_Result = swAesCtrContest.Encrypt(enc, &moveContext, sizeof(moveContext));
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
common::SdReaderWriter sdWriter;
m_Result = sdWriter.WriteBufWithCmac(common::MOVE_CONTEXT_PATHNAME, enc, sizeof(moveContext));
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
// 3. 出力用ディレクトリの作成
// 3.1 システムセーブデータ用ディレクトリ
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::CalculateExportFileSize()
{
CalculateExportSystemSaveDataSize();
CalculateExportSharedExtSaveDataSize();
}
void SaveDataMover::CalculateExportSystemSaveDataSize()
{
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(s32 i = 0; i < systemSaveDataIdNum; ++i)
{
nn::fs::FileInputStream input;
bit32 id = s_SystemSaveDataIdList[i];
if(IsNotMovedId(id))
{
continue;
}
m_Result = nn::fs::OpenSystemSaveDataRawStorageFile(&input, id);
if(m_Result.IsFailure())
{
COMMON_LOGGER_WARN("Can't Export: %08x\n", id);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
continue;
}
m_TotalSize += input.GetSize();
}
}
void SaveDataMover::CalculateExportSharedExtSaveDataSize()
{
// 共有拡張セーブデータのサイズを確認する
// 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. アーカイブ内を走査して、含まれるファイルサイズを計算する
m_Result = common::CalculateFileSizeRecursively(L"sext:/", m_TotalSize);
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_LOG("calculatedSize = %lld\n", m_TotalSize);
}
void SaveDataMover::ExportSystemSaveData(void* buf, size_t bufSize, u64* progress)
{
s64 totalFileSize = 0;
// 0. ID の列挙を行う。
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(s32 i = 0; i < systemSaveDataIdNum; ++i)
{
nn::fs::FileInputStream input;
bit32 id = s_SystemSaveDataIdList[i];
if(IsNotMovedId(id))
{
continue;
}
NN_LOG("id: %08x\n", id);
// 1. fs::OpenSystemSaveDataRawStorageFile を呼び
// ID に対するセーブデータの FileInputStream を得る。
m_Result = nn::fs::OpenSystemSaveDataRawStorageFile(&input, id);
if(m_Result.IsFailure())
{
COMMON_LOGGER_WARN("Can't Export: %08x\n", id);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
continue;
}
NN_LOG("fileSize = %lld\n", input.GetSize());
totalFileSize += input.GetSize();
// SD へコピー
{
char outPath[64];
nn::nstd::TSNPrintf(outPath, 64, "%s/%08x", SD_SAVEDATA_SYS_ROOT_PATH, id);
NN_LOG("outPath = %s\n", outPath);
nn::fs::FileOutputStream output;
m_Result = output.TryInitialize(outPath, true);
if(m_Result.IsFailure())
{
COMMON_LOGGER_WARN("Can't Export: %08x\n", id);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
continue;
}
// 2. 1 で得たストリームからデータを読み込む。
// 本来はここで読み込んだデータを引っ越し先に転送するが
// ここでは SD カードにエクスポートする。
m_Result = CopyFile(input, output, buf, bufSize, progress);
if(m_Result.IsFailure())
{
COMMON_LOGGER_WARN("Can't Export: %08x\n", id);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
continue;
}
}
}
NN_LOG("\n");
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();
}
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)
{
m_Result = root.TryRead(&numOut, &entry, 1);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
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())
{
COMMON_LOGGER_WARN("Can't Import: %08x\n", id);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
continue;
}
// 1. fs::CreateAndOpenNewSystemSaveDataRawStorageFile を呼び
// ID に対する FileOutputStream を得る。
nn::fs::FileOutputStream output;
m_Result = nn::fs::CreateAndOpenNewSystemSaveDataRawStorageFile(&output, id, input.GetSize());
if(m_Result.IsFailure())
{
COMMON_LOGGER_WARN("Can't Import: %08x\n", id);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
continue;
}
// 2. 1 で得たストリームに対して書き込みを行う。
// 本来は引っ越し元からデータを受け取り、書き込むが
// ここでは SD から読み込んだデータを書き込む。
m_Result = CopyFile(input, output, buf, bufSize, progress);
if(m_Result.IsFailure())
{
COMMON_LOGGER_WARN("Can't Import: %08x\n", id);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
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)
{
m_Result = srcRoot.TryRead(&numEntry, &entry, 1);
COMMON_LOGGER_RETURN_VOID_IF_FAILED(m_Result);
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];
COMMON_LOGGER_RETURN_RESULT_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)
{
s64 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;
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(is.TryRead(&read, pBuffer, readSize));
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(os.TryWrite(&write, pBuffer, read, true));
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)
{
m_Result = nn::fs::TryCreateDirectory(destPath);
if (m_Result.IsFailure())
{
if (m_Result.GetDescription() == nn::fs::DESCRIPTION_FAT_ALREADY_EXISTS
&& m_Result.GetModule() == nn::Result::MODULE_NN_FS)
{
}
else
{
return m_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

@ -1,92 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: SaveDataMover.h
Copyright (C)2011 Nintendo Co., Ltd. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#ifndef SAVEDATAMOVER_H_
#define SAVEDATAMOVER_H_
#include <nn.h>
namespace common
{
class SaveDataMover
{
public:
SaveDataMover();
virtual ~SaveDataMover();
//! @brief SDカードへの出力を開始します
void StartExport(void* buf, size_t bufSize, u64* progress);
//! @brief SDカードからの入力を開始します
void StartImport(void* buf, size_t bufSize, u64* progress);
//! @brief 処理の結果を取得します
nn::Result GetLastResult();
private:
//******************** 出力用API群 ********************
//! @brief 出力を準備します
void SetupExport();
//! @brief 出力するファイルサイズを計算します
void CalculateExportFileSize();
void CalculateExportSystemSaveDataSize();
void CalculateExportSharedExtSaveDataSize();
//! @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);
//******************** 入力用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);
nn::Result CopyRecursivly(void* buf, size_t bufSize, const char* src, const char* dest, u64* progress);
NN_PADDING4;
s64 m_Progress;
s64 m_FinishedSize;
s64 m_TotalSize;
NN_PADDING4;
nn::Result m_Result;
};
} /* namespace common */
#endif /* SAVEDATAMOVER_H_ */

View File

@ -1,244 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: SdReaderWriter.cpp
Copyright 2009 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#include "SdReaderWriter.h"
#include "SdMountManager.h"
#include "CommonLogger.h"
#include "Aes_define.h"
#include <nn/crypto/crypto_AesCmac.h>
#include <nn/crypto/crypto_SwAesCtrContext.h>
#include <nn/crypto/crypto_Sha256.h>
#include <nn/crypto/crypto_SwAesCmac.h>
#include <cstdlib>
namespace common
{
nn::Result SdReaderWriter::Initialize()
{
nn::Result result;
// 初期化済みなら何もしない
if(m_IsInitialized)
{
return nn::ResultSuccess();
}
result = SdMountManager::Mount();
if(result.IsSuccess())
{
m_IsInitialized = true;
return nn::ResultSuccess();
}
else
{
return result;
}
}
nn::Result SdReaderWriter::Finalize()
{
nn::Result result;
result = SdMountManager::Unmount();
m_IsInitialized = false;
return result;
}
nn::Result SdReaderWriter::WriteBufCore(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size)
{
NN_ASSERT(path != NULL);
NN_ASSERT(size > 0);
nn::Result result = Initialize();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = file.TryInitialize(path, nn::fs::OPEN_MODE_WRITE | nn::fs::OPEN_MODE_CREATE);
if (result.IsSuccess())
{
s32 writeSize;
result = file.TryWrite(&writeSize, buf, size, false);
if (result.IsSuccess())
{
// 何もしない
}
else
{
NN_LOG("SD TryWrite failed\n");
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
}
}
else
{
NN_LOG("SD TryInitialize failed\n");
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
}
return result;
}
nn::Result SdReaderWriter::WriteBuf(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size)
{
nn::Result result;
result = WriteBufCore(file, path, buf, size);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = file.TryFlush();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
file.Finalize();
result = Finalize();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
return result;
}
nn::Result SdReaderWriter::WriteBufWithCmac(const wchar_t* path, void* buf, size_t size)
{
nn::Result result;
nn::fs::FileStream file;
result = WriteBufCore(file, path, buf, size);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE];
nn::crypto::CalculateSha256(sha256Hash, buf, size);
bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE];
result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
s32 writeSize;
result = file.TryWrite(&writeSize, cmac, sizeof(cmac), false);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = file.TryFlush();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
file.Finalize();
result = Finalize();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
return result;
}
nn::Result SdReaderWriter::ReadBufCore(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size,
size_t* totalSize)
{
NN_ASSERT(path != NULL);
NN_ASSERT(size > 0);
nn::Result result;
if(!m_IsInitialized)
{
Initialize();
}
result = file.TryInitialize(path, nn::fs::OPEN_MODE_READ);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
s32 readSize;
result = file.TryRead(&readSize, buf, size);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
// TODO バッファを超えるサイズのファイル読み込み
*totalSize = readSize;
return result;
}
nn::Result SdReaderWriter::ReadBuf(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size,
size_t* totalSize)
{
nn::Result result;
result = ReadBufCore(file, path, buf, size, totalSize);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
file.Finalize();
return result;
}
nn::Result SdReaderWriter::ReadBufWithCmac(const wchar_t* path, void* buf, size_t size, size_t* totalSize)
{
nn::Result result;
nn::fs::FileStream file;
NN_ASSERT(size > nn::crypto::AES_CMAC_MAC_SIZE);
result = ReadBufCore(file, path, buf, size, totalSize);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
file.Finalize();
// ハッシュが付加されていない
if(*totalSize < nn::crypto::AES_CMAC_MAC_SIZE)
{
return nn::fs::ResultVerificationFailed();
}
*totalSize -= nn::crypto::AES_CMAC_MAC_SIZE;
// CMACの検証を行う
bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE];
nn::crypto::CalculateSha256(sha256Hash, buf, *totalSize);
bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE];
result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
if(std::memcmp(reinterpret_cast<bit8*>(buf) + *totalSize, cmac, sizeof(cmac)) != 0)
{
// 無効なファイル
char filename[256];
std::wcstombs(filename, path, sizeof(filename));
filename[sizeof(filename) - 1] = '\0';
COMMON_LOGGER("Verification Failed %s\n", filename);
return nn::fs::ResultVerificationFailed();
}
// CMACを0埋め
std::memset(reinterpret_cast<bit8*>(buf) + *totalSize, 0, sizeof(cmac));
return result;
}
nn::Result SdReaderWriter::CreateDirectory(const wchar_t* path)
{
nn::Result result;
if(!m_IsInitialized)
{
Initialize();
}
NN_LOG("Create Directory %ls\n", path);
result = nn::fs::TryCreateDirectory(path);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = Finalize();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
return nn::ResultSuccess();
}
}

View File

@ -1,78 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: SdReaderWriter.h
Copyright 2009 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#ifndef SDWRITER_H_
#define SDWRITER_H_
#include <nn.h>
namespace common
{
//! @brief SDカードに書き込むためのクラスです。
class SdReaderWriter
{
public :
SdReaderWriter() : m_IsInitialized(false) {};
~SdReaderWriter() {};
//! @brief 渡されたバッファからsizeバイト指定されたパス名で書きこみます。CMACが付加されます。
//! @param[in] path sdmc:で始まる出力パス名。予めディレクトリを作っておく必要があります。
//! @param[in] buf 入力データへのポインタ
//! @param[in] size 入力データのサイズ
nn::Result WriteBufWithCmac(const wchar_t* path, void* buf, size_t size);
//! @brief 渡されたバッファへ(size - CMAC)バイト指定されたパス名から読み込みます
//! @param[in] path sdmc:で始まるCMAC付きの入力パス名
//! @param[in] buf 出力バッファへのポインタ
//! @param[in] size バッファサイズ
//! @param[out] totalSize 読み込んだデータ - CMAC のサイズ
nn::Result ReadBufWithCmac(const wchar_t* path, void* buf, size_t size, size_t* totalSize);
//! @brief 渡されたディレクトリ名のディレクトリを作成します
nn::Result CreateDirectory(const wchar_t* path);
private:
//! @brief 渡されたバッファからサイズ分指定されたパス名で書きこみます
//! @param[in] path sdmc:で始まる出力パス名。予めディレクトリを作っておく必要があります。
//! @param[in] buf 入力データへのポインタ
//! @param[in] size 入力データのサイズ
nn::Result WriteBuf(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size);
nn::Result WriteBufCore(nn::fs::FileStream& file, const wchar_t*path, void* buf, size_t size);
//! @brief 渡されたバッファへサイズ分指定されたパス名から読み込みます
//! @param[in] path sdmc:で始まる入力パス名
//! @param[in] buf 出力バッファへのポインタ
//! @param[in] size バッファサイズ
//! @param[out] totalSize 読み込んだデータのサイズ
nn::Result ReadBuf(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size, size_t* totalSize);
nn::Result ReadBufCore(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size, size_t* totalSize);
//! @brief 初期化します。
nn::Result Initialize();
//! @brief 終了します。
nn::Result Finalize();
NN_PADDING3;
bool m_IsInitialized;
};
}
#endif /* SDWRITER_H_ */

View File

@ -39,15 +39,13 @@
#include "FileName.h" #include "FileName.h"
#include "CommonLogger.h" #include "CommonLogger.h"
#include "HeapManager.h" #include "HeapManager.h"
#include "FileTransfer.h"
namespace common namespace common
{ {
Util::Util() : Util::Util() :
m_FriendCode(0), mp_Ivs(NULL), m_SizeofIvs(0), m_SerialNoWithoutCGLen(0), m_BatteryRemain(100), m_CanReadSerialNumber(false), m_CanReadIvs( m_BatteryRemain(100)
false), m_HasReadFriendCode(false)
{ {
} }
@ -65,17 +63,6 @@ void Util::InitializeForBackup()
void Util::InitializeForRestore() void Util::InitializeForRestore()
{ {
Initialize(); Initialize();
// friendsの初期化
nn::Result result = nn::friends::detail::Initialize();
// フレンドコードの取得
nn::friends::CTR::FriendKey friendKey;
result = nn::friends::CTR::GetMyFriendKey(&friendKey);
COMMON_LOGGER_RESULT_IF_FAILED(result);
m_FriendCode = nn::friends::CTR::FriendKeyToFriendCode(friendKey);
m_HasReadFriendCode = true;
} }
void Util::Initialize() void Util::Initialize()
@ -86,41 +73,14 @@ void Util::Initialize()
nn::mcu::CTR::InitializeHwCheck(&m_McuSession); nn::mcu::CTR::InitializeHwCheck(&m_McuSession);
mp_Mcu = new nn::mcu::CTR::HwCheck(m_McuSession); mp_Mcu = new nn::mcu::CTR::HwCheck(m_McuSession);
// シリアルナンバーの取得
std::memset(m_SerialNo, '\0',
nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
result = nn::cfg::CTR::system::GetSerialNo(m_SerialNo);
if(result.IsSuccess())
{
m_CanReadSerialNumber = true;
}
COMMON_LOGGER_RESULT_IF_FAILED(result);
AddCheckDigit(reinterpret_cast<char*>(m_SerialNo));
// デバイスIDの取得
result = nn::ps::CTR::GetDeviceId(&m_DeviceId);
COMMON_LOGGER_RESULT_IF_FAILED(result);
// リージョンの取得 // リージョンの取得
m_Region = nn::cfg::CTR::GetRegion(); m_Region = nn::cfg::CTR::GetRegion();
// バージョンの取得 // バージョンの取得
common::GetSystemVersion(&m_VerData, m_Region); common::GetSystemVersion(&m_VerData, m_Region);
// IVSの取得
ReadIvs(m_VerData.cup.majorVersion);
// nwmの初期化 // nwmの初期化
nn::nwm::InitializeExtControl(); nn::nwm::InitializeExtControl();
// MACアドレスの取得
nn::nwm::Mac mac;
result = nn::nwm::GetMacAddress(mac);
COMMON_LOGGER_RESULT_IF_FAILED(result);
mac.GetString(m_MacAddress);
COMMON_LOGGER_RESULT_IF_FAILED(result);
} }
void Util::FinalizeForBackup() void Util::FinalizeForBackup()
@ -157,110 +117,6 @@ bool Util::IsWifiOn()
return nn::nwm::IsWifiOn(); return nn::nwm::IsWifiOn();
} }
void Util::ReadIvs(u8 cupMajorVersion)
{
if (cupMajorVersion < common::CUP_MAJOR_VER_2ND_NUP)
{
nn::Result result;
// 完全性検証SEEDの取得
result = nn::fs::MountSpecialArchive(common::NAND_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
if (result.IsSuccess())
{
nn::fs::FileInputStream fis;
result = fis.TryInitialize(common::IVS_NAND_PATHNAME);
if (result.IsSuccess())
{
s64 fileSize = fis.GetSize();
s32 ret;
void* addr = NULL;
addr = ForceAllocate(fileSize);
if (addr != NULL)
{
mp_Ivs = addr;
m_SizeofIvs = fileSize;
result = fis.TryRead(&ret, addr, fileSize);
if (result.IsSuccess())
{
m_CanReadIvs = true;
}
// 後でIVSを参照するのでFreeしない
}
}
fis.Finalize();
}
// 一旦アンマウントしておく
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
}
else
{
nn::Result result;
void* pSeed = ForceAllocate(sizeof(nn::fs::CTR::IntegrityVerificationSeed));
if(pSeed != NULL)
{
result = nn::fs::CTR::ExportIntegrityVerificationSeed(
reinterpret_cast<nn::fs::CTR::IntegrityVerificationSeed*>(pSeed));
if(result.IsSuccess())
{
mp_Ivs = pSeed;
m_SizeofIvs = sizeof(nn::fs::CTR::IntegrityVerificationSeed);
m_CanReadIvs = true;
}
// 後でIVSを参照するのでFreeしない
}
}
}
// NULL終端されたシリアルナンバーを受け取る
// NULL終端された場所にチェックデジットを付加して新たにNULL終端する
void Util::AddCheckDigit(char* serial)
{
m_SerialNoWithoutCGLen = std::strlen(serial);
u8 digit = 0;
bool odd = true;
for(u8 i = m_SerialNoWithoutCGLen - 1; i > 0 && std::isdigit(serial[i]); i--)
{
if(odd)
{
digit += (serial[i] - '0') * 3;
}
else
{
digit += (serial[i] - '0');
}
odd = !odd;
}
if(digit % 10 != 0)
{
serial[m_SerialNoWithoutCGLen] = 10 - (digit % 10) + '0';
}
else
{
serial[m_SerialNoWithoutCGLen] = '0';
}
serial[m_SerialNoWithoutCGLen + 1] = '\0';
}
// /Nintendo 3DS/6ea6b9d6ab70493ea9edd8b947d5d819/853600b24760a87f534430320002544d
// から、6ea6b9d6ab70493ea9edd8b947d5d819 を取り出す
void Util::GetSaveDataDirectoryRoot(::std::string& sysSaveRoot)
{
nn::Result result;
wchar_t path[512];
result = nn::fs::GetSdmcCtrRootPath(path, sizeof(path));
COMMON_LOGGER_RETURN_VOID_IF_FAILED(result);
NN_LOG("%ls\n", path);
std::string sdmcRootPath = common::GetCharStr(path);
sysSaveRoot = sdmcRootPath.substr(sizeof("Nintendo 3DS/"), 32);
NN_LOG("saveRoot = %s\n", sysSaveRoot.c_str());
}
bool Util::IsAdapterConnected() bool Util::IsAdapterConnected()
{ {
static nn::os::Tick last(0); static nn::os::Tick last(0);
@ -288,44 +144,6 @@ bool Util::IsBatteryLower()
return m_BatteryRemain <= 10; return m_BatteryRemain <= 10;
} }
bool Util::CanReadIVS()
{
return m_CanReadIvs;
}
bool Util::CanReadSerialNumber()
{
return m_CanReadSerialNumber;
}
void Util::GetSerialNumber(u8** serial, size_t* size)
{
*serial = m_SerialNo;
*size = nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN;
}
u8* Util::GetSerialNumber()
{
return m_SerialNo;
}
void Util::GetSerialNumberWithoutCD(u8* serial)
{
std::memcpy(serial, m_SerialNo, nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
serial[m_SerialNoWithoutCGLen] = '\0';
}
void Util::GetIvs(void** ivs, size_t* size)
{
*ivs = mp_Ivs;
*size = m_SizeofIvs;
}
bit32 Util::GetDeviceId()
{
return m_DeviceId;
}
u8 Util::GetCupMajorVersion() u8 Util::GetCupMajorVersion()
{ {
return m_VerData.cup.majorVersion; return m_VerData.cup.majorVersion;
@ -358,23 +176,6 @@ u32 Util::GetBatteryRemain()
return remain; return remain;
} }
u64 Util::GetInfraDeviceId()
{
bit64 infraDeviceId;
infraDeviceId = m_DeviceId + common::INFRA_DEVICE_ID_OFFSET;
return infraDeviceId;
}
u64 Util::GetFriendcode()
{
return m_FriendCode;
}
char8* Util::GetMacAddress()
{
return m_MacAddress;
}
nn::cfg::CTR::CfgRegionCode Util::GetRegion() nn::cfg::CTR::CfgRegionCode Util::GetRegion()
{ {
return m_Region; return m_Region;
@ -390,27 +191,6 @@ void Util::GetVersionData(common::VerDef* version)
*version = m_VerData; *version = m_VerData;
} }
bool Util::HasReadFriendCode()
{
return m_HasReadFriendCode;
}
void Util::SplitDeviceidWithSpace(std::string& deviceIdStr)
{
std::string tmp = deviceIdStr;
deviceIdStr.clear();
u32 i = 0;
do
{
deviceIdStr.append(tmp.substr(i, 1));
i++;
if( i % 4 == 0)
{
deviceIdStr.push_back(' ');
}
}while( i < tmp.size());
}
u32 Util::GetRenderTarget(u32 target, bool flip) u32 Util::GetRenderTarget(u32 target, bool flip)
{ {
if(flip) if(flip)

View File

@ -49,39 +49,12 @@ public:
// 無線状態を取得する // 無線状態を取得する
bool IsWifiOn(); bool IsWifiOn();
// シリアルナンバーにモジュラス10 ウェイト3・1M10W31でチェックデジットを付加する
void AddCheckDigit(char* serial);
// IVSから計算されるセーブデータディレクトリ名を取得する
static void GetSaveDataDirectoryRoot(::std::string& sysSaveRoot);
// ACアダプタが接続されているかどうか // ACアダプタが接続されているかどうか
bool IsAdapterConnected(); bool IsAdapterConnected();
// バッテリ残量が10%未満かどうか // バッテリ残量が10%未満かどうか
bool IsBatteryLower(); bool IsBatteryLower();
// IVSを読み取れるかどうか
bool CanReadIVS();
// シリアルナンバーを読み取れるかどうか
bool CanReadSerialNumber();
// シリアルナンバーを取得する
void GetSerialNumber(u8** serial, size_t* size);
// シリアルナンバーを返す
u8* GetSerialNumber();
// チェックデジット無しのシリアルナンバーを取得する
void GetSerialNumberWithoutCD(u8* serial);
// IVSを取得する
void GetIvs(void** ivs, size_t* size);
// 32bitデバイスIDを返す
bit32 GetDeviceId();
// CUPメジャーバージョンを返す // CUPメジャーバージョンを返す
u8 GetCupMajorVersion(); u8 GetCupMajorVersion();
@ -100,15 +73,6 @@ public:
// バッテリ残量を0100で返す // バッテリ残量を0100で返す
u32 GetBatteryRemain(); u32 GetBatteryRemain();
// 64bitインフラデバイスIDを返す
u64 GetInfraDeviceId();
// フレンドコードを返す
u64 GetFriendcode();
// MACアドレスを返す
char8* GetMacAddress();
// リージョンコードを返す // リージョンコードを返す
nn::cfg::CTR::CfgRegionCode GetRegion(); nn::cfg::CTR::CfgRegionCode GetRegion();
@ -118,12 +82,6 @@ public:
// バージョン情報を取得する // バージョン情報を取得する
void GetVersionData(common::VerDef* version); void GetVersionData(common::VerDef* version);
// フレンドコードを取得済みかどうか
bool HasReadFriendCode();
// デバイスIDを4文字ごとに空白で区切る
static void SplitDeviceidWithSpace(std::string& deviceIdStr);
// 現在の描画先ディスプレイを返す // 現在の描画先ディスプレイを返す
// target NN_GX_DISPLAY0 または NN_GX_DISPLAY1 // target NN_GX_DISPLAY0 または NN_GX_DISPLAY1
// flip 上下画面を入れ替えているかどうか // flip 上下画面を入れ替えているかどうか
@ -134,54 +92,22 @@ private:
void Finalize(); void Finalize();
void ReadIvs(u8 cupMajorVersion); void ReadIvs(u8 cupMajorVersion);
NN_PADDING4;
// フレンドコード
u64 m_FriendCode;
// バージョン情報 // バージョン情報
common::VerDef m_VerData; common::VerDef m_VerData;
// mcu接続のためのハンドル // mcu接続のためのハンドル
nn::Handle m_McuSession; nn::Handle m_McuSession;
// デバイスID
bit32 m_DeviceId;
// IVSへのポインタ
void* mp_Ivs;
// IVSのサイズ
size_t m_SizeofIvs;
// チェックデジット無しのシリアルナンバーの長さ
size_t m_SerialNoWithoutCGLen;
// MCUへのポインタ // MCUへのポインタ
nn::mcu::CTR::HwCheck* mp_Mcu; nn::mcu::CTR::HwCheck* mp_Mcu;
NN_PADDING2;
// リージョン // リージョン
nn::cfg::CTR::CfgRegionCode m_Region; nn::cfg::CTR::CfgRegionCode m_Region;
// バッテリ残量 // バッテリ残量
u8 m_BatteryRemain; u8 m_BatteryRemain;
// シリアルナンバーが読めるかどうか
bool m_CanReadSerialNumber;
// IVSが読めるかどうか
bool m_CanReadIvs;
// シリアルナンバー
u8 m_SerialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
// MACアドレス
char8 m_MacAddress[nn::nwm::Mac::MAC_STRING_SIZE];
NN_PADDING3;
// FriendCodeを読んだかどうか
bool m_HasReadFriendCode;
NN_PADDING3;
NN_PADDING4;
}; };
nn::Result InitializeNetwork(void); nn::Result InitializeNetwork(void);

View File

@ -1,56 +0,0 @@
Index: sources/libraries/act/CTR/act_ApiAdmin.cpp
===================================================================
--- sources/libraries/act/CTR/act_ApiAdmin.cpp (revision 54688)
+++ sources/libraries/act/CTR/act_ApiAdmin.cpp (working copy)
@@ -192,6 +192,22 @@
u32 approvalId,
bool isOffDeviceAccessEnabled)
{
+ NN_UNUSED_VAR(pAccountId);
+ NN_UNUSED_VAR(pAccountPassword);
+ NN_UNUSED_VAR(pMailAddress);
+ NN_UNUSED_VAR(isParentMailAddress);
+ NN_UNUSED_VAR(isEnabledToReceiveAds);
+ NN_UNUSED_VAR(birthday);
+ NN_UNUSED_VAR(gender);
+ NN_UNUSED_VAR(simpleAddressId);
+ NN_UNUSED_VAR(timeZone);
+ NN_UNUSED_VAR(agreedEulaInfo);
+ NN_UNUSED_VAR(agreedEulaTime);
+ NN_UNUSED_VAR(approvalId);
+ NN_UNUSED_VAR(isOffDeviceAccessEnabled);
+ nn::Result result;
+ return result;
+#if 0
NN_ACT_RETURN_RESULT_IF_NOT_INITIALIZED_ADMIN();
NN_ACT_RETURN_RESULT_IF_NULL(pAccountId);
@@ -212,6 +228,7 @@
NN_ACT_RETURN_IF_FAILED(ActAdmin::BindToNewServerAccount(event.GetHandle(), NN_ACT_SLOT_NO_CURRENT, pAccountId, pAccountPassword, pMailAddress, isParentMailAddress, isEnabledToReceiveAds, birthday, gender, simpleAddressId, timeZone, agreedEulaInfo, agreedEulaTime, approvalId, isOffDeviceAccessEnabled));
return WaitAndGetLastResponseResult( &event );
+#endif
}
Result BindToExistentServerAccount(
@@ -452,6 +469,12 @@
u32 simpleAddressId,
const TimeZone& timeZone)
{
+ NN_UNUSED_VAR(gender);
+ NN_UNUSED_VAR(simpleAddressId);
+ NN_UNUSED_VAR(timeZone);
+ nn::Result result;
+ return result;
+#if 0
{
nn::cfg::SimpleAddressId* pSimpleAddressId = reinterpret_cast<nn::cfg::SimpleAddressId*>(&simpleAddressId);
*pSimpleAddressId = nn::cfg::ConvertToWiiUSimpleAddressId( *pSimpleAddressId );
@@ -470,6 +493,7 @@
}
return UpdateAccountInfo(xmlData);
+#endif
}
Result UpdateIsEnabledToReceiveAds( bool isEnabledToReceiveAds )

Some files were not shown because too many files have changed in this diff Show More