| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2009 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include <cstddef>
 | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | #include <memory>
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-07 20:06:58 -05:00
										 |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "Common/FileUtil.h"
 | 
					
						
							|  |  |  | #include "Common/MathUtil.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:29:54 -04:00
										 |  |  | #include "Common/Logging/Log.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include "DiscIO/Blob.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "DiscIO/WiiWad.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace DiscIO | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CBlobBigEndianReader | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	CBlobBigEndianReader(DiscIO::IBlobReader& _rReader) : m_rReader(_rReader) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u32 Read32(u64 _Offset) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		u32 Temp; | 
					
						
							|  |  |  | 		m_rReader.Read(_Offset, 4, (u8*)&Temp); | 
					
						
							|  |  |  | 		return(Common::swap32(Temp)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 	DiscIO::IBlobReader& m_rReader; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | WiiWAD::WiiWAD(const std::string& name) | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | 	std::unique_ptr<IBlobReader> reader(DiscIO::CreateBlobReader(name)); | 
					
						
							|  |  |  | 	if (reader == nullptr || File::IsDirectory(name)) | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		m_Valid = false; | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | 	m_Valid = ParseWAD(*reader); | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | WiiWAD::~WiiWAD() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (m_Valid) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-05-22 17:52:54 -04:00
										 |  |  | 		delete[] m_pCertificateChain; | 
					
						
							|  |  |  | 		delete[] m_pTicket; | 
					
						
							|  |  |  | 		delete[] m_pTMD; | 
					
						
							|  |  |  | 		delete[] m_pDataApp; | 
					
						
							|  |  |  | 		delete[] m_pFooter; | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u8* WiiWAD::CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 	if (_Size > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		u8* pTmpBuffer = new u8[_Size]; | 
					
						
							| 
									
										
										
										
											2014-11-13 21:28:27 -05:00
										 |  |  | 		_dbg_assert_msg_(BOOT, pTmpBuffer!=nullptr, "WiiWAD: Can't allocate memory for WAD entry"); | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 		if (!_rReader.Read(_Offset, _Size, pTmpBuffer)) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 			ERROR_LOG(DISCIO, "WiiWAD: Could not read from file"); | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 			PanicAlertT("WiiWAD: Could not read from file"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return pTmpBuffer; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 	return nullptr; | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool WiiWAD::ParseWAD(DiscIO::IBlobReader& _rReader) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 	CBlobBigEndianReader ReaderBig(_rReader); | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	// get header size
 | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 	u32 HeaderSize = ReaderBig.Read32(0); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	if (HeaderSize != 0x20) | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		_dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20"); | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	// get header
 | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 	u8 Header[0x20]; | 
					
						
							|  |  |  | 	_rReader.Read(0, HeaderSize, Header); | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 	u32 HeaderType = ReaderBig.Read32(0x4); | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 	if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType)) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_CertificateChainSize    = ReaderBig.Read32(0x8); | 
					
						
							|  |  |  | 	u32 Reserved              = ReaderBig.Read32(0xC); | 
					
						
							|  |  |  | 	m_TicketSize              = ReaderBig.Read32(0x10); | 
					
						
							|  |  |  | 	m_TMDSize                 = ReaderBig.Read32(0x14); | 
					
						
							|  |  |  | 	m_DataAppSize             = ReaderBig.Read32(0x18); | 
					
						
							|  |  |  | 	m_FooterSize              = ReaderBig.Read32(0x1C); | 
					
						
							| 
									
										
										
										
											2013-04-16 23:14:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-21 20:11:52 -04:00
										 |  |  | 	if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG) | 
					
						
							|  |  |  | 		_dbg_assert_msg_(BOOT, Reserved==0x00, "WiiWAD: Reserved must be 0x00"); | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 	u32 Offset = 0x40; | 
					
						
							|  |  |  | 	m_pCertificateChain   = CreateWADEntry(_rReader, m_CertificateChainSize, Offset);  Offset += ROUND_UP(m_CertificateChainSize, 0x40); | 
					
						
							|  |  |  | 	m_pTicket             = CreateWADEntry(_rReader, m_TicketSize, Offset);            Offset += ROUND_UP(m_TicketSize, 0x40); | 
					
						
							|  |  |  | 	m_pTMD                = CreateWADEntry(_rReader, m_TMDSize, Offset);               Offset += ROUND_UP(m_TMDSize, 0x40); | 
					
						
							|  |  |  | 	m_pDataApp            = CreateWADEntry(_rReader, m_DataAppSize, Offset);           Offset += ROUND_UP(m_DataAppSize, 0x40); | 
					
						
							|  |  |  | 	m_pFooter             = CreateWADEntry(_rReader, m_FooterSize, Offset);            Offset += ROUND_UP(m_FooterSize, 0x40); | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | bool WiiWAD::IsWiiWAD(const std::string& name) | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | 	std::unique_ptr<IBlobReader> blob_reader(DiscIO::CreateBlobReader(name)); | 
					
						
							|  |  |  | 	if (blob_reader == nullptr) | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | 	CBlobBigEndianReader big_endian_reader(*blob_reader); | 
					
						
							|  |  |  | 	bool result = false; | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-13 21:28:27 -05:00
										 |  |  | 	// check for Wii wad
 | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | 	if (big_endian_reader.Read32(0x00) == 0x20) | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | 		u32 wad_type = big_endian_reader.Read32(0x04); | 
					
						
							|  |  |  | 		switch (wad_type) | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 		case 0x49730000: | 
					
						
							|  |  |  | 		case 0x69620000: | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | 			result = true; | 
					
						
							| 
									
										
										
										
											2013-03-19 09:59:41 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | 	return result; | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace end
 | 
					
						
							|  |  |  | 
 |