2ndNUP本体の場合IVSの入出力用APIを使うように

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@458 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2011-10-20 06:58:58 +00:00
parent a794b015ca
commit 6e498106b8
13 changed files with 139 additions and 106 deletions

View File

@ -103,7 +103,7 @@ extern "C" void nnMain(void)
nn::ps::Initialize(); nn::ps::Initialize();
// amの初期化 // amの初期化
nn::am::InitializeForSystemMenu(); nn::am::InitializeForLocalImporter();
// ヒープの確保 // ヒープの確保
common::InitializeHeap(); common::InitializeHeap();

View File

@ -21,6 +21,7 @@
#include <nn/nstd.h> #include <nn/nstd.h>
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h> #include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h> #include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
#include <nn/fs/fs_ApiDeviceMove.h>
#include <nn/cfg/CTR/cfg_Api.h> #include <nn/cfg/CTR/cfg_Api.h>
#include <nn/cfg/CTR/cfg_ApiNor.h> // cfg:norの初期化に必要 #include <nn/cfg/CTR/cfg_ApiNor.h> // cfg:norの初期化に必要
#include <nn/cfg/CTR/cfg_NtrSettings.h> #include <nn/cfg/CTR/cfg_NtrSettings.h>
@ -485,7 +486,7 @@ void WriteTwlData(enum common::TWL_PATH_INDEX path)
COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded); COMMON_LOGGER_RETURN_VOID_SET_BOOL_IF_FAILED(result, s_IsExportSucceeded);
NN_LOG("File Number = %d\n", fileNum); NN_LOG("File Number = %d\n", fileNum);
NN_LOG("File Size = %d\n", fileSize); NN_LOG("File Size = %lld\n", fileSize);
// 進捗表示用 // 進捗表示用
common::InitializeTransferProgress(fileSize); common::InitializeTransferProgress(fileSize);
@ -816,7 +817,24 @@ void ExportThreadFunc()
NN_LOG("Export Thread Finalize\n"); NN_LOG("Export Thread Finalize\n");
} }
nn::Result WriteSaveData(::std::string& sysSaveRoot) nn::Result WriteExportContext()
{
nn::Result result;
nn::fs::DeviceMoveContext context;
result = nn::fs::StartDeviceMoveAsSource(&context);
NN_UTIL_RETURN_IF_FAILED(result);
common::SdMountManager::Mount();
common::SdReaderWriter sdWriter;
result = sdWriter.WriteBufWithCmac(common::MOVE_CONTEXT_PATHNAME, &context, sizeof(context));
NN_UTIL_RETURN_IF_FAILED(result);
common::SdMountManager::Unmount();
return nn::ResultSuccess();
}
nn::Result WriteSaveData()
{ {
// NANDからSDカードに書き出し // NANDからSDカードに書き出し
nn::Result result; nn::Result result;
@ -833,14 +851,10 @@ nn::Result WriteSaveData(::std::string& sysSaveRoot)
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
NN_LOG("File Number = %d\n", fileNum); NN_LOG("File Number = %d\n", fileNum);
NN_LOG("File Size = %d\n", fileSize); NN_LOG("File Size = %lld\n", fileSize);
// 進捗表示用 // 進捗表示用
common::InitializeTransferProgress(fileSize); common::InitializeTransferProgress(fileSize);
::std::mbstowcs(s_RootName, sysSaveRoot.c_str(), sysSaveRoot.size() + 1);
NN_LOG("%ls\n", (::std::wstring(common::NAND_DATA_ROOT_PATHNAME_WITH_SLASH) + ::std::wstring(s_RootName) + ::std::wstring(L"/")).c_str());
// セーブデータディレクトリ以下のデータをSDカードにコピー // セーブデータディレクトリ以下のデータをSDカードにコピー
// コピー用ディレクトリ作成 // コピー用ディレクトリ作成
common::SdReaderWriter sdWriter; common::SdReaderWriter sdWriter;
@ -949,15 +963,8 @@ bool ExportData(common::HardwareStateManager& manager)
result = WriteVersionData(manager); result = WriteVersionData(manager);
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result); COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
::std::string systemSaveRoot;
void* ivs;
size_t size;
manager.GetIvs(&ivs, &size);
// IVSからセーブデータディレクトリ名を計算
common::Util::GetSaveDataDirectoryRoot(systemSaveRoot, ivs, size);
// NANDのセーブデータをSDに書き出す // NANDのセーブデータをSDに書き出す
result = WriteSaveData(systemSaveRoot); result = WriteSaveData();
COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result); COMMON_LOGGER_RETURN_FALSE_IF_FAILED(result);
init = false; init = false;

