ctr_Repair/trunk/ConsoleDataMigration/sources/common/SdReaderWriter.cpp
N2614 eeca247d7e FSのTry系APIのハンドリング見直し
吸出しスレッドのResultをチェックするように
HeapManagerの挙動変更。コンストラクタでAllocateしてデストラクタでFreeするように。
PlayHistoryManagerの削除

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@358 385bec56-5757-e545-9c3a-d8741f4650f1
2011-07-06 07:20:39 +00:00

254 lines
6.6 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: SdReaderWriter.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 "SdReaderWriter.h"
#include "SdMountManager.h"
#include "CommonLogger.h"
#include "Aes_define.h"
#include <nn/crypto/crypto_AesCmac.h>
#include <nn/crypto/crypto_SwAesCtrContext.h>
#include <nn/crypto/crypto_Sha256.h>
#include <nn/crypto/crypto_SwAesCmac.h>
#include <cstdlib>
namespace common
{
nn::Result SdReaderWriter::Initialize()
{
nn::Result result;
// 初期化済みなら何もしない
if(m_IsInitialized)
{
return nn::ResultSuccess();
}
result = SdMountManager::Mount();
if(result.IsSuccess())
{
m_IsInitialized = true;
return nn::ResultSuccess();
}
else
{
return result;
}
}
nn::Result SdReaderWriter::Finalize()
{
nn::Result result;
result = SdMountManager::Unmount();
m_IsInitialized = false;
return result;
}
nn::Result SdReaderWriter::WriteBufCore(const wchar_t* path, void* buf, size_t size)
{
NN_ASSERT(path != NULL);
NN_ASSERT(size > 0);
nn::Result result = Initialize();
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
result = file.TryInitialize(path, nn::fs::OPEN_MODE_WRITE | nn::fs::OPEN_MODE_CREATE);
if (result.IsSuccess())
{
s32 writeSize;
result = file.TryWrite(&writeSize, buf, size, false);
if (result.IsSuccess())
{
// 何もしない
}
else
{
NN_LOG("SD TryWrite failed\n");
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
}
}
else
{
NN_LOG("SD TryInitialize failed\n");
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
}
return result;
}
nn::Result SdReaderWriter::WriteBuf(const wchar_t* path, void* buf, size_t size)
{
nn::Result result;
result = WriteBufCore(path, buf, size);
NN_UTIL_RETURN_IF_FAILED(result);
result = file.TryFlush();
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
file.Finalize();
result = Finalize();
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
return result;
}
nn::Result SdReaderWriter::WriteBufWithCmac(const wchar_t* path, void* buf, size_t size)
{
nn::Result result;
result = WriteBufCore(path, buf, size);
NN_UTIL_RETURN_IF_FAILED(result);
nn::crypto::Initialize();
bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE];
nn::crypto::CalculateSha256(sha256Hash, buf, size);
bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE];
result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
s32 writeSize;
result = file.TryWrite(&writeSize, cmac, sizeof(cmac), false);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = file.TryFlush();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
file.Finalize();
result = Finalize();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
return result;
}
nn::Result SdReaderWriter::ReadBufCore(const wchar_t* path, void* buf, size_t size, size_t* totalSize)
{
NN_ASSERT(path != NULL);
NN_ASSERT(size > 0);
nn::Result result;
if(!m_IsInitialized)
{
Initialize();
}
result = file.TryInitialize(path, nn::fs::OPEN_MODE_READ);
if (result.IsSuccess())
{
s32 readSize;
result = file.TryRead(&readSize, buf, size);
if (result.IsSuccess())
{
// TODO バッファを超えるサイズのファイル読み込み
*totalSize = readSize;
}
else
{
NN_LOG("SD TryRead failed\n");
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
}
}
else
{
NN_LOG("SD TryInitialize failed\n");
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
}
return result;
}
nn::Result SdReaderWriter::ReadBuf(const wchar_t* path, void* buf, size_t size, size_t* totalSize)
{
nn::Result result;
result = ReadBufCore(path, buf, size, totalSize);
NN_UTIL_RETURN_IF_FAILED(result);
file.Finalize();
return result;
}
nn::Result SdReaderWriter::ReadBufWithCmac(const wchar_t* path, void* buf, size_t size, size_t* totalSize)
{
nn::Result result;
NN_ASSERT(size > nn::crypto::AES_CMAC_MAC_SIZE);
result = ReadBufCore(path, buf, size, totalSize);
NN_UTIL_RETURN_IF_FAILED(result);
file.Finalize();
// ハッシュが付加されていない
if(*totalSize < nn::crypto::AES_CMAC_MAC_SIZE)
{
return nn::fs::ResultVerificationFailed();
}
*totalSize -= nn::crypto::AES_CMAC_MAC_SIZE;
// CMACの検証を行う
nn::crypto::Initialize();
bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE];
nn::crypto::CalculateSha256(sha256Hash, buf, *totalSize);
bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE];
result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey);
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
if(std::memcmp(reinterpret_cast<bit8*>(buf) + *totalSize, cmac, sizeof(cmac)) != 0)
{
// 無効なファイル
char filename[256];
std::wcstombs(filename, path, sizeof(filename));
filename[sizeof(filename) - 1] = '\0';
COMMON_LOGGER("Verification Failed %s\n", filename);
return nn::fs::ResultVerificationFailed();
}
// CMACを0埋め
std::memset(reinterpret_cast<bit8*>(buf) + *totalSize, 0, sizeof(cmac));
return result;
}
nn::Result SdReaderWriter::CreateDirectory(const wchar_t* path)
{
nn::Result result;
if(!m_IsInitialized)
{
Initialize();
}
NN_LOG("Create Directory %ls\n", path);
result = nn::fs::TryCreateDirectory(path);
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
result = Finalize();
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
return nn::ResultSuccess();
}
}