mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Make DVDLowOpenPartition actually change partitions.
This commit is contained in:
@ -107,19 +107,17 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
|
|||||||
_dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[1].m_Address == 0, "DVDLowOpenPartition with ticket");
|
_dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[1].m_Address == 0, "DVDLowOpenPartition with ticket");
|
||||||
_dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[2].m_Address == 0, "DVDLowOpenPartition with cert chain");
|
_dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[2].m_Address == 0, "DVDLowOpenPartition with cert chain");
|
||||||
|
|
||||||
// Get TMD offset for requested partition...
|
u64 const partition_offset = ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2);
|
||||||
u64 const TMDOffset = ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2 ) + 0x2c0;
|
VolumeHandler::GetVolume()->ChangePartition(partition_offset);
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: TMDOffset 0x%016" PRIx64, TMDOffset);
|
INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: partition_offset 0x%016" PRIx64, partition_offset);
|
||||||
|
|
||||||
static u32 const TMDsz = 0x208; //CommandBuffer.PayloadBuffer[0].m_Size;
|
|
||||||
u8 pTMD[TMDsz];
|
|
||||||
|
|
||||||
// Read TMD to the buffer
|
// Read TMD to the buffer
|
||||||
VolumeHandler::RAWReadToPtr(pTMD, TMDOffset, TMDsz);
|
u8 pTMD[0x800];
|
||||||
|
u32 tmdSz;
|
||||||
Memory::CopyToEmu(CommandBuffer.PayloadBuffer[0].m_Address, pTMD, TMDsz);
|
VolumeHandler::GetVolume()->GetTMD(pTMD, &tmdSz);
|
||||||
WII_IPC_HLE_Interface::ES_DIVerify(pTMD, TMDsz);
|
Memory::CopyToEmu(CommandBuffer.PayloadBuffer[0].m_Address, pTMD, tmdSz);
|
||||||
|
WII_IPC_HLE_Interface::ES_DIVerify(pTMD, tmdSz);
|
||||||
|
|
||||||
ReturnValue = 1;
|
ReturnValue = 1;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ public:
|
|||||||
virtual bool CheckIntegrity() const { return false; }
|
virtual bool CheckIntegrity() const { return false; }
|
||||||
virtual bool IsDiscTwo() const { return false; }
|
virtual bool IsDiscTwo() const { return false; }
|
||||||
|
|
||||||
|
virtual bool ChangePartition(u64 offset) { return false; }
|
||||||
|
|
||||||
// Increment CACHE_REVISION if values are changed (ISOFile.cpp)
|
// Increment CACHE_REVISION if values are changed (ISOFile.cpp)
|
||||||
enum ECountry
|
enum ECountry
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,7 @@ static const unsigned char s_master_key_korean[16] = {
|
|||||||
0x13,0xf2,0xfe,0xfb,0xba,0x4c,0x9b,0x7e
|
0x13,0xf2,0xfe,0xfb,0xba,0x4c,0x9b,0x7e
|
||||||
};
|
};
|
||||||
|
|
||||||
static IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _PartitionGroup, u32 _VolumeType, u32 _VolumeNum, bool Korean);
|
static IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _PartitionGroup, u32 _VolumeType, u32 _VolumeNum);
|
||||||
EDiscType GetDiscType(IBlobReader& _rReader);
|
EDiscType GetDiscType(IBlobReader& _rReader);
|
||||||
|
|
||||||
IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionGroup, u32 _VolumeNum)
|
IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionGroup, u32 _VolumeNum)
|
||||||
@ -89,10 +89,7 @@ IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionG
|
|||||||
|
|
||||||
case DISC_TYPE_WII_CONTAINER:
|
case DISC_TYPE_WII_CONTAINER:
|
||||||
{
|
{
|
||||||
u8 region;
|
IVolume* pVolume = CreateVolumeFromCryptedWiiImage(*pReader, _PartitionGroup, 0, _VolumeNum);
|
||||||
pReader->Read(0x3,1,®ion);
|
|
||||||
|
|
||||||
IVolume* pVolume = CreateVolumeFromCryptedWiiImage(*pReader, _PartitionGroup, 0, _VolumeNum, region == 'K');
|
|
||||||
|
|
||||||
if (pVolume == nullptr)
|
if (pVolume == nullptr)
|
||||||
{
|
{
|
||||||
@ -140,7 +137,32 @@ bool IsVolumeWadFile(const IVolume *_rVolume)
|
|||||||
return (Common::swap32(MagicWord) == 0x00204973 || Common::swap32(MagicWord) == 0x00206962);
|
return (Common::swap32(MagicWord) == 0x00204973 || Common::swap32(MagicWord) == 0x00206962);
|
||||||
}
|
}
|
||||||
|
|
||||||
static IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _PartitionGroup, u32 _VolumeType, u32 _VolumeNum, bool Korean)
|
void VolumeKeyForParition(IBlobReader& _rReader, u64 offset, u8* VolumeKey)
|
||||||
|
{
|
||||||
|
CBlobBigEndianReader Reader(_rReader);
|
||||||
|
|
||||||
|
u8 SubKey[16];
|
||||||
|
_rReader.Read(offset + 0x1bf, 16, SubKey);
|
||||||
|
|
||||||
|
u8 IV[16];
|
||||||
|
memset(IV, 0, 16);
|
||||||
|
_rReader.Read(offset + 0x44c, 8, IV);
|
||||||
|
|
||||||
|
bool usingKoreanKey = false;
|
||||||
|
// Issue: 6813
|
||||||
|
// Magic value is at partition's offset + 0x1f1 (1byte)
|
||||||
|
// If encrypted with the Korean key, the magic value would be 1
|
||||||
|
// Otherwise it is zero
|
||||||
|
if (Reader.Read8(0x3) == 'K' && Reader.Read8(offset + 0x1f1) == 1)
|
||||||
|
usingKoreanKey = true;
|
||||||
|
|
||||||
|
aes_context AES_ctx;
|
||||||
|
aes_setkey_dec(&AES_ctx, (usingKoreanKey ? s_master_key_korean : s_master_key), 128);
|
||||||
|
|
||||||
|
aes_crypt_cbc(&AES_ctx, AES_DECRYPT, 16, IV, SubKey, VolumeKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
static IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _PartitionGroup, u32 _VolumeType, u32 _VolumeNum)
|
||||||
{
|
{
|
||||||
CBlobBigEndianReader Reader(_rReader);
|
CBlobBigEndianReader Reader(_rReader);
|
||||||
|
|
||||||
@ -184,32 +206,11 @@ static IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _Part
|
|||||||
{
|
{
|
||||||
const SPartition& rPartition = PartitionGroup[_PartitionGroup].PartitionsVec.at(i);
|
const SPartition& rPartition = PartitionGroup[_PartitionGroup].PartitionsVec.at(i);
|
||||||
|
|
||||||
if (rPartition.Type == _VolumeType || i == _VolumeNum)
|
if ((rPartition.Type == _VolumeType && (int)_VolumeNum == -1) || i == _VolumeNum)
|
||||||
{
|
{
|
||||||
u8 SubKey[16];
|
|
||||||
_rReader.Read(rPartition.Offset + 0x1bf, 16, SubKey);
|
|
||||||
|
|
||||||
u8 IV[16];
|
|
||||||
memset(IV, 0, 16);
|
|
||||||
_rReader.Read(rPartition.Offset + 0x44c, 8, IV);
|
|
||||||
|
|
||||||
bool usingKoreanKey = false;
|
|
||||||
// Issue: 6813
|
|
||||||
// Magic value is at partition's offset + 0x1f1 (1byte)
|
|
||||||
// If encrypted with the Korean key, the magic value would be 1
|
|
||||||
// Otherwise it is zero
|
|
||||||
if (Korean && Reader.Read8(rPartition.Offset + 0x1f1) == 1)
|
|
||||||
usingKoreanKey = true;
|
|
||||||
|
|
||||||
aes_context AES_ctx;
|
|
||||||
aes_setkey_dec(&AES_ctx, (usingKoreanKey ? s_master_key_korean : s_master_key), 128);
|
|
||||||
|
|
||||||
u8 VolumeKey[16];
|
u8 VolumeKey[16];
|
||||||
aes_crypt_cbc(&AES_ctx, AES_DECRYPT, 16, IV, SubKey, VolumeKey);
|
VolumeKeyForParition(_rReader, rPartition.Offset, VolumeKey);
|
||||||
|
return new CVolumeWiiCrypted(&_rReader, rPartition.Offset, VolumeKey);
|
||||||
// -1 means the caller just wanted the partition with matching type
|
|
||||||
if ((int)_VolumeNum == -1 || i == _VolumeNum)
|
|
||||||
return new CVolumeWiiCrypted(&_rReader, rPartition.Offset, VolumeKey);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,10 +12,12 @@ namespace DiscIO
|
|||||||
{
|
{
|
||||||
|
|
||||||
class IVolume;
|
class IVolume;
|
||||||
|
class IBlobReader;
|
||||||
|
|
||||||
IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionGroup = 0, u32 _VolumeNum = -1);
|
IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionGroup = 0, u32 _VolumeNum = -1);
|
||||||
IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader = "", const std::string& _rDOL = "");
|
IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader = "", const std::string& _rDOL = "");
|
||||||
bool IsVolumeWiiDisc(const IVolume *_rVolume);
|
bool IsVolumeWiiDisc(const IVolume *_rVolume);
|
||||||
bool IsVolumeWadFile(const IVolume *_rVolume);
|
bool IsVolumeWadFile(const IVolume *_rVolume);
|
||||||
|
void VolumeKeyForParition(IBlobReader& _rReader, u64 offset, u8* VolumeKey);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "DiscIO/Blob.h"
|
#include "DiscIO/Blob.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
#include "DiscIO/VolumeCreator.h"
|
||||||
#include "DiscIO/VolumeGC.h"
|
#include "DiscIO/VolumeGC.h"
|
||||||
#include "DiscIO/VolumeWiiCrypted.h"
|
#include "DiscIO/VolumeWiiCrypted.h"
|
||||||
|
|
||||||
@ -33,6 +34,17 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset,
|
|||||||
m_pBuffer = new u8[0x8000];
|
m_pBuffer = new u8[0x8000];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CVolumeWiiCrypted::ChangePartition(u64 offset)
|
||||||
|
{
|
||||||
|
m_VolumeOffset = offset;
|
||||||
|
m_LastDecryptedBlockOffset = -1;
|
||||||
|
|
||||||
|
u8 volume_key[16];
|
||||||
|
DiscIO::VolumeKeyForParition(*m_pReader, offset, volume_key);
|
||||||
|
aes_setkey_dec(m_AES_ctx.get(), volume_key, 128);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CVolumeWiiCrypted::~CVolumeWiiCrypted()
|
CVolumeWiiCrypted::~CVolumeWiiCrypted()
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,8 @@ public:
|
|||||||
bool SupportsIntegrityCheck() const override { return true; }
|
bool SupportsIntegrityCheck() const override { return true; }
|
||||||
bool CheckIntegrity() const override;
|
bool CheckIntegrity() const override;
|
||||||
|
|
||||||
|
bool ChangePartition(u64 offset) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IBlobReader> m_pReader;
|
std::unique_ptr<IBlobReader> m_pReader;
|
||||||
std::unique_ptr<aes_context> m_AES_ctx;
|
std::unique_ptr<aes_context> m_AES_ctx;
|
||||||
|
Reference in New Issue
Block a user