SimpleAddressが壊れている場合修正するように

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@551 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2012-01-12 06:57:32 +00:00
parent 0ee21cb674
commit e1feb8c47d
366 changed files with 331 additions and 1 deletions

View File

@ -139,6 +139,7 @@ typedef enum RestoreState
REBOOTING, // 再起動を行う
ERASE, // 削除処理を行う
RESTORE_CAL, // cfgの一部をcal値で上書きする
REPAIR_SIMPLE_ADDRESS_ID, // 本ツールで過去に破壊されたSimpleAddress.idを修正する
TIME_ADJUST, // 時計あわせを行う
DOWNLOAD_TWL, // TWLアプリ本体をダウンロードする
WAIT_SD_EJECT, // SDカードぬき待ち
@ -1428,9 +1429,16 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
if (IsImportThreadFinished())
{
FinalizeImportThread();
s_RestoreState = TIME_ADJUST;
s_RestoreState = REPAIR_SIMPLE_ADDRESS_ID;
}
}
break;
case REPAIR_SIMPLE_ADDRESS_ID:
{
RepairSimpleAddress();
s_RestoreState = TIME_ADJUST;
}
break;
// 時計あわせ

View File

@ -36,6 +36,7 @@
#include <nn/drivers/mcu/CTR/driverMcuRegisterMap.h>
#include <nn/ndm.h>
#include <nn/crypto/crypto_AesCmac.h>
#include <nn/cx.h>
#include "FileName.h"
#include "Importer.h"
@ -50,6 +51,7 @@
#include "FileChecker.h"
#include "VersionDetect.h"
#include "SaveDataMover.h"
#include "RegionIdModifier.h"
#include <string>
#include <cstring>
@ -1941,6 +1943,88 @@ bool IsImportSucceeded()
return s_IsImportSucceeded;
}
void ReadRegionFile(const wchar_t* path, void** decode, size_t* size)
{
if(path == NULL)
{
return;
}
char filePath[256];
std::wcstombs(filePath, path, sizeof(filePath));
char prefix[] = "rom:/regionData/";
char fullPath[256];
std::memset(fullPath, 0, sizeof(fullPath));
strlcpy(fullPath, prefix, sizeof(fullPath));
strlcat(fullPath, filePath, 256 - strlen(fullPath));
NN_LOG("regionData: %s\n", fullPath);
nn::fs::FileInputStream file;
file.Initialize(fullPath);
s64 fileSize = file.GetSize();
common::HeapManager heap(fileSize, AES_BLOCK_SIZE);
void* buf = heap.GetAddr();
file.Read(buf, fileSize);
*size = nn::cx::GetUncompressedSize(buf);
nn::cx::UncompressLZ(buf, *decode);
}
void RepairSimpleAddress()
{
nn::cfg::CTR::SimpleAddress sa;
nn::cfg::CTR::GetSimpleAddress(&sa);
RegionIdModifier rim(sa.id >> 16, s_SDVersionData.nup.majorVersion, nn::cfg::CTR::GetRegion(), sa.regionName[0]);
if(rim.IsValid())
{
// 壊れていなければ何もしない
return;
}
COMMON_LOGGER("Repair SimpleAddress.\n");
size_t size;
PathList filePath[3];
u8 modifiedId;
common::HeapManager heap(common::FILE_COPY_HEAP_SIZE / 8 , AES_BLOCK_SIZE);
void* buf = heap.GetAddr();
size_t fileNum = rim.GetFilePathNum();
std::memset(filePath, 0, sizeof(filePath));
std::memcpy(filePath, rim.GetFilePath(), sizeof(PathList) * fileNum);
for (u8 i = 0; i < fileNum; i++)
{
ReadRegionFile(filePath[fileNum - i - 1].path, &buf, &size);
if (rim.GetValidRegionId(buf, size, &modifiedId))
{
NN_LOG("CurrentRegionId = %02x\n", (sa.id >> 16) & 0x00ff);
NN_LOG("ValidRegionId = %02x\n", modifiedId);
using namespace nn::cfg::CTR;
using namespace nn::cfg::CTR::detail;
nn::cfg::CTR::system::Initialize();
SimpleAddressIdCfgData simpleAddressId;
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)));
simpleAddressId.id = (simpleAddressId.id & 0xff00ffff) | (modifiedId << CFG_SIMPLE_ADDRESS_ID_REGION_SHIFT);
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::FlushConfig());
nn::cfg::CTR::system::Finalize();
}
}
}
nn::Result ImportData()
{
static nn::Result result = nn::ResultSuccess();

View File

@ -160,6 +160,8 @@ bool ImportIvsData();
// 書き込みが成功したかどうか
bool IsImportSucceeded();
void RepairSimpleAddress();
}
#endif /* IMPORTER_H_ */

