ctr_Repair/trunk/KENJEraser/main.cpp
N2205 2b999ad5b5 権限を絞ったdescに変更
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@275 385bec56-5757-e545-9c3a-d8741f4650f1
2011-05-25 05:33:22 +00:00

325 lines
10 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: main.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/fnd.h>
#include <nn/am/am_LocalImportControl.h>
#include <nn/am/am_ApiSystemMenu.h>
#include <nn/am/am_Result.h>
#include <nn/cfg/CTR/cfg_Api.h>
#include <nn/cfg/CTR/cfg_ApiInit.h>
#include <nn/cfg/CTR/cfg_ApiSys.h>
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
#include <vector>
#include <string>
#include "demo.h"
#include "ResFont.h"
#include "HeapManager.h"
#define UTIL_RETURN_IF_NOT_AM_NOT_FOUND(result) \
if(result.IsFailure()) \
{ \
if(result != nn::am::ResultNotFound()) \
{ \
return result; \
} \
nn::dbg::PrintResult(result); \
} \
namespace {
const char* const NAND_TWL_ARCHIVE_NAME = "twln:";
const char* const NAND_TWL_KENJ_DIR_PATHNAME = "twln:/title/00030004/4b454e4a";
const char* const NAND_TWL_KENJ_SAVE_DATA_PATHNAME = "twln:/title/00030004/4b454e4a/data/Public.sav";
const nn::ProgramId NAND_TWL_KENJ_PROGRAM_ID = 0x000480044b454e4aULL;
// 乱数生成クラス
// 線形合同法を用いて乱数を生成する。
class Random
{
private:
nn::util::Int64<u64> m_x; //!< 乱数値
nn::util::Int64<u64> m_mul; //!< 乗数
nn::util::Int64<u64> m_add; //!< 加算する数
public:
Random(u64 seed = 0)
{
SetSeed(seed);
}
void SetSeed(u64 seed)
{
m_x = seed;
m_mul = (1566083941LL << 32) + 1812433253LL;
m_add = 2531011;
}
u32 Get32(u32 max = 0xFFFFFFFFU)
{
m_x = m_mul * m_x + m_add;
if (max != 0)
{
return (u32)(((m_x >> 32) * max) >> 32);
}
return 0;
}
};
nn::Result DeleteKENJ(void);
void FatalDrawing(nn::Result result);
const size_t ERASE_THREAD_STACK_SIZE = 0x1000;
nn::os::Thread s_EraseThread;
nn::os::StackBuffer<ERASE_THREAD_STACK_SIZE> s_EraseThreadStack;
demo::RenderSystemDrawing s_RenderSystem;
// グラフィックスに割り当てるメモリ
const size_t s_GxHeapSize = 0x800000;
::std::vector<std::string>* s_pOperationMessage;
void EraseThreadFunc(void)
{
nn::Result result;
s_pOperationMessage->push_back(std::string(""));
// ほぼ日健康手帳を消去する
result = DeleteKENJ();
if(result.IsFailure())
{
nn::dbg::PrintResult(result);
s_pOperationMessage->push_back(std::string("Failed Delete Program"));
FatalDrawing(result);
}
s_pOperationMessage->push_back(std::string(""));
s_pOperationMessage->push_back(std::string("Finished."));
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0, 1, 0, 0);
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0, 1, 0, 0);
}
nn::Result FillRandamDataToKENJSaveData(void)
{
nn::Result result;
nn::fs::FileStream file;
s64 file_size;
// セーブデータオープン
result = file.TryInitialize( NAND_TWL_KENJ_SAVE_DATA_PATHNAME, nn::fs::OPEN_MODE_WRITE );
if( result.IsFailure() )
{
return result;
}
// セーブデータファイルのサイズを読む
result = file.TryGetSize( &file_size );
if( result.IsFailure() )
{
file.Finalize();
return result;
}
nn::fnd::DateTime tm;
nn::os::Tick tick;
Random rand;
u64 seed;
s32 sizeResult = 0;
// バッファの確保
void *buf = std::malloc( file_size );
NN_TPANIC_IF_NULL_( buf );
// 乱数のシードを設定
nn::fnd::DateTimeParameters param = tm.GetNow().GetParameters();
seed = tm.DateToDays( param.year, param.month, param.day );
seed = (u64)(seed * 86400 + param.hour * 3600 + param.minute * 60 + param.second);
seed = (u64)(seed ^ tick.GetSystemCurrent());
rand.SetSeed( seed );
// バッファを乱数で埋める
u8 *p = (u8 *)buf;
for (s32 loopSizeFile = 0; loopSizeFile < file_size; loopSizeFile++)
{
p[loopSizeFile] = (u8)rand.Get32(0xff);
}
// 書き込み
result = file.TryWrite(&sizeResult, buf, file_size);
file.Finalize();
return result;
}
nn::Result DeleteKENJ(void)
{
nn::Result result;
// TWl領域をマウントする
result = nn::fs::MountSpecialArchive( NAND_TWL_ARCHIVE_NAME, nn::fs::CTR::ARCHIVE_TYPE_TWL_NAND );
if( result.IsFailure() )
{
NN_LOG("Twl NAND Mount Failed...\n");
return result;
}
// アプリが存在するかどうか確かめる
nn::fs::Directory dir;
if( dir.TryInitialize(NAND_TWL_KENJ_DIR_PATHNAME).IsFailure() )
{
s_pOperationMessage->push_back(std::string("KENJ is not Exist\n"));
dir.Finalize();
}
else
{
s_pOperationMessage->push_back(std::string("Deleting..."));
// ここでfinalizeしておかないと、DeleteProgramでフェータルになる。
dir.Finalize();
// ほぼ日健康手帳のセーブデータを乱数で埋める
result = FillRandamDataToKENJSaveData();
if( result.IsFailure() )
{
nn::fs::Unmount( "twln:" );
return result;
}
// ほぼ日健康手帳を消す
result = nn::am::DeleteUserProgram(nn::fs::MEDIA_TYPE_NAND, NAND_TWL_KENJ_PROGRAM_ID);
UTIL_RETURN_IF_NOT_AM_NOT_FOUND(result);
}
nn::fs::Unmount( "twln:" );
return result;
}
void SetTextWriterCore()
{
using namespace common;
GetTextWriter()->Print("KENJ Eraser\n\n");
::std::vector<std::string>::iterator it;
for (it = s_pOperationMessage->begin(); it != s_pOperationMessage->end(); it++)
{
GetTextWriter()->Printf("%s\n", it->c_str());
}
}
void FatalDrawing(nn::Result result)
{
char resultStr[32];
std::snprintf(resultStr, sizeof(resultStr), "%X", result.GetPrintableBits());
s_pOperationMessage->push_back(resultStr);
for(;;)
{
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 1.f, 0, 0, 0);
s_RenderSystem.Clear();
common::SetDrawTextHandler(SetTextWriterCore);
common::DrawResFont(NN_GX_DISPLAY0);
s_RenderSystem.SwapBuffers();
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 1.f, 0, 0, 0);
s_RenderSystem.Clear();
s_RenderSystem.SwapBuffers();
}
}
}
extern "C" void nnMain(void)
{
// os の初期化
nn::os::Initialize();
// fs の初期化
nn::fs::Initialize();
// appletの初期化
nn::applet::Enable( false );
// hid の初期化
nn::Result result = nn::hid::Initialize();
NN_UTIL_PANIC_IF_FAILED(result);
// cfg の初期化
nn::cfg::CTR::Initialize();
// am の初期化
nn::am::InitializeForSystemMenu();
// ヒープの確保
common::HeapManager::GetHeap()->Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(), nn::os::ALLOCATE_OPTION_LINEAR);
// RenderSystem の準備
uptr heapForGx = reinterpret_cast<uptr>(common::HeapManager::GetHeap()->Allocate(s_GxHeapSize));
s_RenderSystem.Initialize(heapForGx, s_GxHeapSize);
// ResFontの初期化
common::InitializeResFont();
std::vector<std::string> operationMessage;
s_pOperationMessage = &operationMessage;
s_EraseThread.Start(EraseThreadFunc, s_EraseThreadStack);
// ボタン入力
nn::hid::PadReader padReader;
nn::hid::PadStatus padStatus;
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0, 0, 0, 0);
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0, 0, 0, 0);
for(;;)
{
padReader.ReadLatest(&padStatus);
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
s_RenderSystem.Clear();
common::SetDrawTextHandler(SetTextWriterCore);
common::DrawResFont(NN_GX_DISPLAY0);
s_RenderSystem.SwapBuffers();
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
s_RenderSystem.Clear();
s_RenderSystem.SwapBuffers();
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(10));
if ( nn::applet::IsExpectedToCloseApplication() )
{
nn::applet::PrepareToCloseApplication();
nn::applet::CloseApplication();
}
}
}