mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@8 385bec56-5757-e545-9c3a-d8741f4650f1
1092 lines
33 KiB
C++
1092 lines
33 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 "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;
|
|
|
|
bool s_IsImportThreadFinished = false;
|
|
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 CheckFileExists(const wchar_t* path);
|
|
|
|
bool s_FileExistsChecked[EXISTS_MAX];
|
|
bool s_FileExistsCheckeResult[EXISTS_MAX];
|
|
|
|
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 CheckFileExists(const wchar_t* path)
|
|
{
|
|
nn::Result result;
|
|
bool exist = false;
|
|
result = common::SdMountManager::Mount();
|
|
|
|
if (result.IsSuccess())
|
|
{
|
|
nn::fs::FileInputStream fis;
|
|
|
|
result = fis.TryInitialize(path);
|
|
if(result.IsSuccess())
|
|
{
|
|
exist = true;
|
|
}
|
|
fis.Finalize();
|
|
}
|
|
|
|
common::SdMountManager::Unmount();
|
|
|
|
|
|
return exist;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
bool ExistsFile(FileExistsCheck index)
|
|
{
|
|
if(index > EXISTS_MAX)
|
|
{
|
|
NN_LOG("Invalid File index!!\n");
|
|
return false;
|
|
}
|
|
|
|
if(s_FileExistsChecked[index])
|
|
{
|
|
return s_FileExistsCheckeResult[index];
|
|
}
|
|
|
|
s_FileExistsChecked[index] = true;
|
|
s_FileExistsCheckeResult[index] = CheckFileExists(FILENAME_TABLE[index]);
|
|
return s_FileExistsCheckeResult[index];
|
|
}
|
|
|
|
}
|
|
|
|
bool ExistsUpdateCheckedFile()
|
|
{
|
|
return ExistsFile(EXISTS_UPDATE_FINISHED);
|
|
}
|
|
|
|
bool ExistsSerialNumberFile()
|
|
{
|
|
return ExistsFile(EXISTS_SERIAL_NUMBER);
|
|
}
|
|
|
|
bool ExistsIVSFile()
|
|
{
|
|
return ExistsFile(EXISTS_IVS);
|
|
}
|
|
|
|
void InitializeFileCheck()
|
|
{
|
|
for(u32 i = 0; i < EXISTS_MAX; i++)
|
|
{
|
|
s_FileExistsChecked[i] = false;
|
|
}
|
|
|
|
s_CheckedEqualsIVSFileandIVS = false;
|
|
s_ReadSerialNumber = false;
|
|
}
|
|
|
|
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 ExistsWriteFinishedFile()
|
|
{
|
|
return ExistsFile(EXISTS_WRITE_FINISHED);
|
|
}
|
|
|
|
bool ExistsAPSetting()
|
|
{
|
|
return ExistsFile(EXISTS_AP_SETTING);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
bool ExistsConsoleInitializedFile()
|
|
{
|
|
return ExistsFile(EXISTS_CONSOLE_INTIALIZED);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
s_IsImportThreadFinished = false;
|
|
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");
|
|
s_IsImportThreadFinished = true;
|
|
|
|
}
|
|
|
|
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_IsImportThreadFinished;
|
|
}
|
|
|
|
void CreateWriteFinishedFile()
|
|
{
|
|
CreateEmptyFile(common::WRITE_FINISHED_PATHNAME);
|
|
}
|
|
|
|
void CreateConsoleInitializedFile()
|
|
{
|
|
CreateEmptyFile(common::INITIALIZED_CHECK_PATHNAME);
|
|
}
|
|
|
|
void CreateUpdateFinishedFile()
|
|
{
|
|
CreateEmptyFile(common::UPDATE_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;
|
|
}
|
|
|
|
COMMON_LOGGER("PASS = %s\n", networkSetting.wireless.essidSecurity.passphrase);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
{
|
|
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 ImportData()
|
|
{
|
|
static bool init = true;
|
|
if(init)
|
|
{
|
|
// NANDのごみを削除する
|
|
Cleanup();
|
|
|
|
// SDカードのIVSファイルを書き込む
|
|
ImportIvs();
|
|
|
|
// NORデータを書き込む
|
|
ImportNorData();
|
|
|
|
// SDカードのセーブデータをNANDに書き込む
|
|
ImportSaveData();
|
|
|
|
init = false;
|
|
}
|
|
|
|
}
|
|
|
|
}
|