View File

@ -30,6 +30,7 @@ SOURCES[] =
Ntpclient.cpp
TitleDownloader.cpp
Shop.cpp
RegionIdModifier.cpp
../common/Util.cpp
../common/DrawSystemState.cpp
../common/FileTransfer.cpp

View File

@ -0,0 +1,152 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: RegionIdModifier.cpp
Copyright (C)2011 Nintendo Co., Ltd. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev:$
*---------------------------------------------------------------------------*/
#include "RegionIdModifier.h"
#include <cwchar>
#include <cstring>
struct CountryData
{
u32 id; // 上記定数にあるように、国IDと地域IDを組み合わせたID
u16 regionName[16][64]; // NULL終端込み
u8 order[16]; // 言語ごとの地域名並び順「未設定」が0になるので、最初の地域は1
u16 latitude; // リストの値を 65536/360 倍して格納して下さい
u16 longitude; // リストの値を 65536/360 倍して格納して下さい
};
const size_t NUP_VERSION_TO_REGIONNUM[] =
{
1, // ローンチ(0)
1, // 0thNUP(1)
2, // 1stNUP(2)
2, // 1.05NUP(3)
2, // 1.1NUP(4)
3, // 2ndNUP(5)
3, // 2.1NUP(6)
};
const wchar_t* DIR_PATH[] =
{
L"0/JP/",
L"0/US/",
L"0/EU/",
L"2/JP/",
L"2/US/",
L"2/EU/",
L"5/JP/",
L"5/US/",
L"5/EU/"
};
RegionIdModifier::RegionIdModifier(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName)
{
m_Id = id;
m_NupVersion = nupVersion;
m_RegionCode = regionCode;
if (regionName != NULL)
{
std::wcsncpy(m_RegionName, regionName, sizeof(m_RegionName) / sizeof(wchar_t));
}
}
bool RegionIdModifier::IsValid()
{
return (m_Id & 0x000f) != 0x01;
}
const PathList* RegionIdModifier::GetDirectoryPath()
{
// 範囲外のリージョン
if (2 < m_RegionCode)
{
return NULL;
}
for (u8 i = 0; i < 3; i++)
{
std::wcsncpy(m_DirectoryPathBuf[i].path, DIR_PATH[m_RegionCode + i * 3], 32);
}
return m_DirectoryPathBuf;
}
size_t RegionIdModifier::GetDirectoryPathNum()
{
// 範囲外のリージョン
if (2 < m_RegionCode)
{
return 0;
}
const size_t countryNum = sizeof(NUP_VERSION_TO_REGIONNUM) / sizeof(NUP_VERSION_TO_REGIONNUM[0]);
if (m_NupVersion > countryNum - 1)
{
return NUP_VERSION_TO_REGIONNUM[countryNum - 1];
}
else
{
return NUP_VERSION_TO_REGIONNUM[m_NupVersion];
}
}
const wchar_t* RegionIdModifier::GetFileName()
{
std::swprintf(m_FileNameBuf, sizeof(m_FileNameBuf), L"%d_LZ.bin", m_Id >> 8);
return m_FileNameBuf;
}
const PathList* RegionIdModifier::GetFilePath()
{
std::memset(m_FilePathBuf, 0, sizeof(m_FilePathBuf));
GetDirectoryPath();
for (u8 i = 0; i < GetDirectoryPathNum(); i++)
{
size_t writeSize = std::wcslen(m_DirectoryPathBuf[i].path);
std::wcsncpy(m_FilePathBuf[i].path, m_DirectoryPathBuf[i].path, writeSize);
std::wcsncat(m_FilePathBuf[i].path, GetFileName(), 32 - writeSize);
}
return m_FilePathBuf;
}
size_t RegionIdModifier::GetFilePathNum()
{
return GetDirectoryPathNum();
}
bool RegionIdModifier::GetValidRegionId(void* buf, size_t size, u8* id)
{
if (buf == NULL || size == 0)
{
return false;
}
u32 numRegion; // その国に含まれる地域の数
numRegion = *reinterpret_cast<u32*>(buf);
CountryData* pCountry;
pCountry = reinterpret_cast<CountryData*>(&reinterpret_cast<u32*>(buf)[1]);
for (u32 i = 0; i < numRegion + 1; i++)
{
if (std::wcscmp(m_RegionName, reinterpret_cast<wchar_t*>(pCountry->regionName[0])) == 0)
{
*id = (pCountry->id >> 16) & 0x00ff;
return true;
}
pCountry++;
}
return false;
}