View File

@ -67,7 +67,7 @@ LIBS += libnn_cfg \
INSTALL_SDK_TOOL = true INSTALL_SDK_TOOL = true
ROM_SPEC_FILE = $(TARGET_PROGRAM).rsf ROM_SPEC_FILE = $(TARGET_PROGRAM).rsf
DESCRIPTOR = $(HORIZON_ROOT)/resources/specfiles/RepairTool.desc DESCRIPTOR = $(HORIZON_ROOT)/resources/specfiles/private/RepairTool.desc
include $(ROOT_OMAKE)/modulerules include $(ROOT_OMAKE)/modulerules

View File

@ -31,6 +31,7 @@
#include <nn/os/os_SharedInfo.h> #include <nn/os/os_SharedInfo.h>
#include <nn/ndm.h> #include <nn/ndm.h>
#include <nn/nim.h> #include <nn/nim.h>
#include <nn/am.h>
#include "demo.h" #include "demo.h"
#include <vector> #include <vector>
@ -128,7 +129,7 @@ extern "C" void nnMain(void)
nn::ps::Initialize(); nn::ps::Initialize();
// amの初期化 // amの初期化
nn::am::InitializeForSystemMenu(); nn::am::InitializeForLocalImporter();
// ヒープの確保 // ヒープの確保
common::InitializeHeap(); common::InitializeHeap();

View File

