示例#1
0
static IVolume* CreateVolumeFromCryptedWiiImage(std::unique_ptr<IBlobReader> reader, u32 _PartitionGroup, u32 _VolumeType, u32 _VolumeNum)
{
	CBlobBigEndianReader big_endian_reader(*reader);

	u32 numPartitions = big_endian_reader.Read32(0x40000 + (_PartitionGroup * 8));
	u64 PartitionsOffset = (u64)big_endian_reader.Read32(0x40000 + (_PartitionGroup * 8) + 4) << 2;

	// Check if we're looking for a valid partition
	if ((int)_VolumeNum != -1 && _VolumeNum > numPartitions)
		return nullptr;

	struct SPartition
	{
		u64 Offset;
		u32 Type;
	};

	struct SPartitionGroup
	{
		u32 numPartitions;
		u64 PartitionsOffset;
		std::vector<SPartition> PartitionsVec;
	};
	SPartitionGroup PartitionGroup[4];

	// Read all partitions
	for (SPartitionGroup& group : PartitionGroup)
	{
		for (u32 i = 0; i < numPartitions; i++)
		{
			SPartition Partition;
			Partition.Offset = ((u64)big_endian_reader.Read32(PartitionsOffset + (i * 8) + 0)) << 2;
			Partition.Type   = big_endian_reader.Read32(PartitionsOffset + (i * 8) + 4);
			group.PartitionsVec.push_back(Partition);
		}
	}

	// Return the partition type specified or number
	// types: 0 = game, 1 = firmware update, 2 = channel installer
	//  some partitions on SSBB use the ASCII title id of the demo VC game they hold...
	for (size_t i = 0; i < PartitionGroup[_PartitionGroup].PartitionsVec.size(); i++)
	{
		const SPartition& rPartition = PartitionGroup[_PartitionGroup].PartitionsVec.at(i);

		if ((rPartition.Type == _VolumeType && (int)_VolumeNum == -1) || i == _VolumeNum)
		{
			u8 VolumeKey[16];
			VolumeKeyForPartition(*reader, rPartition.Offset, VolumeKey);
			return new CVolumeWiiCrypted(std::move(reader), rPartition.Offset, VolumeKey);
		}
	}

	return nullptr;
}
示例#2
0
bool WiiWAD::ParseWAD(IBlobReader& reader)
{
  CBlobBigEndianReader big_endian_reader(reader);

  if (!IsWiiWAD(big_endian_reader))
    return false;

  u32 certificate_chain_size;
  u32 reserved;
  u32 ticket_size;
  u32 tmd_size;
  u32 data_app_size;
  u32 footer_size;

  if (!big_endian_reader.ReadSwapped(0x08, &certificate_chain_size) ||
      !big_endian_reader.ReadSwapped(0x0C, &reserved) ||
      !big_endian_reader.ReadSwapped(0x10, &ticket_size) ||
      !big_endian_reader.ReadSwapped(0x14, &tmd_size) ||
      !big_endian_reader.ReadSwapped(0x18, &data_app_size) ||
      !big_endian_reader.ReadSwapped(0x1C, &footer_size))
    return false;

  if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG)
    _dbg_assert_msg_(BOOT, reserved == 0x00, "WiiWAD: Reserved must be 0x00");

  u32 offset = 0x40;
  m_certificate_chain = CreateWADEntry(reader, certificate_chain_size, offset);
  offset += ROUND_UP(certificate_chain_size, 0x40);
  m_ticket = CreateWADEntry(reader, ticket_size, offset);
  offset += ROUND_UP(ticket_size, 0x40);
  m_tmd = CreateWADEntry(reader, tmd_size, offset);
  offset += ROUND_UP(tmd_size, 0x40);
  m_data_app = CreateWADEntry(reader, data_app_size, offset);
  offset += ROUND_UP(data_app_size, 0x40);
  m_footer = CreateWADEntry(reader, footer_size, offset);
  offset += ROUND_UP(footer_size, 0x40);

  return true;
}
示例#3
0
bool WiiWAD::IsWiiWAD(const std::string& name)
{
	std::unique_ptr<IBlobReader> blob_reader(DiscIO::CreateBlobReader(name));
	if (blob_reader == nullptr)
		return false;

	CBlobBigEndianReader big_endian_reader(*blob_reader);
	bool result = false;

	// check for Wii wad
	if (big_endian_reader.Read32(0x00) == 0x20)
	{
		u32 wad_type = big_endian_reader.Read32(0x04);
		switch (wad_type)
		{
		case 0x49730000:
		case 0x69620000:
			result = true;
		}
	}

	return result;
}