ctr_Repair/trunk/KENJEraser/main.cpp
N2205 d246b688b8 ほぼ日健康手帳削除ツールコミット
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@267 385bec56-5757-e545-9c3a-d8741f4650f1
2011-05-23 12:54:57 +00:00

330 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_ApiLocalImporter.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";
// 乱数生成クラス
// 線形合同法を用いて乱数を生成する。
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 );
NN_LOG("save data size : %d\n", file_size);
if( result.IsFailure() )
{
file.Finalize();
return result;
}
nn::fnd::TimeSpan ts;
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 );
// 乱数のシードを設定
// [TODO]シードをちゃんと決める
seed = (u64)(ts.GetMilliSeconds() ^ tick.GetSystemCurrent());
// NN_LOG("Time Span MilliSec : %x\n", ts.GetMilliSeconds());
// NN_LOG("Get System Current Tick : %x\n", tick.GetSystemCurrent());
NN_LOG("seed : %d\n", seed);
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);
if( file_size != sizeResult )
{
NN_LOG("Write Failed...\n");
NN_LOG("File Size : %d\n", file_size);
NN_LOG("Write Size : %d\n", sizeResult);
}
NN_LOG("Save Data Fill Success!\n");
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();
// ほぼ日健康手帳を消す
result = nn::am::DeleteProgram(nn::fs::MEDIA_TYPE_NAND, 0x000480044b454e4aULL);
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::init::Initialize();
// am の初期化
nn::am::InitializeForLocalImporter();
// ヒープの確保
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();
}
}
}