@ -998,12 +998,8 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
else else
{ {
NN_LOG("Read User's SD Card\n"); NN_LOG("Read User's SD Card\n");
void* ivs;
size_t size;
manager.GetIvs(&ivs, &size);
std::string sysSaveRoot; std::string sysSaveRoot;
common::Util::GetSaveDataDirectoryRoot(sysSaveRoot);
common::Util::GetSaveDataDirectoryRoot(sysSaveRoot, ivs, size);
if (ExistsIvsDirectory(sysSaveRoot)) if (ExistsIvsDirectory(sysSaveRoot))
{ {
s_RestoreState = CHECK_SD_DIRECTORY_SUCCESS; s_RestoreState = CHECK_SD_DIRECTORY_SUCCESS;

View File

@ -16,6 +16,7 @@
#include <nn.h> #include <nn.h>
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h> #include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h> #include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
#include <nn/fs/CTR/MPCore/fs_ApiIntegrityVerificationSeed.h>
#include <nn/cfg/CTR/cfg_ApiInit.h> #include <nn/cfg/CTR/cfg_ApiInit.h>
#include <nn/cfg/CTR/cfg_ApiNor.h> // cfg:norの初期化に必要 #include <nn/cfg/CTR/cfg_ApiNor.h> // cfg:norの初期化に必要
#include <nn/cfg/CTR/cfg_Api.h> #include <nn/cfg/CTR/cfg_Api.h>
@ -659,10 +660,21 @@ nn::Result ImportIvs()
{ {
if (result.IsSuccess()) if (result.IsSuccess())
{ {
s32 writeSize; if (s_SDVersionData.cup.majorVersion < common::CUP_MAJOR_VER_2ND_NUP)
result = fos.TryWrite(&writeSize, dec, readSize, true);
if (result.IsSuccess())
{ {
s32 writeSize;
result = fos.TryWrite(&writeSize, dec, readSize, true);
if (result.IsSuccess())
{
COMMON_LOGGER("Import SDCI.\n");
}
}
// 2ndNUPからはAPI経由で書き込む
else
{
result = nn::fs::CTR::ImportIntegrityVerificationSeed(
*reinterpret_cast<nn::fs::CTR::IntegrityVerificationSeed*>(dec));
NN_UTIL_RETURN_IF_FAILED(result);
COMMON_LOGGER("Import SDCI.\n"); COMMON_LOGGER("Import SDCI.\n");
} }
} }

View File

@ -70,7 +70,7 @@ LIBS += libnn_cfg \
INSTALL_SDK_TOOL = true INSTALL_SDK_TOOL = true
ROM_SPEC_FILE = $(TARGET_PROGRAM).rsf ROM_SPEC_FILE = $(TARGET_PROGRAM).rsf
DESCRIPTOR = $(HORIZON_ROOT)/resources/specfiles/RepairTool.desc DESCRIPTOR = $(HORIZON_ROOT)/resources/specfiles/private/RepairTool.desc
include $(ROOT_OMAKE)/modulerules include $(ROOT_OMAKE)/modulerules

View File

@ -141,6 +141,11 @@ bool ExistsTwlTitleListFile()
return ExistsFile(EXISTS_TWL_TITLELIST); return ExistsFile(EXISTS_TWL_TITLELIST);
} }
bool ExistsFileMoveContextFile()
{
return ExistsFile(EXISTS_MOVE_CONTEXT);
}
void InitializeFileCheck() void InitializeFileCheck()
{ {
for(u32 i = 0; i < EXISTS_MAX; i++) for(u32 i = 0; i < EXISTS_MAX; i++)

View File

@ -37,6 +37,8 @@ typedef enum FILE_EXISTS_CHECK
EXISTS_TRANSFER_ACCOUNT, // アカウント移行完了 EXISTS_TRANSFER_ACCOUNT, // アカウント移行完了
EXISTS_DOWNLOAD_IVS, // IVSダウロード完了 EXISTS_DOWNLOAD_IVS, // IVSダウロード完了
EXISTS_TWL_TITLELIST, // TWLタイトルリストファイル EXISTS_TWL_TITLELIST, // TWLタイトルリストファイル
EXISTS_MOVE_CONTEXT, // ファイル移動用コンテキスト
EXISTS_MAX EXISTS_MAX
} FileExistsCheck; } FileExistsCheck;
@ -55,7 +57,8 @@ const wchar_t* const FILENAME_TABLE[EXISTS_MAX] =
common::DELETE_ACCOUNT_CHECK_PATHNAME, common::DELETE_ACCOUNT_CHECK_PATHNAME,
common::TRANSFER_ACCOUNT_CHECK_PATHNAME, common::TRANSFER_ACCOUNT_CHECK_PATHNAME,
common::DOWNLOAD_IVS_CHECK_PATHNAME, common::DOWNLOAD_IVS_CHECK_PATHNAME,
common::TWL_TITLELIST_PATHNAME common::TWL_TITLELIST_PATHNAME,
common::MOVE_CONTEXT_PATHNAME
}; };
// ファイルが存在するかどうか // ファイルが存在するかどうか
@ -74,6 +77,7 @@ bool ExistsDeleteAccountChecked();
bool ExistsTransferAccountChecked(); bool ExistsTransferAccountChecked();
bool ExistsDownloadIvsCheckedFile(); bool ExistsDownloadIvsCheckedFile();
bool ExistsTwlTitleListFile(); bool ExistsTwlTitleListFile();
bool ExistsFileMoveContextFile();
// ファイルチェックの結果を初期化する // ファイルチェックの結果を初期化する
// 一度チェックするとその結果を保持するため // 一度チェックするとその結果を保持するため

View File

@ -65,6 +65,7 @@ const wchar_t* const REGION_DATA_PATHNAME = L"sdmc:/CTR_Console_Repair/Region.bi
const wchar_t* const DEVICE_ID_PATHNAME = L"sdmc:/CTR_Console_Repair/deviceId.bin"; const wchar_t* const DEVICE_ID_PATHNAME = L"sdmc:/CTR_Console_Repair/deviceId.bin";
const wchar_t* const FILE_LIST_PATHNAME = L"sdmc:/CTR_Console_Repair/FileList.txt"; const wchar_t* const FILE_LIST_PATHNAME = L"sdmc:/CTR_Console_Repair/FileList.txt";
const wchar_t* const TWL_TITLELIST_PATHNAME = L"sdmc:/CTR_Console_Repair/TwlTitleList.txt"; const wchar_t* const TWL_TITLELIST_PATHNAME = L"sdmc:/CTR_Console_Repair/TwlTitleList.txt";
const wchar_t* const MOVE_CONTEXT_PATHNAME = L"sdmc:/CTR_Console_Repair/MoveContext.bin";
const wchar_t* const SD_NINTENDO_3DS_ROOT_PATH = L"sdmc:/Nintendo 3DS/"; const wchar_t* const SD_NINTENDO_3DS_ROOT_PATH = L"sdmc:/Nintendo 3DS/";
enum TWL_PATH_INDEX enum TWL_PATH_INDEX

View File

@ -1,24 +1,24 @@
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Project: Horizon Project: Horizon
File: Util.cpp File: Util.cpp
Copyright 2009 Nintendo. All rights reserved. Copyright (C)2010-2011 Nintendo Co., Ltd. All rights reserved.
These coded instructions, statements, and computer programs contain These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form, 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. in whole or in part, without the prior written consent of Nintendo.
$Rev$ $Rev$
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
#include <cctype> #include <cctype>
#include <nn.h> #include <nn.h>
#include <nn/ptm/CTR/ptm_ApiSysmenu.h> #include <nn/ptm/CTR/ptm_ApiSysmenu.h>
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h> #include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h> #include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
#include <nn/fs/CTR/MPCore/fs_ApiIntegrityVerificationSeed.h>
#include <nn/fs/fs_ApiSysSaveData.h> #include <nn/fs/fs_ApiSysSaveData.h>
#include <nn/cfg/CTR/cfg_Api.h> #include <nn/cfg/CTR/cfg_Api.h>
#include <nn/cfg/CTR/cfg_ApiInit.h> #include <nn/cfg/CTR/cfg_ApiInit.h>
@ -32,13 +32,15 @@
#include "FileName.h" #include "FileName.h"
#include "CommonLogger.h" #include "CommonLogger.h"
#include "HeapManager.h" #include "HeapManager.h"
#include "FileTransfer.h"
namespace common namespace common
{ {
Util::Util() : Util::Util() :
m_FriendCode(0), m_BatteryRemain(100), m_CanReadSerialNumber(false), m_CanReadIvs(false), m_HasReadFriendCode(false) m_FriendCode(0), mp_Ivs(NULL), m_SizeofIvs(0), m_BatteryRemain(100), m_CanReadSerialNumber(false), m_CanReadIvs(
false), m_HasReadFriendCode(false)
{ {
} }
@ -77,37 +79,6 @@ void Util::Initialize()
nn::mcu::CTR::InitializeHwCheck(&m_McuSession); nn::mcu::CTR::InitializeHwCheck(&m_McuSession);
mp_Mcu = new nn::mcu::CTR::HwCheck(m_McuSession); mp_Mcu = new nn::mcu::CTR::HwCheck(m_McuSession);
// 完全性検証SEEDの取得
result = nn::fs::MountSpecialArchive(common::NAND_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
if (result.IsSuccess())
{
nn::fs::FileInputStream fis;
result = fis.TryInitialize(common::IVS_NAND_PATHNAME);
if (result.IsSuccess())
{
s64 fileSize = fis.GetSize();
s32 ret;
void* addr = NULL;
addr = ForceAllocate(fileSize);
if (addr != NULL)
{
mp_Ivs = addr;
m_SizeofIvs = fileSize;
result = fis.TryRead(&ret, addr, fileSize);
if (result.IsSuccess())
{
m_CanReadIvs = true;
}
// 後でIVSを参照するのでFreeしない
}
}
fis.Finalize();
}
// 一旦アンマウントしておく
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
// シリアルナンバーの取得 // シリアルナンバーの取得
std::memset(m_SerialNo, '\0', std::memset(m_SerialNo, '\0',
nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN); nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
@ -130,6 +101,9 @@ void Util::Initialize()
// バージョンの取得 // バージョンの取得
common::GetSystemVersion(&m_VerData, m_Region); common::GetSystemVersion(&m_VerData, m_Region);
// IVSの取得
ReadIvs(m_VerData.cup.majorVersion);
// MACアドレスの取得 // MACアドレスの取得
nn::nwm::Mac mac; nn::nwm::Mac mac;
@ -154,6 +128,61 @@ void Util::Finalize()
nn::mcu::CTR::FinalizeHwCheck(&m_McuSession); nn::mcu::CTR::FinalizeHwCheck(&m_McuSession);
} }
void Util::ReadIvs(u8 cupMajorVersion)
{
if (cupMajorVersion < common::CUP_MAJOR_VER_2ND_NUP)
{
nn::Result result;
// 完全性検証SEEDの取得
result = nn::fs::MountSpecialArchive(common::NAND_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
if (result.IsSuccess())
{
nn::fs::FileInputStream fis;
result = fis.TryInitialize(common::IVS_NAND_PATHNAME);
if (result.IsSuccess())
{
s64 fileSize = fis.GetSize();
s32 ret;
void* addr = NULL;
addr = ForceAllocate(fileSize);
if (addr != NULL)
{
mp_Ivs = addr;
m_SizeofIvs = fileSize;
result = fis.TryRead(&ret, addr, fileSize);
if (result.IsSuccess())
{
m_CanReadIvs = true;
}
// 後でIVSを参照するのでFreeしない
}
}
fis.Finalize();
}
// 一旦アンマウントしておく
nn::fs::Unmount(common::NAND_ARCHIVE_NAME);
}
else
{
nn::Result result;
void* pSeed = ForceAllocate(sizeof(nn::fs::CTR::IntegrityVerificationSeed));
if(pSeed != NULL)
{
result = nn::fs::CTR::ExportIntegrityVerificationSeed(
reinterpret_cast<nn::fs::CTR::IntegrityVerificationSeed*>(pSeed));
nn::dbg::PrintResult(result);
if(result.IsSuccess())
{
mp_Ivs = pSeed;
m_SizeofIvs = sizeof(nn::fs::CTR::IntegrityVerificationSeed);
m_CanReadIvs = true;
}
// 後でIVSを参照するのでFreeしない
}
}
}
// NULL終端されたシリアルナンバーを受け取る // NULL終端されたシリアルナンバーを受け取る
// NULL終端された場所にチェックデジットを付加して新たにNULL終端する // NULL終端された場所にチェックデジットを付加して新たにNULL終端する
void Util::AddCheckDigit(char* serial) void Util::AddCheckDigit(char* serial)
@ -187,45 +216,20 @@ void Util::AddCheckDigit(char* serial)
serial[len + 1] = '\0'; serial[len + 1] = '\0';
} }
// IVSからセーブデータディレクトリ名を生成する // /Nintendo 3DS/6ea6b9d6ab70493ea9edd8b947d5d819/853600b24760a87f534430320002544d
void Util::GetSaveDataDirectoryRoot(::std::string& sysSaveRoot, void* ivs, size_t size) // から、6ea6b9d6ab70493ea9edd8b947d5d819 を取り出す
void Util::GetSaveDataDirectoryRoot(::std::string& sysSaveRoot)
{ {
nn::Result result; nn::Result result;
using namespace nn::dbg;
const size_t SEED_SIZE = 16; wchar_t path[512];
bit8 hash[nn::crypto::Sha256Context::HASH_SIZE]; result = nn::fs::GetSdmcCtrRootPath(path, sizeof(path));
const size_t SYS_SAVE_ROOT_LENGTH = 16; COMMON_LOGGER_RETURN_VOID_IF_FAILED(result);
char rootHash[SYS_SAVE_ROOT_LENGTH]; NN_LOG("%ls\n", path);
char rootStr[SYS_SAVE_ROOT_LENGTH * 2 + 1];
// 最後の16バイトのハッシュを使う std::string sdmcRootPath = common::GetCharStr(path);
nn::crypto::CalculateSha256(hash, &reinterpret_cast<bit8*> (ivs)[size - SEED_SIZE], SEED_SIZE); sysSaveRoot = sdmcRootPath.substr(sizeof("Nintendo 3DS/"), 32);
NN_LOG("saveRoot = %s\n", sysSaveRoot.c_str());
for (u8 i = 0; i < SEED_SIZE / 4; i++)
{
for (u8 j = 0; j < SEED_SIZE / 4; j++)
{
rootHash[i * 4 + j] = hash[i * 4 + 3 - j];
}
}
// 得られたハッシュから文字列を生成
for (s32 k = 0; k < SEED_SIZE; k++)
{
for (s32 i = 6; i < 8; ++i)
{
bit32 n = (rootHash[k] >> ((7 - i) * 4)) & 0xf;
NN_TASSERT_(n < 16);
rootStr[i - 6 + k * 2] = static_cast<char> (n < 10 ? '0' + n : 'a' + (n - 10));
}
}
rootStr[SYS_SAVE_ROOT_LENGTH * 2] = '\0';
// セーブデータディレクトリ名を保存する
sysSaveRoot = ::std::string(rootStr);
NN_LOG("%s\n", sysSaveRoot.c_str());
} }
bool Util::IsAdapterConnected() bool Util::IsAdapterConnected()

View File

@ -43,7 +43,7 @@ public:
static void AddCheckDigit(char* serial); static void AddCheckDigit(char* serial);
// IVSから計算されるセーブデータディレクトリ名を取得する // IVSから計算されるセーブデータディレクトリ名を取得する
static void GetSaveDataDirectoryRoot(::std::string& sysSaveRoot, void* ivs, size_t size); static void GetSaveDataDirectoryRoot(::std::string& sysSaveRoot);
// ACアダプタが接続されているかどうか // ACアダプタが接続されているかどうか
bool IsAdapterConnected(); bool IsAdapterConnected();
@ -111,6 +111,7 @@ public:
private: private:
void Initialize(); void Initialize();
void Finalize(); void Finalize();
void ReadIvs(u8 cupMajorVersion);
NN_PADDING4; NN_PADDING4;
// フレンドコード // フレンドコード

View File

@ -41,6 +41,8 @@ const u64 INFRA_DEVICE_ID_OFFSET = 0x400000000;
const size_t FILE_COPY_HEAP_SIZE = 16 * 1024 * 1024; const size_t FILE_COPY_HEAP_SIZE = 16 * 1024 * 1024;
const u8 CUP_MAJOR_VER_2ND_NUP = 3;
// NOR領域のみにある設定データ用構造体 // NOR領域のみにある設定データ用構造体
struct NtrNorData struct NtrNorData
{ {