mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
IVSのインポートを再起動直前に移動 git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@348 385bec56-5757-e545-9c3a-d8741f4650f1
1880 lines
62 KiB
C++
1880 lines
62 KiB
C++
/*---------------------------------------------------------------------------*
|
|
Project: Horizon
|
|
File: Importer.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 <nn.h>
|
|
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
|
|
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
|
|
#include <nn/cfg/CTR/cfg_ApiInit.h>
|
|
#include <nn/cfg/CTR/cfg_ApiNor.h> // cfg:norの初期化に必要
|
|
#include <nn/cfg/CTR/cfg_Api.h>
|
|
#include <nn/am/am_ApiSystemMenu.h>
|
|
#include <nn/cfg/CTR/cfg_NtrSettings.h>
|
|
#include <nn/cfg/CTR/cfg_ApiSys.h>
|
|
#include <nn/cfg/CTR/detail/cfg_DataStructures.h>
|
|
#include <nn/cfg/CTR/detail/cfg_Keys.h>
|
|
#include <nn/cfg/CTR/detail/cfg_Default.h>
|
|
#include <nn/drivers/aes/CTR/ARM946ES/driverAes_Types.h>
|
|
#include <nn/crypto/crypto_SwAesCtrContext.h>
|
|
#include <nn/ac/CTR/private/ac_NetworkSetting.h>
|
|
#include <nn/ac/CTR/private/ac_InternalApi.h>
|
|
#include <nn/socket.h>
|
|
#include <nn/nwm/CTR/nwm_InfraAPI.h>
|
|
#include <nn/mcu.h>
|
|
#include <nn/drivers/mcu/CTR/driverMcuRegisterMap.h>
|
|
#include <nn/ndm.h>
|
|
|
|
#include "FileName.h"
|
|
#include "Importer.h"
|
|
#include "SdMountManager.h"
|
|
#include "HeapManager.h"
|
|
#include "SdReaderWriter.h"
|
|
#include "CommonLogger.h"
|
|
#include "FileTransfer.h"
|
|
#include "common_Types.h"
|
|
#include "Aes_define.h"
|
|
#include "configLoader.h"
|
|
#include "PlayHistoryManager.h"
|
|
#include "FileChecker.h"
|
|
#include "VersionDetect.h"
|
|
|
|
#include <string>
|
|
#include <cstring>
|
|
|
|
namespace ConsoleRestore
|
|
{
|
|
namespace
|
|
{
|
|
const size_t IMPORT_THREAD_STACK_SIZE = 0x4000;
|
|
nn::os::Thread s_ImportThread;
|
|
nn::os::StackBuffer<IMPORT_THREAD_STACK_SIZE> s_ImportThreadStack;
|
|
|
|
const size_t TIME_ZONE_LENGTH = 9; // "+23:45"
|
|
char s_TimeZoneStr[TIME_ZONE_LENGTH];
|
|
|
|
TimeZone s_TimeZone;
|
|
const size_t NTP_SERVER_NAME_LENGTH = 256;
|
|
char s_NtpServerName[NTP_SERVER_NAME_LENGTH];
|
|
|
|
bool s_CheckedEqualsDeviceIdFileandDeviceId = false;
|
|
bool s_CheckedEqualsRegionDataandRegion = false;
|
|
bool s_ReadSerialNumber = false;
|
|
|
|
struct SdFileSize
|
|
{
|
|
s64 totalFileSize;
|
|
s64 twlFileSize;
|
|
s64 twlSoundFileSize;
|
|
s64 twlPhotoFileSize;
|
|
s64 ctrFileSize;
|
|
};
|
|
|
|
SdFileSize s_SdFileSize;
|
|
|
|
// シリアルナンバー
|
|
u8 s_SerialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
|
|
|
|
// 空のファイルを作成する
|
|
bool CreateEmptyFile(const wchar_t* path);
|
|
// SDからNANDにセーブデータをコピーする
|
|
void ImportSaveData();
|
|
// SDからNORにNORデータをコピーする
|
|
nn::Result ImportNorData();
|
|
|
|
// SDカードに保存してあるバージョン情報
|
|
common::VerDef s_SDVersionData;
|
|
|
|
// SDカードから読み込んだファイル一覧
|
|
common::ImportDataList s_FileLists;
|
|
|
|
}
|
|
|
|
// SDからファイル一覧を読み込む
|
|
nn::Result ReadFileList(SdFileSize* sdFileSize, common::ImportDataList* fileList);
|
|
|
|
CheckedNetworkSetting s_CurrentNetowrkSetting1;
|
|
|
|
void ConvertTimeZoneString(const char* str)
|
|
{
|
|
s_TimeZone.hour = 0;
|
|
s_TimeZone.minutes = 0;
|
|
s_TimeZone.isMinus = false;
|
|
|
|
bool hour = true;
|
|
bool ten = true;
|
|
u32 count = 0;
|
|
for(u32 i = 0; i < TIME_ZONE_LENGTH && count < 2; i++)
|
|
{
|
|
switch (str[i])
|
|
{
|
|
case ':':
|
|
{
|
|
hour = false;
|
|
}
|
|
break;
|
|
|
|
case '"':
|
|
{
|
|
// 2回読んだら終了
|
|
count++;
|
|
}
|
|
break;
|
|
|
|
case '+':
|
|
{
|
|
s_TimeZone.isMinus = false;
|
|
}
|
|
break;
|
|
|
|
case '-':
|
|
{
|
|
s_TimeZone.isMinus = true;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
if(hour)
|
|
{
|
|
if(ten)
|
|
{
|
|
s_TimeZone.hour += (str[i] - '0') * 10;
|
|
ten = false;
|
|
}
|
|
else
|
|
{
|
|
s_TimeZone.hour += str[i] - '0';
|
|
ten = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(ten)
|
|
{
|
|
s_TimeZone.minutes += (str[i] - '0') * 10;
|
|
ten = false;
|
|
}
|
|
else
|
|
{
|
|
s_TimeZone.minutes += str[i] - '0';
|
|
ten = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
NN_LOG("Converted TimeZone = ");
|
|
if(s_TimeZone.isMinus)
|
|
{
|
|
NN_LOG("-");
|
|
}
|
|
NN_LOG("%02d:%02d\n", s_TimeZone.hour, s_TimeZone.minutes);
|
|
|
|
}
|
|
|
|
namespace
|
|
{
|
|
|
|
bool CreateEmptyFile(const wchar_t* path)
|
|
{
|
|
nn::Result result;
|
|
bool create = false;
|
|
result = common::SdMountManager::Mount();
|
|
|
|
if (result.IsSuccess())
|
|
{
|
|
nn::fs::FileOutputStream fos;
|
|
|
|
result = fos.TryInitialize(path, true);
|
|
if(result.IsSuccess())
|
|
{
|
|
fos.TryFlush();
|
|
create = true;
|
|
}
|
|
fos.Finalize();
|
|
}
|
|
|
|
common::SdMountManager::Unmount();
|
|
|
|
return create;
|
|
}
|
|
|
|
}
|
|
|
|
nn::Result ReadSerialNumber(u8* serial)
|
|
{
|
|
static nn::Result result = nn::ResultSuccess();
|
|
|
|
if(s_ReadSerialNumber)
|
|
{
|
|
std::memcpy(serial, s_SerialNo, sizeof(s_SerialNo));
|
|
return result;
|
|
}
|
|
|
|
COMMON_LOGGER("Read Serial Number in SD.\n");
|
|
|
|
size_t readSize;
|
|
common::SdReaderWriter sdReader;
|
|
size_t bufSize = 1024;
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if(buf != NULL)
|
|
{
|
|
result = sdReader.ReadBufWithCmac(common::SERIAL_PATHNAME, buf, bufSize, &readSize);
|
|
if(result.IsSuccess())
|
|
{
|
|
std::memcpy(s_SerialNo, buf, sizeof(s_SerialNo));
|
|
std::memcpy(serial, s_SerialNo, sizeof(s_SerialNo));
|
|
s_ReadSerialNumber = true;
|
|
}
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
}
|
|
else
|
|
{
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
nn::Result EqualsDeviceIdFileandDeviceId(common::HardwareStateManager& manager)
|
|
{
|
|
static nn::Result result = nn::ResultSuccess();
|
|
|
|
if(s_CheckedEqualsDeviceIdFileandDeviceId)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
COMMON_LOGGER("Check Device Id\n");
|
|
|
|
bit32 sdDeviceId;
|
|
common::SdReaderWriter sdReader;
|
|
size_t totalSize;
|
|
size_t bufSize = 1024;
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if (buf != NULL)
|
|
{
|
|
result = sdReader.ReadBufWithCmac(common::DEVICE_ID_PATHNAME, buf, bufSize, &totalSize);
|
|
if (result.IsSuccess())
|
|
{
|
|
s_CheckedEqualsDeviceIdFileandDeviceId = true;
|
|
std::memcpy(&sdDeviceId, buf, sizeof(sdDeviceId));
|
|
|
|
if (manager.GetDeviceId() == sdDeviceId)
|
|
{
|
|
result = nn::ResultSuccess();
|
|
}
|
|
else
|
|
{
|
|
result = nn::Result(nn::Result::LEVEL_STATUS, nn::Result::SUMMARY_INVALID_RESULT_VALUE,
|
|
nn::Result::MODULE_COMMON, nn::Result::DESCRIPTION_INVALID_RESULT_VALUE);
|
|
}
|
|
}
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
}
|
|
else
|
|
{
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
nn::Result EqualsRegionDataandRegion()
|
|
{
|
|
static nn::Result result = nn::ResultSuccess();
|
|
|
|
if(s_CheckedEqualsRegionDataandRegion)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
COMMON_LOGGER("Check Region\n");
|
|
|
|
nn::cfg::CTR::CfgRegionCode region;
|
|
region = nn::cfg::CTR::GetRegion();
|
|
|
|
nn::cfg::CTR::CfgRegionCode sdRegion;
|
|
common::SdReaderWriter sdReader;
|
|
size_t readSize;
|
|
size_t bufSize = 1024;
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if (buf != NULL)
|
|
{
|
|
result = sdReader.ReadBufWithCmac(common::REGION_DATA_PATHNAME, buf, bufSize, &readSize);
|
|
if (result.IsSuccess())
|
|
{
|
|
std::memcpy(&sdRegion, buf, sizeof(sdRegion));
|
|
s_CheckedEqualsRegionDataandRegion = true;
|
|
if(region == sdRegion)
|
|
{
|
|
result = nn::ResultSuccess();
|
|
}
|
|
else
|
|
{
|
|
result = nn::Result(nn::Result::LEVEL_STATUS, nn::Result::SUMMARY_INVALID_RESULT_VALUE,
|
|
nn::Result::MODULE_COMMON, nn::Result::DESCRIPTION_INVALID_RESULT_VALUE);
|
|
}
|
|
}
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
}
|
|
else
|
|
{
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void SetCountry(nn::cfg::CTR::CfgCountryCode countryCode)
|
|
{
|
|
using namespace nn::cfg::CTR;
|
|
using namespace nn::cfg::CTR::detail;
|
|
|
|
SimpleAddressIdCfgData simpleAddressId;
|
|
TwlCountryCodeCfgData countryData;
|
|
|
|
nn::cfg::CTR::system::Initialize();
|
|
|
|
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::system::GetConfig(&simpleAddressId, sizeof(SimpleAddressIdCfgData), GET_CFG_KEY(NN_CFG_SIMPLE_ADDRESS, NN_CFG_SIMPLE_ADDRESS_ID)));
|
|
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::system::GetConfig(&countryData, sizeof(TwlCountryCodeCfgData), GET_CFG_KEY(NN_CFG_TWL, NN_CFG_TWL_COUNTRY_CODE)));
|
|
nn::cfg::CTR::system::Finalize();
|
|
|
|
simpleAddressId.id = (countryCode << CFG_SIMPLE_ADDRESS_ID_COUNTRY_SHIFT) | (1
|
|
<< CFG_SIMPLE_ADDRESS_ID_REGION_SHIFT);
|
|
countryData.country = countryCode;
|
|
|
|
nn::cfg::CTR::system::Initialize();
|
|
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::system::SetConfig(GET_CFG_KEY(NN_CFG_SIMPLE_ADDRESS, NN_CFG_SIMPLE_ADDRESS_ID), &simpleAddressId, sizeof(SimpleAddressIdCfgData)));
|
|
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::system::SetConfig(GET_CFG_KEY(NN_CFG_TWL, NN_CFG_TWL_COUNTRY_CODE), &countryData, sizeof(TwlCountryCodeCfgData)));
|
|
nn::cfg::CTR::system::FlushConfig();
|
|
nn::cfg::CTR::system::Finalize();
|
|
}
|
|
|
|
void SetLanguage(nn::cfg::CTR::CfgLanguageCode languageCode)
|
|
{
|
|
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::init::SetConfig(
|
|
GET_CFG_KEY(nn::cfg::CTR::detail::NN_CFG_USER_INFO,
|
|
nn::cfg::CTR::detail::NN_CFG_USER_INFO_LANGUAGE),
|
|
&languageCode,
|
|
sizeof(nn::cfg::CTR::detail::LanguageCfgData)));
|
|
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::init::FlushConfig());
|
|
nn::cfg::nor::CTR::Initialize();
|
|
NN_UTIL_PANIC_IF_FAILED(nn::cfg::nor::CTR::SetLanguage(static_cast<nn::cfg::CTR::CfgLanguageCode>(languageCode)));
|
|
nn::cfg::nor::CTR::Finalize();
|
|
}
|
|
|
|
nn::Result ImportCountryLanguageData()
|
|
{
|
|
nn::Result result = nn::ResultSuccess();
|
|
|
|
if (common::ExistsCountryLanguageFile())
|
|
{
|
|
size_t bufSize = 1024;
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if (buf != NULL)
|
|
{
|
|
common::SdReaderWriter sdReader;
|
|
|
|
size_t readSize;
|
|
result = sdReader.ReadBufWithCmac(common::COUNTRY_SETTING_PATHNAME, buf, bufSize, &readSize);
|
|
if (result.IsSuccess())
|
|
{
|
|
// SDから読み出し成功
|
|
SetCountry(reinterpret_cast<common::CfgCountryLanguage*> (buf)->country);
|
|
|
|
SetLanguage(reinterpret_cast<common::CfgCountryLanguage*> (buf)->language);
|
|
}
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// リージョンから適当な国を指定する
|
|
nn::cfg::CTR::CfgRegionCode region;
|
|
region = nn::cfg::CTR::GetRegion();
|
|
NN_LOG("Country Setting does not exist. Use Default Setting\n");
|
|
switch(region)
|
|
{
|
|
case nn::cfg::CTR::CFG_REGION_JAPAN:
|
|
{
|
|
SetCountry(nn::cfg::CTR::CFG_COUNTRY_JAPAN);
|
|
}
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_AMERICA:
|
|
{
|
|
SetCountry(nn::cfg::CTR::CFG_COUNTRY_UNITED_STATES);
|
|
}
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_EUROPE:
|
|
{
|
|
SetCountry(nn::cfg::CTR::CFG_COUNTRY_FRANCE);
|
|
}
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_AUSTRALIA:
|
|
{
|
|
SetCountry(nn::cfg::CTR::CFG_COUNTRY_AUSTRALIA);
|
|
}
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_CHINA:
|
|
{
|
|
SetCountry(nn::cfg::CTR::CFG_COUNTRY_CHINA);
|
|
}
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_KOREA:
|
|
{
|
|
SetCountry(nn::cfg::CTR::CFG_COUNTRY_SOUTH_KOREA);
|
|
}
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_TAIWAN:
|
|
{
|
|
SetCountry(nn::cfg::CTR::CFG_COUNTRY_TAIWAN);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
inline u8 DecimalToBcd(u8 param)
|
|
{
|
|
u8 theTen, theOne;
|
|
theTen = param / 10;
|
|
theOne = param - theTen * 10;
|
|
return (theTen << 4 | theOne);
|
|
}
|
|
|
|
nn::Result ImportMcuRtc(common::HardwareStateManager& manager)
|
|
{
|
|
COMMON_LOGGER("Import RTC Data.\n");
|
|
nn::Result result = nn::ResultSuccess();
|
|
nn::Handle handle = manager.GetMcuHandle();
|
|
|
|
if(handle.IsValid())
|
|
{
|
|
if (common::CheckFileExists(common::MCU_RTC_PATHNAME))
|
|
{
|
|
size_t bufSize = 1024;
|
|
NN_LOG("AllocatableSize = %d\n", bufSize);
|
|
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if (buf != NULL)
|
|
{
|
|
common::SdReaderWriter sdReader;
|
|
|
|
size_t readSize;
|
|
result = sdReader.ReadBufWithCmac(common::MCU_RTC_PATHNAME, buf, bufSize, &readSize);
|
|
if (result.IsSuccess())
|
|
{
|
|
// mcuを使ってセットする
|
|
nn::mcu::CTR::HwCheck mcu(handle);
|
|
nn::mcu::CTR::RtcData* rtc = reinterpret_cast<nn::mcu::CTR::RtcData*> (buf);
|
|
NN_LOG("RTC = 20%02d/%02d/%02d %02d:%02d:%02d\n", rtc->m_Year, rtc->m_Month, rtc->m_Day, rtc->m_Hour, rtc->m_Minute, rtc->m_Second);
|
|
|
|
// BCD変換が必要
|
|
|
|
size_t RTC_PARAM_SIZE = sizeof(nn::mcu::CTR::RtcData);
|
|
u8 bcd[RTC_PARAM_SIZE];
|
|
for (int i = 0; i < RTC_PARAM_SIZE; i++)
|
|
{
|
|
bcd[i] = DecimalToBcd(reinterpret_cast<u8*> (rtc)[i]);
|
|
}
|
|
|
|
const u8 RETRY = 10;
|
|
for (u8 i = 0; i < RETRY; i++)
|
|
{
|
|
result = mcu.WriteBySend(nn::drivers::mcu::CTR::MCU_RTC_SEC_ADDR, bcd, RTC_PARAM_SIZE);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
if(result.IsSuccess())
|
|
{
|
|
break;
|
|
}
|
|
nn::os::Thread::Sleep(
|
|
nn::fnd::TimeSpan::FromMilliSeconds(
|
|
nn::os::Tick::GetSystemCurrent().ToTimeSpan().GetMilliSeconds() % 100));
|
|
|
|
}
|
|
}
|
|
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
}
|
|
else
|
|
{
|
|
COMMON_LOGGER("Failed Allocate Heap!!\n");
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = nn::Result(nn::Result::LEVEL_PERMANENT, nn::Result::SUMMARY_INVALID_STATE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_INVALID_HANDLE);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void InitializeFileSystem()
|
|
{
|
|
nn::Result result;
|
|
|
|
for (u32 i = 0; i < common::TWL_PATHNAME_MAX; i++)
|
|
{
|
|
result = nn::fs::MountSpecialArchive(common::TWL_ARCHIVE_NAME_TABLE[i], common::TWL_FS_ARCHIVE_KIND[i]);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
if (result.IsSuccess())
|
|
{
|
|
nn::fs::Directory dir;
|
|
std::vector<nn::fs::DirectoryEntry> entryList; //カレントディレクトリのエントリ一覧を格納
|
|
std::vector<nn::fs::DirectoryEntry>::iterator entryIndex;
|
|
|
|
std::wstring currentDirectory = common::NAND_TWL_ROOT_PATHNAME_WITH_SLASH_TABLE[i];
|
|
result = dir.TryInitialize(currentDirectory.c_str());
|
|
|
|
nn::fs::DirectoryEntry entry;
|
|
s32 numEntry;
|
|
for (;;)
|
|
{
|
|
result = dir.TryRead(&numEntry, &entry, 1);
|
|
if (result.IsFailure())
|
|
{
|
|
dir.Finalize();
|
|
}
|
|
if (numEntry == 0)
|
|
{
|
|
// ルートディレクトリを閉じる
|
|
dir.Finalize();
|
|
|
|
// ルートディレクトリの子を開く
|
|
for (entryIndex = entryList.begin(); entryIndex != entryList.end(); entryIndex++)
|
|
{
|
|
// ディレクトリなら削除する
|
|
if (entryIndex->attributes.isDirectory)
|
|
{
|
|
NN_LOG("Try Delete %ls%ls/\n", currentDirectory.c_str(), entryIndex->entryName);
|
|
result = nn::fs::TryDeleteDirectoryRecursively((currentDirectory + ::std::wstring(
|
|
entryIndex->entryName)).c_str());
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
}
|
|
// ファイルなら削除する
|
|
else
|
|
{
|
|
NN_LOG("Try Delete %ls%ls\n", currentDirectory.c_str(), entryIndex->entryName);
|
|
result = nn::fs::TryDeleteFile(
|
|
(currentDirectory + ::std::wstring(entryIndex->entryName)).c_str());
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
}
|
|
}
|
|
|
|
// 削除完了
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// vectorに保存する
|
|
entryList.push_back(entry);
|
|
if (entry.attributes.isDirectory)
|
|
{
|
|
NN_LOG("%ls%ls/\n", currentDirectory.c_str(), entry.entryName);
|
|
}
|
|
else
|
|
{
|
|
NN_LOG("%ls%ls\n", currentDirectory.c_str(), entry.entryName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
nn::fs::Unmount(common::TWL_ARCHIVE_NAME_TABLE[i]);
|
|
}
|
|
|
|
result = nn::am::DeleteAllTwlUserPrograms();
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
nn::fs::InitializeCtrFileSystem();
|
|
}
|
|
|
|
nn::Result ImportIvs()
|
|
{
|
|
nn::Result result = nn::ResultSuccess();
|
|
nn::fs::FileOutputStream fos;
|
|
|
|
size_t bufSize = 1024;
|
|
void* enc = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if (enc != NULL)
|
|
{
|
|
common::SdReaderWriter sdReader;
|
|
|
|
size_t readSize;
|
|
result = sdReader.ReadBufWithCmac(common::IVS_PATHNAME, enc, bufSize, &readSize);
|
|
if(result.IsSuccess())
|
|
{
|
|
// SDから読み出し成功
|
|
result = nn::fs::MountSpecialArchive(common::NAND_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
|
|
if (result.IsSuccess())
|
|
{
|
|
void *dec = common::HeapManager::GetHeap()->Allocate(readSize);
|
|
if (dec != NULL)
|
|
{
|
|
// AES復号化する
|
|
nn::crypto::Initialize();
|
|
nn::crypto::SwAesCtrContext swAesCtrContest;
|
|
|
|
swAesCtrContest.Initialize(common::iv, common::key, sizeof(common::key));
|
|
swAesCtrContest.Decrypt(dec, enc, readSize);
|
|
|
|
// IVS書き込み
|
|
result = fos.TryInitialize(common::IVS_NAND_PATHNAME, true);
|
|
if (result.IsSuccess())
|
|
{
|
|
if (result.IsSuccess())
|
|
{
|
|
s32 writeSize;
|
|
result = fos.TryWrite(&writeSize, dec, readSize, true);
|
|
if (result.IsSuccess())
|
|
{
|
|
COMMON_LOGGER("Import SDCI.\n");
|
|
}
|
|
}
|
|
}
|
|
common::HeapManager::GetHeap()->Free(dec);
|
|
}
|
|
else
|
|
{
|
|
COMMON_LOGGER("Failed Allocate Heap!!\n");
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
|
|
}
|
|
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
|
|
}
|
|
common::HeapManager::GetHeap()->Free(enc);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
}
|
|
else
|
|
{
|
|
COMMON_LOGGER("Failed Allocate Heap!!\n");
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool ImportIvsData()
|
|
{
|
|
return ImportIvs().IsSuccess();
|
|
}
|
|
|
|
void ImportThreadFunc()
|
|
{
|
|
nn::Result result;
|
|
|
|
result = nn::fs::MountSpecialArchive(common::NAND_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = common::SdMountManager::Mount();
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize();
|
|
NN_LOG("AllocatableSize = %d\n", bufSize);
|
|
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE);
|
|
if (buf != NULL)
|
|
{
|
|
|
|
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);
|
|
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
}
|
|
|
|
common::SdMountManager::Unmount();
|
|
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
|
|
|
|
NN_LOG("Import Thread Finalize\n");
|
|
}
|
|
|
|
namespace
|
|
{
|
|
|
|
void ImportSaveData()
|
|
{
|
|
// SDカードからNANDに読み込み
|
|
nn::Result result;
|
|
|
|
// ファイルサイズ設定
|
|
common::InitializeTransferProgress(s_SdFileSize.ctrFileSize);
|
|
|
|
// SDカードにあるセーブデータディレクトリ以下のデータをNANDにコピー
|
|
COMMON_LOGGER("Import NAND Data Start...\n");
|
|
s_ImportThread.Start(ImportThreadFunc, s_ImportThreadStack);
|
|
|
|
}
|
|
|
|
nn::Result ImportNorData()
|
|
{
|
|
COMMON_LOGGER("Import NOR Data.\n");
|
|
|
|
nn::Result result = nn::ResultSuccess();
|
|
|
|
nn::cfg::nor::CTR::Initialize();
|
|
|
|
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize() / 2;
|
|
NN_LOG("AllocatableSize = %d\n", bufSize);
|
|
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if (buf != NULL)
|
|
{
|
|
common::SdReaderWriter sdReader;
|
|
|
|
size_t readSize;
|
|
result = sdReader.ReadBufWithCmac(common::NOR_PATHNAME, buf, bufSize, &readSize);
|
|
if(result.IsSuccess())
|
|
{
|
|
// cfgを使ってセットする
|
|
result = nn::cfg::nor::CTR::SetNtrSetting(&reinterpret_cast<common::NtrNorData*>(buf)->ntrConfig.ncd,
|
|
&reinterpret_cast<common::NtrNorData*>(buf)->ntrConfig.ncd_ex);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
// WiFiコネクションIDが仮の値であればWiFi設定は移行しない
|
|
// TWL修理に準拠している
|
|
u64 attestedUserId1 = 0;
|
|
u64 attestedUserId2 = 0;
|
|
const u32 WIFI_CONNECTION_USERID_OFFSET1 = 0xf0;
|
|
const u32 WIFI_CONNECTION_USERID_OFFSET2 = 0x1f0;
|
|
const u32 USERID_SIZE = 6;
|
|
const bit64 USERID_MASK = 0x7FFFFFFFFFF; // 43bit
|
|
|
|
|
|
void* NtrWifiSettingAddr = &reinterpret_cast<common::NtrNorData*>(buf)->NtrWiFiSetting;
|
|
std::memcpy(&attestedUserId1,
|
|
&reinterpret_cast<u8*>(NtrWifiSettingAddr)[WIFI_CONNECTION_USERID_OFFSET1],
|
|
USERID_SIZE);
|
|
attestedUserId1 &= USERID_MASK;
|
|
|
|
std::memcpy(&attestedUserId2,
|
|
&reinterpret_cast<u8*>(NtrWifiSettingAddr)[WIFI_CONNECTION_USERID_OFFSET2],
|
|
USERID_SIZE);
|
|
attestedUserId2 &= USERID_MASK;
|
|
|
|
if (attestedUserId1 == attestedUserId2 && attestedUserId1 != 0)
|
|
{
|
|
// TWL WiFi設定
|
|
result = nn::cfg::nor::CTR::WriteTwlWifiSetting(0,
|
|
reinterpret_cast<common::NtrNorData*> (buf)->TwlWiFiSetting, common::TWL_WIFI_SETTING_SIZE);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
// NTR WiFi設定
|
|
result = nn::cfg::nor::CTR::WriteNtrWifiSetting(0,
|
|
reinterpret_cast<common::NtrNorData*> (buf)->NtrWiFiSetting, common::NTR_WIFI_SETTING_SIZE);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
}
|
|
else
|
|
{
|
|
// クリアしておく
|
|
result = nn::cfg::nor::CTR::ClearTwlWifiSetting();
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::nor::CTR::ClearNtrWifiSetting();
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
}
|
|
}
|
|
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
}
|
|
else
|
|
{
|
|
COMMON_LOGGER("Failed Allocate Heap!!\n");
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
nn::Result ReadVersionData()
|
|
{
|
|
nn::Result result = nn::ResultSuccess();
|
|
std::memset(&s_SDVersionData, 0, sizeof(common::VerDef));
|
|
|
|
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize() / 2;
|
|
NN_LOG("AllocatableSize = %d\n", bufSize);
|
|
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if (buf != NULL)
|
|
{
|
|
common::SdReaderWriter sdReader;
|
|
|
|
size_t readSize;
|
|
result = sdReader.ReadBufWithCmac(common::VERSION_DATA_PATHNAME, buf, bufSize, &readSize);
|
|
if(result.IsSuccess())
|
|
{
|
|
// バージョン情報を保持する
|
|
std::memcpy(&s_SDVersionData, buf, readSize);
|
|
NN_LOG("SD Version = %02d.%02d.%02d-%02d\n", s_SDVersionData.cup.majorVersion,
|
|
s_SDVersionData.cup.minorVersion,
|
|
s_SDVersionData.cup.microVersion,
|
|
s_SDVersionData.nup.majorVersion);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
}
|
|
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
}
|
|
else
|
|
{
|
|
COMMON_LOGGER("Failed Allocate Heap!!\n");
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool ExistsIvsDirectory(std::string& ivsRoot)
|
|
{
|
|
nn::Result result;
|
|
nn::fs::Directory dir;
|
|
|
|
common::SdMountManager::Mount();
|
|
|
|
result = dir.TryInitialize(common::SD_NINTENDO_3DS_ROOT_PATH);
|
|
if(result.IsFailure())
|
|
{
|
|
NN_DBG_PRINT_RESULT(result);
|
|
common::SdMountManager::Unmount();
|
|
return false;
|
|
}
|
|
|
|
wchar_t ivs[34];
|
|
std::mbstowcs(ivs, ivsRoot.c_str(), ivsRoot.size() + 1);
|
|
|
|
nn::fs::DirectoryEntry entry;
|
|
s32 numEntry;
|
|
for (;;)
|
|
{
|
|
result = dir.TryRead(&numEntry, &entry, 1);
|
|
if (result.IsFailure())
|
|
{
|
|
dir.Finalize();
|
|
common::SdMountManager::Unmount();
|
|
return false;
|
|
}
|
|
if (numEntry == 0)
|
|
{
|
|
dir.Finalize();
|
|
common::SdMountManager::Unmount();
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// 比較する
|
|
if (entry.attributes.isDirectory)
|
|
{
|
|
NN_LOG("%ls\n", entry.entryName);
|
|
if(std::wcscmp(ivs, entry.entryName) == 0)
|
|
{
|
|
common::SdMountManager::Unmount();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Cleanup()
|
|
{
|
|
nn::Result result;
|
|
bool execCleanup;
|
|
|
|
result = nn::am::NeedsCleanup(&execCleanup, nn::fs::MEDIA_TYPE_NAND);
|
|
if(result.IsSuccess())
|
|
{
|
|
if(execCleanup)
|
|
{
|
|
COMMON_LOGGER("Cleanup NAND\n");
|
|
nn::am::DoCleanup(nn::fs::MEDIA_TYPE_NAND);
|
|
}
|
|
}
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
}
|
|
|
|
void DeleteAllCheckFiles()
|
|
{
|
|
nn::Result result;
|
|
common::SdMountManager::Mount();
|
|
|
|
for(u32 i = 0; i < sizeof(CHECK_FILENAME_TABLE) / sizeof(CHECK_FILENAME_TABLE[0]); i++)
|
|
{
|
|
if(common::CheckFileExists(CHECK_FILENAME_TABLE[i]))
|
|
{
|
|
result = nn::fs::TryDeleteFile(CHECK_FILENAME_TABLE[i]);
|
|
COMMON_LOGGER_RESULT_IF_FAILED(result);
|
|
}
|
|
}
|
|
common::SdMountManager::Unmount();
|
|
}
|
|
|
|
void FinalizeImportThread()
|
|
{
|
|
s_ImportThread.Join();
|
|
s_ImportThread.Finalize();
|
|
}
|
|
|
|
bool IsImportThreadFinished()
|
|
{
|
|
return s_ImportThread.IsValid() && !s_ImportThread.IsAlive();
|
|
}
|
|
|
|
void CreateWriteFinishedFile()
|
|
{
|
|
CreateEmptyFile(common::FILENAME_TABLE[common::EXISTS_WRITE_FINISHED]);
|
|
common::ClearFileCheck(common::EXISTS_WRITE_FINISHED);
|
|
}
|
|
|
|
void CreateConsoleInitializedFile()
|
|
{
|
|
CreateEmptyFile(common::FILENAME_TABLE[common::EXISTS_CONSOLE_INTIALIZED]);
|
|
common::ClearFileCheck(common::EXISTS_CONSOLE_INTIALIZED);
|
|
}
|
|
|
|
void CreateUpdateFinishedFile()
|
|
{
|
|
CreateEmptyFile(common::FILENAME_TABLE[common::EXISTS_UPDATE_FINISHED]);
|
|
common::ClearFileCheck(common::EXISTS_UPDATE_FINISHED);
|
|
}
|
|
|
|
void CreateRtcSyncFinishedFile()
|
|
{
|
|
CreateEmptyFile(common::FILENAME_TABLE[common::EXISTS_RTC_SYNC_FINISHED]);
|
|
common::ClearFileCheck(common::EXISTS_RTC_SYNC_FINISHED);
|
|
}
|
|
|
|
void CreateDownloadIvsFinishedFile()
|
|
{
|
|
CreateEmptyFile(common::FILENAME_TABLE[common::EXISTS_DOWNLOAD_IVS]);
|
|
common::ClearFileCheck(common::EXISTS_DOWNLOAD_IVS);
|
|
}
|
|
|
|
void CreateDeleteAccountFinishedFile()
|
|
{
|
|
CreateEmptyFile(common::FILENAME_TABLE[common::EXISTS_DELETE_ACCOUNT]);
|
|
common::ClearFileCheck(common::EXISTS_DELETE_ACCOUNT);
|
|
|
|
}
|
|
|
|
void CreateTransferAccountFinishedFile()
|
|
{
|
|
CreateEmptyFile(common::FILENAME_TABLE[common::EXISTS_TRANSFER_ACCOUNT]);
|
|
common::ClearFileCheck(common::EXISTS_TRANSFER_ACCOUNT);
|
|
}
|
|
|
|
u32 GetImportProgress()
|
|
{
|
|
return common::GetProgress();
|
|
}
|
|
|
|
bool UpdateNetworkSetting(nn::ac::NetworkSetting& networkSetting)
|
|
{
|
|
nn::Result result;
|
|
bool retval = true;
|
|
|
|
result = nn::ac::InitializeInternal();
|
|
if(result.IsFailure())
|
|
{
|
|
retval = false;
|
|
COMMON_LOGGER("Error: nn::ac::InitializeInternal() failed\n");
|
|
}
|
|
else
|
|
{
|
|
//特に入力させる必要のない自動で設定する項目
|
|
networkSetting.wireless.enable = true;
|
|
networkSetting.wireless.multiSsid.enable = false;
|
|
networkSetting.ip.enableDHCP = true;
|
|
networkSetting.scanlessConnect.hasConnected = false;
|
|
networkSetting.proxy.enable = false;
|
|
networkSetting.other.enableUPnP = false;
|
|
|
|
// 現在のインターネット設定1を一時的に保持
|
|
result = nn::ac::LoadNetworkSetting(0, s_CurrentNetowrkSetting1.setting);
|
|
if(result.IsSuccess())
|
|
{
|
|
s_CurrentNetowrkSetting1.isValid = true;
|
|
}
|
|
else
|
|
{
|
|
s_CurrentNetowrkSetting1.isValid = false;
|
|
}
|
|
|
|
result = nn::ac::UpdateNetworkSetting( 0, networkSetting );
|
|
if(!result.IsSuccess())
|
|
{
|
|
retval = false;
|
|
COMMON_LOGGER("Error: SetNetworkSetting (Update Error)\n");
|
|
}
|
|
else
|
|
{
|
|
result = nn::ac::FinalizeInternal();
|
|
if (!result.IsSuccess())
|
|
{
|
|
retval = false;
|
|
COMMON_LOGGER("Error: SetNetworkSetting (Finalize Error)\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
bool ReadSetting(bool* nupOnly, bool* getIvs, bool* checkSd, bool* skipNup)
|
|
{
|
|
nn::Result result;
|
|
bool retval = true;
|
|
common::ConfigFileLoader configfileLoader;
|
|
|
|
common::SdMountManager::Mount();
|
|
size_t size = 10240;
|
|
void* heapAddr = common::HeapManager::GetHeap()->Allocate(size);
|
|
|
|
if(heapAddr != NULL)
|
|
{
|
|
result = configfileLoader.Initialize(common::AP_SETTING_PATHNAME, heapAddr, size);
|
|
if (result.IsSuccess())
|
|
{
|
|
nn::ac::NetworkSetting networkSetting;
|
|
|
|
{
|
|
const char* ssid = configfileLoader.ReadAsChar(L"SSID"); // SSID
|
|
if(ssid == NULL)
|
|
{
|
|
COMMON_LOGGER("SSID: is missing\n");
|
|
retval = false;
|
|
}
|
|
else
|
|
{
|
|
std::strncpy(reinterpret_cast<char*> (networkSetting.wireless.essidSecurity.ssid), ssid, 32);
|
|
networkSetting.wireless.essidSecurity.ssidLength = std::strlen(ssid) % 33;
|
|
COMMON_LOGGER("SSID = %s\n", networkSetting.wireless.essidSecurity.ssid);
|
|
}
|
|
}
|
|
|
|
|
|
{
|
|
const char* mode = configfileLoader.ReadAsChar(L"MODE"); // MODE
|
|
if(mode == NULL)
|
|
{
|
|
COMMON_LOGGER("MODE: is missing\n");
|
|
retval = false;
|
|
}
|
|
else
|
|
{
|
|
if (std::strcmp(mode, "OPEN") == 0)
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::OPEN;
|
|
}
|
|
else if (std::strcmp(mode, "WEP40") == 0)
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::WEP_40BIT;
|
|
}
|
|
else if (std::strcmp(mode, "WEP104") == 0)
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::WEP_104BIT;
|
|
}
|
|
else if (std::strcmp(mode, "WEP128") == 0)
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::WEP_128BIT;
|
|
}
|
|
else if (std::strcmp(mode, "WPA-TKIP") == 0)
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::WPA_TKIP;
|
|
}
|
|
else if (std::strcmp(mode, "WPA2-TKIP") == 0)
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::WPA2_TKIP;
|
|
}
|
|
else if (std::strcmp(mode, "WPA-AES") == 0)
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::WPA_AES;
|
|
}
|
|
else if (std::strcmp(mode, "WPA2-AES") == 0)
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::WPA2_AES;
|
|
}
|
|
else
|
|
{
|
|
networkSetting.wireless.essidSecurity.securityMode = nn::ac::OPEN;
|
|
}
|
|
|
|
switch (networkSetting.wireless.essidSecurity.securityMode)
|
|
{
|
|
case nn::ac::OPEN:
|
|
{
|
|
COMMON_LOGGER("MODE = OPEN\n");
|
|
}
|
|
break;
|
|
|
|
case nn::ac::WEP_40BIT:
|
|
{
|
|
COMMON_LOGGER("MODE = WEP_40BIT\n");
|
|
}
|
|
break;
|
|
|
|
case nn::ac::WEP_104BIT:
|
|
{
|
|
COMMON_LOGGER("MODE = WEP_104BIT\n");
|
|
}
|
|
break;
|
|
|
|
case nn::ac::WEP_128BIT:
|
|
{
|
|
COMMON_LOGGER("MODE = WEP_128BIT\n");
|
|
}
|
|
break;
|
|
|
|
case nn::ac::WPA_TKIP:
|
|
{
|
|
COMMON_LOGGER("MODE = WPA_TKIP\n");
|
|
}
|
|
break;
|
|
|
|
case nn::ac::WPA2_TKIP:
|
|
{
|
|
COMMON_LOGGER("MODE = WPA2_TKIP\n");
|
|
}
|
|
break;
|
|
|
|
case nn::ac::WPA_AES:
|
|
{
|
|
COMMON_LOGGER("MODE = WPA_AES\n");
|
|
}
|
|
break;
|
|
|
|
case nn::ac::WPA2_AES:
|
|
{
|
|
COMMON_LOGGER("MODE = WPA2_AES\n");
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
{
|
|
const char* pass = configfileLoader.ReadAsChar(L"PASS"); // PASS
|
|
if(pass == NULL)
|
|
{
|
|
COMMON_LOGGER("PASS: is missing\n");
|
|
retval = false;
|
|
}
|
|
else
|
|
{
|
|
switch (networkSetting.wireless.essidSecurity.securityMode)
|
|
{
|
|
case nn::ac::WEP_40BIT:
|
|
case nn::ac::WEP_104BIT:
|
|
case nn::ac::WEP_128BIT:
|
|
{
|
|
std::strncpy(reinterpret_cast<char *> (networkSetting.wireless.essidSecurity.passphrase),
|
|
pass, 64);
|
|
std::memcpy(networkSetting.wireless.essidSecurity.key,
|
|
networkSetting.wireless.essidSecurity.passphrase, 64);
|
|
}
|
|
break;
|
|
|
|
case nn::ac::WPA_TKIP:
|
|
case nn::ac::WPA2_TKIP:
|
|
case nn::ac::WPA_AES:
|
|
case nn::ac::WPA2_AES:
|
|
{
|
|
std::strncpy(reinterpret_cast<char *> (networkSetting.wireless.essidSecurity.passphrase),
|
|
pass, 64);
|
|
size_t phrase_size = std::strlen(
|
|
reinterpret_cast<char *> (networkSetting.wireless.essidSecurity.passphrase));
|
|
|
|
nn::nwm::Ssid ssid(reinterpret_cast<char *> (networkSetting.wireless.essidSecurity.ssid));
|
|
nn::nwm::ConvertPasswordToPsk(
|
|
reinterpret_cast<char *> (networkSetting.wireless.essidSecurity.passphrase),
|
|
phrase_size, ssid, networkSetting.wireless.essidSecurity.key);
|
|
}
|
|
break;
|
|
|
|
case nn::ac::OPEN:
|
|
default:
|
|
{
|
|
//do nothing
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
{
|
|
s32 dnsAuto; // DNS_AUTO
|
|
if(configfileLoader.ReadAsChar(L"DNS_AUTO") == NULL)
|
|
{
|
|
COMMON_LOGGER("DNS_AUTO: is missing\n");
|
|
retval = false;
|
|
}
|
|
else
|
|
{
|
|
dnsAuto = configfileLoader.ReadAsInteger(L"DNS_AUTO");
|
|
if (dnsAuto == 1)
|
|
{
|
|
networkSetting.ip.autoDNSSetting = true;
|
|
}
|
|
else
|
|
{
|
|
networkSetting.ip.autoDNSSetting = false;
|
|
}
|
|
|
|
COMMON_LOGGER("DNS_AUTO = %d\n", networkSetting.ip.autoDNSSetting);
|
|
|
|
}
|
|
}
|
|
|
|
{
|
|
const char* dnsPrimary = configfileLoader.ReadAsChar(L"DNS_PRI"); // プライマリDNS
|
|
if(!networkSetting.ip.autoDNSSetting)
|
|
{
|
|
if (dnsPrimary == NULL)
|
|
{
|
|
COMMON_LOGGER("DNS_PRI: is missing\n");
|
|
retval = false;
|
|
|
|
}
|
|
else
|
|
{
|
|
u8 dns[4];
|
|
nn::socket::InAddr addr;
|
|
if (1 == nn::socket::InetAtoN(dnsPrimary, &addr))
|
|
{
|
|
dns[3] = (0xff & (addr.addr >> 24));
|
|
dns[2] = (0xff & (addr.addr >> 16));
|
|
dns[1] = (0xff & (addr.addr >> 8));
|
|
dns[0] = (0xff & (addr.addr));
|
|
}
|
|
std::memcpy(networkSetting.ip.dns[0], dns, 4);
|
|
COMMON_LOGGER("DNS_PRI = %03d.%03d.%03d.%03d\n", networkSetting.ip.dns[0][0],
|
|
networkSetting.ip.dns[0][1],
|
|
networkSetting.ip.dns[0][2],
|
|
networkSetting.ip.dns[0][3]);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
const char* dnsSecondary = configfileLoader.ReadAsChar(L"DNS_SEC"); // セカンダリDNS
|
|
if(!networkSetting.ip.autoDNSSetting)
|
|
{
|
|
if(dnsSecondary == NULL)
|
|
{
|
|
COMMON_LOGGER("DNS_SEC: is missing\n");
|
|
retval = false;
|
|
}
|
|
else
|
|
{
|
|
u8 dns[4];
|
|
nn::socket::InAddr addr;
|
|
if (1 == nn::socket::InetAtoN(dnsSecondary, &addr))
|
|
{
|
|
dns[3] = (0xff & (addr.addr >> 24));
|
|
dns[2] = (0xff & (addr.addr >> 16));
|
|
dns[1] = (0xff & (addr.addr >> 8));
|
|
dns[0] = (0xff & (addr.addr));
|
|
}
|
|
std::memcpy(networkSetting.ip.dns[1], dns, 4);
|
|
COMMON_LOGGER("DNS_SEC = %03d.%03d.%03d.%03d\n", networkSetting.ip.dns[1][0],
|
|
networkSetting.ip.dns[1][1],
|
|
networkSetting.ip.dns[1][2],
|
|
networkSetting.ip.dns[1][3]);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
const char* ntpServerName = configfileLoader.ReadAsChar(L"NTPSRV"); // NTPサーバ
|
|
if(ntpServerName == NULL)
|
|
{
|
|
COMMON_LOGGER("NTPSRV: is missing\n");
|
|
retval = false;
|
|
}
|
|
else
|
|
{
|
|
std::strlcpy(s_NtpServerName, ntpServerName, sizeof(s_NtpServerName));
|
|
COMMON_LOGGER("NTPSRV = %s\n", s_NtpServerName);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
{
|
|
const char* timeZone = configfileLoader.ReadAsChar(L"TIMEZONE"); // タイムゾーン
|
|
if(timeZone == NULL)
|
|
{
|
|
COMMON_LOGGER("TIMEZONE: is missing\n");
|
|
retval = false;
|
|
}
|
|
else
|
|
{
|
|
std::strlcpy(s_TimeZoneStr, timeZone, sizeof(s_TimeZoneStr));
|
|
COMMON_LOGGER("TIMEZONE = %s\n", s_TimeZoneStr);
|
|
ConvertTimeZoneString(s_TimeZoneStr);
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
const wchar_t* const NUP_ONLY_STR = L"NUP_ONLY";
|
|
NN_NULL_ASSERT(nupOnly);
|
|
if (configfileLoader.ReadAsChar(NUP_ONLY_STR) != NULL)
|
|
{
|
|
s32 num = configfileLoader.ReadAsInteger(NUP_ONLY_STR);
|
|
if (num == 1)
|
|
{
|
|
*nupOnly = true;
|
|
COMMON_LOGGER("NUP Only Mode.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
const wchar_t* const GET_IVS_STR = L"GET_SDCI";
|
|
NN_NULL_ASSERT(getIvs);
|
|
if (configfileLoader.ReadAsChar(GET_IVS_STR) != NULL)
|
|
{
|
|
s32 num = configfileLoader.ReadAsInteger(GET_IVS_STR);
|
|
if (num == 1)
|
|
{
|
|
*getIvs = true;
|
|
COMMON_LOGGER("GET SDCI Mode.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
const wchar_t* const CHECK_SD_STR = L"CHECK_SD";
|
|
NN_NULL_ASSERT(checkSd);
|
|
if (configfileLoader.ReadAsChar(CHECK_SD_STR) != NULL)
|
|
{
|
|
s32 num = configfileLoader.ReadAsInteger(CHECK_SD_STR);
|
|
if (num == 1)
|
|
{
|
|
*checkSd = true;
|
|
COMMON_LOGGER("CHECK SD Mode.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
const wchar_t* const SKIP_NUP_STR = L"SKIP_NUP";
|
|
NN_NULL_ASSERT(skipNup);
|
|
if (configfileLoader.ReadAsChar(SKIP_NUP_STR) != NULL)
|
|
{
|
|
s32 num = configfileLoader.ReadAsInteger(SKIP_NUP_STR);
|
|
if (num == 1)
|
|
{
|
|
*skipNup = true;
|
|
COMMON_LOGGER("Skip NUP Mode.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
configfileLoader.Finalize();
|
|
|
|
// 書き込み完了しなければfalse
|
|
if(!UpdateNetworkSetting(networkSetting))
|
|
{
|
|
retval = false;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
NN_LOG("configfileLoader Initialize Failed\n");
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
retval = false;
|
|
}
|
|
common::HeapManager::GetHeap()->Free(heapAddr);
|
|
}
|
|
else
|
|
{
|
|
NN_LOG("Can't Allocate Heap\n");
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
retval = false;
|
|
}
|
|
|
|
common::SdMountManager::Unmount();
|
|
return retval;
|
|
}
|
|
|
|
char* GetNtpServerName()
|
|
{
|
|
return s_NtpServerName;
|
|
}
|
|
|
|
TimeZone GetTimeZone()
|
|
{
|
|
return s_TimeZone;
|
|
}
|
|
|
|
CheckedNetworkSetting* GetTempNetworkSetting()
|
|
{
|
|
return &s_CurrentNetowrkSetting1;
|
|
}
|
|
|
|
void ImportTwlData(enum common::TWL_PATH_INDEX path, s64 fileSize)
|
|
{
|
|
NN_ASSERT(path < common::TWL_PATHNAME_MAX);
|
|
|
|
nn::Result result;
|
|
|
|
result = nn::fs::MountSpecialArchive(common::TWL_ARCHIVE_NAME_TABLE[path], common::TWL_FS_ARCHIVE_KIND[path]);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = common::SdMountManager::Mount();
|
|
|
|
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize();
|
|
NN_LOG("AllocatableSize = %d\n", bufSize);
|
|
|
|
// ファイルサイズ設定
|
|
common::InitializeTransferProgress(fileSize);
|
|
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE);
|
|
if (buf != NULL)
|
|
{
|
|
wchar_t archiveName[nn::fs::MAX_FILE_PATH_LENGTH];
|
|
::std::mbstowcs(archiveName, common::TWL_ARCHIVE_NAME_TABLE[path], std::strlen(common::TWL_ARCHIVE_NAME_TABLE[path]) + 1);
|
|
std::wstring archiveString(archiveName);
|
|
common::CopyDirectory(
|
|
&s_FileLists,
|
|
(::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(common::SD_TWL_ROOTNAME_TABLE[path])).c_str(),
|
|
(archiveString + ::std::wstring(L"/")).c_str(),
|
|
buf, bufSize, false, NULL, NULL);
|
|
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
}
|
|
|
|
common::SdMountManager::Unmount();
|
|
nn::fs::Unmount(common::TWL_ARCHIVE_NAME_TABLE[path]);
|
|
|
|
}
|
|
|
|
void ImportTwlTitleSaveData(s64 fileSize)
|
|
{
|
|
nn::Result result;
|
|
|
|
result = nn::fs::MountSpecialArchive(common::NAND_TWL_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_TWL_NAND);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = common::SdMountManager::Mount();
|
|
|
|
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize();
|
|
NN_LOG("AllocatableSize = %d\n", bufSize);
|
|
|
|
// ファイルサイズ設定
|
|
common::InitializeTransferProgress(fileSize);
|
|
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE);
|
|
if (buf != NULL)
|
|
{
|
|
common::CopyDirectory(
|
|
&s_FileLists,
|
|
(::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(common::SD_SAVEDATA_TWL_ROOT_NAME)).c_str(),
|
|
(std::wstring(common::NAND_TWL_DATA_ROOT_PATHNAME_WITHOUT_SLASH) + ::std::wstring(L"/")).c_str(),
|
|
buf, bufSize, false, NULL, NULL);
|
|
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
}
|
|
|
|
common::SdMountManager::Unmount();
|
|
nn::fs::Unmount(common::NAND_TWL_ARCHIVE_NAME);
|
|
}
|
|
|
|
void ImportTwlPhotoDataFunc()
|
|
{
|
|
COMMON_LOGGER("Import Twl Photo Data.\n");
|
|
ImportTwlData(common::TWL_PHOTO, s_SdFileSize.twlPhotoFileSize);
|
|
}
|
|
|
|
void ImportTwlSoundDataFunc()
|
|
{
|
|
COMMON_LOGGER("Import Twl Sound Data.\n");
|
|
ImportTwlData(common::TWL_SOUND, s_SdFileSize.twlSoundFileSize);
|
|
}
|
|
|
|
void ImportTwlSaveDataFunc()
|
|
{
|
|
COMMON_LOGGER("Import Twl Save Data.\n");
|
|
ImportTwlTitleSaveData(s_SdFileSize.twlFileSize);
|
|
}
|
|
|
|
void ImportTwlPhotoData()
|
|
{
|
|
s_ImportThread.Start(ImportTwlPhotoDataFunc, s_ImportThreadStack);
|
|
}
|
|
|
|
void ImportTwlSoundData()
|
|
{
|
|
s_ImportThread.Start(ImportTwlSoundDataFunc, s_ImportThreadStack);
|
|
}
|
|
|
|
void ImportTwlSaveData()
|
|
{
|
|
s_ImportThread.Start(ImportTwlSaveDataFunc, s_ImportThreadStack);
|
|
}
|
|
|
|
|
|
void ClearFileReadResult()
|
|
{
|
|
s_CheckedEqualsDeviceIdFileandDeviceId = false;
|
|
s_CheckedEqualsRegionDataandRegion = false;
|
|
s_ReadSerialNumber = false;
|
|
}
|
|
|
|
void ImportPlayHistoryThreadFunc()
|
|
{
|
|
common::PlayHistoryManager historyManager;
|
|
|
|
COMMON_LOGGER("Import PlayHistory\n");
|
|
historyManager.Import();
|
|
}
|
|
|
|
void ImportPlayHistory()
|
|
{
|
|
s_ImportThread.Start(ImportPlayHistoryThreadFunc, s_ImportThreadStack);
|
|
}
|
|
|
|
void ExportCalData()
|
|
{
|
|
using namespace nn::cfg::CTR::detail;
|
|
|
|
nn::Result result;
|
|
common::CfgCalData cfgCalData;
|
|
common::SdReaderWriter sdWriter;
|
|
|
|
COMMON_LOGGER("Export CalData\n");
|
|
|
|
common::SdMountManager::Mount();
|
|
|
|
result = nn::cfg::CTR::init::GetConfig(&cfgCalData.touchPanelCfgData, sizeof(TouchPanelCfgData),
|
|
GET_CFG_KEY(NN_CFG_HID, NN_CFG_HID_CAL_TOUCHPANEL));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::GetConfig(&cfgCalData.lcdFlickerCfgData, sizeof(LcdFlickerCfgData),
|
|
GET_CFG_KEY(NN_CFG_LCD, NN_CFG_LCD_CAL_FLICKER));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::GetConfig(&cfgCalData.fcramCfgData, sizeof(FcramCfgData),
|
|
GET_CFG_KEY(NN_CFG_FCRAM, NN_CFG_FCRAM_CAL_DELAY));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::GetConfig(&cfgCalData.rtcCfgData, sizeof(RtcCfgData),
|
|
GET_CFG_KEY(NN_CFG_RTC, NN_CFG_RTC_CAL_COMPENSATION));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::GetConfig(&cfgCalData.gyroscopeCfgData, sizeof(GyroscopeCfgData),
|
|
GET_CFG_KEY(NN_CFG_HID, NN_CFG_HID_CAL_GYROSCOPE));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::GetConfig(&cfgCalData.accelCfgData, sizeof(AccelCfgData),
|
|
GET_CFG_KEY(NN_CFG_HID, NN_CFG_HID_CAL_ACCELEROMETER));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::GetConfig(&cfgCalData.codecCfgData, sizeof(CodecCfgData),
|
|
GET_CFG_KEY(NN_CFG_CODEC, NN_CFG_CODEC_CAL));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::GetConfig(&cfgCalData.mcuSlideVolumeRangeCfgData, sizeof(McuSlideVolumeRangeCfgData),
|
|
GET_CFG_KEY(NN_CFG_MCU, NN_CFG_MCU_SLIDE_VOLUME));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
sdWriter.WriteBufWithCmac(common::CFG_CALIBRATION_PATHNAME, &cfgCalData, sizeof(cfgCalData));
|
|
|
|
common::SdMountManager::Unmount();
|
|
}
|
|
|
|
nn::Result ImportCalData(common::CfgCalData *data)
|
|
{
|
|
using namespace nn::cfg::CTR::detail;
|
|
|
|
nn::Result result = nn::ResultSuccess();
|
|
|
|
COMMON_LOGGER("Import CalData\n");
|
|
|
|
common::SdMountManager::Mount();
|
|
|
|
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize() / 2;
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
|
|
if (buf != NULL)
|
|
{
|
|
common::SdReaderWriter sdReader;
|
|
|
|
size_t readSize;
|
|
result = sdReader.ReadBufWithCmac(common::CFG_CALIBRATION_PATHNAME, buf, bufSize, &readSize);
|
|
if(result.IsSuccess())
|
|
{
|
|
// SDから読み出し成功
|
|
std::memcpy(data, buf, readSize);
|
|
}
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
}
|
|
else
|
|
{
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
|
|
common::SdMountManager::Unmount();
|
|
return result;
|
|
}
|
|
|
|
nn::Result InitializeHardwareDependentSetting()
|
|
{
|
|
using namespace nn::cfg::CTR::detail;
|
|
nn::Result result = nn::ResultSuccess();
|
|
|
|
common::CfgCalData cfgCalData;
|
|
result = ImportCalData(&cfgCalData);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
|
|
result = nn::cfg::CTR::init::SetConfig(GET_CFG_KEY(NN_CFG_HID, NN_CFG_HID_CAL_TOUCHPANEL),
|
|
&cfgCalData.touchPanelCfgData, sizeof(TouchPanelCfgData));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::SetConfig(GET_CFG_KEY(NN_CFG_LCD, NN_CFG_LCD_CAL_FLICKER),
|
|
&cfgCalData.lcdFlickerCfgData, sizeof(LcdFlickerCfgData));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::SetConfig(GET_CFG_KEY(NN_CFG_FCRAM, NN_CFG_FCRAM_CAL_DELAY), &cfgCalData.fcramCfgData,
|
|
sizeof(FcramCfgData));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::SetConfig(GET_CFG_KEY(NN_CFG_RTC, NN_CFG_RTC_CAL_COMPENSATION),
|
|
&cfgCalData.rtcCfgData, sizeof(RtcCfgData));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::SetConfig(GET_CFG_KEY(NN_CFG_HID, NN_CFG_HID_CAL_GYROSCOPE),
|
|
&cfgCalData.gyroscopeCfgData, sizeof(GyroscopeCfgData));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::SetConfig(GET_CFG_KEY(NN_CFG_HID, NN_CFG_HID_CAL_ACCELEROMETER),
|
|
&cfgCalData.accelCfgData, sizeof(AccelCfgData));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::SetConfig(GET_CFG_KEY(NN_CFG_CODEC, NN_CFG_CODEC_CAL), &cfgCalData.codecCfgData,
|
|
sizeof(CodecCfgData));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
result = nn::cfg::CTR::init::SetConfig(GET_CFG_KEY(NN_CFG_MCU, NN_CFG_MCU_SLIDE_VOLUME),
|
|
&cfgCalData.mcuSlideVolumeRangeCfgData, sizeof(McuSlideVolumeRangeCfgData));
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
NN_LOG("Set cfgCalData\n");
|
|
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
nn::cfg::CTR::init::ResetCameraCalibration();
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
nn::cfg::CTR::init::ResetAnalogStickCalibration();
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
return result;
|
|
}
|
|
|
|
nn::Result SetupFileList()
|
|
{
|
|
std::memset(&s_SdFileSize, 0, sizeof(s_SdFileSize));
|
|
|
|
// ファイル一覧を読み込む
|
|
nn::Result result = ReadFileList(&s_SdFileSize, &s_FileLists);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
|
|
return result;
|
|
}
|
|
|
|
nn::Result ReadFileList(SdFileSize* sdFiles, common::ImportDataList* fileList)
|
|
{
|
|
nn::Result result = nn::ResultSuccess();
|
|
|
|
COMMON_LOGGER("Read File List\n");
|
|
|
|
size_t readSize;
|
|
common::SdReaderWriter sdReader;
|
|
s64 fileSize;
|
|
{
|
|
nn::fs::FileInputStream file;
|
|
|
|
// サイズ取得のため一時的に開く
|
|
result = file.TryInitialize(common::FILE_LIST_PATHNAME);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
|
|
result = file.TryGetSize(&fileSize);
|
|
if (result.IsFailure())
|
|
{
|
|
file.Finalize();
|
|
return result;
|
|
}
|
|
file.Finalize();
|
|
}
|
|
|
|
void* buf = common::HeapManager::GetHeap()->Allocate(fileSize);
|
|
if(buf != NULL)
|
|
{
|
|
result = sdReader.ReadBufWithCmac(common::FILE_LIST_PATHNAME, buf, fileSize, &readSize);
|
|
if(result.IsSuccess())
|
|
{
|
|
// ファイル一覧
|
|
const char comma[] = ",";
|
|
const char newLine[] = "\n";
|
|
char *token = NULL;
|
|
token = std::strtok(reinterpret_cast<char*>(buf), comma);
|
|
bool parseFileName = false;
|
|
common::ImportDataEntry entry;
|
|
|
|
entry.fileName = std::string(token);
|
|
while( token != NULL)
|
|
{
|
|
if(parseFileName)
|
|
{
|
|
token = std::strtok(NULL, comma);
|
|
if(token != NULL)
|
|
{
|
|
entry.fileName = std::string(token);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
token = std::strtok(NULL, newLine);
|
|
if(token != NULL)
|
|
{
|
|
s64 size = std::atoll(token);
|
|
if(size != -1)
|
|
{
|
|
entry.isDirectory = false;
|
|
sdFiles->totalFileSize += size;
|
|
|
|
wchar_t wcToken[nn::fs::MAX_FILE_PATH_LENGTH];
|
|
if(std::mbstowcs(wcToken, entry.fileName.c_str(), entry.fileName.size()) != entry.fileName.size() - 1)
|
|
{
|
|
if(std::wcsstr(wcToken, common::SD_SAVEDATA_ROOT_NAME) != NULL)
|
|
{
|
|
sdFiles->ctrFileSize += size;
|
|
}
|
|
else if(std::wcsstr(wcToken, common::SD_SAVEDATA_TWL_PHOTO_ROOT_NAME) != NULL)
|
|
{
|
|
sdFiles->twlPhotoFileSize += size;
|
|
}
|
|
else if(std::wcsstr(wcToken, common::SD_SAVEDATA_TWL_SOUND_ROOT_NAME) != NULL)
|
|
{
|
|
sdFiles->twlSoundFileSize += size;
|
|
}
|
|
else if(std::wcsstr(wcToken, common::SD_SAVEDATA_TWL_ROOT_NAME) != NULL)
|
|
{
|
|
sdFiles->twlFileSize += size;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
entry.isDirectory = true;
|
|
}
|
|
|
|
fileList->push_back(entry);
|
|
}
|
|
}
|
|
parseFileName = !parseFileName;
|
|
|
|
}
|
|
|
|
}
|
|
common::HeapManager::GetHeap()->Free(buf);
|
|
}
|
|
else
|
|
{
|
|
result = nn::Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_OUT_OF_MEMORY);
|
|
}
|
|
return result;
|
|
|
|
}
|
|
|
|
nn::Result ImportData()
|
|
{
|
|
static nn::Result result = nn::ResultSuccess();
|
|
static bool init = true;
|
|
if(init)
|
|
{
|
|
init = false;
|
|
|
|
// インポート前にACを止める
|
|
result = nn::ndm::SuspendScheduler();
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
|
|
// NANDのごみを削除する
|
|
Cleanup();
|
|
|
|
// NORデータを書き込む
|
|
result = ImportNorData();
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
|
|
// 固体固有calLデータをSDカードに出力する
|
|
// 本体初期化後はcal値が設定されている
|
|
ExportCalData();
|
|
|
|
// SDカードのセーブデータをNANDに書き込む
|
|
ImportSaveData();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|