View File

@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: RegionIdModifier.h
Copyright (C)2011 Nintendo Co., Ltd. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev:$
*---------------------------------------------------------------------------*/
#ifndef _REGION_ID_MODIFIER_H_
#define _REGION_ID_MODIFIER_H_
#include <nn.h>
struct PathList
{
wchar_t path[32];
};
//! @brief データ移行ツールで破壊した地域idを修正するためのクラスです
class RegionIdModifier
{
public:
//! @brief パラメータを与えて初期化します。
//! @param[in] id SimpleAddressの上位16ビット
//! @param[in] nupVersion NUPバージョン
//! @param[in] regionCode リージョン
//! @param[in] regionName 地域名
RegionIdModifier(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName);
~RegionIdModifier() {};
//! @brief 正しいIDかどうか
bool IsValid();
//! @brief バージョン、リージョンに応じたディレクトリパスの配列を取得します
//! @return パス名。バージョン・リージョンが正しくない場合はNULL
const PathList* GetDirectoryPath();
//! @brief バージョン、リージョンに応じたディレクトリパス数を取得します
size_t GetDirectoryPathNum();
//! @brief 国idに応じたファイル名を取得します
const wchar_t* GetFileName();
//! @brief バージョン、リージョン、国idに応じたファイルパスの配列を取得します
const PathList* GetFilePath();
//! @brief バージョン、リージョン、国idに応じたファイルパス数を取得します
size_t GetFilePathNum();
//! @brief 与えられたバッファから正しい地域idを取得します
//! @param[in] buf 展開済みの地域データの入ったバッファ
//! @param[in] size バッファサイズ
//! @param[out] id 正しいid
//! @return 正しいidが見つかったかどうか
bool GetValidRegionId(void* buf , size_t size, u8* id);
private:
//! @brief SimpleAddressの上位16ビット
// 上位8ビットが国id,下位8ビットが地域
u16 m_Id;
//! @brief NUPバージョン番号
u8 m_NupVersion;
//! @brief リージョンコード
u8 m_RegionCode;
//! @brief 地域名
wchar_t m_RegionName[64];
//! @brief ファイル名を保存するバッファ
wchar_t m_FileNameBuf[32];
//! @brief ディレクトリパスを保存するバッファ
PathList m_DirectoryPathBuf[3];
//! @brief ファイルパスを保存するバッファ
PathList m_FilePathBuf[3];
};
#endif // _REGION_ID_MODIFIER_H_

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