ctr_Repair/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp
N2614 ab767e5f96 Updaterのログを残すように
パスワードはログに残さないように

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@20 385bec56-5757-e545-9c3a-d8741f4650f1
2011-02-07 01:32:28 +00:00

1204 lines
38 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/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 "FileName.h"
#include "Importer.h"
#include "SdMountManager.h"
#include "ConsoleRestore.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 <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_CheckedEqualsIVSFileandIVS = false;
bool s_ReadSerialNumber = false;
// シリアルナンバー
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データをコピーする
void ImportNorData();
// IVS復号化用IV
bit8 s_IvsDecryptIv[AES_BLOCK_SIZE] =
{
0xdf, 0x0f, 0xf9, 0x1b, 0x34, 0x47, 0x70, 0x7f,
0x7d, 0x06, 0x85, 0xe6, 0xe7, 0xb6, 0x4e, 0xe9
};
}
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;
}
}
u8* ReadSerialNumber()
{
if(s_ReadSerialNumber)
{
return s_SerialNo;
}
COMMON_LOGGER("Read Serial Number in SD.\n");
size_t size;
common::SdReaderWriter sdReader;
sdReader.ReadBuf(common::SERIAL_PATHNAME, s_SerialNo, nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN, &size);
s_ReadSerialNumber = true;
return s_SerialNo;
}
bool EqualsIVSFileandIVS()
{
nn::Result result;
void* ivs;
size_t ivsSize;
size_t readSize;
static bool retval = false;
if(s_CheckedEqualsIVSFileandIVS)
{
return retval;
}
COMMON_LOGGER("Check IVS\n");
GetIvs(&ivs, &ivsSize);
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize() / 2;
NN_LOG("AllocatableSize = %d\n", bufSize);
void* enc = common::HeapManager::GetHeap()->Allocate(bufSize);
if (enc != NULL)
{
common::SdReaderWriter sdReader;
result = sdReader.ReadBuf(common::IVS_PATHNAME, enc, bufSize, &readSize);
if(result.IsSuccess())
{
void *dec = common::HeapManager::GetHeap()->Allocate(readSize);
if(dec != NULL)
{
// AES復号化する
nn::crypto::Initialize();
nn::crypto::SwAesCtrContext swAesCtrContest;
swAesCtrContest.Initialize(s_IvsDecryptIv, common::key, sizeof(common::key));
swAesCtrContest.Decrypt(dec, enc, readSize);
NN_LOG("readSize = %d, ivsSize = %d\n", readSize, ivsSize);
// サイズ一致かつ内容一致でtrue
if (readSize == ivsSize && std::memcmp(ivs, dec, ivsSize) == 0)
{
retval = true;
}
common::HeapManager::GetHeap()->Free(dec);
}
else
{
NN_LOG("Failed Allocate Heap!! %s, %d", __FILE__, __LINE__);
}
}
else
{
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
}
s_CheckedEqualsIVSFileandIVS = true;
common::HeapManager::GetHeap()->Free(enc);
}
else
{
NN_LOG("Failed Allocate Heap!! %s, %d", __FILE__, __LINE__);
return retval;
}
return retval;
}
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();
}
void ImportCountryLanguageData()
{
nn::Result result;
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize();
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
if (buf != NULL)
{
common::SdReaderWriter sdReader;
size_t readSize;
result = sdReader.ReadBuf(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);
}
else
{
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
}
common::HeapManager::GetHeap()->Free(buf);
}
}
inline u8 DecimalToBcd(u8 param)
{
u8 theTen, theOne;
theTen = param / 10;
theOne = param - theTen * 10;
return (theTen << 4 | theOne);
}
void ImportMcuRtc()
{
COMMON_LOGGER("Import RTC Data.\n");
nn::Result result;
nn::Handle handle = GetMcuHandle();
if(handle.IsValid())
{
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize();
NN_LOG("AllocatableSize = %d\n", bufSize);
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
if (buf != NULL)
{
common::SdReaderWriter sdReader;
size_t readSize;
result = sdReader.ReadBuf(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]);
}
result = mcu.WriteBySend(nn::drivers::mcu::CTR::MCU_RTC_SEC_ADDR, bcd, RTC_PARAM_SIZE);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
}
else
{
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
}
common::HeapManager::GetHeap()->Free(buf);
}
else
{
COMMON_LOGGER("Failed Allocate Heap!!\n");
}
}
}
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());
if (result.IsFailure())
{
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
}
}
// ファイルなら削除する
else
{
NN_LOG("Try Delete %ls%ls\n", currentDirectory.c_str(), entryIndex->entryName);
result = nn::fs::TryDeleteFile(
(currentDirectory + ::std::wstring(entryIndex->entryName)).c_str());
if (result.IsFailure())
{
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
}
}
}
// 削除完了
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]);
}
nn::fs::InitializeCtrFileSystem();
}
void ImportIvs()
{
nn::Result result;
nn::fs::FileOutputStream fos;
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize() / 2;
void* enc = common::HeapManager::GetHeap()->Allocate(bufSize);
if (enc != NULL)
{
common::SdReaderWriter sdReader;
size_t readSize;
result = sdReader.ReadBuf(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(s_IvsDecryptIv, 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 IVS.\n");
}
}
}
common::HeapManager::GetHeap()->Free(dec);
}
else
{
COMMON_LOGGER("Failed Allocate Heap!!\n");
}
}
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
}
common::HeapManager::GetHeap()->Free(enc);
}
else
{
COMMON_LOGGER("Failed Allocate Heap!!\n");
}
}
void ImportThreadFunc()
{
nn::Result result;
result = nn::fs::MountSpecialArchive(common::NAND_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
if(result.IsFailure())
{
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
}
result = common::SdMountManager::Mount();
if(result.IsFailure())
{
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
}
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize();
NN_LOG("AllocatableSize = %d\n", bufSize);
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
if (buf != NULL)
{
common::CopyDirectory(
(::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(common::SD_SAVEDATA_ROOT_NAME)).c_str(),
common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH,
buf, bufSize);
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;
// SDカードにあるセーブデータサイズを計算
u32 fileNum = 0;
u32 fileSize = 0;
common::SdMountManager::Mount();
common::CalculateFileNum(::std::wstring(common::SDMC_ROOT_DIRECTORY_PATH) + ::std::wstring(common::SD_SAVEDATA_ROOT_NAME), fileNum, fileSize);
common::SdMountManager::Unmount();
// ファイルサイズ設定
common::SetTotalSize(fileSize);
NN_LOG("File Number = %d\n", fileNum);
NN_LOG("File Size = %d\n", fileSize);
// SDカードにあるセーブデータディレクトリ以下のデータをNANDにコピー
COMMON_LOGGER("Import NAND Data Start...\n");
s_ImportThread.Start(ImportThreadFunc, s_ImportThreadStack);
}
void ImportNorData()
{
COMMON_LOGGER("Import NOR Data.\n");
nn::Result result;
nn::cfg::nor::CTR::Initialize();
size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize();
NN_LOG("AllocatableSize = %d\n", bufSize);
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
if (buf != NULL)
{
common::SdReaderWriter sdReader;
size_t readSize;
result = sdReader.ReadBuf(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);
// 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
{
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
}
common::HeapManager::GetHeap()->Free(buf);
}
else
{
COMMON_LOGGER("Failed Allocate Heap!!\n");
}
}
}
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);
}
}
else
{
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
}
}
void DeleteConsoleInitializedFile()
{
nn::Result result;
common::SdMountManager::Mount();
result = nn::fs::TryDeleteFile(common::INITIALIZED_CHECK_PATHNAME);
COMMON_LOGGER_RESULT_IF_FAILED(result);
common::SdMountManager::Unmount();
}
bool IsImportFinished()
{
return !s_ImportThread.IsAlive();
}
void CreateWriteFinishedFile()
{
CreateEmptyFile(common::WRITE_FINISHED_PATHNAME);
}
void CreateConsoleInitializedFile()
{
CreateEmptyFile(common::INITIALIZED_CHECK_PATHNAME);
}
void CreateUpdateFinishedFile()
{
CreateEmptyFile(common::UPDATE_CHECK_PATHNAME);
}
void CreateRtcSyncFinishedFile()
{
CreateEmptyFile(common::RTC_SYNC_CHECK_PATHNAME);
}
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()
{
nn::Result result;
bool retval = true;
common::ConfigFileLoader configfileLoader;
common::SdMountManager::Mount();
size_t size = common::HeapManager::GetHeap()->GetAllocatableSize();
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
dnsAuto = configfileLoader.ReadAsInteger(L"DNS_AUTO");
if(configfileLoader.ReadAsChar(L"DNS_AUTO") == NULL)
{
COMMON_LOGGER("DNS_AUTO: is missing\n");
retval = false;
}
else
{
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 && 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 && 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(s_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);
}
}
configfileLoader.Finalize();
// 書き込み完了しなければfalse
if(!UpdateNetworkSetting(networkSetting))
{
retval = false;
}
}
else
{
NN_LOG("configfileLoader Initialize Failed\n");
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
retval = false;
}
common::HeapManager::GetHeap()->Free(heapAddr);
}
else
{
NN_LOG("Can't Allocate Heap\n");
COMMON_LOGGER_RESULT_WITH_LINE(result , __LINE__);
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_PATHNAME path)
{
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);
void* buf = common::HeapManager::GetHeap()->Allocate(bufSize);
if (buf != NULL)
{
wchar_t archiveName[256];
::std::mbstowcs(archiveName, common::TWL_ARCHIVE_NAME_TABLE[path], std::strlen(common::TWL_ARCHIVE_NAME_TABLE[path]) + 1);
std::wstring archiveString(archiveName);
common::CopyDirectory(
(common::SDMC_ROOT_DIRECTORY_PATH + ::std::wstring(common::SD_TWL_ROOTNAME_TABLE[path])).c_str(),
(archiveString + ::std::wstring(L"/")).c_str(),
buf, bufSize);
common::HeapManager::GetHeap()->Free(buf);
}
common::SdMountManager::Unmount();
nn::fs::Unmount(common::TWL_ARCHIVE_NAME_TABLE[path]);
}
void ImportTwlPhotoData()
{
COMMON_LOGGER("Import Twl Photo Data.\n");
ImportTwlData(common::TWL_PHOTO);
}
void ImportTwlSoundData()
{
COMMON_LOGGER("Import Twl Sound Data.\n");
ImportTwlData(common::TWL_SOUND);
}
void ClearFileReadReslt()
{
s_CheckedEqualsIVSFileandIVS = false;
s_ReadSerialNumber = false;
}
void ImportData()
{
static bool init = true;
if(init)
{
// NANDのごみを削除する
Cleanup();
// SDカードのIVSファイルを書き込む
ImportIvs();
// NORデータを書き込む
ImportNorData();
// TWL写真領域のデータをNANDに書き込む
ImportTwlPhotoData();
// TWLサウンド領域のデータをNANDに書き込む
ImportTwlSoundData();
// SDカードのセーブデータをNANDに書き込む
ImportSaveData();
init = false;
}
}
}